Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions certs/check_cert_chains.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,70 @@
# rather than as a runtime TLS handshake failure. Two checks per pair:
# 1. identity: leaf issuer DN == CA subject DN and leaf AKID == CA SKID; runs
# on any OpenSSL and catches the DN drift that has actually broken CI.
# 2. crypto: openssl verify, only when OpenSSL supports the CA's algorithm
# (ML-DSA needs 3.5+; otherwise skipped with notice). Exit 0 if all consistent.
# 2. crypto: openssl verify, only when this OpenSSL will verify the leaf's
# signature algorithm (ML-DSA needs 3.5+, SHA-1 is refused outright by some
# distributions); otherwise skipped with notice. Exit 0 if all consistent.

# Run from the certs directory regardless of the caller's working directory.
cd "$(dirname "$0")" || exit 1

# Pairs to check: "<leaf-pem> <ca-pem> <alg-class>", one per line. alg-class is
# "classic" (RSA/ECDSA) or "mldsa" (needs OpenSSL 3.5+ to verify); it is stated
# here, not parsed, since old OpenSSL cannot decode an ML-DSA cert. Add lines here.
# "classic" (RSA/ECDSA), "mldsa" (needs OpenSSL 3.5+ to verify) or "sha1"; it is
# stated here, not parsed, since old OpenSSL cannot decode an ML-DSA cert. A
# multi-certificate file is checked on its first certificate, which is the leaf.
# Add lines here.
pairs="rsapss/ecc-leaf-rsapss.pem rsapss/ca-rsapss.pem classic
mldsa/ecc-leaf-mldsa44.pem mldsa/mldsa44-cert.pem mldsa"
mldsa/ecc-leaf-mldsa44.pem mldsa/mldsa44-cert.pem mldsa
server-cert-sha1.pem ca-cert.pem sha1
client-cert-sha1.pem ca-cert.pem sha1
server-cert-sha1-root.pem ca-cert.pem classic"

failed=0

# Report whether this OpenSSL can cryptographically verify the given signature
# algorithm class. Returns 0 (supported) or 1 (not supported).
#
# $1 Algorithm class from the pairs table (classic or mldsa).
# $1 Algorithm class from the pairs table (classic, mldsa or sha1).
crypto_supported() {
case $1 in
mldsa)
openssl list -signature-algorithms 2>/dev/null \
| grep -iq 'ML-DSA'
return $?
;;
sha1)
# Stock OpenSSL still verifies a SHA-1 signature at the default
# security level, but distributions that apply a system crypto
# policy refuse it. Rely on the identity check, which is portable.
return 1
;;
*)
# classic: RSA, RSA-PSS and ECDSA verify on any modern OpenSSL.
return 0
;;
esac
}

# Read a key identifier from an "openssl x509 -ext" dump on stdin and print it
# as bare hex. Two layouts occur: a bare value (subjectKeyIdentifier, and an
# authorityKeyIdentifier built from keyid alone) and a labelled value where
# keyid, DirName and serial each get a line. Only the keyid is wanted, so stop
# at the first value rather than joining every hex run in the dump. POSIX awk
# because grep -o is not portable and could silently yield an empty id.
extract_key_id() {
awk '
/[Kk]eyid:/ {
sub(/^.*[Kk]eyid:/, "")
print
exit
}
match($0, /[0-9A-Fa-f][0-9A-Fa-f](:[0-9A-Fa-f][0-9A-Fa-f])+/) {
print substr($0, RSTART, RLENGTH)
exit
}
' | tr -cd '0-9A-Fa-f'
}

# Identity check ($1 leaf, $2 CA): leaf issuer DN == CA subject DN and, when
# both present, leaf AKID == CA SKID. Signature-independent (works on any
# OpenSSL). Returns 0 on match, 1 on mismatch.
Expand All @@ -55,15 +87,10 @@ identity_matches() {
return 1
fi

# Pick the colon-separated hex key id out of the value line with POSIX awk
# (grep -o is not POSIX and could silently yield empty ids, skipping this
# check). The header's hex letters never form the "hh:hh" pattern.
akid=`openssl x509 -in "$leaf" -noout -ext authorityKeyIdentifier 2>/dev/null \
| awk 'match($0,/[0-9A-Fa-f][0-9A-Fa-f](:[0-9A-Fa-f][0-9A-Fa-f])+/){print substr($0,RSTART,RLENGTH)}' \
| tr -cd '0-9A-Fa-f'`
skid=`openssl x509 -in "$ca" -noout -ext subjectKeyIdentifier 2>/dev/null \
| awk 'match($0,/[0-9A-Fa-f][0-9A-Fa-f](:[0-9A-Fa-f][0-9A-Fa-f])+/){print substr($0,RSTART,RLENGTH)}' \
| tr -cd '0-9A-Fa-f'`
akid=`openssl x509 -in "$leaf" -noout -ext authorityKeyIdentifier \
2>/dev/null | extract_key_id`
skid=`openssl x509 -in "$ca" -noout -ext subjectKeyIdentifier \
2>/dev/null | extract_key_id`
if [ -n "$akid" ] && [ -n "$skid" ] && [ "$akid" != "$skid" ]; then
echo "MISMATCH (AKID/SKID): $leaf vs $ca"
echo " leaf AKID : $akid"
Expand Down Expand Up @@ -100,7 +127,7 @@ do
failed=1
fi
else
echo "OK (identity only, crypto skipped - openssl lacks algorithm): $leaf -> $ca"
echo "OK (identity only, crypto verify skipped): $leaf -> $ca"
fi
done <<EOF
$pairs
Expand Down
92 changes: 92 additions & 0 deletions certs/client-cert-sha1.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 53 (0x35)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = facts@wolfssl.com
Validity
Not Before: Aug 6 20:15:58 2026 GMT
Not After : May 2 20:15:58 2029 GMT
Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = facts@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c3:03:d1:2b:fe:39:a4:32:45:3b:53:c8:84:2b:
2a:7c:74:9a:bd:aa:2a:52:07:47:d6:a6:36:b2:07:
32:8e:d0:ba:69:7b:c6:c3:44:9e:d4:81:48:fd:2d:
68:a2:8b:67:bb:a1:75:c8:36:2c:4a:d2:1b:f7:8b:
ba:cf:0d:f9:ef:ec:f1:81:1e:7b:9b:03:47:9a:bf:
65:cc:7f:65:24:69:a6:e8:14:89:5b:e4:34:f7:c5:
b0:14:93:f5:67:7b:3a:7a:78:e1:01:56:56:91:a6:
13:42:8d:d2:3c:40:9c:4c:ef:d1:86:df:37:51:1b:
0c:a1:3b:f5:f1:a3:4a:35:e4:e1:ce:96:df:1b:7e:
bf:4e:97:d0:10:e8:a8:08:30:81:af:20:0b:43:14:
c5:74:67:b4:32:82:6f:8d:86:c2:88:40:99:36:83:
ba:1e:40:72:22:17:d7:52:65:24:73:b0:ce:ef:19:
cd:ae:ff:78:6c:7b:c0:12:03:d4:4e:72:0d:50:6d:
3b:a3:3b:a3:99:5e:9d:c8:d9:0c:85:b3:d9:8a:d9:
54:26:db:6d:fa:ac:bb:ff:25:4c:c4:d1:79:f4:71:
d3:86:40:18:13:b0:63:b5:72:4e:30:c4:97:84:86:
2d:56:2f:d7:15:f7:7f:c0:ae:f5:fc:5b:e5:fb:a1:
ba:d3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0
X509v3 Authority Key Identifier:
keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=facts@wolfssl.com
serial:67:19:D2:A8:7F:E3:2D:FA:75:7A:4F:E7:B2:02:D9:AD:C4:77:5E:F8
X509v3 Basic Constraints:
CA:TRUE
X509v3 Subject Alternative Name:
DNS:example.com, IP Address:127.0.0.1
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
Signature Value:
84:6b:e9:b2:9b:0d:7a:d8:f3:b1:c2:f1:d6:84:5f:d4:5c:68:
02:6d:a0:62:a0:e8:1a:cb:b3:5e:da:9b:1e:5d:02:8d:9d:ed:
65:d9:44:eb:81:54:d0:26:ce:c6:7c:4a:8e:c9:16:a2:e1:58:
a4:17:9f:71:05:85:70:a7:b2:79:11:30:d5:4f:c8:66:6c:8b:
cb:35:c5:22:2d:41:d7:b3:19:10:de:cf:d5:7c:fd:74:6c:66:
77:fa:ae:e7:88:ea:7d:0c:bf:ea:38:2e:4e:ee:d4:b6:da:ab:
55:04:d7:f4:d6:59:c7:48:10:fd:07:95:ab:bf:2d:ea:43:16:
e7:d5:d5:ab:c8:4d:6c:16:3c:3f:37:a5:eb:06:0e:bc:23:ff:
a4:f7:d8:c0:b8:15:db:97:fd:f8:bc:21:33:b5:2b:33:a1:71:
dd:cf:c7:f4:5c:cb:f5:83:e0:c8:2e:f6:85:87:cd:96:67:71:
d0:f4:56:7d:3b:43:8d:c0:37:d6:fd:66:95:58:71:ac:e6:3c:
0d:88:bf:4c:6e:ef:e7:36:5a:34:a5:db:4d:b1:80:34:16:2a:
fb:bf:47:1c:43:79:8c:a9:99:7f:6a:2d:22:4e:aa:bd:08:6a:
bf:9c:84:fd:ec:8a:f8:c0:2b:af:05:94:fd:4b:7e:51:17:e4:
2f:6b:57:b4
-----BEGIN CERTIFICATE-----
MIIE+TCCA+GgAwIBAgIBNTANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCVVMx
EDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNh
d3Rvb3RoMRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
bC5jb20xIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2MDgw
NjIwMTU1OFoXDTI5MDUwMjIwMTU1OFowgZ8xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
DAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIw
NDgxGTAXBgNVBAsMEFByb2dyYW1taW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xm
c3NsLmNvbTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNzbC5jb20wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDA9Er/jmkMkU7U8iEKyp8dJq9qipS
B0fWpjayBzKO0Lppe8bDRJ7UgUj9LWiii2e7oXXINixK0hv3i7rPDfnv7PGBHnub
A0eav2XMf2UkaaboFIlb5DT3xbAUk/Vnezp6eOEBVlaRphNCjdI8QJxM79GG3zdR
GwyhO/Xxo0o15OHOlt8bfr9Ol9AQ6KgIMIGvIAtDFMV0Z7Qygm+NhsKIQJk2g7oe
QHIiF9dSZSRzsM7vGc2u/3hse8ASA9ROcg1QbTujO6OZXp3I2QyFs9mK2VQm2236
rLv/JUzE0Xn0cdOGQBgTsGO1ck4wxJeEhi1WL9cV93/ArvX8W+X7obrTAgMBAAGj
ggFGMIIBQjAdBgNVHQ4EFgQUM9hFZtdohxh+VA1wJ5HHJteFZcAwgdUGA1UdIwSB
zTCByoAUJ45nEXTDJh0/7TNjs6TYHTDl6NWhgZukgZgwgZUxCzAJBgNVBAYTAlVT
MRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhT
YXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZz
c2wuY29tMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3NsLmNvbYIUZxnSqH/j
Lfp1ek/nsgLZrcR3XvgwDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtleGFtcGxl
LmNvbYcEfwAAATAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZI
hvcNAQEFBQADggEBAIRr6bKbDXrY87HC8daEX9RcaAJtoGKg6BrLs17amx5dAo2d
7WXZROuBVNAmzsZ8So7JFqLhWKQXn3EFhXCnsnkRMNVPyGZsi8s1xSItQdezGRDe
z9V8/XRsZnf6rueI6n0Mv+o4Lk7u1Lbaq1UE1/TWWcdIEP0Hlau/LepDFufV1avI
TWwWPD83pesGDrwj/6T32MC4FduX/fi8ITO1KzOhcd3Px/Rcy/WD4Mgu9oWHzZZn
cdD0Vn07Q43AN9b9ZpVYcazmPA2Iv0xu7+c2WjSl202xgDQWKvu/RxxDeYypmX9q
LSJOqr0Iar+chP3sivjAK68FlP1LflEX5C9rV7Q=
-----END CERTIFICATE-----
3 changes: 3 additions & 0 deletions certs/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ EXTRA_DIST += \
certs/client-ca-cert.pem \
certs/dh2048.pem \
certs/server-cert.pem \
certs/server-cert-sha1.pem \
certs/server-cert-sha1-root.pem \
certs/client-cert-sha1.pem \
certs/tsa-bad-ku-cert.pem \
certs/tsa-extra-eku-cert.pem \
certs/tsa-chain-cert.pem \
Expand Down
67 changes: 67 additions & 0 deletions certs/renewcerts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
# server-cert.pem
# server-cert.der
# server-cert-chain.der
# server-cert-sha1.pem
# server-cert-sha1-root.pem
# client-cert-sha1.pem
# server-ecc-rsa.pem
# server-ecc.pem
# 1024/client-cert.der
Expand Down Expand Up @@ -636,6 +639,70 @@ run_renewcerts(){
echo "End of section"
echo "---------------------------------------------------------------------"
###########################################################
########## update and sign server-cert-sha1.pem ###########
###########################################################
# SHA-1 signed leaf. Used by the TLS 1.3 tests that check a server does
# not send a SHA-1 signed chain to a peer that did not advertise SHA-1.
echo "Updating server-cert-sha1.pem"
echo ""
echo -e "US\\nMontana\\nBozeman\\nwolfSSL\\nSupport\\nwww.wolfssl.com\\nfacts@wolfssl.com\\n.\\n.\\n" | openssl req -new -key server-key.pem -config ./wolfssl.cnf -nodes > server-sha1-req.pem
check_result $? "Step 1"

openssl x509 -req -in server-sha1-req.pem -sha1 -extfile wolfssl.cnf -extensions wolfssl_opts -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 51 > server-sha1-tmp.pem
check_result $? "Step 2"

rm server-sha1-req.pem

openssl x509 -in server-sha1-tmp.pem -text > server-cert-sha1.pem
check_result $? "Step 3"
rm server-sha1-tmp.pem
echo "End of section"
echo "---------------------------------------------------------------------"
###########################################################
####### update and sign server-cert-sha1-root.pem #########
###########################################################
# SHA-256 leaf with a self signed SHA-1 root appended. RFC 8446 4.4.2.2
# lets the trust anchor be omitted, so its SHA-1 signature must not stop
# the chain from being sent.
echo "Updating server-cert-sha1-root.pem"
echo ""
echo -e "US\\nMontana\\nBozeman\\nSawtooth\\nConsulting\\nwww.wolfssl.com\\nfacts@wolfssl.com\\n.\\n.\\n" | openssl req -new -key ca-key.pem -config ./wolfssl.cnf -nodes -out ca-sha1-req.pem
check_result $? "Step 1"

openssl x509 -req -in ca-sha1-req.pem -sha1 -days 1000 -extfile wolfssl.cnf -extensions wolfssl_opts -signkey ca-key.pem -set_serial 52 -out ca-sha1-tmp.pem
check_result $? "Step 2"

rm ca-sha1-req.pem

openssl x509 -in server-cert.pem -text > server-cert-sha1-root.pem
check_result $? "Step 3"
openssl x509 -in ca-sha1-tmp.pem -text >> server-cert-sha1-root.pem
check_result $? "Step 4"
rm ca-sha1-tmp.pem
echo "End of section"
echo "---------------------------------------------------------------------"
###########################################################
########## update and sign client-cert-sha1.pem ###########
###########################################################
# SHA-1 signed client leaf, issued by ca-cert.pem rather than self signed
# so it is not exempt from the RFC 8446 4.4.2.2 trust anchor rule. Used to
# check the client falls back to an empty certificate_list.
echo "Updating client-cert-sha1.pem"
echo ""
echo -e "US\\nMontana\\nBozeman\\nwolfSSL_2048\\nProgramming-2048\\nwww.wolfssl.com\\nfacts@wolfssl.com\\n.\\n.\\n" | openssl req -new -key client-key.pem -config ./wolfssl.cnf -nodes > client-sha1-req.pem
check_result $? "Step 1"

openssl x509 -req -in client-sha1-req.pem -sha1 -extfile wolfssl.cnf -extensions wolfssl_opts -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 53 > client-sha1-tmp.pem
check_result $? "Step 2"

rm client-sha1-req.pem

openssl x509 -in client-sha1-tmp.pem -text > client-cert-sha1.pem
check_result $? "Step 3"
rm client-sha1-tmp.pem
echo "End of section"
echo "---------------------------------------------------------------------"
###########################################################
########## update and sign server-revoked-key.pem #########
###########################################################
echo "Updating server-revoked-cert.pem"
Expand Down
Loading