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

Dianne Skoll dianne at bestpractical.com
Mon Nov 23 15:03:33 EST 2020


The branch, 4.4/support-openssl-crl-check has been updated
       via  1271059691e6bb446b647c58bbb34ebe18906be2 (commit)
      from  5d180841f2c5eaa951b55ffd500603c801fa7ec3 (commit)

Summary of changes:
 etc/RT_Config.pm.in       | 14 +++++---
 lib/RT/Crypt/SMIME.pm     | 83 +++++++++++++++++++++++++++--------------------
 t/crypt/smime/crl-check.t |  1 +
 t/crypt/smime/revoked.t   | 25 +++++++++-----
 4 files changed, 74 insertions(+), 49 deletions(-)

- Log -----------------------------------------------------------------
commit 1271059691e6bb446b647c58bbb34ebe18906be2
Author: Dianne Skoll <dianne at bestpractical.com>
Date:   Mon Nov 23 14:58:53 2020 -0500

    Split "DownloadCRL" into "DownloadCRL" and "CheckOCSP" so we can enable/disable independently.
    
    Rename "DownloadCRLTimeout" to "CheckRevocationDownloadTimeout"

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index bcd23dd8d7..42fbb76bef 100644
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -3061,11 +3061,14 @@ Set C<OtherCertificatesToSend> to path to a PEM-formatted certificate file.
 Certificates in the file will be include in outgoing signed emails.
 
 Set C<DownloadCRL> to a true value to have RT check for revoked certificates
-using OCSP or downloading a CRL if no OCSP server is given.  By default,
-C<DownloadCRL> is disabled.
+by downloading a CRL. By default, C<DownloadCRL> is disabled.
 
-Set C<DownloadCRLTimeout> to the timeout in seconds for downloading a CRL.
-The default timeout is 30 seconds.
+Set C<CheckOCSP> to a true value to have RT check for revoked certificates
+against an OCSP server if possible.  By default, C<CheckOCSP> is disabled.
+
+Set C<CheckRevocationDownloadTimeout> to the timeout in seconds for
+downloading a CRL or an issuer certificate (the latter is used when
+checking against OCSP.)  The default timeout is 30 seconds.
 
 See L<RT::Crypt::SMIME> for details.
 
@@ -3082,7 +3085,8 @@ Set( %SMIME,
     Passphrase => undef,
     OtherCertificatesToSend => undef,
     DownloadCRL => 0,
-    DownloadCRLTimeout => 30,
+    CheckOCSP   => 0,
+    CheckRevocationDownloadTimeout => 30,
 );
 
 =head2 GnuPG configuration
diff --git a/lib/RT/Crypt/SMIME.pm b/lib/RT/Crypt/SMIME.pm
index 9a72cf4057..2bfdb19c2f 100644
--- a/lib/RT/Crypt/SMIME.pm
+++ b/lib/RT/Crypt/SMIME.pm
@@ -88,7 +88,8 @@ You should start from reading L<RT::Crypt>.
         },
         OtherCertificatesToSend => '/opt/rt4/var/data/smime/other-certs.pem',
         DownloadCRL => 0,
-        DownloadCRLTimeout => 30,
+        CheckOCSP   => 0,
+        CheckRevocationDownloadTimeout => 30,
     );
 
 =head3 OpenSSL
@@ -138,12 +139,18 @@ receiving agents can verify. CA could also be included here.
 =head3 DownloadCRL
 
 A boolean option that determines whether or not we attempt to check if
-a certificate is revoked by downloading a CRL or checking against an
-OCSP URL.  The default value is false (do not check.)  Additionally,
-if AcceptUntrustedCAs is true, RT will I<never> download a CRL or
-check an OCSP URL for a certificate signed by an untrusted CA.
+a certificate is revoked by downloading a CRL.  The default value is
+false (do not check.)  Additionally, if AcceptUntrustedCAs is true, RT
+will I<never> download a CRL or check an OCSP URL for a certificate
+signed by an untrusted CA.
 
-=head3 DownloadCRLTimeout
+=head3 CheckOCSP
+
+A boolean option that determines whether or not we check if a certificate
+is revoked by checking the OCSP URL (if any).  The default value is
+false.
+
+=head3 CheckRevocationDownloadTimeout
 
 Timeout in seconds for downloading a CRL or issuer certificate for
 OCSP checking.  The default is 30 seconds.
@@ -997,33 +1004,38 @@ sub GetCertificateInfo {
         return %res;
     }
 
-    # If we're not configured to check CRLs, just return
+    # If we're not configured to check CRLs or OCSP, just return
     # what we have.
-    return %res unless (RT::Config->Get('SMIME')->{'DownloadCRL'});
+    return %res unless (RT::Config->Get('SMIME')->{'DownloadCRL'} ||
+                        RT::Config->Get('SMIME')->{'CheckOCSP'  }   );
 
     # 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.
-    my $ocsp_result = $self->CheckRevocationUsingOCSP($PEM, \%res);
-    if ($ocsp_result) {
-        # We got a definitive result from OCSP; return
-        return %res;
+    if (RT::Config->Get('SMIME')->{'CheckOCSP'}) {
+        my $ocsp_result = $self->CheckRevocationUsingOCSP($PEM, \%res);
+        if ($ocsp_result) {
+            # We got a definitive result from OCSP; return
+            return %res;
+        }
     }
 
-    # OCSP didn't give us a result.  Try downloading CRL
-    my $note_about_crl_download = '';
-    if ($OpenSSL_Supports_CRLfile) {
-        # We fetch the CRL file ourselves using LWP rather than
-        # using OpenSSL's -crl_download option so we can
-        # control the timeout.
-        my $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
-        my ($url) = @{$cert->CRLDistributionPoints};
-        if ($url) {
-            my $crl_file = $self->DownloadAndConvertCRLToPEM($tmpdir, $url);
-            if ($crl_file) {
-                $self->RunOpenSSLVerify($PEM, \%res, '-crl_check', '-CRLfile', $crl_file);
-            } else {
-                $res{info}[0]{Trust} .= " (NOTE: Unable to download CRL)";
+    # OCSP didn't give us a result, or was disabled  Try downloading CRL.
+    if (RT::Config->Get('SMIME')->{'DownloadCRL'}) {
+        my $note_about_crl_download = '';
+        if ($OpenSSL_Supports_CRLfile) {
+            # We fetch the CRL file ourselves using LWP rather than
+            # using OpenSSL's -crl_download option so we can
+            # control the timeout.
+            my $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
+            my ($url) = @{$cert->CRLDistributionPoints};
+            if ($url) {
+                my $crl_file = $self->DownloadAndConvertCRLToPEM($tmpdir, $url);
+                if ($crl_file) {
+                    $self->RunOpenSSLVerify($PEM, \%res, '-crl_check', '-CRLfile', $crl_file);
+                } else {
+                    $res{info}[0]{Trust} .= " (NOTE: Unable to download CRL)";
+                }
             }
         }
     }
@@ -1094,22 +1106,23 @@ sub DownloadAndConvertCRLToPEM
 {
     my ($self, $tmpdir, $url) = @_;
     my $ua = LWP::UserAgent->new(env_proxy => 1);
-    $ua->timeout(RT::Config->Get('SMIME')->{DownloadCRLTimeout});
+    $ua->timeout(RT::Config->Get('SMIME')->{CheckRevocationDownloadTimeout});
 
     my $resp = $ua->get($url);
     return undef unless $resp->is_success;
 
     my $fname = File::Spec->catfile($tmpdir, 'crl.pem');
     my $in = $resp->decoded_content;
-    my ($out, $err) = ('', '');
-
-    local $SIG{'CHLD'} = 'DEFAULT';
-
-    safe_run_child { run3( [$self->OpenSSLPath(), 'crl', '-inform', 'DER', '-outform', 'PEM', '-out', $fname], \$in, \$out, \$err) };
-    if ($? == 0) {
+    if ($in !~ /-----BEGIN X509 CRL-----/) {
+        $in =  "-----BEGIN X509 CRL-----\n" .
+                MIME::Base64::encode_base64($in) .
+               "-----END X509 CRL-----\n";
+    }
+    if (open(my $fh, ">$fname")) {
+        print $fh $in;
+        close($fh);
         return $fname;
     }
-    # Something failed and we could not convert CRL to PEM format.
     return undef;
 }
 
@@ -1140,7 +1153,7 @@ sub CheckRevocationUsingOCSP
     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);
-    $ua->timeout(RT::Config->Get('SMIME')->{DownloadCRLTimeout});
+    $ua->timeout(RT::Config->Get('SMIME')->{CheckRevocationDownloadTimeout});
 
     my $resp = $ua->get($issuer_url);
     return undef unless $resp->is_success;
diff --git a/t/crypt/smime/crl-check.t b/t/crypt/smime/crl-check.t
index 89e01cc0c8..583ca48674 100644
--- a/t/crypt/smime/crl-check.t
+++ b/t/crypt/smime/crl-check.t
@@ -14,6 +14,7 @@ RT->Config->Set('SMIME', Enable => 1,
     Keyring => $keyring,
     CAPath  => $ca,
     DownloadCRL => 1,
+    CheckOSCP => 1,
 );
 
 RT::Test::SMIME->import_key('sender-crl at example.com');
diff --git a/t/crypt/smime/revoked.t b/t/crypt/smime/revoked.t
index 3c23577c50..337f4731b9 100644
--- a/t/crypt/smime/revoked.t
+++ b/t/crypt/smime/revoked.t
@@ -14,6 +14,7 @@ RT->Config->Set('SMIME', Enable => 1,
     Keyring => $keyring,
     CAPath  => $ca,
     DownloadCRL => 1,
+    CheckOCSP => 1,
 );
 
 RT::Test::SMIME->import_key('revoked at example.com');
@@ -43,22 +44,28 @@ my %res;
 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]{TrustTerse}, 'none (revoked certificate)', 'TrustTerse 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');
-    is ($res{info}[0]{TrustTerse}, 'none (revoked certificate)', 'TrustTerse indicates revoked certificate');
-}
+# Now disable OCSP
+RT->Config->Set('SMIME', Enable => 1,
+    Passphrase => {'revoked\@example.com' => '123456'},
+    OpenSSL => $openssl,
+    Keyring => $keyring,
+    CAPath  => $ca,
+    DownloadCRL => 1,
+    CheckOCSP => 0,
+);
+
+%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');
+is ($res{info}[0]{TrustTerse}, 'none (revoked certificate)', 'TrustTerse indicates revoked certificate');
 
-# If we have not enabled CRL downloading, the cert should verify
+# Disable both OCSP and CRL... cert should verify
 RT->Config->Set('SMIME', Enable => 1,
     Passphrase => {'revoked\@example.com' => '123456'},
     OpenSSL => $openssl,
     Keyring => $keyring,
     CAPath  => $ca,
     DownloadCRL => 0,
+    CheckOSCP => 0,
 );
 %res = RT::Crypt::SMIME->GetCertificateInfo(Certificate => $crt);
 is ($res{info}[0]{Trust}, 'Signed by trusted CA DigiCert SHA2 Secure Server CA');

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


More information about the rt-commit mailing list