SSL Error: unable to get local issuer certificate - security

I'm having trouble configuring SSL on a Debian 6.0 32bit server. I'm relatively new with SSL so please bear with me. I'm including as much information as I can.
Note: The true domain name has been changed to protect the identity and integrity of the server.
Configuration
The server is running using nginx. It is configured as follows:
ssl_certificate /usr/local/nginx/priv/mysite.ca.chained.crt;
ssl_certificate_key /usr/local/nginx/priv/mysite.ca.key;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_verify_depth 2;
I chained my certificate using the method described here
cat mysite.ca.crt bundle.crt > mysite.ca.chained.crt
where mysite.ca.crt is the certificate given to me by the signing authority, and the bundle.crt is the CA certificate also sent to me by my signing authority. The problem is that I did not purchase the SSL certificate directly from GlobalSign, but instead through my hosting provider, Singlehop.
Testing
The certificate validates properly on Safari and Chrome, but not on Firefox. Initial searching revealed that it may be a problem with the CA.
I explored the answer to a similar question, but was unable to find a solution, as I don't really understand what purpose each certificate serves.
I used openssl's s_client to test the connection, and received output which seems to indicate the same problem as the similar question. The error is as follows:
depth=0 /OU=Domain Control Validated/CN=*.mysite.ca
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /OU=Domain Control Validated/CN=*.mysite.ca
verify error:num=27:certificate not trusted
verify return:1
A full detail of openssl's response (with certificates and unnecessary information truncated) can be found here.
I also see the warning:
No client certificate CA names sent
Is it possible that this is the problem? How can I ensure that nginx sends these CA names?
Attempts to Solve the Problem
I attempted to solve the problem by downloading the root CA directly from GlobalSign, but received the same error. I updated the root CA's on my Debian server using the update-ca-certificates command, but nothing changed. This is likely because the CA sent from my provider was correct, so it led to the certificate being chained twice, which doesn't help.
0 s:/OU=Domain Control Validated/CN=*.mysite.ca
i:/C=BE/O=GlobalSign nv-sa/CN=AlphaSSL CA - SHA256 - G2
1 s:/O=AlphaSSL/CN=AlphaSSL CA - G2
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
Next Steps
Please let me know if there is anything I can try, or if I just have the whole thing configured incorrectly.

jww is right — you're referencing the wrong intermediate certificate.
As you have been issued with a SHA256 certificate, you will need the SHA256 intermediate. You can grab it from here: http://secure2.alphassl.com/cacert/gsalphasha2g2r1.crt

Related

Node unable to verify the first certificate when accessing CouchDB through HTTPS with a Let's Encrypt certificate

I actually found the answer to this question already, and just want to document my finding.
The problem has to do with using Node.js to access CouchDB through HTTPS. The CouchDB server has been configured with a SSL certificate generated by Let's Encrypt. The cert_file specified in local.ini contains both the server certificate and the issue's intermediate certificate. When I verified an URL through the browser, the connection was shown as valid. However, whenever I tried to fetch the same URL from Node, an UNABLE_TO_VERIFY_LEAF_SIGNATURE / unable to verify the first certificate error would be thrown.
I tried adding the root certificate to Node using the NODE_EXTRA_CA_CERTS environment variable. That failed. Then, I tried adding the intermediate certificate to NODE_EXTRA_CA_CERTS, and it worked. I could stop there, but somehow I knew that something was wrong.
After more digging, I finally found that even though the cert_file used by CouchDB includes both the server cert and the intermediate cert, unlike some other servers, CouchDB itself would only send back the server cert. In order to fix this problem the right way, I need to specify the intermediate cert as the cacert_file in the local.ini file as well. Once I did that, the error is gone.

Chrome doesn't prompt for client certificate

I've been trying to setup client certificate authentication for almost three days now but to no avail.
I've signed up for a free domain at heliohost and have installed a free ssl certificate issued by Let's encrypt.
My plan is to have self signed certificates and check them against the database later(for user authentication) therefore I set my SSLVerifyClient to optional_no_ca in the htaccess file. I installed several self signed certificates generated by openssl but no matter which browser I try(Chrome, Firefox or IE) I get no prompts to choose a certificate except when i tried to access it on my phone via Chrome, in this case it offers to install a certificate since I don't have any on the phone.
This is the content of my .htaccess file:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
SSLOptions +StdEnvVars
SSLRequireSSL
SSLVerifyDepth 1
SSLVerifyClient optional_no_ca
I would really appreciate any feedback pertaining the issue, this is my first time trying to implement this and I'm not sure weather the issue is with my setup or chrome.
also I'm using chrome 59
Kriss
You have omitted the part of the ssl certificate authorities configuration. it is needed to configure the CA certificate that signs your client certificates ( see this
SSLCACertificateFile "conf/ssl.crt/ca.crt"
The server is not sending the root CA, then since you have set SSLVerifyClient to optional_no_ca, the browser automatically performs the connection because it can not find any suitable certificate (see below TLS1.2 note)
Since you have set optional_no_ca in your server, it accepts the connection even if no certificate is presented. It you set require you will find that the connection fails with Chrome.
SSLCACertificateFile is not configurable in .htaccess. Since you can not customize chrome, i am afraid you need to configure this parameter to force certificate prompt
When the certificate list is empty, the behavior between browsers may vary because the TLS specification allows it
See TLS1.2 RFC
7.4.4. Certificate Request
certificate_authorities
A list of the distinguished names [X501] of acceptable
certificate_authorities, represented in DER-encoded format. These
distinguished names may specify a desired distinguished name for a
root CA or for a subordinate CA; thus, this message can be used to
describe known roots as well as a desired authorization space. If
the certificate_authorities list is empty, then the client MAY
send any certificate of the appropriate ClientCertificateType,
unless there is some external arrangement to the contrary.
7.4.6. Client Certificate
[...]
If the client does not send any certificates, the
server MAY at its discretion either continue the handshake without
client authentication, or respond with a fatal handshake_failure
alert.
The issue was due to chrome, I have unfortunately not been able to pinpoint it but managed to get it working and prompting me for the certificate on firefox.
Thank you for the answers.

https.createServer ignoring ca array

I use the following options passed to https.createServer,
options =
ca: splitca fs.readFileSync sslpaths.capath, encoding:'utf8'
key: fs.readFileSync sslpaths.keypath, encoding:'utf8'
cert: fs.readFileSync sslpaths.certpath
Where splitca just to splits the two pem blocks of the CA crt bundle file. However sometime Chrome does not like this and when I load my domain it says that the certificate cannot be trusted. Then sometimes it works just fine and shows two Comodo CA nodes coming from the addTrust root, followed by my servers certificate. When I use openssl s_client -connect mydomain.com:443 -showcerts I get the error 'unable to get local issuer certificate'. When I remove the ca parameter completely then Chrome will still sometimes work, but openssl still does not have the two CA pem blocks in the certificate chain. I am guessing that Chrome is doing its own lookup of the CA and caching the certs?
I also tried prepending the CA crt file to in front of my server crt file and before upgrading my nodejs (v0.12) I would get some kind of handshake sslv3 failure from openssl. Now when I try with nodejs v5.0, I get error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch being thrown from nodejs. Any help would be appreciated.

The incorrect localhost certificate is being served by IIS

OK I have a SSL issue that I can't seem to get past on this 1 Win7 x64 machine. I have been using self-signed certs for years and even blogged about them before so I have experience. However something is happening that I can't figure out this time.
I have (2) localhost SSL certs created and insalled on my machine.
localhost (friendly name) issued and created in IIS (7.5). It contains the 'Issued To' and 'Issued By' values of my machine name: 'DevMachine123'. This is the certificate being served up for applications configured under the 'Default Web Site' in IIS.
localhost SSL certificate created using makecert.exe tool where CN=localhost (common name) was used. It contains the 'Issued To' and 'Issued By' values of 'localhost'. This is the SSL cert I want served up in IIS for my applications configured under the 'Default Web Site'.
The error I'm getting is:
'The security certificate presented by this website was issued for a
different website's address.'
When I view the certificate being served up from the IE browser: it shows the localhost cert issued to 'DevMachine123' is being used and not the localhost issued to localhost (#2 above) which should resolve this issue. Hence the name mismatch because 'DevMachine123' does not match 'localhost'.
Another point to make; my certificates have been added to 'Trusted Root Certification Authorities' so they both are trusted certificates.
Last point to make, I checked the https port 443 Binding configuration for the 'Default Web Site' on my machine in IIS. I view the certificate and it shows the correct localhost certificate is bound (#2 above with CN=localhost).
I feel that I have covered my bases here (yes I have seen this and this so please do not re-post). What am I missing here?
Thanks!
I had a similar issue and had also gone through the checks you mentioned above for the site bindings. I ran the following netsh command
netsh http show sslcert
This showed me two SSL Certificate bindings. One on IP:Port 0.0.0.0:443 with the correct certificate and one on IP:Port [::]:443 with an expired certificate. I opened CertMgr.msc for the Local Computer (see here for instructions) and searched for the invalid certificate and discovered it had expired.
To resolve the issue I did the following
netsh http delete sslcert ipport=[::]:443
iisreset /restart
Very similar answer to #IsolatedStorage but with some more details of what helped me.
First a couple points that are probably the same for you
I was trying to update a certificate because it has expired.
I have multiple domains bound to the same IP. They happen to be a SAN certificate but that's probably irrelevant.
I was trying to use the centralized certificate store. Again I think this is irrelevant to most of my answer.
I had already attempted to update the certificate but it wasn't showing the new date.
You're probably in a panic right now if your old certificate already expired. Take a deep breath...
First I'd recommend strongly going to https://www.digicert.com/help/ and downloading their DigiCert tool. You can also use it online.
Enter in your website https://example.com and it will show you the expiration date and thumbprint (what MS calls the certificate hash). It does a realtime lookup so you don't have to worry whether or not your browser (or intermediate server) is caching something.
If you're using the centralized certificate store you'll want to be 100% sure the .pfx file is the latest version so go to your store directory and run this command:
C:\WEBSITES\SSL> certutil -dump www.example.com.pfx
This will show you the expiration date and hash/thumbprint. Obviously if this expiration date is wrong you probaly just exported the wrong certifcate to the filesystem so go and fix that first.
If you are using the CCS then assuming this certutil command gives you the expected expiration date (of your updated certificate) you can proceed.
Run the command:
netsh http show sslcert > c:\temp\certlog.txt
notepad c:\temp\certlog.txt
You likely have a lot of stuff in here so it's easier to open it up in a text editor.
You'll want to search this file for the WRONG hash that you got from digicert.com (or the thumbprint you got fromChrome).
For me this yielded the following. You'll see it is bound to an IP and not my expected domain name. This is the problem. It seems that this (for whatever reason I'm not sure) takes precedence over the binding set in IIS that I just updated for example.com.
IP:port : 10.0.0.1:443
Certificate Hash : d4a17e3b57e48c1166f18394a819edf770459ac8
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : My
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
I don't even know where this binding came from - I don't even have any SSL bindings on my default site but this server is a few years old and I think something just got corrupted and stuck.
So you'll want to delete it.
To be on the safe side you'll want to run the following comand first to be sure you're only deleting this one item:
C:\Windows\system32>netsh http show sslcert ipport=10.0.0.1:443
SSL Certificate bindings:
-------------------------
IP:port : 10.0.0.1:443
Certificate Hash : d4a17e3b57e48c1166f18394a819edf770459ac8
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : My
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Now we've verified this is the 'bad' thumbprint, and expected single record we can delete it with this command:
C:\Windows\system32>netsh http delete sslcert ipport=10.0.0.1:443
SSL Certificate successfully deleted
Hopefully if you now go back to Digicert and re-run the command it will give you the expected certificate thumbprint. You should check all SAN names if you have any just to be sure.
Probably want to IISRESET here to be sure no surprises later.
Final note: If you're using the centralized certificate store and you're seeing erratic behavior trying to even determine if it is picking up your certificate from there or not don't worry - it's not your fault. It seems to sometimes pick up new files immediately, but cache old ones. Opening and resaving the SSL binding after making any kind of change seems to reset it but not 100% of the time.
Good luck :-)
Same symptoms
Changed HTTPS binding in the drop down list to the server IP (in the site bindings dialog). It was set to "all unassigned" Got a warning about overwriting an existing certificate / IP combination, which I accepted, and and issue resolved.
Verify you have only one site set per binding in IIS as well.
If the Default site and a separate one are installed, they may both have an HTTPS binding on the same port. If this happens, the cert served may be the one from the other site.

Is my SSL certificate valid?

I have a weired behaviour with this website: https://cartefidelite.mobi/. I can not determine if the certificate is valid.
On iPhone, it said it's valid, on Androïd it said it's not! On a desktop computer it's the same, it's valid for Safari but not for Google Chrome (on Mac) - On firefox Mac it's not valid either.
So my question is: Is this certificate valid and some browser just can't succesfully build the certificate tree hierarchy to a root certificate? Or is this certificate not valid?
Here is a screenshot on Google Chrome (13.0) and Safari (5.1):
The certificate is valid but some browser just can't succesfully build the certificate tree hierarchy to the root certificate. The "globalsign domain validation CA - G2" certificate is not in the truststore of all browsers yet.
What server are you running this application on? The solution is to add the certificates from the certificate chain to your server configuration. The server will then send them to the client and everything will be fine.
On Apache HTTPD server you add the following to the configuration:
SSLCertificateChainFile <globalsign domain validation CA - G2.crt>
For anybody looking for the GlobalSign Domain Validation CA - G2 (Expiry 13th April 2022), here it is:
Domain Validation Root Bundle 2011 from GlobalSign

Resources