Teiid 2-way SSL- connection successful even without the Truststore - ssl

I have a teiid embedded server and I am trying to connect to a vds on that server through 2-way SSL from my remote client by passing the teiid SSL properties in SystemProperties as per the teiid documentation at: http://teiid.github.io/teiid-documents/12.3.x/content/client-dev/SSL_Client_Connections.html
The connection is successful even without the truststore which is a mandatory property.
Code snippet to replicate this issue:
Properties properties = new Properties();
properties.put("user", "admin");
properties.put("password", "admin");
System.setProperty("org.teiid.ssl.keyStore", "C:/truststore.p12");
System.setProperty("org.teiid.ssl.keyStorePassword", "testssl");
System.setProperty("org.teiid.ssl.trustAll", "false");
DriverManager.registerDriver(new TeiidDriver());
Connection connection1 = DriverManager.getConnection("jdbc:teiid:testvds#mms://localhost:32750", properties);
if (connection.isValid(1000))
{
System.out.println("Connection success");
}
In this case it should have failed. Can you please let me know if this is an issue or I am missing something on my end.
Thanks,
Megha

Can you elaborate on the server side settings? As the other user is getting at, if the server key is already trusted by the default java trust store you don't need additional client settings.

Related

Reload Netty Server's SSL Context for gRPC

Can someone tell me how to reload the SSLContext when a server certificate it refreshed/renewed without restarting the gRPC server?
I have this code to build and start a gRPC server.
The method certificateRefreshed() gets called whenever a certificate changes which is when I create a new SSL context, but this doesn't work unless I restart the grpc server.
public class ServerWithTls {
Server server;
SslContext sslContext;
public ServerWithTls() {
this.sslContext = getSslContext();
NettyServerBuilder serverBuilder = NettyServerBuilder
.forPort(settings.port())
.executor(executorService)
.addService(myService);
.sslContext(this.sslContext);
server = serverBuilder.build();
server.start();
}
public io.netty.handler.ssl.SslContext getSslContext() {
// returns ssl context based on cert and key
}
// gets notified when a server cert changes
public void certificateRefreshed() {
// create a new SSL context when cert changes
this.sslContext = getSslContext();
}
}
I'm unsure if there are easier alternatives, but I see two potentially possible ways.
Make your own SslContext, mimicking DelegatingSslContext. You would swap to a different SslContext (especially during newEngine) when you want a different certificate.
Use a KeyManagerFactory whose key material can change over time. I'm not aware of a pre-existing implementation of such a factory, so you probably would need to implement a KeyManagerFactorySpi that delegates to a KeyManagerFactory. You could then swap out the KeyManagerFactory over time.
I will warn that it would have been easy for me to miss something that would invalidate the approaches.
This question is similar to this question: Reloading a java.net.http.HttpClient's SSLContext
This option is unfortunately not available by default. After you have supplied the SSLContext to the Server and build the Server you cannot change the SSLContext. You will need to create a new SSLContext and a new Server.
I had the same challenge for one of my projects and I solved it by using a custom trustmanager and keymanager which wraps around the actual trustmanager and keymanager while having the capability of swapping the actual trustmanager and trustmanager. So you can use the following setup if you still want to accomplish it without the need of recreating the Server and SSLContext:
SSLFactory baseSslFactory = SSLFactory.builder()
.withDummyIdentityMaterial()
.withDummyTrustMaterial()
.withSwappableIdentityMaterial()
.withSwappableTrustMaterial()
.build();
Runnable sslUpdater = () -> {
SSLFactory updatedSslFactory = SSLFactory.builder()
.withIdentityMaterial(Paths.get("/path/to/your/identity.jks"), "password".toCharArray())
.withTrustMaterial(Paths.get("/path/to/your/truststore.jks"), "password".toCharArray())
.build();
SSLFactoryUtils.reload(baseSslFactory, updatedSslFactory);
};
// initial update of ssl material to replace the dummies
sslUpdater.run();
// update ssl material every hour
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(sslUpdater, 1, 1, TimeUnit.HOURS);
SslContext sslContext = NettySslUtils.forServer(sslFactory).build();
Server server = NettyServerBuilder
.forPort(8443)
.executor(executorService)
.addService(myService)
.sslContext(sslContext)
.build();
server.start();
See here for the documentation of this option: Reloading ssl at runtime
And here for an actual working example with Jetty (similar to Netty): Example swapping certificates at runtime with Jetty Server
You can add the library to your project with:
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>sslcontext-kickstart-for-netty</artifactId>
<version>7.4.4</version>
</dependency>
You can view the full documentation and other examples here: GitHub - SSLContext Kickstart
By the way I need to add a small disclaimer I am the maintainer of the library.

SSL connection via Domino managed bean to payment gateway fails with 'handshake_failure'

I have a Java agent that connects to a payment gateway to validate a CC transaction.
Everything seems to work fine when the Java logic is run on my IBM Notes client (9.0.1FP10IF3).
I am now migrating the logic to a managed bean on my Domino server (9.0.1FP6).
Whenever the connection is made through the bean, I observe the following error on the server console...
HTTP JVM: javax.net.ssl.SSLHandshakeException: Received fatal alert:
handshake_failure
I am certain it's because the payment gateway with which I am attempting to communicate has recently upgraded to enforce mandatory TLS 1.2 communications.
However, I'm not sure how to enforce those communications on the Domino server side?
I have set the recommended NOTES.INI variables...
DISABLE_SSLV3=1
SSL_DISABLE_TLS_10=1
... and set the 'SSLCipherSpec', but nothing is working.
Here is an excerpt from the logic I'm using to test everything out.
The 'DataOutputStream' line is what triggers the error...
URL url = new URL("https://host/endpoint");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setAllowUserInteraction(false);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-type", "text/xml");
connection.setRequestProperty("Content-length", Integer.toString(postContent.length()));
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes(postContent);
out.flush();
out.close();
connection.disconnect();
Any advice/assistance would be most appreciated!
As Per answered, this document allowed me to resolve the issue straight away...
www-01.ibm.com/support/docview.wss?uid=swg21985289

How to set the username/password on Websphere MQ connection string from .Net / C#?

How to I specify the username and password in a wmq connection string? This is the sample connection string I'm working with.
Uri sampleAddress = new Uri("wmq://localhost:1414/msg/queue/Q1?connectQueueManager=QM1&replyTo=Q2");
How do I put the userId/password used for authentication to the MQ Manager here?
For V8.0 I was successful by making the connection in the following way:
Hashtable connectionProperties = new Hashtable();
connectionProperties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
connectionProperties.Add(MQC.HOST_NAME_PROPERTY, _queueServer);
connectionProperties.Add(MQC.PORT_PROPERTY, _portNumber);
connectionProperties.Add(MQC.CHANNEL_PROPERTY, _channelInfo);
connectionProperties.Add(MQC.USER_ID_PROPERTY, "userid");
connectionProperties.Add(MQC.PASSWORD_PROPERTY, "password");
queueManager = new MQQueueManager(_queueManager, connectionProperties);
See here.
Although for version below 8.0 please see that you will have to use an exit mechanism as for them the client provided id is not used.

handshake_failure trying to access file on same server

My code is trying to access a template file on the same server as the application.
It all worked fine until we switched on SSL.
Now when connecting to the file I get a SSLHandshakeException: handshake_failure with not much information on the actual cause of the issue.
If I try to access the file through the browser I get a warning page asking if I want to proceed at my own risk.
Is it a problem with the certificate? Can I bypass it?
Edit: The server is JBoss EAP 6.1 with Java 1.7. It's configured to use TLS1.2.
The bit retrieving the template is:
URL url;
URLConnection urlConnection;
try {
url = new URL(templateUrl);
urlConnection = url.openConnection();
urlConnection.setConnectTimeout(connectionTimeout);
urlConnection.setReadTimeout(connectionTimeout);
BufferedReader breader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = breader.readLine()) != null) {
strHtmlContent.append(line);
}
}
Handshake error is usually not a problem with the certificate, at least not with the validation of the certificate. It can have several other reasons, typically wrong protocol version, no cipher overlap, missing use of SNI... .
Unfortunately it is impossible to say what the problem is in your specific case but you might narrow it down by trying to access the site with different clients (i.e. browser, curl, ...). If not even a browser can access the site it is probably a misconfiguration of the server.

How to reuse an LDAP connection in Unboundid LDAP SDK?

I have tried to reuse an LDAP connection in Unboundid LDAP SDK using the following code:
if (ldapConnection.isConnected()) {
//Connection is still connected.
} else {
try {
// Connection is not connected. Try to reconnect
ldapConnection.reconnect();
} catch (LDAPException e) {
}
}
Unfortunately, ldapConnection.isConnected() returns true and I get exception later in my code.
What I do wrong?
How to reuse an LDAP connection in Unboundid LDAP SDK?
Why you are using the ldapConnection.reconnect() method vs simply using BindResult bindResult = ldapConnection.bind(bindRequest);
You might also consider using "a connection pool, even if that pool only has a single connection. Connection pools have excellent support for connection management and dealing with connections that have become invalid, and they also offer much better options for failover in that they can be configured with information about multiple servers (through the ServerSet API) so that the best server can be selected." (From http://sourceforge.net/p/ldap-sdk/discussion/1001257/thread/2cd4e0de/#14b5
-jim