diff options
Diffstat (limited to 'ssh-rsa.c')
| -rw-r--r-- | ssh-rsa.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/ssh-rsa.c b/ssh-rsa.c index f570ae6d40aa..49e71c87f64b 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.62 2017/07/01 13:50:45 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.66 2018/02/14 16:27:24 jsing Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> * @@ -33,6 +33,7 @@ #define SSHKEY_INTERNAL #include "sshkey.h" #include "digest.h" +#include "log.h" static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); @@ -78,13 +79,12 @@ rsa_hash_alg_nid(int type) } } -/* calculate p-1 and q-1 */ int ssh_rsa_generate_additional_parameters(struct sshkey *key) { - RSA *rsa; BIGNUM *aux = NULL; BN_CTX *ctx = NULL; + BIGNUM d; int r; if (key == NULL || key->rsa == NULL || @@ -97,12 +97,15 @@ ssh_rsa_generate_additional_parameters(struct sshkey *key) r = SSH_ERR_ALLOC_FAIL; goto out; } - rsa = key->rsa; + BN_set_flags(aux, BN_FLG_CONSTTIME); - if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || - (BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || - (BN_sub(aux, rsa->p, BN_value_one()) == 0) || - (BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { + BN_init(&d); + BN_with_flags(&d, key->rsa->d, BN_FLG_CONSTTIME); + + if ((BN_sub(aux, key->rsa->q, BN_value_one()) == 0) || + (BN_mod(key->rsa->dmq1, &d, aux, ctx) == 0) || + (BN_sub(aux, key->rsa->p, BN_value_one()) == 0) || + (BN_mod(key->rsa->dmp1, &d, aux, ctx) == 0)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -119,7 +122,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *alg_ident) { u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; - size_t slen; + size_t slen = 0; u_int dlen, len; int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; @@ -188,21 +191,19 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ret = 0; out: explicit_bzero(digest, sizeof(digest)); - if (sig != NULL) { - explicit_bzero(sig, slen); - free(sig); - } + freezero(sig, slen); sshbuf_free(b); return ret; } int ssh_rsa_verify(const struct sshkey *key, - const u_char *sig, size_t siglen, const u_char *data, size_t datalen) + const u_char *sig, size_t siglen, const u_char *data, size_t datalen, + const char *alg) { - char *ktype = NULL; + char *sigtype = NULL; int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; - size_t len, diff, modlen, dlen; + size_t len = 0, diff, modlen, dlen; struct sshbuf *b = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; @@ -215,11 +216,19 @@ ssh_rsa_verify(const struct sshkey *key, if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; - if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { + if (sshbuf_get_cstring(b, &sigtype, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } - if ((hash_alg = rsa_hash_alg_from_ident(ktype)) == -1) { + /* XXX djm: need cert types that reliably yield SHA-2 signatures */ + if (alg != NULL && strcmp(alg, sigtype) != 0 && + strcmp(alg, "ssh-rsa-cert-v01@openssh.com") != 0) { + error("%s: RSA signature type mismatch: " + "expected %s received %s", __func__, alg, sigtype); + ret = SSH_ERR_SIGNATURE_INVALID; + goto out; + } + if ((hash_alg = rsa_hash_alg_from_ident(sigtype)) == -1) { ret = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } @@ -259,11 +268,8 @@ ssh_rsa_verify(const struct sshkey *key, ret = openssh_RSA_verify(hash_alg, digest, dlen, sigblob, len, key->rsa); out: - if (sigblob != NULL) { - explicit_bzero(sigblob, len); - free(sigblob); - } - free(ktype); + freezero(sigblob, len); + free(sigtype); sshbuf_free(b); explicit_bzero(digest, sizeof(digest)); return ret; @@ -384,10 +390,7 @@ openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, } ret = 0; done: - if (decrypted) { - explicit_bzero(decrypted, rsasize); - free(decrypted); - } + freezero(decrypted, rsasize); return ret; } #endif /* WITH_OPENSSL */ |
