1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

implement proxy client certificate callback

(uses SSLProxyMachineCertificate{File,Cert} when downstream server
requires a client certificate)


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@94329 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Doug MacEachern
2002-03-30 05:40:02 +00:00
parent ada316e24b
commit 9ee8bc12b5
3 changed files with 103 additions and 0 deletions

View File

@@ -1543,6 +1543,104 @@ int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, server_rec *s)
return ok;
}
#define SSLPROXY_CERT_CB_LOG_FMT \
"Proxy client certificate callback: (%s) "
static void modssl_proxy_info_log(server_rec *s,
X509_INFO *info,
const char *msg)
{
SSLSrvConfigRec *sc = mySrvConfig(s);
char name_buf[256];
X509_NAME *name;
const char *dn;
if (sc->log_level < SSL_LOG_TRACE) {
return;
}
name = X509_get_subject_name(info->x509);
dn = X509_NAME_oneline(name, name_buf, sizeof(name_buf));
ssl_log(s, SSL_LOG_TRACE,
SSLPROXY_CERT_CB_LOG_FMT "%s, sending %s",
sc->vhost_id, msg, dn ? dn : "-uknown-");
}
/*
* caller will decrement the cert and key reference
* so we need to increment here to prevent them from
* being freed.
*/
#define modssl_set_cert_info(info, cert, pkey) \
*cert = info->x509; \
*pkey = info->x_pkey->dec_pkey; \
CRYPTO_add(&((*cert)->references), +1, CRYPTO_LOCK_X509_PKEY); \
CRYPTO_add(&((*pkey)->references), +1, CRYPTO_LOCK_X509_PKEY)
int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
server_rec *s = c->base_server;
SSLSrvConfigRec *sc = mySrvConfig(s);
X509_NAME *ca_name, *issuer;
X509_INFO *info;
STACK_OF(X509_NAME) *ca_list;
STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
int i, j;
ssl_log(s, SSL_LOG_TRACE,
SSLPROXY_CERT_CB_LOG_FMT "entered",
sc->vhost_id);
if (!certs || (sk_X509_INFO_num(certs) <= 0)) {
ssl_log(s, SSL_LOG_WARN,
SSLPROXY_CERT_CB_LOG_FMT
"downstream server wanted client certificate "
"but none are configured", sc->vhost_id);
return FALSE;
}
ca_list = SSL_get_client_CA_list(ssl);
if (!ca_list || (sk_X509_NAME_num(ca_list) <= 0)) {
/*
* downstream server didn't send us a list of acceptable CA certs,
* so we send the first client cert in the list.
*/
info = sk_X509_INFO_value(certs, 0);
modssl_proxy_info_log(s, info, "no acceptable CA list");
modssl_set_cert_info(info, x509, pkey);
return TRUE;
}
for (i = 0; i < sk_X509_NAME_num(ca_list); i++) {
ca_name = sk_X509_NAME_value(ca_list, i);
for (j = 0; j < sk_X509_INFO_num(certs); j++) {
info = sk_X509_INFO_value(certs, j);
issuer = X509_get_issuer_name(info->x509);
if (X509_NAME_cmp(issuer, ca_name) == 0) {
modssl_proxy_info_log(s, info, "found acceptable cert");
modssl_set_cert_info(info, x509, pkey);
return TRUE;
}
}
}
ssl_log(s, SSL_LOG_TRACE,
SSLPROXY_CERT_CB_LOG_FMT
"no client certificate found!?", sc->vhost_id);
return FALSE;
}
static void ssl_session_log(server_rec *s,
const char *request,
unsigned char *id,