Closed
Bug 1129645
Opened 11 years ago
Closed 11 years ago
A fake certificate can pass certificate validation
Categories
(NSS :: Libraries, defect)
Tracking
(Not tracked)
RESOLVED
INVALID
People
(Reporter: chenyt.cs.sjtu, Unassigned)
Details
User Agent: Mozilla/5.0 (X11; Linux i686 (x86_64)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Steps to reproduce:
I'm working on some testing tool for testing SSL/TLS implementations. When I made a fake certificate, I found that it can be verified against a ca certificate stored in Chrome's certificate manager (i.e., Builtin Object Token-Verisign Class 1 Public Primary Certification Authority). I just used a fake private key to issue the fake certificate, but let the issuer be the CA certificate. Can any guys help me to confirm that whether it is a security problem?
CA certificate:
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkG
A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
cyAxIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmlt
YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0f
zGVuDLDQVoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHi
TkVWaR94AoDa3EeRKbs2yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0G
CSqGSIb3DQEBBQUAA4GBAFgVKTk8d6PaXCUDfGD67gmZPCcQcMgMCeazh88K4hiW
NWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n0a3hUKw8fGJLj7qE1xIV
Gx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZRjXZ+Hxb
-----END CERTIFICATE-----
Fake certificate:
-----BEGIN CERTIFICATE-----
MIIEIDCCA4mgAwIBAgIHK1sjUF4/+jANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQG
EwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEg
UHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwIBgPMjAxMzA2
MTAwMDAwMDBaFw0xNTExMDgxOTU0MzBaMIHNMRYwFAYDVQQIEw1NYXNzYWNodXNl
dHRzMQ8wDQYDVQQHEwZCb3N0b24xEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsr
BgEEAYI3PAIBAhMIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0
aW9uMSUwDgYDVQQFEwc0NDAzODQ1MBMGA1UEAxMMZmlkZWxpdHkuY29tMQswCQYD
VQQGEwJERTEfMB0GA1UEChMWU05DIExFIFBBUklTSUVOIExJQkVSRTCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAw18yZvsaWTEOQ/FtnnmyXgTFFng0BsC2GISQ
yv/qqU/Z42ev8ddUSYPC6g0j/ijW6Vn4Si2i47dzDdSx79N3Kqd/xChw1ceLvIDQ
FwgyjYwBgfrsasUXWrMMCv83H0UijVpFnPjhge3XGber48ByGDYTsGC3zggj6gGw
jnuAILECAwEAAaOCAXMwggFvMAsGA1UdDwQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwZQYIKwYBBQUHAQEEWTBXMCMGCCsGAQUFBzABhhdodHRw
Oi8vb2NzcC5lbnRydXN0Lm5ldDAwBggrBgEFBQcwAoYkaHR0cDovL2FpYS5lbnRy
dXN0Lm5ldC9sMWUtY2hhaW4uY2VyMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9j
cmwuZW50cnVzdC5uZXQvbGV2ZWwxZS5jcmwwQQYDVR0gBDowODA2BgpghkgBhvps
CgECMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBhMBcG
A1UdEQQQMA6CDGZpZGVsaXR5LmNvbTAfBgNVHSMEGDAWgBRbQYqyxEPBvb/IVEFV
neCWrf+5oTAdBgNVHQ4EFgQUC/COx9x/MMdUY97t7Uwe0m04NzMwCQYDVR0TBAIw
ADANBgkqhkiG9w0BAQUFAAOBgQCfcMnePFx7od7ppqxgCVIFqoH/aF7K55pZRO7U
akxT4FclO6rowsLzeo7yaR7nnKM5kymSp0busJ1T/0b7UqCWjK/1KVVcsBiu7B+e
P+V67R3RVYYX5KvKGatAFbzFuExM9NxhWqPizgbA3UoUxtOS6imG1nD0LMwaoSHM
6Uoo2A==
-----END CERTIFICATE-----
Actual results:
NSS version: 3.17.3. The validation result: certificate is valid
Chrome: the certificate can be imported and it says that the certificate has been verified.
Firefox: the fake certificate cannot pass validation.
Expected results:
The fake certificate should be rejected.
| Reporter | ||
Updated•11 years ago
|
Severity: normal → critical
OS: All → Linux
Hardware: All → x86
| Reporter | ||
Comment 1•11 years ago
|
||
I tested the code certutil.c (nss 3.17.3/3.17.4) and found that:
(1) line 692: rv = CERT_VerifyCertificate(handle, cert, checkSig, usage,
timeBoundary, pwdata, log, &usage);
the function is not called, and thus rv has a NULL value;
(2) if rv is NULL, the leaf certificate passes validation.
See certutil.c line 722.
(3) A possible solution:
line 716: if (rv!=SECSUccess)
=>
line 716: if (rv==NULL || rv!=SECSUccess)
Comment 2•11 years ago
|
||
Hi,
I would like to try to recreate your result on other platforms.
Windows native certificate handling rejects this certificate as invalid. It allows import into the Windows Certificate Store (but its 'integrity cannot be guaranteed').
Firefox let me import this in Certificate Manager.
Firefox Certificate Viewer identified this as being issued by Builtin Object Token:Verisign Class 1 Public Primary Certification Authority so it looks like it is matching on
supplied Issuer DN.
This also displayed the CN of fidelity.com and O=SNC LE PARISIEN LIBERE
No great surprise because you can parse and import invalid certificates into Certificate Manager or Windows Cert store, this shouldn't have any security implications as they should fail at least one other check during TLS handshake.
I substituted the public key for another 1024b RSA to test with TLS, included below. My browser results are:
Windows Firefox:
fidelity.com:8443 uses an invalid security certificate.
The certificate does not come from a trusted source.
(Error code: mozilla_pkix_error_v1_cert_used_as_ca)
Windows Chrome: NET::ERR_CERT_INVALID
Chrome appeared to be appending the expected real entrust path (ie: matching on AKI) from its error message.
I believe firefox certificate manager behavior should match what you were seeing in Linux Chrome
There could be several issues at play here. the fake cert contains:
* SubjectKeyIdentifier of 0B:F0:8E:C7:DC:7F:30:C7:54:63:DE:ED:ED:4C:1E:D2:6D:38:37:33 which matches the pubkey of the real fidelity certificate, not the pubkey included on the
cert.
* AuthorityKeyIdentifier of 5B:41:8A:B2:C4:43:C1:BD:BF:C8:54:41:55:9D:E0:96:AD:FF:B9:A1 matches the keyid of entrust CA, not verisign CA as marked as Issuer
* notValidBefore has been tampered (different ASN.1 object type GeneralizedTime/UTCtime)
* Subject has been tampered (additional C=DE,O=SNC LE PARISIEN LIBERE)
* Sig is wrong size for either entrust or verisign issuer certs
And the signature was generated by the certificate Subject Key, as in Self Signed?
What I believe you are reporting
=========================================================
Trying to recreate with fake.crt and certutil under windows:
A populated cert8.db was copied from nightly
certutil -A -d .\ -n fake -i fake.crt -t P (add to cert store)
certutil -V -n fake -u C -d .\ (validate for purpose clientAuth)
certutil: certificate is valid
certutil -V -n fake -u C -d .\ -e (validate sig)
certutil: certificate is valid
with an empty store, containing only fake, I get
certutil -V -n fake -u C -d .\ -e (validate sig)
certutil: could not authenticate to token NSS Certificate DB.: SEC_ERROR_IO: An I/O error occurred during security authorization.
This would appear to be a false positive on certutil sig tests, as this sig should not be passing, yeah?
You last post indicates that CERT_VerifyCertificate isn't being called which is why this passes this test.
My debugging of certutil showed this function is called and returning SECSucess; logically it shouldn't be returning this value as sig is invalid.
Looking deeper into CERT_VerifyCertificate we find that
certvfy.c:1177
rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted);
is returning SECSuccess and causing trusted to be set to 1, which bypasses the signature check which we expect should occur at certvfy:1192
This actually makes sense, because we flagged this certificate as a trusted peer with
certutil -A -d .\ -n fake -i fake.crt -t P (add to cert store)
So the problem now seems that we never actually check the signature of certificates that are trusted in our store with this function.
Certutil only lets us operate on a certificate nickname, which needs to correspond to a certificate flagged as either trusted or otherwise.
If we have flagged the cert as explicitly not trusted, it our rv = cert_CheckLeafTrust(cert, certUsage, &flags, &trusted) will set rv to SECFailure and cause PORT_SetError(SEC_ERROR_UNTRUSTED_CERT) to be raised.
I'm going to call the whole CERT_VerifyCertificate for checking signatures in certhigh\certvfy.c is broken in this context (checking with certutil).
If cert_CheckLeafTrust passes because its flagged as trusted in the store, it continues for loop for CertificateUsage bypassing sig check
if cert_CheckLeafTrust fails because it is explicitly not trusted is sets the error and continues the for loop.
I cant see how certvfy.c:1192
rv = cert_VerifyCertChain(handle, cert,
checkSig, &sigerror,
certUsage, t, wincx, log,
&revoked)
would ever be reached.
Ultimately the logic flow is that if you have imported this certificate into a trust store, the actual validity of the signature is ignored.
Now this doesn't appear to be bad news for modern browsers because it seems nss CERT_VerifyCertificate isn't used in the ssl functions within firefox.
Certificate validation in firefox appears to use the CertVerifier functions (and libpkix), as shown by the error message returned.
Specifically mozilla::psm::CertVerifier::VerifyCert rather than the NSS certhigh CERT_VerifyCertificate function.
There doesn't appear to be anything special about this or other certificate, it should behave the same for any cert you insert into your cert store for these functions.
My fake certs don't work on an actual TLS session in either browser which is where a security issue would be if it did.
To spare asking for your testing private key, here is the one I used for others the verify function of a fake cert of this form in TLS.
(I subst the public key to match private key below, no other changes, sig is same above cert which wont match anything and won't validate).
fake-k2.crt
-----BEGIN CERTIFICATE-----
MIIEIDCCA4mgAwIBAgIHK1sjUF4/+jANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQG
EwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDEg
UHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwIBgPMjAxMzA2
MTAwMDAwMDBaFw0xNTExMDgxOTU0MzBaMIHNMRYwFAYDVQQIEw1NYXNzYWNodXNl
dHRzMQ8wDQYDVQQHEwZCb3N0b24xEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsr
BgEEAYI3PAIBAhMIRGVsYXdhcmUxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0
aW9uMSUwDgYDVQQFEwc0NDAzODQ1MBMGA1UEAxMMZmlkZWxpdHkuY29tMQswCQYD
VQQGEwJERTEfMB0GA1UEChMWU05DIExFIFBBUklTSUVOIExJQkVSRTCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAv5egWoljdR0bxlYGZHsdQHqCswnmjU9ooImf
apnL8eIlGY6HT4u1xQ+5FoQkKAzsJn088VPO1nKflDD0iUkSNDthXIwKnGFIJPYQ
GMBCNitZ7QC/6kLeI1j97R8N0Jh0V7wKVjQoq5ctjlv6sCQXeC9ACrCjhRT7rG+H
2el+CiUCAwEAAaOCAXMwggFvMAsGA1UdDwQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwZQYIKwYBBQUHAQEEWTBXMCMGCCsGAQUFBzABhhdodHRw
Oi8vb2NzcC5lbnRydXN0Lm5ldDAwBggrBgEFBQcwAoYkaHR0cDovL2FpYS5lbnRy
dXN0Lm5ldC9sMWUtY2hhaW4uY2VyMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9j
cmwuZW50cnVzdC5uZXQvbGV2ZWwxZS5jcmwwQQYDVR0gBDowODA2BgpghkgBhvps
CgECMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBhMBcG
A1UdEQQQMA6CDGZpZGVsaXR5LmNvbTAfBgNVHSMEGDAWgBRbQYqyxEPBvb/IVEFV
neCWrf+5oTAdBgNVHQ4EFgQUC/COx9x/MMdUY97t7Uwe0m04NzMwCQYDVR0TBAIw
ADANBgkqhkiG9w0BAQUFAAOBgQCfcMnePFx7od7ppqxgCVIFqoH/aF7K55pZRO7U
akxT4FclO6rowsLzeo7yaR7nnKM5kymSp0busJ1T/0b7UqCWjK/1KVVcsBiu7B+e
P+V67R3RVYYX5KvKGatAFbzFuExM9NxhWqPizgbA3UoUxtOS6imG1nD0LMwaoSHM
6Uoo2A==
-----END CERTIFICATE-----
fake-k2.key
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQC/l6BaiWN1HRvGVgZkex1AeoKzCeaNT2igiZ9qmcvx4iUZjodP
i7XFD7kWhCQoDOwmfTzxU87Wcp+UMPSJSRI0O2FcjAqcYUgk9hAYwEI2K1ntAL/q
Qt4jWP3tHw3QmHRXvApWNCirly2OW/qwJBd4L0AKsKOFFPusb4fZ6X4KJQIDAQAB
AoGBAKl3BG8QdthwFtEn5h+ahhUyR8j1SOhVBMZ69Hbl8m7RCN/CIg1KFk1nyt8P
oquKQpcIz47mAl3MpTn+001bRK1ENAaRrymBYqshyLUFpb2pS77FYLIAI18ZWbm7
g4n/NL3If5dI5xAncoxP2tNB56V/3NaYraA8MLk327U8IsABAkEA+IpK2TVTcwWf
3ER3sqViXwtFaWpaovAtLj3MtK86B7Cb97i7/mNf787fSLZqA2m9GySqynO0ogUC
Vs93YSMVJQJBAMVXw3P9y0ueQGZfoY4YU2noTccaPrc5N67YWWorZ/0XaGaQobut
laQbimRsUwCNDaWDo8dcSl1ES6hHabSNkQECQQDSXcNSrCcw8S7I8o7Z/9AOoGyk
+Cc1SNMFE7vjp3kXry2kdJFylUxLny8wzW1X7DTq95Mz/tGCXXkIX1wtNNOdAkEA
nZn4k0LFv89TmS6YhDWzMCqBKxgvq/47FRzdU+f0dXDjRL4PHCaGEniYLplANHlx
w5R9EPMIxLGNRog5yCMjAQJAMpQ5nbNeyxGL/Xyx2LA4POJjR/1xC8YiS57jPBLX
3fQnyynvFnYS5kmzjx76LUmVY/nPd/8/z6bn7Dr4V98+7Q==
-----END RSA PRIVATE KEY-----
At this stage I don't know what else could be calling CERT_VerifyCertificate from certhigh. Hopefully nothing modern.
The deeper I look into NSS and related libraries for TLS the more scared I become. :-)
I don't think this is critical as it is functionality that has not been used for a long time, seems to have broken a long time ago also.
MiW
| Reporter | ||
Comment 3•11 years ago
|
||
Hi, MiW, I agreed with you that CERT_VerifyCertificate should have been discarded for a little time. We are very lucky now (with respect to SSL/TLS connections using browsers). How are NSS new versions?
Comment 4•11 years ago
|
||
I looked at your sample certificates.
Note that the issuer CA cert you're referring to has already been marked as "no longer trusted for SSL/TLS" (phased out because of the 1024 bit key), but it's still marked as accepted for email security.
I setup a test NSS database that restores trust for the old issuer CA for SSL/TLS.
Then I used the NSS vfychain utility (which calls CERT_VerifyCertificate) to check both fake certificates that have been attached.
In all scenarios, the tool reported an invalid signature.
Which software did accept your fake certificate as good, and what is necessary to reproduce that?
| Reporter | ||
Comment 5•11 years ago
|
||
Hi, Kai, I verified it using certutil -V (on Ubuntu 14.04 TLS, NSS 3.17.3/4, the steps are almost same as what "MiW CryptoCurrency" did). vfychain may have no problem for this. What I concern is why certutil accepts the fake chain even if CERT_VerifyCertificate is not invoked appropriately (when rv has a NULL value. It really happened when I verified the certificate chain). After all, NSS should not make such confusing issues.
Comment 6•11 years ago
|
||
(In reply to MiW CryptoCurrency from comment #2)
> So the problem now seems that we never actually check the signature of
> certificates that are trusted in our store with this function.
> Certutil only lets us operate on a certificate nickname, which needs to
> correspond to a certificate flagged as either trusted or otherwise.
> If we have flagged the cert as explicitly not trusted, it our rv =
> cert_CheckLeafTrust(cert, certUsage, &flags, &trusted) will set rv to
> SECFailure and cause PORT_SetError(SEC_ERROR_UNTRUSTED_CERT) to be raised.
>
> I'm going to call the whole CERT_VerifyCertificate for checking signatures
> in certhigh\certvfy.c is broken in this context (checking with certutil).
> If cert_CheckLeafTrust passes because its flagged as trusted in the store,
> it continues for loop for CertificateUsage bypassing sig check
> if cert_CheckLeafTrust fails because it is explicitly not trusted is sets
> the error and continues the for loop.
> I cant see how certvfy.c:1192
> rv = cert_VerifyCertChain(handle, cert,
> checkSig, &sigerror,
> certUsage, t, wincx, log,
> &revoked)
> would ever be reached.
>
> Ultimately the logic flow is that if you have imported this certificate into
> a trust store, the actual validity of the signature is ignored.
>
This is not a bug. This is exactly how PKI works.
A trust anchor is a combination of a subject distinguished name and a public key. No signature needs to be checked for a trust anchor. That trust anchors can be delivered as certificates is incidental, and no checking of a certificate is needed.
When you import the leaf cert and flag it as trusted, it's sufficient to simply look at the name of the cert, look at the public key in the cert, see that it's trusted, and stop processing. That is literally EXACTLY how the PKI is supposed to work. You don't check signatures. You don't check extended attributes for consistency. You see it's a trust anchor and you can stop right there.
You can read RFCs such as RFC 5914 or RFC 6024 to understand how Trust Anchors work, or you can read RFCs like RFC 4158 or 5280 to understand how this algorithm works.
Suffice to say, from the description and repro, importing a cert as trusted and it being trusted is Working as Intended.
| Reporter | ||
Comment 7•11 years ago
|
||
(In reply to Ryan Sleevi from comment #6)
> (In reply to MiW CryptoCurrency from comment #2)
> > So the problem now seems that we never actually check the signature of
> > certificates that are trusted in our store with this function.
> > Certutil only lets us operate on a certificate nickname, which needs to
> > correspond to a certificate flagged as either trusted or otherwise.
> > If we have flagged the cert as explicitly not trusted, it our rv =
> > cert_CheckLeafTrust(cert, certUsage, &flags, &trusted) will set rv to
> > SECFailure and cause PORT_SetError(SEC_ERROR_UNTRUSTED_CERT) to be raised.
> >
> > I'm going to call the whole CERT_VerifyCertificate for checking signatures
> > in certhigh\certvfy.c is broken in this context (checking with certutil).
> > If cert_CheckLeafTrust passes because its flagged as trusted in the store,
> > it continues for loop for CertificateUsage bypassing sig check
> > if cert_CheckLeafTrust fails because it is explicitly not trusted is sets
> > the error and continues the for loop.
> > I cant see how certvfy.c:1192
> > rv = cert_VerifyCertChain(handle, cert,
> > checkSig, &sigerror,
> > certUsage, t, wincx, log,
> > &revoked)
> > would ever be reached.
> >
> > Ultimately the logic flow is that if you have imported this certificate into
> > a trust store, the actual validity of the signature is ignored.
> >
>
> This is not a bug. This is exactly how PKI works.
>
> A trust anchor is a combination of a subject distinguished name and a public
> key. No signature needs to be checked for a trust anchor. That trust anchors
> can be delivered as certificates is incidental, and no checking of a
> certificate is needed.
>
> When you import the leaf cert and flag it as trusted, it's sufficient to
> simply look at the name of the cert, look at the public key in the cert, see
> that it's trusted, and stop processing. That is literally EXACTLY how the
> PKI is supposed to work. You don't check signatures. You don't check
> extended attributes for consistency. You see it's a trust anchor and you can
> stop right there.
>
> You can read RFCs such as RFC 5914 or RFC 6024 to understand how Trust
> Anchors work, or you can read RFCs like RFC 4158 or 5280 to understand how
> this algorithm works.
>
> Suffice to say, from the description and repro, importing a cert as trusted
> and it being trusted is Working as Intended.
Does it mean that verification should not really work on a certificate in
the certificate database? So should the option be discarded from certutil utility
since it does not provide with any guarantees?
| Reporter | ||
Comment 8•11 years ago
|
||
If the CA certificate is not in the certificate database, the fake certificate cannot
pass validation. It seems that certutil still tries to find a CA certificate
who can issue the fake certificate. The validation logic in certutil is a
little redundant or messing. An NSS user may misuse (e.g., copy and paste) the code
in certutil.
Comment 9•11 years ago
|
||
Hi Ryan,
This investigation process did help me understand the Trust Anchors (TA) a little better, yes.
I was trying to focus on certutil specifically, and how a signature verification operation could be offered
if trusted certs don't get their signatures checked.
I had not appreciated the incidental nature of the cert sig on TA public keys (rather than 'TA certs').
Thanks for the RFC pointers.
Chen:
Calling -V -e if the certificate is in the database can give no guarantee that the signature is good.
You can think of it when adding the pubkey as trusted you are discarding the cert signature.
Only the subject DN and pubkey are meaningful as Trust Anchors.
As Ryan indicated this is exactly what is expected in PKI.
What I have missed is that you can call -V and use a filename as a nick. This is a working sig check case without being trusted.
Validate selects the peer cert at certutil.c:661 SECU_FindCertByNicknameOrFilename
$ certutil -N -d ./ (new db)
$ certutil -V -n fake-k2.crt -a -d ./ -u C -e (validate without any TA)
certutil: certificate is invalid: Peer's Certificate issuer is not recognized.
$ certutil -A -i ca.crt -a -d ./ -n verisign -t c (add verisign cert as ca)
$ certutil -V -n fake-k2.crt -a -d ./ -u C -e (validate again)
certutil: certificate is invalid: Peer's certificate has an invalid signature.
$ certutil -A -i fake-k2.crt -a -d ./ -n fake -t P (add it as trusted)
$ certutil -V -n fake-k2.crt -a -d ./ -u C -e (validate again)
certutil: certificate is valid (as expected because of trust)
vfychain -d ./ -a -p fake-k2.crt
Chain is good!
vfychain -d ./ -a -p -p fake-k2.crt
Chain is good!
(old and new work the same)
I wouldn't say "verification should not really work on a certificate in the certificate database",
the verification algorithm sees the cert as trusted, and passes it. Its behaving exactly as expected.
I don't think -e signature check option should be discarded either, as it is also behaving as expected as above when not trusted.
I initially had the same thoughts about discard, but this use case is valid in this context.
I believe it would be correct to say explicit /signature checking/ for a trusted certificate doesn't work but this is more a property of PKI. Existence as trusted is sufficient for validity.
If anyone was foolish enough to be trying to verify certificate signatures by
1. adding them to the trust store (regardless of the issuer being in the database)
2. checking the sig on the cert in the trust store, or externally from a pubkey already in the trust store
they would find that they would pass this check, even if they are not valid signatures.
This must be because the mere existence of the cert signature in the database is incidental.
Such is PKI and we can't Доверяй, но проверяй.
If you agree this is indeed the case with your findings,
you might want to drop the criticality of this case as it is all as expected.
No security issue; You and I seem to have both misunderstood the role of sigs play when stored as TA's.
Thank you for your reply Ryan, a little blunt but technically accurate and enlightening. :-)
Updated•11 years ago
|
Severity: critical → normal
Status: UNCONFIRMED → RESOLVED
Closed: 11 years ago
Resolution: --- → INVALID
You need to log in
before you can comment on or make changes to this bug.
Description
•