~psiphon-inc/psiphon/trunk

« back to all changes in this revision

Viewing changes to trunk/PsiphonX/libraries/src/libssh2/kex.c

  • Committer: Adam Kruger
  • Date: 2011-02-07 20:43:10 UTC
  • mfrom: (157.1.3 psiphon-with-psiphonx)
  • Revision ID: akruger@kruger-xps-20110207204310-6ph82r21rce8ldze
Merge PsiphonX.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
 
2
 * All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms,
 
5
 * with or without modification, are permitted provided
 
6
 * that the following conditions are met:
 
7
 *
 
8
 *   Redistributions of source code must retain the above
 
9
 *   copyright notice, this list of conditions and the
 
10
 *   following disclaimer.
 
11
 *
 
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.
 
16
 *
 
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.
 
21
 *
 
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
 
35
 * OF SUCH DAMAGE.
 
36
 */
 
37
 
 
38
#include "libssh2_priv.h"
 
39
 
 
40
#include "transport.h"
 
41
#include "comp.h"
 
42
#include "mac.h"
 
43
 
 
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) \
 
47
    {                                                                   \
 
48
        libssh2_sha1_ctx hash;                                          \
 
49
        unsigned long len = 0;                                          \
 
50
        if (!(value)) {                                                 \
 
51
            value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \
 
52
        }                                                               \
 
53
        if (value)                                                      \
 
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,   \
 
59
                                    SHA_DIGEST_LENGTH);                 \
 
60
                if (len > 0) {                                          \
 
61
                    libssh2_sha1_update(hash, value, len);              \
 
62
                }    else {                                             \
 
63
                    libssh2_sha1_update(hash, (version), 1);            \
 
64
                    libssh2_sha1_update(hash, session->session_id,      \
 
65
                                        session->session_id_len);       \
 
66
                }                                                       \
 
67
                libssh2_sha1_final(hash, (value) + len);                \
 
68
                len += SHA_DIGEST_LENGTH;                               \
 
69
            }                                                           \
 
70
    }
 
71
 
 
72
/*
 
73
 * diffie_hellman_sha1
 
74
 *
 
75
 * Diffie Hellman Key Exchange, Group Agnostic
 
76
 */
 
77
static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
 
78
                               _libssh2_bn *g,
 
79
                               _libssh2_bn *p,
 
80
                               int group_order,
 
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)
 
86
{
 
87
    int ret = 0;
 
88
    int rc;
 
89
 
 
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 */
 
100
 
 
101
        /* Zero the whole thing out */
 
102
        memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t));
 
103
 
 
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);
 
108
 
 
109
        /* Send KEX init */
 
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--;
 
116
        }
 
117
 
 
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");
 
123
            goto clean_exit;
 
124
        }
 
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);
 
131
        } else {
 
132
            exchange_state->e_packet[5] = 0;
 
133
            _libssh2_bn_to_bin(exchange_state->e,
 
134
                               exchange_state->e_packet + 6);
 
135
        }
 
136
 
 
137
        _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d",
 
138
                       (int) packet_type_init);
 
139
        exchange_state->state = libssh2_NB_state_created;
 
140
    }
 
141
 
 
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) {
 
146
            return rc;
 
147
        } else if (rc) {
 
148
            ret = _libssh2_error(session, rc,
 
149
                                 "Unable to send KEX init message");
 
150
            goto clean_exit;
 
151
        }
 
152
        exchange_state->state = libssh2_NB_state_sent;
 
153
    }
 
154
 
 
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 */
 
160
            int burn_type;
 
161
 
 
162
            _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
163
                           "Waiting for badly guessed KEX packet (to be ignored)");
 
164
            burn_type =
 
165
                _libssh2_packet_burn(session, &exchange_state->burn_state);
 
166
            if (burn_type == LIBSSH2_ERROR_EAGAIN) {
 
167
                return burn_type;
 
168
            } else if (burn_type <= 0) {
 
169
                /* Failed to receive a packet */
 
170
                ret = burn_type;
 
171
                goto clean_exit;
 
172
            }
 
173
            session->burn_optimistic_kexinit = 0;
 
174
 
 
175
            _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
176
                           "Burnt packet of type: %02x",
 
177
                           (unsigned int) burn_type);
 
178
        }
 
179
 
 
180
        exchange_state->state = libssh2_NB_state_sent1;
 
181
    }
 
182
 
 
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) {
 
190
            return rc;
 
191
        }
 
192
        if (rc) {
 
193
            ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
 
194
                                 "Timed out waiting for KEX reply");
 
195
            goto clean_exit;
 
196
        }
 
197
 
 
198
        /* Parse KEXDH_REPLY */
 
199
        exchange_state->s = exchange_state->s_packet + 1;
 
200
 
 
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 "
 
208
                                 "of the host key");
 
209
            goto clean_exit;
 
210
        }
 
211
        memcpy(session->server_hostkey, exchange_state->s,
 
212
               session->server_hostkey_len);
 
213
        exchange_state->s += session->server_hostkey_len;
 
214
 
 
215
#if LIBSSH2_MD5
 
216
        {
 
217
            libssh2_md5_ctx fingerprint_ctx;
 
218
 
 
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);
 
223
        }
 
224
#ifdef LIBSSH2DEBUG
 
225
        {
 
226
            char fingerprint[50], *fprint = fingerprint;
 
227
            int i;
 
228
            for(i = 0; i < 16; i++, fprint += 3) {
 
229
                snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]);
 
230
            }
 
231
            *(--fprint) = '\0';
 
232
            _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
233
                           "Server's MD5 Fingerprint: %s", fingerprint);
 
234
        }
 
235
#endif /* LIBSSH2DEBUG */
 
236
#endif /* ! LIBSSH2_MD5 */
 
237
 
 
238
        {
 
239
            libssh2_sha1_ctx fingerprint_ctx;
 
240
 
 
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);
 
245
        }
 
246
#ifdef LIBSSH2DEBUG
 
247
        {
 
248
            char fingerprint[64], *fprint = fingerprint;
 
249
            int i;
 
250
 
 
251
            for(i = 0; i < 20; i++, fprint += 3) {
 
252
                snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]);
 
253
            }
 
254
            *(--fprint) = '\0';
 
255
            _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
256
                           "Server's SHA1 Fingerprint: %s", fingerprint);
 
257
        }
 
258
#endif /* LIBSSH2DEBUG */
 
259
 
 
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");
 
265
            goto clean_exit;
 
266
        }
 
267
 
 
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);
 
274
 
 
275
        exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s);
 
276
        exchange_state->s += 4;
 
277
        exchange_state->h_sig = exchange_state->s;
 
278
 
 
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--;
 
286
        }
 
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");
 
292
            goto clean_exit;
 
293
        }
 
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);
 
298
        } else {
 
299
            exchange_state->k_value[4] = 0;
 
300
            _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5);
 
301
        }
 
302
 
 
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);
 
312
        } else {
 
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);
 
320
        }
 
321
 
 
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));
 
329
 
 
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);
 
337
 
 
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);
 
345
 
 
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);
 
353
 
 
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);
 
365
#else
 
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);
 
370
#endif
 
371
        }
 
372
 
 
373
        if (midhash) {
 
374
            libssh2_sha1_update(exchange_state->exchange_hash, midhash,
 
375
                                midhash_len);
 
376
        }
 
377
 
 
378
        libssh2_sha1_update(exchange_state->exchange_hash,
 
379
                            exchange_state->e_packet + 1,
 
380
                            exchange_state->e_packet_len - 1);
 
381
 
 
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);
 
389
 
 
390
        libssh2_sha1_update(exchange_state->exchange_hash,
 
391
                            exchange_state->k_value,
 
392
                            exchange_state->k_value_len);
 
393
 
 
394
        libssh2_sha1_final(exchange_state->exchange_hash,
 
395
                           exchange_state->h_sig_comp);
 
396
 
 
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");
 
403
            goto clean_exit;
 
404
        }
 
405
 
 
406
        _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message");
 
407
        exchange_state->c = SSH_MSG_NEWKEYS;
 
408
 
 
409
        exchange_state->state = libssh2_NB_state_sent2;
 
410
    }
 
411
 
 
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) {
 
415
            return rc;
 
416
        } else if (rc) {
 
417
            ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message");
 
418
            goto clean_exit;
 
419
        }
 
420
 
 
421
        exchange_state->state = libssh2_NB_state_sent3;
 
422
    }
 
423
 
 
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) {
 
430
            return rc;
 
431
        } else if (rc) {
 
432
            ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS");
 
433
            goto clean_exit;
 
434
        }
 
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");
 
439
 
 
440
        /* This will actually end up being just packet_type(1)
 
441
           for this packet type anyway */
 
442
        LIBSSH2_FREE(session, exchange_state->tmp);
 
443
 
 
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");
 
449
                goto clean_exit;
 
450
            }
 
451
            memcpy(session->session_id, exchange_state->h_sig_comp,
 
452
                   SHA_DIGEST_LENGTH);
 
453
            session->session_id_len = SHA_DIGEST_LENGTH;
 
454
            _libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated");
 
455
        }
 
456
 
 
457
        /* Cleanup any existing cipher */
 
458
        if (session->local.crypt->dtor) {
 
459
            session->local.crypt->dtor(session,
 
460
                                       &session->local.crypt_abstract);
 
461
        }
 
462
 
 
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;
 
467
 
 
468
            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
 
469
                                                        session->local.crypt->
 
470
                                                        iv_len, "A");
 
471
            if (!iv) {
 
472
                ret = -1;
 
473
                goto clean_exit;
 
474
            }
 
475
            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
 
476
                                                        session->local.crypt->
 
477
                                                        secret_len, "C");
 
478
            if (!secret) {
 
479
                LIBSSH2_FREE(session, iv);
 
480
                ret = LIBSSH2_ERROR_KEX_FAILURE;
 
481
                goto clean_exit;
 
482
            }
 
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;
 
489
                goto clean_exit;
 
490
            }
 
491
 
 
492
            if (free_iv) {
 
493
                memset(iv, 0, session->local.crypt->iv_len);
 
494
                LIBSSH2_FREE(session, iv);
 
495
            }
 
496
 
 
497
            if (free_secret) {
 
498
                memset(secret, 0, session->local.crypt->secret_len);
 
499
                LIBSSH2_FREE(session, secret);
 
500
            }
 
501
        }
 
502
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
503
                       "Client to Server IV and Key calculated");
 
504
 
 
505
        if (session->remote.crypt->dtor) {
 
506
            /* Cleanup any existing cipher */
 
507
            session->remote.crypt->dtor(session,
 
508
                                        &session->remote.crypt_abstract);
 
509
        }
 
510
 
 
511
        if (session->remote.crypt->init) {
 
512
            unsigned char *iv = NULL, *secret = NULL;
 
513
            int free_iv = 0, free_secret = 0;
 
514
 
 
515
            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
 
516
                                                        session->remote.crypt->
 
517
                                                        iv_len, "B");
 
518
            if (!iv) {
 
519
                ret = LIBSSH2_ERROR_KEX_FAILURE;
 
520
                goto clean_exit;
 
521
            }
 
522
            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
 
523
                                                        session->remote.crypt->
 
524
                                                        secret_len, "D");
 
525
            if (!secret) {
 
526
                LIBSSH2_FREE(session, iv);
 
527
                ret = LIBSSH2_ERROR_KEX_FAILURE;
 
528
                goto clean_exit;
 
529
            }
 
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;
 
536
                goto clean_exit;
 
537
            }
 
538
 
 
539
            if (free_iv) {
 
540
                memset(iv, 0, session->remote.crypt->iv_len);
 
541
                LIBSSH2_FREE(session, iv);
 
542
            }
 
543
 
 
544
            if (free_secret) {
 
545
                memset(secret, 0, session->remote.crypt->secret_len);
 
546
                LIBSSH2_FREE(session, secret);
 
547
            }
 
548
        }
 
549
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
550
                       "Server to Client IV and Key calculated");
 
551
 
 
552
        if (session->local.mac->dtor) {
 
553
            session->local.mac->dtor(session, &session->local.mac_abstract);
 
554
        }
 
555
 
 
556
        if (session->local.mac->init) {
 
557
            unsigned char *key = NULL;
 
558
            int free_key = 0;
 
559
 
 
560
            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
 
561
                                                        session->local.mac->
 
562
                                                        key_len, "E");
 
563
            if (!key) {
 
564
                ret = LIBSSH2_ERROR_KEX_FAILURE;
 
565
                goto clean_exit;
 
566
            }
 
567
            session->local.mac->init(session, key, &free_key,
 
568
                                     &session->local.mac_abstract);
 
569
 
 
570
            if (free_key) {
 
571
                memset(key, 0, session->local.mac->key_len);
 
572
                LIBSSH2_FREE(session, key);
 
573
            }
 
574
        }
 
575
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
576
                       "Client to Server HMAC Key calculated");
 
577
 
 
578
        if (session->remote.mac->dtor) {
 
579
            session->remote.mac->dtor(session, &session->remote.mac_abstract);
 
580
        }
 
581
 
 
582
        if (session->remote.mac->init) {
 
583
            unsigned char *key = NULL;
 
584
            int free_key = 0;
 
585
 
 
586
            LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
 
587
                                                        session->remote.mac->
 
588
                                                        key_len, "F");
 
589
            if (!key) {
 
590
                ret = LIBSSH2_ERROR_KEX_FAILURE;
 
591
                goto clean_exit;
 
592
            }
 
593
            session->remote.mac->init(session, key, &free_key,
 
594
                                      &session->remote.mac_abstract);
 
595
 
 
596
            if (free_key) {
 
597
                memset(key, 0, session->remote.mac->key_len);
 
598
                LIBSSH2_FREE(session, key);
 
599
            }
 
600
        }
 
601
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
602
                       "Server to Client HMAC Key calculated");
 
603
 
 
604
        /* Initialize compression for each direction */
 
605
 
 
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);
 
610
        }
 
611
 
 
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;
 
616
                goto clean_exit;
 
617
            }
 
618
        }
 
619
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
620
                       "Client to Server compression initialized");
 
621
 
 
622
        if (session->remote.comp && session->remote.comp->dtor) {
 
623
            session->remote.comp->dtor(session, 0,
 
624
                                       &session->remote.comp_abstract);
 
625
        }
 
626
 
 
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;
 
631
                goto clean_exit;
 
632
            }
 
633
        }
 
634
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
635
                       "Server to Client compression initialized");
 
636
 
 
637
    }
 
638
 
 
639
  clean_exit:
 
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;
 
650
 
 
651
    if (exchange_state->e_packet) {
 
652
        LIBSSH2_FREE(session, exchange_state->e_packet);
 
653
        exchange_state->e_packet = NULL;
 
654
    }
 
655
 
 
656
    if (exchange_state->s_packet) {
 
657
        LIBSSH2_FREE(session, exchange_state->s_packet);
 
658
        exchange_state->s_packet = NULL;
 
659
    }
 
660
 
 
661
    if (exchange_state->k_value) {
 
662
        LIBSSH2_FREE(session, exchange_state->k_value);
 
663
        exchange_state->k_value = NULL;
 
664
    }
 
665
 
 
666
    exchange_state->state = libssh2_NB_state_idle;
 
667
 
 
668
    return ret;
 
669
}
 
670
 
 
671
 
 
672
 
 
673
/* kex_method_diffie_hellman_group1_sha1_key_exchange
 
674
 * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1
 
675
 */
 
676
static int
 
677
kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session,
 
678
                                                   key_exchange_state_low_t
 
679
                                                   * key_state)
 
680
{
 
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
 
698
    };
 
699
 
 
700
    int ret;
 
701
 
 
702
    if (key_state->state == libssh2_NB_state_idle) {
 
703
        /* g == 2 */
 
704
        key_state->p = _libssh2_bn_init();      /* SSH2 defined value (p_value) */
 
705
        key_state->g = _libssh2_bn_init();      /* SSH2 defined value (2) */
 
706
 
 
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);
 
710
 
 
711
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
712
                       "Initiating Diffie-Hellman Group1 Key Exchange");
 
713
 
 
714
        key_state->state = libssh2_NB_state_created;
 
715
    }
 
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) {
 
720
        return ret;
 
721
    }
 
722
 
 
723
    _libssh2_bn_free(key_state->p);
 
724
    key_state->p = NULL;
 
725
    _libssh2_bn_free(key_state->g);
 
726
    key_state->g = NULL;
 
727
    key_state->state = libssh2_NB_state_idle;
 
728
 
 
729
    return ret;
 
730
}
 
731
 
 
732
 
 
733
 
 
734
/* kex_method_diffie_hellman_group14_sha1_key_exchange
 
735
 * Diffie-Hellman Group14 Key Exchange using SHA1
 
736
 */
 
737
static int
 
738
kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session,
 
739
                                                    key_exchange_state_low_t
 
740
                                                    * key_state)
 
741
{
 
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
 
775
    };
 
776
    int ret;
 
777
 
 
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) */
 
781
 
 
782
        /* g == 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);
 
786
 
 
787
        _libssh2_debug(session, LIBSSH2_TRACE_KEX,
 
788
                       "Initiating Diffie-Hellman Group14 Key Exchange");
 
789
 
 
790
        key_state->state = libssh2_NB_state_created;
 
791
    }
 
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) {
 
796
        return ret;
 
797
    }
 
798
 
 
799
    key_state->state = libssh2_NB_state_idle;
 
800
    _libssh2_bn_free(key_state->p);
 
801
    key_state->p = NULL;
 
802
    _libssh2_bn_free(key_state->g);
 
803
    key_state->g = NULL;
 
804
 
 
805
    return ret;
 
806
}
 
807
 
 
808
 
 
809
 
 
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
 
813
 */
 
814
static int
 
815
kex_method_diffie_hellman_group_exchange_sha1_key_exchange
 
816
(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state)
 
817
{
 
818
    unsigned long p_len, g_len;
 
819
    int ret = 0;
 
820
    int rc;
 
821
 
 
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)");
 
834
#else
 
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)");
 
840
#endif
 
841
 
 
842
        key_state->state = libssh2_NB_state_created;
 
843
    }
 
844
 
 
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) {
 
849
            return rc;
 
850
        } else if (rc) {
 
851
            ret = _libssh2_error(session, rc,
 
852
                                 "Unable to send Group Exchange Request");
 
853
            goto dh_gex_clean_exit;
 
854
        }
 
855
 
 
856
        key_state->state = libssh2_NB_state_sent;
 
857
    }
 
858
 
 
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) {
 
864
            return rc;
 
865
        } else if (rc) {
 
866
            ret = _libssh2_error(session, rc,
 
867
                                 "Timeout waiting for GEX_GROUP reply");
 
868
            goto dh_gex_clean_exit;
 
869
        }
 
870
 
 
871
        key_state->state = libssh2_NB_state_sent1;
 
872
    }
 
873
 
 
874
    if (key_state->state == libssh2_NB_state_sent1) {
 
875
        unsigned char *s = key_state->data + 1;
 
876
        p_len = _libssh2_ntohu32(s);
 
877
        s += 4;
 
878
        _libssh2_bn_from_bin(key_state->p, p_len, s);
 
879
        s += p_len;
 
880
 
 
881
        g_len = _libssh2_ntohu32(s);
 
882
        s += 4;
 
883
        _libssh2_bn_from_bin(key_state->g, g_len, s);
 
884
 
 
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,
 
888
                                  key_state->data + 1,
 
889
                                  key_state->data_len - 1,
 
890
                                  &key_state->exchange_state);
 
891
        if (ret == LIBSSH2_ERROR_EAGAIN) {
 
892
            return ret;
 
893
        }
 
894
 
 
895
        LIBSSH2_FREE(session, key_state->data);
 
896
    }
 
897
 
 
898
  dh_gex_clean_exit:
 
899
    key_state->state = libssh2_NB_state_idle;
 
900
    _libssh2_bn_free(key_state->g);
 
901
    key_state->g = NULL;
 
902
    _libssh2_bn_free(key_state->p);
 
903
    key_state->p = NULL;
 
904
 
 
905
    return ret;
 
906
}
 
907
 
 
908
 
 
909
 
 
910
#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY     0x0001
 
911
#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY    0x0002
 
912
 
 
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,
 
917
};
 
918
 
 
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,
 
923
};
 
924
 
 
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,
 
930
};
 
931
 
 
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,
 
936
    NULL
 
937
};
 
938
 
 
939
typedef struct _LIBSSH2_COMMON_METHOD
 
940
{
 
941
    const char *name;
 
942
} LIBSSH2_COMMON_METHOD;
 
943
 
 
944
/* kex_method_strlen
 
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.
 
948
 */
 
949
static size_t
 
950
kex_method_strlen(LIBSSH2_COMMON_METHOD ** method)
 
951
{
 
952
    size_t len = 0;
 
953
 
 
954
    if (!method || !*method) {
 
955
        return 0;
 
956
    }
 
957
 
 
958
    while (*method && (*method)->name) {
 
959
        len += strlen((*method)->name) + 1;
 
960
        method++;
 
961
    }
 
962
 
 
963
    return len - 1;
 
964
}
 
965
 
 
966
 
 
967
 
 
968
/* kex_method_list
 
969
 * Generate formatted preference list in buf
 
970
 */
 
971
static size_t
 
972
kex_method_list(unsigned char *buf, size_t list_strlen,
 
973
                LIBSSH2_COMMON_METHOD ** method)
 
974
{
 
975
    _libssh2_htonu32(buf, list_strlen);
 
976
    buf += 4;
 
977
 
 
978
    if (!method || !*method) {
 
979
        return 4;
 
980
    }
 
981
 
 
982
    while (*method && (*method)->name) {
 
983
        int mlen = strlen((*method)->name);
 
984
        memcpy(buf, (*method)->name, mlen);
 
985
        buf += mlen;
 
986
        *(buf++) = ',';
 
987
        method++;
 
988
    }
 
989
 
 
990
    return list_strlen + 4;
 
991
}
 
992
 
 
993
 
 
994
 
 
995
#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar)           \
 
996
    ((prefvar) ? strlen(prefvar) :                              \
 
997
     kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar)))
 
998
 
 
999
#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar)  \
 
1000
    if (prefvar) {                                                      \
 
1001
        _libssh2_htonu32((buf), (prefvarlen));                          \
 
1002
        buf += 4;                                                       \
 
1003
        memcpy((buf), (prefvar), (prefvarlen));                         \
 
1004
        buf += (prefvarlen);                                            \
 
1005
    } else {                                                            \
 
1006
        buf += kex_method_list((buf), (prefvarlen),                     \
 
1007
                               (LIBSSH2_COMMON_METHOD**)(defaultvar));  \
 
1008
    }
 
1009
 
 
1010
/* kexinit
 
1011
 * Send SSH_MSG_KEXINIT packet
 
1012
 */
 
1013
static int kexinit(LIBSSH2_SESSION * session)
 
1014
{
 
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;
 
1024
    int rc;
 
1025
 
 
1026
    if (session->kexinit_state == libssh2_NB_state_idle) {
 
1027
        kex_len =
 
1028
            LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods);
 
1029
        hostkey_len =
 
1030
            LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs,
 
1031
                                     libssh2_hostkey_methods());
 
1032
        crypt_cs_len =
 
1033
            LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs,
 
1034
                                     libssh2_crypt_methods());
 
1035
        crypt_sc_len =
 
1036
            LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs,
 
1037
                                     libssh2_crypt_methods());
 
1038
        mac_cs_len =
 
1039
            LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs,
 
1040
                                     _libssh2_mac_methods());
 
1041
        mac_sc_len =
 
1042
            LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs,
 
1043
                                     _libssh2_mac_methods());
 
1044
        comp_cs_len =
 
1045
            LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs,
 
1046
                                     _libssh2_comp_methods());
 
1047
        comp_sc_len =
 
1048
            LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs,
 
1049
                                     _libssh2_comp_methods());
 
1050
        lang_cs_len =
 
1051
            LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL);
 
1052
        lang_sc_len =
 
1053
            LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL);
 
1054
 
 
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;
 
1058
 
 
1059
        s = data = LIBSSH2_ALLOC(session, data_len);
 
1060
        if (!data) {
 
1061
            return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
 
1062
                                  "Unable to allocate memory");
 
1063
        }
 
1064
 
 
1065
        *(s++) = SSH_MSG_KEXINIT;
 
1066
 
 
1067
        _libssh2_random(s, 16);
 
1068
        s += 16;
 
1069
 
 
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,
 
1090
                                 NULL);
 
1091
        LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs,
 
1092
                                 NULL);
 
1093
 
 
1094
        /* No optimistic KEX packet follows */
 
1095
        /* Deal with optimistic packets
 
1096
         * session->flags |= KEXINIT_OPTIMISTIC
 
1097
         * session->flags |= KEXINIT_METHODSMATCH
 
1098
         */
 
1099
        *(s++) = 0;
 
1100
 
 
1101
        /* Reserved == 0 */
 
1102
        _libssh2_htonu32(s, 0);
 
1103
 
 
1104
#ifdef LIBSSH2DEBUG
 
1105
        {
 
1106
            /* Funnily enough, they'll all "appear" to be '\0' terminated */
 
1107
            unsigned char *p = data + 21;       /* type(1) + cookie(16) + len(4) */
 
1108
 
 
1109
            _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p);
 
1110
            p += kex_len + 4;
 
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;
 
1129
        }
 
1130
#endif /* LIBSSH2DEBUG */
 
1131
 
 
1132
        session->kexinit_state = libssh2_NB_state_created;
 
1133
    } else {
 
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;
 
1139
    }
 
1140
 
 
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;
 
1145
        return rc;
 
1146
    }
 
1147
    else if (rc) {
 
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");
 
1152
 
 
1153
    }
 
1154
 
 
1155
    if (session->local.kexinit) {
 
1156
        LIBSSH2_FREE(session, session->local.kexinit);
 
1157
    }
 
1158
 
 
1159
    session->local.kexinit = data;
 
1160
    session->local.kexinit_len = data_len;
 
1161
 
 
1162
    session->kexinit_state = libssh2_NB_state_idle;
 
1163
 
 
1164
    return 0;
 
1165
}
 
1166
 
 
1167
/* kex_agree_instr
 
1168
 * Kex specific variant of strstr()
 
1169
 * Needle must be preceed by BOL or ',', and followed by ',' or EOL
 
1170
 */
 
1171
static unsigned char *
 
1172
kex_agree_instr(unsigned char *haystack, unsigned long haystack_len,
 
1173
                const unsigned char *needle, unsigned long needle_len)
 
1174
{
 
1175
    unsigned char *s;
 
1176
 
 
1177
    /* Haystack too short to bother trying */
 
1178
    if (haystack_len < needle_len) {
 
1179
        return NULL;
 
1180
    }
 
1181
 
 
1182
    /* Needle at start of haystack */
 
1183
    if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) &&
 
1184
        (needle_len == haystack_len || haystack[needle_len] == ',')) {
 
1185
        return haystack;
 
1186
    }
 
1187
 
 
1188
    s = haystack;
 
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)) {
 
1193
        s++;
 
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] == ',')) {
 
1198
            return s;
 
1199
        }
 
1200
    }
 
1201
 
 
1202
    return NULL;
 
1203
}
 
1204
 
 
1205
 
 
1206
 
 
1207
/* kex_get_method_by_name
 
1208
 */
 
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)
 
1212
{
 
1213
    while (*methodlist) {
 
1214
        if ((strlen((*methodlist)->name) == name_len) &&
 
1215
            (strncmp((*methodlist)->name, name, name_len) == 0)) {
 
1216
            return *methodlist;
 
1217
        }
 
1218
        methodlist++;
 
1219
    }
 
1220
    return NULL;
 
1221
}
 
1222
 
 
1223
 
 
1224
 
 
1225
/* kex_agree_hostkey
 
1226
 * Agree on a Hostkey which works with this kex
 
1227
 */
 
1228
static int kex_agree_hostkey(LIBSSH2_SESSION * session,
 
1229
                             unsigned long kex_flags,
 
1230
                             unsigned char *hostkey, unsigned long hostkey_len)
 
1231
{
 
1232
    const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods();
 
1233
    unsigned char *s;
 
1234
 
 
1235
    if (session->hostkey_prefs) {
 
1236
        s = (unsigned char *) session->hostkey_prefs;
 
1237
 
 
1238
        while (s && *s) {
 
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 **)
 
1246
                                           hostkeyp);
 
1247
 
 
1248
                if (!method) {
 
1249
                    /* Invalid method -- Should never be reached */
 
1250
                    return -1;
 
1251
                }
 
1252
 
 
1253
                /* So far so good, but does it suit our purposes? (Encrypting
 
1254
                   vs Signing) */
 
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;
 
1264
                        return 0;
 
1265
                    }
 
1266
                }
 
1267
            }
 
1268
 
 
1269
            s = p ? p + 1 : NULL;
 
1270
        }
 
1271
        return -1;
 
1272
    }
 
1273
 
 
1274
    while (hostkeyp && (*hostkeyp)->name) {
 
1275
        s = kex_agree_instr(hostkey, hostkey_len,
 
1276
                            (unsigned char *) (*hostkeyp)->name,
 
1277
                            strlen((*hostkeyp)->name));
 
1278
        if (s) {
 
1279
            /* So far so good, but does it suit our purposes? (Encrypting vs
 
1280
               Signing) */
 
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;
 
1290
                    return 0;
 
1291
                }
 
1292
            }
 
1293
        }
 
1294
        hostkeyp++;
 
1295
    }
 
1296
 
 
1297
    return -1;
 
1298
}
 
1299
 
 
1300
 
 
1301
 
 
1302
/* kex_agree_kex_hostkey
 
1303
 * Agree on a Key Exchange method and a hostkey encoding type
 
1304
 */
 
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)
 
1308
{
 
1309
    const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
 
1310
    unsigned char *s;
 
1311
 
 
1312
    if (session->kex_prefs) {
 
1313
        s = (unsigned char *) session->kex_prefs;
 
1314
 
 
1315
        while (s && *s) {
 
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 **)
 
1322
                                           kexp);
 
1323
 
 
1324
                if (!method) {
 
1325
                    /* Invalid method -- Should never be reached */
 
1326
                    return -1;
 
1327
                }
 
1328
 
 
1329
                /* We've agreed on a key exchange method,
 
1330
                 * Can we agree on a hostkey that works with this kex?
 
1331
                 */
 
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;
 
1340
                    }
 
1341
                    return 0;
 
1342
                }
 
1343
            }
 
1344
 
 
1345
            s = p ? p + 1 : NULL;
 
1346
        }
 
1347
        return -1;
 
1348
    }
 
1349
 
 
1350
    while (*kexp && (*kexp)->name) {
 
1351
        s = kex_agree_instr(kex, kex_len,
 
1352
                            (unsigned char *) (*kexp)->name,
 
1353
                            strlen((*kexp)->name));
 
1354
        if (s) {
 
1355
            /* We've agreed on a key exchange method,
 
1356
             * Can we agree on a hostkey that works with this kex?
 
1357
             */
 
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;
 
1366
                }
 
1367
                return 0;
 
1368
            }
 
1369
        }
 
1370
        kexp++;
 
1371
    }
 
1372
    return -1;
 
1373
}
 
1374
 
 
1375
 
 
1376
 
 
1377
/* kex_agree_crypt
 
1378
 * Agree on a cipher algo
 
1379
 */
 
1380
static int kex_agree_crypt(LIBSSH2_SESSION * session,
 
1381
                           libssh2_endpoint_data *endpoint,
 
1382
                           unsigned char *crypt,
 
1383
                           unsigned long crypt_len)
 
1384
{
 
1385
    const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods();
 
1386
    unsigned char *s;
 
1387
 
 
1388
    (void) session;
 
1389
 
 
1390
    if (endpoint->crypt_prefs) {
 
1391
        s = (unsigned char *) endpoint->crypt_prefs;
 
1392
 
 
1393
        while (s && *s) {
 
1394
            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
 
1395
            size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
 
1396
 
 
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 **)
 
1402
                                           cryptp);
 
1403
 
 
1404
                if (!method) {
 
1405
                    /* Invalid method -- Should never be reached */
 
1406
                    return -1;
 
1407
                }
 
1408
 
 
1409
                endpoint->crypt = method;
 
1410
                return 0;
 
1411
            }
 
1412
 
 
1413
            s = p ? p + 1 : NULL;
 
1414
        }
 
1415
        return -1;
 
1416
    }
 
1417
 
 
1418
    while (*cryptp && (*cryptp)->name) {
 
1419
        s = kex_agree_instr(crypt, crypt_len,
 
1420
                            (unsigned char *) (*cryptp)->name,
 
1421
                            strlen((*cryptp)->name));
 
1422
        if (s) {
 
1423
            endpoint->crypt = *cryptp;
 
1424
            return 0;
 
1425
        }
 
1426
        cryptp++;
 
1427
    }
 
1428
 
 
1429
    return -1;
 
1430
}
 
1431
 
 
1432
 
 
1433
 
 
1434
/* kex_agree_mac
 
1435
 * Agree on a message authentication hash
 
1436
 */
 
1437
static int kex_agree_mac(LIBSSH2_SESSION * session,
 
1438
                         libssh2_endpoint_data * endpoint, unsigned char *mac,
 
1439
                         unsigned long mac_len)
 
1440
{
 
1441
    const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods();
 
1442
    unsigned char *s;
 
1443
    (void) session;
 
1444
 
 
1445
    if (endpoint->mac_prefs) {
 
1446
        s = (unsigned char *) endpoint->mac_prefs;
 
1447
 
 
1448
        while (s && *s) {
 
1449
            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
 
1450
            size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
 
1451
 
 
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 **)
 
1456
                                           macp);
 
1457
 
 
1458
                if (!method) {
 
1459
                    /* Invalid method -- Should never be reached */
 
1460
                    return -1;
 
1461
                }
 
1462
 
 
1463
                endpoint->mac = method;
 
1464
                return 0;
 
1465
            }
 
1466
 
 
1467
            s = p ? p + 1 : NULL;
 
1468
        }
 
1469
        return -1;
 
1470
    }
 
1471
 
 
1472
    while (*macp && (*macp)->name) {
 
1473
        s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
 
1474
                            strlen((*macp)->name));
 
1475
        if (s) {
 
1476
            endpoint->mac = *macp;
 
1477
            return 0;
 
1478
        }
 
1479
        macp++;
 
1480
    }
 
1481
 
 
1482
    return -1;
 
1483
}
 
1484
 
 
1485
 
 
1486
 
 
1487
/* kex_agree_comp
 
1488
 * Agree on a compression scheme
 
1489
 */
 
1490
static int kex_agree_comp(LIBSSH2_SESSION * session,
 
1491
                          libssh2_endpoint_data * endpoint, unsigned char *comp,
 
1492
                          unsigned long comp_len)
 
1493
{
 
1494
    const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods();
 
1495
    unsigned char *s;
 
1496
    (void) session;
 
1497
 
 
1498
    if (endpoint->comp_prefs) {
 
1499
        s = (unsigned char *) endpoint->comp_prefs;
 
1500
 
 
1501
        while (s && *s) {
 
1502
            unsigned char *p = (unsigned char *) strchr((char *) s, ',');
 
1503
            size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
 
1504
 
 
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 **)
 
1510
                                           compp);
 
1511
 
 
1512
                if (!method) {
 
1513
                    /* Invalid method -- Should never be reached */
 
1514
                    return -1;
 
1515
                }
 
1516
 
 
1517
                endpoint->comp = method;
 
1518
                return 0;
 
1519
            }
 
1520
 
 
1521
            s = p ? p + 1 : NULL;
 
1522
        }
 
1523
        return -1;
 
1524
    }
 
1525
 
 
1526
    while (*compp && (*compp)->name) {
 
1527
        s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
 
1528
                            strlen((*compp)->name));
 
1529
        if (s) {
 
1530
            endpoint->comp = *compp;
 
1531
            return 0;
 
1532
        }
 
1533
        compp++;
 
1534
    }
 
1535
 
 
1536
    return -1;
 
1537
}
 
1538
 
 
1539
 
 
1540
 
 
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"
 
1543
 */
 
1544
 
 
1545
/* kex_agree_methods
 
1546
 * Decide which specific method to use of the methods offered by each party
 
1547
 */
 
1548
static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data,
 
1549
                             unsigned data_len)
 
1550
{
 
1551
    unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc,
 
1552
        *mac_cs, *mac_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;
 
1556
 
 
1557
    /* Skip packet_type, we know it already */
 
1558
    s++;
 
1559
 
 
1560
    /* Skip cookie, don't worry, it's preserved in the kexinit field */
 
1561
    s += 16;
 
1562
 
 
1563
    /* Locate each string */
 
1564
    kex_len = _libssh2_ntohu32(s);
 
1565
    kex = s + 4;
 
1566
    s += 4 + kex_len;
 
1567
    hostkey_len = _libssh2_ntohu32(s);
 
1568
    hostkey = s + 4;
 
1569
    s += 4 + hostkey_len;
 
1570
    crypt_cs_len = _libssh2_ntohu32(s);
 
1571
    crypt_cs = s + 4;
 
1572
    s += 4 + crypt_cs_len;
 
1573
    crypt_sc_len = _libssh2_ntohu32(s);
 
1574
    crypt_sc = s + 4;
 
1575
    s += 4 + crypt_sc_len;
 
1576
    mac_cs_len = _libssh2_ntohu32(s);
 
1577
    mac_cs = s + 4;
 
1578
    s += 4 + mac_cs_len;
 
1579
    mac_sc_len = _libssh2_ntohu32(s);
 
1580
    mac_sc = s + 4;
 
1581
    s += 4 + mac_sc_len;
 
1582
    comp_cs_len = _libssh2_ntohu32(s);
 
1583
    comp_cs = s + 4;
 
1584
    s += 4 + comp_cs_len;
 
1585
    comp_sc_len = _libssh2_ntohu32(s);
 
1586
    comp_sc = s + 4;
 
1587
#if 0
 
1588
    s += 4 + comp_sc_len;
 
1589
    lang_cs_len = _libssh2_ntohu32(s);
 
1590
    lang_cs = s + 4;
 
1591
    s += 4 + lang_cs_len;
 
1592
    lang_sc_len = _libssh2_ntohu32(s);
 
1593
    lang_sc = s + 4;
 
1594
    s += 4 + lang_sc_len;
 
1595
#endif
 
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) */
 
1601
 
 
1602
    if (data_len < (unsigned) (s - data))
 
1603
        return -1;              /* short packet */
 
1604
 
 
1605
    if (kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) {
 
1606
        return -1;
 
1607
    }
 
1608
 
 
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)) {
 
1611
        return -1;
 
1612
    }
 
1613
 
 
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)) {
 
1616
        return -1;
 
1617
    }
 
1618
 
 
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)) {
 
1621
        return -1;
 
1622
    }
 
1623
 
 
1624
#if 0
 
1625
    if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len)
 
1626
        || libssh2_kex_agree_lang(session, &session->remote, lang_sc,
 
1627
                                  lang_sc_len)) {
 
1628
        return -1;
 
1629
    }
 
1630
#endif
 
1631
 
 
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);
 
1648
 
 
1649
    return 0;
 
1650
}
 
1651
 
 
1652
 
 
1653
 
 
1654
/* _libssh2_kex_exchange
 
1655
 * Exchange keys
 
1656
 * Returns 0 on success, non-zero on failure
 
1657
 *
 
1658
 * Returns some errors without _libssh2_error()
 
1659
 */
 
1660
int
 
1661
_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
 
1662
                     key_exchange_state_t * key_state)
 
1663
{
 
1664
    int rc = 0;
 
1665
    int retcode;
 
1666
 
 
1667
    session->state |= LIBSSH2_STATE_KEX_ACTIVE;
 
1668
 
 
1669
    if (key_state->state == libssh2_NB_state_idle) {
 
1670
        /* Prevent loop in packet_add() */
 
1671
        session->state |= LIBSSH2_STATE_EXCHANGING_KEYS;
 
1672
 
 
1673
        if (reexchange) {
 
1674
            session->kex = NULL;
 
1675
 
 
1676
            if (session->hostkey && session->hostkey->dtor) {
 
1677
                session->hostkey->dtor(session,
 
1678
                                       &session->server_hostkey_abstract);
 
1679
            }
 
1680
            session->hostkey = NULL;
 
1681
        }
 
1682
 
 
1683
        key_state->state = libssh2_NB_state_created;
 
1684
    }
 
1685
 
 
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;
 
1691
 
 
1692
            session->local.kexinit = NULL;
 
1693
 
 
1694
            key_state->state = libssh2_NB_state_sent;
 
1695
        }
 
1696
 
 
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;
 
1701
                return retcode;
 
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;
 
1708
                return -1;
 
1709
            }
 
1710
 
 
1711
            key_state->state = libssh2_NB_state_sent1;
 
1712
        }
 
1713
 
 
1714
        if (key_state->state == libssh2_NB_state_sent1) {
 
1715
            retcode =
 
1716
                _libssh2_packet_require(session, SSH_MSG_KEXINIT,
 
1717
                                        &key_state->data,
 
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;
 
1722
                return retcode;
 
1723
            }
 
1724
            else if (retcode) {
 
1725
                if (session->local.kexinit) {
 
1726
                    LIBSSH2_FREE(session, session->local.kexinit);
 
1727
                }
 
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;
 
1733
                return -1;
 
1734
            }
 
1735
 
 
1736
            if (session->remote.kexinit) {
 
1737
                LIBSSH2_FREE(session, session->remote.kexinit);
 
1738
            }
 
1739
            session->remote.kexinit = key_state->data;
 
1740
            session->remote.kexinit_len = key_state->data_len;
 
1741
 
 
1742
            if (kex_agree_methods(session, key_state->data,
 
1743
                                  key_state->data_len))
 
1744
                rc = LIBSSH2_ERROR_KEX_FAILURE;
 
1745
 
 
1746
            key_state->state = libssh2_NB_state_sent2;
 
1747
        }
 
1748
    } else {
 
1749
        key_state->state = libssh2_NB_state_sent2;
 
1750
    }
 
1751
 
 
1752
    if (rc == 0) {
 
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;
 
1758
                return retcode;
 
1759
            } else if (retcode) {
 
1760
                rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE,
 
1761
                                    "Unrecoverable error exchanging keys");
 
1762
            }
 
1763
        }
 
1764
    }
 
1765
 
 
1766
    /* Done with kexinit buffers */
 
1767
    if (session->local.kexinit) {
 
1768
        LIBSSH2_FREE(session, session->local.kexinit);
 
1769
        session->local.kexinit = NULL;
 
1770
    }
 
1771
    if (session->remote.kexinit) {
 
1772
        LIBSSH2_FREE(session, session->remote.kexinit);
 
1773
        session->remote.kexinit = NULL;
 
1774
    }
 
1775
 
 
1776
    session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
 
1777
    session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
 
1778
 
 
1779
    key_state->state = libssh2_NB_state_idle;
 
1780
 
 
1781
    return rc;
 
1782
}
 
1783
 
 
1784
 
 
1785
 
 
1786
/* libssh2_session_method_pref
 
1787
 * Set preferred method
 
1788
 */
 
1789
LIBSSH2_API int
 
1790
libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
 
1791
                            const char *prefs)
 
1792
{
 
1793
    char **prefvar, *s, *newprefs;
 
1794
    int prefs_len = strlen(prefs);
 
1795
    const LIBSSH2_COMMON_METHOD **mlist;
 
1796
 
 
1797
    switch (method_type) {
 
1798
    case LIBSSH2_METHOD_KEX:
 
1799
        prefvar = &session->kex_prefs;
 
1800
        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods;
 
1801
        break;
 
1802
 
 
1803
    case LIBSSH2_METHOD_HOSTKEY:
 
1804
        prefvar = &session->hostkey_prefs;
 
1805
        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods();
 
1806
        break;
 
1807
 
 
1808
    case LIBSSH2_METHOD_CRYPT_CS:
 
1809
        prefvar = &session->local.crypt_prefs;
 
1810
        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
 
1811
        break;
 
1812
 
 
1813
    case LIBSSH2_METHOD_CRYPT_SC:
 
1814
        prefvar = &session->remote.crypt_prefs;
 
1815
        mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods();
 
1816
        break;
 
1817
 
 
1818
    case LIBSSH2_METHOD_MAC_CS:
 
1819
        prefvar = &session->local.mac_prefs;
 
1820
        mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
 
1821
        break;
 
1822
 
 
1823
    case LIBSSH2_METHOD_MAC_SC:
 
1824
        prefvar = &session->remote.mac_prefs;
 
1825
        mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods();
 
1826
        break;
 
1827
 
 
1828
    case LIBSSH2_METHOD_COMP_CS:
 
1829
        prefvar = &session->local.comp_prefs;
 
1830
        mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods();
 
1831
        break;
 
1832
 
 
1833
    case LIBSSH2_METHOD_COMP_SC:
 
1834
        prefvar = &session->remote.comp_prefs;
 
1835
        mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods();
 
1836
        break;
 
1837
 
 
1838
    case LIBSSH2_METHOD_LANG_CS:
 
1839
        prefvar = &session->local.lang_prefs;
 
1840
        mlist = NULL;
 
1841
        break;
 
1842
 
 
1843
    case LIBSSH2_METHOD_LANG_SC:
 
1844
        prefvar = &session->remote.lang_prefs;
 
1845
        mlist = NULL;
 
1846
        break;
 
1847
 
 
1848
    default:
 
1849
        return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
 
1850
                              "Invalid parameter specified for method_type");
 
1851
    }
 
1852
 
 
1853
    s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1);
 
1854
    if (!newprefs) {
 
1855
        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
 
1856
                              "Error allocated space for method preferences");
 
1857
    }
 
1858
    memcpy(s, prefs, prefs_len + 1);
 
1859
 
 
1860
    while (s && *s) {
 
1861
        char *p = strchr(s, ',');
 
1862
        int method_len = p ? (p - s) : (int) strlen(s);
 
1863
 
 
1864
        if (!kex_get_method_by_name(s, method_len, mlist)) {
 
1865
            /* Strip out unsupported method */
 
1866
            if (p) {
 
1867
                memcpy(s, p + 1, strlen(s) - method_len);
 
1868
            } else {
 
1869
                if (s > newprefs) {
 
1870
                    *(--s) = '\0';
 
1871
                } else {
 
1872
                    *s = '\0';
 
1873
                }
 
1874
            }
 
1875
        }
 
1876
 
 
1877
        s = p ? (p + 1) : NULL;
 
1878
    }
 
1879
 
 
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 "
 
1884
                              "supported");
 
1885
    }
 
1886
 
 
1887
    if (*prefvar) {
 
1888
        LIBSSH2_FREE(session, *prefvar);
 
1889
    }
 
1890
    *prefvar = newprefs;
 
1891
 
 
1892
    return 0;
 
1893
}
 
1894