How to create a single line x509 certificate that can be parsed by OpenSSL commandline tool
Solution 1
I wanted to prepare a single line x509 Certificate string which can be parsed by OpenSSL command-line utility...
-----BEGIN CERTIFICATE----- MIICZjCCAc+gAwIBAgIUUnH/2DwpRMsAkWtkE1jccev9FtwwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA5MTAxMTE0NDRaFw0yNDA5MDgxMTE0NDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ1Z9/FRGmzCCB1F6txz2JMpHy+WNgvtPfyRQh6vjC3g7mcDCHOPORT9vg/9ye2smr0gcPnkJwzA6ftaw0fWvHCXtVcb+cFs7xL3JbC7HexJQWFT4fcQ6KhckTfn8qvkHdSMEX1y6+sFKFgftUgAtWmhRNnYTPaFEjFEjc8MVeM9AgMBAAGjUzBRMB0GA1UdDgQWBBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAfBgNVHSMEGDAWgBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAAlemG77/vf1bvGlADLc+/sPeZ6ppuMz/y3qVRqfFJ+78RMTSrLWSPGUyDFauTAvf7fNj+D/Pt+OrMue+AK+PCi0JxIWxIIv+XJqoSxHTwoBqujn93Xs+vm03hED1aoCs/s7rSsckAR/OjkMtQDoVer/F0izuE7ebAh4IFYXYTUD -----END CERTIFICATE-----
PEM encoding is detailed in RFC 1421, Privacy Enhancement for Internet Electronic Mail. Among the specifications, it says:
- Encapsulation boundaries are on their own lines,
- The message is Base64 encoded,
- Lines are limited to 64 characters,
- End-of-line is CR ('\r') and LF ('\n')
OpenSSL has never handled ill-formed certificates well. It has been that way as long as I can remember. A fair number of libraries don't handle EOL well. They choke on CRLF line endings as well.
In contrast, the OpenSSH file format RFC, RFC 4716, say an implementation must handle an eol that is CR, LF, or CRLF. The RFC also says certificates and keys should be written using native platform conventions, so you will see all three in the field.
Solution 2
You can do some bash dark magic to get what you want. If you see your single_line_publickey.cer
, it has the \n
chars too that show up when you echo. Which means you can force echo to print them as newlines.
If you try something like:
echo -ne $(cat single_line_publickey.cer) | openssl x509 -noout -text
It should work out just fine.
anoop.babu
Updated on June 05, 2022Comments
-
anoop.babu almost 2 years
I wanted to prepare a single line x509 Certificate string which can be parsed by OpenSSL command-line utility.
I created a private key using OpenSSL command-line utility,
openssl genrsa -out privatekey.pem 1024
And then created a public key,
openssl req -new -x509 -key privatekey.pem -out publickey.cer -days 1825
The contents of the certificate is,
$ openssl x509 -in publickey.cer -----BEGIN CERTIFICATE----- MIICZjCCAc+gAwIBAgIUUnH/2DwpRMsAkWtkE1jccev9FtwwDQYJKoZIhvcNAQEL BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA5MTAxMTE0NDRaFw0yNDA5 MDgxMTE0NDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEB BQADgY0AMIGJAoGBAJ1Z9/FRGmzCCB1F6txz2JMpHy+WNgvtPfyRQh6vjC3g7mcD CHOPORT9vg/9ye2smr0gcPnkJwzA6ftaw0fWvHCXtVcb+cFs7xL3JbC7HexJQWFT 4fcQ6KhckTfn8qvkHdSMEX1y6+sFKFgftUgAtWmhRNnYTPaFEjFEjc8MVeM9AgMB AAGjUzBRMB0GA1UdDgQWBBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAfBgNVHSMEGDAW gBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 DQEBCwUAA4GBAAlemG77/vf1bvGlADLc+/sPeZ6ppuMz/y3qVRqfFJ+78RMTSrLW SPGUyDFauTAvf7fNj+D/Pt+OrMue+AK+PCi0JxIWxIIv+XJqoSxHTwoBqujn93Xs +vm03hED1aoCs/s7rSsckAR/OjkMtQDoVer/F0izuE7ebAh4IFYXYTUD -----END CERTIFICATE-----
I then converted the newline symbols to
\n
using below awk command,$ awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' publickey.cer | tee single_line_publickey.cer
The transformed certificate is,
-----BEGIN CERTIFICATE-----\nMIICZjCCAc+gAwIBAgIUUnH/2DwpRMsAkWtkE1jccev9FtwwDQYJKoZIhvcNAQEL\nBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\nGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA5MTAxMTE0NDRaFw0yNDA5\nMDgxMTE0NDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw\nHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEB\nBQADgY0AMIGJAoGBAJ1Z9/FRGmzCCB1F6txz2JMpHy+WNgvtPfyRQh6vjC3g7mcD\nCHOPORT9vg/9ye2smr0gcPnkJwzA6ftaw0fWvHCXtVcb+cFs7xL3JbC7HexJQWFT\n4fcQ6KhckTfn8qvkHdSMEX1y6+sFKFgftUgAtWmhRNnYTPaFEjFEjc8MVeM9AgMB\nAAGjUzBRMB0GA1UdDgQWBBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAfBgNVHSMEGDAW\ngBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\nDQEBCwUAA4GBAAlemG77/vf1bvGlADLc+/sPeZ6ppuMz/y3qVRqfFJ+78RMTSrLW\nSPGUyDFauTAvf7fNj+D/Pt+OrMue+AK+PCi0JxIWxIIv+XJqoSxHTwoBqujn93Xs\n+vm03hED1aoCs/s7rSsckAR/OjkMtQDoVer/F0izuE7ebAh4IFYXYTUD\n-----END CERTIFICATE-----\n
But OpenSSL command line tool is failing to parse this single line certificate,
$ openssl x509 -in single_line_publickey.cer unable to load certificate 140671947637184:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: TRUSTED CERTIFICATE
Looks like it is not able to find the encapsulation boundaries
-----BEGIN CERTIFICATE-----
and-----END CERTIFICATE-----
. From the RFC7468: Textual Encodings of PKIX, PKCS, and CMS Structures standard, I found thatBEGIN CERTIFICATE
andEND CERTIFICATE
labels needs to be separated by newline. Here looks like\n
is not working. I tried\r\n
to simulate CR+LF but still I had the same problem.What I observed is the OpenSSL command-line tool is able to parse the certificate when I keep
BEGIN CERTIFICATE
andEND CERTIFICATE
labels in newlines. The certificate file is,$ cat multi_line_publickey.cer -----BEGIN CERTIFICATE----- MIICZjCCAc+gAwIBAgIUUnH/2DwpRMsAkWtkE1jccev9FtwwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTA5MTAxMTE0NDRaFw0yNDA5MDgxMTE0NDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ1Z9/FRGmzCCB1F6txz2JMpHy+WNgvtPfyRQh6vjC3g7mcDCHOPORT9vg/9ye2smr0gcPnkJwzA6ftaw0fWvHCXtVcb+cFs7xL3JbC7HexJQWFT4fcQ6KhckTfn8qvkHdSMEX1y6+sFKFgftUgAtWmhRNnYTPaFEjFEjc8MVeM9AgMBAAGjUzBRMB0GA1UdDgQWBBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAfBgNVHSMEGDAWgBQ+mp9v3pEw5Oy4FiE3Go9vs/56zzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAAlemG77/vf1bvGlADLc+/sPeZ6ppuMz/y3qVRqfFJ+78RMTSrLWSPGUyDFauTAvf7fNj+D/Pt+OrMue+AK+PCi0JxIWxIIv+XJqoSxHTwoBqujn93Xs+vm03hED1aoCs/s7rSsckAR/OjkMtQDoVer/F0izuE7ebAh4IFYXYTUD -----END CERTIFICATE-----
And the OpenSSL tool is able to parse it,
$ openssl x509 -in multi_line_publickey.cer -noout -subject subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
But here I have three lines. How to prepare this certificate as one line in a way that OpenSSL Command Line utility can parse it?
-
CristiFati over 4 yearsWhat's the reasoning behind the "single line"?
-
anoop.babu over 4 yearsI have a web front-end which takes only strings as input. I wanted the users to pass certificates through this front-end. The frontend then passes this single line certificate as a parameter to openstack heat stack creation. The front end has pretty basic Javascript support with very limited modules.
-
bartonjs over 4 yearsSounds like you should just transport the base64, then write the PEM header and footer yourself.
-
-
anoop.babu over 4 yearsOpenSSL CLI is not recognizing CR ('\r') or LF ('\n'). I tried,
-----BEGIN CERTIFICATE-----\rBASE64Certificate\r-----END CERTIFICATE-----
but OpenSSL CLI is not able to recognize the newline. Not sure OpenSSL treats which symbol as a newline. I am using Ubuntu 18.04.3 LTS. -
Jakub Jabłoński almost 2 yearsFrom what I saw it will also replace also values like "\w" into "w" which breaks pem file