diff options
Diffstat (limited to 'ssh-dss.c')
-rw-r--r-- | ssh-dss.c | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -43,6 +43,8 @@ | |||
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 | #define INTBLOB_LEN 20 | 48 | #define INTBLOB_LEN 20 |
47 | #define SIGBLOB_LEN (2*INTBLOB_LEN) | 49 | #define SIGBLOB_LEN (2*INTBLOB_LEN) |
48 | 50 | ||
@@ -51,6 +53,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | |||
51 | const u_char *data, size_t datalen, u_int compat) | 53 | const u_char *data, size_t datalen, u_int compat) |
52 | { | 54 | { |
53 | DSA_SIG *sig = NULL; | 55 | DSA_SIG *sig = NULL; |
56 | const BIGNUM *sig_r, *sig_s; | ||
54 | u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; | 57 | u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN]; |
55 | size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); | 58 | size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); |
56 | struct sshbuf *b = NULL; | 59 | struct sshbuf *b = NULL; |
@@ -76,15 +79,16 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | |||
76 | goto out; | 79 | goto out; |
77 | } | 80 | } |
78 | 81 | ||
79 | rlen = BN_num_bytes(sig->r); | 82 | DSA_SIG_get0(sig, &sig_r, &sig_s); |
80 | slen = BN_num_bytes(sig->s); | 83 | rlen = BN_num_bytes(sig_r); |
84 | slen = BN_num_bytes(sig_s); | ||
81 | if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { | 85 | if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { |
82 | ret = SSH_ERR_INTERNAL_ERROR; | 86 | ret = SSH_ERR_INTERNAL_ERROR; |
83 | goto out; | 87 | goto out; |
84 | } | 88 | } |
85 | explicit_bzero(sigblob, SIGBLOB_LEN); | 89 | explicit_bzero(sigblob, SIGBLOB_LEN); |
86 | BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); | 90 | BN_bn2bin(sig_r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); |
87 | BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); | 91 | BN_bn2bin(sig_s, sigblob + SIGBLOB_LEN - slen); |
88 | 92 | ||
89 | if ((b = sshbuf_new()) == NULL) { | 93 | if ((b = sshbuf_new()) == NULL) { |
90 | ret = SSH_ERR_ALLOC_FAIL; | 94 | ret = SSH_ERR_ALLOC_FAIL; |
@@ -118,6 +122,7 @@ ssh_dss_verify(const struct sshkey *key, | |||
118 | const u_char *data, size_t datalen, u_int compat) | 122 | const u_char *data, size_t datalen, u_int compat) |
119 | { | 123 | { |
120 | DSA_SIG *sig = NULL; | 124 | DSA_SIG *sig = NULL; |
125 | BIGNUM *sig_r = NULL, *sig_s = NULL; | ||
121 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; | 126 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob = NULL; |
122 | size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); | 127 | size_t len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1); |
123 | int ret = SSH_ERR_INTERNAL_ERROR; | 128 | int ret = SSH_ERR_INTERNAL_ERROR; |
@@ -155,16 +160,21 @@ ssh_dss_verify(const struct sshkey *key, | |||
155 | 160 | ||
156 | /* parse signature */ | 161 | /* parse signature */ |
157 | if ((sig = DSA_SIG_new()) == NULL || | 162 | if ((sig = DSA_SIG_new()) == NULL || |
158 | (sig->r = BN_new()) == NULL || | 163 | (sig_r = BN_new()) == NULL || |
159 | (sig->s = BN_new()) == NULL) { | 164 | (sig_s = BN_new()) == NULL) { |
160 | ret = SSH_ERR_ALLOC_FAIL; | 165 | ret = SSH_ERR_ALLOC_FAIL; |
161 | goto out; | 166 | goto out; |
162 | } | 167 | } |
163 | if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || | 168 | if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig_r) == NULL) || |
164 | (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { | 169 | (BN_bin2bn(sigblob + INTBLOB_LEN, INTBLOB_LEN, sig_s) == NULL)) { |
170 | ret = SSH_ERR_LIBCRYPTO_ERROR; | ||
171 | goto out; | ||
172 | } | ||
173 | if (!DSA_SIG_set0(sig, sig_r, sig_s)) { | ||
165 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 174 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
166 | goto out; | 175 | goto out; |
167 | } | 176 | } |
177 | sig_r = sig_s = NULL; /* transferred */ | ||
168 | 178 | ||
169 | /* sha1 the data */ | 179 | /* sha1 the data */ |
170 | if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, | 180 | if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, |
@@ -186,6 +196,8 @@ ssh_dss_verify(const struct sshkey *key, | |||
186 | out: | 196 | out: |
187 | explicit_bzero(digest, sizeof(digest)); | 197 | explicit_bzero(digest, sizeof(digest)); |
188 | DSA_SIG_free(sig); | 198 | DSA_SIG_free(sig); |
199 | BN_clear_free(sig_r); | ||
200 | BN_clear_free(sig_s); | ||
189 | sshbuf_free(b); | 201 | sshbuf_free(b); |
190 | free(ktype); | 202 | free(ktype); |
191 | if (sigblob != NULL) { | 203 | if (sigblob != NULL) { |