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 f570ae6d40aa7..49e71c87f64b2 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 */ | 
