summaryrefslogtreecommitdiff
path: root/ssh-dss.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-dss.c')
-rw-r--r--ssh-dss.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/ssh-dss.c b/ssh-dss.c
index 322ec9fd8..7b897475c 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-dss.c,v 1.28 2013/05/17 00:13:14 djm Exp $ */ 1/* $OpenBSD: ssh-dss.c,v 1.30 2014/01/09 23:20:00 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -38,6 +38,7 @@
38#include "compat.h" 38#include "compat.h"
39#include "log.h" 39#include "log.h"
40#include "key.h" 40#include "key.h"
41#include "digest.h"
41 42
42#define INTBLOB_LEN 20 43#define INTBLOB_LEN 20
43#define SIGBLOB_LEN (2*INTBLOB_LEN) 44#define SIGBLOB_LEN (2*INTBLOB_LEN)
@@ -47,20 +48,21 @@ ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
47 const u_char *data, u_int datalen) 48 const u_char *data, u_int datalen)
48{ 49{
49 DSA_SIG *sig; 50 DSA_SIG *sig;
50 const EVP_MD *evp_md = EVP_sha1(); 51 u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
51 EVP_MD_CTX md; 52 u_int rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
52 u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
53 u_int rlen, slen, len, dlen;
54 Buffer b; 53 Buffer b;
55 54
56 if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA && 55 if (key == NULL || key_type_plain(key->type) != KEY_DSA ||
57 key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) { 56 key->dsa == NULL) {
58 error("ssh_dss_sign: no DSA key"); 57 error("%s: no DSA key", __func__);
58 return -1;
59 }
60
61 if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
62 digest, sizeof(digest)) != 0) {
63 error("%s: ssh_digest_memory failed", __func__);
59 return -1; 64 return -1;
60 } 65 }
61 EVP_DigestInit(&md, evp_md);
62 EVP_DigestUpdate(&md, data, datalen);
63 EVP_DigestFinal(&md, digest, &dlen);
64 66
65 sig = DSA_do_sign(digest, dlen, key->dsa); 67 sig = DSA_do_sign(digest, dlen, key->dsa);
66 memset(digest, 'd', sizeof(digest)); 68 memset(digest, 'd', sizeof(digest));
@@ -110,16 +112,14 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
110 const u_char *data, u_int datalen) 112 const u_char *data, u_int datalen)
111{ 113{
112 DSA_SIG *sig; 114 DSA_SIG *sig;
113 const EVP_MD *evp_md = EVP_sha1(); 115 u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
114 EVP_MD_CTX md; 116 u_int len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
115 u_char digest[EVP_MAX_MD_SIZE], *sigblob;
116 u_int len, dlen;
117 int rlen, ret; 117 int rlen, ret;
118 Buffer b; 118 Buffer b;
119 119
120 if (key == NULL || key->dsa == NULL || (key->type != KEY_DSA && 120 if (key == NULL || key_type_plain(key->type) != KEY_DSA ||
121 key->type != KEY_DSA_CERT && key->type != KEY_DSA_CERT_V00)) { 121 key->dsa == NULL) {
122 error("ssh_dss_verify: no DSA key"); 122 error("%s: no DSA key", __func__);
123 return -1; 123 return -1;
124 } 124 }
125 125
@@ -135,7 +135,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
135 buffer_append(&b, signature, signaturelen); 135 buffer_append(&b, signature, signaturelen);
136 ktype = buffer_get_cstring(&b, NULL); 136 ktype = buffer_get_cstring(&b, NULL);
137 if (strcmp("ssh-dss", ktype) != 0) { 137 if (strcmp("ssh-dss", ktype) != 0) {
138 error("ssh_dss_verify: cannot handle type %s", ktype); 138 error("%s: cannot handle type %s", __func__, ktype);
139 buffer_free(&b); 139 buffer_free(&b);
140 free(ktype); 140 free(ktype);
141 return -1; 141 return -1;
@@ -145,8 +145,8 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
145 rlen = buffer_len(&b); 145 rlen = buffer_len(&b);
146 buffer_free(&b); 146 buffer_free(&b);
147 if (rlen != 0) { 147 if (rlen != 0) {
148 error("ssh_dss_verify: " 148 error("%s: remaining bytes in signature %d",
149 "remaining bytes in signature %d", rlen); 149 __func__, rlen);
150 free(sigblob); 150 free(sigblob);
151 return -1; 151 return -1;
152 } 152 }
@@ -158,30 +158,32 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
158 158
159 /* parse signature */ 159 /* parse signature */
160 if ((sig = DSA_SIG_new()) == NULL) 160 if ((sig = DSA_SIG_new()) == NULL)
161 fatal("ssh_dss_verify: DSA_SIG_new failed"); 161 fatal("%s: DSA_SIG_new failed", __func__);
162 if ((sig->r = BN_new()) == NULL) 162 if ((sig->r = BN_new()) == NULL)
163 fatal("ssh_dss_verify: BN_new failed"); 163 fatal("%s: BN_new failed", __func__);
164 if ((sig->s = BN_new()) == NULL) 164 if ((sig->s = BN_new()) == NULL)
165 fatal("ssh_dss_verify: BN_new failed"); 165 fatal("ssh_dss_verify: BN_new failed");
166 if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || 166 if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
167 (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) 167 (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL))
168 fatal("ssh_dss_verify: BN_bin2bn failed"); 168 fatal("%s: BN_bin2bn failed", __func__);
169 169
170 /* clean up */ 170 /* clean up */
171 memset(sigblob, 0, len); 171 memset(sigblob, 0, len);
172 free(sigblob); 172 free(sigblob);
173 173
174 /* sha1 the data */ 174 /* sha1 the data */
175 EVP_DigestInit(&md, evp_md); 175 if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
176 EVP_DigestUpdate(&md, data, datalen); 176 digest, sizeof(digest)) != 0) {
177 EVP_DigestFinal(&md, digest, &dlen); 177 error("%s: digest_memory failed", __func__);
178 return -1;
179 }
178 180
179 ret = DSA_do_verify(digest, dlen, sig, key->dsa); 181 ret = DSA_do_verify(digest, dlen, sig, key->dsa);
180 memset(digest, 'd', sizeof(digest)); 182 memset(digest, 'd', sizeof(digest));
181 183
182 DSA_SIG_free(sig); 184 DSA_SIG_free(sig);
183 185
184 debug("ssh_dss_verify: signature %s", 186 debug("%s: signature %s", __func__,
185 ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); 187 ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
186 return ret; 188 return ret;
187} 189}