9

I’m experimenting with scanning certificate transparency logs for my domains, and I’d like to filter out log entries for legitimately issued certificates so I only get alerts when someone else gets ahold of a certificate for my domain.

I tried to find out if a CT log entry was mine by comparing its fingerprint to the fingerprint of the certificate on my server. However, I found that some of the entries in the log are “pre-certificates,” which have an extra critical extension to make them not valid in browsers. These are apparently considered equivalent to the final issued certificate for transparency purposes (so it seems like a bad idea to just ignore all pre-certificates), but their fingerprint doesn’t match the key that I have.

How can I determine that such a pre-certificate is equivalent to an issued certificate?

Wolfgang
  • 253
  • 1
  • 4
  • I had trouble finding examples of PreCertificates, but I'm pretty sure the Serial Number should match. – nbering Apr 22 '18 at 03:55
  • @nbering They do match, but couldn't a rogue CA issue a different cert to someone else with the same serial number? Precert: https://crt.sh/?id=379671311 Cert: https://crt.sh/?id=384921708 – Wolfgang Apr 22 '18 at 15:39
  • "couldn't a rogue CA issue a different cert to someone else with the same serial number" : then the issuer field would be different as it would reflect a different CA... – Patrick Mevzek Apr 22 '18 at 19:49
  • @PatrickMevzek Why would the CA be different? – curiousguy Jul 04 '18 at 20:51

2 Answers2

1

Check the public key, if they match, it is OK. At the end of the day, the key is the important part of the certificate, as if it is your key and the attacker therefore does not have the corresponding private key, the rest is not important.

Do not check the certificate ID as suggested, ID can be manipulated.

Peter Harmann
  • 7,728
  • 5
  • 20
  • 28
1

Yes, easiest way is to just compare public key in pre-certificate and certificate, as stated above. But the way could be wrong if CA issued certificate having incorrect pre-certificate data. Let me explain. Assume you have a TBS (ToBeSigned) part of the possible future certificate. Then CA makes pre-certificate from the TBS (append "poison extension" and sign pre-certificate with kind of fake key) and send it to CT log. Then CA receives SignedCertificateTimestamp (SCT) for the certificate and includes SCT in the initial TBS as an extension. Then CA issues real certificate - sign the TBS with real CA key. But there could be a problem: some CAs could incorrectly issue end-user certificate by making final TBS not the same as in pre-certificate! Here is one real example

All pre-certificates usually issued in order to have value for SignedCertificateTimestampList (1.3.6.1.4.1.11129.2.4.2) X.509 certificate extension. But in fact in the certificate extension, you would only find TBS (ToBeSigned) part of the pre-certificate, not a full pre-certificate. And in order to prove that this particular pre-certificate is for this particular certificate, you would need to verify SignedCertificateTimestampList extension's value against PreCert type deducted from the certificate. Sounds complicated, but this is how all works. In order to help people to solve problems with CT internal data verification, I made CTjs lib. Here you could find an example how to correctly verify pre-certificate data against end-user certificate.

Feel free to ask any further questions about CT data.