SSL and JKS to TLS 1.2 client side - ssl

I am running an old version of jetty that allows SSL TLS v1.0 and v1.1. I want to disable anything other than TLS 1.2 as there are security vulnerabilities with the other implementations.
Currently clients connect to the jetty server using SSL, without any jks file for java clients or any certs or pk12 equivalent for c#/.net clients.
My understanding of jks is that the client and server needs it, which isn't a vulnerability in itself as the alias and servers should not be available in the jks file.
So my question is when I enforce stricter security protocol TLS 1.2 do i need to provide the clients with jks/pk12 or whatever the windows equivalent is? If i dont change the code to allow trustAll etc?
Client(is a request running within jetty server 9.4) server and request code:
System.setProperty("javax.net.ssl.trustStore", "filename");
System.setProperty("java.net.ssl.trustStorePassword", "xyx")
ServletContextHandler context =
ServletContextHandler(ServletContextHandler.SESSIONS);
...
server.setPort(8080);
server.start();
//Then call is via apache server code
CLoseableHttpClient httpClient = HttpClients.createMinimal();
HttpGet httpGet = new HttpGet("https://server:8080/getLogisticsData");
...
httpClient.execute(httpGet), response -> {
//format response
}));

Related

Delayed certificate in TLS 1.3

In ASP.NET Core there are 4 available certificate modes:
// Summary:
// A client certificate is not required and will not be requested from clients.
NoCertificate,
// Summary:
// A client certificate will be requested; however, authentication will not fail
// if a certificate is not provided by the client.
AllowCertificate,
// Summary:
// A client certificate will be requested, and the client must provide a valid certificate
// for authentication to succeed.
RequireCertificate,
// Summary:
// A client certificate is not required and will not be requested from clients at
// the start of the connection. It may be requested by the application later.
DelayCertificate
I want to use DelayCertificate mode because this shouldn't ask for certificate to user in e.g. web explorer, but still I can require certificate on some endpoints. But I have one consideration: It seems to me that I once read that delayed certificates aren't supported in TLS 1.3. I'm not sure about it, and I can't find the source where I read this. So what's it like with this mode? Will it work with TLS 1.3?
... I once read that delayed certificates aren't supported in TLS 1.3
In TLS 1.2 and lower renegotiation was used to ask for client certificates after the initial TLS handshake was already done. This mechanism does not exist in TLS 1.3 anymore, which means it also cannot be used for delayed client certificates anymore in TLS 1.3.
But, TLS 1.3 introduced a different mechanism for this purpose: Post-Handshake Client Authentication. Thus, delayed client certificates can still work with TLS 1.3, only differently. But it requires that the client supports it and not all might do.
Additionally TLS 1.3 post-handshake client authentication is explicitly forbidden in HTTP/2 - see RFC 8740. But similar to this delaying client certificates in response to access to a protected resource weren't allowed with TLS 1.2 in HTTP/2 either: RFC 7540 explicitly forbids renegotiation after the actual HTTP/2 protocol (inside the TLS) has been started.

Is there any method in netty ssl client to know if server requested client certificate after completion of SSL Handshake process

I have a Netty HTTPS(SSL ENABLED) Client which communicates with both Mutual Authentication enabled servers and Mutual Authentication non-enabled servers.
Following is the code I use to Setup SSL Handler for Client.
TrustManagerFactory tmf= ...// Necessary Trust certs
KeyManagerFactory kmf = ...// Necessary Client certs
SslContext sslContext = SslContextBuilder.forClient().keyManager(kmf).trustManager(tmf).build();
SslHandler sslHandler = sslContex.newHandler(ByteBuffAllocator);
I use the above sslHandler in the pipeline. I know that providing keyManager(kmf) will provide client certificate to server if server requests. Everything works as expected.
MY NEED : I need to know if the Server requested Client certificate or not(ie. Mutual Auth enabled server or not) in SSL Handshake process. I need to know this after completion of Handshake process.
You could provide your own KeyManager implementation (that later calls the actual KeyManager). If getPrivateKey() is called you know that the server has requested the client certificate.

Disabling certificate check in gRPC TLS

Currently, I have a ngnix server (on port 5001) behind which a gRPC server is running, nginx having TLS enabled. All gRPC clients need to send the request to nginx port which forwards to gRPC server running. Initially for testing had gRPC request using usePlaintext() and it all worked fine, but the end goal is to use TLS. The requirement here is (as this are internal applications), gRPC channel request need not pass certificate but do a "skip certificate" when creating the channel.
After Googling around, I found examples on TLS but all of them does take .cert, .key file. Below is snippet which i tried and it failed at the server end couldn't validate the certificate
(java code)
ManagedChannel channel = NettyChannelBuilder.forAddress(<server IP address>, 5001).sslContext(GrpcSslContexts.forClient().trustManager
(new File(<.cert file>).build())
.build();
Doing some more research, i see Golang has InsecureSkipVerify() using which i can skip ceritifcate check (pls correct me if i am wrong)
tc := credentials.NewTLS(&tls.Config{
InsecureSkipVerify: true,
})
Now how do I accomplish the same in java?
TLS with disabled certificate checking is of questionable usefulness because it can be trivially MITMed and so is not "supported" by gRPC. I highly recommend providing the client with proper root certificates to verify the server.
That said, you can go around gRPC's API to do this by passing Netty's InsecureTrustManagerFactory to SslContextBuilder.trustManager(TrustManagerFactory):
NettyChannelBuilder.forAddress("<server IP address>", 5001)
.sslContext(GrpcSslContexts.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.build())
.build();

How to get Remote server untrusted SSL certificate using Apache HTTP Client API

I have a remote server which may or may not be running using a valid SSL cert (using self-signed SSL cert).
We are making connection to remote server, which may fail if remote server is using self-signed SSL cert. So, we want to be able to download/view the remote server cert if our SSL handshake fails.
If I use Apache HTTP Client then I couldn't find a method which could allow me to view remote server certificate (you can do it with HttpsURLConnection but we are trying to avoid using it see this example).
I also looked into Spring RestTemplate, and it didn't provide any option either - I searched on Google and didn't find anything around Spring or Apache HTTP Client.
This should give you pretty much a complete control over the process of trust verification.
SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial((chain, authType) -> {
for (X509Certificate cert: chain) {
System.out.println(cert.getSubjectDN());
}
// Let the standard trust managers decide
// whether or not the cert chain is trusted
return false;
})
.build();
CloseableHttpClient client = HttpClientBuilder.create()
.setSSLContext(sslContext)
.build();

Set up Netty-with TLS handsake with ECC and RSA client certificate auth

I am working on a remote server that uses Netty to perform client authentication with a TLS handshake through the Netty SSLHandler library. This S/O question gives a bit: Set up Netty with 2-way SSL Handsake (client and server certificate)
Now, the question I have about this system is that the Server requires a TrustManager to initialize a SSLContext. From what I observe this uses the SunJSSE provider. Now after setting up this implementation, I got it working with RSA client certs. Now, I am having trouble using ECC client certs as SunJSSE cannot recognize them (I think Java SE 7 include SunEC as a provider. But SunEC is a SunJCE implementation and not a SunJSSE one and thus cannot be used as a provider for TrustManager). So, how do I proceed. I heard Bouncy Castle can recognize these certs, but I still cannot instantiate a TrustManager with BC as the provider.
Edit: Also if there is no way to use TrustManagers, should I do the entire handshake only use BouncyCastle's API's and not netty's libraries? That seems off though.
This is my other S/O question that shows the stack trace: Client ECC SSL Certificate contains "unknown named curve"