diff options
-rw-r--r-- | src/gnutls_hooks.c | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index ea59bbf..9ebf771 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c | |||
@@ -1028,8 +1028,9 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1028 | const gnutls_datum_t *cert_list; | 1028 | const gnutls_datum_t *cert_list; |
1029 | unsigned int cert_list_size, status, expired; | 1029 | unsigned int cert_list_size, status, expired; |
1030 | int rv, ret; | 1030 | int rv, ret; |
1031 | unsigned int ch_size = 0; | ||
1031 | union { | 1032 | union { |
1032 | gnutls_x509_crt_t x509; | 1033 | gnutls_x509_crt_t x509[MAX_CHAIN_SIZE]; |
1033 | gnutls_openpgp_crt_t pgp; | 1034 | gnutls_openpgp_crt_t pgp; |
1034 | } cert; | 1035 | } cert; |
1035 | apr_time_t activation_time, expiration_time, cur_time; | 1036 | apr_time_t activation_time, expiration_time, cur_time; |
@@ -1051,19 +1052,40 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1051 | return HTTP_FORBIDDEN; | 1052 | return HTTP_FORBIDDEN; |
1052 | } | 1053 | } |
1053 | 1054 | ||
1054 | if (cert_list_size > 1) { | 1055 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { |
1055 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 1056 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
1057 | "GnuTLS: A Chain of %d certificate(s) was provided for validation", cert_list_size); | ||
1058 | |||
1059 | for (ch_size =0; ch_size<cert_list_size; ch_size++) { | ||
1060 | gnutls_x509_crt_init(&cert.x509[ch_size]); | ||
1061 | rv = gnutls_x509_crt_import(cert.x509[ch_size], &cert_list[ch_size], GNUTLS_X509_FMT_DER); | ||
1062 | // When failure to import, leave the loop | ||
1063 | if ( rv != GNUTLS_E_SUCCESS ) { | ||
1064 | if (ch_size < 1) { | ||
1065 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | ||
1066 | "GnuTLS: Failed to Verify Peer: " | ||
1067 | "Failed to import peer certificates."); | ||
1068 | ret = HTTP_FORBIDDEN; | ||
1069 | goto exit; | ||
1070 | } | ||
1071 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | ||
1072 | "GnuTLS: Failed to import some peer certificates. Using %d certificates", | ||
Christopher Powell e); | |||
1074 | rv = GNUTLS_E_SUCCESS; | ||
1075 | break; | ||
1076 | } | ||
1077 | } | ||
1078 | } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) { | ||
1079 | if (cert_list_size > 1) { | ||
1080 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | ||
1056 | "GnuTLS: Failed to Verify Peer: " | 1081 | "GnuTLS: Failed to Verify Peer: " |
1057 | "Chained Client Certificates are not supported."); | 1082 | "Chained Client Certificates are not supported."); |
1058 | return HTTP_FORBIDDEN; | 1083 | return HTTP_FORBIDDEN; |
1059 | } | 1084 | } |
1060 | 1085 | ||
1061 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { | ||
1062 | gnutls_x509_crt_init(&cert.x509); | ||
1063 | rv = gnutls_x509_crt_import(cert.x509, &cert_list[0], GNUTLS_X509_FMT_DER); | ||
1064 | } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) { | ||
1065 | gnutls_openpgp_crt_init(&cert.pgp); | 1086 | gnutls_openpgp_crt_init(&cert.pgp); |
1066 | rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW); | 1087 | rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW); |
1088 | |||
1067 | } else return HTTP_FORBIDDEN; | 1089 | } else return HTTP_FORBIDDEN; |
1068 | 1090 | ||
1069 | if (rv < 0) { | 1091 | if (rv < 0) { |
@@ -1076,12 +1098,15 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1076 | 1098 | ||
1077 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { | 1099 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { |
1078 | apr_time_ansi_put(&expiration_time, | 1100 | apr_time_ansi_put(&expiration_time, |
1079 | gnutls_x509_crt_get_expiration_time(cert.x509)); | 1101 | gnutls_x509_crt_get_expiration_time(cert.x509[0])); |
1080 | apr_time_ansi_put(&activation_time, | 1102 | apr_time_ansi_put(&activation_time, |
1081 | gnutls_x509_crt_get_activation_time(cert.x509)); | 1103 | gnutls_x509_crt_get_activation_time(cert.x509[0])); |
1082 | 1104 | ||
1083 | rv = gnutls_x509_crt_verify(cert.x509, ctxt->sc->ca_list, | 1105 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
1084 | ctxt->sc->ca_list_size, 0, &status); | 1106 | "GnuTLS: Verifying list of %d certificate(s)", ch_size); |
1107 | rv = gnutls_x509_crt_list_verify(cert.x509, ch_size, | ||
1108 | ctxt->sc->ca_list, ctxt->sc->ca_list_size, | ||
1109 | NULL, 0, 0, &status); | ||
1085 | } else { | 1110 | } else { |
1086 | apr_time_ansi_put(&expiration_time, | 1111 | apr_time_ansi_put(&expiration_time, |
1087 | gnutls_openpgp_crt_get_expiration_time(cert.pgp)); | 1112 | gnutls_openpgp_crt_get_expiration_time(cert.pgp)); |
@@ -1145,7 +1170,7 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1145 | } | 1170 | } |
1146 | 1171 | ||
1147 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) | 1172 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) |
1148 | mgs_add_common_cert_vars(r, cert.x509, 1, | 1173 | mgs_add_common_cert_vars(r, cert.x509[0], 1, |
1149 | ctxt->sc->export_certificates_enabled); | 1174 | ctxt->sc->export_certificates_enabled); |
1150 | else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) | 1175 | else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) |
1151 | mgs_add_common_pgpcert_vars(r, cert.pgp, 1, | 1176 | mgs_add_common_pgpcert_vars(r, cert.pgp, 1, |
@@ -1172,9 +1197,12 @@ static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) | |||
1172 | } | 1197 | } |
1173 | 1198 | ||
1174 | exit: | 1199 | exit: |
1175 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) | 1200 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { |
1176 | gnutls_x509_crt_deinit(cert.x509); | 1201 | int i; |
1177 | else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) | 1202 | for (i=0; i<ch_size; i++) { |
1203 | gnutls_x509_crt_deinit(cert.x509[i]); | ||
1204 | } | ||
1205 | } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) | ||
1178 | gnutls_openpgp_crt_deinit(cert.pgp); | 1206 | gnutls_openpgp_crt_deinit(cert.pgp); |
1179 | return ret; | 1207 | return ret; |
1180 | 1208 | ||