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
#include "transport.h"
44
/* TODO: Switch this to an inline and handle alloc() failures */
45
/* Helper macro called from kex_method_diffie_hellman_group1_sha1_key_exchange */
46
#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \
48
libssh2_sha1_ctx hash; \
49
unsigned long len = 0; \
51
value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
54
while (len < (unsigned long)reqlen) { \
55
libssh2_sha1_init(&hash); \
56
libssh2_sha1_update(hash, exchange_state->k_value, \
57
exchange_state->k_value_len); \
58
libssh2_sha1_update(hash, exchange_state->h_sig_comp, \
61
libssh2_sha1_update(hash, value, len); \
63
libssh2_sha1_update(hash, (version), 1); \
64
libssh2_sha1_update(hash, session->session_id, \
65
session->session_id_len); \
67
libssh2_sha1_final(hash, (value) + len); \
68
len += SHA_DIGEST_LENGTH; \
75
* Diffie Hellman Key Exchange, Group Agnostic
77
static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
81
unsigned char packet_type_init,
82
unsigned char packet_type_reply,
83
unsigned char *midhash,
84
unsigned long midhash_len,
85
kmdhgGPsha1kex_state_t *exchange_state)
90
if (exchange_state->state == libssh2_NB_state_idle) {
91
/* Setup initial values */
92
exchange_state->e_packet = NULL;
93
exchange_state->s_packet = NULL;
94
exchange_state->k_value = NULL;
95
exchange_state->ctx = _libssh2_bn_ctx_new();
96
exchange_state->x = _libssh2_bn_init(); /* Random from client */
97
exchange_state->e = _libssh2_bn_init(); /* g^x mod p */
98
exchange_state->f = _libssh2_bn_init(); /* g^(Random from server) mod p */
99
exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */
101
/* Zero the whole thing out */
102
memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t));
104
/* Generate x and e */
105
_libssh2_bn_rand(exchange_state->x, group_order, 0, -1);
106
_libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p,
107
exchange_state->ctx);
110
/* packet_type(1) + String Length(4) + leading 0(1) */
111
exchange_state->e_packet_len =
112
_libssh2_bn_bytes(exchange_state->e) + 6;
113
if (_libssh2_bn_bits(exchange_state->e) % 8) {
114
/* Leading 00 not needed */
115
exchange_state->e_packet_len--;
118
exchange_state->e_packet =
119
LIBSSH2_ALLOC(session, exchange_state->e_packet_len);
120
if (!exchange_state->e_packet) {
121
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
122
"Out of memory error");
125
exchange_state->e_packet[0] = packet_type_init;
126
_libssh2_htonu32(exchange_state->e_packet + 1,
127
exchange_state->e_packet_len - 5);
128
if (_libssh2_bn_bits(exchange_state->e) % 8) {
129
_libssh2_bn_to_bin(exchange_state->e,
130
exchange_state->e_packet + 5);
132
exchange_state->e_packet[5] = 0;
133
_libssh2_bn_to_bin(exchange_state->e,
134
exchange_state->e_packet + 6);
137
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d",
138
(int) packet_type_init);
139
exchange_state->state = libssh2_NB_state_created;
142
if (exchange_state->state == libssh2_NB_state_created) {
143
rc = _libssh2_transport_write(session, exchange_state->e_packet,
144
exchange_state->e_packet_len);
145
if (rc == LIBSSH2_ERROR_EAGAIN) {
148
ret = _libssh2_error(session, rc,
149
"Unable to send KEX init message");
152
exchange_state->state = libssh2_NB_state_sent;
155
if (exchange_state->state == libssh2_NB_state_sent) {
156
if (session->burn_optimistic_kexinit) {
157
/* The first KEX packet to come along will be the guess initially
158
* sent by the server. That guess turned out to be wrong so we
159
* need to silently ignore it */
162
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
163
"Waiting for badly guessed KEX packet (to be ignored)");
165
_libssh2_packet_burn(session, &exchange_state->burn_state);
166
if (burn_type == LIBSSH2_ERROR_EAGAIN) {
168
} else if (burn_type <= 0) {
169
/* Failed to receive a packet */
173
session->burn_optimistic_kexinit = 0;
175
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
176
"Burnt packet of type: %02x",
177
(unsigned int) burn_type);
180
exchange_state->state = libssh2_NB_state_sent1;
183
if (exchange_state->state == libssh2_NB_state_sent1) {
184
/* Wait for KEX reply */
185
rc = _libssh2_packet_require(session, packet_type_reply,
186
&exchange_state->s_packet,
187
&exchange_state->s_packet_len, 0, NULL,
188
0, &exchange_state->req_state);
189
if (rc == LIBSSH2_ERROR_EAGAIN) {
193
ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
194
"Timed out waiting for KEX reply");
198
/* Parse KEXDH_REPLY */
199
exchange_state->s = exchange_state->s_packet + 1;
201
session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s);
202
exchange_state->s += 4;
203
session->server_hostkey =
204
LIBSSH2_ALLOC(session, session->server_hostkey_len);
205
if (!session->server_hostkey) {
206
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
207
"Unable to allocate memory for a copy "
211
memcpy(session->server_hostkey, exchange_state->s,
212
session->server_hostkey_len);
213
exchange_state->s += session->server_hostkey_len;
217
libssh2_md5_ctx fingerprint_ctx;
219
libssh2_md5_init(&fingerprint_ctx);
220
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
221
session->server_hostkey_len);
222
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
226
char fingerprint[50], *fprint = fingerprint;
228
for(i = 0; i < 16; i++, fprint += 3) {
229
snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
232
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
233
"Server's MD5 Fingerprint: %s", fingerprint);
235
#endif /* LIBSSH2DEBUG */
236
#endif /* ! LIBSSH2_MD5 */
239
libssh2_sha1_ctx fingerprint_ctx;
241
libssh2_sha1_init(&fingerprint_ctx);
242
libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
243
session->server_hostkey_len);
244
libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1);
248
char fingerprint[64], *fprint = fingerprint;
251
for(i = 0; i < 20; i++, fprint += 3) {
252
snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
255
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
256
"Server's SHA1 Fingerprint: %s", fingerprint);
258
#endif /* LIBSSH2DEBUG */
260
if (session->hostkey->init(session, session->server_hostkey,
261
session->server_hostkey_len,
262
&session->server_hostkey_abstract)) {
263
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
264
"Unable to initialize hostkey importer");
268
exchange_state->f_value_len = _libssh2_ntohu32(exchange_state->s);
269
exchange_state->s += 4;
270
exchange_state->f_value = exchange_state->s;
271
exchange_state->s += exchange_state->f_value_len;
272
_libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len,
273
exchange_state->f_value);
275
exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s);
276
exchange_state->s += 4;
277
exchange_state->h_sig = exchange_state->s;
279
/* Compute the shared secret */
280
_libssh2_bn_mod_exp(exchange_state->k, exchange_state->f,
281
exchange_state->x, p, exchange_state->ctx);
282
exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5;
283
if (_libssh2_bn_bits(exchange_state->k) % 8) {
284
/* don't need leading 00 */
285
exchange_state->k_value_len--;
287
exchange_state->k_value =
288
LIBSSH2_ALLOC(session, exchange_state->k_value_len);
289
if (!exchange_state->k_value) {
290
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
291
"Unable to allocate buffer for K");
294
_libssh2_htonu32(exchange_state->k_value,
295
exchange_state->k_value_len - 4);
296
if (_libssh2_bn_bits(exchange_state->k) % 8) {
297
_libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4);
299
exchange_state->k_value[4] = 0;
300
_libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5);
303
libssh2_sha1_init(&exchange_state->exchange_hash);
304
if (session->local.banner) {
305
_libssh2_htonu32(exchange_state->h_sig_comp,
306
strlen((char *) session->local.banner) - 2);
307
libssh2_sha1_update(exchange_state->exchange_hash,
308
exchange_state->h_sig_comp, 4);
309
libssh2_sha1_update(exchange_state->exchange_hash,
310
(char *) session->local.banner,
311
strlen((char *) session->local.banner) - 2);
313
_libssh2_htonu32(exchange_state->h_sig_comp,
314
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
315
libssh2_sha1_update(exchange_state->exchange_hash,
316
exchange_state->h_sig_comp, 4);
317
libssh2_sha1_update(exchange_state->exchange_hash,
318
LIBSSH2_SSH_DEFAULT_BANNER,
319
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
322
_libssh2_htonu32(exchange_state->h_sig_comp,
323
strlen((char *) session->remote.banner));
324
libssh2_sha1_update(exchange_state->exchange_hash,
325
exchange_state->h_sig_comp, 4);
326
libssh2_sha1_update(exchange_state->exchange_hash,
327
session->remote.banner,
328
strlen((char *) session->remote.banner));
330
_libssh2_htonu32(exchange_state->h_sig_comp,
331
session->local.kexinit_len);
332
libssh2_sha1_update(exchange_state->exchange_hash,
333
exchange_state->h_sig_comp, 4);
334
libssh2_sha1_update(exchange_state->exchange_hash,
335
session->local.kexinit,
336
session->local.kexinit_len);
338
_libssh2_htonu32(exchange_state->h_sig_comp,
339
session->remote.kexinit_len);
340
libssh2_sha1_update(exchange_state->exchange_hash,
341
exchange_state->h_sig_comp, 4);
342
libssh2_sha1_update(exchange_state->exchange_hash,
343
session->remote.kexinit,
344
session->remote.kexinit_len);
346
_libssh2_htonu32(exchange_state->h_sig_comp,
347
session->server_hostkey_len);
348
libssh2_sha1_update(exchange_state->exchange_hash,
349
exchange_state->h_sig_comp, 4);
350
libssh2_sha1_update(exchange_state->exchange_hash,
351
session->server_hostkey,
352
session->server_hostkey_len);
354
if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) {
355
/* diffie-hellman-group-exchange hashes additional fields */
356
#ifdef LIBSSH2_DH_GEX_NEW
357
_libssh2_htonu32(exchange_state->h_sig_comp,
358
LIBSSH2_DH_GEX_MINGROUP);
359
_libssh2_htonu32(exchange_state->h_sig_comp + 4,
360
LIBSSH2_DH_GEX_OPTGROUP);
361
_libssh2_htonu32(exchange_state->h_sig_comp + 8,
362
LIBSSH2_DH_GEX_MAXGROUP);
363
libssh2_sha1_update(exchange_state->exchange_hash,
364
exchange_state->h_sig_comp, 12);
366
_libssh2_htonu32(exchange_state->h_sig_comp,
367
LIBSSH2_DH_GEX_OPTGROUP);
368
libssh2_sha1_update(exchange_state->exchange_hash,
369
exchange_state->h_sig_comp, 4);
374
libssh2_sha1_update(exchange_state->exchange_hash, midhash,
378
libssh2_sha1_update(exchange_state->exchange_hash,
379
exchange_state->e_packet + 1,
380
exchange_state->e_packet_len - 1);
382
_libssh2_htonu32(exchange_state->h_sig_comp,
383
exchange_state->f_value_len);
384
libssh2_sha1_update(exchange_state->exchange_hash,
385
exchange_state->h_sig_comp, 4);
386
libssh2_sha1_update(exchange_state->exchange_hash,
387
exchange_state->f_value,
388
exchange_state->f_value_len);
390
libssh2_sha1_update(exchange_state->exchange_hash,
391
exchange_state->k_value,
392
exchange_state->k_value_len);
394
libssh2_sha1_final(exchange_state->exchange_hash,
395
exchange_state->h_sig_comp);
397
if (session->hostkey->
398
sig_verify(session, exchange_state->h_sig,
399
exchange_state->h_sig_len, exchange_state->h_sig_comp,
400
20, &session->server_hostkey_abstract)) {
401
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
402
"Unable to verify hostkey signature");
406
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message");
407
exchange_state->c = SSH_MSG_NEWKEYS;
409
exchange_state->state = libssh2_NB_state_sent2;
412
if (exchange_state->state == libssh2_NB_state_sent2) {
413
rc = _libssh2_transport_write(session, &exchange_state->c, 1);
414
if (rc == LIBSSH2_ERROR_EAGAIN) {
417
ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message");
421
exchange_state->state = libssh2_NB_state_sent3;
424
if (exchange_state->state == libssh2_NB_state_sent3) {
425
rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS,
426
&exchange_state->tmp,
427
&exchange_state->tmp_len, 0, NULL, 0,
428
&exchange_state->req_state);
429
if (rc == LIBSSH2_ERROR_EAGAIN) {
432
ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
435
/* The first key exchange has been performed,
436
switch to active crypt/comp/mac mode */
437
session->state |= LIBSSH2_STATE_NEWKEYS;
438
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message");
440
/* This will actually end up being just packet_type(1)
441
for this packet type anyway */
442
LIBSSH2_FREE(session, exchange_state->tmp);
444
if (!session->session_id) {
445
session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
446
if (!session->session_id) {
447
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
448
"Unable to allocate buffer for SHA digest");
451
memcpy(session->session_id, exchange_state->h_sig_comp,
453
session->session_id_len = SHA_DIGEST_LENGTH;
454
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated");
457
/* Cleanup any existing cipher */
458
if (session->local.crypt->dtor) {
459
session->local.crypt->dtor(session,
460
&session->local.crypt_abstract);
463
/* Calculate IV/Secret/Key for each direction */
464
if (session->local.crypt->init) {
465
unsigned char *iv = NULL, *secret = NULL;
466
int free_iv = 0, free_secret = 0;
468
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
469
session->local.crypt->
475
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
476
session->local.crypt->
479
LIBSSH2_FREE(session, iv);
480
ret = LIBSSH2_ERROR_KEX_FAILURE;
483
if (session->local.crypt->
484
init(session, session->local.crypt, iv, &free_iv, secret,
485
&free_secret, 1, &session->local.crypt_abstract)) {
486
LIBSSH2_FREE(session, iv);
487
LIBSSH2_FREE(session, secret);
488
ret = LIBSSH2_ERROR_KEX_FAILURE;
493
memset(iv, 0, session->local.crypt->iv_len);
494
LIBSSH2_FREE(session, iv);
498
memset(secret, 0, session->local.crypt->secret_len);
499
LIBSSH2_FREE(session, secret);
502
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
503
"Client to Server IV and Key calculated");
505
if (session->remote.crypt->dtor) {
506
/* Cleanup any existing cipher */
507
session->remote.crypt->dtor(session,
508
&session->remote.crypt_abstract);
511
if (session->remote.crypt->init) {
512
unsigned char *iv = NULL, *secret = NULL;
513
int free_iv = 0, free_secret = 0;
515
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
516
session->remote.crypt->
519
ret = LIBSSH2_ERROR_KEX_FAILURE;
522
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
523
session->remote.crypt->
526
LIBSSH2_FREE(session, iv);
527
ret = LIBSSH2_ERROR_KEX_FAILURE;
530
if (session->remote.crypt->
531
init(session, session->remote.crypt, iv, &free_iv, secret,
532
&free_secret, 0, &session->remote.crypt_abstract)) {
533
LIBSSH2_FREE(session, iv);
534
LIBSSH2_FREE(session, secret);
535
ret = LIBSSH2_ERROR_KEX_FAILURE;
540
memset(iv, 0, session->remote.crypt->iv_len);
541
LIBSSH2_FREE(session, iv);
545
memset(secret, 0, session->remote.crypt->secret_len);
546
LIBSSH2_FREE(session, secret);
549
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
550
"Server to Client IV and Key calculated");
552
if (session->local.mac->dtor) {
553
session->local.mac->dtor(session, &session->local.mac_abstract);
556
if (session->local.mac->init) {
557
unsigned char *key = NULL;
560
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
564
ret = LIBSSH2_ERROR_KEX_FAILURE;
567
session->local.mac->init(session, key, &free_key,
568
&session->local.mac_abstract);
571
memset(key, 0, session->local.mac->key_len);
572
LIBSSH2_FREE(session, key);
575
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
576
"Client to Server HMAC Key calculated");
578
if (session->remote.mac->dtor) {
579
session->remote.mac->dtor(session, &session->remote.mac_abstract);
582
if (session->remote.mac->init) {
583
unsigned char *key = NULL;
586
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
587
session->remote.mac->
590
ret = LIBSSH2_ERROR_KEX_FAILURE;
593
session->remote.mac->init(session, key, &free_key,
594
&session->remote.mac_abstract);
597
memset(key, 0, session->remote.mac->key_len);
598
LIBSSH2_FREE(session, key);
601
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
602
"Server to Client HMAC Key calculated");
604
/* Initialize compression for each direction */
606
/* Cleanup any existing compression */
607
if (session->local.comp && session->local.comp->dtor) {
608
session->local.comp->dtor(session, 1,
609
&session->local.comp_abstract);
612
if (session->local.comp && session->local.comp->init) {
613
if (session->local.comp->init(session, 1,
614
&session->local.comp_abstract)) {
615
ret = LIBSSH2_ERROR_KEX_FAILURE;
619
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
620
"Client to Server compression initialized");
622
if (session->remote.comp && session->remote.comp->dtor) {
623
session->remote.comp->dtor(session, 0,
624
&session->remote.comp_abstract);
627
if (session->remote.comp && session->remote.comp->init) {
628
if (session->remote.comp->init(session, 0,
629
&session->remote.comp_abstract)) {
630
ret = LIBSSH2_ERROR_KEX_FAILURE;
634
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
635
"Server to Client compression initialized");
640
_libssh2_bn_free(exchange_state->x);
641
exchange_state->x = NULL;
642
_libssh2_bn_free(exchange_state->e);
643
exchange_state->e = NULL;
644
_libssh2_bn_free(exchange_state->f);
645
exchange_state->f = NULL;
646
_libssh2_bn_free(exchange_state->k);
647
exchange_state->k = NULL;
648
_libssh2_bn_ctx_free(exchange_state->ctx);
649
exchange_state->ctx = NULL;
651
if (exchange_state->e_packet) {
652
LIBSSH2_FREE(session, exchange_state->e_packet);
653
exchange_state->e_packet = NULL;
656
if (exchange_state->s_packet) {
657
LIBSSH2_FREE(session, exchange_state->s_packet);
658
exchange_state->s_packet = NULL;
661
if (exchange_state->k_value) {
662
LIBSSH2_FREE(session, exchange_state->k_value);
663
exchange_state->k_value = NULL;
666
exchange_state->state = libssh2_NB_state_idle;
673
/* kex_method_diffie_hellman_group1_sha1_key_exchange
674
* Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1
677
kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
678
key_exchange_state_low_t
681
static const unsigned char p_value[128] = {
682
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
683
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
684
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
685
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
686
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
687
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
688
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
689
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
690
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
691
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
692
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
693
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
694
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
695
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
696
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
697
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
702
if (key_state->state == libssh2_NB_state_idle) {
704
key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */
705
key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
707
/* Initialize P and G */
708
_libssh2_bn_set_word(key_state->g, 2);
709
_libssh2_bn_from_bin(key_state->p, 128, p_value);
711
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
712
"Initiating Diffie-Hellman Group1 Key Exchange");
714
key_state->state = libssh2_NB_state_created;
716
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128,
717
SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
718
NULL, 0, &key_state->exchange_state);
719
if (ret == LIBSSH2_ERROR_EAGAIN) {
723
_libssh2_bn_free(key_state->p);
725
_libssh2_bn_free(key_state->g);
727
key_state->state = libssh2_NB_state_idle;
734
/* kex_method_diffie_hellman_group14_sha1_key_exchange
735
* Diffie-Hellman Group14 Key Exchange using SHA1
738
kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
739
key_exchange_state_low_t
742
static const unsigned char p_value[256] = {
743
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
744
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
745
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
746
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
747
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
748
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
749
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
750
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
751
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
752
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
753
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
754
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
755
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
756
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
757
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
758
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
759
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
760
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
761
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
762
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
763
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
764
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
765
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
766
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
767
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
768
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
769
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
770
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
771
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
772
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
773
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
774
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
778
if (key_state->state == libssh2_NB_state_idle) {
779
key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */
780
key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
783
/* Initialize P and G */
784
_libssh2_bn_set_word(key_state->g, 2);
785
_libssh2_bn_from_bin(key_state->p, 256, p_value);
787
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
788
"Initiating Diffie-Hellman Group14 Key Exchange");
790
key_state->state = libssh2_NB_state_created;
792
ret = diffie_hellman_sha1(session, key_state->g, key_state->p,
793
256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
794
NULL, 0, &key_state->exchange_state);
795
if (ret == LIBSSH2_ERROR_EAGAIN) {
799
key_state->state = libssh2_NB_state_idle;
800
_libssh2_bn_free(key_state->p);
802
_libssh2_bn_free(key_state->g);
810
/* kex_method_diffie_hellman_group_exchange_sha1_key_exchange
811
* Diffie-Hellman Group Exchange Key Exchange using SHA1
812
* Negotiates random(ish) group for secret derivation
815
kex_method_diffie_hellman_group_exchange_sha1_key_exchange
816
(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
818
unsigned long p_len, g_len;
822
if (key_state->state == libssh2_NB_state_idle) {
823
key_state->p = _libssh2_bn_init();
824
key_state->g = _libssh2_bn_init();
825
/* Ask for a P and G pair */
826
#ifdef LIBSSH2_DH_GEX_NEW
827
key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
828
_libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP);
829
_libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP);
830
_libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP);
831
key_state->request_len = 13;
832
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
833
"Initiating Diffie-Hellman Group-Exchange (New Method)");
835
key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
836
_libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP);
837
key_state->request_len = 5;
838
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
839
"Initiating Diffie-Hellman Group-Exchange (Old Method)");
842
key_state->state = libssh2_NB_state_created;
845
if (key_state->state == libssh2_NB_state_created) {
846
rc = _libssh2_transport_write(session, key_state->request,
847
key_state->request_len);
848
if (rc == LIBSSH2_ERROR_EAGAIN) {
851
ret = _libssh2_error(session, rc,
852
"Unable to send Group Exchange Request");
853
goto dh_gex_clean_exit;
856
key_state->state = libssh2_NB_state_sent;
859
if (key_state->state == libssh2_NB_state_sent) {
860
rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP,
861
&key_state->data, &key_state->data_len,
862
0, NULL, 0, &key_state->req_state);
863
if (rc == LIBSSH2_ERROR_EAGAIN) {
866
ret = _libssh2_error(session, rc,
867
"Timeout waiting for GEX_GROUP reply");
868
goto dh_gex_clean_exit;
871
key_state->state = libssh2_NB_state_sent1;
874
if (key_state->state == libssh2_NB_state_sent1) {
875
unsigned char *s = key_state->data + 1;
876
p_len = _libssh2_ntohu32(s);
878
_libssh2_bn_from_bin(key_state->p, p_len, s);
881
g_len = _libssh2_ntohu32(s);
883
_libssh2_bn_from_bin(key_state->g, g_len, s);
885
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len,
886
SSH_MSG_KEX_DH_GEX_INIT,
887
SSH_MSG_KEX_DH_GEX_REPLY,
889
key_state->data_len - 1,
890
&key_state->exchange_state);
891
if (ret == LIBSSH2_ERROR_EAGAIN) {
895
LIBSSH2_FREE(session, key_state->data);
899
key_state->state = libssh2_NB_state_idle;
900
_libssh2_bn_free(key_state->g);
902
_libssh2_bn_free(key_state->p);
910
#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001
911
#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002
913
static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = {
914
"diffie-hellman-group1-sha1",
915
kex_method_diffie_hellman_group1_sha1_key_exchange,
916
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
919
static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = {
920
"diffie-hellman-group14-sha1",
921
kex_method_diffie_hellman_group14_sha1_key_exchange,
922
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
925
static const LIBSSH2_KEX_METHOD
926
kex_method_diffie_helman_group_exchange_sha1 = {
927
"diffie-hellman-group-exchange-sha1",
928
kex_method_diffie_hellman_group_exchange_sha1_key_exchange,
929
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
932
static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
933
&kex_method_diffie_helman_group14_sha1,
934
&kex_method_diffie_helman_group_exchange_sha1,
935
&kex_method_diffie_helman_group1_sha1,
939
typedef struct _LIBSSH2_COMMON_METHOD
942
} LIBSSH2_COMMON_METHOD;
945
* Calculate the length of a particular method list's resulting string
946
* Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used)
947
* Another sign of bad coding practices gone mad. Pretend you don't see this.
950
kex_method_strlen(LIBSSH2_COMMON_METHOD ** method)
954
if (!method || !*method) {
958
while (*method && (*method)->name) {
959
len += strlen((*method)->name) + 1;
969
* Generate formatted preference list in buf
972
kex_method_list(unsigned char *buf, size_t list_strlen,
973
LIBSSH2_COMMON_METHOD ** method)
975
_libssh2_htonu32(buf, list_strlen);
978
if (!method || !*method) {
982
while (*method && (*method)->name) {
983
int mlen = strlen((*method)->name);
984
memcpy(buf, (*method)->name, mlen);
990
return list_strlen + 4;
995
#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \
996
((prefvar) ? strlen(prefvar) : \
997
kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
999
#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \
1001
_libssh2_htonu32((buf), (prefvarlen)); \
1003
memcpy((buf), (prefvar), (prefvarlen)); \
1004
buf += (prefvarlen); \
1006
buf += kex_method_list((buf), (prefvarlen), \
1007
(LIBSSH2_COMMON_METHOD**)(defaultvar)); \
1011
* Send SSH_MSG_KEXINIT packet
1013
static int kexinit(LIBSSH2_SESSION * session)
1015
/* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) +
1016
reserved(4) + length longs(40) */
1017
size_t data_len = 62;
1018
size_t kex_len, hostkey_len = 0;
1019
size_t crypt_cs_len, crypt_sc_len;
1020
size_t comp_cs_len, comp_sc_len;
1021
size_t mac_cs_len, mac_sc_len;
1022
size_t lang_cs_len, lang_sc_len;
1023
unsigned char *data, *s;
1026
if (session->kexinit_state == libssh2_NB_state_idle) {
1028
LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods);
1030
LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs,
1031
libssh2_hostkey_methods());
1033
LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs,
1034
libssh2_crypt_methods());
1036
LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs,
1037
libssh2_crypt_methods());
1039
LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs,
1040
_libssh2_mac_methods());
1042
LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs,
1043
_libssh2_mac_methods());
1045
LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs,
1046
_libssh2_comp_methods());
1048
LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs,
1049
_libssh2_comp_methods());
1051
LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL);
1053
LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL);
1055
data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len +
1056
comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len +
1057
lang_cs_len + lang_sc_len;
1059
s = data = LIBSSH2_ALLOC(session, data_len);
1061
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1062
"Unable to allocate memory");
1065
*(s++) = SSH_MSG_KEXINIT;
1067
_libssh2_random(s, 16);
1070
/* Ennumerating through these lists twice is probably (certainly?)
1071
inefficient from a CPU standpoint, but it saves multiple
1072
malloc/realloc calls */
1073
LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs,
1074
libssh2_kex_methods);
1075
LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs,
1076
libssh2_hostkey_methods());
1077
LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs,
1078
libssh2_crypt_methods());
1079
LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs,
1080
libssh2_crypt_methods());
1081
LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs,
1082
_libssh2_mac_methods());
1083
LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs,
1084
_libssh2_mac_methods());
1085
LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs,
1086
_libssh2_comp_methods());
1087
LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs,
1088
_libssh2_comp_methods());
1089
LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs,
1091
LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs,
1094
/* No optimistic KEX packet follows */
1095
/* Deal with optimistic packets
1096
* session->flags |= KEXINIT_OPTIMISTIC
1097
* session->flags |= KEXINIT_METHODSMATCH
1102
_libssh2_htonu32(s, 0);
1106
/* Funnily enough, they'll all "appear" to be '\0' terminated */
1107
unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */
1109
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p);
1111
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p);
1112
p += hostkey_len + 4;
1113
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p);
1114
p += crypt_cs_len + 4;
1115
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p);
1116
p += crypt_sc_len + 4;
1117
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p);
1118
p += mac_cs_len + 4;
1119
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p);
1120
p += mac_sc_len + 4;
1121
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p);
1122
p += comp_cs_len + 4;
1123
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p);
1124
p += comp_sc_len + 4;
1125
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p);
1126
p += lang_cs_len + 4;
1127
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p);
1128
p += lang_sc_len + 4;
1130
#endif /* LIBSSH2DEBUG */
1132
session->kexinit_state = libssh2_NB_state_created;
1134
data = session->kexinit_data;
1135
data_len = session->kexinit_data_len;
1136
/* zap the variables to ensure there is NOT a double free later */
1137
session->kexinit_data = NULL;
1138
session->kexinit_data_len = 0;
1141
rc = _libssh2_transport_write(session, data, data_len);
1142
if (rc == LIBSSH2_ERROR_EAGAIN) {
1143
session->kexinit_data = data;
1144
session->kexinit_data_len = data_len;
1148
LIBSSH2_FREE(session, data);
1149
session->kexinit_state = libssh2_NB_state_idle;
1150
return _libssh2_error(session, rc,
1151
"Unable to send KEXINIT packet to remote host");
1155
if (session->local.kexinit) {
1156
LIBSSH2_FREE(session, session->local.kexinit);
1159
session->local.kexinit = data;
1160
session->local.kexinit_len = data_len;
1162
session->kexinit_state = libssh2_NB_state_idle;
1168
* Kex specific variant of strstr()
1169
* Needle must be preceed by BOL or ',', and followed by ',' or EOL
1171
static unsigned char *
1172
kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
1173
const unsigned char *needle, unsigned long needle_len)
1177
/* Haystack too short to bother trying */
1178
if (haystack_len < needle_len) {
1182
/* Needle at start of haystack */
1183
if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) &&
1184
(needle_len == haystack_len || haystack[needle_len] == ',')) {
1189
/* Search until we run out of comas or we run out of haystack,
1190
whichever comes first */
1191
while ((s = (unsigned char *) strchr((char *) s, ','))
1192
&& ((haystack_len - (s - haystack)) > needle_len)) {
1194
/* Needle at X position */
1195
if ((strncmp((char *) s, (char *) needle, needle_len) == 0) &&
1196
(((s - haystack) + needle_len) == haystack_len
1197
|| s[needle_len] == ',')) {
1207
/* kex_get_method_by_name
1209
static const LIBSSH2_COMMON_METHOD *
1210
kex_get_method_by_name(const char *name, size_t name_len,
1211
const LIBSSH2_COMMON_METHOD ** methodlist)
1213
while (*methodlist) {
1214
if ((strlen((*methodlist)->name) == name_len) &&
1215
(strncmp((*methodlist)->name, name, name_len) == 0)) {
1225
/* kex_agree_hostkey
1226
* Agree on a Hostkey which works with this kex
1228
static int kex_agree_hostkey(LIBSSH2_SESSION * session,
1229
unsigned long kex_flags,
1230
unsigned char *hostkey, unsigned long hostkey_len)
1232
const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
1235
if (session->hostkey_prefs) {
1236
s = (unsigned char *) session->hostkey_prefs;
1239
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1240
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1241
if (kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
1242
const LIBSSH2_HOSTKEY_METHOD *method =
1243
(const LIBSSH2_HOSTKEY_METHOD *)
1244
kex_get_method_by_name((char *) s, method_len,
1245
(const LIBSSH2_COMMON_METHOD **)
1249
/* Invalid method -- Should never be reached */
1253
/* So far so good, but does it suit our purposes? (Encrypting
1255
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) ==
1256
0) || (method->encrypt)) {
1257
/* Either this hostkey can do encryption or this kex just
1258
doesn't require it */
1259
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY)
1260
== 0) || (method->sig_verify)) {
1261
/* Either this hostkey can do signing or this kex just
1262
doesn't require it */
1263
session->hostkey = method;
1269
s = p ? p + 1 : NULL;
1274
while (hostkeyp && (*hostkeyp)->name) {
1275
s = 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
1281
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) ||
1282
((*hostkeyp)->encrypt)) {
1283
/* Either this hostkey can do encryption or this kex just
1284
doesn't require it */
1285
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) ==
1286
0) || ((*hostkeyp)->sig_verify)) {
1287
/* Either this hostkey can do signing or this kex just
1288
doesn't require it */
1289
session->hostkey = *hostkeyp;
1302
/* kex_agree_kex_hostkey
1303
* Agree on a Key Exchange method and a hostkey encoding type
1305
static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
1306
unsigned long kex_len, unsigned char *hostkey,
1307
unsigned long hostkey_len)
1309
const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
1312
if (session->kex_prefs) {
1313
s = (unsigned char *) session->kex_prefs;
1316
unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
1317
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1318
if ((q = kex_agree_instr(kex, kex_len, s, method_len))) {
1319
const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
1320
kex_get_method_by_name((char *) s, method_len,
1321
(const LIBSSH2_COMMON_METHOD **)
1325
/* Invalid method -- Should never be reached */
1329
/* We've agreed on a key exchange method,
1330
* Can we agree on a hostkey that works with this kex?
1332
if (kex_agree_hostkey(session, method->flags, hostkey,
1333
hostkey_len) == 0) {
1334
session->kex = method;
1335
if (session->burn_optimistic_kexinit && (kex == q)) {
1336
/* Server sent an optimistic packet,
1337
* and client agrees with preference
1338
* cancel burning the first KEX_INIT packet that comes in */
1339
session->burn_optimistic_kexinit = 0;
1345
s = p ? p + 1 : NULL;
1350
while (*kexp && (*kexp)->name) {
1351
s = kex_agree_instr(kex, kex_len,
1352
(unsigned char *) (*kexp)->name,
1353
strlen((*kexp)->name));
1355
/* We've agreed on a key exchange method,
1356
* Can we agree on a hostkey that works with this kex?
1358
if (kex_agree_hostkey(session, (*kexp)->flags, hostkey,
1359
hostkey_len) == 0) {
1360
session->kex = *kexp;
1361
if (session->burn_optimistic_kexinit && (kex == s)) {
1362
/* Server sent an optimistic packet,
1363
* and client agrees with preference
1364
* cancel burning the first KEX_INIT packet that comes in */
1365
session->burn_optimistic_kexinit = 0;
1378
* Agree on a cipher algo
1380
static int kex_agree_crypt(LIBSSH2_SESSION * session,
1381
libssh2_endpoint_data *endpoint,
1382
unsigned char *crypt,
1383
unsigned long crypt_len)
1385
const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
1390
if (endpoint->crypt_prefs) {
1391
s = (unsigned char *) endpoint->crypt_prefs;
1394
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1395
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1397
if (kex_agree_instr(crypt, crypt_len, s, method_len)) {
1398
const LIBSSH2_CRYPT_METHOD *method =
1399
(const LIBSSH2_CRYPT_METHOD *)
1400
kex_get_method_by_name((char *) s, method_len,
1401
(const LIBSSH2_COMMON_METHOD **)
1405
/* Invalid method -- Should never be reached */
1409
endpoint->crypt = method;
1413
s = p ? p + 1 : NULL;
1418
while (*cryptp && (*cryptp)->name) {
1419
s = kex_agree_instr(crypt, crypt_len,
1420
(unsigned char *) (*cryptp)->name,
1421
strlen((*cryptp)->name));
1423
endpoint->crypt = *cryptp;
1435
* Agree on a message authentication hash
1437
static int kex_agree_mac(LIBSSH2_SESSION * session,
1438
libssh2_endpoint_data * endpoint, unsigned char *mac,
1439
unsigned long mac_len)
1441
const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods();
1445
if (endpoint->mac_prefs) {
1446
s = (unsigned char *) endpoint->mac_prefs;
1449
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1450
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1452
if (kex_agree_instr(mac, mac_len, s, method_len)) {
1453
const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
1454
kex_get_method_by_name((char *) s, method_len,
1455
(const LIBSSH2_COMMON_METHOD **)
1459
/* Invalid method -- Should never be reached */
1463
endpoint->mac = method;
1467
s = p ? p + 1 : NULL;
1472
while (*macp && (*macp)->name) {
1473
s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
1474
strlen((*macp)->name));
1476
endpoint->mac = *macp;
1488
* Agree on a compression scheme
1490
static int kex_agree_comp(LIBSSH2_SESSION * session,
1491
libssh2_endpoint_data * endpoint, unsigned char *comp,
1492
unsigned long comp_len)
1494
const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods();
1498
if (endpoint->comp_prefs) {
1499
s = (unsigned char *) endpoint->comp_prefs;
1502
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1503
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1505
if (kex_agree_instr(comp, comp_len, s, method_len)) {
1506
const LIBSSH2_COMP_METHOD *method =
1507
(const LIBSSH2_COMP_METHOD *)
1508
kex_get_method_by_name((char *) s, method_len,
1509
(const LIBSSH2_COMMON_METHOD **)
1513
/* Invalid method -- Should never be reached */
1517
endpoint->comp = method;
1521
s = p ? p + 1 : NULL;
1526
while (*compp && (*compp)->name) {
1527
s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
1528
strlen((*compp)->name));
1530
endpoint->comp = *compp;
1541
/* TODO: When in server mode we need to turn this logic on its head
1542
* The Client gets to make the final call on "agreed methods"
1545
/* kex_agree_methods
1546
* Decide which specific method to use of the methods offered by each party
1548
static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
1551
unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc,
1553
size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len;
1554
size_t comp_sc_len, mac_cs_len, mac_sc_len;
1555
unsigned char *s = data;
1557
/* Skip packet_type, we know it already */
1560
/* Skip cookie, don't worry, it's preserved in the kexinit field */
1563
/* Locate each string */
1564
kex_len = _libssh2_ntohu32(s);
1567
hostkey_len = _libssh2_ntohu32(s);
1569
s += 4 + hostkey_len;
1570
crypt_cs_len = _libssh2_ntohu32(s);
1572
s += 4 + crypt_cs_len;
1573
crypt_sc_len = _libssh2_ntohu32(s);
1575
s += 4 + crypt_sc_len;
1576
mac_cs_len = _libssh2_ntohu32(s);
1578
s += 4 + mac_cs_len;
1579
mac_sc_len = _libssh2_ntohu32(s);
1581
s += 4 + mac_sc_len;
1582
comp_cs_len = _libssh2_ntohu32(s);
1584
s += 4 + comp_cs_len;
1585
comp_sc_len = _libssh2_ntohu32(s);
1588
s += 4 + comp_sc_len;
1589
lang_cs_len = _libssh2_ntohu32(s);
1591
s += 4 + lang_cs_len;
1592
lang_sc_len = _libssh2_ntohu32(s);
1594
s += 4 + lang_sc_len;
1596
/* If the server sent an optimistic packet, assume that it guessed wrong.
1597
* If the guess is determined to be right (by kex_agree_kex_hostkey)
1598
* This flag will be reset to zero so that it's not ignored */
1599
session->burn_optimistic_kexinit = *(s++);
1600
/* Next uint32 in packet is all zeros (reserved) */
1602
if (data_len < (unsigned) (s - data))
1603
return -1; /* short packet */
1605
if (kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) {
1609
if (kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len)
1610
|| kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) {
1614
if (kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) ||
1615
kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) {
1619
if (kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) ||
1620
kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) {
1625
if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len)
1626
|| libssh2_kex_agree_lang(session, &session->remote, lang_sc,
1632
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s",
1633
session->kex->name);
1634
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s",
1635
session->hostkey->name);
1636
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s",
1637
session->local.crypt->name);
1638
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s",
1639
session->remote.crypt->name);
1640
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s",
1641
session->local.mac->name);
1642
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s",
1643
session->remote.mac->name);
1644
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s",
1645
session->local.comp->name);
1646
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s",
1647
session->remote.comp->name);
1654
/* _libssh2_kex_exchange
1656
* Returns 0 on success, non-zero on failure
1658
* Returns some errors without _libssh2_error()
1661
_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
1662
key_exchange_state_t * key_state)
1667
session->state |= LIBSSH2_STATE_KEX_ACTIVE;
1669
if (key_state->state == libssh2_NB_state_idle) {
1670
/* Prevent loop in packet_add() */
1671
session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
1674
session->kex = NULL;
1676
if (session->hostkey && session->hostkey->dtor) {
1677
session->hostkey->dtor(session,
1678
&session->server_hostkey_abstract);
1680
session->hostkey = NULL;
1683
key_state->state = libssh2_NB_state_created;
1686
if (!session->kex || !session->hostkey) {
1687
if (key_state->state == libssh2_NB_state_created) {
1688
/* Preserve in case of failure */
1689
key_state->oldlocal = session->local.kexinit;
1690
key_state->oldlocal_len = session->local.kexinit_len;
1692
session->local.kexinit = NULL;
1694
key_state->state = libssh2_NB_state_sent;
1697
if (key_state->state == libssh2_NB_state_sent) {
1698
retcode = kexinit(session);
1699
if (retcode == LIBSSH2_ERROR_EAGAIN) {
1700
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1702
} else if (retcode) {
1703
session->local.kexinit = key_state->oldlocal;
1704
session->local.kexinit_len = key_state->oldlocal_len;
1705
key_state->state = libssh2_NB_state_idle;
1706
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1707
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1711
key_state->state = libssh2_NB_state_sent1;
1714
if (key_state->state == libssh2_NB_state_sent1) {
1716
_libssh2_packet_require(session, SSH_MSG_KEXINIT,
1718
&key_state->data_len, 0, NULL, 0,
1719
&key_state->req_state);
1720
if (retcode == LIBSSH2_ERROR_EAGAIN) {
1721
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1725
if (session->local.kexinit) {
1726
LIBSSH2_FREE(session, session->local.kexinit);
1728
session->local.kexinit = key_state->oldlocal;
1729
session->local.kexinit_len = key_state->oldlocal_len;
1730
key_state->state = libssh2_NB_state_idle;
1731
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1732
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1736
if (session->remote.kexinit) {
1737
LIBSSH2_FREE(session, session->remote.kexinit);
1739
session->remote.kexinit = key_state->data;
1740
session->remote.kexinit_len = key_state->data_len;
1742
if (kex_agree_methods(session, key_state->data,
1743
key_state->data_len))
1744
rc = LIBSSH2_ERROR_KEX_FAILURE;
1746
key_state->state = libssh2_NB_state_sent2;
1749
key_state->state = libssh2_NB_state_sent2;
1753
if (key_state->state == libssh2_NB_state_sent2) {
1754
retcode = session->kex->exchange_keys(session,
1755
&key_state->key_state_low);
1756
if (retcode == LIBSSH2_ERROR_EAGAIN) {
1757
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1759
} else if (retcode) {
1760
rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
1761
"Unrecoverable error exchanging keys");
1766
/* Done with kexinit buffers */
1767
if (session->local.kexinit) {
1768
LIBSSH2_FREE(session, session->local.kexinit);
1769
session->local.kexinit = NULL;
1771
if (session->remote.kexinit) {
1772
LIBSSH2_FREE(session, session->remote.kexinit);
1773
session->remote.kexinit = NULL;
1776
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1777
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1779
key_state->state = libssh2_NB_state_idle;
1786
/* libssh2_session_method_pref
1787
* Set preferred method
1790
libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
1793
char **prefvar, *s, *newprefs;
1794
int prefs_len = strlen(prefs);
1795
const LIBSSH2_COMMON_METHOD **mlist;
1797
switch (method_type) {
1798
case LIBSSH2_METHOD_KEX:
1799
prefvar = &session->kex_prefs;
1800
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
1803
case LIBSSH2_METHOD_HOSTKEY:
1804
prefvar = &session->hostkey_prefs;
1805
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
1808
case LIBSSH2_METHOD_CRYPT_CS:
1809
prefvar = &session->local.crypt_prefs;
1810
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
1813
case LIBSSH2_METHOD_CRYPT_SC:
1814
prefvar = &session->remote.crypt_prefs;
1815
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
1818
case LIBSSH2_METHOD_MAC_CS:
1819
prefvar = &session->local.mac_prefs;
1820
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
1823
case LIBSSH2_METHOD_MAC_SC:
1824
prefvar = &session->remote.mac_prefs;
1825
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
1828
case LIBSSH2_METHOD_COMP_CS:
1829
prefvar = &session->local.comp_prefs;
1830
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods();
1833
case LIBSSH2_METHOD_COMP_SC:
1834
prefvar = &session->remote.comp_prefs;
1835
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods();
1838
case LIBSSH2_METHOD_LANG_CS:
1839
prefvar = &session->local.lang_prefs;
1843
case LIBSSH2_METHOD_LANG_SC:
1844
prefvar = &session->remote.lang_prefs;
1849
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1850
"Invalid parameter specified for method_type");
1853
s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
1855
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1856
"Error allocated space for method preferences");
1858
memcpy(s, prefs, prefs_len + 1);
1861
char *p = strchr(s, ',');
1862
int method_len = p ? (p - s) : (int) strlen(s);
1864
if (!kex_get_method_by_name(s, method_len, mlist)) {
1865
/* Strip out unsupported method */
1867
memcpy(s, p + 1, strlen(s) - method_len);
1877
s = p ? (p + 1) : NULL;
1880
if (strlen(newprefs) == 0) {
1881
LIBSSH2_FREE(session, newprefs);
1882
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
1883
"The requested method(s) are not currently "
1888
LIBSSH2_FREE(session, *prefvar);
1890
*prefvar = newprefs;