Possible Cert manager bug
-
Hello,
I've not posted here before so sorry in advance for any formatting mistakes and I'm also not well versed in the details of certificates but near as I can tell I've come across a possible bug in the cert manager Subject Alternative Name input validation process.
I'm not sure exactly when the change occurred but you used to be able to put partial-wildcard values in SAN entries when creating an internal cert. Recent attempts to do this:
have resulted in an error being thrown and no cert being created.
Near as I can tell partial-wildcard is in accordance with RFC 2818 as shown here:I did some quick googling and was unable to find an explanation of what changed or of anyone having similar issues. I didn't know exactly when the change happened so I didn't spend too much time searching once it became clear this was not a common issue.
This being an open source project I started with the code: First I tracked down where the error was coming from. The source was Line 301 in system_certmanager.php. I've included the relevant bit here:
as you can see this is checking for a valid hostname or a valid IP, but the case name of DNS seems to be misleading in this instance as to the best of my knowledge valid domains for DNS and certs do not have complete overlap with one another, with partial-wildcard appearing to be one of those instances.Continuing on my search I tracked down the is_hostname function as the IP function seemed unlikely to apply here. That function is located in Line 981 of utils.inc but it is effectively just a pass through to the is_domain function located just below is on Line 999. I've included the relevant bit that was rejecting my partial-wildcard SAN entries.
If you're familiar with regex you'll see this is only allowing pure wildcard sub-domain entries (e.g. *.example.com), I'm pretty sure this is also allowing multiple wildcards (e.g. *.*.example.com) which I don't think follows either DNS or certificate wildcard standards but I didn't look into that specifically.The obvious option to fix this would be to change the regex entry, but since I'm assuming that this is used in a variety of areas and often for DNS domain/wildcard validation altering it could cause more problems than it would solve for my admittedly somewhat edge case.
A better option may be to create a new function specifically for certificate wildcard validation with an appropriate regex. I believe this regex would be a good starting point:
`/^(?:(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9])?\*(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9])?\.)?(?:(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9])\.)*(?:[a-z_0-9]|[a-z_0-9][a-z_0-9\-]*[a-z_0-9\.])$/i`
but I don't work with PCRE much. There is an edge case here that passes through that may not technically qualify as a certificate standard wildcard: *.tld
Additionally there are blocks on valid certificate standard wildcards such as:
pre*-post.example.com
There's probably more that I've missed or am unaware of but those appear to be the most glaring. Both these instances can be accounted for with either a longer regex or other checks in the check function itself.So that bring me to now. I don't know if this was an intended change or if I'm misunderstanding the RFC or something else, but to me this seems to be a bug preventing valid SAN entries into internally created certificates. Just thought someone with a better working knowledge of the details and the internals should have a look at this.
-
It definitely would need to be a new validation function just for certificates.
It's possible in the past there was no validation on that field, and when it was added, it excluded that syntax.
Feel free to open an issue on https://redmine.pfsense.org with what you have found.