diff options
author | Damien Miller <djm@mindrot.org> | 2010-09-10 11:23:34 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2010-09-10 11:23:34 +1000 |
commit | 041ab7c1e7d6514ed84a539a767f79ffb356e807 (patch) | |
tree | c6528487bfc1cfa824655e48ef884b2c268c8588 /ssh-ecdsa.c | |
parent | 3796ab47d3f68f69512c360f178b77bf0fb12b4f (diff) |
- djm@cvs.openbsd.org 2010/09/09 10:45:45
[kex.c kex.h kexecdh.c key.c key.h monitor.c ssh-ecdsa.c]
ECDH/ECDSA compliance fix: these methods vary the hash function they use
(SHA256/384/512) depending on the length of the curve in use. The previous
code incorrectly used SHA256 in all cases.
This fix will cause authentication failure when using 384 or 521-bit curve
keys if one peer hasn't been upgraded and the other has. (256-bit curve
keys work ok). In particular you may need to specify HostkeyAlgorithms
when connecting to a server that has not been upgraded from an upgraded
client.
ok naddy@
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r-- | ssh-ecdsa.c | 10 |
1 files changed, 6 insertions, 4 deletions
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); |