CI: Update to test OpenSSL 4.0.0 explicitly.
CI: No longer disable deprecated-declaration warnings for OpenSSL 3.4 -Werror build.
* modules/ssl/ssl_engine_kernel.c (ssl_hook_UserCheck): Change name to
const X509_NAME *.
(ssl_callback_proxy_cert): Change ca_name, issuer, and ca_issuer to
const X509_NAME *.
* modules/ssl/ssl_engine_log.c (ssl_log_cert_error): Change cert
parameter to const X509 *. Use X509_get0_serialNumber,
X509_get0_notBefore, and X509_get0_notAfter instead of non-const
variants.
(ssl_log_xerror, ssl_log_cxerror, ssl_log_rxerror): Change cert
parameter to const X509 *.
* modules/ssl/ssl_engine_vars.c (ssl_var_lookup_ssl_cert_dn): Change
xsname parameter to const X509_NAME *.
(ssl_var_lookup_ssl_cert_dn_oneline): Change xsname parameter to
const X509_NAME *.
(ssl_var_lookup_ssl_cert): Change xsname to const X509_NAME *.
(ssl_var_lookup_ssl_cert_rfc4523_cea): Change issuer to const
X509_NAME *.
* modules/ssl/ssl_private.h (ssl_log_xerror, ssl_log_cxerror,
ssl_log_rxerror): Update declarations to use const X509 *.
* modules/ssl/ssl_util_ssl.c (modssl_X509_NAME_to_string): Change dn
parameter to const X509_NAME *.
(getIDs): Change subj to const X509_NAME *.
* modules/ssl/ssl_util_ssl.h (modssl_X509_NAME_to_string): Update
declaration to use const X509_NAME *.
* support/ab.c (ssl_print_cert_info): Change dn to const X509_NAME *.
mod_ssl: use ASN1_STRING accessor API in dump_extn_value:
* modules/ssl/ssl_engine_vars.c (dump_extn_value): Use
ASN1_STRING_get0_data() and ASN1_STRING_length() rather than
directly dereferencing the ASN1_OCTET_STRING structure, which is
opaque in OpenSSL 4.0.
* modules/ssl/ssl_private.h: Add compat macros for
ASN1_STRING_get0_data and ASN1_STRING_length for pre-1.1 API.
mod_ssl: constify ASN1_TIME pointers, use X509_get0_not{Before,After}:
* modules/ssl/ssl_engine_vars.c (ssl_var_lookup_ssl_cert_valid,
ssl_var_lookup_ssl_cert_remain): Constify ASN1_TIME * parameter.
(ssl_var_lookup_ssl_cert): Use X509_get0_notBefore() and
X509_get0_notAfter() which return const pointers.
(ssl_var_lookup_ssl_cert_remain): Use ASN1_TIME_check() directly
rather than INVALID_ASN1_TIME macro which dereferences the
ASN1_TIME structure.
(dump_extn_value): Constify ASN1_OCTET_STRING * parameter.
* modules/ssl/ssl_private.h: Add compat macros for
X509_get0_before and X509_get0_after for pre-1.1 API.
mod_ssl: constify X509_NAME_ENTRY and X509_EXTENSION pointers:
* modules/ssl/ssl_engine_vars.c (ssl_var_lookup_ssl_cert_dn,
extract_dn): Constify X509_NAME_ENTRY * variables, constify
X509_NAME * parameter of extract_dn, drop unnecessary casts
on X509_NAME_ENTRY_get_object() calls.
(ssl_ext_list): Use MODSSL_X509_EXT_CONST for X509_EXTENSION *
since X509_EXTENSION accessors are only constified in OpenSSL 4.
* modules/ssl/ssl_util_ssl.c, modules/ssl/ssl_util_ssl.h
(modssl_X509_NAME_ENTRY_to_string): Constify X509_NAME_ENTRY *
parameter.
* modules/ssl/ssl_private.h: Add MODSSL_X509_EXT_CONST, defined
as const for OpenSSL 4+ and empty otherwise.
* modules/ssl/ssl_util_ssl.c (asn1_string_convert): Constify
ASN1_STRING * argument.
* modules/ssl/ssl_engine_ocsp.c (extract_responder_uri): Use
modssl_ASN1_STRING_convert instead of directly accessing ASN1_STRING
data pointer.
* modules/ssl/ssl_util_ssl.c (modssl_ASN1_STRING_convert): Rename from
asn1_string_convert and export function.
(asn1_string_to_utf8): Update to use modssl_ASN1_STRING_convert.
(modssl_X509_NAME_ENTRY_to_string): Update to use
modssl_ASN1_STRING_convert.
* modules/ssl/ssl_util_ssl.h (modssl_ASN1_STRING_convert): Declare new
function.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Github: closes #609
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@
1933586 13f79535-47bb-0310-9956-
ffa450edef68
# -------------------------------------------------------------------------
- name: OpenSSL 3.4 -Werror
config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto
- notest-cflags: -Werror -O2 -Wno-deprecated-declarations
+ notest-cflags: -Werror -O2
env: |
TEST_OPENSSL3=3.4.4
APR_VERSION=1.7.6
APU_CONFIG="--without-crypto"
pkgs: subversion
# -------------------------------------------------------------------------
- - name: OpenSSL ECH branch
+ - name: OpenSSL 4.0
config: --enable-mods-shared=most --enable-maintainer-mode --disable-md --disable-http2 --disable-ldap --disable-crypto
notest-cflags: -Werror -O2
env: |
- TEST_OPENSSL3=ech2
- TEST_OPENSSL3_BRANCH=feature/ech
+ TEST_OPENSSL3=4.0.0
OPENSSL_CONFIG=no-engine
APR_VERSION=1.7.6
APU_VERSION=1.6.3
}
if (!sslconn->client_dn) {
- X509_NAME *name = X509_get_subject_name(sslconn->client_cert);
+ const X509_NAME *name = X509_get_subject_name(sslconn->client_cert);
char *cp = X509_NAME_oneline(name, NULL, 0);
sslconn->client_dn = apr_pstrdup(r->connection->pool, cp);
OPENSSL_free(cp);
server_rec *s = mySrvFromConn(c);
SSLSrvConfigRec *sc = mySrvConfig(s);
SSLDirConfigRec *dc = myDirConfigFromConn(c);
- X509_NAME *ca_name, *issuer, *ca_issuer;
+ const X509_NAME *ca_name, *issuer, *ca_issuer;
X509_INFO *info;
X509 *ca_cert;
STACK_OF(X509_NAME) *ca_list;
static void ssl_log_cert_error(const char *file, int line, int level,
apr_status_t rv, const server_rec *s,
const conn_rec *c, const request_rec *r,
- apr_pool_t *p, X509 *cert, const char *format,
+ apr_pool_t *p, const X509 *cert, const char *format,
va_list ap)
{
char buf[HUGE_STRING_LEN];
}
BIO_puts(bio, " / serial: ");
- if (i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)) == -1)
+ if (i2a_ASN1_INTEGER(bio, X509_get0_serialNumber(cert)) == -1)
BIO_puts(bio, "(ERROR)");
BIO_puts(bio, " / notbefore: ");
- ASN1_TIME_print(bio, X509_get_notBefore(cert));
+ ASN1_TIME_print(bio, X509_get0_notBefore(cert));
BIO_puts(bio, " / notafter: ");
- ASN1_TIME_print(bio, X509_get_notAfter(cert));
+ ASN1_TIME_print(bio, X509_get0_notAfter(cert));
BIO_puts(bio, "]");
* in the other cases we use the connection and request pool, respectively).
*/
void ssl_log_xerror(const char *file, int line, int level, apr_status_t rv,
- apr_pool_t *ptemp, server_rec *s, X509 *cert,
+ apr_pool_t *ptemp, server_rec *s, const X509 *cert,
const char *fmt, ...)
{
if (APLOG_IS_LEVEL(s,level)) {
}
void ssl_log_cxerror(const char *file, int line, int level, apr_status_t rv,
- conn_rec *c, X509 *cert, const char *fmt, ...)
+ conn_rec *c, const X509 *cert, const char *fmt, ...)
{
if (APLOG_IS_LEVEL(mySrvFromConn(c),level)) {
va_list ap;
}
void ssl_log_rxerror(const char *file, int line, int level, apr_status_t rv,
- request_rec *r, X509 *cert, const char *fmt, ...)
+ request_rec *r, const X509 *cert, const char *fmt, ...)
{
if (APLOG_R_IS_LEVEL(r,level)) {
va_list ap;
/* Name found in extension, and is a URI: */
if (OBJ_obj2nid(value->method) == NID_ad_OCSP
&& value->location->type == GEN_URI) {
- result = apr_pstrdup(pool,
- (char *)value->location->d.uniformResourceIdentifier->data);
+ const ASN1_STRING *uri = value->location->d.uniformResourceIdentifier;
+ result = modssl_ASN1_STRING_convert(pool, uri, 0);
}
}
static const char *ssl_var_lookup_ssl(apr_pool_t *p, const SSLConnRec *sslconn, request_rec *r, const char *var);
static const char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs, const char *var);
-static const char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, const char *var);
+static const char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, const X509_NAME *xsname, const char *var);
static const char *ssl_var_lookup_ssl_cert_san(apr_pool_t *p, X509 *xs, const char *var);
-static const char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm);
-static const char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_TIME *tm);
+static const char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, const ASN1_TIME *tm);
+static const char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, const ASN1_TIME *tm);
static const char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs);
static const char *ssl_var_lookup_ssl_cert_chain(apr_pool_t *p, STACK_OF(X509) *sk, const char *var, int pem);
static const char *ssl_var_lookup_ssl_cert_rfc4523_cea(apr_pool_t *p, SSL *ssl);
}
static const char *ssl_var_lookup_ssl_cert_dn_oneline(apr_pool_t *p, request_rec *r,
- X509_NAME *xsname)
+ const X509_NAME *xsname)
{
char *result = NULL;
SSLDirConfigRec *dc;
const char *var)
{
const char *result;
- X509_NAME *xsname;
+ const X509_NAME *xsname;
int nid;
result = NULL;
result = ssl_var_lookup_ssl_cert_serial(p, xs);
}
else if (strcEQ(var, "V_START")) {
- result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notBefore(xs));
+ result = ssl_var_lookup_ssl_cert_valid(p, X509_get0_notBefore(xs));
}
else if (strcEQ(var, "V_END")) {
- result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notAfter(xs));
+ result = ssl_var_lookup_ssl_cert_valid(p, X509_get0_notAfter(xs));
}
else if (strcEQ(var, "V_REMAIN")) {
- result = ssl_var_lookup_ssl_cert_remain(p, X509_get_notAfter(xs));
+ result = ssl_var_lookup_ssl_cert_remain(p, X509_get0_notAfter(xs));
}
else if (*var && strcEQ(var+1, "_DN")) {
if (*var == 'S')
{ NULL, 0, 0 }
};
-static const char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname,
- const char *var)
+static const char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, const X509_NAME *xsname,
+ const char *var)
{
const char *ptr;
const char *result;
- X509_NAME_ENTRY *xsne;
+ const X509_NAME_ENTRY *xsne;
int i, j, n, idx = 0, raw = 0;
apr_size_t varlen;
for (j = 0; j < X509_NAME_entry_count(xsname); j++) {
xsne = X509_NAME_get_entry(xsname, j);
- n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
+ n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(xsne));
if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) {
result = modssl_X509_NAME_ENTRY_to_string(p, xsne, raw);
return NULL;
}
-static const char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm)
+static const char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, const ASN1_TIME *tm)
{
BIO* bio;
/* Return a string giving the number of days remaining until 'tm', or
* "0" if this can't be determined. */
-static const char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_TIME *tm)
+static const char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, const ASN1_TIME *tm)
{
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
int diff;
- if (INVALID_ASN1_TIME(tm) || ASN1_TIME_diff(&diff, NULL, NULL, tm) != 1) {
+ if (ASN1_TIME_check(tm) != 1 || ASN1_TIME_diff(&diff, NULL, NULL, tm) != 1) {
return "0";
}
#else
serialNumber = X509_get_serialNumber(xs);
if (serialNumber) {
- X509_NAME *issuer = X509_get_issuer_name(xs);
+ const X509_NAME *issuer = X509_get_issuer_name(xs);
if (issuer) {
BIGNUM *bn = ASN1_INTEGER_to_BN(serialNumber, NULL);
if((decimal = BN_bn2dec(bn)) == NULL) {
/* Add each RDN in 'xn' to the table 't' where the NID is present in
* 'nids', using key prefix 'pfx'. */
static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
- X509_NAME *xn, apr_pool_t *p)
+ const X509_NAME *xn, apr_pool_t *p)
{
- X509_NAME_ENTRY *xsne;
+ const X509_NAME_ENTRY *xsne;
apr_hash_t *count;
int i, nid;
/* Retrieve the nid, and check whether this is one of the nids
* which are to be extracted. */
- nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
+ nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(xsne));
tag = apr_hash_get(nids, &nid, sizeof nid);
if (tag) {
* parse the extension type as a primitive string. This will fail for
* any structured extension type per the docs. Returns non-zero on
* success and writes the string to the given bio. */
-static int dump_extn_value(BIO *bio, ASN1_OCTET_STRING *str)
+static int dump_extn_value(BIO *bio, const ASN1_OCTET_STRING *str)
{
- const unsigned char *pp = str->data;
+ const unsigned char *pp = ASN1_STRING_get0_data(str);
ASN1_STRING *ret = ASN1_STRING_new();
int rv = 0;
- if(!ret) {
- return rv;
+ if (!ret) {
+ return rv;
}
/* This allows UTF8String, IA5String, VisibleString, or BMPString;
* conversion to UTF-8 is forced. */
- if (d2i_DISPLAYTEXT(&ret, &pp, str->length)) {
+ if (d2i_DISPLAYTEXT(&ret, &pp, ASN1_STRING_length(str))) {
ASN1_STRING_print_ex(bio, ret, ASN1_STRFLGS_UTF8_CONVERT);
rv = 1;
}
*/
array = apr_array_make(p, count, sizeof(char *));
for (j = 0; j < count; j++) {
- X509_EXTENSION *ext = X509_get_ext(xs, j);
+ MODSSL_X509_EXT_CONST X509_EXTENSION *ext = X509_get_ext(xs, j);
if (OBJ_cmp(X509_EXTENSION_get_object(ext), oid) == 0) {
BIO *bio = BIO_new(BIO_s_mem());
#define MODSSL_SSL_METHOD_CONST
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x40000000L
+#define MODSSL_X509_EXT_CONST const
+#else
+#define MODSSL_X509_EXT_CONST
+#endif
+
#if defined(LIBRESSL_VERSION_NUMBER)
/* Missing from LibreSSL */
#if LIBRESSL_VERSION_NUMBER < 0x2060000f
#define DH_bits(x) (BN_num_bits(x->p))
#define X509_up_ref(x) (CRYPTO_add(&(x)->references, +1, CRYPTO_LOCK_X509))
#define EVP_PKEY_up_ref(pk) (CRYPTO_add(&(pk)->references, +1, CRYPTO_LOCK_EVP_PKEY))
+#define ASN1_STRING_get0_data(x) ((x)->data)
+#define ASN1_STRING_length(x) ((int)(x)->length)
+#define X509_get0_before(x) X509_get_before(x)
+#define X509_get0_after(x) X509_get_after(x)
#else
void init_bio_methods(void);
void free_bio_methods(void);
* counterparts. */
void ssl_log_xerror(const char *file, int line, int level,
apr_status_t rv, apr_pool_t *p, server_rec *s,
- X509 *cert, const char *format, ...)
+ const X509 *cert, const char *format, ...)
__attribute__((format(printf,8,9)));
void ssl_log_cxerror(const char *file, int line, int level,
- apr_status_t rv, conn_rec *c, X509 *cert,
+ apr_status_t rv, conn_rec *c, const X509 *cert,
const char *format, ...)
__attribute__((format(printf,7,8)));
void ssl_log_rxerror(const char *file, int line, int level,
- apr_status_t rv, request_rec *r, X509 *cert,
+ apr_status_t rv, request_rec *r, const X509 *cert,
const char *format, ...)
__attribute__((format(printf,7,8)));
/* Convert ASN.1 string to a pool-allocated char * string, escaping
* control characters. If raw is zero, convert to UTF-8, otherwise
* unchanged from the character set. */
-static char *asn1_string_convert(apr_pool_t *p, ASN1_STRING *asn1str, int raw)
+char *modssl_ASN1_STRING_convert(apr_pool_t *p, const ASN1_STRING *asn1str, int raw)
{
BIO *bio;
int flags = ASN1_STRFLGS_ESC_CTRL;
return modssl_bio_free_read(p, bio);
}
-#define asn1_string_to_utf8(p, a) asn1_string_convert(p, a, 0)
+#define asn1_string_to_utf8(p, a) modssl_ASN1_STRING_convert(p, a, 0)
/* convert a NAME_ENTRY to UTF8 string */
-char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne,
+char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, const X509_NAME_ENTRY *xsne,
int raw)
{
- char *result = asn1_string_convert(p, X509_NAME_ENTRY_get_data(xsne), raw);
+ char *result = modssl_ASN1_STRING_convert(p, X509_NAME_ENTRY_get_data(xsne), raw);
ap_xlate_proto_from_ascii(result, len);
return result;
}
* convert an X509_NAME to an RFC 2253 formatted string, optionally truncated
* to maxlen characters (specify a maxlen of 0 for no length limit)
*/
-char *modssl_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, int maxlen)
+char *modssl_X509_NAME_to_string(apr_pool_t *p, const X509_NAME *dn, int maxlen)
{
char *result = NULL;
BIO *bio;
/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */
static BOOL getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
{
- X509_NAME *subj;
+ const X509_NAME *subj;
int i = -1;
/* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
int modssl_smart_shutdown(SSL *ssl);
BOOL modssl_X509_getBC(X509 *, int *, int *);
-char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne,
+char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, const X509_NAME_ENTRY *xsne,
int raw);
-char *modssl_X509_NAME_to_string(apr_pool_t *, X509_NAME *, int);
+char *modssl_X509_NAME_to_string(apr_pool_t *, const X509_NAME *, int);
BOOL modssl_X509_getSAN(apr_pool_t *, X509 *, int, const char *, int, apr_array_header_t **);
BOOL modssl_X509_match_name(apr_pool_t *, X509 *, const char *, BOOL, server_rec *);
char *modssl_SSL_SESSION_id2sz(IDCONST unsigned char *, int, char *, int);
+/* Convert ASN.1 string to a pool-allocated char * string, escaping
+ * control characters. If raw is zero, convert to UTF-8, otherwise
+ * unchanged from the character set. */
+char *modssl_ASN1_STRING_convert(apr_pool_t *p, const ASN1_STRING *asn1str,
+ int raw);
+
/* Reads the remaining data in BIO, if not empty, and copies it into a
* pool-allocated string. If empty, returns NULL. BIO_free(bio) is
* called for both cases. */
static void ssl_print_cert_info(BIO *bio, X509 *cert)
{
- X509_NAME *dn;
+ const X509_NAME *dn;
EVP_PKEY *pk;
char buf[1024];