Error parsing certificate request. Extensions in the CSR marked critical can cause this error

Hi, I got a problem signing a csr via letsencrypt…

My domain is: wh-gbs.uni-ulm.de (but the certificate is for https://wh-gbs.uni-ulm.de:8443)

I ran this command: ./certbot-auto certonly --csr /var/lib/unifi/unifi_certificate.csr.pem

It produced this output: An unexpected error occurred:
The request message was malformed :: Error parsing certificate request. Extensions in the CSR marked critical can cause this error: https://github.com/letsencrypt/boulder/issues/565

My operating system is (include version): Debian 7

My web server is (include version): ?

My hosting provider, if applicable, is: ?

I can login to a root shell on my machine (yes or no, or I don’t know): yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel): no

Thanks a lot!

Could you provide the CSR (/var/lib/unifi/unifi_certificate.csr.pem)? As the message suggests, this is likely due to an issue with the CSR, so it would be hard to say more without the actual CSR in question and/or more details on how it was generated.

(CSRs do not contain private keys or any other information that Let’s Encrypt does not make public anyway.)

Sure, here it is.

-----BEGIN CERTIFICATE REQUEST-----
MIIC1TCCAb0CAQAwgZExFDASBgNVBAYTC0RldXRzY2hsYW5kMRswGQYDVQQIExJCYWRlbi1XdWVy
dHRlbWJlcmcxDDAKBgNVBAcTA1VsbTEWMBQGA1UEChMNRURWLVdITS1HVVRFTjEaMBgGA1UECxMR
d2gtZ2JzLnVuaS11bG0uZGUxGjAYBgNVBAMTEXdoLWdicy51bmktdWxtLmRlMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyXEt/ylonBowpgomLWYWkox/6Fw7sR8XoLgHsXchQIuRBw9+
bMBDs4kpISQ4jntTrb/Up+JU3Ov3Zh+wIYezGfieEpjervAzz6ASxT3XG5JRQSxP86sxH5DSyjwI
v0KKaAPxtJF3zlD7FcUse4Crjji1Jf0jWOJ7kT9bqyajp8cTgymNFCKI0s5gEPK65Tjso5k/074P
WAGBGmIMB1/qWUYd0EnI+OShGJzp2HdbfrMtG56GBS2Sode8ThX0x6dVX7byPR7hIm0pznx5Iwwj
QVP5ldJipWLAhalk9TZUa5dTWiH2Tp4Uwl/KNyqLZqc3mO5RnsbU7q71TcT0esNMhQIDAQABMA0G
CSqGSIb3DQEBCwUAA4IBAQAfUvxrbQPVCO+0BGJ9LiQIF/R9MSUjVA8E4QpjqsYUBIsQWjbpP/xt
hRTaJx8Bwm7TqBA+feXUWwqjX/v9SILKX/ziDsjna8xqKp0v3bYLyJmBL6YegfHVjLiBBMFdqXz5
2pLghKsBCya1ojpUKg5qiV+SXFAWX4iJbiAqnTUZiC2MtV7a4wEW4UMnHFDcpO16Qt9BejP8TBFy
HFvBayUqiXxGjk7zJFrLFroVNY3CFclNo6KAyTEXJahAUCQIotcW/7t/taC0k6yIgE2ewqwB/oEa
Avzsngg+ilfQGtl++BR87XuNIcbufI2xc8UGLwpI7tU2cavEX0k5eOFKZiIT
-----END CERTIFICATE REQUEST-----

Unfortunately, the error I’m getting when I try to parse that CSR is not particularly useful (“asn1: syntax error: sequence truncated”, use this to reproduce).

My best guess would be that it’s due to the “C=Deutschland” field in your subject; the country field should be a two-letter string (DE for Germany). In fact, trying to generate a CSR with that subject fails with my version of openssl (with “140735108980816:error:0D07A097:asn1 encoding routines:ASN1_mbstring_ncopy:string too long:a_mbstr.c:158:maxsize=2”), though it will happily parse the CSR. I suspect the code used by Let’s Encrypt might be stricter here and that’s the issue.

If the software you’re using to generate the CSR allows you to get rid of all subject fields other than Common Name (CN), I’d recommend you do that, as Let’s Encrypt would remove those from the signed certificate anyway. If that’s not possible, “DE” should be an acceptable value.

Thank you for your reply!

I now tried it with

-----BEGIN CERTIFICATE REQUEST-----
MIICzDCCAbQCAQAwgYgxCzAJBgNVBAYTAkRFMRswGQYDVQQIExJCYXRlbi1XdWVydHRlbWJlcmcx
DDAKBgNVBAcTA1VsbTEWMBQGA1UEChMNRURWLVdITS1HVVRFTjEaMBgGA1UECxMRd2gtZ2JzLnVu
aS11bG0uZGUxGjAYBgNVBAMTEXdoLWdicy51bmktdWxtLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAtdbgGd7ZIN+CCJ9mpJpF/AR15xlFw/UQ1rO5/i+GwKNUv/s3mDsNJJMakbVd
UPYej1mbPI/8EfekKhNOxc2auwNaXtVhFSPpOujPLXdrmsi5U2IoFwXdDbTNtlJt4KaSHEq5cj2i
Tm/TgKeyJhJbwieupoEGWzmwk2g6VLLny9M7Jm4UW6ZVWZAfBFKQU5udVJtBgwKemJu0XzozO2fv
2mF+K5j4ZVAAHX/JPq64M1fGFQC+gVakzvmTEJzNPMixJusKubNgtvD8GUXortWkrQf2gF05Oysw
J3pNLMH/WMwvqm9QIGgmrZRKxVj+Xv52B9lwDY+HrBfCemqk6NOW6wIDAQABMA0GCSqGSIb3DQEB
CwUAA4IBAQCvDXHDOd0n7UKOALfETpJYyyKwdbrFx8KcVZDID8n+Ur+PyYrd6XXGEjmyLKpNfNjc
tkQ0jKWZ4rt2jSFrmk3O9VAor/phtadEYfafDrmu7o3rQ/C88g/V/fitwWpWMKdgOqElQ2Mi2T6q
mcTv4G0KOSUuqK+HNy6RCdG7dUdUx4tfzAZ3P7ALezkt2spI025e3CeOhArjsViaCeVfUVQeswsw
e2fgFmiOTgKsCyN9MW+EznWbwY5GomNHRZcgcJjon5Mne+QFlQJe9faHeZMx2TRSg206lclVAeGc
SmzpRWf/wQyYuHoahj1MaYbi9iLn/ZEeJfae1r7x7Om8wRv1
-----END CERTIFICATE REQUEST-----

but it did fail again. Any other options? :frowning:

It seems like even OpenSSL can't handle that CSR properly (I didn't think that was actually possible :smile:) . Trying to parse it (with openssl asn1parse -inform pem -in your.csr) results in this output:

    0:d=0  hl=4 l= 716 cons: SEQUENCE
    4:d=1  hl=4 l= 436 cons: SEQUENCE
    8:d=2  hl=2 l=   1 prim: INTEGER           :00
   11:d=2  hl=3 l= 136 cons: SEQUENCE
   14:d=3  hl=2 l=  11 cons: SET
   16:d=4  hl=2 l=   9 cons: SEQUENCE
   18:d=5  hl=2 l=   3 prim: OBJECT            :countryName
   23:d=5  hl=2 l=   2 prim: PRINTABLESTRING   :DE
   27:d=3  hl=2 l=  27 cons: SET
   29:d=4  hl=2 l=  25 cons: SEQUENCE
   31:d=5  hl=2 l=   3 prim: OBJECT            :stateOrProvinceName
   36:d=5  hl=2 l=  18 prim: PRINTABLESTRING   :Baten-Wuerttemberg
   56:d=3  hl=2 l=  12 cons: SET
   58:d=4  hl=2 l=  10 cons: SEQUENCE
   60:d=5  hl=2 l=   3 prim: OBJECT            :localityName
   65:d=5  hl=2 l=   3 prim: PRINTABLESTRING   :Ulm
   70:d=3  hl=2 l=  22 cons: SET
   72:d=4  hl=2 l=  20 cons: SEQUENCE
   74:d=5  hl=2 l=   3 prim: OBJECT            :organizationName
   79:d=5  hl=2 l=  13 prim: PRINTABLESTRING   :EDV-WHM-GUTEN
   94:d=3  hl=2 l=  26 cons: SET
   96:d=4  hl=2 l=  24 cons: SEQUENCE
   98:d=5  hl=2 l=   3 prim: OBJECT            :organizationalUnitName
  103:d=5  hl=2 l=  17 prim: PRINTABLESTRING   :wh-gbs.uni-ulm.de
  122:d=3  hl=2 l=  26 cons: SET
  124:d=4  hl=2 l=  24 cons: SEQUENCE
  126:d=5  hl=2 l=   3 prim: OBJECT            :commonName
  131:d=5  hl=2 l=  17 prim: PRINTABLESTRING   :wh-gbs.uni-ulm.de
  150:d=2  hl=4 l= 290 cons: SEQUENCE
  154:d=3  hl=2 l=  13 cons: SEQUENCE
  156:d=4  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  167:d=4  hl=2 l=   0 prim: NULL
  169:d=3  hl=4 l= 271 prim: BIT STRING
  444:d=1  hl=2 l=  13 cons: SEQUENCE
  446:d=2  hl=2 l=   9 prim: OBJECT            :sha256WithRSAEncryption
  457:d=2  hl=2 l=   0 prim: NULL
  459:d=1  hl=4 l= 257 prim: BIT STRING
Error in encoding
140735108980816:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:asn1_lib.c:147:

My search for this particular message turned up this old post from the OpenSSL mailing list. It appears that the CSR is corrupted in some way. The post contains some ideas on what could be causing this:

This is exactly the symptom of a file being treated as text
when it isn't, in particular by transfer protocols like (S)FTP
and maybe HTTP, or other tools like ZIP. A Unix-style "newline"
(0A) gets converted to a DOS/Win/Inet style CR LF (0D 0A).
Similarly C internally uses one byte '\n' newline, but ON
DOS/Win
textfiles use CRLF, so fopen/fwrite/etc. in text mode
converts 0A to 0D0A on output, and 0D0A to 0A on input.
If you are running your C program on DOS/Win, you need
to open the file in binary mode i.e. fopen (foo, "wb").
(But if you're running on cygwin on Win, it's more
complicated; cygwin tries to bridge the gap between Unix-format
and Win-format, AFAIK mostly by 'mount' options.)
Even on other platforms it is good to specify this for
clarity/documentation/robustness even if not strictly needed.
As a check it should be 916=0x394 bytes.

Alternatively, if you want a text file, which is usually
more portable and human recognizable: get the cert data,
base64 it and add the -----BEGIN/END lines to make it
PEM format, and write (and read) that as text.

If you could share more details about how this CSR is generated, transmitted, etc., we might be able to figure this out.

Hello @allrik,

Your CSR doesn’t contain any SAN and it MUST, also your CSR format is PEM and it should be DER.

An example to create a CSR using your existing key.

openssl req -sha256 -nodes -new -key your_existing_key_for_wh-gbs.uni-ulm.de.key -out wh-gbs.uni-ulm.de.der.csr -outform der -subj "/CN=wh-gbs.uni-ulm.de" -reqexts SAN -config <(echo -e "[req]\ndistinguished_name=wh-gbs.uni-ulm.de\n[wh-gbs.uni-ulm.de]\n[SAN]\nsubjectAltName=DNS:wh-gbs.uni-ulm.de")

An example to create a CSR and also a new 4096 bits private key:

openssl req -sha256 -nodes -new -newkey 4096 -keyout new_key_for_wh-gbs.uni-ulm.de.pem.key -out wh-gbs.uni-ulm.de.der.csr -outform der -subj "/CN=wh-gbs.uni-ulm.de" -reqexts SAN -config <(echo -e "[req]\ndistinguished_name=wh-gbs.uni-ulm.de\n[wh-gbs.uni-ulm.de]\n[SAN]\nsubjectAltName=DNS:wh-gbs.uni-ulm.de")

If you want to check the new CSR in DER format:

openssl req -in wh-gbs.uni-ulm.de.der.csr -inform der -text

I hope this helps.

Cheers,
sahsanu

While all certificates issued by Let's Encrypt (or any public CA) must have all domains appearing on the certificate in a SAN field, it's not strictly necessary for the CSR to contain the SAN extension, and the CA server will use the CN field as a kind of fallback. (Of course that'll only work with certificates for a single FQDN.)

You'd think so, with the certbot docs saying as much (and mentioning that you need a SAN field as well :smile:), but apparently it'll happily convert from PEM to DER before submitting the certificates. Will look into filing a doc issue for this.

(In case anyone's curious, this is the CSR I just used successfully to get a certificate from staging via certbot and --csr.)

-----BEGIN CERTIFICATE REQUEST-----
MIICyDCCAbACAQAwgYIxCzAJBgNVBAYTAkRFMRswGQYDVQQIDBJCYWRlbi1XdWVy
dHRlbWJlcmcxDDAKBgNVBAcMA1VsbTEWMBQGA1UECgwNRURWLVdITS1HVVRFTjEX
MBUGA1UECwwOZGVidWcubGUucGYudmMxFzAVBgNVBAMMDmRlYnVnLmxlLnBmLnZj
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy9OyGgapol3Cy6mpKV0P
pUliTnraSlOj4KqPrR6apG10sE5Zc/XyObYrQDJIUwmCzd/b7b1ClGcd7L/DAUsN
zQwszUox2CKeJd8qs3DseF8BenlMMDCY1WHDyEqK26sSYnONC01xkqUZ+B+pqefI
hRLBtEOrfRbX0DEM6HIqpHCaTQNJe79Dr6mYhMwlwAIX4m+oV80zO4yNoBlO/wWA
Vhs4pyhGn9gYSgxOI6ApUVwhRwN3U2qvd0UZ+JOWddcOiEvEjuOBw0ZVDitqs7dx
CzmiUfZM87w6VdTl4Zo6gbbqzXy08cveUNzAkgmqMr6giw84KZM+/lBiBcysgubA
wQIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAAUBB1p/eoCGyUoqnhsagtytkjgI
pKQaJy0t+rXmEn8xD+nGWYT5q7aP+/hkMx7Im8q8RL5Ej0+ItVR6s5mpIMRYE5Ai
9Y1qr/8k/FuqARQNmUMwE1vySrcT0Y0NBgbVin1bV1Dd51ICCzw50A9ko3jeV98P
llm0P6p05wPdXcDwtusPF1XRcSvXkj3Mm7KCm7vhAQ/SVX/RfkKnMIc3ox0Va6do
x4bNzvzoHQ0n7vke0uZw4c9atPfKnniD3o2qztsApsK9oJb2lguQQyPKx9NuyHPp
+Xp2Rgz9RWi31QvvayM1gkDHxnamOxWdyXI0F4bttZFc7N9b+90E8HwLE5M=
-----END CERTIFICATE REQUEST-----

@pfg, thanks for sharing the info, I thought that was a MUST (SAN and DER) and not a... well it is a must but our client and boulder are smart enough to fix it for you ;).

Alright, here’s the whole story.

I want to add a trusted certificate to a “unifi controller system”. To do so, I followed the instructions on https://help.ubnt.com/hc/en-us/articles/212500127-UniFi-SSL-certificate-error-upon-opening-controller-page.

Instead of buying a ssl certificate, I decided to use Let’s Encrypt. But apparently, the .pem (and .der) files created by the ace.jar program cannot be parsed properly.

I can post the .der too, if it would be of any help.

Have you tried using the DER file rather than the PEM? With any luck, the corruption is specific to the PEM and things will work fine when using the other file.

Another option would be to figure out where exactly this tool stores the private key, export that and use it to generate a new, non-corrupted CSR (using something like openssl req -new -sha256 -key privkey.pem -out wh-gbs.uni-ulm.de.csr -subj "/CN=wh-gbs.uni-ulm.de") which you’ll be able to submit with certbot. No idea where to start looking, though.

I tried the .der but it didn’t matter.

I consulted the support, explained them the error and asked them for the location of the private key file. But it seems, that it will take some time to respond to my question.

I’ll give further informations about this as soon as I receive a message.

Thank you so far!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.