Can we use mTLS for smtp communication? - java

It could be a dumb question? Can we use mTLS instead of TLS 1.2 or TLS 1.3 for Java SMTP communication? For e.g. below code is used to enable TLS in Java SMTP.
Properties props= new Properties();
props.put("mail.smtp.ssl.checkserveridentity", true);
Session session = Session.getDefaultInstance(props);
The above code is actually one-way SSL. Here client identifies the server. Can we make it 2-way or mTLS?
I think Spring-boot has support for mTLS (https communication) We need to set the below in application.properties.
server.ssl.client-auth = need
Any solution or reference would be highly appreciated?

Related

Displaying remote SMTP TLS certificate information with org.apache.commons.net.smtp

I'm using org.apache.commons.net.smtp.AuthenticatingSMTPClient to establish connections to SMTP servers. After establishing the initial connection, I use client.execTLS() to send STARTTLS. I want to get the SMTP TLS certificate information for the certificates used by the remote server. I'm curious if it's possible to do so solely with the API offered by the org.apache.commons.net.smtp library.
Alternatively, what options do I have within the Java ecosystem to output the SMTP TLS certificate in a readable format, preferably using the socket already opened by client.execTLS()?
Java version: 11.
Found the solution. You can provide your own HostnameVerifier (null by default) to the org.apache.commons.net.smtp.AuthenticatingSMTPClient object:
client.setHostnameVerifier((hostname, session) -> {
// session.getPeerCertificates();
return true;
});

Connecting to Azure Redis from proxy server

I am trying to connect to Azure redis cache from inside of corporate network. Could anyone give suggestion how to connnect to Azure redis via Proxy? I am using Jedis and spring boot.
According to the official document and the case Does Azure Redis work over http?, Azure Redis use TCP protocol and does not support HTTP protocol.
So you need to use Socket 4/5 proxy instead of HTTP proxy, then set proxy parameters in the Java app.
Properties prop = System.getProperties();
prop.setProperty("socksProxyHost", "IP ADDRESS");
prop.setProperty("socksProxyPort", "PORT");
Authenticator.setDefault(new MyAuthenticator("userName", "Password"));

Adding client authentication in SSL handshake without certificate

I want to implement client - server application which require client authentication using some other data than certificates (for example using password). Everywhere I looked for something like that, I found only 2-way (mutual) SSL authentication with client and server certificates, which I don't want.
Is there some APIs for customizing ssl handshake and adding client authentication? Is it possible to build application like this using JSSE package or some other Java technologies?
Any kind of advice or guidelines about this would be very helpful becouse I'm new in this topic.
You can use HTTP Basic Authentication. So you set up your server just under HTTP and authenticate via password/username. To write your own protocol....there has to be done to much....

Two way SSL authentication in Netty

I'm working on a Server and Client based app which require two way SSL authentication. (Client authenticates server and Server authenticate client both using SSL Certificates.)
I'm quite new to Netty and have few doubts regarding this.
Is two way authentication possible using Netty?
Can it be simply achievable by adding another SslHandler to the pipelinefactories of both server and client?
If the above is true, how can I grab the required SslHandler at the ChannelConnected() method to do the SslHandshake? And Is it possible to invoke the second handshake at the ChannelConected() method by calling the pipeline back again?
Are there any examples I could refer to regarding this?
I really appreciate any help regarding this, answers or a push in right direction.
Is two way authentication possible using Netty?
Yes
Can it be simply achievable by adding another SslHandler to the pipelinefactories of both server and client?
Yes
If the above is true, how can I grab the required SslHandler at the ChannelConnected() method to do the SslHandshake?
You need the setup the keystore and the truststore correctly when creating your SSLContext.
And Is it possible to invoke the second handshake at the ChannelConected() method by calling the pipeline back again?
From memory, client and server authentication is done in the 1st handshake.
On the client, install the client's private key in the keystore and the server's public key in the truststore.
On the server, install the server's private key in the keystore and the client's public key in the truststore.
Are there any examples I could refer to regarding this?
Here's an example I did for websockets. It only shows you how to setup the server keystore. You will have to add a truststore as the 2nd parameter of serverContext.init(kmf.getKeyManagers(), null, null);
Here's a similar example in Scala with trust store setup.
Here's a good java guide on how to setup SSLContext.
Hope this helps.
Two way authentication requires that both server and client have certificates that the other trusts. The client needs to generate a private key, store it in his keystore, and get it signed by somebody that the server's truststore trusts.
It isn't just a matter of what code you write.
SSL is a presentation layer protocol and the SSL handshake happens right after the socket connection is established and the before the application layer gets a usable socket connection. No matter what application you are using, if you have the SSL protocol layer in place then you can work over SSL.
Two way authentication is just a matter of configuration as mentioned by #EJP above. If both the parties can establish and validate each other trust chain then the handshake succeeds. Refer the netty configuration manual for configuring SSL truststores.

ssl client authentication without ssl re-negotiation

On client side I have Apache HTTP client on jdk5u22. On server side I have tomcat on jdk6u27.
With this setup if I try SSL Client authentication (2 way SSL) then it cause "javax.net.ssl.SSLHandshakeException: Insecure renegotiation is not allowed" on the server and handshake fails. It succeeds if I set system properties sun.security.ssl.allowUnsafeRenegotiation=true and sun.security.ssl.allowLegacyHelloMessages=true on server.
As per the link http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html this is coz JRE6u27 has the RFC 5746 implementation and JRE5u26 below doesnt have this and so both are incompatible. Unfortunately 5u22 is the latest freely available java 5 version. So I want to know if it is possible to have SSL client authentication without ssl re-negotiation.
Regards,
Litty Preeth
As per the redhat site https://access.redhat.com/kb/docs/DOC-20491#Renegotiations_disabled_in_Apache_Tomcat :
Tomcat may ask the client to renegotiate in certain configurations using client certificate authentication, for example, configurations where:
A client certificate is not required on the initial connection, such as when:
1. The clientAuth attribute of the HTTPS connector using JSSE is set to
false. Or The SSLVerifyClient attribute of the HTTPS connector using
OpenSSL is set to none.
AND
2. A web application specifies the CLIENT-CERT authentication method in
the login-config section of the application's web.xml file.
So to avoid re-negotiation in tomcat just make the whole site secure and not just a part of it by setting clientAuth="true" for ssl .
Hope this helps someone.
Regards,
Litty

Categories