mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
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
This commit is contained in:
@@ -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
|
certificate files. Upon startup, each client certificate configured will
|
||||||
be examined and a chain of trust will be constructed.
|
be examined and a chain of trust will be constructed.
|
||||||
</p>
|
</p>
|
||||||
|
<note type="warning"><title>Security warning</title>
|
||||||
|
<p>If this directive is enabled, all of the certificates in the file will be
|
||||||
|
trusted as if they were also in <directive module="mod_ssl">
|
||||||
|
SSLProxyCACertificateFile</directive>.</p>
|
||||||
|
</note>
|
||||||
<example><title>Example</title>
|
<example><title>Example</title>
|
||||||
SSLProxyMachineCertificateChainFile /usr/local/apache2/conf/ssl.crt/proxyCA.pem
|
SSLProxyMachineCertificateChainFile /usr/local/apache2/conf/ssl.crt/proxyCA.pem
|
||||||
</example>
|
</example>
|
||||||
|
@@ -1115,7 +1115,9 @@ static void ssl_init_proxy_certs(server_rec *s,
|
|||||||
int n, ncerts = 0;
|
int n, ncerts = 0;
|
||||||
STACK_OF(X509_INFO) *sk;
|
STACK_OF(X509_INFO) *sk;
|
||||||
modssl_pk_proxy_t *pkp = mctx->pkp;
|
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_CTX_set_client_cert_cb(mctx->ssl_ctx,
|
||||||
ssl_callback_proxy_cert);
|
ssl_callback_proxy_cert);
|
||||||
@@ -1161,29 +1163,42 @@ static void ssl_init_proxy_certs(server_rec *s,
|
|||||||
ncerts);
|
ncerts);
|
||||||
pkp->certs = sk;
|
pkp->certs = sk;
|
||||||
|
|
||||||
if (!pkp->ca_cert_file) {
|
|
||||||
|
if (!pkp->ca_cert_file || !store) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load all of the CA certs and construct a chain */
|
/* 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();
|
||||||
|
|
||||||
SSL_X509_INFO_load_file(ptemp, sk, pkp->ca_cert_file);
|
if (!sctx) {
|
||||||
pkp->ca_certs = (STACK_OF(X509_INFO) **) apr_pcalloc(p, ncerts * sizeof(sk));
|
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
|
||||||
|
"SSL proxy client cert initialization failed");
|
||||||
|
ssl_die();
|
||||||
|
}
|
||||||
|
|
||||||
|
X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
|
||||||
|
|
||||||
for (n = 0; n < ncerts; n++) {
|
for (n = 0; n < ncerts; n++) {
|
||||||
int len;
|
int i;
|
||||||
X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
|
X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
|
||||||
chain = sk_X509_INFO_new_null();
|
X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
|
||||||
len = SSL_X509_INFO_create_chain(inf->x509, sk, chain);
|
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;
|
pkp->ca_certs[n] = chain;
|
||||||
|
X509_STORE_CTX_cleanup(sctx);
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
||||||
"client certificate %i has loaded %i "
|
"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,
|
static void ssl_init_proxy_ctx(server_rec *s,
|
||||||
|
@@ -1588,11 +1588,12 @@ int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
|
|||||||
server_rec *s = mySrvFromConn(c);
|
server_rec *s = mySrvFromConn(c);
|
||||||
SSLSrvConfigRec *sc = mySrvConfig(s);
|
SSLSrvConfigRec *sc = mySrvConfig(s);
|
||||||
X509_NAME *ca_name, *issuer, *ca_issuer;
|
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_NAME) *ca_list;
|
||||||
STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
|
STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
|
||||||
STACK_OF(X509_INFO) *ca_certs;
|
STACK_OF(X509) *ca_certs;
|
||||||
STACK_OF(X509_INFO) **ca_cert_chains;
|
STACK_OF(X509) **ca_cert_chains;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
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;
|
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.
|
* (by issuer name), if provided.
|
||||||
*/
|
*/
|
||||||
ca_certs = ca_cert_chains[j];
|
ca_certs = ca_cert_chains[j];
|
||||||
for (k = 0; k < sk_X509_INFO_num(ca_certs); k++) {
|
for (k = 0; k < sk_X509_num(ca_certs); k++) {
|
||||||
ca_info = sk_X509_INFO_value(ca_certs, k);
|
ca_cert = sk_X509_value(ca_certs, k);
|
||||||
ca_issuer = X509_get_issuer_name(ca_info->x509);
|
ca_issuer = X509_get_issuer_name(ca_cert);
|
||||||
|
|
||||||
if(X509_NAME_cmp(ca_issuer, ca_name) == 0 ) {
|
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);
|
modssl_set_cert_info(info, x509, pkey);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
} /* end loop through chained certs */
|
} /* end loop through chained certs */
|
||||||
|
@@ -539,7 +539,7 @@ typedef struct {
|
|||||||
const char *cert_path;
|
const char *cert_path;
|
||||||
const char *ca_cert_file;
|
const char *ca_cert_file;
|
||||||
STACK_OF(X509_INFO) *certs;
|
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;
|
} modssl_pk_proxy_t;
|
||||||
|
|
||||||
/** stuff related to authentication that can also be per-dir */
|
/** stuff related to authentication that can also be per-dir */
|
||||||
|
@@ -385,46 +385,6 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp,
|
|||||||
return ok;
|
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
|
** Extra Server Certificate Chain Support
|
||||||
|
@@ -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 *);
|
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 *);
|
int SSL_CTX_use_certificate_chain(SSL_CTX *, char *, int, pem_password_cb *);
|
||||||
char *SSL_SESSION_id2sz(unsigned char *, int, char *, int);
|
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__ */
|
#endif /* __SSL_UTIL_SSL_H__ */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
Reference in New Issue
Block a user