summaryrefslogtreecommitdiffstatsabout
path: root/src/gnutls_hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnutls_hooks.c')
-rw-r--r--src/gnutls_hooks.c62
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",
1073 ch_size);
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