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