Line 0
Link Here
|
|
|
1 |
From 2b31ce1780e8fdcc7cf55cb9ac17e9bae48eb2b0 Mon Sep 17 00:00:00 2001 |
2 |
From: Bardia Daneshvar <realbardiax@gmail.com> |
3 |
Date: Sun, 25 Mar 2018 00:46:01 +0430 |
4 |
Subject: [PATCH] Compatible with openssl 1.1.x |
5 |
|
6 |
--- |
7 |
core/dcauth.cpp | 40 ++++++++++++++++++ |
8 |
libqtelegram-ae.pri | 2 +- |
9 |
util/cryptoutils.cpp | 98 +++++++++++++++++++++++++++++++++++++++++--- |
10 |
util/cryptoutils.h | 4 ++ |
11 |
util/utils.cpp | 12 +++++- |
12 |
util/utils.h | 2 +- |
13 |
6 files changed, 150 insertions(+), 8 deletions(-) |
14 |
|
15 |
index 4a7c81b..dd5904d 100644 |
16 |
--- core/dcauth.cpp |
17 |
+++ core/dcauth.cpp |
18 |
@@ -213,6 +213,7 @@ void DCAuth::processDHAnswer(InboundPkt &inboundPkt) { |
19 |
inboundPkt.setInPtr(decryptBuffer + 15); |
20 |
inboundPkt.setInEnd(decryptBuffer + (l >> 2)); |
21 |
|
22 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
23 |
BIGNUM dh_prime, dh_g, g_a, auth_key_num; |
24 |
BN_init(&dh_prime); |
25 |
BN_init (&g_a); |
26 |
@@ -223,6 +224,19 @@ void DCAuth::processDHAnswer(InboundPkt &inboundPkt) { |
27 |
qint32 serverTime = inboundPkt.fetchInt(); |
28 |
mAsserter.check(inboundPkt.inPtr() <= inboundPkt.inEnd()); |
29 |
mAsserter.check(mCrypto->checkDHParams (&dh_prime, g) >= 0); |
30 |
+#else |
31 |
+ BIGNUM *dh_prime = BN_new(); |
32 |
+ BIGNUM *dh_g = BN_new(); |
33 |
+ BIGNUM *g_a = BN_new(); |
34 |
+ BIGNUM *auth_key_num = BN_new(); |
35 |
+ mAsserter.check(inboundPkt.fetchBignum(dh_prime) > 0); |
36 |
+ mAsserter.check(inboundPkt.fetchBignum(g_a) > 0); |
37 |
+ mAsserter.check(Utils::check_g_bn(dh_prime, g_a) >= 0); |
38 |
+ |
39 |
+ qint32 serverTime = inboundPkt.fetchInt(); |
40 |
+ mAsserter.check(inboundPkt.inPtr() <= inboundPkt.inEnd()); |
41 |
+ mAsserter.check(mCrypto->checkDHParams (dh_prime, g) >= 0); |
42 |
+#endif |
43 |
|
44 |
static char sha1Buffer[20]; |
45 |
SHA1 ((uchar *) decryptBuffer + 20, (inboundPkt.inPtr() - decryptBuffer - 5) * 4, (uchar *) sha1Buffer); |
46 |
@@ -242,6 +256,7 @@ void DCAuth::processDHAnswer(InboundPkt &inboundPkt) { |
47 |
outboundPkt.appendInts((qint32 *)m_serverNonce, 4); |
48 |
outboundPkt.appendLong(0LL); |
49 |
|
50 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
51 |
BN_init (&dh_g); |
52 |
Utils::ensure (BN_set_word (&dh_g, g)); |
53 |
char s_power [256]; |
54 |
@@ -267,6 +282,31 @@ void DCAuth::processDHAnswer(InboundPkt &inboundPkt) { |
55 |
BN_free (&dh_g); |
56 |
BN_free (&g_a); |
57 |
BN_free (&dh_prime); |
58 |
+#else |
59 |
+ Utils::ensure (BN_set_word (dh_g, g)); |
60 |
+ char s_power [256]; |
61 |
+ Utils::randomBytes(s_power, 256); |
62 |
+ BIGNUM *dh_power = BN_bin2bn ((uchar *)s_power, 256, 0); |
63 |
+ Utils::ensurePtr(dh_power); |
64 |
+ |
65 |
+ BIGNUM *y = BN_new (); |
66 |
+ Utils::ensurePtr(y); |
67 |
+ Utils::ensure(mCrypto->BNModExp(y, dh_g, dh_power, dh_prime)); |
68 |
+ outboundPkt.appendBignum(y); |
69 |
+ BN_free (y); |
70 |
+ |
71 |
+ Utils::ensure(mCrypto->BNModExp(auth_key_num, g_a, dh_power, dh_prime)); |
72 |
+ l = BN_num_bytes (auth_key_num); |
73 |
+ |
74 |
+ mAsserter.check(l >= 250 && l <= 256); |
75 |
+ mAsserter.check(BN_bn2bin (auth_key_num, (uchar *)m_dc->authKey())); |
76 |
+ Utils::secureZeroMemory (m_dc->authKey() + l, 0, 256 - l); |
77 |
+ BN_free (dh_power); |
78 |
+ BN_free (auth_key_num); |
79 |
+ BN_free (dh_g); |
80 |
+ BN_free (g_a); |
81 |
+ BN_free (dh_prime); |
82 |
+#endif |
83 |
|
84 |
SHA1 ((uchar *) (outboundPkt.buffer() + 5), (outboundPkt.length() - 5) * 4, (uchar *) outboundPkt.buffer()); |
85 |
qint32 encryptBuffer[DECRYPT_BUFFER_INTS]; |
86 |
index 73f9e47..a030e19 100644 |
87 |
--- libqtelegram-ae.pri |
88 |
+++ libqtelegram-ae.pri |
89 |
@@ -33,7 +33,7 @@ win32 { |
90 |
LIBS += -L$${OPENSSL_LIB_DIR} -lssl -lcrypto -lz |
91 |
} |
92 |
|
93 |
- INCLUDEPATH += $${OPENSSL_INCLUDE_PATH} |
94 |
+# INCLUDEPATH += $${OPENSSL_INCLUDE_PATH} |
95 |
} |
96 |
|
97 |
include(telegram/telegram.pri) |
98 |
index 83ea85d..d88a2d6 100644 |
99 |
--- util/cryptoutils.cpp |
100 |
+++ util/cryptoutils.cpp |
101 |
@@ -40,7 +40,15 @@ CryptoUtils::~CryptoUtils() { |
102 |
|
103 |
qint32 CryptoUtils::encryptPacketBuffer(OutboundPkt &p, void *encryptBuffer) { |
104 |
RSA *pubKey = mSettings->pubKey(); |
105 |
- return padRsaEncrypt((char *) p.buffer(), p.length() * 4, (char *) encryptBuffer, ENCRYPT_BUFFER_INTS * 4, pubKey->n, pubKey->e); |
106 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
107 |
+ BIGNUM *key_e = pubKey->e; |
108 |
+ BIGNUM *key_n = pubKey->n; |
109 |
+#else |
110 |
+ const BIGNUM *key_e; |
111 |
+ const BIGNUM *key_n; |
112 |
+ RSA_get0_key(pubKey, &key_n, &key_e, NULL); |
113 |
+#endif |
114 |
+ return padRsaEncrypt((char *) p.buffer(), p.length() * 4, (char *) encryptBuffer, ENCRYPT_BUFFER_INTS * 4, key_n, key_e); |
115 |
} |
116 |
|
117 |
qint32 CryptoUtils::encryptPacketBufferAESUnAuth(const char serverNonce[16], const char hiddenClientNonce[32], OutboundPkt &p, void *encryptBuffer) { |
118 |
@@ -48,7 +56,11 @@ qint32 CryptoUtils::encryptPacketBufferAESUnAuth(const char serverNonce[16], con |
119 |
return padAESEncrypt ((char *) p.buffer(), p.length() * 4, (char *) encryptBuffer, ENCRYPT_BUFFER_INTS * 4); |
120 |
} |
121 |
|
122 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
123 |
qint32 CryptoUtils::padRsaEncrypt (char *from, qint32 from_len, char *to, qint32 size, BIGNUM *N, BIGNUM *E) { |
124 |
+#else |
125 |
+qint32 CryptoUtils::padRsaEncrypt (char *from, qint32 from_len, char *to, qint32 size, const BIGNUM *N, const BIGNUM *E) { |
126 |
+#endif |
127 |
qint32 pad = (255000 - from_len - 32) % 255 + 32; |
128 |
qint32 chunks = (from_len + pad) / 255; |
129 |
qint32 bits = BN_num_bits (N); |
130 |
@@ -61,6 +73,7 @@ qint32 CryptoUtils::padRsaEncrypt (char *from, qint32 from_len, char *to, qint32 |
131 |
Q_UNUSED(isSupported); |
132 |
Q_ASSERT(isSupported >= 0); |
133 |
qint32 i; |
134 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
135 |
BIGNUM x, y; |
136 |
BN_init (&x); |
137 |
BN_init (&y); |
138 |
@@ -77,6 +90,23 @@ qint32 CryptoUtils::padRsaEncrypt (char *from, qint32 from_len, char *to, qint32 |
139 |
} |
140 |
BN_free (&x); |
141 |
BN_free (&y); |
142 |
+#else |
143 |
+ BIGNUM *x = BN_new(), |
144 |
+ *y = BN_new(); |
145 |
+ for (i = 0; i < chunks; i++) { |
146 |
+ BN_bin2bn ((uchar *) from, 255, x); |
147 |
+ qint32 success = BN_mod_exp (y, x, E, N, BN_ctx); |
148 |
+ Q_UNUSED(success); |
149 |
+ Q_ASSERT(success == 1); |
150 |
+ unsigned l = 256 - BN_num_bytes (y); |
151 |
+ Q_ASSERT(l <= 256); |
152 |
+ memset (to, 0, l); |
153 |
+ BN_bn2bin (y, (uchar *) to + l); |
154 |
+ to += 256; |
155 |
+ } |
156 |
+ BN_free (x); |
157 |
+ BN_free (y); |
158 |
+#endif |
159 |
return chunks * 256; |
160 |
} |
161 |
|
162 |
@@ -173,18 +203,26 @@ qint32 CryptoUtils::checkPrime (BIGNUM *p) { |
163 |
|
164 |
qint32 CryptoUtils::checkDHParams (BIGNUM *p, qint32 g) { |
165 |
if (g < 2 || g > 7) { return -1; } |
166 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
167 |
BIGNUM t; |
168 |
BN_init (&t); |
169 |
- |
170 |
BIGNUM dh_g; |
171 |
BN_init (&dh_g); |
172 |
- Utils::ensure (BN_set_word (&dh_g, 4 * g)); |
173 |
|
174 |
+ Utils::ensure (BN_set_word (&dh_g, 4 * g)); |
175 |
Utils::ensure (BN_mod (&t, p, &dh_g, BN_ctx)); |
176 |
qint32 x = BN_get_word (&t); |
177 |
- Q_ASSERT(x >= 0 && x < 4 * g); |
178 |
- |
179 |
BN_free (&dh_g); |
180 |
+#else |
181 |
+ BIGNUM *t = BN_new(); |
182 |
+ BIGNUM *dh_g = BN_new(); |
183 |
+ |
184 |
+ Utils::ensure (BN_set_word (dh_g, 4 * g)); |
185 |
+ Utils::ensure (BN_mod (t, p, dh_g, BN_ctx)); |
186 |
+ qint32 x = BN_get_word (t); |
187 |
+ BN_free (dh_g); |
188 |
+#endif |
189 |
+ Q_ASSERT(x >= 0 && x < 4 * g); |
190 |
|
191 |
switch (g) { |
192 |
case 2: |
193 |
@@ -208,6 +246,7 @@ qint32 CryptoUtils::checkDHParams (BIGNUM *p, qint32 g) { |
194 |
|
195 |
if (!checkPrime (p)) { return -1; } |
196 |
|
197 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
198 |
BIGNUM b; |
199 |
BN_init (&b); |
200 |
Utils::ensure (BN_set_word (&b, 2)); |
201 |
@@ -215,6 +254,14 @@ qint32 CryptoUtils::checkDHParams (BIGNUM *p, qint32 g) { |
202 |
if (!checkPrime (&t)) { return -1; } |
203 |
BN_free (&b); |
204 |
BN_free (&t); |
205 |
+#else |
206 |
+ BIGNUM *b = BN_new(); |
207 |
+ Utils::ensure (BN_set_word (b, 2)); |
208 |
+ Utils::ensure (BN_div (t, 0, p, b, BN_ctx)); |
209 |
+ if (!checkPrime (t)) { return -1; } |
210 |
+ BN_free (b); |
211 |
+ BN_free (t); |
212 |
+#endif |
213 |
return 0; |
214 |
} |
215 |
|
216 |
@@ -229,6 +276,7 @@ qint32 CryptoUtils::checkCalculatedParams(const BIGNUM *gAOrB, const BIGNUM *g, |
217 |
ASSERT(p); |
218 |
|
219 |
// 1) gAOrB and g greater than one and smaller than p-1 |
220 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
221 |
BIGNUM one; |
222 |
BN_init(&one); |
223 |
Utils::ensure(BN_one(&one)); |
224 |
@@ -272,6 +320,46 @@ qint32 CryptoUtils::checkCalculatedParams(const BIGNUM *gAOrB, const BIGNUM *g, |
225 |
BN_free(&exp); |
226 |
BN_free(&lowLimit); |
227 |
BN_free(&highLimit); |
228 |
+#else |
229 |
+ BIGNUM *one = BN_new(); |
230 |
+ Utils::ensure(BN_one(one)); |
231 |
+ |
232 |
+ BIGNUM *pMinusOne = BN_dup(p); |
233 |
+ Utils::ensure(BN_sub_word(pMinusOne, 1)); |
234 |
+ |
235 |
+ // check params greater than one |
236 |
+ if (BN_cmp(gAOrB, one) <= 0) return -1; |
237 |
+ if (BN_cmp(g, one) <= 0) return -1; |
238 |
+ |
239 |
+ // check params <= p-1 |
240 |
+ if (BN_cmp(gAOrB, pMinusOne) >= 0) return -1; |
241 |
+ if (BN_cmp(g, pMinusOne) >= 0) return -1; |
242 |
+ |
243 |
+ // 2) gAOrB between 2^{2048-64} and p - 2^{2048-64} |
244 |
+ quint64 expWord = 2048 - 64; |
245 |
+ BIGNUM *exp = BN_new(); |
246 |
+ Utils::ensure(BN_set_word(exp, expWord)); |
247 |
+ |
248 |
+ BIGNUM *base = BN_new(); |
249 |
+ Utils::ensure(BN_set_word(base, 2)); |
250 |
+ |
251 |
+ // lowLimit = base ^ exp |
252 |
+ BIGNUM *lowLimit = BN_new(); |
253 |
+ Utils::ensure(BN_exp(lowLimit, base, exp, BN_ctx)); |
254 |
+ |
255 |
+ // highLimit = p - lowLimit |
256 |
+ BIGNUM *highLimit = BN_new(); |
257 |
+ BN_sub(highLimit, p, lowLimit); |
258 |
+ |
259 |
+ if (BN_cmp(gAOrB, lowLimit) < 0) return -1; |
260 |
+ if (BN_cmp(gAOrB, highLimit) > 0) return -1; |
261 |
+ |
262 |
+ BN_free(one); |
263 |
+ BN_free(pMinusOne); |
264 |
+ BN_free(exp); |
265 |
+ BN_free(lowLimit); |
266 |
+ BN_free(highLimit); |
267 |
+#endif |
268 |
|
269 |
return 0; |
270 |
} |
271 |
index 3eb9fde..bb0df13 100644 |
272 |
--- util/cryptoutils.h |
273 |
+++ util/cryptoutils.h |
274 |
@@ -39,7 +39,11 @@ class CryptoUtils : public QObject |
275 |
|
276 |
qint32 encryptPacketBuffer(OutboundPkt &p, void *encryptBuffer); |
277 |
qint32 encryptPacketBufferAESUnAuth(const char serverNonce[16], const char hiddenClientNonce[32], OutboundPkt &p, void *encryptBuffer); |
278 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
279 |
qint32 padRsaEncrypt(char *from, qint32 from_len, char *to, qint32 size, BIGNUM *N, BIGNUM *E); |
280 |
+#else |
281 |
+ qint32 padRsaEncrypt(char *from, qint32 from_len, char *to, qint32 size, const BIGNUM *N, const BIGNUM *E); |
282 |
+#endif |
283 |
|
284 |
void initAESAuth (char authKey[192], char msgKey[16], qint32 encrypt); |
285 |
void initAESUnAuth(const char serverNonce[16], const char hiddenClientNonce[32], qint32 encrypt); |
286 |
index f12a3b0..8b12b3b 100644 |
287 |
--- util/utils.cpp |
288 |
+++ util/utils.cpp |
289 |
@@ -152,7 +152,7 @@ QByteArray Utils::generateRandomBytes() { |
290 |
return randomBytes; |
291 |
} |
292 |
|
293 |
-qint32 Utils::serializeBignum(BIGNUM *b, char *buffer, qint32 maxlen) { |
294 |
+qint32 Utils::serializeBignum(const BIGNUM *b, char *buffer, qint32 maxlen) { |
295 |
qint32 itslen = BN_num_bytes (b); |
296 |
qint32 reqlen; |
297 |
if (itslen < 254) { |
298 |
@@ -300,10 +300,20 @@ RSA *Utils::rsaLoadPublicKey(const QString &publicKeyName) { |
299 |
qint64 Utils::computeRSAFingerprint(RSA *key) { |
300 |
static char tempbuff[4096]; |
301 |
static uchar sha[20]; |
302 |
+#if OPENSSL_VERSION_NUMBER < 0x10100000L |
303 |
Q_ASSERT(key->n && key->e); |
304 |
qint32 l1 = serializeBignum (key->n, tempbuff, 4096); |
305 |
Q_ASSERT(l1 > 0); |
306 |
qint32 l2 = serializeBignum (key->e, tempbuff + l1, 4096 - l1); |
307 |
+#else |
308 |
+ const BIGNUM *key_e; |
309 |
+ const BIGNUM *key_n; |
310 |
+ RSA_get0_key(key, &key_n, &key_e, NULL); |
311 |
+ Q_ASSERT(key_n && key_e); |
312 |
+ qint32 l1 = serializeBignum (key_n, tempbuff, 4096); |
313 |
+ Q_ASSERT(l1 > 0); |
314 |
+ qint32 l2 = serializeBignum (key_e, tempbuff + l1, 4096 - l1); |
315 |
+#endif |
316 |
Q_ASSERT(l2 > 0 && l1 + l2 <= 4096); |
317 |
SHA1 ((uchar *)tempbuff, l1 + l2, sha); |
318 |
return *(qint64 *)(sha + 12); |
319 |
index 8afcebd..1297e3a 100644 |
320 |
--- util/utils.h |
321 |
+++ util/utils.h |
322 |
@@ -39,5 +39,5 @@ class LIBQTELEGRAMSHARED_EXPORT Utils : public QObject |
323 |
static qint32 randomBytes(void *buffer, qint32 count); |
324 |
- static qint32 serializeBignum(BIGNUM *b, char *buffer, qint32 maxlen); |
325 |
+ static qint32 serializeBignum(const BIGNUM *b, char *buffer, qint32 maxlen); |
326 |
static double getUTime(qint32 clockId); |
327 |
static quint64 gcd (quint64 a, quint64 b); |
328 |
|