diff options
Diffstat (limited to 'ssh-dss.c')
-rw-r--r-- | ssh-dss.c | 58 |
1 files changed, 30 insertions, 28 deletions
@@ -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 | } |