Update mk-ca-bundle.pl tool in repository (#8184)
* Update mk-ca-bundle.pl in repository * Update certs.pem with new version of mk-ca-bundle.pl * Add extra check against curl.se site
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
##
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla as of: Tue Jul 19 06:03:20 2022 GMT
|
||||
## Certificate data from Mozilla as of: Wed Oct 12 12:35:08 2022 GMT
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
@@ -13,8 +13,8 @@
|
||||
## an Apache+mod_ssl webserver for SSL client authentication.
|
||||
## Just configure this file as the SSLCACertificateFile.
|
||||
##
|
||||
## Conversion done with mk-ca-bundle.pl version 1.28.
|
||||
## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066
|
||||
## Conversion done with mk-ca-bundle.pl version 1.29.
|
||||
## SHA256: 3ff8bd209b5f2e739b9f2b96eacb694a774114685b02978257824f37ff528f71
|
||||
##
|
||||
|
||||
|
||||
@@ -993,36 +993,6 @@ tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
|
||||
mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
EC-ACC
|
||||
======
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
|
||||
BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
|
||||
ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
|
||||
VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
|
||||
CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
|
||||
BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
|
||||
MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
|
||||
SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
|
||||
Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
|
||||
cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
|
||||
w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
|
||||
ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
|
||||
HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
|
||||
E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
|
||||
0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
|
||||
BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
|
||||
VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
|
||||
Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
|
||||
dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
|
||||
lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
|
||||
Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
|
||||
l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
|
||||
E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
|
||||
5EI=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Actalis Authentication Root CA
|
||||
==============================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
@@ -3488,3 +3458,49 @@ zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
|
||||
PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W
|
||||
Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Security Communication RootCA3
|
||||
==============================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Security Communication ECC RootCA1
|
||||
==================================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD
|
||||
VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t
|
||||
dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL
|
||||
MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV
|
||||
BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo
|
||||
5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW
|
||||
BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK
|
||||
BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L
|
||||
snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e
|
||||
N9k=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
+200
-112
@@ -6,7 +6,7 @@
|
||||
# * | (__| |_| | _ <| |___
|
||||
# * \___|\___/|_| \_\_____|
|
||||
# *
|
||||
# * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# *
|
||||
# * This software is licensed as described in the file COPYING, which
|
||||
# * you should have received as part of this distribution. The terms
|
||||
@@ -19,6 +19,8 @@
|
||||
# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# * KIND, either express or implied.
|
||||
# *
|
||||
# * SPDX-License-Identifier: curl
|
||||
# *
|
||||
# ***************************************************************************
|
||||
# This Perl script creates a fresh ca-bundle.crt file for use with libcurl.
|
||||
# It downloads certdata.txt from Mozilla's source tree (see URL below),
|
||||
@@ -63,11 +65,12 @@ $opt_d = 'release';
|
||||
# If the OpenSSL commandline is not in search path you can configure it here!
|
||||
my $openssl = 'openssl';
|
||||
|
||||
my $version = '1.28';
|
||||
my $version = '1.29';
|
||||
|
||||
$opt_w = 76; # default base64 encoded lines length
|
||||
|
||||
# default cert types to include in the output (default is to include CAs which may issue SSL server certs)
|
||||
# default cert types to include in the output (default is to include CAs which
|
||||
# may issue SSL server certs)
|
||||
my $default_mozilla_trust_purposes = "SERVER_AUTH";
|
||||
my $default_mozilla_trust_levels = "TRUSTED_DELEGATOR";
|
||||
$opt_p = $default_mozilla_trust_purposes . ":" . $default_mozilla_trust_levels;
|
||||
@@ -94,8 +97,12 @@ my @valid_mozilla_trust_purposes = (
|
||||
my @valid_mozilla_trust_levels = (
|
||||
"TRUSTED_DELEGATOR", # CAs
|
||||
"NOT_TRUSTED", # Don't trust these certs.
|
||||
"MUST_VERIFY_TRUST", # This explicitly tells us that it ISN'T a CA but is otherwise ok. In other words, this should tell the app to ignore any other sources that claim this is a CA.
|
||||
"TRUSTED" # This cert is trusted, but only for itself and not for delegates (i.e. it is not a CA).
|
||||
"MUST_VERIFY_TRUST", # This explicitly tells us that it ISN'T a CA but is
|
||||
# otherwise ok. In other words, this should tell the
|
||||
# app to ignore any other sources that claim this is
|
||||
# a CA.
|
||||
"TRUSTED" # This cert is trusted, but only for itself and not
|
||||
# for delegates (i.e. it is not a CA).
|
||||
);
|
||||
|
||||
my $default_signature_algorithms = $opt_s = "MD5";
|
||||
@@ -210,8 +217,8 @@ sub is_in_list($@) {
|
||||
return defined(List::Util::first { $target eq $_ } @_);
|
||||
}
|
||||
|
||||
# Parses $param_string as a case insensitive comma separated list with optional whitespace
|
||||
# validates that only allowed parameters are supplied
|
||||
# Parses $param_string as a case insensitive comma separated list with optional
|
||||
# whitespace validates that only allowed parameters are supplied
|
||||
sub parse_csv_param($$@) {
|
||||
my $description = shift;
|
||||
my $param_string = shift;
|
||||
@@ -227,7 +234,8 @@ sub parse_csv_param($$@) {
|
||||
my @invalid = grep { !is_in_list($_,"ALL",@valid_values) } @values;
|
||||
|
||||
if ( scalar(@invalid) > 0 ) {
|
||||
# Tell the user which parameters were invalid and print the standard help message which will exit
|
||||
# Tell the user which parameters were invalid and print the standard help
|
||||
# message which will exit
|
||||
print "Error: Invalid ", $description, scalar(@invalid) == 1 ? ": " : "s: ", join( ", ", map { "\"$_\"" } @invalid ), "\n";
|
||||
HELP_MESSAGE();
|
||||
}
|
||||
@@ -282,7 +290,8 @@ sub should_output_cert(%) {
|
||||
my %trust_purposes_by_level = @_;
|
||||
|
||||
foreach my $level (@included_mozilla_trust_levels) {
|
||||
# for each level we want to output, see if any of our desired purposes are included
|
||||
# for each level we want to output, see if any of our desired purposes are
|
||||
# included
|
||||
return 1 if ( defined( List::Util::first { is_in_list( $_, @included_mozilla_trust_purposes ) } @{$trust_purposes_by_level{$level}} ) );
|
||||
}
|
||||
|
||||
@@ -421,9 +430,13 @@ my $caname;
|
||||
my $certnum = 0;
|
||||
my $skipnum = 0;
|
||||
my $start_of_cert = 0;
|
||||
my $main_block = 0;
|
||||
my $main_block_name;
|
||||
my $trust_block = 0;
|
||||
my $trust_block_name;
|
||||
my @precert;
|
||||
my $cka_value;
|
||||
my $valid = 1;
|
||||
my $valid = 0;
|
||||
|
||||
open(TXT,"$txt") or die "Couldn't open $txt: $!\n";
|
||||
while (<TXT>) {
|
||||
@@ -435,101 +448,170 @@ while (<TXT>) {
|
||||
print if ($opt_l);
|
||||
last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/);
|
||||
}
|
||||
next;
|
||||
}
|
||||
# Not Valid After : Thu Sep 30 14:01:15 2021
|
||||
elsif(/^# Not Valid After : (.*)/) {
|
||||
my $stamp = $1;
|
||||
use Time::Piece;
|
||||
my $t = Time::Piece->strptime
|
||||
($stamp, "%a %b %d %H:%M:%S %Y");
|
||||
my $delta = ($t->epoch - time()); # negative means no longer valid
|
||||
if($delta < 0) {
|
||||
# The input file format consists of blocks of Mozilla objects.
|
||||
# The blocks are separated by blank lines but may be related.
|
||||
elsif(/^\s*$/) {
|
||||
$main_block = 0;
|
||||
$trust_block = 0;
|
||||
next;
|
||||
}
|
||||
# Each certificate has a main block.
|
||||
elsif(/^# Certificate "(.*)"/) {
|
||||
(!$main_block && !$trust_block) or die "Unexpected certificate block";
|
||||
$main_block = 1;
|
||||
$main_block_name = $1;
|
||||
# Reset all other certificate variables.
|
||||
$trust_block = 0;
|
||||
$trust_block_name = "";
|
||||
$valid = 0;
|
||||
$start_of_cert = 0;
|
||||
$caname = "";
|
||||
$cka_value = "";
|
||||
undef @precert;
|
||||
next;
|
||||
}
|
||||
# Each certificate's main block is followed by a trust block.
|
||||
elsif(/^# Trust for (?:Certificate )?"(.*)"/) {
|
||||
(!$main_block && !$trust_block) or die "Unexpected trust block";
|
||||
$trust_block = 1;
|
||||
$trust_block_name = $1;
|
||||
if($main_block_name ne $trust_block_name) {
|
||||
die "cert name \"$main_block_name\" != trust name \"$trust_block_name\"";
|
||||
}
|
||||
next;
|
||||
}
|
||||
# Ignore other blocks.
|
||||
#
|
||||
# There is a documentation comment block, a BEGINDATA block, and a bunch of
|
||||
# blocks starting with "# Explicitly Distrust <certname>".
|
||||
#
|
||||
# The latter is for certificates that have already been removed and are not
|
||||
# included. Not all explicitly distrusted certificates are ignored at this
|
||||
# point, just those without an actual certificate.
|
||||
elsif(!$main_block && !$trust_block) {
|
||||
next;
|
||||
}
|
||||
elsif(/^#/) {
|
||||
# The commented lines in a main block are plaintext metadata that describes
|
||||
# the certificate. Issuer, Subject, Fingerprint, etc.
|
||||
if($main_block) {
|
||||
push @precert, $_ if not /^#$/;
|
||||
if(/^# Not Valid After : (.*)/) {
|
||||
my $stamp = $1;
|
||||
use Time::Piece;
|
||||
# Not Valid After : Thu Sep 30 14:01:15 2021
|
||||
my $t = Time::Piece->strptime($stamp, "%a %b %d %H:%M:%S %Y");
|
||||
my $delta = ($t->epoch - time()); # negative means no longer valid
|
||||
if($delta < 0) {
|
||||
$skipnum++;
|
||||
report "Skipping: $caname is not valid anymore" if ($opt_v);
|
||||
report "Skipping: $main_block_name is not valid anymore" if ($opt_v);
|
||||
$valid = 0;
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
$valid = 1;
|
||||
}
|
||||
next;
|
||||
}
|
||||
elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) {
|
||||
push @precert, $_;
|
||||
next;
|
||||
}
|
||||
elsif(/^#|^\s*$/) {
|
||||
undef @precert;
|
||||
next;
|
||||
}
|
||||
chomp;
|
||||
|
||||
# Example:
|
||||
# CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
# \062\060\060\066\061\067\060\060\060\060\060\060\132
|
||||
# END
|
||||
|
||||
if (/^CKA_NSS_SERVER_DISTRUST_AFTER (CK_BBOOL CK_FALSE|MULTILINE_OCTAL)/) {
|
||||
if($1 eq "MULTILINE_OCTAL") {
|
||||
my @timestamp;
|
||||
while (<TXT>) {
|
||||
last if (/^END/);
|
||||
chomp;
|
||||
my @octets = split(/\\/);
|
||||
shift @octets;
|
||||
for (@octets) {
|
||||
push @timestamp, chr(oct);
|
||||
}
|
||||
}
|
||||
# A trailing Z in the timestamp signifies UTC
|
||||
if($timestamp[12] ne "Z") {
|
||||
report "distrust date stamp is not using UTC";
|
||||
}
|
||||
# Example date: 200617000000Z
|
||||
# Means 2020-06-17 00:00:00 UTC
|
||||
my $distrustat =
|
||||
timegm($timestamp[10] . $timestamp[11], # second
|
||||
$timestamp[8] . $timestamp[9], # minute
|
||||
$timestamp[6] . $timestamp[7], # hour
|
||||
$timestamp[4] . $timestamp[5], # day
|
||||
($timestamp[2] . $timestamp[3]) - 1, # month
|
||||
"20" . $timestamp[0] . $timestamp[1]); # year
|
||||
if(time >= $distrustat) {
|
||||
# not trusted anymore
|
||||
$skipnum++;
|
||||
report "Skipping: $caname is not trusted anymore" if ($opt_v);
|
||||
$valid = 0;
|
||||
}
|
||||
else {
|
||||
# still trusted
|
||||
}
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
# this is a match for the start of a certificate
|
||||
if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
|
||||
$start_of_cert = 1
|
||||
}
|
||||
if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) {
|
||||
$caname = $1;
|
||||
}
|
||||
my %trust_purposes_by_level;
|
||||
if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) {
|
||||
$cka_value="";
|
||||
while (<TXT>) {
|
||||
last if (/^END/);
|
||||
chomp;
|
||||
my @octets = split(/\\/);
|
||||
shift @octets;
|
||||
for (@octets) {
|
||||
$cka_value .= chr(oct);
|
||||
}
|
||||
}
|
||||
}
|
||||
next;
|
||||
}
|
||||
if(/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/ && $valid) {
|
||||
elsif(!$valid) {
|
||||
next;
|
||||
}
|
||||
|
||||
chomp;
|
||||
|
||||
if($main_block) {
|
||||
if(/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) {
|
||||
!$start_of_cert or die "Duplicate CKO_CERTIFICATE object";
|
||||
$start_of_cert = 1;
|
||||
next;
|
||||
}
|
||||
elsif(!$start_of_cert) {
|
||||
next;
|
||||
}
|
||||
elsif(/^CKA_LABEL UTF8 \"(.*)\"/) {
|
||||
($caname eq "") or die "Duplicate CKA_LABEL attribute";
|
||||
$caname = $1;
|
||||
if($caname ne $main_block_name) {
|
||||
die "caname \"$caname\" != cert name \"$main_block_name\"";
|
||||
}
|
||||
next;
|
||||
}
|
||||
elsif(/^CKA_VALUE MULTILINE_OCTAL/) {
|
||||
($cka_value eq "") or die "Duplicate CKA_VALUE attribute";
|
||||
while (<TXT>) {
|
||||
last if (/^END/);
|
||||
chomp;
|
||||
my @octets = split(/\\/);
|
||||
shift @octets;
|
||||
for (@octets) {
|
||||
$cka_value .= chr(oct);
|
||||
}
|
||||
}
|
||||
next;
|
||||
}
|
||||
elsif (/^CKA_NSS_SERVER_DISTRUST_AFTER (CK_BBOOL CK_FALSE|MULTILINE_OCTAL)/) {
|
||||
# Example:
|
||||
# CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
# \062\060\060\066\061\067\060\060\060\060\060\060\132
|
||||
# END
|
||||
if($1 eq "MULTILINE_OCTAL") {
|
||||
my @timestamp;
|
||||
while (<TXT>) {
|
||||
last if (/^END/);
|
||||
chomp;
|
||||
my @octets = split(/\\/);
|
||||
shift @octets;
|
||||
for (@octets) {
|
||||
push @timestamp, chr(oct);
|
||||
}
|
||||
}
|
||||
scalar(@timestamp) == 13 or die "Failed parsing timestamp";
|
||||
# A trailing Z in the timestamp signifies UTC
|
||||
if($timestamp[12] ne "Z") {
|
||||
report "distrust date stamp is not using UTC";
|
||||
}
|
||||
# Example date: 200617000000Z
|
||||
# Means 2020-06-17 00:00:00 UTC
|
||||
my $distrustat =
|
||||
timegm($timestamp[10] . $timestamp[11], # second
|
||||
$timestamp[8] . $timestamp[9], # minute
|
||||
$timestamp[6] . $timestamp[7], # hour
|
||||
$timestamp[4] . $timestamp[5], # day
|
||||
($timestamp[2] . $timestamp[3]) - 1, # month
|
||||
"20" . $timestamp[0] . $timestamp[1]); # year
|
||||
if(time >= $distrustat) {
|
||||
# not trusted anymore
|
||||
$skipnum++;
|
||||
report "Skipping: $main_block_name is not trusted anymore" if ($opt_v);
|
||||
$valid = 0;
|
||||
}
|
||||
else {
|
||||
# still trusted
|
||||
}
|
||||
}
|
||||
next;
|
||||
}
|
||||
else {
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$trust_block || !$start_of_cert || $caname eq "" || $cka_value eq "") {
|
||||
die "Certificate extraction failed";
|
||||
}
|
||||
|
||||
my %trust_purposes_by_level;
|
||||
|
||||
if(/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/) {
|
||||
# now scan the trust part to determine how we should trust this cert
|
||||
while (<TXT>) {
|
||||
last if (/^#/);
|
||||
if(/^\s*$/) {
|
||||
$trust_block = 0;
|
||||
last;
|
||||
}
|
||||
if (/^CKA_TRUST_([A-Z_]+)\s+CK_TRUST\s+CKT_NSS_([A-Z_]+)\s*$/) {
|
||||
if ( !is_in_list($1,@valid_mozilla_trust_purposes) ) {
|
||||
report "Warning: Unrecognized trust purpose for cert: $caname. Trust purpose: $1. Trust Level: $2";
|
||||
@@ -541,33 +623,42 @@ while (<TXT>) {
|
||||
}
|
||||
}
|
||||
|
||||
# Sanity check that an explicitly distrusted certificate only has trust
|
||||
# purposes with a trust level of NOT_TRUSTED.
|
||||
#
|
||||
# Certificate objects that are explicitly distrusted are in a certificate
|
||||
# block that starts # Certificate "Explicitly Distrust(ed) <certname>",
|
||||
# where "Explicitly Distrust(ed) " was prepended to the original cert name.
|
||||
if($caname =~ /distrust/i ||
|
||||
$main_block_name =~ /distrust/i ||
|
||||
$trust_block_name =~ /distrust/i) {
|
||||
my @levels = keys %trust_purposes_by_level;
|
||||
if(scalar(@levels) != 1 || $levels[0] ne "NOT_TRUSTED") {
|
||||
die "\"$caname\" must have all trust purposes at level NOT_TRUSTED.";
|
||||
}
|
||||
}
|
||||
|
||||
if ( !should_output_cert(%trust_purposes_by_level) ) {
|
||||
$skipnum ++;
|
||||
report "Skipping: $caname" if ($opt_v);
|
||||
report "Skipping: $caname lacks acceptable trust level" if ($opt_v);
|
||||
} else {
|
||||
my $data = $cka_value;
|
||||
$cka_value = "";
|
||||
|
||||
if(!length($data)) {
|
||||
# if empty, skip
|
||||
next;
|
||||
}
|
||||
my $encoded = MIME::Base64::encode_base64($data, '');
|
||||
my $encoded = MIME::Base64::encode_base64($cka_value, '');
|
||||
$encoded =~ s/(.{1,${opt_w}})/$1\n/g;
|
||||
my $pem = "-----BEGIN CERTIFICATE-----\n"
|
||||
. $encoded
|
||||
. "-----END CERTIFICATE-----\n";
|
||||
print CRT "\n$caname\n";
|
||||
print CRT @precert if($opt_m);
|
||||
my $maxStringLength = length(decode('UTF-8', $caname, Encode::FB_CROAK | Encode::LEAVE_SRC));
|
||||
print CRT ("=" x $maxStringLength . "\n");
|
||||
if ($opt_t) {
|
||||
foreach my $key (sort keys %trust_purposes_by_level) {
|
||||
my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}});
|
||||
$maxStringLength = List::Util::max( length($string), $maxStringLength );
|
||||
print CRT $string . "\n";
|
||||
}
|
||||
}
|
||||
print CRT ("=" x $maxStringLength . "\n");
|
||||
if($opt_m) {
|
||||
print CRT for @precert;
|
||||
}
|
||||
if (!$opt_t) {
|
||||
print CRT $pem;
|
||||
} else {
|
||||
@@ -597,13 +688,10 @@ while (<TXT>) {
|
||||
open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!";
|
||||
}
|
||||
}
|
||||
report "Parsing: $caname" if ($opt_v);
|
||||
report "Processed: $caname" if ($opt_v);
|
||||
$certnum ++;
|
||||
$start_of_cert = 0;
|
||||
}
|
||||
undef @precert;
|
||||
}
|
||||
|
||||
}
|
||||
close(TXT) or die "Couldn't close $txt: $!\n";
|
||||
close(CRT) or die "Couldn't close $crt.~: $!\n";
|
||||
|
||||
Reference in New Issue
Block a user