1 /* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
4 * Redistribution and use in source and binary forms,
5 * with or without modification, are permitted provided
6 * that the following conditions are met:
8 * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * Neither the name of the copyright holder nor the names
18 * of any other contributors may be used to endorse or
19 * promote products derived from this software without
20 * specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38 #include "libssh2_priv.h"
40 /* TODO: Switch this to an inline and handle alloc() failures */
41 /* Helper macro called from libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange */
42 #define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \
44 libssh2_sha1_ctx hash; \
45 unsigned long len = 0; \
47 value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
50 while (len < (unsigned long)reqlen) { \
51 libssh2_sha1_init(&hash); \
52 libssh2_sha1_update(hash, exchange_state->k_value, \
53 exchange_state->k_value_len); \
54 libssh2_sha1_update(hash, exchange_state->h_sig_comp, \
57 libssh2_sha1_update(hash, value, len); \
59 libssh2_sha1_update(hash, (version), 1); \
60 libssh2_sha1_update(hash, session->session_id, \
61 session->session_id_len); \
63 libssh2_sha1_final(hash, (value) + len); \
64 len += SHA_DIGEST_LENGTH; \
68 /* {{{ libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange
69 * Diffie Hellman Key Exchange, Group Agnostic
72 libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(LIBSSH2_SESSION
*
85 kmdhgGPsha1kex_state_t
91 if (exchange_state
->state
== libssh2_NB_state_idle
) {
92 /* Setup initial values */
93 exchange_state
->e_packet
= NULL
;
94 exchange_state
->s_packet
= NULL
;
95 exchange_state
->k_value
= NULL
;
96 exchange_state
->ctx
= _libssh2_bn_ctx_new();
97 exchange_state
->x
= _libssh2_bn_init(); /* Random from client */
98 exchange_state
->e
= _libssh2_bn_init(); /* g^x mod p */
99 exchange_state
->f
= _libssh2_bn_init(); /* g^(Random from server) mod p */
100 exchange_state
->k
= _libssh2_bn_init(); /* The shared secret: f^x mod p */
102 /* Zero the whole thing out */
103 memset(&exchange_state
->req_state
, 0, sizeof(packet_require_state_t
));
105 /* Generate x and e */
106 _libssh2_bn_rand(exchange_state
->x
, group_order
, 0, -1);
107 _libssh2_bn_mod_exp(exchange_state
->e
, g
, exchange_state
->x
, p
,
108 exchange_state
->ctx
);
111 /* packet_type(1) + String Length(4) + leading 0(1) */
112 exchange_state
->e_packet_len
=
113 _libssh2_bn_bytes(exchange_state
->e
) + 6;
114 if (_libssh2_bn_bits(exchange_state
->e
) % 8) {
115 /* Leading 00 not needed */
116 exchange_state
->e_packet_len
--;
119 exchange_state
->e_packet
=
120 LIBSSH2_ALLOC(session
, exchange_state
->e_packet_len
);
121 if (!exchange_state
->e_packet
) {
122 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
, "Out of memory error",
127 exchange_state
->e_packet
[0] = packet_type_init
;
128 libssh2_htonu32(exchange_state
->e_packet
+ 1,
129 exchange_state
->e_packet_len
- 5);
130 if (_libssh2_bn_bits(exchange_state
->e
) % 8) {
131 _libssh2_bn_to_bin(exchange_state
->e
,
132 exchange_state
->e_packet
+ 5);
134 exchange_state
->e_packet
[5] = 0;
135 _libssh2_bn_to_bin(exchange_state
->e
,
136 exchange_state
->e_packet
+ 6);
139 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sending KEX packet %d",
140 (int) packet_type_init
);
141 exchange_state
->state
= libssh2_NB_state_created
;
144 if (exchange_state
->state
== libssh2_NB_state_created
) {
145 rc
= libssh2_packet_write(session
, exchange_state
->e_packet
,
146 exchange_state
->e_packet_len
);
147 if (rc
== PACKET_EAGAIN
) {
148 return PACKET_EAGAIN
;
150 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
151 "Unable to send KEX init message", 0);
155 exchange_state
->state
= libssh2_NB_state_sent
;
158 if (exchange_state
->state
== libssh2_NB_state_sent
) {
159 if (session
->burn_optimistic_kexinit
) {
160 /* The first KEX packet to come along will be the guess initially
161 * sent by the server. That guess turned out to be wrong so we
162 * need to silently ignore it */
165 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
166 "Waiting for badly guessed KEX packet (to be ignored)");
168 libssh2_packet_burn(session
, &exchange_state
->burn_state
);
169 if (burn_type
== PACKET_EAGAIN
) {
170 return PACKET_EAGAIN
;
171 } else if (burn_type
<= 0) {
172 /* Failed to receive a packet */
176 session
->burn_optimistic_kexinit
= 0;
178 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
179 "Burnt packet of type: %02x",
180 (unsigned int) burn_type
);
183 exchange_state
->state
= libssh2_NB_state_sent1
;
186 if (exchange_state
->state
== libssh2_NB_state_sent1
) {
187 /* Wait for KEX reply */
188 rc
= libssh2_packet_require_ex(session
, packet_type_reply
,
189 &exchange_state
->s_packet
,
190 &exchange_state
->s_packet_len
, 0, NULL
,
191 0, &exchange_state
->req_state
);
192 if (rc
== PACKET_EAGAIN
) {
193 return PACKET_EAGAIN
;
196 libssh2_error(session
, LIBSSH2_ERROR_TIMEOUT
,
197 "Timed out waiting for KEX reply", 0);
202 /* Parse KEXDH_REPLY */
203 exchange_state
->s
= exchange_state
->s_packet
+ 1;
205 session
->server_hostkey_len
= libssh2_ntohu32(exchange_state
->s
);
206 exchange_state
->s
+= 4;
207 session
->server_hostkey
=
208 LIBSSH2_ALLOC(session
, session
->server_hostkey_len
);
209 if (!session
->server_hostkey
) {
210 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
211 "Unable to allocate memory for a copy of the host key",
216 memcpy(session
->server_hostkey
, exchange_state
->s
,
217 session
->server_hostkey_len
);
218 exchange_state
->s
+= session
->server_hostkey_len
;
222 libssh2_md5_ctx fingerprint_ctx
;
224 libssh2_md5_init(&fingerprint_ctx
);
225 libssh2_md5_update(fingerprint_ctx
, session
->server_hostkey
,
226 session
->server_hostkey_len
);
227 libssh2_md5_final(fingerprint_ctx
, session
->server_hostkey_md5
);
231 char fingerprint
[50], *fprint
= fingerprint
;
233 for(i
= 0; i
< 16; i
++, fprint
+= 3) {
234 snprintf(fprint
, 4, "%02x:", session
->server_hostkey_md5
[i
]);
237 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
238 "Server's MD5 Fingerprint: %s", fingerprint
);
240 #endif /* LIBSSH2DEBUG */
241 #endif /* ! LIBSSH2_MD5 */
244 libssh2_sha1_ctx fingerprint_ctx
;
246 libssh2_sha1_init(&fingerprint_ctx
);
247 libssh2_sha1_update(fingerprint_ctx
, session
->server_hostkey
,
248 session
->server_hostkey_len
);
249 libssh2_sha1_final(fingerprint_ctx
, session
->server_hostkey_sha1
);
253 char fingerprint
[64], *fprint
= fingerprint
;
256 for(i
= 0; i
< 20; i
++, fprint
+= 3) {
257 snprintf(fprint
, 4, "%02x:", session
->server_hostkey_sha1
[i
]);
260 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
261 "Server's SHA1 Fingerprint: %s", fingerprint
);
263 #endif /* LIBSSH2DEBUG */
265 if (session
->hostkey
->
266 init(session
, session
->server_hostkey
, session
->server_hostkey_len
,
267 &session
->server_hostkey_abstract
)) {
268 libssh2_error(session
, LIBSSH2_ERROR_HOSTKEY_INIT
,
269 "Unable to initialize hostkey importer", 0);
274 exchange_state
->f_value_len
= libssh2_ntohu32(exchange_state
->s
);
275 exchange_state
->s
+= 4;
276 exchange_state
->f_value
= exchange_state
->s
;
277 exchange_state
->s
+= exchange_state
->f_value_len
;
278 _libssh2_bn_from_bin(exchange_state
->f
, exchange_state
->f_value_len
,
279 exchange_state
->f_value
);
281 exchange_state
->h_sig_len
= libssh2_ntohu32(exchange_state
->s
);
282 exchange_state
->s
+= 4;
283 exchange_state
->h_sig
= exchange_state
->s
;
285 /* Compute the shared secret */
286 _libssh2_bn_mod_exp(exchange_state
->k
, exchange_state
->f
,
287 exchange_state
->x
, p
, exchange_state
->ctx
);
288 exchange_state
->k_value_len
= _libssh2_bn_bytes(exchange_state
->k
) + 5;
289 if (_libssh2_bn_bits(exchange_state
->k
) % 8) {
290 /* don't need leading 00 */
291 exchange_state
->k_value_len
--;
293 exchange_state
->k_value
=
294 LIBSSH2_ALLOC(session
, exchange_state
->k_value_len
);
295 if (!exchange_state
->k_value
) {
296 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
297 "Unable to allocate buffer for K", 0);
301 libssh2_htonu32(exchange_state
->k_value
,
302 exchange_state
->k_value_len
- 4);
303 if (_libssh2_bn_bits(exchange_state
->k
) % 8) {
304 _libssh2_bn_to_bin(exchange_state
->k
, exchange_state
->k_value
+ 4);
306 exchange_state
->k_value
[4] = 0;
307 _libssh2_bn_to_bin(exchange_state
->k
, exchange_state
->k_value
+ 5);
310 libssh2_sha1_init(&exchange_state
->exchange_hash
);
311 if (session
->local
.banner
) {
312 libssh2_htonu32(exchange_state
->h_sig_comp
,
313 strlen((char *) session
->local
.banner
) - 2);
314 libssh2_sha1_update(exchange_state
->exchange_hash
,
315 exchange_state
->h_sig_comp
, 4);
316 libssh2_sha1_update(exchange_state
->exchange_hash
,
317 (char *) session
->local
.banner
,
318 strlen((char *) session
->local
.banner
) - 2);
320 libssh2_htonu32(exchange_state
->h_sig_comp
,
321 sizeof(LIBSSH2_SSH_DEFAULT_BANNER
) - 1);
322 libssh2_sha1_update(exchange_state
->exchange_hash
,
323 exchange_state
->h_sig_comp
, 4);
324 libssh2_sha1_update(exchange_state
->exchange_hash
,
325 LIBSSH2_SSH_DEFAULT_BANNER
,
326 sizeof(LIBSSH2_SSH_DEFAULT_BANNER
) - 1);
329 libssh2_htonu32(exchange_state
->h_sig_comp
,
330 strlen((char *) session
->remote
.banner
));
331 libssh2_sha1_update(exchange_state
->exchange_hash
,
332 exchange_state
->h_sig_comp
, 4);
333 libssh2_sha1_update(exchange_state
->exchange_hash
,
334 session
->remote
.banner
,
335 strlen((char *) session
->remote
.banner
));
337 libssh2_htonu32(exchange_state
->h_sig_comp
,
338 session
->local
.kexinit_len
);
339 libssh2_sha1_update(exchange_state
->exchange_hash
,
340 exchange_state
->h_sig_comp
, 4);
341 libssh2_sha1_update(exchange_state
->exchange_hash
,
342 session
->local
.kexinit
,
343 session
->local
.kexinit_len
);
345 libssh2_htonu32(exchange_state
->h_sig_comp
,
346 session
->remote
.kexinit_len
);
347 libssh2_sha1_update(exchange_state
->exchange_hash
,
348 exchange_state
->h_sig_comp
, 4);
349 libssh2_sha1_update(exchange_state
->exchange_hash
,
350 session
->remote
.kexinit
,
351 session
->remote
.kexinit_len
);
353 libssh2_htonu32(exchange_state
->h_sig_comp
,
354 session
->server_hostkey_len
);
355 libssh2_sha1_update(exchange_state
->exchange_hash
,
356 exchange_state
->h_sig_comp
, 4);
357 libssh2_sha1_update(exchange_state
->exchange_hash
,
358 session
->server_hostkey
,
359 session
->server_hostkey_len
);
361 if (packet_type_init
== SSH_MSG_KEX_DH_GEX_INIT
) {
362 /* diffie-hellman-group-exchange hashes additional fields */
363 #ifdef LIBSSH2_DH_GEX_NEW
364 libssh2_htonu32(exchange_state
->h_sig_comp
,
365 LIBSSH2_DH_GEX_MINGROUP
);
366 libssh2_htonu32(exchange_state
->h_sig_comp
+ 4,
367 LIBSSH2_DH_GEX_OPTGROUP
);
368 libssh2_htonu32(exchange_state
->h_sig_comp
+ 8,
369 LIBSSH2_DH_GEX_MAXGROUP
);
370 libssh2_sha1_update(exchange_state
->exchange_hash
,
371 exchange_state
->h_sig_comp
, 12);
373 libssh2_htonu32(exchange_state
->h_sig_comp
,
374 LIBSSH2_DH_GEX_OPTGROUP
);
375 libssh2_sha1_update(exchange_state
->exchange_hash
,
376 exchange_state
->h_sig_comp
, 4);
381 libssh2_sha1_update(exchange_state
->exchange_hash
, midhash
,
385 libssh2_sha1_update(exchange_state
->exchange_hash
,
386 exchange_state
->e_packet
+ 1,
387 exchange_state
->e_packet_len
- 1);
389 libssh2_htonu32(exchange_state
->h_sig_comp
,
390 exchange_state
->f_value_len
);
391 libssh2_sha1_update(exchange_state
->exchange_hash
,
392 exchange_state
->h_sig_comp
, 4);
393 libssh2_sha1_update(exchange_state
->exchange_hash
,
394 exchange_state
->f_value
,
395 exchange_state
->f_value_len
);
397 libssh2_sha1_update(exchange_state
->exchange_hash
,
398 exchange_state
->k_value
,
399 exchange_state
->k_value_len
);
401 libssh2_sha1_final(exchange_state
->exchange_hash
,
402 exchange_state
->h_sig_comp
);
404 if (session
->hostkey
->
405 sig_verify(session
, exchange_state
->h_sig
,
406 exchange_state
->h_sig_len
, exchange_state
->h_sig_comp
,
407 20, &session
->server_hostkey_abstract
)) {
408 libssh2_error(session
, LIBSSH2_ERROR_HOSTKEY_SIGN
,
409 "Unable to verify hostkey signature", 0);
414 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sending NEWKEYS message");
415 exchange_state
->c
= SSH_MSG_NEWKEYS
;
417 exchange_state
->state
= libssh2_NB_state_sent2
;
420 if (exchange_state
->state
== libssh2_NB_state_sent2
) {
421 rc
= libssh2_packet_write(session
, &exchange_state
->c
, 1);
422 if (rc
== PACKET_EAGAIN
) {
423 return PACKET_EAGAIN
;
425 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
426 "Unable to send NEWKEYS message", 0);
431 exchange_state
->state
= libssh2_NB_state_sent3
;
434 if (exchange_state
->state
== libssh2_NB_state_sent3
) {
435 rc
= libssh2_packet_require_ex(session
, SSH_MSG_NEWKEYS
,
436 &exchange_state
->tmp
,
437 &exchange_state
->tmp_len
, 0, NULL
, 0,
438 &exchange_state
->req_state
);
439 if (rc
== PACKET_EAGAIN
) {
440 return PACKET_EAGAIN
;
442 libssh2_error(session
, LIBSSH2_ERROR_TIMEOUT
,
443 "Timed out waiting for NEWKEYS", 0);
447 /* The first key exchange has been performed,
448 switch to active crypt/comp/mac mode */
449 session
->state
|= LIBSSH2_STATE_NEWKEYS
;
450 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Received NEWKEYS message");
452 /* This will actually end up being just packet_type(1)
453 for this packet type anyway */
454 LIBSSH2_FREE(session
, exchange_state
->tmp
);
456 if (!session
->session_id
) {
457 session
->session_id
= LIBSSH2_ALLOC(session
, SHA_DIGEST_LENGTH
);
458 if (!session
->session_id
) {
462 memcpy(session
->session_id
, exchange_state
->h_sig_comp
,
464 session
->session_id_len
= SHA_DIGEST_LENGTH
;
465 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "session_id calculated");
468 /* Cleanup any existing cipher */
469 if (session
->local
.crypt
->dtor
) {
470 session
->local
.crypt
->dtor(session
,
471 &session
->local
.crypt_abstract
);
474 /* Calculate IV/Secret/Key for each direction */
475 if (session
->local
.crypt
->init
) {
476 unsigned char *iv
= NULL
, *secret
= NULL
;
477 int free_iv
= 0, free_secret
= 0;
479 LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv
,
480 session
->local
.crypt
->
486 LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret
,
487 session
->local
.crypt
->
490 LIBSSH2_FREE(session
, iv
);
494 if (session
->local
.crypt
->
495 init(session
, session
->local
.crypt
, iv
, &free_iv
, secret
,
496 &free_secret
, 1, &session
->local
.crypt_abstract
)) {
497 LIBSSH2_FREE(session
, iv
);
498 LIBSSH2_FREE(session
, secret
);
504 memset(iv
, 0, session
->local
.crypt
->iv_len
);
505 LIBSSH2_FREE(session
, iv
);
509 memset(secret
, 0, session
->local
.crypt
->secret_len
);
510 LIBSSH2_FREE(session
, secret
);
513 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
514 "Client to Server IV and Key calculated");
516 if (session
->remote
.crypt
->dtor
) {
517 /* Cleanup any existing cipher */
518 session
->remote
.crypt
->dtor(session
,
519 &session
->remote
.crypt_abstract
);
522 if (session
->remote
.crypt
->init
) {
523 unsigned char *iv
= NULL
, *secret
= NULL
;
524 int free_iv
= 0, free_secret
= 0;
526 LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv
,
527 session
->remote
.crypt
->
533 LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret
,
534 session
->remote
.crypt
->
537 LIBSSH2_FREE(session
, iv
);
541 if (session
->remote
.crypt
->
542 init(session
, session
->remote
.crypt
, iv
, &free_iv
, secret
,
543 &free_secret
, 0, &session
->remote
.crypt_abstract
)) {
544 LIBSSH2_FREE(session
, iv
);
545 LIBSSH2_FREE(session
, secret
);
551 memset(iv
, 0, session
->remote
.crypt
->iv_len
);
552 LIBSSH2_FREE(session
, iv
);
556 memset(secret
, 0, session
->remote
.crypt
->secret_len
);
557 LIBSSH2_FREE(session
, secret
);
560 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
561 "Server to Client IV and Key calculated");
563 if (session
->local
.mac
->dtor
) {
564 session
->local
.mac
->dtor(session
, &session
->local
.mac_abstract
);
567 if (session
->local
.mac
->init
) {
568 unsigned char *key
= NULL
;
571 LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key
,
578 session
->local
.mac
->init(session
, key
, &free_key
,
579 &session
->local
.mac_abstract
);
582 memset(key
, 0, session
->local
.mac
->key_len
);
583 LIBSSH2_FREE(session
, key
);
586 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
587 "Client to Server HMAC Key calculated");
589 if (session
->remote
.mac
->dtor
) {
590 session
->remote
.mac
->dtor(session
, &session
->remote
.mac_abstract
);
593 if (session
->remote
.mac
->init
) {
594 unsigned char *key
= NULL
;
597 LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key
,
598 session
->remote
.mac
->
604 session
->remote
.mac
->init(session
, key
, &free_key
,
605 &session
->remote
.mac_abstract
);
608 memset(key
, 0, session
->remote
.mac
->key_len
);
609 LIBSSH2_FREE(session
, key
);
612 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
613 "Server to Client HMAC Key calculated");
617 _libssh2_bn_free(exchange_state
->x
);
618 exchange_state
->x
= NULL
;
619 _libssh2_bn_free(exchange_state
->e
);
620 exchange_state
->e
= NULL
;
621 _libssh2_bn_free(exchange_state
->f
);
622 exchange_state
->f
= NULL
;
623 _libssh2_bn_free(exchange_state
->k
);
624 exchange_state
->k
= NULL
;
625 _libssh2_bn_ctx_free(exchange_state
->ctx
);
626 exchange_state
->ctx
= NULL
;
628 if (exchange_state
->e_packet
) {
629 LIBSSH2_FREE(session
, exchange_state
->e_packet
);
630 exchange_state
->e_packet
= NULL
;
633 if (exchange_state
->s_packet
) {
634 LIBSSH2_FREE(session
, exchange_state
->s_packet
);
635 exchange_state
->s_packet
= NULL
;
638 if (exchange_state
->k_value
) {
639 LIBSSH2_FREE(session
, exchange_state
->k_value
);
640 exchange_state
->k_value
= NULL
;
643 if (session
->server_hostkey
) {
644 LIBSSH2_FREE(session
, session
->server_hostkey
);
645 session
->server_hostkey
= NULL
;
648 exchange_state
->state
= libssh2_NB_state_idle
;
655 /* {{{ libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange
656 * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1
659 libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION
*
661 key_exchange_state_low_t
664 static const unsigned char p_value
[128] = {
665 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
666 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
667 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
668 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
669 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
670 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
671 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
672 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
673 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
674 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
675 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
676 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
677 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
678 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
679 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
680 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
685 if (key_state
->state
== libssh2_NB_state_idle
) {
687 key_state
->p
= _libssh2_bn_init(); /* SSH2 defined value (p_value) */
688 key_state
->g
= _libssh2_bn_init(); /* SSH2 defined value (2) */
690 /* Initialize P and G */
691 _libssh2_bn_set_word(key_state
->g
, 2);
692 _libssh2_bn_from_bin(key_state
->p
, 128, p_value
);
694 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
695 "Initiating Diffie-Hellman Group1 Key Exchange");
697 key_state
->state
= libssh2_NB_state_created
;
701 libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session
,
711 if (ret
== PACKET_EAGAIN
) {
712 return PACKET_EAGAIN
;
715 _libssh2_bn_free(key_state
->p
);
717 _libssh2_bn_free(key_state
->g
);
719 key_state
->state
= libssh2_NB_state_idle
;
726 /* {{{ libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange
727 * Diffie-Hellman Group14 Key Exchange using SHA1
730 libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION
*
732 key_exchange_state_low_t
735 static const unsigned char p_value
[256] = {
736 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
737 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
738 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
739 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
740 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
741 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
742 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
743 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
744 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
745 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
746 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
747 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
748 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
749 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
750 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
751 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
752 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
753 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
754 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
755 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
756 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
757 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
758 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
759 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
760 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
761 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
762 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
763 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
764 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
765 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
766 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
767 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
771 if (key_state
->state
== libssh2_NB_state_idle
) {
772 key_state
->p
= _libssh2_bn_init(); /* SSH2 defined value (p_value) */
773 key_state
->g
= _libssh2_bn_init(); /* SSH2 defined value (2) */
776 /* Initialize P and G */
777 _libssh2_bn_set_word(key_state
->g
, 2);
778 _libssh2_bn_from_bin(key_state
->p
, 256, p_value
);
780 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
781 "Initiating Diffie-Hellman Group14 Key Exchange");
783 key_state
->state
= libssh2_NB_state_created
;
786 libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange(session
,
796 if (ret
== PACKET_EAGAIN
) {
797 return PACKET_EAGAIN
;
800 key_state
->state
= libssh2_NB_state_idle
;
801 _libssh2_bn_free(key_state
->p
);
803 _libssh2_bn_free(key_state
->g
);
811 /* {{{ libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange
812 * Diffie-Hellman Group Exchange Key Exchange using SHA1
813 * Negotiates random(ish) group for secret derivation
816 libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange
817 (LIBSSH2_SESSION
* session
, key_exchange_state_low_t
* key_state
)
820 unsigned long p_len
, g_len
;
824 if (key_state
->state
== libssh2_NB_state_idle
) {
825 key_state
->p
= _libssh2_bn_init();
826 key_state
->g
= _libssh2_bn_init();
827 /* Ask for a P and G pair */
828 #ifdef LIBSSH2_DH_GEX_NEW
829 key_state
->request
[0] = SSH_MSG_KEX_DH_GEX_REQUEST
;
830 libssh2_htonu32(key_state
->request
+ 1, LIBSSH2_DH_GEX_MINGROUP
);
831 libssh2_htonu32(key_state
->request
+ 5, LIBSSH2_DH_GEX_OPTGROUP
);
832 libssh2_htonu32(key_state
->request
+ 9, LIBSSH2_DH_GEX_MAXGROUP
);
833 key_state
->request_len
= 13;
834 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
835 "Initiating Diffie-Hellman Group-Exchange (New Method)");
837 key_state
->request
[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD
;
838 libssh2_htonu32(key_state
->request
+ 1, LIBSSH2_DH_GEX_OPTGROUP
);
839 key_state
->request_len
= 5;
840 _libssh2_debug(session
, LIBSSH2_DBG_KEX
,
841 "Initiating Diffie-Hellman Group-Exchange (Old Method)");
844 key_state
->state
= libssh2_NB_state_created
;
847 if (key_state
->state
== libssh2_NB_state_created
) {
848 rc
= libssh2_packet_write(session
, key_state
->request
,
849 key_state
->request_len
);
850 if (rc
== PACKET_EAGAIN
) {
851 return PACKET_EAGAIN
;
853 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
854 "Unable to send Group Exchange Request", 0);
856 goto dh_gex_clean_exit
;
859 key_state
->state
= libssh2_NB_state_sent
;
862 if (key_state
->state
== libssh2_NB_state_sent
) {
863 rc
= libssh2_packet_require_ex(session
, SSH_MSG_KEX_DH_GEX_GROUP
,
864 &key_state
->data
, &key_state
->data_len
,
865 0, NULL
, 0, &key_state
->req_state
);
866 if (rc
== PACKET_EAGAIN
) {
867 return PACKET_EAGAIN
;
869 libssh2_error(session
, LIBSSH2_ERROR_TIMEOUT
,
870 "Timeout waiting for GEX_GROUP reply", 0);
872 goto dh_gex_clean_exit
;
875 key_state
->state
= libssh2_NB_state_sent1
;
878 if (key_state
->state
== libssh2_NB_state_sent1
) {
879 s
= key_state
->data
+ 1;
880 p_len
= libssh2_ntohu32(s
);
882 _libssh2_bn_from_bin(key_state
->p
, p_len
, s
);
885 g_len
= libssh2_ntohu32(s
);
887 _libssh2_bn_from_bin(key_state
->g
, g_len
, s
);
891 libssh2_kex_method_diffie_hellman_groupGP_sha1_key_exchange
892 (session
, key_state
->g
, key_state
->p
, p_len
,
893 SSH_MSG_KEX_DH_GEX_INIT
, SSH_MSG_KEX_DH_GEX_REPLY
,
894 key_state
->data
+ 1, key_state
->data_len
- 1,
895 &key_state
->exchange_state
);
896 if (ret
== PACKET_EAGAIN
) {
897 return PACKET_EAGAIN
;
900 LIBSSH2_FREE(session
, key_state
->data
);
904 key_state
->state
= libssh2_NB_state_idle
;
905 _libssh2_bn_free(key_state
->g
);
907 _libssh2_bn_free(key_state
->p
);
915 #define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001
916 #define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002
918 static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group1_sha1
= {
919 "diffie-hellman-group1-sha1",
920 libssh2_kex_method_diffie_hellman_group1_sha1_key_exchange
,
921 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY
,
924 static const LIBSSH2_KEX_METHOD libssh2_kex_method_diffie_helman_group14_sha1
= {
925 "diffie-hellman-group14-sha1",
926 libssh2_kex_method_diffie_hellman_group14_sha1_key_exchange
,
927 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY
,
930 static const LIBSSH2_KEX_METHOD
931 libssh2_kex_method_diffie_helman_group_exchange_sha1
= {
932 "diffie-hellman-group-exchange-sha1",
933 libssh2_kex_method_diffie_hellman_group_exchange_sha1_key_exchange
,
934 LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY
,
937 static const LIBSSH2_KEX_METHOD
*libssh2_kex_methods
[] = {
938 &libssh2_kex_method_diffie_helman_group14_sha1
,
939 &libssh2_kex_method_diffie_helman_group_exchange_sha1
,
940 &libssh2_kex_method_diffie_helman_group1_sha1
,
944 typedef struct _LIBSSH2_COMMON_METHOD
947 } LIBSSH2_COMMON_METHOD
;
949 /* {{{ libssh2_kex_method_strlen
950 * Calculate the length of a particular method list's resulting string
951 * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used)
952 * Another sign of bad coding practices gone mad. Pretend you don't see this.
955 libssh2_kex_method_strlen(LIBSSH2_COMMON_METHOD
** method
)
959 if (!method
|| !*method
) {
963 while (*method
&& (*method
)->name
) {
964 len
+= strlen((*method
)->name
) + 1;
973 /* {{{ libssh2_kex_method_list
974 * Generate formatted preference list in buf
977 libssh2_kex_method_list(unsigned char *buf
, size_t list_strlen
,
978 LIBSSH2_COMMON_METHOD
** method
)
980 libssh2_htonu32(buf
, list_strlen
);
983 if (!method
|| !*method
) {
987 while (*method
&& (*method
)->name
) {
988 int mlen
= strlen((*method
)->name
);
989 memcpy(buf
, (*method
)->name
, mlen
);
995 return list_strlen
+ 4;
1000 #define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) ((prefvar) ? strlen(prefvar) : libssh2_kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
1001 #define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \
1003 libssh2_htonu32((buf), (prefvarlen)); \
1005 memcpy((buf), (prefvar), (prefvarlen)); \
1006 buf += (prefvarlen); \
1008 buf += libssh2_kex_method_list((buf), (prefvarlen), (LIBSSH2_COMMON_METHOD**)(defaultvar)); \
1011 /* {{{ libssh2_kexinit
1012 * Send SSH_MSG_KEXINIT packet
1015 libssh2_kexinit(LIBSSH2_SESSION
* session
)
1017 /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) +
1018 reserved(4) + length longs(40) */
1019 size_t data_len
= 62;
1020 size_t kex_len
, hostkey_len
= 0;
1021 size_t crypt_cs_len
, crypt_sc_len
;
1022 size_t comp_cs_len
, comp_sc_len
;
1023 size_t mac_cs_len
, mac_sc_len
;
1024 size_t lang_cs_len
, lang_sc_len
;
1025 unsigned char *data
, *s
;
1028 if (session
->kexinit_state
== libssh2_NB_state_idle
) {
1030 LIBSSH2_METHOD_PREFS_LEN(session
->kex_prefs
, libssh2_kex_methods
);
1032 LIBSSH2_METHOD_PREFS_LEN(session
->hostkey_prefs
,
1033 libssh2_hostkey_methods());
1035 LIBSSH2_METHOD_PREFS_LEN(session
->local
.crypt_prefs
,
1036 libssh2_crypt_methods());
1038 LIBSSH2_METHOD_PREFS_LEN(session
->remote
.crypt_prefs
,
1039 libssh2_crypt_methods());
1041 LIBSSH2_METHOD_PREFS_LEN(session
->local
.mac_prefs
,
1042 libssh2_mac_methods());
1044 LIBSSH2_METHOD_PREFS_LEN(session
->remote
.mac_prefs
,
1045 libssh2_mac_methods());
1047 LIBSSH2_METHOD_PREFS_LEN(session
->local
.comp_prefs
,
1048 libssh2_comp_methods());
1050 LIBSSH2_METHOD_PREFS_LEN(session
->remote
.comp_prefs
,
1051 libssh2_comp_methods());
1053 LIBSSH2_METHOD_PREFS_LEN(session
->local
.lang_prefs
, NULL
);
1055 LIBSSH2_METHOD_PREFS_LEN(session
->remote
.lang_prefs
, NULL
);
1057 data_len
+= kex_len
+ hostkey_len
+ crypt_cs_len
+ crypt_sc_len
+
1058 comp_cs_len
+ comp_sc_len
+ mac_cs_len
+ mac_sc_len
+
1059 lang_cs_len
+ lang_sc_len
;
1061 s
= data
= LIBSSH2_ALLOC(session
, data_len
);
1063 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1064 "Unable to allocate memory", 0);
1068 *(s
++) = SSH_MSG_KEXINIT
;
1070 libssh2_random(s
, 16);
1073 /* Ennumerating through these lists twice is probably (certainly?)
1074 inefficient from a CPU standpoint, but it saves multiple
1075 malloc/realloc calls */
1076 LIBSSH2_METHOD_PREFS_STR(s
, kex_len
, session
->kex_prefs
,
1077 libssh2_kex_methods
);
1078 LIBSSH2_METHOD_PREFS_STR(s
, hostkey_len
, session
->hostkey_prefs
,
1079 libssh2_hostkey_methods());
1080 LIBSSH2_METHOD_PREFS_STR(s
, crypt_cs_len
, session
->local
.crypt_prefs
,
1081 libssh2_crypt_methods());
1082 LIBSSH2_METHOD_PREFS_STR(s
, crypt_sc_len
, session
->remote
.crypt_prefs
,
1083 libssh2_crypt_methods());
1084 LIBSSH2_METHOD_PREFS_STR(s
, mac_cs_len
, session
->local
.mac_prefs
,
1085 libssh2_mac_methods());
1086 LIBSSH2_METHOD_PREFS_STR(s
, mac_sc_len
, session
->remote
.mac_prefs
,
1087 libssh2_mac_methods());
1088 LIBSSH2_METHOD_PREFS_STR(s
, comp_cs_len
, session
->local
.comp_prefs
,
1089 libssh2_comp_methods());
1090 LIBSSH2_METHOD_PREFS_STR(s
, comp_sc_len
, session
->remote
.comp_prefs
,
1091 libssh2_comp_methods());
1092 LIBSSH2_METHOD_PREFS_STR(s
, lang_cs_len
, session
->local
.lang_prefs
,
1094 LIBSSH2_METHOD_PREFS_STR(s
, lang_sc_len
, session
->remote
.lang_prefs
,
1097 /* No optimistic KEX packet follows */
1098 /* Deal with optimistic packets
1099 * session->flags |= KEXINIT_OPTIMISTIC
1100 * session->flags |= KEXINIT_METHODSMATCH
1112 /* Funnily enough, they'll all "appear" to be '\0' terminated */
1113 unsigned char *p
= data
+ 21; /* type(1) + cookie(16) + len(4) */
1115 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent KEX: %s", p
);
1117 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent HOSTKEY: %s", p
);
1118 p
+= hostkey_len
+ 4;
1119 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent CRYPT_CS: %s", p
);
1120 p
+= crypt_cs_len
+ 4;
1121 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent CRYPT_SC: %s", p
);
1122 p
+= crypt_sc_len
+ 4;
1123 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent MAC_CS: %s", p
);
1124 p
+= mac_cs_len
+ 4;
1125 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent MAC_SC: %s", p
);
1126 p
+= mac_sc_len
+ 4;
1127 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent COMP_CS: %s", p
);
1128 p
+= comp_cs_len
+ 4;
1129 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent COMP_SC: %s", p
);
1130 p
+= comp_sc_len
+ 4;
1131 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent LANG_CS: %s", p
);
1132 p
+= lang_cs_len
+ 4;
1133 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Sent LANG_SC: %s", p
);
1134 p
+= lang_sc_len
+ 4;
1136 #endif /* LIBSSH2DEBUG */
1138 session
->kexinit_state
= libssh2_NB_state_created
;
1140 data
= session
->kexinit_data
;
1141 data_len
= session
->kexinit_data_len
;
1144 if ((rc
= libssh2_packet_write(session
, data
, data_len
)) == PACKET_EAGAIN
) {
1145 session
->kexinit_data
= data
;
1146 session
->kexinit_data_len
= data_len
;
1147 return PACKET_EAGAIN
;
1149 LIBSSH2_FREE(session
, data
);
1150 libssh2_error(session
, LIBSSH2_ERROR_SOCKET_SEND
,
1151 "Unable to send KEXINIT packet to remote host", 0);
1152 session
->kexinit_state
= libssh2_NB_state_idle
;
1156 if (session
->local
.kexinit
) {
1157 LIBSSH2_FREE(session
, session
->local
.kexinit
);
1160 session
->local
.kexinit
= data
;
1161 session
->local
.kexinit_len
= data_len
;
1163 session
->kexinit_state
= libssh2_NB_state_idle
;
1170 /* {{{ libssh2_kex_agree_instr
1171 * Kex specific variant of strstr()
1172 * Needle must be preceed by BOL or ',', and followed by ',' or EOL
1174 static unsigned char *
1175 libssh2_kex_agree_instr(unsigned char *haystack
, unsigned long haystack_len
,
1176 const unsigned char *needle
, unsigned long needle_len
)
1180 /* Haystack too short to bother trying */
1181 if (haystack_len
< needle_len
) {
1185 /* Needle at start of haystack */
1186 if ((strncmp((char *) haystack
, (char *) needle
, needle_len
) == 0) &&
1187 (needle_len
== haystack_len
|| haystack
[needle_len
] == ',')) {
1192 /* Search until we run out of comas or we run out of haystack,
1193 whichever comes first */
1194 while ((s
= (unsigned char *) strchr((char *) s
, ','))
1195 && ((haystack_len
- (s
- haystack
)) > needle_len
)) {
1197 /* Needle at X position */
1198 if ((strncmp((char *) s
, (char *) needle
, needle_len
) == 0) &&
1199 (((s
- haystack
) + needle_len
) == haystack_len
1200 || s
[needle_len
] == ',')) {
1210 /* {{{ libssh2_get_method_by_name
1212 static const LIBSSH2_COMMON_METHOD
*
1213 libssh2_get_method_by_name(const char *name
, int name_len
,
1214 const LIBSSH2_COMMON_METHOD
** methodlist
)
1216 while (*methodlist
) {
1217 if ((strlen((*methodlist
)->name
) == name_len
) &&
1218 (strncmp((*methodlist
)->name
, name
, name_len
) == 0)) {
1228 /* {{{ libssh2_kex_agree_hostkey
1229 * Agree on a Hostkey which works with this kex
1232 libssh2_kex_agree_hostkey(LIBSSH2_SESSION
* session
, unsigned long kex_flags
,
1233 unsigned char *hostkey
, unsigned long hostkey_len
)
1235 const LIBSSH2_HOSTKEY_METHOD
**hostkeyp
= libssh2_hostkey_methods();
1238 if (session
->hostkey_prefs
) {
1239 s
= (unsigned char *) session
->hostkey_prefs
;
1242 unsigned char *p
= (unsigned char *) strchr((char *) s
, ',');
1243 int method_len
= (p
? (p
- s
) : strlen((char *) s
));
1244 if (libssh2_kex_agree_instr(hostkey
, hostkey_len
, s
, method_len
)) {
1245 const LIBSSH2_HOSTKEY_METHOD
*method
=
1246 (const LIBSSH2_HOSTKEY_METHOD
*)
1247 libssh2_get_method_by_name((char *) s
, method_len
,
1248 (const LIBSSH2_COMMON_METHOD
**)
1252 /* Invalid method -- Should never be reached */
1256 /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */
1257 if (((kex_flags
& LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY
) ==
1258 0) || (method
->encrypt
)) {
1259 /* Either this hostkey can do encryption or this kex just doesn't require it */
1260 if (((kex_flags
& LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY
)
1261 == 0) || (method
->sig_verify
)) {
1262 /* Either this hostkey can do signing or this kex just doesn't require it */
1263 session
->hostkey
= method
;
1269 s
= p
? p
+ 1 : NULL
;
1274 while (hostkeyp
&& (*hostkeyp
)->name
) {
1275 s
= libssh2_kex_agree_instr(hostkey
, hostkey_len
,
1276 (unsigned char *) (*hostkeyp
)->name
,
1277 strlen((*hostkeyp
)->name
));
1279 /* So far so good, but does it suit our purposes? (Encrypting vs Signing) */
1280 if (((kex_flags
& LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY
) == 0) ||
1281 ((*hostkeyp
)->encrypt
)) {
1282 /* Either this hostkey can do encryption or this kex just doesn't require it */
1283 if (((kex_flags
& LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY
) ==
1284 0) || ((*hostkeyp
)->sig_verify
)) {
1285 /* Either this hostkey can do signing or this kex just doesn't require it */
1286 session
->hostkey
= *hostkeyp
;
1299 /* {{{ libssh2_kex_agree_kex_hostkey
1300 * Agree on a Key Exchange method and a hostkey encoding type
1303 libssh2_kex_agree_kex_hostkey(LIBSSH2_SESSION
* session
, unsigned char *kex
,
1304 unsigned long kex_len
, unsigned char *hostkey
,
1305 unsigned long hostkey_len
)
1307 const LIBSSH2_KEX_METHOD
**kexp
= libssh2_kex_methods
;
1310 if (session
->kex_prefs
) {
1311 s
= (unsigned char *) session
->kex_prefs
;
1314 unsigned char *q
, *p
= (unsigned char *) strchr((char *) s
, ',');
1315 int method_len
= (p
? (p
- s
) : strlen((char *) s
));
1316 if ((q
= libssh2_kex_agree_instr(kex
, kex_len
, s
, method_len
))) {
1317 const LIBSSH2_KEX_METHOD
*method
= (const LIBSSH2_KEX_METHOD
*)
1318 libssh2_get_method_by_name((char *) s
, method_len
,
1319 (const LIBSSH2_COMMON_METHOD
**)
1323 /* Invalid method -- Should never be reached */
1327 /* We've agreed on a key exchange method,
1328 * Can we agree on a hostkey that works with this kex?
1330 if (libssh2_kex_agree_hostkey
1331 (session
, method
->flags
, hostkey
, hostkey_len
) == 0) {
1332 session
->kex
= method
;
1333 if (session
->burn_optimistic_kexinit
&& (kex
== q
)) {
1334 /* Server sent an optimistic packet,
1335 * and client agrees with preference
1336 * cancel burning the first KEX_INIT packet that comes in */
1337 session
->burn_optimistic_kexinit
= 0;
1343 s
= p
? p
+ 1 : NULL
;
1348 while (*kexp
&& (*kexp
)->name
) {
1349 s
= libssh2_kex_agree_instr(kex
, kex_len
,
1350 (unsigned char *) (*kexp
)->name
,
1351 strlen((*kexp
)->name
));
1353 /* We've agreed on a key exchange method,
1354 * Can we agree on a hostkey that works with this kex?
1356 if (libssh2_kex_agree_hostkey
1357 (session
, (*kexp
)->flags
, hostkey
, hostkey_len
) == 0) {
1358 session
->kex
= *kexp
;
1359 if (session
->burn_optimistic_kexinit
&& (kex
== s
)) {
1360 /* Server sent an optimistic packet,
1361 * and client agrees with preference
1362 * cancel burning the first KEX_INIT packet that comes in */
1363 session
->burn_optimistic_kexinit
= 0;
1375 /* {{{ libssh2_kex_agree_crypt
1376 * Agree on a cipher algo
1379 libssh2_kex_agree_crypt(LIBSSH2_SESSION
* session
,
1380 libssh2_endpoint_data
* endpoint
, unsigned char *crypt
,
1381 unsigned long crypt_len
)
1383 const LIBSSH2_CRYPT_METHOD
**cryptp
= libssh2_crypt_methods();
1388 if (endpoint
->crypt_prefs
) {
1389 s
= (unsigned char *) endpoint
->crypt_prefs
;
1392 unsigned char *p
= (unsigned char *) strchr((char *) s
, ',');
1393 int method_len
= (p
? (p
- s
) : strlen((char *) s
));
1395 if (libssh2_kex_agree_instr(crypt
, crypt_len
, s
, method_len
)) {
1396 const LIBSSH2_CRYPT_METHOD
*method
=
1397 (const LIBSSH2_CRYPT_METHOD
*)
1398 libssh2_get_method_by_name((char *) s
, method_len
,
1399 (const LIBSSH2_COMMON_METHOD
**)
1403 /* Invalid method -- Should never be reached */
1407 endpoint
->crypt
= method
;
1411 s
= p
? p
+ 1 : NULL
;
1416 while (*cryptp
&& (*cryptp
)->name
) {
1417 s
= libssh2_kex_agree_instr(crypt
, crypt_len
,
1418 (unsigned char *) (*cryptp
)->name
,
1419 strlen((*cryptp
)->name
));
1421 endpoint
->crypt
= *cryptp
;
1432 /* {{{ libssh2_kex_agree_mac
1433 * Agree on a message authentication hash
1436 libssh2_kex_agree_mac(LIBSSH2_SESSION
* session
,
1437 libssh2_endpoint_data
* endpoint
, unsigned char *mac
,
1438 unsigned long mac_len
)
1440 const LIBSSH2_MAC_METHOD
**macp
= libssh2_mac_methods();
1444 if (endpoint
->mac_prefs
) {
1445 s
= (unsigned char *) endpoint
->mac_prefs
;
1448 unsigned char *p
= (unsigned char *) strchr((char *) s
, ',');
1449 int method_len
= (p
? (p
- s
) : strlen((char *) s
));
1451 if (libssh2_kex_agree_instr(mac
, mac_len
, s
, method_len
)) {
1452 const LIBSSH2_MAC_METHOD
*method
= (const LIBSSH2_MAC_METHOD
*)
1453 libssh2_get_method_by_name((char *) s
, method_len
,
1454 (const LIBSSH2_COMMON_METHOD
**)
1458 /* Invalid method -- Should never be reached */
1462 endpoint
->mac
= method
;
1466 s
= p
? p
+ 1 : NULL
;
1471 while (*macp
&& (*macp
)->name
) {
1472 s
= libssh2_kex_agree_instr(mac
, mac_len
,
1473 (unsigned char *) (*macp
)->name
,
1474 strlen((*macp
)->name
));
1476 endpoint
->mac
= *macp
;
1487 /* {{{ libssh2_kex_agree_comp
1488 * Agree on a compression scheme
1491 libssh2_kex_agree_comp(LIBSSH2_SESSION
* session
,
1492 libssh2_endpoint_data
* endpoint
, unsigned char *comp
,
1493 unsigned long comp_len
)
1495 const LIBSSH2_COMP_METHOD
**compp
= libssh2_comp_methods();
1499 if (endpoint
->comp_prefs
) {
1500 s
= (unsigned char *) endpoint
->comp_prefs
;
1503 unsigned char *p
= (unsigned char *) strchr((char *) s
, ',');
1504 int method_len
= (p
? (p
- s
) : strlen((char *) s
));
1506 if (libssh2_kex_agree_instr(comp
, comp_len
, s
, method_len
)) {
1507 const LIBSSH2_COMP_METHOD
*method
=
1508 (const LIBSSH2_COMP_METHOD
*)
1509 libssh2_get_method_by_name((char *) s
, method_len
,
1510 (const LIBSSH2_COMMON_METHOD
**)
1514 /* Invalid method -- Should never be reached */
1518 endpoint
->comp
= method
;
1522 s
= p
? p
+ 1 : NULL
;
1527 while (*compp
&& (*compp
)->name
) {
1528 s
= libssh2_kex_agree_instr(comp
, comp_len
,
1529 (unsigned char *) (*compp
)->name
,
1530 strlen((*compp
)->name
));
1532 endpoint
->comp
= *compp
;
1543 /* TODO: When in server mode we need to turn this logic on its head
1544 * The Client gets to make the final call on "agreed methods"
1547 /* {{{ libssh2_kex_agree_methods
1548 * Decide which specific method to use of the methods offered by each party
1551 libssh2_kex_agree_methods(LIBSSH2_SESSION
* session
, unsigned char *data
,
1554 unsigned char *kex
, *hostkey
, *crypt_cs
, *crypt_sc
, *comp_cs
, *comp_sc
,
1555 *mac_cs
, *mac_sc
, *lang_cs
, *lang_sc
;
1556 size_t kex_len
, hostkey_len
, crypt_cs_len
, crypt_sc_len
, comp_cs_len
;
1557 size_t comp_sc_len
, mac_cs_len
, mac_sc_len
, lang_cs_len
, lang_sc_len
;
1558 unsigned char *s
= data
;
1560 /* Skip packet_type, we know it already */
1563 /* Skip cookie, don't worry, it's preserved in the kexinit field */
1566 /* Locate each string */
1567 kex_len
= libssh2_ntohu32(s
);
1570 hostkey_len
= libssh2_ntohu32(s
);
1572 s
+= 4 + hostkey_len
;
1573 crypt_cs_len
= libssh2_ntohu32(s
);
1575 s
+= 4 + crypt_cs_len
;
1576 crypt_sc_len
= libssh2_ntohu32(s
);
1578 s
+= 4 + crypt_sc_len
;
1579 mac_cs_len
= libssh2_ntohu32(s
);
1581 s
+= 4 + mac_cs_len
;
1582 mac_sc_len
= libssh2_ntohu32(s
);
1584 s
+= 4 + mac_sc_len
;
1585 comp_cs_len
= libssh2_ntohu32(s
);
1587 s
+= 4 + comp_cs_len
;
1588 comp_sc_len
= libssh2_ntohu32(s
);
1590 s
+= 4 + comp_sc_len
;
1591 lang_cs_len
= libssh2_ntohu32(s
);
1593 s
+= 4 + lang_cs_len
;
1594 lang_sc_len
= libssh2_ntohu32(s
);
1596 s
+= 4 + lang_sc_len
;
1598 /* If the server sent an optimistic packet, assume that it guessed wrong.
1599 * If the guess is determined to be right (by libssh2_kex_agree_kex_hostkey)
1600 * This flag will be reset to zero so that it's not ignored */
1601 session
->burn_optimistic_kexinit
= *(s
++);
1602 /* Next uint32 in packet is all zeros (reserved) */
1604 if (data_len
< (unsigned) (s
- data
))
1605 return -1; /* short packet */
1607 if (libssh2_kex_agree_kex_hostkey
1608 (session
, kex
, kex_len
, hostkey
, hostkey_len
)) {
1612 if (libssh2_kex_agree_crypt
1613 (session
, &session
->local
, crypt_cs
, crypt_cs_len
)
1614 || libssh2_kex_agree_crypt(session
, &session
->remote
, crypt_sc
,
1619 if (libssh2_kex_agree_mac(session
, &session
->local
, mac_cs
, mac_cs_len
) ||
1620 libssh2_kex_agree_mac(session
, &session
->remote
, mac_sc
, mac_sc_len
)) {
1624 if (libssh2_kex_agree_comp(session
, &session
->local
, comp_cs
, comp_cs_len
)
1625 || libssh2_kex_agree_comp(session
, &session
->remote
, comp_sc
,
1630 if (libssh2_kex_agree_lang(session
, &session
->local
, lang_cs
, lang_cs_len
)
1631 || libssh2_kex_agree_lang(session
, &session
->remote
, lang_sc
,
1636 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on KEX method: %s",
1637 session
->kex
->name
);
1638 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on HOSTKEY method: %s",
1639 session
->hostkey
->name
);
1640 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on CRYPT_CS method: %s",
1641 session
->local
.crypt
->name
);
1642 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on CRYPT_SC method: %s",
1643 session
->remote
.crypt
->name
);
1644 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on MAC_CS method: %s",
1645 session
->local
.mac
->name
);
1646 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on MAC_SC method: %s",
1647 session
->remote
.mac
->name
);
1648 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on COMP_CS method: %s",
1649 session
->local
.comp
->name
);
1650 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on COMP_SC method: %s",
1651 session
->remote
.comp
->name
);
1652 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on LANG_CS method:"); /* None yet */
1653 _libssh2_debug(session
, LIBSSH2_DBG_KEX
, "Agreed on LANG_SC method:"); /* None yet */
1655 /* Initialize compression layer */
1656 if (session
->local
.comp
&& session
->local
.comp
->init
&&
1657 session
->local
.comp
->init(session
, 1, &session
->local
.comp_abstract
)) {
1661 if (session
->remote
.comp
&& session
->remote
.comp
->init
&&
1662 session
->remote
.comp
->init(session
, 0,
1663 &session
->remote
.comp_abstract
)) {
1672 /* {{{ libssh2_kex_exchange
1674 * Returns 0 on success, non-zero on failure
1677 libssh2_kex_exchange(LIBSSH2_SESSION
* session
, int reexchange
, /* session->flags |= SERVER */
1678 key_exchange_state_t
* key_state
)
1683 if (key_state
->state
== libssh2_NB_state_idle
) {
1684 /* Prevent loop in packet_add() */
1685 session
->state
|= LIBSSH2_STATE_EXCHANGING_KEYS
;
1688 session
->kex
= NULL
;
1690 if (session
->hostkey
&& session
->hostkey
->dtor
) {
1691 session
->hostkey
->dtor(session
,
1692 &session
->server_hostkey_abstract
);
1694 session
->hostkey
= NULL
;
1697 key_state
->state
= libssh2_NB_state_created
;
1700 if (!session
->kex
|| !session
->hostkey
) {
1701 if (key_state
->state
== libssh2_NB_state_created
) {
1702 /* Preserve in case of failure */
1703 key_state
->oldlocal
= session
->local
.kexinit
;
1704 key_state
->oldlocal_len
= session
->local
.kexinit_len
;
1706 session
->local
.kexinit
= NULL
;
1708 key_state
->state
= libssh2_NB_state_sent
;
1711 if (key_state
->state
== libssh2_NB_state_sent
) {
1712 retcode
= libssh2_kexinit(session
);
1713 if (retcode
== PACKET_EAGAIN
) {
1714 return PACKET_EAGAIN
;
1715 } else if (retcode
) {
1716 session
->local
.kexinit
= key_state
->oldlocal
;
1717 session
->local
.kexinit_len
= key_state
->oldlocal_len
;
1718 key_state
->state
= libssh2_NB_state_idle
;
1722 key_state
->state
= libssh2_NB_state_sent1
;
1725 if (key_state
->state
== libssh2_NB_state_sent1
) {
1727 libssh2_packet_require_ex(session
, SSH_MSG_KEXINIT
,
1729 &key_state
->data_len
, 0, NULL
, 0,
1730 &key_state
->req_state
);
1731 if (retcode
== PACKET_EAGAIN
) {
1732 return PACKET_EAGAIN
;
1733 } else if (retcode
) {
1734 if (session
->local
.kexinit
) {
1735 LIBSSH2_FREE(session
, session
->local
.kexinit
);
1737 session
->local
.kexinit
= key_state
->oldlocal
;
1738 session
->local
.kexinit_len
= key_state
->oldlocal_len
;
1739 key_state
->state
= libssh2_NB_state_idle
;
1743 if (session
->remote
.kexinit
) {
1744 LIBSSH2_FREE(session
, session
->remote
.kexinit
);
1746 session
->remote
.kexinit
= key_state
->data
;
1747 session
->remote
.kexinit_len
= key_state
->data_len
;
1749 if (libssh2_kex_agree_methods
1750 (session
, key_state
->data
, key_state
->data_len
)) {
1754 key_state
->state
= libssh2_NB_state_sent2
;
1757 key_state
->state
= libssh2_NB_state_sent2
;
1761 if (key_state
->state
== libssh2_NB_state_sent2
) {
1763 session
->kex
->exchange_keys(session
,
1764 &key_state
->key_state_low
);
1765 if (retcode
== PACKET_EAGAIN
) {
1766 return PACKET_EAGAIN
;
1767 } else if (retcode
) {
1768 libssh2_error(session
, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE
,
1769 "Unrecoverable error exchanging keys", 0);
1775 /* Done with kexinit buffers */
1776 if (session
->local
.kexinit
) {
1777 LIBSSH2_FREE(session
, session
->local
.kexinit
);
1778 session
->local
.kexinit
= NULL
;
1780 if (session
->remote
.kexinit
) {
1781 LIBSSH2_FREE(session
, session
->remote
.kexinit
);
1782 session
->remote
.kexinit
= NULL
;
1785 session
->state
&= ~LIBSSH2_STATE_EXCHANGING_KEYS
;
1787 key_state
->state
= libssh2_NB_state_idle
;
1794 /* {{{ libssh2_session_method_pref
1795 * Set preferred method
1798 libssh2_session_method_pref(LIBSSH2_SESSION
* session
, int method_type
,
1801 char **prefvar
, *s
, *newprefs
;
1802 int prefs_len
= strlen(prefs
);
1803 const LIBSSH2_COMMON_METHOD
**mlist
;
1805 switch (method_type
) {
1806 case LIBSSH2_METHOD_KEX
:
1807 prefvar
= &session
->kex_prefs
;
1808 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_kex_methods
;
1811 case LIBSSH2_METHOD_HOSTKEY
:
1812 prefvar
= &session
->hostkey_prefs
;
1813 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_hostkey_methods();
1816 case LIBSSH2_METHOD_CRYPT_CS
:
1817 prefvar
= &session
->local
.crypt_prefs
;
1818 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_crypt_methods();
1821 case LIBSSH2_METHOD_CRYPT_SC
:
1822 prefvar
= &session
->remote
.crypt_prefs
;
1823 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_crypt_methods();
1826 case LIBSSH2_METHOD_MAC_CS
:
1827 prefvar
= &session
->local
.mac_prefs
;
1828 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_mac_methods();
1831 case LIBSSH2_METHOD_MAC_SC
:
1832 prefvar
= &session
->remote
.mac_prefs
;
1833 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_mac_methods();
1836 case LIBSSH2_METHOD_COMP_CS
:
1837 prefvar
= &session
->local
.comp_prefs
;
1838 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_comp_methods();
1841 case LIBSSH2_METHOD_COMP_SC
:
1842 prefvar
= &session
->remote
.comp_prefs
;
1843 mlist
= (const LIBSSH2_COMMON_METHOD
**) libssh2_comp_methods();
1846 case LIBSSH2_METHOD_LANG_CS
:
1847 prefvar
= &session
->local
.lang_prefs
;
1851 case LIBSSH2_METHOD_LANG_SC
:
1852 prefvar
= &session
->remote
.lang_prefs
;
1857 libssh2_error(session
, LIBSSH2_ERROR_INVAL
,
1858 "Invalid parameter specified for method_type", 0);
1862 s
= newprefs
= LIBSSH2_ALLOC(session
, prefs_len
+ 1);
1864 libssh2_error(session
, LIBSSH2_ERROR_ALLOC
,
1865 "Error allocated space for method preferences", 0);
1868 memcpy(s
, prefs
, prefs_len
+ 1);
1871 char *p
= strchr(s
, ',');
1872 int method_len
= p
? (p
- s
) : (int) strlen(s
);
1874 if (!libssh2_get_method_by_name(s
, method_len
, mlist
)) {
1875 /* Strip out unsupported method */
1877 memcpy(s
, p
+ 1, strlen(s
) - method_len
);
1887 s
= p
? (p
+ 1) : NULL
;
1890 if (strlen(newprefs
) == 0) {
1891 libssh2_error(session
, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED
,
1892 "The requested method(s) are not currently supported",
1894 LIBSSH2_FREE(session
, newprefs
);
1899 LIBSSH2_FREE(session
, *prefvar
);
1901 *prefvar
= newprefs
;