summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2007-12-08 16:07:12 (GMT)
committer Nokis Mavrogiannopoulos <nmav@gnutls.org>2007-12-08 16:07:12 (GMT)
commit5e81262428771649043a728ac813370aaa47a46b (patch)
tree9225c0da012618b8d88d2562c9ee8024a523765e
parent3b83e00f867a2264aa6742ebca86c4c450d6939c (diff)
Added support for sending more than one certificate.
-rw-r--r--NEWS4
-rw-r--r--include/mod_gnutls.h.in8
-rw-r--r--src/gnutls_config.c14
-rw-r--r--src/gnutls_hooks.c10
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 @@
1** Version 0.4.2
2
3- Added support for sending a certificate chain.
4
1** Version 0.4.1 (2007-12-03) 5** Version 0.4.1 (2007-12-03)
2 6
3- Added support for subject alternative names in certificates. 7- 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
80/* The maximum number of client CA certificates allowed. 80/* The maximum number of client CA certificates allowed.
81 */ 81 */
82#define MAX_CA_CRTS 128 82#define MAX_CA_CRTS 128
83#define MAX_CIPHERS 16 83
84/* The maximum number of certificates to send in a chain
85 */
86#define MAX_CHAIN_SIZE 8
84 87
85typedef struct 88typedef struct
86{ 89{
@@ -88,7 +91,8 @@ typedef struct
88 gnutls_srp_server_credentials_t srp_creds; 91 gnutls_srp_server_credentials_t srp_creds;
89 gnutls_anon_server_credentials_t anon_creds; 92 gnutls_anon_server_credentials_t anon_creds;
90 char* cert_cn; 93 char* cert_cn;
91 gnutls_x509_crt_t cert_x509; 94 gnutls_x509_crt_t certs_x509[MAX_CHAIN_SIZE]; /* A certificate chain */
95 unsigned int certs_x509_num;
92 gnutls_x509_privkey_t privkey_x509; 96 gnutls_x509_privkey_t privkey_x509;
93 int enabled; 97 int enabled;
94 /* whether to send the PEM encoded certificates 98 /* 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,
151 "Certificate '%s'", file); 151 "Certificate '%s'", file);
152 } 152 }
153 153
154 ret = gnutls_x509_crt_init(&sc->cert_x509); 154 sc->certs_x509_num = MAX_CHAIN_SIZE;
155 if (ret < 0) {
156 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
157 ": (%d) %s", ret, gnutls_strerror(ret));
158 }
159
160 ret = 155 ret =
161 gnutls_x509_crt_import(sc->cert_x509, &data, GNUTLS_X509_FMT_PEM); 156 gnutls_x509_crt_list_import(sc->certs_x509, &sc->certs_x509_num, &data, GNUTLS_X509_FMT_PEM, 0);
162 if (ret != 0) { 157 if (ret < 0) {
163 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " 158 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
164 "Certificate '%s': (%d) %s", file, ret, 159 "Certificate '%s': (%d) %s", file, ret,
165 gnutls_strerror(ret)); 160 gnutls_strerror(ret));
@@ -440,7 +435,8 @@ void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
440 sc->srp_tpasswd_conf_file = NULL; 435 sc->srp_tpasswd_conf_file = NULL;
441 sc->srp_tpasswd_file = NULL; 436 sc->srp_tpasswd_file = NULL;
442 sc->privkey_x509 = NULL; 437 sc->privkey_x509 = NULL;
443 sc->cert_x509 = NULL; 438 memset( sc->certs_x509, 0, sizeof(sc->certs_x509));
439 sc->certs_x509_num = 0;
444 sc->cache_timeout = apr_time_from_sec(300); 440 sc->cache_timeout = apr_time_from_sec(300);
445 sc->cache_type = mgs_cache_dbm; 441 sc->cache_type = mgs_cache_dbm;
446 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); 442 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)
148 ctxt = gnutls_transport_get_ptr(session); 148 ctxt = gnutls_transport_get_ptr(session);
149 149
150 ret->type = GNUTLS_CRT_X509; 150 ret->type = GNUTLS_CRT_X509;
151 ret->ncerts = 1; 151 ret->ncerts = ctxt->sc->certs_x509_num;
152 ret->deinit_all = 0; 152 ret->deinit_all = 0;
153 153
154 ret->cert.x509 = &ctxt->sc->cert_x509; 154 ret->cert.x509 = ctxt->sc->certs_x509;
155 ret->key.x509 = ctxt->sc->privkey_x509; 155 ret->key.x509 = ctxt->sc->privkey_x509;
156 return 0; 156 return 0;
157} 157}
@@ -334,7 +334,7 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
334 } 334 }
335 } 335 }
336 336
337 if (sc->cert_x509 == NULL 337 if (sc->certs_x509[0] == NULL
338 && sc->enabled == GNUTLS_ENABLED_TRUE) { 338 && sc->enabled == GNUTLS_ENABLED_TRUE) {
339 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 339 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
340 "[GnuTLS] - Host '%s:%d' is missing a " 340 "[GnuTLS] - Host '%s:%d' is missing a "
@@ -353,7 +353,7 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
353 } 353 }
354 354
355 if (sc->enabled == GNUTLS_ENABLED_TRUE) { 355 if (sc->enabled == GNUTLS_ENABLED_TRUE) {
356 rv = read_crt_cn(s, p, sc->cert_x509, &sc->cert_cn); 356 rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn);
357 if (rv < 0) { 357 if (rv < 0) {
358 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 358 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
359 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", 359 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
@@ -686,7 +686,7 @@ int mgs_hook_fixups(request_rec * r)
686 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); 686 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
687 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); 687 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
688 688
689 mgs_add_common_cert_vars(r, ctxt->sc->cert_x509, 0, 689 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
690 ctxt->sc->export_certificates_enabled); 690 ctxt->sc->export_certificates_enabled);
691 691
692 return rv; 692 return rv;