diff options
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r-- | ssh-ecdsa.c | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 766338941..10ad9da60 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-ecdsa.c,v 1.6 2013/05/17 00:13:14 djm Exp $ */ | 1 | /* $OpenBSD: ssh-ecdsa.c,v 1.8 2014/01/09 23:20:00 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. |
@@ -42,27 +42,34 @@ | |||
42 | #include "compat.h" | 42 | #include "compat.h" |
43 | #include "log.h" | 43 | #include "log.h" |
44 | #include "key.h" | 44 | #include "key.h" |
45 | #include "digest.h" | ||
45 | 46 | ||
46 | int | 47 | int |
47 | ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, | 48 | ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, |
48 | const u_char *data, u_int datalen) | 49 | const u_char *data, u_int datalen) |
49 | { | 50 | { |
50 | ECDSA_SIG *sig; | 51 | ECDSA_SIG *sig; |
51 | const EVP_MD *evp_md; | 52 | int hash_alg; |
52 | EVP_MD_CTX md; | 53 | u_char digest[SSH_DIGEST_MAX_LENGTH]; |
53 | u_char digest[EVP_MAX_MD_SIZE]; | ||
54 | u_int len, dlen; | 54 | u_int len, dlen; |
55 | Buffer b, bb; | 55 | Buffer b, bb; |
56 | 56 | ||
57 | if (key == NULL || key->ecdsa == NULL || | 57 | if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || |
58 | (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { | 58 | key->ecdsa == NULL) { |
59 | error("%s: no ECDSA key", __func__); | 59 | error("%s: no ECDSA key", __func__); |
60 | return -1; | 60 | return -1; |
61 | } | 61 | } |
62 | evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); | 62 | |
63 | EVP_DigestInit(&md, evp_md); | 63 | hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid); |
64 | EVP_DigestUpdate(&md, data, datalen); | 64 | if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { |
65 | EVP_DigestFinal(&md, digest, &dlen); | 65 | error("%s: bad hash algorithm %d", __func__, hash_alg); |
66 | return -1; | ||
67 | } | ||
68 | if (ssh_digest_memory(hash_alg, data, datalen, | ||
69 | digest, sizeof(digest)) != 0) { | ||
70 | error("%s: digest_memory failed", __func__); | ||
71 | return -1; | ||
72 | } | ||
66 | 73 | ||
67 | sig = ECDSA_do_sign(digest, dlen, key->ecdsa); | 74 | sig = ECDSA_do_sign(digest, dlen, key->ecdsa); |
68 | memset(digest, 'd', sizeof(digest)); | 75 | memset(digest, 'd', sizeof(digest)); |
@@ -97,20 +104,18 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
97 | const u_char *data, u_int datalen) | 104 | const u_char *data, u_int datalen) |
98 | { | 105 | { |
99 | ECDSA_SIG *sig; | 106 | ECDSA_SIG *sig; |
100 | const EVP_MD *evp_md; | 107 | int hash_alg; |
101 | EVP_MD_CTX md; | 108 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; |
102 | u_char digest[EVP_MAX_MD_SIZE], *sigblob; | ||
103 | u_int len, dlen; | 109 | u_int len, dlen; |
104 | int rlen, ret; | 110 | int rlen, ret; |
105 | Buffer b, bb; | 111 | Buffer b, bb; |
106 | char *ktype; | 112 | char *ktype; |
107 | 113 | ||
108 | if (key == NULL || key->ecdsa == NULL || | 114 | if (key == NULL || key_type_plain(key->type) != KEY_ECDSA || |
109 | (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { | 115 | key->ecdsa == NULL) { |
110 | error("%s: no ECDSA key", __func__); | 116 | error("%s: no ECDSA key", __func__); |
111 | return -1; | 117 | return -1; |
112 | } | 118 | } |
113 | evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); | ||
114 | 119 | ||
115 | /* fetch signature */ | 120 | /* fetch signature */ |
116 | buffer_init(&b); | 121 | buffer_init(&b); |
@@ -152,9 +157,16 @@ ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
152 | free(sigblob); | 157 | free(sigblob); |
153 | 158 | ||
154 | /* hash the data */ | 159 | /* hash the data */ |
155 | EVP_DigestInit(&md, evp_md); | 160 | hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid); |
156 | EVP_DigestUpdate(&md, data, datalen); | 161 | if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { |
157 | EVP_DigestFinal(&md, digest, &dlen); | 162 | error("%s: bad hash algorithm %d", __func__, hash_alg); |
163 | return -1; | ||
164 | } | ||
165 | if (ssh_digest_memory(hash_alg, data, datalen, | ||
166 | digest, sizeof(digest)) != 0) { | ||
167 | error("%s: digest_memory failed", __func__); | ||
168 | return -1; | ||
169 | } | ||
158 | 170 | ||
159 | ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); | 171 | ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); |
160 | memset(digest, 'd', sizeof(digest)); | 172 | memset(digest, 'd', sizeof(digest)); |