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.security; 019 020import java.io.IOException; 021import java.security.Key; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 025import org.apache.hadoop.hbase.client.TableDescriptor; 026import org.apache.hadoop.hbase.io.crypto.Cipher; 027import org.apache.hadoop.hbase.io.crypto.Encryption; 028import org.apache.hadoop.hbase.io.hfile.FixedFileTrailer; 029import org.apache.hadoop.hbase.keymeta.ManagedKeyDataCache; 030import org.apache.hadoop.hbase.keymeta.SystemKeyCache; 031import org.apache.yetus.audience.InterfaceAudience; 032import org.apache.yetus.audience.InterfaceStability; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036/** 037 * Security related generic utility methods. 038 */ 039@InterfaceAudience.Private 040@InterfaceStability.Evolving 041public final class SecurityUtil { 042 private static final Logger LOG = LoggerFactory.getLogger(SecurityUtil.class); 043 044 private SecurityUtil() { 045 // Utility class 046 } 047 048 /** 049 * Get the user name from a principal 050 */ 051 public static String getUserFromPrincipal(final String principal) { 052 int i = principal.indexOf("/"); 053 if (i == -1) { 054 i = principal.indexOf("@"); 055 } 056 return (i > -1) ? principal.substring(0, i) : principal; 057 } 058 059 /** 060 * Get the user name from a principal 061 */ 062 public static String getPrincipalWithoutRealm(final String principal) { 063 int i = principal.indexOf("@"); 064 return (i > -1) ? principal.substring(0, i) : principal; 065 } 066 067 /** 068 * Helper to create an encryption context with current encryption key, suitable for writes. STUB 069 * IMPLEMENTATION - Key management not yet implemented. Cache parameters are placeholders for 070 * future implementation. 071 * @param conf The current configuration. 072 * @param tableDescriptor The table descriptor. 073 * @param family The current column descriptor. 074 * @param managedKeyDataCache The managed key data cache (unused in stub). 075 * @param systemKeyCache The system key cache (unused in stub). 076 * @return The created encryption context. 077 * @throws IOException if an encryption key for the column cannot be unwrapped 078 * @throws IllegalStateException in case of encryption related configuration errors 079 */ 080 public static Encryption.Context createEncryptionContext(Configuration conf, 081 TableDescriptor tableDescriptor, ColumnFamilyDescriptor family, 082 ManagedKeyDataCache managedKeyDataCache, SystemKeyCache systemKeyCache) throws IOException { 083 Encryption.Context cryptoContext = Encryption.Context.NONE; 084 String cipherName = family.getEncryptionType(); 085 086 if (cipherName != null) { 087 if (!Encryption.isEncryptionEnabled(conf)) { 088 throw new IllegalStateException("Encryption for family '" + family.getNameAsString() 089 + "' configured with type '" + cipherName + "' but the encryption feature is disabled"); 090 } 091 092 Key key = null; 093 byte[] familyKeyBytes = family.getEncryptionKey(); 094 095 // Unwrap family key if present 096 if (familyKeyBytes != null) { 097 key = EncryptionUtil.unwrapKey(conf, familyKeyBytes); 098 } 099 100 Cipher cipher = Encryption.getCipher(conf, cipherName); 101 if (cipher == null) { 102 throw new IllegalStateException("Cipher '" + cipherName + "' is not available"); 103 } 104 105 // Generate random key if none provided 106 if (key == null) { 107 key = cipher.getRandomKey(); 108 } 109 110 cryptoContext = Encryption.newContext(conf); 111 cryptoContext.setCipher(cipher); 112 cryptoContext.setKey(key); 113 } 114 return cryptoContext; 115 } 116 117 /** 118 * Create an encryption context from encryption key found in a file trailer, suitable for read. 119 * STUB IMPLEMENTATION - Key management not yet implemented. Cache parameters are placeholders for 120 * future implementation. 121 * @param conf The current configuration. 122 * @param path The path of the file. 123 * @param trailer The file trailer. 124 * @param managedKeyDataCache The managed key data cache (unused in stub). 125 * @param systemKeyCache The system key cache (unused in stub). 126 * @return The created encryption context or null if no key material is available. 127 * @throws IOException if an encryption key for the file cannot be unwrapped 128 */ 129 public static Encryption.Context createEncryptionContext(Configuration conf, Path path, 130 FixedFileTrailer trailer, ManagedKeyDataCache managedKeyDataCache, 131 SystemKeyCache systemKeyCache) throws IOException { 132 byte[] keyBytes = trailer.getEncryptionKey(); 133 Encryption.Context cryptoContext = Encryption.Context.NONE; 134 135 if (keyBytes != null) { 136 cryptoContext = Encryption.newContext(conf); 137 Key key = EncryptionUtil.unwrapKey(conf, keyBytes); 138 Cipher cipher = Encryption.getCipher(conf, key.getAlgorithm()); 139 140 if (cipher == null) { 141 throw new IllegalStateException("Cipher '" + key.getAlgorithm() + "' is not available"); 142 } 143 144 cryptoContext.setCipher(cipher); 145 cryptoContext.setKey(key); 146 } 147 return cryptoContext; 148 } 149 150 /** 151 * Check if key management is enabled in configuration. STUB - Always returns false in precursor. 152 * @param conf the configuration to check 153 * @return false in stub implementation 154 */ 155 public static boolean isKeyManagementEnabled(Configuration conf) { 156 return false; 157 } 158}