diff options
Diffstat (limited to 'crypto/openssh/sshkey.c')
-rw-r--r-- | crypto/openssh/sshkey.c | 96 |
1 files changed, 47 insertions, 49 deletions
diff --git a/crypto/openssh/sshkey.c b/crypto/openssh/sshkey.c index f1e92003b7e4..770932357139 100644 --- a/crypto/openssh/sshkey.c +++ b/crypto/openssh/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.120 2022/01/06 22:05:42 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.122 2022/09/17 10:30:45 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -2125,14 +2125,38 @@ sshkey_shield_private(struct sshkey *k) return r; } +/* Check deterministic padding after private key */ +static int +private2_check_padding(struct sshbuf *decrypted) +{ + u_char pad; + size_t i; + int r; + + i = 0; + while (sshbuf_len(decrypted)) { + if ((r = sshbuf_get_u8(decrypted, &pad)) != 0) + goto out; + if (pad != (++i & 0xff)) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + } + /* success */ + r = 0; + out: + explicit_bzero(&pad, sizeof(pad)); + explicit_bzero(&i, sizeof(i)); + return r; +} + int sshkey_unshield_private(struct sshkey *k) { struct sshbuf *prvbuf = NULL; - u_char pad, *cp, keyiv[SSH_DIGEST_MAX_LENGTH]; + u_char *cp, keyiv[SSH_DIGEST_MAX_LENGTH]; struct sshcipher_ctx *cctx = NULL; const struct sshcipher *cipher; - size_t i; struct sshkey *kswap = NULL, tmp; int r = SSH_ERR_INTERNAL_ERROR; @@ -2194,16 +2218,9 @@ sshkey_unshield_private(struct sshkey *k) /* Parse private key */ if ((r = sshkey_private_deserialize(prvbuf, &kswap)) != 0) goto out; - /* Check deterministic padding */ - i = 0; - while (sshbuf_len(prvbuf)) { - if ((r = sshbuf_get_u8(prvbuf, &pad)) != 0) - goto out; - if (pad != (++i & 0xff)) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - } + + if ((r = private2_check_padding(prvbuf)) != 0) + goto out; /* Swap the parsed key back into place */ tmp = *kswap; @@ -2348,18 +2365,24 @@ cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) return ret; } -#ifdef WITH_OPENSSL -static int -check_rsa_length(const RSA *rsa) +int +sshkey_check_rsa_length(const struct sshkey *k, int min_size) { +#ifdef WITH_OPENSSL const BIGNUM *rsa_n; + int nbits; - RSA_get0_key(rsa, &rsa_n, NULL, NULL); - if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) + if (k == NULL || k->rsa == NULL || + (k->type != KEY_RSA && k->type != KEY_RSA_CERT)) + return 0; + RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); + nbits = BN_num_bits(rsa_n); + if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || + (min_size > 0 && nbits < min_size)) return SSH_ERR_KEY_LENGTH; +#endif /* WITH_OPENSSL */ return 0; } -#endif static int sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, @@ -2422,7 +2445,7 @@ sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, goto out; } rsa_n = rsa_e = NULL; /* transferred */ - if ((ret = check_rsa_length(key->rsa)) != 0) + if ((ret = sshkey_check_rsa_length(key, 0)) != 0) goto out; #ifdef DEBUG_PK RSA_print_fp(stderr, key->rsa, 8); @@ -3625,7 +3648,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) goto out; } rsa_p = rsa_q = NULL; /* transferred */ - if ((r = check_rsa_length(k->rsa)) != 0) + if ((r = sshkey_check_rsa_length(k, 0)) != 0) goto out; if ((r = ssh_rsa_complete_crt_parameters(k, rsa_iqmp)) != 0) goto out; @@ -4028,9 +4051,9 @@ sshkey_private_to_blob2(struct sshkey *prv, struct sshbuf *blob, explicit_bzero(salt, sizeof(salt)); if (key != NULL) freezero(key, keylen + ivlen); - if (pubkeyblob != NULL) + if (pubkeyblob != NULL) freezero(pubkeyblob, pubkeylen); - if (b64 != NULL) + if (b64 != NULL) freezero(b64, strlen(b64)); return r; } @@ -4257,31 +4280,6 @@ private2_decrypt(struct sshbuf *decoded, const char *passphrase, return r; } -/* Check deterministic padding after private key */ -static int -private2_check_padding(struct sshbuf *decrypted) -{ - u_char pad; - size_t i; - int r = SSH_ERR_INTERNAL_ERROR; - - i = 0; - while (sshbuf_len(decrypted)) { - if ((r = sshbuf_get_u8(decrypted, &pad)) != 0) - goto out; - if (pad != (++i & 0xff)) { - r = SSH_ERR_INVALID_FORMAT; - goto out; - } - } - /* success */ - r = 0; - out: - explicit_bzero(&pad, sizeof(pad)); - explicit_bzero(&i, sizeof(i)); - return r; -} - static int sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) @@ -4652,7 +4650,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((r = check_rsa_length(prv->rsa)) != 0) + if ((r = sshkey_check_rsa_length(prv, 0)) != 0) goto out; } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_DSA && (type == KEY_UNSPEC || type == KEY_DSA)) { |