diff options
Diffstat (limited to 'ssh-rsa.c')
-rw-r--r-- | ssh-rsa.c | 57 |
1 files changed, 30 insertions, 27 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-rsa.c,v 1.62 2017/07/01 13:50:45 djm Exp $ */ | 1 | /* $OpenBSD: ssh-rsa.c,v 1.66 2018/02/14 16:27:24 jsing 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 | * |
@@ -33,6 +33,7 @@ | |||
33 | #define SSHKEY_INTERNAL | 33 | #define SSHKEY_INTERNAL |
34 | #include "sshkey.h" | 34 | #include "sshkey.h" |
35 | #include "digest.h" | 35 | #include "digest.h" |
36 | #include "log.h" | ||
36 | 37 | ||
37 | static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); | 38 | static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); |
38 | 39 | ||
@@ -78,13 +79,12 @@ rsa_hash_alg_nid(int type) | |||
78 | } | 79 | } |
79 | } | 80 | } |
80 | 81 | ||
81 | /* calculate p-1 and q-1 */ | ||
82 | int | 82 | int |
83 | ssh_rsa_generate_additional_parameters(struct sshkey *key) | 83 | ssh_rsa_generate_additional_parameters(struct sshkey *key) |
84 | { | 84 | { |
85 | RSA *rsa; | ||
86 | BIGNUM *aux = NULL; | 85 | BIGNUM *aux = NULL; |
87 | BN_CTX *ctx = NULL; | 86 | BN_CTX *ctx = NULL; |
87 | BIGNUM d; | ||
88 | int r; | 88 | int r; |
89 | 89 | ||
90 | if (key == NULL || key->rsa == NULL || | 90 | if (key == NULL || key->rsa == NULL || |
@@ -97,12 +97,15 @@ ssh_rsa_generate_additional_parameters(struct sshkey *key) | |||
97 | r = SSH_ERR_ALLOC_FAIL; | 97 | r = SSH_ERR_ALLOC_FAIL; |
98 | goto out; | 98 | goto out; |
99 | } | 99 | } |
100 | rsa = key->rsa; | 100 | BN_set_flags(aux, BN_FLG_CONSTTIME); |
101 | 101 | ||
102 | if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || | 102 | BN_init(&d); |
103 | (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || | 103 | BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); |
104 | (BN_sub(aux, rsa->p, BN_value_one()) == 0) || | 104 | |
105 | (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { | 105 | if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || |
106 | (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || | ||
107 | (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || | ||
108 | (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { | ||
106 | r = SSH_ERR_LIBCRYPTO_ERROR; | 109 | r = SSH_ERR_LIBCRYPTO_ERROR; |
107 | goto out; | 110 | goto out; |
108 | } | 111 | } |
@@ -119,7 +122,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | |||
119 | const u_char *data, size_t datalen, const char *alg_ident) | 122 | const u_char *data, size_t datalen, const char *alg_ident) |
120 | { | 123 | { |
121 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; | 124 | u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; |
122 | size_t slen; | 125 | size_t slen = 0; |
123 | u_int dlen, len; | 126 | u_int dlen, len; |
124 | int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; | 127 | int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; |
125 | struct sshbuf *b = NULL; | 128 | struct sshbuf *b = NULL; |
@@ -188,21 +191,19 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, | |||
188 | ret = 0; | 191 | ret = 0; |
189 | out: | 192 | out: |
190 | explicit_bzero(digest, sizeof(digest)); | 193 | explicit_bzero(digest, sizeof(digest)); |
191 | if (sig != NULL) { | 194 | freezero(sig, slen); |
192 | explicit_bzero(sig, slen); | ||
193 | free(sig); | ||
194 | } | ||
195 | sshbuf_free(b); | 195 | sshbuf_free(b); |
196 | return ret; | 196 | return ret; |
197 | } | 197 | } |
198 | 198 | ||
199 | int | 199 | int |
200 | ssh_rsa_verify(const struct sshkey *key, | 200 | ssh_rsa_verify(const struct sshkey *key, |
201 | const u_char *sig, size_t siglen, const u_char *data, size_t datalen) | 201 | const u_char *sig, size_t siglen, const u_char *data, size_t datalen, |
202 | const char *alg) | ||
202 | { | 203 | { |
203 | char *ktype = NULL; | 204 | char *sigtype = NULL; |
204 | int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; | 205 | int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; |
205 | size_t len, diff, modlen, dlen; | 206 | size_t len = 0, diff, modlen, dlen; |
206 | struct sshbuf *b = NULL; | 207 | struct sshbuf *b = NULL; |
207 | u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; | 208 | u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; |
208 | 209 | ||
@@ -215,11 +216,19 @@ ssh_rsa_verify(const struct sshkey *key, | |||
215 | 216 | ||
216 | if ((b = sshbuf_from(sig, siglen)) == NULL) | 217 | if ((b = sshbuf_from(sig, siglen)) == NULL) |
217 | return SSH_ERR_ALLOC_FAIL; | 218 | return SSH_ERR_ALLOC_FAIL; |
218 | if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { | 219 | if (sshbuf_get_cstring(b, &sigtype, NULL) != 0) { |
219 | ret = SSH_ERR_INVALID_FORMAT; | 220 | ret = SSH_ERR_INVALID_FORMAT; |
220 | goto out; | 221 | goto out; |
221 | } | 222 | } |
222 | if ((hash_alg = rsa_hash_alg_from_ident(ktype)) == -1) { | 223 | /* XXX djm: need cert types that reliably yield SHA-2 signatures */ |
224 | if (alg != NULL && strcmp(alg, sigtype) != 0 && | ||
225 | strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { | ||
226 | error("%s: RSA signature type mismatch: " | ||
227 | "expected %s received %s", __func__, alg, sigtype); | ||
228 | ret = SSH_ERR_SIGNATURE_INVALID; | ||
229 | goto out; | ||
230 | } | ||
231 | if ((hash_alg = rsa_hash_alg_from_ident(sigtype)) == -1) { | ||
223 | ret = SSH_ERR_KEY_TYPE_MISMATCH; | 232 | ret = SSH_ERR_KEY_TYPE_MISMATCH; |
224 | goto out; | 233 | goto out; |
225 | } | 234 | } |
@@ -259,11 +268,8 @@ ssh_rsa_verify(const struct sshkey *key, | |||
259 | ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, | 268 | ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, |
260 | key->rsa); | 269 | key->rsa); |
261 | out: | 270 | out: |
262 | if (sigblob != NULL) { | 271 | freezero(sigblob, len); |
263 | explicit_bzero(sigblob, len); | 272 | free(sigtype); |
264 | free(sigblob); | ||
265 | } | ||
266 | free(ktype); | ||
267 | sshbuf_free(b); | 273 | sshbuf_free(b); |
268 | explicit_bzero(digest, sizeof(digest)); | 274 | explicit_bzero(digest, sizeof(digest)); |
269 | return ret; | 275 | return ret; |
@@ -384,10 +390,7 @@ openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, | |||
384 | } | 390 | } |
385 | ret = 0; | 391 | ret = 0; |
386 | done: | 392 | done: |
387 | if (decrypted) { | 393 | freezero(decrypted, rsasize); |
388 | explicit_bzero(decrypted, rsasize); | ||
389 | free(decrypted); | ||
390 | } | ||
391 | return ret; | 394 | return ret; |
392 | } | 395 | } |
393 | #endif /* WITH_OPENSSL */ | 396 | #endif /* WITH_OPENSSL */ |