How to get Nginx to verify MIT personal certificates? - ssl

I run a webapp with users at MIT. They have asked whether the webapp could authenticate users (perhaps as a second factor) by their MIT personal certificates. I have tried but I can't get it to work.
I downloaded the MIT CA certificate from the MIT certificates page – see the link "Get MIT CA (Certificate Authority)" near the bottom of the page – and converted it to PEM format.
Then I uploaded the certificate to the webserver, configured Nginx like this, and reloaded it:
ssl_client_certificate /etc/nginx/certs/mitca.pem;
ssl_verify_client optional;
ssl_verify_depth 2;
When an MIT user visited the webapp, their browser prompted them to choose a certificate. They chose their MIT personal one. Then Nginx showed an error page: "400 Bad Request / The SSL certificate error". The error log contained this:
client SSL certificate verify error: (21:unable to verify the first certificate) while reading client request headers
Error 21 (or X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) means "No signatures could be verified because the chain contains only one certificate and it is not self signed" according to openssl's docs.
Presumably the "chain" refers to the MIT CA certificate?
I thought the MIT CA certificate was self-signed because of this result:
$ openssl verify -CAfile mitca.pem mitca.pem
mitca.pem: OK
Does anybody know what's wrong?

With nginx, you have to concatenate the certificate chain and the cert into one file, in this case at /etc/nginx/certs/mitca.pem
This can be done on a UNIX CLI with the following command:
cat your-signed.crt ca-cert-chain.crt > /etc/nginx/certs/mitca.pem
...then restart nginx. You can use nginx -t beforehand to make sure that the syntax is OK and the certs are valid (and nginx will restart)

Related

ca-bundle.crt seems updated but CA still missing in it

I am trying to connect to a webserver from my CentOS but I got an error regarding the certificate.
curl https://mywebsite ends with error 60 : Peer's certificate issuer is not recognized.
I am not able to add my CA certificate issuer.crt to the ca-bundle.crt.
Looking at /etc/pki/tls/certs/ca-bundle.crt.
My website certificate issuer is missing, that's why i got an error.
Verifying my CA_issuer_crt with curl --cacert /path/to/my/CA_issuer.crt https://mywebsite
Curl is successful.
So, trying to add my CA_issuer.crt to the ca-bundle.crt
I put my CA_issuer.crt to /etc/pki/ca-trust/source/anchors/CA_issuer.crt
running update-ca-certificate
Tried the followings
update-ca-certificate enable update-ca-certificate force enable update-ca-certificate extract
My /etc/pki/tls/certs/ca-bundle.crt seems updated (the last modified date is right now) but my CA certificate is still missing in the file + my curl test is still KO.
My certificate is an authority CA certificate is X509v3 Basic Constraits: CA:TRUE
openssl verify my CA_issuer.crt gives me an error.
18 at 0 depth lookup:self signed certificate OK
This CA certificate is deployed on several servers without issue.
I only have a couple of servers with this issue.
Any help is welcome to find a solution.
Thank you.

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.

SSL Certificate - Reason why the page is not trusted

I am not very familiar with the SSL Certificates and how they work.
However I succeed to install a SSL Certificate via cPanel of my shared hosting.
Please checkout this page: https://www.sportsdirect.bg/customer/account/create/
As you can see there is a problem with the certificate.
The padlock in the browser URL address is not green. Can you please tell me what can be the reason for this and how I can fix it ?
Off topic for this site.
Your web server is not properly configured to deliver the full certificate chain, see https://serverfault.com/questions/633247/ssl-error-on-mobile-devices .
Check your SSL Labs report and you will see Chain Issues: Incomplete. Your intermediate certificate:
RapidSSL SHA256 CA - G3
Fingerprint: 0e34141846e7423d37f20dc0ab06c9bbd843dc24
RSA 2048 bits (e 65537) / SHA256withRSA
... is not in your server's trust store and is not being served. Take a look at How to install an Intermediate CA cert in Apache.

SSL client verification failure

I have a backend server with SSL only as defaut public interface. This server listens on 443 with cert, key and ca files on, ssl verify client is set to true.
On client side, I have client cert, key and a ca file made of 2 CA files catted together (intermediate CA, root CA) in a single ca.pem file. When I do curl request on my backend server, it works fine. I also tested the server / client cert and key with gnutls-serv and openssl s_server to ensure all was valid.
But when I create a keystore on Apigee (client cert and key file [pem format]) and a trustore (ca.pem file), there is an error:
- target.name fsbca-test
- Properties
- Expression ("fsbca-test" equals target.name)
- ExpressionResult true
- Tree TARGET_fsbca-test
- error The Service is temporarily unavailable
- error.cause General SSLEngine problem
- error.cause.cause General SSLEngine problem
- error.class com.apigee.messaging.adaptors.http.HttpAdaptorException
- state TARGET_REQ_FLOW
- type ErrorPoint
If I put SSL verify client to false on my backend, then the request is correctly diverted by Apigee and I get the response.
If I put IgnoreValidationErrors to true in the target endpoints property, then the request is diverted to my backend server but I can see an error in the server's log: "client sent no required SSL certificate while reading c...".
Any ideas about what could be wrong in what I am doing?
Additional track: could it be an issue on Apigee side with the CA file made of 2 certs (it may ignore trailing certificates found in a .pem). If wanted to test pkcs12 and jks but I failed to upload them to Apigee (the API doc page only describes .pem, JAR and cert action). I wrote a small Java client with pkcs12 keystore and jks trustore and it worked fine from my local workstation.
Thank you in advance for any piece of information that could help me.
Regards
Fr
You should upload your certificates separately (one per cert), and you need the entire trust chain of certificates to be stored in your truststore.
Here is the page about SSL to your backend.
EDIT:
Here is a method I know works:
1) Separate certs into separate PEM files. Do not put more than once cert in a file.
2) Validate each cert using openssl:
openssl x509 -noout -text -in <cert file name>
Validate that no certs are expired, and that the Subject and Issuer fields create a chain of all the certs, with identical names.
The server's certificate, the root certificate, and all certificates in between need to be in the truststore.

SSL certificate verification fails, how to figure out what's causing it?

I've recently obtained a PositiveSSL certificate at Namecheap and installed it on my server. Accessing the site from Firefox works fine, but accessing it from Ruby's net/https library doesn't work: it fails to verify the connection certificate even though I've specified the path to the certificate and I've checked that the file is readable. Curl also fails:
curl --cacert /path/to/cert https://mysite.com/
It simply says something like this:
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
"certificate verify failed" isn't a terribly useful error message. How do I find out what exactly is wrong with my certificate and what to do about it? I find it confusing that it works in the browser but not anywhere else.
It looks like curl requires that the CA certificate file contains ALL certificates in the chain. I've downloaded all of them and combined them into a single file and now both Curl and Ruby are happy.