Parse RSAPrivateKey with CBS.
This removes the version field from RSA and instead handles versioning as part of parsing. (As a bonus, we now correctly limit multi-prime RSA to version 1 keys.) Most consumers are also converted. old_rsa_priv_{de,en}code are left alone for now. Those hooks are passed in parameters which match the old d2i/i2d pattern (they're only used in d2i_PrivateKey and i2d_PrivateKey). Include a test which, among other things, checks that public keys being serialized as private keys are handled properly. BUG=499653 Change-Id: Icdd5f0382c4a84f9c8867024f29756e1a306ba08 Reviewed-on: https://boringssl-review.googlesource.com/5273 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
c0e245a546
commit
74f711083d
@ -5,6 +5,7 @@ RSA,function,103,BN_BLINDING_new
|
||||
RSA,function,104,BN_BLINDING_update
|
||||
RSA,function,123,RSA_add_pkcs1_prefix
|
||||
RSA,function,105,RSA_check_key
|
||||
RSA,function,135,RSA_marshal_private_key
|
||||
RSA,function,129,RSA_marshal_public_key
|
||||
RSA,function,106,RSA_new_method
|
||||
RSA,function,107,RSA_padding_add_PKCS1_OAEP_mgf1
|
||||
@ -16,7 +17,10 @@ RSA,function,112,RSA_padding_check_PKCS1_OAEP_mgf1
|
||||
RSA,function,113,RSA_padding_check_PKCS1_type_1
|
||||
RSA,function,114,RSA_padding_check_PKCS1_type_2
|
||||
RSA,function,115,RSA_padding_check_none
|
||||
RSA,function,136,RSA_parse_private_key
|
||||
RSA,function,130,RSA_parse_public_key
|
||||
RSA,function,137,RSA_private_key_from_bytes
|
||||
RSA,function,138,RSA_private_key_to_bytes
|
||||
RSA,function,131,RSA_public_key_from_bytes
|
||||
RSA,function,132,RSA_public_key_to_bytes
|
||||
RSA,function,116,RSA_recover_crt_params
|
||||
@ -25,11 +29,13 @@ RSA,function,118,RSA_verify
|
||||
RSA,function,119,RSA_verify_PKCS1_PSS_mgf1
|
||||
RSA,function,120,decrypt
|
||||
RSA,function,121,encrypt
|
||||
RSA,function,139,i2d_RSAPrivateKey
|
||||
RSA,function,133,i2d_RSAPublicKey
|
||||
RSA,function,122,keygen
|
||||
RSA,function,128,keygen_multiprime
|
||||
RSA,function,134,marshal_integer
|
||||
RSA,function,124,private_transform
|
||||
RSA,function,140,rsa_parse_additional_prime
|
||||
RSA,function,125,rsa_setup_blinding
|
||||
RSA,function,126,sign_raw
|
||||
RSA,function,127,verify_raw
|
||||
@ -39,6 +45,7 @@ RSA,reason,101,BAD_FIXED_HEADER_DECRYPT
|
||||
RSA,reason,102,BAD_PAD_BYTE_COUNT
|
||||
RSA,reason,103,BAD_RSA_PARAMETERS
|
||||
RSA,reason,104,BAD_SIGNATURE
|
||||
RSA,reason,145,BAD_VERSION
|
||||
RSA,reason,105,BLOCK_TYPE_IS_NOT_01
|
||||
RSA,reason,106,BN_NOT_INITIALIZED
|
||||
RSA,reason,142,CANNOT_RECOVER_MULTI_PRIME_KEY
|
||||
|
@ -322,8 +322,8 @@ static const uint8_t kExampleBadECKeyDER[] = {
|
||||
};
|
||||
|
||||
static ScopedEVP_PKEY LoadExampleRSAKey() {
|
||||
const uint8_t *derp = kExampleRSAKeyDER;
|
||||
ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &derp, sizeof(kExampleRSAKeyDER)));
|
||||
ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
|
||||
sizeof(kExampleRSAKeyDER)));
|
||||
if (!rsa) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -114,8 +114,8 @@ struct evp_pkey_asn1_method_st {
|
||||
int (*pkey_size)(const EVP_PKEY *pk);
|
||||
int (*pkey_bits)(const EVP_PKEY *pk);
|
||||
|
||||
int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*param_decode)(EVP_PKEY *pkey, const uint8_t **pder, int derlen);
|
||||
int (*param_encode)(const EVP_PKEY *pkey, uint8_t **pder);
|
||||
int (*param_missing)(const EVP_PKEY *pk);
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
@ -129,9 +129,9 @@ struct evp_pkey_asn1_method_st {
|
||||
|
||||
/* Legacy functions for old PEM */
|
||||
|
||||
int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
|
||||
int (*old_priv_decode)(EVP_PKEY *pkey, const uint8_t **pder,
|
||||
int derlen);
|
||||
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*old_priv_encode)(const EVP_PKEY *pkey, uint8_t **pder);
|
||||
|
||||
/* Converting parameters to/from AlgorithmIdentifier (X509_ALGOR). */
|
||||
int (*digest_verify_init_from_algorithm)(EVP_MD_CTX *ctx,
|
||||
@ -242,23 +242,23 @@ struct evp_pkey_method_st {
|
||||
int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
|
||||
|
||||
int (*sign_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen);
|
||||
int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
|
||||
const uint8_t *tbs, size_t tbslen);
|
||||
|
||||
int (*verify_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
|
||||
const unsigned char *tbs, size_t tbslen);
|
||||
int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen,
|
||||
const uint8_t *tbs, size_t tbslen);
|
||||
|
||||
int (*encrypt_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen);
|
||||
int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
|
||||
const uint8_t *in, size_t inlen);
|
||||
|
||||
int (*decrypt_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
|
||||
const unsigned char *in, size_t inlen);
|
||||
int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
|
||||
const uint8_t *in, size_t inlen);
|
||||
|
||||
int (*derive_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
|
||||
int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen);
|
||||
|
||||
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
|
||||
int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
|
||||
|
@ -107,20 +107,16 @@ 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_free(rk);
|
||||
V_ASN1_NULL, NULL, encoded, encoded_len)) {
|
||||
OPENSSL_free(encoded);
|
||||
OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
@ -131,14 +127,12 @@ 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);
|
||||
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);
|
||||
return 0;
|
||||
@ -227,8 +221,7 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
|
||||
}
|
||||
|
||||
if (include_private && rsa->d) {
|
||||
if (BIO_printf(out, "Private-Key: (%d bit)\nversion: %ld\n", mod_len,
|
||||
rsa->version) <= 0) {
|
||||
if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
|
||||
goto err;
|
||||
}
|
||||
str = "modulus:";
|
||||
@ -442,7 +435,7 @@ 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) {
|
||||
@ -453,7 +446,7 @@ static int old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -142,6 +142,195 @@ int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* kVersionTwoPrime and kVersionMulti are the supported values of the version
|
||||
* field of an RSAPrivateKey structure (RFC 3447). */
|
||||
static const uint64_t kVersionTwoPrime = 0;
|
||||
static const uint64_t kVersionMulti = 1;
|
||||
|
||||
/* rsa_parse_additional_prime parses a DER-encoded OtherPrimeInfo from |cbs| and
|
||||
* advances |cbs|. It returns a newly-allocated |RSA_additional_prime| on
|
||||
* success or NULL on error. The |r| and |method_mod| fields of the result are
|
||||
* set to NULL. */
|
||||
static RSA_additional_prime *rsa_parse_additional_prime(CBS *cbs) {
|
||||
RSA_additional_prime *ret = OPENSSL_malloc(sizeof(RSA_additional_prime));
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(RSA, rsa_parse_additional_prime, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memset(ret, 0, sizeof(RSA_additional_prime));
|
||||
|
||||
CBS child;
|
||||
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
|
||||
!parse_integer(&child, &ret->prime) ||
|
||||
!parse_integer(&child, &ret->exp) ||
|
||||
!parse_integer(&child, &ret->coeff) ||
|
||||
CBS_len(&child) != 0) {
|
||||
OPENSSL_PUT_ERROR(RSA, rsa_parse_additional_prime, RSA_R_BAD_ENCODING);
|
||||
RSA_additional_prime_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
RSA *RSA_parse_private_key(CBS *cbs) {
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *product_of_primes_so_far = NULL;
|
||||
RSA *ret = RSA_new();
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CBS child;
|
||||
uint64_t version;
|
||||
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1_uint64(&child, &version) ||
|
||||
(version != kVersionTwoPrime && version != kVersionMulti) ||
|
||||
!parse_integer(&child, &ret->n) ||
|
||||
!parse_integer(&child, &ret->e) ||
|
||||
!parse_integer(&child, &ret->d) ||
|
||||
!parse_integer(&child, &ret->p) ||
|
||||
!parse_integer(&child, &ret->q) ||
|
||||
!parse_integer(&child, &ret->dmp1) ||
|
||||
!parse_integer(&child, &ret->dmq1) ||
|
||||
!parse_integer(&child, &ret->iqmp)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_parse_private_key, RSA_R_BAD_VERSION);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Multi-prime RSA requires a newer version. */
|
||||
if (version == kVersionMulti &&
|
||||
CBS_peek_asn1_tag(&child, CBS_ASN1_SEQUENCE)) {
|
||||
CBS other_prime_infos;
|
||||
if (!CBS_get_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE) ||
|
||||
CBS_len(&other_prime_infos) == 0) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_parse_private_key, RSA_R_BAD_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
ret->additional_primes = sk_RSA_additional_prime_new_null();
|
||||
if (ret->additional_primes == NULL) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_parse_private_key, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
product_of_primes_so_far = BN_new();
|
||||
if (ctx == NULL ||
|
||||
product_of_primes_so_far == NULL ||
|
||||
!BN_mul(product_of_primes_so_far, ret->p, ret->q, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (CBS_len(&other_prime_infos) > 0) {
|
||||
RSA_additional_prime *ap = rsa_parse_additional_prime(&other_prime_infos);
|
||||
if (ap == NULL) {
|
||||
goto err;
|
||||
}
|
||||
if (!sk_RSA_additional_prime_push(ret->additional_primes, ap)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_parse_private_key, ERR_R_MALLOC_FAILURE);
|
||||
RSA_additional_prime_free(ap);
|
||||
goto err;
|
||||
}
|
||||
ap->r = BN_dup(product_of_primes_so_far);
|
||||
if (ap->r == NULL ||
|
||||
!BN_mul(product_of_primes_so_far, product_of_primes_so_far,
|
||||
ap->prime, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CBS_len(&child) != 0) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_parse_private_key, RSA_R_BAD_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_CTX_free(ctx);
|
||||
BN_free(product_of_primes_so_far);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
BN_free(product_of_primes_so_far);
|
||||
RSA_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) {
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, in, in_len);
|
||||
RSA *ret = RSA_parse_private_key(&cbs);
|
||||
if (ret == NULL || CBS_len(&cbs) != 0) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_private_key_from_bytes, RSA_R_BAD_ENCODING);
|
||||
RSA_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) {
|
||||
const int is_multiprime =
|
||||
sk_RSA_additional_prime_num(rsa->additional_primes) > 0;
|
||||
|
||||
CBB child;
|
||||
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
|
||||
!CBB_add_asn1_uint64(&child,
|
||||
is_multiprime ? kVersionMulti : kVersionTwoPrime) ||
|
||||
!marshal_integer(&child, rsa->n) ||
|
||||
!marshal_integer(&child, rsa->e) ||
|
||||
!marshal_integer(&child, rsa->d) ||
|
||||
!marshal_integer(&child, rsa->p) ||
|
||||
!marshal_integer(&child, rsa->q) ||
|
||||
!marshal_integer(&child, rsa->dmp1) ||
|
||||
!marshal_integer(&child, rsa->dmq1) ||
|
||||
!marshal_integer(&child, rsa->iqmp)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_marshal_private_key, RSA_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_multiprime) {
|
||||
CBB other_prime_infos;
|
||||
if (!CBB_add_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_marshal_private_key, RSA_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
size_t i;
|
||||
for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
|
||||
RSA_additional_prime *ap =
|
||||
sk_RSA_additional_prime_value(rsa->additional_primes, i);
|
||||
CBB other_prime_info;
|
||||
if (!CBB_add_asn1(&other_prime_infos, &other_prime_info,
|
||||
CBS_ASN1_SEQUENCE) ||
|
||||
!marshal_integer(&other_prime_info, ap->prime) ||
|
||||
!marshal_integer(&other_prime_info, ap->exp) ||
|
||||
!marshal_integer(&other_prime_info, ap->coeff)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_marshal_private_key, RSA_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_marshal_private_key, RSA_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
|
||||
const RSA *rsa) {
|
||||
CBB cbb;
|
||||
CBB_zero(&cbb);
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!RSA_marshal_private_key(&cbb, rsa) ||
|
||||
!CBB_finish(&cbb, out_bytes, out_len)) {
|
||||
OPENSSL_PUT_ERROR(RSA, RSA_private_key_to_bytes, RSA_R_ENCODE_ERROR);
|
||||
CBB_cleanup(&cbb);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
@ -184,75 +373,47 @@ int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) {
|
||||
return (int)der_len;
|
||||
}
|
||||
|
||||
/* Override the default free and new methods */
|
||||
static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg) {
|
||||
RSA *rsa = (RSA *)*pval;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *product_of_primes_so_far = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (operation == ASN1_OP_NEW_PRE) {
|
||||
*pval = (ASN1_VALUE *)RSA_new();
|
||||
if (*pval) {
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
} else if (operation == ASN1_OP_FREE_PRE) {
|
||||
RSA_free(rsa);
|
||||
*pval = NULL;
|
||||
return 2;
|
||||
} else if (operation == ASN1_OP_D2I_POST) {
|
||||
if (rsa->additional_primes != NULL) {
|
||||
ctx = BN_CTX_new();
|
||||
product_of_primes_so_far = BN_new();
|
||||
if (ctx == NULL ||
|
||||
product_of_primes_so_far == NULL ||
|
||||
!BN_mul(product_of_primes_so_far, rsa->p, rsa->q, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
|
||||
RSA_additional_prime *ap =
|
||||
sk_RSA_additional_prime_value(rsa->additional_primes, i);
|
||||
ap->r = BN_dup(product_of_primes_so_far);
|
||||
if (ap->r == NULL ||
|
||||
!BN_mul(product_of_primes_so_far, product_of_primes_so_far,
|
||||
ap->prime, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = 2;
|
||||
} else {
|
||||
return 1;
|
||||
RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
BN_free(product_of_primes_so_far);
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
RSA *ret = RSA_parse_private_key(&cbs);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (out != NULL) {
|
||||
RSA_free(*out);
|
||||
*out = ret;
|
||||
}
|
||||
*inp += (size_t)len - CBS_len(&cbs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE(RSA_additional_prime) = {
|
||||
ASN1_SIMPLE(RSA_additional_prime, prime, BIGNUM),
|
||||
ASN1_SIMPLE(RSA_additional_prime, exp, BIGNUM),
|
||||
ASN1_SIMPLE(RSA_additional_prime, coeff, BIGNUM),
|
||||
} ASN1_SEQUENCE_END(RSA_additional_prime);
|
||||
|
||||
ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
|
||||
ASN1_SIMPLE(RSA, version, LONG),
|
||||
ASN1_SIMPLE(RSA, n, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, e, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, d, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, p, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, q, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, dmp1, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, dmq1, BIGNUM),
|
||||
ASN1_SIMPLE(RSA, iqmp, BIGNUM),
|
||||
ASN1_SEQUENCE_OF_OPT(RSA, additional_primes, RSA_additional_prime),
|
||||
} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey);
|
||||
int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) {
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
if (!RSA_private_key_to_bytes(&der, &der_len, in)) {
|
||||
return -1;
|
||||
}
|
||||
if (der_len > INT_MAX) {
|
||||
OPENSSL_PUT_ERROR(RSA, i2d_RSAPrivateKey, ERR_R_OVERFLOW);
|
||||
OPENSSL_free(der);
|
||||
return -1;
|
||||
}
|
||||
if (outp != NULL) {
|
||||
if (*outp == NULL) {
|
||||
*outp = der;
|
||||
der = NULL;
|
||||
} else {
|
||||
memcpy(*outp, der, der_len);
|
||||
*outp += der_len;
|
||||
}
|
||||
}
|
||||
OPENSSL_free(der);
|
||||
return (int)der_len;
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
|
||||
ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
|
||||
@ -271,8 +432,6 @@ ASN1_SEQUENCE(RSA_OAEP_PARAMS) = {
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS);
|
||||
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey);
|
||||
|
||||
RSA *RSAPublicKey_dup(const RSA *rsa) {
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
@ -285,5 +444,12 @@ RSA *RSAPublicKey_dup(const RSA *rsa) {
|
||||
}
|
||||
|
||||
RSA *RSAPrivateKey_dup(const RSA *rsa) {
|
||||
return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), (RSA *) rsa);
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) {
|
||||
return NULL;
|
||||
}
|
||||
RSA *ret = RSA_private_key_from_bytes(der, der_len);
|
||||
OPENSSL_free(der);
|
||||
return ret;
|
||||
}
|
||||
|
@ -742,6 +742,57 @@ static bool TestRecoverCRTParams() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestASN1() {
|
||||
// Test that private keys may be decoded.
|
||||
ScopedRSA rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
|
||||
if (!rsa) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test that the serialization round-trips.
|
||||
uint8_t *der;
|
||||
size_t der_len;
|
||||
if (!RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes delete_der(der);
|
||||
if (der_len != sizeof(kKey1) - 1 || memcmp(der, kKey1, der_len) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test that serializing public keys works.
|
||||
if (!RSA_public_key_to_bytes(&der, &der_len, rsa.get())) {
|
||||
return false;
|
||||
}
|
||||
delete_der.reset(der);
|
||||
|
||||
// Public keys may be parsed back out.
|
||||
rsa.reset(RSA_public_key_from_bytes(der, der_len));
|
||||
if (!rsa || rsa->p != NULL || rsa->q != NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Serializing the result round-trips.
|
||||
uint8_t *der2;
|
||||
size_t der2_len;
|
||||
if (!RSA_public_key_to_bytes(&der2, &der2_len, rsa.get())) {
|
||||
return false;
|
||||
}
|
||||
ScopedOpenSSLBytes delete_der2(der2);
|
||||
if (der_len != der2_len || memcmp(der, der2, der_len) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Public keys cannot be serialized as private keys.
|
||||
if (RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
|
||||
OPENSSL_free(der);
|
||||
return false;
|
||||
}
|
||||
ERR_clear_error();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
CRYPTO_library_init();
|
||||
|
||||
@ -763,7 +814,8 @@ int main(int argc, char *argv[]) {
|
||||
!TestMultiPrimeKey(6, kSixPrimeKey, sizeof(kSixPrimeKey) - 1,
|
||||
kSixPrimeEncryptedMessage,
|
||||
sizeof(kSixPrimeEncryptedMessage)) ||
|
||||
!TestMultiPrimeKeygen()) {
|
||||
!TestMultiPrimeKeygen() ||
|
||||
!TestASN1()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,6 @@
|
||||
#include <openssl/x509.h>
|
||||
|
||||
|
||||
extern const ASN1_ITEM RSAPrivateKey_it;
|
||||
|
||||
int X509_verify(X509 *a, EVP_PKEY *r)
|
||||
{
|
||||
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
|
||||
@ -244,12 +242,12 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
|
||||
{
|
||||
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
|
||||
return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa);
|
||||
}
|
||||
|
||||
int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
|
||||
{
|
||||
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
|
||||
return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
|
||||
}
|
||||
|
||||
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
|
||||
@ -277,12 +275,12 @@ int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
|
||||
|
||||
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
|
||||
{
|
||||
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
|
||||
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa);
|
||||
}
|
||||
|
||||
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
|
||||
{
|
||||
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
|
||||
return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
|
||||
}
|
||||
|
||||
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
|
||||
|
@ -353,19 +353,27 @@ OPENSSL_EXPORT int RSA_marshal_public_key(CBB *cbb, const RSA *rsa);
|
||||
OPENSSL_EXPORT int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
|
||||
const RSA *rsa);
|
||||
|
||||
/* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
|
||||
* bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
|
||||
* is in |*out|. If |*out| is already non-NULL on entry then the result is
|
||||
* written directly into |*out|, otherwise a fresh |RSA| is allocated. On
|
||||
* successful exit, |*inp| is advanced past the DER structure. It returns the
|
||||
* result or NULL on error. */
|
||||
OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
|
||||
/* RSA_parse_private_key parses a DER-encoded RSAPrivateKey structure (RFC 3447)
|
||||
* from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on
|
||||
* error. */
|
||||
OPENSSL_EXPORT RSA *RSA_parse_private_key(CBS *cbs);
|
||||
|
||||
/* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
|
||||
* NULL then the result is written to |*outp| and |*outp| is advanced just past
|
||||
* the output. It returns the number of bytes in the result, whether written or
|
||||
* not, or a negative value on error. */
|
||||
OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
|
||||
/* RSA_private_key_from_bytes parses |in| as a DER-encoded RSAPrivateKey
|
||||
* structure (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. */
|
||||
OPENSSL_EXPORT RSA *RSA_private_key_from_bytes(const uint8_t *in,
|
||||
size_t in_len);
|
||||
|
||||
/* RSA_marshal_private_key marshals |rsa| as a DER-encoded RSAPrivateKey
|
||||
* structure (RFC 3447) and appends the result to |cbb|. It returns one on
|
||||
* success and zero on failure. */
|
||||
OPENSSL_EXPORT int RSA_marshal_private_key(CBB *cbb, const RSA *rsa);
|
||||
|
||||
/* RSA_private_key_to_bytes marshals |rsa| as a DER-encoded RSAPrivateKey
|
||||
* structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated
|
||||
* buffer containing the result and returns one. Otherwise, it returns zero. The
|
||||
* result should be freed with |OPENSSL_free|. */
|
||||
OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes,
|
||||
size_t *out_len, const RSA *rsa);
|
||||
|
||||
|
||||
/* Deprecated functions. */
|
||||
@ -384,6 +392,20 @@ OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
|
||||
* not, or a negative value on error. */
|
||||
OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
|
||||
|
||||
/* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
|
||||
* bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
|
||||
* is in |*out|. If |*out| is already non-NULL on entry then the result is
|
||||
* written directly into |*out|, otherwise a fresh |RSA| is allocated. On
|
||||
* successful exit, |*inp| is advanced past the DER structure. It returns the
|
||||
* result or NULL on error. */
|
||||
OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
|
||||
|
||||
/* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
|
||||
* NULL then the result is written to |*outp| and |*outp| is advanced just past
|
||||
* the output. It returns the number of bytes in the result, whether written or
|
||||
* not, or a negative value on error. */
|
||||
OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
|
||||
|
||||
|
||||
/* ex_data functions.
|
||||
*
|
||||
@ -509,8 +531,6 @@ struct rsa_meth_st {
|
||||
typedef struct bn_blinding_st BN_BLINDING;
|
||||
|
||||
struct rsa_st {
|
||||
/* version is only used during ASN.1 (de)serialisation. */
|
||||
long version;
|
||||
RSA_METHOD *meth;
|
||||
|
||||
BIGNUM *n;
|
||||
@ -588,6 +608,12 @@ struct rsa_st {
|
||||
#define RSA_F_RSA_public_key_to_bytes 132
|
||||
#define RSA_F_i2d_RSAPublicKey 133
|
||||
#define RSA_F_marshal_integer 134
|
||||
#define RSA_F_RSA_marshal_private_key 135
|
||||
#define RSA_F_RSA_parse_private_key 136
|
||||
#define RSA_F_RSA_private_key_from_bytes 137
|
||||
#define RSA_F_RSA_private_key_to_bytes 138
|
||||
#define RSA_F_i2d_RSAPrivateKey 139
|
||||
#define RSA_F_rsa_parse_additional_prime 140
|
||||
#define RSA_R_BAD_E_VALUE 100
|
||||
#define RSA_R_BAD_FIXED_HEADER_DECRYPT 101
|
||||
#define RSA_R_BAD_PAD_BYTE_COUNT 102
|
||||
@ -633,5 +659,6 @@ struct rsa_st {
|
||||
#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 142
|
||||
#define RSA_R_BAD_ENCODING 143
|
||||
#define RSA_R_ENCODE_ERROR 144
|
||||
#define RSA_R_BAD_VERSION 145
|
||||
|
||||
#endif /* OPENSSL_HEADER_RSA_H */
|
||||
|
@ -649,9 +649,10 @@ OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
|
||||
const uint8_t *d, long len);
|
||||
|
||||
OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx,
|
||||
const uint8_t *d,
|
||||
long len);
|
||||
OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len);
|
||||
const uint8_t *der,
|
||||
size_t der_len);
|
||||
OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der,
|
||||
size_t der_len);
|
||||
|
||||
/* The following functions configure certificates or private keys but take as
|
||||
* input files to read from. They return one on success and zero on failure. The
|
||||
|
@ -227,19 +227,14 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len) {
|
||||
int ret;
|
||||
const uint8_t *p;
|
||||
RSA *rsa;
|
||||
|
||||
p = d;
|
||||
rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
|
||||
int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
|
||||
RSA *rsa = RSA_private_key_from_bytes(der, der_len);
|
||||
if (rsa == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = SSL_use_RSAPrivateKey(ssl, rsa);
|
||||
int ret = SSL_use_RSAPrivateKey(ssl, rsa);
|
||||
RSA_free(rsa);
|
||||
return ret;
|
||||
}
|
||||
@ -482,19 +477,15 @@ end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *d, long len) {
|
||||
int ret;
|
||||
const uint8_t *p;
|
||||
RSA *rsa;
|
||||
|
||||
p = d;
|
||||
rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
|
||||
int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
|
||||
size_t der_len) {
|
||||
RSA *rsa = RSA_private_key_from_bytes(der, der_len);
|
||||
if (rsa == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
|
||||
int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
|
||||
RSA_free(rsa);
|
||||
return ret;
|
||||
}
|
||||
|
@ -407,9 +407,9 @@ bool Speed(const std::vector<std::string> &args) {
|
||||
selected = args[0];
|
||||
}
|
||||
|
||||
RSA *key = NULL;
|
||||
const uint8_t *inp = kDERRSAPrivate2048;
|
||||
if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate2048Len)) {
|
||||
RSA *key = RSA_private_key_from_bytes(kDERRSAPrivate2048,
|
||||
kDERRSAPrivate2048Len);
|
||||
if (key == NULL) {
|
||||
fprintf(stderr, "Failed to parse RSA key.\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return false;
|
||||
@ -420,10 +420,9 @@ bool Speed(const std::vector<std::string> &args) {
|
||||
}
|
||||
|
||||
RSA_free(key);
|
||||
key = NULL;
|
||||
|
||||
inp = kDERRSAPrivate3Prime2048;
|
||||
if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate3Prime2048Len)) {
|
||||
key = RSA_private_key_from_bytes(kDERRSAPrivate3Prime2048,
|
||||
kDERRSAPrivate3Prime2048Len);
|
||||
if (key == NULL) {
|
||||
fprintf(stderr, "Failed to parse RSA key.\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return false;
|
||||
@ -434,10 +433,9 @@ bool Speed(const std::vector<std::string> &args) {
|
||||
}
|
||||
|
||||
RSA_free(key);
|
||||
key = NULL;
|
||||
|
||||
inp = kDERRSAPrivate4096;
|
||||
if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate4096Len)) {
|
||||
key = RSA_private_key_from_bytes(kDERRSAPrivate4096,
|
||||
kDERRSAPrivate4096Len);
|
||||
if (key == NULL) {
|
||||
fprintf(stderr, "Failed to parse 4096-bit RSA key.\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user