diff options
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r-- | ssh-ecdsa.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 3d3b78d7..9e92af04 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -49,6 +49,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat) { ECDSA_SIG *sig = NULL; + const BIGNUM *sig_r, *sig_s; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t len, dlen; @@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ret = SSH_ERR_ALLOC_FAIL; goto out; } - if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || - (ret = sshbuf_put_bignum2(bb, sig->s)) != 0) + ECDSA_SIG_get0(sig, &sig_r, &sig_s); + if ((ret = sshbuf_put_bignum2(bb, sig_r)) != 0 || + (ret = sshbuf_put_bignum2(bb, sig_s)) != 0) goto out; if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || (ret = sshbuf_put_stringb(b, bb)) != 0) @@ -112,6 +114,7 @@ ssh_ecdsa_verify(const struct sshkey *key, const u_char *data, size_t datalen, u_int compat) { ECDSA_SIG *sig = NULL; + BIGNUM *sig_r = NULL, *sig_s = NULL; int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH]; size_t dlen; @@ -146,15 +149,23 @@ ssh_ecdsa_verify(const struct sshkey *key, } /* parse signature */ - if ((sig = ECDSA_SIG_new()) == NULL) { + if ((sig = ECDSA_SIG_new()) == NULL || + (sig_r = BN_new()) == NULL || + (sig_s = BN_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || - sshbuf_get_bignum2(sigbuf, sig->s) != 0) { + if (sshbuf_get_bignum2(sigbuf, sig_r) != 0 || + sshbuf_get_bignum2(sigbuf, sig_s) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } + if (!ECDSA_SIG_set0(sig, sig_r, sig_s)) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + sig_r = sig_s = NULL; /* transferred */ + if (sshbuf_len(sigbuf) != 0) { ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; goto out; @@ -180,6 +191,8 @@ ssh_ecdsa_verify(const struct sshkey *key, sshbuf_free(sigbuf); sshbuf_free(b); ECDSA_SIG_free(sig); + BN_clear_free(sig_r); + BN_clear_free(sig_s); free(ktype); return ret; } |