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