Closed Bug 1889468 Opened 10 months ago Closed 10 months ago

Issuer Field Interpretation Differences Between Firefox and Chrome Leading to Validation Discrepancies Reported

Categories

(Core :: Security: PSM, defect)

Other Branch
defect

Tracking

()

RESOLVED WONTFIX

People

(Reporter: 2295456556, Unassigned)

Details

Attachments

(9 files)

Steps to reproduce:

1.Generating a mutated digital certificate with an additional Subject Alternative Name (SAN) of "ypj.test.com", along with its corresponding root CA and private key.
2.Configuring an Nginx web server to use the mutated certificate and private key in HTTPS mode.
3.Setting up the local machine (127.0.0.1) as the server and mapping "ypj.test.com" to 127.0.0.1 in the hosts file.
4.Adding the root CA to the system's trusted root certificate store using certutil.
5.Running nginx.exe. Accessing the URL "https://ypj.test.com:443" in a web browser, where the certificate's SAN matches the URL.
Firefox-version-113.0

Actual results:

We have mutated the issuer field of a digital certificate. According to RFC 5280, "The type of the component AttributeValue is determined by the AttributeType; in general, it will be a DirectoryString (teletexString, printableString, universalString, utf8String, bmpString).” However, we have replaced one of the printableString TLV structures in the original certificate's issuer field with a SEQUENCE TLV structure. While Firefox can still parse this, it does not comply with RFC 5280’s specification that "in general, AttributeValue will be a DirectoryString (teletexString, printableString, universalString, utf8String, bmpString).”Although RFC5280 uses the keyword "generally," which implies that AttributeValue permits tags other than 'teletexString, printableString, universalString, utf8String, bmpString,' I believe that for the correctness of decoding, the AttributeType should still be a TLV structure, rather than a structure like TL(TL(TLV)). Furthermore, even if we allow parsing of such a structure, it is extremely difficult to confirm the real CA identity from the parsed content, as the comprehensibility of the content, whether for humans or for computers, is poor after parsing and contains a large amount of content that does not belong to the issuer's attributes. I believe such a lenient parsing policy could easily lead to potential security issues. In contrast, Chrome deems such a structure undecodable and, accordingly, rejects the certificate.

Expected results:

Firefox should determine that there is a decoding error in this field and reject the certificate.
Firefox-version-113.0

Attached image firefox.png
Attached image hosts.png
Attached image nginx_conf.png
Attached file rsa_pri_2048.pem
Attached image chrome.png

Even when forceful parsing is applied to content that ambiguously conforms to standards or presents difficulties in parsing, and it ultimately determines that the issuer field of an end-user certificate exactly matches the subject field of a CA certificate, the certificate appears to have passed validation on a formal level. However, such validation is inherently unreliable as it is based on an incorrect parsing approach that fails to adhere strictly to X.509 and RFC standards.

From the user's perspective, there may be a false sense of security regarding their connection, compounded by the difficulty of accurately ascertaining the genuine origin of the CA certificate and the validity of the certificate chain.

Moreover, from a coding standpoint, even if the certificate seems to pass validation at face value, the standard conformity of certificate parsing is questionable. A validation process that rests on erroneous parsing can lead to an unreliable verification of the certificate's security, potentially resulting in an inability to differentiate between tampered and legitimate certificates within the validation logic.

Therefore, relying solely on the equivalence of field values does not guarantee the security of the certificate chain. This approach can introduce potential security vulnerabilities that must be addressed to ensure the robustness and integrity of cryptographic communications.

The certificate viewer (about:certificate) uses a different parser than the one that we use for validation.

For the purposes of path building, the issuer name is an opaque octet string. We don't parse it other than to check that it contains at least one RDN.

It looks like we return a non-overridable SEC_ERROR_BAD_DER result if the user has not manually trusted the issuer. I would have expected SEC_ERROR_UNKNOWN_ISSUER, which is overridable. The SEC_ERROR_BAD_DER return is a quirk of our MITM canary check here: https://searchfox.org/mozilla-central/rev/e1e4a33e82ee1d278df238cf0896b7358a4bc359/security/certverifier/CertVerifier.cpp#907-912. I think either return code is fine in this case. I don't see us changing it.

If the user has manually trusted the issuer, there's no reason to return an error.

Status: UNCONFIRMED → RESOLVED
Closed: 10 months ago
Resolution: --- → WONTFIX

I've understood your explanation, and it appears that I initially believed your policy could not detect a tampered certificate. However, it indeed can detect a tampered certificate, but since I manually trusted the CA certificate, it was possible to bypass the 'SEC_ERROR_BAD_DER' or 'SEC_ERROR_UNKNOWN_ISSUER' validation results. This is my understanding of your explanation. And I would like to propose two questions.

1.Based on your response, when constructing the path, in determining whether the leaf certificate issuer field and the CA subject are equal, do you compare the corresponding fields of the two in binary? Instead of using the parsed text fields for comparison?
2.How can we obtain the parsing results from the parser used for validation? Is there any available programming interface or method for this?

And you have not directly answered another question of mine. While it's understood that, for the purposes of path building, the issuer name is considered an opaque octet string and thus not parsed by your system, when the certificate viewer does attempt a parsing, users are confronted with garbled text interpretations. This might lead users to suspect the certificate with such confusing text interpretations as insecure, prompting them to abandon their normal access. Have you considered the impact of this on user experience?

Based on your response, when constructing the path, in determining whether the leaf certificate issuer field and the CA subject are equal, do you compare the corresponding fields of the two in binary? Instead of using the parsed text fields for comparison?

Yes, we compare in binary. This is sufficient for certs in the WebPKI as the baseline requirements mandate that the issuer field of a tbsCertificate "MUST be byte-for-byte identical to the subject field of the Issuing CA." See Section 7.1.2 of https://cabforum.org/uploads/CA-Browser-Forum-TLS-BRs-v2.0.2.pdf.

How can we obtain the parsing results from the parser used for validation? Is there any available programming interface or method for this?

You might look at our unit tests, e.g. https://searchfox.org/mozilla-central/source/security/manager/ssl/tests/unit/test_cert_signatures.js. There are some helper functions in https://searchfox.org/mozilla-central/source/security/manager/ssl/tests/unit/head_psm.js. You can do something similar from the browser console if you don't want to write xpcshell tests.

You could also build a utility that uses mozpkix directly. The mozpkix gtests might be a good guide for how to do that https://searchfox.org/nss/source/gtests/mozpkix_gtest.

This might lead users to suspect the certificate with such confusing text interpretations as insecure, prompting them to abandon their normal access.

Yes, that's a good thing. The user should be suspicious in this case. The issuer encoding here is not allowed on the WebPKI. If a public CA issued a certificate like this they would be required to revoke it and file an incident report.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: