]> andersk Git - gssapi-openssh.git/blame - openssh/kex.c
in addition to GLOBUS_PKG_LIBS, use GLOBUS_LDFLAGS, GLOBUS_CPPFLAGS,
[gssapi-openssh.git] / openssh / kex.c
CommitLineData
fa0f0f45 1/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */
3c0ef626 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "includes.h"
30460aeb 27
28#include <sys/param.h>
29
30#include <signal.h>
31#include <stdarg.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
3c0ef626 35
36#include <openssl/crypto.h>
37
3c0ef626 38#include "xmalloc.h"
30460aeb 39#include "ssh2.h"
3c0ef626 40#include "buffer.h"
3c0ef626 41#include "packet.h"
42#include "compat.h"
43#include "cipher.h"
3c0ef626 44#include "key.h"
30460aeb 45#include "kex.h"
3c0ef626 46#include "log.h"
47#include "mac.h"
48#include "match.h"
49#include "dispatch.h"
350391c5 50#include "monitor.h"
3c0ef626 51
5598e598 52#ifdef GSSAPI
53#include "ssh-gss.h"
54#endif
55
3c0ef626 56#define KEX_COOKIE_LEN 16
57
30460aeb 58#if OPENSSL_VERSION_NUMBER >= 0x00907000L
59# if defined(HAVE_EVP_SHA256)
60# define evp_ssh_sha256 EVP_sha256
61# else
62extern const EVP_MD *evp_ssh_sha256(void);
63# endif
64#endif
65
3c0ef626 66/* prototype */
67static void kex_kexinit_finish(Kex *);
68static void kex_choose_conf(Kex *);
69
70/* put algorithm proposal into buffer */
6df46d40 71/* used in sshconnect.c as well as kex.c */
473db5ab 72void
3c0ef626 73kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
74{
2ce0bfe4 75 u_int i;
3c0ef626 76
77 buffer_clear(b);
350391c5 78 /*
79 * add a dummy cookie, the cookie will be overwritten by
80 * kex_send_kexinit(), each time a kexinit is set
81 */
82 for (i = 0; i < KEX_COOKIE_LEN; i++)
83 buffer_put_char(b, 0);
3c0ef626 84 for (i = 0; i < PROPOSAL_MAX; i++)
85 buffer_put_cstring(b, proposal[i]);
86 buffer_put_char(b, 0); /* first_kex_packet_follows */
87 buffer_put_int(b, 0); /* uint32 reserved */
88}
89
90/* parse buffer and return algorithm proposal */
91static char **
8afc6a66 92kex_buf2prop(Buffer *raw, int *first_kex_follows)
3c0ef626 93{
94 Buffer b;
fa0f0f45 95 u_int i;
3c0ef626 96 char **proposal;
97
30460aeb 98 proposal = xcalloc(PROPOSAL_MAX, sizeof(char *));
3c0ef626 99
100 buffer_init(&b);
101 buffer_append(&b, buffer_ptr(raw), buffer_len(raw));
102 /* skip cookie */
103 for (i = 0; i < KEX_COOKIE_LEN; i++)
104 buffer_get_char(&b);
105 /* extract kex init proposal strings */
106 for (i = 0; i < PROPOSAL_MAX; i++) {
107 proposal[i] = buffer_get_string(&b,NULL);
108 debug2("kex_parse_kexinit: %s", proposal[i]);
109 }
110 /* first kex follows / reserved */
111 i = buffer_get_char(&b);
8afc6a66 112 if (first_kex_follows != NULL)
113 *first_kex_follows = i;
3c0ef626 114 debug2("kex_parse_kexinit: first_kex_follows %d ", i);
115 i = buffer_get_int(&b);
fa0f0f45 116 debug2("kex_parse_kexinit: reserved %u ", i);
3c0ef626 117 buffer_free(&b);
118 return proposal;
119}
120
121static void
122kex_prop_free(char **proposal)
123{
2ce0bfe4 124 u_int i;
3c0ef626 125
126 for (i = 0; i < PROPOSAL_MAX; i++)
127 xfree(proposal[i]);
128 xfree(proposal);
129}
130
fa0f0f45 131/* ARGSUSED */
3c0ef626 132static void
e9702f7d 133kex_protocol_error(int type, u_int32_t seq, void *ctxt)
3c0ef626 134{
e9702f7d 135 error("Hm, kex protocol error: type %d seq %u", type, seq);
3c0ef626 136}
137
138static void
e9702f7d 139kex_reset_dispatch(void)
3c0ef626 140{
e9702f7d 141 dispatch_range(SSH2_MSG_TRANSPORT_MIN,
142 SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
143 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
3c0ef626 144}
145
146void
147kex_finish(Kex *kex)
148{
e9702f7d 149 kex_reset_dispatch();
3c0ef626 150
151 packet_start(SSH2_MSG_NEWKEYS);
152 packet_send();
153 /* packet_write_wait(); */
154 debug("SSH2_MSG_NEWKEYS sent");
155
8afc6a66 156 debug("expecting SSH2_MSG_NEWKEYS");
e9702f7d 157 packet_read_expect(SSH2_MSG_NEWKEYS);
158 packet_check_eom();
3c0ef626 159 debug("SSH2_MSG_NEWKEYS received");
160
161 kex->done = 1;
162 buffer_clear(&kex->peer);
163 /* buffer_clear(&kex->my); */
164 kex->flags &= ~KEX_INIT_SENT;
165 xfree(kex->name);
166 kex->name = NULL;
167}
168
169void
170kex_send_kexinit(Kex *kex)
171{
7e82606e 172 u_int32_t rnd = 0;
350391c5 173 u_char *cookie;
2ce0bfe4 174 u_int i;
350391c5 175
3c0ef626 176 if (kex == NULL) {
177 error("kex_send_kexinit: no kex, cannot rekey");
178 return;
179 }
180 if (kex->flags & KEX_INIT_SENT) {
181 debug("KEX_INIT_SENT");
182 return;
183 }
184 kex->done = 0;
350391c5 185
186 /* generate a random cookie */
187 if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
188 fatal("kex_send_kexinit: kex proposal too short");
189 cookie = buffer_ptr(&kex->my);
190 for (i = 0; i < KEX_COOKIE_LEN; i++) {
191 if (i % 4 == 0)
7e82606e 192 rnd = arc4random();
193 cookie[i] = rnd;
194 rnd >>= 8;
350391c5 195 }
3c0ef626 196 packet_start(SSH2_MSG_KEXINIT);
197 packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
198 packet_send();
199 debug("SSH2_MSG_KEXINIT sent");
200 kex->flags |= KEX_INIT_SENT;
201}
202
fa0f0f45 203/* ARGSUSED */
3c0ef626 204void
e9702f7d 205kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
3c0ef626 206{
207 char *ptr;
2ce0bfe4 208 u_int i, dlen;
3c0ef626 209 Kex *kex = (Kex *)ctxt;
210
211 debug("SSH2_MSG_KEXINIT received");
212 if (kex == NULL)
213 fatal("kex_input_kexinit: no kex, cannot rekey");
214
215 ptr = packet_get_raw(&dlen);
216 buffer_append(&kex->peer, ptr, dlen);
217
218 /* discard packet */
219 for (i = 0; i < KEX_COOKIE_LEN; i++)
220 packet_get_char();
221 for (i = 0; i < PROPOSAL_MAX; i++)
222 xfree(packet_get_string(NULL));
276b07a3 223 (void) packet_get_char();
224 (void) packet_get_int();
e9702f7d 225 packet_check_eom();
3c0ef626 226
227 kex_kexinit_finish(kex);
228}
229
230Kex *
231kex_setup(char *proposal[PROPOSAL_MAX])
232{
233 Kex *kex;
234
30460aeb 235 kex = xcalloc(1, sizeof(*kex));
3c0ef626 236 buffer_init(&kex->peer);
237 buffer_init(&kex->my);
238 kex_prop2buf(&kex->my, proposal);
239 kex->done = 0;
240
241 kex_send_kexinit(kex); /* we start */
e9702f7d 242 kex_reset_dispatch();
3c0ef626 243
244 return kex;
245}
246
247static void
248kex_kexinit_finish(Kex *kex)
249{
250 if (!(kex->flags & KEX_INIT_SENT))
251 kex_send_kexinit(kex);
252
253 kex_choose_conf(kex);
254
8afc6a66 255 if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX &&
256 kex->kex[kex->kex_type] != NULL) {
257 (kex->kex[kex->kex_type])(kex);
258 } else {
3c0ef626 259 fatal("Unsupported key exchange %d", kex->kex_type);
260 }
261}
262
263static void
264choose_enc(Enc *enc, char *client, char *server)
265{
266 char *name = match_list(client, server, NULL);
267 if (name == NULL)
fa0f0f45 268 fatal("no matching cipher found: client %s server %s",
269 client, server);
e9702f7d 270 if ((enc->cipher = cipher_by_name(name)) == NULL)
3c0ef626 271 fatal("matching cipher is not supported: %s", name);
272 enc->name = name;
273 enc->enabled = 0;
274 enc->iv = NULL;
275 enc->key = NULL;
e9702f7d 276 enc->key_len = cipher_keylen(enc->cipher);
277 enc->block_size = cipher_blocksize(enc->cipher);
3c0ef626 278}
30460aeb 279
3c0ef626 280static void
281choose_mac(Mac *mac, char *client, char *server)
282{
283 char *name = match_list(client, server, NULL);
284 if (name == NULL)
fa0f0f45 285 fatal("no matching mac found: client %s server %s",
286 client, server);
287 if (mac_setup(mac, name) < 0)
3c0ef626 288 fatal("unsupported mac %s", name);
289 /* truncate the key */
290 if (datafellows & SSH_BUG_HMAC)
291 mac->key_len = 16;
292 mac->name = name;
293 mac->key = NULL;
294 mac->enabled = 0;
295}
30460aeb 296
3c0ef626 297static void
298choose_comp(Comp *comp, char *client, char *server)
299{
300 char *name = match_list(client, server, NULL);
301 if (name == NULL)
302 fatal("no matching comp found: client %s server %s", client, server);
2ce0bfe4 303 if (strcmp(name, "zlib@openssh.com") == 0) {
304 comp->type = COMP_DELAYED;
305 } else if (strcmp(name, "zlib") == 0) {
306 comp->type = COMP_ZLIB;
3c0ef626 307 } else if (strcmp(name, "none") == 0) {
2ce0bfe4 308 comp->type = COMP_NONE;
3c0ef626 309 } else {
310 fatal("unsupported comp %s", name);
311 }
312 comp->name = name;
313}
30460aeb 314
3c0ef626 315static void
316choose_kex(Kex *k, char *client, char *server)
317{
318 k->name = match_list(client, server, NULL);
319 if (k->name == NULL)
fa0f0f45 320 fatal("Unable to negotiate a key exchange method");
3c0ef626 321 if (strcmp(k->name, KEX_DH1) == 0) {
8afc6a66 322 k->kex_type = KEX_DH_GRP1_SHA1;
08822d99 323 k->evp_md = EVP_sha1();
7e82606e 324 } else if (strcmp(k->name, KEX_DH14) == 0) {
325 k->kex_type = KEX_DH_GRP14_SHA1;
08822d99 326 k->evp_md = EVP_sha1();
327 } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
8afc6a66 328 k->kex_type = KEX_DH_GEX_SHA1;
08822d99 329 k->evp_md = EVP_sha1();
f713db99 330#if OPENSSL_VERSION_NUMBER >= 0x00907000L
331 } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
332 k->kex_type = KEX_DH_GEX_SHA256;
333 k->evp_md = evp_ssh_sha256();
334#endif
5598e598 335#ifdef GSSAPI
fe4ad273 336 } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
f713db99 337 sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
fe4ad273 338 k->kex_type = KEX_GSS_GEX_SHA1;
08822d99 339 k->evp_md = EVP_sha1();
c06c9ae8 340 } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
f713db99 341 sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
8afc6a66 342 k->kex_type = KEX_GSS_GRP1_SHA1;
08822d99 343 k->evp_md = EVP_sha1();
f713db99 344 } else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
345 sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
346 k->kex_type = KEX_GSS_GRP14_SHA1;
347 k->evp_md = EVP_sha1();
5598e598 348#endif
3c0ef626 349 } else
350 fatal("bad kex alg %s", k->name);
351}
08822d99 352
3c0ef626 353static void
354choose_hostkeyalg(Kex *k, char *client, char *server)
355{
356 char *hostkeyalg = match_list(client, server, NULL);
357 if (hostkeyalg == NULL)
358 fatal("no hostkey alg");
359 k->hostkey_type = key_type_from_name(hostkeyalg);
360 if (k->hostkey_type == KEY_UNSPEC)
361 fatal("bad hostkey alg '%s'", hostkeyalg);
362 xfree(hostkeyalg);
363}
364
540d72c3 365static int
8afc6a66 366proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
367{
368 static int check[] = {
369 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
370 };
371 int *idx;
372 char *p;
373
374 for (idx = &check[0]; *idx != -1; idx++) {
375 if ((p = strchr(my[*idx], ',')) != NULL)
376 *p = '\0';
377 if ((p = strchr(peer[*idx], ',')) != NULL)
378 *p = '\0';
379 if (strcmp(my[*idx], peer[*idx]) != 0) {
380 debug2("proposal mismatch: my %s peer %s",
381 my[*idx], peer[*idx]);
382 return (0);
383 }
384 }
385 debug2("proposals match");
386 return (1);
387}
388
3c0ef626 389static void
390kex_choose_conf(Kex *kex)
391{
392 Newkeys *newkeys;
393 char **my, **peer;
394 char **cprop, **sprop;
395 int nenc, nmac, ncomp;
2ce0bfe4 396 u_int mode, ctos, need;
8afc6a66 397 int first_kex_follows, type;
3c0ef626 398
6df46d40 399 int auth_flag;
400
401 auth_flag = packet_authentication_state();
402
403 debug ("AUTH STATE IS %d", auth_flag);
404
8afc6a66 405 my = kex_buf2prop(&kex->my, NULL);
406 peer = kex_buf2prop(&kex->peer, &first_kex_follows);
3c0ef626 407
408 if (kex->server) {
409 cprop=peer;
410 sprop=my;
411 } else {
412 cprop=my;
413 sprop=peer;
414 }
415
416 /* Algorithm Negotiation */
417 for (mode = 0; mode < MODE_MAX; mode++) {
30460aeb 418 newkeys = xcalloc(1, sizeof(*newkeys));
3c0ef626 419 kex->newkeys[mode] = newkeys;
fa0f0f45 420 ctos = (!kex->server && mode == MODE_OUT) ||
421 (kex->server && mode == MODE_IN);
3c0ef626 422 nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC;
423 nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC;
424 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
425 choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]);
426 choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]);
427 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
6df46d40 428 debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
429 if (strcmp(newkeys->enc.name, "none") == 0) {
430 debug("Requesting NONE. Authflag is %d", auth_flag);
431 if (auth_flag == 1) {
432 debug("None requested post authentication.");
433 } else {
434 fatal("Pre-authentication none cipher requests are not allowed.");
435 }
436 }
3c0ef626 437 debug("kex: %s %s %s %s",
438 ctos ? "client->server" : "server->client",
439 newkeys->enc.name,
440 newkeys->mac.name,
441 newkeys->comp.name);
442 }
443 choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
444 choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
445 sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
446 need = 0;
447 for (mode = 0; mode < MODE_MAX; mode++) {
448 newkeys = kex->newkeys[mode];
e9702f7d 449 if (need < newkeys->enc.key_len)
450 need = newkeys->enc.key_len;
451 if (need < newkeys->enc.block_size)
452 need = newkeys->enc.block_size;
3c0ef626 453 if (need < newkeys->mac.key_len)
454 need = newkeys->mac.key_len;
455 }
456 /* XXX need runden? */
457 kex->we_need = need;
458
8afc6a66 459 /* ignore the next message if the proposals do not match */
540d72c3 460 if (first_kex_follows && !proposals_match(my, peer) &&
2ce0bfe4 461 !(datafellows & SSH_BUG_FIRSTKEX)) {
8afc6a66 462 type = packet_read();
463 debug2("skipping next packet (type %u)", type);
464 }
465
3c0ef626 466 kex_prop_free(my);
467 kex_prop_free(peer);
468}
469
470static u_char *
08822d99 471derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
472 BIGNUM *shared_secret)
3c0ef626 473{
474 Buffer b;
3c0ef626 475 EVP_MD_CTX md;
476 char c = id;
2ce0bfe4 477 u_int have;
08822d99 478 int mdsz;
2ce0bfe4 479 u_char *digest;
480
08822d99 481 if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
482 fatal("bad kex md size %d", mdsz);
30460aeb 483 digest = xmalloc(roundup(need, mdsz));
3c0ef626 484
485 buffer_init(&b);
486 buffer_put_bignum2(&b, shared_secret);
487
488 /* K1 = HASH(K || H || "A" || session_id) */
08822d99 489 EVP_DigestInit(&md, kex->evp_md);
3c0ef626 490 if (!(datafellows & SSH_BUG_DERIVEKEY))
491 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
08822d99 492 EVP_DigestUpdate(&md, hash, hashlen);
3c0ef626 493 EVP_DigestUpdate(&md, &c, 1);
494 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
495 EVP_DigestFinal(&md, digest, NULL);
496
497 /*
498 * expand key:
499 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
500 * Key = K1 || K2 || ... || Kn
501 */
502 for (have = mdsz; need > have; have += mdsz) {
08822d99 503 EVP_DigestInit(&md, kex->evp_md);
3c0ef626 504 if (!(datafellows & SSH_BUG_DERIVEKEY))
505 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
08822d99 506 EVP_DigestUpdate(&md, hash, hashlen);
3c0ef626 507 EVP_DigestUpdate(&md, digest, have);
508 EVP_DigestFinal(&md, digest + have, NULL);
509 }
510 buffer_free(&b);
511#ifdef DEBUG_KEX
512 fprintf(stderr, "key '%c'== ", c);
513 dump_digest("key", digest, need);
514#endif
515 return digest;
516}
517
518Newkeys *current_keys[MODE_MAX];
519
520#define NKEYS 6
521void
08822d99 522kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
3c0ef626 523{
524 u_char *keys[NKEYS];
2ce0bfe4 525 u_int i, mode, ctos;
3c0ef626 526
08822d99 527 for (i = 0; i < NKEYS; i++) {
528 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
529 shared_secret);
530 }
3c0ef626 531
8afc6a66 532 debug2("kex_derive_keys");
3c0ef626 533 for (mode = 0; mode < MODE_MAX; mode++) {
534 current_keys[mode] = kex->newkeys[mode];
535 kex->newkeys[mode] = NULL;
30460aeb 536 ctos = (!kex->server && mode == MODE_OUT) ||
537 (kex->server && mode == MODE_IN);
3c0ef626 538 current_keys[mode]->enc.iv = keys[ctos ? 0 : 1];
539 current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
540 current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
541 }
542}
543
544Newkeys *
545kex_get_newkeys(int mode)
546{
547 Newkeys *ret;
548
549 ret = current_keys[mode];
550 current_keys[mode] = NULL;
551 return ret;
552}
553
7e82606e 554void
555derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
556 u_int8_t cookie[8], u_int8_t id[16])
557{
558 const EVP_MD *evp_md = EVP_md5();
559 EVP_MD_CTX md;
560 u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE];
561 int len;
562
563 EVP_DigestInit(&md, evp_md);
564
565 len = BN_num_bytes(host_modulus);
2ce0bfe4 566 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
7e82606e 567 fatal("%s: bad host modulus (len %d)", __func__, len);
568 BN_bn2bin(host_modulus, nbuf);
569 EVP_DigestUpdate(&md, nbuf, len);
570
571 len = BN_num_bytes(server_modulus);
2ce0bfe4 572 if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
7e82606e 573 fatal("%s: bad server modulus (len %d)", __func__, len);
574 BN_bn2bin(server_modulus, nbuf);
575 EVP_DigestUpdate(&md, nbuf, len);
576
577 EVP_DigestUpdate(&md, cookie, 8);
578
579 EVP_DigestFinal(&md, obuf, NULL);
580 memcpy(id, obuf, 16);
581
582 memset(nbuf, 0, sizeof(nbuf));
583 memset(obuf, 0, sizeof(obuf));
584 memset(&md, 0, sizeof(md));
585}
586
3c0ef626 587#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
588void
589dump_digest(char *msg, u_char *digest, int len)
590{
2ce0bfe4 591 u_int i;
3c0ef626 592
593 fprintf(stderr, "%s\n", msg);
0b90ac93 594 for (i = 0; i < len; i++) {
3c0ef626 595 fprintf(stderr, "%02x", digest[i]);
596 if (i%32 == 31)
597 fprintf(stderr, "\n");
598 else if (i%8 == 7)
599 fprintf(stderr, " ");
600 }
601 fprintf(stderr, "\n");
602}
603#endif
This page took 0.288088 seconds and 5 git commands to generate.