HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-rest / src / test / java / org / apache / hadoop / hbase / rest / TestRESTServerSSL.java
blob4201c3210fe596646b94521d9918aae5438bd5eb
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
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.rest;
20 import static org.junit.Assert.assertEquals;
21 import java.io.File;
22 import java.lang.reflect.Method;
23 import java.security.KeyPair;
24 import java.security.cert.X509Certificate;
25 import java.util.Optional;
26 import org.apache.hadoop.conf.Configuration;
27 import org.apache.hadoop.hbase.HBaseClassTestRule;
28 import org.apache.hadoop.hbase.HBaseTestingUtil;
29 import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil;
30 import org.apache.hadoop.hbase.rest.client.Client;
31 import org.apache.hadoop.hbase.rest.client.Cluster;
32 import org.apache.hadoop.hbase.rest.client.Response;
33 import org.apache.hadoop.hbase.testclassification.MediumTests;
34 import org.apache.hadoop.hbase.testclassification.RestTests;
35 import org.junit.After;
36 import org.junit.AfterClass;
37 import org.junit.Before;
38 import org.junit.BeforeClass;
39 import org.junit.ClassRule;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
45 @Category({ RestTests.class, MediumTests.class})
46 public class TestRESTServerSSL {
48 @ClassRule
49 public static final HBaseClassTestRule CLASS_RULE =
50 HBaseClassTestRule.forClass(TestRESTServerSSL.class);
52 private static final Logger LOG = LoggerFactory.getLogger(TestRESTServerSSL.class);
54 private static final String KEY_STORE_PASSWORD = "myKSPassword";
55 private static final String TRUST_STORE_PASSWORD = "myTSPassword";
57 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
58 private static final HBaseRESTTestingUtility REST_TEST_UTIL = new HBaseRESTTestingUtility();
59 private static Client sslClient;
60 private static File keyDir;
61 private Configuration conf;
63 // Workaround for jdk8 292 bug. See https://github.com/bcgit/bc-java/issues/941
64 // Below is a workaround described in above URL. Issue fingered first in comments in
65 // HBASE-25920 Support Hadoop 3.3.1
66 private static void initializeAlgorithmId() {
67 try {
68 Class<?> algoId = Class.forName("sun.security.x509.AlgorithmId");
69 Method method = algoId.getMethod("get", String.class);
70 method.setAccessible(true);
71 method.invoke(null, "PBEWithSHA1AndDESede");
72 } catch (Exception e) {
73 LOG.warn("failed to initialize AlgorithmId", e);
77 @BeforeClass
78 public static void beforeClass() throws Exception {
79 initializeAlgorithmId();
80 keyDir = initKeystoreDir();
81 KeyPair keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
82 X509Certificate serverCertificate = KeyStoreTestUtil.generateCertificate(
83 "CN=localhost, O=server", keyPair, 30, "SHA1withRSA");
85 generateTrustStore("jks", serverCertificate);
86 generateTrustStore("jceks", serverCertificate);
87 generateTrustStore("pkcs12", serverCertificate);
89 generateKeyStore("jks", keyPair, serverCertificate);
90 generateKeyStore("jceks", keyPair, serverCertificate);
91 generateKeyStore("pkcs12", keyPair, serverCertificate);
93 TEST_UTIL.startMiniCluster();
96 @AfterClass
97 public static void afterClass() throws Exception {
98 // this will also delete the generated test keystore / teststore files,
99 // as we were placing them under the dataTestDir used by the minicluster
100 TEST_UTIL.shutdownMiniCluster();
103 @Before
104 public void beforeEachTest() {
105 conf = new Configuration(TEST_UTIL.getConfiguration());
106 conf.set(Constants.REST_SSL_ENABLED, "true");
107 conf.set(Constants.REST_SSL_KEYSTORE_KEYPASSWORD, KEY_STORE_PASSWORD);
108 conf.set(Constants.REST_SSL_KEYSTORE_PASSWORD, KEY_STORE_PASSWORD);
109 conf.set(Constants.REST_SSL_TRUSTSTORE_PASSWORD, TRUST_STORE_PASSWORD);
112 @After
113 public void tearDownAfterTest() {
114 REST_TEST_UTIL.shutdownServletContainer();
117 @Test
118 public void testSslConnection() throws Exception {
119 startRESTServerWithDefaultKeystoreType();
121 Response response = sslClient.get("/version", Constants.MIMETYPE_TEXT);
122 assertEquals(200, response.getCode());
124 // Default security headers
125 assertEquals("max-age=63072000;includeSubDomains;preload",
126 response.getHeader("Strict-Transport-Security"));
127 assertEquals("default-src https: data: 'unsafe-inline' 'unsafe-eval'",
128 response.getHeader("Content-Security-Policy"));
131 @Test(expected = org.apache.http.client.ClientProtocolException.class)
132 public void testNonSslClientDenied() throws Exception {
133 startRESTServerWithDefaultKeystoreType();
135 Cluster localCluster = new Cluster().add("localhost", REST_TEST_UTIL.getServletPort());
136 Client nonSslClient = new Client(localCluster, false);
138 nonSslClient.get("/version");
141 @Test
142 public void testSslConnectionUsingKeystoreFormatJKS() throws Exception {
143 startRESTServer("jks");
145 Response response = sslClient.get("/version", Constants.MIMETYPE_TEXT);
146 assertEquals(200, response.getCode());
149 @Test
150 public void testSslConnectionUsingKeystoreFormatJCEKS() throws Exception {
151 startRESTServer("jceks");
153 Response response = sslClient.get("/version", Constants.MIMETYPE_TEXT);
154 assertEquals(200, response.getCode());
157 @Test
158 public void testSslConnectionUsingKeystoreFormatPKCS12() throws Exception {
159 startRESTServer("pkcs12");
161 Response response = sslClient.get("/version", Constants.MIMETYPE_TEXT);
162 assertEquals(200, response.getCode());
167 private static File initKeystoreDir() {
168 String dataTestDir = TEST_UTIL.getDataTestDir().toString();
169 File keystoreDir = new File(dataTestDir, TestRESTServerSSL.class.getSimpleName() + "_keys");
170 keystoreDir.mkdirs();
171 return keystoreDir;
174 private static void generateKeyStore(String keyStoreType, KeyPair keyPair,
175 X509Certificate serverCertificate) throws Exception {
176 String keyStorePath = getKeystoreFilePath(keyStoreType);
177 KeyStoreTestUtil.createKeyStore(keyStorePath, KEY_STORE_PASSWORD, KEY_STORE_PASSWORD,
178 "serverKS", keyPair.getPrivate(), serverCertificate, keyStoreType);
181 private static void generateTrustStore(String trustStoreType, X509Certificate serverCertificate)
182 throws Exception {
183 String trustStorePath = getTruststoreFilePath(trustStoreType);
184 KeyStoreTestUtil.createTrustStore(trustStorePath, TRUST_STORE_PASSWORD, "serverTS",
185 serverCertificate, trustStoreType);
188 private static String getKeystoreFilePath(String keyStoreType) {
189 return String.format("%s/serverKS.%s", keyDir.getAbsolutePath(), keyStoreType);
192 private static String getTruststoreFilePath(String trustStoreType) {
193 return String.format("%s/serverTS.%s", keyDir.getAbsolutePath(), trustStoreType);
196 private void startRESTServerWithDefaultKeystoreType() throws Exception {
197 conf.set(Constants.REST_SSL_KEYSTORE_STORE, getKeystoreFilePath("jks"));
198 conf.set(Constants.REST_SSL_TRUSTSTORE_STORE, getTruststoreFilePath("jks"));
200 REST_TEST_UTIL.startServletContainer(conf);
201 Cluster localCluster = new Cluster().add("localhost", REST_TEST_UTIL.getServletPort());
202 sslClient = new Client(localCluster, getTruststoreFilePath("jks"),
203 Optional.of(TRUST_STORE_PASSWORD), Optional.empty());
206 private void startRESTServer(String storeType) throws Exception {
207 conf.set(Constants.REST_SSL_KEYSTORE_TYPE, storeType);
208 conf.set(Constants.REST_SSL_KEYSTORE_STORE, getKeystoreFilePath(storeType));
210 conf.set(Constants.REST_SSL_TRUSTSTORE_STORE, getTruststoreFilePath(storeType));
211 conf.set(Constants.REST_SSL_TRUSTSTORE_TYPE, storeType);
213 REST_TEST_UTIL.startServletContainer(conf);
214 Cluster localCluster = new Cluster().add("localhost", REST_TEST_UTIL.getServletPort());
215 sslClient = new Client(localCluster, getTruststoreFilePath(storeType),
216 Optional.of(TRUST_STORE_PASSWORD), Optional.of(storeType));