Failing Client Authentication on Chrome with Self Signed Certificates - ssl

I understand there are lot of questions on this same topic out there. Unfortunately nothing solved my exact problem. So let me be specific.
I'm developing a set of REST APIs which require certificate authentication(weird but its like that). So for testing we created self-signed certificates with openssl as follows:
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=Lead Services'
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=*.lservices.eu'
openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out services/server.crt
openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out services/client.crt
Now, an nginx was setup to run with these ssl certificates, requiring client authentication. The nginx config looks like this:
listen 443 ssl;
server_name lacs.lservices.eu localhost;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_certificate certs/server.crt;
ssl_certificate_key certs/server.key;
ssl_client_certificate certs/ca.crt;
ssl_verify_client on;
Testing the API with postman using the above generated client certificate worked fine. All good so far. We had created a swagger-ui and it gives an option to test directly from browser. But here the client authentication is not working.
I tried importing the CA certificates to Trusted CA store and Client certificate to Personal in my Windows 10 and tried testing from Chrome and Edge, but server rejects the calls with 400 No required SSL certificate was sent.
Update
Adding the output of openssl s_client -connect localhost:443
CONNECTED(00000218)
depth=0 CN = *.lservices.eu
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = *.lservices.eu
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=*.lservices.eu
i:/CN=Lead Services
---
Server certificate
-----BEGIN CERTIFICATE-----
......certificate content removed ---
-----END CERTIFICATE-----
subject=/CN=*.lservices.eu
issuer=/CN=Lead Services
---
Acceptable client certificate CA names
/CN=Lead Services
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:0x07+0x08:0x08+0x08:0x09+0x08:0x0A+0x08:0x0B+0x08:0x04+0x08:0x05+0x08:0x06+0x08:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1:DSA+SHA224:DSA+SHA1:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:ECDSA+SHA1:RSA+SHA224:RSA+SHA1:DSA+SHA224:DSA+SHA1:DSA+SHA256:DSA+SHA384:DSA+SHA512
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2245 bytes and written 455 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: C2A281888B9899B68D6734DBDACE351F7975709F887FDD1EC011419D25F67B36
Session-ID-ctx:
Master-Key: CE307DF955A22CA2F901E95078DDEFF5AB8668B4789B7979504DC054E1DA8400B244B10C825DB899F713BE9E3665C63A
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 5c 99 a8 3c e8 e4 c2 f3-ce 19 db fd c7 35 4f f0 \..<.........5O.
0010 - 80 6f b7 59 19 c6 50 9c-c1 ad 2c 5c 06 30 94 05 .o.Y..P...,\.0..
0020 - 95 02 2b af 80 07 c4 0b-fd b2 64 a3 7c 2b d7 91 ..+.......d.|+..
0030 - 33 d0 65 3a 47 23 2c 07-6a c6 62 7f 90 bb 75 50 3.e:G#,.j.b...uP
0040 - 18 35 ae 08 38 59 ec 59-9c 6e 77 69 40 16 49 46 .5..8Y.Y.nwi#.IF
0050 - ce 5f b8 35 88 e1 d9 7a-6b e5 21 db 30 83 c0 b8 ._.5...zk.!.0...
0060 - 72 37 91 d9 ce e4 e8 d4-88 e0 b0 10 2c cc c2 c6 r7..........,...
0070 - ac 39 da 68 de cb 92 be-6c 61 77 cc cd 10 0b 47 .9.h....law....G
0080 - ae 0b 97 40 0b 41 46 98-5b fe 1e 17 a2 40 4a 2a ...#.AF.[....#J*
0090 - c8 d1 02 2e 3e 73 df 8e-ac 5c 3e 85 54 a2 ee 68 ....>s...\>.T..h
00a0 - 05 3f 76 2f 5a e4 36 dc-c4 1b c2 f1 81 70 b3 63 .?v/Z.6......p.c
Start Time: 1577357945
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
How can I make it work? Is there any restrictions on self-signed certificates that it cannot be used like this? Any help appreciated!

Generally:
1.) Verify if server accepts client certs from your CA. Check Acceptable client certificate CA from:
openssl s_client -connect <server:tls-port>
2.) Verify if imported personal cert matches requirements from Acceptable client certificate CA from 1.)
It is not clear how did you create client.csr - probably there is a problem. I hope you have used different key.

After trying several combinations of openssl calls, I finally figured a sequence that would allow me to generate a client certificate that Chrome would accept. I then created two shell scripts to handle the process, one responsible for generating a self-signed server certificate that doubles as CA, the other to generate the client certificate signed with it.
create_server_certificate.sh
#!/bin/bash
# Generate a self-signed certificate and validating private key.
#
# See: https://serverfault.com/a/870832/486539
FILE_PREFIX="server"
SERVER_NAME="$HOSTNAME"
# See: https://stackoverflow.com/a/14203146/476920
for i in "$#"
do
case $i in
--host=*)
SERVER_NAME="${i#*=}"
;;
--name=*)
FILE_PREFIX="${i#*=}"
;;
*)
echo "Unkwnown option: \""$i'"'
exit 1
;;
esac
done
CONFIG="
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = san_self_signed
[ req_distinguished_name ]
CN=$SERVER_NAME
[ san_self_signed ]
subjectAltName = DNS:$SERVER_NAME, DNS:localhost
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
extendedKeyUsage = serverAuth, clientAuth, timeStamping
"
SERVER_CERT="$OUTPUT_DIR/${FILE_PREFIX}_crt.pem"
SERVER_KEY="$OUTPUT_DIR/${FILE_PREFIX}_key.pem"
openssl req \
-newkey rsa:2048 -nodes \
-keyout "$SERVER_KEY" \
-x509 -sha256 -days 3650 \
-config <(echo "$CONFIG") \
-out "$SERVER_CERT"
openssl x509 -noout -text -in "$SERVER_CERT"
create_client_certificate.sh
#!/bin/bash
# Generate a client SSL certificate and validating private key for client-side
# authentication on web browsers.
#
# See:
#
# * https://serverfault.com/a/870832/486539
# * https://blog.devolutions.net/2020/07/tutorial-how-to-generate-secure-self-signed-server-and-client-certificates-with-openssl
CLIENT_ID="client"
CLIENT_PREFIX="client"
ROOT_PREFIX="server"
# See: https://stackoverflow.com/a/14203146/476920
for i in "$#"
do
case $i in
--id=*)
CLIENT_ID="${i#*=}"
;;
--root=*)
ROOT_PREFIX="${i#*=}"
;;
--out=*)
CLIENT_PREFIX="${i#*=}"
;;
*)
echo "Unkwnown option: \""$i'"'
exit 1
;;
esac
done
CLIENT_CRT="${CLIENT_PREFIX}_crt.pem"
CLIENT_REQ="${CLIENT_PREFIX}_csr.pem"
CLIENT_KEY="${CLIENT_PREFIX}_key.pem"
ROOT_CRT="${ROOT_PREFIX}_crt.pem"
ROOT_KEY="${ROOT_PREFIX}_key.pem"
CONFIG="
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
CN=$CLIENT_ID
"
# Generate client private key.
openssl ecparam -name prime256v1 -genkey -noout -out "$CLIENT_KEY"
# Generate client certificate request.
openssl req -new -sha256 -key "$CLIENT_KEY" -out "$CLIENT_REQ" -config <(echo "$CONFIG")
# Generate client certificate.
openssl x509 -req -in "$CLIENT_REQ" -CA "$ROOT_CRT" -CAkey "$ROOT_KEY" -CAcreateserial -out "$CLIENT_CRT" -days 1000 -sha256
# Generate a PFX certificate that can be imported to Google Chrome.
openssl pkcs12 -inkey "$CLIENT_KEY" -in "$CLIENT_CRT" -export -out "${CLIENT_PREFIX}.pfx"
openssl x509 -noout -text -in "$CLIENT_CRT"
rm "$CLIENT_REQ"
First run create_server_certificate.sh to generate the server / CA certificate, then create_client_certificate.sh to generate the client certificate signed by the former. Next import server_crt.pem in the Authorities tab of Chrome's Manage certificates screen, and client.pfx in the Your certificates tab.
To test your certificates, run the test OpenSSL server with:
openssl s_server -cert server_crt.pem -key server_key.pem -CAfile client_crt.pem -accept 4443 -www -Verify 1
And direct Chrome to the suitable local address, e.g. https://localhost:4443.

Related

NET::ERR_CERT_AUTHORITY_INVALID with a Letsencrypt certificate

My Chrome Version 92.0.4515.159 (Official Build) (64-bit) browser says: NET::ERR_CERT_AUTHORITY_INVALID when requesting the https://www.europasprak.com/ page.
The page https://incomplete-chain.badssl.com/ says:
incomplete-chain.badssl.com
The SSL Check https://www.sslshopper.com/ssl-checker.html#hostname=europasprak.com:443 shows:
europasprak.com resolves to 51.178.39.8
Server Type: Apache/2.4.46 (Unix) OpenSSL/1.1.1j PHP/7.3.9
The certificate will expire in 89 days. Remind me
The hostname (europasprak.com) is correctly listed in the certificate.
The certificate is not trusted in all web browsers. You may need to install an Intermediate/chain certificate to link it to a trusted root certificate. Learn more about this error. The fastest way to fix this problem is to contact your SSL provider.
I just created the certificate:
sudo certbot certonly --webroot -w /home/europasprak/dev/learnintouch/www.europasprak -d europasprak.com -d www.europasprak.com \
-m example#example.com --agree-tos --staging
and it gave me the certificate files.
I can see it does not need to be renewed:
sudo certbot certonly --webroot -w /home/europasprak/dev/learnintouch/www.europasprak -d europasprak.com -d www.europasprak.com --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Cert not due for renewal, but simulating renewal for dry run
Simulating renewal of an existing certificate for europasprak.com and www.europasprak.com
Performing the following challenges:
http-01 challenge for europasprak.com
http-01 challenge for www.europasprak.com
Using the webroot path /home/europasprak/dev/learnintouch/www.europasprak for all unmatched domains.
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- The dry run was successful.
The certbot version:
sudo certbot --version
certbot 1.12.0
Here is the Apache configuration I have in the apache/conf/extra/httpd-ssl.conf file:
<VirtualHost _default_:443>
ServerName www.europasprak.com:443
ServerAdmin example#example.se
ErrorLog "/home/europasprak/programs/install/apache/logs/error_log"
TransferLog "/home/europasprak/programs/install/apache/logs/access_log"
SSLEngine on
SSLCertificateFile "/etc/letsencrypt/live/europasprak.com/cert.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/europasprak.com/privkey.pem"
SSLCertificateChainFile "/etc/letsencrypt/live/europasprak.com/fullchain.pem"
Here is the Apache configuration I have in the apache/conf/extra/httpd-vhosts.conf file:
<VirtualHost *:443>
ServerName www.europasprak.com
ServerAlias europasprak.com
DocumentRoot /home/europasprak/dev/learnintouch/www.europasprak
CustomLog /home/europasprak/programs/install/logs/learnintouch-access_log combined
<Directory "/home/europasprak/dev/learnintouch/www.europasprak">
Include /home/europasprak/dev/learnintouch/engine/setup/url_rewrite.conf
AllowOverride All
Require all granted
</Directory>
AddDefaultCharset UTF-8
SSLEngine on
SSLCertificateFile "/etc/letsencrypt/live/europasprak.com/cert.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/europasprak.com/privkey.pem"
SSLCertificateChainFile "/etc/letsencrypt/live/europasprak.com/fullchain.pem"
</VirtualHost>
Some additional commands show:
13:12 $ curl -v https://incomplete-chain.badssl.com
* Trying 104.154.89.105:443...
* TCP_NODELAY set
* Connected to incomplete-chain.badssl.com (104.154.89.105) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
stephane#stephane-pc:~$ openssl s_client -connect incomplete-chain.badssl.com:443 -servername incomplete-chain.badssl.com
CONNECTED(00000003)
depth=0 C = US, ST = California, L = Walnut Creek, O = Lucas Garron Torres, CN = *.badssl.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, L = Walnut Creek, O = Lucas Garron Torres, CN = *.badssl.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:C = US, ST = California, L = Walnut Creek, O = Lucas Garron Torres, CN = *.badssl.com
i:C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGqDCCBZCgAwIBAgIQCvBs2jemC2QTQvCh6x1Z/TANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E
aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMjAwMzIzMDAwMDAwWhcN
MjIwNTE3MTIwMDAwWjBuMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5p
YTEVMBMGA1UEBxMMV2FsbnV0IENyZWVrMRwwGgYDVQQKExNMdWNhcyBHYXJyb24g
VG9ycmVzMRUwEwYDVQQDDAwqLmJhZHNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQDCBOz4jO4EwrPYUNVwWMyTGOtcqGhJsCK1+ZWesSssdj5s
wEtgTEzqsrTAD4C2sPlyyYYC+VxBXRMrf3HES7zplC5QN6ZnHGGM9kFCxUbTFocn
n3TrCp0RUiYhc2yETHlV5NFr6AY9SBVSrbMo26r/bv9glUp3aznxJNExtt1NwMT8
U7ltQq21fP6u9RXSM0jnInHHwhR6bCjqN0rf6my1crR+WqIW3GmxV0TbChKr3sMP
R3RcQSLhmvkbk+atIgYpLrG6SRwMJ56j+4v3QHIArJII2YxXhFOBBcvm/mtUmEAn
hccQu3Nw72kYQQdFVXz5ZD89LMOpfOuTGkyG0cqFAgMBAAGjggNhMIIDXTAfBgNV
HSMEGDAWgBQPgGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUne7Be4ELOkdp
cRh9ETeTvKUbP/swIwYDVR0RBBwwGoIMKi5iYWRzc2wuY29tggpiYWRzc2wuY29t
MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
awYDVR0fBGQwYjAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Et
c2hhMi1nNi5jcmwwL6AtoCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2Nh
LXNoYTItZzYuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUH
AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQIDMHwGCCsG
AQUFBwEBBHAwbjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
MEYGCCsGAQUFBzAChjpodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
cnRTSEEyU2VjdXJlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQCMAAwggF+BgorBgEE
AdZ5AgQCBIIBbgSCAWoBaAB2ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaO
HtGFAAABcQhGXioAAAQDAEcwRQIgDfWVBXEuUZC2YP4Si3AQDidHC4U9e5XTGyG7
SFNDlRkCIQCzikrA1nf7boAdhvaGu2Vkct3VaI+0y8p3gmonU5d9DwB2ACJFRQdZ
VSRWlj+hL/H3bYbgIyZjrcBLf13Gg1xu4g8CAAABcQhGXlsAAAQDAEcwRQIhAMWi
Vsi2vYdxRCRsu/DMmCyhY0iJPKHE2c6ejPycIbgqAiAs3kSSS0NiUFiHBw7QaQ/s
GO+/lNYvjExlzVUWJbgNLwB2AFGjsPX9AXmcVm24N3iPDKR6zBsny/eeiEKaDf7U
iwXlAAABcQhGXnoAAAQDAEcwRQIgKsntiBqt8Au8DAABFkxISELhP3U/wb5lb76p
vfenWL0CIQDr2kLhCWP/QUNxXqGmvr1GaG9EuokTOLEnGPhGv1cMkDANBgkqhkiG
9w0BAQsFAAOCAQEA0RGxlwy3Tl0lhrUAn2mIi8LcZ9nBUyfAcCXCtYyCdEbjIP64
xgX6pzTt0WJoxzlT+MiK6fc0hECZXqpkTNVTARYtGkJoljlTK2vAdHZ0SOpm9OT4
RLfjGnImY0hiFbZ/LtsvS2Zg7cVJecqnrZe/za/nbDdljnnrll7C8O5naQuKr4te
uice3e8a4TtviFwS/wdDnJ3RrE83b1IljILbU5SV0X1NajyYkUWS7AnOmrFUUByz
MwdGrM6kt0lfJy/gvGVsgIKZocHdedPeECqAtq7FAJYanOsjNN9RbBOGhbwq0/FP
CC01zojqS10nGowxzOiqyB4m6wytmzf0QwjpMw==
-----END CERTIFICATE-----
subject=C = US, ST = California, L = Walnut Creek, O = Lucas Garron Torres, CN = *.badssl.com
issuer=C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2414 bytes and written 445 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: 6D14962A68C1190A92BF35C87CBBD88EFF179361453CB59CA14F318BB3A84CCE
Session-ID-ctx:
Master-Key: C1A08B4ED09A6E57535700BE20EF728A5DFA768733A6D122C83C0136F50B8B0CEC766F1B6A658A63AC4D61C2C2B05149
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 5b d5 ed df 6b dc 79 68-af a2 3e 33 a2 72 4a fe [...k.yh..>3.rJ.
0010 - 68 8d 8b a9 27 e6 35 d8-0a 73 14 96 c3 e2 6c 7f h...'.5..s....l.
0020 - d6 51 09 7e 83 08 4c 9c-c9 f9 a3 f4 58 55 bd 67 .Q.~..L.....XU.g
0030 - b3 11 1b e8 fe 02 be a9-b8 9a e3 78 8c 90 54 20 ...........x..T
0040 - e0 b6 c0 c9 62 e4 37 ee-9a f1 aa 54 41 5c 13 7b ....b.7....TA\.{
0050 - 59 07 16 9d 5f 7d 47 c8-b0 52 a1 b5 d1 6c 28 33 Y..._}G..R...l(3
0060 - 2c 1d 90 24 65 a1 de 67-be 09 78 ff 1c 20 ba ca ,..$e..g..x.. ..
0070 - 29 c9 27 7c e9 6a 85 95-39 0c a2 80 27 1f f9 24 ).'|.j..9...'..$
0080 - 13 cb 98 08 d7 fc b4 1b-56 7a d4 ae bc 82 a3 e5 ........Vz......
0090 - 9a b4 03 e2 51 70 b1 be-b1 ab 51 3b cf 3d 92 96 ....Qp....Q;.=..
00a0 - d0 d9 f1 b8 2c 94 ad bc-f6 50 60 85 43 6d 7c 81 ....,....P`.Cm|.
00b0 - 66 e1 c4 36 ae 5b 36 56-e6 f5 57 ce 97 ee d3 c4 f..6.[6V..W.....
00c0 - 8e 93 df a9 01 77 99 77-10 c8 7a e6 82 fe 06 19 .....w.w..z.....
Start Time: 1630235514
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
Extended master secret: no
---
read:errno=0
openssl x509 -in -noout -issuer
Can't open -noout for reading, No such file or directory
140596603377024:error:02001002:system library:fopen:No such file or directory:../crypto/bio/bss_file.c:69:fopen('-noout','r')
140596603377024:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:76:
unable to load certificate
openssl x509 -in cert.pem -noout -issuer
issuer=C = US, O = (STAGING) Let's Encrypt, CN = (STAGING) Artificial Apricot R3
I finally did some verification of the certificate files:
europasprak#vps-3506b083:/etc/letsencrypt/live/europasprak.com$ openssl x509 -in cert.pem -noout -issuer
issuer=C = US, O = (STAGING) Let's Encrypt, CN = (STAGING) Artificial Apricot R3
europasprak#vps-3506b083:/etc/letsencrypt/live/europasprak.com$ openssl x509 -in chain.pem -noout -subject
subject=C = US, O = (STAGING) Let's Encrypt, CN = (STAGING) Artificial Apricot R3
europasprak#vps-3506b083:/etc/letsencrypt/live/europasprak.com$ openssl verify -untrusted chain.pem
(This command hangs indefinitely)
europasprak#vps-3506b083:/etc/letsencrypt/live/europasprak.com$ openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout
subject=CN = europasprak.com
issuer=C = US, O = (STAGING) Let's Encrypt, CN = (STAGING) Artificial Apricot R3
subject=C = US, O = (STAGING) Let's Encrypt, CN = (STAGING) Artificial Apricot R3
issuer=C = US, O = (STAGING) Internet Security Research Group, CN = (STAGING) Pretend Pear X1
subject=C = US, O = (STAGING) Internet Security Research Group, CN = (STAGING) Pretend Pear X1
issuer=C = US, O = (STAGING) Internet Security Research Group, CN = (STAGING) Doctored Durian Root CA X3
Looking at your certificate the Common Name (CN) and Organization (O) are incorrect as they both say Staging, they should say R3 and Let's Encrypt. When creating the certificate you specified --staging. Use the below command to generate a certificate.
sudo certbot ‐‐apache ‐d your_domain ‐d www.your_domain

TLS 1.2 with CloudFront default domain

I have created a CloudFront distribution to front some publicly accessible content from an S3 origin. This is all fine, but I need to set the minimum supported TLS version to 1.2.
It seems that the only way to do this is to import a custom SSL certificate and set the ViewerCertificate properties, specifically the MinimumProtocolVersion. I can have Certificate Manager issue a public cert but I don't want to have to register a domain. For the purpose of this content, I'm happy with the default cloudfront.net domain.
It seems like specifying the minimum TLS version should be supported by default. Am I missing something here?
Thanks,
John
This might not be supported forever, but it turns out you can import a bogus, self-signed certificate for the default domain. CloudFront will ignore it, but will enforce your TLS policy.
For example, I'm currently testing this on d2uwa7ugi8xf89.cloudfront.net -- configured with security policy TLSv1.2_2019. openssl s_client will show that it's vending the default certificate:
% openssl s_client -servername d2uwa7ugi8xf89.cloudfront.net -tls1_2 -connect d2uwa7ugi8xf89.cloudfront.net:443
CONNECTED(00000003)
depth=3 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Global CA G2
depth=0 C = US, ST = Washington, L = Seattle, O = "Amazon.com, Inc.", CN = *.cloudfront.net
---
Certificate chain
0 s:/C=US/ST=Washington/L=Seattle/O=Amazon.com, Inc./CN=*.cloudfront.net
i:/C=US/O=DigiCert Inc/CN=DigiCert Global CA G2
1 s:/C=US/O=DigiCert Inc/CN=DigiCert Global CA G2
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5
---
...
Attempt to connect with TLS 1.0 or TLS 1.1? No go:
% openssl s_client -servername d2uwa7ugi8xf89.cloudfront.net -tls1_1 -connect d2uwa7ugi8xf89.cloudfront.net:443
CONNECTED(00000003)
139725480863648:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:s3_pkt.c:1493:SSL alert number 70
139725480863648:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
...
This certificate was generated in the usual bogus self-signed certificate way:
openssl genrsa 2048 > cf.privkey
openssl req -new -subj /CN=d2uwa7ugi8xf89.cloudfront.net -key cf.privkey -out cf.csr
openssl x509 -in cf.csr -req -signkey cf.privkey -out cf.pem -days 99999

Not sure if self-signed ECDSA certificate generated programmatically complies for use with WebRTC and if fingerprint computation is correct

As should be clear, I am a newbie to certificates and cryptography in general.
I am trying to generate self-signed certificates programmatically for use with WebRTC in the implementation of a SFU. The RFC at Section 4.9, on the subject of certificates used for WebRTC, states:
The following values MUST be supported by a user agent: { name:
"RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new
Uint8Array([1, 0, 1]), hash: "SHA-256" }, and { name: "ECDSA",
namedCurve: "P-256" }.
After creating an ECDSA cert programmatically in C and saving it, I run the following command on the certificate file created:
openssl x509 -in /tmp/ecdsa_certificate -text #Linux command-line
I get the output:
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 1 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = IN, O = XYZ Tech., CN = localhost
Validity
Not Before: Jun 23 17:28:14 2020 GMT
Not After : Jun 23 17:28:14 2021 GMT
Subject: C = IN, O = XYZ Tech., CN = localhost
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:d9:c8:cc:93:13:54:3d:e6:40:d7:2f:33:da:f2:
d4:e4:62:83:a4:ec:ad:98:f5:d5:2e:cf:3b:e8:5f:
ad:da:b9:e0:59:f0:19:59:84:b8:47:45:b4:21:56:
30:c8:1d:0b:9b:2d:02:e2:f5:4d:c7:57:2e:e6:a6:
f9:c4:c4:a7:5c
ASN1 OID: secp256k1
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:58:0a:49:7d:e3:0f:d7:56:6a:5c:af:f8:bd:1d:
5e:54:bb:15:10:ec:05:3a:3a:db:79:8f:e6:70:86:6d:3d:f1:
02:20:4f:89:5f:df:21:46:1b:da:6b:40:04:98:2c:df:35:ff:
e5:3d:52:d5:07:76:bf:23:a4:01:b7:28:bf:f5:83:30
-----BEGIN CERTIFICATE-----
MIIBTTCB9QIBATAKBggqhkjOPQQDAjA1MQswCQYDVQQGEwJJTjESMBAGA1UECgwJ
WFlaIFRlY2guMRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwNjIzMTcyODE0WhcN
MjEwNjIzMTcyODE0WjA1MQswCQYDVQQGEwJJTjESMBAGA1UECgwJWFlaIFRlY2gu
MRIwEAYDVQQDDAlsb2NhbGhvc3QwVjAQBgcqhkjOPQIBBgUrgQQACgNCAATZyMyT
E1Q95kDXLzPa8tTkYoOk7K2Y9dUuzzvoX63aueBZ8BlZhLhHRbQhVjDIHQubLQLi
9U3HVy7mpvnExKdcMAoGCCqGSM49BAMCA0cAMEQCIFgKSX3jD9dWalyv+L0dXlS7
FRDsBTo623mP5nCGbT3xAiBPiV/fIUYb2mtABJgs3zX/5T1S1Qd2vyOkAbcov/WD
MA==
-----END CERTIFICATE-----
Does this certificate comply with the requirements of WebRTC for DTLS handshaking. It appears that only the public key and the fingerprint of the certificate matters for WebRTC usage.
Question 2:
I tried to compute the fingerprint over the certificate using the following function:
if (X509_digest(certificate, EVP_sha256(), rfingerprint, &fingerprintSize) !=0 )
printf("Error in X509_digest\n");
printf("finger print size is %d\n", fingerprintSize);
It displays a fingerprint size of only 7! In most of the SDPs I see that the fingerprint attribute is a lot longer. Any comments?
When working on Pion I was in the same boat as you asinix :) This is what I use to generate locally when testing WebRTC stuff.
openssl ecparam -out key.pem -name prime256v1 -genkey
openssl req -new -sha256 -key key.pem -out server.csr
openssl x509 -req -sha256 -days 365 -in server.csr -signkey key.pem -out cert.pem
If you get stuck you can also do RSA! Maybe just to unblock you on building your MVP :)
The implementation is Pure Go now, but you can see the first version where we did CGO here
I am not sure where your stuff differs, but feel free to copy/compare (no attribution needed)!

How can I detect if my service is using SSL or TLS and which version

There are options to specify TLS or SSL on weblogic server & webservers communicating [LISTENING] over HTTPS.
I do not have access to web or app server configurations, however i wish to determine if my connection to webserver [nginx, apache http webserver] or appserver [weblogic] over HTTPS is using SSL or TLS and which version of it.
If & how is it possible to determine ? Kindly suggest.
If you are not able to use some online tools for your service or your service is not hosted to public internet, then there are somethings that you can try.
You can use nmap as nmap -sV --script ssl-enum-ciphers -p <port> <host> to see what TLS versions and particularly what ciphers on which your server is responding.
If you don't have nmap or you are not allowed to install nmap on the system from your the service is reachable, then you can use some default tools to see what ciphers are available.
eg:
openssl: You can use openssl to connect to the server and you can specify the ssl ciphers in the command line.
eg:
$ openssl s_client -connect <host>:<port> -tls1_2 -cipher AES128-GCM-SHA256
If you see a successful connection, then you can be sure that the server is able to negotiate using that TLS version, TLSv1.2 in the example, and using that cipher, TLS_RSA_WITH_AES_128_GCM_SHA256 in the example.
You can find all the ciphers that are valid for openssl here. A sample run would look like this:
$ openssl s_client -connect example.com:443 -tls1_2 -cipher AES128-GCM-SHA256
CONNECTED(00000005)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
verify return:1
depth=0 C = US, ST = California, L = Los Angeles, O = Internet Corporation for Assigned Names and Numbers, OU = Technology, CN = www.example.org
verify return:1
---
Certificate chain
....
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHQDCCBiigAwIBAgIQD9B43Ujxor1NDyupa2A4/jANBgkqhkiG9w0BAQsFADBN
...
0Gs4+eH6F9h3SojmPTYkT+8KuZ9w84Mn+M8qBXUQoYoKgIjN
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Los Angeles/O=Internet Corporation for Assigned Names and Numbers/OU=Technology/CN=www.example.org
issuer=/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA
---
No client certificate CA names sent
---
SSL handshake has read 4297 bytes and written 408 bytes
---
New, TLSv1/SSLv3, Cipher is AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
...
TLS session ticket:
0000 - 57 04 cc 0f 69 dc 93 6c-e5 d6 50 0a 1c d0 d8 ce W...i..l..P.....
...
0090 - 9a 34 af 1e c2 09 cf 00-6d 68 36 41 09 40 de 0a .4......mh6A.#..
Start Time: 1558594372
Timeout : 7200 (sec)
Verify return code: 0 (ok)
---
curl: you can use curl to do the same thing. eg:
$ curl https://example.com --tlsv1.2 --ciphers AES128-GCM-SHA256 -w "%{http_code}\n" -o /dev/null -s
In this case, you will get the output as a valid response code, say 200 if the connection is successful and 000 is the Handshake failed, so you can differentiate using that.
Note: the TLS version supported in openssl and curl can be looked up by checking the --help in both cases. eg:
curl:
-1, --tlsv1 Use >= TLSv1 (SSL)
--tlsv1.0 Use TLSv1.0 (SSL)
--tlsv1.1 Use TLSv1.1 (SSL)
--tlsv1.2 Use TLSv1.2 (SSL)
--tlsv1.3 Use TLSv1.3 (SSL)
openssl:
-tls1_2 - just use TLSv1.2
-tls1_1 - just use TLSv1.1
-tls1 - just use TLSv1
-dtls1 - just use DTLSv1

OpenSSL Client-side Certificate-based Authentication Fails

I am trying to run the following command:
[root#localhost certs]# openssl s_client -connect localhost:7043 -cert /opt/openssl-1.0.0a/ssl/certwork_client/client.crt -key /opt/openssl-1.0.0a/ssl/certwork_client/client.key -CAfile /opt/openssl-1.0.0a/ssl/certwork/ca.crt -showcerts -state -verify 2
verify depth is 2
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=1 C = US, ST = Florida, L = Orlando, O = Company XYZ, OU = MyApp, CN = MyApp CA
verify return:1
depth=0 C = US, ST = Florida, L = Orlando, O = Company XYZ, OU = MyApp, CN = MyApp Manager Server
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server certificate request A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client certificate A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write certificate verify A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL3 alert read:fatal:unknown CA
SSL_connect:failed in SSLv3 read finished A
15238796:error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca:s3_pkt.c:1193:SSL alert number 48
15238796:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:184:
---
Certificate chain
0 s:/C=US/ST=Florida/L=Orlando/O=Company XYZ/OU=MyApp/CN=MyApp Manager Server
i:/C=US/ST=Florida/L=Orlando/O=Company XYZ/OU=MyApp/CN=MyApp CA
-----BEGIN CERTIFICATE-----
MIIFWDCCA0ACAQEwDQYJKoZIhvcNAQEFBQAwajELMAkGA1UEBhMCVVMxEDAOBgNV
BAgMB0Zsb3JpZGExEDAOBgNVBAcMB09ybGFuZG8xGDAWBgNVBAoMD0xvY2toZWVk
IE1hcnRpbjEMMAoGA1UECwwDTkNSMQ8wDQYDVQQDDAZOQ1IgQ0EwHhcNMTEwMzA4
MTc0MzQ3WhcNMjEwMzA1MTc0MzQ3WjB6MQswCQYDVQQGEwJVUzEQMA4GA1UECAwH
RmxvcmlkYTEQMA4GA1UEBwwHT3JsYW5kbzEYMBYGA1UECgwPTG9ja2hlZWQgTWFy
dGluMQwwCgYDVQQLDANOQ1IxHzAdBgNVBAMMFk5DUiBTQU4gTWFuYWdlciBTZXJ2
ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDYCut4DlfOcEXXyN1F
jNwyhEqLcdfQEDNWZDoQ/R3PfN3uTJGhYGuAgAIJZccYHF4BTTjZ5BA2u9ASYMJV
dUcCFU+mvCf3K6SzTG1/v46jBZz+C9OsQVZqc6UA/EmQKYzlDecvtukpQ6cquHBa
02JxBD3W2oZzdNWYZW6dn82YfzQGcySQhpFJMyyjf0baPV9wFKNqot7ZNiyusQTJ
g/GL8c29UJXHBYw15UMHm0dlDl2FREWEdNfbGbZCU+QTpyS059itkgmNQRKgNdBh
JpmRBJLp+iIk29JoKFJTyADR/QtIFnv/gl3P7FFvy1AZ+dGLQTHcf/MIFsbpf+s8
J7FtT+i/dCnLVDsz5e29jaSP32D0wAs66+I7ik4hOA0Eicaykwau19zkXpt1qScI
cb9ynjiGmoKzN+0ESm+S0Mr8+CgzTpfrNqDkJEgW8CQQqv8gzIYXgued+86omFvy
Qiq5ISeY13XrzbwX8NmFsByvAzWQ+emfkTF7A2HbGSpaeXWVUUqnT+BKeLk1uuGV
L8oWIGYJdjQiUGapjcU0uMxef8PKtJp3O40bqDSb5d7wONtwgEURr8583fo9415N
EMCkPiddgRet0TRATmNGgBpMpkOR5lf1WI4lgBRvHUFObbbwI7ByPyxifYtMwSFG
HVEz2MWol2cgQGWGG77nBaxPYQIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQALpEtS
b2j1eKXPzdjqB9cN0TDc87j49+dPJiinQqHvCqLN3sPpXIXeh/mPGWL71s/4pQmS
rMZwe/0vmOI5tCvUCM84xtbCW07UvtiBcOpvFjdoW9KfCvPiPiIiPs0FNUcaYcdZ
y+bxgCHDLnk3FnNW4ECqHHIpio6bvKOJKEBB1DE0kBxzv4ayqHVeRTIBahVeIun2
5XftPiScRQE+b4//qozyU9v3gzbQ1UuEFvYgWAlmllneiRw2oLpazIOrLi3YJbie
wnPnbT1wM4b/JpVUSw41NAlVY5W2OujCcQWHNAWu3UW8GE0pLTFPj/DSAV+rkb0f
l1anvsmKly5oTcxEhi4lV6VhWabsJYag5uXZMViBoUK4hZRTXIgylVrvSZWpFTgO
vgeheOT2IJ1pXJRzuuB7/8pwvqliGDIeIccwvBzlIuY9mTehyX+uAfKKQwQ0IGDG
exPIVySi4HZi6rPNbO6Q17Tz6HYdlr1NMri82lLiOgjzNH8yPHXMSYjqtT3bG9a2
YWjYeNWjFtcyVOb60UXQRf+ghc2TDBii8pZ4u9dbsVoenzevFHc+k/8Ku6RAeMjo
+BqB7wzS39jAL+AmOa3XM0GI7h3Wrj0sZs2D32VejECzn6xat+NGKE+oZH0d2RKs
eVA5Vo+zKcEFskiWWBdPhG3Flqn8pfvMLpqoDA==
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=Florida/L=Orlando/O=Company XYZ/OU=MyApp/CN=MyApp Manager Server
issuer=/C=US/ST=Florida/L=Orlando/O=Company XYZ/OU=MyApp/CN=MyApp CA
---
Acceptable client certificate CA names
/C=US/ST=Florida/L=Orlando/O=Company XYZ/OU=MyApp/CN=MyApp Client CA
---
SSL handshake has read 1615 bytes and written 3975 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID: 10AB798BBA57D06F61D0E970EF8919619942EC2A22131260C3718CA23ED75FD1
Session-ID-ctx:
Master-Key: D9EC43146764BAEE7E32A591C5A933914B57DA2EC479A6419EE3E822B3022E80E093798D1E17947159B7080F8AA80C85
Key-Arg : None
PSK identity: None
PSK identity hint: None
Start Time: 1299706827
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
In the server, I have the following code:
certificateFile = /opt/openssl-1.0.0a/ssl/certwork/server.crt
privatKeyFile = /opt/openssl-1.0.0a/ssl/certwork/server.key
ctx = Ctx::client_server(certificateFile, privateKeyFile);
ctx->context()->verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE;
ctx->context()->client_CA = SSL_load_client_CA_file("/opt/openssl-1.0.0a/ssl/certwork_client/ca.crt");
The context() calls methods in OpenSSL’s ssl.h.
I created the server CA (certificate authority) and server certificates with the following commands:
cd /opt/openssl-1.0.0a/ssl
mkdir certwork
chmod 600 certwork
cd certwork
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
openssl genrsa -des3 -out server.key 4096
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
I created the client CA and client certificates with the following commands:
cd /opt/openssl-1.0.0a/ssl
mkdir certwork_client
chmod 600 certwork_client
cd certwork_client
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
openssl genrsa -des3 -out client.key 4096
openssl req -new -key client.key -out client.csr
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
I can get server-side authentication to work via certificates, but when I add client-side authentication using certificates, I get tlsv1 alert unknown ca:s3_pkt.c:1193:SSL alert number 48 error.
I setup the client to use the server’s CA (/opt/openssl-1.0.0a/ssl/certwork/ca.crt) and I setup the server to use the client’s CA file (/opt/openssl-1.0.0a/ssl/certwork_client/ca.crt).
What am I missing?
It seems to me the server is rejecting the client certificate.
There are 3 different CA settings for TLS server:
The server chain provided to the client (SSL_CTX_add_extra_chain_cert)
The CAs you announce to support to the client (SSL_CTX_set_client_CA_list)
The CAs you actually use to verify (SSL_CTX_load_verify_locations)
You might be configuring your server with the wrong equivalent in your bindings.
Have you tested with openssl s_server ?
what do you mean "I can get server-side authentication to work" ? Normally the server-side authentication is the last one; first the client verify the identity of your server, and then it send its certificate to server.
If the client recognized your server, it mean your client have CA certificate that signed the certificate of your server, OR your server certificate.
If the server doesn't recognize your client, check your server's truststore (in JAVA), or your CACertificateFile in your apache2 configuration ...
Hope it helps
I had this problem before. It turned out that I hadn't created the correct certificate, key and signature. This quick start guide was all I needed to create them.