diff options
| author | 2007-12-16 09:04:11 +0000 | |
|---|---|---|
| committer | 2007-12-16 09:04:11 +0000 | |
| commit | e2b7f8e1d72fa4f8987b1174364f32e95f06ea22 (patch) | |
| tree | 65b75bc8d52305df8ecaf4608c049294b29571cb | |
| parent | 517e02f03e246f32a740958237f8e6de03796cd5 (diff) | |
more changes for openpgp support. Seems to be at a workable state.
| -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, |
