1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver.wal;
20
21 import java.io.IOException;
22 import java.security.Key;
23 import java.security.KeyException;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.fs.FSDataInputStream;
28 import org.apache.hadoop.hbase.HConstants;
29 import org.apache.hadoop.hbase.io.crypto.Cipher;
30 import org.apache.hadoop.hbase.io.crypto.Decryptor;
31 import org.apache.hadoop.hbase.io.crypto.Encryption;
32 import org.apache.hadoop.hbase.protobuf.generated.WALProtos.WALHeader;
33 import org.apache.hadoop.hbase.security.EncryptionUtil;
34 import org.apache.hadoop.hbase.security.User;
35
36 public class SecureProtobufLogReader extends ProtobufLogReader {
37
38 private static final Log LOG = LogFactory.getLog(SecureProtobufLogReader.class);
39
40 private Decryptor decryptor = null;
41
42 @Override
43 protected boolean readHeader(WALHeader.Builder builder, FSDataInputStream stream)
44 throws IOException {
45 boolean result = super.readHeader(builder, stream);
46
47
48
49 if (result && builder.hasEncryptionKey()) {
50
51
52
53
54
55 byte[] keyBytes = builder.getEncryptionKey().toByteArray();
56 Key key = null;
57 String walKeyName = conf.get(HConstants.CRYPTO_WAL_KEY_NAME_CONF_KEY);
58
59 if (walKeyName != null) {
60 try {
61 key = EncryptionUtil.unwrapKey(conf, walKeyName, keyBytes);
62 } catch (KeyException e) {
63 if (LOG.isDebugEnabled()) {
64 LOG.debug("Unable to unwrap key with WAL key '" + walKeyName + "'");
65 }
66 key = null;
67 }
68 }
69 if (key == null) {
70 String masterKeyName = conf.get(HConstants.CRYPTO_MASTERKEY_NAME_CONF_KEY,
71 User.getCurrent().getShortName());
72 try {
73
74 key = EncryptionUtil.unwrapKey(conf, masterKeyName, keyBytes);
75 } catch (KeyException e) {
76
77
78 if (LOG.isDebugEnabled()) {
79 LOG.debug("Unable to unwrap key with current master key '" + masterKeyName + "'");
80 }
81 String alternateKeyName =
82 conf.get(HConstants.CRYPTO_MASTERKEY_ALTERNATE_NAME_CONF_KEY);
83 if (alternateKeyName != null) {
84 try {
85 key = EncryptionUtil.unwrapKey(conf, alternateKeyName, keyBytes);
86 } catch (KeyException ex) {
87 throw new IOException(ex);
88 }
89 } else {
90 throw new IOException(e);
91 }
92 }
93 }
94
95
96
97 Cipher cipher = Encryption.getCipher(conf, key.getAlgorithm());
98 if (cipher == null) {
99 throw new IOException("Cipher '" + key.getAlgorithm() + "' is not available");
100 }
101
102
103
104 decryptor = cipher.getDecryptor();
105 decryptor.setKey(key);
106
107 if (LOG.isTraceEnabled()) {
108 LOG.trace("Initialized secure protobuf WAL: cipher=" + cipher.getName());
109 }
110 }
111
112 return result;
113 }
114
115 @Override
116 protected void initAfterCompression() throws IOException {
117 if (decryptor != null) {
118 WALCellCodec codec = SecureWALCellCodec.getCodec(this.conf, decryptor);
119 this.cellDecoder = codec.getDecoder(this.inputStream);
120
121 this.compressionContext = null;
122 this.hasCompression = false;
123 } else {
124 super.initAfterCompression();
125 }
126 }
127
128 }