update main-with-bazel from master branch

This commit is contained in:
BoringSSL Robot
2024-01-23 23:56:21 +00:00
6 changed files with 798 additions and 172 deletions
+5 -1
View File
@@ -342,7 +342,11 @@ if(WIN32)
target_link_libraries(crypto ws2_32)
endif()
if(NOT ANDROID)
# CMAKE_SYSTEM_NAME is "Generic" for embedded OSes:
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Cross%20Compiling%20With%20CMake.html#toolchain-files
#
# For now we assume embedded OSes do not have threads.
if(NOT (ANDROID OR CMAKE_SYSTEM_NAME STREQUAL "Generic"))
find_package(Threads REQUIRED)
target_link_libraries(crypto Threads::Threads)
endif()
+9 -10
View File
@@ -432,6 +432,10 @@ static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
return 0;
}
if (ca) {
// TODO(davidben): Move the various |check_ca| calls out of the
// |check_purpose| callbacks. Those checks are purpose-independent. They are
// also redundant when called from |X509_verify_cert|, though
// not when |X509_check_purpose| is called directly.
return check_ca(x);
}
// We need to do digital signatures or key agreement
@@ -473,8 +477,7 @@ static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
int ca) {
int ret;
ret = check_purpose_ssl_server(xp, x, ca);
int ret = check_purpose_ssl_server(xp, x, ca);
if (!ret || ca) {
return ret;
}
@@ -507,8 +510,7 @@ static int purpose_smime(const X509 *x, int ca) {
static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
int ca) {
int ret;
ret = purpose_smime(x, ca);
int ret = purpose_smime(x, ca);
if (!ret || ca) {
return ret;
}
@@ -520,8 +522,7 @@ static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
int ca) {
int ret;
ret = purpose_smime(x, ca);
int ret = purpose_smime(x, ca);
if (!ret || ca) {
return ret;
}
@@ -555,8 +556,6 @@ static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) {
static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
int ca) {
int i_ext;
// If ca is true we must return if this is a valid CA certificate.
if (ca) {
return check_ca(x);
@@ -580,9 +579,9 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
}
// Extended Key Usage MUST be critical
i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1);
int i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
if (i_ext >= 0) {
const X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext);
const X509_EXTENSION *ext = X509_get_ext(x, i_ext);
if (!X509_EXTENSION_get_critical(ext)) {
return 0;
}
+406
View File
@@ -1725,6 +1725,46 @@ static bssl::UniquePtr<X509> MakeTestCert(const char *issuer,
return cert;
}
static bool AddExtendedKeyUsage(X509 *x509, const std::vector<int> &eku_nids) {
bssl::UniquePtr<STACK_OF(ASN1_OBJECT)> objs(sk_ASN1_OBJECT_new_null());
if (objs == nullptr) {
return false;
}
for (int nid : eku_nids) {
if (!sk_ASN1_OBJECT_push(objs.get(), OBJ_nid2obj(nid))) {
return false;
}
}
return X509_add1_ext_i2d(x509, NID_ext_key_usage, objs.get(), /*crit=*/1,
/*flags=*/0);
}
enum class KeyUsage : int {
kDigitalSignature = 0,
kNonRepudiation = 1,
kKeyEncipherment = 2,
kDataEncipherment = 3,
kKeyAgreement = 4,
kKeyCertSign = 5,
kCRLSign = 6,
kEncipherOnly = 7,
kDecipherOnly = 8,
};
static bool AddKeyUsage(X509 *x509, const std::vector<KeyUsage> usages) {
bssl::UniquePtr<ASN1_BIT_STRING> str(ASN1_BIT_STRING_new());
if (str == nullptr) {
return false;
}
for (KeyUsage usage : usages) {
if (!ASN1_BIT_STRING_set_bit(str.get(), static_cast<int>(usage), 1)) {
return false;
}
}
return X509_add1_ext_i2d(x509, NID_key_usage, str.get(), /*crit=*/1,
/*flags=*/0);
}
TEST(X509Test, NameConstraints) {
bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
ASSERT_TRUE(key);
@@ -2780,6 +2820,15 @@ TEST(X509Test, NoBasicConstraintsCertSign) {
// basicConstraints.
EXPECT_EQ(X509_V_ERR_INVALID_CA,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0));
// |X509_check_purpose| with |X509_PURPOSE_ANY| and purpose -1 do not check
// basicConstraints, but other purpose types do. (This is redundant with the
// actual basicConstraints check, but |X509_check_purpose| is public API.)
EXPECT_TRUE(X509_check_purpose(intermediate.get(), -1, /*ca=*/1));
EXPECT_TRUE(
X509_check_purpose(intermediate.get(), X509_PURPOSE_ANY, /*ca=*/1));
EXPECT_FALSE(X509_check_purpose(intermediate.get(), X509_PURPOSE_SSL_SERVER,
/*ca=*/1));
}
TEST(X509Test, NoBasicConstraintsNetscapeCA) {
@@ -7309,3 +7358,360 @@ TEST(X509Test, PublicKeyCache) {
key2.reset(X509_PUBKEY_get(pub));
EXPECT_FALSE(key2);
}
// Tests some unusual behavior in |X509_STORE_CTX_set_purpose| and
// |X509_STORE_CTX_set_trust|.
TEST(X509Test, ContextTrustAndPurpose) {
bssl::UniquePtr<X509_STORE> store(X509_STORE_new());
ASSERT_TRUE(store);
bssl::UniquePtr<X509> leaf(CertFromPEM(kLeafPEM));
ASSERT_TRUE(leaf);
bssl::UniquePtr<X509_STORE_CTX> ctx(X509_STORE_CTX_new());
ASSERT_TRUE(ctx);
ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr));
// Initially, neither parameter is set.
EXPECT_EQ(ctx->param->purpose, 0);
EXPECT_EQ(ctx->param->trust, 0);
// Invalid purpose and trust types fail.
EXPECT_FALSE(X509_STORE_CTX_set_purpose(ctx.get(), 999));
EXPECT_FALSE(X509_STORE_CTX_set_trust(ctx.get(), 999));
// It is not possible to set |X509_PURPOSE_ANY| with this API, because there
// is no corresponding trust.
EXPECT_FALSE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_ANY));
// Setting a purpose also sets the corresponding trust.
ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_SERVER));
EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_SERVER);
EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER);
// Once set, the functions silently do nothing.
ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_CLIENT));
ASSERT_TRUE(X509_STORE_CTX_set_trust(ctx.get(), X509_TRUST_SSL_CLIENT));
EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_SERVER);
EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER);
// Start over.
ctx.reset(X509_STORE_CTX_new());
ASSERT_TRUE(ctx);
ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr));
EXPECT_EQ(ctx->param->purpose, 0);
EXPECT_EQ(ctx->param->trust, 0);
// Setting trust leaves purpose unset.
ASSERT_TRUE(X509_STORE_CTX_set_trust(ctx.get(), X509_TRUST_SSL_SERVER));
EXPECT_EQ(ctx->param->purpose, 0);
EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER);
// If trust is set, but not purpose, |X509_STORE_CTX_set_purpose| only sets
// purpose.
ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_CLIENT));
EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_CLIENT);
EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER);
// Start over.
ctx.reset(X509_STORE_CTX_new());
ASSERT_TRUE(ctx);
ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr));
EXPECT_EQ(ctx->param->purpose, 0);
EXPECT_EQ(ctx->param->trust, 0);
// If purpose is set, but not trust, |X509_STORE_CTX_set_purpose| only sets
// trust.
ASSERT_TRUE(X509_VERIFY_PARAM_set_purpose(
X509_STORE_CTX_get0_param(ctx.get()), X509_PURPOSE_SSL_CLIENT));
EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_CLIENT);
EXPECT_EQ(ctx->param->trust, 0);
ASSERT_TRUE(X509_STORE_CTX_set_purpose(ctx.get(), X509_PURPOSE_SSL_SERVER));
EXPECT_EQ(ctx->param->purpose, X509_PURPOSE_SSL_CLIENT);
EXPECT_EQ(ctx->param->trust, X509_TRUST_SSL_SERVER);
}
TEST(X509Test, Purpose) {
bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
ASSERT_TRUE(key);
struct {
int purpose;
int eku_nid;
std::vector<KeyUsage> key_usages;
} kTests[] = {
{X509_PURPOSE_SSL_CLIENT,
NID_client_auth,
{KeyUsage::kDigitalSignature, KeyUsage::kKeyAgreement}},
{X509_PURPOSE_SSL_SERVER,
NID_server_auth,
{KeyUsage::kDigitalSignature, KeyUsage::kKeyAgreement,
KeyUsage::kKeyEncipherment}},
{X509_PURPOSE_NS_SSL_SERVER,
NID_server_auth,
{KeyUsage::kKeyEncipherment}},
{X509_PURPOSE_SMIME_SIGN,
NID_email_protect,
{KeyUsage::kDigitalSignature, KeyUsage::kNonRepudiation}},
{X509_PURPOSE_SMIME_ENCRYPT,
NID_email_protect,
{KeyUsage::kKeyEncipherment}},
{X509_PURPOSE_CRL_SIGN, NID_undef, {KeyUsage::kCRLSign}},
};
for (const auto &t : kTests) {
SCOPED_TRACE(t.purpose);
auto configure_callback = [&](X509_STORE_CTX *ctx) {
X509_STORE_CTX_set_purpose(ctx, t.purpose);
};
// An unconstrained cert chain is valid.
bssl::UniquePtr<X509> root =
MakeTestCert("Root", "Root", key.get(), /*is_ca=*/true);
ASSERT_TRUE(root);
ASSERT_TRUE(X509_sign(root.get(), key.get(), EVP_sha256()));
bssl::UniquePtr<X509> intermediate =
MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true);
ASSERT_TRUE(intermediate);
ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256()));
bssl::UniquePtr<X509> leaf =
MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()},
{}, 0, configure_callback));
// A leaf and intermediate with compatible constraints is valid.
intermediate =
MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true);
ASSERT_TRUE(intermediate);
ASSERT_TRUE(AddKeyUsage(intermediate.get(), {KeyUsage::kKeyCertSign}));
if (t.eku_nid != NID_undef) {
ASSERT_TRUE(AddExtendedKeyUsage(intermediate.get(), {t.eku_nid}));
}
ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256()));
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
if (t.eku_nid != NID_undef) {
ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {t.eku_nid}));
}
ASSERT_TRUE(AddKeyUsage(leaf.get(), t.key_usages));
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()},
{}, 0, configure_callback));
// Each key usage asserted individually is valid.
for (KeyUsage usage : t.key_usages) {
SCOPED_TRACE(static_cast<int>(usage));
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
if (t.eku_nid != NID_undef) {
ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {t.eku_nid}));
}
ASSERT_TRUE(AddKeyUsage(leaf.get(), {usage}));
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_OK,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0,
configure_callback));
}
// A leaf with the wrong EKU is invalid.
if (t.eku_nid != NID_undef) {
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {NID_rsaEncryption}));
ASSERT_TRUE(AddKeyUsage(leaf.get(), t.key_usages));
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0,
configure_callback));
}
// A leaf without any of the requested key usages is invalid.
std::vector<KeyUsage> usages;
for (int i = 0; i < 10; i++) {
auto k = static_cast<KeyUsage>(i);
if (std::find(t.key_usages.begin(), t.key_usages.end(), k) ==
t.key_usages.end()) {
usages.push_back(k);
}
}
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
if (t.eku_nid != NID_undef) {
ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {t.eku_nid}));
}
ASSERT_TRUE(AddKeyUsage(leaf.get(), usages));
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0,
configure_callback));
// Extra EKUs and key usages are fine.
usages.clear();
for (int i = 0; i < 10; i++) {
usages.push_back(static_cast<KeyUsage>(i));
}
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
if (t.eku_nid != NID_undef) {
ASSERT_TRUE(
AddExtendedKeyUsage(leaf.get(), {t.eku_nid, NID_rsaEncryption}));
}
ASSERT_TRUE(AddKeyUsage(leaf.get(), usages));
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_OK, Verify(leaf.get(), {root.get()}, {intermediate.get()},
{}, 0, configure_callback));
// anyExtendedKeyUsage is not allowed in place of a concrete EKU.
if (t.eku_nid != NID_undef) {
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
ASSERT_TRUE(AddExtendedKeyUsage(leaf.get(), {NID_anyExtendedKeyUsage}));
ASSERT_TRUE(AddKeyUsage(leaf.get(), t.key_usages));
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0,
configure_callback));
}
// Restore |leaf| to a valid option.
leaf = MakeTestCert("Intermediate", "Leaf", key.get(), /*is_ca=*/false);
ASSERT_TRUE(leaf);
ASSERT_TRUE(X509_sign(leaf.get(), key.get(), EVP_sha256()));
// The intermediate must have the keyCertSign bit. This bit is checked in
// multiple places. The first place that fails is in looking for candidate
// issuers.
intermediate =
MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true);
ASSERT_TRUE(intermediate);
ASSERT_TRUE(AddKeyUsage(intermediate.get(), {KeyUsage::kDigitalSignature}));
if (t.eku_nid != NID_undef) {
ASSERT_TRUE(AddExtendedKeyUsage(intermediate.get(), {t.eku_nid}));
}
ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0,
configure_callback));
// The intermediate must have the EKU asserted.
if (t.eku_nid != NID_undef) {
intermediate =
MakeTestCert("Root", "Intermediate", key.get(), /*is_ca=*/true);
ASSERT_TRUE(intermediate);
ASSERT_TRUE(AddKeyUsage(intermediate.get(), {KeyUsage::kKeyCertSign}));
ASSERT_TRUE(AddExtendedKeyUsage(intermediate.get(), {NID_rsaEncryption}));
ASSERT_TRUE(X509_sign(intermediate.get(), key.get(), EVP_sha256()));
EXPECT_EQ(X509_V_ERR_INVALID_PURPOSE,
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}, 0,
configure_callback));
}
}
}
TEST(X509Test, Trust) {
struct Certs {
bssl::UniquePtr<X509> normal;
bssl::UniquePtr<X509> trusted_server, distrusted_server;
bssl::UniquePtr<X509> trusted_any, distrusted_any;
};
auto certs_from_pem = [](const char *pem) -> Certs {
Certs certs;
certs.normal = CertFromPEM(pem);
certs.trusted_server = CertFromPEM(pem);
certs.distrusted_server = CertFromPEM(pem);
certs.trusted_any = CertFromPEM(pem);
certs.distrusted_any = CertFromPEM(pem);
if (certs.normal == nullptr || certs.trusted_server == nullptr ||
certs.distrusted_server == nullptr || certs.trusted_any == nullptr ||
certs.distrusted_any == nullptr ||
!X509_add1_trust_object(certs.trusted_server.get(),
OBJ_nid2obj(NID_server_auth)) ||
!X509_add1_reject_object(certs.distrusted_server.get(),
OBJ_nid2obj(NID_server_auth)) ||
!X509_add1_trust_object(certs.trusted_any.get(),
OBJ_nid2obj(NID_anyExtendedKeyUsage)) ||
!X509_add1_reject_object(certs.distrusted_any.get(),
OBJ_nid2obj(NID_anyExtendedKeyUsage))) {
return Certs{};
}
return certs;
};
Certs root = certs_from_pem(kRootCAPEM);
Certs intermediate = certs_from_pem(kIntermediatePEM);
Certs leaf = certs_from_pem(kLeafPEM);
ASSERT_TRUE(root.normal);
ASSERT_TRUE(intermediate.normal);
ASSERT_TRUE(leaf.normal);
// By default, trust is determined by a combination of self-signedness and
// NID_anyExtendedKeyUsage.
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.normal.get()},
{intermediate.normal.get()}, {}));
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.trusted_any.get()},
{intermediate.normal.get()}, {}));
EXPECT_EQ(X509_V_ERR_CERT_REJECTED,
Verify(leaf.normal.get(), {root.distrusted_any.get()},
{intermediate.normal.get()}, {}));
// Intermediate certificates are not self-signed, so must have an
// NID_anyExtendedKeyUsage trust setting.
EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
Verify(leaf.normal.get(), {intermediate.normal.get()}, {}, {}));
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(),
{intermediate.trusted_any.get()}, {}, {}));
EXPECT_EQ(
X509_V_ERR_CERT_REJECTED,
Verify(leaf.normal.get(), {intermediate.distrusted_any.get()}, {}, {}));
// If a certificate has trust settings, but only for a different OID, the
// self-signed rule still takes effect.
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.trusted_server.get()},
{intermediate.normal.get()}, {}));
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.distrusted_server.get()},
{intermediate.normal.get()}, {}));
EXPECT_EQ(
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
Verify(leaf.normal.get(), {intermediate.trusted_server.get()}, {}, {}));
// |X509_TRUST_SSL_SERVER| should instead look at self-signedness and
// |NID_server_auth|.
auto set_server_trust = [](X509_STORE_CTX *ctx) {
X509_STORE_CTX_set_trust(ctx, X509_TRUST_SSL_SERVER);
};
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.normal.get()},
{intermediate.normal.get()}, {}, /*flags=*/0,
set_server_trust));
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(), {root.trusted_server.get()},
{intermediate.normal.get()}, {}, /*flags=*/0,
set_server_trust));
EXPECT_EQ(
X509_V_ERR_CERT_REJECTED,
Verify(leaf.normal.get(), {root.distrusted_server.get()},
{intermediate.normal.get()}, {}, /*flags=*/0, set_server_trust));
EXPECT_EQ(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
Verify(leaf.normal.get(), {intermediate.normal.get()}, {}, {},
/*flags=*/0, set_server_trust));
EXPECT_EQ(X509_V_OK, Verify(leaf.normal.get(),
{intermediate.trusted_server.get()}, {}, {},
/*flags=*/0, set_server_trust));
EXPECT_EQ(X509_V_ERR_CERT_REJECTED,
Verify(leaf.normal.get(), {intermediate.distrusted_server.get()},
{}, {}, /*flags=*/0, set_server_trust));
// NID_anyExtendedKeyUsage is just an unrelated OID to X509_TRUST_SSL_SERVER.
// Unlike the default behavior, once a certificate has explicit trust settings
// for any OID, the self-signed check is disabled.
EXPECT_EQ(
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
Verify(leaf.normal.get(), {root.trusted_any.get()},
{intermediate.normal.get()}, {}, /*flags=*/0, set_server_trust));
}
+3 -5
View File
@@ -85,20 +85,18 @@ static const X509_TRUST trstandard[] = {
NULL}};
int X509_check_trust(X509 *x, int id, int flags) {
int idx;
if (id == -1) {
return 1;
return X509_TRUST_TRUSTED;
}
// We get this as a default value
if (id == 0) {
int rv;
rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
int rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
if (rv != X509_TRUST_UNTRUSTED) {
return rv;
}
return trust_compat(NULL, x, 0);
}
idx = X509_TRUST_get_by_id(id);
int idx = X509_TRUST_get_by_id(id);
if (idx == -1) {
return obj_trust(id, x, flags);
}
+29 -52
View File
@@ -1480,62 +1480,40 @@ void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) {
}
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) {
return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
// If |purpose| is zero, this function historically silently did nothing.
if (purpose == 0) {
return 1;
}
int idx = X509_PURPOSE_get_by_id(purpose);
if (idx == -1) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
int trust = X509_PURPOSE_get_trust(X509_PURPOSE_get0(idx));
if (!X509_STORE_CTX_set_trust(ctx, trust)) {
return 0;
}
if (ctx->param->purpose == 0) {
ctx->param->purpose = purpose;
}
return 1;
}
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) {
return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
}
// This function is used to set the X509_STORE_CTX purpose and trust values.
// This is intended to be used when another structure has its own trust and
// purpose values which (if set) will be inherited by the ctx. If they aren't
// set then we will usually have a default purpose in mind which should then
// be used to set the trust value. An example of this is SSL use: an SSL
// structure will have its own purpose and trust settings which the
// application can set: if they aren't set then we use the default of SSL
// client/server.
int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
int purpose, int trust) {
int idx;
// If purpose not set use default
if (!purpose) {
purpose = def_purpose;
}
// If we have a purpose then check it is valid
if (purpose) {
idx = X509_PURPOSE_get_by_id(purpose);
if (idx == -1) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
const X509_PURPOSE *ptmp = X509_PURPOSE_get0(idx);
if (ptmp->trust == X509_TRUST_DEFAULT) {
idx = X509_PURPOSE_get_by_id(def_purpose);
if (idx == -1) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
ptmp = X509_PURPOSE_get0(idx);
}
// If trust not set then get from purpose default
if (!trust) {
trust = ptmp->trust;
}
}
if (trust) {
idx = X509_TRUST_get_by_id(trust);
if (idx == -1) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
return 0;
}
// If |trust| is zero, this function historically silently did nothing.
if (trust == 0) {
return 1;
}
if (purpose && !ctx->param->purpose) {
ctx->param->purpose = purpose;
if (X509_TRUST_get_by_id(trust) == -1) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
return 0;
}
if (trust && !ctx->param->trust) {
if (ctx->param->trust == 0) {
ctx->param->trust = trust;
}
return 1;
@@ -1658,8 +1636,7 @@ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
}
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) {
const X509_VERIFY_PARAM *param;
param = X509_VERIFY_PARAM_lookup(name);
const X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_lookup(name);
if (!param) {
return 0;
}
+346 -104
View File
@@ -659,11 +659,15 @@ OPENSSL_EXPORT const uint8_t *X509_keyid_get0(const X509 *x509, int *out_len);
// 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.
//
// See |X509_VERIFY_PARAM_set_trust| for details on how this value is evaluated.
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.
//
// See |X509_VERIFY_PARAM_set_trust| for details on how this value is evaluated.
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
@@ -2185,6 +2189,323 @@ OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr,
int idx);
// Certificate stores.
//
// An |X509_STORE| contains trusted certificates, CRLs, and verification
// parameters that are shared between multiple certificate verifications.
//
// Certificates in an |X509_STORE| are referred to as "trusted certificates",
// but an individual certificate verification may not necessarily treat every
// trusted certificate as a trust anchor. See |X509_VERIFY_PARAM_set_trust| for
// details.
//
// WARNING: Although a trusted certificate which fails the
// |X509_VERIFY_PARAM_set_trust| check is functionally an untrusted
// intermediate certificate, callers should not rely on this to configure
// untrusted intermediates in an |X509_STORE|. The trust check is complex, so
// this risks inadvertently treating it as a trust anchor. Instead, configure
// untrusted intermediates with the |chain| parameter of |X509_STORE_CTX_init|.
//
// Certificates in |X509_STORE| may be specified in several ways:
// - Added by |X509_STORE_add_cert|.
// - Returned by an |X509_LOOKUP| added by |X509_STORE_add_lookup|.
//
// |X509_STORE|s are reference-counted and may be shared by certificate
// verifications running concurrently on multiple threads. However, an
// |X509_STORE|'s verification parameters may not be modified concurrently with
// certificate verification or other operations. Unless otherwise documented,
// functions which take const pointer may be used concurrently, while
// functions which take a non-const pointer may not. Callers that wish to modify
// verification parameters in a shared |X509_STORE| should instead modify
// |X509_STORE_CTX|s individually.
// X509_STORE_new returns a newly-allocated |X509_STORE|, or NULL on error.
OPENSSL_EXPORT X509_STORE *X509_STORE_new(void);
// X509_STORE_up_ref adds one to the reference count of |store| and returns one.
// Although |store| is not const, this function's use of |store| is thread-safe.
OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store);
// X509_STORE_free releases memory associated with |store|.
OPENSSL_EXPORT void X509_STORE_free(X509_STORE *store);
// X509_STORE_add_cert adds |x509| to |store| as a trusted certificate. It
// returns one on success and zero on error. This function internally increments
// |x509|'s reference count, so the caller retains ownership of |x509|.
//
// Certificates configured by this function are still subject to the checks
// described in |X509_VERIFY_PARAM_set_trust|.
//
// Although |store| is not const, this function's use of |store| is thread-safe.
// However, if this function is called concurrently with |X509_verify_cert|, it
// is a race condition whether |x509| is available for issuer lookups.
// Moreover, the result may differ for each issuer lookup performed by a single
// |X509_verify_cert| call.
OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *store, X509 *x509);
// X509_STORE_add_crl adds |crl| to |store|. It returns one on success and zero
// on error. This function internally increments |crl|'s reference count, so the
// caller retains ownership of |crl|. CRLs added in this way are candidates for
// CRL lookup when |X509_V_FLAG_CRL_CHECK| is set.
//
// Although |store| is not const, this function's use of |store| is thread-safe.
// However, if this function is called concurrently with |X509_verify_cert|, it
// is a race condition whether |crl| is available for CRL checks. Moreover, the
// result may differ for each CRL check performed by a single
// |X509_verify_cert| call.
//
// Note there are no supported APIs to remove CRLs from |store| once inserted.
// To vary the set of CRLs over time, callers should either create a new
// |X509_STORE| or configure CRLs on a per-verification basis with
// |X509_STORE_CTX_set0_crls|.
OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *store, X509_CRL *crl);
// X509_STORE_set_purpose configures the purpose check for |store|. See
// |X509_VERIFY_PARAM_set_purpose| for details.
OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose);
// X509_STORE_set_trust configures the trust check for |store|. See
// |X509_VERIFY_PARAM_set_trust| for details.
OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *store, int trust);
// TODO(crbug.com/boringssl/426): Move the other |X509_STORE| functions here.
// Certificate verification.
//
// An |X509_STORE_CTX| object represents a single certificate verification
// operation. To verify a certificate chain, callers construct an
// |X509_STORE_CTX|, initialize it with |X509_STORE_CTX_init|, configure extra
// parameters, and call |X509_verify_cert|.
// X509_STORE_CTX_new returns a newly-allocated, empty |X509_STORE_CTX|, or NULL
// on error.
OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void);
// X509_STORE_CTX_free releases memory associated with |ctx|.
OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
// X509_STORE_CTX_init initializes |ctx| to verify |x509|, using trusted
// certificates and parameters in |store|. It returns one on success and zero on
// error. |chain| is a list of untrusted intermediate certificates to use in
// verification.
//
// |ctx| stores pointers to |store|, |x509|, and |chain|. Each of these objects
// must outlive |ctx| and may not be mutated for the duration of the certificate
// verification.
OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
X509 *x509, STACK_OF(X509) *chain);
// X509_verify_cert performs certifice verification with |ctx|, which must have
// been initialized with |X509_STORE_CTX_init|. It returns one on success and
// zero on error. On success, |X509_STORE_CTX_get0_chain| or
// |X509_STORE_CTX_get1_chain| may be used to return the verified certificate
// chain. On error, |X509_STORE_CTX_get_error| may be used to return additional
// error information.
OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx);
// X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates
// in |sk|. |sk| must remain valid for the duration of |ctx|. Calling this
// function causes |ctx| to ignore any certificates configured in the
// |X509_STORE|. Certificates in |sk| are still subject to the check described
// in |X509_VERIFY_PARAM_set_trust|.
//
// WARNING: This function differs from most |set0| functions in that it does not
// take ownership of its input. The caller is required to ensure the lifetimes
// are consistent.
OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx,
STACK_OF(X509) *sk);
// X509_STORE_CTX_set_default looks up the set of parameters named |name| and
// applies those default verification parameters for |ctx|. As in
// |X509_VERIFY_PARAM_inherit|, only unset parameters are changed. This function
// returns one on success and zero on error.
//
// The supported values of |name| are:
// - "default" is an internal value which configures some late defaults. See the
// discussion in |X509_STORE_get0_param|.
// - "pkcs7" configures default trust and purpose checks for PKCS#7 signatures.
// - "smime_sign" configures trust and purpose checks for S/MIME signatures.
// - "ssl_client" configures trust and purpose checks for TLS clients.
// - "ssl_server" configures trust and purpose checks for TLS servers.
//
// TODO(crbug.com/boringssl/441): Make "default" a no-op.
OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx,
const char *name);
// X509_STORE_CTX_set_purpose simultaneously configures |ctx|'s purpose and
// trust checks, if unset. It returns one on success and zero if |purpose| is
// not a valid purpose value. |purpose| should be an |X509_PURPOSE_*| constant.
// If so, it configures |ctx| with a purpose check of |purpose| and a trust
// check of |purpose|'s corresponding trust value. If either the purpose or
// trust check had already been specified for |ctx|, that corresponding
// modification is silently dropped.
//
// See |X509_VERIFY_PARAM_set_purpose| and |X509_VERIFY_PARAM_set_trust| for
// details on the purpose and trust checks, respectively.
//
// If |purpose| is |X509_PURPOSE_ANY|, this function returns an error because it
// has no corresponding |X509_TRUST_*| value. It is not possible to set
// |X509_PURPOSE_ANY| with this function, only |X509_VERIFY_PARAM_set_purpose|.
//
// WARNING: Unlike similarly named functions in this header, this function
// silently does not behave the same as |X509_VERIFY_PARAM_set_purpose|. Callers
// may use |X509_VERIFY_PARAM_set_purpose| with |X509_STORE_CTX_get0_param| to
// avoid this difference.
OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
// X509_STORE_CTX_set_trust configures |ctx|'s trust check, if unset. It returns
// one on success and zero if |trust| is not a valid trust value. |trust| should
// be an |X509_TRUST_*| constant. If so, it configures |ctx| with a trust check
// of |trust|. If the trust check had already been specified for |ctx|, it
// silently does nothing.
//
// See |X509_VERIFY_PARAM_set_trust| for details on the purpose and trust check.
//
// WARNING: Unlike similarly named functions in this header, this function
// does not behave the same as |X509_VERIFY_PARAM_set_trust|. Callers may use
// |X509_VERIFY_PARAM_set_trust| with |X509_STORE_CTX_get0_param| to avoid this
// difference.
OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
// TODO(crbug.com/boringssl/426): Move the other |X509_STORE_CTX| functions
// here.
// Verification parameters.
//
// An |X509_VERIFY_PARAM| contains a set of parameters for certificate
// verification.
// X509_VERIFY_PARAM_new returns a newly-allocated |X509_VERIFY_PARAM|, or NULL
// on error.
OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
// X509_VERIFY_PARAM_free releases memory associated with |param|.
OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
// X509_PURPOSE_SSL_CLIENT validates TLS client certificates. It checks for the
// id-kp-clientAuth EKU and one of digitalSignature or keyAgreement key usages.
// The TLS library is expected to check for the key usage specific to the
// negotiated TLS parameters.
#define X509_PURPOSE_SSL_CLIENT 1
// X509_PURPOSE_SSL_SERVER validates TLS server certificates. It checks for the
// id-kp-clientAuth EKU and one of digitalSignature, keyAgreement, or
// keyEncipherment key usages. The TLS library is expected to check for the key
// usage specific to the negotiated TLS parameters.
#define X509_PURPOSE_SSL_SERVER 2
// X509_PURPOSE_NS_SSL_SERVER is a legacy mode. It behaves like
// |X509_PURPOSE_SSL_SERVER|, but only accepts the keyEncipherment key usage,
// used by SSL 2.0 and RSA key exchange. Do not use this.
#define X509_PURPOSE_NS_SSL_SERVER 3
// X509_PURPOSE_SMIME_SIGN validates S/MIME signing certificates. It checks for
// the id-kp-emailProtection EKU and one of digitalSignature or nonRepudiation
// key usages.
#define X509_PURPOSE_SMIME_SIGN 4
// X509_PURPOSE_SMIME_ENCRYPT validates S/MIME encryption certificates. It
// checks for the id-kp-emailProtection EKU and keyEncipherment key usage.
#define X509_PURPOSE_SMIME_ENCRYPT 5
// X509_PURPOSE_CRL_SIGN validates indirect CRL signers. It checks for the
// cRLSign key usage. BoringSSL does not support indirect CRLs and does not use
// this mode.
#define X509_PURPOSE_CRL_SIGN 6
// X509_PURPOSE_ANY performs no EKU or key usage checks. Such checks are the
// responsibility of the caller.
#define X509_PURPOSE_ANY 7
// X509_PURPOSE_OCSP_HELPER performs no EKU or key usage checks. It was
// historically used in OpenSSL's OCSP implementation, which left those checks
// to the OCSP implementation itself.
#define X509_PURPOSE_OCSP_HELPER 8
// X509_PURPOSE_TIMESTAMP_SIGN validates Time Stamping Authority (RFC 3161)
// certificates. It checks for the id-kp-timeStamping EKU and one of
// digitalSignature or nonRepudiation key usages. It additionally checks that
// the EKU extension is critical and that no other EKUs or key usages are
// asserted.
#define X509_PURPOSE_TIMESTAMP_SIGN 9
// X509_VERIFY_PARAM_set_purpose configures |param| to validate certificates for
// a specified purpose. It returns one on success and zero if |purpose| is not a
// valid purpose type. |purpose| should be one of the |X509_PURPOSE_*| values.
//
// This option controls checking the extended key usage (EKU) and key usage
// extensions. These extensions specify how a certificate's public key may be
// used and are important to avoid cross-protocol attacks, particularly in PKIs
// that may issue certificates for multiple protocols, or for protocols that use
// keys in multiple ways. If not configured, these security checks are the
// caller's responsibility.
//
// This library applies the EKU checks to all untrusted intermediates. Although
// not defined in RFC 5280, this matches widely-deployed practice. It also does
// not accept anyExtendedKeyUsage.
//
// Many purpose values have a corresponding trust value, which is not configured
// by this function. See |X509_VERIFY_PARAM_set_trust| for details. Callers
// that wish to configure both should either call both functions, or use
// |X509_STORE_CTX_set_purpose|.
//
// It is currently not possible to configure custom EKU OIDs or key usage bits.
// Contact the BoringSSL maintainers if your application needs to do so. OpenSSL
// had an |X509_PURPOSE_add| API, but it was not thread-safe and relied on
// global mutable state, so we removed it.
//
// TODO(davidben): This function additionally configures checking the legacy
// Netscape certificate type extension. Remove this.
OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param,
int purpose);
// X509_TRUST_COMPAT evaluates trust using only the self-signed fallback. Trust
// and distrust OIDs are ignored.
#define X509_TRUST_COMPAT 1
// X509_TRUST_SSL_CLIENT evaluates trust with the |NID_client_auth| OID, for
// validating TLS client certificates.
#define X509_TRUST_SSL_CLIENT 2
// X509_TRUST_SSL_SERVER evaluates trust with the |NID_server_auth| OID, for
// validating TLS server certificates.
#define X509_TRUST_SSL_SERVER 3
// X509_TRUST_EMAIL evaluates trust with the |NID_email_protect| OID, for
// validating S/MIME email certificates.
#define X509_TRUST_EMAIL 4
// X509_TRUST_OBJECT_SIGN evaluates trust with the |NID_code_sign| OID, for
// validating code signing certificates.
#define X509_TRUST_OBJECT_SIGN 5
// X509_TRUST_TSA evaluates trust with the |NID_time_stamp| OID, for validating
// Time Stamping Authority (RFC 3161) certificates.
#define X509_TRUST_TSA 8
// X509_VERIFY_PARAM_set_trust configures which certificates from |X509_STORE|
// are trust anchors. It returns one on success and zero if |trust| is not a
// valid trust value. |trust| should be one of the |X509_TRUST_*| constants.
// This function allows applications to vary trust anchors when the same set of
// trusted certificates is used in multiple contexts.
//
// Two properties determine whether a certificate is a trust anchor:
//
// - Whether it is trusted or distrusted for some OID, via auxiliary information
// configured by |X509_add1_trust_object| or |X509_add1_reject_object|.
//
// - Whether it is "self-signed". That is, whether |X509_get_extension_flags|
// includes |EXFLAG_SS|. The signature itself is not checked.
//
// When this function is called, |trust| determines the OID to check in the
// first case. If the certificate is not explicitly trusted or distrusted for
// any OID, it is trusted if self-signed instead.
//
// If unset, the default behavior is to check for the |NID_anyExtendedKeyUsage|
// OID. If the certificate is not explicitly trusted or distrusted for this OID,
// it is trusted if self-signed instead. Note this slightly differs from the
// above.
//
// 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
// state, so we removed it.
OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param,
int trust);
// TODO(crbug.com/boringssl/426): Move the other |X509_VERIFY_PARAM| functions
// here.
// SignedPublicKeyAndChallenge structures.
//
// The SignedPublicKeyAndChallenge (SPKAC) is a legacy structure to request
@@ -3109,6 +3430,31 @@ OPENSSL_EXPORT int X509_check_ip_asc(const X509 *x509, const char *ipasc,
OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **out_issuer,
X509_STORE_CTX *ctx, X509 *x509);
// X509_check_purpose performs checks if |x509|'s basic constraints, key usage,
// and extended key usage extensions for the specified purpose. |purpose| should
// be one of |X509_PURPOSE_*| constants. See |X509_VERIFY_PARAM_set_purpose| for
// details. It returns one if |x509|'s extensions are consistent with |purpose|
// and zero otherwise. If |ca| is non-zero, |x509| is checked as a CA
// certificate. Otherwise, it is checked as an end-entity certificate.
//
// If |purpose| is -1, this function performs no purpose checks, but it parses
// some extensions in |x509| and may return zero on syntax error. Historically,
// callers primarily used this function to trigger this parsing, but this is no
// longer necessary. Functions acting on |X509| will internally parse as needed.
OPENSSL_EXPORT int X509_check_purpose(X509 *x509, int purpose, int ca);
#define X509_TRUST_TRUSTED 1
#define X509_TRUST_REJECTED 2
#define X509_TRUST_UNTRUSTED 3
// X509_check_trust checks if |x509| is a valid trust anchor for trust type
// |id|. See |X509_VERIFY_PARAM_set_trust| for details. It returns
// |X509_TRUST_TRUSTED| if |x509| is a trust anchor, |X509_TRUST_REJECTED| if it
// was distrusted, and |X509_TRUST_UNTRUSTED| otherwise. |id| should be one of
// the |X509_TRUST_*| constants, or zero to indicate the default behavior.
// |flags| should be zero and is ignored.
OPENSSL_EXPORT int X509_check_trust(X509 *x509, int id, int flags);
// X.509 information.
//
@@ -3570,19 +3916,6 @@ DEFINE_STACK_OF(X509_TRUST)
#define X509_TRUST_DEFAULT (-1) // Only valid in purpose settings
#define X509_TRUST_COMPAT 1
#define X509_TRUST_SSL_CLIENT 2
#define X509_TRUST_SSL_SERVER 3
#define X509_TRUST_EMAIL 4
#define X509_TRUST_OBJECT_SIGN 5
#define X509_TRUST_TSA 8
// check_trust return codes
#define X509_TRUST_TRUSTED 1
#define X509_TRUST_REJECTED 2
#define X509_TRUST_UNTRUSTED 3
// X509_verify_cert_error_string returns |err| as a human-readable string, where
// |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns
// a default description.
@@ -3628,15 +3961,6 @@ OPENSSL_EXPORT uint32_t X509_NAME_hash_old(X509_NAME *name);
OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
// X509_verify_cert performs certifice verification with |ctx|, which must have
// been initialized with |X509_STORE_CTX_init|. It returns one on success and
// zero on error. On success, |X509_STORE_CTX_get0_chain| or
// |X509_STORE_CTX_get1_chain| may be used to return the verified certificate
// chain. On error, |X509_STORE_CTX_get_error| may be used to return additional
// error information.
OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx);
OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags);
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);
@@ -3845,15 +4169,6 @@ OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *obj);
// a certificate.
OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *obj);
// X509_STORE_new returns a newly-allocated |X509_STORE|, or NULL on error.
OPENSSL_EXPORT X509_STORE *X509_STORE_new(void);
// X509_STORE_up_ref adds one to the reference count of |store| and returns one.
OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store);
// X509_STORE_free releases memory associated with |store|.
OPENSSL_EXPORT void X509_STORE_free(X509_STORE *store);
OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st);
OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st,
X509_NAME *nm);
@@ -3868,9 +4183,6 @@ OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st,
// the |X509_STORE|. See discussion in |X509_STORE_get0_param|.
OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *store, unsigned long flags);
OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *store, int purpose);
OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *store, int trust);
// |X509_STORE_set1_param| copies verification parameters from |param| as in
// |X509_VERIFY_PARAM_set1|. It returns one on success and zero on error.
OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *store,
@@ -3896,35 +4208,6 @@ OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *store,
// |X509_V_FLAG_TRUSTED_FIRST| is mostly a workaround for poor path-building.
OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store);
// X509_STORE_CTX_new returns a newly-allocated, empty |X509_STORE_CTX|, or NULL
// on error.
OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void);
// X509_STORE_CTX_free releases memory associated with |ctx|.
OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
// X509_STORE_CTX_init initializes |ctx| to verify |x509|, using trusted
// certificates and parameters in |store|. It returns one on success and zero on
// error. |chain| is a list of untrusted intermediate certificates to use in
// verification.
//
// |ctx| stores pointers to |store|, |x509|, and |chain|. Each of these objects
// must outlive |ctx| and may not be mutated for the duration of the certificate
// verification.
OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
X509 *x509, STACK_OF(X509) *chain);
// X509_STORE_CTX_set0_trusted_stack configures |ctx| to trust the certificates
// in |sk|. |sk| must remain valid for the duration of |ctx|. Calling this
// function causes |ctx| to ignore any certificates configured in the
// |X509_STORE|.
//
// WARNING: This function differs from most |set0| functions in that it does not
// take ownership of its input. The caller is required to ensure the lifetimes
// are consistent.
OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx,
STACK_OF(X509) *sk);
// X509_STORE_CTX_get0_store returns the |X509_STORE| that |ctx| uses.
OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx);
@@ -3938,9 +4221,6 @@ OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v,
OPENSSL_EXPORT const X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
OPENSSL_EXPORT const X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, int type,
X509_NAME *name,
X509_OBJECT *ret);
@@ -4008,11 +4288,6 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(
const X509_STORE_CTX *ctx);
OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,
STACK_OF(X509_CRL) *sk);
OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx,
int def_purpose, int purpose,
int trust);
// X509_STORE_CTX_set_flags enables all values in |flags| in |ctx|'s
// verification flags. |flags| should be a combination of |X509_V_FLAG_*|
@@ -4052,22 +4327,6 @@ OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(
OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx,
X509_VERIFY_PARAM *param);
// X509_STORE_CTX_set_default looks up the set of parameters named |name| and
// applies those default verification parameters for |ctx|. As in
// |X509_VERIFY_PARAM_inherit|, only unset parameters are changed. This function
// returns one on success and zero on error.
OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx,
const char *name);
// X509_VERIFY_PARAM functions
// X509_VERIFY_PARAM_new returns a newly-allocated |X509_VERIFY_PARAM|, or NULL
// on error.
OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
// X509_VERIFY_PARAM_free releases memory associated with |param|.
OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
// X509_VERIFY_PARAM_inherit applies |from| as the default values for |to|. That
// is, for each parameter that is unset in |to|, it copies the value in |from|.
// This function returns one on success and zero on error.
@@ -4096,11 +4355,6 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags(
const X509_VERIFY_PARAM *param);
OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param,
int purpose);
OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param,
int trust);
// X509_VERIFY_PARAM_set_depth configures |param| to limit certificate chains to
// |depth| intermediate certificates. This count excludes both the target
// certificate and the trust anchor (root certificate).
@@ -4375,16 +4629,6 @@ typedef struct x509_purpose_st {
void *usr_data;
} X509_PURPOSE;
#define X509_PURPOSE_SSL_CLIENT 1
#define X509_PURPOSE_SSL_SERVER 2
#define X509_PURPOSE_NS_SSL_SERVER 3
#define X509_PURPOSE_SMIME_SIGN 4
#define X509_PURPOSE_SMIME_ENCRYPT 5
#define X509_PURPOSE_CRL_SIGN 6
#define X509_PURPOSE_ANY 7
#define X509_PURPOSE_OCSP_HELPER 8
#define X509_PURPOSE_TIMESTAMP_SIGN 9
DEFINE_STACK_OF(X509_PURPOSE)
DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS)
@@ -4586,8 +4830,6 @@ OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit,
OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid,
void *value, int crit, unsigned long flags);
OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca);
OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose);
OPENSSL_EXPORT int X509_PURPOSE_get_count(void);