1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
2 * Copyright (c) 2010-2019, Daniel Stenberg <daniel@haxx.se>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms,
6 * with or without modification, are permitted provided
7 * that the following conditions are met:
8 *
9 * Redistributions of source code must retain the above
10 * copyright notice, this list of conditions and the
11 * following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials
16 * provided with the distribution.
17 *
18 * Neither the name of the copyright holder nor the names
19 * of any other contributors may be used to endorse or
20 * promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 * OF SUCH DAMAGE.
37 */
38
39 #include "libssh2_priv.h"
40
41 #include "transport.h"
42 #include "comp.h"
43 #include "mac.h"
44
45 #include <assert.h>
46
47 /* define SHA1_DIGEST_LENGTH for the macro below */
48 #ifndef SHA1_DIGEST_LENGTH
49 #define SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
50 #endif
51
52 /* TODO: Switch this to an inline and handle alloc() failures */
53 /* Helper macro called from
54 kex_method_diffie_hellman_group1_sha1_key_exchange */
55
56 #define LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(value, reqlen, version) \
57 { \
58 if(type == LIBSSH2_EC_CURVE_NISTP256) { \
59 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, value, reqlen, version); \
60 } \
61 else if(type == LIBSSH2_EC_CURVE_NISTP384) { \
62 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(384, value, reqlen, version); \
63 } \
64 else if(type == LIBSSH2_EC_CURVE_NISTP521) { \
65 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, value, reqlen, version); \
66 } \
67 } \
68
69
70 #define LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(digest_type, value, \
71 reqlen, version) \
72 { \
73 libssh2_sha##digest_type##_ctx hash; \
74 unsigned long len = 0; \
75 if(!(value)) { \
76 value = LIBSSH2_ALLOC(session, \
77 reqlen + SHA##digest_type##_DIGEST_LENGTH); \
78 } \
79 if(value) \
80 while(len < (unsigned long)reqlen) { \
81 libssh2_sha##digest_type##_init(&hash); \
82 libssh2_sha##digest_type##_update(hash, \
83 exchange_state->k_value, \
84 exchange_state->k_value_len); \
85 libssh2_sha##digest_type##_update(hash, \
86 exchange_state->h_sig_comp, \
87 SHA##digest_type##_DIGEST_LENGTH); \
88 if(len > 0) { \
89 libssh2_sha##digest_type##_update(hash, value, len); \
90 } \
91 else { \
92 libssh2_sha##digest_type##_update(hash, (version), 1); \
93 libssh2_sha##digest_type##_update(hash, session->session_id,\
94 session->session_id_len); \
95 } \
96 libssh2_sha##digest_type##_final(hash, (value) + len); \
97 len += SHA##digest_type##_DIGEST_LENGTH; \
98 } \
99 }
100
101 /*!
102 * @note The following are wrapper functions used by diffie_hellman_sha_algo().
103 * TODO: Switch backend SHA macros to functions to allow function pointers
104 * @discussion Ideally these would be function pointers but the backend macros
105 * don't allow it so we have to wrap them up in helper functions
106 */
107
_libssh2_sha_algo_ctx_init(int sha_algo,void * ctx)108 static void _libssh2_sha_algo_ctx_init(int sha_algo, void *ctx)
109 {
110 if(sha_algo == 512) {
111 libssh2_sha512_init((libssh2_sha512_ctx*)ctx);
112 }
113 else if(sha_algo == 384) {
114 libssh2_sha384_init((libssh2_sha384_ctx*)ctx);
115 }
116 else if(sha_algo == 256) {
117 libssh2_sha256_init((libssh2_sha256_ctx*)ctx);
118 }
119 else if(sha_algo == 1) {
120 libssh2_sha1_init((libssh2_sha1_ctx*)ctx);
121 }
122 else {
123 assert(0);
124 }
125 }
126
_libssh2_sha_algo_ctx_update(int sha_algo,void * ctx,void * data,size_t len)127 static void _libssh2_sha_algo_ctx_update(int sha_algo, void *ctx,
128 void *data, size_t len)
129 {
130 if(sha_algo == 512) {
131 libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx;
132 libssh2_sha512_update(*_ctx, data, len);
133 }
134 else if(sha_algo == 384) {
135 libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx;
136 libssh2_sha384_update(*_ctx, data, len);
137 }
138 else if(sha_algo == 256) {
139 libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx;
140 libssh2_sha256_update(*_ctx, data, len);
141 }
142 else if(sha_algo == 1) {
143 libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx;
144 libssh2_sha1_update(*_ctx, data, len);
145 }
146 else {
147 #if LIBSSH2DEBUG
148 assert(0);
149 #endif
150 }
151 }
152
_libssh2_sha_algo_ctx_final(int sha_algo,void * ctx,void * hash)153 static void _libssh2_sha_algo_ctx_final(int sha_algo, void *ctx,
154 void *hash)
155 {
156 if(sha_algo == 512) {
157 libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx;
158 libssh2_sha512_final(*_ctx, hash);
159 }
160 else if(sha_algo == 384) {
161 libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx;
162 libssh2_sha384_final(*_ctx, hash);
163 }
164 else if(sha_algo == 256) {
165 libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx;
166 libssh2_sha256_final(*_ctx, hash);
167 }
168 else if(sha_algo == 1) {
169 libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx;
170 libssh2_sha1_final(*_ctx, hash);
171 }
172 else {
173 #if LIBSSH2DEBUG
174 assert(0);
175 #endif
176 }
177 }
178
_libssh2_sha_algo_value_hash(int sha_algo,LIBSSH2_SESSION * session,kmdhgGPshakex_state_t * exchange_state,unsigned char ** data,size_t data_len,const unsigned char * version)179 static void _libssh2_sha_algo_value_hash(int sha_algo,
180 LIBSSH2_SESSION *session,
181 kmdhgGPshakex_state_t *exchange_state,
182 unsigned char **data, size_t data_len,
183 const unsigned char *version)
184 {
185 if(sha_algo == 512) {
186 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, *data, data_len, version);
187 }
188 else if(sha_algo == 384) {
189 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(384, *data, data_len, version);
190 }
191 else if(sha_algo == 256) {
192 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, *data, data_len, version);
193 }
194 else if(sha_algo == 1) {
195 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(1, *data, data_len, version);
196 }
197 else {
198 #if LIBSSH2DEBUG
199 assert(0);
200 #endif
201 }
202 }
203
204
205 /*!
206 * @function diffie_hellman_sha_algo
207 * @abstract Diffie Hellman Key Exchange, Group Agnostic,
208 * SHA Algorithm Agnostic
209 * @result 0 on success, error code on failure
210 */
diffie_hellman_sha_algo(LIBSSH2_SESSION * session,_libssh2_bn * g,_libssh2_bn * p,int group_order,int sha_algo_value,void * exchange_hash_ctx,unsigned char packet_type_init,unsigned char packet_type_reply,unsigned char * midhash,unsigned long midhash_len,kmdhgGPshakex_state_t * exchange_state)211 static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
212 _libssh2_bn *g,
213 _libssh2_bn *p,
214 int group_order,
215 int sha_algo_value,
216 void *exchange_hash_ctx,
217 unsigned char packet_type_init,
218 unsigned char packet_type_reply,
219 unsigned char *midhash,
220 unsigned long midhash_len,
221 kmdhgGPshakex_state_t *exchange_state)
222 {
223 int ret = 0;
224 int rc;
225
226 int digest_len = 0;
227
228 if(sha_algo_value == 512)
229 digest_len = SHA512_DIGEST_LENGTH;
230 else if(sha_algo_value == 384)
231 digest_len = SHA384_DIGEST_LENGTH;
232 else if(sha_algo_value == 256)
233 digest_len = SHA256_DIGEST_LENGTH;
234 else if(sha_algo_value == 1)
235 digest_len = SHA1_DIGEST_LENGTH;
236 else {
237 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
238 "sha algo value is unimplemented");
239 goto clean_exit;
240 }
241
242 if(exchange_state->state == libssh2_NB_state_idle) {
243 /* Setup initial values */
244 exchange_state->e_packet = NULL;
245 exchange_state->s_packet = NULL;
246 exchange_state->k_value = NULL;
247 exchange_state->ctx = _libssh2_bn_ctx_new();
248 libssh2_dh_init(&exchange_state->x);
249 exchange_state->e = _libssh2_bn_init(); /* g^x mod p */
250 exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from
251 server) mod p */
252 exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod
253 p */
254
255 /* Zero the whole thing out */
256 memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t));
257
258 /* Generate x and e */
259 if(_libssh2_bn_bits(p) > LIBSSH2_DH_MAX_MODULUS_BITS) {
260 ret = _libssh2_error(session, LIBSSH2_ERROR_INVAL,
261 "dh modulus value is too large");
262 goto clean_exit;
263 }
264
265 rc = libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p,
266 group_order, exchange_state->ctx);
267 if(rc)
268 goto clean_exit;
269
270 /* Send KEX init */
271 /* packet_type(1) + String Length(4) + leading 0(1) */
272 exchange_state->e_packet_len =
273 _libssh2_bn_bytes(exchange_state->e) + 6;
274 if(_libssh2_bn_bits(exchange_state->e) % 8) {
275 /* Leading 00 not needed */
276 exchange_state->e_packet_len--;
277 }
278
279 exchange_state->e_packet =
280 LIBSSH2_ALLOC(session, exchange_state->e_packet_len);
281 if(!exchange_state->e_packet) {
282 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
283 "Out of memory error");
284 goto clean_exit;
285 }
286 exchange_state->e_packet[0] = packet_type_init;
287 _libssh2_htonu32(exchange_state->e_packet + 1,
288 exchange_state->e_packet_len - 5);
289 if(_libssh2_bn_bits(exchange_state->e) % 8) {
290 _libssh2_bn_to_bin(exchange_state->e,
291 exchange_state->e_packet + 5);
292 }
293 else {
294 exchange_state->e_packet[5] = 0;
295 _libssh2_bn_to_bin(exchange_state->e,
296 exchange_state->e_packet + 6);
297 }
298
299 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d",
300 (int) packet_type_init);
301 exchange_state->state = libssh2_NB_state_created;
302 }
303
304 if(exchange_state->state == libssh2_NB_state_created) {
305 rc = _libssh2_transport_send(session, exchange_state->e_packet,
306 exchange_state->e_packet_len,
307 NULL, 0);
308 if(rc == LIBSSH2_ERROR_EAGAIN) {
309 return rc;
310 }
311 else if(rc) {
312 ret = _libssh2_error(session, rc,
313 "Unable to send KEX init message");
314 goto clean_exit;
315 }
316 exchange_state->state = libssh2_NB_state_sent;
317 }
318
319 if(exchange_state->state == libssh2_NB_state_sent) {
320 if(session->burn_optimistic_kexinit) {
321 /* The first KEX packet to come along will be the guess initially
322 * sent by the server. That guess turned out to be wrong so we
323 * need to silently ignore it */
324 int burn_type;
325
326 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
327 "Waiting for badly guessed KEX packet "
328 "(to be ignored)");
329 burn_type =
330 _libssh2_packet_burn(session, &exchange_state->burn_state);
331 if(burn_type == LIBSSH2_ERROR_EAGAIN) {
332 return burn_type;
333 }
334 else if(burn_type <= 0) {
335 /* Failed to receive a packet */
336 ret = burn_type;
337 goto clean_exit;
338 }
339 session->burn_optimistic_kexinit = 0;
340
341 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
342 "Burnt packet of type: %02x",
343 (unsigned int) burn_type);
344 }
345
346 exchange_state->state = libssh2_NB_state_sent1;
347 }
348
349 if(exchange_state->state == libssh2_NB_state_sent1) {
350 /* Wait for KEX reply */
351 struct string_buf buf;
352 size_t host_key_len;
353
354 rc = _libssh2_packet_require(session, packet_type_reply,
355 &exchange_state->s_packet,
356 &exchange_state->s_packet_len, 0, NULL,
357 0, &exchange_state->req_state);
358 if(rc == LIBSSH2_ERROR_EAGAIN) {
359 return rc;
360 }
361 if(rc) {
362 ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
363 "Timed out waiting for KEX reply");
364 goto clean_exit;
365 }
366
367 /* Parse KEXDH_REPLY */
368 if(exchange_state->s_packet_len < 5) {
369 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
370 "Unexpected packet length");
371 goto clean_exit;
372 }
373
374 buf.data = exchange_state->s_packet;
375 buf.len = exchange_state->s_packet_len;
376 buf.dataptr = buf.data;
377 buf.dataptr++; /* advance past type */
378
379 if(session->server_hostkey)
380 LIBSSH2_FREE(session, session->server_hostkey);
381
382 if(_libssh2_copy_string(session, &buf, &(session->server_hostkey),
383 &host_key_len)) {
384 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
385 "Could not copy host key");
386 goto clean_exit;
387 }
388
389 session->server_hostkey_len = (uint32_t)host_key_len;
390
391 #if LIBSSH2_MD5
392 {
393 libssh2_md5_ctx fingerprint_ctx;
394
395 if(libssh2_md5_init(&fingerprint_ctx)) {
396 libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
397 session->server_hostkey_len);
398 libssh2_md5_final(fingerprint_ctx,
399 session->server_hostkey_md5);
400 session->server_hostkey_md5_valid = TRUE;
401 }
402 else {
403 session->server_hostkey_md5_valid = FALSE;
404 }
405 }
406 #ifdef LIBSSH2DEBUG
407 {
408 char fingerprint[50], *fprint = fingerprint;
409 int i;
410 for(i = 0; i < 16; i++, fprint += 3) {
411 snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
412 }
413 *(--fprint) = '\0';
414 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
415 "Server's MD5 Fingerprint: %s", fingerprint);
416 }
417 #endif /* LIBSSH2DEBUG */
418 #endif /* ! LIBSSH2_MD5 */
419
420 {
421 libssh2_sha1_ctx fingerprint_ctx;
422
423 if(libssh2_sha1_init(&fingerprint_ctx)) {
424 libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
425 session->server_hostkey_len);
426 libssh2_sha1_final(fingerprint_ctx,
427 session->server_hostkey_sha1);
428 session->server_hostkey_sha1_valid = TRUE;
429 }
430 else {
431 session->server_hostkey_sha1_valid = FALSE;
432 }
433 }
434 #ifdef LIBSSH2DEBUG
435 {
436 char fingerprint[64], *fprint = fingerprint;
437 int i;
438
439 for(i = 0; i < 20; i++, fprint += 3) {
440 snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
441 }
442 *(--fprint) = '\0';
443 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
444 "Server's SHA1 Fingerprint: %s", fingerprint);
445 }
446 #endif /* LIBSSH2DEBUG */
447
448 {
449 libssh2_sha256_ctx fingerprint_ctx;
450
451 if(libssh2_sha256_init(&fingerprint_ctx)) {
452 libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
453 session->server_hostkey_len);
454 libssh2_sha256_final(fingerprint_ctx,
455 session->server_hostkey_sha256);
456 session->server_hostkey_sha256_valid = TRUE;
457 }
458 else {
459 session->server_hostkey_sha256_valid = FALSE;
460 }
461 }
462 #ifdef LIBSSH2DEBUG
463 {
464 char *base64Fingerprint = NULL;
465 _libssh2_base64_encode(session,
466 (const char *)
467 session->server_hostkey_sha256,
468 SHA256_DIGEST_LENGTH, &base64Fingerprint);
469 if(base64Fingerprint != NULL) {
470 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
471 "Server's SHA256 Fingerprint: %s",
472 base64Fingerprint);
473 LIBSSH2_FREE(session, base64Fingerprint);
474 }
475 }
476 #endif /* LIBSSH2DEBUG */
477
478
479 if(session->hostkey->init(session, session->server_hostkey,
480 session->server_hostkey_len,
481 &session->server_hostkey_abstract)) {
482 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
483 "Unable to initialize hostkey importer");
484 goto clean_exit;
485 }
486
487 if(_libssh2_get_string(&buf, &(exchange_state->f_value),
488 &(exchange_state->f_value_len))) {
489 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
490 "Unable to get f value");
491 goto clean_exit;
492 }
493
494 _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len,
495 exchange_state->f_value);
496
497 if(_libssh2_get_string(&buf, &(exchange_state->h_sig),
498 &(exchange_state->h_sig_len))) {
499 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
500 "Unable to get h sig");
501 goto clean_exit;
502 }
503
504 /* Compute the shared secret */
505 libssh2_dh_secret(&exchange_state->x, exchange_state->k,
506 exchange_state->f, p, exchange_state->ctx);
507 exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5;
508 if(_libssh2_bn_bits(exchange_state->k) % 8) {
509 /* don't need leading 00 */
510 exchange_state->k_value_len--;
511 }
512 exchange_state->k_value =
513 LIBSSH2_ALLOC(session, exchange_state->k_value_len);
514 if(!exchange_state->k_value) {
515 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
516 "Unable to allocate buffer for K");
517 goto clean_exit;
518 }
519 _libssh2_htonu32(exchange_state->k_value,
520 exchange_state->k_value_len - 4);
521 if(_libssh2_bn_bits(exchange_state->k) % 8) {
522 _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4);
523 }
524 else {
525 exchange_state->k_value[4] = 0;
526 _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5);
527 }
528
529 exchange_state->exchange_hash = (void *)&exchange_hash_ctx;
530 _libssh2_sha_algo_ctx_init(sha_algo_value, exchange_hash_ctx);
531
532 if(session->local.banner) {
533 _libssh2_htonu32(exchange_state->h_sig_comp,
534 strlen((char *) session->local.banner) - 2);
535 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
536 exchange_state->h_sig_comp, 4);
537 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
538 session->local.banner,
539 strlen((char *) session->local.banner) - 2);
540 }
541 else {
542 _libssh2_htonu32(exchange_state->h_sig_comp,
543 sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
544 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
545 exchange_state->h_sig_comp, 4);
546 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
547 (unsigned char *)
548 LIBSSH2_SSH_DEFAULT_BANNER,
549 sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
550 }
551
552 _libssh2_htonu32(exchange_state->h_sig_comp,
553 strlen((char *) session->remote.banner));
554 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
555 exchange_state->h_sig_comp, 4);
556 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
557 session->remote.banner,
558 strlen((char *) session->remote.banner));
559
560 _libssh2_htonu32(exchange_state->h_sig_comp,
561 session->local.kexinit_len);
562 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
563 exchange_state->h_sig_comp, 4);
564 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
565 session->local.kexinit,
566 session->local.kexinit_len);
567
568 _libssh2_htonu32(exchange_state->h_sig_comp,
569 session->remote.kexinit_len);
570 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
571 exchange_state->h_sig_comp, 4);
572 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
573 session->remote.kexinit,
574 session->remote.kexinit_len);
575
576 _libssh2_htonu32(exchange_state->h_sig_comp,
577 session->server_hostkey_len);
578 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
579 exchange_state->h_sig_comp, 4);
580 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
581 session->server_hostkey,
582 session->server_hostkey_len);
583
584 if(packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) {
585 /* diffie-hellman-group-exchange hashes additional fields */
586 #ifdef LIBSSH2_DH_GEX_NEW
587 _libssh2_htonu32(exchange_state->h_sig_comp,
588 LIBSSH2_DH_GEX_MINGROUP);
589 _libssh2_htonu32(exchange_state->h_sig_comp + 4,
590 LIBSSH2_DH_GEX_OPTGROUP);
591 _libssh2_htonu32(exchange_state->h_sig_comp + 8,
592 LIBSSH2_DH_GEX_MAXGROUP);
593 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
594 exchange_state->h_sig_comp, 12);
595 #else
596 _libssh2_htonu32(exchange_state->h_sig_comp,
597 LIBSSH2_DH_GEX_OPTGROUP);
598 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
599 exchange_state->h_sig_comp, 4);
600 #endif
601 }
602
603 if(midhash) {
604 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
605 midhash, midhash_len);
606 }
607
608 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
609 exchange_state->e_packet + 1,
610 exchange_state->e_packet_len - 1);
611
612 _libssh2_htonu32(exchange_state->h_sig_comp,
613 exchange_state->f_value_len);
614 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
615 exchange_state->h_sig_comp, 4);
616 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
617 exchange_state->f_value,
618 exchange_state->f_value_len);
619
620 _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
621 exchange_state->k_value,
622 exchange_state->k_value_len);
623
624 _libssh2_sha_algo_ctx_final(sha_algo_value, exchange_hash_ctx,
625 exchange_state->h_sig_comp);
626
627 if(session->hostkey->
628 sig_verify(session, exchange_state->h_sig,
629 exchange_state->h_sig_len, exchange_state->h_sig_comp,
630 digest_len, &session->server_hostkey_abstract)) {
631 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
632 "Unable to verify hostkey signature");
633 goto clean_exit;
634 }
635
636 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message");
637 exchange_state->c = SSH_MSG_NEWKEYS;
638
639 exchange_state->state = libssh2_NB_state_sent2;
640 }
641
642 if(exchange_state->state == libssh2_NB_state_sent2) {
643 rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0);
644 if(rc == LIBSSH2_ERROR_EAGAIN) {
645 return rc;
646 }
647 else if(rc) {
648 ret = _libssh2_error(session, rc,
649 "Unable to send NEWKEYS message");
650 goto clean_exit;
651 }
652
653 exchange_state->state = libssh2_NB_state_sent3;
654 }
655
656 if(exchange_state->state == libssh2_NB_state_sent3) {
657 rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS,
658 &exchange_state->tmp,
659 &exchange_state->tmp_len, 0, NULL, 0,
660 &exchange_state->req_state);
661 if(rc == LIBSSH2_ERROR_EAGAIN) {
662 return rc;
663 }
664 else if(rc) {
665 ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
666 goto clean_exit;
667 }
668 /* The first key exchange has been performed,
669 switch to active crypt/comp/mac mode */
670 session->state |= LIBSSH2_STATE_NEWKEYS;
671 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message");
672
673 /* This will actually end up being just packet_type(1)
674 for this packet type anyway */
675 LIBSSH2_FREE(session, exchange_state->tmp);
676
677 if(!session->session_id) {
678 session->session_id = LIBSSH2_ALLOC(session, digest_len);
679 if(!session->session_id) {
680 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
681 "Unable to allocate buffer for "
682 "SHA digest");
683 goto clean_exit;
684 }
685 memcpy(session->session_id, exchange_state->h_sig_comp,
686 digest_len);
687 session->session_id_len = digest_len;
688 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
689 "session_id calculated");
690 }
691
692 /* Cleanup any existing cipher */
693 if(session->local.crypt->dtor) {
694 session->local.crypt->dtor(session,
695 &session->local.crypt_abstract);
696 }
697
698 /* Calculate IV/Secret/Key for each direction */
699 if(session->local.crypt->init) {
700 unsigned char *iv = NULL, *secret = NULL;
701 int free_iv = 0, free_secret = 0;
702
703 _libssh2_sha_algo_value_hash(sha_algo_value, session,
704 exchange_state, &iv,
705 session->local.crypt->iv_len,
706 (const unsigned char *)"A");
707
708 if(!iv) {
709 ret = -1;
710 goto clean_exit;
711 }
712 _libssh2_sha_algo_value_hash(sha_algo_value, session,
713 exchange_state, &secret,
714 session->local.crypt->secret_len,
715 (const unsigned char *)"C");
716
717 if(!secret) {
718 LIBSSH2_FREE(session, iv);
719 ret = LIBSSH2_ERROR_KEX_FAILURE;
720 goto clean_exit;
721 }
722 if(session->local.crypt->
723 init(session, session->local.crypt, iv, &free_iv, secret,
724 &free_secret, 1, &session->local.crypt_abstract)) {
725 LIBSSH2_FREE(session, iv);
726 LIBSSH2_FREE(session, secret);
727 ret = LIBSSH2_ERROR_KEX_FAILURE;
728 goto clean_exit;
729 }
730
731 if(free_iv) {
732 _libssh2_explicit_zero(iv, session->local.crypt->iv_len);
733 LIBSSH2_FREE(session, iv);
734 }
735
736 if(free_secret) {
737 _libssh2_explicit_zero(secret,
738 session->local.crypt->secret_len);
739 LIBSSH2_FREE(session, secret);
740 }
741 }
742 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
743 "Client to Server IV and Key calculated");
744
745 if(session->remote.crypt->dtor) {
746 /* Cleanup any existing cipher */
747 session->remote.crypt->dtor(session,
748 &session->remote.crypt_abstract);
749 }
750
751 if(session->remote.crypt->init) {
752 unsigned char *iv = NULL, *secret = NULL;
753 int free_iv = 0, free_secret = 0;
754
755 _libssh2_sha_algo_value_hash(sha_algo_value, session,
756 exchange_state, &iv,
757 session->remote.crypt->iv_len,
758 (const unsigned char *)"B");
759 if(!iv) {
760 ret = LIBSSH2_ERROR_KEX_FAILURE;
761 goto clean_exit;
762 }
763 _libssh2_sha_algo_value_hash(sha_algo_value, session,
764 exchange_state, &secret,
765 session->remote.crypt->secret_len,
766 (const unsigned char *)"D");
767 if(!secret) {
768 LIBSSH2_FREE(session, iv);
769 ret = LIBSSH2_ERROR_KEX_FAILURE;
770 goto clean_exit;
771 }
772 if(session->remote.crypt->
773 init(session, session->remote.crypt, iv, &free_iv, secret,
774 &free_secret, 0, &session->remote.crypt_abstract)) {
775 LIBSSH2_FREE(session, iv);
776 LIBSSH2_FREE(session, secret);
777 ret = LIBSSH2_ERROR_KEX_FAILURE;
778 goto clean_exit;
779 }
780
781 if(free_iv) {
782 _libssh2_explicit_zero(iv, session->remote.crypt->iv_len);
783 LIBSSH2_FREE(session, iv);
784 }
785
786 if(free_secret) {
787 _libssh2_explicit_zero(secret,
788 session->remote.crypt->secret_len);
789 LIBSSH2_FREE(session, secret);
790 }
791 }
792 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
793 "Server to Client IV and Key calculated");
794
795 if(session->local.mac->dtor) {
796 session->local.mac->dtor(session, &session->local.mac_abstract);
797 }
798
799 if(session->local.mac->init) {
800 unsigned char *key = NULL;
801 int free_key = 0;
802
803 _libssh2_sha_algo_value_hash(sha_algo_value, session,
804 exchange_state, &key,
805 session->local.mac->key_len,
806 (const unsigned char *)"E");
807 if(!key) {
808 ret = LIBSSH2_ERROR_KEX_FAILURE;
809 goto clean_exit;
810 }
811 session->local.mac->init(session, key, &free_key,
812 &session->local.mac_abstract);
813
814 if(free_key) {
815 _libssh2_explicit_zero(key, session->local.mac->key_len);
816 LIBSSH2_FREE(session, key);
817 }
818 }
819 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
820 "Client to Server HMAC Key calculated");
821
822 if(session->remote.mac->dtor) {
823 session->remote.mac->dtor(session, &session->remote.mac_abstract);
824 }
825
826 if(session->remote.mac->init) {
827 unsigned char *key = NULL;
828 int free_key = 0;
829
830 _libssh2_sha_algo_value_hash(sha_algo_value, session,
831 exchange_state, &key,
832 session->remote.mac->key_len,
833 (const unsigned char *)"F");
834 if(!key) {
835 ret = LIBSSH2_ERROR_KEX_FAILURE;
836 goto clean_exit;
837 }
838 session->remote.mac->init(session, key, &free_key,
839 &session->remote.mac_abstract);
840
841 if(free_key) {
842 _libssh2_explicit_zero(key, session->remote.mac->key_len);
843 LIBSSH2_FREE(session, key);
844 }
845 }
846 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
847 "Server to Client HMAC Key calculated");
848
849 /* Initialize compression for each direction */
850
851 /* Cleanup any existing compression */
852 if(session->local.comp && session->local.comp->dtor) {
853 session->local.comp->dtor(session, 1,
854 &session->local.comp_abstract);
855 }
856
857 if(session->local.comp && session->local.comp->init) {
858 if(session->local.comp->init(session, 1,
859 &session->local.comp_abstract)) {
860 ret = LIBSSH2_ERROR_KEX_FAILURE;
861 goto clean_exit;
862 }
863 }
864 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
865 "Client to Server compression initialized");
866
867 if(session->remote.comp && session->remote.comp->dtor) {
868 session->remote.comp->dtor(session, 0,
869 &session->remote.comp_abstract);
870 }
871
872 if(session->remote.comp && session->remote.comp->init) {
873 if(session->remote.comp->init(session, 0,
874 &session->remote.comp_abstract)) {
875 ret = LIBSSH2_ERROR_KEX_FAILURE;
876 goto clean_exit;
877 }
878 }
879 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
880 "Server to Client compression initialized");
881
882 }
883
884 clean_exit:
885 libssh2_dh_dtor(&exchange_state->x);
886 _libssh2_bn_free(exchange_state->e);
887 exchange_state->e = NULL;
888 _libssh2_bn_free(exchange_state->f);
889 exchange_state->f = NULL;
890 _libssh2_bn_free(exchange_state->k);
891 exchange_state->k = NULL;
892 _libssh2_bn_ctx_free(exchange_state->ctx);
893 exchange_state->ctx = NULL;
894
895 if(exchange_state->e_packet) {
896 LIBSSH2_FREE(session, exchange_state->e_packet);
897 exchange_state->e_packet = NULL;
898 }
899
900 if(exchange_state->s_packet) {
901 LIBSSH2_FREE(session, exchange_state->s_packet);
902 exchange_state->s_packet = NULL;
903 }
904
905 if(exchange_state->k_value) {
906 LIBSSH2_FREE(session, exchange_state->k_value);
907 exchange_state->k_value = NULL;
908 }
909
910 exchange_state->state = libssh2_NB_state_idle;
911
912 return ret;
913 }
914
915
916
917 /* kex_method_diffie_hellman_group1_sha1_key_exchange
918 * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1
919 */
920 static int
kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)921 kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
922 key_exchange_state_low_t
923 * key_state)
924 {
925 static const unsigned char p_value[128] = {
926 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
927 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
928 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
929 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
930 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
931 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
932 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
933 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
934 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
935 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
936 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
937 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
938 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
939 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
940 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
941 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
942 };
943
944 int ret;
945 libssh2_sha1_ctx exchange_hash_ctx;
946
947 if(key_state->state == libssh2_NB_state_idle) {
948 /* g == 2 */
949 key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value
950 (p_value) */
951 key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
952
953 /* Initialize P and G */
954 _libssh2_bn_set_word(key_state->g, 2);
955 _libssh2_bn_from_bin(key_state->p, 128, p_value);
956
957 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
958 "Initiating Diffie-Hellman Group1 Key Exchange");
959
960 key_state->state = libssh2_NB_state_created;
961 }
962
963 ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, 128, 1,
964 (void *)&exchange_hash_ctx,
965 SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
966 NULL, 0, &key_state->exchange_state);
967 if(ret == LIBSSH2_ERROR_EAGAIN) {
968 return ret;
969 }
970
971 _libssh2_bn_free(key_state->p);
972 key_state->p = NULL;
973 _libssh2_bn_free(key_state->g);
974 key_state->g = NULL;
975 key_state->state = libssh2_NB_state_idle;
976
977 return ret;
978 }
979
980
981 /* kex_method_diffie_hellman_group14_key_exchange
982 * Diffie-Hellman Group14 Key Exchange with hash function callback
983 */
984 typedef int (*diffie_hellman_hash_func_t)(LIBSSH2_SESSION *,
985 _libssh2_bn *,
986 _libssh2_bn *,
987 int,
988 int,
989 void *,
990 unsigned char,
991 unsigned char,
992 unsigned char *,
993 unsigned long,
994 kmdhgGPshakex_state_t *);
995 static int
kex_method_diffie_hellman_group14_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state,int sha_algo_value,void * exchange_hash_ctx,diffie_hellman_hash_func_t hashfunc)996 kex_method_diffie_hellman_group14_key_exchange(LIBSSH2_SESSION *session,
997 key_exchange_state_low_t
998 * key_state,
999 int sha_algo_value,
1000 void *exchange_hash_ctx,
1001 diffie_hellman_hash_func_t
1002 hashfunc)
1003 {
1004 static const unsigned char p_value[256] = {
1005 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1006 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
1007 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
1008 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
1009 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
1010 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
1011 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
1012 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
1013 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
1014 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
1015 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
1016 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
1017 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
1018 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
1019 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
1020 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
1021 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
1022 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
1023 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
1024 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
1025 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
1026 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
1027 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
1028 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
1029 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
1030 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
1031 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
1032 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
1033 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
1034 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
1035 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
1036 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1037 };
1038 int ret;
1039
1040 if(key_state->state == libssh2_NB_state_idle) {
1041 key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value
1042 (p_value) */
1043 key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
1044
1045 /* g == 2 */
1046 /* Initialize P and G */
1047 _libssh2_bn_set_word(key_state->g, 2);
1048 _libssh2_bn_from_bin(key_state->p, 256, p_value);
1049
1050 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1051 "Initiating Diffie-Hellman Group14 Key Exchange");
1052
1053 key_state->state = libssh2_NB_state_created;
1054 }
1055 ret = hashfunc(session, key_state->g, key_state->p,
1056 256, sha_algo_value, exchange_hash_ctx, SSH_MSG_KEXDH_INIT,
1057 SSH_MSG_KEXDH_REPLY, NULL, 0, &key_state->exchange_state);
1058 if(ret == LIBSSH2_ERROR_EAGAIN) {
1059 return ret;
1060 }
1061
1062 key_state->state = libssh2_NB_state_idle;
1063 _libssh2_bn_free(key_state->p);
1064 key_state->p = NULL;
1065 _libssh2_bn_free(key_state->g);
1066 key_state->g = NULL;
1067
1068 return ret;
1069 }
1070
1071
1072
1073 /* kex_method_diffie_hellman_group14_sha1_key_exchange
1074 * Diffie-Hellman Group14 Key Exchange using SHA1
1075 */
1076 static int
kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)1077 kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
1078 key_exchange_state_low_t
1079 * key_state)
1080 {
1081 libssh2_sha1_ctx ctx;
1082 return kex_method_diffie_hellman_group14_key_exchange(session,
1083 key_state, 1,
1084 &ctx,
1085 diffie_hellman_sha_algo);
1086 }
1087
1088
1089
1090 /* kex_method_diffie_hellman_group14_sha256_key_exchange
1091 * Diffie-Hellman Group14 Key Exchange using SHA256
1092 */
1093 static int
kex_method_diffie_hellman_group14_sha256_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)1094 kex_method_diffie_hellman_group14_sha256_key_exchange(LIBSSH2_SESSION *session,
1095 key_exchange_state_low_t
1096 * key_state)
1097 {
1098 libssh2_sha256_ctx ctx;
1099 return kex_method_diffie_hellman_group14_key_exchange(session,
1100 key_state, 256,
1101 &ctx,
1102 diffie_hellman_sha_algo);
1103 }
1104
1105 /* kex_method_diffie_hellman_group16_sha512_key_exchange
1106 * Diffie-Hellman Group16 Key Exchange using SHA512
1107 */
1108 static int
kex_method_diffie_hellman_group16_sha512_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)1109 kex_method_diffie_hellman_group16_sha512_key_exchange(LIBSSH2_SESSION *session,
1110 key_exchange_state_low_t
1111 * key_state)
1112
1113 {
1114 static const unsigned char p_value[512] = {
1115 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
1116 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
1117 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
1118 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
1119 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
1120 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
1121 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
1122 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
1123 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
1124 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
1125 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
1126 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
1127 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
1128 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
1129 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
1130 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
1131 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
1132 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
1133 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
1134 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
1135 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
1136 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
1137 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
1138 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
1139 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
1140 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
1141 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
1142 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
1143 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
1144 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
1145 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
1146 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
1147 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
1148 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
1149 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
1150 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
1151 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
1152 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
1153 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
1154 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
1155 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
1156 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
1157 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1158 };
1159 int ret;
1160 libssh2_sha512_ctx exchange_hash_ctx;
1161
1162 if(key_state->state == libssh2_NB_state_idle) {
1163 key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value
1164 (p_value) */
1165 key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
1166
1167 /* g == 2 */
1168 /* Initialize P and G */
1169 _libssh2_bn_set_word(key_state->g, 2);
1170 _libssh2_bn_from_bin(key_state->p, 512, p_value);
1171
1172 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1173 "Initiating Diffie-Hellman Group16 Key Exchange");
1174
1175 key_state->state = libssh2_NB_state_created;
1176 }
1177
1178 ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, 512,
1179 512, (void *)&exchange_hash_ctx,
1180 SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
1181 NULL, 0, &key_state->exchange_state);
1182 if(ret == LIBSSH2_ERROR_EAGAIN) {
1183 return ret;
1184 }
1185
1186 key_state->state = libssh2_NB_state_idle;
1187 _libssh2_bn_free(key_state->p);
1188 key_state->p = NULL;
1189 _libssh2_bn_free(key_state->g);
1190 key_state->g = NULL;
1191
1192 return ret;
1193 }
1194
1195 /* kex_method_diffie_hellman_group16_sha512_key_exchange
1196 * Diffie-Hellman Group18 Key Exchange using SHA512
1197 */
1198 static int
kex_method_diffie_hellman_group18_sha512_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)1199 kex_method_diffie_hellman_group18_sha512_key_exchange(LIBSSH2_SESSION *session,
1200 key_exchange_state_low_t
1201 * key_state)
1202
1203 {
1204 static const unsigned char p_value[1024] = {
1205 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
1206 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
1207 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
1208 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
1209 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
1210 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
1211 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
1212 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
1213 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
1214 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
1215 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
1216 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
1217 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
1218 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
1219 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
1220 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
1221 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
1222 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
1223 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
1224 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
1225 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
1226 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
1227 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
1228 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
1229 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
1230 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
1231 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
1232 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
1233 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
1234 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
1235 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
1236 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
1237 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
1238 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
1239 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
1240 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
1241 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
1242 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
1243 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
1244 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
1245 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
1246 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
1247 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
1248 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
1249 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
1250 0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
1251 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
1252 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
1253 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
1254 0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
1255 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
1256 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
1257 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
1258 0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
1259 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
1260 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
1261 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
1262 0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
1263 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
1264 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
1265 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
1266 0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
1267 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
1268 0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
1269 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0,
1270 0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
1271 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93,
1272 0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
1273 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB,
1274 0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
1275 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8,
1276 0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
1277 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F,
1278 0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
1279 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8,
1280 0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
1281 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5,
1282 0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
1283 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3,
1284 0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
1285 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E,
1286 0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
1287 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2,
1288 0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
1289 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
1290 0xFF, 0xFF, 0xFF, 0xFF
1291 };
1292 int ret;
1293 libssh2_sha512_ctx exchange_hash_ctx;
1294
1295 if(key_state->state == libssh2_NB_state_idle) {
1296 key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value
1297 (p_value) */
1298 key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
1299
1300 /* g == 2 */
1301 /* Initialize P and G */
1302 _libssh2_bn_set_word(key_state->g, 2);
1303 _libssh2_bn_from_bin(key_state->p, 1024, p_value);
1304
1305 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1306 "Initiating Diffie-Hellman Group18 Key Exchange");
1307
1308 key_state->state = libssh2_NB_state_created;
1309 }
1310
1311 ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p, 1024,
1312 512, (void *)&exchange_hash_ctx,
1313 SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
1314 NULL, 0, &key_state->exchange_state);
1315 if(ret == LIBSSH2_ERROR_EAGAIN) {
1316 return ret;
1317 }
1318
1319 key_state->state = libssh2_NB_state_idle;
1320 _libssh2_bn_free(key_state->p);
1321 key_state->p = NULL;
1322 _libssh2_bn_free(key_state->g);
1323 key_state->g = NULL;
1324
1325 return ret;
1326 }
1327
1328 /* kex_method_diffie_hellman_group_exchange_sha1_key_exchange
1329 * Diffie-Hellman Group Exchange Key Exchange using SHA1
1330 * Negotiates random(ish) group for secret derivation
1331 */
1332 static int
kex_method_diffie_hellman_group_exchange_sha1_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)1333 kex_method_diffie_hellman_group_exchange_sha1_key_exchange
1334 (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
1335 {
1336 int ret = 0;
1337 int rc;
1338
1339 if(key_state->state == libssh2_NB_state_idle) {
1340 key_state->p = _libssh2_bn_init_from_bin();
1341 key_state->g = _libssh2_bn_init_from_bin();
1342 /* Ask for a P and G pair */
1343 #ifdef LIBSSH2_DH_GEX_NEW
1344 key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
1345 _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP);
1346 _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP);
1347 _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP);
1348 key_state->request_len = 13;
1349 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1350 "Initiating Diffie-Hellman Group-Exchange "
1351 "(New Method)");
1352 #else
1353 key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
1354 _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP);
1355 key_state->request_len = 5;
1356 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1357 "Initiating Diffie-Hellman Group-Exchange "
1358 "(Old Method)");
1359 #endif
1360
1361 key_state->state = libssh2_NB_state_created;
1362 }
1363
1364 if(key_state->state == libssh2_NB_state_created) {
1365 rc = _libssh2_transport_send(session, key_state->request,
1366 key_state->request_len, NULL, 0);
1367 if(rc == LIBSSH2_ERROR_EAGAIN) {
1368 return rc;
1369 }
1370 else if(rc) {
1371 ret = _libssh2_error(session, rc,
1372 "Unable to send Group Exchange Request");
1373 goto dh_gex_clean_exit;
1374 }
1375
1376 key_state->state = libssh2_NB_state_sent;
1377 }
1378
1379 if(key_state->state == libssh2_NB_state_sent) {
1380 rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP,
1381 &key_state->data, &key_state->data_len,
1382 0, NULL, 0, &key_state->req_state);
1383 if(rc == LIBSSH2_ERROR_EAGAIN) {
1384 return rc;
1385 }
1386 else if(rc) {
1387 ret = _libssh2_error(session, rc,
1388 "Timeout waiting for GEX_GROUP reply");
1389 goto dh_gex_clean_exit;
1390 }
1391
1392 key_state->state = libssh2_NB_state_sent1;
1393 }
1394
1395 if(key_state->state == libssh2_NB_state_sent1) {
1396 size_t p_len, g_len;
1397 unsigned char *p, *g;
1398 struct string_buf buf;
1399 libssh2_sha1_ctx exchange_hash_ctx;
1400
1401 if(key_state->data_len < 9) {
1402 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1403 "Unexpected key length");
1404 goto dh_gex_clean_exit;
1405 }
1406
1407 buf.data = key_state->data;
1408 buf.dataptr = buf.data;
1409 buf.len = key_state->data_len;
1410
1411 buf.dataptr++; /* increment to big num */
1412
1413 if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) {
1414 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1415 "Unexpected value");
1416 goto dh_gex_clean_exit;
1417 }
1418
1419 if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) {
1420 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1421 "Unexpected value");
1422 goto dh_gex_clean_exit;
1423 }
1424
1425 _libssh2_bn_from_bin(key_state->p, p_len, p);
1426 _libssh2_bn_from_bin(key_state->g, g_len, g);
1427
1428 ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p,
1429 p_len, 1,
1430 (void *)&exchange_hash_ctx,
1431 SSH_MSG_KEX_DH_GEX_INIT,
1432 SSH_MSG_KEX_DH_GEX_REPLY,
1433 key_state->data + 1,
1434 key_state->data_len - 1,
1435 &key_state->exchange_state);
1436 if(ret == LIBSSH2_ERROR_EAGAIN) {
1437 return ret;
1438 }
1439
1440 LIBSSH2_FREE(session, key_state->data);
1441 }
1442
1443 dh_gex_clean_exit:
1444 key_state->state = libssh2_NB_state_idle;
1445 _libssh2_bn_free(key_state->g);
1446 key_state->g = NULL;
1447 _libssh2_bn_free(key_state->p);
1448 key_state->p = NULL;
1449
1450 return ret;
1451 }
1452
1453
1454
1455 /* kex_method_diffie_hellman_group_exchange_sha256_key_exchange
1456 * Diffie-Hellman Group Exchange Key Exchange using SHA256
1457 * Negotiates random(ish) group for secret derivation
1458 */
1459 static int
kex_method_diffie_hellman_group_exchange_sha256_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)1460 kex_method_diffie_hellman_group_exchange_sha256_key_exchange
1461 (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
1462 {
1463 int ret = 0;
1464 int rc;
1465
1466 if(key_state->state == libssh2_NB_state_idle) {
1467 key_state->p = _libssh2_bn_init();
1468 key_state->g = _libssh2_bn_init();
1469 /* Ask for a P and G pair */
1470 #ifdef LIBSSH2_DH_GEX_NEW
1471 key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
1472 _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP);
1473 _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP);
1474 _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP);
1475 key_state->request_len = 13;
1476 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1477 "Initiating Diffie-Hellman Group-Exchange "
1478 "(New Method SHA256)");
1479 #else
1480 key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
1481 _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP);
1482 key_state->request_len = 5;
1483 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1484 "Initiating Diffie-Hellman Group-Exchange "
1485 "(Old Method SHA256)");
1486 #endif
1487
1488 key_state->state = libssh2_NB_state_created;
1489 }
1490
1491 if(key_state->state == libssh2_NB_state_created) {
1492 rc = _libssh2_transport_send(session, key_state->request,
1493 key_state->request_len, NULL, 0);
1494 if(rc == LIBSSH2_ERROR_EAGAIN) {
1495 return rc;
1496 }
1497 else if(rc) {
1498 ret = _libssh2_error(session, rc,
1499 "Unable to send "
1500 "Group Exchange Request SHA256");
1501 goto dh_gex_clean_exit;
1502 }
1503
1504 key_state->state = libssh2_NB_state_sent;
1505 }
1506
1507 if(key_state->state == libssh2_NB_state_sent) {
1508 rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP,
1509 &key_state->data, &key_state->data_len,
1510 0, NULL, 0, &key_state->req_state);
1511 if(rc == LIBSSH2_ERROR_EAGAIN) {
1512 return rc;
1513 }
1514 else if(rc) {
1515 ret = _libssh2_error(session, rc,
1516 "Timeout waiting for GEX_GROUP reply SHA256");
1517 goto dh_gex_clean_exit;
1518 }
1519
1520 key_state->state = libssh2_NB_state_sent1;
1521 }
1522
1523 if(key_state->state == libssh2_NB_state_sent1) {
1524 unsigned char *p, *g;
1525 size_t p_len, g_len;
1526 struct string_buf buf;
1527 libssh2_sha256_ctx exchange_hash_ctx;
1528
1529 if(key_state->data_len < 9) {
1530 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1531 "Unexpected key length");
1532 goto dh_gex_clean_exit;
1533 }
1534
1535 buf.data = key_state->data;
1536 buf.dataptr = buf.data;
1537 buf.len = key_state->data_len;
1538
1539 buf.dataptr++; /* increment to big num */
1540
1541 if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) {
1542 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1543 "Unexpected value");
1544 goto dh_gex_clean_exit;
1545 }
1546
1547 if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) {
1548 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1549 "Unexpected value");
1550 goto dh_gex_clean_exit;
1551 }
1552
1553 _libssh2_bn_from_bin(key_state->p, p_len, p);
1554 _libssh2_bn_from_bin(key_state->g, g_len, g);
1555
1556 ret = diffie_hellman_sha_algo(session, key_state->g, key_state->p,
1557 p_len, 256,
1558 (void *)&exchange_hash_ctx,
1559 SSH_MSG_KEX_DH_GEX_INIT,
1560 SSH_MSG_KEX_DH_GEX_REPLY,
1561 key_state->data + 1,
1562 key_state->data_len - 1,
1563 &key_state->exchange_state);
1564 if(ret == LIBSSH2_ERROR_EAGAIN) {
1565 return ret;
1566 }
1567
1568 LIBSSH2_FREE(session, key_state->data);
1569 }
1570
1571 dh_gex_clean_exit:
1572 key_state->state = libssh2_NB_state_idle;
1573 _libssh2_bn_free(key_state->g);
1574 key_state->g = NULL;
1575 _libssh2_bn_free(key_state->p);
1576 key_state->p = NULL;
1577
1578 return ret;
1579 }
1580
1581
1582 /* LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY
1583 *
1584 * Macro that create and verifies EC SHA hash with a given digest bytes
1585 *
1586 * Payload format:
1587 *
1588 * string V_C, client's identification string (CR and LF excluded)
1589 * string V_S, server's identification string (CR and LF excluded)
1590 * string I_C, payload of the client's SSH_MSG_KEXINIT
1591 * string I_S, payload of the server's SSH_MSG_KEXINIT
1592 * string K_S, server's public host key
1593 * string Q_C, client's ephemeral public key octet string
1594 * string Q_S, server's ephemeral public key octet string
1595 * mpint K, shared secret
1596 *
1597 */
1598
1599 #define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \
1600 { \
1601 libssh2_sha##digest_type##_ctx ctx; \
1602 exchange_state->exchange_hash = (void *)&ctx; \
1603 libssh2_sha##digest_type##_init(&ctx); \
1604 if(session->local.banner) { \
1605 _libssh2_htonu32(exchange_state->h_sig_comp, \
1606 strlen((char *) session->local.banner) - 2); \
1607 libssh2_sha##digest_type##_update(ctx, \
1608 exchange_state->h_sig_comp, 4); \
1609 libssh2_sha##digest_type##_update(ctx, \
1610 (char *) session->local.banner, \
1611 strlen((char *) \
1612 session->local.banner) \
1613 - 2); \
1614 } \
1615 else { \
1616 _libssh2_htonu32(exchange_state->h_sig_comp, \
1617 sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \
1618 libssh2_sha##digest_type##_update(ctx, \
1619 exchange_state->h_sig_comp, 4); \
1620 libssh2_sha##digest_type##_update(ctx, \
1621 LIBSSH2_SSH_DEFAULT_BANNER, \
1622 sizeof(LIBSSH2_SSH_DEFAULT_BANNER) \
1623 - 1); \
1624 } \
1625 \
1626 _libssh2_htonu32(exchange_state->h_sig_comp, \
1627 strlen((char *) session->remote.banner)); \
1628 libssh2_sha##digest_type##_update(ctx, \
1629 exchange_state->h_sig_comp, 4); \
1630 libssh2_sha##digest_type##_update(ctx, \
1631 session->remote.banner, \
1632 strlen((char *) \
1633 session->remote.banner)); \
1634 \
1635 _libssh2_htonu32(exchange_state->h_sig_comp, \
1636 session->local.kexinit_len); \
1637 libssh2_sha##digest_type##_update(ctx, \
1638 exchange_state->h_sig_comp, 4); \
1639 libssh2_sha##digest_type##_update(ctx, \
1640 session->local.kexinit, \
1641 session->local.kexinit_len); \
1642 \
1643 _libssh2_htonu32(exchange_state->h_sig_comp, \
1644 session->remote.kexinit_len); \
1645 libssh2_sha##digest_type##_update(ctx, \
1646 exchange_state->h_sig_comp, 4); \
1647 libssh2_sha##digest_type##_update(ctx, \
1648 session->remote.kexinit, \
1649 session->remote.kexinit_len); \
1650 \
1651 _libssh2_htonu32(exchange_state->h_sig_comp, \
1652 session->server_hostkey_len); \
1653 libssh2_sha##digest_type##_update(ctx, \
1654 exchange_state->h_sig_comp, 4); \
1655 libssh2_sha##digest_type##_update(ctx, \
1656 session->server_hostkey, \
1657 session->server_hostkey_len); \
1658 \
1659 _libssh2_htonu32(exchange_state->h_sig_comp, \
1660 public_key_len); \
1661 libssh2_sha##digest_type##_update(ctx, \
1662 exchange_state->h_sig_comp, 4); \
1663 libssh2_sha##digest_type##_update(ctx, \
1664 public_key, \
1665 public_key_len); \
1666 \
1667 _libssh2_htonu32(exchange_state->h_sig_comp, \
1668 server_public_key_len); \
1669 libssh2_sha##digest_type##_update(ctx, \
1670 exchange_state->h_sig_comp, 4); \
1671 libssh2_sha##digest_type##_update(ctx, \
1672 server_public_key, \
1673 server_public_key_len); \
1674 \
1675 libssh2_sha##digest_type##_update(ctx, \
1676 exchange_state->k_value, \
1677 exchange_state->k_value_len); \
1678 \
1679 libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \
1680 \
1681 if(session->hostkey-> \
1682 sig_verify(session, exchange_state->h_sig, \
1683 exchange_state->h_sig_len, exchange_state->h_sig_comp, \
1684 SHA##digest_type##_DIGEST_LENGTH, \
1685 &session->server_hostkey_abstract)) { \
1686 rc = -1; \
1687 } \
1688 } \
1689
1690
1691 #if LIBSSH2_ECDSA
1692
1693 /* kex_session_ecdh_curve_type
1694 * returns the EC curve type by name used in key exchange
1695 */
1696
1697 static int
kex_session_ecdh_curve_type(const char * name,libssh2_curve_type * out_type)1698 kex_session_ecdh_curve_type(const char *name, libssh2_curve_type *out_type)
1699 {
1700 int ret = 0;
1701 libssh2_curve_type type;
1702
1703 if(name == NULL)
1704 return -1;
1705
1706 if(strcmp(name, "ecdh-sha2-nistp256") == 0)
1707 type = LIBSSH2_EC_CURVE_NISTP256;
1708 else if(strcmp(name, "ecdh-sha2-nistp384") == 0)
1709 type = LIBSSH2_EC_CURVE_NISTP384;
1710 else if(strcmp(name, "ecdh-sha2-nistp521") == 0)
1711 type = LIBSSH2_EC_CURVE_NISTP521;
1712 else {
1713 ret = -1;
1714 }
1715
1716 if(ret == 0 && out_type) {
1717 *out_type = type;
1718 }
1719
1720 return ret;
1721 }
1722
1723
1724 /* ecdh_sha2_nistp
1725 * Elliptic Curve Diffie Hellman Key Exchange
1726 */
1727
ecdh_sha2_nistp(LIBSSH2_SESSION * session,libssh2_curve_type type,unsigned char * data,size_t data_len,unsigned char * public_key,size_t public_key_len,_libssh2_ec_key * private_key,kmdhgGPshakex_state_t * exchange_state)1728 static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type,
1729 unsigned char *data, size_t data_len,
1730 unsigned char *public_key,
1731 size_t public_key_len, _libssh2_ec_key *private_key,
1732 kmdhgGPshakex_state_t *exchange_state)
1733 {
1734 int ret = 0;
1735 int rc;
1736
1737 if(data_len < 5) {
1738 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
1739 "Host key data is too short");
1740 return ret;
1741 }
1742
1743 if(exchange_state->state == libssh2_NB_state_idle) {
1744
1745 /* Setup initial values */
1746 exchange_state->k = _libssh2_bn_init();
1747
1748 exchange_state->state = libssh2_NB_state_created;
1749 }
1750
1751 if(exchange_state->state == libssh2_NB_state_created) {
1752 /* parse INIT reply data */
1753
1754 /* host key K_S */
1755 unsigned char *server_public_key;
1756 size_t server_public_key_len;
1757 struct string_buf buf;
1758
1759 buf.data = data;
1760 buf.len = data_len;
1761 buf.dataptr = buf.data;
1762 buf.dataptr++; /* Advance past packet type */
1763
1764 if(_libssh2_copy_string(session, &buf, &(session->server_hostkey),
1765 &server_public_key_len)) {
1766 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1767 "Unable to allocate memory for a copy "
1768 "of the host key");
1769 goto clean_exit;
1770 }
1771
1772 session->server_hostkey_len = (uint32_t)server_public_key_len;
1773
1774 #if LIBSSH2_MD5
1775 {
1776 libssh2_md5_ctx fingerprint_ctx;
1777
1778 if(libssh2_md5_init(&fingerprint_ctx)) {
1779 libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
1780 session->server_hostkey_len);
1781 libssh2_md5_final(fingerprint_ctx,
1782 session->server_hostkey_md5);
1783 session->server_hostkey_md5_valid = TRUE;
1784 }
1785 else {
1786 session->server_hostkey_md5_valid = FALSE;
1787 }
1788 }
1789 #ifdef LIBSSH2DEBUG
1790 {
1791 char fingerprint[50], *fprint = fingerprint;
1792 int i;
1793 for(i = 0; i < 16; i++, fprint += 3) {
1794 snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
1795 }
1796 *(--fprint) = '\0';
1797 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1798 "Server's MD5 Fingerprint: %s", fingerprint);
1799 }
1800 #endif /* LIBSSH2DEBUG */
1801 #endif /* ! LIBSSH2_MD5 */
1802
1803 {
1804 libssh2_sha1_ctx fingerprint_ctx;
1805
1806 if(libssh2_sha1_init(&fingerprint_ctx)) {
1807 libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
1808 session->server_hostkey_len);
1809 libssh2_sha1_final(fingerprint_ctx,
1810 session->server_hostkey_sha1);
1811 session->server_hostkey_sha1_valid = TRUE;
1812 }
1813 else {
1814 session->server_hostkey_sha1_valid = FALSE;
1815 }
1816 }
1817 #ifdef LIBSSH2DEBUG
1818 {
1819 char fingerprint[64], *fprint = fingerprint;
1820 int i;
1821
1822 for(i = 0; i < 20; i++, fprint += 3) {
1823 snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
1824 }
1825 *(--fprint) = '\0';
1826 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1827 "Server's SHA1 Fingerprint: %s", fingerprint);
1828 }
1829 #endif /* LIBSSH2DEBUG */
1830
1831 /* SHA256 */
1832 {
1833 libssh2_sha256_ctx fingerprint_ctx;
1834
1835 if(libssh2_sha256_init(&fingerprint_ctx)) {
1836 libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
1837 session->server_hostkey_len);
1838 libssh2_sha256_final(fingerprint_ctx,
1839 session->server_hostkey_sha256);
1840 session->server_hostkey_sha256_valid = TRUE;
1841 }
1842 else {
1843 session->server_hostkey_sha256_valid = FALSE;
1844 }
1845 }
1846 #ifdef LIBSSH2DEBUG
1847 {
1848 char *base64Fingerprint = NULL;
1849 _libssh2_base64_encode(session,
1850 (const char *)
1851 session->server_hostkey_sha256,
1852 SHA256_DIGEST_LENGTH, &base64Fingerprint);
1853 if(base64Fingerprint != NULL) {
1854 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
1855 "Server's SHA256 Fingerprint: %s",
1856 base64Fingerprint);
1857 LIBSSH2_FREE(session, base64Fingerprint);
1858 }
1859 }
1860 #endif /* LIBSSH2DEBUG */
1861
1862 if(session->hostkey->init(session, session->server_hostkey,
1863 session->server_hostkey_len,
1864 &session->server_hostkey_abstract)) {
1865 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
1866 "Unable to initialize hostkey importer");
1867 goto clean_exit;
1868 }
1869
1870 /* server public key Q_S */
1871 if(_libssh2_get_string(&buf, &server_public_key,
1872 &server_public_key_len)) {
1873 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
1874 "Unexpected key length");
1875 goto clean_exit;
1876 }
1877
1878 /* server signature */
1879 if(_libssh2_get_string(&buf, &exchange_state->h_sig,
1880 &(exchange_state->h_sig_len))) {
1881 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
1882 "Unexpected ecdh server sig length");
1883 goto clean_exit;
1884 }
1885
1886 /* Compute the shared secret K */
1887 rc = _libssh2_ecdh_gen_k(&exchange_state->k, private_key,
1888 server_public_key, server_public_key_len);
1889 if(rc != 0) {
1890 ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
1891 "Unable to create ECDH shared secret");
1892 goto clean_exit;
1893 }
1894
1895 exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5;
1896 if(_libssh2_bn_bits(exchange_state->k) % 8) {
1897 /* don't need leading 00 */
1898 exchange_state->k_value_len--;
1899 }
1900 exchange_state->k_value =
1901 LIBSSH2_ALLOC(session, exchange_state->k_value_len);
1902 if(!exchange_state->k_value) {
1903 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1904 "Unable to allocate buffer for K");
1905 goto clean_exit;
1906 }
1907 _libssh2_htonu32(exchange_state->k_value,
1908 exchange_state->k_value_len - 4);
1909 if(_libssh2_bn_bits(exchange_state->k) % 8) {
1910 _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4);
1911 }
1912 else {
1913 exchange_state->k_value[4] = 0;
1914 _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5);
1915 }
1916
1917 /* verify hash */
1918
1919 switch(type) {
1920 case LIBSSH2_EC_CURVE_NISTP256:
1921 LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256);
1922 break;
1923
1924 case LIBSSH2_EC_CURVE_NISTP384:
1925 LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(384);
1926 break;
1927 case LIBSSH2_EC_CURVE_NISTP521:
1928 LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(512);
1929 break;
1930 }
1931
1932 if(rc != 0) {
1933 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
1934 "Unable to verify hostkey signature");
1935 goto clean_exit;
1936 }
1937
1938 exchange_state->c = SSH_MSG_NEWKEYS;
1939 exchange_state->state = libssh2_NB_state_sent;
1940 }
1941
1942 if(exchange_state->state == libssh2_NB_state_sent) {
1943 rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0);
1944 if(rc == LIBSSH2_ERROR_EAGAIN) {
1945 return rc;
1946 }
1947 else if(rc) {
1948 ret = _libssh2_error(session, rc,
1949 "Unable to send NEWKEYS message");
1950 goto clean_exit;
1951 }
1952
1953 exchange_state->state = libssh2_NB_state_sent2;
1954 }
1955
1956 if(exchange_state->state == libssh2_NB_state_sent2) {
1957 rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS,
1958 &exchange_state->tmp,
1959 &exchange_state->tmp_len, 0, NULL, 0,
1960 &exchange_state->req_state);
1961 if(rc == LIBSSH2_ERROR_EAGAIN) {
1962 return rc;
1963 }
1964 else if(rc) {
1965 ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
1966 goto clean_exit;
1967 }
1968
1969 /* The first key exchange has been performed,
1970 switch to active crypt/comp/mac mode */
1971 session->state |= LIBSSH2_STATE_NEWKEYS;
1972 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message");
1973
1974 /* This will actually end up being just packet_type(1)
1975 for this packet type anyway */
1976 LIBSSH2_FREE(session, exchange_state->tmp);
1977
1978 if(!session->session_id) {
1979
1980 size_t digest_length = 0;
1981
1982 if(type == LIBSSH2_EC_CURVE_NISTP256)
1983 digest_length = SHA256_DIGEST_LENGTH;
1984 else if(type == LIBSSH2_EC_CURVE_NISTP384)
1985 digest_length = SHA384_DIGEST_LENGTH;
1986 else if(type == LIBSSH2_EC_CURVE_NISTP521)
1987 digest_length = SHA512_DIGEST_LENGTH;
1988 else{
1989 ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
1990 "Unknown SHA digest for EC curve");
1991 goto clean_exit;
1992
1993 }
1994 session->session_id = LIBSSH2_ALLOC(session, digest_length);
1995 if(!session->session_id) {
1996 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1997 "Unable to allocate buffer for "
1998 "SHA digest");
1999 goto clean_exit;
2000 }
2001 memcpy(session->session_id, exchange_state->h_sig_comp,
2002 digest_length);
2003 session->session_id_len = digest_length;
2004 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2005 "session_id calculated");
2006 }
2007
2008 /* Cleanup any existing cipher */
2009 if(session->local.crypt->dtor) {
2010 session->local.crypt->dtor(session,
2011 &session->local.crypt_abstract);
2012 }
2013
2014 /* Calculate IV/Secret/Key for each direction */
2015 if(session->local.crypt->init) {
2016 unsigned char *iv = NULL, *secret = NULL;
2017 int free_iv = 0, free_secret = 0;
2018
2019 LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(iv,
2020 session->local.crypt->
2021 iv_len, "A");
2022 if(!iv) {
2023 ret = -1;
2024 goto clean_exit;
2025 }
2026
2027 LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(secret,
2028 session->local.crypt->
2029 secret_len, "C");
2030
2031 if(!secret) {
2032 LIBSSH2_FREE(session, iv);
2033 ret = LIBSSH2_ERROR_KEX_FAILURE;
2034 goto clean_exit;
2035 }
2036 if(session->local.crypt->
2037 init(session, session->local.crypt, iv, &free_iv, secret,
2038 &free_secret, 1, &session->local.crypt_abstract)) {
2039 LIBSSH2_FREE(session, iv);
2040 LIBSSH2_FREE(session, secret);
2041 ret = LIBSSH2_ERROR_KEX_FAILURE;
2042 goto clean_exit;
2043 }
2044
2045 if(free_iv) {
2046 _libssh2_explicit_zero(iv, session->local.crypt->iv_len);
2047 LIBSSH2_FREE(session, iv);
2048 }
2049
2050 if(free_secret) {
2051 _libssh2_explicit_zero(secret,
2052 session->local.crypt->secret_len);
2053 LIBSSH2_FREE(session, secret);
2054 }
2055 }
2056 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2057 "Client to Server IV and Key calculated");
2058
2059 if(session->remote.crypt->dtor) {
2060 /* Cleanup any existing cipher */
2061 session->remote.crypt->dtor(session,
2062 &session->remote.crypt_abstract);
2063 }
2064
2065 if(session->remote.crypt->init) {
2066 unsigned char *iv = NULL, *secret = NULL;
2067 int free_iv = 0, free_secret = 0;
2068
2069 LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(iv,
2070 session->remote.crypt->
2071 iv_len, "B");
2072
2073 if(!iv) {
2074 ret = LIBSSH2_ERROR_KEX_FAILURE;
2075 goto clean_exit;
2076 }
2077 LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(secret,
2078 session->remote.crypt->
2079 secret_len, "D");
2080
2081 if(!secret) {
2082 LIBSSH2_FREE(session, iv);
2083 ret = LIBSSH2_ERROR_KEX_FAILURE;
2084 goto clean_exit;
2085 }
2086 if(session->remote.crypt->
2087 init(session, session->remote.crypt, iv, &free_iv, secret,
2088 &free_secret, 0, &session->remote.crypt_abstract)) {
2089 LIBSSH2_FREE(session, iv);
2090 LIBSSH2_FREE(session, secret);
2091 ret = LIBSSH2_ERROR_KEX_FAILURE;
2092 goto clean_exit;
2093 }
2094
2095 if(free_iv) {
2096 _libssh2_explicit_zero(iv, session->remote.crypt->iv_len);
2097 LIBSSH2_FREE(session, iv);
2098 }
2099
2100 if(free_secret) {
2101 _libssh2_explicit_zero(secret,
2102 session->remote.crypt->secret_len);
2103 LIBSSH2_FREE(session, secret);
2104 }
2105 }
2106 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2107 "Server to Client IV and Key calculated");
2108
2109 if(session->local.mac->dtor) {
2110 session->local.mac->dtor(session, &session->local.mac_abstract);
2111 }
2112
2113 if(session->local.mac->init) {
2114 unsigned char *key = NULL;
2115 int free_key = 0;
2116
2117 LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(key,
2118 session->local.mac->
2119 key_len, "E");
2120
2121 if(!key) {
2122 ret = LIBSSH2_ERROR_KEX_FAILURE;
2123 goto clean_exit;
2124 }
2125 session->local.mac->init(session, key, &free_key,
2126 &session->local.mac_abstract);
2127
2128 if(free_key) {
2129 _libssh2_explicit_zero(key, session->local.mac->key_len);
2130 LIBSSH2_FREE(session, key);
2131 }
2132 }
2133 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2134 "Client to Server HMAC Key calculated");
2135
2136 if(session->remote.mac->dtor) {
2137 session->remote.mac->dtor(session, &session->remote.mac_abstract);
2138 }
2139
2140 if(session->remote.mac->init) {
2141 unsigned char *key = NULL;
2142 int free_key = 0;
2143
2144 LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(key,
2145 session->remote.mac->
2146 key_len, "F");
2147
2148 if(!key) {
2149 ret = LIBSSH2_ERROR_KEX_FAILURE;
2150 goto clean_exit;
2151 }
2152 session->remote.mac->init(session, key, &free_key,
2153 &session->remote.mac_abstract);
2154
2155 if(free_key) {
2156 _libssh2_explicit_zero(key, session->remote.mac->key_len);
2157 LIBSSH2_FREE(session, key);
2158 }
2159 }
2160 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2161 "Server to Client HMAC Key calculated");
2162
2163 /* Initialize compression for each direction */
2164
2165 /* Cleanup any existing compression */
2166 if(session->local.comp && session->local.comp->dtor) {
2167 session->local.comp->dtor(session, 1,
2168 &session->local.comp_abstract);
2169 }
2170
2171 if(session->local.comp && session->local.comp->init) {
2172 if(session->local.comp->init(session, 1,
2173 &session->local.comp_abstract)) {
2174 ret = LIBSSH2_ERROR_KEX_FAILURE;
2175 goto clean_exit;
2176 }
2177 }
2178 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2179 "Client to Server compression initialized");
2180
2181 if(session->remote.comp && session->remote.comp->dtor) {
2182 session->remote.comp->dtor(session, 0,
2183 &session->remote.comp_abstract);
2184 }
2185
2186 if(session->remote.comp && session->remote.comp->init) {
2187 if(session->remote.comp->init(session, 0,
2188 &session->remote.comp_abstract)) {
2189 ret = LIBSSH2_ERROR_KEX_FAILURE;
2190 goto clean_exit;
2191 }
2192 }
2193 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2194 "Server to Client compression initialized");
2195
2196 }
2197
2198 clean_exit:
2199 _libssh2_bn_free(exchange_state->k);
2200 exchange_state->k = NULL;
2201
2202 if(exchange_state->k_value) {
2203 LIBSSH2_FREE(session, exchange_state->k_value);
2204 exchange_state->k_value = NULL;
2205 }
2206
2207 exchange_state->state = libssh2_NB_state_idle;
2208
2209 return ret;
2210 }
2211
2212 /* kex_method_ecdh_key_exchange
2213 *
2214 * Elliptic Curve Diffie Hellman Key Exchange
2215 * supports SHA256/384/512 hashes based on negotated ecdh method
2216 *
2217 */
2218
2219 static int
kex_method_ecdh_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)2220 kex_method_ecdh_key_exchange
2221 (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
2222 {
2223 int ret = 0;
2224 int rc = 0;
2225 unsigned char *s;
2226 libssh2_curve_type type;
2227
2228 if(key_state->state == libssh2_NB_state_idle) {
2229
2230 key_state->public_key_oct = NULL;
2231 key_state->state = libssh2_NB_state_created;
2232 }
2233
2234 if(key_state->state == libssh2_NB_state_created) {
2235 rc = kex_session_ecdh_curve_type(session->kex->name, &type);
2236
2237 if(rc != 0) {
2238 ret = _libssh2_error(session, -1,
2239 "Unknown KEX nistp curve type");
2240 goto ecdh_clean_exit;
2241 }
2242
2243 rc = _libssh2_ecdsa_create_key(session, &key_state->private_key,
2244 &key_state->public_key_oct,
2245 &key_state->public_key_oct_len, type);
2246
2247 if(rc != 0) {
2248 ret = _libssh2_error(session, rc,
2249 "Unable to create private key");
2250 goto ecdh_clean_exit;
2251 }
2252
2253 key_state->request[0] = SSH2_MSG_KEX_ECDH_INIT;
2254 s = key_state->request + 1;
2255 _libssh2_store_str(&s, (const char *)key_state->public_key_oct,
2256 key_state->public_key_oct_len);
2257 key_state->request_len = key_state->public_key_oct_len + 5;
2258
2259 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2260 "Initiating ECDH SHA2 NISTP256");
2261
2262 key_state->state = libssh2_NB_state_sent;
2263 }
2264
2265 if(key_state->state == libssh2_NB_state_sent) {
2266 rc = _libssh2_transport_send(session, key_state->request,
2267 key_state->request_len, NULL, 0);
2268 if(rc == LIBSSH2_ERROR_EAGAIN) {
2269 return rc;
2270 }
2271 else if(rc) {
2272 ret = _libssh2_error(session, rc,
2273 "Unable to send ECDH_INIT");
2274 goto ecdh_clean_exit;
2275 }
2276
2277 key_state->state = libssh2_NB_state_sent1;
2278 }
2279
2280 if(key_state->state == libssh2_NB_state_sent1) {
2281 rc = _libssh2_packet_require(session, SSH2_MSG_KEX_ECDH_REPLY,
2282 &key_state->data, &key_state->data_len,
2283 0, NULL, 0, &key_state->req_state);
2284 if(rc == LIBSSH2_ERROR_EAGAIN) {
2285 return rc;
2286 }
2287 else if(rc) {
2288 ret = _libssh2_error(session, rc,
2289 "Timeout waiting for ECDH_REPLY reply");
2290 goto ecdh_clean_exit;
2291 }
2292
2293 key_state->state = libssh2_NB_state_sent2;
2294 }
2295
2296 if(key_state->state == libssh2_NB_state_sent2) {
2297
2298 (void)kex_session_ecdh_curve_type(session->kex->name, &type);
2299
2300 ret = ecdh_sha2_nistp(session, type, key_state->data,
2301 key_state->data_len,
2302 (unsigned char *)key_state->public_key_oct,
2303 key_state->public_key_oct_len,
2304 key_state->private_key,
2305 &key_state->exchange_state);
2306
2307 if(ret == LIBSSH2_ERROR_EAGAIN) {
2308 return ret;
2309 }
2310
2311 LIBSSH2_FREE(session, key_state->data);
2312 }
2313
2314 ecdh_clean_exit:
2315
2316 if(key_state->public_key_oct) {
2317 LIBSSH2_FREE(session, key_state->public_key_oct);
2318 key_state->public_key_oct = NULL;
2319 }
2320
2321 if(key_state->private_key) {
2322 _libssh2_ecdsa_free(key_state->private_key);
2323 key_state->private_key = NULL;
2324 }
2325
2326 key_state->state = libssh2_NB_state_idle;
2327
2328 return ret;
2329 }
2330
2331 #endif /*LIBSSH2_ECDSA*/
2332
2333
2334 #if LIBSSH2_ED25519
2335
2336 /* curve25519_sha256
2337 * Elliptic Curve Key Exchange
2338 */
2339
2340 static int
curve25519_sha256(LIBSSH2_SESSION * session,unsigned char * data,size_t data_len,unsigned char public_key[LIBSSH2_ED25519_KEY_LEN],unsigned char private_key[LIBSSH2_ED25519_KEY_LEN],kmdhgGPshakex_state_t * exchange_state)2341 curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
2342 size_t data_len,
2343 unsigned char public_key[LIBSSH2_ED25519_KEY_LEN],
2344 unsigned char private_key[LIBSSH2_ED25519_KEY_LEN],
2345 kmdhgGPshakex_state_t *exchange_state)
2346 {
2347 int ret = 0;
2348 int rc;
2349 int public_key_len = LIBSSH2_ED25519_KEY_LEN;
2350
2351 if(data_len < 5) {
2352 return _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
2353 "Data is too short");
2354 }
2355
2356 if(exchange_state->state == libssh2_NB_state_idle) {
2357
2358 /* Setup initial values */
2359 exchange_state->k = _libssh2_bn_init();
2360
2361 exchange_state->state = libssh2_NB_state_created;
2362 }
2363
2364 if(exchange_state->state == libssh2_NB_state_created) {
2365 /* parse INIT reply data */
2366 unsigned char *server_public_key, *server_host_key;
2367 size_t server_public_key_len, hostkey_len;
2368 struct string_buf buf;
2369
2370 if(data_len < 5) {
2371 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2372 "Unexpected key length");
2373 goto clean_exit;
2374 }
2375
2376 buf.data = data;
2377 buf.len = data_len;
2378 buf.dataptr = buf.data;
2379 buf.dataptr++; /* advance past packet type */
2380
2381 if(_libssh2_get_string(&buf, &server_host_key, &hostkey_len)) {
2382 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2383 "Unexpected key length");
2384 goto clean_exit;
2385 }
2386
2387 session->server_hostkey_len = (uint32_t)hostkey_len;
2388 session->server_hostkey = LIBSSH2_ALLOC(session,
2389 session->server_hostkey_len);
2390 if(!session->server_hostkey) {
2391 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
2392 "Unable to allocate memory for a copy "
2393 "of the host key");
2394 goto clean_exit;
2395 }
2396
2397 memcpy(session->server_hostkey, server_host_key,
2398 session->server_hostkey_len);
2399
2400 #if LIBSSH2_MD5
2401 {
2402 libssh2_md5_ctx fingerprint_ctx;
2403
2404 if(libssh2_md5_init(&fingerprint_ctx)) {
2405 libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
2406 session->server_hostkey_len);
2407 libssh2_md5_final(fingerprint_ctx,
2408 session->server_hostkey_md5);
2409 session->server_hostkey_md5_valid = TRUE;
2410 }
2411 else {
2412 session->server_hostkey_md5_valid = FALSE;
2413 }
2414 }
2415 #ifdef LIBSSH2DEBUG
2416 {
2417 char fingerprint[50], *fprint = fingerprint;
2418 int i;
2419 for(i = 0; i < 16; i++, fprint += 3) {
2420 snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
2421 }
2422 *(--fprint) = '\0';
2423 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2424 "Server's MD5 Fingerprint: %s", fingerprint);
2425 }
2426 #endif /* LIBSSH2DEBUG */
2427 #endif /* ! LIBSSH2_MD5 */
2428
2429 {
2430 libssh2_sha1_ctx fingerprint_ctx;
2431
2432 if(libssh2_sha1_init(&fingerprint_ctx)) {
2433 libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
2434 session->server_hostkey_len);
2435 libssh2_sha1_final(fingerprint_ctx,
2436 session->server_hostkey_sha1);
2437 session->server_hostkey_sha1_valid = TRUE;
2438 }
2439 else {
2440 session->server_hostkey_sha1_valid = FALSE;
2441 }
2442 }
2443 #ifdef LIBSSH2DEBUG
2444 {
2445 char fingerprint[64], *fprint = fingerprint;
2446 int i;
2447
2448 for(i = 0; i < 20; i++, fprint += 3) {
2449 snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
2450 }
2451 *(--fprint) = '\0';
2452 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2453 "Server's SHA1 Fingerprint: %s", fingerprint);
2454 }
2455 #endif /* LIBSSH2DEBUG */
2456
2457 /* SHA256 */
2458 {
2459 libssh2_sha256_ctx fingerprint_ctx;
2460
2461 if(libssh2_sha256_init(&fingerprint_ctx)) {
2462 libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
2463 session->server_hostkey_len);
2464 libssh2_sha256_final(fingerprint_ctx,
2465 session->server_hostkey_sha256);
2466 session->server_hostkey_sha256_valid = TRUE;
2467 }
2468 else {
2469 session->server_hostkey_sha256_valid = FALSE;
2470 }
2471 }
2472 #ifdef LIBSSH2DEBUG
2473 {
2474 char *base64Fingerprint = NULL;
2475 _libssh2_base64_encode(session,
2476 (const char *)
2477 session->server_hostkey_sha256,
2478 SHA256_DIGEST_LENGTH, &base64Fingerprint);
2479 if(base64Fingerprint != NULL) {
2480 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2481 "Server's SHA256 Fingerprint: %s",
2482 base64Fingerprint);
2483 LIBSSH2_FREE(session, base64Fingerprint);
2484 }
2485 }
2486 #endif /* LIBSSH2DEBUG */
2487
2488 if(session->hostkey->init(session, session->server_hostkey,
2489 session->server_hostkey_len,
2490 &session->server_hostkey_abstract)) {
2491 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
2492 "Unable to initialize hostkey importer");
2493 goto clean_exit;
2494 }
2495
2496 /* server public key Q_S */
2497 if(_libssh2_get_string(&buf, &server_public_key,
2498 &server_public_key_len)) {
2499 ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
2500 "Unexpected key length");
2501 goto clean_exit;
2502 }
2503
2504 if(server_public_key_len != LIBSSH2_ED25519_KEY_LEN) {
2505 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
2506 "Unexpected curve25519 server "
2507 "public key length");
2508 goto clean_exit;
2509 }
2510
2511 /* server signature */
2512 if(_libssh2_get_string(&buf, &exchange_state->h_sig,
2513 &(exchange_state->h_sig_len))) {
2514 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
2515 "Unexpected curve25519 server sig length");
2516 goto clean_exit;
2517 }
2518
2519 /* Compute the shared secret K */
2520 rc = _libssh2_curve25519_gen_k(&exchange_state->k, private_key,
2521 server_public_key);
2522 if(rc != 0) {
2523 ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE,
2524 "Unable to create ECDH shared secret");
2525 goto clean_exit;
2526 }
2527
2528 exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5;
2529 if(_libssh2_bn_bits(exchange_state->k) % 8) {
2530 /* don't need leading 00 */
2531 exchange_state->k_value_len--;
2532 }
2533 exchange_state->k_value =
2534 LIBSSH2_ALLOC(session, exchange_state->k_value_len);
2535 if(!exchange_state->k_value) {
2536 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
2537 "Unable to allocate buffer for K");
2538 goto clean_exit;
2539 }
2540 _libssh2_htonu32(exchange_state->k_value,
2541 exchange_state->k_value_len - 4);
2542 if(_libssh2_bn_bits(exchange_state->k) % 8) {
2543 _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4);
2544 }
2545 else {
2546 exchange_state->k_value[4] = 0;
2547 _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5);
2548 }
2549
2550 /*/ verify hash */
2551 LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256);
2552
2553 if(rc != 0) {
2554 ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
2555 "Unable to verify hostkey signature");
2556 goto clean_exit;
2557 }
2558
2559 exchange_state->c = SSH_MSG_NEWKEYS;
2560 exchange_state->state = libssh2_NB_state_sent;
2561 }
2562
2563 if(exchange_state->state == libssh2_NB_state_sent) {
2564 rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0);
2565 if(rc == LIBSSH2_ERROR_EAGAIN) {
2566 return rc;
2567 }
2568 else if(rc) {
2569 ret = _libssh2_error(session, rc,
2570 "Unable to send NEWKEYS message");
2571 goto clean_exit;
2572 }
2573
2574 exchange_state->state = libssh2_NB_state_sent2;
2575 }
2576
2577 if(exchange_state->state == libssh2_NB_state_sent2) {
2578 rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS,
2579 &exchange_state->tmp,
2580 &exchange_state->tmp_len, 0, NULL, 0,
2581 &exchange_state->req_state);
2582 if(rc == LIBSSH2_ERROR_EAGAIN) {
2583 return rc;
2584 }
2585 else if(rc) {
2586 ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
2587 goto clean_exit;
2588 }
2589
2590 /* The first key exchange has been performed, switch to active
2591 crypt/comp/mac mode */
2592
2593 session->state |= LIBSSH2_STATE_NEWKEYS;
2594 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message");
2595
2596 /* This will actually end up being just packet_type(1) for this packet
2597 type anyway */
2598 LIBSSH2_FREE(session, exchange_state->tmp);
2599
2600 if(!session->session_id) {
2601
2602 size_t digest_length = SHA256_DIGEST_LENGTH;
2603 session->session_id = LIBSSH2_ALLOC(session, digest_length);
2604 if(!session->session_id) {
2605 ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
2606 "Unable to allxcocate buffer for "
2607 "SHA digest");
2608 goto clean_exit;
2609 }
2610 memcpy(session->session_id, exchange_state->h_sig_comp,
2611 digest_length);
2612 session->session_id_len = digest_length;
2613 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2614 "session_id calculated");
2615 }
2616
2617 /* Cleanup any existing cipher */
2618 if(session->local.crypt->dtor) {
2619 session->local.crypt->dtor(session,
2620 &session->local.crypt_abstract);
2621 }
2622
2623 /* Calculate IV/Secret/Key for each direction */
2624 if(session->local.crypt->init) {
2625 unsigned char *iv = NULL, *secret = NULL;
2626 int free_iv = 0, free_secret = 0;
2627
2628 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv,
2629 session->local.crypt->
2630 iv_len, "A");
2631 if(!iv) {
2632 ret = -1;
2633 goto clean_exit;
2634 }
2635
2636 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret,
2637 session->local.crypt->
2638 secret_len, "C");
2639
2640 if(!secret) {
2641 LIBSSH2_FREE(session, iv);
2642 ret = LIBSSH2_ERROR_KEX_FAILURE;
2643 goto clean_exit;
2644 }
2645 if(session->local.crypt->
2646 init(session, session->local.crypt, iv, &free_iv, secret,
2647 &free_secret, 1, &session->local.crypt_abstract)) {
2648 LIBSSH2_FREE(session, iv);
2649 LIBSSH2_FREE(session, secret);
2650 ret = LIBSSH2_ERROR_KEX_FAILURE;
2651 goto clean_exit;
2652 }
2653
2654 if(free_iv) {
2655 _libssh2_explicit_zero(iv, session->local.crypt->iv_len);
2656 LIBSSH2_FREE(session, iv);
2657 }
2658
2659 if(free_secret) {
2660 _libssh2_explicit_zero(secret,
2661 session->local.crypt->secret_len);
2662 LIBSSH2_FREE(session, secret);
2663 }
2664 }
2665 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2666 "Client to Server IV and Key calculated");
2667
2668 if(session->remote.crypt->dtor) {
2669 /* Cleanup any existing cipher */
2670 session->remote.crypt->dtor(session,
2671 &session->remote.crypt_abstract);
2672 }
2673
2674 if(session->remote.crypt->init) {
2675 unsigned char *iv = NULL, *secret = NULL;
2676 int free_iv = 0, free_secret = 0;
2677
2678 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv,
2679 session->remote.crypt->
2680 iv_len, "B");
2681
2682 if(!iv) {
2683 ret = LIBSSH2_ERROR_KEX_FAILURE;
2684 goto clean_exit;
2685 }
2686 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret,
2687 session->remote.crypt->
2688 secret_len, "D");
2689
2690 if(!secret) {
2691 LIBSSH2_FREE(session, iv);
2692 ret = LIBSSH2_ERROR_KEX_FAILURE;
2693 goto clean_exit;
2694 }
2695 if(session->remote.crypt->
2696 init(session, session->remote.crypt, iv, &free_iv, secret,
2697 &free_secret, 0, &session->remote.crypt_abstract)) {
2698 LIBSSH2_FREE(session, iv);
2699 LIBSSH2_FREE(session, secret);
2700 ret = LIBSSH2_ERROR_KEX_FAILURE;
2701 goto clean_exit;
2702 }
2703
2704 if(free_iv) {
2705 _libssh2_explicit_zero(iv, session->remote.crypt->iv_len);
2706 LIBSSH2_FREE(session, iv);
2707 }
2708
2709 if(free_secret) {
2710 _libssh2_explicit_zero(secret,
2711 session->remote.crypt->secret_len);
2712 LIBSSH2_FREE(session, secret);
2713 }
2714 }
2715 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2716 "Server to Client IV and Key calculated");
2717
2718 if(session->local.mac->dtor) {
2719 session->local.mac->dtor(session, &session->local.mac_abstract);
2720 }
2721
2722 if(session->local.mac->init) {
2723 unsigned char *key = NULL;
2724 int free_key = 0;
2725
2726 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key,
2727 session->local.mac->
2728 key_len, "E");
2729
2730 if(!key) {
2731 ret = LIBSSH2_ERROR_KEX_FAILURE;
2732 goto clean_exit;
2733 }
2734 session->local.mac->init(session, key, &free_key,
2735 &session->local.mac_abstract);
2736
2737 if(free_key) {
2738 _libssh2_explicit_zero(key, session->local.mac->key_len);
2739 LIBSSH2_FREE(session, key);
2740 }
2741 }
2742 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2743 "Client to Server HMAC Key calculated");
2744
2745 if(session->remote.mac->dtor) {
2746 session->remote.mac->dtor(session, &session->remote.mac_abstract);
2747 }
2748
2749 if(session->remote.mac->init) {
2750 unsigned char *key = NULL;
2751 int free_key = 0;
2752
2753 LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key,
2754 session->remote.mac->
2755 key_len, "F");
2756
2757 if(!key) {
2758 ret = LIBSSH2_ERROR_KEX_FAILURE;
2759 goto clean_exit;
2760 }
2761 session->remote.mac->init(session, key, &free_key,
2762 &session->remote.mac_abstract);
2763
2764 if(free_key) {
2765 _libssh2_explicit_zero(key, session->remote.mac->key_len);
2766 LIBSSH2_FREE(session, key);
2767 }
2768 }
2769 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2770 "Server to Client HMAC Key calculated");
2771
2772 /* Initialize compression for each direction */
2773
2774 /* Cleanup any existing compression */
2775 if(session->local.comp && session->local.comp->dtor) {
2776 session->local.comp->dtor(session, 1,
2777 &session->local.comp_abstract);
2778 }
2779
2780 if(session->local.comp && session->local.comp->init) {
2781 if(session->local.comp->init(session, 1,
2782 &session->local.comp_abstract)) {
2783 ret = LIBSSH2_ERROR_KEX_FAILURE;
2784 goto clean_exit;
2785 }
2786 }
2787 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2788 "Client to Server compression initialized");
2789
2790 if(session->remote.comp && session->remote.comp->dtor) {
2791 session->remote.comp->dtor(session, 0,
2792 &session->remote.comp_abstract);
2793 }
2794
2795 if(session->remote.comp && session->remote.comp->init) {
2796 if(session->remote.comp->init(session, 0,
2797 &session->remote.comp_abstract)) {
2798 ret = LIBSSH2_ERROR_KEX_FAILURE;
2799 goto clean_exit;
2800 }
2801 }
2802 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2803 "Server to Client compression initialized");
2804 }
2805
2806 clean_exit:
2807 _libssh2_bn_free(exchange_state->k);
2808 exchange_state->k = NULL;
2809
2810 if(exchange_state->k_value) {
2811 LIBSSH2_FREE(session, exchange_state->k_value);
2812 exchange_state->k_value = NULL;
2813 }
2814
2815 exchange_state->state = libssh2_NB_state_idle;
2816
2817 return ret;
2818 }
2819
2820 /* kex_method_curve25519_key_exchange
2821 *
2822 * Elliptic Curve X25519 Key Exchange with SHA256 hash
2823 *
2824 */
2825
2826 static int
kex_method_curve25519_key_exchange(LIBSSH2_SESSION * session,key_exchange_state_low_t * key_state)2827 kex_method_curve25519_key_exchange
2828 (LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
2829 {
2830 int ret = 0;
2831 int rc = 0;
2832
2833 if(key_state->state == libssh2_NB_state_idle) {
2834
2835 key_state->public_key_oct = NULL;
2836 key_state->state = libssh2_NB_state_created;
2837 }
2838
2839 if(key_state->state == libssh2_NB_state_created) {
2840 unsigned char *s = NULL;
2841
2842 rc = strcmp(session->kex->name, "curve25519-sha256@libssh.org");
2843 if(rc != 0)
2844 rc = strcmp(session->kex->name, "curve25519-sha256");
2845
2846 if(rc != 0) {
2847 ret = _libssh2_error(session, -1,
2848 "Unknown KEX curve25519 curve type");
2849 goto clean_exit;
2850 }
2851
2852 rc = _libssh2_curve25519_new(session,
2853 &key_state->curve25519_public_key,
2854 &key_state->curve25519_private_key);
2855
2856 if(rc != 0) {
2857 ret = _libssh2_error(session, rc,
2858 "Unable to create private key");
2859 goto clean_exit;
2860 }
2861
2862 key_state->request[0] = SSH2_MSG_KEX_ECDH_INIT;
2863 s = key_state->request + 1;
2864 _libssh2_store_str(&s, (const char *)key_state->curve25519_public_key,
2865 LIBSSH2_ED25519_KEY_LEN);
2866 key_state->request_len = LIBSSH2_ED25519_KEY_LEN + 5;
2867
2868 _libssh2_debug(session, LIBSSH2_TRACE_KEX,
2869 "Initiating curve25519 SHA2");
2870
2871 key_state->state = libssh2_NB_state_sent;
2872 }
2873
2874 if(key_state->state == libssh2_NB_state_sent) {
2875 rc = _libssh2_transport_send(session, key_state->request,
2876 key_state->request_len, NULL, 0);
2877 if(rc == LIBSSH2_ERROR_EAGAIN) {
2878 return rc;
2879 }
2880 else if(rc) {
2881 ret = _libssh2_error(session, rc,
2882 "Unable to send ECDH_INIT");
2883 goto clean_exit;
2884 }
2885
2886 key_state->state = libssh2_NB_state_sent1;
2887 }
2888
2889 if(key_state->state == libssh2_NB_state_sent1) {
2890 rc = _libssh2_packet_require(session, SSH2_MSG_KEX_ECDH_REPLY,
2891 &key_state->data, &key_state->data_len,
2892 0, NULL, 0, &key_state->req_state);
2893 if(rc == LIBSSH2_ERROR_EAGAIN) {
2894 return rc;
2895 }
2896 else if(rc) {
2897 ret = _libssh2_error(session, rc,
2898 "Timeout waiting for ECDH_REPLY reply");
2899 goto clean_exit;
2900 }
2901
2902 key_state->state = libssh2_NB_state_sent2;
2903 }
2904
2905 if(key_state->state == libssh2_NB_state_sent2) {
2906
2907 ret = curve25519_sha256(session, key_state->data, key_state->data_len,
2908 key_state->curve25519_public_key,
2909 key_state->curve25519_private_key,
2910 &key_state->exchange_state);
2911
2912 if(ret == LIBSSH2_ERROR_EAGAIN) {
2913 return ret;
2914 }
2915
2916 LIBSSH2_FREE(session, key_state->data);
2917 }
2918
2919 clean_exit:
2920
2921 if(key_state->curve25519_public_key) {
2922 _libssh2_explicit_zero(key_state->curve25519_public_key,
2923 LIBSSH2_ED25519_KEY_LEN);
2924 LIBSSH2_FREE(session, key_state->curve25519_public_key);
2925 key_state->curve25519_public_key = NULL;
2926 }
2927
2928 if(key_state->curve25519_private_key) {
2929 _libssh2_explicit_zero(key_state->curve25519_private_key,
2930 LIBSSH2_ED25519_KEY_LEN);
2931 LIBSSH2_FREE(session, key_state->curve25519_private_key);
2932 key_state->curve25519_private_key = NULL;
2933 }
2934
2935 key_state->state = libssh2_NB_state_idle;
2936
2937 return ret;
2938 }
2939
2940
2941 #endif /*LIBSSH2_ED25519*/
2942
2943
2944 #define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001
2945 #define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002
2946
2947 static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = {
2948 "diffie-hellman-group1-sha1",
2949 kex_method_diffie_hellman_group1_sha1_key_exchange,
2950 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2951 };
2952
2953 static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = {
2954 "diffie-hellman-group14-sha1",
2955 kex_method_diffie_hellman_group14_sha1_key_exchange,
2956 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2957 };
2958
2959 static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha256 = {
2960 "diffie-hellman-group14-sha256",
2961 kex_method_diffie_hellman_group14_sha256_key_exchange,
2962 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2963 };
2964
2965 static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group16_sha512 = {
2966 "diffie-hellman-group16-sha512",
2967 kex_method_diffie_hellman_group16_sha512_key_exchange,
2968 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2969 };
2970
2971 static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group18_sha512 = {
2972 "diffie-hellman-group18-sha512",
2973 kex_method_diffie_hellman_group18_sha512_key_exchange,
2974 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2975 };
2976
2977 static const LIBSSH2_KEX_METHOD
2978 kex_method_diffie_helman_group_exchange_sha1 = {
2979 "diffie-hellman-group-exchange-sha1",
2980 kex_method_diffie_hellman_group_exchange_sha1_key_exchange,
2981 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2982 };
2983
2984 static const LIBSSH2_KEX_METHOD
2985 kex_method_diffie_helman_group_exchange_sha256 = {
2986 "diffie-hellman-group-exchange-sha256",
2987 kex_method_diffie_hellman_group_exchange_sha256_key_exchange,
2988 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2989 };
2990
2991 #if LIBSSH2_ECDSA
2992 static const LIBSSH2_KEX_METHOD
2993 kex_method_ecdh_sha2_nistp256 = {
2994 "ecdh-sha2-nistp256",
2995 kex_method_ecdh_key_exchange,
2996 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
2997 };
2998
2999 static const LIBSSH2_KEX_METHOD
3000 kex_method_ecdh_sha2_nistp384 = {
3001 "ecdh-sha2-nistp384",
3002 kex_method_ecdh_key_exchange,
3003 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
3004 };
3005
3006 static const LIBSSH2_KEX_METHOD
3007 kex_method_ecdh_sha2_nistp521 = {
3008 "ecdh-sha2-nistp521",
3009 kex_method_ecdh_key_exchange,
3010 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
3011 };
3012 #endif
3013
3014 #if LIBSSH2_ED25519
3015 static const LIBSSH2_KEX_METHOD
3016 kex_method_ssh_curve25519_sha256_libssh = {
3017 "curve25519-sha256@libssh.org",
3018 kex_method_curve25519_key_exchange,
3019 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
3020 };
3021 static const LIBSSH2_KEX_METHOD
3022 kex_method_ssh_curve25519_sha256 = {
3023 "curve25519-sha256",
3024 kex_method_curve25519_key_exchange,
3025 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
3026 };
3027 #endif
3028
3029 static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
3030 #if LIBSSH2_ED25519
3031 &kex_method_ssh_curve25519_sha256,
3032 &kex_method_ssh_curve25519_sha256_libssh,
3033 #endif
3034 #if LIBSSH2_ECDSA
3035 &kex_method_ecdh_sha2_nistp256,
3036 &kex_method_ecdh_sha2_nistp384,
3037 &kex_method_ecdh_sha2_nistp521,
3038 #endif
3039 &kex_method_diffie_helman_group_exchange_sha256,
3040 &kex_method_diffie_helman_group16_sha512,
3041 &kex_method_diffie_helman_group18_sha512,
3042 &kex_method_diffie_helman_group14_sha256,
3043 &kex_method_diffie_helman_group14_sha1,
3044 &kex_method_diffie_helman_group1_sha1,
3045 &kex_method_diffie_helman_group_exchange_sha1,
3046 NULL
3047 };
3048
3049 typedef struct _LIBSSH2_COMMON_METHOD
3050 {
3051 const char *name;
3052 } LIBSSH2_COMMON_METHOD;
3053
3054 /* kex_method_strlen
3055 * Calculate the length of a particular method list's resulting string
3056 * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1
3057 * (because the last coma isn't used)
3058 * Another sign of bad coding practices gone mad. Pretend you don't see this.
3059 */
3060 static size_t
kex_method_strlen(LIBSSH2_COMMON_METHOD ** method)3061 kex_method_strlen(LIBSSH2_COMMON_METHOD ** method)
3062 {
3063 size_t len = 0;
3064
3065 if(!method || !*method) {
3066 return 0;
3067 }
3068
3069 while(*method && (*method)->name) {
3070 len += strlen((*method)->name) + 1;
3071 method++;
3072 }
3073
3074 return len - 1;
3075 }
3076
3077
3078
3079 /* kex_method_list
3080 * Generate formatted preference list in buf
3081 */
3082 static size_t
kex_method_list(unsigned char * buf,size_t list_strlen,LIBSSH2_COMMON_METHOD ** method)3083 kex_method_list(unsigned char *buf, size_t list_strlen,
3084 LIBSSH2_COMMON_METHOD ** method)
3085 {
3086 _libssh2_htonu32(buf, list_strlen);
3087 buf += 4;
3088
3089 if(!method || !*method) {
3090 return 4;
3091 }
3092
3093 while(*method && (*method)->name) {
3094 int mlen = strlen((*method)->name);
3095 memcpy(buf, (*method)->name, mlen);
3096 buf += mlen;
3097 *(buf++) = ',';
3098 method++;
3099 }
3100
3101 return list_strlen + 4;
3102 }
3103
3104
3105
3106 #define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \
3107 ((prefvar) ? strlen(prefvar) : \
3108 kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
3109
3110 #define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \
3111 if(prefvar) { \
3112 _libssh2_htonu32((buf), (prefvarlen)); \
3113 buf += 4; \
3114 memcpy((buf), (prefvar), (prefvarlen)); \
3115 buf += (prefvarlen); \
3116 } \
3117 else { \
3118 buf += kex_method_list((buf), (prefvarlen), \
3119 (LIBSSH2_COMMON_METHOD**)(defaultvar)); \
3120 }
3121
3122 /* kexinit
3123 * Send SSH_MSG_KEXINIT packet
3124 */
kexinit(LIBSSH2_SESSION * session)3125 static int kexinit(LIBSSH2_SESSION * session)
3126 {
3127 /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) +
3128 reserved(4) + length longs(40) */
3129 size_t data_len = 62;
3130 size_t kex_len, hostkey_len = 0;
3131 size_t crypt_cs_len, crypt_sc_len;
3132 size_t comp_cs_len, comp_sc_len;
3133 size_t mac_cs_len, mac_sc_len;
3134 size_t lang_cs_len, lang_sc_len;
3135 unsigned char *data, *s;
3136 int rc;
3137
3138 if(session->kexinit_state == libssh2_NB_state_idle) {
3139 kex_len =
3140 LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods);
3141 hostkey_len =
3142 LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs,
3143 libssh2_hostkey_methods());
3144 crypt_cs_len =
3145 LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs,
3146 libssh2_crypt_methods());
3147 crypt_sc_len =
3148 LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs,
3149 libssh2_crypt_methods());
3150 mac_cs_len =
3151 LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs,
3152 _libssh2_mac_methods());
3153 mac_sc_len =
3154 LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs,
3155 _libssh2_mac_methods());
3156 comp_cs_len =
3157 LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs,
3158 _libssh2_comp_methods(session));
3159 comp_sc_len =
3160 LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs,
3161 _libssh2_comp_methods(session));
3162 lang_cs_len =
3163 LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL);
3164 lang_sc_len =
3165 LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL);
3166
3167 data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len +
3168 comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len +
3169 lang_cs_len + lang_sc_len;
3170
3171 s = data = LIBSSH2_ALLOC(session, data_len);
3172 if(!data) {
3173 return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
3174 "Unable to allocate memory");
3175 }
3176
3177 *(s++) = SSH_MSG_KEXINIT;
3178
3179 if(_libssh2_random(s, 16)) {
3180 return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN,
3181 "Unable to get random bytes "
3182 "for KEXINIT cookie");
3183 }
3184 s += 16;
3185
3186 /* Ennumerating through these lists twice is probably (certainly?)
3187 inefficient from a CPU standpoint, but it saves multiple
3188 malloc/realloc calls */
3189 LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs,
3190 libssh2_kex_methods);
3191 LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs,
3192 libssh2_hostkey_methods());
3193 LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs,
3194 libssh2_crypt_methods());
3195 LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs,
3196 libssh2_crypt_methods());
3197 LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs,
3198 _libssh2_mac_methods());
3199 LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs,
3200 _libssh2_mac_methods());
3201 LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs,
3202 _libssh2_comp_methods(session));
3203 LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs,
3204 _libssh2_comp_methods(session));
3205 LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs,
3206 NULL);
3207 LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs,
3208 NULL);
3209
3210 /* No optimistic KEX packet follows */
3211 /* Deal with optimistic packets
3212 * session->flags |= KEXINIT_OPTIMISTIC
3213 * session->flags |= KEXINIT_METHODSMATCH
3214 */
3215 *(s++) = 0;
3216
3217 /* Reserved == 0 */
3218 _libssh2_htonu32(s, 0);
3219
3220 #ifdef LIBSSH2DEBUG
3221 {
3222 /* Funnily enough, they'll all "appear" to be '\0' terminated */
3223 unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */
3224
3225 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p);
3226 p += kex_len + 4;
3227 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p);
3228 p += hostkey_len + 4;
3229 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p);
3230 p += crypt_cs_len + 4;
3231 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p);
3232 p += crypt_sc_len + 4;
3233 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p);
3234 p += mac_cs_len + 4;
3235 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p);
3236 p += mac_sc_len + 4;
3237 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p);
3238 p += comp_cs_len + 4;
3239 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p);
3240 p += comp_sc_len + 4;
3241 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p);
3242 p += lang_cs_len + 4;
3243 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p);
3244 p += lang_sc_len + 4;
3245 }
3246 #endif /* LIBSSH2DEBUG */
3247
3248 session->kexinit_state = libssh2_NB_state_created;
3249 }
3250 else {
3251 data = session->kexinit_data;
3252 data_len = session->kexinit_data_len;
3253 /* zap the variables to ensure there is NOT a double free later */
3254 session->kexinit_data = NULL;
3255 session->kexinit_data_len = 0;
3256 }
3257
3258 rc = _libssh2_transport_send(session, data, data_len, NULL, 0);
3259 if(rc == LIBSSH2_ERROR_EAGAIN) {
3260 session->kexinit_data = data;
3261 session->kexinit_data_len = data_len;
3262 return rc;
3263 }
3264 else if(rc) {
3265 LIBSSH2_FREE(session, data);
3266 session->kexinit_state = libssh2_NB_state_idle;
3267 return _libssh2_error(session, rc,
3268 "Unable to send KEXINIT packet to remote host");
3269
3270 }
3271
3272 if(session->local.kexinit) {
3273 LIBSSH2_FREE(session, session->local.kexinit);
3274 }
3275
3276 session->local.kexinit = data;
3277 session->local.kexinit_len = data_len;
3278
3279 session->kexinit_state = libssh2_NB_state_idle;
3280
3281 return 0;
3282 }
3283
3284 /* kex_agree_instr
3285 * Kex specific variant of strstr()
3286 * Needle must be precede by BOL or ',', and followed by ',' or EOL
3287 */
3288 static unsigned char *
kex_agree_instr(unsigned char * haystack,unsigned long haystack_len,const unsigned char * needle,unsigned long needle_len)3289 kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
3290 const unsigned char *needle, unsigned long needle_len)
3291 {
3292 unsigned char *s;
3293 unsigned char *end_haystack;
3294 unsigned long left;
3295
3296 if(haystack == NULL || needle == NULL) {
3297 return NULL;
3298 }
3299
3300 /* Haystack too short to bother trying */
3301 if(haystack_len < needle_len || needle_len == 0) {
3302 return NULL;
3303 }
3304
3305 s = haystack;
3306 end_haystack = &haystack[haystack_len];
3307 left = end_haystack - s;
3308
3309 /* Needle at start of haystack */
3310 if((strncmp((char *) haystack, (char *) needle, needle_len) == 0) &&
3311 (needle_len == haystack_len || haystack[needle_len] == ',')) {
3312 return haystack;
3313 }
3314
3315 /* Search until we run out of comas or we run out of haystack,
3316 whichever comes first */
3317 while((s = (unsigned char *) memchr((char *) s, ',', left))) {
3318 /* Advance buffer past coma if we can */
3319 left = end_haystack - s;
3320 if((left >= 1) && (left <= haystack_len) && (left > needle_len)) {
3321 s++;
3322 }
3323 else {
3324 return NULL;
3325 }
3326
3327 /* Needle at X position */
3328 if((strncmp((char *) s, (char *) needle, needle_len) == 0) &&
3329 (((s - haystack) + needle_len) == haystack_len
3330 || s[needle_len] == ',')) {
3331 return s;
3332 }
3333 }
3334
3335 return NULL;
3336 }
3337
3338
3339
3340 /* kex_get_method_by_name
3341 */
3342 static const LIBSSH2_COMMON_METHOD *
kex_get_method_by_name(const char * name,size_t name_len,const LIBSSH2_COMMON_METHOD ** methodlist)3343 kex_get_method_by_name(const char *name, size_t name_len,
3344 const LIBSSH2_COMMON_METHOD ** methodlist)
3345 {
3346 while(*methodlist) {
3347 if((strlen((*methodlist)->name) == name_len) &&
3348 (strncmp((*methodlist)->name, name, name_len) == 0)) {
3349 return *methodlist;
3350 }
3351 methodlist++;
3352 }
3353 return NULL;
3354 }
3355
3356
3357
3358 /* kex_agree_hostkey
3359 * Agree on a Hostkey which works with this kex
3360 */
kex_agree_hostkey(LIBSSH2_SESSION * session,unsigned long kex_flags,unsigned char * hostkey,unsigned long hostkey_len)3361 static int kex_agree_hostkey(LIBSSH2_SESSION * session,
3362 unsigned long kex_flags,
3363 unsigned char *hostkey, unsigned long hostkey_len)
3364 {
3365 const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
3366 unsigned char *s;
3367
3368 if(session->hostkey_prefs) {
3369 s = (unsigned char *) session->hostkey_prefs;
3370
3371 while(s && *s) {
3372 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
3373 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
3374 if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
3375 const LIBSSH2_HOSTKEY_METHOD *method =
3376 (const LIBSSH2_HOSTKEY_METHOD *)
3377 kex_get_method_by_name((char *) s, method_len,
3378 (const LIBSSH2_COMMON_METHOD **)
3379 hostkeyp);
3380
3381 if(!method) {
3382 /* Invalid method -- Should never be reached */
3383 return -1;
3384 }
3385
3386 /* So far so good, but does it suit our purposes? (Encrypting
3387 vs Signing) */
3388 if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) ==
3389 0) || (method->encrypt)) {
3390 /* Either this hostkey can do encryption or this kex just
3391 doesn't require it */
3392 if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY)
3393 == 0) || (method->sig_verify)) {
3394 /* Either this hostkey can do signing or this kex just
3395 doesn't require it */
3396 session->hostkey = method;
3397 return 0;
3398 }
3399 }
3400 }
3401
3402 s = p ? p + 1 : NULL;
3403 }
3404 return -1;
3405 }
3406
3407 while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) {
3408 s = kex_agree_instr(hostkey, hostkey_len,
3409 (unsigned char *) (*hostkeyp)->name,
3410 strlen((*hostkeyp)->name));
3411 if(s) {
3412 /* So far so good, but does it suit our purposes? (Encrypting vs
3413 Signing) */
3414 if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) ||
3415 ((*hostkeyp)->encrypt)) {
3416 /* Either this hostkey can do encryption or this kex just
3417 doesn't require it */
3418 if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) ==
3419 0) || ((*hostkeyp)->sig_verify)) {
3420 /* Either this hostkey can do signing or this kex just
3421 doesn't require it */
3422 session->hostkey = *hostkeyp;
3423 return 0;
3424 }
3425 }
3426 }
3427 hostkeyp++;
3428 }
3429
3430 return -1;
3431 }
3432
3433
3434
3435 /* kex_agree_kex_hostkey
3436 * Agree on a Key Exchange method and a hostkey encoding type
3437 */
kex_agree_kex_hostkey(LIBSSH2_SESSION * session,unsigned char * kex,unsigned long kex_len,unsigned char * hostkey,unsigned long hostkey_len)3438 static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
3439 unsigned long kex_len, unsigned char *hostkey,
3440 unsigned long hostkey_len)
3441 {
3442 const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
3443 unsigned char *s;
3444
3445 if(session->kex_prefs) {
3446 s = (unsigned char *) session->kex_prefs;
3447
3448 while(s && *s) {
3449 unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
3450 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
3451 q = kex_agree_instr(kex, kex_len, s, method_len);
3452 if(q) {
3453 const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
3454 kex_get_method_by_name((char *) s, method_len,
3455 (const LIBSSH2_COMMON_METHOD **)
3456 kexp);
3457
3458 if(!method) {
3459 /* Invalid method -- Should never be reached */
3460 return -1;
3461 }
3462
3463 /* We've agreed on a key exchange method,
3464 * Can we agree on a hostkey that works with this kex?
3465 */
3466 if(kex_agree_hostkey(session, method->flags, hostkey,
3467 hostkey_len) == 0) {
3468 session->kex = method;
3469 if(session->burn_optimistic_kexinit && (kex == q)) {
3470 /* Server sent an optimistic packet, and client agrees
3471 * with preference cancel burning the first KEX_INIT
3472 * packet that comes in */
3473 session->burn_optimistic_kexinit = 0;
3474 }
3475 return 0;
3476 }
3477 }
3478
3479 s = p ? p + 1 : NULL;
3480 }
3481 return -1;
3482 }
3483
3484 while(*kexp && (*kexp)->name) {
3485 s = kex_agree_instr(kex, kex_len,
3486 (unsigned char *) (*kexp)->name,
3487 strlen((*kexp)->name));
3488 if(s) {
3489 /* We've agreed on a key exchange method,
3490 * Can we agree on a hostkey that works with this kex?
3491 */
3492 if(kex_agree_hostkey(session, (*kexp)->flags, hostkey,
3493 hostkey_len) == 0) {
3494 session->kex = *kexp;
3495 if(session->burn_optimistic_kexinit && (kex == s)) {
3496 /* Server sent an optimistic packet, and client agrees
3497 * with preference cancel burning the first KEX_INIT
3498 * packet that comes in */
3499 session->burn_optimistic_kexinit = 0;
3500 }
3501 return 0;
3502 }
3503 }
3504 kexp++;
3505 }
3506 return -1;
3507 }
3508
3509
3510
3511 /* kex_agree_crypt
3512 * Agree on a cipher algo
3513 */
kex_agree_crypt(LIBSSH2_SESSION * session,libssh2_endpoint_data * endpoint,unsigned char * crypt,unsigned long crypt_len)3514 static int kex_agree_crypt(LIBSSH2_SESSION * session,
3515 libssh2_endpoint_data *endpoint,
3516 unsigned char *crypt,
3517 unsigned long crypt_len)
3518 {
3519 const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
3520 unsigned char *s;
3521
3522 (void) session;
3523
3524 if(endpoint->crypt_prefs) {
3525 s = (unsigned char *) endpoint->crypt_prefs;
3526
3527 while(s && *s) {
3528 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
3529 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
3530
3531 if(kex_agree_instr(crypt, crypt_len, s, method_len)) {
3532 const LIBSSH2_CRYPT_METHOD *method =
3533 (const LIBSSH2_CRYPT_METHOD *)
3534 kex_get_method_by_name((char *) s, method_len,
3535 (const LIBSSH2_COMMON_METHOD **)
3536 cryptp);
3537
3538 if(!method) {
3539 /* Invalid method -- Should never be reached */
3540 return -1;
3541 }
3542
3543 endpoint->crypt = method;
3544 return 0;
3545 }
3546
3547 s = p ? p + 1 : NULL;
3548 }
3549 return -1;
3550 }
3551
3552 while(*cryptp && (*cryptp)->name) {
3553 s = kex_agree_instr(crypt, crypt_len,
3554 (unsigned char *) (*cryptp)->name,
3555 strlen((*cryptp)->name));
3556 if(s) {
3557 endpoint->crypt = *cryptp;
3558 return 0;
3559 }
3560 cryptp++;
3561 }
3562
3563 return -1;
3564 }
3565
3566
3567
3568 /* kex_agree_mac
3569 * Agree on a message authentication hash
3570 */
kex_agree_mac(LIBSSH2_SESSION * session,libssh2_endpoint_data * endpoint,unsigned char * mac,unsigned long mac_len)3571 static int kex_agree_mac(LIBSSH2_SESSION * session,
3572 libssh2_endpoint_data * endpoint, unsigned char *mac,
3573 unsigned long mac_len)
3574 {
3575 const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods();
3576 unsigned char *s;
3577 (void) session;
3578
3579 if(endpoint->mac_prefs) {
3580 s = (unsigned char *) endpoint->mac_prefs;
3581
3582 while(s && *s) {
3583 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
3584 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
3585
3586 if(kex_agree_instr(mac, mac_len, s, method_len)) {
3587 const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
3588 kex_get_method_by_name((char *) s, method_len,
3589 (const LIBSSH2_COMMON_METHOD **)
3590 macp);
3591
3592 if(!method) {
3593 /* Invalid method -- Should never be reached */
3594 return -1;
3595 }
3596
3597 endpoint->mac = method;
3598 return 0;
3599 }
3600
3601 s = p ? p + 1 : NULL;
3602 }
3603 return -1;
3604 }
3605
3606 while(*macp && (*macp)->name) {
3607 s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
3608 strlen((*macp)->name));
3609 if(s) {
3610 endpoint->mac = *macp;
3611 return 0;
3612 }
3613 macp++;
3614 }
3615
3616 return -1;
3617 }
3618
3619
3620
3621 /* kex_agree_comp
3622 * Agree on a compression scheme
3623 */
kex_agree_comp(LIBSSH2_SESSION * session,libssh2_endpoint_data * endpoint,unsigned char * comp,unsigned long comp_len)3624 static int kex_agree_comp(LIBSSH2_SESSION *session,
3625 libssh2_endpoint_data *endpoint, unsigned char *comp,
3626 unsigned long comp_len)
3627 {
3628 const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods(session);
3629 unsigned char *s;
3630 (void) session;
3631
3632 if(endpoint->comp_prefs) {
3633 s = (unsigned char *) endpoint->comp_prefs;
3634
3635 while(s && *s) {
3636 unsigned char *p = (unsigned char *) strchr((char *) s, ',');
3637 size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
3638
3639 if(kex_agree_instr(comp, comp_len, s, method_len)) {
3640 const LIBSSH2_COMP_METHOD *method =
3641 (const LIBSSH2_COMP_METHOD *)
3642 kex_get_method_by_name((char *) s, method_len,
3643 (const LIBSSH2_COMMON_METHOD **)
3644 compp);
3645
3646 if(!method) {
3647 /* Invalid method -- Should never be reached */
3648 return -1;
3649 }
3650
3651 endpoint->comp = method;
3652 return 0;
3653 }
3654
3655 s = p ? p + 1 : NULL;
3656 }
3657 return -1;
3658 }
3659
3660 while(*compp && (*compp)->name) {
3661 s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
3662 strlen((*compp)->name));
3663 if(s) {
3664 endpoint->comp = *compp;
3665 return 0;
3666 }
3667 compp++;
3668 }
3669
3670 return -1;
3671 }
3672
3673
3674 /* TODO: When in server mode we need to turn this logic on its head
3675 * The Client gets to make the final call on "agreed methods"
3676 */
3677
3678 /* kex_agree_methods
3679 * Decide which specific method to use of the methods offered by each party
3680 */
kex_agree_methods(LIBSSH2_SESSION * session,unsigned char * data,unsigned data_len)3681 static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
3682 unsigned data_len)
3683 {
3684 unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc,
3685 *mac_cs, *mac_sc;
3686 size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len;
3687 size_t comp_sc_len, mac_cs_len, mac_sc_len;
3688 struct string_buf buf;
3689
3690 if(data_len < 17)
3691 return -1;
3692
3693 buf.data = (unsigned char *)data;
3694 buf.len = data_len;
3695 buf.dataptr = buf.data;
3696 buf.dataptr++; /* advance past packet type */
3697
3698 /* Skip cookie, don't worry, it's preserved in the kexinit field */
3699 buf.dataptr += 16;
3700
3701 /* Locate each string */
3702 if(_libssh2_get_string(&buf, &kex, &kex_len))
3703 return -1;
3704 if(_libssh2_get_string(&buf, &hostkey, &hostkey_len))
3705 return -1;
3706 if(_libssh2_get_string(&buf, &crypt_cs, &crypt_cs_len))
3707 return -1;
3708 if(_libssh2_get_string(&buf, &crypt_sc, &crypt_sc_len))
3709 return -1;
3710 if(_libssh2_get_string(&buf, &mac_cs, &mac_cs_len))
3711 return -1;
3712 if(_libssh2_get_string(&buf, &mac_sc, &mac_sc_len))
3713 return -1;
3714 if(_libssh2_get_string(&buf, &comp_cs, &comp_cs_len))
3715 return -1;
3716 if(_libssh2_get_string(&buf, &comp_sc, &comp_sc_len))
3717 return -1;
3718
3719 /* If the server sent an optimistic packet, assume that it guessed wrong.
3720 * If the guess is determined to be right (by kex_agree_kex_hostkey)
3721 * This flag will be reset to zero so that it's not ignored */
3722 if(_libssh2_check_length(&buf, 1)) {
3723 session->burn_optimistic_kexinit = *(buf.dataptr++);
3724 }
3725 else {
3726 return -1;
3727 }
3728
3729 /* Next uint32 in packet is all zeros (reserved) */
3730
3731 if(kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) {
3732 return -1;
3733 }
3734
3735 if(kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len)
3736 || kex_agree_crypt(session, &session->remote, crypt_sc,
3737 crypt_sc_len)) {
3738 return -1;
3739 }
3740
3741 if(kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) ||
3742 kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) {
3743 return -1;
3744 }
3745
3746 if(kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) ||
3747 kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) {
3748 return -1;
3749 }
3750
3751 #if 0
3752 if(libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len)
3753 || libssh2_kex_agree_lang(session, &session->remote, lang_sc,
3754 lang_sc_len)) {
3755 return -1;
3756 }
3757 #endif
3758
3759 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s",
3760 session->kex->name);
3761 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s",
3762 session->hostkey->name);
3763 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s",
3764 session->local.crypt->name);
3765 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s",
3766 session->remote.crypt->name);
3767 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s",
3768 session->local.mac->name);
3769 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s",
3770 session->remote.mac->name);
3771 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s",
3772 session->local.comp->name);
3773 _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s",
3774 session->remote.comp->name);
3775
3776 return 0;
3777 }
3778
3779
3780
3781 /* _libssh2_kex_exchange
3782 * Exchange keys
3783 * Returns 0 on success, non-zero on failure
3784 *
3785 * Returns some errors without _libssh2_error()
3786 */
3787 int
_libssh2_kex_exchange(LIBSSH2_SESSION * session,int reexchange,key_exchange_state_t * key_state)3788 _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
3789 key_exchange_state_t * key_state)
3790 {
3791 int rc = 0;
3792 int retcode;
3793
3794 session->state |= LIBSSH2_STATE_KEX_ACTIVE;
3795
3796 if(key_state->state == libssh2_NB_state_idle) {
3797 /* Prevent loop in packet_add() */
3798 session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
3799
3800 if(reexchange) {
3801 session->kex = NULL;
3802
3803 if(session->hostkey && session->hostkey->dtor) {
3804 session->hostkey->dtor(session,
3805 &session->server_hostkey_abstract);
3806 }
3807 session->hostkey = NULL;
3808 }
3809
3810 key_state->state = libssh2_NB_state_created;
3811 }
3812
3813 if(!session->kex || !session->hostkey) {
3814 if(key_state->state == libssh2_NB_state_created) {
3815 /* Preserve in case of failure */
3816 key_state->oldlocal = session->local.kexinit;
3817 key_state->oldlocal_len = session->local.kexinit_len;
3818
3819 session->local.kexinit = NULL;
3820
3821 key_state->state = libssh2_NB_state_sent;
3822 }
3823
3824 if(key_state->state == libssh2_NB_state_sent) {
3825 retcode = kexinit(session);
3826 if(retcode == LIBSSH2_ERROR_EAGAIN) {
3827 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
3828 return retcode;
3829 }
3830 else if(retcode) {
3831 session->local.kexinit = key_state->oldlocal;
3832 session->local.kexinit_len = key_state->oldlocal_len;
3833 key_state->state = libssh2_NB_state_idle;
3834 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
3835 session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
3836 return -1;
3837 }
3838
3839 key_state->state = libssh2_NB_state_sent1;
3840 }
3841
3842 if(key_state->state == libssh2_NB_state_sent1) {
3843 retcode =
3844 _libssh2_packet_require(session, SSH_MSG_KEXINIT,
3845 &key_state->data,
3846 &key_state->data_len, 0, NULL, 0,
3847 &key_state->req_state);
3848 if(retcode == LIBSSH2_ERROR_EAGAIN) {
3849 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
3850 return retcode;
3851 }
3852 else if(retcode) {
3853 if(session->local.kexinit) {
3854 LIBSSH2_FREE(session, session->local.kexinit);
3855 }
3856 session->local.kexinit = key_state->oldlocal;
3857 session->local.kexinit_len = key_state->oldlocal_len;
3858 key_state->state = libssh2_NB_state_idle;
3859 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
3860 session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
3861 return -1;
3862 }
3863
3864 if(session->remote.kexinit) {
3865 LIBSSH2_FREE(session, session->remote.kexinit);
3866 }
3867 session->remote.kexinit = key_state->data;
3868 session->remote.kexinit_len = key_state->data_len;
3869
3870 if(kex_agree_methods(session, key_state->data,
3871 key_state->data_len))
3872 rc = LIBSSH2_ERROR_KEX_FAILURE;
3873
3874 key_state->state = libssh2_NB_state_sent2;
3875 }
3876 }
3877 else {
3878 key_state->state = libssh2_NB_state_sent2;
3879 }
3880
3881 if(rc == 0 && session->kex) {
3882 if(key_state->state == libssh2_NB_state_sent2) {
3883 retcode = session->kex->exchange_keys(session,
3884 &key_state->key_state_low);
3885 if(retcode == LIBSSH2_ERROR_EAGAIN) {
3886 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
3887 return retcode;
3888 }
3889 else if(retcode) {
3890 rc = _libssh2_error(session,
3891 LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
3892 "Unrecoverable error exchanging keys");
3893 }
3894 }
3895 }
3896
3897 /* Done with kexinit buffers */
3898 if(session->local.kexinit) {
3899 LIBSSH2_FREE(session, session->local.kexinit);
3900 session->local.kexinit = NULL;
3901 }
3902 if(session->remote.kexinit) {
3903 LIBSSH2_FREE(session, session->remote.kexinit);
3904 session->remote.kexinit = NULL;
3905 }
3906
3907 session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
3908 session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
3909
3910 key_state->state = libssh2_NB_state_idle;
3911
3912 return rc;
3913 }
3914
3915
3916
3917 /* libssh2_session_method_pref
3918 * Set preferred method
3919 */
3920 LIBSSH2_API int
libssh2_session_method_pref(LIBSSH2_SESSION * session,int method_type,const char * prefs)3921 libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
3922 const char *prefs)
3923 {
3924 char **prefvar, *s, *newprefs;
3925 int prefs_len = strlen(prefs);
3926 const LIBSSH2_COMMON_METHOD **mlist;
3927
3928 switch(method_type) {
3929 case LIBSSH2_METHOD_KEX:
3930 prefvar = &session->kex_prefs;
3931 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
3932 break;
3933
3934 case LIBSSH2_METHOD_HOSTKEY:
3935 prefvar = &session->hostkey_prefs;
3936 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
3937 break;
3938
3939 case LIBSSH2_METHOD_CRYPT_CS:
3940 prefvar = &session->local.crypt_prefs;
3941 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
3942 break;
3943
3944 case LIBSSH2_METHOD_CRYPT_SC:
3945 prefvar = &session->remote.crypt_prefs;
3946 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
3947 break;
3948
3949 case LIBSSH2_METHOD_MAC_CS:
3950 prefvar = &session->local.mac_prefs;
3951 mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
3952 break;
3953
3954 case LIBSSH2_METHOD_MAC_SC:
3955 prefvar = &session->remote.mac_prefs;
3956 mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
3957 break;
3958
3959 case LIBSSH2_METHOD_COMP_CS:
3960 prefvar = &session->local.comp_prefs;
3961 mlist = (const LIBSSH2_COMMON_METHOD **)
3962 _libssh2_comp_methods(session);
3963 break;
3964
3965 case LIBSSH2_METHOD_COMP_SC:
3966 prefvar = &session->remote.comp_prefs;
3967 mlist = (const LIBSSH2_COMMON_METHOD **)
3968 _libssh2_comp_methods(session);
3969 break;
3970
3971 case LIBSSH2_METHOD_LANG_CS:
3972 prefvar = &session->local.lang_prefs;
3973 mlist = NULL;
3974 break;
3975
3976 case LIBSSH2_METHOD_LANG_SC:
3977 prefvar = &session->remote.lang_prefs;
3978 mlist = NULL;
3979 break;
3980
3981 default:
3982 return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
3983 "Invalid parameter specified for method_type");
3984 }
3985
3986 s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
3987 if(!newprefs) {
3988 return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
3989 "Error allocated space for method preferences");
3990 }
3991 memcpy(s, prefs, prefs_len + 1);
3992
3993 while(s && *s && mlist) {
3994 char *p = strchr(s, ',');
3995 int method_len = p ? (p - s) : (int) strlen(s);
3996
3997 if(!kex_get_method_by_name(s, method_len, mlist)) {
3998 /* Strip out unsupported method */
3999 if(p) {
4000 memcpy(s, p + 1, strlen(s) - method_len);
4001 }
4002 else {
4003 if(s > newprefs) {
4004 *(--s) = '\0';
4005 }
4006 else {
4007 *s = '\0';
4008 }
4009 }
4010 }
4011 else {
4012 s = p ? (p + 1) : NULL;
4013 }
4014 }
4015
4016 if(!*newprefs) {
4017 LIBSSH2_FREE(session, newprefs);
4018 return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
4019 "The requested method(s) are not currently "
4020 "supported");
4021 }
4022
4023 if(*prefvar) {
4024 LIBSSH2_FREE(session, *prefvar);
4025 }
4026 *prefvar = newprefs;
4027
4028 return 0;
4029 }
4030
4031 /*
4032 * libssh2_session_supported_algs()
4033 * returns a number of returned algorithms (a positive number) on success,
4034 * a negative number on failure
4035 */
4036
libssh2_session_supported_algs(LIBSSH2_SESSION * session,int method_type,const char *** algs)4037 LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
4038 int method_type,
4039 const char ***algs)
4040 {
4041 unsigned int i;
4042 unsigned int j;
4043 unsigned int ialg;
4044 const LIBSSH2_COMMON_METHOD **mlist;
4045
4046 /* to prevent coredumps due to dereferencing of NULL */
4047 if(NULL == algs)
4048 return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
4049 "algs must not be NULL");
4050
4051 switch(method_type) {
4052 case LIBSSH2_METHOD_KEX:
4053 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
4054 break;
4055
4056 case LIBSSH2_METHOD_HOSTKEY:
4057 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
4058 break;
4059
4060 case LIBSSH2_METHOD_CRYPT_CS:
4061 case LIBSSH2_METHOD_CRYPT_SC:
4062 mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
4063 break;
4064
4065 case LIBSSH2_METHOD_MAC_CS:
4066 case LIBSSH2_METHOD_MAC_SC:
4067 mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
4068 break;
4069
4070 case LIBSSH2_METHOD_COMP_CS:
4071 case LIBSSH2_METHOD_COMP_SC:
4072 mlist = (const LIBSSH2_COMMON_METHOD **)
4073 _libssh2_comp_methods(session);
4074 break;
4075
4076 default:
4077 return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
4078 "Unknown method type");
4079 } /* switch */
4080
4081 /* weird situation */
4082 if(NULL == mlist)
4083 return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
4084 "No algorithm found");
4085
4086 /*
4087 mlist is looped through twice. The first time to find the number od
4088 supported algorithms (needed to allocate the proper size of array) and
4089 the second time to actually copy the pointers. Typically this function
4090 will not be called often (typically at the beginning of a session) and
4091 the number of algorithms (i.e. number of iterations in one loop) will
4092 not be high (typically it will not exceed 20) for quite a long time.
4093
4094 So double looping really shouldn't be an issue and it is definitely a
4095 better solution than reallocation several times.
4096 */
4097
4098 /* count the number of supported algorithms */
4099 for(i = 0, ialg = 0; NULL != mlist[i]; i++) {
4100 /* do not count fields with NULL name */
4101 if(mlist[i]->name)
4102 ialg++;
4103 }
4104
4105 /* weird situation, no algorithm found */
4106 if(0 == ialg)
4107 return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
4108 "No algorithm found");
4109
4110 /* allocate buffer */
4111 *algs = (const char **) LIBSSH2_ALLOC(session, ialg*sizeof(const char *));
4112 if(NULL == *algs) {
4113 return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
4114 "Memory allocation failed");
4115 }
4116 /* Past this point *algs must be deallocated in case of an error!! */
4117
4118 /* copy non-NULL pointers only */
4119 for(i = 0, j = 0; NULL != mlist[i] && j < ialg; i++) {
4120 if(NULL == mlist[i]->name) {
4121 /* maybe a weird situation but if it occurs, do not include NULL
4122 pointers */
4123 continue;
4124 }
4125
4126 /* note that [] has higher priority than * (dereferencing) */
4127 (*algs)[j++] = mlist[i]->name;
4128 }
4129
4130 /* correct number of pointers copied? (test the code above) */
4131 if(j != ialg) {
4132 /* deallocate buffer */
4133 LIBSSH2_FREE(session, (void *)*algs);
4134 *algs = NULL;
4135
4136 return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
4137 "Internal error");
4138 }
4139
4140 return ialg;
4141 }
4142