Root Certificate of website through openssl command - ssl

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

Related

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

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.

Unable To Trust Self-Signed SSL Certificate

I have an application running on Centos7 that needs to connect to a remote host over HTTPS. However, it is unable to verify the certificate and fails. Also, if I try to download a file from the server using wget, I get the below error:
[root#foo:~]# wget https://10.65.127.9/index.html
--2017-05-22 09:03:01-- https://10.65.127.9/index.html
Connecting to 10.65.127.9:443... connected.
ERROR: cannot verify 10.65.127.9's certificate, issued by ‘/CN=us6877vnxe7827’:
Unable to locally verify the issuer's authority.
To connect to 10.65.127.9 insecurely, use `--no-check-certificate'.
So I get the certificate from the host:
openssl s_client -connect 10.65.127.9:443 <<<'' | openssl x509 -out /etc/pki/ca-trust/source/anchors/mycert.pem
And execute the following to process it:
update-ca-trust extract
This however results in the same issue.. If I run:
openssl s_client -connect 10.65.127.9:443 -showcerts -debug
I do get some errors and various messages:
depth=0 CN = us6877vnxe7827
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = us6877vnxe7827
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=us6877vnxe7827
i:/CN=us6877vnxe7827
Server certificate
subject=/CN=us6877vnxe7827
issuer=/CN=us6877vnxe7827
---
No client certificate CA names sent
---
Verify return code: 21 (unable to verify the first certificate)
Any ideas what I may be missing? If any further info helps, please let me know.
For wget you need to provide the certificate authority (CA) certificate(s) that signed the https server certificate. If you have those CA certificates - add them under --ca-certificate=file or --ca-directory=directory options
If you don't have them and you want to skip https server certificate verification (unsecure and can be dangerous) then use --no-check-certificate option.
I had the same problem with Jenkins trying to connect to our GitLab server.
The server does have a valid official certificate in our case, but Java didn't except it.
You are right about downloading the certificate.
However, the application you are mentioning is probably running inside a Java Virtual Machine (as a lot of applications are).
So from the point that you downloaded the certificate to a PEM file, you may have to add it to the VM's trusted certificates instead.
This article describes how to do that. Hope it helps.

Checking server certificate with openssl versus a web request

Working with a standard MediaTemple server setup with an installed GeoTrust domain certificate I am getting different responses from openssl and web requests.
Visiting the site from a site checker site I get a good response and see my domain certificate and the full Geotrust certificate chain.
When using
openssl s_client -connect subdomain.domain.com:443 -showcerts -ssl3
from my local machine I see
Server certificate
subject=/C=US/ST=Virginia/L=Herndon/O=Parallels/OU=Parallels
Panel/CN=Parallels Panel/emailAddress=info#parallels.com
issuer=/C=US/ST=Virginia/L=Herndon/O=Parallels/OU=Parallels Panel/CN=Parallels
Panel/emailAddress=info#parallels.com
and Verify return code: 18 (self signed certificate)
openssl version -d = OPENSSLDIR: "/etc/pki/tls"
It's a Centos 6.x box.
The apache httpd.conf file points to a certificate and CA list in a completely different location: /usr/local/psa/var/certificates/ which would seem fine to me.
Where is the openssl s_client finding the Parallels certificate? It is not located in /etc/pki/tls. Is there a way to configure the box so that the openssl requests and apache use the same server certificate?
Thanks in advance!
openssl s_client gets the certificate from the server during the SSL handshake. OPENSSLDIR is only the place where any (optional) configurations for the openssl tool gets stored.
Note that you might get a different certificate with openssl than you have configured on your server because you need to use SNI (Server Name Indication) like the browser do. This feature is used if you have multiple certificates behind the same IP. To use this feature with openssl add the -servername hostname parameter and provide the name you expect. You must also remove the -ssl3 option since this restricts the connection to SSL 3.0 which is not only insecure but also does not support SNI.
Turns out that on MediaTemple servers they maintain certs in two locations. The apache server has a location for the CA file in its conf files that is different from where openssl maintains its CA files.
You can find the apache location in the conf files and the openssl location with
openssl version -d
Within MediaTemple's web administration pages you can use plesk to install the domain cert into the openssl location as the "server's" cert. The apache server should already have the cert and CA files in the right location. The MediaTemple custom apache configuration overrides the standard apache setup which sets apache's cert locations to be the same as openssl's.

WCF error "The X.509 certificate chain building failed" despite trusted root CA

I'm getting the error mentioned in this question:
The X.509 certificate CN=Farm chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust.
What I don't understand why I'm getting this error as the certificate I use for my request to the WCF service is added as shown below:
client.ClientCredentials.Peer.PeerAuthentication.CertificateValidationMode =
X509CertificateValidationMode.ChainTrust;
client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySerialNumber,
"MyCertificatesSerialNumber" );
The certificate itself is a self-signed certificate in the store shown above. When I click on it to show the certification path, no errors are shown (the root certificate is also a self-signed certificate). The root certificate was manually imported into the trusted root certification authorities.
From the error message I would have expected that there was an error in the certification chain with one of my certificates, but there isn't. Any ideas?
Update
I'm using Internet Explorer 9 as my browser to access the webservice. Programmatically I'm using a C# console application.
I had exactly the same problem - my own trusted root CA which signed another certificate. No errors were shown in the certificate store.
It turned out that having a trusted root CA and a certificate is not sufficient! You also need a certificate revocation list! Take a look at this MSDN Link.
So simply create such a .crl and add it also to the trusted root certificate authorities and everything works fine!
makecert -crl -n "CN=CARoot" -r -sv CARoot.pvk CARoot.crl
or simply turn of the revocation list check:
...RevocationMode = X509RevocationMode.NoCheck;
I had this problem - this is what I'd suggest:
On the server, make sure that the root cert is located on the "local computer" side of the computer, not "Current User". The other thing is that the SSL cert needs to be derived from the root cert. I eventually got it all to work using a script that included these lines:
rem creates root authority file and cert in localmachine\root and gives it the right to sign certs
makecert.exe -a sha1 -n CN=RootCert RootCertName -sr LocalMachine -ss Root -sky signature -pe -r -sk MyNewKey -cy authority
rem creates ssl cert, puts it in the currentuser\Personal store, signing it based on the root cert
makecert.exe -n cn=HostURL SSLCertName -is root -ic RootCertName -sky exchange -pe -sv SSLCertPrivateKeyName -eku 1.3.6.1.5.5.7.3.1
It's complicated, tedious stuff. You just have to keep at it.
I faced a similar issue while trying to connect to a self hosted WCF service using net.tcp binding. I already had the self signed root CA certificate installed in the CurrentUser certificate store, client was using a certificate signed by the root CA cert.
Installing the root CA certificate in LocalComputer certificate store fixed the error "A certificate chain could not be built to a trusted root authority". My WCF Server process runs using current user account hence this step was not obvious.
The next error was "The revocation function was unable to check revocation for the certificate"
To fix this, I created an empty Certificate Revocation List for the root CA cert and then installed the CRL in the LocalComputer certificate store. (Please check this link for details : https://msdn.microsoft.com/en-us/library/ff648732.aspx)
I also set the revocation check mode to Offline for both server and client certificates.
defaultCredentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.Offline;
defaultCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.ChainTrust;
Now I don't have to turn off certificate validation or use different validation mode for development (In my case production code will also use self signed certificates for the time being)

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.