blob: d5b8cc9baaab09d9eeda5a0da55d01c96cef7622 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
2 Copyright (C) 2006, 2009 by Werner Dittmann
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18 * In addition, as a special exception, the copyright holders give
19 * permission to link the code of portions of this program with the
20 * OpenSSL library under certain conditions as described in each
21 * individual source file, and distribute linked combinations
22 * including the two.
23 * You must obey the GNU General Public License in all respects
24 * for all of the code used other than OpenSSL. If you modify
25 * file(s) with this exception, you may extend this exception to your
26 * version of the file(s), but you are not obligated to do so. If you
27 * do not wish to do so, delete this exception statement from your
28 * version. If you delete this exception statement from all source
29 * files in the program, then also delete it here.
30 */
31
32/** Copyright (C) 2006, 2009
33 *
34 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
35 */
36
37#include <string.h>
38
39#include <openssl/crypto.h>
40#include <openssl/bio.h>
41#include <openssl/bn.h>
42#include <openssl/rand.h>
43#include <openssl/err.h>
44#include <openssl/dh.h>
45#include <openssl/evp.h>
46#include <openssl/ec.h>
47#include <openssl/ecdh.h>
48
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050049#include <zrtp/crypto/zrtpDH.h>
50#include <zrtp/libzrtpcpp/ZrtpTextData.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050051
52// extern void initializeOpenSSL();
53
54static BIGNUM* bnP2048 = NULL;
55static BIGNUM* bnP3072 = NULL;
56// static BIGNUM* bnP4096 = NULL;
57
58static BIGNUM* bnP2048MinusOne = NULL;
59static BIGNUM* bnP3072MinusOne = NULL;
60// static BIGNUM* bnP4096MinusOne = NULL;
61
62static uint8_t dhinit = 0;
63
64void randomZRTP(uint8_t *buf, int32_t length)
65{
66// initializeOpenSSL();
67 RAND_bytes(buf, length);
68}
69
70static const uint8_t P2048[] =
71{
72 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
73 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
74 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
75 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
76 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
77 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
78 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
79 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
80 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
81 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
82 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
83 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
84 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
85 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
86 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
87 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
88 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
89 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
90 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
91 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
92 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
93 0xFF, 0xFF, 0xFF, 0xFF
94};
95
96static const uint8_t P3072[] =
97{
98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
99 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
100 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
101 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
102 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
103 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
104 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
105 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
106 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
107 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
108 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
109 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
110 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
111 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
112 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
113 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
114 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
115 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
116 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
117 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
118 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
119 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
120 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
121 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
122 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
123 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
124 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
125 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
126 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
127 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
128 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
129 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
130};
131
132/* **************
133static const uint8_t P4096[] =
134{
1350xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
1360x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
1370x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
1380x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
1390xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
1400xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
1410xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
1420xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
1430xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
1440x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
1450xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
1460x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
1470x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
1480x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
1490x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
1500xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
1510xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
1520xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
1530xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
1540xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
1550x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
1560x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
1570xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
1580x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
1590xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
1600x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
1610xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
1620x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
1630xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
1640xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
1650x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
1660xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
1670x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
1680x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
1690x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
1700x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
1710x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
1720xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
1730x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
1740x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
1750x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
1760x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
1770xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
178};
179*************** */
180
181ZrtpDH::ZrtpDH(const char* type) {
182
183 uint8_t random[64];
184
185 // Well - the algo type is only 4 char thus cast to int32 and compare
186 if (*(int32_t*)type == *(int32_t*)dh2k) {
187 pkType = DH2K;
188 }
189 else if (*(int32_t*)type == *(int32_t*)dh3k) {
190 pkType = DH3K;
191 }
192 else if (*(int32_t*)type == *(int32_t*)ec25) {
193 pkType = EC25;
194 }
195 else if (*(int32_t*)type == *(int32_t*)ec38) {
196 pkType = EC38;
197 }
198 else {
199 return;
200 }
201
202// initializeOpenSSL();
203
204 if (!dhinit) {
205 bnP2048 = BN_bin2bn(P2048,sizeof(P2048),NULL);
206 bnP3072 = BN_bin2bn(P3072,sizeof(P3072),NULL);
207// bnP4096 = BN_bin2bn(P4096,sizeof(P4096),NULL);
208
209 bnP2048MinusOne = BN_dup(bnP2048);
210 BN_sub_word(bnP2048MinusOne, 1);
211
212 bnP3072MinusOne = BN_dup(bnP3072);
213 BN_sub_word(bnP3072MinusOne, 1);
214
215// bnP4096MinusOne = BN_dup(bnP4096);
216// BN_sub_word(bnP4096MinusOne, 1);
217 dhinit = 1;
218 }
219
220 DH* tmpCtx = NULL;
221 switch (pkType) {
222 case DH2K:
223 case DH3K:
224 ctx = static_cast<void*>(DH_new());
225 tmpCtx = static_cast<DH*>(ctx);
226 tmpCtx->g = BN_new();
227 BN_set_word(tmpCtx->g, DH_GENERATOR_2);
228
229 if (pkType == DH2K) {
230 tmpCtx->p = BN_dup(bnP2048);
231 RAND_bytes(random, 32);
232 tmpCtx->priv_key = BN_bin2bn(random, 32, NULL);
233 }
234 else if (pkType == DH3K) {
235 tmpCtx->p = BN_dup(bnP3072);
236 RAND_bytes(random, 64);
237 tmpCtx->priv_key = BN_bin2bn(random, 32, NULL);
238 }
239 break;
240
241 case EC25:
242 ctx = static_cast<void*>(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
243 break;
244 case EC38:
245 ctx = static_cast<void*>(EC_KEY_new_by_curve_name(NID_secp384r1));
246 break;
247 }
248}
249
250ZrtpDH::~ZrtpDH() {
251 if (ctx == NULL)
252 return;
253
254 switch (pkType) {
255 case DH2K:
256 case DH3K:
257 DH_free(static_cast<DH*>(ctx));
258 break;
259
260 case EC25:
261 case EC38:
262 EC_KEY_free(static_cast<EC_KEY*>(ctx));
263 break;
264 }
265}
266
267int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {
268
269 if (pkType == DH2K || pkType == DH3K) {
270 DH* tmpCtx = static_cast<DH*>(ctx);
271
272 if (tmpCtx->pub_key != NULL) {
273 BN_free(tmpCtx->pub_key);
274 }
275 tmpCtx->pub_key = BN_bin2bn(pubKeyBytes, getDhSize(), NULL);
276 return DH_compute_key(secret, tmpCtx->pub_key, tmpCtx);
277 }
278 if (pkType == EC25 || pkType == EC38) {
279 uint8_t buffer[100];
280 int32_t ret;
281 int32_t len = getPubKeySize();
282
283 buffer[0] = POINT_CONVERSION_UNCOMPRESSED;
284 memcpy(buffer+1, pubKeyBytes, len);
285
286 EC_POINT* point = EC_POINT_new(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)));
287 EC_POINT_oct2point(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),
288 point, buffer, len+1, NULL);
289 ret = ECDH_compute_key(secret, getDhSize(), point, static_cast<EC_KEY*>(ctx), NULL);
290 EC_POINT_free(point);
291 return ret;
292 }
293 return -1;
294}
295
296int32_t ZrtpDH::generatePublicKey()
297{
298 if (pkType == DH2K || pkType == DH3K)
299 return DH_generate_key(static_cast<DH*>(ctx));
300
301 if (pkType == EC25 || pkType == EC38)
302 return EC_KEY_generate_key(static_cast<EC_KEY*>(ctx));
303 return 0;
304}
305
306int32_t ZrtpDH::getDhSize() const
307{
308 if (pkType == DH2K || pkType == DH3K)
309 return DH_size(static_cast<DH*>(ctx));
310
311 if (pkType == EC25)
312 return 32;
313 if (pkType == EC38)
314 return 48;
315
316 return 0;
317}
318
319int32_t ZrtpDH::getPubKeySize() const
320{
321 if (pkType == DH2K || pkType == DH3K)
322 return BN_num_bytes(static_cast<DH*>(ctx)->pub_key);
323
324 if (pkType == EC25 || pkType == EC38)
325 return EC_POINT_point2oct(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),
326 EC_KEY_get0_public_key(static_cast<EC_KEY*>(ctx)),
327 POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL) - 1;
328 return 0;
329
330}
331
332int32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const
333{
334
335 if (pkType == DH2K || pkType == DH3K) {
336 // get len of pub_key, prepend with zeros to DH size
337 int32_t prepend = getDhSize() - getPubKeySize();
338 if (prepend > 0) {
339 memset(buf, 0, prepend);
340 }
341 return BN_bn2bin(static_cast<DH*>(ctx)->pub_key, buf + prepend);
342 }
343 if (pkType == EC25 || pkType == EC38) {
344 uint8_t buffer[100];
345
346 int len = EC_POINT_point2oct(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),
347 EC_KEY_get0_public_key(static_cast<EC_KEY*>(ctx)),
348 POINT_CONVERSION_UNCOMPRESSED, buffer, 100, NULL);
349 memcpy(buf, buffer+1, len-1);
350 return len-1;
351 }
352 return 0;
353}
354
355int32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const
356{
357 if (pkType == EC25 || pkType == EC38) {
358 uint8_t buffer[100];
359 int32_t ret;
360 int32_t len = getPubKeySize();
361
362 buffer[0] = POINT_CONVERSION_UNCOMPRESSED;
363 memcpy(buffer+1, pubKeyBytes, len);
364
365 EC_POINT* point = EC_POINT_new(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)));
366 EC_POINT_oct2point(EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)),
367 point, buffer, len+1, NULL);
368 EC_KEY* chkKey = EC_KEY_new();
369 EC_KEY_set_group(chkKey, EC_KEY_get0_group(static_cast<EC_KEY*>(ctx)));
370 EC_KEY_set_public_key(chkKey, point);
371 ret = EC_KEY_check_key(chkKey);
372
373 EC_POINT_free(point);
374 EC_KEY_free(chkKey);
375
376 return ret;
377 }
378
379 BIGNUM* pubKeyOther = BN_bin2bn(pubKeyBytes, getDhSize(), NULL);
380
381 if (pkType == DH2K) {
382 if (BN_cmp(bnP2048MinusOne, pubKeyOther) == 0)
383 return 0;
384 }
385 else if (pkType == DH3K) {
386 if (BN_cmp(bnP3072MinusOne, pubKeyOther) == 0)
387 return 0;
388 }
389 else {
390// if (BN_cmp(bnP4096MinusOne, pubKeyOther) == 0)
391 return 0;
392 }
393 int one = BN_is_one(pubKeyOther);
394 if (one == 1)
395 return 0;
396
397 BN_free(pubKeyOther);
398 return 1;
399}
400
401const char* ZrtpDH::getDHtype()
402{
403 switch (pkType) {
404 case DH2K:
405 return dh2k;
406 break;
407 case DH3K:
408 return dh3k;
409 break;
410 case EC25:
411 return ec25;
412 break;
413 case EC38:
414 return ec38;
415 break;
416 }
417 return NULL;
418}
419
420/** EMACS **
421 * Local variables:
422 * mode: c++
423 * c-default-style: ellemtel
424 * c-basic-offset: 4
425 * End:
426 */