diff options
Diffstat (limited to 'src/gnutls_hooks.c')
-rw-r--r-- | src/gnutls_hooks.c | 143 |
1 files changed, 91 insertions, 52 deletions
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 | ||