diff options
author | Damien Miller <djm@mindrot.org> | 2014-01-10 10:58:53 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-01-10 10:58:53 +1100 |
commit | b3051d01e505c9c2dc00faab472a0d06fa6b0e65 (patch) | |
tree | c0ca49b5fc4e5e1a066157b4dbd9c68cfcd41d63 /ssh-rsa.c | |
parent | e00e413dd16eb747fb2c15a099971d91c13cf70f (diff) |
- djm@cvs.openbsd.org 2014/01/09 23:20:00
[digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c]
[kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c]
[kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c]
[schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c]
Introduce digest API and use it to perform all hashing operations
rather than calling OpenSSL EVP_Digest* directly. Will make it easier
to build a reduced-feature OpenSSH without OpenSSL in future;
feedback, ok markus@
Diffstat (limited to 'ssh-rsa.c')
-rw-r--r-- | ssh-rsa.c | 54 |
1 files changed, 30 insertions, 24 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-rsa.c,v 1.49 2013/12/30 23:52:27 djm Exp $ */ | 1 | /* $OpenBSD: ssh-rsa.c,v 1.50 2014/01/09 23:20:00 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> | 3 | * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> |
4 | * | 4 | * |
@@ -32,6 +32,7 @@ | |||
32 | #include "compat.h" | 32 | #include "compat.h" |
33 | #include "misc.h" | 33 | #include "misc.h" |
34 | #include "ssh.h" | 34 | #include "ssh.h" |
35 | #include "digest.h" | ||
35 | 36 | ||
36 | static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); | 37 | static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *); |
37 | 38 | ||
@@ -40,9 +41,8 @@ int | |||
40 | ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, | 41 | ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, |
41 | const u_char *data, u_int datalen) | 42 | const u_char *data, u_int datalen) |
42 | { | 43 | { |
43 | const EVP_MD *evp_md; | 44 | int hash_alg; |
44 | EVP_MD_CTX md; | 45 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sig; |
45 | u_char digest[EVP_MAX_MD_SIZE], *sig; | ||
46 | u_int slen, dlen, len; | 46 | u_int slen, dlen, len; |
47 | int ok, nid; | 47 | int ok, nid; |
48 | Buffer b; | 48 | Buffer b; |
@@ -53,14 +53,18 @@ ssh_rsa_sign(const Key *key, u_char **sigp, u_int *lenp, | |||
53 | return -1; | 53 | return -1; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* hash the data */ | ||
57 | hash_alg = SSH_DIGEST_SHA1; | ||
56 | nid = NID_sha1; | 58 | nid = NID_sha1; |
57 | if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { | 59 | if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { |
58 | error("%s: EVP_get_digestbynid %d failed", __func__, nid); | 60 | error("%s: bad hash algorithm %d", __func__, hash_alg); |
61 | return -1; | ||
62 | } | ||
63 | if (ssh_digest_memory(hash_alg, data, datalen, | ||
64 | digest, sizeof(digest)) != 0) { | ||
65 | error("%s: ssh_digest_memory failed", __func__); | ||
59 | return -1; | 66 | return -1; |
60 | } | 67 | } |
61 | EVP_DigestInit(&md, evp_md); | ||
62 | EVP_DigestUpdate(&md, data, datalen); | ||
63 | EVP_DigestFinal(&md, digest, &dlen); | ||
64 | 68 | ||
65 | slen = RSA_size(key->rsa); | 69 | slen = RSA_size(key->rsa); |
66 | sig = xmalloc(slen); | 70 | sig = xmalloc(slen); |
@@ -109,12 +113,11 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
109 | const u_char *data, u_int datalen) | 113 | const u_char *data, u_int datalen) |
110 | { | 114 | { |
111 | Buffer b; | 115 | Buffer b; |
112 | const EVP_MD *evp_md; | 116 | int hash_alg; |
113 | EVP_MD_CTX md; | ||
114 | char *ktype; | 117 | char *ktype; |
115 | u_char digest[EVP_MAX_MD_SIZE], *sigblob; | 118 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob; |
116 | u_int len, dlen, modlen; | 119 | u_int len, dlen, modlen; |
117 | int rlen, ret, nid; | 120 | int rlen, ret; |
118 | 121 | ||
119 | if (key == NULL || key_type_plain(key->type) != KEY_RSA || | 122 | if (key == NULL || key_type_plain(key->type) != KEY_RSA || |
120 | key->rsa == NULL) { | 123 | key->rsa == NULL) { |
@@ -161,17 +164,20 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, | |||
161 | memset(sigblob, 0, diff); | 164 | memset(sigblob, 0, diff); |
162 | len = modlen; | 165 | len = modlen; |
163 | } | 166 | } |
164 | nid = NID_sha1; | 167 | /* hash the data */ |
165 | if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { | 168 | hash_alg = SSH_DIGEST_SHA1; |
166 | error("%s: EVP_get_digestbynid %d failed", __func__, nid); | 169 | if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { |
167 | free(sigblob); | 170 | error("%s: bad hash algorithm %d", __func__, hash_alg); |
171 | return -1; | ||
172 | } | ||
173 | if (ssh_digest_memory(hash_alg, data, datalen, | ||
174 | digest, sizeof(digest)) != 0) { | ||
175 | error("%s: ssh_digest_memory failed", __func__); | ||
168 | return -1; | 176 | return -1; |
169 | } | 177 | } |
170 | EVP_DigestInit(&md, evp_md); | ||
171 | EVP_DigestUpdate(&md, data, datalen); | ||
172 | EVP_DigestFinal(&md, digest, &dlen); | ||
173 | 178 | ||
174 | ret = openssh_RSA_verify(nid, digest, dlen, sigblob, len, key->rsa); | 179 | ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, |
180 | key->rsa); | ||
175 | memset(digest, 'd', sizeof(digest)); | 181 | memset(digest, 'd', sizeof(digest)); |
176 | memset(sigblob, 's', len); | 182 | memset(sigblob, 's', len); |
177 | free(sigblob); | 183 | free(sigblob); |
@@ -198,7 +204,7 @@ static const u_char id_sha1[] = { | |||
198 | }; | 204 | }; |
199 | 205 | ||
200 | static int | 206 | static int |
201 | openssh_RSA_verify(int type, u_char *hash, u_int hashlen, | 207 | openssh_RSA_verify(int hash_alg, u_char *hash, u_int hashlen, |
202 | u_char *sigbuf, u_int siglen, RSA *rsa) | 208 | u_char *sigbuf, u_int siglen, RSA *rsa) |
203 | { | 209 | { |
204 | u_int ret, rsasize, oidlen = 0, hlen = 0; | 210 | u_int ret, rsasize, oidlen = 0, hlen = 0; |
@@ -207,8 +213,8 @@ openssh_RSA_verify(int type, u_char *hash, u_int hashlen, | |||
207 | u_char *decrypted = NULL; | 213 | u_char *decrypted = NULL; |
208 | 214 | ||
209 | ret = 0; | 215 | ret = 0; |
210 | switch (type) { | 216 | switch (hash_alg) { |
211 | case NID_sha1: | 217 | case SSH_DIGEST_SHA1: |
212 | oid = id_sha1; | 218 | oid = id_sha1; |
213 | oidlen = sizeof(id_sha1); | 219 | oidlen = sizeof(id_sha1); |
214 | hlen = 20; | 220 | hlen = 20; |