summaryrefslogtreecommitdiff
path: root/ssh-ecdsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-ecdsa.c')
-rw-r--r--ssh-ecdsa.c25
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 */
47int 49int
48ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, 50ssh_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}