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