- Update fetch to handle merging microsoft code signing certs.

- Update fetchobjsign.sh and merge2certdata.py to their
ca-certificate-scripts equivalent.
 - Update to CKBI 2.62-v7.0.401 from NSS 3.93
   Removing:
    # Certificate "Camerfirma Chambers of Commerce Root"
    # Certificate "Hongkong Post Root CA 1"
    # Certificate "FNMT-RCM"
   Adding:
    # Certificate "LAWtrust Root CA2 (4096)"
    # Certificate "Sectigo Public Email Protection Root E46"
    # Certificate "Sectigo Public Email Protection Root R46"
    # Certificate "Sectigo Public Server Authentication Root E46"
    # Certificate "Sectigo Public Server Authentication Root R46"
    # Certificate "SSL.com TLS RSA Root CA 2022"
    # Certificate "SSL.com TLS ECC Root CA 2022"
    # Certificate "SSL.com Client ECC Root CA 2022"
    # Certificate "SSL.com Client RSA Root CA 2022"
    # Certificate "Atos TrustedRoot Root CA ECC G2 2020"
    # Certificate "Atos TrustedRoot Root CA RSA G2 2020"
    # Certificate "Atos TrustedRoot Root CA ECC TLS 2021"
    # Certificate "Atos TrustedRoot Root CA RSA TLS 2021"
    # Certificate "Chambers of Commerce Root"
This commit is contained in:
Robert Relyea 2023-10-04 14:31:59 -07:00
parent e004a0c69f
commit fe9aee3d97
6 changed files with 2862 additions and 1104 deletions

4
.gitignore vendored
View File

@ -3,3 +3,7 @@ noarch
clog clog
/.*build.log /.*build.log
/ca-certificates /ca-certificates
certdata.txt.orig
codesign-release.txt
microsoft_sign_obj_ca.pem

View File

@ -35,10 +35,10 @@ Name: ca-certificates
# to have increasing version numbers. However, the new scheme will work, # to have increasing version numbers. However, the new scheme will work,
# because all future versions will start with 2013 or larger.) # because all future versions will start with 2013 or larger.)
Version: 2023.2.60_v7.0.306 Version: 2023.2.62-v7.0.401
# for Rawhide, please always use release >= 2 # for Rawhide, please always use release >= 2
# for Fedora release branches, please use release < 2 (1.0, 1.1, ...) # for Fedora release branches, please use release < 2 (1.0, 1.1, ...)
Release: 4%{?dist} Release: 2%{?dist}
License: MIT AND GPL-2.0-or-later License: MIT AND GPL-2.0-or-later
URL: https://fedoraproject.org/wiki/CA-Certificates URL: https://fedoraproject.org/wiki/CA-Certificates
@ -404,6 +404,28 @@ fi
%changelog %changelog
*Wed Oct 04 2023 Robert Relyea <rrelyea@redhat.com> 2023.2.62-v7.0.401-2
- Update to CKBI 2.62-v7.0.401 from NSS 3.93
Removing:
# Certificate "Camerfirma Chambers of Commerce Root"
# Certificate "Hongkong Post Root CA 1"
# Certificate "FNMT-RCM"
Adding:
# Certificate "LAWtrust Root CA2 (4096)"
# Certificate "Sectigo Public Email Protection Root E46"
# Certificate "Sectigo Public Email Protection Root R46"
# Certificate "Sectigo Public Server Authentication Root E46"
# Certificate "Sectigo Public Server Authentication Root R46"
# Certificate "SSL.com TLS RSA Root CA 2022"
# Certificate "SSL.com TLS ECC Root CA 2022"
# Certificate "SSL.com Client ECC Root CA 2022"
# Certificate "SSL.com Client RSA Root CA 2022"
# Certificate "Atos TrustedRoot Root CA ECC G2 2020"
# Certificate "Atos TrustedRoot Root CA RSA G2 2020"
# Certificate "Atos TrustedRoot Root CA ECC TLS 2021"
# Certificate "Atos TrustedRoot Root CA RSA TLS 2021"
# Certificate "Chambers of Commerce Root"
* Fri Sep 29 2023 Clemens Lang <cllang@redhat.com> - 2023.2.60_v7.0.306-4 * Fri Sep 29 2023 Clemens Lang <cllang@redhat.com> - 2023.2.60_v7.0.306-4
- update-ca-trust: Support --output and non-root operation (rhbz#2241240) - update-ca-trust: Support --output and non-root operation (rhbz#2241240)

File diff suppressed because it is too large Load Diff

View File

@ -94,6 +94,21 @@ if [ `basename ${cwd}` = rawhide ]; then
else else
release="1.0" release="1.0"
fi fi
# fetch the codesigning certs now so we can get
# the code signing version number
if [ ${skip_signed_obj} -eq 0 ]; then
./fetch_objsign.sh
if [ -f codesign-release.txt ]; then
mcs_version=$(cat codesign-release.txt)
if [[ $ms_version != "unknown" ]]; then
ckbi_version="${ckbi_version}-${mcs_version}"
fi
signobjects="and Microsoft Signed Objects version $ms_version"
fi
fi
version=${year}.${ckbi_version} version=${year}.${ckbi_version}
#make sure the the current version is newer than what is already there #make sure the the current version is newer than what is already there
@ -113,13 +128,15 @@ if [ $? -ne 0 ]; then
exit 1; exit 1;
fi fi
# merge the signing certs into the normal certdata.txt file.
if [ ${skip_signed_obj} -eq 0 ]; then if [ ${skip_signed_obj} -eq 0 ]; then
./fetch_objsign.sh cp certdata.txt certdata.txt.orig
python3 ./mergepem2certdata.py -c "certdata.txt.orig" -p "microsoft_sign_obj_ca.pem" -o "certdata.txt" -t "CKA_TRUST_CODE_SIGNING" -l "Microsoft Code Signing Only Certificate" -x "NEVER"
fi fi
# Verify everything is good with the user # Verify everything is good with the user
echo -e "Upgrading ${current_version} -> ${version}:" echo -e "Upgrading ${current_version} -> ${version}:"
echo -e "*${log_date} ${name} <$email> ${version}-${release}\n - Update to CKBI ${ckbi_version} from NSS ${nss_version}" echo -e "*${log_date} ${name} <$email> ${version}-${release}\n - Update to CKBI ${ckbi_version} from NSS ${nss_version}${sign_objects}"
./check_certs.sh ./check_certs.sh
echo "" echo ""

View File

@ -3,16 +3,62 @@
# This script fetches the object signing list from the Microsoft list. It then # This script fetches the object signing list from the Microsoft list. It then
# mergest that list into the fetched certdata.txt. # mergest that list into the fetched certdata.txt.
# #
baseurl="https://ccadb-public.secure.force.com/microsoft/IncludedRootsPEMTxtForMSFT?TrustBitsInclude=Code%20Signing" giturl="https://github.com/dotnet/sdk"
target="microsoft_code_siging.pem" gitrawurl="https://raw.githubusercontent.com/dotnet/sdk"
release="latest"
treedir="src/Layout/redist/trustedroots/codesignctl.pem"
target="microsoft_sign_obj_ca.pem"
certdata="./certdata.txt" certdata="./certdata.txt"
baseurl=""
merge=1 merge=1
diff=0 diff=0
function getlatest
{
local url=$1
local latest="0"
local tags=($(git ls-remote --tags ${url}))
for tag in "${tags[@]}"
do
if [[ ! ${tag} =~ refs/.* ]]; then
continue # skip hashes
fi
if [[ ${tag} =~ .*preview.* ]]; then
continue # skip preview tags, we only want release tags
fi
if [[ ${tag} =~ .*rc.* ]]; then
continue # skip release candidate tags, we only want release tags
fi
if [[ ${latest} < ${tag} ]]; then
latest=$tag
fi
done
latest=${latest##refs/tags/}
echo $latest
}
while [ -n "$1" ]; do while [ -n "$1" ]; do
case $1 in case $1 in
"-g")
shift
giturl=$1
;;
"-r")
shift
gitrawurl=$1
;;
"-t")
shift
treedir=$1
;;
"-r")
shift
release=$1
;;
"-u") "-u")
shift shift
baseurl=$1 baseurl=$1
release="unknown"
;; ;;
"-o") "-o")
shift shift
@ -26,11 +72,16 @@ while [ -n "$1" ]; do
merge=0 merge=0
;; ;;
"-d") "-d")
shift
diff=1 diff=1
difffile=$1 difffile=$1
;; ;;
*) *)
echo "usage: $0 [-u URL] [-o target] [-c certdata] [-n]" echo "usage: $0 [-u URL] [-o target] [-c certdata] [-n]"
echo "-g URL git URL to fetch code signing list"
echo "-r URL raw git URL to fetch code signing list"
echo "-t URL git tree directory to fetch code signing list"
echo "-r release code signing list release version"
echo "-u URL base URL to fetch code signing list" echo "-u URL base URL to fetch code signing list"
echo "-o target name of the codesigning target" echo "-o target name of the codesigning target"
echo "-c certdata patch to certdata.txt to merge with" echo "-c certdata patch to certdata.txt to merge with"
@ -42,6 +93,17 @@ while [ -n "$1" ]; do
shift shift
done done
if [ "${release}" = "latest" ]; then
release=$(getlatest ${giturl} )
fi
if [ "${baseurl}" = "" ]; then
baseurl="${gitrawurl}/${release}/${treedir}"
fi
echo $release > "./codesign-release.txt"
echo "Fetching release=${release}, ${target} from ${baseurl}"
wget ${baseurl} -O ${target} wget ${baseurl} -O ${target}
@ -53,7 +115,6 @@ out=${certdata}
if [ ${diff} -eq 1 ]; then if [ ${diff} -eq 1 ]; then
out=${certdata}.out out=${certdata}.out
fi fi
python3 ./mergepem2certdata.py -c "${certdata}" -p "${target}" -o "${out}" -t "CKA_TRUST_CODE_SIGNING" -l "Microsoft Code Signing Only Certificate" python3 ./mergepem2certdata.py -c "${certdata}" -p "${target}" -o "${out}" -t "CKA_TRUST_CODE_SIGNING" -l "Microsoft Code Signing Only Certificate"
if [ ${diff} -eq 1 ]; then if [ ${diff} -eq 1 ]; then

View File

@ -30,7 +30,7 @@ import subprocess
import getopt import getopt
import asn1 import asn1
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import hashes, serialization
from datetime import datetime from datetime import datetime
from dateutil.parser import parse from dateutil.parser import parse
@ -118,6 +118,40 @@ def isDistrusted(obj) :
return False return False
return obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_NOT_TRUSTED' and obj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_NOT_TRUSTED' and obj['CKA_TRUST_CODE_SIGNING'] == 'CKT_NSS_NOT_TRUSTED' return obj['CKA_TRUST_SERVER_AUTH'] == 'CKT_NSS_NOT_TRUSTED' and obj['CKA_TRUST_EMAIL_PROTECTION'] == 'CKT_NSS_NOT_TRUSTED' and obj['CKA_TRUST_CODE_SIGNING'] == 'CKT_NSS_NOT_TRUSTED'
def stripQuotes(label) :
if label[:1] == "\"" :
label=label[1:]
if label[-1] == "\"" :
label = label[:-1]
return label
# another object of the same class has the same label
def labelExists(objlist, obj) :
for iobj in objlist:
if obj['CKA_CLASS'] == iobj['CKA_CLASS'] and obj['CKA_LABEL'] == iobj['CKA_LABEL']:
return True
return False
# add an object, make sure that label is unique
def addObj(objlist, newObj, specialLabel, drop) :
label = stripQuotes(newObj['CKA_LABEL'])
count=1
if specialLabel != None :
count=0
label=label+' '+specialLabel
# make sure the label is unique
while labelExists(objlist, newObj) :
if drop :
return 'DROPPED'
if count != 0 :
newObj['CKA_LABEL'] = "\"%s %d\""%(label,count)
else :
newObj['CKA_LABEL'] = "\"%s\""%label
count=count+1
objlist.append(obj)
return stripQuotes(newObj['CKA_LABEL'])
try: try:
opts, args = getopt.getopt(sys.argv[1:],"c:o:p:t:l:x:",) opts, args = getopt.getopt(sys.argv[1:],"c:o:p:t:l:x:",)
except getopt.GetoptError as err: except getopt.GetoptError as err:
@ -146,11 +180,13 @@ for opt, arg in opts:
dateString = arg dateString = arg
# parse dateString # parse dateString
print ("datastring=",dateString)
verifyDate = True verifyDate = True
if dateString.upper() == "NEVER": if dateString.upper() == "NEVER":
verifyDate = False verifyDate = False
else: else:
date = getdate(dateString) date = getdate(dateString)
print ("verifyDate=",verifyDate)
# read the pem file # read the pem file
@ -193,7 +229,7 @@ for line in open(certdata, 'r'):
# collect all the inline comments in this object # collect all the inline comments in this object
obj['Comment'] += comment obj['Comment'] += comment
comment = "" comment = ""
objects.append(obj) addObj(objects, obj, None, False)
obj = dict() obj = dict()
in_obj = False in_obj = False
continue continue
@ -232,14 +268,15 @@ for line in open(certdata, 'r'):
binval = bytearray() binval = bytearray()
continue continue
obj[field] = value obj[field] = value
if len(list(obj.items())) > 0: if len(list(obj.items())) > 0:
objects.append(obj) addObj(objects, obj, None, False)
# strip out expired certificates from certdata.txt # strip out expired certificates from certdata.txt
if verifyDate : if verifyDate :
for obj in objects: for obj in objects:
if obj['CKA_CLASS'] == 'CKO_CERTIFICATE' : if obj['CKA_CLASS'] == 'CKO_CERTIFICATE' :
cert = x509.load_der_x509_certificate(obj['CKA_VALUE']) cert = x509.load_der_x509_certificate(bytes(obj['CKA_VALUE']))
if (cert.not_valid_after <= date) : if (cert.not_valid_after <= date) :
trust_obj = getTrust(objects,obj['CKA_SERIAL_NUMBER'],obj['CKA_ISSUER']) trust_obj = getTrust(objects,obj['CKA_SERIAL_NUMBER'],obj['CKA_ISSUER'])
# we don't remove distrusted expired certificates # we don't remove distrusted expired certificates
@ -265,6 +302,7 @@ for certval in pemcerts:
label=cert.subject.get_attributes_for_oid(x509.oid.NameOID.ORGANIZATION_NAME)[0].value label=cert.subject.get_attributes_for_oid(x509.oid.NameOID.ORGANIZATION_NAME)[0].value
except: except:
label="Unknown Certificate" label="Unknown Certificate"
if verifyDate :
if cert.not_valid_after <= date: if cert.not_valid_after <= date:
print(" Skipping code signing cert %s"%label) print(" Skipping code signing cert %s"%label)
print(" Expires: %s"%cert.not_valid_after.strftime("%m/%d/%Y")) print(" Expires: %s"%cert.not_valid_after.strftime("%m/%d/%Y"))
@ -292,6 +330,32 @@ for certval in pemcerts:
break break
if found : if found :
continue continue
# check for almost duplicates, certs with the same subject and key, but
# different values. If they exist, treat them as the same certificate
for obj in objects:
if obj['CKA_CLASS'] != 'CKO_CERTIFICATE':
continue
# do they have the same subject?
if obj['CKA_SUBJECT'] != cert.subject.public_bytes():
continue
# do they have the same public key?
cert2 = x509.load_der_x509_certificate(bytes(obj['CKA_VALUE']))
if cert2.public_key().public_bytes(serialization.Encoding.DER,serialization.PublicFormat.SubjectPublicKeyInfo) != cert.public_key().public_bytes(serialization.Encoding.DER,serialization.PublicFormat.SubjectPublicKeyInfo) :
continue
#found now update trust record
trust_obj = getTrust(objects,obj['CKA_SERIAL_NUMBER'],obj['CKA_ISSUER'])
if trust_obj is None :
print('Couldn\'t find trust object for "'+obj['CKA_LABEL']);
exit
trust_obj[trust] = 'CKT_NSS_TRUSTED_DELEGATOR'
found = True
print('Updating sister certificate "'+obj['CKA_LABEL']+'" with code signing based on Microsoft "'+label+'"');
break
if found :
break
if found :
continue
# append this certificate # append this certificate
obj=dict() obj=dict()
time='%a %b %d %H:%M:%S %Y' time='%a %b %d %H:%M:%S %Y'
@ -323,7 +387,9 @@ for certval in pemcerts:
obj['CKA_NSS_MOZILLA_CA_POLICY'] = 'CK_FALSE' obj['CKA_NSS_MOZILLA_CA_POLICY'] = 'CK_FALSE'
obj['CKA_NSS_SERVER_DISTRUST_AFTER'] = 'CK_FALSE' obj['CKA_NSS_SERVER_DISTRUST_AFTER'] = 'CK_FALSE'
obj['CKA_NSS_EMAIL_DISTRUST_AFTER'] = 'CK_FALSE' obj['CKA_NSS_EMAIL_DISTRUST_AFTER'] = 'CK_FALSE'
objects.append(obj) label = addObj(objects, obj, 'CodeSigning', True)
if label == 'DROPPED' :
continue
# append the trust values # append the trust values
obj=dict() obj=dict()
@ -343,7 +409,7 @@ for certval in pemcerts:
else: else:
obj[t] = 'CKT_NSS_MUST_VERIFY_TRUST' obj[t] = 'CKT_NSS_MUST_VERIFY_TRUST'
obj['CKA_TRUST_STEP_UP_APPROVED'] = 'CK_FALSE' obj['CKA_TRUST_STEP_UP_APPROVED'] = 'CK_FALSE'
objects.append(obj) label = addObj(objects, obj, 'CodeSigning', True)
print('Adding code signing cert "'+label+'"'); print('Adding code signing cert "'+label+'"');
# now dump the results # now dump the results