summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--kex.c10
-rw-r--r--kex.h5
-rw-r--r--kexecdh.c14
-rw-r--r--key.c47
-rw-r--r--key.h4
-rw-r--r--monitor.c8
-rw-r--r--ssh-ecdsa.c10
8 files changed, 80 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 32f82369d..87fee3bf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -49,6 +49,19 @@
49 gcc, at least in earlier versions, but this does not forgive your current 49 gcc, at least in earlier versions, but this does not forgive your current
50 transgressions) seen between zlib and openssl 50 transgressions) seen between zlib and openssl
51 ok djm 51 ok djm
52 - djm@cvs.openbsd.org 2010/09/09 10:45:45
53 [kex.c kex.h kexecdh.c key.c key.h monitor.c ssh-ecdsa.c]
54 ECDH/ECDSA compliance fix: these methods vary the hash function they use
55 (SHA256/384/512) depending on the length of the curve in use. The previous
56 code incorrectly used SHA256 in all cases.
57
58 This fix will cause authentication failure when using 384 or 521-bit curve
59 keys if one peer hasn't been upgraded and the other has. (256-bit curve
60 keys work ok). In particular you may need to specify HostkeyAlgorithms
61 when connecting to a server that has not been upgraded from an upgraded
62 client.
63
64 ok naddy@
52 65
5320100831 6620100831
54 - OpenBSD CVS Sync 67 - OpenBSD CVS Sync
diff --git a/kex.c b/kex.c
index abe9b9f5d..7c8763191 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.c,v 1.84 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: kex.c,v 1.85 2010/09/09 10:45:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
4 * 4 *
@@ -325,10 +325,10 @@ choose_kex(Kex *k, char *client, char *server)
325 } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) { 325 } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
326 k->kex_type = KEX_DH_GEX_SHA256; 326 k->kex_type = KEX_DH_GEX_SHA256;
327 k->evp_md = evp_ssh_sha256(); 327 k->evp_md = evp_ssh_sha256();
328 } else if (strncmp(k->name, KEX_ECDH_SHA256, 328 } else if (strncmp(k->name, KEX_ECDH_SHA2_STEM,
329 sizeof(KEX_ECDH_SHA256) - 1) == 0) { 329 sizeof(KEX_ECDH_SHA2_STEM) - 1) == 0) {
330 k->kex_type = KEX_ECDH_SHA2; 330 k->kex_type = KEX_ECDH_SHA2;
331 k->evp_md = evp_ssh_sha256(); 331 k->evp_md = kex_ecdh_name_to_evpmd(k->name);
332#endif 332#endif
333 } else 333 } else
334 fatal("bad kex alg %s", k->name); 334 fatal("bad kex alg %s", k->name);
diff --git a/kex.h b/kex.h
index a183ffda2..f5dcc8791 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: kex.h,v 1.50 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: kex.h,v 1.51 2010/09/09 10:45:45 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.
@@ -39,7 +39,7 @@
39#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" 39#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256"
40#define KEX_RESUME "resume@appgate.com" 40#define KEX_RESUME "resume@appgate.com"
41/* The following represents the family of ECDH methods */ 41/* The following represents the family of ECDH methods */
42#define KEX_ECDH_SHA256 "ecdh-sha2-" 42#define KEX_ECDH_SHA2_STEM "ecdh-sha2-"
43 43
44#define COMP_NONE 0 44#define COMP_NONE 0
45#define COMP_ZLIB 1 45#define COMP_ZLIB 1
@@ -165,6 +165,7 @@ kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int,
165 const BIGNUM *, u_char **, u_int *); 165 const BIGNUM *, u_char **, u_int *);
166 166
167int kex_ecdh_name_to_nid(const char *); 167int kex_ecdh_name_to_nid(const char *);
168const EVP_MD *kex_ecdh_name_to_evpmd(const char *);
168 169
169void 170void
170derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); 171derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
diff --git a/kexecdh.c b/kexecdh.c
index bd5718136..f59d7b903 100644
--- a/kexecdh.c
+++ b/kexecdh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexecdh.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: kexecdh.c,v 1.2 2010/09/09 10:45:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -48,15 +48,23 @@ kex_ecdh_name_to_nid(const char *kexname)
48{ 48{
49 int ret; 49 int ret;
50 50
51 if (strlen(kexname) < sizeof(KEX_ECDH_SHA256) - 1) 51 if (strlen(kexname) < sizeof(KEX_ECDH_SHA2_STEM) - 1)
52 fatal("%s: kexname too short \"%s\"", __func__, kexname); 52 fatal("%s: kexname too short \"%s\"", __func__, kexname);
53 ret = key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA256) - 1); 53 ret = key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1);
54 if (ret == -1) 54 if (ret == -1)
55 fatal("%s: unsupported curve negotiated \"%s\"", __func__, 55 fatal("%s: unsupported curve negotiated \"%s\"", __func__,
56 kexname); 56 kexname);
57 return ret; 57 return ret;
58} 58}
59 59
60const EVP_MD *
61kex_ecdh_name_to_evpmd(const char *kexname)
62{
63 int nid = kex_ecdh_name_to_nid(kexname);
64
65 return key_ec_nid_to_evpmd(nid);
66}
67
60void 68void
61kex_ecdh_hash( 69kex_ecdh_hash(
62 const EVP_MD *evp_md, 70 const EVP_MD *evp_md,
diff --git a/key.c b/key.c
index 842280a9f..b9dc2355b 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.92 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: key.c,v 1.93 2010/09/09 10:45:45 djm Exp $ */
2/* 2/*
3 * read_bignum(): 3 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -978,17 +978,7 @@ key_size(const Key *k)
978 return BN_num_bits(k->dsa->p); 978 return BN_num_bits(k->dsa->p);
979 case KEY_ECDSA: 979 case KEY_ECDSA:
980 case KEY_ECDSA_CERT: 980 case KEY_ECDSA_CERT:
981 switch (k->ecdsa_nid) { 981 return key_curve_nid_to_bits(k->ecdsa_nid);
982 case NID_X9_62_prime256v1:
983 return 256;
984 case NID_secp384r1:
985 return 384;
986 case NID_secp521r1:
987 return 521;
988 default:
989 break;
990 }
991 break;
992 } 982 }
993 return 0; 983 return 0;
994} 984}
@@ -1961,6 +1951,7 @@ key_cert_is_legacy(Key *k)
1961 } 1951 }
1962} 1952}
1963 1953
1954/* XXX: these are really begging for a table-driven approach */
1964int 1955int
1965key_curve_name_to_nid(const char *name) 1956key_curve_name_to_nid(const char *name)
1966{ 1957{
@@ -1975,6 +1966,22 @@ key_curve_name_to_nid(const char *name)
1975 return -1; 1966 return -1;
1976} 1967}
1977 1968
1969u_int
1970key_curve_nid_to_bits(int nid)
1971{
1972 switch (nid) {
1973 case NID_X9_62_prime256v1:
1974 return 256;
1975 case NID_secp384r1:
1976 return 384;
1977 case NID_secp521r1:
1978 return 521;
1979 default:
1980 error("%s: unsupported EC curve nid %d", __func__, nid);
1981 return 0;
1982 }
1983}
1984
1978const char * 1985const char *
1979key_curve_nid_to_name(int nid) 1986key_curve_nid_to_name(int nid)
1980{ 1987{
@@ -1989,6 +1996,22 @@ key_curve_nid_to_name(int nid)
1989 return NULL; 1996 return NULL;
1990} 1997}
1991 1998
1999const EVP_MD *
2000key_ec_nid_to_evpmd(int nid)
2001{
2002 int kbits = key_curve_nid_to_bits(nid);
2003
2004 if (kbits == 0)
2005 fatal("%s: invalid nid %d", __func__, nid);
2006 /* RFC5656 section 6.2.1 */
2007 if (kbits <= 256)
2008 return EVP_sha256();
2009 else if (kbits <= 384)
2010 return EVP_sha384();
2011 else
2012 return EVP_sha512();
2013}
2014
1992int 2015int
1993key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) 2016key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
1994{ 2017{
diff --git a/key.h b/key.h
index 2eb124364..ba1a20c07 100644
--- a/key.h
+++ b/key.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.h,v 1.31 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: key.h,v 1.32 2010/09/09 10:45:45 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.
@@ -112,8 +112,10 @@ int key_cert_is_legacy(Key *);
112int key_ecdsa_nid_from_name(const char *); 112int key_ecdsa_nid_from_name(const char *);
113int key_curve_name_to_nid(const char *); 113int key_curve_name_to_nid(const char *);
114const char * key_curve_nid_to_name(int); 114const char * key_curve_nid_to_name(int);
115u_int key_curve_nid_to_bits(int);
115int key_ecdsa_bits_to_nid(int); 116int key_ecdsa_bits_to_nid(int);
116int key_ecdsa_group_to_nid(const EC_GROUP *); 117int key_ecdsa_group_to_nid(const EC_GROUP *);
118const EVP_MD * key_ec_nid_to_evpmd(int nid);
117int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); 119int key_ec_validate_public(const EC_GROUP *, const EC_POINT *);
118int key_ec_validate_private(const EC_KEY *); 120int key_ec_validate_private(const EC_KEY *);
119 121
diff --git a/monitor.c b/monitor.c
index 32395ee44..29d987c70 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.109 2010/08/31 11:54:45 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.110 2010/09/09 10:45:45 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -590,10 +590,10 @@ mm_answer_sign(int sock, Buffer *m)
590 p = buffer_get_string(m, &datlen); 590 p = buffer_get_string(m, &datlen);
591 591
592 /* 592 /*
593 * Supported KEX types will only return SHA1 (20 byte) or 593 * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
594 * SHA256 (32 byte) hashes 594 * SHA384 (48 bytes) and SHA512 (64 bytes).
595 */ 595 */
596 if (datlen != 20 && datlen != 32) 596 if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64)
597 fatal("%s: data length incorrect: %u", __func__, datlen); 597 fatal("%s: data length incorrect: %u", __func__, datlen);
598 598
599 /* save session id, it will be passed on the first call */ 599 /* save session id, it will be passed on the first call */
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 0627ee5c0..5c4ce2311 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
1/* $OpenBSD$ */ 1/* $OpenBSD: ssh-ecdsa.c,v 1.4 2010/09/10 01:04:10 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -46,7 +46,7 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
46 const u_char *data, u_int datalen) 46 const u_char *data, u_int datalen)
47{ 47{
48 ECDSA_SIG *sig; 48 ECDSA_SIG *sig;
49 const EVP_MD *evp_md = EVP_sha256(); 49 const EVP_MD *evp_md;
50 EVP_MD_CTX md; 50 EVP_MD_CTX md;
51 u_char digest[EVP_MAX_MD_SIZE]; 51 u_char digest[EVP_MAX_MD_SIZE];
52 u_int len, dlen; 52 u_int len, dlen;
@@ -57,6 +57,7 @@ ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
57 error("%s: no ECDSA key", __func__); 57 error("%s: no ECDSA key", __func__);
58 return -1; 58 return -1;
59 } 59 }
60 evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);
60 EVP_DigestInit(&md, evp_md); 61 EVP_DigestInit(&md, evp_md);
61 EVP_DigestUpdate(&md, data, datalen); 62 EVP_DigestUpdate(&md, data, datalen);
62 EVP_DigestFinal(&md, digest, &dlen); 63 EVP_DigestFinal(&md, digest, &dlen);
@@ -94,21 +95,22 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
94 const u_char *data, u_int datalen) 95 const u_char *data, u_int datalen)
95{ 96{
96 ECDSA_SIG *sig; 97 ECDSA_SIG *sig;
97 const EVP_MD *evp_md = EVP_sha256(); 98 const EVP_MD *evp_md;
98 EVP_MD_CTX md; 99 EVP_MD_CTX md;
99 u_char digest[EVP_MAX_MD_SIZE], *sigblob; 100 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
100 u_int len, dlen; 101 u_int len, dlen;
101 int rlen, ret; 102 int rlen, ret;
102 Buffer b, bb; 103 Buffer b, bb;
104 char *ktype;
103 105
104 if (key == NULL || key->ecdsa == NULL || 106 if (key == NULL || key->ecdsa == NULL ||
105 (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { 107 (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) {
106 error("%s: no ECDSA key", __func__); 108 error("%s: no ECDSA key", __func__);
107 return -1; 109 return -1;
108 } 110 }
111 evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);
109 112
110 /* fetch signature */ 113 /* fetch signature */
111 char *ktype;
112 buffer_init(&b); 114 buffer_init(&b);
113 buffer_append(&b, signature, signaturelen); 115 buffer_append(&b, signature, signaturelen);
114 ktype = buffer_get_string(&b, NULL); 116 ktype = buffer_get_string(&b, NULL);