Incorrect wildcard certificate parsing during creation
Description
Problem/Justification
Impact
Activity
Relevant forum post with a crypto.py patch:
https://www.truenas.com/community/threads/acme-cert-approval.87827/
No problem.
One note to make reproducing the issue easier: the error occurs prior to actually checking the Route53 credentials, so it can be tested with a dummy authenticator.
Thank you for @John C .
I have moved this ticket in to our queue to review.
An engineering representative will update with any further questions or details in the near future.
I believe I have found the issue. I modified crypto.py line 1377 to include the failing domain name with the error message (lines with context below):
1374 if '*' in domain and not domain.startswith('*.'):
1375 verrors.add(
1376 'acme_create.dns_mapping',
1377 f'Wildcards must be at the start of domain name followed by a period: {domain}'
1378 )
After restarting middlewared and rerunning the process, I get the following error message:
[EINVAL] acme_create.dns_mapping: Wildcards must be at the start of domain name followed by a period: DNS:*.mydomain.net
It looks like the code has appended the "DNS:" SAN identifier, which is causing wildcard validation to always fail since it can never "startswith('*.')"
As an aside, I might suggest that including the failing variable with these error messages could be very helpful in troubleshooting.
The "create ACME certificate" process incorrectly parses wildcard certificates and refuses to validate.
Steps to reproduce:
Create a new CSR under the "OpenVPN Server Certificate" profile. Select "*.mydomain.com" as your SAN, and leave CN blank
Attempt to "Create ACME Certificate"
Fill in name, agree to TOS, select authenticator, submit
See error.
FAILED
[EINVAL] acme_create.dns_mapping: Wildcards must be at the start of domain name followed by a period
The full error trace is as follows:
Error: Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/middlewared/job.py", line 367, in run
await self.future
File "/usr/local/lib/python3.9/site-packages/middlewared/job.py", line 403, in __run_body
rv = await self.method(*([self] + args))
File "/usr/local/lib/python3.9/site-packages/middlewared/schema.py", line 975, in nf
return await f(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/middlewared/plugins/crypto.py", line 1709, in do_create
data = await self.middleware.run_in_thread(
File "/usr/local/lib/python3.9/site-packages/middlewared/utils/run_in_thread.py", line 10, in run_in_thread
return await self.loop.run_in_executor(self.run_in_thread_executor, functools.partial(method, *args, **kwargs))
File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.9/site-packages/middlewared/schema.py", line 979, in nf
return f(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/middlewared/plugins/crypto.py", line 1757, in __create_acme_certificate
final_order = self.acme_issue_certificate(job, 25, data, csr_data)
File "/usr/local/lib/python3.9/site-packages/middlewared/plugins/crypto.py", line 1387, in acme_issue_certificate
raise verrors
middlewared.service_exception.ValidationErrors: [EINVAL] acme_create.dns_mapping: Wildcards must be at the start of domain name followed by a period