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.MockAesKeyProvider;
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, MockAesKeyProvider.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, MockAesKeyProvider.class.getName());
081    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
082    try {
083      EncryptionTest.testEncryption(conf, algorithm, null);
084    } catch (Exception e) {
085      fail("Test for cipher " + algorithm + " should have succeeded");
086    }
087  }
088
089  @Test(expected = IOException.class)
090  public void testUnknownCipher() throws Exception {
091    Configuration conf = HBaseConfiguration.create();
092    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
093    EncryptionTest.testEncryption(conf, "foobar", null);
094    fail("Test for bogus cipher should have failed");
095  }
096
097  @Test
098  public void testTestEnabledWithDefaultConfig() {
099    Configuration conf = HBaseConfiguration.create();
100    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
101    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
102    try {
103      EncryptionTest.testEncryption(conf, algorithm, null);
104    } catch (Exception e) {
105      fail("Test for cipher " + algorithm + " should have succeeded, when "
106        + Encryption.CRYPTO_ENABLED_CONF_KEY + " is not set");
107    }
108  }
109
110  @Test
111  public void testTestEnabledWhenCryptoIsExplicitlyEnabled() {
112    Configuration conf = HBaseConfiguration.create();
113    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
114    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
115    conf.setBoolean(Encryption.CRYPTO_ENABLED_CONF_KEY, true);
116    try {
117      EncryptionTest.testEncryption(conf, algorithm, null);
118    } catch (Exception e) {
119      fail("Test for cipher " + algorithm + " should have succeeded, when "
120        + Encryption.CRYPTO_ENABLED_CONF_KEY + " is set to true");
121    }
122  }
123
124  @Test(expected = IOException.class)
125  public void testTestEnabledWhenCryptoIsExplicitlyDisabled() throws Exception {
126    Configuration conf = HBaseConfiguration.create();
127    conf.set(HConstants.CRYPTO_KEYPROVIDER_CONF_KEY, MockAesKeyProvider.class.getName());
128    String algorithm = conf.get(HConstants.CRYPTO_KEY_ALGORITHM_CONF_KEY, HConstants.CIPHER_AES);
129    conf.setBoolean(Encryption.CRYPTO_ENABLED_CONF_KEY, false);
130    EncryptionTest.testEncryption(conf, algorithm, null);
131  }
132
133  public static class FailingKeyProvider implements KeyProvider {
134
135    @Override
136    public void init(String params) {
137      throw new RuntimeException("BAD!");
138    }
139
140    @Override
141    public Key getKey(String alias) {
142      return null;
143    }
144
145    @Override
146    public Key[] getKeys(String[] aliases) {
147      return null;
148    }
149
150  }
151
152  public static class FailingCipherProvider implements CipherProvider {
153
154    public FailingCipherProvider() {
155      super();
156      throw new RuntimeException("BAD!");
157    }
158
159    @Override
160    public Configuration getConf() {
161      return null;
162    }
163
164    @Override
165    public void setConf(Configuration conf) {
166    }
167
168    @Override
169    public String getName() {
170      return null;
171    }
172
173    @Override
174    public String[] getSupportedCiphers() {
175      return null;
176    }
177
178    @Override
179    public Cipher getCipher(String name) {
180      return null;
181    }
182
183  }
184}