Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure without DirectoryName in non-empty permitted subtrees of name constraints #134

Open
est31 opened this issue Jun 29, 2020 · 0 comments

Comments

@est31
Copy link

est31 commented Jun 29, 2020

If I have a CA certificate with non-empty permitted_subtrees, webpki always performs a check of DirectoryName, even if the permitted_subtrees doesn't contain any DirectoryName. Due to that, you are basically required to put a DirectoryName constraint if you want it to be non-empty. In other words, webpki (wrongly) rejects this chain (order is entity cert followed by CA cert):

-----BEGIN CERTIFICATE-----
MIIBuzCCAWGgAwIBAgIBKjAKBggqhkjOPQQDAjAuMRIwEAYDVQQDDAlNYXN0ZXIg
Q0ExGDAWBgNVBAoMD0NyYWIgd2lkZ2l0cyBTRTAgFw03NTAxMDEwMDAwMDBaGA80
MDk2MDEwMTAwMDAwMFowLjESMBAGA1UEAwwJTWFzdGVyIENBMRgwFgYDVQQKDA9D
cmFiIHdpZGdpdHMgU0UwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ0Md/7306Z
z3d0/UmGXbN4zgAlzxckizaUPl4Q4/VK5Vx4yxlpyBpGHuD7vQakuaWX8yMXDT2S
cBlUW8N7ah0Ko24wbDAhBgNVHREEGjAYggtjcmFicy5jcmFic4IJbG9jYWxob3N0
MBcGA1UdHgEB/wQNMAugCTAHMAWCA2RldjAdBgNVHQ4EFgQUK0R+iWG+t7ic3dxf
HT8Ftc7TJOowDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiA0KJud
vLDNsIHGSlODCUCrpHbcg39Ik4nd5eOpn/fBZQIhALoD34QczpfLMPoDWvPmCp5W
XwuCoSyP+KCyCbeagTuO
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIBNjCB3aADAgECAgEqMAoGCCqGSM49BAMCMC4xEjAQBgNVBAMMCU1hc3RlciBD
QTEYMBYGA1UECgwPQ3JhYiB3aWRnaXRzIFNFMCAXDTc1MDEwMTAwMDAwMFoYDzQw
OTYwMTAxMDAwMDAwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdW54ceF7
KIjr8NxMcabZINzCezYEj5GC/WSOwU6clGVg3eYAyuZaJhCkFYmvYzckmV4S0CqP
gq1fDzX+RXt19KMYMBYwFAYDVR0RBA0wC4IJY3JhYnMuZGV2MAoGCCqGSM49BAMC
A0gAMEUCIQC8Wy8n7K0HLXW0EFR1/YJZrrH9PDQjzhS3amEM3dcG7AIgQiS/SWpY
MPSDgjKtBa/5rskwuyDpYMwjOJqPpb4hQeM=
-----END CERTIFICATE-----

As the DirectoryName comparison is implemented as an equality check in webpki, you are required to constrain the DirectoryName to precisely that value for all sub-CAs. With this in mind, I was able to come up with a working certificate chain, but I think it's too restrictive.

-----BEGIN CERTIFICATE-----
MIIBvzCCAWWgAwIBAgIBKjAKBggqhkjOPQQDAjAuMRIwEAYDVQQDDAlNYXN0ZXIg
Q0ExGDAWBgNVBAoMD0NyYWIgd2lkZ2l0cyBTRTAgFw03NTAxMDEwMDAwMDBaGA80
MDk2MDEwMTAwMDAwMFowLjESMBAGA1UEAwwJTWFzdGVyIENBMRgwFgYDVQQKDA9D
cmFiIHdpZGdpdHMgU0UwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATaX8aGD/6M
pelcmKx3VhYStprpcC+FSQND56tPrpE9oqMd17vk7VG+VwHs8OYX1J17a6Jf7FiI
ZVjqIxtn0ZB6o3IwcDAhBgNVHREEGjAYggtjcmFicy5jcmFic4IJbG9jYWxob3N0
MBsGA1UdHgEB/wQRMA+gDTALMAWCA2RldjACpAAwHQYDVR0OBBYEFGVDkFrv6WW1
b7FeiD1kVI5l2RaLMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIh
AIm9LNIefoVoxZRaZeYnczqfDysUDWlr+GSxCIum8guyAiAKLpuAslcbSK018Zoo
WStn3pkZcgtYxxx5WZHgx7mdBw==
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIBNjCB3aADAgECAgEqMAoGCCqGSM49BAMCMC4xEjAQBgNVBAMMCU1hc3RlciBD
QTEYMBYGA1UECgwPQ3JhYiB3aWRnaXRzIFNFMCAXDTc1MDEwMTAwMDAwMFoYDzQw
OTYwMTAxMDAwMDAwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjxY08jii
7ij9iYrtIfZCeowCAYUsBJ/Dn15hthSBmXGrPKOopcCnn89xLdoejK9foApt2BXO
7sJ34tuERDvrL6MYMBYwFAYDVR0RBA0wC4IJY3JhYnMuZGV2MAoGCCqGSM49BAMC
A0gAMEUCIQCW+euxirb1atn5FLoMM8GrlMBC2JmpiMddy44QJsUYDAIgPn8+Vwv2
CzgdB5GccI8xq/yqwzO0sbJAEhlrB1KER28=
-----END CERTIFICATE-----

Note that openssl isn't as restrictive and doesn't require a DirectoryName to be present. For example, it is just fine with this chain:

-----BEGIN CERTIFICATE-----
MIIBNzCB36ADAgECAgEqMAoGCCqGSM49BAMCMC4xEjAQBgNVBAMMCU1hc3RlciBD
QTEYMBYGA1UECgwPQ3JhYiB3aWRnaXRzIFNFMCAXDTc1MDEwMTAwMDAwMFoYDzQw
OTYwMTAxMDAwMDAwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyB08z5A+
9k01UOErrsi6PGeOmLNyEeiBJ0MoVWSEDCbIjcpvfdv+GMkeurmBCIZMjFQIqwIv
LH3erfiZK/yKzKMaMBgwFgYDVR0RBA8wDYILY3JhYnMuY3JhYnMwCgYIKoZIzj0E
AwIDRwAwRAIgeHyjRoz6cfA0HOoEY1Gp/srAmssGis7uU8mOLYrz9UACIBBUCKeS
PnH9JHvd+LNN0IQEC86cwhtIY7Qqi32qr/ie
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIBwTCCAWegAwIBAgIBKjAKBggqhkjOPQQDAjAuMRIwEAYDVQQDDAlNYXN0ZXIg
Q0ExGDAWBgNVBAoMD0NyYWIgd2lkZ2l0cyBTRTAgFw03NTAxMDEwMDAwMDBaGA80
MDk2MDEwMTAwMDAwMFowLjESMBAGA1UEAwwJTWFzdGVyIENBMRgwFgYDVQQKDA9D
cmFiIHdpZGdpdHMgU0UwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQYQIhXkFtA
VEDi5tgasEaYaazt23531oy/bthDvFsIu3NE4R12Zv0dL2+ObECrfio0OhJvTren
LFILdkAFCAeBo3QwcjAhBgNVHREEGjAYggtjcmFicy5jcmFic4IJbG9jYWxob3N0
MB0GA1UdHgEB/wQTMBGgDzANggtjcmFicy5jcmFiczAdBgNVHQ4EFgQUVb0U0bBp
eklcaGtTjKPCY+CdM8cwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBF
AiAwpysdo0t7bo294FoC0+DgYRYfaP78ijq46bfCixvjZwIhAIGQY9CfnZIuWTSz
Wq502nKjAt07zrRYrNOnKHJcMGl7
-----END CERTIFICATE-----

Note that openssl also assumes a different format for the restrictions, i.e. one nesting layer of SEQUENCE more shallow.
I think that this is a violation of the format specified in RFC 5280 and, will file a bug in the openssl tracker after more research. Edit: this is another bug in webpki which assumes explicit tagging, but the spec wants implicit tagging: #135

Back to this bug. The RFC is admittedly a bit vague on the question. Quoting RFC 5280:

   Restrictions apply to the subject distinguished name and apply to
   subject alternative names.  Restrictions apply only when the
   specified name form is present.  If no name of the type is in the
   certificate, the certificate is acceptable.

Note the second sentence. It doesn't specify which name form, the one in the CA's restriction list or the name form of the entity cert. Reading the third sentence makes you believe they only mean the name form in the entity cert. If you interpret the second sentence to apply to the CA's list as well as the certificate's list, you can conclude that if the CA's list doesn't contain any DirectoryName restriction, then no restrictions apply to the entity cert regarding its DirectoryName.

I think the core of this bug is the check_presented_id_conforms_to_constraints_in_subtree function in src/name.rs.
I suggest only setting has_permitted_subtrees_mismatch to true if there has been a match in the type, but a mismatch in the content. So making the default arm in match (name, base) { still evaluate to something indicating a mismatch, but one that doesn't set has_permitted_subtrees_mismatch later.

Related, but more general than this bug: #20

bnoordhuis added a commit to bnoordhuis/webpki that referenced this issue May 1, 2021
There were two bugs. webpki didn't:

1. read the X.509 Name Constraints field in its entirety, nor

2. check the certificate subject against the constraints correctly

(1) is a simple fix, (2) requires reading the Common Name from the
certificate.

Closes briansmith#20, briansmith#134.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant