How to set client certificate chain in WinHttp - ssl

I am working on a client-server application where server is a web server which performs client validation based on SSL certificate. Server trust a Root CA certificate. Client is a windows application developed in C++ which has a certificate signed by intermediate CA which in turn signed by Root CA.
I am able to set client certificate during https connection by calling WinHttpSetOption api with WINHTTP_OPTION_CLIENT_CERT_CONTEXT as option. However this will set only client certificate but not the entire chain. Server does not have intermediate CA in its store hence it is not able to authenticate the client.
Is there a way to set the full client certificate chain in WinHttp, provided the full chain is already present in certificate store of client?

The server has to have the CA certificate beforehand, it's not going to trust the root CA the client hands it. (I'm not sure about whether it (the server-side) would trust an intermediate CA signed by a trusted CA but my inclination says no).
Trusting some random CA a client sends would break the entire point of certificate verification, you would have no idea of whether the data the client submits is actually meaningful. So add the root and intermediate CA certificates to the server's certificate stores. (If you don't have access to that you'll have to talk to an admin and have them do it).

I'm not really seeing anything wrong with what you are doing.
You are implementing mTLS. The client side has a private key that it uses to validate itself to the Server. Most times the client will generate this private key itself and just send it to the server via CSR. In your case you have some CA generate it for you.
mTLS is used in place of some other sort of login a client might do to a server. The client itself doesnt care about the cert chain. The client doesnt need to validate itself. It just sends a token encoded via its private key. The server DOES need the root or intermediate cert in order to validate the key the client has sent. Usually you just install this root into your normal cert store (server side) so the server can validate the client.

Only I could find was to Add Sub CA to system store. During service startup or installation, open the CA certificate store and Add certificate context to it.

Related

HTTPS client authentication self signed certificate

I would like to offer a customer a cloud service in form of a website. Now I had the idea that it would increase security enormously if this customer (several employees) also authenticated himself with a client certificate. This certificate should then be installed on his office computers and tablets. The server SSL certificate is a Letsencrypt certificate. From the client certificate I would then also know the private key, but from my point of view this is not dangerous because it is only used to authenticate against my server.
Is there a practicable solution to provide the customer with a client certificate whose public key I then store on my HTTP server?
Can I buy such client certificates from an authentication authority? Did I understand correctly that if I generate a own client certificate, the customer also has to trust my CA and this represents a security risk? Or can the customer only trust this one generated certificate and not my self signed CA/Root CA?
Thanks for anwsers
Did I understand correctly that if I generate a own client certificate, the customer also has to trust my CA and this represents a security risk?
Trusting the issuer CA of a certificate is only needed by the one who verifies the certificate, not the one who authenticates itself with the certificate. Thus in case of a client certificate only the server needs to trust the issuer CA, the client not. This also means that the client does not need to import the CA as trusted which means that there is no security risk from importing some third-party CA.
Or can the customer only trust this one generated certificate and not my self signed CA/Root CA?
The client does neither need to trust the client certificate nor its issuer CA. The client just needs to import the client certificate and the associated private key to be used as client certificate.
It is thus perfectly fine to use a private CA and let it create the client certificates for the customers. The server will then only trust this private CA for client certificate validation.
From the client certificate I would then also know the private key, but from my point of view this is not dangerous because it is only used to authenticate against my server.
Any Certificate is publicly available and only contains public key apart from other attributes and is signed by issuer CA. This can be private CA also if you only need to use certificates at organization level and not across the internet.
You may setup your private CA on your intranet and provide certificate to all Company or Organization employees. Having said this, depending on Certificate validation and revocation requirements (and your local law), you may achive PKI authentication with any Public and Private Key pair and may not require CA signed Certificate but this arrangement does not provide Certificate Revocation check and systematic PKI framework.
Refer working POC for PKI Web Authentication at PKI Authentication
This requires installing Signer.Digital Browser Extension (provided by my Company, CISPL) to be installed on clients to access User's Digital Certificate from local Certificate Store or Cryptographic device like Smartcard or USB.
The above extension also provides JavaScript API for Certificate issuance which also adds root certificate to user's trust store at the time of certificate download. You may test it at CSR Generation and Certificate Download

Does verification of digital certificates require remote calls?

I have a few questions about digital certificates:
1) As far as I understand, clients are able to verify server digital certificates, because clients contain a set of well known CA self-signed certificates on their machine. Is that enough for the whole verification to be complete or are there some additional remote calls that need to be made by the client to the actual CA (wherever it lives)? I read some things about certificate revocation (CRL and OCSP) which seemed to indicate that remote calls are necessary at some point or another.
2) When validating a server certificate what happens exactly on client-side? I've always explained it to myself that based on the CA in the server certificate the client finds the corresponding CA self-signed certificate on it's machine and uses the public key from it to decrypt the signature in the server certificate (so no remote calls here). The decrypted result is as far as I understand a digest of the server's public key. So the client hashes the public key in the server certificate to match it to the digest from the last step. If both match, then everything is ok and the client and server can exchange a symmetric key for further communication. Is that correct?
1) Technically, no, there are no remote calls required. Of course, it's a little more complex than that - if you're using OCSP, then yes, you will need to reach an OCSP server and it must be a remote call. If you use CRLs, you will need to make remote calls to fetch the CRL from the CRL Distribution Point [CDP] in the cert; but if the CRL is fetched and cached locally, and is not expired, then the cert checks are all local.
2) You are correct, the client-side 'chains to a trusted root'; there are more checks performed including key usage, date range checks and, as you noted, verifying the signatures of the certs. The final check is to make sure the root is available at the client.
I hope that helps.

How to configure gRPC Client communicating over TLS transport layer without server certificate?

Currently I want to expose a gRPC Method as Public API and protected by Auth0 (JWT Token), with Istio(Envoy Proxy) will help validating the token on server side. Since the JWT Token is not encrypted by the standard (it is only used to end-user authentication and authorization layer), I want to encrypt the communication using TLS. Also, my public server already have valid certificate.
The problem is on the gRPC Client side. Every example I look, the gRPC Client have to initialize the TLS Connection with server cert pem file. Is it really necessary? Because it adds operational burden and complexity, where we have to distribute our server pem file everytime we renew the certificate AND/OR the client side has to restart the application.
Thanks,
Agung
If you are using a self signed certificate, then yes you must explicitly trust it in your client. If you use a publicly signed certificate on your Server, gRPC will use the Operating System's certificate authorities to verify the cert. (In the case of Java, it uses the JVMs cert authorities.)
If you are using a self-signed certificate you need to specify the server's root certificates in the pem_root_certs member of the SslCredentialsOptions struct passed in when creating a channel, as Carl says.
However if you are using a CA issued certificate, leaving the pem_root_certs member empty will cause gRPC to default to its own master list (reviewable online), not any OS-specific list.

Is SSL with server certificate and client password possible?

Based on this answer: https://stackoverflow.com/a/3107645/1559672 it's possible to set up ssl connection without user verification.
I think the answer to my question would be yes but can't find anything to confirm/reject it.
The idea is that the server has a certificate that the client can verify via a CA. Then client generates some secret and encrypts with server's public key. Based on this shared secret they generate 'key material' for encryption/decryption. After they have the secured connection, client can verify itself with username/password.
Is it possible like this? if yes, please show me some example or proof.
If not, why not?
The reason of confusion was because of RabbitMQ doc: rabbitmq.com/ssl.html "Connecting without validating certificates" 's example code doesnt define what server certificates or RootCAs are accepted. (RabbitMQ cert is self signed) So I don't get how TLS is set up without that?
Encryption does not depend on certificates. And a self-signed certificate is still a valid certificate.
The purpose of certificates is to prove the identity of the remote peer. Can you really be sure you're talking to the server you think you're talking to and that your connection isn't currently being hijacked? This is ensured by the server presenting a certificate only it could have (public/private key crypto validates this, only the server should have the private key for the certificate; trust/security here depends on the server keeping its private key to itself).
How do you trust the certificate? Well, you may have a copy of it in your trusted certificate store. You'd do this with a self-signed certificate: just put it in your trusted store; since you (presumably) know where it came from, it's trustworthy.
Since this is unrealistic for every public site on the web, a public key infrastructure exists which allows you to trust a limited known number of certificate authorities which can sign certificates of arbitrary unknown parties, and you can indirectly trust those heretofore unknown certificates.
Having said all this, encryption is a separate component and an encrypted, secured connection can be set up with or without the identity verification that certificates provide.

Two-way SSL clarification

I am somewhat confused as to how two-way SSL works. How does the client create its certificate to send to the server? Is it generated from the server and distributed to the client?
Also, what is the advantage of two-way SSL over one-way SSL?
Both certificates should exist prior to the connection. They're usually created by Certification Authorities (not necessarily the same). (There are alternative cases where verification can be done differently, but some verification will need to be made.)
The server certificate should be created by a CA that the client trusts (and following the naming conventions defined in RFC 6125).
The client certificate should be created by a CA that the server trusts.
It's up to each party to choose what it trusts.
There are online CA tools that will allow you to apply for a certificate within your browser and get it installed there once the CA has issued it. They need not be on the server that requests client-certificate authentication.
The certificate distribution and trust management is the role of the Public Key Infrastructure (PKI), implemented via the CAs. The SSL/TLS client and servers and then merely users of that PKI.
When the client connects to a server that requests client-certificate authentication, the server sends a list of CAs it's willing to accept as part of the client-certificate request. The client is then able to send its client certificate, if it wishes to and a suitable one is available.
The main advantages of client-certificate authentication are:
The private information (the private key) is never sent to the server. The client doesn't let its secret out at all during the authentication.
A server that doesn't know a user with that certificate can still authenticate that user, provided it trusts the CA that issued the certificate (and that the certificate is valid). This is very similar to the way passports are used: you may have never met a person showing you a passport, but because you trust the issuing authority, you're able to link the identity to the person.
You may be interested in Advantages of client certificates for client authentication? (on Security.SE).
What you call "Two-Way SSL" is usually called TLS/SSL with client certificate authentication.
In a "normal" TLS connection to example.com only the client verifies that it is indeed communicating with the server for example.com. The server doesn't know who the client is. If the server wants to authenticate the client the usual thing is to use passwords, so a client needs to send a user name and password to the server, but this happens inside the TLS connection as part of an inner protocol (e.g. HTTP) it's not part of the TLS protocol itself. The disadvantage is that you need a separate password for every site because you send the password to the server. So if you use the same password on for example PayPal and MyPonyForum then every time you log into MyPonyForum you send this password to the server of MyPonyForum so the operator of this server could intercept it and try it on PayPal and can issue payments in your name.
Client certificate authentication offers another way to authenticate the client in a TLS connection. In contrast to password login, client certificate authentication is specified as part of the TLS protocol. It works analogous to the way the client authenticates the server: The client generates a public private key pair and submits the public key to a trusted CA for signing. The CA returns a client certificate that can be used to authenticate the client. The client can now use the same certificate to authenticate to different servers (i.e. you could use the same certificate for PayPal and MyPonyForum without risking that it can be abused). The way it works is that after the server has sent its certificate it asks the client to provide a certificate too. Then some public key magic happens (if you want to know the details read RFC 5246) and now the client knows it communicates with the right server, the server knows it communicates with the right client and both have some common key material to encrypt and verify the connection.
In two way ssl the client asks for servers digital certificate and server ask for the same from the client. It is more secured as it is both ways, although its bit slow. Generally we dont follow it as the server doesnt care about the identity of the client, but a client needs to make sure about the integrity of server it is connecting to.