Openssl certificate verification stricter/different than browsers? [duplicate] - ssl

This question already has answers here:
SSL working in chrome but sometimes in Firefox and not on IOS, Android or Blackberry
(2 answers)
Closed 1 year ago.
I've put together a Linux (Centos 7) server to serve eye-n-sky.net.
Serving content from that site to browsers on Win10 and Linux systems works beautifully. However, when I use openssl to access the site,
openssl s_client -connect eye-n-sky.net:443
the site certificate is rejected,
Verify return code: 21 (unable to verify the first certificate)
I've concluded that the way a browser verifies the certificate is different from what openssl does. Am I on the right track?
I've tested this on three different openssl instances (Debian, Centos, FreeBSD) and have consistent results.
Openssl as a client to other sites, e.g. www.godaddy.com, microsoft.com, work fine, being able to verify the certificate against the installed CA chain.
Believing that I was missing a CA cert, I used the -CAfile option to specify the possibly missing cert, to no effect.
What am I missing? I'm guessing that openssl has a stricter verification discipline, but I don't know where that gets configured.
Thanks,
Andy
Summary: yes, eye-n-sky was providing only it's cert when it needed to include the intermediate and root certs.
However, it took me forever to figure out that my Apache version did not support including the chain in the server cert file. Instead, I had to provide the chain file separately in an SSLCertificateChainFile directive.

OpenSSL's command-line s_client utility has nothing built in to validate the server's certificate. Browsers have a built-in list of trusted certificates to verify the server certificate against.
You have to supply the trusted certificates using options such as -CAfile file or -CApath directory. Per the OpenSSL 1.1.1 s_client man page:
-CApath directory
The directory to use for server certificate verification. This
directory must be in "hash format", see verify(1) for more
information. These are also used when building the client certificate
chain.
-CAfile file
A file containing trusted certificates to use during server
authentication and to use when attempting to build the client
certificate chain.
Note the use of words such as "certificate chain". If you go to godaddy.com you'll see that the server's cert is for *.godaddy.com, but it was signed by Go Daddy Secure Certificate Authority - G2, and that intermediate certificate was signed by Go Daddy Root Certificate Authority - G2 - a different certificate. There's a total of three certificates in that chain.
Verify return code 21 is "no signatures could be verified because the chain contains only one certificate and it is not self signed", so if your CA file only had the certificate from Go Daddy Root Certificate Authority - G2 and not the one from Go Daddy Secure Certificate Authority - G2, OpenSSL would see from the server's cert itself that it was signed by Go Daddy Secure Certificate Authority - G2 and could go no further - it doesn't have that cert to see who signed it.

Related

Root Certificate of website through openssl command

I am trying to obtain the root certificate of various websites for my project, but I am not sure the certificates that I am getting back with this command, contains root certificate or not?
openssl s_client -showcerts -connect google.com:443
I was searching for an answer when I came across a post where wget was used to get the root certificate from the certificate repository of godaddy
wget https://certs.godaddy.com/repository/gd_bundle.crt -O ~/.cert/mail.nixcraft.net/gd.pem
how do i find the repository for every website?
The server must include the certification chain during TLS connection (https). The chain may include the CA root certificate, but it is optional, So you have no guarantee that it will be available. The TLS protocol expects the client to have the certificate in their truststore to verify the trust
You can download the server certificate of every site programmatically, but it is needed to look for the root CA certificate. As you can see, godaddy publish them in its website. In many cases the certificate itself includes a reference to download the root certificate

Self-signed wilcard certificate not working for Firefox

Generate self-signed root certificate using makecert.exe and imported in Trusted Root Certification Authorities.
Since, Mozilla Firefox has it own list of Certification Authority (CA) certificates,
imported self-signed certificate into Firefox's Authority certificates list.
Generate derived certificate with CN=*.test.com
Setup proxy server which uses self-signed certificate.
Browsing something.test.com with Internet Explorer and Chrome, certificate is accepted and no security issue warning is shown. Firefox shows error message
'something.test.com uses an invalid security certificate.
The certificate is only valid for *.test.com
(Error code: ssl_error_bad_cert_domain)'.
Problem seems to be about using wildcard in CN, because if i generate derived certificate with CN=something.test.com no error is shown for none of the browsers.
Solved problem by using Multi-Domain (SAN) Certificate.
makecert.exe is unable to generate SAN Certificate. at least i can't find out how.
Used OpenSSL to generate SAN Certificate and it worked.
OpenSSL PKI Tutorial is good resource to know how generate SAN Certificate.

How to generate intermediate and root cert from an existing leaf certificate?

Now i have a X509 leaf certificate. From the certification path to see, there's a intermediate cert and a root cert in it.
I want to generate the intermediate cert(..CA- G3) and the root cert(VerSign). Currently, my way is to double click the intermediate one and then click "Copy to file.." to export it. Do same for the root one too. Is this way to correct to generate intermediate/root certs?
From my test result, it seems the generated root cert with wrong fingerprint. The fingerpring doesn't match the one on server side.
Anyone can help on how to generate intermediate/root certs correctly?
You have fundamental misunderstanding of certificates and certificate chains.
CA and Root certificates are searched for and found, not generated.
Some certificates include location of their CA certificate in the body of the certificate (in special certificate extension). For others you need to look in your CA certificates storage (this is what Windows does). Sometimes chains are sent together with end-entity certificate (depending on data format). Finally, sometimes CA and Root are just not available.
[supply the answer... , maybe this is an alternative approach to get all certs that the SSL server using]
To retrieve the ntermediate and root certs by OpenSSL command:
openssl s_client -showcerts -connect [host]:[port]

OpenSSL: unable to verify the first certificate for Experian URL

I am trying to verify an SSL connection to Experian in Ubuntu 10.10 with OpenSSL client.
openssl s_client -CApath /etc/ssl/certs/ -connect dm1.experian.com:443
The problem is that the connection closes with a Verify return code: 21 (unable to verify the first certificate).
I've checked the certificate list, and the Certificate used to sign Experian (VeriSign Class 3 Secure Server CA - G3) is included in the list.
/etc/ssl/certs/ca-certificates.crt
Yet I don't know why it is not able to verify the first certificate.
The entire response could be seen here:
https://gist.github.com/1248790
The first error message is telling you more about the problem:
verify error:num=20:unable to get local issuer certificate
The issuing certificate authority of the end entity server certificate is
VeriSign Class 3 Secure Server CA - G3
Look closely in your CA file - you will not find this certificate since it is an intermediary CA - what you found was a similar-named G3 Public Primary CA of VeriSign.
But why does the other connection succeed, but this one doesn't? The problem is a misconfiguration of the servers (see for yourself using the -debug option). The "good" server sends the entire certificate chain during the handshake, therefore providing you with the necessary intermediate certificates.
But the server that is failing sends you only the end entity certificate, and OpenSSL is not capable of downloading the missing intermediate certificate "on the fly" (which would be possible by interpreting the Authority Information Access extension). Therefore your attempt fails using s_client but it would succeed nevertheless if you browse to the same URL using e.g. FireFox (which does support the "certificate discovery" feature).
Your options to solve the problem are either fixing this on the server side by making the server send the entire chain, too, or by passing the missing intermediate certificate to OpenSSL as a client-side parameter.
Adding additional information to emboss's answer.
To put it simply, there is an incorrect cert in your certificate chain.
For example, your certificate authority will have most likely given you 3 files.
your_domain_name.crt
DigiCertCA.crt # (Or whatever the name of your certificate authority is)
TrustedRoot.crt
You most likely combined all of these files into one bundle.
-----BEGIN CERTIFICATE-----
(Your Primary SSL certificate: your_domain_name.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Your Intermediate certificate: DigiCertCA.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Your Root certificate: TrustedRoot.crt)
-----END CERTIFICATE-----
If you create the bundle, but use an old, or an incorrect version of your Intermediate Cert (DigiCertCA.crt in my example), you will get the exact symptoms you are describing.
SSL connections appear to work from browser
SSL connections fail from other clients
Curl fails with error: "curl: (60) SSL certificate : unable to get local issuer certificate"
openssl s_client -connect gives error "verify error:num=20:unable to get local issuer certificate"
Redownload all certs from your certificate authority and make a fresh bundle.
I came across the same issue installing my signed certificate on an Amazon Elastic Load Balancer instance.
All seemed find via a browser (Chrome) but accessing the site via my java client produced the exception javax.net.ssl.SSLPeerUnverifiedException
What I had not done was provide a "certificate chain" file when installing my certificate on my ELB instance (see https://serverfault.com/questions/419432/install-ssl-on-amazon-elastic-load-balancer-with-godaddy-wildcard-certificate)
We were only sent our signed public key from the signing authority so I had to create my own certificate chain file. Using my browser's certificate viewer panel I exported each certificate in the signing chain. (The order of the certificate chain in important, see https://forums.aws.amazon.com/message.jspa?messageID=222086)
Here is what you can do:-
Exim SSL certificates
By default, the /etc/exim.conf will use the cert/key files:
/etc/exim.cert
/etc/exim.key
so if you're wondering where to set your files, that's where.
They're controlled by the exim.conf's options:
tls_certificate = /etc/exim.cert
tls_privatekey = /etc/exim.key
Intermediate Certificates
If you have a CA Root certificate (ca bundle, chain, etc.) you'll add the contents of your CA into the exim.cert, after your actual certificate.
Probably a good idea to make sure you have a copy of everything elsewhere in case you make an error.
Dovecot and ProFtpd should also read it correctly, so dovecot no longer needs the ssl_ca option.
So for both cases, there is no need to make any changes to either the exim.conf or dovecot.conf(/etc/dovecot/conf/ssl.conf)
If you are using MacOS use:
sudo cp /usr/local/etc/openssl/cert.pem /etc/ssl/certs
after this Trust anchor not found error disappears
For those using zerossl.com certificates, drag and drop all certificates (as is) to their respective folders.
Cut and pasting text into existing files, may cause utf8 issues - depending upon OS, format and character spacings.

Having issues using existing Entrust certificates for Jetty SSL connection

I have three files from Entrust: *.csr, *.key and *.crt.
So far:
I have brought the *.key and *.crt into a PKCS12 keystore using OpenSSL
I have imported the *.pkcs12 into a keystore using keytool
Using this technique, I am able to use an SSL connection with Jetty
However, I'm getting a Certificate Error in IE (unsecured items in Chrome).
In our case, the certificates are currently being used for domain:80 (Apache) and I'm attempting to "reuse" them for domain:8443 (Jetty).
Am I wrong in thinking that I can use these for Jetty as well? On the same IP/domain, but on a different port and webserver? My gut is telling me that one of these files relates to Entrust recognizing Apache (*.csr) and that I should have to do the same for Jetty?
Edit #1
The error goes as follow:
Certificate Error
Untrusted Certificate
The security certificate presented by this webiste was not issued by a trusted certificate authority
This problem may indicate an attempt to fool you or intercept any data you send to the server.
We recommend that you close this webpage.
But yet Chrome, sees it as valid. I does have to work on IE since it's our standard.
Edit #2
Chrome doesn't complain
Nor does Firefox
Edit #3
I found our CA certificate specified in the Apache conf file. I then proceeded to concatenate our cert with the CA cert into a PKCS12 file. Then, using keytool, I generated the keystore.
I loaded it on the server, rebooted and viewed in IE. IE still shows a certificate issue.
In the concatenated file, I see in this order: our cert and then 2 other certificates.
On a side note, I called Entrust and the CSR saw no problems as he was using IE 8. We're on IE7.
Edit #4
Using this command:
keytool -list -keystore keystore -v
It shows 3 certificates (in this order):
Ours
Owner: CN=Entrust Certification Authority - L1C,
Owner: CN=Entrust.net Certification Authority (2048)
Edit 5
Solved! I guess I had a caching issue. Confirmed with colleagues.
Answer, Concatenating all my certs, including the CA cert, into the keystore solved my issue.
The port number, as stated in the comments, is irrelevant for trusting an SSL/TLS connection.
The problem is that the entire certificate chain from your certificate up to the Entrust root probably looks like this
your cert - intermediate CA 1 - intermediate CA 2 - ... - root CA
To make this work for IE you have to import not only your certificate into the PKCS#12 container, but additionally the intermediate certificates and also the root certificate. Otherwise your SSL implementation won't be able to provide the full path during the SSL handshake and thus IE has no means to build a proper chain to compare to its set of trusted root certificates.
So my advise would be to get the intermediate certificates from the appropriate web sites and importing them with keytool into your PKCS#12 key store.
Once done, IE should from then on accept without complaining.