Cuberite
A lightweight, fast and extensible game server for Minecraft
CryptoKey.cpp
Go to the documentation of this file.
1 
2 // CryptoKey.cpp
3 
4 // Implements the cCryptoKey class representing a RSA public key in mbedTLS
5 
6 #include "Globals.h"
7 #include "CryptoKey.h"
8 
9 
10 
11 
12 
14 {
15  mbedtls_pk_init(&m_Pk);
16  m_CtrDrbg.Initialize("rsa_pubkey", 10);
17 }
18 
19 
20 
21 
22 
23 cCryptoKey::cCryptoKey(const AString & a_PublicKeyData)
24 {
25  mbedtls_pk_init(&m_Pk);
26  m_CtrDrbg.Initialize("rsa_pubkey", 10);
27  int res = ParsePublic(a_PublicKeyData.data(), a_PublicKeyData.size());
28  if (res != 0)
29  {
30  LOGWARNING("Failed to parse public key: -0x%x", res);
31  ASSERT(!"Cannot parse PubKey");
32  return;
33  }
34 }
35 
36 
37 
38 
39 
40 cCryptoKey::cCryptoKey(const AString & a_PrivateKeyData, const AString & a_Password)
41 {
42  mbedtls_pk_init(&m_Pk);
43  m_CtrDrbg.Initialize("rsa_privkey", 11);
44  int res = ParsePrivate(a_PrivateKeyData.data(), a_PrivateKeyData.size(), a_Password);
45  if (res != 0)
46  {
47  LOGWARNING("Failed to parse private key: -0x%x", res);
48  ASSERT(!"Cannot parse PrivKey");
49  return;
50  }
51 }
52 
53 
54 
55 
56 
58 {
59  mbedtls_pk_free(&m_Pk);
60 }
61 
62 
63 
64 
65 
66 int cCryptoKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength)
67 {
68  ASSERT(IsValid());
69 
70  size_t DecryptedLen = a_DecryptedMaxLength;
71  int res = mbedtls_pk_decrypt(&m_Pk,
72  a_EncryptedData, a_EncryptedLength,
73  a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength,
74  mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
75  );
76  if (res != 0)
77  {
78  return res;
79  }
80  return static_cast<int>(DecryptedLen);
81 }
82 
83 
84 
85 
86 
87 int cCryptoKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength)
88 {
89  ASSERT(IsValid());
90 
91  size_t EncryptedLength = a_EncryptedMaxLength;
92  int res = mbedtls_pk_encrypt(&m_Pk,
93  a_PlainData, a_PlainLength, a_EncryptedData, &EncryptedLength, a_EncryptedMaxLength,
94  mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
95  );
96  if (res != 0)
97  {
98  return res;
99  }
100  return static_cast<int>(EncryptedLength);
101 }
102 
103 
104 
105 
106 
107 int cCryptoKey::ParsePublic(const void * a_Data, size_t a_NumBytes)
108 {
109  ASSERT(!IsValid()); // Cannot parse a second key
110 
111  return mbedtls_pk_parse_public_key(&m_Pk, static_cast<const unsigned char *>(a_Data), a_NumBytes);
112 }
113 
114 
115 
116 
117 
118 int cCryptoKey::ParsePrivate(const void * a_Data, size_t a_NumBytes, const AString & a_Password)
119 {
120  ASSERT(!IsValid()); // Cannot parse a second key
121  // mbedTLS requires that PEM-encoded data is passed including the terminating NUL byte,
122  // and DER-encoded data is decoded properly even with an extra trailing NUL byte, so we simply add one to everything:
123  AString keyData(static_cast<const char *>(a_Data), a_NumBytes);
124 
125  if (a_Password.empty())
126  {
127  return mbedtls_pk_parse_key(&m_Pk, reinterpret_cast<const unsigned char *>(keyData.data()), a_NumBytes + 1, nullptr, 0, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal());
128  }
129  else
130  {
131  return mbedtls_pk_parse_key(
132  &m_Pk,
133  reinterpret_cast<const unsigned char *>(keyData.data()), a_NumBytes + 1,
134  reinterpret_cast<const unsigned char *>(a_Password.c_str()), a_Password.size(),
135  mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal()
136  );
137  }
138 }
139 
140 
141 
142 
143 
144 bool cCryptoKey::IsValid(void) const
145 {
146  return (mbedtls_pk_get_type(&m_Pk) != MBEDTLS_PK_NONE);
147 }
#define ASSERT(x)
Definition: Globals.h:276
unsigned char Byte
Definition: Globals.h:161
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
std::string AString
Definition: StringUtils.h:11
int ParsePrivate(const void *a_Data, size_t a_NumBytes, const AString &a_Password)
Parses the specified data into a private key representation.
Definition: CryptoKey.cpp:118
mbedtls_pk_context m_Pk
The mbedTLS representation of the key data.
Definition: CryptoKey.h:62
int Encrypt(const Byte *a_PlainData, size_t a_PlainLength, Byte *a_EncryptedData, size_t a_EncryptedMaxLength)
Encrypts the data using the stored public key Both a_EncryptedData and a_DecryptedData must be at lea...
Definition: CryptoKey.cpp:87
int ParsePublic(const void *a_Data, size_t a_NumBytes)
Parses the specified data into a public key representation.
Definition: CryptoKey.cpp:107
bool IsValid(void) const
Returns true if the contained key is valid.
Definition: CryptoKey.cpp:144
cCryptoKey(void)
Constructs an empty key instance.
Definition: CryptoKey.cpp:13
int Decrypt(const Byte *a_EncryptedData, size_t a_EncryptedLength, Byte *a_DecryptedData, size_t a_DecryptedMaxLength)
Decrypts the data using the stored public key Both a_EncryptedData and a_DecryptedData must be at lea...
Definition: CryptoKey.cpp:66
cCtrDrbgContext m_CtrDrbg
The random generator used in encryption and decryption.
Definition: CryptoKey.h:65
mbedtls_ctr_drbg_context * GetInternal(void)
Returns the internal context ptr.
int Initialize(const void *a_Custom, size_t a_CustomSize)
Initializes the context.