Reduce crypto/pkcs8 dependency on OID table.

To remove the OID table from Chromium, we'll need to decouple a lot of
this code. In preparation for that, detach the easy cases from the OID
table. What remains is PBES, cipher, and digest OIDs which will be doing
in follow-up changes.

BUG=54

Change-Id: Ie205d23d042e21114ca1faf68917fdc870969d09
Reviewed-on: https://boringssl-review.googlesource.com/14209
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2017-03-14 00:13:00 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent aea20c15c9
commit d851842228
2 changed files with 55 additions and 19 deletions

View File

@ -69,6 +69,18 @@
#include "../internal.h" #include "../internal.h"
/* 1.2.840.113549.1.5.12 */
static const uint8_t kPBKDF2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x05, 0x0c};
/* 1.2.840.113549.1.5.13 */
static const uint8_t kPBES2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x05, 0x0d};
/* 1.2.840.113549.2.7 */
static const uint8_t kHMACWithSHA1[] = {0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x02, 0x07};
static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
unsigned iterations, const uint8_t *pass_raw, unsigned iterations, const uint8_t *pass_raw,
size_t pass_raw_len, const uint8_t *salt, size_t pass_raw_len, const uint8_t *salt,
@ -105,12 +117,15 @@ int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx,
} }
/* See RFC 2898, appendix A. */ /* See RFC 2898, appendix A. */
CBB algorithm, param, kdf, kdf_param, salt_cbb, cipher_cbb, iv_cbb; CBB algorithm, oid, param, kdf, kdf_oid, kdf_param, salt_cbb, cipher_cbb,
iv_cbb;
if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) ||
!OBJ_nid2cbb(&algorithm, NID_pbes2) || !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
!CBB_add_bytes(&oid, kPBES2, sizeof(kPBES2)) ||
!CBB_add_asn1(&algorithm, &param, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&algorithm, &param, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&param, &kdf, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&param, &kdf, CBS_ASN1_SEQUENCE) ||
!OBJ_nid2cbb(&kdf, NID_id_pbkdf2) || !CBB_add_asn1(&kdf, &kdf_oid, CBS_ASN1_OBJECT) ||
!CBB_add_bytes(&kdf_oid, kPBKDF2, sizeof(kPBKDF2)) ||
!CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) || !CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&salt_cbb, salt, salt_len) || !CBB_add_bytes(&salt_cbb, salt, salt_len) ||
@ -149,8 +164,8 @@ int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx,
return 0; return 0;
} }
/* Check that the key derivation function is PBKDF2. */ /* Only PBKDF2 is supported. */
if (OBJ_cbs2nid(&kdf_obj) != NID_id_pbkdf2) { if (!CBS_mem_equal(&kdf_obj, kPBKDF2, sizeof(kPBKDF2))) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
return 0; return 0;
} }
@ -203,7 +218,7 @@ int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx,
/* We only support hmacWithSHA1. It is the DEFAULT, so DER requires it be /* We only support hmacWithSHA1. It is the DEFAULT, so DER requires it be
* omitted, but we match OpenSSL in tolerating it being present. */ * omitted, but we match OpenSSL in tolerating it being present. */
if (OBJ_cbs2nid(&prf) != NID_hmacWithSHA1) { if (!CBS_mem_equal(&prf, kHMACWithSHA1, sizeof(kHMACWithSHA1))) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF);
return 0; return 0;
} }

View File

@ -718,6 +718,18 @@ err:
return ret; return ret;
} }
/* 1.2.840.113549.1.12.10.1.2 */
static const uint8_t kPKCS8ShroudedKeyBag[] = {
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02};
/* 1.2.840.113549.1.12.10.1.3 */
static const uint8_t kCertBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x0c, 0x0a, 0x01, 0x03};
/* 1.2.840.113549.1.9.22.1 */
static const uint8_t kX509Certificate[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x09, 0x16, 0x01};
/* PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12 /* PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12
* structure. */ * structure. */
static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) { static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) {
@ -730,8 +742,8 @@ static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) {
return 0; return 0;
} }
int nid = OBJ_cbs2nid(&bag_id); if (CBS_mem_equal(&bag_id, kPKCS8ShroudedKeyBag,
if (nid == NID_pkcs8ShroudedKeyBag) { sizeof(kPKCS8ShroudedKeyBag))) {
/* See RFC 7292, section 4.2.2. */ /* See RFC 7292, section 4.2.2. */
if (*ctx->out_key) { if (*ctx->out_key) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12);
@ -770,7 +782,7 @@ static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) {
return ctx->out_key != NULL; return ctx->out_key != NULL;
} }
if (nid == NID_certBag) { if (CBS_mem_equal(&bag_id, kCertBag, sizeof(kCertBag))) {
/* See RFC 7292, section 4.2.3. */ /* See RFC 7292, section 4.2.3. */
CBS cert_bag, cert_type, wrapped_cert, cert; CBS cert_bag, cert_type, wrapped_cert, cert;
if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) || if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) ||
@ -782,7 +794,9 @@ static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) {
return 0; return 0;
} }
if (OBJ_cbs2nid(&cert_type) != NID_x509Certificate) { /* Skip unknown certificate types. */
if (!CBS_mem_equal(&cert_type, kX509Certificate,
sizeof(kX509Certificate))) {
return 1; return 1;
} }
@ -816,12 +830,20 @@ static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) {
return 1; return 1;
} }
/* 1.2.840.113549.1.7.1 */
static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x07, 0x01};
/* 1.2.840.113549.1.7.6 */
static const uint8_t kPKCS7EncryptedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x07, 0x06};
/* PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a /* PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a
* PKCS#12 structure. */ * PKCS#12 structure. */
static int PKCS12_handle_content_info(CBS *content_info, static int PKCS12_handle_content_info(CBS *content_info,
struct pkcs12_context *ctx) { struct pkcs12_context *ctx) {
CBS content_type, wrapped_contents, contents; CBS content_type, wrapped_contents, contents;
int nid, ret = 0; int ret = 0;
uint8_t *storage = NULL; uint8_t *storage = NULL;
if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) ||
@ -832,8 +854,8 @@ static int PKCS12_handle_content_info(CBS *content_info,
goto err; goto err;
} }
nid = OBJ_cbs2nid(&content_type); if (CBS_mem_equal(&content_type, kPKCS7EncryptedData,
if (nid == NID_pkcs7_encrypted) { sizeof(kPKCS7EncryptedData))) {
/* See https://tools.ietf.org/html/rfc2315#section-13. /* See https://tools.ietf.org/html/rfc2315#section-13.
* *
* PKCS#7 encrypted data inside a PKCS#12 structure is generally an * PKCS#7 encrypted data inside a PKCS#12 structure is generally an
@ -859,7 +881,7 @@ static int PKCS12_handle_content_info(CBS *content_info,
goto err; goto err;
} }
if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) { if (!CBS_mem_equal(&contents_type, kPKCS7Data, sizeof(kPKCS7Data))) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err; goto err;
} }
@ -874,7 +896,7 @@ static int PKCS12_handle_content_info(CBS *content_info,
CBS_init(&safe_contents, out, out_len); CBS_init(&safe_contents, out, out_len);
ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag); ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag);
OPENSSL_free(out); OPENSSL_free(out);
} else if (nid == NID_pkcs7_data) { } else if (CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) {
CBS octet_string_contents; CBS octet_string_contents;
if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents,
@ -957,10 +979,9 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
goto err; goto err;
} }
/* The content type can either be |NID_pkcs7_data| or |NID_pkcs7_signed|. The /* The content type can either be data or signedData. The latter indicates
* latter indicates that it's signed by a public key, which isn't * that it's signed by a public key, which isn't supported. */
* supported. */ if (!CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) {
if (OBJ_cbs2nid(&content_type) != NID_pkcs7_data) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED); OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED);
goto err; goto err;
} }