diff options
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r-- | ssh-ecdsa.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 3d3b78d7b..2f5531752 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c | |||
@@ -43,12 +43,15 @@ | |||
43 | #define SSHKEY_INTERNAL | 43 | #define SSHKEY_INTERNAL |
44 | #include "sshkey.h" | 44 | #include "sshkey.h" |
45 | 45 | ||
46 | #include "openbsd-compat/openssl-compat.h" | ||
47 | |||
46 | /* ARGSUSED */ | 48 | /* ARGSUSED */ |
47 | int | 49 | int |
48 | ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | 50 | ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, |
49 | const u_char *data, size_t datalen, u_int compat) | 51 | const u_char *data, size_t datalen, u_int compat) |
50 | { | 52 | { |
51 | ECDSA_SIG *sig = NULL; | 53 | ECDSA_SIG *sig = NULL; |
54 | const BIGNUM *sig_r, *sig_s; | ||
52 | int hash_alg; | 55 | int hash_alg; |
53 | u_char digest[SSH_DIGEST_MAX_LENGTH]; | 56 | u_char digest[SSH_DIGEST_MAX_LENGTH]; |
54 | size_t len, dlen; | 57 | size_t len, dlen; |
@@ -80,8 +83,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | |||
80 | ret = SSH_ERR_ALLOC_FAIL; | 83 | ret = SSH_ERR_ALLOC_FAIL; |
81 | goto out; | 84 | goto out; |
82 | } | 85 | } |
83 | if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || | 86 | ECDSA_SIG_get0(sig, &sig_r, &sig_s); |
84 | (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) | 87 | if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 || |
88 | (ret = sshbuf_put_bignum2(bb, sig_s)) != 0) | ||
85 | goto out; | 89 | goto out; |
86 | if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || | 90 | if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || |
87 | (ret = sshbuf_put_stringb(b, bb)) != 0) | 91 | (ret = sshbuf_put_stringb(b, bb)) != 0) |
@@ -112,6 +116,7 @@ ssh_ecdsa_verify(const struct sshkey *key, | |||
112 | const u_char *data, size_t datalen, u_int compat) | 116 | const u_char *data, size_t datalen, u_int compat) |
113 | { | 117 | { |
114 | ECDSA_SIG *sig = NULL; | 118 | ECDSA_SIG *sig = NULL; |
119 | BIGNUM *sig_r = NULL, *sig_s = NULL; | ||
115 | int hash_alg; | 120 | int hash_alg; |
116 | u_char digest[SSH_DIGEST_MAX_LENGTH]; | 121 | u_char digest[SSH_DIGEST_MAX_LENGTH]; |
117 | size_t dlen; | 122 | size_t dlen; |
@@ -146,15 +151,23 @@ ssh_ecdsa_verify(const struct sshkey *key, | |||
146 | } | 151 | } |
147 | 152 | ||
148 | /* parse signature */ | 153 | /* parse signature */ |
149 | if ((sig = ECDSA_SIG_new()) == NULL) { | 154 | if ((sig = ECDSA_SIG_new()) == NULL || |
155 | (sig_r = BN_new()) == NULL || | ||
156 | (sig_s = BN_new()) == NULL) { | ||
150 | ret = SSH_ERR_ALLOC_FAIL; | 157 | ret = SSH_ERR_ALLOC_FAIL; |
151 | goto out; | 158 | goto out; |
152 | } | 159 | } |
153 | if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || | 160 | if (sshbuf_get_bignum2(sigbuf, sig_r) != 0 || |
154 | sshbuf_get_bignum2(sigbuf, sig->s) != 0) { | 161 | sshbuf_get_bignum2(sigbuf, sig_s) != 0) { |
155 | ret = SSH_ERR_INVALID_FORMAT; | 162 | ret = SSH_ERR_INVALID_FORMAT; |
156 | goto out; | 163 | goto out; |
157 | } | 164 | } |
165 | if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) { | ||
166 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
167 | goto out; | ||
168 | } | ||
169 | sig_r = sig_s = NULL; /* transferred */ | ||
170 | |||
158 | if (sshbuf_len(sigbuf) != 0) { | 171 | if (sshbuf_len(sigbuf) != 0) { |
159 | ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; | 172 | ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; |
160 | goto out; | 173 | goto out; |
@@ -180,6 +193,8 @@ ssh_ecdsa_verify(const struct sshkey *key, | |||
180 | sshbuf_free(sigbuf); | 193 | sshbuf_free(sigbuf); |
181 | sshbuf_free(b); | 194 | sshbuf_free(b); |
182 | ECDSA_SIG_free(sig); | 195 | ECDSA_SIG_free(sig); |
196 | BN_clear_free(sig_r); | ||
197 | BN_clear_free(sig_s); | ||
183 | free(ktype); | 198 | free(ktype); |
184 | return ret; | 199 | return ret; |
185 | } | 200 | } |