Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save robstradling/a34393f6e81639099c201a032db84853 to your computer and use it in GitHub Desktop.
Save robstradling/a34393f6e81639099c201a032db84853 to your computer and use it in GitHub Desktop.
Intermediate certificates that might not comply with Mozilla Root Store Policy section 5.3
crt.sh ID notBefore Subject CA Issuer CA
2657659203 2019-11-28 08:48:09 AC Sector Público AC RAIZ FNMT-RCM
2657658668 2019-11-28 08:50:02 AC Unidades de Sellado de Tiempo AC RAIZ FNMT-RCM
1849145005 2018-12-20 10:15:49 AC SERVIDORES SEGUROS TIPO1 AC RAIZ FNMT-RCM SERVIDORES SEGUROS
1849145003 2018-12-20 10:20:38 AC SERVIDORES SEGUROS TIPO2 AC RAIZ FNMT-RCM SERVIDORES SEGUROS
1287935739 2019-03-12 09:29:48 Actalis Domain Validation Server CA G1 Actalis Authentication Root CA
1283820374 2019-03-13 08:27:08 Actalis Extended Validation Server CA G2 Actalis Authentication Root CA
1435438944 2019-04-15 12:36:04 AgID CA1 Actalis Authentication Root CA
3517096458 2020-10-13 06:10:10 AgID CA1 Actalis Authentication Root CA
2620763357 2020-02-19 09:58:32 AgID CA1 Actalis Authentication Root CA
2440092184 2020-01-30 07:19:47 AgID CA1 Actalis Authentication Root CA
1708458487 2019-06-13 07:48:47 AgID CA1 Actalis Authentication Root CA
1566589408 2015-03-03 18:30:15 ABB Intermediate CA 3 Baltimore CyberTrust Root
2382695512 2016-09-07 12:43:50 ABB Intermediate CA 5 Baltimore CyberTrust Root
1229115734 2018-06-27 12:53:30 EC de Assinatura Digital Qualificada do Cartão de Cidadão 0015 Cartão de Cidadão 004
3470671161 2020-09-30 19:52:04 R3 DST Root CA X3
3470671160 2020-09-30 19:52:08 R4 DST Root CA X3
3925990702 2018-10-09 12:33:24 ECCE 002 ECRaizEstado
1302818097 2017-09-17 21:00:00 e-Szigno Class2 CA 2017 e-Szigno Root CA 2017
1302818096 2017-09-17 21:00:00 e-Szigno Class2 SSL CA 2017 e-Szigno Root CA 2017
1302818094 2017-09-17 21:00:00 e-Szigno Class3 CA 2017 e-Szigno Root CA 2017
1109401901 2017-09-17 21:00:00 e-Szigno Class3 SSL CA 2017 e-Szigno Root CA 2017
1302818098 2017-09-17 21:00:00 e-Szigno Online SSL CA 2017 e-Szigno Root CA 2017
1302818099 2017-09-17 21:00:00 e-Szigno Pseudonymous CA 2017 e-Szigno Root CA 2017
1159740529 2018-07-31 09:00:00 e-Szigno Qualified TLS CA 2018 e-Szigno Root CA 2017
2629646531 2009-03-09 20:44:42 Advanced Class 2 e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
2629646790 2009-06-16 14:39:49 Advanced Class 2 e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
2629646624 2009-12-02 16:00:00 Advanced Pseudonymous e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
2629646669 2009-03-09 20:45:17 Advanced Pseudonymous e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
2629646543 2009-06-16 14:42:17 Advanced Pseudonymous e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
2629646584 2009-03-09 20:43:40 Qualified e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
2629646659 2009-03-09 20:44:07 Qualified Pseudonymous e-Szigno CA 2009 Microsec e-Szigno Root CA 2009
1478364564 2017-08-18 10:05:55 NAVER Secure Certification Authority 1 NAVER Global Root Certification Authority
1639470777 2019-05-27 21:11:45 MKB SubCA 5 NetLock Arany (Class Gold) Főtanúsítvány
1490728474 2019-04-23 11:39:16 NETLOCK Trust EV CA 2 NetLock Arany (Class Gold) Főtanúsítvány
1379548755 2019-04-02 11:54:30 NETLOCK Trust Qualified EV CA 2 NetLock Arany (Class Gold) Főtanúsítvány
1473552421 2019-05-14 14:15:52 QuoVadis EU Issuing Certification Authority G4 QuoVadis Enterprise Trust CA 1 G3
2133775377 2019-11-12 09:31:35 SwissSign Advanced Platinum CA 2019 - G22 SwissSign Platinum CA - G2
1876464697 2019-09-06 08:26:39 Telia Document Signing CA v3 Telia Root CA v2
1205305195 2019-02-12 12:29:15 TeleSec GlobalRoot Class 2 G2 T-TeleSec GlobalRoot Class 2
1205307110 2019-02-12 12:23:03 TeleSec GlobalRoot Class 3 G2 T-TeleSec GlobalRoot Class 3
#!/bin/bash
#
# This script uses the public crt.sh database to find intermediate certificates that either don't comply, or that cannot be programatically proven to comply, with the following rules from the Mozilla Root Store Policy:
#
# "Intermediate certificates created after January 1, 2019, with the exception of cross-certificates that share a private key with a corresponding root certificate:
# - MUST contain an EKU extension; and,
# - MUST NOT include the anyExtendedKeyUsage KeyPurposeId; and,
# - MUST NOT include both the id-kp-serverAuth and id-kp-emailProtection KeyPurposeIds in the same certificate."
# https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/#53-intermediate-certificates
#
# psql doesn't support multi-line \COPY statements, so we use the HEREDOC workaround described by https://minhajuddin.com/2017/05/18/how-to-pass-a-multi-line-copy-sql-to-psql/
#
# If any of the following errors occur, simply try running this script again.
# 1. ERROR: canceling statement due to conflict with recovery
# DETAIL: User query might have needed to see row versions that must be removed.
# 2. ERROR: no more connections allowed (max_client_conn)
cat <<SQL | tr -d '\n' | psql -h crt.sh -p 5432 -U guest -d certwatch
\COPY (
SELECT c.ID AS "crt.sh ID",
x509_notBefore(c.CERTIFICATE) AS "notBefore",
get_ca_name_attribute(cac.CA_ID) AS "Subject CA",
get_ca_name_attribute(c.ISSUER_CA_ID) AS "Issuer CA"
FROM ca_certificate cac
JOIN certificate c ON (cac.CERTIFICATE_ID = c.ID)
WHERE
/* Only consider trust paths that terminate with an NSS built-in root */
EXISTS (
SELECT 1
FROM ca_trust_purpose ctp
WHERE ctp.CA_ID = c.ISSUER_CA_ID
AND ctp.TRUST_CONTEXT_ID = 5 /* Mozilla */
AND ctp.IS_TIME_VALID
)
/* Exclude self-signed certificates, because we are evaluating rules that only apply to intermediate certificates */
AND cac.CA_ID != c.ISSUER_CA_ID
/* "Intermediate certificates created after January 1, 2019," */
AND cac.CERTIFICATE_ID >= (
/* Certificate notBefore dates can be (and sometimes are) backdated, but we expect SCT timestamps to never be backdated.
crt.sh IDs are allocated sequentially, and the crt.sh CT log monitor usually stays up-to-date with fetching new log entries.
Therefore, we can know approximately when an intermediate certificate became known to crt.sh, even if that intermediate certificate has no SCTs from around that time.
This may produce some false positives, but (unlike relying on notBefore dates) it will avoid false negatives.
Find the lowest crt.sh ID for any certificate "created after January 1, 2019", and filter out earlier crt.sh IDs. */
SELECT ctle.CERTIFICATE_ID
FROM ct_log_entry ctle, certificate c2
WHERE ctle.ENTRY_TIMESTAMP >= '2019-01-01T00:00:00Z'::date
AND ctle.certificate_id = c2.ID
ORDER BY ENTRY_TIMESTAMP
LIMIT 1
)
/* Filter out any historical intermediates certs that had already expired by January 1, 2019 */
AND coalesce(x509_notAfter(c.CERTIFICATE), 'infinity'::timestamp) >= '2019-01-01T00:00:00Z'::date
/* "with the exception of cross-certificates that share a private key with a corresponding root certificate:" */
AND NOT EXISTS (
SELECT 1
FROM ca_certificate cac2, certificate c3
WHERE cac2.CA_ID = cac.CA_ID
AND cac2.CERTIFICATE_ID = c3.ID
AND cac2.CA_ID = c3.ISSUER_CA_ID
)
AND (
/* "MUST contain an EKU extension; and," */
NOT EXISTS (
SELECT 1
FROM x509_extensions(c.CERTIFICATE)
WHERE x509_extensions = '2.5.29.37' /* extKeyUsage */
)
/* "MUST NOT include the anyExtendedKeyUsage KeyPurposeId; and," */
OR EXISTS (
SELECT 1
FROM x509_extkeyusages(c.CERTIFICATE)
WHERE x509_extkeyusages = '2.5.29.37.0' /* anyExtendedKeyUsage */
)
/* "MUST NOT include both the id-kp-serverAuth and id-kp-emailProtection KeyPurposeIds in the same certificate." */
OR (
EXISTS (
SELECT 1
FROM x509_extkeyusages(c.CERTIFICATE)
WHERE x509_extkeyusages = '1.3.6.1.5.5.7.3.1' /* id-kp-serverAuth */
)
AND EXISTS (
SELECT 1
FROM x509_extkeyusages(c.CERTIFICATE)
WHERE x509_extkeyusages = '1.3.6.1.5.5.7.3.4' /* id-kp-emailProtection */
)
)
)
ORDER BY "Issuer CA", "Subject CA"
) TO '__temp__intermediates_with_questionable_eku.csv' CSV HEADER
SQL
mv __temp__intermediates_with_questionable_eku.csv $(date +%Y%m%d)_intermediates_with_questionable_eku.csv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment