Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 26 additions & 5 deletions crypto/x509/v3_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
static unsigned char *generic_asn1(const char *value, const X509V3_CTX *ctx,
size_t *ext_len);

static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext);

X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, const X509V3_CTX *ctx,
const char *name, const char *value) {
// If omitted, fill in an empty |X509V3_CTX|.
Expand Down Expand Up @@ -344,6 +346,16 @@ static unsigned char *generic_asn1(const char *value, const X509V3_CTX *ctx,
return ext_der;
}

static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext) {
int idx;
ASN1_OBJECT *obj;

obj = X509_EXTENSION_get_object(dext);
while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0) {
X509_EXTENSION_free(X509v3_delete_ext(sk, idx));
}
}

// This is the main function: add a bunch of extensions based on a config
// file section to an extension STACK.

Expand All @@ -357,8 +369,19 @@ int X509V3_EXT_add_nconf_sk(const CONF *conf, const X509V3_CTX *ctx,
for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
const CONF_VALUE *val = sk_CONF_VALUE_value(nval, i);
X509_EXTENSION *ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value);
int ok = ext != NULL && //
(sk == NULL || X509v3_add_ext(sk, ext, -1) != NULL);

int ok = 0;
if (ext) {
if (!sk) {
ok = 1;
} else {
if (ctx->flags == X509V3_CTX_REPLACE) {
delete_ext(*sk, ext);
}
ok = X509v3_add_ext(sk, ext, -1) != NULL;
}
}

X509_EXTENSION_free(ext);
if (!ok) {
return 0;
Expand Down Expand Up @@ -418,9 +441,7 @@ const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx,
return NCONF_get_section(ctx->db, section);
}

void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf) {
ctx->db = conf;
}
void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf) { ctx->db = conf; }

void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, const X509 *subj,
const X509_REQ *req, const X509_CRL *crl, int flags) {
Expand Down
58 changes: 32 additions & 26 deletions include/openssl/x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -2602,7 +2602,8 @@ OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *obj);
typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)(
X509_STORE_CTX *ctx, X509_NAME *nm);

OPENSSL_EXPORT X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx);
OPENSSL_EXPORT X509_STORE_CTX_lookup_crls_fn
X509_STORE_get_lookup_crls(X509_STORE *ctx);

OPENSSL_EXPORT void X509_STORE_set_lookup_crls(
X509_STORE *ctx, X509_STORE_CTX_lookup_crls_fn lookup_crls);
Expand Down Expand Up @@ -2797,7 +2798,8 @@ OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx);

// X509_STORE_CTX_get0_untrusted returns the stack of untrusted intermediates
// used by |ctx| for certificate verification.
OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx);
OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(
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
Expand Down Expand Up @@ -3123,19 +3125,21 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
const char *name,
size_t name_len);

// X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT enables always checking the subject name for host match
// even if subject alt names are present.
// X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT enables always checking the subject name
// for host match even if subject alt names are present.
#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1

// X509_CHECK_FLAG_NO_WILDCARDS disables wildcard matching for DNS names.
#define X509_CHECK_FLAG_NO_WILDCARDS 0x2

// X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS constrains host name patterns passed to |X509_check_host|
// starting with '.' to only match a single label / subdomain.
// X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS constrains host name patterns passed
// to |X509_check_host| starting with '.' to only match a single label /
// subdomain.
//
// For example, by default the host name '.example.com' would match a certificate DNS name like
// 'www.example.com' and 'www.foo.example.com'. Setting this flag would result in the same host name
// only matching 'www.example.com' but not 'www.foo.example.com'.
// For example, by default the host name '.example.com' would match a
// certificate DNS name like 'www.example.com' and 'www.foo.example.com'.
// Setting this flag would result in the same host name only matching
// 'www.example.com' but not 'www.foo.example.com'.
#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10

// X509_CHECK_FLAG_NEVER_CHECK_SUBJECT disables the subject fallback, normally
Expand Down Expand Up @@ -4687,6 +4691,7 @@ struct v3_ext_ctx {
};

#define X509V3_CTX_TEST 0x1
#define X509V3_CTX_REPLACE 0x2

// X509V3_set_ctx initializes |ctx| with the specified objects. Some string
// formats will reference fields in these objects. Each object may be NULL to
Expand Down Expand Up @@ -5006,7 +5011,8 @@ typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *);
OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb(
X509_STORE_CTX *ctx, int (*verify_cb)(int ok, X509_STORE_CTX *ctx));

OPENSSL_EXPORT X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx);
OPENSSL_EXPORT X509_STORE_CTX_verify_cb
X509_STORE_get_verify_cb(X509_STORE *ctx);

// X509_STORE_set_verify_cb acts like |X509_STORE_CTX_set_verify_cb| but sets
// the verify callback for any |X509_STORE_CTX| created from this |X509_STORE|
Expand Down Expand Up @@ -5081,17 +5087,17 @@ OPENSSL_EXPORT void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx,
#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;
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)
DEFINE_STACK_OF(X509_PURPOSE)

// X509_STORE_get0_objects returns a non-owning pointer of |store|'s internal
// object list. Although this function is not const, callers must not modify
Expand Down Expand Up @@ -5151,12 +5157,12 @@ 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 *);
char *name;
int arg1;
void *arg2;
int trust;
int flags;
int (*check_trust)(const X509_TRUST *, X509 *);
char *name;
int arg1;
void *arg2;
} /* X509_TRUST */;

DEFINE_STACK_OF(X509_TRUST)
Expand Down
3 changes: 2 additions & 1 deletion tool-openssl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ add_executable(
../tool/fd.cc
../tool/client.cc
../tool/transport_common.cc

crl.cc
dgst.cc
ec.cc
Expand Down Expand Up @@ -86,6 +86,7 @@ if(BUILD_TESTING)
../tool/client.cc
../tool/transport_common.cc

test_util.cc
crl.cc
crl_test.cc
dgst.cc
Expand Down
6 changes: 2 additions & 4 deletions tool-openssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct Tool {

bool IsNumeric(const std::string &str);

X509 *CreateAndSignX509Certificate();

X509_CRL *createTestCRL();
bool isStringUpperCaseEqual(const std::string &a, const std::string &b);

Expand All @@ -38,7 +38,7 @@ enum class Source : uint8_t {
kEnv, // Password from environment with env: prefix
kStdin, // Password from stdin
#ifndef _WIN32
kFd, // Password from file descriptor with fd: prefix (Unix only)
kFd, // Password from file descriptor with fd: prefix (Unix only)
#endif
};

Expand Down Expand Up @@ -82,8 +82,6 @@ BSSL_NAMESPACE_BEGIN
BORINGSSL_MAKE_DELETER(std::string, pass_util::SensitiveStringDeleter)
BSSL_NAMESPACE_END

bool LoadPrivateKeyAndSignCertificate(X509 *x509,
const std::string &signkey_path);
EVP_PKEY *CreateTestKey(int key_bits);

tool_func_t FindTool(const std::string &name);
Expand Down
59 changes: 32 additions & 27 deletions tool-openssl/rehash_test.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

#include "internal.h"
#include <gtest/gtest.h>
#include "../crypto/test/test_util.h"
#include "internal.h"
#include "test_util.h"
#include <gtest/gtest.h>

#if !defined(OPENSSL_WINDOWS)
#include <openssl/pem.h>
Expand All @@ -17,13 +17,14 @@ using ScopedCharBuffer = std::unique_ptr<char, FreeOpenSSLChar>;

// Test fixture class
class RehashTest : public ::testing::Test {
protected:
BUCKET** hash_table = get_table();
protected:
BUCKET **hash_table = get_table();

void makePathInDir(ScopedCharBuffer &full_path, const char *dir, const char *filename) {
void makePathInDir(ScopedCharBuffer &full_path, const char *dir,
const char *filename) {
size_t buffer_len = strlen(dir) + strlen(filename) + 2;
char *buffer = (char *)OPENSSL_zalloc(sizeof(char)*buffer_len);
if(buffer == nullptr) {
char *buffer = (char *)OPENSSL_zalloc(sizeof(char) * buffer_len);
if (buffer == nullptr) {
abort();
}
full_path.reset(buffer);
Expand All @@ -38,13 +39,14 @@ class RehashTest : public ::testing::Test {
makePathInDir(crl2_path, test_dir, "crl2.pem");

ScopedFILE in_file(fopen(cert1_path.get(), "wb"));
bssl::UniquePtr<X509> x509(CreateAndSignX509Certificate());
bssl::UniquePtr<X509> x509;
CreateAndSignX509Certificate(x509, nullptr);
ASSERT_TRUE(x509);
ASSERT_TRUE(in_file);
ASSERT_TRUE(PEM_write_X509(in_file.get(), x509.get()));

ScopedFILE in_file2(fopen(cert2_path.get(), "wb"));
x509.reset(CreateAndSignX509Certificate());
CreateAndSignX509Certificate(x509, nullptr);
ASSERT_TRUE(x509);
ASSERT_TRUE(in_file2);
ASSERT_TRUE(PEM_write_X509(in_file2.get(), x509.get()));
Expand All @@ -71,15 +73,15 @@ class RehashTest : public ::testing::Test {
}

// Helper function to create test entries
void CreateTestEntry(Type type, uint32_t hash, const char* filename,
uint8_t* digest) {
void CreateTestEntry(Type type, uint32_t hash, const char *filename,
uint8_t *digest) {
add_entry(type, hash, filename, digest);
}

// Helper to count entries in a bucket
size_t CountEntriesInBucket(BUCKET* bucket) {
size_t CountEntriesInBucket(BUCKET *bucket) {
size_t count = 0;
HASH_ENTRY* entry = bucket ? bucket->first_entry : nullptr;
HASH_ENTRY *entry = bucket ? bucket->first_entry : nullptr;
while (entry) {
count++;
entry = entry->next;
Expand Down Expand Up @@ -119,7 +121,7 @@ TEST_F(RehashTest, BucketCollision) {
CreateTestEntry(TYPE_CRL, hash2, "crl.pem", digest2);
CreateTestEntry(TYPE_CERT, hash3, "cert2.pem", digest3);

BUCKET* bucket = hash_table[idx1];
BUCKET *bucket = hash_table[idx1];
ASSERT_NE(bucket, nullptr);

// First bucket should be the most recently added
Expand Down Expand Up @@ -164,15 +166,15 @@ TEST_F(RehashTest, EntryCollision) {
CreateTestEntry(TYPE_CERT, 0x12345678, "cert4.pem", digest1);

uint32_t expected_idx = (TYPE_CERT + 0x12345678) % 257;
BUCKET* bucket = hash_table[expected_idx];
BUCKET *bucket = hash_table[expected_idx];

ASSERT_NE(bucket, nullptr);
EXPECT_EQ(bucket->num_entries, 3u);
EXPECT_EQ(CountEntriesInBucket(bucket), 3u);

// Verify entries are in correct order
HASH_ENTRY* entry = bucket->first_entry;
HASH_ENTRY* last = bucket->last_entry;
HASH_ENTRY *entry = bucket->first_entry;
HASH_ENTRY *last = bucket->last_entry;
EXPECT_STREQ(entry->filename, "cert1.pem");
entry = entry->next;
EXPECT_STREQ(entry->filename, "cert2.pem");
Expand Down Expand Up @@ -219,19 +221,20 @@ TEST_F(RehashTest, ValidDirectory) {

// Get hashes for certs and CRLs
ScopedFILE cert_file(fopen(cert1_path.get(), "rb"));
bssl::UniquePtr<X509> cert(PEM_read_X509(
cert_file.get(), nullptr, nullptr, nullptr));
bssl::UniquePtr<X509> cert(
PEM_read_X509(cert_file.get(), nullptr, nullptr, nullptr));
ASSERT_TRUE(cert);
uint32_t cert_hash = X509_subject_name_hash(cert.get());

ScopedFILE crl_file(fopen(crl1_path.get(), "rb"));
bssl::UniquePtr<X509_CRL> crl(PEM_read_X509_CRL(
crl_file.get(), nullptr, nullptr, nullptr));
bssl::UniquePtr<X509_CRL> crl(
PEM_read_X509_CRL(crl_file.get(), nullptr, nullptr, nullptr));
ASSERT_TRUE(crl);
uint32_t crl_hash = X509_NAME_hash(X509_CRL_get_issuer(crl.get()));

// Check that symlinks exist with correct format and targets
size_t link_path_len = strlen(test_dir) + 13; // 13 = slash + hex + decimal + char + int + nul
size_t link_path_len =
strlen(test_dir) + 13; // 13 = slash + hex + decimal + char + int + nul
ScopedCharBuffer link_path(
(char *)OPENSSL_zalloc(sizeof(char) * link_path_len));
char link_target[PATH_MAX];
Expand All @@ -246,7 +249,8 @@ TEST_F(RehashTest, ValidDirectory) {
ASSERT_EQ(0, lstat(link_path.get(), &st));
ASSERT_TRUE(S_ISLNK(st.st_mode));

ssize_t len = readlink(link_path.get(), link_target, sizeof(link_target) - 1);
ssize_t len =
readlink(link_path.get(), link_target, sizeof(link_target) - 1);
ASSERT_GT(len, 0);
link_target[len] = '\0';
ASSERT_TRUE(strstr(link_target, "cert") != nullptr);
Expand All @@ -260,10 +264,11 @@ TEST_F(RehashTest, ValidDirectory) {
ASSERT_EQ(0, lstat(link_path.get(), &st));
ASSERT_TRUE(S_ISLNK(st.st_mode));

ssize_t len = readlink(link_path.get(), link_target, sizeof(link_target) - 1);
ssize_t len =
readlink(link_path.get(), link_target, sizeof(link_target) - 1);
ASSERT_GT(len, 0);
link_target[len] = '\0';
ASSERT_TRUE(strstr(link_target, "crl") != nullptr);\
ASSERT_TRUE(strstr(link_target, "crl") != nullptr);
unlink(link_path.get());
}
}
Expand All @@ -284,13 +289,13 @@ TEST(TmpDir, CreateTmpDir) {
// Test we can create a file in the directory
char testfile[PATH_MAX];
snprintf(testfile, PATH_MAX, "%s\\test.txt", tempdir);
FILE* f = fopen(testfile, "w");
FILE *f = fopen(testfile, "w");
ASSERT_TRUE(f != nullptr);
fprintf(f, "test");
fclose(f);

// Cleanup
DeleteFileA(testfile); // Delete test file
DeleteFileA(testfile); // Delete test file
EXPECT_TRUE(RemoveDirectoryA(tempdir)); // Delete directory
}

Expand Down
Loading
Loading