summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorNokis Mavrogiannopoulos <nmav@gnutls.org>2008-02-20 19:59:41 (GMT)
committer Nokis Mavrogiannopoulos <nmav@gnutls.org>2008-02-20 19:59:41 (GMT)
commit75f74f92f068309b2c77d83340008ef7e9c6d2df (patch)
treeddb46be1b66a4d2a9a9b9f6e816a7fedc9031a82
parentaa6fd149d2e558a60b8c022516619c33aee3f75d (diff)
parent9120fdbd1f33e4ed465ee181ec237a68fa27bf2c (diff)
added new branch
-rw-r--r--Makefile.am2
-rw-r--r--NEWS5
-rw-r--r--NOTICE3
-rw-r--r--README34
-rw-r--r--configure.ac16
-rw-r--r--include/mod_gnutls.h.in14
-rw-r--r--src/gnutls_config.c117
-rw-r--r--src/gnutls_hooks.c255
-rw-r--r--src/mod_gnutls.c28
9 files changed, 66 insertions, 408 deletions
diff --git a/Makefile.am b/Makefile.am
index a19e755..205da9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
1AUTOMAKE_OPTIONS = foreign dist-bzip2 1AUTOMAKE_OPTIONS = foreign dist-bzip2
2 2
3EXTRA_DIST = m4/outoforder.m4 m4/apache.m4 \ 3EXTRA_DIST = m4/outoforder.m4 m4/apache.m4 \
4 libgnutls.m4 m4/apr_memcache.m4 \ 4 m4/libgnutls.m4 m4/apr_memcache.m4 \
5 m4/apache_test.m4 m4/lua.m4 \ 5 m4/apache_test.m4 m4/lua.m4 \
6 include/mod_gnutls.h.in \ 6 include/mod_gnutls.h.in \
7 README README.ENV NEWS \ 7 README README.ENV NEWS \
diff --git a/NEWS b/NEWS
index a9fe9fd..49abeda 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,3 @@
1** Version 0.5.0-alpha (2008-01-24)
2
3- Added support for OpenPGP keys. The new directives are:
4 GnuTLSPGPKeyringFile, GnuTLSPGPCertificateFile, GnuTLSPGPKeyFile
5
6** Version 0.4.2 (2007-12-10) 1** Version 0.4.2 (2007-12-10)
7 2
8- Added support for sending a certificate chain. 3- Added support for sending a certificate chain.
diff --git a/NOTICE b/NOTICE
index 25efd6f..7b09606 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,7 +1,4 @@
1This product includes software developed by 1This product includes software developed by
2Nikos Mavrogiannopoulos (http://www.gnutls.org/).
3
4This product includes software developed by
5Paul Querna (http://www.outoforder.cc/). 2Paul Querna (http://www.outoforder.cc/).
6 3
7This product includes software developed by 4This product includes software developed by
diff --git a/README b/README
index 5198ed7..83ced25 100644
--- a/README
+++ b/README
@@ -54,12 +54,13 @@ GnuTLSCache dbm conf/gnutls_cache
54 GnuTLSEnable On 54 GnuTLSEnable On
55 55
56 # This is the Private key for your server. 56 # This is the Private key for your server.
57 GnuTLSX509KeyFile conf/server.key 57 GnuTLSKeyFile conf/server.key
58 58
59 # This is the Server Certificate. 59 # This is the Server Certificate.
60 GnuTLSX509CertificateFile conf/server.cert 60 GnuTLSCertificateFile conf/server.cert
61</VirtualHost> 61</VirtualHost>
62 62
63
63# a more advanced configuration 64# a more advanced configuration
64GnuTLSCache dbm "/var/cache/www-tls-cache/cache" 65GnuTLSCache dbm "/var/cache/www-tls-cache/cache"
65GnuTLSCacheTimeout 600 66GnuTLSCacheTimeout 600
@@ -72,8 +73,8 @@ NameVirtualHost 1.2.3.4:443
72# To export exactly the same environment variables as mod_ssl to CGI scripts. 73# To export exactly the same environment variables as mod_ssl to CGI scripts.
73 GNUTLSExportCertificates on 74 GNUTLSExportCertificates on
74 75
75 GnuTLSX509CertificateFile /etc/apache2/server-cert.pem 76 GnuTLSCertificateFile /etc/apache2/server-cert.pem
76 GnuTLSX509KeyFile /etc/apache2/server-key.pem 77 GnuTLSKeyFile /etc/apache2/server-key.pem
77 78
78# To enable SRP you must have these files installed. Check the gnutls srptool. 79# To enable SRP you must have these files installed. Check the gnutls srptool.
79 GnuTLSSRPPasswdFile /etc/apache2/tpasswd 80 GnuTLSSRPPasswdFile /etc/apache2/tpasswd
@@ -83,29 +84,6 @@ NameVirtualHost 1.2.3.4:443
83# GnuTLSClientVerify could be ignore or require. The GnuTLSClientCAFile 84# GnuTLSClientVerify could be ignore or require. The GnuTLSClientCAFile
84# contains the CAs to verify client certificates. 85# contains the CAs to verify client certificates.
85 GnuTLSClientVerify request 86 GnuTLSClientVerify request
86 GnuTLSX509CAFile ca.pem
87 ...
88</VirtualHost>
89
90# A setup for OpenPGP and X.509 authentication
91<VirtualHost 1.2.3.4:443>
92 Servername crystal.lan:443
93 GnuTLSEnable on
94 GnuTLSPriorities NORMAL:+COMP-NULL
95
96# setup the openpgp keys
97 GnuTLSPGPCertificateFile /etc/apache2/test.pub.asc
98 GnuTLSPGPKeyFile /etc/apache2/test.sec.asc
99
100# and the X.509 keys
101 GnuTLSCertificateFile /etc/apache2/server-cert.pem
102 GnuTLSKeyFile /etc/apache2/server-key.pem
103 GnuTLSClientVerify ignore
104
105# To avoid using the default DH params
106 GnuTLSDHFile /etc/apache2/dh.pem
107
108# these are only needed if GnuTLSClientVerify != ignore
109 GnuTLSClientCAFile ca.pem 87 GnuTLSClientCAFile ca.pem
110 GnuTLSPGPKeyringFile /etc/apache2/ring.asc 88 ...
111</VirtualHost> 89</VirtualHost>
diff --git a/configure.ac b/configure.ac
index 0cdcdd9..259e289 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
1dnl 1dnl
2AC_INIT(mod_gnutls, 0.5.0-alpha) 2AC_INIT(mod_gnutls, 0.4.2.1)
3OOO_CONFIG_NICE(config.nice) 3OOO_CONFIG_NICE(config.nice)
4MOD_GNUTLS_VERSION=AC_PACKAGE_VERSION 4MOD_GNUTLS_VERSION=AC_PACKAGE_VERSION
5AC_PREREQ(2.53) 5AC_PREREQ(2.53)
@@ -28,14 +28,8 @@ CHECK_APACHE(,$AP_VERSION,
28dnl LIBTOOL="`${APR_CONFIG} --apr-libtool`" 28dnl LIBTOOL="`${APR_CONFIG} --apr-libtool`"
29dnl AC_SUBST(LIBTOOL) 29dnl AC_SUBST(LIBTOOL)
30 30
31MIN_TLS_VERSION=2.2.1 31MIN_TLS_VERSION=2.1.7
32AM_PATH_LIBGNUTLS_EXTRA($MIN_TLS_VERSION,, 32CHECK_LIBGNUTLS($MIN_TLS_VERSION)
33 AC_MSG_ERROR([[
34***
35*** libgnutls and libgnutls-extra were not found. You may want to get it from
36*** http://www.gnutls.org/
37***
38]]))
39 33
40dnl CHECK_LUA() 34dnl CHECK_LUA()
41 35
@@ -43,8 +37,8 @@ have_apr_memcache=0
43CHECK_APR_MEMCACHE([have_apr_memcache=1], [have_apr_memcache=0]) 37CHECK_APR_MEMCACHE([have_apr_memcache=1], [have_apr_memcache=0])
44AC_SUBST(have_apr_memcache) 38AC_SUBST(have_apr_memcache)
45 39
46MODULE_CFLAGS="${LIBGNUTLS_EXTRA_CFLAGS} ${APR_MEMCACHE_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES}" 40MODULE_CFLAGS="${LIBGNUTLS_CFLAGS} ${APR_MEMCACHE_CFLAGS} ${APXS_CFLAGS} ${AP_INCLUDES} ${APR_INCLUDES} ${APU_INCLUDES}"
47MODULE_LIBS="${APR_MEMCACHE_LIBS} ${LIBGNUTLS_EXTRA_LIBS}" 41MODULE_LIBS="${APR_MEMCACHE_LIBS} ${LIBGNUTLS_LIBS}"
48 42
49AC_SUBST(MODULE_CFLAGS) 43AC_SUBST(MODULE_CFLAGS)
50AC_SUBST(MODULE_LIBS) 44AC_SUBST(MODULE_LIBS)
diff --git a/include/mod_gnutls.h.in b/include/mod_gnutls.h.in
index db7e7dd..a0f6581 100644
--- a/include/mod_gnutls.h.in
+++ b/include/mod_gnutls.h.in
@@ -29,8 +29,6 @@
29 29
30#include <gcrypt.h> 30#include <gcrypt.h>
31#include <gnutls/gnutls.h> 31#include <gnutls/gnutls.h>
32#include <gnutls/extra.h>
33#include <gnutls/openpgp.h>
34#include <gnutls/x509.h> 32#include <gnutls/x509.h>
35 33
36#ifndef __mod_gnutls_h_inc 34#ifndef __mod_gnutls_h_inc
@@ -96,8 +94,6 @@ typedef struct
96 gnutls_x509_crt_t certs_x509[MAX_CHAIN_SIZE]; /* A certificate chain */ 94 gnutls_x509_crt_t certs_x509[MAX_CHAIN_SIZE]; /* A certificate chain */
97 unsigned int certs_x509_num; 95 unsigned int certs_x509_num;
98 gnutls_x509_privkey_t privkey_x509; 96 gnutls_x509_privkey_t privkey_x509;
99 gnutls_openpgp_crt_t cert_pgp; /* A certificate chain */
100 gnutls_openpgp_privkey_t privkey_pgp;
101 int enabled; 97 int enabled;
102 /* whether to send the PEM encoded certificates 98 /* whether to send the PEM encoded certificates
103 * to CGIs 99 * to CGIs
@@ -112,7 +108,6 @@ typedef struct
112 const char* srp_tpasswd_file; 108 const char* srp_tpasswd_file;
113 const char* srp_tpasswd_conf_file; 109 const char* srp_tpasswd_conf_file;
114 gnutls_x509_crt_t ca_list[MAX_CA_CRTS]; 110 gnutls_x509_crt_t ca_list[MAX_CA_CRTS];
115 gnutls_openpgp_keyring_t pgp_list;
116 unsigned int ca_list_size; 111 unsigned int ca_list_size;
117 int client_verify_mode; 112 int client_verify_mode;
118} mgs_srvconf_rec; 113} mgs_srvconf_rec;
@@ -259,12 +254,6 @@ const char *mgs_set_cert_file(cmd_parms * parms, void *dummy,
259const char *mgs_set_key_file(cmd_parms * parms, void *dummy, 254const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
260 const char *arg); 255 const char *arg);
261 256
262const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
263 const char *arg);
264
265const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
266 const char *arg);
267
268const char *mgs_set_cache(cmd_parms * parms, void *dummy, 257const char *mgs_set_cache(cmd_parms * parms, void *dummy,
269 const char *type, const char* arg); 258 const char *type, const char* arg);
270 259
@@ -277,9 +266,6 @@ const char *mgs_set_client_verify(cmd_parms * parms, void *dummy,
277const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy, 266const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
278 const char *arg); 267 const char *arg);
279 268
280const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
281 const char *arg);
282
283const char *mgs_set_enabled(cmd_parms * parms, void *dummy, 269const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
284 const char *arg); 270 const char *arg);
285const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy, 271const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy,
diff --git a/src/gnutls_config.c b/src/gnutls_config.c
index f08512e..8d6308a 100644
--- a/src/gnutls_config.c
+++ b/src/gnutls_config.c
@@ -1,6 +1,5 @@
1/** 1/**
2 * Copyright 2004-2005 Paul Querna 2 * Copyright 2004-2005 Paul Querna
3 * Copyright 2007 Nikos Mavrogiannopoulos
4 * 3 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -203,84 +202,6 @@ const char *mgs_set_key_file(cmd_parms * parms, void *dummy,
203 return NULL; 202 return NULL;
204} 203}
205 204
206const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
207 const char *arg)
208{
209 int ret;
210 gnutls_datum_t data;
211 const char *file;
212 apr_pool_t *spool;
213 mgs_srvconf_rec *sc =
214 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
215 module_config,
216 &gnutls_module);
217 apr_pool_create(&spool, parms->pool);
218
219 file = ap_server_root_relative(spool, arg);
220
221 if (load_datum_from_file(spool, file, &data) != 0) {
222 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
223 "Certificate '%s'", file);
224 }
225
226 ret = gnutls_openpgp_crt_init( &sc->cert_pgp);
227 if (ret < 0) {
228 return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
229 "PGP Certificate: (%d) %s", ret,
230 gnutls_strerror(ret));
231 }
232
233 ret =
234 gnutls_openpgp_crt_import(sc->cert_pgp, &data, GNUTLS_OPENPGP_FMT_BASE64);
235 if (ret < 0) {
236 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
237 "PGP Certificate '%s': (%d) %s", file, ret,
238 gnutls_strerror(ret));
239 }
240
241 apr_pool_destroy(spool);
242 return NULL;
243}
244
245const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
246 const char *arg)
247{
248 int ret;
249 gnutls_datum_t data;
250 const char *file;
251 apr_pool_t *spool;
252 mgs_srvconf_rec *sc =
253 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
254 module_config,
255 &gnutls_module);
256 apr_pool_create(&spool, parms->pool);
257
258 file = ap_server_root_relative(spool, arg);
259
260 if (load_datum_from_file(spool, file, &data) != 0) {
261 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
262 "Private Key '%s'", file);
263 }
264
265 ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp);
266 if (ret < 0) {
267 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
268 ": (%d) %s", ret, gnutls_strerror(ret));
269 }
270
271 ret =
272 gnutls_openpgp_privkey_import(sc->privkey_pgp, &data,
273 GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
274 if (ret != 0) {
275 return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
276 "PGP Private Key '%s': (%d) %s", file, ret,
277 gnutls_strerror(ret));
278 }
279 apr_pool_destroy(spool);
280 return NULL;
281}
282
283
284const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy, 205const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
285 const char *arg) 206 const char *arg)
286{ 207{
@@ -429,44 +350,6 @@ const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
429 return NULL; 350 return NULL;
430} 351}
431 352
432const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
433 const char *arg)
434{
435 int rv;
436 const char *file;
437 apr_pool_t *spool;
438 gnutls_datum_t data;
439
440 mgs_srvconf_rec *sc =
441 (mgs_srvconf_rec *) ap_get_module_config(parms->server->
442 module_config,
443 &gnutls_module);
444 apr_pool_create(&spool, parms->pool);
445
446 file = ap_server_root_relative(spool, arg);
447
448 if (load_datum_from_file(spool, file, &data) != 0) {
449 return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
450 "Keyring File '%s'", file);
451 }
452
453 rv = gnutls_openpgp_keyring_init(&sc->pgp_list);
454 if (rv < 0) {
455 return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
456 "keyring: (%d) %s", rv, gnutls_strerror(rv));
457 }
458
459 rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64);
460 if (rv < 0) {
461 return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
462 "Keyring File '%s': (%d) %s", file, rv,
463 gnutls_strerror(rv));
464 }
465
466 apr_pool_destroy(spool);
467 return NULL;
468}
469
470const char *mgs_set_enabled(cmd_parms * parms, void *dummy, 353const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
471 const char *arg) 354 const char *arg)
472{ 355{
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c
index 26917b8..55a1120 100644
--- a/src/gnutls_hooks.c
+++ b/src/gnutls_hooks.c
@@ -36,10 +36,7 @@ static int mpm_is_threaded;
36 36
37static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); 37static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt);
38/* use side==0 for server and side==1 for client */ 38/* use side==0 for server and side==1 for client */
39static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, 39static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert,
40 int side,
41 int export_certificates_enabled);
42static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert,
43 int side, 40 int side,
44 int export_certificates_enabled); 41 int export_certificates_enabled);
45 42
@@ -71,23 +68,9 @@ int ret;
71 mpm_is_threaded = 0; 68 mpm_is_threaded = 0;
72#endif 69#endif
73 70
74 if (gnutls_check_version(LIBGNUTLS_VERSION)==NULL) {
75 fprintf(stderr, "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n",
76 LIBGNUTLS_VERSION, gnutls_check_version(NULL));
77 return -3;
78 }
79
80 ret = gnutls_global_init(); 71 ret = gnutls_global_init();
81 if (ret < 0) { 72 if (ret < 0) /* FIXME: can we print here? */
82 fprintf(stderr, "gnutls_global_init: %s\n", gnutls_strerror(ret)); 73 exit(ret);
83 return -3;
84 }
85
86 ret = gnutls_global_init_extra();
87 if (ret < 0) {
88 fprintf(stderr, "gnutls_global_init_extra: %s\n", gnutls_strerror(ret));
89 return -3;
90 }
91 74
92 apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config, 75 apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config,
93 apr_pool_cleanup_null); 76 apr_pool_cleanup_null);
@@ -99,18 +82,19 @@ int ret;
99 82
100 gnutls_global_set_log_level(9); 83 gnutls_global_set_log_level(9);
101 gnutls_global_set_log_function(gnutls_debug_log_all); 84 gnutls_global_set_log_function(gnutls_debug_log_all);
102 apr_file_printf(debug_log_fp, "gnutls: %s\n", gnutls_check_version(NULL));
103#endif 85#endif
104 86
105 return OK; 87 return OK;
106} 88}
107 89
90/* We don't support openpgp certificates, yet */
91const static int cert_type_prio[2] = { GNUTLS_CRT_X509, 0 };
92
108static int mgs_select_virtual_server_cb(gnutls_session_t session) 93static int mgs_select_virtual_server_cb(gnutls_session_t session)
109{ 94{
110 mgs_handle_t *ctxt; 95 mgs_handle_t *ctxt;
111 mgs_srvconf_rec *tsc; 96 mgs_srvconf_rec *tsc;
112 int ret; 97 int ret;
113 int cprio[2];
114 98
115 ctxt = gnutls_transport_get_ptr(session); 99 ctxt = gnutls_transport_get_ptr(session);
116 100
@@ -142,22 +126,13 @@ static int mgs_select_virtual_server_cb(gnutls_session_t session)
142 * negotiation. 126 * negotiation.
143 */ 127 */
144 ret = gnutls_priority_set(session, ctxt->sc->priorities); 128 ret = gnutls_priority_set(session, ctxt->sc->priorities);
129 gnutls_certificate_type_set_priority(session, cert_type_prio);
130
131
145 /* actually it shouldn't fail since we have checked at startup */ 132 /* actually it shouldn't fail since we have checked at startup */
146 if (ret < 0) 133 if (ret < 0)
147 return ret; 134 return ret;
148 135
149 /* If both certificate types are not present disallow them from
150 * being negotiated.
151 */
152 if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) {
153 cprio[0] = GNUTLS_CRT_X509;
154 cprio[1] = 0;
155 gnutls_certificate_type_set_priority( session, cprio);
156 } else if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0]==NULL) {
157 cprio[0] = GNUTLS_CRT_OPENPGP;
158 cprio[1] = 0;
159 gnutls_certificate_type_set_priority( session, cprio);
160 }
161 136
162 return 0; 137 return 0;
163} 138}
@@ -168,31 +143,15 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret)
168 143
169 ctxt = gnutls_transport_get_ptr(session); 144 ctxt = gnutls_transport_get_ptr(session);
170 145
171 if (gnutls_certificate_type_get( session) == GNUTLS_CRT_X509) { 146 ret->type = GNUTLS_CRT_X509;
172 ret->type = GNUTLS_CRT_X509; 147 ret->ncerts = ctxt->sc->certs_x509_num;
173 ret->ncerts = ctxt->sc->certs_x509_num; 148 ret->deinit_all = 0;
174 ret->deinit_all = 0;
175
176 ret->cert.x509 = ctxt->sc->certs_x509;
177 ret->key.x509 = ctxt->sc->privkey_x509;
178
179 return 0;
180 } else if (gnutls_certificate_type_get( session) == GNUTLS_CRT_OPENPGP) {
181 ret->type = GNUTLS_CRT_OPENPGP;
182 ret->ncerts = 1;
183 ret->deinit_all = 0;
184
185 ret->cert.pgp = ctxt->sc->cert_pgp;
186 ret->key.pgp = ctxt->sc->privkey_pgp;
187
188 return 0;
189
190 }
191 149
192 return GNUTLS_E_INTERNAL_ERROR; 150 ret->cert.x509 = ctxt->sc->certs_x509;
151 ret->key.x509 = ctxt->sc->privkey_x509;
152 return 0;
193} 153}
194 154
195/* 2048-bit group parameters from SRP specification */
196const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" 155const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
197 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" 156 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n"
198 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" 157 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n"
@@ -208,7 +167,7 @@ const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n"
208 * Returns negative on error. 167 * Returns negative on error.
209 */ 168 */
210static int read_crt_cn(server_rec * s, apr_pool_t * p, 169static int read_crt_cn(server_rec * s, apr_pool_t * p,
211 gnutls_x509_crt_t cert, char **cert_cn) 170 gnutls_x509_crt cert, char **cert_cn)
212{ 171{
213 int rv = 0, i; 172 int rv = 0, i;
214 size_t data_len; 173 size_t data_len;
@@ -216,7 +175,6 @@ static int read_crt_cn(server_rec * s, apr_pool_t * p,
216 175
217 *cert_cn = NULL; 176 *cert_cn = NULL;
218 177
219 data_len = 0;
220 rv = gnutls_x509_crt_get_dn_by_oid(cert, 178 rv = gnutls_x509_crt_get_dn_by_oid(cert,
221 GNUTLS_OID_X520_COMMON_NAME, 179 GNUTLS_OID_X520_COMMON_NAME,
222 0, 0, NULL, &data_len); 180 0, 0, NULL, &data_len);
@@ -227,8 +185,8 @@ static int read_crt_cn(server_rec * s, apr_pool_t * p,
227 GNUTLS_OID_X520_COMMON_NAME, 0, 185 GNUTLS_OID_X520_COMMON_NAME, 0,
228 0, *cert_cn, &data_len); 186 0, *cert_cn, &data_len);
229 } else { /* No CN return subject alternative name */ 187 } else { /* No CN return subject alternative name */
230 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 188 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
231 "No common name found in certificate for '%s:%d'. Looking for subject alternative name...", 189 "No common name found in certificate for '%s:%d'. Looking for subject alternative name.",
232 s->server_hostname, s->port); 190 s->server_hostname, s->port);
233 rv = 0; 191 rv = 0;
234 /* read subject alternative name */ 192 /* read subject alternative name */
@@ -256,33 +214,9 @@ static int read_crt_cn(server_rec * s, apr_pool_t * p,
256 } 214 }
257 215
258 return rv; 216 return rv;
259}
260
261static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p,
262 gnutls_openpgp_crt_t cert, char **cert_cn)
263{
264 int rv = 0;
265 size_t data_len;
266
267 217
268 *cert_cn = NULL;
269
270 data_len = 0;
271 rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len);
272
273 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
274 *cert_cn = apr_palloc(p, data_len);
275 rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, &data_len);
276 } else { /* No CN return subject alternative name */
277 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
278 "No name found in PGP certificate for '%s:%d'.",
279 s->server_hostname, s->port);
280 }
281
282 return rv;
283} 218}
284 219
285
286int 220int
287mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, 221mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
288 apr_pool_t * ptemp, server_rec * base_server) 222 apr_pool_t * ptemp, server_rec * base_server)
@@ -416,9 +350,6 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog,
416 350
417 if (sc->enabled == GNUTLS_ENABLED_TRUE) { 351 if (sc->enabled == GNUTLS_ENABLED_TRUE) {
418 rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); 352 rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn);
419 if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */
420 rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn);
421
422 if (rv < 0) { 353 if (rv < 0) {
423 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 354 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
424 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", 355 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!",
@@ -547,6 +478,15 @@ mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session)
547 478
548 ctxt = gnutls_transport_get_ptr(session); 479 ctxt = gnutls_transport_get_ptr(session);
549 480
481 sni_type = gnutls_certificate_type_get(session);
482 if (sni_type != GNUTLS_CRT_X509) {
483 /* In theory, we could support OpenPGP Certificates. Theory != code. */
484 ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
485 ctxt->c->base_server,
486 "GnuTLS: Only x509 Certificates are currently supported.");
487 return NULL;
488 }
489
550 rv = gnutls_server_name_get(ctxt->session, sni_name, 490 rv = gnutls_server_name_get(ctxt->session, sni_name,
551 &data_len, &sni_type, 0); 491 &data_len, &sni_type, 0);
552 492
@@ -744,11 +684,7 @@ int mgs_hook_fixups(request_rec * r)
744 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); 684 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
745 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); 685 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
746 686
747 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 687 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
748 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
749 ctxt->sc->export_certificates_enabled);
750 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
751 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0,
752 ctxt->sc->export_certificates_enabled); 688 ctxt->sc->export_certificates_enabled);
753 689
754 return rv; 690 return rv;
@@ -810,7 +746,7 @@ int mgs_hook_authz(request_rec * r)
810 */ 746 */
811#define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT") 747#define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT")
812static void 748static void
813mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, 749mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side,
814 int export_certificates_enabled) 750 int export_certificates_enabled)
815{ 751{
816 unsigned char sbuf[64]; /* buffer to hold serials */ 752 unsigned char sbuf[64]; /* buffer to hold serials */
@@ -916,82 +852,17 @@ mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side,
916 } 852 }
917 } 853 }
918 } 854 }
919}
920
921static void
922mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side,
923 int export_certificates_enabled)
924{
925 unsigned char sbuf[64]; /* buffer to hold serials */
926 char buf[AP_IOBUFSIZE];
927 const char *tmp;
928 size_t len;
929 int ret;
930
931 apr_table_t *env = r->subprocess_env;
932
933 if (export_certificates_enabled != 0) {
934 char cert_buf[10 * 1024];
935 len = sizeof(cert_buf);
936
937 if (gnutls_openpgp_crt_export
938 (cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0)
939 apr_table_setn(env,
940 apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL),
941 apr_pstrmemdup(r->pool, cert_buf, len));
942
943 }
944
945 len = sizeof(buf);
946 gnutls_openpgp_crt_get_name(cert, 0, buf, &len);
947 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_NAME", NULL),
948 apr_pstrmemdup(r->pool, buf, len));
949 855
950 len = sizeof(sbuf);
951 gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len);
952 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
953 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_FINGERPRINT", NULL),
954 apr_pstrdup(r->pool, tmp));
955
956 ret = gnutls_openpgp_crt_get_version(cert);
957 if (ret > 0)
958 apr_table_setn(env,
959 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL),
960 apr_psprintf(r->pool, "%u", ret));
961
962 apr_table_setn(env,
963 apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "OPENPGP");
964
965 tmp =
966 mgs_time2sz(gnutls_openpgp_crt_get_expiration_time
967 (cert), buf, sizeof(buf));
968 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
969 apr_pstrdup(r->pool, tmp));
970
971 tmp =
972 mgs_time2sz(gnutls_openpgp_crt_get_creation_time
973 (cert), buf, sizeof(buf));
974 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
975 apr_pstrdup(r->pool, tmp));
976
977 ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL);
978 if (ret >= 0) {
979 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL),
980 gnutls_pk_algorithm_get_name(ret));
981 }
982 856
983} 857}
984 858
985/* TODO: Allow client sending a X.509 certificate chain */ 859
986static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) 860static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
987{ 861{
988 const gnutls_datum_t *cert_list; 862 const gnutls_datum_t *cert_list;
989 unsigned int cert_list_size, status, expired; 863 unsigned int cert_list_size, status, expired;
990 int rv, ret; 864 int rv, ret;
991 union { 865 gnutls_x509_crt_t cert;
992 gnutls_x509_crt_t x509;
993 gnutls_openpgp_crt_t pgp;
994 } cert;
995 apr_time_t activation_time, expiration_time, cur_time; 866 apr_time_t activation_time, expiration_time, cur_time;
996 867
997 cert_list = 868 cert_list =
@@ -1017,56 +888,32 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
1017 return HTTP_FORBIDDEN; 888 return HTTP_FORBIDDEN;
1018 } 889 }
1019 890
1020 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { 891 gnutls_x509_crt_init(&cert);
1021 gnutls_x509_crt_init(&cert.x509); 892 rv = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
1022 rv = gnutls_x509_crt_import(cert.x509, &cert_list[0], GNUTLS_X509_FMT_DER);
1023 } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) {
1024 gnutls_openpgp_crt_init(&cert.pgp);
1025 rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
1026 } else return HTTP_FORBIDDEN;
1027
1028 if (rv < 0) { 893 if (rv < 0) {
1029 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 894 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
1030 "GnuTLS: Failed to Verify Peer: " 895 "GnuTLS: Failed to Verify Peer: "
1031 "Failed to import peer certificates."); 896 "Failed to import peer certificates.");
1032 ret = HTTP_FORBIDDEN; 897 ret = HTTP_FORBIDDEN;
1033 goto exit; 898 goto exit;
1034 } 899 }
1035 900
1036 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { 901 apr_time_ansi_put(&expiration_time,
1037 apr_time_ansi_put(&expiration_time, 902 gnutls_x509_crt_get_expiration_time(cert));
1038 gnutls_x509_crt_get_expiration_time(cert.x509)); 903 apr_time_ansi_put(&activation_time,
1039 apr_time_ansi_put(&activation_time, 904 gnutls_x509_crt_get_activation_time(cert));
1040 gnutls_x509_crt_get_activation_time(cert.x509));
1041 905
1042 rv = gnutls_x509_crt_verify(cert.x509, ctxt->sc->ca_list, 906 rv = gnutls_x509_crt_verify(cert, ctxt->sc->ca_list,
1043 ctxt->sc->ca_list_size, 0, &status); 907 ctxt->sc->ca_list_size, 0, &status);
1044 } else {
1045 apr_time_ansi_put(&expiration_time,
1046 gnutls_openpgp_crt_get_expiration_time(cert.pgp));
1047 apr_time_ansi_put(&activation_time,
1048 gnutls_openpgp_crt_get_creation_time(cert.pgp));
1049
1050 rv = gnutls_openpgp_crt_verify_ring(cert.pgp, ctxt->sc->pgp_list,
1051 0, &status);
1052 }
1053 908
1054 if (rv < 0) { 909 if (rv < 0) {
1055 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 910 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
1056 "GnuTLS: Failed to Verify Peer certificate: (%d) %s", 911 "GnuTLS: Failed to Verify Peer certificate: (%d) %s",
1057 rv, gnutls_strerror(rv)); 912 rv, gnutls_strerror(rv));
1058 if (rv == GNUTLS_E_NO_CERTIFICATE_FOUND)
1059 ap_log_rerror(APLOG_MARK, APLOG_EMERG, 0, r,
1060 "GnuTLS: No certificate was found for verification. Did you set the GnuTLSX509CAFile or GnuTLSPGPKeyringFile directives?");
1061 ret = HTTP_FORBIDDEN; 913 ret = HTTP_FORBIDDEN;
1062 goto exit; 914 goto exit;
1063 } 915 }
1064 916
1065 /* TODO: X509 CRL Verification. */
1066 /* May add later if anyone needs it.
1067 */
1068 /* ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size); */
1069
1070 expired = 0; 917 expired = 0;
1071 cur_time = apr_time_now(); 918 cur_time = apr_time_now();
1072 if (activation_time > cur_time) { 919 if (activation_time > cur_time) {
@@ -1101,11 +948,16 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
1101 "GnuTLS: Peer Certificate is revoked."); 948 "GnuTLS: Peer Certificate is revoked.");
1102 } 949 }
1103 950
1104 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 951 /* TODO: Further Verification. */
1105 mgs_add_common_cert_vars(r, cert.x509, 1, 952 /* Revocation is X.509 non workable paradigm, I really doubt implementation
1106 ctxt->sc->export_certificates_enabled); 953 * is worth doing --nmav
1107 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) 954 */
1108 mgs_add_common_pgpcert_vars(r, cert.pgp, 1, 955/// ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size);
956
957// mgs_hook_fixups(r);
958// rv = mgs_authz_lua(r);
959
960 mgs_add_common_cert_vars(r, cert, 1,
1109 ctxt->sc->export_certificates_enabled); 961 ctxt->sc->export_certificates_enabled);
1110 962
1111 { 963 {
@@ -1129,10 +981,7 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
1129 } 981 }
1130 982
1131 exit: 983 exit:
1132 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 984 gnutls_x509_crt_deinit(cert);
1133 gnutls_x509_crt_deinit(cert.x509);
1134 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
1135 gnutls_openpgp_crt_deinit(cert.pgp);
1136 return ret; 985 return ret;
1137 986
1138 987
diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c
index 014bfc8..a6e5528 100644
--- a/src/mod_gnutls.c
+++ b/src/mod_gnutls.c
@@ -64,14 +64,6 @@ static const command_rec mgs_config_cmds[] = {
64 NULL, 64 NULL,
65 RSRC_CONF, 65 RSRC_CONF,
66 "Set the CA File to verify Client Certificates"), 66 "Set the CA File to verify Client Certificates"),
67 AP_INIT_TAKE1("GnuTLSX509CAFile", mgs_set_client_ca_file,
68 NULL,
69 RSRC_CONF,
70 "Set the CA File to verify Client Certificates"),
71 AP_INIT_TAKE1("GnuTLSPGPKeyringFile", mgs_set_keyring_file,
72 NULL,
73 RSRC_CONF,
74 "Set the Keyring File to verify Client Certificates"),
75 AP_INIT_TAKE1("GnuTLSDHFile", mgs_set_dh_file, 67 AP_INIT_TAKE1("GnuTLSDHFile", mgs_set_dh_file,
76 NULL, 68 NULL,
77 RSRC_CONF, 69 RSRC_CONF,
@@ -83,27 +75,11 @@ static const command_rec mgs_config_cmds[] = {
83 AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file, 75 AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file,
84 NULL, 76 NULL,
85 RSRC_CONF, 77 RSRC_CONF,
86 "SSL Server X509 Certificate file"), 78 "SSL Server Key file"),
87 AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file, 79 AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file,
88 NULL, 80 NULL,
89 RSRC_CONF, 81 RSRC_CONF,
90 "SSL Server X509 Private Key file"), 82 "SSL Server SRP Password file"),
91 AP_INIT_TAKE1("GnuTLSX509CertificateFile", mgs_set_cert_file,
92 NULL,
93 RSRC_CONF,
94 "SSL Server X509 Certificate file"),
95 AP_INIT_TAKE1("GnuTLSX509KeyFile", mgs_set_key_file,
96 NULL,
97 RSRC_CONF,
98 "SSL Server X509 Private Key file"),
99 AP_INIT_TAKE1("GnuTLSPGPCertificateFile", mgs_set_pgpcert_file,
100 NULL,
101 RSRC_CONF,
102 "SSL Server PGP Certificate file"),
103 AP_INIT_TAKE1("GnuTLSPGPKeyFile", mgs_set_pgpkey_file,
104 NULL,
105 RSRC_CONF,
106 "SSL Server PGP Private key file"),
107 AP_INIT_TAKE1("GnuTLSSRPPasswdFile", mgs_set_srp_tpasswd_file, 83 AP_INIT_TAKE1("GnuTLSSRPPasswdFile", mgs_set_srp_tpasswd_file,
108 NULL, 84 NULL,
109 RSRC_CONF, 85 RSRC_CONF,