SSL_connect:error in SSLv3 read server hello A [duplicate] - ssl

I am running Windows Vista and am attempting to connect via https to upload a file in a multi part form but I am having some trouble with the local issuer certificate. I am just trying to figure out why this isnt working now, and go back to my cURL code later after this is worked out. Im running the command:
openssl s_client -connect connect_to_site.com:443
It gives me an digital certificate from VeriSign, Inc., but also shoots out an error:
Verify return code: 20 (unable to get local issuer certificate)
What is the local issuer certificate? Is that a certificate from my own computer? Is there a way around this? I have tried using -CAfile mozilla.pem file but still gives me same error.

I had the same problem and solved it by passing path to a directory where CA keys are stored. On Ubuntu it was:
openssl s_client -CApath /etc/ssl/certs/ -connect address.com:443

Solution:
You must explicitly add the parameter -CAfile your-ca-file.pem.
Note: I tried also param -CApath mentioned in another answers, but is does not works for me.
Explanation:
Error unable to get local issuer certificate means, that the openssl does not know your root CA cert.
Note: If you have web server with more domains, do not forget to add also -servername your.domain.net parameter. This parameter will "Set TLS extension servername in ClientHello". Without this parameter, the response will always contain the default SSL cert (not certificate, that match to your domain).

This error also happens if you're using a self-signed certificate with a keyUsage missing the value keyCertSign.

Is your server configured for client authentication? If so you need to pass the client certificate while connecting with the server.

I had the same problem on OSX OpenSSL 1.0.1i from Macports, and also had to specify CApath as a workaround (and as mentioned in the Ubuntu bug report, even an invalid CApath will make openssl look in the default directory).
Interestingly, connecting to the same server using PHP's openssl functions (as used in PHPMailer 5) worked fine.

put your CA & root certificate in /usr/share/ca-certificate or /usr/local/share/ca-certificate.
Then
dpkg-reconfigure ca-certificates
or even reinstall ca-certificate package with apt-get.
After doing this your certificate is collected into system's DB:
/etc/ssl/certs/ca-certificates.crt
Then everything should be fine.

With client authentication:
openssl s_client -cert ./client-cert.pem -key ./client-key.key -CApath /etc/ssl/certs/ -connect foo.example.com:443

Create the certificate chain file with the intermediate and root ca.
cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
chmod 444 intermediate/certs/ca-chain.cert.pem
Then verfify
openssl verify -CAfile intermediate/certs/ca-chain.cert.pem \
intermediate/certs/www.example.com.cert.pem
www.example.com.cert.pem: OK
Deploy the certific

I faced the same issue,
It got fixed after keeping issuer subject value in the certificate as it is as subject of issuer certificate.
so please check "issuer subject value in the certificate(cert.pem) == subject of issuer (CA.pem)"
openssl verify -CAfile CA.pem cert.pem
cert.pem: OK

I got this problem when my NGINX server did not have a complete certificate chain in the certificate file it was configured with.
My solution was to find a similar server and extract the certificates from that server with something like:
openssl s_client -showcerts -CAfile my_local_issuer_CA.cer -connect my.example.com:443 > output.txt
Then I added the ASCII armoured certificates from that 'output.txt' file (except the machine-certificate) to a copy of my machines certificate-file and pointed NGINX at that copied file instead and the error went away.

this error messages means that
CABundle is not given by (-CAfile ...)
OR
the CABundle file is not closed by a self-signed root certificate.
Don't worry. The connection to server will work even
you get theis message from openssl s_client ...
(assumed you dont take other mistake too)

I would update #user1462586 answer by doing the following:
I think it is more suitable to use update-ca-certificates command, included in the ca-certificates package than dpkg-reconfigure.
So basically, I would change its useful answer to this:
Retrieve the certificate (from this stackoverflow answer and write it in the right directory:
# let's say we call it my-own-cert.crt
openssl s_client -CApath /etc/ssl/certs/ -connect <hostname.domain.tld>:<port> 2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /usr/share/ca-certificates/my-own-cert.crt
Repeat the operation if you need other certificates.
For example, if you need CA certs for ldaps/starttls with Active Directory, see here for how to process this + use openssl to convert it in pem/crt:
openssl x509 -inform der -in LdapSecure.cer -out my-own-ca.pem
#and copy it in the right directory...
cp my-own-ca.pem /usr/share/ca-certificates/my-own-ca.crt
Add this certificates to the /etc/ca-certificates.conf configuration file:
echo "my-own-cert.crt" >> /etc/ca-certificates.conf
echo "my-own-ca.crt" >> /etc/ca-certificates.conf
Update /etc/ssl/certs directory:
update-ca-certificate
Enjoy
Note that if you use private domain name machines, instead of legitimate public domain names, you may need to edit your /etc/hosts file to be able to have the corresponding FQDN.

This is due to SNI Certificate binding issue on the Vserver or server itself

Related

getting ` x509: certificate signed by unknown authority` error while verifying certificates for rest application

I am generating a self signed certificate using openssl in Ubuntu. I want to use it for localhost rest server. But while verification, I am getting error : x509: certificate signed by unknown authority, can anyone please tell me how I can resolve this error?
Thanks!
Place your root certificate and intermediate (if you have one) in /usr/share/local/ca-certificates with the .crt extension.
Run:
sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
In this case, curl is your friend:
curl -Iv https://localhost/path/to/api
Also you can run openssl s_client
openssl s_client localhost:443
Additionally, you can interrogate your certificate by providing your certificate:
openssl s_client -connect localhost:443 -CAfile /path/to/your/cert.pem
If you certificate does not match, you know. Possibly you are using the wrong certificate for your REST API or the certificate is not being installed, which you can verify by looking in /etc/ssl/certs directory on your system (if you are running Linux)
Place your .crt certificate to /usr/share/ca-certificates
Edit /etc/ca-certificates.conf and add your certificate name there.
(Look at update-ca-certificates man page for more information.)
Then run sudo update-ca-certificates
Works for me in Ubuntu 22

Openssl Client Certificates [duplicate]

I am developing a client/server application with TLS. My idea is to use a certificate on the client so it is authenticated by the server. Also another certificate on the server so the client is also able to authenticate that it is connecting to the right server.
I want first to test and use openssl s_server and openssl s_client to validate the proposal.
Until now I have created a CA private key on the server, I have created a root certificate. With the root certificate I have signed two CSR, so I get one certificate for the server and one certificate for the client.
I also have installed the client certificate + root certificate on the client, and the server certificate + root certificate on the server.
I want now to try to establish a connection between openssl s_server and openssl s_client and verify that they get both authenticated mutually, but I cannot wrap my mind with the documentation on how to do it. Any help or any guide on that?
Once I have that set up, the next step is to test the own developed client against that server, and our own developed server against the s_client. Can we use that for testing?
Thanks
It looks like you are trying to set up a root of trust with (1) s_client and s_server for testing; and (2) programmatically within your code using OpenSSL.
To ensure openssl s_client (or openssl s_server) uses your root, use the following options:
-CAfile option to specify the root
-cert option for the certificate to use
-key option for the private key of the certificate
See the docs on s_client(1) and s_server(1) for details.
To do the same programmatically on the client, you would use:
SSL_CTX_load_verify_locations to load the trusted root
SSL_CTX_use_certificate to specify the client certificate
SSL_CTX_use_PrivateKey to load the private key for the client certificate
To do the same programmatically on the server, you would use:
SSL_CTX_load_verify_locations to load the trusted root
SSL_CTX_use_certificate_chain_file to specify the server certificate
SSL_CTX_use_PrivateKey to load the private key for the server certificate
SSL_CTX_set_client_CA_list to tell the client to send its client certificate
If you don't want to use the parameters for every connection (i.e. the common context), then set it for each SSL connection with, for example, SSL_use_certificate and SSL_use_PrivateKey.
A lot goes on with SSL_CTX_set_client_CA_list. It (1) loads the CA's to the server uses to verify a client, (2) it causes the server to send a list of CAs it accepts when verifing a client, and (3) it triggers the ClientCertificate message at the client if the client has a certificate that satisfies the server's accepted CAs list.
Also see the docs on SSL_CTX_load_verify_locations(3), SSL_CTX_use_certificate(3), SSL_CTX_set_client_CA_list and friends.
The easiest certificate and key format to use is PEM. PEM is the one that uses, for example, ----- BEGIN CERTIFICATE -----. For the server certificate, be sure the file is a concatenation of the server's certificate and any intermediates needed by the client to build the chain.
Having the server send all required certificates is standard practice for a problem known as the "which directory" problem. Its a well known problem in PKI, and its essentially the problem that clients don't know where to go to fetch missing intermediate certificates.
In general, you now know the functions that you need to use. Download a small server like nginx, and see how a production server uses them in practice. You could even use a SQL server like Postgres since it sets up a SSL/TLS server. Simply search the source files for SSL_CTX_load_verify_locations or SSL_load_verify_locations, and you will find the right place.
Though I don't recommend it, you could even look at s_client.c and s_server.c. They are located in <openssl dir>/apps. But the code can be difficult to read at times.
Generate two pairs of certificates/keys, one for the server and one for the client. Also create test.txt with any content.
To set up an SSL server that checks a client certificate, run the following command:
openssl s_server -cert server_cert.pem -key server_key.pem -WWW -port 12345 -CAfile client_cert.pem -verify_return_error -Verify 1
To test the server with client certificate, run the following command:
echo -e 'GET /test.txt HTTP/1.1\r\n\r\n' | openssl s_client -cert client_cert.pem -key client_key.pem -CAfile server_cert.pem -connect localhost:12345 -quiet
Alternatively you can use curl command:
curl -k --cert client_cert.pem --key client_key.pem https://localhost:12345/test.txt

HTTPS issue "Your connection is not private", Ngnix

I'm trying to get HTTPS work on all subdomains using"Nginx", but receive:
This server could not prove that it is api.wokcraft.com; its security certificate is not trusted by your computer's operating system. This may be caused by a misconfiguration or an attacker intercepting your connection.
URL: https://api.wokcraft.com/
Can any one inform what missing?
thx
edit: I followed this instructions: https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/1091/0/certificate-installation--nginx
Nginx doesn't send the correct list of intermediate certificates: https://www.ssllabs.com/ssltest/analyze.html?d=api.wokcraft.com&latest
Create the correct bundle:
You want to create Comodo Bundle this way (replacing your_cert with actual name of your file):
cat your_cert.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > your_cert.ca-bundle
Get the new ca-bundle onto your server
Once that is done copy this to your server as in the Nginx set it this way:
ssl_certificate /your/ssl/path/your_cert.ca-bundle;
ssl_certificate_key /your/ssl/path/your_cert_privateKey.key;
Verify the cert and key are matching after they have been copied (compare md5 hashes).
openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in privateKey.key | openssl md5
Test the config (need to run as sudo):
sudo nginx -t
If no errors, reload nginx and re-run you SSLlabs check:
https://www.ssllabs.com/ssltest/analyze.html?d=api.wokcraft.com

openssl unable to get local issuer certificate debian

I can not verify the certificate by openssl
openssl verify cert.pem
Gets something like this:
cert.pem: / C = PL / O = DATA
error 20 at 0 depth lookup: unable to get local issuer certificate
The same cert from the machine on Centos - verified correctly.
Debian: squeeze / sid
Is it a problem with the CA ROOT? Update openssl help?
Unlike browsers, which trust nearly everything from anybody, OpenSSL trusts nothing by default.
Its up to you to determine what should be trusted. You will have to specify something when using OpenSSL. It may be a cert or list of certs to trust.
The directory /etc/ssl/certs contains many certs. Using such directory should allow to verify almost anything:
openssl verify -CApath /etc/ssl/certs cert.pem
It is recommended that you reduce the number of trusted certs to one, two or the minimum possible.
You need to specify the CA cert in order to verify the issued cert since it's obviously not included in the pem (though this would be possible):
openssl verify -CAfile your_ca_cert_file cert.pem
If you do not get the error on centOS then there's the CA cert around and openssl can use it to successfully verify cert.pem
You need to make your CA trusted on the server. For example, if your cert is from goadday, run the following commands.
cd /tmp
sudo wget -O gd_intermediate.crt https://certs.godaddy.com/repository/gd_intermediate.crt
sudo cp /tmp/gd_intermediate.crt /usr/local/share/ca-certificates/gd_intermediate.crt
sudo update-ca-certificates
After running these commands, your certificate should be verified.
openssl verify cert.pem

Testing SSL/TLS Client Authentication with OpenSSL

I am developing a client/server application with TLS. My idea is to use a certificate on the client so it is authenticated by the server. Also another certificate on the server so the client is also able to authenticate that it is connecting to the right server.
I want first to test and use openssl s_server and openssl s_client to validate the proposal.
Until now I have created a CA private key on the server, I have created a root certificate. With the root certificate I have signed two CSR, so I get one certificate for the server and one certificate for the client.
I also have installed the client certificate + root certificate on the client, and the server certificate + root certificate on the server.
I want now to try to establish a connection between openssl s_server and openssl s_client and verify that they get both authenticated mutually, but I cannot wrap my mind with the documentation on how to do it. Any help or any guide on that?
Once I have that set up, the next step is to test the own developed client against that server, and our own developed server against the s_client. Can we use that for testing?
Thanks
It looks like you are trying to set up a root of trust with (1) s_client and s_server for testing; and (2) programmatically within your code using OpenSSL.
To ensure openssl s_client (or openssl s_server) uses your root, use the following options:
-CAfile option to specify the root
-cert option for the certificate to use
-key option for the private key of the certificate
See the docs on s_client(1) and s_server(1) for details.
To do the same programmatically on the client, you would use:
SSL_CTX_load_verify_locations to load the trusted root
SSL_CTX_use_certificate to specify the client certificate
SSL_CTX_use_PrivateKey to load the private key for the client certificate
To do the same programmatically on the server, you would use:
SSL_CTX_load_verify_locations to load the trusted root
SSL_CTX_use_certificate_chain_file to specify the server certificate
SSL_CTX_use_PrivateKey to load the private key for the server certificate
SSL_CTX_set_client_CA_list to tell the client to send its client certificate
If you don't want to use the parameters for every connection (i.e. the common context), then set it for each SSL connection with, for example, SSL_use_certificate and SSL_use_PrivateKey.
A lot goes on with SSL_CTX_set_client_CA_list. It (1) loads the CA's to the server uses to verify a client, (2) it causes the server to send a list of CAs it accepts when verifing a client, and (3) it triggers the ClientCertificate message at the client if the client has a certificate that satisfies the server's accepted CAs list.
Also see the docs on SSL_CTX_load_verify_locations(3), SSL_CTX_use_certificate(3), SSL_CTX_set_client_CA_list and friends.
The easiest certificate and key format to use is PEM. PEM is the one that uses, for example, ----- BEGIN CERTIFICATE -----. For the server certificate, be sure the file is a concatenation of the server's certificate and any intermediates needed by the client to build the chain.
Having the server send all required certificates is standard practice for a problem known as the "which directory" problem. Its a well known problem in PKI, and its essentially the problem that clients don't know where to go to fetch missing intermediate certificates.
In general, you now know the functions that you need to use. Download a small server like nginx, and see how a production server uses them in practice. You could even use a SQL server like Postgres since it sets up a SSL/TLS server. Simply search the source files for SSL_CTX_load_verify_locations or SSL_load_verify_locations, and you will find the right place.
Though I don't recommend it, you could even look at s_client.c and s_server.c. They are located in <openssl dir>/apps. But the code can be difficult to read at times.
Generate two pairs of certificates/keys, one for the server and one for the client. Also create test.txt with any content.
To set up an SSL server that checks a client certificate, run the following command:
openssl s_server -cert server_cert.pem -key server_key.pem -WWW -port 12345 -CAfile client_cert.pem -verify_return_error -Verify 1
To test the server with client certificate, run the following command:
echo -e 'GET /test.txt HTTP/1.1\r\n\r\n' | openssl s_client -cert client_cert.pem -key client_key.pem -CAfile server_cert.pem -connect localhost:12345 -quiet
Alternatively you can use curl command:
curl -k --cert client_cert.pem --key client_key.pem https://localhost:12345/test.txt