Cuberite
A lightweight, fast and extensible game server for Minecraft
Sha1Checksum.cpp
Go to the documentation of this file.
1 
2 // Sha1Checksum.cpp
3 
4 // Declares the cSha1Checksum class representing the SHA-1 checksum calculator
5 
6 #include "Globals.h"
7 #include "Sha1Checksum.h"
8 
9 
10 
11 
12 
13 /*
14 // Self-test the hash formatting for known values:
15 // sha1(Notch) : 4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48
16 // sha1(jeb_) : -7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1
17 // sha1(simon) : 88e16a1019277b15d58faf0541e11910eb756f6
18 
19 static class Test
20 {
21 public:
22  Test(void)
23  {
24  AString DigestNotch, DigestJeb, DigestSimon;
25  Byte Digest[20];
26  cSha1Checksum Checksum;
27  Checksum.Update((const Byte *)"Notch", 5);
28  Checksum.Finalize(Digest);
29  cSha1Checksum::DigestToJava(Digest, DigestNotch);
30  Checksum.Restart();
31  Checksum.Update((const Byte *)"jeb_", 4);
32  Checksum.Finalize(Digest);
33  cSha1Checksum::DigestToJava(Digest, DigestJeb);
34  Checksum.Restart();
35  Checksum.Update((const Byte *)"simon", 5);
36  Checksum.Finalize(Digest);
37  cSha1Checksum::DigestToJava(Digest, DigestSimon);
38  printf("Notch: \"%s\"\n", DigestNotch.c_str());
39  printf("jeb_: \"%s\"\n", DigestJeb.c_str());
40  printf("simon: \"%s\"\n", DigestSimon.c_str());
41  assert(DigestNotch == "4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48");
42  assert(DigestJeb == "-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1");
43  assert(DigestSimon == "88e16a1019277b15d58faf0541e11910eb756f6");
44  }
45 } test;
46 */
47 
48 
49 
50 
51 
53 // cSha1Checksum:
54 
56  m_DoesAcceptInput(true)
57 {
58  mbedtls_sha1_starts(&m_Sha1);
59 }
60 
61 
62 
63 
64 
65 void cSha1Checksum::Update(const Byte * a_Data, size_t a_Length)
66 {
67  ASSERT(m_DoesAcceptInput); // Not Finalize()-d yet, or Restart()-ed
68 
69  mbedtls_sha1_update(&m_Sha1, a_Data, a_Length);
70 }
71 
72 
73 
74 
75 
77 {
78  ASSERT(m_DoesAcceptInput); // Not Finalize()-d yet, or Restart()-ed
79 
80  mbedtls_sha1_finish(&m_Sha1, a_Output);
81  m_DoesAcceptInput = false;
82 }
83 
84 
85 
86 
87 
88 void cSha1Checksum::DigestToJava(const Checksum & a_Digest, AString & a_Out)
89 {
90  Checksum Digest;
91  memcpy(Digest, a_Digest, sizeof(Digest));
92 
93  bool IsNegative = (Digest[0] >= 0x80);
94  if (IsNegative)
95  {
96  // Two's complement:
97  bool carry = true; // Add one to the whole number
98  for (int i = 19; i >= 0; i--)
99  {
100  Digest[i] = ~Digest[i];
101  if (carry)
102  {
103  carry = (Digest[i] == 0xff);
104  Digest[i]++;
105  }
106  }
107  }
108  a_Out.clear();
109  a_Out.reserve(40);
110  for (int i = 0; i < 20; i++)
111  {
112  AppendPrintf(a_Out, "%02x", Digest[i]);
113  }
114  while ((a_Out.length() > 0) && (a_Out[0] == '0'))
115  {
116  a_Out.erase(0, 1);
117  }
118  if (IsNegative)
119  {
120  a_Out.insert(0, "-");
121  }
122 }
123 
124 
125 
126 
127 
129 {
130  mbedtls_sha1_starts(&m_Sha1);
131  m_DoesAcceptInput = true;
132 }
133 
134 
135 
136 
void Finalize(Checksum &a_Output)
Calculates and returns the final checksum.
Byte Checksum[20]
Definition: Sha1Checksum.h:22
void Update(const Byte *a_Data, size_t a_Length)
Adds the specified data to the checksum.
AString & AppendPrintf(AString &a_Dst, const char *format, const Args &...args)
Add the formated string to the existing data in the string.
Definition: StringUtils.h:37
#define ASSERT(x)
Definition: Globals.h:335
std::string AString
Definition: StringUtils.h:13
mbedtls_sha1_context m_Sha1
Definition: Sha1Checksum.h:47
bool m_DoesAcceptInput
True if the object is accepts more input data, false if Finalize()-d (need to Restart()) ...
Definition: Sha1Checksum.h:45
unsigned char Byte
Definition: Globals.h:117
static void DigestToJava(const Checksum &a_Digest, AString &a_JavaOut)
Converts a raw 160-bit SHA1 digest into a Java Hex representation According to http://wiki.vg/Protocol_Encryption.
void Restart(void)
Clears the current context and start a new checksum calculation.