From: Daniel Ruggeri
Date: Wed, 14 Sep 2011 20:16:02 +0000 (+0000)
Subject: Modify SSLProxyMachineCertificateChainFile to use X509 instead of X509_INFO and use...
X-Git-Tag: 2.3.15~256
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=47cf15b8520bd445ae6b2bf1a4a0dcdcf9a8d810;p=apache
Modify SSLProxyMachineCertificateChainFile to use X509 instead of X509_INFO and use openssl to construct the chain
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1170833 13f79535-47bb-0310-9956-ffa450edef68
---
diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml
index 37e766e083..933a12da74 100644
--- a/docs/manual/mod/mod_ssl.xml
+++ b/docs/manual/mod/mod_ssl.xml
@@ -1549,6 +1549,11 @@ This referenced file is simply the concatenation of the various PEM-encoded
certificate files. Upon startup, each client certificate configured will
be examined and a chain of trust will be constructed.
+Security warning
+If this directive is enabled, all of the certificates in the file will be
+trusted as if they were also in
+SSLProxyCACertificateFile.
+
Example
SSLProxyMachineCertificateChainFile /usr/local/apache2/conf/ssl.crt/proxyCA.pem
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 48cb2b39f4..59fea93d01 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -1115,7 +1115,9 @@ static void ssl_init_proxy_certs(server_rec *s,
int n, ncerts = 0;
STACK_OF(X509_INFO) *sk;
modssl_pk_proxy_t *pkp = mctx->pkp;
- STACK_OF(X509_INFO) *chain;
+ STACK_OF(X509) *chain;
+ X509_STORE_CTX *sctx;
+ X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
ssl_callback_proxy_cert);
@@ -1161,29 +1163,42 @@ static void ssl_init_proxy_certs(server_rec *s,
ncerts);
pkp->certs = sk;
- if (!pkp->ca_cert_file) {
+
+ if (!pkp->ca_cert_file || !store) {
return;
}
/* Load all of the CA certs and construct a chain */
- sk = sk_X509_INFO_new_null();
+ pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk));
+ sctx = X509_STORE_CTX_new();
+
+ if (!sctx) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
+ "SSL proxy client cert initialization failed");
+ ssl_die();
+ }
- SSL_X509_INFO_load_file(ptemp, sk, pkp->ca_cert_file);
- pkp->ca_certs = (STACK_OF(X509_INFO) **) apr_pcalloc(p, ncerts * sizeof(sk));
+ X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
for (n = 0; n < ncerts; n++) {
- int len;
+ int i;
X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
- chain = sk_X509_INFO_new_null();
- len = SSL_X509_INFO_create_chain(inf->x509, sk, chain);
+ X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
+ X509_verify_cert(sctx);
+ ERR_clear_error();
+
+ chain = X509_STORE_CTX_get1_chain(sctx);
+ sk_X509_shift(chain);
+ i=sk_X509_num(chain);
pkp->ca_certs[n] = chain;
+ X509_STORE_CTX_cleanup(sctx);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"client certificate %i has loaded %i "
- "intermediary signers ", n, len);
+ "intermediate CA%s", n, i, i == 1 ? "" : "s");
}
- sk_X509_INFO_free(sk);
+ X509_STORE_CTX_free(sctx);
}
static void ssl_init_proxy_ctx(server_rec *s,
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 3015130469..c88f6949cd 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -1588,11 +1588,12 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
server_rec *s = mySrvFromConn(c);
SSLSrvConfigRec *sc = mySrvConfig(s);
X509_NAME *ca_name, *issuer, *ca_issuer;
- X509_INFO *info, *ca_info;
+ X509_INFO *info;
+ X509 *ca_cert;
STACK_OF(X509_NAME) *ca_list;
STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
- STACK_OF(X509_INFO) *ca_certs;
- STACK_OF(X509_INFO) **ca_cert_chains;
+ STACK_OF(X509) *ca_certs;
+ STACK_OF(X509) **ca_cert_chains;
int i, j, k;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
@@ -1640,21 +1641,21 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
return TRUE;
}
- if (ca_cert_chains) {
+ if (ca_cert_chains) {
/*
- * Failed to find direct issuer - search intermediaries
+ * Failed to find direct issuer - search intermediates
* (by issuer name), if provided.
*/
ca_certs = ca_cert_chains[j];
- for (k = 0; k < sk_X509_INFO_num(ca_certs); k++) {
- ca_info = sk_X509_INFO_value(ca_certs, k);
- ca_issuer = X509_get_issuer_name(ca_info->x509);
+ for (k = 0; k < sk_X509_num(ca_certs); k++) {
+ ca_cert = sk_X509_value(ca_certs, k);
+ ca_issuer = X509_get_issuer_name(ca_cert);
if(X509_NAME_cmp(ca_issuer, ca_name) == 0 ) {
- modssl_proxy_info_log(c, info, "found acceptable cert by intermediary");
+ modssl_proxy_info_log(c, info, "found acceptable cert by intermediate CA");
modssl_set_cert_info(info, x509, pkey);
-
+
return TRUE;
}
} /* end loop through chained certs */
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index fd9ff2bd95..2a55f6795e 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -539,7 +539,7 @@ typedef struct {
const char *cert_path;
const char *ca_cert_file;
STACK_OF(X509_INFO) *certs;
- STACK_OF(X509_INFO) **ca_certs; /* ptr to array of ptrs */
+ STACK_OF(X509) **ca_certs; /* ptr to array of ptrs */
} modssl_pk_proxy_t;
/** stuff related to authentication that can also be per-dir */
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index f9ae5ee38a..dc59224734 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -385,46 +385,6 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp,
return ok;
}
-/*
- * Construct a stack of X509_INFO containing only certificates
- * that have signed the provided certificate or are an intermediary
- * signer of the certificate
-*/
-int SSL_X509_INFO_create_chain(const X509 *x509,
- STACK_OF(X509_INFO) *ca_certs,
- STACK_OF(X509_INFO) *chain)
-{
- int can_proceed = 1;
- int len = 0;
- int i;
- X509 *certificate = (X509 *)x509;
- X509_INFO *info;
- X509_NAME *cert_issuer_name, *ca_name, *ca_issuer_name;
-
- while (can_proceed) {
- can_proceed = 0;
- cert_issuer_name = X509_get_issuer_name(certificate);
-
- for (i = 0; i < sk_X509_INFO_num(ca_certs); i++) {
- info = sk_X509_INFO_value(ca_certs, i);
- ca_name = X509_get_subject_name(info->x509);
- ca_issuer_name = X509_get_issuer_name(info->x509);
-
- if (X509_NAME_cmp(cert_issuer_name, ca_name) == 0) {
- /* Check for a self-signed cert (no issuer) */
- can_proceed = X509_NAME_cmp(ca_name, ca_issuer_name) == 0
- ? 0 : 1;
- len++;
- certificate = info->x509;
- sk_X509_INFO_unshift(chain, info);
- break;
- }
- }
- }
-
- return len;
-}
-
/* _________________________________________________________________
**
** Extra Server Certificate Chain Support
diff --git a/modules/ssl/ssl_util_ssl.h b/modules/ssl/ssl_util_ssl.h
index d2f995de2b..3da9c462f9 100644
--- a/modules/ssl/ssl_util_ssl.h
+++ b/modules/ssl/ssl_util_ssl.h
@@ -72,7 +72,6 @@ BOOL SSL_X509_INFO_load_file(apr_pool_t *, STACK_OF(X509_INFO) *, const c
BOOL SSL_X509_INFO_load_path(apr_pool_t *, STACK_OF(X509_INFO) *, const char *);
int SSL_CTX_use_certificate_chain(SSL_CTX *, char *, int, pem_password_cb *);
char *SSL_SESSION_id2sz(unsigned char *, int, char *, int);
-int SSL_X509_INFO_create_chain(const X509 *, STACK_OF(X509_INFO) *, STACK_OF(X509_INFO) *);
#endif /* __SSL_UTIL_SSL_H__ */
/** @} */