Driver version or jar name
6.3.6
SQL Server version
Microsoft SQL Azure (RTM) - 12.0.2000.8
Client operating system
Ubuntu 16.04
Java/JVM version
java version "1.8.0_161"
Table schema
N/A
Problem description
Using the mentioned version of the mssql-jdbc, and connecting to SQL Server on
Azure with a jdbc string provided by Azure, which includes the following
properties:
- sqlserver
- database
- user
- password
- encrypt (with value 'true')
- trustServerCertificate (with value 'false')
- hostNameInCertificate (with value '*.database.windows.net')
- loginTimeout (with value '30')
We are getting sometimes the following stacktrace:
com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.security.cert.CertificateException: Failed to validate the server name in a certificate during Secure Sockets Layer (SSL) initialization.". ClientConnectionId:d5e13b9e-546d-417c-be63-abfece6929fe
at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:2675)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1837)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2262)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:1927)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:1768)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1076)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.checkClosed(SQLServerConnection.java:1011)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.createStatement(SQLServerConnection.java:3161)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.createStatement(SQLServerConnection.java:2843)
at com.feedzai.commons.sql.abstraction.engine.impl.SqlServerEngine.checkConnection(SqlServerEngine.java:743)
at com.feedzai.commons.sql.abstraction.engine.AbstractDatabaseEngine.getConnection(AbstractDatabaseEngine.java:273)
at com.feedzai.commons.sql.abstraction.engine.AbstractDatabaseEngine.beginTransaction(AbstractDatabaseEngine.java:416)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.beginTx(ThreadScopeTransactionFun.java:331)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.transaction(ThreadScopeTransactionFun.java:280)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.call(ThreadScopeTransactionFun.java:257)
at com.feedzai.pulse.service.apps.database.TransactionInterceptor.invoke(TransactionInterceptor.java:91)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:77)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:55)
at com.feedzai.pulse.service.apps.manager.RoleManagerImpl$$EnhancerByGuice$$eba0945d.list(<generated>)
at com.feedzai.pulse.service.security.projection.Projection.reload(Projection.java:72)
at com.feedzai.pulse.service.security.PulseSecurityImpl.doReloadSecurity(PulseSecurityImpl.java:287)
at com.feedzai.pulse.service.security.PulseSecurityImpl.lambda$reloadSecurityLocally$2(PulseSecurityImpl.java:349)
at com.feedzai.pulse.service.security.PulseSecurityUtils.lambda$doAsSystemUser$0(PulseSecurityUtils.java:268)
at com.feedzai.pulse.service.security.PulseSecurityUtils.getAsSystemUser(PulseSecurityUtils.java:286)
at com.feedzai.pulse.service.security.PulseSecurityUtils.doAsSystemUser(PulseSecurityUtils.java:267)
at com.feedzai.pulse.service.security.PulseSecurityImpl.reloadSecurityLocally(PulseSecurityImpl.java:341)
at com.feedzai.pulse.service.security.PulseSecurityImpl.reloadSecurityInCluster(PulseSecurityImpl.java:506)
at com.feedzai.pulse.service.security.PulseSecurityImpl.reloadSecurity(PulseSecurityImpl.java:272)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.reloadSecurity(ThreadScopeTransactionFun.java:460)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.commitTx(ThreadScopeTransactionFun.java:413)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.transaction(ThreadScopeTransactionFun.java:294)
at com.feedzai.pulse.service.apps.util.ThreadScopeTransactionFun.call(ThreadScopeTransactionFun.java:257)
at com.feedzai.pulse.service.apps.database.TransactionInterceptor.invoke(TransactionInterceptor.java:91)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:77)
at com.feedzai.pulse.service.security.guice.EnforcePermissionsInterceptor.invoke(EnforcePermissionsInterceptor.java:55)
at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:77)
at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:55)
at com.feedzai.pulse.service.apps.manager.datascience.AppDataScienceTagGroupManagerImpl$$EnhancerByGuice$$2b7a2b98.ensureTags(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.feedzai.remote.autowire.remote.RemoteWrapperImpl.invokeRemotely(RemoteWrapperImpl.java:102)
at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:361)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: Failed to validate the server name in a certificate during Secure Sockets Layer (SSL) initialization.
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1767)
... 57 common frames omitted
Caused by: java.security.cert.CertificateException: Failed to validate the server name in a certificate during Secure Sockets Layer (SSL) initialization.
at com.microsoft.sqlserver.jdbc.TDSChannel$HostNameOverrideX509TrustManager.validateServerNameInCertificate(IOBuffer.java:1547)
at com.microsoft.sqlserver.jdbc.TDSChannel$HostNameOverrideX509TrustManager.checkServerTrusted(IOBuffer.java:1462)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:985)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
... 65 common frames omitted
This problem happens when the "hostNameInCertificate" property is changed by the driver on the SQLServerConnection class (because of a ENVCHANGE_ROUTING).
In that case, the original "hostNameInCertificate" (which comes from the jdbc string provided by Azure) is replaced by the routing server name.
This will trigger an exception on the method validateServerNameInCertificate since the routing server name does not exist on the certificate.
Expected behavior and actual behavior
Probably, the "hostNameInCertificate" property shouldn't be changed the way it is currently being done, because there are no guarantees that afterward, we will validate the server name in the certificate successfully.
The expected behavior is that this error shouldn't happen since we are providing a correct "hostNameInCertificate" (and which works fine until we have that ENVCHANGE_ROUTING event).
Repro code
Setup on an Azure account both a SQL Server/Database and a VM with a client that uses the mssql-jdbc lib and perform operations with it.
As said previously, this happens from time to time so it may take a little bit to reproduce this behavior.
Driver version or jar name
6.3.6
SQL Server version
Microsoft SQL Azure (RTM) - 12.0.2000.8
Client operating system
Ubuntu 16.04
Java/JVM version
java version "1.8.0_161"
Table schema
N/A
Problem description
Using the mentioned version of the mssql-jdbc, and connecting to SQL Server on
Azure with a jdbc string provided by Azure, which includes the following
properties:
We are getting sometimes the following stacktrace:
This problem happens when the "hostNameInCertificate" property is changed by the driver on the SQLServerConnection class (because of a ENVCHANGE_ROUTING).
In that case, the original "hostNameInCertificate" (which comes from the jdbc string provided by Azure) is replaced by the routing server name.
This will trigger an exception on the method validateServerNameInCertificate since the routing server name does not exist on the certificate.
Expected behavior and actual behavior
Probably, the "hostNameInCertificate" property shouldn't be changed the way it is currently being done, because there are no guarantees that afterward, we will validate the server name in the certificate successfully.
The expected behavior is that this error shouldn't happen since we are providing a correct "hostNameInCertificate" (and which works fine until we have that ENVCHANGE_ROUTING event).
Repro code
Setup on an Azure account both a SQL Server/Database and a VM with a client that uses the mssql-jdbc lib and perform operations with it.
As said previously, this happens from time to time so it may take a little bit to reproduce this behavior.