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.security.Security; 022import java.util.ArrayList; 023import java.util.List; 024import java.util.stream.Stream; 025import org.apache.commons.io.FileUtils; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.hbase.HBaseCommonTestingUtil; 028import org.bouncycastle.jce.provider.BouncyCastleProvider; 029import org.junit.jupiter.api.AfterAll; 030import org.junit.jupiter.api.AfterEach; 031import org.junit.jupiter.api.BeforeAll; 032import org.junit.jupiter.api.BeforeEach; 033import org.junit.jupiter.params.provider.Arguments; 034 035/** 036 * Base class for parameterized unit tests that use X509TestContext for testing different X509 037 * parameter combinations (CA key type, cert key type, with/without a password, with/without 038 * hostname verification, etc). 039 * <p/> 040 * This base class takes care of setting up / cleaning up the test environment, and caching the 041 * X509TestContext objects used by the tests. 042 * <p/> 043 * This file has been copied from the Apache ZooKeeper project. 044 * @see <a href= 045 * "https://github.com/apache/zookeeper/blob/master/zookeeper-server/src/test/java/org/apache/zookeeper/common/BaseX509ParameterizedTestCase.java">Base 046 * revision</a> 047 */ 048public abstract class AbstractTestX509Parameterized { 049 050 private static final HBaseCommonTestingUtil UTIL = new HBaseCommonTestingUtil(); 051 private static X509TestContextProvider PROVIDER; 052 053 private X509KeyType caKeyType; 054 private X509KeyType certKeyType; 055 private char[] keyPassword; 056 057 public AbstractTestX509Parameterized(X509KeyType caKeyType, X509KeyType certKeyType, 058 char[] keyPassword) { 059 this.caKeyType = caKeyType; 060 this.certKeyType = certKeyType; 061 this.keyPassword = keyPassword; 062 } 063 064 /** 065 * Default parameters suitable for most subclasses. See example usage in {@link TestX509Util}. 066 * @return a stream of parameter combinations to test with. 067 */ 068 public static Stream<Arguments> parameters() { 069 List<Arguments> result = new ArrayList<>(); 070 for (X509KeyType caKeyType : X509KeyType.values()) { 071 for (X509KeyType certKeyType : X509KeyType.values()) { 072 for (char[] keyPassword : new char[][] { "".toCharArray(), "pa$$w0rd".toCharArray() }) { 073 result.add(Arguments.of(caKeyType, certKeyType, keyPassword)); 074 } 075 } 076 } 077 return result.stream(); 078 } 079 080 /** 081 * Because key generation and writing / deleting files is kind of expensive, we cache the certs 082 * and on-disk files between test cases. None of the test cases modify any of this data so it's 083 * safe to reuse between tests. This caching makes all test cases after the first one for a given 084 * parameter combination complete almost instantly. 085 */ 086 protected static Configuration conf; 087 088 protected X509TestContext x509TestContext; 089 090 @BeforeAll 091 public static void setUpBaseClass() throws Exception { 092 Security.addProvider(new BouncyCastleProvider()); 093 File dir = new File(UTIL.getDataTestDir(TestX509Util.class.getSimpleName()).toString()) 094 .getCanonicalFile(); 095 FileUtils.forceMkdir(dir); 096 PROVIDER = new X509TestContextProvider(UTIL.getConfiguration(), dir); 097 } 098 099 @AfterAll 100 public static void cleanUpBaseClass() { 101 Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); 102 UTIL.cleanupTestDir(); 103 } 104 105 @BeforeEach 106 public void setUp() throws Exception { 107 x509TestContext = PROVIDER.get(caKeyType, certKeyType, keyPassword); 108 x509TestContext.setConfigurations(KeyStoreFileType.JKS, KeyStoreFileType.JKS); 109 conf = new Configuration(UTIL.getConfiguration()); 110 } 111 112 @AfterEach 113 public void cleanUp() { 114 x509TestContext.clearConfigurations(); 115 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_OCSP); 116 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_CLR); 117 x509TestContext.getConf().unset(X509Util.TLS_CONFIG_PROTOCOL); 118 System.clearProperty("com.sun.net.ssl.checkRevocation"); 119 System.clearProperty("com.sun.security.enableCRLDP"); 120 Security.setProperty("ocsp.enable", Boolean.FALSE.toString()); 121 Security.setProperty("com.sun.security.enableCRLDP", Boolean.FALSE.toString()); 122 } 123}