View | Details | Raw Unified | Return to bug 234517
Collapse All | Expand All

(-)./files/patch-openssl-11x (+328 lines)
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
 
(-)./Makefile (-1 / +1 lines)
Lines 3-9 Link Here
3
3
4
PORTNAME=	libqtelegram-ae
4
PORTNAME=	libqtelegram-ae
5
PORTVERSION=	6.1
5
PORTVERSION=	6.1
6
PORTREVISION=	2
6
PORTREVISION=	3
7
DISTVERSIONPREFIX=	v
7
DISTVERSIONPREFIX=	v
8
DISTVERSIONSUFFIX=	-stable
8
DISTVERSIONSUFFIX=	-stable
9
CATEGORIES=	net-im
9
CATEGORIES=	net-im

Return to bug 234517