[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