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.util;
019
020import static org.junit.jupiter.api.Assertions.assertThrows;
021import static org.junit.jupiter.api.Assertions.fail;
022
023import java.io.IOException;
024import java.security.Key;
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.hbase.HBaseConfiguration;
027import org.apache.hadoop.hbase.HConstants;
028import org.apache.hadoop.hbase.io.crypto.Cipher;
029import org.apache.hadoop.hbase.io.crypto.CipherProvider;
030import org.apache.hadoop.hbase.io.crypto.DefaultCipherProvider;
031import org.apache.hadoop.hbase.io.crypto.Encryption;
032import org.apache.hadoop.hbase.io.crypto.KeyProvider;
033import org.apache.hadoop.hbase.io.crypto.MockAesKeyProvider;
034import org.apache.hadoop.hbase.testclassification.MiscTests;
035import org.apache.hadoop.hbase.testclassification.SmallTests;
036import org.junit.jupiter.api.Tag;
037import org.junit.jupiter.api.Test;
038
039@Tag(MiscTests.TAG)
040@Tag(SmallTests.TAG)
041public class TestEncryptionTest {
042
043  @Test
044  public void testTestKeyProvider() throws Exception {
045    Configuration conf = HBaseConfiguration.create();
046    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
047    EncryptionTest.testKeyProvider(conf);
048  }
049
050  @Test
051  public void testBadKeyProvider() throws Exception {
052    Configuration conf = HBaseConfiguration.create();
053    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, FailingKeyProvider.class.getName());
054    assertThrows(IOException.class, () -> {
055      EncryptionTest.testKeyProvider(conf);
056    });
057  }
058
059  @Test
060  public void testDefaultCipherProvider() throws Exception {
061    Configuration conf = HBaseConfiguration.create();
062    conf.set(HConstants.CRYPTO_CIPHERPROVIDER_CONF_KEY, DefaultCipherProvider.class.getName());
063    EncryptionTest.testCipherProvider(conf);
064  }
065
066  @Test
067  public void testBadCipherProvider() throws Exception {
068    Configuration conf = HBaseConfiguration.create();
069    conf.set(HConstants.CRYPTO_CIPHERPROVIDER_CONF_KEY, FailingCipherProvider.class.getName());
070    assertThrows(IOException.class, () -> {
071      EncryptionTest.testCipherProvider(conf);
072    });
073  }
074
075  @Test
076  public void testAESCipher() {
077    Configuration conf = HBaseConfiguration.create();
078    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
079    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
080    try {
081      EncryptionTest.testEncryption(conf, algorithm, null);
082    } catch (Exception e) {
083      fail("Test for cipher " + algorithm + " should have succeeded");
084    }
085  }
086
087  @Test
088  public void testUnknownCipher() throws Exception {
089    Configuration conf = HBaseConfiguration.create();
090    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
091    assertThrows(IOException.class, () -> {
092      EncryptionTest.testEncryption(conf, "foobar", null);
093    });
094  }
095
096  @Test
097  public void testTestEnabledWithDefaultConfig() {
098    Configuration conf = HBaseConfiguration.create();
099    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
100    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
101    try {
102      EncryptionTest.testEncryption(conf, algorithm, null);
103    } catch (Exception e) {
104      fail("Test for cipher " + algorithm + " should have succeeded, when "
105        + Encryption.CRYPTO_ENABLED_CONF_KEY + " is not set");
106    }
107  }
108
109  @Test
110  public void testTestEnabledWhenCryptoIsExplicitlyEnabled() {
111    Configuration conf = HBaseConfiguration.create();
112    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
113    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
114    conf.setBoolean(Encryption.CRYPTO_ENABLED_CONF_KEY, true);
115    try {
116      EncryptionTest.testEncryption(conf, algorithm, null);
117    } catch (Exception e) {
118      fail("Test for cipher " + algorithm + " should have succeeded, when "
119        + Encryption.CRYPTO_ENABLED_CONF_KEY + " is set to true");
120    }
121  }
122
123  @Test
124  public void testTestEnabledWhenCryptoIsExplicitlyDisabled() throws Exception {
125    Configuration conf = HBaseConfiguration.create();
126    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
127    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
128    conf.setBoolean(Encryption.CRYPTO_ENABLED_CONF_KEY, false);
129    assertThrows(IOException.class, () -> {
130      EncryptionTest.testEncryption(conf, algorithm, null);
131    });
132  }
133
134  public static class FailingKeyProvider implements KeyProvider {
135
136    @Override
137    public void init(String params) {
138      throw new RuntimeException("BAD!");
139    }
140
141    @Override
142    public Key getKey(String alias) {
143      return null;
144    }
145
146    @Override
147    public Key[] getKeys(String[] aliases) {
148      return null;
149    }
150
151  }
152
153  public static class FailingCipherProvider implements CipherProvider {
154
155    public FailingCipherProvider() {
156      super();
157      throw new RuntimeException("BAD!");
158    }
159
160    @Override
161    public Configuration getConf() {
162      return null;
163    }
164
165    @Override
166    public void setConf(Configuration conf) {
167    }
168
169    @Override
170    public String getName() {
171      return null;
172    }
173
174    @Override
175    public String[] getSupportedCiphers() {
176      return null;
177    }
178
179    @Override
180    public Cipher getCipher(String name) {
181      return null;
182    }
183
184  }
185}