diff options
-rw-r--r-- | README | 10 | ||||
-rw-r--r-- | src/gnutls_config.c | 8 | ||||
-rw-r--r-- | src/gnutls_hooks.c | 53 | ||||
-rw-r--r-- | src/mod_gnutls.c | 16 |
4 files changed, 55 insertions, 32 deletions
@@ -54,10 +54,10 @@ 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 | GnuTLSKeyFile conf/server.key | 57 | GnuTLSX509KeyFile conf/server.key |
58 | 58 | ||
59 | # This is the Server Certificate. | 59 | # This is the Server Certificate. |
60 | GnuTLSCertificateFile conf/server.cert | 60 | GnuTLSX509CertificateFile conf/server.cert |
61 | </VirtualHost> | 61 | </VirtualHost> |
62 | 62 | ||
63 | 63 | ||
@@ -73,8 +73,8 @@ NameVirtualHost 1.2.3.4:443 | |||
73 | # 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. |
74 | GNUTLSExportCertificates on | 74 | GNUTLSExportCertificates on |
75 | 75 | ||
76 | GnuTLSCertificateFile /etc/apache2/server-cert.pem | 76 | GnuTLSX509CertificateFile /etc/apache2/server-cert.pem |
77 | GnuTLSKeyFile /etc/apache2/server-key.pem | 77 | GnuTLSX509KeyFile /etc/apache2/server-key.pem |
78 | 78 | ||
79 | # 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. |
80 | GnuTLSSRPPasswdFile /etc/apache2/tpasswd | 80 | GnuTLSSRPPasswdFile /etc/apache2/tpasswd |
@@ -84,6 +84,6 @@ NameVirtualHost 1.2.3.4:443 | |||
84 | # GnuTLSClientVerify could be ignore or require. The GnuTLSClientCAFile | 84 | # GnuTLSClientVerify could be ignore or require. The GnuTLSClientCAFile |
85 | # contains the CAs to verify client certificates. | 85 | # contains the CAs to verify client certificates. |
86 | GnuTLSClientVerify request | 86 | GnuTLSClientVerify request |
87 | GnuTLSClientCAFile ca.pem | 87 | GnuTLSX509CAFile ca.pem |
88 | ... | 88 | ... |
89 | </VirtualHost> | 89 | </VirtualHost> |
diff --git a/src/gnutls_config.c b/src/gnutls_config.c index 4dccd08..f08512e 100644 --- a/src/gnutls_config.c +++ b/src/gnutls_config.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright 2004-2005 Paul Querna | 2 | * Copyright 2004-2005 Paul Querna |
3 | * Copyright 2007 Nikos Mavrogiannopoulos | ||
3 | * | 4 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. | 6 | * you may not use this file except in compliance with the License. |
@@ -229,7 +230,6 @@ const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy, | |||
229 | gnutls_strerror(ret)); | 230 | gnutls_strerror(ret)); |
230 | } | 231 | } |
231 | 232 | ||
232 | |||
233 | ret = | 233 | ret = |
234 | gnutls_openpgp_crt_import(sc->cert_pgp, &data, GNUTLS_OPENPGP_FMT_BASE64); | 234 | gnutls_openpgp_crt_import(sc->cert_pgp, &data, GNUTLS_OPENPGP_FMT_BASE64); |
235 | if (ret < 0) { | 235 | if (ret < 0) { |
@@ -450,6 +450,12 @@ const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy, | |||
450 | "Keyring File '%s'", file); | 450 | "Keyring File '%s'", file); |
451 | } | 451 | } |
452 | 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 | |||
453 | rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64); | 459 | rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64); |
454 | if (rv < 0) { | 460 | if (rv < 0) { |
455 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " | 461 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " |
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index 6223d89..70254bb 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c | |||
@@ -71,14 +71,20 @@ int ret; | |||
71 | mpm_is_threaded = 0; | 71 | mpm_is_threaded = 0; |
72 | #endif | 72 | #endif |
73 | 73 | ||
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 | |||
74 | ret = gnutls_global_init(); | 80 | ret = gnutls_global_init(); |
75 | if (ret < 0) /* FIXME: can we print here? */ { | 81 | if (ret < 0) { |
76 | fprintf(stderr, "gnutls_global_init: %s\n", gnutls_strerror(ret)); | 82 | fprintf(stderr, "gnutls_global_init: %s\n", gnutls_strerror(ret)); |
77 | return -3; | 83 | return -3; |
78 | } | 84 | } |
79 | 85 | ||
80 | ret = gnutls_global_init_extra(); | 86 | ret = gnutls_global_init_extra(); |
81 | if (ret < 0) { /* FIXME: can we print here? */ | 87 | if (ret < 0) { |
82 | fprintf(stderr, "gnutls_global_init_extra: %s\n", gnutls_strerror(ret)); | 88 | fprintf(stderr, "gnutls_global_init_extra: %s\n", gnutls_strerror(ret)); |
83 | return -3; | 89 | return -3; |
84 | } | 90 | } |
@@ -93,6 +99,7 @@ int ret; | |||
93 | 99 | ||
94 | gnutls_global_set_log_level(9); | 100 | gnutls_global_set_log_level(9); |
95 | gnutls_global_set_log_function(gnutls_debug_log_all); | 101 | gnutls_global_set_log_function(gnutls_debug_log_all); |
102 | apr_file_printf(debug_log_fp, "gnutls: %s\n", gnutls_check_version(NULL)); | ||
96 | #endif | 103 | #endif |
97 | 104 | ||
98 | return OK; | 105 | return OK; |
@@ -103,7 +110,7 @@ static int mgs_select_virtual_server_cb(gnutls_session_t session) | |||
103 | mgs_handle_t *ctxt; | 110 | mgs_handle_t *ctxt; |
104 | mgs_srvconf_rec *tsc; | 111 | mgs_srvconf_rec *tsc; |
105 | int ret; | 112 | int ret; |
106 | int cprio[3] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; | 113 | int cprio[2]; |
107 | 114 | ||
108 | ctxt = gnutls_transport_get_ptr(session); | 115 | ctxt = gnutls_transport_get_ptr(session); |
109 | 116 | ||
@@ -135,24 +142,23 @@ static int mgs_select_virtual_server_cb(gnutls_session_t session) | |||
135 | * negotiation. | 142 | * negotiation. |
136 | */ | 143 | */ |
137 | ret = gnutls_priority_set(session, ctxt->sc->priorities); | 144 | ret = gnutls_priority_set(session, ctxt->sc->priorities); |
145 | /* actually it shouldn't fail since we have checked at startup */ | ||
146 | if (ret < 0) | ||
147 | return ret; | ||
138 | 148 | ||
139 | /* Do not allow the user to override certificate priorities. We know | 149 | /* If both certificate types are not present disallow them from |
140 | * better if the certificate of certain type is enabled. */ | 150 | * being negotiated. |
141 | if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0] != NULL) { | 151 | */ |
142 | gnutls_certificate_type_set_priority( session, cprio); | 152 | if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) { |
143 | } else if (ctxt->sc->certs_x509[0] != NULL) { | ||
144 | cprio[0] = GNUTLS_CRT_X509; | 153 | cprio[0] = GNUTLS_CRT_X509; |
145 | cprio[1] = 0; | 154 | cprio[1] = 0; |
146 | gnutls_certificate_type_set_priority( session, cprio); | 155 | gnutls_certificate_type_set_priority( session, cprio); |
147 | } else if (ctxt->sc->cert_pgp != NULL) { | 156 | } else if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0]==NULL) { |
148 | cprio[0] = GNUTLS_CRT_OPENPGP; | 157 | cprio[0] = GNUTLS_CRT_OPENPGP; |
149 | cprio[1] = 0; | 158 | cprio[1] = 0; |
150 | gnutls_certificate_type_set_priority( session, cprio); | 159 | gnutls_certificate_type_set_priority( session, cprio); |
151 | } | 160 | } |
152 | 161 | ||
153 | /* actually it shouldn't fail since we have checked at startup */ | ||
154 | if (ret < 0) | ||
155 | return ret; | ||
156 | 162 | ||
157 | 163 | ||
158 | return 0; | 164 | return 0; |
@@ -188,6 +194,7 @@ static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret) | |||
188 | return GNUTLS_E_INTERNAL_ERROR; | 194 | return GNUTLS_E_INTERNAL_ERROR; |
189 | } | 195 | } |
190 | 196 | ||
197 | /* 2048-bit group parameters from SRP specification */ | ||
191 | const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" | 198 | const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" |
192 | "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" | 199 | "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" |
193 | "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" | 200 | "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" |
@@ -411,7 +418,7 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | |||
411 | 418 | ||
412 | if (sc->enabled == GNUTLS_ENABLED_TRUE) { | 419 | if (sc->enabled == GNUTLS_ENABLED_TRUE) { |
413 | rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); | 420 | rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); |
414 | if (rv < 0) /* try openpgp certificate */ | 421 | if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */ |
415 | rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn); | 422 | rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn); |
416 | 423 | ||
417 | if (rv < 0) { | 424 | if (rv < 0) { |
@@ -977,7 +984,7 @@ mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side | |||
977 | 984 | ||
978 | } | 985 | } |
979 | 986 | ||
980 | /* FIXME: Allow client sending a certificate chain */ | 987 | /* TODO: Allow client sending a X.509 certificate chain */ |
981 | static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | 988 | static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) |
982 | { | 989 | { |
983 | const gnutls_datum_t *cert_list; | 990 | const gnutls_datum_t *cert_list; |
@@ -1046,15 +1053,22 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1046 | 0, &status); | 1053 | 0, &status); |
1047 | } | 1054 | } |
1048 | 1055 | ||
1049 | |||
1050 | if (rv < 0) { | 1056 | if (rv < 0) { |
1051 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 1057 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
1052 | "GnuTLS: Failed to Verify Peer certificate: (%d) %s", | 1058 | "GnuTLS: Failed to Verify Peer certificate: (%d) %s", |
1053 | rv, gnutls_strerror(rv)); | 1059 | rv, gnutls_strerror(rv)); |
1060 | if (rv == GNUTLS_E_NO_CERTIFICATE_FOUND) | ||
1061 | ap_log_rerror(APLOG_MARK, APLOG_EMERG, 0, r, | ||
1062 | "GnuTLS: No certificate was found for verification. Did you set the GnuTLSX509CAFile or GnuTLSPGPKeyringFile directives?"); | ||
1054 | ret = HTTP_FORBIDDEN; | 1063 | ret = HTTP_FORBIDDEN; |
1055 | goto exit; | 1064 | goto exit; |
1056 | } | 1065 | } |
1057 | 1066 | ||
1067 | /* TODO: X509 CRL Verification. */ | ||
1068 | /* May add later if anyone needs it. | ||
1069 | */ | ||
1070 | /* ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size); */ | ||
1071 | |||
1058 | expired = 0; | 1072 | expired = 0; |
1059 | cur_time = apr_time_now(); | 1073 | cur_time = apr_time_now(); |
1060 | if (activation_time > cur_time) { | 1074 | if (activation_time > cur_time) { |
@@ -1089,15 +1103,6 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1089 | "GnuTLS: Peer Certificate is revoked."); | 1103 | "GnuTLS: Peer Certificate is revoked."); |
1090 | } | 1104 | } |
1091 | 1105 | ||
1092 | /* TODO: Further Verification. */ | ||
1093 | /* Revocation is X.509 non workable paradigm, I really doubt implementation | ||
1094 | * is worth doing --nmav | ||
1095 | */ | ||
1096 | /// ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size); | ||
1097 | |||
1098 | // mgs_hook_fixups(r); | ||
1099 | // rv = mgs_authz_lua(r); | ||
1100 | |||
1101 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) | 1106 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) |
1102 | mgs_add_common_cert_vars(r, cert.x509, 1, | 1107 | mgs_add_common_cert_vars(r, cert.x509, 1, |
1103 | ctxt->sc->export_certificates_enabled); | 1108 | ctxt->sc->export_certificates_enabled); |
diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c index 4d70fbd..014bfc8 100644 --- a/src/mod_gnutls.c +++ b/src/mod_gnutls.c | |||
@@ -64,6 +64,10 @@ 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"), | ||
67 | AP_INIT_TAKE1("GnuTLSPGPKeyringFile", mgs_set_keyring_file, | 71 | AP_INIT_TAKE1("GnuTLSPGPKeyringFile", mgs_set_keyring_file, |
68 | NULL, | 72 | NULL, |
69 | RSRC_CONF, | 73 | RSRC_CONF, |
@@ -79,11 +83,19 @@ static const command_rec mgs_config_cmds[] = { | |||
79 | AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file, | 83 | AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file, |
80 | NULL, | 84 | NULL, |
81 | RSRC_CONF, | 85 | RSRC_CONF, |
82 | "SSL Server Certificate file"), | 86 | "SSL Server X509 Certificate file"), |
83 | AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file, | 87 | AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file, |
84 | NULL, | 88 | NULL, |
85 | RSRC_CONF, | 89 | RSRC_CONF, |
86 | "SSL Server Private Key file"), | 90 | "SSL Server X509 Private Key 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"), | ||
87 | AP_INIT_TAKE1("GnuTLSPGPCertificateFile", mgs_set_pgpcert_file, | 99 | AP_INIT_TAKE1("GnuTLSPGPCertificateFile", mgs_set_pgpcert_file, |
88 | NULL, | 100 | NULL, |
89 | RSRC_CONF, | 101 | RSRC_CONF, |