0

I followed the same steps when I tried to use Mockoon Self-Signed SSL, and all worked fine. I exported the Mockoon SSL using Chrome Browser and added it to jssecacerts using keytool and it worked fine. Also, I used the tool 'InstallCert.java' from GitHub and followed the steps to create a new trust store file, it also worked fine.

I managed to start a WireMock server with SSL as per the steps here:

https://wiremock.org/docs/https/

I used this code below in a JUnit 4 test class to configure the server and test invoking REST services with SSL from my local:

wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().httpsPort(8443).port(8089));

wireMockServer.start();

Then, I run the test above and put a break-point before stopping the server, to test the setup using Chrome Browser and Postman.

I confirmed that "HTTPS" is working fine from Chrome Browser. I tried to export the certificate from Chrome Browser and added it to jssecacerts or an existing trust store file I have, I got an error when I invoke the service with SSL from my local. I set up the mock service using a JSON mapping file under the mappings folder, and I enable SSL in Java, I get the following error when executing this line of code:

((HttpURLConnection)urlConnection).connect();

The error is:

javax.net.ssl.SSLHandshakeException: No name matching localhost found

I did some digging, and I think the WireMock Self-Signed certificate is not marked with the correct CN name. I think the CN should be "localhost". See the command line output of the steps I followed using the tool 'InstallCert.java' and you can see the CN=Tom Akehurst:

C:\Projects\SAT\install certificate>C:\apps\jdk1.8.0_351\bin\java InstallCert localhost:8443
Loading KeyStore jssecacerts...
Opening connection to localhost:8443 ...
Starting SSL handshake...

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:370)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:313)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
        at sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1355)
        at sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1230)
        at sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1173)
        at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:376)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:479)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:457)
        at sun.security.ssl.TransportContext.dispatch(TransportContext.java:200)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:155)
        at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1320)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1233)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:417)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:389)
        at InstallCert.main(InstallCert.java:150)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
        at sun.security.validator.Validator.validate(Validator.java:271)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:232)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:109)
        at InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:248)
        at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:1257)
        at sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1339)
        ... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
        ... 20 more

Server sent 1 certificate(s):

 1 Subject CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
   Issuer  CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
   sha1    6f b3 cc 4f 53 f3 89 4c 70 6f cc 1d 43 f4 ea b3 55 f0 ad 95
   md5     a8 cb 72 1e 19 e2 3d a1 d1 80 9c e8 08 48 04 b3

Enter certificate to add to trusted keystore or 'q' to quit: [1]
1

[
[
  Version: V3
  Subject: CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 2048 bits
  params: null
  modulus: 16162811599997437670024325232093400418478212143396095301325549189805590306783227883083284364453457615893858264294238688239430771669295437290996184629436638130978501233955452329850079285658793303035959256253528976045906886986406333317493030534226253285257726086357068697209146911044976286072066873509393816195164204783023078735828350752718589222442240996413022972362184792369971488626885171029793821887871975122481690953784562330474007286147206795416645490450507513174892201829940700367426767157759073817765308911582508302203841860388208167091799369665611086691071592657494061212129654521104283864301320982025481461669
  public exponent: 65537
  Validity: [From: Tue Feb 24 08:58:50 EST 2015,
               To: Thu Jan 31 08:58:50 EST 2115]
  Issuer: CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
  SerialNumber: [    1d892e4f]

Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 36 7A B2 85 D1 C4 3F CD   DA 7E 5B FB E0 95 AD 66  6z....?...[....f
0010: EB 5C B2 96                                        .\..
]
]

]
  Algorithm: [SHA256withRSA]
  Signature:
0000: 62 3D F0 94 83 B1 07 CF   CA 68 46 06 4B EB 43 F3  b=.......hF.K.C.
0010: 31 DC 9A 28 BC 1A 7C 6B   45 76 C8 66 63 5C BD BF  1..(...kEv.fc\..
0020: 3A 4F 24 8A 05 70 81 FB   72 B4 AC 99 47 11 93 E5  :O$..p..r...G...
0030: D2 8F 95 A1 4A BE 11 4F   7C B5 E4 9B 1F 67 2F 77  ....J..O.....g/w
0040: E7 4E 7B 7F 49 27 11 71   1F A2 BF 86 8B C0 65 0D  .N..I'.q......e.
0050: A0 B7 DE A5 FE EA DC 22   01 AB 9B D6 29 C4 0D CD  ......."....)...
0060: 36 F1 91 6D 13 06 F3 25   06 20 26 8D 46 BC B1 B6  6..m...%. &.F...
0070: A3 60 4C 64 1D 42 E4 5F   A4 36 6F 63 6B 0B B8 AD  .`Ld.B._.6ock...
0080: 33 6D 5E 4B 57 96 83 61   A3 1A D2 5A DC 84 52 80  3m^KW..a...Z..R.
0090: C0 BC 68 01 56 70 09 C1   05 DC 7D AC 96 AB 70 2C  ..h.Vp........p,
00A0: 0A BF 64 A4 72 37 6C 1C   0B 27 D3 40 18 2E 0C F2  ..d.r7l..'.@....
00B0: 3E F3 F4 0C 3B D4 91 A6   C0 10 E4 D6 8A 00 3B A2  >...;.........;.
00C0: FC D9 6E C3 58 16 0F CE   92 D7 5D E5 E6 1D 10 B1  ..n.X.....].....
00D0: A6 E8 CA 59 AB DE 01 5D   93 72 0B 10 68 29 B3 CB  ...Y...].r..h)..
00E0: 6F 62 F8 5D 37 A4 B9 7B   56 2A 38 12 2F B3 F5 74  ob.]7...V*8./..t
00F0: 20 66 23 78 03 08 B0 CF   D0 FE 96 C8 67 2A E2 08   f#x........g*..

]

Added certificate to keystore 'jssecacerts' using alias 'localhost-1'

C:\Projects\SAT\install certificate>C:\apps\jdk1.8.0_351\bin\java InstallCert localhost:8443
Loading KeyStore jssecacerts...
Opening connection to localhost:8443 ...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 1 certificate(s):

 1 Subject CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
   Issuer  CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
   sha1    6f b3 cc 4f 53 f3 89 4c 70 6f cc 1d 43 f4 ea b3 55 f0 ad 95
   md5     a8 cb 72 1e 19 e2 3d a1 d1 80 9c e8 08 48 04 b3

Enter certificate to add to trusted keystore or 'q' to quit: [1]
q
KeyStore not changed

C:\Projects\SAT\install certificate>keytool -exportcert -alias localhost-1 -keystore jssecacerts -storepass changeit -file mywiremock.cer
Certificate stored in file <mywiremock.cer>

C:\Projects\SAT\install certificate>keytool -importcert -file mywiremock.cer -keystore wiremockstore.jks -alias localhost-1 -storepass changeit
Owner: CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Issuer: CN=Tom Akehurst, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Serial number: 1d892e4f
Valid from: Tue Feb 24 08:58:50 EST 2015 until: Thu Jan 31 08:58:50 EST 2115
Certificate fingerprints:
         SHA1: 6F:B3:CC:4F:53:F3:89:4C:70:6F:CC:1D:43:F4:EA:B3:55:F0:AD:95
         SHA256: 66:02:81:F6:DD:F9:C1:DE:66:21:10:8B:69:A9:85:42:9A:5B:CE:17:9A:4A:6C:F4:89:59:A1:BD:A6:E1:9C:31
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 36 7A B2 85 D1 C4 3F CD   DA 7E 5B FB E0 95 AD 66  6z....?...[....f
0010: EB 5C B2 96                                        .\..
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

I appreciate your help to fix this issue. I want to be able to mock the service on my local and use SSL. It is not working with WireMock. How I can solve this error:

javax.net.ssl.SSLHandshakeException: No name matching localhost found
tarekahf
  • 738
  • 1
  • 16
  • 42

2 Answers2

1

I think your issue is related to the content of the certificate (Subject Alternative Name field), similar as the following answer which I also provided here: Certificate for doesn't match any of the subject alternative names

Can you retry with a newly created certificate with the additional extension containing the SAN field value of localhost? So something similar to:

keytool -genkeypair -keyalg RSA -keysize 2048 -alias stackoverflow \
-dname "CN=stackoverflow,OU=Hakan,O=Hakan,C=NL" \
-ext "SAN:c=DNS:localhost,IP:127.0.0.1" -validity 3650 \
-storepass mypassword -keypass mypassword \
-keystore identity.jks -deststoretype pkcs12

And use that new keystore in your wiremock configuration like the snippet below:

@Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig()
    .httpsPort(8443)
    .keystorePath("/path/to/identity.jks") // Either a path to a file or a resource on the classpath
    .keystorePassword("mypassword") // The password used to access the keystore. Defaults to "password" if omitted
    .keyManagerPassword("mypassword")); // The password used to access individual keys in the keystore. Defaults to "password" if omitted

Export the server certificate from wiremock and add it to your https url connection:

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, "secret".toCharArray());

CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
try (InputStream inputStream = Files.newInputStream(Paths.get("/path/to/trusted-server-certificate.crt"));) {
    Certificate certificate = certificateFactory.generateCertificate(inputStream);
    trustStore.setCertificateEntry("wiremock-server-certificate", certificate);
}

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

HttpsURLConnection connection = (HttpsURLConnection) new URL("https://localhost:8443").openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());

Can you give this a try and share your results?

Hakan54
  • 3,121
  • 1
  • 23
  • 37
  • Thanks a lot. I will try that tomorrow. Just checking, wouldn't be a lot more easier to change CN in the default self-signed certificate generated by Wiremock? How I can change the CN value from `Tom Akehurst` to `localhost`? – tarekahf Jul 13 '23 at 04:49
  • I don't think you need the java InstallCert script. I have updated my initial answer with the other configuration for wiremock and httpsurlconnection. I think that should do the trick. Can you retry with the new code snippets? – Hakan54 Jul 13 '23 at 06:49
  • I found the answer which is very simple and serves the purpose. Thank you for your help. I might use your approach when I get stuck in the future. – tarekahf Jul 13 '23 at 18:38
0

I found the answer here:

CertificateException: No name matching ssl.someUrl.de found

and here:

https://mkyong.com/webservices/jax-ws/java-security-cert-certificateexception-no-name-matching-localhost-found/

I just added the code block below to the test class:

    static {
        //for localhost testing only
        javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(newJavaKeyword javax.net.ssl.HostnameVerifier() {
            public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
                if (hostname.equals("localhost")) {
                    return true;
                }
                return false;
            }
        });
    }

Note: replace the keyword above newJavaKeyword with new as it won't let me post it using new for some reason.

And it worked right away. This is just fine as during testing, all I want is to make sure my SSL code is working fine.

To summarize, I executed the unit test, and put a breakpoint after the WireMock server was started using the following code:

    private final static int WIREMOCK_PORT = 8089;
    private final static int WIREMOCK_PORT_SSL = 8443;
    private final static String BASE_URL = "http://localhost:" + WIREMOCK_PORT + "/";
    private final static String BASE_URL_SSL = "https://localhost:" + WIREMOCK_PORT_SSL + "/";

    @BeforeClass
    public static void setup() {
        System.out.println("This is the Setup Method");
        wireMockServer = new WireMockServer(options().port(WIREMOCK_PORT).httpsPort(WIREMOCK_PORT_SSL).notifier(new ConsoleNotifier(false)));
        wireMockServer.start();
    }
    

Then, I used the Java tool InstallCert.java to extract the WireMock trust store file and I used it to create the SSLContext object in Java. You can check the details of creating the trust store file in the question body above.

tarekahf
  • 738
  • 1
  • 16
  • 42