diff options
Diffstat (limited to 'main/ca-certificates')
5 files changed, 15 insertions, 948 deletions
diff --git a/main/ca-certificates/0001-update-ca-fix-compiler-warning.patch b/main/ca-certificates/0001-update-ca-fix-compiler-warning.patch deleted file mode 100644 index 9630cf7fd6c..00000000000 --- a/main/ca-certificates/0001-update-ca-fix-compiler-warning.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 3184fe80e403b9dc6d5fe3b7ebcd9d375363e2e4 Mon Sep 17 00:00:00 2001 -From: Natanael Copa <ncopa@alpinelinux.org> -Date: Wed, 5 Feb 2020 14:42:38 +0100 -Subject: [PATCH 1/3] update-ca: fix compiler warning - ---- - update-ca.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/update-ca.c b/update-ca.c -index 7bb4f1b..2b3195b 100644 ---- a/update-ca.c -+++ b/update-ca.c -@@ -330,7 +330,7 @@ int main(int a, char **v) - free(tmpfile); - - /* Execute run-parts */ -- static const char *run_parts_args[] = { "run-parts", RUNPARTSDIR, 0 }; -+ static char *const run_parts_args[] = { "run-parts", RUNPARTSDIR, 0 }; - execve("/usr/bin/run-parts", run_parts_args, NULL); - execve("/bin/run-parts", run_parts_args, NULL); - perror("run-parts"); --- -2.25.0 - diff --git a/main/ca-certificates/0002-replace-python-script-with-perl-script.patch b/main/ca-certificates/0002-replace-python-script-with-perl-script.patch deleted file mode 100644 index fe7e3d98b9f..00000000000 --- a/main/ca-certificates/0002-replace-python-script-with-perl-script.patch +++ /dev/null @@ -1,874 +0,0 @@ -From 6674063331cc37a6a496e44577d9be434cbfc9a2 Mon Sep 17 00:00:00 2001 -From: Natanael Copa <ncopa@alpinelinux.org> -Date: Wed, 5 Feb 2020 15:58:32 +0100 -Subject: [PATCH 2/3] replace python script with perl script - -we need ca-certificates when bootstrapping new architectures. Avoid use -of python to reduce number of dependencies when bootstrapping. - -So use mk-ca-bundle.pl script from curl, and add a small shell script -that splits the bundle to separate .crt files, similar way that the -python script did. ---- - .gitignore | 1 + - Makefile | 11 +- - certdata2pem.py | 155 ------------ - mk-ca-bundle.pl | 604 +++++++++++++++++++++++++++++++++++++++++++++ - split-ca-bundle.sh | 30 +++ - 5 files changed, 642 insertions(+), 159 deletions(-) - delete mode 100644 certdata2pem.py - create mode 100644 mk-ca-bundle.pl - create mode 100644 split-ca-bundle.sh - -diff --git a/.gitignore b/.gitignore -index 8878f38..6f5e9fe 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -2,3 +2,4 @@ update-ca-certificates - c_rehash - certdata.stamp - *.crt -+*.pem -diff --git a/Makefile b/Makefile -index 3eb6672..c688d73 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,4 +1,4 @@ --PYTHON := python3 -+PERL := perl - - all: update-ca-certificates c_rehash certdata.stamp - -@@ -8,8 +8,11 @@ update-ca-certificates: update-ca.c - c_rehash: c_rehash.c - ${CC} ${CFLAGS} -o $@ c_rehash.c -lcrypto ${LDFLAGS} - --certdata.stamp: -- ${PYTHON} certdata2pem.py -+cert.pem: mk-ca-bundle.pl -+ ${PERL} mk-ca-bundle.pl -n -w 64 $@ -+ -+certdata.stamp: cert.pem split-ca-bundle.sh -+ ${SHELL} split-ca-bundle.sh < cert.pem - touch $@ - - install: all -@@ -29,7 +32,7 @@ install: all - install -m755 c_rehash ${DESTDIR}/usr/bin - - clean: -- rm -rf update-ca-certificates c_rehash certdata.stamp *.crt -+ rm -rf update-ca-certificates c_rehash certdata.stamp *.crt cert.pem - - # https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt - update: -diff --git a/certdata2pem.py b/certdata2pem.py -deleted file mode 100644 -index f91422b..0000000 ---- a/certdata2pem.py -+++ /dev/null -@@ -1,155 +0,0 @@ --#!/usr/bin/python --# vim:set et sw=4: --# --# certdata2pem.py - splits certdata.txt into multiple files --# --# Copyright (C) 2009 Philipp Kern <pkern@debian.org> --# --# This program is free software; you can redistribute it and/or modify --# it under the terms of the GNU General Public License as published by --# the Free Software Foundation; either version 2 of the License, or --# (at your option) any later version. --# --# This program is distributed in the hope that it will be useful, --# but WITHOUT ANY WARRANTY; without even the implied warranty of --# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --# GNU General Public License for more details. --# --# You should have received a copy of the GNU General Public License --# along with this program; if not, write to the Free Software --# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, --# USA. -- --import base64 --import os.path --import re --import sys --import textwrap --import io -- --objects = [] -- --# Dirty file parser. --in_data, in_multiline, in_obj = False, False, False --field, type, value, obj = None, None, None, dict() -- --# Python 3 will not let us decode non-ascii characters if we --# have not specified an encoding, but Python 2's open does not --# have an option to set the encoding. Python 3's open is io.open --# and io.open has been backported to Python 2.6 and 2.7, so use io.open. --for line in io.open('certdata.txt', 'rt', encoding='utf8'): -- # Ignore the file header. -- if not in_data: -- if line.startswith('BEGINDATA'): -- in_data = True -- continue -- # Ignore comment lines. -- if line.startswith('#'): -- continue -- # Empty lines are significant if we are inside an object. -- if in_obj and len(line.strip()) == 0: -- objects.append(obj) -- obj = dict() -- in_obj = False -- continue -- if len(line.strip()) == 0: -- continue -- if in_multiline: -- if not line.startswith('END'): -- if type == 'MULTILINE_OCTAL': -- line = line.strip() -- for i in re.finditer(r'\\([0-3][0-7][0-7])', line): -- value.append(int(i.group(1), 8)) -- else: -- value += line -- continue -- obj[field] = value -- in_multiline = False -- continue -- if line.startswith('CKA_CLASS'): -- in_obj = True -- line_parts = line.strip().split(' ', 2) -- if len(line_parts) > 2: -- field, type = line_parts[0:2] -- value = ' '.join(line_parts[2:]) -- elif len(line_parts) == 2: -- field, type = line_parts -- value = None -- else: -- raise NotImplementedError('line_parts < 2 not supported.') -- if type == 'MULTILINE_OCTAL': -- in_multiline = True -- value = bytearray() -- continue -- obj[field] = value --if len(obj) > 0: -- objects.append(obj) -- --# Read blacklist. --blacklist = [] --if os.path.exists('blacklist.txt'): -- for line in open('blacklist.txt', 'r'): -- line = line.strip() -- if line.startswith('#') or len(line) == 0: -- continue -- item = line.split('#', 1)[0].strip() -- blacklist.append(item) -- --# Build up trust database. --trust = dict() --for obj in objects: -- if obj['CKA_CLASS'] != 'CKO_NSS_TRUST': -- continue -- if obj['CKA_LABEL'] in blacklist: -- print("Certificate %s blacklisted, ignoring." % obj['CKA_LABEL']) -- elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_TRUSTED_DELEGATOR': -- trust[obj['CKA_LABEL']] = True -- elif obj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_TRUSTED_DELEGATOR': -- trust[obj['CKA_LABEL']] = True -- elif obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_NOT_TRUSTED': -- print('!'*74) -- print("UNTRUSTED BUT NOT BLACKLISTED CERTIFICATE FOUND: %s" % obj['CKA_LABEL']) -- print('!'*74) -- else: -- print("Ignoring certificate %s. SAUTH=%s, EPROT=%s" % \ -- (obj['CKA_LABEL'], obj['CKA_TRUST_SERVER_AUTH'], -- obj['CKA_TRUST_EMAIL_PROTECTION'])) -- --for obj in objects: -- if obj['CKA_CLASS'] == 'CKO_CERTIFICATE': -- if not obj['CKA_LABEL'] in trust or not trust[obj['CKA_LABEL']]: -- continue -- bname = obj['CKA_LABEL'][1:-1].replace('/', '_')\ -- .replace(' ', '_')\ -- .replace('(', '=')\ -- .replace(')', '=')\ -- .replace(',', '_') -- -- # this is the only way to decode the way NSS stores multi-byte UTF-8 -- # and we need an escaped string for checking existence of things -- # otherwise we're dependant on the user's current locale. -- if bytes != str: -- # We're in python 3, convert the utf-8 string to a -- # sequence of bytes that represents this utf-8 string -- # then encode the byte-sequence as an escaped string that -- # can be passed to open() and os.path.exists() -- bname = bname.encode('utf-8').decode('unicode_escape').encode('latin-1') -- else: -- # Python 2 -- # Convert the unicode string back to its original byte form -- # (contents of files returned by io.open are returned as -- # unicode strings) -- # then to an escaped string that can be passed to open() -- # and os.path.exists() -- bname = bname.encode('utf-8').decode('string_escape') -- -- fname = bname + b'.crt' -- if os.path.exists(fname): -- print("Found duplicate certificate name %s, renaming." % bname) -- fname = bname + b'_2.crt' -- f = open(fname, 'w') -- f.write("-----BEGIN CERTIFICATE-----\n") -- encoded = base64.b64encode(obj['CKA_VALUE']).decode('utf-8') -- f.write("\n".join(textwrap.wrap(encoded, 64))) -- f.write("\n-----END CERTIFICATE-----\n") -- -diff --git a/mk-ca-bundle.pl b/mk-ca-bundle.pl -new file mode 100644 -index 0000000..09e8e5b ---- /dev/null -+++ b/mk-ca-bundle.pl -@@ -0,0 +1,604 @@ -+#!/usr/bin/env perl -+# *************************************************************************** -+# * _ _ ____ _ -+# * Project ___| | | | _ \| | -+# * / __| | | | |_) | | -+# * | (__| |_| | _ <| |___ -+# * \___|\___/|_| \_\_____| -+# * -+# * Copyright (C) 1998 - 2020, 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 -+# * are also available at https://curl.haxx.se/docs/copyright.html. -+# * -+# * You may opt to use, copy, modify, merge, publish, distribute and/or sell -+# * copies of the Software, and permit persons to whom the Software is -+# * furnished to do so, under the terms of the COPYING file. -+# * -+# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -+# * KIND, either express or implied. -+# * -+# *************************************************************************** -+# 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), -+# then parses certdata.txt and extracts CA Root Certificates into PEM format. -+# These are then processed with the OpenSSL commandline tool to produce the -+# final ca-bundle.crt file. -+# The script is based on the parse-certs script written by Roland Krikava. -+# This Perl script works on almost any platform since its only external -+# dependency is the OpenSSL commandline tool for optional text listing. -+# Hacked by Guenter Knauf. -+# -+use Encode; -+use Getopt::Std; -+use MIME::Base64; -+use strict; -+use warnings; -+use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_k $opt_l $opt_m $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w); -+use List::Util; -+use Text::Wrap; -+use Time::Local; -+my $MOD_SHA = "Digest::SHA"; -+eval "require $MOD_SHA"; -+if ($@) { -+ $MOD_SHA = "Digest::SHA::PurePerl"; -+ eval "require $MOD_SHA"; -+} -+eval "require LWP::UserAgent"; -+ -+my %urls = ( -+ 'nss' => -+ 'https://hg.mozilla.org/projects/nss/raw-file/default/lib/ckfw/builtins/certdata.txt', -+ 'central' => -+ 'https://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', -+ 'beta' => -+ 'https://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', -+ 'release' => -+ 'https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', -+); -+ -+$opt_d = 'release'; -+ -+# If the OpenSSL commandline is not in search path you can configure it here! -+my $openssl = 'openssl'; -+ -+my $version = '1.27'; -+ -+$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) -+my $default_mozilla_trust_purposes = "SERVER_AUTH"; -+my $default_mozilla_trust_levels = "TRUSTED_DELEGATOR"; -+$opt_p = $default_mozilla_trust_purposes . ":" . $default_mozilla_trust_levels; -+ -+my @valid_mozilla_trust_purposes = ( -+ "DIGITAL_SIGNATURE", -+ "NON_REPUDIATION", -+ "KEY_ENCIPHERMENT", -+ "DATA_ENCIPHERMENT", -+ "KEY_AGREEMENT", -+ "KEY_CERT_SIGN", -+ "CRL_SIGN", -+ "SERVER_AUTH", -+ "CLIENT_AUTH", -+ "CODE_SIGNING", -+ "EMAIL_PROTECTION", -+ "IPSEC_END_SYSTEM", -+ "IPSEC_TUNNEL", -+ "IPSEC_USER", -+ "TIME_STAMPING", -+ "STEP_UP_APPROVED" -+); -+ -+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). -+); -+ -+my $default_signature_algorithms = $opt_s = "MD5"; -+ -+my @valid_signature_algorithms = ( -+ "MD5", -+ "SHA1", -+ "SHA256", -+ "SHA384", -+ "SHA512" -+); -+ -+$0 =~ s@.*(/|\\)@@; -+$Getopt::Std::STANDARD_HELP_VERSION = 1; -+getopts('bd:fhiklmnp:qs:tuvw:'); -+ -+if(!defined($opt_d)) { -+ # to make plain "-d" use not cause warnings, and actually still work -+ $opt_d = 'release'; -+} -+ -+# Use predefined URL or else custom URL specified on command line. -+my $url; -+if(defined($urls{$opt_d})) { -+ $url = $urls{$opt_d}; -+ if(!$opt_k && $url !~ /^https:\/\//i) { -+ die "The URL for '$opt_d' is not HTTPS. Use -k to override (insecure).\n"; -+ } -+} -+else { -+ $url = $opt_d; -+} -+ -+my $curl = `curl -V`; -+ -+if ($opt_i) { -+ print ("=" x 78 . "\n"); -+ print "Script Version : $version\n"; -+ print "Perl Version : $]\n"; -+ print "Operating System Name : $^O\n"; -+ print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n"; -+ print "Encode::Encoding.pm Version : ${Encode::Encoding::VERSION}\n"; -+ print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n"; -+ print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n" if($LWP::UserAgent::VERSION); -+ print "LWP.pm Version : ${LWP::VERSION}\n" if($LWP::VERSION); -+ print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION); -+ print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION); -+ print ("=" x 78 . "\n"); -+} -+ -+sub warning_message() { -+ if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit -+ print "Warning: Use of this script may pose some risk:\n"; -+ print "\n"; -+ print " 1) If you use HTTP URLs they are subject to a man in the middle attack\n"; -+ print " 2) Default to 'release', but more recent updates may be found in other trees\n"; -+ print " 3) certdata.txt file format may change, lag time to update this script\n"; -+ print " 4) Generally unwise to blindly trust CAs without manual review & verification\n"; -+ print " 5) Mozilla apps use additional security checks aren't represented in certdata\n"; -+ print " 6) Use of this script will make a security engineer grind his teeth and\n"; -+ print " swear at you. ;)\n"; -+ exit; -+ } else { # Short Form Warning -+ print "Warning: Use of this script may pose some risk, -d risk for more details.\n"; -+ } -+} -+ -+sub HELP_MESSAGE() { -+ print "Usage:\t${0} [-b] [-d<certdata>] [-f] [-i] [-k] [-l] [-n] [-p<purposes:levels>] [-q] [-s<algorithms>] [-t] [-u] [-v] [-w<l>] [<outputfile>]\n"; -+ print "\t-b\tbackup an existing version of ca-bundle.crt\n"; -+ print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n"; -+ print "\t\t Valid names are:\n"; -+ print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n"; -+ print "\t-f\tforce rebuild even if certdata.txt is current\n"; -+ print "\t-i\tprint version info about used modules\n"; -+ print "\t-k\tallow URLs other than HTTPS, enable HTTP fallback (insecure)\n"; -+ print "\t-l\tprint license info about certdata.txt\n"; -+ print "\t-m\tinclude meta data in output\n"; -+ print "\t-n\tno download of certdata.txt (to use existing)\n"; -+ print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n"; -+ print "\t\t Valid purposes are:\n"; -+ print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_purposes ) ), "\n"; -+ print "\t\t Valid levels are:\n"; -+ print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_levels ) ), "\n"; -+ print "\t-q\tbe really quiet (no progress output at all)\n"; -+ print wrap("\t","\t\t", "-s\tcomma separated list of certificate signatures/hashes to output in plain text mode. (default: $default_signature_algorithms)\n"); -+ print "\t\t Valid signature algorithms are:\n"; -+ print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_signature_algorithms ) ), "\n"; -+ print "\t-t\tinclude plain text listing of certificates\n"; -+ print "\t-u\tunlink (remove) certdata.txt after processing\n"; -+ print "\t-v\tbe verbose and print out processed CAs\n"; -+ print "\t-w <l>\twrap base64 output lines after <l> chars (default: ${opt_w})\n"; -+ exit; -+} -+ -+sub VERSION_MESSAGE() { -+ print "${0} version ${version} running Perl ${]} on ${^O}\n"; -+} -+ -+warning_message() unless ($opt_q || $url =~ m/^(ht|f)tps:/i ); -+HELP_MESSAGE() if ($opt_h); -+ -+sub report($@) { -+ my $output = shift; -+ -+ print STDERR $output . "\n" unless $opt_q; -+} -+ -+sub is_in_list($@) { -+ my $target = shift; -+ -+ 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 -+sub parse_csv_param($$@) { -+ my $description = shift; -+ my $param_string = shift; -+ my @valid_values = @_; -+ -+ my @values = map { -+ s/^\s+//; # strip leading spaces -+ s/\s+$//; # strip trailing spaces -+ uc $_ # return the modified string as upper case -+ } split( ',', $param_string ); -+ -+ # Find all values which are not in the list of valid values or "ALL" -+ 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 -+ print "Error: Invalid ", $description, scalar(@invalid) == 1 ? ": " : "s: ", join( ", ", map { "\"$_\"" } @invalid ), "\n"; -+ HELP_MESSAGE(); -+ } -+ -+ @values = @valid_values if ( is_in_list("ALL",@values) ); -+ -+ return @values; -+} -+ -+sub sha256 { -+ my $result; -+ if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) { -+ open(FILE, $_[0]) or die "Can't open '$_[0]': $!"; -+ binmode(FILE); -+ $result = $MOD_SHA->new(256)->addfile(*FILE)->hexdigest; -+ close(FILE); -+ } else { -+ # Use OpenSSL command if Perl Digest::SHA modules not available -+ $result = `"$openssl" dgst -r -sha256 "$_[0]"`; -+ $result =~ s/^([0-9a-f]{64}) .+/$1/is; -+ } -+ return $result; -+} -+ -+ -+sub oldhash { -+ my $hash = ""; -+ open(C, "<$_[0]") || return 0; -+ while(<C>) { -+ chomp; -+ if($_ =~ /^\#\# SHA256: (.*)/) { -+ $hash = $1; -+ last; -+ } -+ } -+ close(C); -+ return $hash; -+} -+ -+if ( $opt_p !~ m/:/ ) { -+ print "Error: Mozilla trust identifier list must include both purposes and levels\n"; -+ HELP_MESSAGE(); -+} -+ -+(my $included_mozilla_trust_purposes_string, my $included_mozilla_trust_levels_string) = split( ':', $opt_p ); -+my @included_mozilla_trust_purposes = parse_csv_param( "trust purpose", $included_mozilla_trust_purposes_string, @valid_mozilla_trust_purposes ); -+my @included_mozilla_trust_levels = parse_csv_param( "trust level", $included_mozilla_trust_levels_string, @valid_mozilla_trust_levels ); -+ -+my @included_signature_algorithms = parse_csv_param( "signature algorithm", $opt_s, @valid_signature_algorithms ); -+ -+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 -+ return 1 if ( defined( List::Util::first { is_in_list( $_, @included_mozilla_trust_purposes ) } @{$trust_purposes_by_level{$level}} ) ); -+ } -+ -+ return 0; -+} -+ -+my $crt = $ARGV[0] || 'ca-bundle.crt'; -+(my $txt = $url) =~ s@(.*/|\?.*)@@g; -+ -+my $stdout = $crt eq '-'; -+my $resp; -+my $fetched; -+ -+my $oldhash = oldhash($crt); -+ -+report "SHA256 of old file: $oldhash"; -+ -+if(!$opt_n) { -+ report "Downloading $txt ..."; -+ -+ # If we have an HTTPS URL then use curl -+ if($url =~ /^https:\/\//i) { -+ if($curl) { -+ if($curl =~ /^Protocols:.* https( |$)/m) { -+ report "Get certdata with curl!"; -+ my $proto = !$opt_k ? "--proto =https" : ""; -+ my $quiet = $opt_q ? "-s" : ""; -+ my @out = `curl -w %{response_code} $proto $quiet -o "$txt" "$url"`; -+ if(!$? && @out && $out[0] == 200) { -+ $fetched = 1; -+ report "Downloaded $txt"; -+ } -+ else { -+ report "Failed downloading via HTTPS with curl"; -+ if(-e $txt && !unlink($txt)) { -+ report "Failed to remove '$txt': $!"; -+ } -+ } -+ } -+ else { -+ report "curl lacks https support"; -+ } -+ } -+ else { -+ report "curl not found"; -+ } -+ } -+ -+ # If nothing was fetched then use LWP -+ if(!$fetched) { -+ if($url =~ /^https:\/\//i) { -+ report "Falling back to HTTP"; -+ $url =~ s/^https:\/\//http:\/\//i; -+ } -+ if(!$opt_k) { -+ report "URLs other than HTTPS are disabled by default, to enable use -k"; -+ exit 1; -+ } -+ report "Get certdata with LWP!"; -+ if(!defined(${LWP::UserAgent::VERSION})) { -+ report "LWP is not available (LWP::UserAgent not found)"; -+ exit 1; -+ } -+ my $ua = new LWP::UserAgent(agent => "$0/$version"); -+ $ua->env_proxy(); -+ $resp = $ua->mirror($url, $txt); -+ if($resp && $resp->code eq '304') { -+ report "Not modified"; -+ exit 0 if -e $crt && !$opt_f; -+ } -+ else { -+ $fetched = 1; -+ report "Downloaded $txt"; -+ } -+ if(!$resp || $resp->code !~ /^(?:200|304)$/) { -+ report "Unable to download latest data: " -+ . ($resp? $resp->code . ' - ' . $resp->message : "LWP failed"); -+ exit 1 if -e $crt || ! -r $txt; -+ } -+ } -+} -+ -+my $filedate = $resp ? $resp->last_modified : (stat($txt))[9]; -+my $datesrc = "as of"; -+if(!$filedate) { -+ # mxr.mozilla.org gave us a time, hg.mozilla.org does not! -+ $filedate = time(); -+ $datesrc="downloaded on"; -+} -+ -+# get the hash from the download file -+my $newhash= sha256($txt); -+ -+if(!$opt_f && $oldhash eq $newhash) { -+ report "Downloaded file identical to previous run\'s source file. Exiting"; -+ if($opt_u && -e $txt && !unlink($txt)) { -+ report "Failed to remove $txt: $!\n"; -+ } -+ exit; -+} -+ -+report "SHA256 of new file: $newhash"; -+ -+my $currentdate = scalar gmtime($filedate); -+ -+my $format = $opt_t ? "plain text and " : ""; -+if( $stdout ) { -+ open(CRT, '> -') or die "Couldn't open STDOUT: $!\n"; -+} else { -+ open(CRT,">$crt.~") or die "Couldn't open $crt.~: $!\n"; -+} -+print CRT <<EOT; -+## -+## Bundle of CA Root Certificates -+## -+## Certificate data from Mozilla ${datesrc}: ${currentdate} GMT -+## -+## This is a bundle of X.509 certificates of public Certificate Authorities -+## (CA). These were automatically extracted from Mozilla's root certificates -+## file (certdata.txt). This file can be found in the mozilla source tree: -+## ${url} -+## -+## It contains the certificates in ${format}PEM format and therefore -+## can be directly used with curl / libcurl / php_curl, or with -+## an Apache+mod_ssl webserver for SSL client authentication. -+## Just configure this file as the SSLCACertificateFile. -+## -+## Conversion done with mk-ca-bundle.pl version $version. -+## SHA256: $newhash -+## -+ -+EOT -+ -+report "Processing '$txt' ..."; -+my $caname; -+my $certnum = 0; -+my $skipnum = 0; -+my $start_of_cert = 0; -+my @precert; -+my $cka_value; -+my $valid = 1; -+ -+open(TXT,"$txt") or die "Couldn't open $txt: $!\n"; -+while (<TXT>) { -+ if (/\*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*/) { -+ print CRT; -+ print if ($opt_l); -+ while (<TXT>) { -+ print CRT; -+ print if ($opt_l); -+ last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/); -+ } -+ } -+ elsif(/^# (Issuer|Serial Number|Subject|Not Valid Before|Not Valid After |Fingerprint \(MD5\)|Fingerprint \(SHA1\)):/) { -+ push @precert, $_; -+ $valid = 1; -+ 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); -+ } -+ } -+ } -+ if(/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/ && $valid) { -+ # now scan the trust part to determine how we should trust this cert -+ while (<TXT>) { -+ last if (/^#/); -+ 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"; -+ } elsif ( !is_in_list($2,@valid_mozilla_trust_levels) ) { -+ report "Warning: Unrecognized trust level for cert: $caname. Trust purpose: $1. Trust Level: $2"; -+ } else { -+ push @{$trust_purposes_by_level{$2}}, $1; -+ } -+ } -+ } -+ -+ if ( !should_output_cert(%trust_purposes_by_level) ) { -+ $skipnum ++; -+ report "Skipping: $caname" if ($opt_v); -+ } else { -+ my $data = $cka_value; -+ $cka_value = ""; -+ my $encoded = MIME::Base64::encode_base64($data, ''); -+ $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)); -+ if ($opt_t) { -+ foreach my $key (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_t) { -+ print CRT $pem; -+ } else { -+ my $pipe = ""; -+ foreach my $hash (@included_signature_algorithms) { -+ $pipe = "|$openssl x509 -" . $hash . " -fingerprint -noout -inform PEM"; -+ if (!$stdout) { -+ $pipe .= " >> $crt.~"; -+ close(CRT) or die "Couldn't close $crt.~: $!"; -+ } -+ open(TMP, $pipe) or die "Couldn't open openssl pipe: $!"; -+ print TMP $pem; -+ close(TMP) or die "Couldn't close openssl pipe: $!"; -+ if (!$stdout) { -+ open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!"; -+ } -+ } -+ $pipe = "|$openssl x509 -text -inform PEM"; -+ if (!$stdout) { -+ $pipe .= " >> $crt.~"; -+ close(CRT) or die "Couldn't close $crt.~: $!"; -+ } -+ open(TMP, $pipe) or die "Couldn't open openssl pipe: $!"; -+ print TMP $pem; -+ close(TMP) or die "Couldn't close openssl pipe: $!"; -+ if (!$stdout) { -+ open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!"; -+ } -+ } -+ report "Parsing: $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"; -+unless( $stdout ) { -+ if ($opt_b && -e $crt) { -+ my $bk = 1; -+ while (-e "$crt.~${bk}~") { -+ $bk++; -+ } -+ rename $crt, "$crt.~${bk}~" or die "Failed to create backup $crt.~$bk}~: $!\n"; -+ } elsif( -e $crt ) { -+ unlink( $crt ) or die "Failed to remove $crt: $!\n"; -+ } -+ rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n"; -+} -+if($opt_u && -e $txt && !unlink($txt)) { -+ report "Failed to remove $txt: $!\n"; -+} -+report "Done ($certnum CA certs processed, $skipnum skipped)."; -diff --git a/split-ca-bundle.sh b/split-ca-bundle.sh -new file mode 100644 -index 0000000..d0f39a8 ---- /dev/null -+++ b/split-ca-bundle.sh -@@ -0,0 +1,30 @@ -+#!/bin/sh -+ -+mkcert() { -+ local name="$1" -+ local line -+ rm -f "$name" -+ while read line; do -+ printf "%s\n" "$line" >> "$name" -+ if [ "$line" = "-----END CERTIFICATE-----" ]; then -+ break; -+ fi -+ done -+} -+ -+prev= -+while read line; do -+ case "$line" in -+ =*=) -+ fname="$(printf "%s" "$prev" | tr '/ (),' '__==_').crt" -+ while read cline; do -+ printf "%s\n" "$cline" -+ if [ "$cline" = "-----END CERTIFICATE-----" ]; then -+ break; -+ fi -+ done > "$fname" -+ ;; -+ esac -+ prev="$line" -+done -+ --- -2.25.0 - diff --git a/main/ca-certificates/0003-update-ca-insert-newline-between-certs.patch b/main/ca-certificates/0003-update-ca-insert-newline-between-certs.patch deleted file mode 100644 index 4a945a076ba..00000000000 --- a/main/ca-certificates/0003-update-ca-insert-newline-between-certs.patch +++ /dev/null @@ -1,38 +0,0 @@ -From fd399b2416191bd7f3b0f267bdb530ed829de271 Mon Sep 17 00:00:00 2001 -From: Natanael Copa <ncopa@alpinelinux.org> -Date: Wed, 5 Feb 2020 17:40:57 +0100 -Subject: [PATCH 3/3] update-ca: insert newline between certs - -There may be certificates that lack a trailing newline, which is allowed -in the certificate format. We work around that by inject a newline after -each cert. - -see https://gitlab.alpinelinux.org/alpine/aports/issues/8379 ---- - update-ca.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/update-ca.c b/update-ca.c -index 2b3195b..0260f83 100644 ---- a/update-ca.c -+++ b/update-ca.c -@@ -191,6 +191,7 @@ static void proc_localglobaldir(const char *fullpath, struct hash *h, int tmpfil - fprintf(stderr, "Warning! Cannot hash: %s\n", fullpath); - if (!copyfile(fullpath, tmpfile_fd)) - fprintf(stderr, "Warning! Cannot copy to bundle: %s\n", fullpath); -+ write(tmpfile_fd, "\n", 1); - free(actual_file); - } - -@@ -260,7 +261,7 @@ static bool dir_readfiles(struct hash* d, const char* path, - DIR *dp = opendir(path); - if (!dp) - return false; -- -+ - struct dirent *dirp; - while ((dirp = readdir(dp)) != NULL) { - if (str_begins(dirp->d_name, ".")) --- -2.25.0 - diff --git a/main/ca-certificates/APKBUILD b/main/ca-certificates/APKBUILD index 9d6e2cbcf71..15de66d5d8c 100644 --- a/main/ca-certificates/APKBUILD +++ b/main/ca-certificates/APKBUILD @@ -1,7 +1,7 @@ # Contributor: Sören Tempel <soeren+alpine@soeren-tempel.net> # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=ca-certificates -pkgver=20211220 +pkgver=20240226 pkgrel=0 pkgdesc="Common CA certificates PEM files from Mozilla" url="https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/" @@ -9,10 +9,9 @@ arch="all" # There is a GPL-2.0-or-later script inside the source but it is not shipped license="MPL-2.0 AND MIT" makedepends_build="perl" -makedepends_host="openssl1.1-compat-dev" -subpackages="$pkgname-doc $pkgname-bundle" -# c_rehash is either in libcrypto1.0 or openssl depending on package, grr. replace both of them -replaces="libcrypto1.0 openssl openssl1.0" +makedepends_host="openssl-dev>3" +subpackages="$pkgname-doc $pkgname-bundle::noarch" +replaces="openssl" options="!fhs !check" triggers="ca-certificates.trigger=/usr/share/ca-certificates:/usr/local/share/ca-certificates:/etc/ssl/certs:/etc/ca-certificates/update.d" install="$pkgname.post-deinstall" @@ -26,15 +25,15 @@ package() { make install DESTDIR="$pkgdir" ( - echo "# Automatically generated by $pkgname-$pkgver-$pkgrel" + echo "# Automatically generated by $pkgname-$pkgver-r$pkgrel" echo "# $(date -u)" - echo "# Do not edit." + echo "#" cd "$pkgdir"/usr/share/ca-certificates find . -name '*.crt' | sort | cut -b3- ) > "$pkgdir"/etc/ca-certificates.conf # generate the bundle in similar way as update-ca-certificates would do - for i in $(ls *.crt | sort); do + find -- *.crt | sort | while read -r i; do cat "$i" printf "\n" done > "$pkgdir"/etc/ssl/certs/ca-certificates.crt @@ -55,15 +54,20 @@ package() { bundle() { pkgdesc="Pre generated bundle of Mozilla certificates" - replaces="libressl2.7-libcrypto" + replaces="libressl2.7-libcrypto libcrypto1.1" provides="$pkgname-cacert=$pkgver-r$pkgrel" mkdir -p "$subpkgdir"/etc/ssl/certs mv "$pkgdir"/etc/ssl/certs/ca-certificates.crt \ "$subpkgdir"/etc/ssl/certs/ ln -s certs/ca-certificates.crt \ "$subpkgdir"/etc/ssl/cert.pem + + # Symlinks for OpenSSL 1.1 compatibility + mkdir -p "$subpkgdir"/etc/ssl1.1/ + ln -s /etc/ssl/certs "$subpkgdir"/etc/ssl1.1/ + ln -s /etc/ssl/cert.pem "$subpkgdir"/etc/ssl1.1/ } sha512sums=" -6b486384c80b29632939a28524acfeeedc60f5df44da86bc16ce79f3cf2ff464455e963ebeb410c3072829b9083215961b32c18673ff77b211652d4c1e870799 ca-certificates-20211220.tar.bz2 +48a872010eab178dc64aa09ee7d977403b73416e870d0cd2a2dcf004fb86f1468547c116ef82413c3603ac1b9bc20ea70fd169a9426ae756b234ea9fa0287dca ca-certificates-20240226.tar.bz2 " diff --git a/main/ca-certificates/ca-certificates.trigger b/main/ca-certificates/ca-certificates.trigger index eff198163eb..a68e9c7d928 100644 --- a/main/ca-certificates/ca-certificates.trigger +++ b/main/ca-certificates/ca-certificates.trigger @@ -1,3 +1,3 @@ #!/bin/sh -/usr/sbin/update-ca-certificates --fresh &> /dev/null +/usr/sbin/update-ca-certificates &> /dev/null exit 0 |