Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ dump_context(const char *ca_path, const char *ck_path)
// expiration date, serial number, common name, and subject alternative names
const ASN1_TIME *not_after = X509_get_notAfter(cert);
const ASN1_INTEGER *serial = X509_get_serialNumber(cert);
X509_NAME *subject_name = X509_get_subject_name(cert);
auto *subject_name = X509_get_subject_name(cert);

// Subject name
BIO *subject_bio = BIO_new(BIO_s_mem());
Expand Down
11 changes: 9 additions & 2 deletions include/cripts/Certs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,17 @@ class CertBase
}
}

void _load_name(X509_NAME *(*getter)(const X509 *)) const;
// OpenSSL 4.0 returns a pointer to const from X509_get_subject_name() and
// X509_get_issuer_name(), and dropped the const from the X509 parameter of
// X509_get_notBefore()/X509_get_notAfter(). Deduce the function pointer types so
// these match on any OpenSSL version.
using NameGetter = decltype(&X509_get_subject_name);
using TimeGetter = decltype(&X509_get_notBefore);

void _load_name(NameGetter getter) const;
void _load_integer(ASN1_INTEGER *(*getter)(X509 *)) const;
void _load_long(long (*getter)(const X509 *)) const;
void _load_time(ASN1_TIME *(*getter)(const X509 *)) const;
void _load_time(TimeGetter getter) const;

CertBase *_owner = nullptr;
mutable std::unique_ptr<BIO, decltype(&BIO_free)> _bio{nullptr, BIO_free};
Expand Down
24 changes: 17 additions & 7 deletions plugins/certifier/certifier.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ template <> struct default_delete<SSL_CTX> {
} // namespace std

/// Name aliases for unique pts to openSSL objects
using scoped_X509 = std::unique_ptr<X509>;
using scoped_X509_REQ = std::unique_ptr<X509_REQ>;
using scoped_EVP_PKEY = std::unique_ptr<EVP_PKEY>;
using scoped_SSL_CTX = std::unique_ptr<SSL_CTX>;
using scoped_X509 = std::unique_ptr<X509>;
using scoped_X509_REQ = std::unique_ptr<X509_REQ>;
using scoped_EVP_PKEY = std::unique_ptr<EVP_PKEY>;
using scoped_SSL_CTX = std::unique_ptr<SSL_CTX>;
using scoped_X509_NAME = std::unique_ptr<X509_NAME, decltype(&X509_NAME_free)>;

class SslLRUList
{
Expand Down Expand Up @@ -400,13 +401,22 @@ mkcrt(const std::string &commonName, int serial)
X509_gmtime_adj(X509_get_notBefore(cert.get()), 0);
X509_gmtime_adj(X509_get_notAfter(cert.get()), static_cast<long>(3650) * 24 * 3600);

// Get handle to subject name
X509_NAME *n = X509_get_subject_name(cert.get());
// Get a mutable copy of the subject name. OpenSSL 4.0 returns a pointer to const
// from X509_get_subject_name(), so the name cannot be modified in place.
scoped_X509_NAME n{X509_NAME_dup(X509_get_subject_name(cert.get())), X509_NAME_free};
if (n == nullptr) {
TSError("[%s] %s: failed to duplicate certificate subject", PLUGIN_NAME, __func__);
return nullptr;
}
// Set common name field
if (X509_NAME_add_entry_by_txt(n, "CN", MBSTRING_ASC, (unsigned char *)commonName.c_str(), -1, -1, 0) != 1) {
if (X509_NAME_add_entry_by_txt(n.get(), "CN", MBSTRING_ASC, (unsigned char *)commonName.c_str(), -1, -1, 0) != 1) {
TSError("[%s] %s: failed to add certificate subject CN", PLUGIN_NAME, __func__);
return nullptr;
}
if (X509_set_subject_name(cert.get(), n.get()) != 1) {
TSError("[%s] %s: failed to set certificate subject", PLUGIN_NAME, __func__);
return nullptr;
}

// Set Traffic Server public key
if (X509_set_pubkey(cert.get(), ca_pkey_scoped.get()) == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ dump_context(const char *ca_path, const char *ck_path)
// expiration date, serial number, common name, and subject alternative names
const ASN1_TIME *not_after = X509_get_notAfter(cert);
const ASN1_INTEGER *serial = X509_get_serialNumber(cert);
X509_NAME *subject_name = X509_get_subject_name(cert);
const X509_NAME *subject_name = X509_get_subject_name(cert);

// Subject name
BIO *subject_bio = BIO_new(BIO_s_mem());
Expand Down
8 changes: 4 additions & 4 deletions plugins/experimental/sslheaders/expand.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ x509_expand_certificate(X509 *x509, BIO *bio)
static void
x509_expand_subject(X509 *x509, BIO *bio)
{
X509_NAME *name = X509_get_subject_name(x509);
const X509_NAME *name = X509_get_subject_name(x509);
X509_NAME_print_ex(bio, name, 0 /* indent */, XN_FLAG_ONELINE);
}

static void
x509_expand_issuer(X509 *x509, BIO *bio)
{
X509_NAME *name = X509_get_issuer_name(x509);
const X509_NAME *name = X509_get_issuer_name(x509);
X509_NAME_print_ex(bio, name, 0 /* indent */, XN_FLAG_ONELINE);
}

Expand All @@ -72,8 +72,8 @@ x509_expand_signature(X509 *x509, BIO *bio)
{
const ASN1_BIT_STRING *sig;
X509_get0_signature(&sig, nullptr, x509);
const char *ptr = reinterpret_cast<const char *>(sig->data);
const char *end = ptr + sig->length;
const char *ptr = reinterpret_cast<const char *>(ASN1_STRING_get0_data(sig));
const char *end = ptr + ASN1_STRING_length(sig);

// The canonical OpenSSL way to format the signature seems to be
// X509_signature_dump(). However that separates each byte with a ':', which is
Expand Down
8 changes: 7 additions & 1 deletion plugins/experimental/txn_box/plugin/src/ts_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1111,8 +1111,14 @@ ssl_nid(swoc::TextView const &name)

namespace
{
// OpenSSL 4.0 returns a pointer to const from X509_get_subject_name() and
// X509_get_issuer_name() while earlier versions do not, and
// X509_NAME_get_index_by_NID() only accepts a pointer to const as of 3.0. Deduce
// the parameter type from the accessor so this compiles against either.
using X509_NAME_ptr = decltype(X509_get_subject_name(nullptr));

TextView
ssl_value_for(X509_NAME *name, int nid)
ssl_value_for(X509_NAME_ptr name, int nid)
{
if (int loc = X509_NAME_get_index_by_NID(name, nid, -1); loc >= 0) {
if (auto entry = X509_NAME_get_entry(name, loc); entry != nullptr) {
Expand Down
11 changes: 7 additions & 4 deletions plugins/lua/ts_lua_client_cert_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

// Helper functions for certificate data extraction
static std::string
get_x509_name_string(X509_NAME *name)
get_x509_name_string(const X509_NAME *name)
{
if (!name) {
return "";
Expand Down Expand Up @@ -157,12 +157,15 @@ get_x509_signature_string(X509 *cert)
return "";
}

for (int i = 0; i < sig->length; i++) {
if (BIO_printf(bio, "%02x", sig->data[i]) <= 0) {
const int siglen = ASN1_STRING_length(sig);
const unsigned char *sigdata = ASN1_STRING_get0_data(sig);

for (int i = 0; i < siglen; i++) {
if (BIO_printf(bio, "%02x", sigdata[i]) <= 0) {
BIO_free(bio);
return "";
}
if (i < sig->length - 1) {
if (i < siglen - 1) {
if (BIO_printf(bio, ":") <= 0) {
BIO_free(bio);
return "";
Expand Down
8 changes: 4 additions & 4 deletions src/api/InkAPI.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8316,10 +8316,10 @@ TSSslServerCertUpdate(const char *cert_path, const char *key_path)
}

// Extract common name
int pos = X509_NAME_get_index_by_NID(X509_get_subject_name(cert.get()), NID_commonName, -1);
X509_NAME_ENTRY *common_name = X509_NAME_get_entry(X509_get_subject_name(cert.get()), pos);
ASN1_STRING *common_name_asn1 = X509_NAME_ENTRY_get_data(common_name);
char *common_name_str = reinterpret_cast<char *>(const_cast<unsigned char *>(ASN1_STRING_get0_data(common_name_asn1)));
int pos = X509_NAME_get_index_by_NID(X509_get_subject_name(cert.get()), NID_commonName, -1);
auto *common_name = X509_NAME_get_entry(X509_get_subject_name(cert.get()), pos);
auto *common_name_asn1 = X509_NAME_ENTRY_get_data(common_name);
char *common_name_str = reinterpret_cast<char *>(const_cast<unsigned char *>(ASN1_STRING_get0_data(common_name_asn1)));
if (ASN1_STRING_length(common_name_asn1) != static_cast<int>(strlen(common_name_str))) {
Comment thread
cmcfarlen marked this conversation as resolved.
// Embedded null char
return TS_ERROR;
Expand Down
12 changes: 6 additions & 6 deletions src/cripts/Certs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ CertBase::Signature::_load() const
if (!_ready && _owner->_x509) {
const ASN1_BIT_STRING *sig;
X509_get0_signature(&sig, nullptr, _owner->_x509);
const char *ptr = reinterpret_cast<const char *>(sig->data);
const char *end = ptr + sig->length;
const char *ptr = reinterpret_cast<const char *>(ASN1_STRING_get0_data(sig));
const char *end = ptr + ASN1_STRING_length(sig);

super_type::_load();
for (; ptr < end; ++ptr) {
Expand All @@ -78,7 +78,7 @@ CertBase::X509Value::_update_value() const
}

void
CertBase::X509Value::_load_name(X509_NAME *(*getter)(const X509 *)) const
CertBase::X509Value::_load_name(NameGetter getter) const
{
if (!_ready && _owner->_x509) {
auto *name = getter(_owner->_x509);
Expand Down Expand Up @@ -119,7 +119,7 @@ CertBase::X509Value::_load_long(long (*getter)(const X509 *)) const
}

void
CertBase::X509Value::_load_time(ASN1_TIME *(*getter)(const X509 *)) const
CertBase::X509Value::_load_time(TimeGetter getter) const
{
if (!_ready && _owner->_x509) {
auto *time = getter(_owner->_x509);
Expand Down Expand Up @@ -153,8 +153,8 @@ namespace
_write_ip_address(const ASN1_OCTET_STRING *ip, BIO *_bio)
{
char buffer[INET6_ADDRSTRLEN];
const unsigned char *raw = ip->data;
int len = ip->length;
const unsigned char *raw = ASN1_STRING_get0_data(ip);
int len = ASN1_STRING_length(ip);

if (inet_ntop(len == 4 ? AF_INET : AF_INET6, raw, buffer, sizeof(buffer))) {
BIO_printf(_bio, "%s", buffer);
Expand Down
8 changes: 4 additions & 4 deletions src/iocore/net/OCSPStapling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ TS_OCSP_cert_id_new(const EVP_MD *dgst, const X509_NAME *issuerName, const ASN1_
}

/* Calculate the issuerKey hash, excluding tag and length */
if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, nullptr)) {
if (!EVP_Digest(ASN1_STRING_get0_data(issuerKey), ASN1_STRING_length(issuerKey), md, &i, dgst, nullptr)) {
goto err;
}

Expand All @@ -514,9 +514,9 @@ TS_OCSP_cert_id_new(const EVP_MD *dgst, const X509_NAME *issuerName, const ASN1_
TS_OCSP_CERTID *
TS_OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, const X509 *issuer)
{
const X509_NAME *iname;
const ASN1_INTEGER *serial;
ASN1_BIT_STRING *ikey;
const X509_NAME *iname;
const ASN1_INTEGER *serial;
const ASN1_BIT_STRING *ikey;

if (!dgst) {
dgst = EVP_sha1();
Expand Down
2 changes: 1 addition & 1 deletion src/iocore/net/SSLNetVConnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ SSLNetVConnection::_unbindSSLObject()
}

static void
debug_certificate_name(const char *msg, X509_NAME *name)
debug_certificate_name(const char *msg, const X509_NAME *name)
{
BIO *bio;

Expand Down
14 changes: 8 additions & 6 deletions src/iocore/net/SSLUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ SSLMultiCertConfigLoader::check_server_cert_now(X509 *cert, const char *certname
} /* CheckServerCertNow() */

static char *
asn1_strdup(ASN1_STRING *s)
asn1_strdup(const ASN1_STRING *s)
{
// Make sure we have an 8-bit encoding.
ink_assert(ASN1_STRING_type(s) == V_ASN1_IA5STRING || ASN1_STRING_type(s) == V_ASN1_UTF8STRING ||
Expand Down Expand Up @@ -2212,10 +2212,12 @@ SSLMultiCertConfigLoader::load_certs_and_cross_reference_names(

std::set<std::string> name_set;
// Grub through the names in the certs
X509_NAME *subject = nullptr;

// Insert a key for the subject CN.
subject = X509_get_subject_name(cert);
// Let the constness of the X509_NAME pointer be deduced: OpenSSL 4.0 returns a
// pointer to const here while earlier versions do not, and
// X509_NAME_get_index_by_NID() below only accepts a pointer to const as of 3.0.
auto *subject = X509_get_subject_name(cert);
ats_scoped_str subj_name;
if (subject) {
int pos = -1;
Expand All @@ -2225,9 +2227,9 @@ SSLMultiCertConfigLoader::load_certs_and_cross_reference_names(
break;
}

X509_NAME_ENTRY *e = X509_NAME_get_entry(subject, pos);
ASN1_STRING *cn = X509_NAME_ENTRY_get_data(e);
subj_name = asn1_strdup(cn);
auto *e = X509_NAME_get_entry(subject, pos);
auto *cn = X509_NAME_ENTRY_get_data(e);
subj_name = asn1_strdup(cn);

Dbg(dbg_ctl_ssl_load, "subj '%s' in certificate %s %p", subj_name.get(), data.cert_names_list[i].c_str(), cert);
name_set.insert(subj_name.get());
Expand Down
10 changes: 8 additions & 2 deletions src/iocore/net/unit_tests/test_SSLDHParams.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,15 @@ make_cert_and_key(EVP_CIPHER const *cipher = nullptr, char *pass = nullptr)
X509_gmtime_adj(X509_getm_notAfter(x509), 60L * 60L * 24L * 365L);
REQUIRE(X509_set_pubkey(x509, pkey) == 1);

X509_NAME *name = X509_get_subject_name(x509);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char const *>("ats-test"), -1, -1, 0);
// OpenSSL 4.0 returns a pointer to const from X509_get_subject_name(), so the name
// has to be duplicated before it can be modified and stored back.
X509_NAME *name = X509_NAME_dup(X509_get_subject_name(x509));
REQUIRE(name != nullptr);
REQUIRE(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char const *>("ats-test"), -1, -1, 0) ==
1);
REQUIRE(X509_set_subject_name(x509, name) == 1);
REQUIRE(X509_set_issuer_name(x509, name) == 1);
X509_NAME_free(name);
REQUIRE(X509_sign(x509, pkey, EVP_sha256()) > 0);

BIO *cert_bio = BIO_new(BIO_s_mem());
Expand Down
17 changes: 9 additions & 8 deletions src/tscore/X509HostnameValidator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, const unsigned cha
{
bool retval = false;

if (!a->data || !a->length || cmp_type != a->type) {
if (!ASN1_STRING_get0_data(a) || !ASN1_STRING_length(a) || cmp_type != ASN1_STRING_type(a)) {
return false;
}
retval = equal(a->data, a->length, b, blen);
retval = equal(ASN1_STRING_get0_data(a), ASN1_STRING_length(a), b, blen);
if (retval && peername) {
*peername = ats_strndup((char *)a->data, a->length);
*peername = ats_strndup(reinterpret_cast<const char *>(ASN1_STRING_get0_data(a)), ASN1_STRING_length(a));
}
Comment thread
cmcfarlen marked this conversation as resolved.
return retval;
}
Expand All @@ -220,7 +220,6 @@ bool
validate_hostname(X509 *x, std::string_view hostname, bool is_ip, char **peername)
{
GENERAL_NAMES *gens = nullptr;
X509_NAME *name = nullptr;
int i;
int alt_type;
bool retval = false;
Expand Down Expand Up @@ -269,14 +268,16 @@ validate_hostname(X509 *x, std::string_view hostname, bool is_ip, char **peernam
}
}
// No SAN match -- check the subject
i = -1;
name = X509_get_subject_name(x);
i = -1;
// Let the constness of the X509_NAME pointer be deduced: OpenSSL 4.0 returns a
// pointer to const here while earlier versions do not, and
// X509_NAME_get_index_by_NID() below only accepts a pointer to const as of 3.0.
auto *name = X509_get_subject_name(x);

while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0) {
ASN1_STRING *str;
auto *str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
int astrlen;
unsigned char *astr;
str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
// Convert to UTF-8
astrlen = ASN1_STRING_to_UTF8(&astr, str);

Expand Down
15 changes: 8 additions & 7 deletions tests/tools/plugins/ssl_client_verify_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ check_names(X509 *cert)
{
bool retval = false;

// Check the common name
X509_NAME *subject = X509_get_subject_name(cert);
// Check the common name. Let the constness of the X509_NAME pointer be deduced:
// OpenSSL 4.0 returns a pointer to const here while earlier versions do not, and
// X509_NAME_get_index_by_NID() below only accepts a pointer to const as of 3.0.
auto *subject = X509_get_subject_name(cert);
if (subject) {
int pos = -1;
for (; !retval;) {
Expand All @@ -67,11 +69,10 @@ check_names(X509 *cert)
break;
}

X509_NAME_ENTRY *e = X509_NAME_get_entry(subject, pos);
ASN1_STRING *cn = X509_NAME_ENTRY_get_data(e);
char *subj_name = strndup(reinterpret_cast<const char *>(ASN1_STRING_get0_data(cn)), ASN1_STRING_length(cn));
retval = check_name(subj_name);
free(subj_name);
auto *e = X509_NAME_get_entry(subject, pos);
auto *cn = X509_NAME_ENTRY_get_data(e);
std::string subj_name{reinterpret_cast<const char *>(ASN1_STRING_get0_data(cn)), static_cast<size_t>(ASN1_STRING_length(cn))};
retval = check_name(subj_name);
}
}
if (!retval) {
Expand Down