/*
*
* Copyright 2013 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.netflix.niws.client.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URI;
import java.util.Random;
import org.apache.commons.configuration.AbstractConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.netflix.client.ClientFactory;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.client.testutil.SimpleSSLTestServer;
import com.netflix.config.ConfigurationManager;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.core.util.Base64;
import com.sun.jersey.core.util.MultivaluedMapImpl;
/**
*
* Test TLS configurations work against a very dumbed down test server.
*
* @author jzarfoss
*
*/
public class SecureGetTest {
// custom minted test keystores/truststores for Ribbon testing
// PLEASE DO NOT USE FOR ANYTHING OTHER THAN TESTING (the private keys are sitting right here in a String!!)
// but if you need keystore to test with, help yourself, they're good until 2113!
// we have a pair of independently valid keystore/truststore combinations
// thus allowing us to perform both positive and negative testing,
// the negative testing being that set 1 and set 2 cannot talk to each other
// base64 encoded
// Keystore type: JKS
// Keystore provider: SUN
//
// Your keystore contains 1 entry
//
// Alias name: ribbon_root
// Creation date: Sep 6, 2013
// Entry type: trustedCertEntry
//
// Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot1
// Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot1
// Serial number: 1
// Valid from: Fri Sep 06 10:25:22 PDT 2013 until: Sun Aug 13 10:25:22 PDT 2113
// Certificate fingerprints:
// MD5: BD:08:2A:F3:3B:26:C0:D4:44:B9:6D:EE:D2:45:31:C0
// SHA1: 64:95:7E:C6:0C:D7:81:56:28:0C:93:60:85:AB:9D:E2:60:33:70:43
// Signature algorithm name: SHA1withRSA
// Version: 3
//
// Extensions:
//
// #1: ObjectId: 2.5.29.19 Criticality=false
// BasicConstraints:[
// CA:true
// PathLen:2147483647
// ]
public static final String TEST_TS1 =
"/u3+7QAAAAIAAAABAAAAAgALcmliYm9uX3Jvb3QAAAFA9E6KkQAFWC41MDkAAAIyMIICLjCCAZeg" +
"AwIBAgIBATANBgkqhkiG9w0BAQUFADBTMRgwFgYDVQQDDA9SaWJib25UZXN0Um9vdDExCzAJBgNV" +
"BAsMAklUMRAwDgYDVQQKDAdOZXRmbGl4MQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwIBcNMTMw" +
"OTA2MTcyNTIyWhgPMjExMzA4MTMxNzI1MjJaMFMxGDAWBgNVBAMMD1JpYmJvblRlc3RSb290MTEL" +
"MAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCB" +
"nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAg8riOgT2Y39SQlZE+MWnOiKjREZzQ3ecvPf40oF8" +
"9YPNGpBhJzIKdA0TR1vQ70p3Fl2+Y5txs1H2/iguOdFMBrSdv1H8qJG1UufaeYO++HBm3Mi2L02F" +
"6fcTEEyXQMebKCWf04mxvLy5M6B5yMqZ9rHEZD+qsF4rXspx70bd0tUCAwEAAaMQMA4wDAYDVR0T" +
"BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBzTEn9AZniODYSRa+N7IvZu127rh+Sc6XWth68TBRj" +
"hThDFARnGxxe2d3EFXB4xH7qcvLl3HQ3U6lIycyLabdm06D3/jzu68mkMToE5sHJmrYNHHTVl0aj" +
"0gKFBQjLRJRlgJ3myUbbfrM+/a5g6S90TsVGTxXwFn5bDvdErsn8F8Hd41plMkW5ywsn6yFZMaFr" +
"MxnX";
// Keystore type: JKS
// Keystore provider: SUN
//
// Your keystore contains 1 entry
//
// Alias name: ribbon_root
// Creation date: Sep 6, 2013
// Entry type: trustedCertEntry
//
// Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot2
// Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot2
// Serial number: 1
// Valid from: Fri Sep 06 10:26:22 PDT 2013 until: Sun Aug 13 10:26:22 PDT 2113
// Certificate fingerprints:
// MD5: 44:64:E3:25:4F:D2:2C:8D:4D:B0:53:19:59:BD:B3:20
// SHA1: 26:2F:41:6D:03:C7:D0:8E:4F:AF:0E:4F:29:E3:08:53:B7:3C:DB:EE
// Signature algorithm name: SHA1withRSA
// Version: 3
//
// Extensions:
//
// #1: ObjectId: 2.5.29.19 Criticality=false
// BasicConstraints:[
// CA:true
// PathLen:2147483647
// ]
public static final String TEST_TS2 =
"/u3+7QAAAAIAAAABAAAAAgALcmliYm9uX3Jvb3QAAAFA9E92vgAFWC41MDkAAAIyMIICLjCCAZeg" +
"AwIBAgIBATANBgkqhkiG9w0BAQUFADBTMRgwFgYDVQQDDA9SaWJib25UZXN0Um9vdDIxCzAJBgNV" +
"BAsMAklUMRAwDgYDVQQKDAdOZXRmbGl4MQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwIBcNMTMw" +
"OTA2MTcyNjIyWhgPMjExMzA4MTMxNzI2MjJaMFMxGDAWBgNVBAMMD1JpYmJvblRlc3RSb290MjEL" +
"MAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCB" +
"nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAnEwAfuHYKRJviVB3RyV3+/mp4qjWZZd/q+fE2Z0k" +
"o2N2rrC8fAw53KXwGOE5fED6wXd3B2zyoSFHVsWOeL+TUoohn+eHSfwH7xK+0oWC8IvUoXWehOft" +
"grYtv9Jt5qNY5SmspBmyxFiaiAWQJYuf12Ycu4Gqg+P7mieMHgu6Do0CAwEAAaMQMA4wDAYDVR0T" +
"BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBNA0ask9eTYYhYA3bbmQZInxkBV74Gq/xorLlVygjn" +
"OgyGYp4/L274qwlPMqnQRmVbezkug2YlUK8xbrjwCUvHq2XW38e2RjK5q3EXVkGJxgCBuHug/eIf" +
"wD+/IEIE8aVkTW2j1QrrdkXDhRO5OsjvIVdy5/V4U0hVDnSo865ud9VQ/hZmOQuZItHViSoGSe2j" +
"bbZk";
// Keystore type: JKS
// Keystore provider: SUN
//
// Your keystore contains 1 entry
//
// Alias name: ribbon_key
// Creation date: Sep 6, 2013
// Entry type: PrivateKeyEntry
// Certificate chain length: 1
// Certificate[1]:
// Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestEndEntity1
// Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot1
// Serial number: 64
// Valid from: Fri Sep 06 10:25:22 PDT 2013 until: Sun Aug 13 10:25:22 PDT 2113
// Certificate fingerprints:
// MD5: 79:C5:F3:B2:B8:4C:F2:3F:2E:C7:67:FC:E7:04:BF:90
// SHA1: B1:D0:4E:A6:D8:84:BF:8B:01:46:B6:EA:97:5B:A0:4E:13:8B:A9:DE
// Signature algorithm name: SHA1withRSA
// Version: 3
public static final String TEST_KS1 =
"/u3+7QAAAAIAAAABAAAAAQAKcmliYm9uX2tleQAAAUD0Toq4AAACuzCCArcwDgYKKwYBBAEqAhEB" +
"AQUABIICo9fLN8zeXLcyx50+6B6gdXiUslZKY0SgLwL8kKNlQFiccD3Oc1yWjMnVC2QOdLsFzcVk" +
"ROhgMH/nHfFeXFlvY5IYMXqhbEC37LjE52RtX5KHv4FLYxxZCHduAwO8UTPa603XzrJ0VTMJ6Hso" +
"9+Ql76cGxPtIPcYm8IfqIY22as3NlKO4eMbiur9GLvuC57eql8vROaxGy8y657gc6kZMUyQOC+HG" +
"a5M3DTFpjl4V6HHbXHhMNEk9eXHnrZwYVOJmOgdgIrNNHOyD4kE+k21C7rUHhLAwK84wKL/tW4k9" +
"xnhOJK/L1RmycRIFWwXVi3u/3vi49bzdZsRLn73MdQkTe5p8oNZzG9sxg76u67ua6+99TMZYE1ay" +
"5JCYgbr85KbRsoX9Hd5XBcSNzROKJl0To2tAF8eTTMRlhEy7JZyTF2M9877juNaregVwE3Tp+a/J" +
"ACeNMyrxOQItNDam7a5dgBohpM8oJdEFqqj/S9BU7H5sR0XYo8TyIe1BV9zR5ZC/23fj5l5zkrri" +
"TCMgMbvt95JUGOT0gSzxBMmhV+ZLxpmVz3M5P2pXX0DXGTKfuHSiBWrh1GAQL4BOVpuKtyXlH1/9" +
"55/xY25W0fpLzMiQJV7jf6W69LU0FAFWFH9uuwf/sFph0S1QQXcQSfpYmWPMi1gx/IgIbvT1xSuI" +
"6vajgFqv6ctiVbFAJ6zmcnGd6e33+Ao9pmjs5JPZP3rtAYd6+PxtlwUbGLZuqIVK4o68LEISDfvm" +
"nGlk4/1+S5CILKVqTC6Ja8ojwUjjsNSJbZwHue3pOkmJQUNtuK6kDOYXgiMRLURbrYLyen0azWw8" +
"C5/nPs5J4pN+irD/hhD6cupCnUJmzMw30u8+LOCN6GaM5fdCTQ2uQKF7quYuD+gR3lLNOqq7KAAA" +
"AAEABVguNTA5AAACJTCCAiEwggGKoAMCAQICAWQwDQYJKoZIhvcNAQEFBQAwUzEYMBYGA1UEAwwP" +
"UmliYm9uVGVzdFJvb3QxMQswCQYDVQQLDAJJVDEQMA4GA1UECgwHTmV0ZmxpeDELMAkGA1UECAwC" +
"Q0ExCzAJBgNVBAYTAlVTMCAXDTEzMDkwNjE3MjUyMloYDzIxMTMwODEzMTcyNTIyWjBYMR0wGwYD" +
"VQQDDBRSaWJib25UZXN0RW5kRW50aXR5MTELMAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgx" +
"CzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAydqk" +
"AJuUcSF8dpUbNJWl+G1usgHtEFEbOMm54N/ZqGC7iSYs6EXfeoEyiHrMw/hdCKACERq2vuiuqan8" +
"h6z65/DXIiHUyykGb/Z4NK1I0aCQLZG4Ek3sERilILWyy2NRpjUrvqDPr/mQgymXqpuYhSD81jHx" +
"F84AOpTrnGsY7/sCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAjvtRKNhb1R6XIuWaOxJ0XDLine464" +
"Ie7LDfkE/KB43oE4MswjRh7nR9q6C73oa6TlIXmW6ysyKPp0vAyWHlq/zZhL3gNQ6faHuYHqas5s" +
"nJQgvQpHAQh4VXRyZt1K8ZdsHg3Qbd4APTL0aRVQkxDt+Dxd6AsoRMKmO/c5CRwUFIV/CK7k5VSh" +
"Sl5PRtH3PVj2vp84";
// Keystore type: JKS
// Keystore provider: SUN
//
// Your keystore contains 1 entry
//
// Alias name: ribbon_key
// Creation date: Sep 6, 2013
// Entry type: PrivateKeyEntry
// Certificate chain length: 1
// Certificate[1]:
// Owner: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestEndEntity2
// Issuer: C=US, ST=CA, O=Netflix, OU=IT, CN=RibbonTestRoot2
// Serial number: 64
// Valid from: Fri Sep 06 10:26:22 PDT 2013 until: Sun Aug 13 10:26:22 PDT 2113
// Certificate fingerprints:
// MD5: C3:AF:6A:DB:18:ED:70:22:83:73:9A:A5:DB:58:6D:04
// SHA1: B7:D4:F0:87:A8:4E:49:0A:91:B1:7B:62:28:CA:A2:4A:0E:AE:40:CC
// Signature algorithm name: SHA1withRSA
// Version: 3
//
//
//
public static final String TEST_KS2 =
"/u3+7QAAAAIAAAABAAAAAQAKcmliYm9uX2tleQAAAUD0T3bNAAACuzCCArcwDgYKKwYBBAEqAhEB" +
"AQUABIICoysDP4inwmxxKZkS8EYMW3DCJCD1AmpwFHxJIzo2v9fMysg+vjKxsrvVyKG23ZcHcznI" +
"ftmrEpriCCUZp+NNAf0EJWVAIzGenwrsd0+rI5I96gBOh9slJUzgucn7164R3XKNKk+VWcwGJRh+" +
"IuHxVrwFN025pfhlBJXNGJg4ZlzB7ZwcQPYblBzhLbhS3vJ1Vc46pEYWpnjxmHaDSetaQIcueAp8" +
"HnTUkFMXJ6t51N0u9QMPhBH7p7N8tNjaa5noSdxhSl/2Znj6r04NwQU1qX2n4rSWEnYaW1qOVkgx" +
"YrQzxI2kSHZfQDM2T918UikboQvAS1aX4h5P3gVCDKLr3EOO6UYO0ZgLHUr/DZrhVKd1KAhnzaJ8" +
"BABxot2ES7Zu5EzY9goiaYDA2/bkURmt0zDdKpeORb7r59XBZUm/8D80naaNnE45W/gBA9bCiDu3" +
"R99xie447c7ZX9Jio25yil3ncv+npBO1ozc5QIgQnbEfxbbwii3//shvPT6oxYPrcwWBXnaJNC5w" +
"2HDpCTXJZNucyjnNVVxC7p1ANNnvvZhgC0+GpEqmf/BW+fb9Qu+AXe0/h4Vnoe/Zs92vPDehpaKy" +
"oe+jBlUNiW2bpR88DSqxVcIu1DemlgzPa1Unzod0FdrOr/272bJnB2zAo4OBaBSv3KNf/rsMKjsU" +
"X2Po77+S+PKoQkqd8KJFpmLEb0vxig9JsrTDJXLf4ebeSA1W7+mBotimMrp646PA3NciMSbS4csh" +
"A7o/dBYhHlEosVgThm1JknIKhemf+FZsOzR3bJDT1oXJ/GhYpfzlCLyVFBeVP0KRnhih4xO0MEO7" +
"Q21DBaTTqAvUo7Iv3/F3mGMOanLcLgoRoq3moQ7FhfCDRtRAPA1qT2+pxPG5wqlGeYc6McOvogAA" +
"AAEABVguNTA5AAACJTCCAiEwggGKoAMCAQICAWQwDQYJKoZIhvcNAQEFBQAwUzEYMBYGA1UEAwwP" +
"UmliYm9uVGVzdFJvb3QyMQswCQYDVQQLDAJJVDEQMA4GA1UECgwHTmV0ZmxpeDELMAkGA1UECAwC" +
"Q0ExCzAJBgNVBAYTAlVTMCAXDTEzMDkwNjE3MjYyMloYDzIxMTMwODEzMTcyNjIyWjBYMR0wGwYD" +
"VQQDDBRSaWJib25UZXN0RW5kRW50aXR5MjELMAkGA1UECwwCSVQxEDAOBgNVBAoMB05ldGZsaXgx" +
"CzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtOvK" +
"fBMC/oMo4xf4eYGN7hTNn+IywaSaVYndqECIfuznoIqRKSbeCKPSGs4CN1D+u3E2UoXcsDmTguHU" +
"fokDA7sLUu8wD5ndAXfCkP3gXlFtUpNz/jPaXDsMFntTn2BdLKccxRxNwtwC0zzwIdtx9pw/Ru0g" +
"NXIQnPi50aql5WcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCYWM2ZdBjG3jCvMw/RkebMLkEDRxVM" +
"XU63Ygo+iCZUk8V8d0/S48j8Nk/hhVGHljsHqE/dByEF77X6uHaDGtt3Xwe+AYPofoJukh89jKnT" +
"jEDtLF+y5AVfz6b2z3TnJcuigMr4ZtBFv18R00KLnVAznl/waXG8ix44IL5ss6nRZBJE4jr+ZMG9" +
"9I4P1YhySxo3Qd3g";
private static String SERVICE_URI1;
private static int PORT1;
private static String SERVICE_URI2;
private static int PORT2;
private static SimpleSSLTestServer testServer1;
private static SimpleSSLTestServer testServer2;
private static File FILE_TS1;
private static File FILE_KS1;
private static File FILE_TS2;
private static File FILE_KS2;
public static final String PASSWORD = "changeit";
@BeforeClass
public static void init() throws Exception {
// setup server 1, will use first keystore/truststore with client auth
PORT1 = new Random().nextInt(1000) + 4000;
SERVICE_URI1 = "https://127.0.0.1:" + PORT1 + "/";
// jks format
byte[] sampleTruststore1 = Base64.decode(TEST_TS1);
byte[] sampleKeystore1 = Base64.decode(TEST_KS1);
FILE_KS1 = File.createTempFile("SecureGetTest1", ".keystore");
FILE_TS1 = File.createTempFile("SecureGetTest1", ".truststore");
FileOutputStream keystoreFileOut = new FileOutputStream(FILE_KS1);
try {
keystoreFileOut.write(sampleKeystore1);
} finally {
keystoreFileOut.close();
}
FileOutputStream truststoreFileOut = new FileOutputStream(FILE_TS1);
try {
truststoreFileOut.write(sampleTruststore1);
} finally {
truststoreFileOut.close();
}
try{
testServer1 = new SimpleSSLTestServer(FILE_TS1, PASSWORD, FILE_KS1, PASSWORD, PORT1, true);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
// setup server 2, will use second keystore truststore without client auth
PORT2 = PORT1 + 1;
SERVICE_URI2 = "https://127.0.0.1:" + PORT2 + "/";
// jks format
byte[] sampleTruststore2 = Base64.decode(TEST_TS2);
byte[] sampleKeystore2 = Base64.decode(TEST_KS2);
FILE_KS2 = File.createTempFile("SecureGetTest2", ".keystore");
FILE_TS2 = File.createTempFile("SecureGetTest2", ".truststore");
keystoreFileOut = new FileOutputStream(FILE_KS2);
try {
keystoreFileOut.write(sampleKeystore2);
} finally {
keystoreFileOut.close();
}
truststoreFileOut = new FileOutputStream(FILE_TS2);
try {
truststoreFileOut.write(sampleTruststore2);
} finally {
truststoreFileOut.close();
}
try{
testServer2 = new SimpleSSLTestServer(FILE_TS2, PASSWORD, FILE_KS2, PASSWORD, PORT2, false);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@AfterClass
public static void shutDown(){
try{
testServer1.close();
}catch(Exception e){
e.printStackTrace();
}
try{
testServer2.close();
}catch(Exception e){
e.printStackTrace();
}
}
@Test
public void testSunnyDay() throws Exception {
AbstractConfiguration cm = ConfigurationManager.getConfigInstance();
String name = "GetPostSecureTest" + ".testSunnyDay";
String configPrefix = name + "." + "ribbon";
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(PORT1));
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "false");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsClientAuthRequired, "true");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStore, FILE_KS1.getAbsolutePath());
cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStorePassword, PASSWORD);
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS1.getAbsolutePath());
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);
RestClient rc = (RestClient) ClientFactory.getNamedClient(name);
testServer1.accept();
URI getUri = new URI(SERVICE_URI1 + "test/");
HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
HttpResponse response = rc.execute(request);
assertEquals(200, response.getStatus());
}
@Test
public void testSunnyDayNoClientAuth() throws Exception{
AbstractConfiguration cm = ConfigurationManager.getConfigInstance();
String name = "GetPostSecureTest" + ".testSunnyDayNoClientAuth";
String configPrefix = name + "." + "ribbon";
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(PORT2));
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "false");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS2.getAbsolutePath());
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);
RestClient rc = (RestClient) ClientFactory.getNamedClient(name);
testServer2.accept();
URI getUri = new URI(SERVICE_URI2 + "test/");
HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
HttpResponse response = rc.execute(request);
assertEquals(200, response.getStatus());
}
@Test
public void testFailsWithHostNameValidationOn() throws Exception {
AbstractConfiguration cm = ConfigurationManager.getConfigInstance();
String name = "GetPostSecureTest" + ".testFailsWithHostNameValidationOn";
String configPrefix = name + "." + "ribbon";
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(PORT1));
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "true"); // <--
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsClientAuthRequired, "true");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStore, FILE_KS1.getAbsolutePath());
cm.setProperty(configPrefix + "." + CommonClientConfigKey.KeyStorePassword, PASSWORD);
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS1.getAbsolutePath());
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);
RestClient rc = (RestClient) ClientFactory.getNamedClient(name);
testServer1.accept();
URI getUri = new URI(SERVICE_URI1 + "test/");
MultivaluedMapImpl params = new MultivaluedMapImpl();
params.add("name", "test");
HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
try{
rc.execute(request);
fail("expecting ssl hostname validation error");
}catch(ClientHandlerException che){
assertTrue(che.getMessage().indexOf("hostname in certificate didn't match") > -1);
}
}
@Test
public void testClientRejectsWrongServer() throws Exception{
AbstractConfiguration cm = ConfigurationManager.getConfigInstance();
String name = "GetPostSecureTest" + ".testClientRejectsWrongServer";
String configPrefix = name + "." + "ribbon";
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsSecure, "true");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.SecurePort, Integer.toString(PORT2));
cm.setProperty(configPrefix + "." + CommonClientConfigKey.IsHostnameValidationRequired, "false");
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStore, FILE_TS1.getAbsolutePath()); // <--
cm.setProperty(configPrefix + "." + CommonClientConfigKey.TrustStorePassword, PASSWORD);
RestClient rc = (RestClient) ClientFactory.getNamedClient(name);
testServer2.accept();
URI getUri = new URI(SERVICE_URI2 + "test/");
HttpRequest request = HttpRequest.newBuilder().uri(getUri).queryParams("name", "test").build();
try{
rc.execute(request);
fail("expecting ssl hostname validation error");
}catch(ClientHandlerException che){
assertTrue(che.getMessage().indexOf("peer not authenticated") > -1);
}
}
}