Skip to content

Commit fae6fab

Browse files
committed
Fix hostname verification using the deprecated SSL stack
1 parent eaa7a4c commit fae6fab

File tree

7 files changed

+285
-1
lines changed

7 files changed

+285
-1
lines changed

Diff for: rt/transports/http/src/main/java/org/apache/cxf/transport/https/AllowAllHostnameVerifier.java

+4
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,8 @@ public boolean verify(String host, SSLSession session) {
3939
return false;
4040
}
4141
}
42+
43+
public boolean verify(final String host, final String certHostname) {
44+
return certHostname != null && !certHostname.isEmpty();
45+
}
4246
}

Diff for: rt/transports/http/src/main/java/org/apache/cxf/transport/https/HttpsURLConnectionFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public Object invoke(Object proxy,
182182
try {
183183
return super.invoke(proxy, method, args);
184184
} catch (Exception ex) {
185-
return true;
185+
return false;
186186
}
187187
}
188188
};

Diff for: rt/transports/http/src/main/java/org/apache/cxf/transport/https/httpclient/DefaultHostnameVerifier.java

+12
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ public void verify(
130130
}
131131
}
132132

133+
public boolean verify(final String host, final String certHostname) {
134+
try {
135+
matchCN(host, certHostname, this.publicSuffixMatcher);
136+
return true;
137+
} catch (SSLException ex) {
138+
if (LOG.isLoggable(Level.FINE)) {
139+
LOG.log(Level.FINE, ex.getMessage(), ex);
140+
}
141+
return false;
142+
}
143+
}
144+
133145
static void matchIPAddress(final String host, final List<String> subjectAlts) throws SSLException {
134146
for (int i = 0; i < subjectAlts.size(); i++) {
135147
final String subjectAlt = subjectAlts.get(i);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.cxf.systest.https.hostname;
21+
22+
import java.net.URL;
23+
24+
import org.apache.cxf.Bus;
25+
import org.apache.cxf.BusFactory;
26+
import org.apache.cxf.bus.spring.SpringBusFactory;
27+
import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
28+
29+
public class HostnameVerificationDeprecatedServer extends AbstractBusTestServerBase {
30+
31+
public HostnameVerificationDeprecatedServer() {
32+
33+
}
34+
35+
protected void run() {
36+
URL busFile = HostnameVerificationDeprecatedServer.class.getResource("hostname-server-bethal.xml");
37+
Bus busLocal = new SpringBusFactory().createBus(busFile);
38+
BusFactory.setDefaultBus(busLocal);
39+
setBus(busLocal);
40+
41+
try {
42+
new HostnameVerificationDeprecatedServer();
43+
} catch (Exception e) {
44+
e.printStackTrace();
45+
}
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.cxf.systest.https.hostname;
21+
22+
import java.net.URL;
23+
24+
import javax.xml.ws.BindingProvider;
25+
26+
import org.apache.cxf.Bus;
27+
import org.apache.cxf.BusFactory;
28+
import org.apache.cxf.bus.spring.SpringBusFactory;
29+
import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
30+
import org.apache.hello_world.Greeter;
31+
import org.apache.hello_world.services.SOAPService;
32+
33+
import org.junit.AfterClass;
34+
import org.junit.BeforeClass;
35+
36+
/**
37+
* A test for hostname verification when the Java system property "java.protocol.handler.pkgs" is set to
38+
* "com.sun.net.ssl.internal.www.protocol". This means that com.sun.net.ssl.HostnameVerifier is used
39+
* instead of the javax version.
40+
*/
41+
public class HostnameVerificationDeprecatedTest extends AbstractBusClientServerTestBase {
42+
static final String PORT = allocatePort(HostnameVerificationDeprecatedServer.class);
43+
static final String PORT2 = allocatePort(HostnameVerificationDeprecatedServer.class, 2);
44+
45+
@BeforeClass
46+
public static void startServers() throws Exception {
47+
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
48+
assertTrue(
49+
"Server failed to launch",
50+
// run the server in the same process
51+
// set this to false to fork
52+
launchServer(HostnameVerificationDeprecatedServer.class, true)
53+
);
54+
}
55+
56+
@AfterClass
57+
public static void cleanup() throws Exception {
58+
System.clearProperty("java.protocol.handler.pkgs");
59+
stopAllServers();
60+
}
61+
62+
// Here we expect an exception, as the default hostname verifier contributed by CXF will object to the
63+
// fact that the server certificate does not have "CN=localhost".
64+
@org.junit.Test
65+
public void testLocalhostNotMatching() throws Exception {
66+
SpringBusFactory bf = new SpringBusFactory();
67+
URL busFile = HostnameVerificationDeprecatedTest.class.getResource("hostname-client-bethal.xml");
68+
69+
Bus bus = bf.createBus(busFile.toString());
70+
BusFactory.setDefaultBus(bus);
71+
BusFactory.setThreadDefaultBus(bus);
72+
73+
URL url = SOAPService.WSDL_LOCATION;
74+
SOAPService service = new SOAPService(url, SOAPService.SERVICE);
75+
assertNotNull("Service is null", service);
76+
final Greeter port = service.getHttpsPort();
77+
assertNotNull("Port is null", port);
78+
79+
updateAddressPort(port, PORT);
80+
81+
try {
82+
port.greetMe("Kitty");
83+
fail("Failure expected on the hostname verification");
84+
} catch (Exception ex) {
85+
// expected
86+
}
87+
88+
((java.io.Closeable)port).close();
89+
bus.shutdown(true);
90+
}
91+
92+
// No Subject Alternative Name, but the CN matches ("localhost"), so the default HostnameVerifier
93+
// should work fine
94+
@org.junit.Test
95+
public void testNoSubjectAlternativeNameCNMatch() throws Exception {
96+
SpringBusFactory bf = new SpringBusFactory();
97+
URL busFile = HostnameVerificationDeprecatedTest.class.getResource("hostname-client.xml");
98+
99+
Bus bus = bf.createBus(busFile.toString());
100+
BusFactory.setDefaultBus(bus);
101+
BusFactory.setThreadDefaultBus(bus);
102+
103+
URL url = SOAPService.WSDL_LOCATION;
104+
SOAPService service = new SOAPService(url, SOAPService.SERVICE);
105+
assertNotNull("Service is null", service);
106+
final Greeter port = service.getHttpsPort();
107+
assertNotNull("Port is null", port);
108+
109+
updateAddressPort(port, PORT2);
110+
111+
assertEquals(port.greetMe("Kitty"), "Hello Kitty");
112+
113+
// Enable Async
114+
((BindingProvider)port).getRequestContext().put("use.async.http.conduit", true);
115+
116+
assertEquals(port.greetMe("Kitty"), "Hello Kitty");
117+
118+
((java.io.Closeable)port).close();
119+
bus.shutdown(true);
120+
}
121+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
-->
20+
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core" xmlns:p="http://cxf.apache.org/policy" xmlns:sec="http://cxf.apache.org/configuration/security" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd">
21+
22+
<cxf:bus>
23+
<cxf:features>
24+
<cxf:logging/>
25+
</cxf:features>
26+
</cxf:bus>
27+
<http:conduit name="https://localhost:.*">
28+
<http:tlsClientParameters>
29+
<sec:trustManagers>
30+
<sec:keyStore type="jks" password="password" resource="keys/Bethal.jks"/>
31+
</sec:trustManagers>
32+
</http:tlsClientParameters>
33+
</http:conduit>
34+
</beans>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one
4+
or more contributor license agreements. See the NOTICE file
5+
distributed with this work for additional information
6+
regarding copyright ownership. The ASF licenses this file
7+
to you under the Apache License, Version 2.0 (the
8+
"License"); you may not use this file except in compliance
9+
with the License. You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing,
14+
software distributed under the License is distributed on an
15+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
-->
20+
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:cxf="http://cxf.apache.org/core" xmlns:p="http://cxf.apache.org/policy" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd ">
21+
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
22+
<cxf:bus>
23+
<cxf:features>
24+
<cxf:logging/>
25+
</cxf:features>
26+
</cxf:bus>
27+
28+
<httpj:engine-factory id="non-localhost-match-settings">
29+
<httpj:engine port="${testutil.ports.HostnameVerificationDeprecatedServer}">
30+
<httpj:tlsServerParameters>
31+
<sec:keyManagers keyPassword="password">
32+
<sec:keyStore type="jks" password="password" resource="keys/Bethal.jks"/>
33+
</sec:keyManagers>
34+
<sec:clientAuthentication want="false" required="false"/>
35+
</httpj:tlsServerParameters>
36+
</httpj:engine>
37+
</httpj:engine-factory>
38+
39+
<jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
40+
xmlns:s="http://apache.org/hello_world/services"
41+
id="NonLocalhostMatch"
42+
implementor="org.apache.cxf.systest.http.GreeterImpl"
43+
address="https://localhost:${testutil.ports.HostnameVerificationDeprecatedServer}/SoapContext/HttpsPort"
44+
serviceName="s:SOAPService"
45+
endpointName="e:HttpsPort" depends-on="non-localhost-match-settings"/>
46+
47+
<httpj:engine-factory id="no-subject-alt-cn-match-settings">
48+
<httpj:engine port="${testutil.ports.HostnameVerificationDeprecatedServer.2}">
49+
<httpj:tlsServerParameters>
50+
<sec:keyManagers keyPassword="security">
51+
<sec:keyStore type="jks" password="security" resource="keys/subjalt.jks"/>
52+
</sec:keyManagers>
53+
<sec:clientAuthentication want="false" required="false"/>
54+
<sec:certAlias>nosubjaltcnmatch</sec:certAlias>
55+
</httpj:tlsServerParameters>
56+
</httpj:engine>
57+
</httpj:engine-factory>
58+
59+
<jaxws:endpoint xmlns:e="http://apache.org/hello_world/services"
60+
xmlns:s="http://apache.org/hello_world/services"
61+
id="NoSubjectAltCNMatch"
62+
implementor="org.apache.cxf.systest.http.GreeterImpl"
63+
address="https://localhost:${testutil.ports.HostnameVerificationDeprecatedServer.2}/SoapContext/HttpsPort"
64+
serviceName="s:SOAPService"
65+
endpointName="e:HttpsPort" depends-on="no-subject-alt-cn-match-settings"/>
66+
</beans>

0 commit comments

Comments
 (0)