Cuberite
A lightweight, fast and extensible game server for Minecraft
RsaPrivateKey.cpp
Go to the documentation of this file.
1 
2 // RsaPrivateKey.cpp
3 
4 #include "Globals.h"
5 #include "RsaPrivateKey.h"
6 #include "mbedtls/pk.h"
7 
8 
9 
10 
11 
13 {
14  mbedtls_rsa_init(&m_Rsa);
15  m_CtrDrbg.Initialize("RSA", 3);
16 }
17 
18 
19 
20 
21 
23 {
24  mbedtls_rsa_init(&m_Rsa);
25  mbedtls_rsa_copy(&m_Rsa, &a_Other.m_Rsa);
26  m_CtrDrbg.Initialize("RSA", 3);
27 }
28 
29 
30 
31 
32 
34 {
35  mbedtls_rsa_free(&m_Rsa);
36 }
37 
38 
39 
40 
41 
42 bool cRsaPrivateKey::Generate(unsigned a_KeySizeBits)
43 {
44  int res = mbedtls_rsa_gen_key(&m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), a_KeySizeBits, 65537);
45  if (res != 0)
46  {
47  LOG("RSA key generation failed: -0x%x", -res);
48  return false;
49  }
50 
51  return true;
52 }
53 
54 
55 
56 
57 
59 {
60  class cPubKey
61  {
62  public:
63  cPubKey(mbedtls_rsa_context * a_Rsa) :
64  m_IsValid(false)
65  {
66  mbedtls_pk_init(&m_Key);
67  if (mbedtls_pk_setup(&m_Key, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) != 0)
68  {
69  ASSERT(!"Cannot init PrivKey context");
70  return;
71  }
72  if (mbedtls_rsa_copy(mbedtls_pk_rsa(m_Key), a_Rsa) != 0)
73  {
74  ASSERT(!"Cannot copy PrivKey to PK context");
75  return;
76  }
77  m_IsValid = true;
78  }
79 
80  ~cPubKey()
81  {
82  if (m_IsValid)
83  {
84  mbedtls_pk_free(&m_Key);
85  }
86  }
87 
88  operator mbedtls_pk_context * (void) { return &m_Key; }
89 
90  protected:
91  bool m_IsValid;
92  mbedtls_pk_context m_Key;
93  } PkCtx(&m_Rsa);
94 
95  unsigned char buf[3000];
96  int res = mbedtls_pk_write_pubkey_der(PkCtx, buf, sizeof(buf));
97  if (res < 0)
98  {
99  return {};
100  }
101  return { reinterpret_cast<const std::byte *>(buf + sizeof(buf) - res), static_cast<size_t>(res) };
102 }
103 
104 
105 
106 
107 
108 int cRsaPrivateKey::Decrypt(const ContiguousByteBufferView a_EncryptedData, Byte * a_DecryptedData, size_t a_DecryptedMaxLength)
109 {
110  const auto KeyLength = mbedtls_rsa_get_len(&m_Rsa);
111  if (a_EncryptedData.size() < KeyLength)
112  {
113  LOGD("%s: Invalid a_EncryptedLength: got %zu, exp at least %zu", __FUNCTION__, a_EncryptedData.size(), KeyLength);
114  ASSERT(!"Invalid a_DecryptedMaxLength!");
115  return -1;
116  }
117  if (a_DecryptedMaxLength < KeyLength)
118  {
119  LOGD("%s: Invalid a_DecryptedMaxLength: got %zu, exp at least %zu", __FUNCTION__, a_DecryptedMaxLength, KeyLength);
120  ASSERT(!"Invalid a_DecryptedMaxLength!");
121  return -1;
122  }
123  size_t DecryptedLength;
124  int res = mbedtls_rsa_pkcs1_decrypt(
125  &m_Rsa, mbedtls_ctr_drbg_random, m_CtrDrbg.GetInternal(), &DecryptedLength,
126  reinterpret_cast<const unsigned char *>(a_EncryptedData.data()), a_DecryptedData, a_DecryptedMaxLength
127  );
128  if (res != 0)
129  {
130  return -1;
131  }
132  return static_cast<int>(DecryptedLength);
133 }
std::basic_string_view< std::byte > ContiguousByteBufferView
Definition: Globals.h:376
#define ASSERT(x)
Definition: Globals.h:276
std::basic_string< std::byte > ContiguousByteBuffer
Definition: Globals.h:375
unsigned char Byte
Definition: Globals.h:161
void LOG(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:55
#define LOGD
Definition: LoggerSimple.h:83
mbedtls_ctr_drbg_context * GetInternal(void)
Returns the internal context ptr.
int Initialize(const void *a_Custom, size_t a_CustomSize)
Initializes the context.
Encapsulates an RSA private key used in PKI cryptography.
Definition: RsaPrivateKey.h:21
cRsaPrivateKey(void)
Creates a new empty object, the key is not assigned.
mbedtls_rsa_context m_Rsa
The mbedTLS key context.
Definition: RsaPrivateKey.h:47
cCtrDrbgContext m_CtrDrbg
The random generator used for generating the key and encryption / decryption.
Definition: RsaPrivateKey.h:50
int Decrypt(ContiguousByteBufferView a_EncryptedData, Byte *a_DecryptedData, size_t a_DecryptedMaxLength)
Decrypts the data using RSAES-PKCS#1 algorithm.
ContiguousByteBuffer GetPubKeyDER(void)
Returns the public key part encoded in ASN1 DER encoding.
bool Generate(unsigned a_KeySizeBits=1024)
Generates a new key within this object, with the specified size in bits.