View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with this
4    * work for additional information regarding copyright ownership. The ASF
5    * licenses this file to you under the Apache License, Version 2.0 (the
6    * "License"); you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package org.apache.hadoop.hbase.io.crypto;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertNotNull;
21  
22  import java.io.File;
23  import java.io.FileOutputStream;
24  import java.net.URLEncoder;
25  import java.security.Key;
26  import java.security.KeyStore;
27  import java.security.MessageDigest;
28  import java.util.Properties;
29  
30  import javax.crypto.spec.SecretKeySpec;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
35  import org.apache.hadoop.hbase.testclassification.SmallTests;
36  import org.junit.BeforeClass;
37  import org.junit.Test;
38  import org.junit.experimental.categories.Category;
39  
40  @Category(SmallTests.class)
41  public class TestKeyStoreKeyProvider {
42  
43    static final Log LOG = LogFactory.getLog(TestKeyStoreKeyProvider.class);
44    static final HBaseCommonTestingUtility TEST_UTIL = new HBaseCommonTestingUtility();
45    static final String ALIAS = "test";
46    static final String PASSWORD = "password";
47  
48    static byte[] KEY;
49    static File storeFile;
50    static File passwordFile;
51  
52    @BeforeClass
53    public static void setUp() throws Exception {
54      KEY = MessageDigest.getInstance("SHA-256").digest(ALIAS.getBytes());
55      // Create a JKECS store containing a test secret key
56      KeyStore store = KeyStore.getInstance("JCEKS");
57      store.load(null, PASSWORD.toCharArray());
58      store.setEntry(ALIAS,
59        new KeyStore.SecretKeyEntry(new SecretKeySpec(KEY, "AES")),
60        new KeyStore.PasswordProtection(PASSWORD.toCharArray()));
61      // Create the test directory
62      String dataDir = TEST_UTIL.getDataTestDir().toString();
63      new File(dataDir).mkdirs();
64      // Write the keystore file
65      storeFile = new File(dataDir, "keystore.jks");
66      FileOutputStream os = new FileOutputStream(storeFile);
67      try {
68        store.store(os, PASSWORD.toCharArray());
69      } finally {
70        os.close();
71      }
72      // Write the password file
73      Properties p = new Properties();
74      p.setProperty(ALIAS, PASSWORD);
75      passwordFile = new File(dataDir, "keystore.pw");
76      os = new FileOutputStream(passwordFile);
77      try {
78        p.store(os, "");
79      } finally {
80        os.close();
81      }
82    }
83  
84    @Test(timeout=30000)
85    public void testKeyStoreKeyProviderWithPassword() throws Exception {
86      KeyProvider provider = new KeyStoreKeyProvider();
87      provider.init("jceks://" + storeFile.toURI().getPath() + "?password=" + PASSWORD);
88      Key key = provider.getKey(ALIAS);
89      assertNotNull(key);
90      byte[] keyBytes = key.getEncoded();
91      assertEquals(keyBytes.length, KEY.length);
92      for (int i = 0; i < KEY.length; i++) {
93        assertEquals(keyBytes[i], KEY[i]);
94      }
95    }
96  
97    @Test(timeout=30000)
98    public void testKeyStoreKeyProviderWithPasswordFile() throws Exception {
99      KeyProvider provider = new KeyStoreKeyProvider();
100     provider.init("jceks://" + storeFile.toURI().getPath() + "?passwordFile=" +
101       URLEncoder.encode(passwordFile.getAbsolutePath(), "UTF-8"));
102     Key key = provider.getKey(ALIAS);
103     assertNotNull(key);
104     byte[] keyBytes = key.getEncoded();
105     assertEquals(keyBytes.length, KEY.length);
106     for (int i = 0; i < KEY.length; i++) {
107       assertEquals(keyBytes[i], KEY[i]);
108     }
109   }
110 }