diff --git a/CMakeLists.txt b/CMakeLists.txt index 5933f02..77ba873 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -59,14 +59,6 @@ endif() endif() -if(USE_CUSTOM_LIBCXX) - set(BORINGSSL_ALLOW_CXX_RUNTIME 1) -endif() - -if(BORINGSSL_ALLOW_CXX_RUNTIME) - add_definitions(-DBORINGSSL_ALLOW_CXX_RUNTIME) -endif() - string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) if(NOT FIPS) if(CMAKE_BUILD_TYPE_LOWER STREQUAL "relwithassert" OR @@ -177,10 +169,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_FLAGS} -Wmissing-declarations") - if(NOT MSVC AND NOT BORINGSSL_ALLOW_CXX_RUNTIME) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti") - endif() - # In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes # and using the wrong one is an error. In Clang, -Wmissing-prototypes is the # spelling for both and -Wmissing-declarations is some other warning.
diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 422e51c..1cdefaf 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h
@@ -588,6 +588,13 @@ // |X509_NAME| issue is resolved. int X509_check_akid(X509 *issuer, const AUTHORITY_KEYID *akid); +int X509_is_valid_trust_id(int trust); + +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); + +// TODO(https://crbug.com/boringssl/695): Remove this. +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + #if defined(__cplusplus) } // extern C
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index 5419f06..78681c5 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c
@@ -54,8 +54,6 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -#include <assert.h> -#include <limits.h> #include <string.h> #include <openssl/digest.h> @@ -68,6 +66,14 @@ #include "../internal.h" #include "internal.h" + +struct x509_purpose_st { + int purpose; + int trust; // Default trust ID + int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); + const char *sname; +} /* X509_PURPOSE */; + #define V1_ROOT (EXFLAG_V1 | EXFLAG_SS) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) @@ -91,30 +97,30 @@ int ca); static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); +// X509_TRUST_NONE is not a valid |X509_TRUST_*| constant. It is used by +// |X509_PURPOSE_ANY| to indicate that it has no corresponding trust type and +// cannot be used with |X509_STORE_CTX_set_purpose|. +#define X509_TRUST_NONE (-1) + static const X509_PURPOSE xstandard[] = { - {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, - check_purpose_ssl_client, (char *)"SSL client", (char *)"sslclient", NULL}, - {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, - check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver", NULL}, - {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, - check_purpose_ns_ssl_server, (char *)"Netscape SSL server", - (char *)"nssslserver", NULL}, - {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, - (char *)"S/MIME signing", (char *)"smimesign", NULL}, - {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, - check_purpose_smime_encrypt, (char *)"S/MIME encryption", - (char *)"smimeencrypt", NULL}, - {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, - (char *)"CRL signing", (char *)"crlsign", NULL}, - {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *)"Any Purpose", - (char *)"any", NULL}, + {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, check_purpose_ssl_client, + "sslclient"}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, check_purpose_ssl_server, + "sslserver"}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, + check_purpose_ns_ssl_server, "nssslserver"}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, check_purpose_smime_sign, + "smimesign"}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, check_purpose_smime_encrypt, + "smimeencrypt"}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, check_purpose_crl_sign, + "crlsign"}, + {X509_PURPOSE_ANY, X509_TRUST_NONE, no_check, "any"}, // |X509_PURPOSE_OCSP_HELPER| performs no actual checks. OpenSSL's OCSP // implementation relied on the caller performing EKU and KU checks. - {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, no_check, - (char *)"OCSP helper", (char *)"ocsphelper", NULL}, - {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, - check_purpose_timestamp_sign, (char *)"Time Stamp signing", - (char *)"timestampsign", NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, no_check, "ocsphelper"}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, check_purpose_timestamp_sign, + "timestampsign"}, }; int X509_check_purpose(X509 *x, int id, int ca) { @@ -127,8 +133,8 @@ if (id == -1) { return 1; } - int idx = X509_PURPOSE_get_by_id(id); - if (idx == -1) { + const X509_PURPOSE *pt = X509_PURPOSE_get0(id); + if (pt == NULL) { return 0; } // Historically, |check_purpose| implementations other than |X509_PURPOSE_ANY| @@ -138,45 +144,22 @@ if (ca && id != X509_PURPOSE_ANY && !check_ca(x)) { return 0; } - const X509_PURPOSE *pt = X509_PURPOSE_get0(idx); return pt->check_purpose(pt, x, ca); } -int X509_PURPOSE_set(int *p, int purpose) { - if (X509_PURPOSE_get_by_id(purpose) == -1) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE); - return 0; +const X509_PURPOSE *X509_PURPOSE_get0(int id) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) { + if (xstandard[i].purpose == id) { + return &xstandard[i]; + } } - *p = purpose; - return 1; -} - -int X509_PURPOSE_get_count(void) { return OPENSSL_ARRAY_SIZE(xstandard); } - -const X509_PURPOSE *X509_PURPOSE_get0(int idx) { - if (idx < 0 || (size_t)idx >= OPENSSL_ARRAY_SIZE(xstandard)) { - return NULL; - } - return xstandard + idx; + return NULL; } int X509_PURPOSE_get_by_sname(const char *sname) { - const X509_PURPOSE *xptmp; - for (int i = 0; i < X509_PURPOSE_get_count(); i++) { - xptmp = X509_PURPOSE_get0(i); - if (!strcmp(xptmp->sname, sname)) { - return i; - } - } - return -1; -} - -int X509_PURPOSE_get_by_id(int purpose) { - for (size_t i = 0; i <OPENSSL_ARRAY_SIZE(xstandard); i++) { - if (xstandard[i].purpose == purpose) { - static_assert(OPENSSL_ARRAY_SIZE(xstandard) <= INT_MAX, - "indices must fit in int"); - return (int)i; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) { + if (strcmp(xstandard[i].sname, sname) == 0) { + return xstandard[i].purpose; } } return -1; @@ -184,10 +167,6 @@ int X509_PURPOSE_get_id(const X509_PURPOSE *xp) { return xp->purpose; } -char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp) { return xp->name; } - -char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp) { return xp->sname; } - int X509_PURPOSE_get_trust(const X509_PURPOSE *xp) { return xp->trust; } int X509_supported_extension(const X509_EXTENSION *ex) {
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index a3616dc..6b06b7c 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc
@@ -4329,6 +4329,17 @@ {}, {}, flags)); } } + + // X509_V_FLAG_USE_CHECK_TIME is an internal flag, but one caller relies on + // being able to clear it to restore the system time. Using the system time, + // all certificates in this test should read as expired. + EXPECT_EQ(X509_V_ERR_CERT_HAS_EXPIRED, + Verify(leaf.valid.get(), {root.valid.get()}, + {intermediate.valid.get()}, {}, 0, [](X509_STORE_CTX *ctx) { + X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx); + X509_VERIFY_PARAM_clear_flags(param, + X509_V_FLAG_USE_CHECK_TIME); + })); } TEST(X509Test, SignatureVerification) { @@ -7719,6 +7730,36 @@ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, Verify(leaf.normal.get(), {root.trusted_any.get()}, {intermediate.normal.get()}, {}, /*flags=*/0, set_server_trust)); + + // Trust settings on a certificate are ignored if the leaf did not come from + // |X509_STORE|. This is important because trust settings may be serialized + // via |d2i_X509_AUX|. It is often not obvious which functions may trigger + // this, so callers may inadvertently run with attacker-supplied trust + // settings on untrusted certificates. + EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, + Verify(leaf.trusted_server.get(), /*roots=*/{}, + /*intermediates=*/{intermediate.trusted_server.get()}, {}, + /*flags=*/0, set_server_trust)); + EXPECT_EQ( + X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, + Verify(leaf.trusted_server.get(), /*roots=*/{}, + /*intermediates=*/ + {intermediate.trusted_server.get(), root.trusted_server.get()}, {}, + /*flags=*/0, set_server_trust)); + + // Likewise, distrusts only take effect from |X509_STORE|. + EXPECT_EQ(X509_V_OK, Verify(leaf.distrusted_server.get(), {root.normal.get()}, + {intermediate.normal.get()}, {}, + /*flags=*/0, set_server_trust)); +} + +// Test some APIs that rust-openssl uses to look up purposes by name. +TEST(X509Test, PurposeByShortName) { + int idx = X509_PURPOSE_get_by_sname("sslserver"); + ASSERT_NE(idx, -1); + const X509_PURPOSE *purpose = X509_PURPOSE_get0(idx); + ASSERT_TRUE(purpose); + EXPECT_EQ(X509_PURPOSE_get_id(purpose), X509_PURPOSE_SSL_SERVER); } TEST(X509Test, CriticalExtension) { @@ -7745,4 +7786,6 @@ EXPECT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, Verify(leaf.get(), {root.get()}, {}, {})); + EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {}, {}, + X509_V_FLAG_IGNORE_CRITICAL)); }
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index 907e492..87137b1 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c
@@ -54,9 +54,6 @@ * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). */ -#include <assert.h> -#include <limits.h> - #include <openssl/err.h> #include <openssl/mem.h> #include <openssl/obj.h> @@ -66,23 +63,35 @@ #include "internal.h" +typedef struct x509_trust_st X509_TRUST; + +struct x509_trust_st { + int trust; + int (*check_trust)(const X509_TRUST *, X509 *, int); + int nid; +} /* X509_TRUST */; + static int trust_1oidany(const X509_TRUST *trust, X509 *x, int flags); static int trust_compat(const X509_TRUST *trust, X509 *x, int flags); static int obj_trust(int id, X509 *x, int flags); static const X509_TRUST trstandard[] = { - {X509_TRUST_COMPAT, 0, trust_compat, (char *)"compatible", 0, NULL}, - {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client", - NID_client_auth, NULL}, - {X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *)"SSL Server", - NID_server_auth, NULL}, - {X509_TRUST_EMAIL, 0, trust_1oidany, (char *)"S/MIME email", - NID_email_protect, NULL}, - {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *)"Object Signer", - NID_code_sign, NULL}, - {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp, - NULL}}; + {X509_TRUST_COMPAT, trust_compat, 0}, + {X509_TRUST_SSL_CLIENT, trust_1oidany, NID_client_auth}, + {X509_TRUST_SSL_SERVER, trust_1oidany, NID_server_auth}, + {X509_TRUST_EMAIL, trust_1oidany, NID_email_protect}, + {X509_TRUST_OBJECT_SIGN, trust_1oidany, NID_code_sign}, + {X509_TRUST_TSA, trust_1oidany, NID_time_stamp}}; + +static const X509_TRUST *X509_TRUST_get0(int id) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(trstandard); i++) { + if (trstandard[i].trust == id) { + return &trstandard[i]; + } + } + return NULL; +} int X509_check_trust(X509 *x, int id, int flags) { if (id == -1) { @@ -96,52 +105,23 @@ } return trust_compat(NULL, x, 0); } - int idx = X509_TRUST_get_by_id(id); - if (idx == -1) { + const X509_TRUST *pt = X509_TRUST_get0(id); + if (pt == NULL) { + // Unknown trust IDs are silently reintrepreted as NIDs. This is unreachable + // from the certificate verifier itself, but wpa_supplicant relies on it. + // Note this relies on commonly-used NIDs and trust IDs not colliding. return obj_trust(id, x, flags); } - const X509_TRUST *pt = X509_TRUST_get0(idx); return pt->check_trust(pt, x, flags); } -int X509_TRUST_get_count(void) { return OPENSSL_ARRAY_SIZE(trstandard); } - -const X509_TRUST *X509_TRUST_get0(int idx) { - if (idx < 0 || (size_t)idx >= OPENSSL_ARRAY_SIZE(trstandard)) { - return NULL; - } - return trstandard + idx; +int X509_is_valid_trust_id(int trust) { + return X509_TRUST_get0(trust) != NULL; } -int X509_TRUST_get_by_id(int id) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(trstandard); i++) { - if (trstandard[i].trust == id) { - static_assert(OPENSSL_ARRAY_SIZE(trstandard) <= INT_MAX, - "indices must fit in int"); - return (int)i; - } - } - return -1; -} - -int X509_TRUST_set(int *t, int trust) { - if (X509_TRUST_get_by_id(trust) == -1) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST); - return 0; - } - *t = trust; - return 1; -} - -int X509_TRUST_get_flags(const X509_TRUST *xp) { return xp->flags; } - -char *X509_TRUST_get0_name(const X509_TRUST *xp) { return xp->name; } - -int X509_TRUST_get_trust(const X509_TRUST *xp) { return xp->trust; } - static int trust_1oidany(const X509_TRUST *trust, X509 *x, int flags) { if (x->aux && (x->aux->trust || x->aux->reject)) { - return obj_trust(trust->arg1, x, flags); + return obj_trust(trust->nid, x, flags); } // we don't have any trust settings: for compatibility we return trusted // if it is self signed @@ -160,24 +140,21 @@ } static int obj_trust(int id, X509 *x, int flags) { - ASN1_OBJECT *obj; - size_t i; - X509_CERT_AUX *ax; - ax = x->aux; + X509_CERT_AUX *ax = x->aux; if (!ax) { return X509_TRUST_UNTRUSTED; } if (ax->reject) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { - obj = sk_ASN1_OBJECT_value(ax->reject, i); + for (size_t i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + const ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i); if (OBJ_obj2nid(obj) == id) { return X509_TRUST_REJECTED; } } } if (ax->trust) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { - obj = sk_ASN1_OBJECT_value(ax->trust, i); + for (size_t i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + const ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i); if (OBJ_obj2nid(obj) == id) { return X509_TRUST_TRUSTED; }
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index a6f6215..81e413e 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c
@@ -1485,13 +1485,13 @@ return 1; } - int idx = X509_PURPOSE_get_by_id(purpose); - if (idx == -1) { + const X509_PURPOSE *pobj = X509_PURPOSE_get0(purpose); + if (pobj == NULL) { OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID); return 0; } - int trust = X509_PURPOSE_get_trust(X509_PURPOSE_get0(idx)); + int trust = X509_PURPOSE_get_trust(pobj); if (!X509_STORE_CTX_set_trust(ctx, trust)) { return 0; } @@ -1508,7 +1508,7 @@ return 1; } - if (X509_TRUST_get_by_id(trust) == -1) { + if (!X509_is_valid_trust_id(trust)) { OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); return 0; }
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 7314c44..0640fd0 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c
@@ -269,11 +269,22 @@ } int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) { - return X509_PURPOSE_set(¶m->purpose, purpose); + if (X509_PURPOSE_get0(purpose) == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE); + return 0; + } + param->purpose = purpose; + return 1; } int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) { - return X509_TRUST_set(¶m->trust, trust); + if (!X509_is_valid_trust_id(trust)) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID); + return 0; + } + + param->trust = trust; + return 1; } void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) {
diff --git a/include/openssl/base.h b/include/openssl/base.h index 98de503..9b72e99 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h
@@ -378,11 +378,11 @@ typedef struct x509_lookup_st X509_LOOKUP; typedef struct x509_lookup_method_st X509_LOOKUP_METHOD; typedef struct x509_object_st X509_OBJECT; +typedef struct x509_purpose_st X509_PURPOSE; typedef struct x509_revoked_st X509_REVOKED; typedef struct x509_st X509; typedef struct x509_store_ctx_st X509_STORE_CTX; typedef struct x509_store_st X509_STORE; -typedef struct x509_trust_st X509_TRUST; typedef void *OPENSSL_BLOCK;
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 171ac43..c5c21bb 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h
@@ -162,6 +162,7 @@ #define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0 #define OPENSSL_INIT_LOAD_CONFIG 0 #define OPENSSL_INIT_NO_LOAD_CONFIG 0 +#define OPENSSL_INIT_NO_ATEXIT 0 // OPENSSL_init_crypto calls |CRYPTO_library_init| and returns one. OPENSSL_EXPORT int OPENSSL_init_crypto(uint64_t opts,
diff --git a/include/openssl/pem.h b/include/openssl/pem.h index 351e3f6..b67417f 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h
@@ -358,6 +358,11 @@ // If |sk| is non-NULL, it appends the results to |sk| instead and returns |sk| // on success. In this case, the caller retains ownership of |sk| in both // success and failure. +// +// WARNING: If the input contains "TRUSTED CERTIFICATE" PEM blocks, this +// function parses auxiliary properties as in |d2i_X509_AUX|. Passing untrusted +// input to this function allows an attacker to influence those properties. See +// |d2i_X509_AUX| for details. OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio( BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); @@ -390,6 +395,8 @@ DECLARE_PEM_rw(X509, X509) +// TODO(crbug.com/boringssl/426): When documenting these, copy the warning +// about auxiliary properties from |PEM_X509_INFO_read_bio|. DECLARE_PEM_rw(X509_AUX, X509) DECLARE_PEM_rw(X509_REQ, X509_REQ)
diff --git a/include/openssl/pki/certificate.h b/include/openssl/pki/certificate.h index 3adaa03..782a70a 100644 --- a/include/openssl/pki/certificate.h +++ b/include/openssl/pki/certificate.h
@@ -12,7 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef OPENSSL_HEADER_BSSL_PKI_CERTIFICATE_H_ +#if !defined(OPENSSL_HEADER_BSSL_PKI_CERTIFICATE_H_) && defined(__cplusplus) #define OPENSSL_HEADER_BSSL_PKI_CERTIFICATE_H_ #include <memory> @@ -80,4 +80,4 @@ } // namespace bssl -#endif // OPENSSL_HEADER_BSSL_PKI_CERTIFICATE_H_ +#endif // OPENSSL_HEADER_BSSL_PKI_CERTIFICATE_H_ && __cplusplus
diff --git a/include/openssl/pki/signature_verify_cache.h b/include/openssl/pki/signature_verify_cache.h index 640132e..ae73765 100644 --- a/include/openssl/pki/signature_verify_cache.h +++ b/include/openssl/pki/signature_verify_cache.h
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef BSSL_PKI_SIGNATURE_VERIFY_CACHE_H_ +#if !defined(BSSL_PKI_SIGNATURE_VERIFY_CACHE_H_) && defined(__cplusplus) #define BSSL_PKI_SIGNATURE_VERIFY_CACHE_H_ #include <openssl/base.h> @@ -38,4 +38,4 @@ } // namespace bssl -#endif // BSSL_PKI_SIGNATURE_VERIFY_CACHE_H_ +#endif // BSSL_PKI_SIGNATURE_VERIFY_CACHE_H_ && __cplusplus
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 2f1264a..839cf2f 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -1229,6 +1229,11 @@ // reads the contents of |file| as a PEM-encoded leaf certificate followed // optionally by the certificate chain to send to the peer. It returns one on // success and zero on failure. +// +// WARNING: If the input contains "TRUSTED CERTIFICATE" PEM blocks, this +// function parses auxiliary properties as in |d2i_X509_AUX|. Passing untrusted +// input to this function allows an attacker to influence those properties. See +// |d2i_X509_AUX| for details. OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
diff --git a/include/openssl/x509.h b/include/openssl/x509.h index c7e6919..008c0cb 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h
@@ -102,10 +102,6 @@ // // In the future, a replacement library will be available. Meanwhile, minimize // dependencies on this header where possible. -// -// TODO(https://crbug.com/boringssl/426): Documentation for this library is -// still in progress. Some functions have not yet been documented, and some -// functions have not yet been grouped into sections. // Certificates. @@ -608,8 +604,11 @@ // Certificate (RFC 5280), followed optionally by a separate, OpenSSL-specific // structure with auxiliary properties. It behaves as described in |d2i_SAMPLE|. // -// Some auxiliary properties affect trust decisions, so this function should not -// be used with untrusted input. +// WARNING: Passing untrusted input to this function allows an attacker to +// control auxiliary properties. This can allow unexpected influence over the +// application if the certificate is used in a context that reads auxiliary +// properties. This includes PKCS#12 serialization, trusted certificates in +// |X509_STORE|, and callers of |X509_alias_get0| or |X509_keyid_get0|. // // Unlike similarly-named functions, this function does not parse a single // ASN.1 element. Trying to parse data directly embedded in a larger ASN.1 @@ -619,7 +618,9 @@ // X509_alias_set1 sets |x509|'s alias to |len| bytes from |name|. If |name| is // NULL, the alias is cleared instead. Aliases are not part of the certificate -// itself and will not be serialized by |i2d_X509|. +// itself and will not be serialized by |i2d_X509|. If |x509| is serialized in +// a PKCS#12 structure, the friendlyName attribute (RFC 2985) will contain this +// alias. OPENSSL_EXPORT int X509_alias_set1(X509 *x509, const uint8_t *name, ossl_ssize_t len); @@ -655,16 +656,20 @@ // X509_add1_trust_object configures |x509| as a valid trust anchor for |obj|. // It returns one on success and zero on error. |obj| should be a certificate -// usage OID associated with an |X509_TRUST| object. +// usage OID associated with an |X509_TRUST_*| constant. // // See |X509_VERIFY_PARAM_set_trust| for details on how this value is evaluated. +// Note this only takes effect if |x509| was configured as a trusted certificate +// via |X509_STORE|. OPENSSL_EXPORT int X509_add1_trust_object(X509 *x509, const ASN1_OBJECT *obj); // X509_add1_reject_object configures |x509| as distrusted for |obj|. It returns // one on success and zero on error. |obj| should be a certificate usage OID -// associated with an |X509_TRUST| object. +// associated with an |X509_TRUST_*| constant. // // See |X509_VERIFY_PARAM_set_trust| for details on how this value is evaluated. +// Note this only takes effect if |x509| was configured as a trusted certificate +// via |X509_STORE|. OPENSSL_EXPORT int X509_add1_reject_object(X509 *x509, const ASN1_OBJECT *obj); // X509_trust_clear clears the list of OIDs for which |x509| is trusted. See @@ -2647,6 +2652,70 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from); +// X509_V_FLAG_* are flags for |X509_VERIFY_PARAM_set_flags| and +// |X509_VERIFY_PARAM_clear_flags|. + +// X509_V_FLAG_CB_ISSUER_CHECK causes the deprecated verify callback (see +// |X509_STORE_CTX_set_verify_cb|) to be called for errors while matching +// subject and issuer certificates. +#define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +// X509_V_FLAG_USE_CHECK_TIME is an internal flag used to track whether +// |X509_STORE_CTX_set_time| has been used. If cleared, the system time is +// restored. +#define X509_V_FLAG_USE_CHECK_TIME 0x2 +// X509_V_FLAG_CRL_CHECK enables CRL lookup and checking for the leaf. +#define X509_V_FLAG_CRL_CHECK 0x4 +// X509_V_FLAG_CRL_CHECK_ALL enables CRL lookup and checking for the entire +// certificate chain. |X509_V_FLAG_CRL_CHECK| must be set for this flag to take +// effect. +#define X509_V_FLAG_CRL_CHECK_ALL 0x8 +// X509_V_FLAG_IGNORE_CRITICAL ignores unhandled critical extensions. Do not use +// this option. Critical extensions ensure the verifier does not bypass +// unrecognized security restrictions in certificates. +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 +// X509_V_FLAG_X509_STRICT does nothing. Its functionality has been enabled by +// default. +#define X509_V_FLAG_X509_STRICT 0x00 +// X509_V_FLAG_ALLOW_PROXY_CERTS does nothing. Proxy certificate support has +// been removed. +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +// X509_V_FLAG_POLICY_CHECK does nothing. Policy checking is always enabled. +#define X509_V_FLAG_POLICY_CHECK 0x80 +// X509_V_FLAG_EXPLICIT_POLICY requires some policy OID to be asserted by the +// final certificate chain. See initial-explicit-policy from RFC 5280, +// section 6.1.1. +#define X509_V_FLAG_EXPLICIT_POLICY 0x100 +// X509_V_FLAG_INHIBIT_ANY inhibits the anyPolicy OID. See +// initial-any-policy-inhibit from RFC 5280, section 6.1.1. +#define X509_V_FLAG_INHIBIT_ANY 0x200 +// X509_V_FLAG_INHIBIT_MAP inhibits policy mapping. See +// initial-policy-mapping-inhibit from RFC 5280, section 6.1.1. +#define X509_V_FLAG_INHIBIT_MAP 0x400 +// X509_V_FLAG_NOTIFY_POLICY does nothing. Its functionality has been removed. +#define X509_V_FLAG_NOTIFY_POLICY 0x800 +// X509_V_FLAG_EXTENDED_CRL_SUPPORT causes all verifications to fail. Extended +// CRL features have been removed. +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +// X509_V_FLAG_USE_DELTAS causes all verifications to fail. Delta CRL support +// has been removed. +#define X509_V_FLAG_USE_DELTAS 0x2000 +// X509_V_FLAG_CHECK_SS_SIGNATURE checks the redundant signature on self-signed +// trust anchors. This check provides no security benefit and only wastes CPU. +#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +// X509_V_FLAG_TRUSTED_FIRST, during path-building, checks for a match in the +// trust store before considering an untrusted intermediate. This flag is +// enabled by default. +#define X509_V_FLAG_TRUSTED_FIRST 0x8000 +// X509_V_FLAG_PARTIAL_CHAIN treats all trusted certificates as trust anchors, +// independent of the |X509_VERIFY_PARAM_set_trust| setting. +#define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +// X509_V_FLAG_NO_ALT_CHAINS disables building alternative chains if the initial +// one was rejected. +#define X509_V_FLAG_NO_ALT_CHAINS 0x100000 +// X509_V_FLAG_NO_CHECK_TIME disables all time checks in certificate +// verification. +#define X509_V_FLAG_NO_CHECK_TIME 0x200000 + // X509_VERIFY_PARAM_set_flags enables all values in |flags| in |param|'s // verification flags and returns one. |flags| should be a combination of // |X509_V_FLAG_*| constants. @@ -2868,6 +2937,10 @@ // it is trusted if self-signed instead. Note this slightly differs from the // above. // +// If the |X509_V_FLAG_PARTIAL_CHAIN| is set, every certificate from +// |X509_STORE| is a trust anchor, unless it was explicitly distrusted for the +// OID. +// // It is currently not possible to configure custom trust OIDs. Contact the // BoringSSL maintainers if your application needs to do so. OpenSSL had an // |X509_TRUST_add| API, but it was not thread-safe and relied on global mutable @@ -4313,6 +4386,31 @@ OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects( X509_STORE *store); +// X509_PURPOSE_get_by_sname returns the |X509_PURPOSE_*| constant corresponding +// a short name |sname|, or -1 if |sname| was not recognized. +// +// Use |X509_PURPOSE_*| constants directly instead. The short names used by this +// function look like "sslserver" or "smimeencrypt", so they do not make +// especially good APIs. +// +// This function differs from OpenSSL, which returns an "index" to be passed to +// |X509_PURPOSE_get0|, followed by |X509_PURPOSE_get_id|, to finally obtain an +// |X509_PURPOSE_*| value suitable for use with |X509_VERIFY_PARAM_set_purpose|. +OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname); + +// X509_PURPOSE_get0 returns the |X509_PURPOSE| object corresponding to |id|, +// which should be one of the |X509_PURPOSE_*| constants, or NULL if none +// exists. +// +// This function differs from OpenSSL, which takes an "index", returned from +// |X509_PURPOSE_get_by_sname|. In BoringSSL, indices and |X509_PURPOSE_*| IDs +// are the same. +OPENSSL_EXPORT const X509_PURPOSE *X509_PURPOSE_get0(int id); + +// X509_PURPOSE_get_id returns |purpose|'s ID. This will be one of the +// |X509_PURPOSE_*| constants. +OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *purpose); + // Private structures. @@ -4322,7 +4420,10 @@ } /* X509_ALGOR */; -// Functions below this point have not yet been organized into sections. +// Underdocumented functions. +// +// TODO(https://crbug.com/boringssl/426): Functions below this point have not +// yet been documented or organized into sections. // This stuff is certificate "auxiliary info" // it contains details which are useful in certificate @@ -4331,23 +4432,6 @@ DECLARE_STACK_OF(DIST_POINT) -// This is used for a table of trust checking functions - -struct x509_trust_st { - int trust; - int flags; - int (*check_trust)(const X509_TRUST *, X509 *, int); - char *name; - int arg1; - void *arg2; -} /* X509_TRUST */; - -DEFINE_STACK_OF(X509_TRUST) - -// standard trust ids - -#define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings - OPENSSL_EXPORT const char *X509_get_default_cert_area(void); OPENSSL_EXPORT const char *X509_get_default_cert_dir(void); OPENSSL_EXPORT const char *X509_get_default_cert_file(void); @@ -4356,8 +4440,6 @@ OPENSSL_EXPORT const char *X509_get_default_private_dir(void); -OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); - OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); // X509_NAME_hash returns a hash of |name|, or zero on error. This is the new @@ -4388,13 +4470,6 @@ OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); -OPENSSL_EXPORT int X509_TRUST_get_count(void); -OPENSSL_EXPORT const X509_TRUST *X509_TRUST_get0(int idx); -OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); -OPENSSL_EXPORT int X509_TRUST_get_flags(const X509_TRUST *xp); -OPENSSL_EXPORT char *X509_TRUST_get0_name(const X509_TRUST *xp); -OPENSSL_EXPORT int X509_TRUST_get_trust(const X509_TRUST *xp); - /* SSL_CTX -> X509_STORE @@ -4442,53 +4517,6 @@ OPENSSL_EXPORT int X509_LOOKUP_add_dir(X509_LOOKUP *lookup, const char *path, int type); -// Certificate verify flags - -// Send issuer+subject checks to verify_cb -#define X509_V_FLAG_CB_ISSUER_CHECK 0x1 -// Use check time instead of current time -#define X509_V_FLAG_USE_CHECK_TIME 0x2 -// Lookup CRLs -#define X509_V_FLAG_CRL_CHECK 0x4 -// Lookup CRLs for whole chain -#define X509_V_FLAG_CRL_CHECK_ALL 0x8 -// Ignore unhandled critical extensions -#define X509_V_FLAG_IGNORE_CRITICAL 0x10 -// Does nothing as its functionality has been enabled by default. -#define X509_V_FLAG_X509_STRICT 0x00 -// This flag does nothing as proxy certificate support has been removed. -#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 -// Does nothing as its functionality has been enabled by default. -#define X509_V_FLAG_POLICY_CHECK 0x80 -// Policy variable require-explicit-policy -#define X509_V_FLAG_EXPLICIT_POLICY 0x100 -// Policy variable inhibit-any-policy -#define X509_V_FLAG_INHIBIT_ANY 0x200 -// Policy variable inhibit-policy-mapping -#define X509_V_FLAG_INHIBIT_MAP 0x400 -// Does nothing -#define X509_V_FLAG_NOTIFY_POLICY 0x800 -// Causes all verifications to fail. Extended CRL features have been removed. -#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 -// Causes all verifications to fail. Delta CRL support has been removed. -#define X509_V_FLAG_USE_DELTAS 0x2000 -// Check selfsigned CA signature -#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 -// Use trusted store first -#define X509_V_FLAG_TRUSTED_FIRST 0x8000 - -// Allow partial chains if at least one certificate is in trusted store -#define X509_V_FLAG_PARTIAL_CHAIN 0x80000 - -// If the initial chain is not trusted, do not attempt to build an alternative -// chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag -// will force the behaviour to match that of previous versions. -#define X509_V_FLAG_NO_ALT_CHAINS 0x100000 - -// X509_V_FLAG_NO_CHECK_TIME disables all time checks in certificate -// verification. -#define X509_V_FLAG_NO_CHECK_TIME 0x200000 - OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, const X509_LOOKUP_METHOD *m); @@ -4561,7 +4589,6 @@ DEFINE_STACK_OF(X509V3_EXT_METHOD) -// ext_flags values #define X509V3_EXT_CTX_DEP 0x2 #define X509V3_EXT_MULTILINE 0x4 @@ -4590,8 +4617,6 @@ // If relativename then this contains the full distribution point name X509_NAME *dpname; } DIST_POINT_NAME; -// All existing reasons -#define CRLDP_ALL_REASONS 0x807f struct DIST_POINT_st { DIST_POINT_NAME *distpoint; @@ -4686,18 +4711,6 @@ #define NS_OBJSIGN_CA 0x01 #define NS_ANY_CA (NS_SSL_CA | NS_SMIME_CA | NS_OBJSIGN_CA) -typedef struct x509_purpose_st { - int purpose; - int trust; // Default trust ID - int flags; - int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); - char *name; - char *sname; - void *usr_data; -} X509_PURPOSE; - -DEFINE_STACK_OF(X509_PURPOSE) - DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) // TODO(https://crbug.com/boringssl/407): This is not const because it contains @@ -4725,9 +4738,6 @@ // an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) -OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, - X509_NAME *iname); - // TODO(https://crbug.com/boringssl/407): This is not const because it contains // an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) @@ -4863,8 +4873,8 @@ // append if it is not present. #define X509V3_ADD_REPLACE 2L -// X509V3_ADD_REPLACE causes the function to replace the existing extension and -// fail if it is not present. +// X509V3_ADD_REPLACE_EXISTING causes the function to replace the existing +// extension and fail if it is not present. #define X509V3_ADD_REPLACE_EXISTING 3L // X509V3_ADD_KEEP_EXISTING causes the function to succeed without replacing the @@ -4897,17 +4907,6 @@ OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); -OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); - -OPENSSL_EXPORT int X509_PURPOSE_get_count(void); -OPENSSL_EXPORT const X509_PURPOSE *X509_PURPOSE_get0(int idx); -OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname); -OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); -OPENSSL_EXPORT char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); -OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); -OPENSSL_EXPORT int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); -OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *); - #if defined(__cplusplus) } // extern C
diff --git a/pki/certificate_policies.cc b/pki/certificate_policies.cc index 5a6df34..198e348 100644 --- a/pki/certificate_policies.cc +++ b/pki/certificate_policies.cc
@@ -12,7 +12,6 @@ #include "input.h" #include "parse_values.h" #include "parser.h" -#include "tag.h" namespace bssl { @@ -64,7 +63,7 @@ } // policyQualifierId PolicyQualifierId, der::Input qualifier_oid; - if (!policy_information_parser.ReadTag(der::kOid, &qualifier_oid)) { + if (!policy_information_parser.ReadTag(CBS_ASN1_OBJECT, &qualifier_oid)) { return false; } if (restrict_to_known_qualifiers && @@ -164,7 +163,7 @@ } // policyIdentifier CertPolicyId, der::Input policy_oid; - if (!policy_information_parser.ReadTag(der::kOid, &policy_oid)) { + if (!policy_information_parser.ReadTag(CBS_ASN1_OBJECT, &policy_oid)) { return false; } @@ -273,7 +272,7 @@ } std::optional<der::Input> require_value; - if (!sequence_parser.ReadOptionalTag(der::ContextSpecificPrimitive(0), + if (!sequence_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 0, &require_value)) { return false; } @@ -289,7 +288,7 @@ } std::optional<der::Input> inhibit_value; - if (!sequence_parser.ReadOptionalTag(der::ContextSpecificPrimitive(1), + if (!sequence_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, &inhibit_value)) { return false; } @@ -364,10 +363,12 @@ } ParsedPolicyMapping mapping; - if (!mapping_parser.ReadTag(der::kOid, &mapping.issuer_domain_policy)) { + if (!mapping_parser.ReadTag(CBS_ASN1_OBJECT, + &mapping.issuer_domain_policy)) { return false; } - if (!mapping_parser.ReadTag(der::kOid, &mapping.subject_domain_policy)) { + if (!mapping_parser.ReadTag(CBS_ASN1_OBJECT, + &mapping.subject_domain_policy)) { return false; }
diff --git a/pki/crl.cc b/pki/crl.cc index cc9c878..63e1cc6 100644 --- a/pki/crl.cc +++ b/pki/crl.cc
@@ -6,6 +6,7 @@ #include <iterator> #include <openssl/base.h> +#include <openssl/bytestring.h> #include "cert_errors.h" #include "crl.h" @@ -14,7 +15,6 @@ #include "parser.h" #include "revocation_util.h" #include "signature_algorithm.h" -#include "tag.h" #include "verify_name_match.h" #include "verify_signed_data.h" @@ -31,7 +31,7 @@ der::Parser parser(name_tlv); der::Input name_rdn; bssl::CertErrors unused_errors; - return parser.ReadTag(der::kSequence, &name_rdn) && + return parser.ReadTag(CBS_ASN1_SEQUENCE, &name_rdn) && NormalizeName(name_rdn, out_normalized_name, &unused_errors) && !parser.HasMore(); } @@ -104,7 +104,7 @@ // version Version OPTIONAL, // -- if present, MUST be v2 std::optional<der::Input> version_der; - if (!tbs_parser.ReadOptionalTag(der::kInteger, &version_der)) { + if (!tbs_parser.ReadOptionalTag(CBS_ASN1_INTEGER, &version_der)) { return false; } if (version_der.has_value()) { @@ -139,12 +139,12 @@ } // nextUpdate Time OPTIONAL, - der::Tag maybe_next_update_tag; + CBS_ASN1_TAG maybe_next_update_tag; der::Input unused_next_update_input; if (tbs_parser.PeekTagAndValue(&maybe_next_update_tag, &unused_next_update_input) && - (maybe_next_update_tag == der::kUtcTime || - maybe_next_update_tag == der::kGeneralizedTime)) { + (maybe_next_update_tag == CBS_ASN1_UTCTIME || + maybe_next_update_tag == CBS_ASN1_GENERALIZEDTIME)) { der::GeneralizedTime next_update_time; if (!ReadUTCOrGeneralizedTime(&tbs_parser, &next_update_time)) { return false; @@ -156,10 +156,10 @@ // revokedCertificates SEQUENCE OF SEQUENCE { ... } OPTIONAL, der::Input unused_revoked_certificates; - der::Tag maybe_revoked_certifigates_tag; + CBS_ASN1_TAG maybe_revoked_certifigates_tag; if (tbs_parser.PeekTagAndValue(&maybe_revoked_certifigates_tag, &unused_revoked_certificates) && - maybe_revoked_certifigates_tag == der::kSequence) { + maybe_revoked_certifigates_tag == CBS_ASN1_SEQUENCE) { der::Input revoked_certificates_tlv; if (!tbs_parser.ReadRawTLV(&revoked_certificates_tlv)) { return false; @@ -171,8 +171,9 @@ // crlExtensions [0] EXPLICIT Extensions OPTIONAL // -- if present, version MUST be v2 - if (!tbs_parser.ReadOptionalTag(der::ContextSpecificConstructed(0), - &out->crl_extensions_tlv)) { + if (!tbs_parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, + &out->crl_extensions_tlv)) { return false; } if (out->crl_extensions_tlv.has_value()) { @@ -216,7 +217,7 @@ // distributionPoint [0] DistributionPointName OPTIONAL, std::optional<der::Input> distribution_point; if (!idp_parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 0, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &distribution_point)) { return false; } @@ -228,7 +229,7 @@ // nameRelativeToCRLIssuer [1] RelativeDistinguishedName } std::optional<der::Input> der_full_name; if (!dp_name_parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 0, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &der_full_name)) { return false; } @@ -253,7 +254,7 @@ // onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, std::optional<der::Input> only_contains_user_certs; - if (!idp_parser.ReadOptionalTag(der::kTagContextSpecific | 1, + if (!idp_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, &only_contains_user_certs)) { return false; } @@ -270,7 +271,7 @@ // onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, std::optional<der::Input> only_contains_ca_certs; - if (!idp_parser.ReadOptionalTag(der::kTagContextSpecific | 2, + if (!idp_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 2, &only_contains_ca_certs)) { return false; } @@ -343,7 +344,8 @@ der::Input revoked_cert_serial_number; // userCertificate CertificateSerialNumber, - if (!crl_entry_parser.ReadTag(der::kInteger, &revoked_cert_serial_number)) { + if (!crl_entry_parser.ReadTag(CBS_ASN1_INTEGER, + &revoked_cert_serial_number)) { return CRLRevocationStatus::UNKNOWN; }
diff --git a/pki/extended_key_usage.cc b/pki/extended_key_usage.cc index a5d007f..1aeeb6a 100644 --- a/pki/extended_key_usage.cc +++ b/pki/extended_key_usage.cc
@@ -4,9 +4,10 @@ #include "extended_key_usage.h" +#include <openssl/bytestring.h> + #include "input.h" #include "parser.h" -#include "tag.h" namespace bssl { @@ -27,7 +28,7 @@ } while (sequence_parser.HasMore()) { der::Input eku_oid; - if (!sequence_parser.ReadTag(der::kOid, &eku_oid)) { + if (!sequence_parser.ReadTag(CBS_ASN1_OBJECT, &eku_oid)) { // The SEQUENCE OF must contain only KeyPurposeIds (OIDs). return false; }
diff --git a/pki/general_names.cc b/pki/general_names.cc index 74874ba..c446287 100644 --- a/pki/general_names.cc +++ b/pki/general_names.cc
@@ -5,6 +5,7 @@ #include "general_names.h" #include <openssl/base.h> +#include <openssl/bytestring.h> #include <climits> #include <cstring> @@ -15,7 +16,6 @@ #include "ip_util.h" #include "parser.h" #include "string_util.h" -#include "tag.h" namespace bssl { @@ -52,7 +52,7 @@ // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName der::Parser parser(general_names_tlv); der::Input sequence_value; - if (!parser.ReadTag(der::kSequence, &sequence_value)) { + if (!parser.ReadTag(CBS_ASN1_SEQUENCE, &sequence_value)) { errors->AddError(kFailedReadingGeneralNames); return nullptr; } @@ -101,17 +101,17 @@ GeneralNames *subtrees, CertErrors *errors) { BSSL_CHECK(errors); der::Parser parser(input); - der::Tag tag; + CBS_ASN1_TAG tag; der::Input value; if (!parser.ReadTagAndValue(&tag, &value)) { return false; } GeneralNameTypes name_type = GENERAL_NAME_NONE; - if (tag == der::ContextSpecificConstructed(0)) { + if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { // otherName [0] OtherName, name_type = GENERAL_NAME_OTHER_NAME; subtrees->other_names.push_back(value); - } else if (tag == der::ContextSpecificPrimitive(1)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 1)) { // rfc822Name [1] IA5String, name_type = GENERAL_NAME_RFC822_NAME; const std::string_view s = BytesAsStringView(value); @@ -120,7 +120,7 @@ return false; } subtrees->rfc822_names.push_back(s); - } else if (tag == der::ContextSpecificPrimitive(2)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 2)) { // dNSName [2] IA5String, name_type = GENERAL_NAME_DNS_NAME; const std::string_view s = BytesAsStringView(value); @@ -129,11 +129,11 @@ return false; } subtrees->dns_names.push_back(s); - } else if (tag == der::ContextSpecificConstructed(3)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3)) { // x400Address [3] ORAddress, name_type = GENERAL_NAME_X400_ADDRESS; subtrees->x400_addresses.push_back(value); - } else if (tag == der::ContextSpecificConstructed(4)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 4)) { // directoryName [4] Name, name_type = GENERAL_NAME_DIRECTORY_NAME; // Name is a CHOICE { rdnSequence RDNSequence }, therefore the SEQUENCE @@ -141,15 +141,16 @@ // only the value portion. der::Parser name_parser(value); der::Input name_value; - if (!name_parser.ReadTag(der::kSequence, &name_value) || parser.HasMore()) { + if (!name_parser.ReadTag(CBS_ASN1_SEQUENCE, &name_value) || + parser.HasMore()) { return false; } subtrees->directory_names.push_back(name_value); - } else if (tag == der::ContextSpecificConstructed(5)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 5)) { // ediPartyName [5] EDIPartyName, name_type = GENERAL_NAME_EDI_PARTY_NAME; subtrees->edi_party_names.push_back(value); - } else if (tag == der::ContextSpecificPrimitive(6)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 6)) { // uniformResourceIdentifier [6] IA5String, name_type = GENERAL_NAME_UNIFORM_RESOURCE_IDENTIFIER; const std::string_view s = BytesAsStringView(value); @@ -158,7 +159,7 @@ return false; } subtrees->uniform_resource_identifiers.push_back(s); - } else if (tag == der::ContextSpecificPrimitive(7)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 7)) { // iPAddress [7] OCTET STRING, name_type = GENERAL_NAME_IP_ADDRESS; if (ip_address_type == GeneralNames::IP_ADDRESS_ONLY) { @@ -201,7 +202,7 @@ } subtrees->ip_address_ranges.emplace_back(addr, mask); } - } else if (tag == der::ContextSpecificPrimitive(8)) { + } else if (tag == (CBS_ASN1_CONTEXT_SPECIFIC | 8)) { // registeredID [8] OBJECT IDENTIFIER } name_type = GENERAL_NAME_REGISTERED_ID; subtrees->registered_ids.push_back(value);
diff --git a/pki/name_constraints.cc b/pki/name_constraints.cc index 73d87aa..1ce9a8f 100644 --- a/pki/name_constraints.cc +++ b/pki/name_constraints.cc
@@ -7,9 +7,11 @@ #include <limits.h> #include <memory> +#include <optional> #include <openssl/base.h> -#include <optional> +#include <openssl/bytestring.h> + #include "cert_errors.h" #include "common_cert_errors.h" #include "general_names.h" @@ -17,7 +19,6 @@ #include "ip_util.h" #include "parser.h" #include "string_util.h" -#include "tag.h" #include "verify_name_match.h" namespace bssl { @@ -317,8 +318,9 @@ } std::optional<der::Input> permitted_subtrees_value; - if (!sequence_parser.ReadOptionalTag(der::ContextSpecificConstructed(0), - &permitted_subtrees_value)) { + if (!sequence_parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, + &permitted_subtrees_value)) { return false; } if (permitted_subtrees_value && @@ -331,8 +333,9 @@ (is_critical ? GENERAL_NAME_ALL_TYPES : kSupportedNameTypes); std::optional<der::Input> excluded_subtrees_value; - if (!sequence_parser.ReadOptionalTag(der::ContextSpecificConstructed(1), - &excluded_subtrees_value)) { + if (!sequence_parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, + &excluded_subtrees_value)) { return false; } if (excluded_subtrees_value &&
diff --git a/pki/ocsp.cc b/pki/ocsp.cc index 49076e9..03d6c21 100644 --- a/pki/ocsp.cc +++ b/pki/ocsp.cc
@@ -51,16 +51,16 @@ if (!parser.ReadRawTLV(&sigalg_tlv)) { return false; } - if (!ParseHashAlgorithm(sigalg_tlv, &(out->hash_algorithm))) { + if (!ParseHashAlgorithm(sigalg_tlv, &out->hash_algorithm)) { return false; } - if (!parser.ReadTag(der::kOctetString, &(out->issuer_name_hash))) { + if (!parser.ReadTag(CBS_ASN1_OCTETSTRING, &out->issuer_name_hash)) { return false; } - if (!parser.ReadTag(der::kOctetString, &(out->issuer_key_hash))) { + if (!parser.ReadTag(CBS_ASN1_OCTETSTRING, &out->issuer_key_hash)) { return false; } - if (!parser.ReadTag(der::kInteger, &(out->serial_number))) { + if (!parser.ReadTag(CBS_ASN1_INTEGER, &out->serial_number)) { return false; } CertErrors errors; @@ -89,15 +89,16 @@ } der::Input reason_input; - if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), &reason_input, - &(out->has_reason))) { + if (!parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &reason_input, + &(out->has_reason))) { return false; } if (out->has_reason) { der::Parser reason_parser(reason_input); der::Input reason_value_input; uint8_t reason_value; - if (!reason_parser.ReadTag(der::kEnumerated, &reason_value_input)) { + if (!reason_parser.ReadTag(CBS_ASN1_ENUMERATED, &reason_value_input)) { return false; } if (!der::ParseUint8(reason_value_input, &reason_value)) { @@ -132,21 +133,22 @@ // UnknownInfo ::= NULL bool ParseCertStatus(der::Input raw_tlv, OCSPCertStatus *out) { der::Parser parser(raw_tlv); - der::Tag status_tag; + CBS_ASN1_TAG status_tag; der::Input status; if (!parser.ReadTagAndValue(&status_tag, &status)) { return false; } out->has_reason = false; - if (status_tag == der::ContextSpecificPrimitive(0)) { + if (status_tag == (CBS_ASN1_CONTEXT_SPECIFIC | 0)) { out->status = OCSPRevocationStatus::GOOD; - } else if (status_tag == der::ContextSpecificConstructed(1)) { + } else if (status_tag == + (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { out->status = OCSPRevocationStatus::REVOKED; if (!ParseRevokedInfo(status, out)) { return false; } - } else if (status_tag == der::ContextSpecificPrimitive(2)) { + } else if (status_tag == (CBS_ASN1_CONTEXT_SPECIFIC | 2)) { out->status = OCSPRevocationStatus::UNKNOWN; } else { return false; @@ -203,8 +205,9 @@ } der::Input next_update_input; - if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), - &next_update_input, &(out->has_next_update))) { + if (!parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, + &next_update_input, &(out->has_next_update))) { return false; } if (out->has_next_update) { @@ -217,8 +220,9 @@ } } - if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(1), - &(out->extensions), &(out->has_extensions))) { + if (!parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, + &(out->extensions), &(out->has_extensions))) { return false; } @@ -236,19 +240,19 @@ // } bool ParseResponderID(der::Input raw_tlv, OCSPResponseData::ResponderID *out) { der::Parser parser(raw_tlv); - der::Tag id_tag; + CBS_ASN1_TAG id_tag; der::Input id_input; if (!parser.ReadTagAndValue(&id_tag, &id_input)) { return false; } - if (id_tag == der::ContextSpecificConstructed(1)) { + if (id_tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { out->type = OCSPResponseData::ResponderType::NAME; out->name = id_input; - } else if (id_tag == der::ContextSpecificConstructed(2)) { + } else if (id_tag == (CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2)) { der::Parser key_parser(id_input); der::Input key_hash; - if (!key_parser.ReadTag(der::kOctetString, &key_hash)) { + if (!key_parser.ReadTag(CBS_ASN1_OCTETSTRING, &key_hash)) { return false; } if (key_parser.HasMore()) { @@ -287,8 +291,9 @@ der::Input version_input; bool version_present; - if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), - &version_input, &version_present)) { + if (!parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &version_input, + &version_present)) { return false; } @@ -335,8 +340,9 @@ out->responses.push_back(single_response); } - if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(1), - &(out->extensions), &(out->has_extensions))) { + if (!parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, + &(out->extensions), &(out->has_extensions))) { return false; } @@ -385,8 +391,9 @@ } out->signature = signature.value(); der::Input certs_input; - if (!parser.ReadOptionalTag(der::ContextSpecificConstructed(0), &certs_input, - &(out->has_certs))) { + if (!parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &certs_input, + &(out->has_certs))) { return false; } @@ -435,7 +442,7 @@ der::Input response_status_input; uint8_t response_status; - if (!parser.ReadTag(der::kEnumerated, &response_status_input)) { + if (!parser.ReadTag(CBS_ASN1_ENUMERATED, &response_status_input)) { return false; } if (!der::ParseUint8(response_status_input, &response_status)) { @@ -453,8 +460,9 @@ if (out->status == OCSPResponse::ResponseStatus::SUCCESSFUL) { der::Parser outer_bytes_parser; der::Parser bytes_parser; - if (!parser.ReadConstructed(der::ContextSpecificConstructed(0), - &outer_bytes_parser)) { + if (!parser.ReadConstructed( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, + &outer_bytes_parser)) { return false; } if (!outer_bytes_parser.ReadSequence(&bytes_parser)) { @@ -465,7 +473,7 @@ } der::Input type_oid; - if (!bytes_parser.ReadTag(der::kOid, &type_oid)) { + if (!bytes_parser.ReadTag(CBS_ASN1_OBJECT, &type_oid)) { return false; } if (type_oid != der::Input(kBasicOCSPResponseOid)) { @@ -475,7 +483,7 @@ // As per RFC 6960 Section 4.2.1, the value of |response| SHALL be the DER // encoding of BasicOCSPResponse. der::Input response; - if (!bytes_parser.ReadTag(der::kOctetString, &response)) { + if (!bytes_parser.ReadTag(CBS_ASN1_OCTETSTRING, &response)) { return false; } if (!ParseBasicOCSPResponse(response, out)) { @@ -607,9 +615,9 @@ case OCSPResponseData::ResponderType::NAME: { der::Input name_rdn; der::Input cert_rdn; - if (!der::Parser(id.name).ReadTag(der::kSequence, &name_rdn) || + if (!der::Parser(id.name).ReadTag(CBS_ASN1_SEQUENCE, &name_rdn) || !der::Parser(cert->tbs().subject_tlv) - .ReadTag(der::kSequence, &cert_rdn)) { + .ReadTag(CBS_ASN1_SEQUENCE, &cert_rdn)) { return false; } return VerifyNameMatch(name_rdn, cert_rdn);
diff --git a/pki/parse_certificate.cc b/pki/parse_certificate.cc index de910d3..5e2ff88 100644 --- a/pki/parse_certificate.cc +++ b/pki/parse_certificate.cc
@@ -8,6 +8,7 @@ #include <utility> #include <openssl/base.h> +#include <openssl/bytestring.h> #include "cert_error_params.h" #include "cert_errors.h" @@ -152,7 +153,7 @@ der::Parser parser(dp_name); std::optional<der::Input> der_full_name; if (!parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 0, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &der_full_name)) { return false; } @@ -168,7 +169,7 @@ } if (!parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 1, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, &distribution_point ->distribution_point_name_relative_to_crl_issuer)) { return false; @@ -201,7 +202,7 @@ // distributionPoint [0] DistributionPointName OPTIONAL, std::optional<der::Input> distribution_point_name; if (!distrib_point_parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 0, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &distribution_point_name)) { return false; } @@ -213,14 +214,14 @@ } // reasons [1] ReasonFlags OPTIONAL, - if (!distrib_point_parser.ReadOptionalTag(der::kTagContextSpecific | 1, + if (!distrib_point_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, &distribution_point.reasons)) { return false; } // cRLIssuer [2] GeneralNames OPTIONAL } if (!distrib_point_parser.ReadOptionalTag( - der::kTagContextSpecific | der::kTagConstructed | 2, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2, &distribution_point.crl_issuer)) { return false; } @@ -290,17 +291,17 @@ bool ReadUTCOrGeneralizedTime(der::Parser *parser, der::GeneralizedTime *out) { der::Input value; - der::Tag tag; + CBS_ASN1_TAG tag; if (!parser->ReadTagAndValue(&tag, &value)) { return false; } - if (tag == der::kUtcTime) { + if (tag == CBS_ASN1_UTCTIME) { return der::ParseUTCTime(value, out); } - if (tag == der::kGeneralizedTime) { + if (tag == CBS_ASN1_GENERALIZEDTIME) { return der::ParseGeneralizedTime(value, out); } @@ -443,8 +444,8 @@ // version [0] EXPLICIT Version DEFAULT v1, std::optional<der::Input> version; - if (!tbs_parser.ReadOptionalTag(der::ContextSpecificConstructed(0), - &version)) { + if (!tbs_parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &version)) { errors->AddError(kFailedReadingVersion); return false; } @@ -464,7 +465,7 @@ } // serialNumber CertificateSerialNumber, - if (!tbs_parser.ReadTag(der::kInteger, &out->serial_number)) { + if (!tbs_parser.ReadTag(CBS_ASN1_INTEGER, &out->serial_number)) { errors->AddError(kFailedReadingSerialNumber); return false; } @@ -516,7 +517,7 @@ // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, // -- If present, version MUST be v2 or v3 std::optional<der::Input> issuer_unique_id; - if (!tbs_parser.ReadOptionalTag(der::ContextSpecificPrimitive(1), + if (!tbs_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, &issuer_unique_id)) { errors->AddError(kFailedReadingIssuerUniqueId); return false; @@ -537,7 +538,7 @@ // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, // -- If present, version MUST be v2 or v3 std::optional<der::Input> subject_unique_id; - if (!tbs_parser.ReadOptionalTag(der::ContextSpecificPrimitive(2), + if (!tbs_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 2, &subject_unique_id)) { errors->AddError(kFailedReadingSubjectUniqueId); return false; @@ -557,8 +558,9 @@ // extensions [3] EXPLICIT Extensions OPTIONAL // -- If present, version MUST be v3 - if (!tbs_parser.ReadOptionalTag(der::ContextSpecificConstructed(3), - &out->extensions_tlv)) { + if (!tbs_parser.ReadOptionalTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3, + &out->extensions_tlv)) { errors->AddError(kFailedReadingExtensions); return false; } @@ -616,7 +618,7 @@ } // extnID OBJECT IDENTIFIER, - if (!extension_parser.ReadTag(der::kOid, &out->oid)) { + if (!extension_parser.ReadTag(CBS_ASN1_OBJECT, &out->oid)) { return false; } @@ -624,7 +626,8 @@ out->critical = false; bool has_critical; der::Input critical; - if (!extension_parser.ReadOptionalTag(der::kBool, &critical, &has_critical)) { + if (!extension_parser.ReadOptionalTag(CBS_ASN1_BOOLEAN, &critical, + &has_critical)) { return false; } if (has_critical) { @@ -637,7 +640,7 @@ } // extnValue OCTET STRING - if (!extension_parser.ReadTag(der::kOctetString, &out->value)) { + if (!extension_parser.ReadTag(CBS_ASN1_OCTETSTRING, &out->value)) { return false; } @@ -733,7 +736,7 @@ out->is_ca = false; bool has_ca; der::Input ca; - if (!sequence_parser.ReadOptionalTag(der::kBool, &ca, &has_ca)) { + if (!sequence_parser.ReadOptionalTag(CBS_ASN1_BOOLEAN, &ca, &has_ca)) { return false; } if (has_ca) { @@ -748,7 +751,7 @@ // pathLenConstraint INTEGER (0..MAX) OPTIONAL } der::Input encoded_path_len; - if (!sequence_parser.ReadOptionalTag(der::kInteger, &encoded_path_len, + if (!sequence_parser.ReadOptionalTag(CBS_ASN1_INTEGER, &encoded_path_len, &out->has_path_len)) { return false; } @@ -830,7 +833,7 @@ // accessMethod OBJECT IDENTIFIER, if (!access_description_sequence_parser.ReadTag( - der::kOid, &access_description.access_method_oid)) { + CBS_ASN1_OBJECT, &access_description.access_method_oid)) { return false; } @@ -862,7 +865,7 @@ for (const auto &access_description : access_descriptions) { der::Parser access_location_parser(access_description.access_location); - der::Tag access_location_tag; + CBS_ASN1_TAG access_location_tag; der::Input access_location_value; if (!access_location_parser.ReadTagAndValue(&access_location_tag, &access_location_value)) { @@ -870,7 +873,7 @@ } // GeneralName ::= CHOICE { - if (access_location_tag == der::ContextSpecificPrimitive(6)) { + if (access_location_tag == (CBS_ASN1_CONTEXT_SPECIFIC | 6)) { // uniformResourceIdentifier [6] IA5String, std::string_view uri = BytesAsStringView(access_location_value); if (!bssl::string_util::IsAscii(uri)) { @@ -956,21 +959,21 @@ // error? RFC 5280 doesn't explicitly say it. // keyIdentifier [0] KeyIdentifier OPTIONAL, - if (!aki_parser.ReadOptionalTag(der::ContextSpecificPrimitive(0), + if (!aki_parser.ReadOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 0, &authority_key_identifier->key_identifier)) { return false; } // authorityCertIssuer [1] GeneralNames OPTIONAL, if (!aki_parser.ReadOptionalTag( - der::ContextSpecificConstructed(1), + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, &authority_key_identifier->authority_cert_issuer)) { return false; } // authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } if (!aki_parser.ReadOptionalTag( - der::ContextSpecificPrimitive(2), + CBS_ASN1_CONTEXT_SPECIFIC | 2, &authority_key_identifier->authority_cert_serial_number)) { return false; } @@ -997,7 +1000,7 @@ // // KeyIdentifier ::= OCTET STRING der::Parser extension_value_parser(extension_value); - if (!extension_value_parser.ReadTag(der::kOctetString, + if (!extension_value_parser.ReadTag(CBS_ASN1_OCTETSTRING, subject_key_identifier)) { return false; }
diff --git a/pki/parse_name.cc b/pki/parse_name.cc index dca76b4..f1b3a91 100644 --- a/pki/parse_name.cc +++ b/pki/parse_name.cc
@@ -8,6 +8,7 @@ #include <openssl/bytestring.h> #include <openssl/mem.h> + #include "parse_values.h" #include "string_util.h" @@ -31,18 +32,18 @@ bool X509NameAttribute::ValueAsString(std::string *out) const { switch (value_tag) { - case der::kTeletexString: + case CBS_ASN1_T61STRING: return der::ParseTeletexStringAsLatin1(value, out); - case der::kIA5String: + case CBS_ASN1_IA5STRING: return der::ParseIA5String(value, out); - case der::kPrintableString: + case CBS_ASN1_PRINTABLESTRING: return der::ParsePrintableString(value, out); - case der::kUtf8String: + case CBS_ASN1_UTF8STRING: *out = BytesAsStringView(value); return true; - case der::kUniversalString: + case CBS_ASN1_UNIVERSALSTRING: return der::ParseUniversalString(value, out); - case der::kBmpString: + case CBS_ASN1_BMPSTRING: return der::ParseBmpString(value, out); default: return false; @@ -52,7 +53,7 @@ bool X509NameAttribute::ValueAsStringWithUnsafeOptions( PrintableStringHandling printable_string_handling, std::string *out) const { if (printable_string_handling == PrintableStringHandling::kAsUTF8Hack && - value_tag == der::kPrintableString) { + value_tag == CBS_ASN1_PRINTABLESTRING) { *out = BytesAsStringView(value); return true; } @@ -61,15 +62,15 @@ bool X509NameAttribute::ValueAsStringUnsafe(std::string *out) const { switch (value_tag) { - case der::kIA5String: - case der::kPrintableString: - case der::kTeletexString: - case der::kUtf8String: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_T61STRING: + case CBS_ASN1_UTF8STRING: *out = BytesAsStringView(value); return true; - case der::kUniversalString: + case CBS_ASN1_UNIVERSALSTRING: return der::ParseUniversalString(value, out); - case der::kBmpString: + case CBS_ASN1_BMPSTRING: return der::ParseBmpString(value, out); default: assert(0); // NOTREACHED @@ -137,7 +138,7 @@ // If we have non-printable characters in a TeletexString, we hex encode // since we don't handle Teletex control codes. - if (nonprintable && value_tag == der::kTeletexString) { + if (nonprintable && value_tag == CBS_ASN1_T61STRING) { value_string = "#" + bssl::string_util::HexEncode(value); } } @@ -154,12 +155,12 @@ } // Read the attribute type, which must be an OBJECT IDENTIFIER. der::Input type; - if (!attr_type_and_value.ReadTag(der::kOid, &type)) { + if (!attr_type_and_value.ReadTag(CBS_ASN1_OBJECT, &type)) { return false; } // Read the attribute value. - der::Tag tag; + CBS_ASN1_TAG tag; der::Input value; if (!attr_type_and_value.ReadTagAndValue(&tag, &value)) { return false; @@ -182,7 +183,7 @@ bool ParseName(der::Input name_tlv, RDNSequence *out) { der::Parser name_parser(name_tlv); der::Input name_value; - if (!name_parser.ReadTag(der::kSequence, &name_value)) { + if (!name_parser.ReadTag(CBS_ASN1_SEQUENCE, &name_value)) { return false; } return ParseNameValue(name_value, out); @@ -192,7 +193,7 @@ der::Parser rdn_sequence_parser(name_value); while (rdn_sequence_parser.HasMore()) { der::Parser rdn_parser; - if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser)) { + if (!rdn_sequence_parser.ReadConstructed(CBS_ASN1_SET, &rdn_parser)) { return false; } RelativeDistinguishedName type_and_values;
diff --git a/pki/parse_name.h b/pki/parse_name.h index 837f326..be5c53e 100644 --- a/pki/parse_name.h +++ b/pki/parse_name.h
@@ -8,10 +8,10 @@ #include <vector> #include <openssl/base.h> +#include <openssl/bytestring.h> #include "input.h" #include "parser.h" -#include "tag.h" namespace bssl { @@ -65,7 +65,7 @@ // value AttributeValue // } struct OPENSSL_EXPORT X509NameAttribute { - X509NameAttribute(der::Input in_type, der::Tag in_value_tag, + X509NameAttribute(der::Input in_type, CBS_ASN1_TAG in_value_tag, der::Input in_value) : type(in_type), value_tag(in_value_tag), value(in_value) {} @@ -106,7 +106,7 @@ [[nodiscard]] bool AsRFC2253String(std::string *out) const; der::Input type; - der::Tag value_tag; + CBS_ASN1_TAG value_tag; der::Input value; };
diff --git a/pki/parse_name_unittest.cc b/pki/parse_name_unittest.cc index 9858121..ceef9c2 100644 --- a/pki/parse_name_unittest.cc +++ b/pki/parse_name_unittest.cc
@@ -36,7 +36,7 @@ const uint8_t der[] = { 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kIA5String, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_IA5STRING, der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("Foo bar", result_unsafe); @@ -49,7 +49,7 @@ const uint8_t der[] = { 0x46, 0x6f, 0xFF, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kIA5String, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_IA5STRING, der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("Fo\377 bar", result_unsafe); @@ -61,7 +61,8 @@ const uint8_t der[] = { 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kPrintableString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_PRINTABLESTRING, + der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("Foo bar", result_unsafe); @@ -74,7 +75,8 @@ const uint8_t der[] = { 0x46, 0x6f, 0x5f, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kPrintableString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_PRINTABLESTRING, + der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("Fo_ bar", result_unsafe); @@ -86,7 +88,8 @@ const uint8_t der[] = { 0x46, 0x6f, 0x5f, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kPrintableString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_PRINTABLESTRING, + der::Input(der)); std::string result; ASSERT_FALSE(value.ValueAsStringWithUnsafeOptions( X509NameAttribute::PrintableStringHandling::kDefault, &result)); @@ -99,7 +102,7 @@ const uint8_t der[] = { 0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kTeletexString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_T61STRING, der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("Foo bar", result_unsafe); @@ -112,7 +115,7 @@ const uint8_t der[] = { 0x46, 0x6f, 0xd6, 0x20, 0x62, 0x61, 0x72, }; - X509NameAttribute value(der::Input(), der::kTeletexString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_T61STRING, der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("Fo\xd6 bar", result_unsafe); @@ -125,7 +128,7 @@ const uint8_t der[] = { 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x62, 0x00, 0x61, 0x00, 0x72, }; - X509NameAttribute value(der::Input(), der::kBmpString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_BMPSTRING, der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("foobar", result_unsafe); @@ -137,7 +140,7 @@ // BmpString must encode characters in pairs of 2 bytes. TEST(ParseNameTest, ConvertInvalidBmpString) { const uint8_t der[] = {0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x72}; - X509NameAttribute value(der::Input(), der::kBmpString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_BMPSTRING, der::Input(der)); std::string result; ASSERT_FALSE(value.ValueAsStringUnsafe(&result)); ASSERT_FALSE(value.ValueAsString(&result)); @@ -147,7 +150,8 @@ const uint8_t der[] = {0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x72}; - X509NameAttribute value(der::Input(), der::kUniversalString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_UNIVERSALSTRING, + der::Input(der)); std::string result_unsafe; ASSERT_TRUE(value.ValueAsStringUnsafe(&result_unsafe)); ASSERT_EQ("foobar", result_unsafe); @@ -159,7 +163,8 @@ // UniversalString must encode characters in pairs of 4 bytes. TEST(ParseNameTest, ConvertInvalidUniversalString) { const uint8_t der[] = {0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72}; - X509NameAttribute value(der::Input(), der::kUniversalString, der::Input(der)); + X509NameAttribute value(der::Input(), CBS_ASN1_UNIVERSALSTRING, + der::Input(der)); std::string result; ASSERT_FALSE(value.ValueAsStringUnsafe(&result)); ASSERT_FALSE(value.ValueAsString(&result));
diff --git a/pki/parsed_certificate.cc b/pki/parsed_certificate.cc index 3e9058d..9e23d30 100644 --- a/pki/parsed_certificate.cc +++ b/pki/parsed_certificate.cc
@@ -4,7 +4,9 @@ #include "parsed_certificate.h" +#include <openssl/bytestring.h> #include <openssl/pool.h> + #include "cert_errors.h" #include "certificate_policies.h" #include "extended_key_usage.h" @@ -51,7 +53,7 @@ [[nodiscard]] bool GetSequenceValue(der::Input tlv, der::Input *value) { der::Parser parser(tlv); - return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); + return parser.ReadTag(CBS_ASN1_SEQUENCE, value) && !parser.HasMore(); } } // namespace
diff --git a/pki/parser.cc b/pki/parser.cc index f352178..51f2661 100644 --- a/pki/parser.cc +++ b/pki/parser.cc
@@ -13,11 +13,11 @@ Parser::Parser(Input input) { CBS_init(&cbs_, input.data(), input.size()); } -bool Parser::PeekTagAndValue(Tag *tag, Input *out) { +bool Parser::PeekTagAndValue(CBS_ASN1_TAG *tag, Input *out) { CBS peeker = cbs_; CBS tmp_out; size_t header_len; - unsigned tag_value; + CBS_ASN1_TAG tag_value; if (!CBS_get_any_asn1_element(&peeker, &tmp_out, &tag_value, &header_len) || !CBS_skip(&tmp_out, header_len)) { return false; @@ -48,7 +48,7 @@ return true; } -bool Parser::ReadTagAndValue(Tag *tag, Input *out) { +bool Parser::ReadTagAndValue(CBS_ASN1_TAG *tag, Input *out) { if (!PeekTagAndValue(tag, out)) { return false; } @@ -56,12 +56,12 @@ return true; } -bool Parser::ReadOptionalTag(Tag tag, std::optional<Input> *out) { +bool Parser::ReadOptionalTag(CBS_ASN1_TAG tag, std::optional<Input> *out) { if (!HasMore()) { *out = std::nullopt; return true; } - Tag actual_tag; + CBS_ASN1_TAG actual_tag; Input value; if (!PeekTagAndValue(&actual_tag, &value)) { return false; @@ -76,7 +76,7 @@ return true; } -bool Parser::ReadOptionalTag(Tag tag, Input *out, bool *present) { +bool Parser::ReadOptionalTag(CBS_ASN1_TAG tag, Input *out, bool *present) { std::optional<Input> tmp_out; if (!ReadOptionalTag(tag, &tmp_out)) { return false; @@ -86,13 +86,13 @@ return true; } -bool Parser::SkipOptionalTag(Tag tag, bool *present) { +bool Parser::SkipOptionalTag(CBS_ASN1_TAG tag, bool *present) { Input out; return ReadOptionalTag(tag, &out, present); } -bool Parser::ReadTag(Tag tag, Input *out) { - Tag actual_tag; +bool Parser::ReadTag(CBS_ASN1_TAG tag, Input *out) { + CBS_ASN1_TAG actual_tag; Input value; if (!PeekTagAndValue(&actual_tag, &value) || actual_tag != tag) { return false; @@ -102,15 +102,15 @@ return true; } -bool Parser::SkipTag(Tag tag) { +bool Parser::SkipTag(CBS_ASN1_TAG tag) { Input out; return ReadTag(tag, &out); } // Type-specific variants of ReadTag -bool Parser::ReadConstructed(Tag tag, Parser *out) { - if (!IsConstructed(tag)) { +bool Parser::ReadConstructed(CBS_ASN1_TAG tag, Parser *out) { + if (!(tag & CBS_ASN1_CONSTRUCTED)) { return false; } Input data; @@ -122,12 +122,12 @@ } bool Parser::ReadSequence(Parser *out) { - return ReadConstructed(kSequence, out); + return ReadConstructed(CBS_ASN1_SEQUENCE, out); } bool Parser::ReadUint8(uint8_t *out) { Input encoded_int; - if (!ReadTag(kInteger, &encoded_int)) { + if (!ReadTag(CBS_ASN1_INTEGER, &encoded_int)) { return false; } return ParseUint8(encoded_int, out); @@ -135,7 +135,7 @@ bool Parser::ReadUint64(uint64_t *out) { Input encoded_int; - if (!ReadTag(kInteger, &encoded_int)) { + if (!ReadTag(CBS_ASN1_INTEGER, &encoded_int)) { return false; } return ParseUint64(encoded_int, out); @@ -143,7 +143,7 @@ std::optional<BitString> Parser::ReadBitString() { Input value; - if (!ReadTag(kBitString, &value)) { + if (!ReadTag(CBS_ASN1_BITSTRING, &value)) { return std::nullopt; } return ParseBitString(value); @@ -151,7 +151,7 @@ bool Parser::ReadGeneralizedTime(GeneralizedTime *out) { Input value; - if (!ReadTag(kGeneralizedTime, &value)) { + if (!ReadTag(CBS_ASN1_GENERALIZEDTIME, &value)) { return false; } return ParseGeneralizedTime(value, out);
diff --git a/pki/parser.h b/pki/parser.h index c585c60..64599b5 100644 --- a/pki/parser.h +++ b/pki/parser.h
@@ -13,7 +13,6 @@ #include <openssl/bytestring.h> #include "input.h" -#include "tag.h" namespace bssl::der { @@ -106,7 +105,7 @@ // encoding for the current value is invalid, this method returns false and // does not advance the input. Otherwise, it returns true, putting the // read tag in |tag| and the value in |out|. - [[nodiscard]] bool ReadTagAndValue(Tag *tag, Input *out); + [[nodiscard]] bool ReadTagAndValue(CBS_ASN1_TAG *tag, Input *out); // Reads the current TLV from the input and advances. Unlike ReadTagAndValue // where only the value is put in |out|, this puts the raw bytes from the @@ -123,7 +122,7 @@ // something else, then |out| is set to nullopt and the input is not // advanced. Like ReadTagAndValue, it returns false if the encoding is // invalid and does not advance the input. - [[nodiscard]] bool ReadOptionalTag(Tag tag, std::optional<Input> *out); + [[nodiscard]] bool ReadOptionalTag(CBS_ASN1_TAG tag, std::optional<Input> *out); // If the current tag in the input is |tag|, it puts the corresponding value // in |out|, sets |was_present| to true, and advances the input to the next @@ -132,25 +131,25 @@ // false if the encoding is invalid and does not advance the input. // DEPRECATED: use the std::optional version above in new code. // TODO(mattm): convert the existing callers and remove this override. - [[nodiscard]] bool ReadOptionalTag(Tag tag, Input *out, bool *was_present); + [[nodiscard]] bool ReadOptionalTag(CBS_ASN1_TAG tag, Input *out, bool *was_present); // Like ReadOptionalTag, but the value is discarded. - [[nodiscard]] bool SkipOptionalTag(Tag tag, bool *was_present); + [[nodiscard]] bool SkipOptionalTag(CBS_ASN1_TAG tag, bool *was_present); // If the current tag matches |tag|, it puts the current value in |out|, // advances the input, and returns true. Otherwise, it returns false. - [[nodiscard]] bool ReadTag(Tag tag, Input *out); + [[nodiscard]] bool ReadTag(CBS_ASN1_TAG tag, Input *out); // Advances the input and returns true if the current tag matches |tag|; // otherwise it returns false. - [[nodiscard]] bool SkipTag(Tag tag); + [[nodiscard]] bool SkipTag(CBS_ASN1_TAG tag); // Convenience methods to combine parsing the TLV with parsing the DER // encoding for a specific type. // Reads the current TLV from the input, checks that the tag matches |tag| // and is a constructed tag, and creates a new Parser from the value. - [[nodiscard]] bool ReadConstructed(Tag tag, Parser *out); + [[nodiscard]] bool ReadConstructed(CBS_ASN1_TAG tag, Parser *out); // A more specific form of ReadConstructed that expects the current tag // to be 0x30 (SEQUENCE). @@ -196,7 +195,7 @@ // Reads the current TLV from the input, putting the tag in |tag| and the raw // value in |out|, but does not advance the input. Returns true if the tag // and length are successfully read and the output exists. - [[nodiscard]] bool PeekTagAndValue(Tag *tag, Input *out); + [[nodiscard]] bool PeekTagAndValue(CBS_ASN1_TAG *tag, Input *out); // Advances the input to the next TLV. This method only needs to be called // after PeekTagAndValue; all other methods will advance the input if they
diff --git a/pki/parser_unittest.cc b/pki/parser_unittest.cc index e813bfd..2deb1cd 100644 --- a/pki/parser_unittest.cc +++ b/pki/parser_unittest.cc
@@ -13,10 +13,10 @@ TEST(ParserTest, ConsumesAllBytesOfTLV) { const uint8_t der[] = {0x04 /* OCTET STRING */, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - ASSERT_EQ(kOctetString, tag); + ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag); ASSERT_FALSE(parser.HasMore()); } @@ -38,7 +38,7 @@ // with an invalid encoding - its length is too long. const uint8_t der[] = {0x30, 0x02, 0x30, 0x7e}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); } @@ -58,7 +58,7 @@ ASSERT_FALSE(parser.HasMore()); // Try to read the INTEGER from the SEQUENCE, which should fail. - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_FALSE(inner_sequence.ReadTagAndValue(&tag, &value)); } @@ -72,14 +72,14 @@ Input value; bool present; - ASSERT_TRUE(parser.ReadOptionalTag(kInteger, &value, &present)); + ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present)); ASSERT_TRUE(present); const uint8_t expected_int_value[] = {0x01}; ASSERT_EQ(Input(expected_int_value), value); - Tag tag; + CBS_ASN1_TAG tag; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - ASSERT_EQ(kOctetString, tag); + ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag); const uint8_t expected_octet_string_value[] = {0x02}; ASSERT_EQ(Input(expected_octet_string_value), value); @@ -94,15 +94,15 @@ Parser parser((Input(der))); std::optional<Input> optional_value; - ASSERT_TRUE(parser.ReadOptionalTag(kInteger, &optional_value)); + ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &optional_value)); ASSERT_TRUE(optional_value.has_value()); const uint8_t expected_int_value[] = {0x01}; ASSERT_EQ(Input(expected_int_value), *optional_value); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - ASSERT_EQ(kOctetString, tag); + ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag); const uint8_t expected_octet_string_value[] = {0x02}; ASSERT_EQ(Input(expected_octet_string_value), value); @@ -117,12 +117,12 @@ Input value; bool present; - ASSERT_TRUE(parser.ReadOptionalTag(kInteger, &value, &present)); + ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present)); ASSERT_FALSE(present); - Tag tag; + CBS_ASN1_TAG tag; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - ASSERT_EQ(kOctetString, tag); + ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag); const uint8_t expected_octet_string_value[] = {0x02}; ASSERT_EQ(Input(expected_octet_string_value), value); @@ -136,13 +136,13 @@ Parser parser((Input(der))); std::optional<Input> optional_value; - ASSERT_TRUE(parser.ReadOptionalTag(kInteger, &optional_value)); + ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &optional_value)); ASSERT_FALSE(optional_value.has_value()); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - ASSERT_EQ(kOctetString, tag); + ASSERT_EQ(CBS_ASN1_OCTETSTRING, tag); const uint8_t expected_octet_string_value[] = {0x02}; ASSERT_EQ(Input(expected_octet_string_value), value); @@ -153,11 +153,11 @@ const uint8_t der[] = {0x02 /* INTEGER */, 0x01, 0x01}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); bool present; - ASSERT_TRUE(parser.ReadOptionalTag(kInteger, &value, &present)); + ASSERT_TRUE(parser.ReadOptionalTag(CBS_ASN1_INTEGER, &value, &present)); ASSERT_FALSE(present); ASSERT_FALSE(parser.HasMore()); } @@ -167,9 +167,9 @@ Parser parser((Input(der))); bool present; - ASSERT_TRUE(parser.SkipOptionalTag(kOctetString, &present)); + ASSERT_TRUE(parser.SkipOptionalTag(CBS_ASN1_OCTETSTRING, &present)); ASSERT_FALSE(present); - ASSERT_TRUE(parser.SkipOptionalTag(kInteger, &present)); + ASSERT_TRUE(parser.SkipOptionalTag(CBS_ASN1_INTEGER, &present)); ASSERT_TRUE(present); ASSERT_FALSE(parser.HasMore()); } @@ -179,10 +179,10 @@ const uint8_t der[] = {0x9f, 0x1f, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - EXPECT_EQ(kTagContextSpecific | 31u, tag); + EXPECT_EQ(CBS_ASN1_CONTEXT_SPECIFIC | 31u, tag); ASSERT_FALSE(parser.HasMore()); } @@ -192,10 +192,10 @@ const uint8_t der[] = {0x04, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - EXPECT_EQ(kOctetString, tag); + EXPECT_EQ(CBS_ASN1_OCTETSTRING, tag); } { @@ -203,10 +203,10 @@ const uint8_t der[] = {0x30, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - EXPECT_EQ(kSequence, tag); + EXPECT_EQ(CBS_ASN1_SEQUENCE, tag); } { @@ -214,10 +214,10 @@ const uint8_t der[] = {0x41, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - EXPECT_EQ(kTagApplication | 1, tag); + EXPECT_EQ(CBS_ASN1_APPLICATION | 1, tag); } { @@ -225,10 +225,10 @@ const uint8_t der[] = {0xbe, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - EXPECT_EQ(kTagContextSpecific | kTagConstructed | 30, tag); + EXPECT_EQ(CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 30, tag); } { @@ -236,10 +236,10 @@ const uint8_t der[] = {0xcf, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_TRUE(parser.ReadTagAndValue(&tag, &value)); - EXPECT_EQ(kTagPrivate | 15, tag); + EXPECT_EQ(CBS_ASN1_PRIVATE | 15, tag); } } @@ -247,7 +247,7 @@ const uint8_t der[] = {0x01}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value)); ASSERT_TRUE(parser.HasMore()); @@ -259,7 +259,7 @@ const uint8_t der[] = {0x04, 0x81}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value)); ASSERT_TRUE(parser.HasMore()); @@ -270,7 +270,7 @@ const uint8_t der[] = {0x04, 0x02, 0x84}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value)); ASSERT_TRUE(parser.HasMore()); @@ -280,7 +280,7 @@ const uint8_t der[] = {0x01, 0x81, 0x01, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value)); ASSERT_TRUE(parser.HasMore()); @@ -304,7 +304,7 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; Parser parser((Input(der))); - Tag tag; + CBS_ASN1_TAG tag; Input value; ASSERT_FALSE(parser.ReadTagAndValue(&tag, &value)); ASSERT_TRUE(parser.HasMore()); @@ -315,7 +315,7 @@ const uint8_t der[] = {0x10, 0x00}; Parser parser((Input(der))); - Tag expected_tag = 0x10; + CBS_ASN1_TAG expected_tag = 0x10; Parser sequence_parser; ASSERT_FALSE(parser.ReadConstructed(expected_tag, &sequence_parser));
diff --git a/pki/path_builder.cc b/pki/path_builder.cc index 4bb5d2f..a7fddd3 100644 --- a/pki/path_builder.cc +++ b/pki/path_builder.cc
@@ -11,6 +11,7 @@ #include <openssl/base.h> #include <openssl/sha.h> + #include "cert_issuer_source.h" #include "certificate_policies.h" #include "common_cert_errors.h" @@ -18,7 +19,6 @@ #include "parse_name.h" // For CertDebugString. #include "parser.h" #include "string_util.h" -#include "tag.h" #include "trust_store.h" #include "verify_certificate_chain.h" #include "verify_name_match.h"
diff --git a/pki/signature_algorithm.cc b/pki/signature_algorithm.cc index 8116862..73d8bc1 100644 --- a/pki/signature_algorithm.cc +++ b/pki/signature_algorithm.cc
@@ -6,6 +6,7 @@ #include <openssl/bytestring.h> #include <openssl/digest.h> + #include "input.h" #include "parse_values.h" #include "parser.h" @@ -126,7 +127,7 @@ [[nodiscard]] bool IsNull(der::Input input) { der::Parser parser(input); der::Input null_value; - if (!parser.ReadTag(der::kNull, &null_value)) { + if (!parser.ReadTag(CBS_ASN1_NULL, &null_value)) { return false; } @@ -237,12 +238,15 @@ DigestAlgorithm hash, mgf1_hash; der::Parser salt_length_parser; uint64_t salt_length; - if (!params_parser.ReadTag(der::ContextSpecificConstructed(0), &field) || + if (!params_parser.ReadTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0, &field) || !ParseHashAlgorithm(field, &hash) || - !params_parser.ReadTag(der::ContextSpecificConstructed(1), &field) || + !params_parser.ReadTag( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1, &field) || !ParseMaskGenAlgorithm(field, &mgf1_hash) || - !params_parser.ReadConstructed(der::ContextSpecificConstructed(2), - &salt_length_parser) || + !params_parser.ReadConstructed( + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2, + &salt_length_parser) || !salt_length_parser.ReadUint64(&salt_length) || salt_length_parser.HasMore() || params_parser.HasMore()) { return std::nullopt; @@ -285,7 +289,7 @@ return false; } - if (!algorithm_identifier_parser.ReadTag(der::kOid, algorithm)) { + if (!algorithm_identifier_parser.ReadTag(CBS_ASN1_OBJECT, algorithm)) { return false; }
diff --git a/pki/tag.cc b/pki/tag.cc deleted file mode 100644 index d2192ef..0000000 --- a/pki/tag.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "tag.h" - -#include <openssl/base.h> - -namespace bssl::der { - -Tag ContextSpecificConstructed(uint8_t tag_number) { - BSSL_CHECK(tag_number == (tag_number & kTagNumberMask)); - return (tag_number & kTagNumberMask) | kTagConstructed | kTagContextSpecific; -} - -Tag ContextSpecificPrimitive(uint8_t base) { - BSSL_CHECK(base == (base & kTagNumberMask)); - return (base & kTagNumberMask) | kTagPrimitive | kTagContextSpecific; -} - -bool IsConstructed(Tag tag) { - return (tag & kTagConstructionMask) == kTagConstructed; -} - -} // namespace bssl::der
diff --git a/pki/tag.h b/pki/tag.h deleted file mode 100644 index 683e527..0000000 --- a/pki/tag.h +++ /dev/null
@@ -1,77 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BSSL_DER_TAG_H_ -#define BSSL_DER_TAG_H_ - -#include <stdint.h> - -#include <openssl/base.h> -#include <openssl/bytestring.h> - -namespace bssl::der { - -// This Tag type represents the identifier for an ASN.1 tag as encoded with -// DER. It matches the BoringSSL CBS and CBB in-memory representation for a -// tag. -// -// Callers must not assume it matches the DER representation for small tag -// numbers. Instead, constants are provided for universal class types, and -// functions are provided for building context specific tags. Tags can also be -// built from the provided constants and bitmasks. -using Tag = unsigned; - -// Universal class primitive types -const Tag kBool = CBS_ASN1_BOOLEAN; -const Tag kInteger = CBS_ASN1_INTEGER; -const Tag kBitString = CBS_ASN1_BITSTRING; -const Tag kOctetString = CBS_ASN1_OCTETSTRING; -const Tag kNull = CBS_ASN1_NULL; -const Tag kOid = CBS_ASN1_OBJECT; -const Tag kEnumerated = CBS_ASN1_ENUMERATED; -const Tag kUtf8String = CBS_ASN1_UTF8STRING; -const Tag kPrintableString = CBS_ASN1_PRINTABLESTRING; -const Tag kTeletexString = CBS_ASN1_T61STRING; -const Tag kIA5String = CBS_ASN1_IA5STRING; -const Tag kUtcTime = CBS_ASN1_UTCTIME; -const Tag kGeneralizedTime = CBS_ASN1_GENERALIZEDTIME; -const Tag kVisibleString = CBS_ASN1_VISIBLESTRING; -const Tag kUniversalString = CBS_ASN1_UNIVERSALSTRING; -const Tag kBmpString = CBS_ASN1_BMPSTRING; - -// Universal class constructed types -const Tag kSequence = CBS_ASN1_SEQUENCE; -const Tag kSet = CBS_ASN1_SET; - -// Primitive/constructed bits -const unsigned kTagPrimitive = 0x00; -const unsigned kTagConstructed = CBS_ASN1_CONSTRUCTED; - -// Tag classes -const unsigned kTagUniversal = 0x00; -const unsigned kTagApplication = CBS_ASN1_APPLICATION; -const unsigned kTagContextSpecific = CBS_ASN1_CONTEXT_SPECIFIC; -const unsigned kTagPrivate = CBS_ASN1_PRIVATE; - -// Masks for the 3 components of a tag (class, primitive/constructed, number) -const unsigned kTagNumberMask = CBS_ASN1_TAG_NUMBER_MASK; -const unsigned kTagConstructionMask = CBS_ASN1_CONSTRUCTED; -const unsigned kTagClassMask = CBS_ASN1_CLASS_MASK; - -// Creates the value for the outer tag of an explicitly tagged type. -// -// The ASN.1 keyword for this is: -// [tag_number] EXPLICIT -// -// (Note, the EXPLICIT may be omitted if the entire schema is in -// EXPLICIT mode, the default) -OPENSSL_EXPORT Tag ContextSpecificConstructed(uint8_t tag_number); - -OPENSSL_EXPORT Tag ContextSpecificPrimitive(uint8_t base); - -OPENSSL_EXPORT bool IsConstructed(Tag tag); - -} // namespace bssl::der - -#endif // BSSL_DER_TAG_H_
diff --git a/pki/test_helpers.cc b/pki/test_helpers.cc index cc32622..b6712af 100644 --- a/pki/test_helpers.cc +++ b/pki/test_helpers.cc
@@ -147,7 +147,7 @@ der::Input SequenceValueFromString(std::string_view s) { der::Parser parser((der::Input(s))); der::Input data; - if (!parser.ReadTag(der::kSequence, &data)) { + if (!parser.ReadTag(CBS_ASN1_SEQUENCE, &data)) { ADD_FAILURE(); return der::Input(); }
diff --git a/pki/verify_name_match.cc b/pki/verify_name_match.cc index 73d3f9a..09f6102 100644 --- a/pki/verify_name_match.cc +++ b/pki/verify_name_match.cc
@@ -6,12 +6,12 @@ #include <openssl/base.h> #include <openssl/bytestring.h> + #include "cert_error_params.h" #include "cert_errors.h" #include "input.h" #include "parse_name.h" #include "parser.h" -#include "tag.h" namespace bssl { @@ -127,15 +127,15 @@ bool success = false; switch (attribute.value_tag) { - case der::kPrintableString: + case CBS_ASN1_PRINTABLESTRING: success = NormalizeDirectoryString(ENFORCE_PRINTABLE_STRING, output); break; - case der::kBmpString: - case der::kUniversalString: - case der::kUtf8String: + case CBS_ASN1_BMPSTRING: + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_UTF8STRING: success = NormalizeDirectoryString(NO_ENFORCEMENT, output); break; - case der::kIA5String: + case CBS_ASN1_IA5STRING: success = NormalizeDirectoryString(ENFORCE_ASCII, output); break; default: @@ -153,15 +153,15 @@ } // Returns true if |tag| is a string type that NormalizeValue can handle. -bool IsNormalizableDirectoryString(der::Tag tag) { +bool IsNormalizableDirectoryString(CBS_ASN1_TAG tag) { switch (tag) { - case der::kPrintableString: - case der::kUtf8String: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_UTF8STRING: // RFC 5280 only requires handling IA5String for comparing domainComponent // values, but handling it here avoids the need to special case anything. - case der::kIA5String: - case der::kUniversalString: - case der::kBmpString: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_BMPSTRING: return true; // TeletexString isn't normalized. Section 8 of RFC 5280 briefly // describes the historical confusion between treating TeletexString @@ -274,8 +274,8 @@ der::Parser a_rdn_sequence_counter(a); der::Parser b_rdn_sequence_counter(b); while (a_rdn_sequence_counter.HasMore() && b_rdn_sequence_counter.HasMore()) { - if (!a_rdn_sequence_counter.SkipTag(der::kSet) || - !b_rdn_sequence_counter.SkipTag(der::kSet)) { + if (!a_rdn_sequence_counter.SkipTag(CBS_ASN1_SET) || + !b_rdn_sequence_counter.SkipTag(CBS_ASN1_SET)) { return false; } } @@ -294,8 +294,8 @@ der::Parser b_rdn_sequence(b); while (a_rdn_sequence.HasMore() && b_rdn_sequence.HasMore()) { der::Parser a_rdn, b_rdn; - if (!a_rdn_sequence.ReadConstructed(der::kSet, &a_rdn) || - !b_rdn_sequence.ReadConstructed(der::kSet, &b_rdn)) { + if (!a_rdn_sequence.ReadConstructed(CBS_ASN1_SET, &a_rdn) || + !b_rdn_sequence.ReadConstructed(CBS_ASN1_SET, &b_rdn)) { return false; } if (!VerifyRdnMatch(&a_rdn, &b_rdn)) { @@ -324,7 +324,7 @@ while (rdn_sequence_parser.HasMore()) { // RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue der::Parser rdn_parser; - if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser)) { + if (!rdn_sequence_parser.ReadConstructed(CBS_ASN1_SET, &rdn_parser)) { return false; } RelativeDistinguishedName type_and_values; @@ -412,7 +412,7 @@ der::Parser rdn_sequence_parser(name_rdn_sequence); while (rdn_sequence_parser.HasMore()) { der::Parser rdn_parser; - if (!rdn_sequence_parser.ReadConstructed(der::kSet, &rdn_parser)) { + if (!rdn_sequence_parser.ReadConstructed(CBS_ASN1_SET, &rdn_parser)) { return false; }
diff --git a/rust/bssl-crypto/src/lib.rs b/rust/bssl-crypto/src/lib.rs index bb80ef4..5a6e58a 100644 --- a/rust/bssl-crypto/src/lib.rs +++ b/rust/bssl-crypto/src/lib.rs
@@ -101,9 +101,6 @@ /// See the comment [`FfiSlice`]. trait FfiMutSlice { fn as_mut_ffi_ptr(&mut self) -> *mut u8; - fn as_ffi_void_ptr(&mut self) -> *mut c_void { - self.as_mut_ffi_ptr() as *mut c_void - } } impl FfiMutSlice for [u8] { @@ -203,17 +200,6 @@ unsafe { &*(ptr as *mut _) } } - /// Constructs a mutable reference of this type from its raw type. - /// - /// # Safety - /// - /// `ptr` must be a valid, unique, instance of the type for the `'a` lifetime. - #[inline] - unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self { - debug_assert!(!ptr.is_null()); - unsafe { &mut *(ptr as *mut _) } - } - /// Returns a raw pointer to the wrapped value. #[inline] fn as_ptr(&self) -> *mut Self::CType { @@ -221,29 +207,6 @@ } } -/// A helper trait implemented by types which has an owned reference to foreign types. -/// -/// # Safety -/// -/// Implementations of `ForeignType` must guarantee the following: -/// -/// - `Self::from_ptr(x).as_ptr() == x` -unsafe trait ForeignType { - /// The raw C type. - type CType; - - /// Constructs an instance of this type from its raw type. - /// - /// # Safety - /// - /// - `ptr` must be a valid, immutable, instance of `CType`. - /// - Ownership of `ptr` is passed to the implementation, and will free `ptr` when dropped. - unsafe fn from_ptr(ptr: *mut Self::CType) -> Self; - - /// Returns a raw pointer to the wrapped value. - fn as_ptr(&self) -> *mut Self::CType; -} - /// Returns a BoringSSL structure that is initialized by some function. /// Requires that the given function completely initializes the value. ///
diff --git a/rust/bssl-sys/CMakeLists.txt b/rust/bssl-sys/CMakeLists.txt index d17a8f1..0ed1c95 100644 --- a/rust/bssl-sys/CMakeLists.txt +++ b/rust/bssl-sys/CMakeLists.txt
@@ -1,19 +1,15 @@ -# Additional interop for things like macros and inlined functions. -add_library(rust_wrapper STATIC rust_wrapper.c) -target_link_libraries(rust_wrapper crypto) - # Generate architecture-specific wrappers. bindgen must be called from # ${CMAKE_BINARY_DIR}, with the output path as a relative path. bindgen writes # the depfile using the same syntax as the command-line argument, and ninja # requires a path relative to the top-level build directory. -set(wrapper wrapper_${RUST_BINDINGS}.rs) -binary_dir_relative_path(${wrapper} wrapper_relative) -binary_dir_relative_path(${wrapper}.d depfile_relative) +set(wrapper_rs wrapper_${RUST_BINDINGS}.rs) +binary_dir_relative_path(${wrapper_rs} wrapper_rs_relative) +binary_dir_relative_path(${wrapper_rs}.d depfile_relative) add_custom_command( - OUTPUT ${wrapper} + OUTPUT ${wrapper_rs} wrapper.c COMMAND ${BINDGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wrapper.h - -o ${wrapper_relative} + -o ${wrapper_rs_relative} --depfile=${depfile_relative} --no-derive-default --enable-function-attribute-detection @@ -37,13 +33,23 @@ # https://github.com/rust-lang/rust-bindgen/issues/2508), we can # switch to that. --allowlist-file=".*[[:punct:]]include[[:punct:]]openssl[[:punct:]].*\\.h" - --allowlist-file=".*[[:punct:]]rust_wrapper\\.h" + --experimental + --wrap-static-fns + --wrap-static-fns-path="${CMAKE_CURRENT_BINARY_DIR}/wrapper.c" -- # these are LLVM arg passthroughs -I${PROJECT_SOURCE_DIR}/include # https://doc.rust-lang.org/nightly/rustc/platform-support.html --target=${RUST_BINDINGS} DEPENDS wrapper.h - DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${wrapper}.d + DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${wrapper_rs}.d WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) -add_custom_target(bssl_sys ALL DEPENDS ${wrapper}) + +add_library(rust_wrapper STATIC wrapper.c) +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_COMPILER_IS_GNUCXX) + target_compile_options(rust_wrapper PRIVATE "-Wno-missing-prototypes") +endif() +target_include_directories(rust_wrapper PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(rust_wrapper crypto ssl) + +add_custom_target(bssl_sys ALL DEPENDS ${wrapper_rs} rust_wrapper)
diff --git a/rust/bssl-sys/README.md b/rust/bssl-sys/README.md index c988813..13b7290 100644 --- a/rust/bssl-sys/README.md +++ b/rust/bssl-sys/README.md
@@ -1,7 +1,7 @@ bssl-sys ============ -A low-level binding crate for Rust that moves in lockstop with BoringSSL. BoringSSL explicitly does not have a stable ABI, `bssl-sys` is the solution for preventing subtle-memory corruption bugs due to version skew. +A low-level binding crate for Rust that moves in lockstop with BoringSSL. ### How it works `bssl-sys` uses `bindgen` as part of the cmake build process to generate Rust compatibility shims for the targeted platform. It is important to generate it for the correct platform because `bindgen` uses LLVM information for alignment which varies depending on architecture.
diff --git a/rust/bssl-sys/rust_wrapper.h b/rust/bssl-sys/rust_wrapper.h index 632622a..55d5a6f 100644 --- a/rust/bssl-sys/rust_wrapper.h +++ b/rust/bssl-sys/rust_wrapper.h
@@ -23,8 +23,10 @@ // The following functions are wrappers over inline functions and macros in -// BoringSSL, which bindgen cannot currently correctly bind. These wrappers -// ensure changes to the functions remain in lockstep with the Rust versions. +// BoringSSL. These are not necessary, as bindgen has long supported +// --wrap-static-fns, however Android is still missing support for this. (See +// b/290347127.) These manual wrappers are, temporarily, retained for Android, +// but this codepath is no longer tested or supported by BoringSSL. int ERR_GET_LIB_RUST(uint32_t packed_error); int ERR_GET_REASON_RUST(uint32_t packed_error); int ERR_GET_FUNC_RUST(uint32_t packed_error);
diff --git a/rust/bssl-sys/src/lib.rs b/rust/bssl-sys/src/lib.rs index 06b907c..9edbd08 100644 --- a/rust/bssl-sys/src/lib.rs +++ b/rust/bssl-sys/src/lib.rs
@@ -2,18 +2,56 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] -// Set in build.rs -include!(env!("BINDGEN_RS_FILE")); +use core::ffi::c_ulong; + +// Wrap the bindgen output in a module and re-export it, so we can override it +// as needed. +mod bindgen { + include!(env!("BINDGEN_RS_FILE")); +} +pub use bindgen::*; + +// bindgen does not handle C constants correctly. See +// https://github.com/rust-lang/rust-bindgen/issues/923. Work around this bug by +// redefining some constants with the correct type. Once the bindgen bug has +// been fixed, remove this. +pub const ASN1_STRFLGS_ESC_2253: c_ulong = bindgen::ASN1_STRFLGS_ESC_2253 as c_ulong; +pub const ASN1_STRFLGS_ESC_CTRL: c_ulong = bindgen::ASN1_STRFLGS_ESC_CTRL as c_ulong; +pub const ASN1_STRFLGS_ESC_MSB: c_ulong = bindgen::ASN1_STRFLGS_ESC_MSB as c_ulong; +pub const ASN1_STRFLGS_ESC_QUOTE: c_ulong = bindgen::ASN1_STRFLGS_ESC_QUOTE as c_ulong; +pub const ASN1_STRFLGS_UTF8_CONVERT: c_ulong = bindgen::ASN1_STRFLGS_UTF8_CONVERT as c_ulong; +pub const ASN1_STRFLGS_IGNORE_TYPE: c_ulong = bindgen::ASN1_STRFLGS_IGNORE_TYPE as c_ulong; +pub const ASN1_STRFLGS_SHOW_TYPE: c_ulong = bindgen::ASN1_STRFLGS_SHOW_TYPE as c_ulong; +pub const ASN1_STRFLGS_DUMP_ALL: c_ulong = bindgen::ASN1_STRFLGS_DUMP_ALL as c_ulong; +pub const ASN1_STRFLGS_DUMP_UNKNOWN: c_ulong = bindgen::ASN1_STRFLGS_DUMP_UNKNOWN as c_ulong; +pub const ASN1_STRFLGS_DUMP_DER: c_ulong = bindgen::ASN1_STRFLGS_DUMP_DER as c_ulong; +pub const ASN1_STRFLGS_RFC2253: c_ulong = bindgen::ASN1_STRFLGS_RFC2253 as c_ulong; +pub const XN_FLAG_COMPAT: c_ulong = bindgen::XN_FLAG_COMPAT as c_ulong; +pub const XN_FLAG_SEP_MASK: c_ulong = bindgen::XN_FLAG_SEP_MASK as c_ulong; +pub const XN_FLAG_SEP_COMMA_PLUS: c_ulong = bindgen::XN_FLAG_SEP_COMMA_PLUS as c_ulong; +pub const XN_FLAG_SEP_CPLUS_SPC: c_ulong = bindgen::XN_FLAG_SEP_CPLUS_SPC as c_ulong; +pub const XN_FLAG_SEP_SPLUS_SPC: c_ulong = bindgen::XN_FLAG_SEP_SPLUS_SPC as c_ulong; +pub const XN_FLAG_SEP_MULTILINE: c_ulong = bindgen::XN_FLAG_SEP_MULTILINE as c_ulong; +pub const XN_FLAG_DN_REV: c_ulong = bindgen::XN_FLAG_DN_REV as c_ulong; +pub const XN_FLAG_FN_MASK: c_ulong = bindgen::XN_FLAG_FN_MASK as c_ulong; +pub const XN_FLAG_FN_SN: c_ulong = bindgen::XN_FLAG_FN_SN as c_ulong; +pub const XN_FLAG_SPC_EQ: c_ulong = bindgen::XN_FLAG_SPC_EQ as c_ulong; +pub const XN_FLAG_DUMP_UNKNOWN_FIELDS: c_ulong = bindgen::XN_FLAG_DUMP_UNKNOWN_FIELDS as c_ulong; +pub const XN_FLAG_RFC2253: c_ulong = bindgen::XN_FLAG_RFC2253 as c_ulong; +pub const XN_FLAG_ONELINE: c_ulong = bindgen::XN_FLAG_ONELINE as c_ulong; // TODO(crbug.com/boringssl/596): Remove these wrappers. +#[cfg(unsupported_inline_wrappers)] pub fn ERR_GET_LIB(packed_error: u32) -> i32 { unsafe { ERR_GET_LIB_RUST(packed_error) } } +#[cfg(unsupported_inline_wrappers)] pub fn ERR_GET_REASON(packed_error: u32) -> i32 { unsafe { ERR_GET_REASON_RUST(packed_error) } } +#[cfg(unsupported_inline_wrappers)] pub fn ERR_GET_FUNC(packed_error: u32) -> i32 { unsafe { ERR_GET_FUNC_RUST(packed_error) } }
diff --git a/sources.cmake b/sources.cmake index febdb31..d32f24b 100644 --- a/sources.cmake +++ b/sources.cmake
@@ -382,7 +382,6 @@ pki/signature_algorithm.cc pki/simple_path_builder_delegate.cc pki/string_util.cc - pki/tag.cc pki/trust_store_collection.cc pki/trust_store_in_memory.cc pki/trust_store.cc @@ -2276,4 +2275,6 @@ pki/testdata/verify_signed_data_unittest/rsa-pss-sha256.pem pki/testdata/verify_signed_data_unittest/rsa-using-ec-key.pem pki/testdata/verify_signed_data_unittest/rsa2048-pkcs1-sha512.pem + pki/testdata/verify_unittest/google-leaf.der + pki/testdata/verify_unittest/self-issued.pem )
diff --git a/ssl/internal.h b/ssl/internal.h index c9facb6..d9972dc 100644 --- a/ssl/internal.h +++ b/ssl/internal.h
@@ -227,22 +227,10 @@ return UniquePtr<T>(New<T>(std::forward<Args>(args)...)); } -#if defined(BORINGSSL_ALLOW_CXX_RUNTIME) +// TODO(davidben): Remove these macros after April 2024, once the C++ runtime +// dependency has stuck. #define HAS_VIRTUAL_DESTRUCTOR #define PURE_VIRTUAL = 0 -#else -// HAS_VIRTUAL_DESTRUCTOR should be declared in any base class which defines a -// virtual destructor. This avoids a dependency on |_ZdlPv| and prevents the -// class from being used with |delete|. -#define HAS_VIRTUAL_DESTRUCTOR \ - void operator delete(void *) { abort(); } - -// PURE_VIRTUAL should be used instead of = 0 when defining pure-virtual -// functions. This avoids a dependency on |__cxa_pure_virtual| but loses -// compile-time checking. -#define PURE_VIRTUAL \ - { abort(); } -#endif // Array<T> is an owning array of elements of |T|. template <typename T>
diff --git a/util/check_imported_libraries.go b/util/check_imported_libraries.go index f3803f1..c7aa69f 100644 --- a/util/check_imported_libraries.go +++ b/util/check_imported_libraries.go
@@ -23,36 +23,49 @@ "debug/elf" "fmt" "os" + "path/filepath" ) -func checkImportedLibraries(path string) { +func checkImportedLibraries(path string) bool { file, err := elf.Open(path) if err != nil { fmt.Fprintf(os.Stderr, "Error opening %s: %s\n", path, err) - os.Exit(1) + return false } defer file.Close() libs, err := file.ImportedLibraries() if err != nil { fmt.Fprintf(os.Stderr, "Error reading %s: %s\n", path, err) - os.Exit(1) + return false } + allowCpp := filepath.Base(path) == "libssl.so" for _, lib := range libs { - if lib != "libc.so.6" && lib != "libcrypto.so" && lib != "libpthread.so.0" { - fmt.Printf("Invalid dependency for %s: %s\n", path, lib) - fmt.Printf("All dependencies:\n") - for _, lib := range libs { - fmt.Printf(" %s\n", lib) - } - os.Exit(1) + if lib == "libc.so.6" || lib == "libcrypto.so" || lib == "libpthread.so.0" || lib == "libgcc_s.so.1" { + continue } + if allowCpp && lib == "libstdc++.so.6" { + continue + } + fmt.Printf("Invalid dependency for %s: %s\n", path, lib) + fmt.Printf("All dependencies:\n") + for _, lib := range libs { + fmt.Printf(" %s\n", lib) + } + return false } + return true } func main() { + ok := true for _, path := range os.Args[1:] { - checkImportedLibraries(path) + if !checkImportedLibraries(path) { + ok = false + } + } + if !ok { + os.Exit(1) } }
diff --git a/util/doc.config b/util/doc.config index d2bc500..e36a960 100644 --- a/util/doc.config +++ b/util/doc.config
@@ -57,7 +57,8 @@ "Name": "Legacy ASN.1 and X.509 implementation (documentation in progress)", "Headers": [ "include/openssl/asn1.h", - "include/openssl/conf.h" + "include/openssl/conf.h", + "include/openssl/x509.h" ] },{ "Name": "SSL implementation",