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.util.ArrayList;
022import java.util.Arrays;
023import java.util.Collection;
024import java.util.List;
025import java.util.Objects;
026import org.apache.hadoop.conf.Configuration;
027
028import org.apache.hbase.thirdparty.com.google.common.cache.CacheBuilder;
029import org.apache.hbase.thirdparty.com.google.common.cache.CacheLoader;
030import org.apache.hbase.thirdparty.com.google.common.cache.LoadingCache;
031
032/**
033 * Will cache X509TestContext to speed up tests.
034 */
035public class X509TestContextProvider {
036
037  private static final class CacheKey {
038    private final X509KeyType caKeyType;
039
040    private final X509KeyType certKeyType;
041
042    private final char[] keyPassword;
043
044    CacheKey(X509KeyType caKeyType, X509KeyType certKeyType, char[] keyPassword) {
045      this.caKeyType = caKeyType;
046      this.certKeyType = certKeyType;
047      this.keyPassword = keyPassword;
048    }
049
050    @Override
051    public int hashCode() {
052      return Objects.hash(caKeyType, certKeyType, Arrays.hashCode(keyPassword));
053    }
054
055    @Override
056    public boolean equals(Object obj) {
057      if (!(obj instanceof CacheKey)) {
058        return false;
059      }
060      CacheKey other = (CacheKey) obj;
061      return caKeyType == other.caKeyType && certKeyType == other.certKeyType
062        && Arrays.equals(keyPassword, other.keyPassword);
063    }
064  }
065
066  private final Configuration conf;
067
068  private final File tempDir;
069
070  private final LoadingCache<CacheKey, X509TestContext> ctxs =
071    CacheBuilder.newBuilder().build(new CacheLoader<CacheKey, X509TestContext>() {
072
073      @Override
074      public X509TestContext load(CacheKey key) throws Exception {
075        return X509TestContext.newBuilder(conf).setTempDir(tempDir)
076          .setKeyStorePassword(key.keyPassword).setKeyStoreKeyType(key.certKeyType)
077          .setTrustStorePassword(key.keyPassword).setTrustStoreKeyType(key.caKeyType).build();
078      }
079    });
080
081  public X509TestContextProvider(Configuration conf, File tempDir) {
082    this.conf = conf;
083    this.tempDir = tempDir;
084  }
085
086  public X509TestContext get(X509KeyType caKeyType, X509KeyType certKeyType, char[] keyPassword) {
087    return ctxs.getUnchecked(new CacheKey(caKeyType, certKeyType, keyPassword));
088  }
089
090  static Collection<Object[]> defaultParams() {
091    List<Object[]> params = new ArrayList<>();
092    int paramIndex = 0;
093    for (X509KeyType caKeyType : X509KeyType.values()) {
094      for (X509KeyType certKeyType : X509KeyType.values()) {
095        for (char[] keyPassword : new char[][] { "".toCharArray(), "pa$$w0rd".toCharArray() }) {
096          params.add(new Object[] { caKeyType, certKeyType, keyPassword, paramIndex++ });
097        }
098      }
099    }
100    return params;
101  }
102
103}