Add CBB_add_asn1_element convenience function This is common enough that we probably should have one available. Saves declaring a variable, calling flush, etc. Change-Id: Ib21627e9e4caea01c729ad0dbb6266fdd30bb533 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/78788 Commit-Queue: Adam Langley <agl@google.com> Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc index f2604ac..36ef5d6 100644 --- a/crypto/asn1/asn1_test.cc +++ b/crypto/asn1/asn1_test.cc
@@ -3002,9 +3002,8 @@ // Test only the first field present. bssl::ScopedCBB cbb; ASSERT_TRUE(CBB_init(cbb.get(), 64)); - CBB seq; - ASSERT_TRUE(CBB_add_asn1(cbb.get(), &seq, CBS_ASN1_SEQUENCE)); - ASSERT_TRUE(CBB_add_bytes(&seq, inp.data(), inp.size())); + ASSERT_TRUE(CBB_add_asn1_element(cbb.get(), CBS_ASN1_SEQUENCE, inp.data(), + inp.size())); ASSERT_TRUE(CBB_flush(cbb.get())); const uint8_t *ptr = CBB_data(cbb.get()); obj.reset(d2i_embed(nullptr, &ptr, CBB_len(cbb.get()))); @@ -3020,6 +3019,7 @@ // Test all fields present. cbb.Reset(); ASSERT_TRUE(CBB_init(cbb.get(), 64)); + CBB seq; ASSERT_TRUE(CBB_add_asn1(cbb.get(), &seq, CBS_ASN1_SEQUENCE)); ASSERT_TRUE(CBB_add_bytes(&seq, inp.data(), inp.size())); CBB child;
diff --git a/crypto/bytestring/cbb.cc b/crypto/bytestring/cbb.cc index 316ac4a..b847331 100644 --- a/crypto/bytestring/cbb.cc +++ b/crypto/bytestring/cbb.cc
@@ -481,6 +481,19 @@ cbb->child = NULL; } +int CBB_add_asn1_element(CBB *cbb, CBS_ASN1_TAG tag, const uint8_t *data, + size_t data_len) { + CBB child; + if (!CBB_add_asn1(cbb, &child, tag) || + !CBB_add_bytes(&child, data, data_len) || // + !CBB_flush(cbb)) { + cbb_on_error(cbb); + return 0; + } + + return 1; +} + int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { return CBB_add_asn1_uint64_with_tag(cbb, value, CBS_ASN1_INTEGER); } @@ -557,14 +570,7 @@ } int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) { - CBB child; - if (!CBB_add_asn1(cbb, &child, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&child, data, data_len) || !CBB_flush(cbb)) { - cbb_on_error(cbb); - return 0; - } - - return 1; + return CBB_add_asn1_element(cbb, CBS_ASN1_OCTETSTRING, data, data_len); } int CBB_add_asn1_bool(CBB *cbb, int value) {
diff --git a/crypto/ec/ec_asn1.cc b/crypto/ec/ec_asn1.cc index c5ced25..ce81580 100644 --- a/crypto/ec/ec_asn1.cc +++ b/crypto/ec/ec_asn1.cc
@@ -320,10 +320,7 @@ return 0; } - CBB child; - return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) && - CBB_add_bytes(&child, group->oid, group->oid_len) && // - CBB_flush(cbb); + return CBB_add_asn1_element(cbb, CBS_ASN1_OBJECT, group->oid, group->oid_len); } EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) {
diff --git a/crypto/evp/p_dsa_asn1.cc b/crypto/evp/p_dsa_asn1.cc index aab3f59..8503d4d 100644 --- a/crypto/evp/p_dsa_asn1.cc +++ b/crypto/evp/p_dsa_asn1.cc
@@ -62,11 +62,11 @@ dsa->p != nullptr && dsa->q != nullptr && dsa->g != nullptr; // See RFC 5480, section 2. - CBB spki, algorithm, oid, key_bitstring; + CBB spki, algorithm, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, dsa_asn1_meth.oid, + dsa_asn1_meth.oid_len) || (has_params && !DSA_marshal_parameters(&algorithm, dsa)) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || @@ -126,12 +126,12 @@ } // See PKCS#11, v2.40, section 2.5. - CBB pkcs8, algorithm, oid, private_key; + CBB pkcs8, algorithm, private_key; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, dsa_asn1_meth.oid, + dsa_asn1_meth.oid_len) || !DSA_marshal_parameters(&algorithm, dsa) || !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || !BN_marshal_asn1(&private_key, dsa->priv_key) || !CBB_flush(out)) {
diff --git a/crypto/evp/p_ec_asn1.cc b/crypto/evp/p_ec_asn1.cc index bcf2525..d89c6eb 100644 --- a/crypto/evp/p_ec_asn1.cc +++ b/crypto/evp/p_ec_asn1.cc
@@ -30,11 +30,11 @@ const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); // See RFC 5480, section 2. - CBB spki, algorithm, oid, key_bitstring; + CBB spki, algorithm, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, ec_asn1_meth.oid, + ec_asn1_meth.oid_len) || !EC_KEY_marshal_curve_name(&algorithm, group) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || @@ -114,12 +114,12 @@ unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS; // See RFC 5915. - CBB pkcs8, algorithm, oid, private_key; + CBB pkcs8, algorithm, private_key; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, ec_asn1_meth.oid, + ec_asn1_meth.oid_len) || !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) || !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) ||
diff --git a/crypto/evp/p_ed25519_asn1.cc b/crypto/evp/p_ed25519_asn1.cc index 45947d8..8053422 100644 --- a/crypto/evp/p_ed25519_asn1.cc +++ b/crypto/evp/p_ed25519_asn1.cc
@@ -129,11 +129,11 @@ const ED25519_KEY *key = reinterpret_cast<const ED25519_KEY *>(pkey->pkey); // See RFC 8410, section 4. - CBB spki, algorithm, oid, key_bitstring; + CBB spki, algorithm, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, ed25519_asn1_meth.oid, + ed25519_asn1_meth.oid_len) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || !CBB_add_bytes(&key_bitstring, key->key + ED25519_PUBLIC_KEY_OFFSET, @@ -176,12 +176,12 @@ } // See RFC 8410, section 7. - CBB pkcs8, algorithm, oid, private_key, inner; + CBB pkcs8, algorithm, private_key, inner; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, ed25519_asn1_meth.oid, + ed25519_asn1_meth.oid_len) || !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || // The PKCS#8 encoding stores only the 32-byte seed which is the first 32
diff --git a/crypto/evp/p_rsa_asn1.cc b/crypto/evp/p_rsa_asn1.cc index cdcb6b4..6c6bfc5 100644 --- a/crypto/evp/p_rsa_asn1.cc +++ b/crypto/evp/p_rsa_asn1.cc
@@ -28,11 +28,11 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { // See RFC 3279, section 2.3.1. const RSA *rsa = reinterpret_cast<const RSA *>(key->pkey); - CBB spki, algorithm, oid, null, key_bitstring; + CBB spki, algorithm, null, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, rsa_asn1_meth.oid, + rsa_asn1_meth.oid_len) || !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || @@ -76,12 +76,12 @@ static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { const RSA *rsa = reinterpret_cast<const RSA *>(key->pkey); - CBB pkcs8, algorithm, oid, null, private_key; + CBB pkcs8, algorithm, null, private_key; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, rsa_asn1_meth.oid, + rsa_asn1_meth.oid_len) || !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || !RSA_marshal_private_key(&private_key, rsa) || //
diff --git a/crypto/evp/p_x25519_asn1.cc b/crypto/evp/p_x25519_asn1.cc index 351b788..c31dcc5 100644 --- a/crypto/evp/p_x25519_asn1.cc +++ b/crypto/evp/p_x25519_asn1.cc
@@ -143,11 +143,11 @@ const X25519_KEY *key = reinterpret_cast<X25519_KEY *>(pkey->pkey); // See RFC 8410, section 4. - CBB spki, algorithm, oid, key_bitstring; + CBB spki, algorithm, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, x25519_asn1_meth.oid, x25519_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, x25519_asn1_meth.oid, + x25519_asn1_meth.oid_len) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || !CBB_add_bytes(&key_bitstring, key->pub, 32) || // @@ -188,12 +188,12 @@ } // See RFC 8410, section 7. - CBB pkcs8, algorithm, oid, private_key, inner; + CBB pkcs8, algorithm, private_key, inner; if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, x25519_asn1_meth.oid, x25519_asn1_meth.oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, x25519_asn1_meth.oid, + x25519_asn1_meth.oid_len) || !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || // The PKCS#8 encoding stores only the 32-byte seed which is the first 32
diff --git a/crypto/obj/obj.cc b/crypto/obj/obj.cc index ffc12ff..9fa26bb 100644 --- a/crypto/obj/obj.cc +++ b/crypto/obj/obj.cc
@@ -278,14 +278,8 @@ OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) { const ASN1_OBJECT *obj = OBJ_nid2obj(nid); - CBB oid; - - if (obj == NULL || !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, obj->data, obj->length) || !CBB_flush(out)) { - return 0; - } - - return 1; + return obj != NULL && + CBB_add_asn1_element(out, CBS_ASN1_OBJECT, obj->data, obj->length); } const ASN1_OBJECT *OBJ_get_undef(void) {
diff --git a/crypto/pkcs7/pkcs7.cc b/crypto/pkcs7/pkcs7.cc index 2a5a5a7..aa92cc1 100644 --- a/crypto/pkcs7/pkcs7.cc +++ b/crypto/pkcs7/pkcs7.cc
@@ -167,13 +167,12 @@ int (*cert_crl_cb)(CBB *out, void *arg), int (*signer_infos_cb)(CBB *out, void *arg), void *arg) { - CBB outer_seq, oid, wrapped_seq, seq, digest_algos_set, content_info, - signer_infos; + CBB outer_seq, wrapped_seq, seq, digest_algos_set, content_info, signer_infos; // See https://tools.ietf.org/html/rfc2315#section-7 if (!CBB_add_asn1(out, &outer_seq, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&outer_seq, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kPKCS7SignedData, sizeof(kPKCS7SignedData)) || + !CBB_add_asn1_element(&outer_seq, CBS_ASN1_OBJECT, kPKCS7SignedData, + sizeof(kPKCS7SignedData)) || !CBB_add_asn1(&outer_seq, &wrapped_seq, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || // See https://tools.ietf.org/html/rfc2315#section-9.1 @@ -183,8 +182,8 @@ (digest_algos_cb != NULL && !digest_algos_cb(&digest_algos_set, arg)) || !CBB_flush_asn1_set_of(&digest_algos_set) || !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1_element(&content_info, CBS_ASN1_OBJECT, kPKCS7Data, + sizeof(kPKCS7Data)) || (cert_crl_cb != NULL && !cert_crl_cb(&seq, arg)) || !CBB_add_asn1(&seq, &signer_infos, CBS_ASN1_SET) || (signer_infos_cb != NULL && !signer_infos_cb(&signer_infos, arg)) ||
diff --git a/crypto/pkcs7/pkcs7_x509.cc b/crypto/pkcs7/pkcs7_x509.cc index d762da1..8933f61 100644 --- a/crypto/pkcs7/pkcs7_x509.cc +++ b/crypto/pkcs7/pkcs7_x509.cc
@@ -422,9 +422,9 @@ return 0; } // subjectKeyIdentifier is implicitly-tagged. - if (!CBB_add_asn1(&seq, &child, CBS_ASN1_CONTEXT_SPECIFIC | 0) || - !CBB_add_bytes(&child, ASN1_STRING_get0_data(skid), - ASN1_STRING_length(skid))) { + if (!CBB_add_asn1_element(&seq, CBS_ASN1_CONTEXT_SPECIFIC | 0, + ASN1_STRING_get0_data(skid), + ASN1_STRING_length(skid))) { return 0; } } else {
diff --git a/crypto/pkcs8/p5_pbev2.cc b/crypto/pkcs8/p5_pbev2.cc index 7117763..bac897e 100644 --- a/crypto/pkcs8/p5_pbev2.cc +++ b/crypto/pkcs8/p5_pbev2.cc
@@ -90,10 +90,8 @@ static int add_cipher_oid(CBB *out, int nid) { for (const auto &cipher : kCipherOIDs) { if (cipher.nid == nid) { - CBB child; - return CBB_add_asn1(out, &child, CBS_ASN1_OBJECT) && - CBB_add_bytes(&child, cipher.oid, cipher.oid_len) && - CBB_flush(out); + return CBB_add_asn1_element(out, CBS_ASN1_OBJECT, cipher.oid, + cipher.oid_len); } } @@ -145,18 +143,15 @@ } // See RFC 2898, appendix A. - CBB algorithm, oid, param, kdf, kdf_oid, kdf_param, salt_cbb, cipher_cbb, - iv_cbb; + CBB algorithm, param, kdf, kdf_param, cipher_cbb; if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kPBES2, sizeof(kPBES2)) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, kPBES2, + sizeof(kPBES2)) || !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(¶m, &kdf, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&kdf, &kdf_oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&kdf_oid, kPBKDF2, sizeof(kPBKDF2)) || + !CBB_add_asn1_element(&kdf, CBS_ASN1_OBJECT, kPBKDF2, sizeof(kPBKDF2)) || !CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_octet_string(&kdf_param, salt, salt_len) || !CBB_add_asn1_uint64(&kdf_param, iterations) || // Specify a key length for RC2. (cipher_nid == NID_rc2_cbc && @@ -167,8 +162,8 @@ !add_cipher_oid(&cipher_cbb, cipher_nid) || // RFC 2898 says RC2-CBC and RC5-CBC-Pad use a SEQUENCE with version and // IV, but OpenSSL always uses an OCTET STRING IV, so we do the same. - !CBB_add_asn1(&cipher_cbb, &iv_cbb, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&iv_cbb, iv, EVP_CIPHER_iv_length(cipher)) || + !CBB_add_asn1_octet_string(&cipher_cbb, iv, + EVP_CIPHER_iv_length(cipher)) || !CBB_flush(out)) { return 0; }
diff --git a/crypto/pkcs8/pkcs8.cc b/crypto/pkcs8/pkcs8.cc index a6937c1..4b5609d 100644 --- a/crypto/pkcs8/pkcs8.cc +++ b/crypto/pkcs8/pkcs8.cc
@@ -302,13 +302,12 @@ } // See RFC 2898, appendix A.3. - CBB algorithm, oid, param, salt_cbb; + CBB algorithm, param; if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, suite->oid, suite->oid_len) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, suite->oid, + suite->oid_len) || !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(¶m, &salt_cbb, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_octet_string(¶m, salt, salt_len) || !CBB_add_asn1_uint64(¶m, iterations) || !CBB_flush(out)) { return 0; }
diff --git a/crypto/pkcs8/pkcs8_x509.cc b/crypto/pkcs8/pkcs8_x509.cc index ede84f7..c5abc75 100644 --- a/crypto/pkcs8/pkcs8_x509.cc +++ b/crypto/pkcs8/pkcs8_x509.cc
@@ -904,15 +904,15 @@ return 1; // Omit the OPTIONAL SET. } // See https://tools.ietf.org/html/rfc7292#section-4.2. - CBB attrs, attr, oid, values, value; + CBB attrs, attr, values, value; if (!CBB_add_asn1(bag, &attrs, CBS_ASN1_SET)) { return 0; } if (name_len != 0) { // See https://tools.ietf.org/html/rfc2985, section 5.5.1. if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kFriendlyName, sizeof(kFriendlyName)) || + !CBB_add_asn1_element(&attr, CBS_ASN1_OBJECT, kFriendlyName, + sizeof(kFriendlyName)) || !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) || !CBB_add_asn1(&values, &value, CBS_ASN1_BMPSTRING)) { return 0; @@ -931,11 +931,10 @@ if (key_id_len != 0) { // See https://tools.ietf.org/html/rfc2985, section 5.5.2. if (!CBB_add_asn1(&attrs, &attr, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&attr, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kLocalKeyID, sizeof(kLocalKeyID)) || + !CBB_add_asn1_element(&attr, CBS_ASN1_OBJECT, kLocalKeyID, + sizeof(kLocalKeyID)) || !CBB_add_asn1(&attr, &values, CBS_ASN1_SET) || - !CBB_add_asn1(&values, &value, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&value, key_id, key_id_len)) { + !CBB_add_asn1_octet_string(&values, key_id, key_id_len)) { return 0; } } @@ -944,17 +943,17 @@ static int add_cert_bag(CBB *cbb, X509 *cert, const char *name, const uint8_t *key_id, size_t key_id_len) { - CBB bag, bag_oid, bag_contents, cert_bag, cert_type, wrapped_cert, cert_value; + CBB bag, bag_contents, cert_bag, wrapped_cert, cert_value; if ( // See https://tools.ietf.org/html/rfc7292#section-4.2. !CBB_add_asn1(cbb, &bag, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&bag_oid, kCertBag, sizeof(kCertBag)) || + !CBB_add_asn1_element(&bag, CBS_ASN1_OBJECT, kCertBag, + sizeof(kCertBag)) || !CBB_add_asn1(&bag, &bag_contents, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || // See https://tools.ietf.org/html/rfc7292#section-4.2.3. !CBB_add_asn1(&bag_contents, &cert_bag, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&cert_type, kX509Certificate, sizeof(kX509Certificate)) || + !CBB_add_asn1_element(&cert_bag, CBS_ASN1_OBJECT, kX509Certificate, + sizeof(kX509Certificate)) || !CBB_add_asn1(&cert_bag, &wrapped_cert, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || !CBB_add_asn1(&wrapped_cert, &cert_value, CBS_ASN1_OCTETSTRING)) { @@ -1019,12 +1018,12 @@ } bssl::ScopedEVP_CIPHER_CTX ctx; - CBB content_info, type, wrapper, encrypted_data, encrypted_content_info, - inner_type, encrypted_content; + CBB content_info, wrapper, encrypted_data, encrypted_content_info, + encrypted_content; if ( // Add the ContentInfo wrapping. !CBB_add_asn1(out, &content_info, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&content_info, &type, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&type, kPKCS7EncryptedData, sizeof(kPKCS7EncryptedData)) || + !CBB_add_asn1_element(&content_info, CBS_ASN1_OBJECT, kPKCS7EncryptedData, + sizeof(kPKCS7EncryptedData)) || !CBB_add_asn1(&content_info, &wrapper, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || // See https://tools.ietf.org/html/rfc2315#section-13. @@ -1033,8 +1032,8 @@ // See https://tools.ietf.org/html/rfc2315#section-10.1. !CBB_add_asn1(&encrypted_data, &encrypted_content_info, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&encrypted_content_info, &inner_type, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&inner_type, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1_element(&encrypted_content_info, CBS_ASN1_OBJECT, + kPKCS7Data, sizeof(kPKCS7Data)) || // Set up encryption and fill in contentEncryptionAlgorithm. !pkcs12_pbe_encrypt_init(&encrypted_content_info, ctx.get(), pbe_nid, pbe_cipher, iterations, password, password_len, @@ -1143,15 +1142,14 @@ // See https://tools.ietf.org/html/rfc7292#section-4. PKCS12 *ret = NULL; - CBB cbb, pfx, auth_safe, auth_safe_oid, auth_safe_wrapper, auth_safe_data, - content_infos; + CBB cbb, pfx, auth_safe, auth_safe_wrapper, auth_safe_data, content_infos; uint8_t mac_key[EVP_MAX_MD_SIZE]; if (!CBB_init(&cbb, 0) || !CBB_add_asn1(&cbb, &pfx, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&pfx, 3) || // auth_safe is a data ContentInfo. !CBB_add_asn1(&pfx, &auth_safe, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&auth_safe, &auth_safe_oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&auth_safe_oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1_element(&auth_safe, CBS_ASN1_OBJECT, kPKCS7Data, + sizeof(kPKCS7Data)) || !CBB_add_asn1(&auth_safe, &auth_safe_wrapper, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || !CBB_add_asn1(&auth_safe_wrapper, &auth_safe_data, @@ -1171,10 +1169,10 @@ // OpenSSL does not do this. We keep them separate for consistency. (Keys, // even when encrypted, are always placed in unencrypted ContentInfos. // PKCS#12 defines bag-level encryption for keys.) - CBB content_info, oid, wrapper, data; + CBB content_info, wrapper, data; if (!CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1_element(&content_info, CBS_ASN1_OBJECT, kPKCS7Data, + sizeof(kPKCS7Data)) || !CBB_add_asn1(&content_info, &wrapper, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) || @@ -1211,23 +1209,22 @@ // inside an encrypted ContentInfo, but OpenSSL does not do this and some // PKCS#12 consumers do not support KeyBags.) if (pkey != NULL) { - CBB content_info, oid, wrapper, data, safe_contents, bag, bag_oid, - bag_contents; + CBB content_info, wrapper, data, safe_contents, bag, bag_contents; if ( // Add another data ContentInfo. !CBB_add_asn1(&content_infos, &content_info, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !CBB_add_asn1_element(&content_info, CBS_ASN1_OBJECT, kPKCS7Data, + sizeof(kPKCS7Data)) || !CBB_add_asn1(&content_info, &wrapper, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || !CBB_add_asn1(&wrapper, &data, CBS_ASN1_OCTETSTRING) || !CBB_add_asn1(&data, &safe_contents, CBS_ASN1_SEQUENCE) || // Add a SafeBag containing a PKCS8ShroudedKeyBag. - !CBB_add_asn1(&safe_contents, &bag, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&bag, &bag_oid, CBS_ASN1_OBJECT)) { + !CBB_add_asn1(&safe_contents, &bag, CBS_ASN1_SEQUENCE)) { goto err; } if (key_nid < 0) { - if (!CBB_add_bytes(&bag_oid, kKeyBag, sizeof(kKeyBag)) || + if (!CBB_add_asn1_element(&bag, CBS_ASN1_OBJECT, kKeyBag, + sizeof(kKeyBag)) || !CBB_add_asn1(&bag, &bag_contents, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || !EVP_marshal_private_key(&bag_contents, pkey)) { @@ -1241,8 +1238,8 @@ if (cipher != nullptr) { key_nid = -1; } - if (!CBB_add_bytes(&bag_oid, kPKCS8ShroudedKeyBag, - sizeof(kPKCS8ShroudedKeyBag)) || + if (!CBB_add_asn1_element(&bag, CBS_ASN1_OBJECT, kPKCS8ShroudedKeyBag, + sizeof(kPKCS8ShroudedKeyBag)) || !CBB_add_asn1(&bag, &bag_contents, CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || !PKCS8_marshal_encrypted_private_key( @@ -1279,7 +1276,7 @@ goto err; } - CBB mac_data, digest_info, mac_cbb, mac_salt_cbb; + CBB mac_data, digest_info; if (!CBB_add_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&mac_data, &digest_info, CBS_ASN1_SEQUENCE) || // OpenSSL and NSS always include a NULL parameter with the digest @@ -1293,10 +1290,8 @@ // // We match OpenSSL, NSS, and RSASSA-PKCS1-v1_5 in including the NULL. !EVP_marshal_digest_algorithm(&digest_info, mac_md) || - !CBB_add_asn1(&digest_info, &mac_cbb, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&mac_cbb, mac, mac_len) || - !CBB_add_asn1(&mac_data, &mac_salt_cbb, CBS_ASN1_OCTETSTRING) || - !CBB_add_bytes(&mac_salt_cbb, mac_salt, sizeof(mac_salt)) || + !CBB_add_asn1_octet_string(&digest_info, mac, mac_len) || + !CBB_add_asn1_octet_string(&mac_data, mac_salt, sizeof(mac_salt)) || // The iteration count has a DEFAULT of 1, but RFC 7292 says "The // default is for historical reasons and its use is deprecated." Thus we // explicitly encode the iteration count, though it is not valid DER.
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index b7e9fbf..aa96a28 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc
@@ -17,6 +17,7 @@ #include <algorithm> #include <functional> #include <string> +#include <string_view> #include <vector> #include <gtest/gtest.h> @@ -7151,20 +7152,16 @@ static const char kOIDText[] = "1.2.840.113554.4.1.72585.0"; auto encode_single_attribute_name = - [](CBS_ASN1_TAG tag, - const std::string &contents) -> std::vector<uint8_t> { + [](CBS_ASN1_TAG tag, std::string_view contents) -> std::vector<uint8_t> { + auto bytes = bssl::StringAsBytes(contents); bssl::ScopedCBB cbb; - CBB seq, rdn, attr, attr_type, attr_value; + CBB seq, rdn, attr; if (!CBB_init(cbb.get(), 128) || !CBB_add_asn1(cbb.get(), &seq, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&seq, &rdn, CBS_ASN1_SET) || !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) || - !CBB_add_asn1(&attr, &attr_type, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&attr_type, kOID, sizeof(kOID)) || - !CBB_add_asn1(&attr, &attr_value, tag) || - !CBB_add_bytes(&attr_value, - reinterpret_cast<const uint8_t *>(contents.data()), - contents.size()) || + !CBB_add_asn1_element(&attr, CBS_ASN1_OBJECT, kOID, sizeof(kOID)) || + !CBB_add_asn1_element(&attr, tag, bytes.data(), bytes.size()) || !CBB_flush(cbb.get())) { ADD_FAILURE() << "Could not encode name"; return {};
diff --git a/fuzz/der_roundtrip.cc b/fuzz/der_roundtrip.cc index ffce3b9..5df58ff 100644 --- a/fuzz/der_roundtrip.cc +++ b/fuzz/der_roundtrip.cc
@@ -29,11 +29,9 @@ // correctly. size_t consumed = len - CBS_len(&cbs); bssl::ScopedCBB cbb; - CBB body_cbb; if (!CBB_init(cbb.get(), consumed) || - !CBB_add_asn1(cbb.get(), &body_cbb, tag) || - !CBB_add_bytes(&body_cbb, CBS_data(&body), CBS_len(&body)) || - !CBB_flush(cbb.get()) || + !CBB_add_asn1_element(cbb.get(), tag, CBS_data(&body), + CBS_len(&body)) || CBB_len(cbb.get()) != consumed || memcmp(CBB_data(cbb.get()), buf, consumed) != 0) { abort();
diff --git a/include/openssl/bytestring.h b/include/openssl/bytestring.h index f4dae0f..1738c08 100644 --- a/include/openssl/bytestring.h +++ b/include/openssl/bytestring.h
@@ -601,6 +601,12 @@ // child's contents nor the length prefix will be included in the output. OPENSSL_EXPORT void CBB_discard_child(CBB *cbb); +// CBB_add_asn1_element adds an ASN.1 element with the specified tag and +// contents. It returns one on success and zero on error. This is a convenience +// function over |CBB_add_asn1| when the data is already available. +OPENSSL_EXPORT int CBB_add_asn1_element(CBB *cbb, CBS_ASN1_TAG tag, + const uint8_t *data, size_t data_len); + // CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| // and writes |value| in its contents. It returns one on success and zero on // error.
diff --git a/ssl/handoff.cc b/ssl/handoff.cc index 4cee993..a24d741 100644 --- a/ssl/handoff.cc +++ b/ssl/handoff.cc
@@ -910,9 +910,9 @@ } if (!hints->server_random_tls13.empty()) { - if (!CBB_add_asn1(&seq, &child, kServerRandomTLS13Tag) || - !CBB_add_bytes(&child, hints->server_random_tls13.data(), - hints->server_random_tls13.size())) { + if (!CBB_add_asn1_element(&seq, kServerRandomTLS13Tag, + hints->server_random_tls13.data(), + hints->server_random_tls13.size())) { return 0; } } @@ -944,9 +944,9 @@ } if (!hints->decrypted_psk.empty()) { - if (!CBB_add_asn1(&seq, &child, kDecryptedPSKTag) || - !CBB_add_bytes(&child, hints->decrypted_psk.data(), - hints->decrypted_psk.size())) { + if (!CBB_add_asn1_element(&seq, kDecryptedPSKTag, + hints->decrypted_psk.data(), + hints->decrypted_psk.size())) { return 0; } } @@ -971,9 +971,9 @@ } if (!hints->server_random_tls12.empty()) { - if (!CBB_add_asn1(&seq, &child, kServerRandomTLS12Tag) || - !CBB_add_bytes(&child, hints->server_random_tls12.data(), - hints->server_random_tls12.size())) { + if (!CBB_add_asn1_element(&seq, kServerRandomTLS12Tag, + hints->server_random_tls12.data(), + hints->server_random_tls12.size())) { return 0; } } @@ -992,9 +992,9 @@ if (!hints->decrypted_ticket.empty()) { - if (!CBB_add_asn1(&seq, &child, kDecryptedTicketTag) || - !CBB_add_bytes(&child, hints->decrypted_ticket.data(), - hints->decrypted_ticket.size())) { + if (!CBB_add_asn1_element(&seq, kDecryptedTicketTag, + hints->decrypted_ticket.data(), + hints->decrypted_ticket.size())) { return 0; } }
diff --git a/ssl/ssl_asn1.cc b/ssl/ssl_asn1.cc index 037d34b..484dc9c 100644 --- a/ssl/ssl_asn1.cc +++ b/ssl/ssl_asn1.cc
@@ -168,9 +168,8 @@ // serialized instead. if (sk_CRYPTO_BUFFER_num(in->certs.get()) > 0 && !in->peer_sha256_valid) { const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs.get(), 0); - if (!CBB_add_asn1(&session, &child, kPeerTag) || - !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), - CRYPTO_BUFFER_len(buffer))) { + if (!CBB_add_asn1_element(&session, kPeerTag, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { return 0; } }