mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-03-14 03:22:06 +01:00
BUILD: ssl: make X509_NAME usage OpenSSL 4.0 ready
Starting with OpenSSL 4.0, X509_get_subject_name(), X509_get_issuer_name(), and X509_CRL_get_issuer() return a const-qualified X509_NAME pointer. Similarly, X509_NAME_get_entry() returns a const X509_NAME_ENTRY *, and X509_NAME_ENTRY_get_data() returns a const ASN1_STRING *. Introduce the __X509_NAME_CONST__ macro (defined to 'const' for OpenSSL >= 4.0.0, empty for WolfSSL and older OpenSSL version which lacks const on these APIs) and use it to qualify X509_NAME * variables and the parameters of the three DN helper functions ssl_sock_get_dn_entry(), ssl_sock_get_dn_formatted(), and ssl_sock_get_dn_oneline(). This avoids both const-qualifier warnings on OpenSSL 4.0 and discarded-qualifier warnings on WolfSSL, without needing explicit casts at call sites. In ssl_sock.c (ssl_get_client_ca_file) and ssl_gencert.c (ssl_sock_do_create_cert), a __X509_NAME_CONST__ X509_NAME * variable was being reused to store the result of X509_NAME_dup() and then passed to mutating functions (X509_NAME_add_entry_by_txt, X509_NAME_free). Introduce separate X509_NAME * variables (xn_dup, subject) to hold the mutable duplicate. Original patch from Alexandr Nedvedicky <sashan@openssl.org>: https://www.mail-archive.com/haproxy@formilux.org/msg46696.html
This commit is contained in:
parent
e82f03dd88
commit
73732abfb2
@ -394,6 +394,12 @@ static inline unsigned long ERR_peek_error_func(const char **func)
|
||||
#define __OPENSSL_110_CONST__
|
||||
#endif
|
||||
|
||||
#if (HA_OPENSSL_VERSION_NUMBER >= 0x40000000L) && (!defined(USE_OPENSSL_WOLFSSL))
|
||||
#define __X509_NAME_CONST__ const
|
||||
#else
|
||||
#define __X509_NAME_CONST__
|
||||
#endif
|
||||
|
||||
/* ERR_remove_state() was deprecated in 1.0.0 in favor of
|
||||
* ERR_remove_thread_state(), which was in turn deprecated in
|
||||
* 1.1.0 and does nothing anymore. Let's simply silently kill
|
||||
|
||||
@ -34,10 +34,10 @@ int cert_get_pkey_algo(X509 *crt, struct buffer *out);
|
||||
int ssl_sock_get_serial(X509 *crt, struct buffer *out);
|
||||
int ssl_sock_crt2der(X509 *crt, struct buffer *out);
|
||||
int ssl_sock_get_time(ASN1_TIME *tm, struct buffer *out);
|
||||
int ssl_sock_get_dn_entry(X509_NAME *a, const struct buffer *entry, int pos,
|
||||
int ssl_sock_get_dn_entry(__X509_NAME_CONST__ X509_NAME *a, const struct buffer *entry, int pos,
|
||||
struct buffer *out);
|
||||
int ssl_sock_get_dn_formatted(X509_NAME *a, const struct buffer *format, struct buffer *out);
|
||||
int ssl_sock_get_dn_oneline(X509_NAME *a, struct buffer *out);
|
||||
int ssl_sock_get_dn_formatted(__X509_NAME_CONST__ X509_NAME *a, const struct buffer *format, struct buffer *out);
|
||||
int ssl_sock_get_dn_oneline(__X509_NAME_CONST__ X509_NAME *a, struct buffer *out);
|
||||
X509* ssl_sock_get_peer_certificate(SSL *ssl);
|
||||
X509* ssl_sock_get_verified_chain_root(SSL *ssl);
|
||||
unsigned int openssl_version_parser(const char *version);
|
||||
|
||||
@ -2126,7 +2126,7 @@ static int show_cert_detail(X509 *cert, STACK_OF(X509) *chain, struct issuer_cha
|
||||
int i;
|
||||
int write = -1;
|
||||
unsigned int len = 0;
|
||||
X509_NAME *name = NULL;
|
||||
__X509_NAME_CONST__ X509_NAME *name = NULL;
|
||||
|
||||
if (!tmp)
|
||||
return -1;
|
||||
@ -4412,7 +4412,7 @@ static int show_crl_detail(X509_CRL *crl, struct buffer *out)
|
||||
BIO *bio = NULL;
|
||||
struct buffer *tmp = alloc_trash_chunk();
|
||||
long version;
|
||||
X509_NAME *issuer;
|
||||
__X509_NAME_CONST__ X509_NAME *issuer;
|
||||
int write = -1;
|
||||
#ifndef USE_OPENSSL_WOLFSSL
|
||||
STACK_OF(X509_REVOKED) *rev = NULL;
|
||||
|
||||
@ -92,7 +92,8 @@ static SSL_CTX *ssl_sock_do_create_cert(const char *servername, struct bind_conf
|
||||
EVP_PKEY *pkey = NULL;
|
||||
SSL *tmp_ssl = NULL;
|
||||
CONF *ctmp = NULL;
|
||||
X509_NAME *name;
|
||||
__X509_NAME_CONST__ X509_NAME *name;
|
||||
X509_NAME *subject = NULL;
|
||||
const EVP_MD *digest;
|
||||
X509V3_CTX ctx;
|
||||
unsigned int i;
|
||||
@ -140,21 +141,21 @@ static SSL_CTX *ssl_sock_do_create_cert(const char *servername, struct bind_conf
|
||||
goto mkcert_error;
|
||||
|
||||
/* Set the subject name using the same, but the CN */
|
||||
name = X509_NAME_dup(name);
|
||||
subject = X509_NAME_dup(name);
|
||||
|
||||
if (strlen(servername) <= 64) {
|
||||
if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
|
||||
if (X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC,
|
||||
(const unsigned char *)servername,
|
||||
-1, -1, 0) != 1) {
|
||||
X509_NAME_free(name);
|
||||
X509_NAME_free(subject);
|
||||
goto mkcert_error;
|
||||
}
|
||||
}
|
||||
if (X509_set_subject_name(newcrt, name) != 1) {
|
||||
X509_NAME_free(name);
|
||||
if (X509_set_subject_name(newcrt, subject) != 1) {
|
||||
X509_NAME_free(subject);
|
||||
goto mkcert_error;
|
||||
}
|
||||
X509_NAME_free(name);
|
||||
X509_NAME_free(subject);
|
||||
|
||||
/* Add x509v3 extensions as specified */
|
||||
ctmp = NCONF_new(NULL);
|
||||
|
||||
@ -779,7 +779,7 @@ static int
|
||||
smp_fetch_ssl_r_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
X509 *crt = NULL;
|
||||
X509_NAME *name;
|
||||
__X509_NAME_CONST__ X509_NAME *name;
|
||||
int ret = 0;
|
||||
struct buffer *smp_trash;
|
||||
struct connection *conn;
|
||||
@ -1113,7 +1113,7 @@ smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw,
|
||||
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
|
||||
int conn_server = (kw[4] == 's') ? 1 : 0;
|
||||
X509 *crt = NULL;
|
||||
X509_NAME *name;
|
||||
__X509_NAME_CONST__ X509_NAME *name;
|
||||
int ret = 0;
|
||||
struct buffer *smp_trash;
|
||||
struct connection *conn;
|
||||
@ -1309,7 +1309,7 @@ smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw,
|
||||
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
|
||||
int conn_server = (kw[4] == 's') ? 1 : 0;
|
||||
X509 *crt = NULL;
|
||||
X509_NAME *name;
|
||||
__X509_NAME_CONST__ X509_NAME *name;
|
||||
int ret = 0;
|
||||
struct buffer *smp_trash;
|
||||
struct connection *conn;
|
||||
|
||||
@ -691,7 +691,8 @@ static STACK_OF(X509_NAME)* ssl_get_client_ca_file(char *path)
|
||||
STACK_OF(X509_OBJECT) *objs;
|
||||
STACK_OF(X509_NAME) *skn;
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
__X509_NAME_CONST__ X509_NAME *xn;
|
||||
X509_NAME *xn_dup;
|
||||
|
||||
skn = sk_X509_NAME_new_null();
|
||||
/* take x509 from cafile_tree */
|
||||
@ -716,19 +717,19 @@ static STACK_OF(X509_NAME)* ssl_get_client_ca_file(char *path)
|
||||
if (ca_name)
|
||||
continue;
|
||||
ca_name = calloc(1, sizeof *ca_name);
|
||||
xn = X509_NAME_dup(xn);
|
||||
xn_dup = X509_NAME_dup(xn);
|
||||
if (!ca_name ||
|
||||
!xn ||
|
||||
!sk_X509_NAME_push(skn, xn)) {
|
||||
!xn_dup ||
|
||||
!sk_X509_NAME_push(skn, xn_dup)) {
|
||||
free(ca_name);
|
||||
X509_NAME_free(xn);
|
||||
X509_NAME_free(xn_dup);
|
||||
sk_X509_NAME_pop_free(skn, X509_NAME_free);
|
||||
sk_X509_NAME_free(skn);
|
||||
skn = NULL;
|
||||
break;
|
||||
}
|
||||
ca_name->node.key = key;
|
||||
ca_name->xname = xn;
|
||||
ca_name->xname = xn_dup;
|
||||
eb64_insert(&ca_name_tree, &ca_name->node);
|
||||
}
|
||||
sk_X509_OBJECT_popX_free(objs, X509_OBJECT_free);
|
||||
@ -3151,7 +3152,7 @@ int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct
|
||||
SSL_CTX *ctx;
|
||||
int i;
|
||||
int order = 0;
|
||||
X509_NAME *xname;
|
||||
__X509_NAME_CONST__ X509_NAME *xname;
|
||||
char *str;
|
||||
EVP_PKEY *pkey;
|
||||
struct pkey_info kinfo = { .sig = TLSEXT_signature_anonymous, .bits = 0 };
|
||||
@ -3243,8 +3244,8 @@ int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct
|
||||
xname = X509_get_subject_name(data->cert);
|
||||
i = -1;
|
||||
while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
|
||||
X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
|
||||
ASN1_STRING *value;
|
||||
__X509_NAME_CONST__ X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
|
||||
__X509_NAME_CONST__ ASN1_STRING *value;
|
||||
|
||||
value = X509_NAME_ENTRY_get_data(entry);
|
||||
if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
|
||||
@ -4897,7 +4898,7 @@ static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
|
||||
X509 *cert;
|
||||
STACK_OF(GENERAL_NAME) *alt_names;
|
||||
int i;
|
||||
X509_NAME *cert_subject;
|
||||
__X509_NAME_CONST__ X509_NAME *cert_subject;
|
||||
char *str;
|
||||
|
||||
if (ok == 0)
|
||||
@ -4963,8 +4964,8 @@ static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
|
||||
cert_subject = X509_get_subject_name(cert);
|
||||
i = -1;
|
||||
while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
|
||||
X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
|
||||
ASN1_STRING *value;
|
||||
__X509_NAME_CONST__ X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
|
||||
__X509_NAME_CONST__ ASN1_STRING *value;
|
||||
value = X509_NAME_ENTRY_get_data(entry);
|
||||
if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
|
||||
ok = ssl_sock_srv_hostcheck(str, servername);
|
||||
@ -7637,7 +7638,7 @@ int ssl_sock_get_remote_common_name(struct connection *conn,
|
||||
{
|
||||
struct ssl_sock_ctx *ctx = conn_get_ssl_sock_ctx(conn);
|
||||
X509 *crt = NULL;
|
||||
X509_NAME *name;
|
||||
__X509_NAME_CONST__ X509_NAME *name;
|
||||
const char find_cn[] = "CN";
|
||||
const struct buffer find_cn_chunk = {
|
||||
.area = (char *)&find_cn,
|
||||
@ -7737,7 +7738,7 @@ int ssl_sock_get_alpn(const struct connection *conn, void *xprt_ctx, const char
|
||||
int ssl_load_global_issuer_from_BIO(BIO *in, char *fp, char **err)
|
||||
{
|
||||
X509 *ca;
|
||||
X509_NAME *name = NULL;
|
||||
__X509_NAME_CONST__ X509_NAME *name = NULL;
|
||||
ASN1_OCTET_STRING *skid = NULL;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
struct issuer_chain *issuer;
|
||||
|
||||
@ -140,7 +140,7 @@ static void ssl_trace(enum trace_level level, uint64_t mask, const struct trace_
|
||||
X509 *crt = SSL_get_certificate(ssl);
|
||||
|
||||
if (crt) {
|
||||
X509_NAME *name = X509_get_subject_name(crt);
|
||||
__X509_NAME_CONST__ X509_NAME *name = X509_get_subject_name(crt);
|
||||
if (name)
|
||||
chunk_appendf(&trace_buf, " subject=\"%s\"",
|
||||
X509_NAME_oneline(name, 0, 0));
|
||||
|
||||
@ -187,12 +187,12 @@ int ssl_sock_get_time(ASN1_TIME *tm, struct buffer *out)
|
||||
/* Extract an entry from a X509_NAME and copy its value to an output chunk.
|
||||
* Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
|
||||
*/
|
||||
int ssl_sock_get_dn_entry(X509_NAME *a, const struct buffer *entry, int pos,
|
||||
int ssl_sock_get_dn_entry(__X509_NAME_CONST__ X509_NAME *a, const struct buffer *entry, int pos,
|
||||
struct buffer *out)
|
||||
{
|
||||
X509_NAME_ENTRY *ne;
|
||||
ASN1_OBJECT *obj;
|
||||
ASN1_STRING *data;
|
||||
__X509_NAME_CONST__ X509_NAME_ENTRY *ne;
|
||||
__X509_NAME_CONST__ ASN1_OBJECT *obj;
|
||||
__X509_NAME_CONST__ ASN1_STRING *data;
|
||||
const unsigned char *data_ptr;
|
||||
int data_len;
|
||||
int i, j, n;
|
||||
@ -249,7 +249,7 @@ int ssl_sock_get_dn_entry(X509_NAME *a, const struct buffer *entry, int pos,
|
||||
* Currently supports rfc2253 for returning LDAP V3 DNs.
|
||||
* Returns 1 if dn entries exist, 0 if no dn entry was found.
|
||||
*/
|
||||
int ssl_sock_get_dn_formatted(X509_NAME *a, const struct buffer *format, struct buffer *out)
|
||||
int ssl_sock_get_dn_formatted(__X509_NAME_CONST__ X509_NAME *a, const struct buffer *format, struct buffer *out)
|
||||
{
|
||||
BIO *bio = NULL;
|
||||
int ret = 0;
|
||||
@ -279,11 +279,11 @@ out:
|
||||
/* Extract and format full DN from a X509_NAME and copy result into a chunk
|
||||
* Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
|
||||
*/
|
||||
int ssl_sock_get_dn_oneline(X509_NAME *a, struct buffer *out)
|
||||
int ssl_sock_get_dn_oneline(__X509_NAME_CONST__ X509_NAME *a, struct buffer *out)
|
||||
{
|
||||
X509_NAME_ENTRY *ne;
|
||||
ASN1_OBJECT *obj;
|
||||
ASN1_STRING *data;
|
||||
__X509_NAME_CONST__ X509_NAME_ENTRY *ne;
|
||||
__X509_NAME_CONST__ ASN1_OBJECT *obj;
|
||||
__X509_NAME_CONST__ ASN1_STRING *data;
|
||||
const unsigned char *data_ptr;
|
||||
int data_len;
|
||||
int i, n, ln;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user