[QFJ-254] SSLContextFactory doesn't load a SocketKeyStore configured as a file path Created: 01/Oct/07 Updated: 15/Jan/08 Resolved: 13/Dec/07 Status: Project: Component/s: Affects Version/s: Fix Version/s: Closed QuickFIX/J None 1.3.0 Type: Reporter: Resolution: Labels: Environment: Improvement Priority: James Furness Assignee: Fixed Votes: None WinXP SP2, jdk1.5.0_11, QuickFIXJ 1.3.0 1.3.1 Default Unassigned 0 Description The initializeKeyStore() method of SSLContextFactory uses SSLContextFactory.class.getResourceAsStream() followed by SSLContextFactory.class.getClassLoader().getResourceAsStream() to locate the configured SocketKeyStore. Both of these seem to return null if SocketKeyStore is a local path. The Configuring QuickFIX/J section of the user manual states valid values for SocketKeyStore are "File path", so I assume this isn't intentional. Applying the patch below to SSLContextFactory.java fixes the issue for me: 75a84,89 > if (in == null) { > try { > in = new FileInputStream(keyStoreName); > } catch (FileNotFoundException ex) { >} >} I've attached the abridged output from running a test app with Djavax.net.debug=ssl:handshake, this shows the SSL handshake is failing due to an empty certificate chain, and that a keystore hasn't been loaded. Before: ----------------- <20071001-17:33:32, FIX.4.4:SOURCE->TARGET, event> (Session FIX.4.4:SOURCE>TARGET schedule is daily, 00:00:00 UTC - 00:00:00 UTC (daily, 00:00:00 UTC - 00:00:00 UTC)) <20071001-17:33:32, FIX.4.4:SOURCE->TARGET, event> (Created session: FIX.4.4:SOURCE->TARGET) trigger seeding of SecureRandom done seeding SecureRandom Using SSLEngineImpl. %% No cached client session *** ClientHello, TLSv1 RandomCookie: ... Session ID: {} Cipher Suites: ... Compression Methods: { 0 } *** SocketConnector-0, WRITE: TLSv1 Handshake, length = 73 SocketConnector-0, WRITE: SSLv2 client hello message, length = 98 SocketConnectorIoProcessor-0.0, READ: TLSv1 Handshake, length = 1425 *** ServerHello, TLSv1 RandomCookie: ... Session ID: ... Cipher Suite: SSL_RSA_WITH_RC4_128_MD5 Compression Method: 0 *** %% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5] ** SSL_RSA_WITH_RC4_128_MD5 *** Certificate chain chain [0] = [ [ Version: V1 Subject: ... Signature Algorithm: ... Key: Sun RSA public key, 1024 bits modulus: ... public exponent: ... Validity: [From: Tue Jun 07 19:13:15 BST 2005, To: Fri Jun 05 19:13:15 BST 2015] Issuer: ... SerialNumber: ... ] Algorithm: [MD5withRSA] Signature: ... ] *** *** CertificateRequest Cert Types: RSA, DSS, Cert Authorities: ... *** ServerHelloDone *** Certificate chain *** *** ClientKeyExchange, RSA PreMasterSecret, TLSv1 Random Secret: ... SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 141 SESSION KEYGEN: ... CONNECTION KEYGEN: Client Nonce: ... Server Nonce: ... Master Secret: ... Client MAC write Secret: ... Server MAC write Secret: ... Client write key: ... Server write key: ... ... no IV for cipher SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Change Cipher Spec, length = 1 *** Finished verify_data: ... *** SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 32 SocketConnectorIoProcessor-0.0, READ: TLSv1 Alert, length = 2 SocketConnectorIoProcessor-0.0, RECV TLSv1 ALERT: fatal, bad_certificate SocketConnectorIoProcessor-0.0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: bad_certificate SocketConnectorIoProcessor-0.0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: bad_certificate <20071001-17:33:37, FIX.4.4:SOURCE->TARGET, event> (Disconnecting) SocketConnectorIoProcessor-0.0, called closeOutbound() SocketConnectorIoProcessor-0.0, closeOutboundInternal() SocketConnectorIoProcessor-0.0, SEND TLSv1 ALERT: warning, description = close_notify SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Alert, length = 18 SocketConnectorIoProcessor-0.0, called closeInbound() SocketConnectorIoProcessor-0.0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack? SocketConnectorIoProcessor-0.0, called closeOutbound() SocketConnectorIoProcessor-0.0, closeOutboundInternal() ----------------After: ----------------<20071001-17:34:17, FIX.4.4:SOURCE->TARGET, event> (Session FIX.4.4:SOURCE>TARGET schedule is daily, 00:00:00 UTC - 00:00:00 UTC (daily, 00:00:00 UTC - 00:00:00 UTC)) <20071001-17:34:17, FIX.4.4:SOURCE->TARGET, event> (Created session: FIX.4.4:SOURCE->TARGET) *** found key for : TARGET chain [0] = [ [ Version: V1 Subject: ... Signature Algorithm: ... Key: Sun RSA public key, 1024 bits modulus: ... public exponent: ... Validity: [From: Wed Jun 06 16:51:56 BST 2007, To: Sat Jun 03 16:51:56 BST 2017] Issuer: ... SerialNumber: ... ] Algorithm: [MD5withRSA] Signature: ... ] *** trigger seeding of SecureRandom done seeding SecureRandom Using SSLEngineImpl. %% No cached client session *** ClientHello, TLSv1 RandomCookie: ... Session ID: {} Cipher Suites: ... Compression Methods: { 0 } *** SocketConnector-0, WRITE: TLSv1 Handshake, length = 73 SocketConnector-0, WRITE: SSLv2 client hello message, length = 98 SocketConnectorIoProcessor-0.0, READ: TLSv1 Handshake, length = 1425 *** ServerHello, TLSv1 RandomCookie: ... Session ID: ... Cipher Suite: SSL_RSA_WITH_RC4_128_MD5 Compression Method: 0 *** %% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5] ** SSL_RSA_WITH_RC4_128_MD5 *** Certificate chain chain [0] = [ [ Version: V1 Subject: ... Signature Algorithm: ... Key: Sun RSA public key, 1024 bits modulus: ... public exponent: ... Validity: [From: Tue Jun 07 19:13:15 BST 2005, To: Fri Jun 05 19:13:15 BST 2015] Issuer: ... SerialNumber: ... ] Algorithm: [MD5withRSA] Signature: ... ] *** *** CertificateRequest Cert Types: RSA, DSS, Cert Authorities: ... *** ServerHelloDone matching alias: TARGET *** Certificate chain chain [0] = [ [ Version: V1 Subject: ... Signature Algorithm: ... Key: Sun RSA public key, 1024 bits modulus: ... public exponent: ... Validity: [From: Wed Jun 06 16:51:56 BST 2007, To: Sat Jun 03 16:51:56 BST 2017] Issuer: ... SerialNumber: ... ] Algorithm: [MD5withRSA] Signature: ... ] *** *** ClientKeyExchange, RSA PreMasterSecret, TLSv1 Random Secret: ... SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 604 SESSION KEYGEN: PreMaster Secret: ... CONNECTION KEYGEN: Client Nonce: ... Server Nonce: ... Master Secret: ... Client MAC write Secret: ... Server MAC write Secret: ... Client write key: ... Server write key: ... ... no IV for cipher *** CertificateVerify SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 134 SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Change Cipher Spec, length = 1 *** Finished verify_data: ... *** SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 32 SocketConnectorIoProcessor-0.0, READ: TLSv1 Change Cipher Spec, length = 1 SocketConnectorIoProcessor-0.0, READ: TLSv1 Handshake, length = 32 *** Finished verify_data: ... *** %% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5] QFJ Timer, WRITE: TLSv1 Application Data, length = 156 <20071001-17:34:21, FIX.4.4:SOURCE->TARGET, event> (Initiated logon request) <20071001-17:34:21, FIX.4.4:SOURCE->TARGET, event> (Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1) <20071001-17:34:21, FIX.4.4:SOURCE->TARGET, event> (Received logon response) ----------------Thanks, James Comments Comment by Steve Bate [ 13/Dec/07 ] I added the file system search. Thanks. Generated at Tue Feb 09 18:28:13 CET 2016 using JIRA 7.0.10#70120sha1:37e3d7a6fc4d580639533e7f7c232c925e554a6a.