users@jersey.java.net

[Jersey] Re: ApacheConnectorProvider and SSL

From: John MacAuley <john_at_blackacorn.ca>
Date: Tue, 3 Feb 2015 12:39:55 -0500

Just to verify I just used the httpclient directly with the same -Djavax.net.ssl.*Store* parameters and it worked properly. I guess that means worst case I can replace jersey with use of the httpclient. Would rather not, but if I must…

That reminds me of another issue I ran into last week. Will send a new email for it :-)

John

On 2015-02-03, at 11:18 AM, John MacAuley <john_at_blackacorn.ca> wrote:

> Michal,
>
> Same result. The key and trust stores are loading but getting the same issue after ServerHelloDone. Only difference I can see is TLS1.2 versus TLS1. Here is my updated initialization segment. I include the complete configuration so you can tell me what I am doing wrong.
>
> ClientConfig clientConfig = new ClientConfig();
> clientConfig.connectorProvider(new ApacheConnectorProvider());
>
> PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
> connectionManager.setDefaultMaxPerRoute(10);
> connectionManager.setMaxTotal(80);
> clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
>
> clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED);
> clientConfig.register(new MoxyXmlFeature());
> clientConfig.register(new LoggingFilter(java.util.logging.Logger.getGlobal(), true));
>
> RequestConfig.Builder custom = RequestConfig.custom();
> custom.setExpectContinueEnabled(true);
> custom.setRelativeRedirectsAllowed(true);
> custom.setRedirectsEnabled(true);
> clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, custom.build());
>
> SslConfigurator sslConfig = SslConfigurator.newInstance()
> .trustStoreFile("/path/to/truststore.jks")
> .trustStorePassword("changeit")
> .trustStoreType("JKS")
> .trustManagerFactoryAlgorithm("PKIX")
>
> .keyStoreFile("/path/to/keystore.jks")
> .keyPassword("changeit")
> .keyStoreType("JKS")
> .keyManagerFactoryAlgorithm("SunX509")
> .keyStoreProvider("SUN")
>
> .securityProtocol("SSL");
>
> clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslConfig);
> Client client = ClientBuilder.newClient(clientConfig);
>
>
> Thanks,
> John
>
> On 2015-02-03, at 10:53 AM, Michal Gajdos <michal.gajdos_at_oracle.com> wrote:
>
>> Thanks for the last code segment - pass the SslConfigurator instance not the SSLContext otherwise it should not work.
>>
>> Michal
>>
>>> On 3 Feb, 2015, at 16:49 , John MacAuley <john_at_blackacorn.ca> wrote:
>>>
>>> Michal,
>>>
>>> I should have expanded the last code segment. Here is what it looked like:
>>>
>>> SslConfigurator sslConfig = SslConfigurator.newInstance()
>>> .trustStoreFile(trustStore)
>>> .trustStorePassword(trustStorePassword)
>>> .trustStoreType("JKS")
>>> .trustManagerFactoryAlgorithm("PKIX")
>>>
>>> .keyStoreFile(keyStore)
>>> .keyPassword(keyStorePassword)
>>> .keyStoreType("JKS")
>>> .keyManagerFactoryAlgorithm("SunX509")
>>> .keyStoreProvider("SUN")
>>>
>>> .securityProtocol("SSL");
>>>
>>> clientConfig.property(ApacheClientProperties.SSL_CONFIG, sslConfig.createSSLContext());
>>>
>>> I think I did what you are proposing but will retry just to make sure.
>>>
>>> Thanks,
>>> John
>>>
>>> On 2015-02-03, at 10:43 AM, Michal Gajdos <michal.gajdos_at_oracle.com> wrote:
>>>
>>>> Hi John,
>>>>
>>>> there is a bug in our Apache HttpClient connector. It doesn’t take SSLContext from the client but it expects a certain property to be set. Specifically it’s ApacheClientProperties.SSL_CONFIG (see [1]). Until this bug gets fixed, you need to use:
>>>>
>>>> SslConfigurator sslConfig = …;
>>>> ClientBuilder.newBuilder().property(ApacheClientProperties.SSL_CONFIG, sslConfig).build();
>>>>
>>>> [1] https://jersey.java.net/apidocs/latest/jersey/org/glassfish/jersey/apache/connector/ApacheClientProperties.html#SSL_CONFIG
>>>>
>>>> Michal
>>>>
>>>>> On 3 Feb, 2015, at 16:13 , John MacAuley <john_at_blackacorn.ca> wrote:
>>>>>
>>>>> Peoples,
>>>>>
>>>>> I have been using Jersey with the default HttpUrlConnectorProvider but decided to switch to the ApacheConnectorProvider for chunked POST support and 100-Continue for better SSL re-negotiation support on the POST. With the HttpUrlConnectorProvider I was able to fully configure SSL for my needs using the standard javax.net.ssl.*Store properties. I configured my own key and trust stores. I have configured SSL on httpd for client authentication (SSLVerifyClient).
>>>>>
>>>>> On startup with the HttpUrlConnectorProvider and SSL debug enabled I see the keyStore and trustStore initialization occur with my private key and a list of trusted certificates. When the POST goes out I see the initial SSL session being set up, and when httpd determines the POST is to a "SSLVerifyClient" protected URL it initiates a re-negotition. I then see the re-negotition start, the CertificateRequest with the list of certificate authorities followed up with ServerHelloDone. I then see the my matching private key being selected (matching alias), the Certificate chain for my key being dumped, then a run to completion on SSL setup (TLSv1).
>>>>>
>>>>> When I switched to the ApacheConnectorProvider I see my truststore getting loaded but not the keystore. The client authentication fails since it cannot find a matching private key.
>>>>>
>>>>> *** ServerHelloDone
>>>>> [read] MD5 and SHA1 hashes: len = 4
>>>>> 0000: 0E 00 00 00 ....
>>>>> *** Certificate chain
>>>>> ***
>>>>> *** ECDHClientKeyExchange
>>>>>
>>>>> I then used the following to initialize the default SSL context for the client:
>>>>>
>>>>> SSLContext sslContext = SSLContexts.createSystemDefault();
>>>>> client = ClientBuilder.newBuilder().sslContext(sslContext).withConfig(clientConfig).build();
>>>>>
>>>>> I see the truststore and keystore being loaded such as below, but get the same result.
>>>>>
>>>>> SslConfigurator sslConfig = SslConfigurator.newInstance()
>>>>> .trustStoreFile(trustStore)
>>>>> .trustStorePassword(trustStorePassword)
>>>>> .trustStoreType("JKS")
>>>>> .trustManagerFactoryAlgorithm("PKIX")
>>>>>
>>>>> .keyStoreFile(keyStore)
>>>>> .keyPassword(keyStorePassword)
>>>>> .keyStoreType("JKS")
>>>>> .keyManagerFactoryAlgorithm("SunX509")
>>>>> .keyStoreProvider("SUN")
>>>>>
>>>>> .securityProtocol("SSL");
>>>>>
>>>>> I tried other ways to initialize the truststore and keystore with the same results.
>>>>>
>>>>> Anyone have a clue why this is not working?
>>>>>
>>>>> Thanks!
>>>>> John
>>>>
>>>
>>
>