diff options
Diffstat (limited to 'src/crypto/evp/p_rsa_asn1.c')
-rw-r--r-- | src/crypto/evp/p_rsa_asn1.c | 116 |
1 files changed, 76 insertions, 40 deletions
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c index 1e2d3f6..f60625b 100644 --- a/src/crypto/evp/p_rsa_asn1.c +++ b/src/crypto/evp/p_rsa_asn1.c @@ -57,6 +57,7 @@ #include <openssl/asn1.h> #include <openssl/asn1t.h> +#include <openssl/bytestring.h> #include <openssl/digest.h> #include <openssl/err.h> #include <openssl/mem.h> @@ -69,16 +70,14 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { - uint8_t *encoded = NULL; - int len; - len = i2d_RSAPublicKey(pkey->pkey.rsa, &encoded); - - if (len <= 0) { + uint8_t *encoded; + size_t encoded_len; + if (!RSA_public_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) { return 0; } if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL, - encoded, len)) { + encoded, encoded_len)) { OPENSSL_free(encoded); return 0; } @@ -89,16 +88,25 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p; int pklen; - RSA *rsa; - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) { return 0; } - rsa = d2i_RSAPublicKey(NULL, &p, pklen); - if (rsa == NULL) { - OPENSSL_PUT_ERROR(EVP, rsa_pub_decode, ERR_R_RSA_LIB); + + /* Estonian IDs issued between September 2014 to September 2015 are + * broken. See https://crbug.com/532048 and https://crbug.com/534766. + * + * TODO(davidben): Switch this to the strict version in March 2016 or when + * Chromium can force client certificates down a different codepath, whichever + * comes first. */ + CBS cbs; + CBS_init(&cbs, p, pklen); + RSA *rsa = RSA_parse_public_key_buggy(&cbs); + if (rsa == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); return 0; } + EVP_PKEY_assign_RSA(pkey, rsa); return 1; } @@ -109,20 +117,17 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { - uint8_t *rk = NULL; - int rklen; - - rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); - - if (rklen <= 0) { - OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE); + uint8_t *encoded; + size_t encoded_len; + if (!RSA_private_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) { return 0; } /* TODO(fork): const correctness in next line. */ if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_rsaEncryption), 0, - V_ASN1_NULL, NULL, rk, rklen)) { - OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE); + V_ASN1_NULL, NULL, encoded, encoded_len)) { + OPENSSL_free(encoded); + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } @@ -132,16 +137,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const uint8_t *p; int pklen; - RSA *rsa; - if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) { - OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); return 0; } - rsa = d2i_RSAPrivateKey(NULL, &p, pklen); + RSA *rsa = RSA_private_key_from_bytes(p, pklen); if (rsa == NULL) { - OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_RSA_LIB); + OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB); return 0; } @@ -198,11 +201,24 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off, update_buflen(rsa->dmp1, &buf_len); update_buflen(rsa->dmq1, &buf_len); update_buflen(rsa->iqmp, &buf_len); + + if (rsa->additional_primes != NULL) { + size_t i; + + for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); + i++) { + const RSA_additional_prime *ap = + sk_RSA_additional_prime_value(rsa->additional_primes, i); + update_buflen(ap->prime, &buf_len); + update_buflen(ap->exp, &buf_len); + update_buflen(ap->coeff, &buf_len); + } + } } m = (uint8_t *)OPENSSL_malloc(buf_len + 10); if (m == NULL) { - OPENSSL_PUT_ERROR(EVP, do_rsa_print, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } @@ -241,6 +257,28 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off, !ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) { goto err; } + + if (rsa->additional_primes != NULL && + sk_RSA_additional_prime_num(rsa->additional_primes) > 0) { + size_t i; + + if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) { + goto err; + } + for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); + i++) { + const RSA_additional_prime *ap = + sk_RSA_additional_prime_value(rsa->additional_primes, i); + + if (BIO_printf(out, "otherPrimeInfo (prime %u):\n", + (unsigned)(i + 3)) <= 0 || + !ASN1_bn_print(out, "prime:", ap->prime, m, off) || + !ASN1_bn_print(out, "exponent:", ap->exp, m, off) || + !ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) { + goto err; + } + } + } } ret = 1; @@ -407,18 +445,18 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, return 1; } -static int old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, +static int old_rsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) { RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen); if (rsa == NULL) { - OPENSSL_PUT_ERROR(EVP, old_rsa_priv_decode, ERR_R_RSA_LIB); + OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB); return 0; } EVP_PKEY_assign_RSA(pkey, rsa); return 1; } -static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) { +static int old_rsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) { return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); } @@ -474,7 +512,7 @@ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) { } md = EVP_get_digestbyobj(alg->algorithm); if (md == NULL) { - OPENSSL_PUT_ERROR(EVP, rsa_algor_to_md, EVP_R_UNKNOWN_DIGEST); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_DIGEST); } return md; } @@ -487,16 +525,16 @@ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) { } /* Check mask and lookup mask hash algorithm */ if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) { - OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_ALGORITHM); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_ALGORITHM); return NULL; } if (!maskHash) { - OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_PARAMETER); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_PARAMETER); return NULL; } md = EVP_get_digestbyobj(maskHash->algorithm); if (md == NULL) { - OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNKNOWN_MASK_DIGEST); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MASK_DIGEST); return NULL; } return md; @@ -576,13 +614,13 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { - OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg, &maskHash); if (pss == NULL) { - OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS); + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_PARAMETERS); goto err; } @@ -602,7 +640,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* Could perform more salt length sanity checks but the main * RSA routines will trap other invalid values anyway. */ if (saltlen < 0) { - OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH); + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SALT_LENGTH); goto err; } } @@ -610,7 +648,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* low-level routines support only trailer field 0xbc (value 1) * and PKCS#1 says we should reject any other value anyway. */ if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { - OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER); + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_TRAILER); goto err; } @@ -638,8 +676,7 @@ static int rsa_digest_verify_init_from_algorithm(EVP_MD_CTX *ctx, EVP_PKEY *pkey) { /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { - OPENSSL_PUT_ERROR(EVP, rsa_digest_verify_init_from_algorithm, - EVP_R_UNSUPPORTED_SIGNATURE_TYPE); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE); return 0; } return rsa_pss_to_ctx(ctx, sigalg, pkey); @@ -671,7 +708,6 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { ASN1_PKEY_SIGPARAM_NULL, "RSA", - "OpenSSL RSA method", rsa_pub_decode, rsa_pub_encode, |