Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTPS support with keystore #166

Closed
jianghaolu opened this issue Aug 14, 2014 · 2 comments
Closed

HTTPS support with keystore #166

jianghaolu opened this issue Aug 14, 2014 · 2 comments

Comments

@jianghaolu
Copy link

Hi Tom,

I have a customized client sending HTTPS requests to a web API. It reads a local JKS keystore and gets verified perfectly in real scenario tests.

I mocked the base URI to point to https://localhost:8089 and write a test like following:

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().httpsPort(8089));

    @Test
    public void listLocationSuccess() throws Exception {
        if (mocked) {
            setupListLocationSuccessMocked();
        }

        LocationsListResponse locationsListResponse = managementClient
                .getLocationsOperations().list(); // where my client sends an HTTPS request
        Assert.assertEquals(200, locationsListResponse.getStatusCode());
        Assert.assertNotNull(locationsListResponse.getRequestId());
        Assert.assertTrue(locationsListResponse.getLocations().size() > 0);

        if (mocked) {
            verifyListLocationSuccessMocked();
        }
    }

    private void setupListLocationSuccessMocked() throws Exception {
        stubFor(get(urlEqualTo("/" + subscriptionId + "/locations"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/xml")
                        .withHeader("x-ms-servedbyregion", "ussouth2")
                        .withHeader("x-ms-request-id",locationListRequestId)
                        .withBodyFile("ListOperationsResponse.xml")));
    }

    private void verifyListLocationSuccessMocked() throws Exception {
        verify(getRequestedFor(urlEqualTo("/" + subscriptionId + "/locations")));
    }

However, I get the following failure:

javax.net.ssl.SSLException: hostname in certificate didn't match: <localhost> != <tom akehurst>
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:231)
    at org.apache.http.conn.ssl.BrowserCompatHostnameVerifier.verify(BrowserCompatHostnameVerifier.java:54)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:152)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:133)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:291)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:262)
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:118)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:357)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:218)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:194)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:85)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
    at com.microsoft.windowsazure.management.LocationOperationsImpl.list(LocationOperationsImpl.java:145)
    at com.microsoft.windowsazure.management.LocationOperationsTest.listLocationSuccess(LocationOperationsTest.java:53)
    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:483)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:74)
    at org.junit.rules.RunRules.evaluate(RunRules.java:18)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

I assume my keystore is just not verified in wiremock. So I change the Rule declaration to be

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().httpsPort(8089).keystorePath(keyStorePath));

and then java.security.UnrecoverableKeyException is thrown. I don't find anywhere to bring keystore verification in wiremock.

Can you help me out here?
Thanks.

@tomakehurst
Copy link
Member

If you're passing the same keystore to keyStorePath() and your client, then what you're trying should work.

Is your keystore password protected? At the moment WireMock will only work with keystores whose password is "password" so you might want to try that.

Please could you re-post any further discussion on the mailing list? That way there might be some additional folks who can help.

Thanks,
Tom

@jianghaolu
Copy link
Author

Thanks for your reply.

I was able to pass in my keystore finally but the hostname not match problem still exists. Basically it's still <localhost>!=<my certificate CN>.

Thanks for mentioning this mailing list and I'm able to find this post https://groups.google.com/forum/#!searchin/wiremock-user/hostname/wiremock-user/5VKdf-ZJVYw/OopN5yNhKUwJ. I'll follow up over there.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants