diff --git a/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt b/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt index 3ce7695ddfe..498307e6bc7 100644 --- a/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt +++ b/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt @@ -51,3 +51,6 @@ fs-encryption (Unreleased) BUG FIXES HADOOP-10871. incorrect prototype in OpensslSecureRandom.c (cmccabe) + + HADOOP-10886. CryptoCodec#getCodecclasses throws NPE when configurations not + loaded. (umamahesh) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoCodec.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoCodec.java index f484083b592..9de7f95200f 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoCodec.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/CryptoCodec.java @@ -45,14 +45,21 @@ public abstract class CryptoCodec implements Configurable { /** * Get crypto codec for specified algorithm/mode/padding. - * @param conf the configuration - * @param CipherSuite algorithm/mode/padding - * @return CryptoCodec the codec object + * + * @param conf + * the configuration + * @param CipherSuite + * algorithm/mode/padding + * @return CryptoCodec the codec object. Null value will be returned if no + * crypto codec classes with cipher suite configured. */ public static CryptoCodec getInstance(Configuration conf, CipherSuite cipherSuite) { List> klasses = getCodecClasses( conf, cipherSuite); + if (klasses == null) { + return null; + } CryptoCodec codec = null; for (Class klass : klasses) { try { @@ -80,10 +87,13 @@ public abstract class CryptoCodec implements Configurable { } /** - * Get crypto codec for algorithm/mode/padding in config value + * Get crypto codec for algorithm/mode/padding in config value * hadoop.security.crypto.cipher.suite - * @param conf the configuration - * @return CryptoCodec the codec object + * + * @param conf + * the configuration + * @return CryptoCodec the codec object Null value will be returned if no + * crypto codec classes with cipher suite configured. */ public static CryptoCodec getInstance(Configuration conf) { String name = conf.get(HADOOP_SECURITY_CRYPTO_CIPHER_SUITE_KEY, @@ -97,6 +107,10 @@ public abstract class CryptoCodec implements Configurable { String configName = HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_KEY_PREFIX + cipherSuite.getConfigSuffix(); String codecString = conf.get(configName); + if (codecString == null) { + LOG.warn("No crypto codec classes with cipher suite configured."); + return null; + } for (String c : Splitter.on(',').trimResults().omitEmptyStrings(). split(codecString)) { try { diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/TestCryptoStreamsForLocalFS.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/TestCryptoStreamsForLocalFS.java index 286fb6a3d29..765a364faa6 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/TestCryptoStreamsForLocalFS.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/TestCryptoStreamsForLocalFS.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.io.OutputStream; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.fs.LocalFileSystem; @@ -50,6 +51,11 @@ public class TestCryptoStreamsForLocalFS extends CryptoStreamsTestBase { conf = new Configuration(false); conf.set("fs.file.impl", LocalFileSystem.class.getName()); fileSys = FileSystem.getLocal(conf); + conf.set( + CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_KEY_PREFIX + + CipherSuite.AES_CTR_NOPADDING.getConfigSuffix(), + OpensslAesCtrCryptoCodec.class.getName() + "," + + JceAesCtrCryptoCodec.class.getName()); codec = CryptoCodec.getInstance(conf); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java index 04acb037665..d3532607c84 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSClient.java @@ -598,7 +598,9 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory, DFSUtil.getRandom().nextInt() + "_" + Thread.currentThread().getId(); this.codec = CryptoCodec.getInstance(conf); this.cipherSuites = Lists.newArrayListWithCapacity(1); - cipherSuites.add(codec.getCipherSuite()); + if (codec != null) { + cipherSuites.add(codec.getCipherSuite()); + } provider = DFSUtil.createKeyProviderCryptoExtension(conf); if (provider == null) { LOG.info("No KeyProvider found."); @@ -1333,9 +1335,12 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory, if (feInfo != null) { // File is encrypted, wrap the stream in a crypto stream. KeyVersion decrypted = decryptEncryptedDataEncryptionKey(feInfo); + CryptoCodec codec = CryptoCodec + .getInstance(conf, feInfo.getCipherSuite()); + Preconditions.checkNotNull(codec == null, + "No crypto codec classes with cipher suite configured."); final CryptoInputStream cryptoIn = - new CryptoInputStream(dfsis, CryptoCodec.getInstance(conf, - feInfo.getCipherSuite()), decrypted.getMaterial(), + new CryptoInputStream(dfsis, codec, decrypted.getMaterial(), feInfo.getIV()); return new HdfsDataInputStream(cryptoIn); } else { @@ -1361,6 +1366,8 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory, FileSystem.Statistics statistics, long startPos) throws IOException { final FileEncryptionInfo feInfo = dfsos.getFileEncryptionInfo(); if (feInfo != null) { + Preconditions.checkNotNull(codec == null, + "No crypto codec classes with cipher suite configured."); // File is encrypted, wrap the stream in a crypto stream. KeyVersion decrypted = decryptEncryptedDataEncryptionKey(feInfo); final CryptoOutputStream cryptoOut = diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java index 0982ee23884..b71cc32fb80 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDistributedFileSystem.java @@ -38,7 +38,6 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Random; -import java.util.concurrent.CancellationException; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.logging.impl.Log4JLogger;