summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-11-05 15:19:35 +1100
committerDamien Miller <djm@mindrot.org>2005-11-05 15:19:35 +1100
commit19bb3a57f88adc789d61964fcb8f50165026b322 (patch)
treeba18e185c014c1da12ce4422a7e7bad9e71725f5
parent24ecf612614d83622d9777349b4ecd21ee22bb2a (diff)
- djm@cvs.openbsd.org 2005/11/04 05:15:59
[kex.c kex.h kexdh.c kexdhc.c kexdhs.c kexgex.c kexgexc.c kexgexs.c] remove hardcoded hash lengths in key exchange code, allowing implementation of KEX methods with different hashes (e.g. SHA-256); ok markus@ dtucker@ stevesk@
-rw-r--r--ChangeLog7
-rw-r--r--kex.c36
-rw-r--r--kex.h22
-rw-r--r--kexdh.c10
-rw-r--r--kexdhc.c15
-rw-r--r--kexdhs.c17
-rw-r--r--kexgex.c16
-rw-r--r--kexgexc.c17
-rw-r--r--kexgexs.c20
9 files changed, 90 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index cefc3e0b4..6fb0b7d35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -93,6 +93,11 @@
93 - dtucker@cvs.openbsd.org 2005/11/03 13:38:29 93 - dtucker@cvs.openbsd.org 2005/11/03 13:38:29
94 [canohost.c] 94 [canohost.c]
95 Cache reverse lookups with and without DNS separately; ok markus@ 95 Cache reverse lookups with and without DNS separately; ok markus@
96 - djm@cvs.openbsd.org 2005/11/04 05:15:59
97 [kex.c kex.h kexdh.c kexdhc.c kexdhs.c kexgex.c kexgexc.c kexgexs.c]
98 remove hardcoded hash lengths in key exchange code, allowing
99 implementation of KEX methods with different hashes (e.g. SHA-256);
100 ok markus@ dtucker@ stevesk@
96 101
9720051102 10220051102
98 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). 103 - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup().
@@ -3226,4 +3231,4 @@
3226 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 3231 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
3227 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 3232 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
3228 3233
3229$Id: ChangeLog,v 1.3950 2005/11/05 04:16:52 djm Exp $ 3234$Id: ChangeLog,v 1.3951 2005/11/05 04:19:35 djm Exp $
diff --git a/kex.c b/kex.c
index 5dce335fe..cd71be9ca 100644
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kex.c,v 1.64 2005/07/25 11:59:39 markus Exp $"); 26RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $");
27 27
28#include <openssl/crypto.h> 28#include <openssl/crypto.h>
29 29
@@ -294,13 +294,17 @@ choose_kex(Kex *k, char *client, char *server)
294 fatal("no kex alg"); 294 fatal("no kex alg");
295 if (strcmp(k->name, KEX_DH1) == 0) { 295 if (strcmp(k->name, KEX_DH1) == 0) {
296 k->kex_type = KEX_DH_GRP1_SHA1; 296 k->kex_type = KEX_DH_GRP1_SHA1;
297 k->evp_md = EVP_sha1();
297 } else if (strcmp(k->name, KEX_DH14) == 0) { 298 } else if (strcmp(k->name, KEX_DH14) == 0) {
298 k->kex_type = KEX_DH_GRP14_SHA1; 299 k->kex_type = KEX_DH_GRP14_SHA1;
299 } else if (strcmp(k->name, KEX_DHGEX) == 0) { 300 k->evp_md = EVP_sha1();
301 } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
300 k->kex_type = KEX_DH_GEX_SHA1; 302 k->kex_type = KEX_DH_GEX_SHA1;
303 k->evp_md = EVP_sha1();
301 } else 304 } else
302 fatal("bad kex alg %s", k->name); 305 fatal("bad kex alg %s", k->name);
303} 306}
307
304static void 308static void
305choose_hostkeyalg(Kex *k, char *client, char *server) 309choose_hostkeyalg(Kex *k, char *client, char *server)
306{ 310{
@@ -404,28 +408,28 @@ kex_choose_conf(Kex *kex)
404} 408}
405 409
406static u_char * 410static u_char *
407derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) 411derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
412 BIGNUM *shared_secret)
408{ 413{
409 Buffer b; 414 Buffer b;
410 const EVP_MD *evp_md = EVP_sha1();
411 EVP_MD_CTX md; 415 EVP_MD_CTX md;
412 char c = id; 416 char c = id;
413 u_int have; 417 u_int have;
414 int mdsz = EVP_MD_size(evp_md); 418 int mdsz;
415 u_char *digest; 419 u_char *digest;
416 420
417 if (mdsz < 0) 421 if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
418 fatal("derive_key: mdsz < 0"); 422 fatal("bad kex md size %d", mdsz);
419 digest = xmalloc(roundup(need, mdsz)); 423 digest = xmalloc(roundup(need, mdsz));
420 424
421 buffer_init(&b); 425 buffer_init(&b);
422 buffer_put_bignum2(&b, shared_secret); 426 buffer_put_bignum2(&b, shared_secret);
423 427
424 /* K1 = HASH(K || H || "A" || session_id) */ 428 /* K1 = HASH(K || H || "A" || session_id) */
425 EVP_DigestInit(&md, evp_md); 429 EVP_DigestInit(&md, kex->evp_md);
426 if (!(datafellows & SSH_BUG_DERIVEKEY)) 430 if (!(datafellows & SSH_BUG_DERIVEKEY))
427 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 431 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
428 EVP_DigestUpdate(&md, hash, mdsz); 432 EVP_DigestUpdate(&md, hash, hashlen);
429 EVP_DigestUpdate(&md, &c, 1); 433 EVP_DigestUpdate(&md, &c, 1);
430 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); 434 EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
431 EVP_DigestFinal(&md, digest, NULL); 435 EVP_DigestFinal(&md, digest, NULL);
@@ -436,10 +440,10 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret)
436 * Key = K1 || K2 || ... || Kn 440 * Key = K1 || K2 || ... || Kn
437 */ 441 */
438 for (have = mdsz; need > have; have += mdsz) { 442 for (have = mdsz; need > have; have += mdsz) {
439 EVP_DigestInit(&md, evp_md); 443 EVP_DigestInit(&md, kex->evp_md);
440 if (!(datafellows & SSH_BUG_DERIVEKEY)) 444 if (!(datafellows & SSH_BUG_DERIVEKEY))
441 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 445 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
442 EVP_DigestUpdate(&md, hash, mdsz); 446 EVP_DigestUpdate(&md, hash, hashlen);
443 EVP_DigestUpdate(&md, digest, have); 447 EVP_DigestUpdate(&md, digest, have);
444 EVP_DigestFinal(&md, digest + have, NULL); 448 EVP_DigestFinal(&md, digest + have, NULL);
445 } 449 }
@@ -455,13 +459,15 @@ Newkeys *current_keys[MODE_MAX];
455 459
456#define NKEYS 6 460#define NKEYS 6
457void 461void
458kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) 462kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
459{ 463{
460 u_char *keys[NKEYS]; 464 u_char *keys[NKEYS];
461 u_int i, mode, ctos; 465 u_int i, mode, ctos;
462 466
463 for (i = 0; i < NKEYS; i++) 467 for (i = 0; i < NKEYS; i++) {
464 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); 468 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
469 shared_secret);
470 }
465 471
466 debug2("kex_derive_keys"); 472 debug2("kex_derive_keys");
467 for (mode = 0; mode < MODE_MAX; mode++) { 473 for (mode = 0; mode < MODE_MAX; mode++) {
diff --git a/kex.h b/kex.h
index 3024a2717..bbd931e04 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.37 2005/07/25 11:59:39 markus Exp $ */ 1/* $OpenBSD: kex.h,v 1.38 2005/11/04 05:15:59 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -31,9 +31,9 @@
31#include "cipher.h" 31#include "cipher.h"
32#include "key.h" 32#include "key.h"
33 33
34#define KEX_DH1 "diffie-hellman-group1-sha1" 34#define KEX_DH1 "diffie-hellman-group1-sha1"
35#define KEX_DH14 "diffie-hellman-group14-sha1" 35#define KEX_DH14 "diffie-hellman-group14-sha1"
36#define KEX_DHGEX "diffie-hellman-group-exchange-sha1" 36#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
37 37
38#define COMP_NONE 0 38#define COMP_NONE 0
39#define COMP_ZLIB 1 39#define COMP_ZLIB 1
@@ -114,6 +114,7 @@ struct Kex {
114 Buffer peer; 114 Buffer peer;
115 int done; 115 int done;
116 int flags; 116 int flags;
117 const EVP_MD *evp_md;
117 char *client_version_string; 118 char *client_version_string;
118 char *server_version_string; 119 char *server_version_string;
119 int (*verify_host_key)(Key *); 120 int (*verify_host_key)(Key *);
@@ -127,7 +128,7 @@ void kex_finish(Kex *);
127 128
128void kex_send_kexinit(Kex *); 129void kex_send_kexinit(Kex *);
129void kex_input_kexinit(int, u_int32_t, void *); 130void kex_input_kexinit(int, u_int32_t, void *);
130void kex_derive_keys(Kex *, u_char *, BIGNUM *); 131void kex_derive_keys(Kex *, u_char *, u_int, BIGNUM *);
131 132
132Newkeys *kex_get_newkeys(int); 133Newkeys *kex_get_newkeys(int);
133 134
@@ -136,12 +137,13 @@ void kexdh_server(Kex *);
136void kexgex_client(Kex *); 137void kexgex_client(Kex *);
137void kexgex_server(Kex *); 138void kexgex_server(Kex *);
138 139
139u_char * 140void
140kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, 141kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
141 BIGNUM *, BIGNUM *, BIGNUM *); 142 BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
142u_char * 143void
143kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, 144kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
144 int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); 145 int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
146 BIGNUM *, BIGNUM *, u_char **, u_int *);
145 147
146void 148void
147derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); 149derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
diff --git a/kexdh.c b/kexdh.c
index 4bbb7d1db..f79d8781d 100644
--- a/kexdh.c
+++ b/kexdh.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $"); 26RCSID("$OpenBSD: kexdh.c,v 1.20 2005/11/04 05:15:59 djm Exp $");
27 27
28#include <openssl/evp.h> 28#include <openssl/evp.h>
29 29
@@ -32,7 +32,7 @@ RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $");
32#include "ssh2.h" 32#include "ssh2.h"
33#include "kex.h" 33#include "kex.h"
34 34
35u_char * 35void
36kex_dh_hash( 36kex_dh_hash(
37 char *client_version_string, 37 char *client_version_string,
38 char *server_version_string, 38 char *server_version_string,
@@ -41,7 +41,8 @@ kex_dh_hash(
41 u_char *serverhostkeyblob, int sbloblen, 41 u_char *serverhostkeyblob, int sbloblen,
42 BIGNUM *client_dh_pub, 42 BIGNUM *client_dh_pub,
43 BIGNUM *server_dh_pub, 43 BIGNUM *server_dh_pub,
44 BIGNUM *shared_secret) 44 BIGNUM *shared_secret,
45 u_char **hash, u_int *hashlen)
45{ 46{
46 Buffer b; 47 Buffer b;
47 static u_char digest[EVP_MAX_MD_SIZE]; 48 static u_char digest[EVP_MAX_MD_SIZE];
@@ -77,5 +78,6 @@ kex_dh_hash(
77#ifdef DEBUG_KEX 78#ifdef DEBUG_KEX
78 dump_digest("hash", digest, EVP_MD_size(evp_md)); 79 dump_digest("hash", digest, EVP_MD_size(evp_md));
79#endif 80#endif
80 return digest; 81 *hash = digest;
82 *hashlen = EVP_MD_size(evp_md);
81} 83}
diff --git a/kexdhc.c b/kexdhc.c
index f48bd4678..d8a2fa3b7 100644
--- a/kexdhc.c
+++ b/kexdhc.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kexdhc.c,v 1.2 2004/06/13 12:53:24 djm Exp $"); 26RCSID("$OpenBSD: kexdhc.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
27 27
28#include "xmalloc.h" 28#include "xmalloc.h"
29#include "key.h" 29#include "key.h"
@@ -41,7 +41,7 @@ kexdh_client(Kex *kex)
41 Key *server_host_key; 41 Key *server_host_key;
42 u_char *server_host_key_blob = NULL, *signature = NULL; 42 u_char *server_host_key_blob = NULL, *signature = NULL;
43 u_char *kbuf, *hash; 43 u_char *kbuf, *hash;
44 u_int klen, kout, slen, sbloblen; 44 u_int klen, kout, slen, sbloblen, hashlen;
45 45
46 /* generate and send 'e', client DH public key */ 46 /* generate and send 'e', client DH public key */
47 switch (kex->kex_type) { 47 switch (kex->kex_type) {
@@ -114,7 +114,7 @@ kexdh_client(Kex *kex)
114 xfree(kbuf); 114 xfree(kbuf);
115 115
116 /* calc and verify H */ 116 /* calc and verify H */
117 hash = kex_dh_hash( 117 kex_dh_hash(
118 kex->client_version_string, 118 kex->client_version_string,
119 kex->server_version_string, 119 kex->server_version_string,
120 buffer_ptr(&kex->my), buffer_len(&kex->my), 120 buffer_ptr(&kex->my), buffer_len(&kex->my),
@@ -122,25 +122,26 @@ kexdh_client(Kex *kex)
122 server_host_key_blob, sbloblen, 122 server_host_key_blob, sbloblen,
123 dh->pub_key, 123 dh->pub_key,
124 dh_server_pub, 124 dh_server_pub,
125 shared_secret 125 shared_secret,
126 &hash, &hashlen
126 ); 127 );
127 xfree(server_host_key_blob); 128 xfree(server_host_key_blob);
128 BN_clear_free(dh_server_pub); 129 BN_clear_free(dh_server_pub);
129 DH_free(dh); 130 DH_free(dh);
130 131
131 if (key_verify(server_host_key, signature, slen, hash, 20) != 1) 132 if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
132 fatal("key_verify failed for server_host_key"); 133 fatal("key_verify failed for server_host_key");
133 key_free(server_host_key); 134 key_free(server_host_key);
134 xfree(signature); 135 xfree(signature);
135 136
136 /* save session id */ 137 /* save session id */
137 if (kex->session_id == NULL) { 138 if (kex->session_id == NULL) {
138 kex->session_id_len = 20; 139 kex->session_id_len = hashlen;
139 kex->session_id = xmalloc(kex->session_id_len); 140 kex->session_id = xmalloc(kex->session_id_len);
140 memcpy(kex->session_id, hash, kex->session_id_len); 141 memcpy(kex->session_id, hash, kex->session_id_len);
141 } 142 }
142 143
143 kex_derive_keys(kex, hash, shared_secret); 144 kex_derive_keys(kex, hash, hashlen, shared_secret);
144 BN_clear_free(shared_secret); 145 BN_clear_free(shared_secret);
145 kex_finish(kex); 146 kex_finish(kex);
146} 147}
diff --git a/kexdhs.c b/kexdhs.c
index 225e65592..26c8cdfd6 100644
--- a/kexdhs.c
+++ b/kexdhs.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kexdhs.c,v 1.2 2004/06/13 12:53:24 djm Exp $"); 26RCSID("$OpenBSD: kexdhs.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
27 27
28#include "xmalloc.h" 28#include "xmalloc.h"
29#include "key.h" 29#include "key.h"
@@ -41,7 +41,7 @@ kexdh_server(Kex *kex)
41 DH *dh; 41 DH *dh;
42 Key *server_host_key; 42 Key *server_host_key;
43 u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; 43 u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
44 u_int sbloblen, klen, kout; 44 u_int sbloblen, klen, kout, hashlen;
45 u_int slen; 45 u_int slen;
46 46
47 /* generate server DH public key */ 47 /* generate server DH public key */
@@ -103,7 +103,7 @@ kexdh_server(Kex *kex)
103 key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); 103 key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
104 104
105 /* calc H */ 105 /* calc H */
106 hash = kex_dh_hash( 106 kex_dh_hash(
107 kex->client_version_string, 107 kex->client_version_string,
108 kex->server_version_string, 108 kex->server_version_string,
109 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 109 buffer_ptr(&kex->peer), buffer_len(&kex->peer),
@@ -111,21 +111,20 @@ kexdh_server(Kex *kex)
111 server_host_key_blob, sbloblen, 111 server_host_key_blob, sbloblen,
112 dh_client_pub, 112 dh_client_pub,
113 dh->pub_key, 113 dh->pub_key,
114 shared_secret 114 shared_secret,
115 &hash, &hashlen
115 ); 116 );
116 BN_clear_free(dh_client_pub); 117 BN_clear_free(dh_client_pub);
117 118
118 /* save session id := H */ 119 /* save session id := H */
119 /* XXX hashlen depends on KEX */
120 if (kex->session_id == NULL) { 120 if (kex->session_id == NULL) {
121 kex->session_id_len = 20; 121 kex->session_id_len = hashlen;
122 kex->session_id = xmalloc(kex->session_id_len); 122 kex->session_id = xmalloc(kex->session_id_len);
123 memcpy(kex->session_id, hash, kex->session_id_len); 123 memcpy(kex->session_id, hash, kex->session_id_len);
124 } 124 }
125 125
126 /* sign H */ 126 /* sign H */
127 /* XXX hashlen depends on KEX */ 127 PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
128 PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
129 128
130 /* destroy_sensitive_data(); */ 129 /* destroy_sensitive_data(); */
131 130
@@ -141,7 +140,7 @@ kexdh_server(Kex *kex)
141 /* have keys, free DH */ 140 /* have keys, free DH */
142 DH_free(dh); 141 DH_free(dh);
143 142
144 kex_derive_keys(kex, hash, shared_secret); 143 kex_derive_keys(kex, hash, hashlen, shared_secret);
145 BN_clear_free(shared_secret); 144 BN_clear_free(shared_secret);
146 kex_finish(kex); 145 kex_finish(kex);
147} 146}
diff --git a/kexgex.c b/kexgex.c
index b0c39c8cb..705484a47 100644
--- a/kexgex.c
+++ b/kexgex.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include "includes.h" 26#include "includes.h"
27RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $"); 27RCSID("$OpenBSD: kexgex.c,v 1.24 2005/11/04 05:15:59 djm Exp $");
28 28
29#include <openssl/evp.h> 29#include <openssl/evp.h>
30 30
@@ -33,8 +33,9 @@ RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $");
33#include "kex.h" 33#include "kex.h"
34#include "ssh2.h" 34#include "ssh2.h"
35 35
36u_char * 36void
37kexgex_hash( 37kexgex_hash(
38 const EVP_MD *evp_md,
38 char *client_version_string, 39 char *client_version_string,
39 char *server_version_string, 40 char *server_version_string,
40 char *ckexinit, int ckexinitlen, 41 char *ckexinit, int ckexinitlen,
@@ -43,11 +44,11 @@ kexgex_hash(
43 int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, 44 int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
44 BIGNUM *client_dh_pub, 45 BIGNUM *client_dh_pub,
45 BIGNUM *server_dh_pub, 46 BIGNUM *server_dh_pub,
46 BIGNUM *shared_secret) 47 BIGNUM *shared_secret,
48 u_char **hash, u_int *hashlen)
47{ 49{
48 Buffer b; 50 Buffer b;
49 static u_char digest[EVP_MAX_MD_SIZE]; 51 static u_char digest[EVP_MAX_MD_SIZE];
50 const EVP_MD *evp_md = EVP_sha1();
51 EVP_MD_CTX md; 52 EVP_MD_CTX md;
52 53
53 buffer_init(&b); 54 buffer_init(&b);
@@ -79,14 +80,15 @@ kexgex_hash(
79#ifdef DEBUG_KEXDH 80#ifdef DEBUG_KEXDH
80 buffer_dump(&b); 81 buffer_dump(&b);
81#endif 82#endif
83
82 EVP_DigestInit(&md, evp_md); 84 EVP_DigestInit(&md, evp_md);
83 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); 85 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
84 EVP_DigestFinal(&md, digest, NULL); 86 EVP_DigestFinal(&md, digest, NULL);
85 87
86 buffer_free(&b); 88 buffer_free(&b);
87 89 *hash = digest;
90 *hashlen = EVP_MD_size(evp_md);
88#ifdef DEBUG_KEXDH 91#ifdef DEBUG_KEXDH
89 dump_digest("hash", digest, EVP_MD_size(evp_md)); 92 dump_digest("hash", digest, *hashlen);
90#endif 93#endif
91 return digest;
92} 94}
diff --git a/kexgexc.c b/kexgexc.c
index 0193183b9..a6ff8757d 100644
--- a/kexgexc.c
+++ b/kexgexc.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include "includes.h" 26#include "includes.h"
27RCSID("$OpenBSD: kexgexc.c,v 1.2 2003/12/08 11:00:47 markus Exp $"); 27RCSID("$OpenBSD: kexgexc.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
28 28
29#include "xmalloc.h" 29#include "xmalloc.h"
30#include "key.h" 30#include "key.h"
@@ -42,7 +42,7 @@ kexgex_client(Kex *kex)
42 BIGNUM *p = NULL, *g = NULL; 42 BIGNUM *p = NULL, *g = NULL;
43 Key *server_host_key; 43 Key *server_host_key;
44 u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; 44 u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
45 u_int klen, kout, slen, sbloblen; 45 u_int klen, kout, slen, sbloblen, hashlen;
46 int min, max, nbits; 46 int min, max, nbits;
47 DH *dh; 47 DH *dh;
48 48
@@ -155,7 +155,8 @@ kexgex_client(Kex *kex)
155 min = max = -1; 155 min = max = -1;
156 156
157 /* calc and verify H */ 157 /* calc and verify H */
158 hash = kexgex_hash( 158 kexgex_hash(
159 kex->evp_md,
159 kex->client_version_string, 160 kex->client_version_string,
160 kex->server_version_string, 161 kex->server_version_string,
161 buffer_ptr(&kex->my), buffer_len(&kex->my), 162 buffer_ptr(&kex->my), buffer_len(&kex->my),
@@ -165,25 +166,27 @@ kexgex_client(Kex *kex)
165 dh->p, dh->g, 166 dh->p, dh->g,
166 dh->pub_key, 167 dh->pub_key,
167 dh_server_pub, 168 dh_server_pub,
168 shared_secret 169 shared_secret,
170 &hash, &hashlen
169 ); 171 );
172
170 /* have keys, free DH */ 173 /* have keys, free DH */
171 DH_free(dh); 174 DH_free(dh);
172 xfree(server_host_key_blob); 175 xfree(server_host_key_blob);
173 BN_clear_free(dh_server_pub); 176 BN_clear_free(dh_server_pub);
174 177
175 if (key_verify(server_host_key, signature, slen, hash, 20) != 1) 178 if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
176 fatal("key_verify failed for server_host_key"); 179 fatal("key_verify failed for server_host_key");
177 key_free(server_host_key); 180 key_free(server_host_key);
178 xfree(signature); 181 xfree(signature);
179 182
180 /* save session id */ 183 /* save session id */
181 if (kex->session_id == NULL) { 184 if (kex->session_id == NULL) {
182 kex->session_id_len = 20; 185 kex->session_id_len = hashlen;
183 kex->session_id = xmalloc(kex->session_id_len); 186 kex->session_id = xmalloc(kex->session_id_len);
184 memcpy(kex->session_id, hash, kex->session_id_len); 187 memcpy(kex->session_id, hash, kex->session_id_len);
185 } 188 }
186 kex_derive_keys(kex, hash, shared_secret); 189 kex_derive_keys(kex, hash, hashlen, shared_secret);
187 BN_clear_free(shared_secret); 190 BN_clear_free(shared_secret);
188 191
189 kex_finish(kex); 192 kex_finish(kex);
diff --git a/kexgexs.c b/kexgexs.c
index baebfcfb0..c48b27af9 100644
--- a/kexgexs.c
+++ b/kexgexs.c
@@ -24,7 +24,7 @@
24 */ 24 */
25 25
26#include "includes.h" 26#include "includes.h"
27RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); 27RCSID("$OpenBSD: kexgexs.c,v 1.2 2005/11/04 05:15:59 djm Exp $");
28 28
29#include "xmalloc.h" 29#include "xmalloc.h"
30#include "key.h" 30#include "key.h"
@@ -43,7 +43,7 @@ kexgex_server(Kex *kex)
43 Key *server_host_key; 43 Key *server_host_key;
44 DH *dh; 44 DH *dh;
45 u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; 45 u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
46 u_int sbloblen, klen, kout, slen; 46 u_int sbloblen, klen, kout, slen, hashlen;
47 int min = -1, max = -1, nbits = -1, type; 47 int min = -1, max = -1, nbits = -1, type;
48 48
49 if (kex->load_host_key == NULL) 49 if (kex->load_host_key == NULL)
@@ -137,8 +137,9 @@ kexgex_server(Kex *kex)
137 if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) 137 if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)
138 min = max = -1; 138 min = max = -1;
139 139
140 /* calc H */ /* XXX depends on 'kex' */ 140 /* calc H */
141 hash = kexgex_hash( 141 kexgex_hash(
142 kex->evp_md,
142 kex->client_version_string, 143 kex->client_version_string,
143 kex->server_version_string, 144 kex->server_version_string,
144 buffer_ptr(&kex->peer), buffer_len(&kex->peer), 145 buffer_ptr(&kex->peer), buffer_len(&kex->peer),
@@ -148,21 +149,20 @@ kexgex_server(Kex *kex)
148 dh->p, dh->g, 149 dh->p, dh->g,
149 dh_client_pub, 150 dh_client_pub,
150 dh->pub_key, 151 dh->pub_key,
151 shared_secret 152 shared_secret,
153 &hash, &hashlen
152 ); 154 );
153 BN_clear_free(dh_client_pub); 155 BN_clear_free(dh_client_pub);
154 156
155 /* save session id := H */ 157 /* save session id := H */
156 /* XXX hashlen depends on KEX */
157 if (kex->session_id == NULL) { 158 if (kex->session_id == NULL) {
158 kex->session_id_len = 20; 159 kex->session_id_len = hashlen;
159 kex->session_id = xmalloc(kex->session_id_len); 160 kex->session_id = xmalloc(kex->session_id_len);
160 memcpy(kex->session_id, hash, kex->session_id_len); 161 memcpy(kex->session_id, hash, kex->session_id_len);
161 } 162 }
162 163
163 /* sign H */ 164 /* sign H */
164 /* XXX hashlen depends on KEX */ 165 PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
165 PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
166 166
167 /* destroy_sensitive_data(); */ 167 /* destroy_sensitive_data(); */
168 168
@@ -179,7 +179,7 @@ kexgex_server(Kex *kex)
179 /* have keys, free DH */ 179 /* have keys, free DH */
180 DH_free(dh); 180 DH_free(dh);
181 181
182 kex_derive_keys(kex, hash, shared_secret); 182 kex_derive_keys(kex, hash, hashlen, shared_secret);
183 BN_clear_free(shared_secret); 183 BN_clear_free(shared_secret);
184 184
185 kex_finish(kex); 185 kex_finish(kex);