summaryrefslogtreecommitdiff
path: root/ssh-dss.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-dss.c')
-rw-r--r--ssh-dss.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/ssh-dss.c b/ssh-dss.c
index 9f832ee2b..a23c383dc 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -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) {