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