go-acme / lego

Let's Encrypt/ACME client and library written in Go
https://go-acme.github.io/lego/
MIT License
8.02k stars 1.02k forks source link

--csr parser cannot handle CSRs with a header that looks like "-----BEGIN NEW CERTIFICATE REQUEST-----" #1422

Closed waweber closed 3 years ago

waweber commented 3 years ago

What did you expect to see?

The program parses and uses the provided certificate signing request.

What did you see instead?

The program fails with the following error message:

2021/06/04 16:09:59 Could not obtain certificates:
        asn1: structure error: tags don't match (16 vs {class:0 tag:13 length:45 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} certificateRequest @2

Steps to reproduce

  1. Use gnutls's certtool utility to generate a CSR. I used certtool --generate-request --load-privkey test.key --no-crq-ext --outfile test.crq and then removed the extra non-request info from the file.
  2. Attempt to use the request with lego, observe the error message
  3. Edit the PEM headers to not include the word "NEW"
  4. Attempt to use the request with lego, see that it works this time

Details

Version of lego ```console $ lego --version lego version v4.3.1 linux/amd64 ```
Logs ```console 2021/06/04 16:09:59 No key found for account test@test.com. Generating a P256 key. 2021/06/04 16:09:59 Saved key to /.lego/accounts/acme-staging-v02.api.letsencrypt.org/test@test.com/keys/test@test.com.key 2021/06/04 16:09:59 [INFO] acme: Registering account for test@test.com !!!! HEADS UP !!!! Your account credentials have been saved in your Let's Encrypt configuration directory at "/.lego/accounts". You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained from Let's Encrypt so making regular backups of this folder is ideal. 2021/06/04 16:09:59 Could not obtain certificates: asn1: structure error: tags don't match (16 vs {class:0 tag:13 length:45 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue: tag: stringType:0 timeType:0 set:false omitEmpty:false} certificateRequest @2 ```
waweber commented 3 years ago

Here is the CSR used. Some utilities (e.g. gnutls, Microsoft) have headers with the word "NEW" in them, others (openssl) do not. test2.txt

ldez commented 3 years ago

As you observed, it's related to your CRS type NEW CERTIFICATE REQUEST.

In lego, we detect only the standard type CERTIFICATE REQUEST.

I found little information on this type:

The label "NEW CERTIFICATE REQUEST" is also in wide use. Generators conforming to this document MUST generate "CERTIFICATE REQUEST" labels. Parsers MAY treat "NEW CERTIFICATE REQUEST" as equivalent to "CERTIFICATE REQUEST".

https://datatracker.ietf.org/doc/html/rfc7468#section-7

Then certtool, or your version of certtool, seems to not respect RFC 7468. (MUST)

If we follow the RFC: generators must use CERTIFICATE REQUEST but parsers can see NEW CERTIFICATE REQUEST as CERTIFICATE REQUEST

Then as we are parsing the CSR, we can support this type.