[Rt-commit] rt branch, 4.4/support-openssl-crl-check, updated. rt-4.4.4-159-g50448b0b69

Dianne Skoll dianne at bestpractical.com
Tue Nov 10 11:07:04 EST 2020


The branch, 4.4/support-openssl-crl-check has been updated
       via  50448b0b69813aafbbed0e883670f48f60b3e8df (commit)
      from  68c721f3c8d79647f4adf72aaea19f2052cde2e2 (commit)

Summary of changes:
 lib/RT/Crypt/SMIME.pm   | 69 +++++++++++++++++++++++++++++++++++++++++++++++++
 t/crypt/smime/revoked.t |  9 ++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)

- Log -----------------------------------------------------------------
commit 50448b0b69813aafbbed0e883670f48f60b3e8df
Author: Dianne Skoll <dianne at skoll.ca>
Date:   Tue Nov 10 11:05:59 2020 -0500

    Check for certificate revocation using OCSP if possible.

diff --git a/lib/RT/Crypt/SMIME.pm b/lib/RT/Crypt/SMIME.pm
index 44d3ab57fa..bb21d611d1 100644
--- a/lib/RT/Crypt/SMIME.pm
+++ b/lib/RT/Crypt/SMIME.pm
@@ -973,6 +973,13 @@ sub GetCertificateInfo {
         stderr => ''
     );
 
+    # Check if certificate has been revoked using OCSP if the cert has
+    # an OCSP URL.  Unfortunately, Crypt::X509 doesn't let us query
+    # for OCSP URLs, so we need to run OpenSSL.
+    if ($self->CheckRevocationUsingOCSP($PEM, \%res)) {
+        return %res;
+    }
+
     my $note_about_crl_download = '';
     if ($OpenSSL_Supports_CRL_Download) {
         $self->RunOpenSSLVerify($PEM, \%res, '-crl_check', '-crl_download');
@@ -1088,4 +1095,66 @@ sub DownloadAndConvertCRLToPEM
     return undef;
 }
 
+sub CheckRevocationUsingOCSP
+{
+    my ($self, $PEM, $res) = @_;
+
+    # Can't do anything without a CAPath
+    my $ca = RT->Config->Get('SMIME')->{'CAPath'};
+    return undef unless $ca;
+
+    my ($out, $err);
+    $out = '';
+    $err = '';
+    # We need to download the issuer certificate, so look for its URL and
+    # that of the OCSP
+    safe_run_child { run3( [$self->OpenSSLPath, 'x509', '-noout', '-text'],
+                           \$PEM, \$out, \$err ) };
+    return undef unless $out =~ /CA Issuers - URI:(https?:.*)/;
+    my $issuer_url = $1;
+
+    return undef unless $out =~ /OCSP - URI:(https?:.*)/;
+    my $ocsp_url = $1;
+
+    # We have the issuer certificate URL; make a temp dir and grab it
+    my $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
+    my $issuer = File::Spec->catfile($tmpdir, 'issuer.crt');
+    my $ua = LWP::UserAgent->new(env_proxy => 1);
+
+    my $resp = $ua->get($issuer_url);
+    return undef unless $resp->is_success;
+
+    open(my $fh, '>', $issuer) or return undef;
+    my $content = $resp->decoded_content;
+    if ($content !~ /BEGIN CERTIFICATE/) {
+        # Convert from DER to PEM
+        $content = "-----BEGIN CERTIFICATE-----\n" .
+            MIME::Base64::encode_base64($content) .
+            "-----END CERTIFICATE-----\n";
+    }
+    print $fh $content;
+    close($fh);
+
+    # Check for revocation
+    my @ca_verify;
+    if (-d $ca) {
+        @ca_verify = ('-CApath', $ca);
+    } elsif (-f $ca) {
+        @ca_verify = ('-CAfile', $ca);
+    }
+    $out = '';
+    $err = '';
+
+    safe_run_child { run3( [$self->OpenSSLPath(), 'ocsp', '-issuer', $issuer, '-cert', '-', @ca_verify, '-url', $ocsp_url],
+                           \$PEM, \$out, \$err) };
+    if ($out =~ /^-: revoked/) {
+        $res->{info}[0]{Trust} = "REVOKED certificate checked against OCSP URI $ocsp_url";
+        $res->{info}[0]{TrustTerse} = "none";
+        $res->{info}[0]{TrustLevel} = -1;
+        $res->{exit_code} = 0;
+        return 1;
+    }
+    return undef;
+}
+
 1;
diff --git a/t/crypt/smime/revoked.t b/t/crypt/smime/revoked.t
index a9f0c5ba2a..682a13825f 100644
--- a/t/crypt/smime/revoked.t
+++ b/t/crypt/smime/revoked.t
@@ -35,7 +35,14 @@ my $crt;
 
 my %res;
 %res = RT::Crypt::SMIME->GetCertificateInfo(Certificate => $crt);
+is ($res{info}[0]{Trust}, 'REVOKED certificate checked against OCSP URI http://ocsp.digicert.com', 'Trust info indicates revoked certificate using OCSP');
 
-is ($res{info}[0]{Trust}, 'REVOKED certificate from CA DigiCert SHA2 Secure Server CA', 'Trust info indicates revoked certificate');
+# Now pretend we couldn't use OCSP
+{
+    no warnings 'redefine';
+    *RT::Crypt::SMIME::CheckRevocationUsingOCSP = sub { return undef; };
+    %res = RT::Crypt::SMIME->GetCertificateInfo(Certificate => $crt);
+    is ($res{info}[0]{Trust}, 'REVOKED certificate from CA DigiCert SHA2 Secure Server CA', 'Trust info indicates revoked certificate using CRL');
+}
 
 done_testing;

-----------------------------------------------------------------------


More information about the rt-commit mailing list