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

Dianne Skoll dianne at bestpractical.com
Tue Nov 10 10:13:46 EST 2020


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

Summary of changes:
 lib/RT/Crypt/SMIME.pm                       | 48 ++++++++++++++++++++++++++++-
 t/crypt/smime/{crl-download.t => revoked.t} | 14 ++++-----
 t/data/smime/keys/revoked-ca.pem            | 27 ++++++++++++++++
 t/data/smime/keys/revoked at example.com.pem   | 39 +++++++++++++++++++++++
 4 files changed, 120 insertions(+), 8 deletions(-)
 copy t/crypt/smime/{crl-download.t => revoked.t} (52%)
 create mode 100644 t/data/smime/keys/revoked-ca.pem
 create mode 100644 t/data/smime/keys/revoked at example.com.pem

- Log -----------------------------------------------------------------
commit 68c721f3c8d79647f4adf72aaea19f2052cde2e2
Author: Dianne Skoll <dianne at skoll.ca>
Date:   Tue Nov 10 10:12:36 2020 -0500

    Add code to handle CRLs in DER format.
    
    The "openssl verify -crl_download" command misleadingly fails if the
    CRL is in DER format rather than PEM.  Work around this by downloading
    the CRL ourselves and converting to PEM.

diff --git a/lib/RT/Crypt/SMIME.pm b/lib/RT/Crypt/SMIME.pm
index ecf33b4518..44d3ab57fa 100644
--- a/lib/RT/Crypt/SMIME.pm
+++ b/lib/RT/Crypt/SMIME.pm
@@ -61,6 +61,7 @@ use IPC::Run3 0.036 'run3';
 use RT::Util 'safe_run_child';
 use Crypt::X509;
 use String::ShellQuote 'shell_quote';
+use LWP;
 
 # This will be set to a true value by Probe
 # if "openssl verify" supports the -crl_download option
@@ -978,6 +979,24 @@ sub GetCertificateInfo {
         if ($res{stderr} !~ /unable to get certificate CRL/) {
             return %res;
         }
+        # If OpenSSL said: "Error loading CRL from URL", try to fetch
+        # the URL ourselves.  OpenSSL gives that misleading message if
+        # the CRL is in DER format rather than PEM.  So we download
+        # it ourselves, try to convert from DER to PEM, and then
+        # rerun with -CRLfile <crl.pem>
+        if ($res{stderr} =~ /Error loading CRL from (https?:.*)/i) {
+            my $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
+            my $crl_file = $self->DownloadAndConvertCRLToPEM($tmpdir, $1);
+            if ($crl_file) {
+                $self->RunOpenSSLVerify($PEM, \%res, '-crl_check', '-CRLfile', $crl_file);
+                return %res;
+            }
+        }
+    }
+
+    # If we got here and we support -crl_download, then clearly
+    # the CRL download failed, so make a note of that
+    if ($OpenSSL_Supports_CRL_Download) {
         $note_about_crl_download = " (NOTE: Unable to download CRL)";
     }
 
@@ -1022,10 +1041,16 @@ sub RunOpenSSLVerify
             $res->{info}[0]{Trust} = "Signed by trusted CA $res->{info}[0]{Issuer}[0]{String}";
             $res->{info}[0]{TrustTerse} = "full";
             $res->{info}[0]{TrustLevel} = 2;
+            $res->{exit_code} = 0;
         } elsif ($? == 0 or ($? >> 8) == 2) {
-            $res->{info}[0]{Trust} = "UNTRUSTED signing CA $res->{info}[0]{Issuer}[0]{String}";
+            if ($res->{stderr} =~ /certificate revoked/i) {
+                $res->{info}[0]{Trust} = "REVOKED certificate from CA $res->{info}[0]{Issuer}[0]{String}";
+            } else {
+                $res->{info}[0]{Trust} = "UNTRUSTED signing CA $res->{info}[0]{Issuer}[0]{String}";
+            }
             $res->{info}[0]{TrustTerse} = "none";
             $res->{info}[0]{TrustLevel} = -1;
+            $res->{exit_code} = $?;
         } else {
             $res->{exit_code} = $?;
             $res->{message} = "openssl exited with error code ". ($? >> 8)
@@ -1042,4 +1067,25 @@ sub RunOpenSSLVerify
     $res->{info}[0]{Formatted} = $res->{info}[0]{User}[0]{String} . " (issued by $res->{info}[0]{Issuer}[0]{String})";
 }
 
+sub DownloadAndConvertCRLToPEM
+{
+    my ($self, $tmpdir, $url) = @_;
+    my $ua = LWP::UserAgent->new(env_proxy => 1);
+    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) {
+        return $fname;
+    }
+    # Something failed and we could not convert CRL to PEM format.
+    return undef;
+}
+
 1;
diff --git a/t/crypt/smime/revoked.t b/t/crypt/smime/revoked.t
new file mode 100644
index 0000000000..a9f0c5ba2a
--- /dev/null
+++ b/t/crypt/smime/revoked.t
@@ -0,0 +1,41 @@
+use strict;
+use warnings;
+
+use RT::Test::SMIME tests => undef;
+
+my $openssl = RT::Test->find_executable('openssl');
+my $keyring = File::Spec->catfile(RT::Test->temp_directory, "smime" );
+my $ca = RT::Test::find_relocatable_path(qw(data smime keys));
+$ca = File::Spec->catfile($ca, 'revoked-ca.pem');
+
+RT->Config->Set('SMIME', Enable => 1,
+    Passphrase => {'revoked\@example.com' => '123456'},
+    OpenSSL => $openssl,
+    Keyring => $keyring,
+    CAPath  => $ca,
+);
+
+RT::Test::SMIME->import_key('revoked at example.com');
+
+
+if (!$::RT::Crypt::SMIME::OpenSSL_Supports_CRL_Download) {
+    RT::Test::plan( skip_all => 'This version of openssl does not support the -crl_download option');
+}
+
+my $crt;
+{
+    local $/;
+    if (open my $fh, "<" . File::Spec->catfile($keyring, 'revoked at example.com.pem')) {
+        $crt = <$fh>;
+        close($fh);
+    } else {
+        die("Could not read " . File::Spec->catfile($keyring, 'revoked at example.com.pem') . ": $!");
+    }
+}
+
+my %res;
+%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');
+
+done_testing;
diff --git a/t/data/smime/keys/revoked-ca.pem b/t/data/smime/keys/revoked-ca.pem
new file mode 100644
index 0000000000..70b86dfd71
--- /dev/null
+++ b/t/data/smime/keys/revoked-ca.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
+U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
+nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
+KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
+/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
+kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
+/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
+AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
+aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
+Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
+oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
+QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
+d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
+xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
+CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
+5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
+8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
+2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
+c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
+j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
+-----END CERTIFICATE-----
diff --git a/t/data/smime/keys/revoked at example.com.pem b/t/data/smime/keys/revoked at example.com.pem
new file mode 100644
index 0000000000..7c96dc9d6e
--- /dev/null
+++ b/t/data/smime/keys/revoked at example.com.pem
@@ -0,0 +1,39 @@
+-----BEGIN CERTIFICATE-----
+MIIGvzCCBaegAwIBAgIQA3G1iob2zpw+y3v0L5II/DANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
+aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTkxMDA0MDAwMDAwWhcN
+MjExMDA4MTIwMDAwWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p
+YTEVMBMGA1UEBxMMV2FsbnV0IENyZWVrMRwwGgYDVQQKExNMdWNhcyBHYXJyb24g
+VG9ycmVzMRswGQYDVQQDExJyZXZva2VkLmJhZHNzbC5jb20wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQC0Ljkn9nZW+vmCL6At8tAyGZlV3IlElvdzI6/3
+pF4+dL9Zec1fC+eP+wMZv4+eY9L/Anx2/hbpAvyGkF+YXNaaui6V6NilxfScnae5
+3rhKcWL9Kih9Aq9G1g0dcWHZTNuXFQA09FOBvI6UOd7YvkJ/JOoCU8ZbgD4RLtLZ
+C20Yhqwh1nfZSKlPo1sd86U2ZNZNH0a38zUQ9XtFOt2kGNu9o07DEJsZhOWWlZtd
+51ZyqyeFaRTc4V42zWnKc8CCB338fo0u+8vJeS6XNkMPFpRFDr3TCWvZ4AP+KgAQ
+m5c48FMRXo165qG+LjKp/2NPoMbqNbhZ5KtDokjAGggRvmzDAgMBAAGjggNyMIID
+bjAfBgNVHSMEGDAWgBQPgGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUOE25
+xq19bGjCX3XXG27LpumeOq0wNQYDVR0RBC4wLIIScmV2b2tlZC5iYWRzc2wuY29t
+ghZ3d3cucmV2b2tlZC5iYWRzc2wuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE
+FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAvoC2gK4YpaHR0cDov
+L2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwL6AtoCuGKWh0dHA6
+Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzYuY3JsMEwGA1UdIARFMEMw
+NwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0
+LmNvbS9DUFMwCAYGZ4EMAQIDMHwGCCsGAQUFBwEBBHAwbjAkBggrBgEFBQcwAYYY
+aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEYGCCsGAQUFBzAChjpodHRwOi8vY2Fj
+ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyU2VjdXJlU2VydmVyQ0EuY3J0
+MAwGA1UdEwEB/wQCMAAwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB1AKS5CZC0
+GFgUh7sTosxncAo8NZgE+RvfuON3zQ7IDdwQAAABbZjwwc8AAAQDAEYwRAIgWPi8
+7t5MzJnvLDJGmCppeQwyHa1VkvAG811Mg19KbcsCIDpbsejn8Feo/pD1g3xUHm9y
+2a5K3ZT2qOI+FfwaNcm7AHYAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16g
+gw8AAAFtmPDCOgAABAMARzBFAiEAmciNTmK3x9F52b+jyQonojj5PR3UTX7I1EY2
+yrbyDVsCIDhrUCuwgpjKzdEkKXC8pTrPT750awtW28nCTZLaCVb1AHYARJRlLrDu
+zq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gagAAAFtmPDBQQAABAMARzBFAiEAwXnV
+kwbWLzukEmOVbs8IQHiQaERcC3RD7IrKHt4dUvMCIFfUv6IL18E/ROuuFQYDwZrv
+DpbCjJdvFw9Cb++GhzzBMA0GCSqGSIb3DQEBCwUAA4IBAQAXzncD0qMluMFZDLOx
+Pzev4B56a0EW7X5YJnyy32UVms+VAp5TDDN1kAxmphecVWRc5DpEn+acXM3hHzx0
+hBfbYYpAANy96MRgGg3qYIN14OV8QzGIIxCRVDzH3f7kQR1bgZvCQC6fs3JnRJ8l
+OhCFNnktylrwV1p48DxxBULjI1oYtXKikEdxs7ZgulOIoVFCSPtzF+MeSwyqYv8I
+OCMAvbctgnsuo0eekLyVlJOTe7Cw+hjz5nYX5yCc2wFu0vlL0kw8d6DaS1isZBZ5
+p7fCfVZfW4WLJdgxYgATKoTkxVFpcTOr4TodGE3G8fOu6G/BknS9r3g5pLpWaNc6
+NtqK
+-----END CERTIFICATE-----

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


More information about the rt-commit mailing list