diff options
author | Paul Querna | 2005-05-24 17:55:17 +0000 |
---|---|---|
committer | Paul Querna | 2005-05-24 17:55:17 +0000 |
commit | 836c2f9f5d0d3c6cc1369a08683860e940c935b8 (patch) | |
tree | 96f31a9b0f769110d72963b5f6a58edb60eb58f5 /src | |
parent | 84cb5b2ad2abada1069659895d16dcb64f669008 (diff) |
start the CA Certificate code.
Diffstat (limited to 'src')
-rw-r--r-- | src/gnutls_config.c | 20 | ||||
-rw-r--r-- | src/gnutls_hooks.c | 143 | ||||
-rw-r--r-- | src/mod_gnutls.c | 5 |
3 files changed, 110 insertions, 58 deletions
diff --git a/src/gnutls_config.c b/src/gnutls_config.c index 1194448..d3879f1 100644 --- a/src/gnutls_config.c +++ b/src/gnutls_config.c | |||
@@ -214,19 +214,31 @@ const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy, | |||
214 | { | 214 | { |
215 | int rv; | 215 | int rv; |
216 | const char* file; | 216 | const char* file; |
217 | apr_pool_t* spool; | ||
218 | gnutls_datum_t data; | ||
219 | |||
217 | mgs_srvconf_rec *sc = | 220 | mgs_srvconf_rec *sc = |
218 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 221 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
219 | module_config, | 222 | module_config, |
220 | &gnutls_module); | 223 | &gnutls_module); |
221 | file = ap_server_root_relative(parms->pool, arg); | 224 | apr_pool_create(&spool, parms->pool); |
222 | rv = gnutls_certificate_set_x509_trust_file(sc->certs, | 225 | |
223 | file, GNUTLS_X509_FMT_PEM); | 226 | file = ap_server_root_relative(spool, arg); |
224 | 227 | ||
228 | sc->ca_list_size = 16; | ||
229 | |||
230 | load_datum_from_file(spool, file, &data); | ||
231 | |||
232 | rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, | ||
233 | &data, GNUTLS_X509_FMT_PEM, | ||
234 | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); | ||
225 | if (rv < 0) { | 235 | if (rv < 0) { |
226 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " | 236 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " |
227 | "Client CA File '%s': (%d) %s", file, rv, | 237 | "Client CA File '%s': (%d) %s", file, rv, |
228 | gnutls_strerror(rv)); | 238 | gnutls_strerror(rv)); |
229 | } | 239 | } |
240 | |||
241 | apr_pool_destroy(spool); | ||
230 | return NULL; | 242 | return NULL; |
231 | } | 243 | } |
232 | 244 | ||
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index 3862c9d..8452d36 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c | |||
@@ -586,41 +586,66 @@ int mgs_hook_authz(request_rec *r) | |||
586 | if (!ctxt) { | 586 | if (!ctxt) { |
587 | return DECLINED; | 587 | return DECLINED; |
588 | } | 588 | } |
589 | ap_add_common_vars(r); | 589 | |
590 | mgs_hook_fixups(r); | ||
591 | status = mgs_authz_lua(r); | ||
592 | if (status != 0) { | ||
593 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, | ||
594 | "GnuTLS: FAILED Lua Authorization Test"); | ||
595 | return HTTP_FORBIDDEN; | ||
596 | } | ||
597 | if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { | 590 | if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { |
598 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, | 591 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
599 | "GnuTLS: Directory set to Ignore Client Certificate!"); | 592 | "GnuTLS: Directory set to Ignore Client Certificate!"); |
600 | return DECLINED; | ||
601 | } | 593 | } |
602 | 594 | else { | |
603 | if (ctxt->sc->client_verify_mode < dc->client_verify_mode) { | 595 | if (ctxt->sc->client_verify_mode < dc->client_verify_mode) { |
604 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, | 596 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
605 | "GnuTLS: Attempting to rehandshake with peer. %d %d", | 597 | "GnuTLS: Attempting to rehandshake with peer. %d %d", |
606 | ctxt->sc->client_verify_mode, dc->client_verify_mode); | 598 | ctxt->sc->client_verify_mode, dc->client_verify_mode); |
607 | 599 | ||
608 | gnutls_certificate_server_set_request(ctxt->session, | 600 | gnutls_certificate_server_set_request(ctxt->session, |
609 | dc->client_verify_mode); | 601 | dc->client_verify_mode); |
610 | 602 | ||
611 | if (mgs_rehandshake(ctxt) != 0) { | 603 | if (mgs_rehandshake(ctxt) != 0) { |
612 | return HTTP_FORBIDDEN; | 604 | return HTTP_FORBIDDEN; |
605 | } | ||
613 | } | 606 | } |
614 | } | 607 | else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) { |
615 | else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) { | ||
616 | #if MOD_GNUTLS_DEBUG | 608 | #if MOD_GNUTLS_DEBUG |
617 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 609 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
618 | "GnuTLS: Peer is set to IGNORE"); | 610 | "GnuTLS: Peer is set to IGNORE"); |
619 | #endif | 611 | #endif |
620 | return DECLINED; | 612 | } |
613 | else { | ||
614 | rv = mgs_cert_verify(r, ctxt); | ||
615 | if (rv != DECLINED) { | ||
616 | return rv; | ||
617 | } | ||
618 | } | ||
619 | |||
620 | |||
621 | static int mgs_cert_verify(request_rec *r, mgs_handle_t *ctxt) | ||
622 | { | ||
623 | const gnutls_datum_t* cert_list; | ||
624 | int cert_list_size; | ||
625 | gnutls_x509_crt_t cert; | ||
626 | |||
627 | |||
628 | cert_list = gnutls_certificate_get_peers(ctxt->session, &cert_list_size); | ||
629 | |||
630 | if (cert_list == NULL || cert_list_size == 0) { | ||
631 | /* no certificate provided by the client, but one was required. */ | ||
632 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | ||
633 | "GnuTLS: Failed to Verify Peer: " | ||
634 | "Client did not submit a certificate"); | ||
635 | return HTTP_FORBIDDEN; | ||
621 | } | 636 | } |
622 | 637 | ||
623 | rv = gnutls_certificate_verify_peers2(ctxt->session, &status); | 638 | if (cert_list_size > 1) { |
639 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | ||
640 | "GnuTLS: Failed to Verify Peer: " | ||
641 | "Chained Client Certificates are not supported."); | ||
642 | return HTTP_FORBIDDEN; | ||
643 | } | ||
644 | |||
645 | gnutls_x509_crt_init(&cert); | ||
646 | gnutls_x509_crt_import(cert, &cert_chain[0], GNUTLS_X509_FMT_DER); | ||
647 | |||
648 | rv = gnutls_x509_crt_verify(cert, ctxt->sc->ca_list, ctxt->sc->ca_list_size, 0, &status); | ||
624 | 649 | ||
625 | if (rv < 0) { | 650 | if (rv < 0) { |
626 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 651 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
@@ -629,42 +654,56 @@ int mgs_hook_authz(request_rec *r) | |||
629 | return HTTP_FORBIDDEN; | 654 | return HTTP_FORBIDDEN; |
630 | } | 655 | } |
631 | 656 | ||
632 | if (status < 0) { | 657 | if (status < 0) { |
633 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 658 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
634 | "GnuTLS: Peer Status is invalid."); | 659 | "GnuTLS: Peer Status is invalid."); |
635 | return HTTP_FORBIDDEN; | 660 | return HTTP_FORBIDDEN; |
636 | } | 661 | } |
637 | 662 | ||
638 | if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { | 663 | if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { |
639 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 664 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
640 | "GnuTLS: Could not find Signer for Peer Certificate"); | 665 | "GnuTLS: Could not find Signer for Peer Certificate"); |
641 | } | 666 | } |
642 | 667 | ||
643 | if (status & GNUTLS_CERT_SIGNER_NOT_CA) { | 668 | if (status & GNUTLS_CERT_SIGNER_NOT_CA) { |
644 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 669 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
645 | "GnuTLS: Could not find CA for Peer Certificate"); | 670 | "GnuTLS: Could not find CA for Peer Certificate"); |
646 | } | 671 | } |
647 | 672 | ||
648 | if (status & GNUTLS_CERT_INVALID) { | 673 | if (status & GNUTLS_CERT_INVALID) { |
649 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 674 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
650 | "GnuTLS: Peer Certificate is invalid."); | 675 | "GnuTLS: Peer Certificate is invalid."); |
651 | return HTTP_FORBIDDEN; | 676 | return HTTP_FORBIDDEN; |
652 | } | 677 | } |
653 | else if (status & GNUTLS_CERT_REVOKED) { | 678 | else if (status & GNUTLS_CERT_REVOKED) { |
654 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 679 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
655 | "GnuTLS: Peer Certificate is revoked."); | 680 | "GnuTLS: Peer Certificate is revoked."); |
656 | return HTTP_FORBIDDEN; | 681 | return HTTP_FORBIDDEN; |
657 | } | 682 | } |
658 | 683 | ||
659 | /* TODO: OpenPGP Certificates */ | 684 | /* TODO: OpenPGP Certificates */ |
660 | if (gnutls_certificate_type_get(ctxt->session) != GNUTLS_CRT_X509) { | 685 | if (gnutls_certificate_type_get(ctxt->session) != GNUTLS_CRT_X509) { |
686 | ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, | ||
687 | "GnuTLS: Only x509 is supported for client certificates"); | ||
688 | return HTTP_FORBIDDEN; | ||
689 | } | ||
690 | /* TODO: Further Verification. */ | ||
691 | // gnutls_x509_crt_get_expiration_time() < time | ||
692 | // gnutls_x509_crt_get_activation_time() > time | ||
693 | /// ret = gnutls_x509_crt_check_revocation(crt, crl_list, crl_list_size); | ||
661 | ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, | 694 | ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, |
662 | "GnuTLS: Only x509 is supported for client certificates"); | 695 | "GnuTLS: Verified Peer."); |
696 | } | ||
697 | |||
698 | ap_add_common_vars(r); | ||
699 | mgs_hook_fixups(r); | ||
700 | status = mgs_authz_lua(r); | ||
701 | |||
702 | if (status != 0) { | ||
703 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, | ||
704 | "GnuTLS: FAILED Authorization Test"); | ||
663 | return HTTP_FORBIDDEN; | 705 | return HTTP_FORBIDDEN; |
664 | } | 706 | } |
665 | /* TODO: Further Verification. */ | 707 | |
666 | ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, | ||
667 | "GnuTLS: Verified Peer."); | ||
668 | return OK; | ||
669 | } | 708 | } |
670 | 709 | ||
diff --git a/src/mod_gnutls.c b/src/mod_gnutls.c index 84440d0..5ca198d 100644 --- a/src/mod_gnutls.c +++ b/src/mod_gnutls.c | |||
@@ -44,8 +44,9 @@ static void gnutls_hooks(apr_pool_t * p) | |||
44 | 44 | ||
45 | /* TODO: HTTP Upgrade Filter */ | 45 | /* TODO: HTTP Upgrade Filter */ |
46 | /* ap_register_output_filter ("UPGRADE_FILTER", | 46 | /* ap_register_output_filter ("UPGRADE_FILTER", |
47 | * ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); | 47 | * ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); |
48 | */ | 48 | */ |
49 | |||
49 | ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, | 50 | ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, |
50 | mgs_filter_input, NULL, | 51 | mgs_filter_input, NULL, |
51 | AP_FTYPE_CONNECTION + 5); | 52 | AP_FTYPE_CONNECTION + 5); |