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