summaryrefslogtreecommitdiffstats
path: root/src/PolarSSL++/CryptoKey.cpp
blob: b01fee5f909b2ab4e65b77fa3d75b0a625d8e101 (plain) (blame)
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

// CryptoKey.cpp

// Implements the cCryptoKey class representing a RSA public key in PolarSSL

#include "Globals.h"
#include "CryptoKey.h"





cCryptoKey::cCryptoKey(void)
{
	pk_init(&m_Pk);
	m_CtrDrbg.Initialize("rsa_pubkey", 10);
}





cCryptoKey::cCryptoKey(const AString & a_PublicKeyData)
{
	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)
{
	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()
{
	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 = pk_decrypt(&m_Pk,
		a_EncryptedData, a_EncryptedLength,
		a_DecryptedData, &DecryptedLen, a_DecryptedMaxLength,
		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 = pk_encrypt(&m_Pk,
		a_PlainData, a_PlainLength, a_EncryptedData, &EncryptedLength, a_EncryptedMaxLength,
		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 pk_parse_public_key(&m_Pk, reinterpret_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

	if (a_Password.empty())
	{
		return pk_parse_key(&m_Pk, reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes, nullptr, 0);
	}
	else
	{
		return pk_parse_key(
			&m_Pk,
			reinterpret_cast<const unsigned char *>(a_Data), a_NumBytes,
			reinterpret_cast<const unsigned char *>(a_Password.c_str()), a_Password.size()
		);
	}
}





bool cCryptoKey::IsValid(void) const
{
	return (pk_get_type(&m_Pk) != POLARSSL_PK_NONE);
}