SSL Cert Validation between Client and Server - ssl

I have some confusion on the SSL Certificate Validation in a Client - Server model.
This is what happens as all of you know
Client (C), Server(S), PublicKey(PB), PrivateKey(PK), ServerSSLCert(SR)
CABundle(Root + Intermediate) - (CAB)
AS you know client always attaches CAB file when connecting/communicating with server. no server cars are attached.(correct me if I am wrong)
This is what the flow
Client Sends Hello with all needed Details to Server
Server Validates the needed things and Sends the Cert to Client
==> So confusion here is ... What is the certificate that server send - is that a Root/Intermediate/Server Cert it exchanges with client ?
==> Will the Client Validate the ServerName (hostname -f) with what is in the Certificates CN/Subject ??
==> Assume the Servername has ALIAS/CNAME (ABCD.dmn.com (real hostname is server.dmn.com))
Since the Client has ABCD.dmn and Subject in Server cert will be different will that validate at network level to certify both are same IP and move further (or) the names are different thus client unable to validate and fails ?
Can some one please explain.

Related

How to trust a self-signed server certificate with the node-opcua client

I have a simple node-opcua client and it wants to connect to a server via Basic128Rsa15 policy.
I have created a self-signed certificate and the server does receive this cert and I can move it on the server to the trusted pki directory.
At my client - the node-opcua - I also see a new directory "pki/rejected" with the cert from the server.
My question is now: What do I have to do now so that the client will trust this self-signed cert from the server?
I have already tried to create a "trusted" directory and move it to there, but this does not help, I also have tried to add an option (which I have found via google): serverCertificate=crypto_utils.readCertificate("pki/trusted/04c9f401be19e5a2349460306579c692e777cea5.pem"); But that also didn't help. When I start the client it creates again the cert in the "rejected" folder.
My node-opcua options for the connection:
options:
securityMode: 3 # None = 1, Sign = 2, SignAndEncrypt = 3
securityPolicy: "http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15"
certificateFile: certificates/cert.pem
privateKeyFile: certificates/key.pem
[EDITED]
version 2.30 onward: node-opcua clients now perform full certificate validation coming from servers:
if a server certificate has been generated by a CA, the CA certificate must appear in the PKI of the client ( in the issuer folder) along side with the corresponding CRL.
by default the client certificate manager accepts valid unknown server certificate for backward compatibility with previous version. This can be reverted by setting the automaticallyAcceptUnknownCertificates to false.
other checks are performed to verify that the certificate of the server strictly complies to the requirements of OPCUA, such as subjectAltName.uniqueResourceIdentify must match server's applicationUri, keyUsage, key length etc ...
if server certificate is known and in rejected folder, client will reject connection with server.
version 2.28 and below: node-opcua clients did not perform server certificate trust/reject checks yet, nor full certificate validation, just basic validate (date, signature ...)

How do Virtual Hosts and TLS work together?

As I understand it Virtual Hosts work in HTTP servers by receiving a HTTP request from the client and examining the Host header, which contains service1.example.com or service2.example.com, etc. and then forwarding the request based on some rules in the HTTP server configuration.
But as I understand it TLS works as follows:
Client opens connection to server.
Client and server have a handshake where the client checks the server's certificate is valid for the name the client is trying to access.
Client transmits the request.
Server transmits the response.
These two seem like they would be incompatible, the server doesn't know which TLS certificate to present to the client until after the request has been sent, but the client won't send the request until the handshake is completed.
They clearly aren't incompatible, I have run web servers with multiple separate TLS virtual hosts each with completely separate certificates. Where have I gone wrong here?

How to enforce tomcat server not to share SSL public certificate to clients(Browsers) requesting for it?

A Certified Domain should be accessible only if SSL public certificate of the domain is already present in client's trust store. If not, client should prompt to import server certificate instead of getting it from tomcat server automatically(Via SSL handshake)
This will not work: the server has no knowledge which CA certificates are known to the client so the server cannot decide what to send to the client. Also, the server can only send a certificate to the client but not make the client import a new root CA - no matter if with or without prompt.
Apart from that it makes no sense: the idea of TLS/HTTPS is that the client will only connect to a server which identity can be verified. If the server can make a client import a new trusted root CA an attacker could do the same and thusman in the middle attacks would be possible.
If one instead just want to know if the client will trust a specific certificate or not one could include a resource (image, script...) served with this certificate into a known good HTML page and then check with some script in the page if the resource was loaded successfully. This check could also result in a redirect of the client, for example to some page describing the problem and linking to the correct root CA.

How to setup IIS to verify a client certificate and pass it to the backend as an http header?

I've read quite a few articles on the client certificate authentication in IIS but they mostly talk about the Required mode for the client certificate. In this case, the authentication is fully done on the web server side and the user is redirected to the error page in case the certificate is missing or invalid. What I need is to configure IIS to check the client certificate if it exists and pass the results as http headers to my backend. It can be easily done with nginx or apache web servers. The client authentication can be set up as optional. Then, the web server checks the certificate and pass the results of the check as SSL_CLIENT_CERT (PEM representation of the certificate) and SSL_CLIENT_VERIFY (the result of the check - SUCCESS, NONE,...) headers to the application backend. So, on the backend part, I can read the headers and use the values to do the actual authentication -- find a user in the database, issue an auth token. Is it possible in IIS? If yes, is there any documentation on how to bypass the certificate and the check state as http headers?
After a while, I'm writing an answer to my question.
IIS has to be set up with ARR extension to act as a reverse proxy. Then, the client certificate authentication can be enabled for the default web site. Here are several links to instructions how to achieve it:
https://blogs.msdn.microsoft.com/benjaminperkins/2014/06/02/configure-application-request-routing-arr-with-client-certificates/
https://blogs.msdn.microsoft.com/asiatech/2014/01/27/configuring-arr-with-client-certificate/
and couple of links to very solid explanations of the SSL/TLS handshake and certificates in general:
https://blogs.msdn.microsoft.com/kaushal/2013/08/02/ssl-handshake-and-https-bindings-on-iis/
https://blogs.msdn.microsoft.com/kaushal/2013/01/09/self-signed-root-ca-and-intermediate-ca-certificates/
https://blogs.msdn.microsoft.com/kaushal/2015/05/27/client-certificate-authentication-part-1/
Basically, the Application Request Routing (ARR) extension should be enabled for the IIS to act as a proxy. Then, you set up proxy bypass routes. Next, you need to set up a valid server certificate for the IIS server and use it in the Default Web Site https bindings. The certificate should be issued by a CA which certificate should be placed into the Trusted Root Certification Authorities and Intermediate Certification Authorities of the Local Computer. Then, you should require SSL in the SSL settings of the Default Web Site with the client certificates setting equal to Accept. In this case, any client that connects to the web server will be asked for a valid client certificate that has been issued by the same CA as the server certificate.
Actually, IIS sends a list of distinguished names of root issuers that are trusted by the web server to the client browser. The browser finds an intersection of this names with client trusted certificate issuers and looks for valid certificates that have been issued by the issuers in the intersection. After that, the user selects one of them (or none) and the selected certificate is checked against the CA certificate. If the certificate passes the check the request is "redirected" to the backend application with the certificate in the X-ARR-ClientCert header. The name of the header can be changed in the Server -> Configuration Editor -> system.webServer/proxy -> clientCertHeaderName IIS parameter. In case the user selects (or has) none of the required certificates, the request is "redirected" to the app backend without the header.
Seems, there is no need in the SSL_CLIENT_VERIFY header with the state of the check at all. If the certificate is valid it is passed in the header. If the certificate is missing the header is empty. If the certificate is provided by the client but is invalid then the request fails and is not "redirected" to the backend app server at all. Seems, it is a rare case but I have an example.
Imagine, a server certificate is issued by a CA with a distinguished name XXX, and there is a client certificate YYY (on the client computer) that is issued by a CA with the distinguished name XXX but those CAs are not the same (one or both of them are self-signed). In this case, the YYY certificate is present in the certificate selection dialog that is shown by a browser but the certificate doesn't pass the further validation against the real web server CA.
That's it. Also, seems IIS has no way to require (or accept) a client certificate for some app endpoints (addresses) only. I haven't found any other option apart from enabling in for the whole web site.
IIS ARR can also be configured with a client certificate for the backend or upstream server. In this case users connecting to this IIS do not need to provide the certificate as it will be attached by IIS automatically.
This configuration is available on IIS server level only.

SSL Certificate Expires

My idea of the SSL communication is a bit hazy and I needed some clarifications.
Architecture of my application - Internal Machine which has the application running is exposed to internet via a BIG IP server.
The certificate hierarchy on my website - Root (expires in 2040) R - Intermediate( expires in 2036) I - xxxx.com (expires in 2 days) F
I have the new certificate created with the same root and intermediate CAs. It is created with a different key. I also have the key.
My questions are :
1) When I perform a HTTP Post using a stand alone application from computer X (some random machine on internet) onto the exposed URL, the SSL handshake should occur at two places. a) Computer X and BIG -IP b) BIG-IP and the internal machine that has the application running. The standalone application should have the public certificates of the URL i.e., R and I, in its key store. Correct? Or should I have the xxxx.com certificate as well i.e., F as well? Who decides this?
2) This is a different scenario. I have placed the newly created certificate of xxxx.com (it has same Root and Intermediate certificates R and I) on the BIG IP server. The start period of this certificate is 1st Aug 2014. My internal instance, although, still has the old certificate. It expires on 3rd Sept 2014. I am able to post successfully even in this scenario. Why is it so? Since the keys are different for the new and old ones, the requests should fail during the SSL handshake of BIG-IP and Internal instance.
Kindly help me understand these two scenarios. I will be grateful.
Thanks
The root CAs should be in the client machine's trusted certificate repository. The server (BIG-IP) should have the intermediate cert and the cert for the fqdn (or SAN/wildcard) if you are offloading. If you are offloading at the BIG-IP and not re-encrypting to the origin server, then you don't need any certificates on the origin server. If you are, then it would be the same setup as the BIG-IP with intermediate and server cert.
In the event your intermediate and server certs are signed by a root NOT trusted by your client (internal certs or custom clients without the standard trusted CAs), you'll need to make sure your clients install the root CA manually or push it.