Making SSL tests all pass for Phoenix + Let's Encrypt

In case anyone comes across this post like I did, and wonders what the minimal config would be as of July 2020 to get an A+ on both SSL Labs and ImmuniwebSSL (htbridge) using a Let’s Encrypt certificate, here it is:

 https: [
    port: System.get_env("HTTPS_PORT"),
    keyfile: System.get_env("TLS_KEY_FILE"),
    certfile: System.get_env("TLS_CERT_FILE"),
    dhfile: "/etc/ssl/dhparam.pem",
    cipher_suite: :strong,
    client_renegotiation: false,
    transport_options: [socket_opts: [:inet6]]
  ]

The TLS_KEY_FILE being the privkey.pem and the TLS_CERT_FILE the fullchain.pem that are generated by certbot.

1 Like

Hi, I have tried most of these but i still get this error here:

setting up SSL correctly on an erlang/ elixir server - Stack Overflow.

Any help please.

1 Like

openssl s_client -connect paperlesssolutionsltd.com.ng:8443

gives:

λ openssl s_client -connect paperlesssolutionsltd.com.ng:8443
CONNECTED(000001B8)
depth=0 CN = www.paperlesssolutionsltd.com.ng
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = www.paperlesssolutionsltd.com.ng
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:CN = www.paperlesssolutionsltd.com.ng
   i:C = US, O = Let's Encrypt, CN = R3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGiTCCBXGgAwIBAgISBJEvL3uT8YZMvG0HGiFugEe9MA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTAyMDUxMTAyNTNaFw0yMTA1MDYxMTAyNTNaMCsxKTAnBgNVBAMT
IHd3dy5wYXBlcmxlc3Nzb2x1dGlvbnNsdGQuY29tLm5nMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEA/pJFz2InXO8UiTggt3ThP3tiIiipVWfGzteHLI7S
6VhJRjv+/W+Mcu5EXXdVum/1ZTe6E1Ko/i0qrqvwvBNhuCCI0EnK5H299jAICt0/
JnSTDp1JDz2k7Nm0MIiIEZfvaIRXuoopR4iM91svIku6D3rzZ+OwoTUvZXvEscky
pBJc+fVUJvfnGhDwLqLXvXyzXqapKphrGxAAHD2GzxOEGo33N3N97m18qbyeG+hA
UOcIRVfLP2jPrWDolKchtM9AyUj4lAiMsPU7Jc+Rt6AnMyTr1hsXduUCNNn3i/h/
s7Kg3xIo++izDhC9Qj5Pedgy2pbZ6z4ZMKQ9UsPGHJ6X3BmT7lgX796nGeaySC+L
HqwBtoAlFMwE96i4yNEhFlQuM5roNhlVc4Vv5yyvtVNtxoYMGpsrJ0upAWHmJ+0J
UJVlCcemng+7eSfNBrdZ1XvSvHxSqPEOmmn7gqdBzad3PKj9inkibtmSqt9gNOGR
RzI0DZK8CE52LUrqBNrUsifmE8uw/FQ11+7eahL65b0nNj0wreExONb0aQEYOR1/
/4YXK742K3l4hZn5r/sIuzgYFFIZwIKckYi821EHE3ugwPG3asBXBaZ9vSZ5CFt+
vAzedpTNV3nN/55KlqHhll98FF6JQAFNsGRY5kcWC2SVv/KRIczrfVm2R/USVXOX
iWcCAwEAAaOCAp4wggKaMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUnReY/FdZAB8x
NTbPm+A1kBqwgAYwHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYI
KwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5vcmcw
IgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9yZy8wbAYDVR0RBGUwY4Ih
bWFpbC5wYXBlcmxlc3Nzb2x1dGlvbnNsdGQuY29tLm5nghxwYXBlcmxlc3Nzb2x1
dGlvbnNsdGQuY29tLm5ngiB3d3cucGFwZXJsZXNzc29sdXRpb25zbHRkLmNvbS5u
ZzBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUF
BwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCCAQYGCisGAQQB1nkCBAIE
gfcEgfQA8gB3AESUZS6w7s6vxEAH2Kj+KMDa5oK+2MsxtT/TM5a1toGoAAABd3IS
1lkAAAQDAEgwRgIhAODIbmogAX5fAQ8pKfAlEbZMFJYqksp3iInqCepNymN3AiEA
zdJOaSOHe2A78x9thbdf8WCndV/rPVLw0tME6hzpW6QAdwD2XJQv0XcwIhRUGAgw
lFaO400TGTO/3wwvIAvMTvFk4wAAAXdyEtZZAAAEAwBIMEYCIQD8FomGRVUtXy5e
XByxhM383UUKt+35L217GUAZ7FUgjwIhANrw1gax+fOWp6qRLpBFDz7S3D9SL5RA
KHWQYOJmM8ciMA0GCSqGSIb3DQEBCwUAA4IBAQCU1EzS7Lt1hAZ4+WtPisM+B8R/
RKJ72PTE+E8dHB+SlNeFoJGpj5Z4FO9bp69fdOcG6D2NxJBDVc1VCR7Gx20Sxngs
wm9CexnRlsRaWuXLTJoxn/QoQ+kEWRIIYVXaa7MmlkljpTGLHkBHpwOT7/rtmgpB
geUmgjia+hlah2jltYP6QwhXriOXuhUU/DltAm8S2yS8ITtIIe/0yCXy3CilY7Um
0qtQW5lDecCqZtYlBGwNtoJbAWJrAnlMavdlM6Z1ziRh33BiPQXKNFfBk2P9kBmA
Yud7vIIOK5SB5KhZ45WWm2Tmu2ZsHPu+iaDR+rQB68BOi1aQY0P6+JbY6V1j
-----END CERTIFICATE-----
subject=CN = www.paperlesssolutionsltd.com.ng

issuer=C = US, O = Let's Encrypt, CN = R3

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2489 bytes and written 410 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 4096 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 21 (unable to verify the first certificate)
---

HTTP/1.1 400 Bad Request
connection: close
content-type: text/plain
content-length: 19

Invalid line:


closed

c:\Projects
λ

The intermediate certs are not being sent. Please is there aa config needed for erlang ssl to send the intermediate certs?

I have tried both Elli and Ace servers

The cert.pem file from Let’s Encrypt contains only the end certificate. You should also have a file called fullchain.pem containing the end certificate and any associated intermediates. If you point the :certfile option to the fullchain.pem file, your server should send those intermediates in the handshake.

(There are some more subtleties, but in most cases this should be enough to get going)

I have obtained the full-chain.pem by combining both my cert.pem and the intermediate cert from lets-encrypt.

The result is still the same.

Can you share the contents of your cert.pem file?

Unlike many other servers, Erlang/OTP’s ssl does not blindly copy the contents of the file into the TLS handshake. Instead, it inspects the end certificate and then looks for its issuer certificate (recursively) using the available CA certificates. If you specify the :cacertfile/:cacerts option, then it will look for the intermediates there, rather than in the file :certfile points to. Of you don’t, then it falls back to looking in :certfile for the intermediates.

It sounds like in your case this process does not result in a valid issuer for your end certificate, so none is sent in the handshake. The question is why exactly…

Could it be the line break between the two certificates is not a newline, but maybe CR or a space? Try opening the file and adding one or more new lines just before “-----BEGIN CERTIFICATE-----”.

I have adjusted like you suggested.

-----BEGIN CERTIFICATE-----
MIIGiTCCBXGgAwIBAgISBJEvL3uT8YZMvG0HGiFugEe9MA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTAyMDUxMTAyNTNaFw0yMTA1MDYxMTAyNTNaMCsxKTAnBgNVBAMT
IHd3dy5wYXBlcmxlc3Nzb2x1dGlvbnNsdGQuY29tLm5nMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEA/pJFz2InXO8UiTggt3ThP3tiIiipVWfGzteHLI7S
6VhJRjv+/W+Mcu5EXXdVum/1ZTe6E1Ko/i0qrqvwvBNhuCCI0EnK5H299jAICt0/
JnSTDp1JDz2k7Nm0MIiIEZfvaIRXuoopR4iM91svIku6D3rzZ+OwoTUvZXvEscky
pBJc+fVUJvfnGhDwLqLXvXyzXqapKphrGxAAHD2GzxOEGo33N3N97m18qbyeG+hA
UOcIRVfLP2jPrWDolKchtM9AyUj4lAiMsPU7Jc+Rt6AnMyTr1hsXduUCNNn3i/h/
s7Kg3xIo++izDhC9Qj5Pedgy2pbZ6z4ZMKQ9UsPGHJ6X3BmT7lgX796nGeaySC+L
HqwBtoAlFMwE96i4yNEhFlQuM5roNhlVc4Vv5yyvtVNtxoYMGpsrJ0upAWHmJ+0J
UJVlCcemng+7eSfNBrdZ1XvSvHxSqPEOmmn7gqdBzad3PKj9inkibtmSqt9gNOGR
RzI0DZK8CE52LUrqBNrUsifmE8uw/FQ11+7eahL65b0nNj0wreExONb0aQEYOR1/
/4YXK742K3l4hZn5r/sIuzgYFFIZwIKckYi821EHE3ugwPG3asBXBaZ9vSZ5CFt+
vAzedpTNV3nN/55KlqHhll98FF6JQAFNsGRY5kcWC2SVv/KRIczrfVm2R/USVXOX
iWcCAwEAAaOCAp4wggKaMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF
BQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUnReY/FdZAB8x
NTbPm+A1kBqwgAYwHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYI
KwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5vcmcw
IgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9yZy8wbAYDVR0RBGUwY4Ih
bWFpbC5wYXBlcmxlc3Nzb2x1dGlvbnNsdGQuY29tLm5nghxwYXBlcmxlc3Nzb2x1
dGlvbnNsdGQuY29tLm5ngiB3d3cucGFwZXJsZXNzc29sdXRpb25zbHRkLmNvbS5u
ZzBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUF
BwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCCAQYGCisGAQQB1nkCBAIE
gfcEgfQA8gB3AESUZS6w7s6vxEAH2Kj+KMDa5oK+2MsxtT/TM5a1toGoAAABd3IS
1lkAAAQDAEgwRgIhAODIbmogAX5fAQ8pKfAlEbZMFJYqksp3iInqCepNymN3AiEA
zdJOaSOHe2A78x9thbdf8WCndV/rPVLw0tME6hzpW6QAdwD2XJQv0XcwIhRUGAgw
lFaO400TGTO/3wwvIAvMTvFk4wAAAXdyEtZZAAAEAwBIMEYCIQD8FomGRVUtXy5e
XByxhM383UUKt+35L217GUAZ7FUgjwIhANrw1gax+fOWp6qRLpBFDz7S3D9SL5RA
KHWQYOJmM8ciMA0GCSqGSIb3DQEBCwUAA4IBAQCU1EzS7Lt1hAZ4+WtPisM+B8R/
RKJ72PTE+E8dHB+SlNeFoJGpj5Z4FO9bp69fdOcG6D2NxJBDVc1VCR7Gx20Sxngs
wm9CexnRlsRaWuXLTJoxn/QoQ+kEWRIIYVXaa7MmlkljpTGLHkBHpwOT7/rtmgpB
geUmgjia+hlah2jltYP6QwhXriOXuhUU/DltAm8S2yS8ITtIIe/0yCXy3CilY7Um
0qtQW5lDecCqZtYlBGwNtoJbAWJrAnlMavdlM6Z1ziRh33BiPQXKNFfBk2P9kBmA
Yud7vIIOK5SB5KhZ45WWm2Tmu2ZsHPu+iaDR+rQB68BOi1aQY0P6+JbY6V1j
-----END CERTIFICATE-----


-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIk
XPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----

same result.

Hmm, just to rule out file encoding issues altogether, when you run :public_key.pem_decode(File.read!("cert.pem")) in iEX, do you get a list with one or two certificates?

iex> :public_key.pem_decode(File.read!(~S"C:\Apps\LSETF\server\priv\cert.pem"))
[
  {:Certificate,
   <<48, 130, 6, 137, 48, 130, 5, 113, 160, 3, 2, 1, 2, 2, 18, 4, 145, 47, 47, 123, 147, 241, 134, 76, 188, 109, 7, 26, 33, 110, 128, 71, 189, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 50, 49, 11, 48, 9, 6, 3,
     85, 4, 6, 19, 2, 85, 83, 49, 22, 48, 20, 6, 3, 85, 4, 10, 19, 13, 76, 101, 116, 39, 115, 32, 69, 110, 99, 114, 121, 112, 116, 49, 11, 48, 9, 6, 3, 85, 4, 3, 19, 2, 82, 51, 48, 30, 23, 13, 50, 49, 48, 50, 48, 53, 49, 49, 48,
     50, 53, 51, 90, 23, 13, 50, 49, 48, 53, 48, 54, 49, 49, 48, 50, 53, 51, 90, 48, 43, 49, 41, 48, 39, 6, 3, 85, 4, 3, 19, 32, 119, 119, 119, 46, 112, 97, 112, 101, 114, 108, 101, 115, 115, 115, 111, 108, 117, 116, 105, 111,
     110, 115, 108, 116, 100, 46, 99, 111, 109, 46, 110, 103, 48, 130, 2, 34, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 1, 5, 0, 3, 130, 2, 15, 0, 48, 130, 2, 10, 2, 130, 2, 1, 0, 254, 146, 69, 207, 98, 39, 92, 239, 20, 137,
     56, 32, 183, 116, 225, 63, 123, 98, 34, 40, 169, 85, 103, 198, 206, 215, 135, 44, 142, 210, 233, 88, 73, 70, 59, 254, 253, 111, 140, 114, 238, 68, 93, 119, 85, 186, 111, 245, 101, 55, 186, 19, 82, 168, 254, 45, 42, 174, 171,
     240, 188, 19, 97, 184, 32, 136, 208, 73, 202, 228, 125, 189, 246, 48, 8, 10, 221, 63, 38, 116, 147, 14, 157, 73, 15, 61, 164, 236, 217, 180, 48, 136, 136, 17, 151, 239, 104, 132, 87, 186, 138, 41, 71, 136, 140, 247, 91, 47,
     34, 75, 186, 15, 122, 243, 103, 227, 176, 161, 53, 47, 101, 123, 196, 177, 201, 50, 164, 18, 92, 249, 245, 84, 38, 247, 231, 26, 16, 240, 46, 162, 215, 189, 124, 179, 94, 166, 169, 42, 152, 107, 27, 16, 0, 28, 61, 134, 207,
     19, 132, 26, 141, 247, 55, 115, 125, 238, 109, 124, 169, 188, 158, 27, 232, 64, 80, 231, 8, 69, 87, 203, 63, 104, 207, 173, 96, 232, 148, 167, 33, 180, 207, 64, 201, 72, 248, 148, 8, 140, 176, 245, 59, 37, 207, 145, 183, 160,
     39, 51, 36, 235, 214, 27, 23, 118, 229, 2, 52, 217, 247, 139, 248, 127, 179, 178, 160, 223, 18, 40, 251, 232, 179, 14, 16, 189, 66, 62, 79, 121, 216, 50, 218, 150, 217, 235, 62, 25, 48, 164, 61, 82, 195, 198, 28, 158, 151,
     220, 25, 147, 238, 88, 23, 239, 222, 167, 25, 230, 178, 72, 47, 139, 30, 172, 1, 182, 128, 37, 20, 204, 4, 247, 168, 184, 200, 209, 33, 22, 84, 46, 51, 154, 232, 54, 25, 85, 115, 133, 111, 231, 44, 175, 181, 83, 109, 198,
     134, 12, 26, 155, 43, 39, 75, 169, 1, 97, 230, 39, 237, 9, 80, 149, 101, 9, 199, 166, 158, 15, 187, 121, 39, 205, 6, 183, 89, 213, 123, 210, 188, 124, 82, 168, 241, 14, 154, 105, 251, 130, 167, 65, 205, 167, 119, 60, 168,
     253, 138, 121, 34, 110, 217, 146, 170, 223, 96, 52, 225, 145, 71, 50, 52, 13, 146, 188, 8, 78, 118, 45, 74, 234, 4, 218, 212, 178, 39, 230, 19, 203, 176, 252, 84, 53, 215, 238, 222, 106, 18, 250, 229, 189, 39, 54, 61, 48,
     173, 225, 49, 56, 214, 244, 105, 1, 24, 57, 29, 127, 255, 134, 23, 43, 190, 54, 43, 121, 120, 133, 153, 249, 175, 251, 8, 187, 56, 24, 20, 82, 25, 192, 130, 156, 145, 136, 188, 219, 81, 7, 19, 123, 160, 192, 241, 183, 106,
     192, 87, 5, 166, 125, 189, 38, 121, 8, 91, 126, 188, 12, 222, 118, 148, 205, 87, 121, 205, 255, 158, 74, 150, 161, 225, 150, 95, 124, 20, 94, 137, 64, 1, 77, 176, 100, 88, 230, 71, 22, 11, 100, 149, 191, 242, 145, 33, 204,
     235, 125, 89, 182, 71, 245, 18, 85, 115, 151, 137, 103, 2, 3, 1, 0, 1, 163, 130, 2, 158, 48, 130, 2, 154, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4, 4, 3, 2, 5, 160, 48, 29, 6, 3, 85, 29, 37, 4, 22, 48, 20, 6, 8, 43, 6, 1, 5, 5,
     7, 3, 1, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 48, 12, 6, 3, 85, 29, 19, 1, 1, 255, 4, 2, 48, 0, 48, 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, 157, 23, 152, 252, 87, 89, 0, 31, 49, 53, 54, 207, 155, 224, 53, 144, 26, 176, 128, 6, 48, 31,
     6, 3, 85, 29, 35, 4, 24, 48, 22, 128, 20, 20, 46, 179, 23, 183, 88, 86, 203, 174, 80, 9, 64, 230, 31, 175, 157, 139, 20, 194, 198, 48, 85, 6, 8, 43, 6, 1, 5, 5, 7, 1, 1, 4, 73, 48, 71, 48, 33, 6, 8, 43, 6, 1, 5, 5, 7, 48, 1,
     134, 21, 104, 116, 116, 112, 58, 47, 47, 114, 51, 46, 111, 46, 108, 101, 110, 99, 114, 46, 111, 114, 103, 48, 34, 6, 8, 43, 6, 1, 5, 5, 7, 48, 2, 134, 22, 104, 116, 116, 112, 58, 47, 47, 114, 51, 46, 105, 46, 108, 101, 110,
     99, 114, 46, 111, 114, 103, 47, 48, 108, 6, 3, 85, 29, 17, 4, 101, 48, 99, 130, 33, 109, 97, 105, 108, 46, 112, 97, 112, 101, 114, 108, 101, 115, 115, 115, 111, 108, 117, 116, 105, 111, 110, 115, 108, 116, 100, 46, 99, 111,
     109, 46, 110, 103, 130, 28, 112, 97, 112, 101, 114, 108, 101, 115, 115, 115, 111, 108, 117, 116, 105, 111, 110, 115, 108, 116, 100, 46, 99, 111, 109, 46, 110, 103, 130, 32, 119, 119, 119, 46, 112, 97, 112, 101, 114, 108, 101,
     115, 115, 115, 111, 108, 117, 116, 105, 111, 110, 115, 108, 116, 100, 46, 99, 111, 109, 46, 110, 103, 48, 76, 6, 3, 85, 29, 32, 4, 69, 48, 67, 48, 8, 6, 6, 103, 129, 12, 1, 2, 1, 48, 55, 6, 11, 43, 6, 1, 4, 1, 130, 223, 19,
     1, 1, 1, 48, 40, 48, 38, 6, 8, 43, 6, 1, 5, 5, 7, 2, 1, 22, 26, 104, 116, 116, 112, 58, 47, 47, 99, 112, 115, 46, 108, 101, 116, 115, 101, 110, 99, 114, 121, 112, 116, 46, 111, 114, 103, 48, 130, 1, 6, 6, 10, 43, 6, 1, 4, 1,
     214, 121, 2, 4, 2, 4, 129, 247, 4, 129, 244, 0, 242, 0, 119, 0, 68, 148, 101, 46, 176, 238, 206, 175, 196, 64, 7, 216, 168, 254, 40, 192, 218, 230, 130, 190, 216, 203, 49, 181, 63, 211, 51, 150, 181, 182, 129, 168, 0, 0, 1,
     119, 114, 18, 214, 89, 0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 224, 200, 110, 106, 32, 1, 126, 95, 1, 15, 41, 41, 240, 37, 17, 182, 76, 20, 150, 42, 146, 202, 119, 136, 137, 234, 9, 234, 77, 202, 99, 119, 2, 33, 0, 205, 210, 78,
     105, 35, 135, 123, 96, 59, 243, 31, 109, 133, 183, 95, 241, 96, 167, 117, 95, 235, 61, 82, 240, 210, 211, 4, 234, 28, 233, 91, 164, 0, 119, 0, 246, 92, 148, 47, 209, 119, 48, 34, 20, 84, 24, 8, 48, 148, 86, 142, 227, 77, 19,
     25, 51, 191, 223, 12, 47, 32, 11, 204, 78, 241, 100, 227, 0, 0, 1, 119, 114, 18, 214, 89, 0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 252, 22, 137, 134, 69, 85, 45, 95, 46, 94, 92, 28, 177, 132, 205, 252, 221, 69, 10, 183, 237, 249,
     47, 109, 123, 25, 64, 25, 236, 85, 32, 143, 2, 33, 0, 218, 240, 214, 6, 177, 249, 243, 150, 167, 170, 145, 46, 144, 69, 15, 62, 210, 220, 63, 82, 47, 148, 64, 40, 117, 144, 96, 226, 102, 51, 199, 34, 48, 13, 6, 9, 42, 134,
     72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 1, 1, 0, 148, 212, 76, 210, 236, 187, 117, 132, 6, 120, 249, 107, 79, 138, 195, 62, 7, 196, 127, 68, 162, 123, 216, 244, 196, 248, 79, 29, 28, 31, 146, 148, 215, 133, 160, 145, 169,
     143, 150, 120, 20, 239, 91, 167, 175, 95, 116, 231, 6, 232, 61, 141, 196, 144, 67, 85, 205, 85, 9, 30, 198, 199, 109, 18, 198, 120, 44, 194, 111, 66, 123, 25, 209, 150, 196, 90, 90, 229, 203, 76, 154, 49, 159, 244, 40, 67,
     233, 4, 89, 18, 8, 97, 85, 218, 107, 179, 38, 150, 73, 99, 165, 49, 139, 30, 64, 71, 167, 3, 147, 239, 250, 237, 154, 10, 65, 129, 229, 38, 130, 56, 154, 250, 25, 90, 135, 104, 229, 181, 131, 250, 67, 8, 87, 174, 35, 151,
     186, 21, 20, 252, 57, 109, 2, 111, 18, 219, 36, 188, 33, 59, 72, 33, 239, 244, 200, 37, 242, 220, 40, 165, 99, 181, 38, 210, 171, 80, 91, 153, 67, 121, 192, 170, 102, 214, 37, 4, 108, 13, 182, 130, 91, 1, 98, 107, 2, 121, 76,
     106, 247, 101, 51, 166, 117, 206, 36, 97, 223, 112, 98, 61, 5, 202, 52, 87, 193, 147, 99, 253, 144, 25, 128, 98, 231, 123, 188, 130, 14, 43, 148, 129, 228, 168, 89, 227, 149, 150, 155, 100, 230, 187, 102, 108, 28, 251, 190,
     137, 160, 209, 250, 180, 1, 235, 192, 78, 139, 86, 144, 99, 67, 250, 248, 150, 216, 233, 93, 99>>, :not_encrypted},
  {:Certificate,
   <<48, 130, 5, 22, 48, 130, 2, 254, 160, 3, 2, 1, 2, 2, 17, 0, 145, 43, 8, 74, 207, 12, 24, 167, 83, 246, 214, 46, 37, 167, 95, 90, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 48, 79, 49, 11, 48, 9, 6, 3, 85, 4, 6,
     19, 2, 85, 83, 49, 41, 48, 39, 6, 3, 85, 4, 10, 19, 32, 73, 110, 116, 101, 114, 110, 101, 116, 32, 83, 101, 99, 117, 114, 105, 116, 121, 32, 82, 101, 115, 101, 97, 114, 99, 104, 32, 71, 114, 111, 117, 112, 49, 21, 48, 19, 6,
     3, 85, 4, 3, 19, 12, 73, 83, 82, 71, 32, 82, 111, 111, 116, 32, 88, 49, 48, 30, 23, 13, 50, 48, 48, 57, 48, 52, 48, 48, 48, 48, 48, 48, 90, 23, 13, 50, 53, 48, 57, 49, 53, 49, 54, 48, 48, 48, 48, 90, 48, 50, 49, 11, 48, 9, 6,
     3, 85, 4, 6, 19, 2, 85, 83, 49, 22, 48, 20, 6, 3, 85, 4, 10, 19, 13, 76, 101, 116, 39, 115, 32, 69, 110, 99, 114, 121, 112, 116, 49, 11, 48, 9, 6, 3, 85, 4, 3, 19, 2, 82, 51, 48, 130, 1, 34, 48, 13, 6, 9, 42, 134, 72, 134,
     247, 13, 1, 1, 1, 5, 0, 3, 130, 1, 15, 0, 48, 130, 1, 10, 2, 130, 1, 1, 0, 187, 2, 21, 40, 204, 246, 160, 148, 211, 15, 18, 236, 141, 85, 146, 195, 248, 130, 241, 153, 166, 122, 66, 136, 167, 93, 38, 170, 181, 43, 185, 197,
     76, 177, 175, 142, 107, 249, 117, 200, 163, 215, 15, 71, 148, 20, 85, 53, 87, 140, 158, 168, 162, 57, 25, 245, 130, 60, 66, 169, 78, 110, 245, 59, 195, 46, 219, 141, 192, 176, 92, 243, 89, 56, 231, 237, 207, 105, 240, 90, 11,
     27, 190, 192, 148, 36, 37, 135, 250, 55, 113, 179, 19, 231, 28, 172, 225, 155, 239, 219, 228, 59, 69, 82, 69, 150, 169, 193, 83, 206, 52, 200, 82, 238, 181, 174, 237, 143, 222, 96, 112, 226, 165, 84, 171, 182, 109, 14, 151,
     165, 64, 52, 107, 43, 211, 188, 102, 235, 102, 52, 124, 250, 107, 139, 143, 87, 41, 153, 248, 48, 23, 93, 186, 114, 111, 251, 129, 197, 173, 210, 134, 88, 61, 23, 199, 231, 9, 187, 241, 43, 247, 134, 220, 193, 218, 113, 93,
     212, 70, 227, 204, 173, 37, 193, 136, 188, 96, 103, 117, 102, 179, 241, 24, 247, 162, 92, 230, 83, 255, 58, 136, 182, 71, 165, 255, 19, 24, 234, 152, 9, 119, 63, 157, 83, 249, 207, 1, 229, 245, 166, 112, 23, 20, 175, 99, 164,
     255, 153, 179, 147, 157, 220, 83, 167, 6, 254, 72, 133, 29, 161, 105, 174, 37, 117, 187, 19, 204, 82, 3, 245, 237, 81, 161, 139, 219, 21, 2, 3, 1, 0, 1, 163, 130, 1, 8, 48, 130, 1, 4, 48, 14, 6, 3, 85, 29, 15, 1, 1, 255, 4,
     4, 3, 2, 1, 134, 48, 29, 6, 3, 85, 29, 37, 4, 22, 48, 20, 6, 8, 43, 6, 1, 5, 5, 7, 3, 2, 6, 8, 43, 6, 1, 5, 5, 7, 3, 1, 48, 18, 6, 3, 85, 29, 19, 1, 1, 255, 4, 8, 48, 6, 1, 1, 255, 2, 1, 0, 48, 29, 6, 3, 85, 29, 14, 4, 22, 4,
     20, 20, 46, 179, 23, 183, 88, 86, 203, 174, 80, 9, 64, 230, 31, 175, 157, 139, 20, 194, 198, 48, 31, 6, 3, 85, 29, 35, 4, 24, 48, 22, 128, 20, 121, 180, 89, 230, 123, 182, 229, 228, 1, 115, 128, 8, 136, 200, 26, 88, 246, 233,
     155, 110, 48, 50, 6, 8, 43, 6, 1, 5, 5, 7, 1, 1, 4, 38, 48, 36, 48, 34, 6, 8, 43, 6, 1, 5, 5, 7, 48, 2, 134, 22, 104, 116, 116, 112, 58, 47, 47, 120, 49, 46, 105, 46, 108, 101, 110, 99, 114, 46, 111, 114, 103, 47, 48, 39, 6,
     3, 85, 29, 31, 4, 32, 48, 30, 48, 28, 160, 26, 160, 24, 134, 22, 104, 116, 116, 112, 58, 47, 47, 120, 49, 46, 99, 46, 108, 101, 110, 99, 114, 46, 111, 114, 103, 47, 48, 34, 6, 3, 85, 29, 32, 4, 27, 48, 25, 48, 8, 6, 6, 103,
     129, 12, 1, 2, 1, 48, 13, 6, 11, 43, 6, 1, 4, 1, 130, 223, 19, 1, 1, 1, 48, 13, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 11, 5, 0, 3, 130, 2, 1, 0, 133, 202, 78, 71, 62, 163, 247, 133, 68, 133, 188, 213, 103, 120, 178, 152, 99,
     173, 117, 77, 30, 150, 61, 51, 101, 114, 84, 45, 129, 160, 234, 195, 237, 248, 32, 191, 95, 204, 183, 112, 0, 183, 110, 59, 246, 94, 148, 222, 228, 32, 159, 166, 239, 139, 178, 3, 231, 162, 181, 22, 60, 145, 206, 180, 237,
     57, 2, 231, 124, 37, 138, 71, 230, 101, 110, 63, 70, 244, 217, 240, 206, 148, 43, 238, 84, 206, 18, 188, 140, 39, 75, 184, 193, 152, 47, 162, 175, 205, 113, 145, 74, 8, 183, 200, 184, 35, 123, 4, 45, 8, 249, 8, 87, 62, 131,
     217, 4, 51, 10, 71, 33, 120, 9, 130, 39, 195, 42, 200, 155, 185, 206, 92, 242, 100, 200, 192, 190, 121, 192, 79, 142, 109, 68, 12, 94, 146, 187, 46, 247, 139, 16, 225, 232, 29, 68, 41, 219, 89, 32, 237, 99, 185, 33, 248, 18,
     38, 148, 147, 87, 160, 29, 101, 4, 193, 10, 34, 174, 16, 13, 67, 151, 161, 24, 31, 126, 224, 224, 134, 55, 181, 90, 177, 189, 48, 191, 135, 110, 43, 42, 255, 33, 78, 27, 5, 195, 245, 24, 151, 240, 94, 172, 195, 165, 184, 106,
     240, 46, 188, 59, 51, 185, 238, 75, 222, 204, 252, 228, 175, 132, 11, 134, 63, 192, 85, 67, 54, 246, 104, 225, 54, 23, 106, 142, 153, 209, 255, 165, 64, 167, 52, 183, 192, 208, 99, 57, 53, 57, 117, 110, 242, 186, 118, 200,
     147, 2, 233, 169, 75, 108, 23, 206, 12, 2, 217, 189, 129, 251, 159, 183, 104, 212, 6, 101, 179, 130, 61, 119, 83, 248, 142, 121, 3, 173, 10, 49, 7, 117, 42, 67, 216, 85, 151, 114, 196, 41, 14, 247, 196, 93, 78, 200, 174, 70,
     132, 48, 215, 242, 133, 95, 24, 161, 121, 187, 231, 94, 112, 139, 7, 225, 134, 147, 195, 185, 143, 220, 97, 113, 37, 42, 175, 223, 237, 37, 80, 82, 104, 139, 146, 220, 229, 214, 181, 227, 218, 125, 208, 135, 108, 132, 33, 49,
     174, 130, 245, 251, 185, 171, 200, 137, 23, 61, 225, 76, 229, 56, 14, 246, 189, 43, 189, 150, 129, 20, 235, 213, 219, 61, 32, 167, 126, 89, 211, 226, 248, 88, 249, 91, 184, 72, 205, 254, 92, 79, 22, 41, 254, 30, 85, 35, 175,
     200, 17, 176, 141, 234, 124, 147, 144, 23, 47, 253, 172, 162, 9, 71, 70, 63, 240, 233, 176, 183, 255, 40, 77, 104, 50, 214, 103, 94, 30, 105, 163, 147, 184, 245, 157, 139, 47, 11, 210, 82, 67, 166, 111, 50, 87, 101, 77, 50,
     129, 223, 56, 83, 133, 93, 126, 93, 102, 41, 234, 184, 221, 228, 149, 181, 205, 181, 86, 18, 66, 205, 196, 78, 198, 37, 56, 68, 80, 109, 236, 206, 0, 85, 24, 254, 233, 73, 100, 212, 78, 202, 151, 156, 180, 91, 192, 115, 168,
     171, 184, 71, 194>>, :not_encrypted}
]
iex>

Ok, I can reproduce the issue here, but only with some Erlang/OTP versions. The problem goes away when I add cacertfile: "cert.pem" to the ssl options. I don’t know why: when :cacertfile is not specified, ssl is supposed to look in the file specified by certfile.

The server is:

λ elixir --version
Erlang/OTP 23 [erts-11.1.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]

Elixir 1.11.1 (compiled with Erlang/OTP 21)

So you saying I should use the combined cert.pem for both :cacertfile and :certfile ?

Sadly, same result

cacertfile: Application.app_dir(@app, "priv/cert.pem"),
      certfile: Application.app_dir(@app, "priv/cert.pem"),
      keyfile: Application.app_dir(@app, "priv/cert.key")

I saw the issue with 22.3, and just now I also reproduced it with 23.1. With 23.2 it works ok out of the box.

Yes, the workaround is to set both :certfile and :cacertfile to the same path containing the full chain.

3 Likes

I was about to move to:

http://erlang.org/download/otp_win64_23.2.4.exe

let me do this and see

God bless & thanks sooooo much! :pray: :pray: :pray:

I’ve been bitten by this before too… there was some discussion last year: ssl server doesn't send complete chain?

I think this is the commit that fixed it in 23.2: ssl: Extend cert and certfile option to be able to include a cert chain · erlang/otp@8d97c09 · GitHub

  OTP-16277    Application(s): ssl

               Handle extraneous certs in certificate chains as well
               as chains that are incomplete but can be reconstructed
               or unordered chains. The cert and certfile options will
               now accept a list of certificates so that the user may
               specify the chain explicitly.

               Also, the default value of the depth option has been
               increased to allow longer chains by default.
1 Like

I’ve been bitten by this before too… there was some discussion last year: ssl server doesn’t send complete chain?

The author of that post wants to separate the intermediate CAs for their server certificate from the list of trusted root CAs used to verify client certificates. Right now this is not possible, as Ingela pointed out in her response. If the :cacertfile option is set, the server does not look for (intermediate) CAs in the file referenced by :certfile. Only if :cacertfile is not specified does it look in that file instead.

I think this is the commit that fixed it in 23.2: ssl: Extend cert and certfile option to be able to include a cert chain · erlang/otp@8d97c09 · GitHub

That change affects the way a chain is built for a peer certificate (e.g. a client checking a server’s certificate during a TLS handshake). In particular, it is supposed to handle multiple possible paths, as in the case of cross-signed certificates. It should not affect the sources used to locate issuers of the local end certificate.

Ah yes, indeed. I just happened to hit both problems at the same time because I was trying to configure RabbitMQ for mTLS.