[Moderate] gnutls x509 nameconstraints: excluded dns/email subtree bypass via case-sensitive comparison (security report)

hey,

gnutls compares nameConstraints labels using a case-sensitive memcmp path without an ascii-casefold canonicalization step. when excludedSubtrees/permittedSubtrees dNSName (dns) or rfc822Name (email) constraints are present, attacker-controlled casing differences in the leaf certificate SAN can cause a false accept (policy bypass) where the certificate should be rejected.

severity

critical (certificate verification bypass in deployments relying on nameConstraints; end-to-end PoC included) cvss: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N (9.1)

relevant links

  • repo: https://gitlab.com/gnutls/gnutls
  • commit: 165ae258
  • files: lib/x509/name_constraints.c, lib/x509/verify.c
  • related upstream issue (public): #1223 (closed) (case-sensitive matching under permitted dNSName; false reject). this report focuses on excludedSubtrees false accepts (bypass), and additionally reproduces the bypass class for excluded rfc822Name.

root cause

compare_strings() uses memcmp() for dns label comparisons and neither the constraint value nor the leaf SAN dNSName are normalized with ascii-casefold before comparison. as a result, nameconstraints decisions can depend on attacker-controlled case.

impact

in deployments that rely on constrained sub-ca nameConstraints as a security boundary, excludedSubtrees/permittedSubtrees constraints can be bypassed via case variation, leading to certificate verification bypass (false accept) for a leaf certificate in a forbidden dns subtree or excluded email domain.

proof of concept

dns excludedSubtrees bypass:

unzip poc.zip -d poc
cd poc
bash ./canonical.sh

expected:

[CALLSITE_HIT]: gnutls-certtool --verify invoked with chain (root trust anchor + constrained sub-ca nameconstraints + leaf san dNSName=ExAmPlE.CoM) [PROOF_MARKER]: unexpected trust: leaf accepted despite excluded dNSName constraint due to case-sensitive dns compare

unzip poc.zip -d poc
cd poc
bash ./control.sh

expected:

[NC_MARKER]: expected rejection: chain violates signer's constraints when leaf san matches excluded dNSName

expected: excluded dNSName constraint rejects a leaf SAN dNSName differing only by case. actual: canonical accepts a leaf whose SAN differs only by case from an excluded dNSName constraint; control rejects when the leaf SAN matches the excluded dNSName.

email excluded rfc822Name bypass:

unzip poc.zip -d poc
cd poc
bash ./canonical_email.sh

expected:

[CALLSITE_HIT]: gnutls-certtool --verify invoked with chain (root trust anchor + constrained sub-ca nameconstraints + leaf san rfc822name=user@ExAmPlE.CoM) [PROOF_MARKER]: unexpected trust: leaf accepted despite excluded rfc822name constraint due to case-sensitive dns compare

unzip poc.zip -d poc
cd poc
bash ./control_email.sh

expected:

[NC_MARKER]: expected rejection: chain violates signer's constraints when leaf rfc822name matches excluded email domain

expected: excluded rfc822Name constraint rejects a leaf SAN rfc822Name differing only by case (domain part). actual: canonical_email accepts the mixed-case email while control_email rejects the lowercase email under the same excluded constraint.

recommended fix

apply ascii-casefold normalization for dns labels (and email domain parts) before comparisons in the nameConstraints decision path, and add regression tests ensuring:

  • excluded dNSName=example.com rejects leaf SAN dNSName=ExAmPlE.CoM
  • excluded rfc822Name=example.com rejects leaf SAN rfc822name=user@ExAmPlE.CoM

attachments: poc.zip

note: canonical/control logs should include a line like:

[CALLSITE_HIT]: name_constraints.c compare_strings -> compare_dns_names (memcmp path)

​[https://res.public.onecdn.static.microsoft/assets/fluentui-resources/1.1.0/app-min/assets/item-types/24_2x/zip.png]poc 100.ziphttps://1seal-my.sharepoint.com/:u:/g/personal/security_1seal_org/IQAEsKaIoqI5R4jsMkHniUmRAV1D-CzK6V2Dn5zTIR-B0yI​ ​[https://res.public.onecdn.static.microsoft/assets/fluentui-resources/1.1.0/app-min/assets/item-types/24_2x/code.png]PR_DESCRIPTION 90.mdhttps://1seal-my.sharepoint.com/:t:/g/personal/security_1seal_org/IQDLnbN6d5D-RKye1UGR4MdYAW_gX44INz6PeRMF9LQuTGg​ ​[https://res.public.onecdn.static.microsoft/assets/fluentui-resources/1.1.0/app-min/assets/item-types/24_2x/code.png]attack_scenario 43.mdhttps://1seal-my.sharepoint.com/:t:/g/personal/security_1seal_org/IQCNKsbKMUt4RZyvzQoyJ1nwAfStheWi9wMEO87MFN4yCag​

cheers, Oleh Konko

Assignee Loading
Time tracking Loading