{"action":"created","issue":{"url":"https://api.github.com/repos/ARMmbed/mbedtls/issues/280","labels_url":"https://api.github.com/repos/ARMmbed/mbedtls/issues/280/labels{/name}","comments_url":"https://api.github.com/repos/ARMmbed/mbedtls/issues/280/comments","events_url":"https://api.github.com/repos/ARMmbed/mbedtls/issues/280/events","html_url":"https://github.com/ARMmbed/mbedtls/issues/280","id":105856588,"number":280,"title":"mbedtls_x509_crt_verify ignores max_pathlen on intermediate certificates","user":{"login":"NWilson","id":363415,"avatar_url":"https://avatars.githubusercontent.com/u/363415?v=3","gravatar_id":"","url":"https://api.github.com/users/NWilson","html_url":"https://github.com/NWilson","followers_url":"https://api.github.com/users/NWilson/followers","following_url":"https://api.github.com/users/NWilson/following{/other_user}","gists_url":"https://api.github.com/users/NWilson/gists{/gist_id}","starred_url":"https://api.github.com/users/NWilson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NWilson/subscriptions","organizations_url":"https://api.github.com/users/NWilson/orgs","repos_url":"https://api.github.com/users/NWilson/repos","events_url":"https://api.github.com/users/NWilson/events{/privacy}","received_events_url":"https://api.github.com/users/NWilson/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ARMmbed/mbedtls/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/ARMmbed/mbedtls/labels/scraped","name":"scraped","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-09-10T17:20:14Z","updated_at":"2015-10-15T15:07:07Z","closed_at":null,"body":"While writing unittests, I discovered that `mbedtls_x509_crt_verify` only enforces max_pathlen on the top (root) certificate. If it is set on any intermediate certificates, it doesn't appear to be enforced at all. (At least, that field isn't read anywhere I can see!)\r\n\r\nI'm not an authority on how the basic constraints are used in practice, but this seems surprising. Note that JSSE's PKIXCertPathBuilder does apply the max_pathlen constraint on intermediate certs, which is how I found the bug, by applying our existing Java tests to mbedTLS.\r\n\r\nHere are some certs generated using mbedTLS:\r\n\r\n    pkey/gen_key type=rsa rsa_keysize=2048 filename=cert11.key\r\n    pkey/gen_key type=rsa rsa_keysize=2048 filename=cert12.key\r\n    pkey/gen_key type=rsa rsa_keysize=2048 filename=cert13.key\r\n    pkey/gen_key type=rsa rsa_keysize=2048 filename=cert14.key\r\n    x509/cert_write selfsign=1 issuer_key=cert11.key\\\r\n      issuer_name='CN=Test root 2' is_ca=1 output_file=cert11.crt\r\n    x509/cert_write issuer_crt=cert11.crt issuer_key=cert11.key subject_key=cert12.key\\\r\n      is_ca=1 subject_name='CN=Test intermediate maxpath 1' max_pathlen=0 output_file=cert12.crt\r\n    x509/cert_write issuer_crt=cert12.crt issuer_key=cert12.key subject_key=cert13.key\\\r\n      is_ca=1 subject_name='CN=Test intermediate maxpath 2' output_file=cert13.crt\r\n    x509/cert_write issuer_crt=cert13.crt issuer_key=cert13.key subject_key=cert14.key\\\r\n      subject_name='CN=Test leaf invalid 3' output_file=cert14.crt\r\n\r\nIt gives you a path like this:\r\n\r\n    \"CN=Test root 2\"\r\n    -> \"CN=Test intermediate maxpath 1\", max_pathlen=0\r\n       -> \"CN=Test intermediate maxpath 2\"\r\n          -> \"CN=Test leaf invalid 3\"\r\n\r\nRunning the following pseudocode validates successfully (the code from our test harness is hard to extract):\r\n\r\n    chain = \"Test leaf invalid 3\" -> \"Test intermediate maxpath 2\" ->\r\n            \"Test intermediate maxpath 1\" -> NULL\r\n    root2 = \"Test root 2\" -> NULL\r\n    mbedtls_x509_crt_verify(chain, root2, ...)\r\n\r\nAs a fix, I would expect `x509_crt_check_parent` to take an `int pathlen` argument and check both the path length and CA bit of the certificate's basic constraints."},"comment":{"url":"https://api.github.com/repos/ARMmbed/mbedtls/issues/comments/148416139","html_url":"https://github.com/ARMmbed/mbedtls/issues/280#issuecomment-148416139","issue_url":"https://api.github.com/repos/ARMmbed/mbedtls/issues/280","id":148416139,"user":{"login":"rainierwolfcastle","id":1611833,"avatar_url":"https://avatars.githubusercontent.com/u/1611833?v=3","gravatar_id":"","url":"https://api.github.com/users/rainierwolfcastle","html_url":"https://github.com/rainierwolfcastle","followers_url":"https://api.github.com/users/rainierwolfcastle/followers","following_url":"https://api.github.com/users/rainierwolfcastle/following{/other_user}","gists_url":"https://api.github.com/users/rainierwolfcastle/gists{/gist_id}","starred_url":"https://api.github.com/users/rainierwolfcastle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rainierwolfcastle/subscriptions","organizations_url":"https://api.github.com/users/rainierwolfcastle/orgs","repos_url":"https://api.github.com/users/rainierwolfcastle/repos","events_url":"https://api.github.com/users/rainierwolfcastle/events{/privacy}","received_events_url":"https://api.github.com/users/rainierwolfcastle/received_events","type":"User","site_admin":false},"created_at":"2015-10-15T15:07:07Z","updated_at":"2015-10-15T15:07:07Z","body":"http://jira-dev0.cambridge.arm.com/browse/IOTSSL-472"}}