1
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
2
* Copyright (c) 2010, Daniel Stenberg <daniel@haxx.se>
5
* Redistribution and use in source and binary forms,
6
* with or without modification, are permitted provided
7
* that the following conditions are met:
9
* Redistributions of source code must retain the above
10
* copyright notice, this list of conditions and the
11
* following disclaimer.
13
* Redistributions in binary form must reproduce the above
14
* copyright notice, this list of conditions and the following
15
* disclaimer in the documentation and/or other materials
16
* provided with the distribution.
18
* Neither the name of the copyright holder nor the names
19
* of any other contributors may be used to endorse or
20
* promote products derived from this software without
21
* specific prior written permission.
23
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
35
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39
#include "libssh2_priv.h"
41
#include "transport.h"
45
/* TODO: Switch this to an inline and handle alloc() failures */
46
/* Helper macro called from kex_method_diffie_hellman_group1_sha1_key_exchange */
47
#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \
49
libssh2_sha1_ctx hash; \
50
unsigned long len = 0; \
52
value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
55
while (len < (unsigned long)reqlen) { \
56
libssh2_sha1_init(&hash); \
57
libssh2_sha1_update(hash, exchange_state->k_value, \
58
exchange_state->k_value_len); \
59
libssh2_sha1_update(hash, exchange_state->h_sig_comp, \
62
libssh2_sha1_update(hash, value, len); \
64
libssh2_sha1_update(hash, (version), 1); \
65
libssh2_sha1_update(hash, session->session_id, \
66
session->session_id_len); \
68
libssh2_sha1_final(hash, (value) + len); \
69
len += SHA_DIGEST_LENGTH; \
76
* Diffie Hellman Key Exchange, Group Agnostic
78
static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
82
unsigned char packet_type_init,
83
unsigned char packet_type_reply,
84
unsigned char *midhash,
85
unsigned long midhash_len,
86
kmdhgGPsha1kex_state_t *exchange_state)
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
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
123
"Out of memory error");
126
exchange_state->e_packet[0] = packet_type_init;
127
_libssh2_htonu32(exchange_state->e_packet + 1,
128
exchange_state->e_packet_len - 5);
129
if (_libssh2_bn_bits(exchange_state->e) % 8) {
130
_libssh2_bn_to_bin(exchange_state->e,
131
exchange_state->e_packet + 5);
133
exchange_state->e_packet[5] = 0;
134
_libssh2_bn_to_bin(exchange_state->e,
135
exchange_state->e_packet + 6);
138
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d",
139
(int) packet_type_init);
140
exchange_state->state = libssh2_NB_state_created;
143
if (exchange_state->state == libssh2_NB_state_created) {
144
rc = _libssh2_transport_send(session, exchange_state->e_packet,
145
exchange_state->e_packet_len,
147
if (rc == LIBSSH2_ERROR_EAGAIN) {
150
ret = _libssh2_error(session, rc,
151
"Unable to send KEX init message");
154
exchange_state->state = libssh2_NB_state_sent;
157
if (exchange_state->state == libssh2_NB_state_sent) {
158
if (session->burn_optimistic_kexinit) {
159
/* The first KEX packet to come along will be the guess initially
160
* sent by the server. That guess turned out to be wrong so we
161
* need to silently ignore it */
164
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
165
"Waiting for badly guessed KEX packet (to be ignored)");
167
_libssh2_packet_burn(session, &exchange_state->burn_state);
168
if (burn_type == LIBSSH2_ERROR_EAGAIN) {
170
} else if (burn_type <= 0) {
171
/* Failed to receive a packet */
175
session->burn_optimistic_kexinit = 0;
177
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
178
"Burnt packet of type: %02x",
179
(unsigned int) burn_type);
182
exchange_state->state = libssh2_NB_state_sent1;
185
if (exchange_state->state == libssh2_NB_state_sent1) {
186
/* Wait for KEX reply */
187
rc = _libssh2_packet_require(session, packet_type_reply,
188
&exchange_state->s_packet,
189
&exchange_state->s_packet_len, 0, NULL,
190
0, &exchange_state->req_state);
191
if (rc == LIBSSH2_ERROR_EAGAIN) {
195
ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
196
"Timed out waiting for KEX reply");
200
/* Parse KEXDH_REPLY */
201
exchange_state->s = exchange_state->s_packet + 1;
203
session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s);
204
exchange_state->s += 4;
205
session->server_hostkey =
206
LIBSSH2_ALLOC(session, session->server_hostkey_len);
207
if (!session->server_hostkey) {
208
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
209
"Unable to allocate memory for a copy "
213
memcpy(session->server_hostkey, exchange_state->s,
214
session->server_hostkey_len);
215
exchange_state->s += session->server_hostkey_len;
219
libssh2_md5_ctx fingerprint_ctx;
221
if (libssh2_md5_init(&fingerprint_ctx)) {
222
libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
223
session->server_hostkey_len);
224
libssh2_md5_final(fingerprint_ctx, session->server_hostkey_md5);
225
session->server_hostkey_md5_valid = TRUE;
228
session->server_hostkey_md5_valid = FALSE;
233
char fingerprint[50], *fprint = fingerprint;
235
for(i = 0; i < 16; i++, fprint += 3) {
236
snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
239
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
240
"Server's MD5 Fingerprint: %s", fingerprint);
242
#endif /* LIBSSH2DEBUG */
243
#endif /* ! LIBSSH2_MD5 */
246
libssh2_sha1_ctx fingerprint_ctx;
248
libssh2_sha1_init(&fingerprint_ctx);
249
libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
250
session->server_hostkey_len);
251
libssh2_sha1_final(fingerprint_ctx, session->server_hostkey_sha1);
255
char fingerprint[64], *fprint = fingerprint;
258
for(i = 0; i < 20; i++, fprint += 3) {
259
snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
262
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
263
"Server's SHA1 Fingerprint: %s", fingerprint);
265
#endif /* LIBSSH2DEBUG */
267
if (session->hostkey->init(session, session->server_hostkey,
268
session->server_hostkey_len,
269
&session->server_hostkey_abstract)) {
270
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT,
271
"Unable to initialize hostkey importer");
275
exchange_state->f_value_len = _libssh2_ntohu32(exchange_state->s);
276
exchange_state->s += 4;
277
exchange_state->f_value = exchange_state->s;
278
exchange_state->s += exchange_state->f_value_len;
279
_libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len,
280
exchange_state->f_value);
282
exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s);
283
exchange_state->s += 4;
284
exchange_state->h_sig = exchange_state->s;
286
/* Compute the shared secret */
287
_libssh2_bn_mod_exp(exchange_state->k, exchange_state->f,
288
exchange_state->x, p, exchange_state->ctx);
289
exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5;
290
if (_libssh2_bn_bits(exchange_state->k) % 8) {
291
/* don't need leading 00 */
292
exchange_state->k_value_len--;
294
exchange_state->k_value =
295
LIBSSH2_ALLOC(session, exchange_state->k_value_len);
296
if (!exchange_state->k_value) {
297
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
298
"Unable to allocate buffer for K");
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
ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN,
409
"Unable to verify hostkey signature");
413
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message");
414
exchange_state->c = SSH_MSG_NEWKEYS;
416
exchange_state->state = libssh2_NB_state_sent2;
419
if (exchange_state->state == libssh2_NB_state_sent2) {
420
rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0);
421
if (rc == LIBSSH2_ERROR_EAGAIN) {
424
ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message");
428
exchange_state->state = libssh2_NB_state_sent3;
431
if (exchange_state->state == libssh2_NB_state_sent3) {
432
rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS,
433
&exchange_state->tmp,
434
&exchange_state->tmp_len, 0, NULL, 0,
435
&exchange_state->req_state);
436
if (rc == LIBSSH2_ERROR_EAGAIN) {
439
ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
442
/* The first key exchange has been performed,
443
switch to active crypt/comp/mac mode */
444
session->state |= LIBSSH2_STATE_NEWKEYS;
445
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message");
447
/* This will actually end up being just packet_type(1)
448
for this packet type anyway */
449
LIBSSH2_FREE(session, exchange_state->tmp);
451
if (!session->session_id) {
452
session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH);
453
if (!session->session_id) {
454
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
455
"Unable to allocate buffer for SHA digest");
458
memcpy(session->session_id, exchange_state->h_sig_comp,
460
session->session_id_len = SHA_DIGEST_LENGTH;
461
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated");
464
/* Cleanup any existing cipher */
465
if (session->local.crypt->dtor) {
466
session->local.crypt->dtor(session,
467
&session->local.crypt_abstract);
470
/* Calculate IV/Secret/Key for each direction */
471
if (session->local.crypt->init) {
472
unsigned char *iv = NULL, *secret = NULL;
473
int free_iv = 0, free_secret = 0;
475
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
476
session->local.crypt->
482
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
483
session->local.crypt->
486
LIBSSH2_FREE(session, iv);
487
ret = LIBSSH2_ERROR_KEX_FAILURE;
490
if (session->local.crypt->
491
init(session, session->local.crypt, iv, &free_iv, secret,
492
&free_secret, 1, &session->local.crypt_abstract)) {
493
LIBSSH2_FREE(session, iv);
494
LIBSSH2_FREE(session, secret);
495
ret = LIBSSH2_ERROR_KEX_FAILURE;
500
memset(iv, 0, session->local.crypt->iv_len);
501
LIBSSH2_FREE(session, iv);
505
memset(secret, 0, session->local.crypt->secret_len);
506
LIBSSH2_FREE(session, secret);
509
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
510
"Client to Server IV and Key calculated");
512
if (session->remote.crypt->dtor) {
513
/* Cleanup any existing cipher */
514
session->remote.crypt->dtor(session,
515
&session->remote.crypt_abstract);
518
if (session->remote.crypt->init) {
519
unsigned char *iv = NULL, *secret = NULL;
520
int free_iv = 0, free_secret = 0;
522
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
523
session->remote.crypt->
526
ret = LIBSSH2_ERROR_KEX_FAILURE;
529
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
530
session->remote.crypt->
533
LIBSSH2_FREE(session, iv);
534
ret = LIBSSH2_ERROR_KEX_FAILURE;
537
if (session->remote.crypt->
538
init(session, session->remote.crypt, iv, &free_iv, secret,
539
&free_secret, 0, &session->remote.crypt_abstract)) {
540
LIBSSH2_FREE(session, iv);
541
LIBSSH2_FREE(session, secret);
542
ret = LIBSSH2_ERROR_KEX_FAILURE;
547
memset(iv, 0, session->remote.crypt->iv_len);
548
LIBSSH2_FREE(session, iv);
552
memset(secret, 0, session->remote.crypt->secret_len);
553
LIBSSH2_FREE(session, secret);
556
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
557
"Server to Client IV and Key calculated");
559
if (session->local.mac->dtor) {
560
session->local.mac->dtor(session, &session->local.mac_abstract);
563
if (session->local.mac->init) {
564
unsigned char *key = NULL;
567
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
571
ret = LIBSSH2_ERROR_KEX_FAILURE;
574
session->local.mac->init(session, key, &free_key,
575
&session->local.mac_abstract);
578
memset(key, 0, session->local.mac->key_len);
579
LIBSSH2_FREE(session, key);
582
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
583
"Client to Server HMAC Key calculated");
585
if (session->remote.mac->dtor) {
586
session->remote.mac->dtor(session, &session->remote.mac_abstract);
589
if (session->remote.mac->init) {
590
unsigned char *key = NULL;
593
LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
594
session->remote.mac->
597
ret = LIBSSH2_ERROR_KEX_FAILURE;
600
session->remote.mac->init(session, key, &free_key,
601
&session->remote.mac_abstract);
604
memset(key, 0, session->remote.mac->key_len);
605
LIBSSH2_FREE(session, key);
608
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
609
"Server to Client HMAC Key calculated");
611
/* Initialize compression for each direction */
613
/* Cleanup any existing compression */
614
if (session->local.comp && session->local.comp->dtor) {
615
session->local.comp->dtor(session, 1,
616
&session->local.comp_abstract);
619
if (session->local.comp && session->local.comp->init) {
620
if (session->local.comp->init(session, 1,
621
&session->local.comp_abstract)) {
622
ret = LIBSSH2_ERROR_KEX_FAILURE;
626
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
627
"Client to Server compression initialized");
629
if (session->remote.comp && session->remote.comp->dtor) {
630
session->remote.comp->dtor(session, 0,
631
&session->remote.comp_abstract);
634
if (session->remote.comp && session->remote.comp->init) {
635
if (session->remote.comp->init(session, 0,
636
&session->remote.comp_abstract)) {
637
ret = LIBSSH2_ERROR_KEX_FAILURE;
641
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
642
"Server to Client compression initialized");
647
_libssh2_bn_free(exchange_state->x);
648
exchange_state->x = NULL;
649
_libssh2_bn_free(exchange_state->e);
650
exchange_state->e = NULL;
651
_libssh2_bn_free(exchange_state->f);
652
exchange_state->f = NULL;
653
_libssh2_bn_free(exchange_state->k);
654
exchange_state->k = NULL;
655
_libssh2_bn_ctx_free(exchange_state->ctx);
656
exchange_state->ctx = NULL;
658
if (exchange_state->e_packet) {
659
LIBSSH2_FREE(session, exchange_state->e_packet);
660
exchange_state->e_packet = NULL;
663
if (exchange_state->s_packet) {
664
LIBSSH2_FREE(session, exchange_state->s_packet);
665
exchange_state->s_packet = NULL;
668
if (exchange_state->k_value) {
669
LIBSSH2_FREE(session, exchange_state->k_value);
670
exchange_state->k_value = NULL;
673
exchange_state->state = libssh2_NB_state_idle;
680
/* kex_method_diffie_hellman_group1_sha1_key_exchange
681
* Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1
684
kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
685
key_exchange_state_low_t
688
static const unsigned char p_value[128] = {
689
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
690
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
691
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
692
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
693
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
694
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
695
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
696
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
697
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
698
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
699
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
700
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
701
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
702
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
703
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
704
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
709
if (key_state->state == libssh2_NB_state_idle) {
711
key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */
712
key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
714
/* Initialize P and G */
715
_libssh2_bn_set_word(key_state->g, 2);
716
_libssh2_bn_from_bin(key_state->p, 128, p_value);
718
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
719
"Initiating Diffie-Hellman Group1 Key Exchange");
721
key_state->state = libssh2_NB_state_created;
723
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128,
724
SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
725
NULL, 0, &key_state->exchange_state);
726
if (ret == LIBSSH2_ERROR_EAGAIN) {
730
_libssh2_bn_free(key_state->p);
732
_libssh2_bn_free(key_state->g);
734
key_state->state = libssh2_NB_state_idle;
741
/* kex_method_diffie_hellman_group14_sha1_key_exchange
742
* Diffie-Hellman Group14 Key Exchange using SHA1
745
kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
746
key_exchange_state_low_t
749
static const unsigned char p_value[256] = {
750
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
751
0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
752
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
753
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
754
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
755
0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
756
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
757
0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
758
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
759
0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
760
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
761
0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
762
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
763
0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
764
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
765
0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
766
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
767
0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
768
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
769
0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
770
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
771
0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
772
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
773
0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
774
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
775
0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
776
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
777
0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
778
0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
779
0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
780
0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
781
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
785
if (key_state->state == libssh2_NB_state_idle) {
786
key_state->p = _libssh2_bn_init(); /* SSH2 defined value (p_value) */
787
key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */
790
/* Initialize P and G */
791
_libssh2_bn_set_word(key_state->g, 2);
792
_libssh2_bn_from_bin(key_state->p, 256, p_value);
794
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
795
"Initiating Diffie-Hellman Group14 Key Exchange");
797
key_state->state = libssh2_NB_state_created;
799
ret = diffie_hellman_sha1(session, key_state->g, key_state->p,
800
256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY,
801
NULL, 0, &key_state->exchange_state);
802
if (ret == LIBSSH2_ERROR_EAGAIN) {
806
key_state->state = libssh2_NB_state_idle;
807
_libssh2_bn_free(key_state->p);
809
_libssh2_bn_free(key_state->g);
817
/* kex_method_diffie_hellman_group_exchange_sha1_key_exchange
818
* Diffie-Hellman Group Exchange Key Exchange using SHA1
819
* Negotiates random(ish) group for secret derivation
822
kex_method_diffie_hellman_group_exchange_sha1_key_exchange
823
(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
825
unsigned long p_len, g_len;
829
if (key_state->state == libssh2_NB_state_idle) {
830
key_state->p = _libssh2_bn_init();
831
key_state->g = _libssh2_bn_init();
832
/* Ask for a P and G pair */
833
#ifdef LIBSSH2_DH_GEX_NEW
834
key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST;
835
_libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP);
836
_libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP);
837
_libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP);
838
key_state->request_len = 13;
839
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
840
"Initiating Diffie-Hellman Group-Exchange (New Method)");
842
key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD;
843
_libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP);
844
key_state->request_len = 5;
845
_libssh2_debug(session, LIBSSH2_TRACE_KEX,
846
"Initiating Diffie-Hellman Group-Exchange (Old Method)");
849
key_state->state = libssh2_NB_state_created;
852
if (key_state->state == libssh2_NB_state_created) {
853
rc = _libssh2_transport_send(session, key_state->request,
854
key_state->request_len, NULL, 0);
855
if (rc == LIBSSH2_ERROR_EAGAIN) {
858
ret = _libssh2_error(session, rc,
859
"Unable to send Group Exchange Request");
860
goto dh_gex_clean_exit;
863
key_state->state = libssh2_NB_state_sent;
866
if (key_state->state == libssh2_NB_state_sent) {
867
rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP,
868
&key_state->data, &key_state->data_len,
869
0, NULL, 0, &key_state->req_state);
870
if (rc == LIBSSH2_ERROR_EAGAIN) {
873
ret = _libssh2_error(session, rc,
874
"Timeout waiting for GEX_GROUP reply");
875
goto dh_gex_clean_exit;
878
key_state->state = libssh2_NB_state_sent1;
881
if (key_state->state == libssh2_NB_state_sent1) {
882
unsigned char *s = key_state->data + 1;
883
p_len = _libssh2_ntohu32(s);
885
_libssh2_bn_from_bin(key_state->p, p_len, s);
888
g_len = _libssh2_ntohu32(s);
890
_libssh2_bn_from_bin(key_state->g, g_len, s);
892
ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len,
893
SSH_MSG_KEX_DH_GEX_INIT,
894
SSH_MSG_KEX_DH_GEX_REPLY,
896
key_state->data_len - 1,
897
&key_state->exchange_state);
898
if (ret == LIBSSH2_ERROR_EAGAIN) {
902
LIBSSH2_FREE(session, key_state->data);
906
key_state->state = libssh2_NB_state_idle;
907
_libssh2_bn_free(key_state->g);
909
_libssh2_bn_free(key_state->p);
917
#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001
918
#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002
920
static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = {
921
"diffie-hellman-group1-sha1",
922
kex_method_diffie_hellman_group1_sha1_key_exchange,
923
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
926
static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = {
927
"diffie-hellman-group14-sha1",
928
kex_method_diffie_hellman_group14_sha1_key_exchange,
929
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
932
static const LIBSSH2_KEX_METHOD
933
kex_method_diffie_helman_group_exchange_sha1 = {
934
"diffie-hellman-group-exchange-sha1",
935
kex_method_diffie_hellman_group_exchange_sha1_key_exchange,
936
LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY,
939
static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
940
&kex_method_diffie_helman_group14_sha1,
941
&kex_method_diffie_helman_group_exchange_sha1,
942
&kex_method_diffie_helman_group1_sha1,
946
typedef struct _LIBSSH2_COMMON_METHOD
949
} LIBSSH2_COMMON_METHOD;
952
* Calculate the length of a particular method list's resulting string
953
* Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used)
954
* Another sign of bad coding practices gone mad. Pretend you don't see this.
957
kex_method_strlen(LIBSSH2_COMMON_METHOD ** method)
961
if (!method || !*method) {
965
while (*method && (*method)->name) {
966
len += strlen((*method)->name) + 1;
976
* Generate formatted preference list in buf
979
kex_method_list(unsigned char *buf, size_t list_strlen,
980
LIBSSH2_COMMON_METHOD ** method)
982
_libssh2_htonu32(buf, list_strlen);
985
if (!method || !*method) {
989
while (*method && (*method)->name) {
990
int mlen = strlen((*method)->name);
991
memcpy(buf, (*method)->name, mlen);
997
return list_strlen + 4;
1002
#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \
1003
((prefvar) ? strlen(prefvar) : \
1004
kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
1006
#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \
1008
_libssh2_htonu32((buf), (prefvarlen)); \
1010
memcpy((buf), (prefvar), (prefvarlen)); \
1011
buf += (prefvarlen); \
1013
buf += kex_method_list((buf), (prefvarlen), \
1014
(LIBSSH2_COMMON_METHOD**)(defaultvar)); \
1018
* Send SSH_MSG_KEXINIT packet
1020
static int kexinit(LIBSSH2_SESSION * session)
1022
/* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) +
1023
reserved(4) + length longs(40) */
1024
size_t data_len = 62;
1025
size_t kex_len, hostkey_len = 0;
1026
size_t crypt_cs_len, crypt_sc_len;
1027
size_t comp_cs_len, comp_sc_len;
1028
size_t mac_cs_len, mac_sc_len;
1029
size_t lang_cs_len, lang_sc_len;
1030
unsigned char *data, *s;
1033
if (session->kexinit_state == libssh2_NB_state_idle) {
1035
LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods);
1037
LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs,
1038
libssh2_hostkey_methods());
1040
LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs,
1041
libssh2_crypt_methods());
1043
LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs,
1044
libssh2_crypt_methods());
1046
LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs,
1047
_libssh2_mac_methods());
1049
LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs,
1050
_libssh2_mac_methods());
1052
LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs,
1053
_libssh2_comp_methods(session));
1055
LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs,
1056
_libssh2_comp_methods(session));
1058
LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL);
1060
LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL);
1062
data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len +
1063
comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len +
1064
lang_cs_len + lang_sc_len;
1066
s = data = LIBSSH2_ALLOC(session, data_len);
1068
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1069
"Unable to allocate memory");
1072
*(s++) = SSH_MSG_KEXINIT;
1074
_libssh2_random(s, 16);
1077
/* Ennumerating through these lists twice is probably (certainly?)
1078
inefficient from a CPU standpoint, but it saves multiple
1079
malloc/realloc calls */
1080
LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs,
1081
libssh2_kex_methods);
1082
LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs,
1083
libssh2_hostkey_methods());
1084
LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs,
1085
libssh2_crypt_methods());
1086
LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs,
1087
libssh2_crypt_methods());
1088
LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs,
1089
_libssh2_mac_methods());
1090
LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs,
1091
_libssh2_mac_methods());
1092
LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs,
1093
_libssh2_comp_methods(session));
1094
LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs,
1095
_libssh2_comp_methods(session));
1096
LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs,
1098
LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs,
1101
/* No optimistic KEX packet follows */
1102
/* Deal with optimistic packets
1103
* session->flags |= KEXINIT_OPTIMISTIC
1104
* session->flags |= KEXINIT_METHODSMATCH
1109
_libssh2_htonu32(s, 0);
1113
/* Funnily enough, they'll all "appear" to be '\0' terminated */
1114
unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */
1116
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p);
1118
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p);
1119
p += hostkey_len + 4;
1120
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p);
1121
p += crypt_cs_len + 4;
1122
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p);
1123
p += crypt_sc_len + 4;
1124
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p);
1125
p += mac_cs_len + 4;
1126
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p);
1127
p += mac_sc_len + 4;
1128
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p);
1129
p += comp_cs_len + 4;
1130
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p);
1131
p += comp_sc_len + 4;
1132
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p);
1133
p += lang_cs_len + 4;
1134
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p);
1135
p += lang_sc_len + 4;
1137
#endif /* LIBSSH2DEBUG */
1139
session->kexinit_state = libssh2_NB_state_created;
1141
data = session->kexinit_data;
1142
data_len = session->kexinit_data_len;
1143
/* zap the variables to ensure there is NOT a double free later */
1144
session->kexinit_data = NULL;
1145
session->kexinit_data_len = 0;
1148
rc = _libssh2_transport_send(session, data, data_len, NULL, 0);
1149
if (rc == LIBSSH2_ERROR_EAGAIN) {
1150
session->kexinit_data = data;
1151
session->kexinit_data_len = data_len;
1155
LIBSSH2_FREE(session, data);
1156
session->kexinit_state = libssh2_NB_state_idle;
1157
return _libssh2_error(session, rc,
1158
"Unable to send KEXINIT packet to remote host");
1162
if (session->local.kexinit) {
1163
LIBSSH2_FREE(session, session->local.kexinit);
1166
session->local.kexinit = data;
1167
session->local.kexinit_len = data_len;
1169
session->kexinit_state = libssh2_NB_state_idle;
1175
* Kex specific variant of strstr()
1176
* Needle must be preceed by BOL or ',', and followed by ',' or EOL
1178
static unsigned char *
1179
kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
1180
const unsigned char *needle, unsigned long needle_len)
1184
/* Haystack too short to bother trying */
1185
if (haystack_len < needle_len) {
1189
/* Needle at start of haystack */
1190
if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) &&
1191
(needle_len == haystack_len || haystack[needle_len] == ',')) {
1196
/* Search until we run out of comas or we run out of haystack,
1197
whichever comes first */
1198
while ((s = (unsigned char *) strchr((char *) s, ','))
1199
&& ((haystack_len - (s - haystack)) > needle_len)) {
1201
/* Needle at X position */
1202
if ((strncmp((char *) s, (char *) needle, needle_len) == 0) &&
1203
(((s - haystack) + needle_len) == haystack_len
1204
|| s[needle_len] == ',')) {
1214
/* kex_get_method_by_name
1216
static const LIBSSH2_COMMON_METHOD *
1217
kex_get_method_by_name(const char *name, size_t name_len,
1218
const LIBSSH2_COMMON_METHOD ** methodlist)
1220
while (*methodlist) {
1221
if ((strlen((*methodlist)->name) == name_len) &&
1222
(strncmp((*methodlist)->name, name, name_len) == 0)) {
1232
/* kex_agree_hostkey
1233
* Agree on a Hostkey which works with this kex
1235
static int kex_agree_hostkey(LIBSSH2_SESSION * session,
1236
unsigned long kex_flags,
1237
unsigned char *hostkey, unsigned long hostkey_len)
1239
const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
1242
if (session->hostkey_prefs) {
1243
s = (unsigned char *) session->hostkey_prefs;
1246
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1247
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1248
if (kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
1249
const LIBSSH2_HOSTKEY_METHOD *method =
1250
(const LIBSSH2_HOSTKEY_METHOD *)
1251
kex_get_method_by_name((char *) s, method_len,
1252
(const LIBSSH2_COMMON_METHOD **)
1256
/* Invalid method -- Should never be reached */
1260
/* So far so good, but does it suit our purposes? (Encrypting
1262
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) ==
1263
0) || (method->encrypt)) {
1264
/* Either this hostkey can do encryption or this kex just
1265
doesn't require it */
1266
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY)
1267
== 0) || (method->sig_verify)) {
1268
/* Either this hostkey can do signing or this kex just
1269
doesn't require it */
1270
session->hostkey = method;
1276
s = p ? p + 1 : NULL;
1281
while (hostkeyp && (*hostkeyp) && (*hostkeyp)->name) {
1282
s = kex_agree_instr(hostkey, hostkey_len,
1283
(unsigned char *) (*hostkeyp)->name,
1284
strlen((*hostkeyp)->name));
1286
/* So far so good, but does it suit our purposes? (Encrypting vs
1288
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) ||
1289
((*hostkeyp)->encrypt)) {
1290
/* Either this hostkey can do encryption or this kex just
1291
doesn't require it */
1292
if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) ==
1293
0) || ((*hostkeyp)->sig_verify)) {
1294
/* Either this hostkey can do signing or this kex just
1295
doesn't require it */
1296
session->hostkey = *hostkeyp;
1309
/* kex_agree_kex_hostkey
1310
* Agree on a Key Exchange method and a hostkey encoding type
1312
static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
1313
unsigned long kex_len, unsigned char *hostkey,
1314
unsigned long hostkey_len)
1316
const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
1319
if (session->kex_prefs) {
1320
s = (unsigned char *) session->kex_prefs;
1323
unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
1324
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1325
if ((q = kex_agree_instr(kex, kex_len, s, method_len))) {
1326
const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
1327
kex_get_method_by_name((char *) s, method_len,
1328
(const LIBSSH2_COMMON_METHOD **)
1332
/* Invalid method -- Should never be reached */
1336
/* We've agreed on a key exchange method,
1337
* Can we agree on a hostkey that works with this kex?
1339
if (kex_agree_hostkey(session, method->flags, hostkey,
1340
hostkey_len) == 0) {
1341
session->kex = method;
1342
if (session->burn_optimistic_kexinit && (kex == q)) {
1343
/* Server sent an optimistic packet,
1344
* and client agrees with preference
1345
* cancel burning the first KEX_INIT packet that comes in */
1346
session->burn_optimistic_kexinit = 0;
1352
s = p ? p + 1 : NULL;
1357
while (*kexp && (*kexp)->name) {
1358
s = kex_agree_instr(kex, kex_len,
1359
(unsigned char *) (*kexp)->name,
1360
strlen((*kexp)->name));
1362
/* We've agreed on a key exchange method,
1363
* Can we agree on a hostkey that works with this kex?
1365
if (kex_agree_hostkey(session, (*kexp)->flags, hostkey,
1366
hostkey_len) == 0) {
1367
session->kex = *kexp;
1368
if (session->burn_optimistic_kexinit && (kex == s)) {
1369
/* Server sent an optimistic packet,
1370
* and client agrees with preference
1371
* cancel burning the first KEX_INIT packet that comes in */
1372
session->burn_optimistic_kexinit = 0;
1385
* Agree on a cipher algo
1387
static int kex_agree_crypt(LIBSSH2_SESSION * session,
1388
libssh2_endpoint_data *endpoint,
1389
unsigned char *crypt,
1390
unsigned long crypt_len)
1392
const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
1397
if (endpoint->crypt_prefs) {
1398
s = (unsigned char *) endpoint->crypt_prefs;
1401
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1402
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1404
if (kex_agree_instr(crypt, crypt_len, s, method_len)) {
1405
const LIBSSH2_CRYPT_METHOD *method =
1406
(const LIBSSH2_CRYPT_METHOD *)
1407
kex_get_method_by_name((char *) s, method_len,
1408
(const LIBSSH2_COMMON_METHOD **)
1412
/* Invalid method -- Should never be reached */
1416
endpoint->crypt = method;
1420
s = p ? p + 1 : NULL;
1425
while (*cryptp && (*cryptp)->name) {
1426
s = kex_agree_instr(crypt, crypt_len,
1427
(unsigned char *) (*cryptp)->name,
1428
strlen((*cryptp)->name));
1430
endpoint->crypt = *cryptp;
1442
* Agree on a message authentication hash
1444
static int kex_agree_mac(LIBSSH2_SESSION * session,
1445
libssh2_endpoint_data * endpoint, unsigned char *mac,
1446
unsigned long mac_len)
1448
const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods();
1452
if (endpoint->mac_prefs) {
1453
s = (unsigned char *) endpoint->mac_prefs;
1456
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1457
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1459
if (kex_agree_instr(mac, mac_len, s, method_len)) {
1460
const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
1461
kex_get_method_by_name((char *) s, method_len,
1462
(const LIBSSH2_COMMON_METHOD **)
1466
/* Invalid method -- Should never be reached */
1470
endpoint->mac = method;
1474
s = p ? p + 1 : NULL;
1479
while (*macp && (*macp)->name) {
1480
s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
1481
strlen((*macp)->name));
1483
endpoint->mac = *macp;
1495
* Agree on a compression scheme
1497
static int kex_agree_comp(LIBSSH2_SESSION *session,
1498
libssh2_endpoint_data *endpoint, unsigned char *comp,
1499
unsigned long comp_len)
1501
const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods(session);
1505
if (endpoint->comp_prefs) {
1506
s = (unsigned char *) endpoint->comp_prefs;
1509
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
1510
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
1512
if (kex_agree_instr(comp, comp_len, s, method_len)) {
1513
const LIBSSH2_COMP_METHOD *method =
1514
(const LIBSSH2_COMP_METHOD *)
1515
kex_get_method_by_name((char *) s, method_len,
1516
(const LIBSSH2_COMMON_METHOD **)
1520
/* Invalid method -- Should never be reached */
1524
endpoint->comp = method;
1528
s = p ? p + 1 : NULL;
1533
while (*compp && (*compp)->name) {
1534
s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
1535
strlen((*compp)->name));
1537
endpoint->comp = *compp;
1548
/* TODO: When in server mode we need to turn this logic on its head
1549
* The Client gets to make the final call on "agreed methods"
1552
/* kex_agree_methods
1553
* Decide which specific method to use of the methods offered by each party
1555
static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
1558
unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc,
1560
size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len;
1561
size_t comp_sc_len, mac_cs_len, mac_sc_len;
1562
unsigned char *s = data;
1564
/* Skip packet_type, we know it already */
1567
/* Skip cookie, don't worry, it's preserved in the kexinit field */
1570
/* Locate each string */
1571
kex_len = _libssh2_ntohu32(s);
1574
hostkey_len = _libssh2_ntohu32(s);
1576
s += 4 + hostkey_len;
1577
crypt_cs_len = _libssh2_ntohu32(s);
1579
s += 4 + crypt_cs_len;
1580
crypt_sc_len = _libssh2_ntohu32(s);
1582
s += 4 + crypt_sc_len;
1583
mac_cs_len = _libssh2_ntohu32(s);
1585
s += 4 + mac_cs_len;
1586
mac_sc_len = _libssh2_ntohu32(s);
1588
s += 4 + mac_sc_len;
1589
comp_cs_len = _libssh2_ntohu32(s);
1591
s += 4 + comp_cs_len;
1592
comp_sc_len = _libssh2_ntohu32(s);
1595
s += 4 + comp_sc_len;
1596
lang_cs_len = _libssh2_ntohu32(s);
1598
s += 4 + lang_cs_len;
1599
lang_sc_len = _libssh2_ntohu32(s);
1601
s += 4 + lang_sc_len;
1603
/* If the server sent an optimistic packet, assume that it guessed wrong.
1604
* If the guess is determined to be right (by kex_agree_kex_hostkey)
1605
* This flag will be reset to zero so that it's not ignored */
1606
session->burn_optimistic_kexinit = *(s++);
1607
/* Next uint32 in packet is all zeros (reserved) */
1609
if (data_len < (unsigned) (s - data))
1610
return -1; /* short packet */
1612
if (kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) {
1616
if (kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len)
1617
|| kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) {
1621
if (kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) ||
1622
kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) {
1626
if (kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) ||
1627
kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) {
1632
if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len)
1633
|| libssh2_kex_agree_lang(session, &session->remote, lang_sc,
1639
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s",
1640
session->kex->name);
1641
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s",
1642
session->hostkey->name);
1643
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s",
1644
session->local.crypt->name);
1645
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s",
1646
session->remote.crypt->name);
1647
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s",
1648
session->local.mac->name);
1649
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s",
1650
session->remote.mac->name);
1651
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s",
1652
session->local.comp->name);
1653
_libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s",
1654
session->remote.comp->name);
1661
/* _libssh2_kex_exchange
1663
* Returns 0 on success, non-zero on failure
1665
* Returns some errors without _libssh2_error()
1668
_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
1669
key_exchange_state_t * key_state)
1674
session->state |= LIBSSH2_STATE_KEX_ACTIVE;
1676
if (key_state->state == libssh2_NB_state_idle) {
1677
/* Prevent loop in packet_add() */
1678
session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
1681
session->kex = NULL;
1683
if (session->hostkey && session->hostkey->dtor) {
1684
session->hostkey->dtor(session,
1685
&session->server_hostkey_abstract);
1687
session->hostkey = NULL;
1690
key_state->state = libssh2_NB_state_created;
1693
if (!session->kex || !session->hostkey) {
1694
if (key_state->state == libssh2_NB_state_created) {
1695
/* Preserve in case of failure */
1696
key_state->oldlocal = session->local.kexinit;
1697
key_state->oldlocal_len = session->local.kexinit_len;
1699
session->local.kexinit = NULL;
1701
key_state->state = libssh2_NB_state_sent;
1704
if (key_state->state == libssh2_NB_state_sent) {
1705
retcode = kexinit(session);
1706
if (retcode == LIBSSH2_ERROR_EAGAIN) {
1707
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1709
} else if (retcode) {
1710
session->local.kexinit = key_state->oldlocal;
1711
session->local.kexinit_len = key_state->oldlocal_len;
1712
key_state->state = libssh2_NB_state_idle;
1713
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1714
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1718
key_state->state = libssh2_NB_state_sent1;
1721
if (key_state->state == libssh2_NB_state_sent1) {
1723
_libssh2_packet_require(session, SSH_MSG_KEXINIT,
1725
&key_state->data_len, 0, NULL, 0,
1726
&key_state->req_state);
1727
if (retcode == LIBSSH2_ERROR_EAGAIN) {
1728
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1732
if (session->local.kexinit) {
1733
LIBSSH2_FREE(session, session->local.kexinit);
1735
session->local.kexinit = key_state->oldlocal;
1736
session->local.kexinit_len = key_state->oldlocal_len;
1737
key_state->state = libssh2_NB_state_idle;
1738
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1739
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
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 (kex_agree_methods(session, key_state->data,
1750
key_state->data_len))
1751
rc = LIBSSH2_ERROR_KEX_FAILURE;
1753
key_state->state = libssh2_NB_state_sent2;
1756
key_state->state = libssh2_NB_state_sent2;
1760
if (key_state->state == libssh2_NB_state_sent2) {
1761
retcode = session->kex->exchange_keys(session,
1762
&key_state->key_state_low);
1763
if (retcode == LIBSSH2_ERROR_EAGAIN) {
1764
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1766
} else if (retcode) {
1767
rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
1768
"Unrecoverable error exchanging keys");
1773
/* Done with kexinit buffers */
1774
if (session->local.kexinit) {
1775
LIBSSH2_FREE(session, session->local.kexinit);
1776
session->local.kexinit = NULL;
1778
if (session->remote.kexinit) {
1779
LIBSSH2_FREE(session, session->remote.kexinit);
1780
session->remote.kexinit = NULL;
1783
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
1784
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
1786
key_state->state = libssh2_NB_state_idle;
1793
/* libssh2_session_method_pref
1794
* Set preferred method
1797
libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
1800
char **prefvar, *s, *newprefs;
1801
int prefs_len = strlen(prefs);
1802
const LIBSSH2_COMMON_METHOD **mlist;
1804
switch (method_type) {
1805
case LIBSSH2_METHOD_KEX:
1806
prefvar = &session->kex_prefs;
1807
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
1810
case LIBSSH2_METHOD_HOSTKEY:
1811
prefvar = &session->hostkey_prefs;
1812
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
1815
case LIBSSH2_METHOD_CRYPT_CS:
1816
prefvar = &session->local.crypt_prefs;
1817
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
1820
case LIBSSH2_METHOD_CRYPT_SC:
1821
prefvar = &session->remote.crypt_prefs;
1822
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
1825
case LIBSSH2_METHOD_MAC_CS:
1826
prefvar = &session->local.mac_prefs;
1827
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
1830
case LIBSSH2_METHOD_MAC_SC:
1831
prefvar = &session->remote.mac_prefs;
1832
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
1835
case LIBSSH2_METHOD_COMP_CS:
1836
prefvar = &session->local.comp_prefs;
1837
mlist = (const LIBSSH2_COMMON_METHOD **)
1838
_libssh2_comp_methods(session);
1841
case LIBSSH2_METHOD_COMP_SC:
1842
prefvar = &session->remote.comp_prefs;
1843
mlist = (const LIBSSH2_COMMON_METHOD **)
1844
_libssh2_comp_methods(session);
1847
case LIBSSH2_METHOD_LANG_CS:
1848
prefvar = &session->local.lang_prefs;
1852
case LIBSSH2_METHOD_LANG_SC:
1853
prefvar = &session->remote.lang_prefs;
1858
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1859
"Invalid parameter specified for method_type");
1862
s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
1864
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1865
"Error allocated space for method preferences");
1867
memcpy(s, prefs, prefs_len + 1);
1870
char *p = strchr(s, ',');
1871
int method_len = p ? (p - s) : (int) strlen(s);
1873
if (!kex_get_method_by_name(s, method_len, mlist)) {
1874
/* Strip out unsupported method */
1876
memcpy(s, p + 1, strlen(s) - method_len);
1886
s = p ? (p + 1) : NULL;
1889
if (strlen(newprefs) == 0) {
1890
LIBSSH2_FREE(session, newprefs);
1891
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
1892
"The requested method(s) are not currently "
1897
LIBSSH2_FREE(session, *prefvar);
1899
*prefvar = newprefs;
1905
* libssh2_session_supported_algs()
1906
* returns a number of returned algorithms (a positive number) on success,
1907
* a negative number on failure
1910
LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
1917
const LIBSSH2_COMMON_METHOD **mlist;
1919
/* to prevent coredumps due to dereferencing of NULL */
1921
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,
1922
"algs must not be NULL");
1924
switch (method_type) {
1925
case LIBSSH2_METHOD_KEX:
1926
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
1929
case LIBSSH2_METHOD_HOSTKEY:
1930
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
1933
case LIBSSH2_METHOD_CRYPT_CS:
1934
case LIBSSH2_METHOD_CRYPT_SC:
1935
mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
1938
case LIBSSH2_METHOD_MAC_CS:
1939
case LIBSSH2_METHOD_MAC_SC:
1940
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
1943
case LIBSSH2_METHOD_COMP_CS:
1944
case LIBSSH2_METHOD_COMP_SC:
1945
mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods(session);
1949
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
1950
"Unknown method type");
1953
/* weird situation */
1955
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1956
"No algorithm found");
1959
mlist is looped through twice. The first time to find the number od
1960
supported algorithms (needed to allocate the proper size of array) and
1961
the second time to actually copy the pointers. Typically this function
1962
will not be called often (typically at the beginning of a session) and
1963
the number of algorithms (i.e. niumber of iterations in one loop) will
1964
not be high (typically it will not exceed 20) for quite a long time.
1966
So double looping really shouldn't be an issue and it is definitely a
1967
better solution than reallocation several times.
1970
/* count the number of supported algorithms */
1971
for ( i=0, ialg=0; NULL!=mlist[i]; i++) {
1972
/* do not count fields with NULL name */
1977
/* weird situation, no algorithm found */
1979
return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
1980
"No algorithm found");
1982
/* allocate buffer */
1983
*algs = (const char**) LIBSSH2_ALLOC(session, ialg*sizeof(const char*));
1984
if ( NULL==*algs ) {
1985
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
1986
"Memory allocation failed");
1988
/* Past this point *algs must be deallocated in case of an error!! */
1990
/* copy non-NULL pointers only */
1991
for ( i=0, j=0; NULL!=mlist[i] && j<ialg; i++ ) {
1992
if ( NULL==mlist[i]->name ){
1993
/* maybe a weird situation but if it occurs, do not include NULL
1998
/* note that [] has higher priority than * (dereferencing) */
1999
(*algs)[j++] = mlist[i]->name;
2002
/* correct number of pointers copied? (test the code above) */
2004
/* deallocate buffer */
2005
LIBSSH2_FREE(session, (void *)*algs);
2008
return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE,