Germany's cybersecurity authority (BSI) TLS cert untrusted on Apple devices
quality 7/10 · good
0 net
Germany's Cybersecurity Authority (BSI) Has an Untrusted TLS Certificate on Every Apple Device · Echoes from the Shell Update (April 5, 2026, ~09:40 CEST): The BSI has fixed the issue. The server now sends a cross-signed certificate for D-TRUST BR Root CA 2 2023, issued by D-TRUST Root Class 3 CA 2 2009 (which Apple trusts). The leaf certificate is unchanged – they added a bridge cert to the chain. Safari and /usr/bin/curl on macOS now verify successfully. The cross-signed certificate is byte-for-byte identical to D-TRUST_BR_Root_CA_2_2023_cross.crt , published on D-Trust’s repository page since July 14, 2025. It was available for nine months before this incident. Full analysis below. The fix was deployed within hours of my report. The BSI chose the correct approach – adding D-Trust’s published cross-signed root to the chain rather than switching CAs or reverting to an older certificate. The original analysis below remains accurate as of April 3–5, 2026. The BSI – Germany’s Bundesamt für Sicherheit in der Informationstechnik (Federal Office for Information Security) – is the authority that advises the German government, businesses, and citizens on IT security. They publish the IT-Grundschutz framework, they coordinate CERT-Bund , and they are the agency you’d expect to get TLS right. On April 3rd, 2026, they switched their TLS certificate. And broke their website on every Apple device. What happened Link to heading The BSI’s web server now serves a certificate issued by D-TRUST BR CA 2-23-1 2023 , which chains up to the D-TRUST BR Root CA 2 2023 . The problem: Apple’s trust store does not include this root CA. macOS and iOS only ship with three older D-TRUST roots: D-TRUST Root Class 3 CA 2 2009 D-TRUST Root Class 3 CA 2 EV 2009 D-TRUST Root CA 3 2013 (listed in Apple’s trust store for most recent iOS and macOS 26) The 2023 root is not among them. As a result, Safari, Mail, curl, and every app using Apple’s native TLS stack shows an untrusted certificate warning. Chrome and Firefox are unaffected because they ship their own root stores. Safari on macOS showing a certificate warning for the BSI’s website. Reproducing the issue Link to heading You can verify this yourself on any Mac. The key is to use Apple’s built-in openssl and curl , not Homebrew versions (which use their own trust stores). Using Apple’s OpenSSL (LibreSSL) Link to heading $ /usr/bin/openssl s_client -connect www.bsi.bund.de:443 \ -servername www.bsi.bund.de 2>& 1 | grep "Verify return code" Verify return code: 20 ( unable to get local issuer certificate ) Error code 20 means the client could not find the root CA in its trust store. For comparison, Homebrew’s OpenSSL uses its own certificate bundle and will verify successfully: $ /opt/homebrew/bin/openssl s_client -connect www.bsi.bund.de:443 \ -servername www.bsi.bund.de 2>& 1 | grep "Verify return code" Verify return code: 0 ( ok ) This is a subtle trap. If you’re testing TLS on a Mac and have Homebrew installed, openssl in your PATH is likely the Homebrew version. Your tests pass, but Safari and iOS still fail. Using curl Link to heading macOS system curl uses SecureTransport (Apple’s TLS implementation), so it reflects what Safari sees: $ curl https://www.bsi.bund.de/ curl: ( 60 ) SSL certificate problem: unable to get local issuer certificate Checking the certificate chain Link to heading The server sends the leaf and intermediate correctly. The root is not served (which is standard: it must be in the client’s trust store): $ /usr/bin/openssl s_client -connect www.bsi.bund.de:443 \ -servername www.bsi.bund.de -showcerts 2>/dev/null | grep -E "s:|i:" 0 s:C = DE, ST = Nordrhein-Westfalen, O = Bundesamt fuer Sicherheit in der Informationstechnik, CN = www.bsi.bund.de i:C = DE, O = D-Trust GmbH, CN = D-TRUST BR CA 2-23-1 2023 1 s:C = DE, O = D-Trust GmbH, CN = D-TRUST BR CA 2-23-1 2023 i:C = DE, O = D-Trust GmbH, CN = D-TRUST BR Root CA 2 2023 The chain is: # Certificate Details 1 Leaf CN=www.bsi.bund.de, RSA 4096-bit, SHA-512, issued Apr 3 2026 2 Intermediate D-TRUST BR CA 2-23-1 2023 3 Root (not served) D-TRUST BR Root CA 2 2023 – not in Apple’s trust store Nothing is wrong with the chain itself. The server configuration is correct. The issue is that Apple does not trust the root. Confirming what Apple trusts Link to heading You can list the D-TRUST roots in macOS’s system keychain: $ security find-certificate -a -c "D-TRUST" \ /System/Library/Keychains/SystemRootCertificates.keychain \ | grep "labl" "labl" = "D-TRUST Root Class 3 CA 2 2009" "labl" = "D-TRUST Root Class 3 CA 2 EV 2009" "labl" = "D-TRUST Root CA 3 2013" No 2023 root. This is on macOS 26.4 (Tahoe), the latest release as of this writing. The blast radius Link to heading The certificate uses a Subject Alternative Name (SAN) extension covering 13 domains , all affected: Domain Purpose www.bsi.bund.de , bsi.bund.de Main BSI website bsi.de , www.bsi.de Short domain reports.cert-bund.de CERT-Bund incident reports buerger-cert.de , www.buerger-cert.de Citizen CERT portal bsi-fuer-buerger.de , www.bsi-fuer-buerger.de BSI citizen security advice vpki.bund.de , www.vpki.bund.de Federal PKI baond.bund.de , www.baond.bund.de Federal network operations All 13 domains return the same certificate and the same verification failure on Apple devices: $ for domain in www.bsi.bund.de bsi.de reports.cert-bund.de; do echo -n " $domain : " /usr/bin/openssl s_client -connect $domain :443 \ -servername $domain 2>& 1 | grep "Verify return code" done www.bsi.bund.de: Verify return code: 20 ( unable to get local issuer certificate ) bsi.de: Verify return code: 20 ( unable to get local issuer certificate ) reports.cert-bund.de:Verify return code: 20 ( unable to get local issuer certificate ) This includes CERT-Bund – Germany’s national Computer Emergency Response Team – and the federal PKI portal. If you’re a German citizen on an iPhone trying to read a security advisory from the BSI, you get a warning that the connection is not secure. Root store fragmentation: the actual problem Link to heading This isn’t just a BSI misconfiguration. It’s a structural problem with how root certificate trust works across platforms. There is no single “internet trust store.” Four major platforms maintain independent root programs, each with their own application process, review timeline, and approval criteria: Platform Root Program Publishes included CAs? Mozilla/Firefox Mozilla Root Program Yes, via CCADB Google Chrome Chrome Root Program Yes, via CCADB Microsoft Trusted Root Program Yes, via CCADB Apple Apple Root Program No Apple is the outlier. Mozilla, Microsoft, and Chrome all publish their included CA lists through the Common CA Database (CCADB) . Apple does not. CAs apply by emailing [email protected] and creating a CCADB case, but Apple publishes no pending request status and no public timeline. There is no way to check from the outside whether D-Trust has applied or where in the process they are. Where D-TRUST BR Root CA 2 2023 stands today Link to heading D-Trust began the cross-platform rollout of their new 2023 root in mid-2023. The Mozilla inclusion request shows the full timeline: ~Mid 2023 : D-Trust files the inclusion request July 2023 : Mozilla begins verification September 2024 : Public discussion opens December 3, 2024 : Mozilla approves inclusion Early 2025 : Ships in NSS 3.108 / Firefox 136 That’s roughly 18 months from application to shipping in Firefox. Expect similar timelines for other platforms. Here’s the current status: Mozilla/Firefox: â Included (NSS 3.108, Firefox 136) Google Chrome: â Included (Root Store v30) Microsoft/Windows: â Included (Trusted Root Program) Apple (macOS/iOS): â Not included Three out of four. Apple is the only holdout. Why D-TRUST? Link to heading D-Trust is a German certificate authority, a subsidiary of Bundesdruckerei (the federal printing office). Choosing a domestic CA for government infrastructure is a reasonable sovereignty decision. Germany’s government PKI should arguably be anchored to a German root, not a US-based one. But sovereignty doesn’t change the fact that each platform has its own root program. D-Trust knew this: they started the Mozilla application two years ago. The BSI went live with the new certificate on April 3rd, before the rollout was complete across all major platforms. The Easter certificate recall Link to heading The timing of the switch is likely not coincidental. On Easter weekend, D-Trust announced an emergency recall of all TLS certificates issued between March 15, 2025 and April 2, 2026, with a deadline of Easter Monday (April 6, 2026). The reason was a technical disagreement over certificate linting standards: specifically how long precertificates may remain valid. The BSI’s new certificate was issued on April 3rd – one day after the cutoff of the affected period. The BSI’s previous certificate likely fell within the revocation window and had to be replaced under time pressure. So the certificate switch was probably not a planned migration but a forced replacement due to the recall. Under that pressure, the BSI (or D-Trust on their behalf) issued the replacement under the new 2023 root hierarchy, the one Apple doesn’t trust. That context matters, but it doesn’t change the outcome. Even under time pressure, verifying the new certificate against all major trust stores before deployment is a basic operational check. And D-Trust publishes a cross-signed version of the 2023 root on their repository page, signed by the older D-TRUST Root Class 3 CA 2 2009 that Apple trusts. It was issued July 14, 2025 – nine months before this incident. Including it in the chain would have avoided the problem entirely. The irony Link to heading The BSI is the German government’s authority on IT security. Their Technical Guideline TR-03116 specifies TLS requirements for federal infrastructure. They publish guidance on certificate management and advise organizations on secure deployment. The very first check in any TLS migration checklist should be: does the new certificate chain validate on all target platforms? A single command would have caught this: $ /usr/bin/curl -sI https://www.bsi.bund.de/ curl: ( 60 ) SSL certificate problem: unable to get local issuer certificate What should have been done differently Link to heading Before the switch: Verify root inclusion across all major platforms. Don’t just test in Chrome. Check Apple’s trust store – either by running security find-certificate -c "YOUR-ROOT" /System/Library/Keychains/SystemRootCertificates.keychain on a Mac, or by consulting Apple’s published trust store lists . Test with platform-native TLS stacks. On macOS, that means /usr/bin/curl and /usr/bin/openssl (LibreSSL), not Homebrew. On iOS, that means Safari, not a Chrome install. Use the cross-signed root that D-Trust already published. D-Trust’s own repository page lists a cross-signed version of D-TRUST BR Root CA 2 2023 ( D-TRUST_BR_Root_CA_2_2023_cross.crt ), signed by D-TRUST Root Class 3 CA 2 2009 – a root Apple trusts. It was issued July 14, 2025. Adding it to the served chain is the standard way to bridge trust during a root migration. It was sitting right there on D-Trust’s website. Wait for full inclusion. If cross-signing isn’t an option, don’t deploy until all four major platforms trust the root. Three out of four is not enough when the fourth is every iPhone in the country. In this case, cross-signing was an option – and it’s what eventually fixed the problem. This will happen again Link to heading This isn’t a BSI-specific problem. Root store fragmentation bites organizations during every CA migration. If you’re switching CAs, renewing with a different root, or deploying certificates from a newer CA hierarchy, here’s the minimum verification: # On macOS: does Apple trust the root? /usr/bin/curl -sI https://your-domain/ 2>& 1 | head -5 # Check which roots are in the system store security find-certificate -a -c "YOUR-CA-NAME" \ /System/Library/Keychains/SystemRootCertificates.keychain | grep "labl" If you see “SSL certificate problem” on a Mac, your Safari and iOS users will too. Chrome working is not sufficient. The BSI’s job is to be the authority that catches these things. This time, they didn’t. Update: the cross-signed fix (April 5, 2026) Link to heading Between 00:20 and 09:40 CEST on April 5th, the BSI’s server started sending a third certificate in the chain: a cross-signed version of D-TRUST BR Root CA 2 2023, signed by the older D-TRUST Root Class 3 CA 2 2009 that Apple trusts. The leaf and intermediate are unchanged. The fix was adding one certificate. Self-signed root (in Firefox, Chrome, Windows trust stores) Link to heading This is the version that ships in trust stores via CCADB. It’s self-signed – it works as a trust anchor only if the platform has it pre-installed: Certificate: Data: Version: 3 (0x2) Serial Number: 73:3b:30:04:48:5b:d9:4d:78:2e:73:4b:c9:a1:dc:66 Signature Algorithm: sha512WithRSAEncryption Issuer: C=DE, O=D-Trust GmbH, CN=D-TRUST BR Root CA 2 2023 Validity Not Before: May 9 08:56:31 2023 GMT Not After : May 9 08:56:30 2038 GMT Subject: C=DE, O=D-Trust GmbH, CN=D-TRUST BR Root CA 2 2023 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:ae:ff:09:59:91:80:0a:4a:68:e6:24:3f:b8:a7: ... Note the issuer and subject are the same – self-signed. Serial 733B3004... . Cross-signed version (now served by BSI) Link to heading This is the bridge certificate added to the chain. Same subject, same public key, but signed by a different CA: Certificate: Data: Version: 3 (0x2) Serial Number: 4e:ca:5b:e7:f1:30:21:e3:5c:a3:9e:99:fb:9e:9b:fe Signature Algorithm: sha512WithRSAEncryption Issuer: C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 2009 Validity Not Before: Jul 14 08:32:31 2025 GMT Not After : Nov 5 08:35:58 2029 GMT Subject: C=DE, O=D-Trust GmbH, CN=D-TRUST BR Root CA 2 2023 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) Modulus: 00:ae:ff:09:59:91:80:0a:4a:68:e6:24:3f:b8:a7: ... Different serial ( 4ECA5BE7... ), different issuer (the 2009 root), shorter validity (2025–2029 instead of 2023–2038). But the subject and public key modulus are identical – this is the same CA key, just signed by a different parent. How it works Link to heading The two certificates represent the same CA identity (same key, same subject). The difference is who vouches for it: Self-signed root Cross-signed root Subject D-TRUST BR Root CA 2 2023 D-TRUST BR Root CA 2 2023 Issuer self D-TRUST Root Class 3 CA 2 2009 Serial 73:3B:30:04:... 4E:CA:5B:E7:... Valid May 2023 – May 2038 Jul 2025 – Nov 2029 Public key (SHA-256) 9898ffcad4b16917... 9898ffcad4b16917... Apple trusts it? No Yes (via 2009 root) When Apple’s TLS stack receives the chain, it now sees: Leaf cert â issued by D-TRUST BR CA 2-23-1 2023 Intermediate â issued by D-TRUST BR Root CA 2 2023 Cross-signed D-TRUST BR Root CA 2 2023 â issued by D-TRUST Root Class 3 CA 2 2009 D-TRUST Root Class 3 CA 2 2009 â in Apple’s trust store The cross-sign was issued July 14, 2025 – nine months before the April 3rd certificate switch. D-Trust published this certificate Link to heading The cross-signed root is a public artifact. D-Trust publishes it on their repository page as D-TRUST_BR_Root_CA_2_2023_cross.crt , right next to the self-signed root. I downloaded it and compared it to the certificate now served by the BSI: $ diff < ( openssl x509 -in D-TRUST_BR_Root_CA_2_2023_cross.crt -inform DER \ -outform DER ) \ < ( openssl x509 -in bsi-served-cross-sign.pem -outform DER ) # (no output -- identical) Byte-for-byte identical. The BSI’s fix was to take the cross-signed certificate that D-Trust had published since July 2025 and add it to their server’s chain. This is the standard procedure for bridging trust during a root CA migration. It should have been part of the original deployment on April 3rd. Have you encountered similar root store fragmentation issues? I’d like to hear about it – reach out on LinkedIn .