- 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
/.*build.log
/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,
# 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 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
URL: https://fedoraproject.org/wiki/CA-Certificates
@ -404,6 +404,28 @@ fi
%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
- 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
release="1.0"
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}
#make sure the the current version is newer than what is already there
@ -113,13 +128,15 @@ if [ $? -ne 0 ]; then
exit 1;
fi
# merge the signing certs into the normal certdata.txt file.
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
# Verify everything is good with the user
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
echo ""

View File

@ -3,16 +3,62 @@
# This script fetches the object signing list from the Microsoft list. It then
# mergest that list into the fetched certdata.txt.
#
baseurl="https://ccadb-public.secure.force.com/microsoft/IncludedRootsPEMTxtForMSFT?TrustBitsInclude=Code%20Signing"
target="microsoft_code_siging.pem"
giturl="https://github.com/dotnet/sdk"
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"
baseurl=""
merge=1
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
case $1 in
"-g")
shift
giturl=$1
;;
"-r")
shift
gitrawurl=$1
;;
"-t")
shift
treedir=$1
;;
"-r")
shift
release=$1
;;
"-u")
shift
baseurl=$1
release="unknown"
;;
"-o")
shift
@ -26,11 +72,16 @@ while [ -n "$1" ]; do
merge=0
;;
"-d")
shift
diff=1
difffile=$1
;;
*)
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 "-o target name of the codesigning target"
echo "-c certdata patch to certdata.txt to merge with"
@ -42,6 +93,17 @@ while [ -n "$1" ]; do
shift
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}
@ -53,7 +115,6 @@ out=${certdata}
if [ ${diff} -eq 1 ]; then
out=${certdata}.out
fi
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

View File

@ -30,7 +30,7 @@ import subprocess
import getopt
import asn1
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import hashes, serialization
from datetime import datetime
from dateutil.parser import parse
@ -118,6 +118,40 @@ def isDistrusted(obj) :
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'
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:
opts, args = getopt.getopt(sys.argv[1:],"c:o:p:t:l:x:",)
except getopt.GetoptError as err:
@ -146,11 +180,13 @@ for opt, arg in opts:
dateString = arg
# parse dateString
print ("datastring=",dateString)
verifyDate = True
if dateString.upper() == "NEVER":
verifyDate = False
else:
date = getdate(dateString)
print ("verifyDate=",verifyDate)
# read the pem file
@ -193,7 +229,7 @@ for line in open(certdata, 'r'):
# collect all the inline comments in this object
obj['Comment'] += comment
comment = ""
objects.append(obj)
addObj(objects, obj, None, False)
obj = dict()
in_obj = False
continue
@ -232,14 +268,15 @@ for line in open(certdata, 'r'):
binval = bytearray()
continue
obj[field] = value
if len(list(obj.items())) > 0:
objects.append(obj)
addObj(objects, obj, None, False)
# strip out expired certificates from certdata.txt
if verifyDate :
for obj in objects:
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) :
trust_obj = getTrust(objects,obj['CKA_SERIAL_NUMBER'],obj['CKA_ISSUER'])
# we don't remove distrusted expired certificates
@ -265,11 +302,12 @@ for certval in pemcerts:
label=cert.subject.get_attributes_for_oid(x509.oid.NameOID.ORGANIZATION_NAME)[0].value
except:
label="Unknown Certificate"
if cert.not_valid_after <= date:
print(" Skipping code signing cert %s"%label)
print(" Expires: %s"%cert.not_valid_after.strftime("%m/%d/%Y"))
print(" Prune time %s: "%date.strftime("%m/%d/%Y"))
continue
if verifyDate :
if cert.not_valid_after <= date:
print(" Skipping code signing cert %s"%label)
print(" Expires: %s"%cert.not_valid_after.strftime("%m/%d/%Y"))
print(" Prune time %s: "%date.strftime("%m/%d/%Y"))
continue
certhashsha1 = cert.fingerprint(hashes.SHA1())
certhashmd5 = cert.fingerprint(hashes.MD5())
@ -292,6 +330,32 @@ for certval in pemcerts:
break
if found :
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
obj=dict()
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_SERVER_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
obj=dict()
@ -343,7 +409,7 @@ for certval in pemcerts:
else:
obj[t] = 'CKT_NSS_MUST_VERIFY_TRUST'
obj['CKA_TRUST_STEP_UP_APPROVED'] = 'CK_FALSE'
objects.append(obj)
label = addObj(objects, obj, 'CodeSigning', True)
print('Adding code signing cert "'+label+'"');
# now dump the results