001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.io.crypto.tls; 019 020import java.io.File; 021import java.io.IOException; 022import java.security.Security; 023import java.util.ArrayList; 024import java.util.List; 025import java.util.stream.Stream; 026import org.apache.commons.io.FileUtils; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.hbase.HBaseCommonTestingUtil; 029import org.bouncycastle.jce.provider.BouncyCastleProvider; 030import org.junit.jupiter.api.AfterAll; 031import org.junit.jupiter.api.AfterEach; 032import org.junit.jupiter.api.BeforeAll; 033import org.junit.jupiter.api.BeforeEach; 034import org.junit.jupiter.params.provider.Arguments; 035 036/** 037 * Base class for parameterized unit tests that use X509TestContext for testing different X509 038 * parameter combinations (CA key type, cert key type, with/without a password, with/without 039 * hostname verification, etc). 040 * <p/> 041 * This base class takes care of setting up / cleaning up the test environment, and caching the 042 * X509TestContext objects used by the tests. 043 * <p/> 044 * This file has been copied from the Apache ZooKeeper project. 045 * @see <a href= 046 * "https://github.com/apache/zookeeper/blob/master/zookeeper-server/src/test/java/org/apache/zookeeper/common/BaseX509ParameterizedTestCase.java">Base 047 * revision</a> 048 */ 049public abstract class AbstractTestX509Parameterized { 050 051 private static final HBaseCommonTestingUtil UTIL = new HBaseCommonTestingUtil(); 052 private static X509TestContextProvider PROVIDER; 053 054 private X509KeyType caKeyType; 055 private X509KeyType certKeyType; 056 private char[] keyPassword; 057 058 public AbstractTestX509Parameterized(X509KeyType caKeyType, X509KeyType certKeyType, 059 char[] keyPassword) { 060 this.caKeyType = caKeyType; 061 this.certKeyType = certKeyType; 062 this.keyPassword = keyPassword; 063 } 064 065 /** 066 * Default parameters suitable for most subclasses. See example usage in {@link TestX509Util}. 067 * @return a stream of parameter combinations to test with. 068 */ 069 public static Stream<Arguments> parameters() { 070 List<Arguments> result = new ArrayList<>(); 071 for (X509KeyType caKeyType : X509KeyType.values()) { 072 for (X509KeyType certKeyType : X509KeyType.values()) { 073 for (char[] keyPassword : new char[][] { "".toCharArray(), "pa$$w0rd".toCharArray() }) { 074 result.add(Arguments.of(caKeyType, certKeyType, keyPassword)); 075 } 076 } 077 } 078 return result.stream(); 079 } 080 081 /** 082 * Because key generation and writing / deleting files is kind of expensive, we cache the certs 083 * and on-disk files between test cases. None of the test cases modify any of this data so it's 084 * safe to reuse between tests. This caching makes all test cases after the first one for a given 085 * parameter combination complete almost instantly. 086 */ 087 protected static Configuration conf; 088 089 protected X509TestContext x509TestContext; 090 091 @BeforeAll 092 public static void setUpBaseClass() throws Exception { 093 Security.addProvider(new BouncyCastleProvider()); 094 File dir = new File(UTIL.getDataTestDir(TestX509Util.class.getSimpleName()).toString()) 095 .getCanonicalFile(); 096 FileUtils.forceMkdir(dir); 097 PROVIDER = new X509TestContextProvider(UTIL.getConfiguration(), dir); 098 } 099 100 @AfterAll 101 public static void cleanUpBaseClass() { 102 Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); 103 UTIL.cleanupTestDir(); 104 } 105 106 @BeforeEach 107 public void setUp() throws IOException { 108 x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword); 109 x509TestContext.setConfigurations(KeyStoreFileType.JKS, KeyStoreFileType.JKS); 110 conf = new Configuration(UTIL.getConfiguration()); 111 } 112 113 @AfterEach 114 public void cleanUp() { 115 x509TestContext.clearConfigurations(); 116 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_OCSP); 117 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_CLR); 118 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_PROTOCOL); 119 System.clearProperty("com.sun.net.ssl.checkRevocation"); 120 System.clearProperty("com.sun.security.enableCRLDP"); 121 Security.setProperty("ocsp.enable", Boolean.FALSE.toString()); 122 Security.setProperty("com.sun.security.enableCRLDP", Boolean.FALSE.toString()); 123 } 124}