From 5e81262428771649043a728ac813370aaa47a46b Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Sat, 8 Dec 2007 16:07:12 +0000 Subject: Added support for sending more than one certificate. --- NEWS | 4 ++++ include/mod_gnutls.h.in | 8 ++++++-- src/gnutls_config.c | 14 +++++--------- src/gnutls_hooks.c | 10 +++++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/NEWS b/NEWS index e4b908d..29bf060 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +** Version 0.4.2 + +- Added support for sending a certificate chain. + ** Version 0.4.1 (2007-12-03) - Added support for subject alternative names in certificates. diff --git a/include/mod_gnutls.h.in b/include/mod_gnutls.h.in index 6a311a3..a0f6581 100644 --- a/include/mod_gnutls.h.in +++ b/include/mod_gnutls.h.in @@ -80,7 +80,10 @@ typedef struct /* The maximum number of client CA certificates allowed. */ #define MAX_CA_CRTS 128 -#define MAX_CIPHERS 16 + +/* The maximum number of certificates to send in a chain + */ +#define MAX_CHAIN_SIZE 8 typedef struct { @@ -88,7 +91,8 @@ typedef struct gnutls_srp_server_credentials_t srp_creds; gnutls_anon_server_credentials_t anon_creds; char* cert_cn; - gnutls_x509_crt_t cert_x509; + gnutls_x509_crt_t certs_x509[MAX_CHAIN_SIZE]; /* A certificate chain */ + unsigned int certs_x509_num; gnutls_x509_privkey_t privkey_x509; int enabled; /* whether to send the PEM encoded certificates diff --git a/src/gnutls_config.c b/src/gnutls_config.c index 7b5a42b..8d6308a 100644 --- a/src/gnutls_config.c +++ b/src/gnutls_config.c @@ -151,15 +151,10 @@ const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, "Certificate '%s'", file); } - ret = gnutls_x509_crt_init(&sc->cert_x509); - if (ret < 0) { - return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" - ": (%d) %s", ret, gnutls_strerror(ret)); - } - + sc->certs_x509_num = MAX_CHAIN_SIZE; ret = - gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM); - if (ret != 0) { + gnutls_x509_crt_list_import(sc->certs_x509, &sc->certs_x509_num, &data, GNUTLS_X509_FMT_PEM, 0); + if (ret < 0) { return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " "Certificate '%s': (%d) %s", file, ret, gnutls_strerror(ret)); @@ -440,7 +435,8 @@ void *mgs_config_server_create(apr_pool_t * p, server_rec * s) sc->srp_tpasswd_conf_file = NULL; sc->srp_tpasswd_file = NULL; sc->privkey_x509 = NULL; - sc->cert_x509 = NULL; + memset( sc->certs_x509, 0, sizeof(sc->certs_x509)); + sc->certs_x509_num = 0; sc->cache_timeout = apr_time_from_sec(300); sc->cache_type = mgs_cache_dbm; sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index 4364add..025e4e1 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c @@ -148,10 +148,10 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret) ctxt = gnutls_transport_get_ptr(session); ret->type = GNUTLS_CRT_X509; - ret->ncerts = 1; + ret->ncerts = ctxt->sc->certs_x509_num; ret->deinit_all = 0; - ret->cert.x509 = &ctxt->sc->cert_x509; + ret->cert.x509 = ctxt->sc->certs_x509; ret->key.x509 = ctxt->sc->privkey_x509; return 0; } @@ -334,7 +334,7 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, } } - if (sc->cert_x509 == NULL + if (sc->certs_x509[0] == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "[GnuTLS] - Host '%s:%d' is missing a " @@ -353,7 +353,7 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, } if (sc->enabled == GNUTLS_ENABLED_TRUE) { - rv = read_crt_cn(s, p, sc->cert_x509, &sc->cert_cn); + rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); if (rv < 0) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", @@ -686,7 +686,7 @@ int mgs_hook_fixups(request_rec * r) tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); - mgs_add_common_cert_vars(r, ctxt->sc->cert_x509, 0, + mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0, ctxt->sc->export_certificates_enabled); return rv; -- cgit