Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/manual-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '1.21'
go-version: '1.27.3'
- run: go version
- name: Install dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scheduled-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: '1.21'
go-version: '1.27.3'
- run: go version
- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Dockerfile to run the cfssl_trust release script locally.
# WARP must be turned off to run the script.
# Provides Go 1.21, certdump, cfssl tools, and cfssl-trust
# Provides Go 1.27.3, certdump, cfssl tools, and cfssl-trust

FROM golang:1.21-bookworm
FROM golang:1.27.3-trixie

# Install git and update CA certificates
RUN apt-get update && apt-get install -y \
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ systems. Currently, we have trust stores from

#### Prerequisites

Use Go 1.27.3 or a later patched release for the release tools.

```
$ go install git.wntrmute.dev/kyle/goutils/cmd/certdump@v1.7.7
$ go install github.com/cloudflare/cfssl/cmd/...@latest
Expand Down Expand Up @@ -105,3 +107,20 @@ These calls to the `expiring` command will provide an output showing if there ar
1 certificates expiring.
0 certificates revoked.
```

### eMudhra compromise mitigation (October 2026)

Following the [eMudhra intermediate key compromise](https://blog.mozilla.org/security/2026/10/20/protecting-firefox-users-following-the-compromise-of-emudhra-intermediate-certificates/),
AAA Certificate Services and emSign ECC Root CA - G3 have been removed from
the root bundle in release `2026.10.0`. Dated distrust records prevent future
release rolls from including them. Historical releases and platform snapshots
are preserved for reproducibility. emSign Root TLS CA - G3 and the eight
compromised intermediate keys were absent from the bundles. The unaffected
emSign C1, C3, and G1 roots remain trusted.

Removing these roots can also reject legitimate certificate chains.
Replacement intermediates are not included.

Consumers must deploy the updated bundle and restart services that load roots
at startup. Rebuild Go services with Go 1.27.3 or Go 1.26.10 (or a later
patched release) to also block the compromised keys during path validation.
40 changes: 0 additions & 40 deletions ca-bundle.crt
Original file line number Diff line number Diff line change
Expand Up @@ -604,31 +604,6 @@ ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
Expand Down Expand Up @@ -8409,21 +8384,6 @@ RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
iN66zB+Afko=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
+JbNR6iC8hZVdyR+EhCVBCyj
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFcjCCA1qgAwIBAgIKLwq3aw3LSq8nWDANBgkqhkiG9w0BAQwFADBWMQswCQYD
VQQGEwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJ
bmMxHDAaBgNVBAMTE2VtU2lnbiBSb290IENBIC0gQzIwHhcNMTgwMjE4MTgzMDAw
Expand Down
Binary file modified cert.db
Binary file not shown.
39 changes: 39 additions & 0 deletions certdata/aaa_cross_sign_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"bytes"
"testing"
)

// Keep the independently trusted roots, but not their dead-end AAA cross-signs.
// Verifiers without issuer backtracking can otherwise select an AAA-issued
// copy instead of the self-signed root and fail after AAA is distrusted.
func TestUSERTrustAndCOMODORootsDoNotDependOnAAA(t *testing.T) {
roots := map[string]bool{
"USERTrust RSA Certification Authority": false,
"USERTrust ECC Certification Authority": false,
"COMODO RSA Certification Authority": false,
"COMODO ECC Certification Authority": false,
}

for _, cert := range loadBundle(t, intBundleFile) {
if _, checked := roots[cert.Subject.CommonName]; checked && cert.Issuer.CommonName == aaaRootCommonName {
t.Errorf("%s contains AAA-issued cross-sign %q (serial %X)",
intBundleFile, cert.Subject.CommonName, cert.SerialNumber)
}
}

for _, cert := range loadBundle(t, caBundleFile) {
if _, checked := roots[cert.Subject.CommonName]; !checked {
continue
}
if bytes.Equal(cert.RawSubject, cert.RawIssuer) && cert.CheckSignatureFrom(cert) == nil {
roots[cert.Subject.CommonName] = true
}
}
for name, found := range roots {
if !found {
t.Errorf("%s is missing self-signed root %q", caBundleFile, name)
}
}
}
30 changes: 0 additions & 30 deletions certdata/ca-bundle.txt
Original file line number Diff line number Diff line change
Expand Up @@ -407,21 +407,6 @@ Details:
Basic constraints: valid, is a CA certificate, max path length 12
SANs (1): email:chambersignroot@chambersign.org
CERTIFICATE
Subject: /AAA Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Issuer: /AAA Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Signature algorithm: RSA / SHA1
Details:
Public key: RSA-2048
Serial number: 1
SKI: A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4
Valid from: 2004-01-01T00:00:00+0000
until: 2028-12-31T23:59:59+0000
Key usages: cert sign, crl sign
Basic constraints: valid, is a CA certificate
SANs (0):
CERTIFICATE
Subject: /Secure Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Issuer: /Secure Certificate Services/C=GB/O=Comodo CA
Expand Down Expand Up @@ -4409,21 +4394,6 @@ Details:
Basic constraints: valid, is a CA certificate
SANs (0):
CERTIFICATE
Subject: /emSign ECC Root CA - G3/C=IN/O=eMudhra Technologies
Limited/OU=emSign PKI
Issuer: /emSign ECC Root CA - G3/C=IN/O=eMudhra Technologies Limited/OU=emSign
PKI
Signature algorithm: ECDSA / SHA384
Details:
Public key: ECDSA-secp384r1
Serial number: 287880440101571086945156
SKI: 7C:5D:02:84:13:D4:CC:8A:9B:81:CE:17:1C:2E:29:1E:9C:48:63:42
Valid from: 2018-02-18T18:30:00+0000
until: 2043-02-18T18:30:00+0000
Key usages: cert sign, crl sign
Basic constraints: valid, is a CA certificate
SANs (0):
CERTIFICATE
Subject: /emSign Root CA - C2/C=US/O=eMudhra Inc/OU=emSign PKI
Issuer: /emSign Root CA - C2/C=US/O=eMudhra Inc/OU=emSign PKI
Signature algorithm: RSA / SHA384
Expand Down
72 changes: 0 additions & 72 deletions certdata/int-bundle.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,42 +50,6 @@ Details:
Basic constraints: valid, is a CA certificate, max path length 11
SANs (1): email:ac_camerfirma@camerfirma.com
CERTIFICATE
Subject: /COMODO RSA Certification Authority/C=GB/O=COMODO CA
Limited/L=Salford/ST=Greater Manchester
Issuer: /AAA Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Signature algorithm: RSA / SHA384
Details:
Public key: RSA-4096
Serial number: 138068127363266052427974132567073013892
AKI: A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4
SKI: BB:AF:7E:02:3D:FA:A6:F1:3C:84:8E:AD:EE:38:98:EC:D9:32:32:D4
Valid from: 2004-01-01T00:00:00+0000
until: 2028-12-31T23:59:59+0000
Key usages: cert sign, crl sign, digital signature
Basic constraints: valid, is a CA certificate
SANs (0):
OCSP server:
- http://ocsp.comodoca.com
CERTIFICATE
Subject: /COMODO ECC Certification Authority/C=GB/O=COMODO CA
Limited/L=Salford/ST=Greater Manchester
Issuer: /AAA Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Signature algorithm: RSA / SHA384
Details:
Public key: ECDSA-secp384r1
Serial number: 30434779307599757625323899518303222751
AKI: A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4
SKI: 75:71:A7:19:48:19:BC:9D:9D:EA:41:47:DF:94:C4:48:77:99:D3:79
Valid from: 2004-01-01T00:00:00+0000
until: 2028-12-31T23:59:59+0000
Key usages: cert sign, crl sign, digital signature
Basic constraints: valid, is a CA certificate
SANs (0):
OCSP server:
- http://ocsp.comodoca.com
CERTIFICATE
Subject: /UTN-USERFirst-Client Authentication and Email/C=US/O=The USERTRUST
Network/OU=http://www.usertrust.com/L=Salt Lake City/ST=UT
Issuer: /AAA Certificate Services/C=GB/O=Comodo CA
Expand Down Expand Up @@ -11844,42 +11808,6 @@ Details:
OCSP server:
- http://ocsps.ssl.com
CERTIFICATE
Subject: /USERTrust RSA Certification Authority/C=US/O=The USERTRUST
Network/L=Jersey City/ST=New Jersey
Issuer: /AAA Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Signature algorithm: RSA / SHA384
Details:
Public key: RSA-4096
Serial number: 76359301477803385872276235234032301461
AKI: A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4
SKI: 53:79:BF:5A:AA:2B:4A:CF:54:80:E1:D8:9B:C0:9D:F2:B2:03:66:CB
Valid from: 2019-03-12T00:00:00+0000
until: 2028-12-31T23:59:59+0000
Key usages: cert sign, crl sign, digital signature
Basic constraints: valid, is a CA certificate
SANs (0):
OCSP server:
- http://ocsp.comodoca.com
CERTIFICATE
Subject: /USERTrust ECC Certification Authority/C=US/O=The USERTRUST
Network/L=Jersey City/ST=New Jersey
Issuer: /AAA Certificate Services/C=GB/O=Comodo CA
Limited/L=Salford/ST=Greater Manchester
Signature algorithm: RSA / SHA384
Details:
Public key: ECDSA-secp384r1
Serial number: 114849002793238729640937462275813569940
AKI: A0:11:0A:23:3E:96:F1:07:EC:E2:AF:29:EF:82:A5:7F:D0:30:A4:B4
SKI: 3A:E1:09:86:D4:CF:19:C2:96:76:74:49:76:DC:E0:35:C6:63:63:9A
Valid from: 2019-03-12T00:00:00+0000
until: 2028-12-31T23:59:59+0000
Key usages: cert sign, crl sign, digital signature
Basic constraints: valid, is a CA certificate
SANs (0):
OCSP server:
- http://ocsp.comodoca.com
CERTIFICATE
Subject: /HARICA SSL RSA SubCA R3/C=GR/O=Hellenic Academic and Research
Institutions Cert. Authority/L=Athens
Issuer: /Hellenic Academic and Research Institutions RootCA
Expand Down
28 changes: 3 additions & 25 deletions certdata/sslcom_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,44 +28,22 @@ func loadBundle(t *testing.T, file string) []*x509.Certificate {
return certificates
}

func aaaRootPool(t *testing.T) *x509.CertPool {
t.Helper()
for _, root := range loadBundle(t, caBundleFile) {
if root.Subject.CommonName == aaaRootCommonName {
pool := x509.NewCertPool()
pool.AddCert(root)
return pool
}
}
t.Fatalf("%s does not contain %q", caBundleFile, aaaRootCommonName)
return nil
}

func isSSLcomTLSIssuingOrTransitCA(cert *x509.Certificate) bool {
name := cert.Subject.CommonName
return cert.IsCA && strings.HasPrefix(name, "SSL.com ") &&
(strings.Contains(name, " TLS Issuing ") || strings.Contains(name, " TLS Transit "))
}

// SSL.com TLS Issuing/Transit CAs in the intermediate bundle must not be
// copies issued by AAA Certificate Services. AAA has been removed from Chrome
// and Mozilla, and an AAA-issued copy of the CA that signs the leaf makes the
// whole chain depend on AAA (SECENG-14034). An AAA cross-sign of SSL.com TLS
// Root CA 2022 is allowed: clients that trust Root CA 2022 stop there, and
// only legacy clients use the AAA path.
// SSL.com TLS Issuing/Transit CAs must chain to SSL.com roots without
// depending on the distrusted AAA Certificate Services root.
func TestSSLcomTLSIssuingAndTransitCAsAreNotIssuedByAAARoot(t *testing.T) {
aaa := aaaRootPool(t)
checked := 0
for _, cert := range loadBundle(t, intBundleFile) {
if !isSSLcomTLSIssuingOrTransitCA(cert) {
continue
}
checked++
_, err := cert.Verify(x509.VerifyOptions{
Roots: aaa,
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
})
if err == nil {
if cert.Issuer.CommonName == aaaRootCommonName {
t.Errorf("%q (serial %X) is issued by %q",
cert.Subject.CommonName, cert.SerialNumber, aaaRootCommonName)
}
Expand Down
Loading