Getting SSLHandshakeException when using Dropbox Java SDK for API v2

In the XPages app, I want to use the Dropbox Java SDK (2.1.2) for the API v2 to get information about my Dropbox account. The following code is used to retrieve the corresponding account object:

String atoken = "****"; DbxRequestConfig rc = new DbxRequestConfig("****"); DbxClientV2 client = new DbxClientV2(rc,atoken); DbxUserUsersRequests users = client.users(); FullAccount acc = users.getCurrentAccount(); // Exception raised here 

The last line throws the following exception:

 com.dropbox.core.NetworkIOException: No appropriate protocol at com.dropbox.core.DbxRequestUtil.startPostRaw(DbxRequestUtil.java:240) ... Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol at com.ibm.jsse2.kb.c(kb.java:347) ... 

From stacktrace, I came to the conclusion that IBMJSSE2 is the security provider used to handle SSL handshakes. So I ran the code from above in a non-Domino JVM (JRE7) that uses the SunJSSE security provider , and it worked without problems. Therefore, the problem should be related to the IBM Domino JVM, but I cannot figure out how to fix it.

Can someone help me with this or give a hint for a solution?


Additional information :

Domino server version: 9.0.1 FP4 HF70

Java Runtime Version: pwa6460sr16fp4-20150414_01 (SR16 FP4) [22B8: 0002-1E88]

JVM version: JRE 1.6.0 IBM J9 2.4 Windows 7 amd64-64 jvmwa6460sr16fp4-20150406_242976 (JIT on, AOT on) J9VM - 20150406_242976 JIT - r9_20150402_88984 GC - GA24_Java6_SR16_201504024676141

Domino JVM has unlimited JCE policy files installed.

IBMJSSE2 Security Provider Properties :

 Alg.Alias.TrustManagerFactory.IbmPKIX = PKIX Alg.Alias.TrustManagerFactory.X.509 = PKIX Alg.Alias.TrustManagerFactory.X509 = PKIX KeyManagerFactory.IbmX509 = com.ibm.jsse2.rc$a_ KeyManagerFactory.NewIbmX509 = com.ibm.jsse2.rc$b_ Provider.id className = com.ibm.jsse2.IBMJSSEProvider2 Provider.id info = IBM JSSE provider2 (implements IbmX509 key/trust factories, SSLv3, TLSv1) Provider.id name = IBMJSSE2 Provider.id version = 1.6 SSLContext.Default = com.ibm.jsse2.tc SSLContext.SSL = com.ibm.jsse2.uc SSLContext.SSL_TLS = com.ibm.jsse2.vc SSLContext.SSL_TLSv2 = com.ibm.jsse2.wc SSLContext.TLS = com.ibm.jsse2.yc SSLContext.TLSv1 = com.ibm.jsse2.zc SSLContext.TLSv1.1 = com.ibm.jsse2.ad SSLContext.TLSv1.2 = com.ibm.jsse2.bd TrustManagerFactory.IbmX509 = com.ibm.jsse2.ed$b_ TrustManagerFactory.PKIX = com.ibm.jsse2.ed$a_ 

Full stack of exceptions:

 com.dropbox.core.NetworkIOException: No appropriate protocol at com.dropbox.core.DbxRequestUtil.startPostRaw(DbxRequestUtil.java:240) at com.dropbox.core.v2.DbxRawClientV2$1.execute(DbxRawClientV2.java:100) at com.dropbox.core.v2.DbxRawClientV2.executeRetriable(DbxRawClientV2.java:256) at com.dropbox.core.v2.DbxRawClientV2.rpcStyle(DbxRawClientV2.java:97) at com.dropbox.core.v2.users.DbxUserUsersRequests.getCurrentAccount(DbxUserUsersRequests.java:120) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:611) at com.ibm.jscript.types.JavaAccessObject.call(JavaAccessObject.java:321) at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161) at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197) at com.ibm.jscript.ASTTree.ASTAssign.interpret(ASTAssign.java:91) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109) at com.ibm.jscript.std.FunctionObject._executeFunction(FunctionObject.java:261) at com.ibm.jscript.std.FunctionObject.executeFunction(FunctionObject.java:185) at com.ibm.jscript.std.FunctionObject.call(FunctionObject.java:171) at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161) at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197) at com.ibm.jscript.ASTTree.ASTAssign.interpret(ASTAssign.java:91) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85) at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119) at com.ibm.jscript.types.FBSGlobalObject$GlobalMethod.call(FBSGlobalObject.java:280) at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161) at com.ibm.jscript.types.FBSGlobalObject$GlobalMethod.call(FBSGlobalObject.java:219) at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109) at com.ibm.jscript.std.FunctionObject._executeFunction(FunctionObject.java:261) at com.ibm.jscript.std.FunctionObject.executeFunction(FunctionObject.java:185) at com.ibm.jscript.std.FunctionObject.call(FunctionObject.java:171) at com.ibm.jscript.std.FunctionPrototype$FunctionMethod.call(FunctionPrototype.java:169) at com.ibm.jscript.types.FBSObject.call(FBSObject.java:161) at com.ibm.jscript.ASTTree.ASTCall.interpret(ASTCall.java:197) at com.ibm.jscript.ASTTree.ASTAssign.interpret(ASTAssign.java:91) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTIf.interpret(ASTIf.java:85) at com.ibm.jscript.ASTTree.ASTBlock.interpret(ASTBlock.java:100) at com.ibm.jscript.ASTTree.ASTTry.interpret(ASTTry.java:109) at com.ibm.jscript.ASTTree.ASTProgram.interpret(ASTProgram.java:119) at com.ibm.jscript.ASTTree.ASTProgram.interpretEx(ASTProgram.java:139) at com.ibm.jscript.JSExpression._interpretExpression(JSExpression.java:435) at com.ibm.jscript.JSExpression.access$1(JSExpression.java:424) at com.ibm.jscript.JSExpression$2.run(JSExpression.java:414) at java.security.AccessController.doPrivileged(AccessController.java:448) at com.ibm.jscript.JSExpression.interpretExpression(JSExpression.java:410) at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:251) at com.ibm.jscript.JSExpression.evaluateValue(JSExpression.java:234) at com.ibm.xsp.javascript.JavaScriptInterpreter.interpret(JavaScriptInterpreter.java:222) at com.ibm.xsp.binding.javascript.JavaScriptMethodBinding.invoke(JavaScriptMethodBinding.java:111) at com.ibm.xsp.component.UIViewRootEx.invokePhaseMethodBinding(UIViewRootEx.java:1735) at com.ibm.xsp.controller.FacesControllerImpl.invokePhaseMethodBinding(FacesControllerImpl.java:450) at com.ibm.xsp.controller.FacesControllerImpl.access$0(FacesControllerImpl.java:444) at com.ibm.xsp.controller.FacesControllerImpl$ViewPhaseListener.afterPhase(FacesControllerImpl.java:512) at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:218) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:120) at com.ibm.xsp.controller.FacesControllerImpl.render(FacesControllerImpl.java:270) at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:261) at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:157) at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160) at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138) at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103) at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:576) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1335) at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:853) at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:796) at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:565) at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1319) at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:662) at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:482) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:357) at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:313) at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272) Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol at com.ibm.jsse2.kb.c(kb.java:347) at com.ibm.jsse2.SSLSocketImpl.i(SSLSocketImpl.java:363) at com.ibm.jsse2.SSLSocketImpl.h(SSLSocketImpl.java:650) at com.ibm.jsse2.SSLSocketImpl.a(SSLSocketImpl.java:669) at com.ibm.jsse2.SSLSocketImpl.startHandshake(SSLSocketImpl.java:95) at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:162) at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:36) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1044) at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:53) at com.dropbox.core.http.StandardHttpRequestor.getOutputStream(StandardHttpRequestor.java:123) at com.dropbox.core.http.StandardHttpRequestor.access$000(StandardHttpRequestor.java:28) at com.dropbox.core.http.StandardHttpRequestor$Uploader.(StandardHttpRequestor.java:133) at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:72) at com.dropbox.core.http.StandardHttpRequestor.startPost(StandardHttpRequestor.java:28) at com.dropbox.core.DbxRequestUtil.startPostRaw(DbxRequestUtil.java:232) ... 

Update . After setting javax.net.debug=ssl:handshake:data (as suggested by Jigar Joshi), the error log and trace log provide the following additional information:

Certificate with subject EMAILADDRESS = ****, CN = ****, O = ****, L = ****, ST = ****, C = **** issued by CN = ** **, OU = ****, O = ****, C = ****, do not trust. Verification error with error 3659 .

 CommonBaseEventLogRecord:sourceClassName = com.ibm.domino.napi.ssl.DominoX509TrustManager CommonBaseEventLogRecord:sourceMethodName = checkServerTrusted <sourcecomponentid component="Expeditor 6.2" componentidtype="ProductName" instanceid="" location="****" locationtype="Hostname" subcomponent="com.ibm.domino.napi.ssl" threadid="5" componenttype="http://www.w3.org/2001/XMLSchema-instance"> 

The untrusted certificate is my own , although all certificates and the private key were imported into my key store. The fact that the keystore is running in a non-Domino JVM allows us to conclude that the keystore file must be valid. However, the certificate is still not trusted when running code in the Domino JVM.


Refresh . The bulk of the debug output ( javax.net.debug=ssl:handshake ) -

 SSLContextImpl: Using X509ExtendedKeyManager com.ibm.jsse2.hd SSLContextImpl: Using X509TrustManager com.ibm.jsse2.pc IBMJSSE2 will ignore com.ibm.jsse2.overrideDefaultProtocol since was set to a non recognized value TLSv1 Installed Providers = IBMJSSE2, IBMJCE, IBMJGSSProvider, IBMCertPath, IBMSASL, IBMXMLCRYPTO, IBMXMLEnc, Policy, IBMSPNEGO JsseJCE: Using SecureRandom IBMSecureRandom from provider IBMJCE version 1.2 trigger seeding of SecureRandom done seeding SecureRandom IBMJSSE2 will enable CBC protection IBMJSSE2 to send SCSV Cipher Suite on initial ClientHello JsseJCE: Using SecureRandom IBMSecureRandom from provider IBMJCE version 1.2 IBMJSSE2 will allow RFC 5746 renegotiation per com.ibm.jsse2.renegotiate set to none or default IBMJSSE2 will not require renegotiation indicator during initial handshake per com.ibm.jsse2.renegotiation.indicator set to OPTIONAL or default taken IBMJSSE2 will not perform identity checking against the peer cert check during renegotiation per com.ibm.jsse2.renegotiation.peer.cert.check set to OFF or default IBMJSSE2 will not allow unsafe server certificate change during renegotiation per jdk.tls.allowUnsafeServerCertChange set to FALSE or default Is initial handshake: true JsseJCE: Using KeyAgreement ECDH from provider IBMJCE version 1.2 JsseJCE: Using signature SHA1withECDSA from provider TBD via init JsseJCE: Using signature NONEwithECDSA from provider TBD via init JsseJCE: Using KeyFactory EC from provider IBMJCE version 1.2 JsseJCE: Using KeyPairGenerator EC from provider TBD via init JsseJce: EC is available Ignoring disabled cipher suite: SSL_RENEGO_PROTECTION_REQUEST for TLSv1 No available cipher suite for TLSv1 Thread-8, handling exception: javax.net.ssl.SSLHandshakeException: No appropriate protocol Thread-8, SEND TLSv1 ALERT: fatal, description = handshake_failure 

The โ€œ missing cipher suite for TLSv1 โ€ seems to be the root of my problem.


Refresh . Getting the standard factory SSL server socket ( SSLServerSocketFactory.getDefault() ) and the corresponding standard and supported cipher suites ( getDefaultCipherSuites() / getSupportedCipherSuites() ) showed that only SSL encryption is available:

 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [supported] SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA [default] SSL_DHE_DSS_WITH_AES_128_CBC_SHA [default] SSL_DHE_DSS_WITH_AES_128_CBC_SHA256 [supported] SSL_DHE_DSS_WITH_AES_128_GCM_SHA256 [supported] SSL_DHE_DSS_WITH_AES_256_CBC_SHA [default] SSL_DHE_DSS_WITH_AES_256_CBC_SHA256 [supported] SSL_DHE_DSS_WITH_AES_256_GCM_SHA384 [supported] SSL_DHE_DSS_WITH_DES_CBC_SHA [default] SSL_DHE_DSS_WITH_RC4_128_SHA [supported] SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [supported] SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA [default] SSL_DHE_RSA_WITH_AES_128_CBC_SHA [default] SSL_DHE_RSA_WITH_AES_128_CBC_SHA256 [supported] SSL_DHE_RSA_WITH_AES_128_GCM_SHA256 [supported] SSL_DHE_RSA_WITH_AES_256_CBC_SHA [default] SSL_DHE_RSA_WITH_AES_256_CBC_SHA256 [supported] SSL_DHE_RSA_WITH_AES_256_GCM_SHA384 [supported] SSL_DHE_RSA_WITH_DES_CBC_SHA [default] SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA [supported] SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 [supported] SSL_DH_anon_WITH_3DES_EDE_CBC_SHA [supported] SSL_DH_anon_WITH_AES_128_CBC_SHA [supported] SSL_DH_anon_WITH_AES_128_CBC_SHA256 [supported] SSL_DH_anon_WITH_AES_128_GCM_SHA256 [supported] SSL_DH_anon_WITH_AES_256_CBC_SHA [supported] SSL_DH_anon_WITH_AES_256_CBC_SHA256 [supported] SSL_DH_anon_WITH_AES_256_GCM_SHA384 [supported] SSL_DH_anon_WITH_DES_CBC_SHA [supported] SSL_DH_anon_WITH_RC4_128_MD5 [supported] SSL_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [supported] SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [supported] SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [supported] SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [supported] SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [supported] SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [supported] SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [supported] SSL_ECDHE_ECDSA_WITH_NULL_SHA [supported] SSL_ECDHE_ECDSA_WITH_RC4_128_SHA [supported] SSL_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [supported] SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA [supported] SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [supported] SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [supported] SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA [supported] SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [supported] SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [supported] SSL_ECDHE_RSA_WITH_NULL_SHA [supported] SSL_ECDHE_RSA_WITH_RC4_128_SHA [supported] SSL_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [supported] SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA [supported] SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [supported] SSL_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [supported] SSL_ECDH_ECDSA_WITH_AES_256_CBC_SHA [supported] SSL_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [supported] SSL_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [supported] SSL_ECDH_ECDSA_WITH_NULL_SHA [supported] SSL_ECDH_ECDSA_WITH_RC4_128_SHA [supported] SSL_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [supported] SSL_ECDH_RSA_WITH_AES_128_CBC_SHA [supported] SSL_ECDH_RSA_WITH_AES_128_CBC_SHA256 [supported] SSL_ECDH_RSA_WITH_AES_128_GCM_SHA256 [supported] SSL_ECDH_RSA_WITH_AES_256_CBC_SHA [supported] SSL_ECDH_RSA_WITH_AES_256_CBC_SHA384 [supported] SSL_ECDH_RSA_WITH_AES_256_GCM_SHA384 [supported] SSL_ECDH_RSA_WITH_NULL_SHA [supported] SSL_ECDH_RSA_WITH_RC4_128_SHA [supported] SSL_ECDH_anon_WITH_3DES_EDE_CBC_SHA [supported] SSL_ECDH_anon_WITH_AES_128_CBC_SHA [supported] SSL_ECDH_anon_WITH_AES_256_CBC_SHA [supported] SSL_ECDH_anon_WITH_NULL_SHA [supported] SSL_ECDH_anon_WITH_RC4_128_SHA [supported] SSL_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [supported] SSL_KRB5_EXPORT_WITH_DES_CBC_40_SHA [supported] SSL_KRB5_EXPORT_WITH_RC4_40_MD5 [supported] SSL_KRB5_EXPORT_WITH_RC4_40_SHA [supported] SSL_KRB5_WITH_3DES_EDE_CBC_MD5 [supported] SSL_KRB5_WITH_3DES_EDE_CBC_SHA [supported] SSL_KRB5_WITH_DES_CBC_MD5 [supported] SSL_KRB5_WITH_DES_CBC_SHA [supported] SSL_KRB5_WITH_RC4_128_MD5 [supported] SSL_KRB5_WITH_RC4_128_SHA [supported] SSL_RSA_EXPORT_WITH_DES40_CBC_SHA [supported] SSL_RSA_EXPORT_WITH_RC4_40_MD5 [supported] SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA [default] SSL_RSA_FIPS_WITH_DES_CBC_SHA [default] SSL_RSA_WITH_3DES_EDE_CBC_SHA [default] SSL_RSA_WITH_AES_128_CBC_SHA [default] SSL_RSA_WITH_AES_128_CBC_SHA256 [supported] SSL_RSA_WITH_AES_128_GCM_SHA256 [supported] SSL_RSA_WITH_AES_256_CBC_SHA [default] SSL_RSA_WITH_AES_256_CBC_SHA256 [supported] SSL_RSA_WITH_AES_256_GCM_SHA384 [supported] SSL_RSA_WITH_DES_CBC_SHA [default] SSL_RSA_WITH_NULL_MD5 [supported] SSL_RSA_WITH_NULL_SHA [supported] SSL_RSA_WITH_NULL_SHA256 [supported] SSL_RSA_WITH_RC4_128_MD5 [supported] SSL_RSA_WITH_RC4_128_SHA [supported] 

Can someone tell me how to make the TLS encryption set available in the factory server socket?

0
source share
2 answers

The problem is that the Dropbox Java SDK limits the allowed encryption blocks in SSL sockets based on a hard-coded list. All matching cipher suite names in this list begin with " TLS _ ". However, in Domino cipher names, JVMs always begin with " SSL _ ", even if in the SSL context they are associated with TLSv1 or higher.

Now I have stopped working with the Dropbox Java SDK and started using the Dropbox API by making HTTP messages using the HttpsUrlConnection . This is not as convenient as the Java SDK, but at least the SSL handshake with TLSv1 works as expected.

0
source

Re

 com.dropbox.core.NetworkIOException: No appropriate protocol 

My best guess is that this line is a strong hint of your problem:

 Provider.id info = IBM JSSE provider2 (implements IbmX509 key/trust factories, SSLv3, TLSv1) 

โ€œThere is no suitable protocolโ€, it looks like it probably tells you that the endpoint does not support SSLv3 or TLSv1.

I donโ€™t know about Dropbox, but many service providers are abandoning obsolete old protocols due to known security issues.

You can find useful information in these two IBM technotes .

+1
source

Source: https://habr.com/ru/post/1260412/


All Articles