Skip to content

Commit 84e10b8

Browse files
committed
Use reflection.
1 parent 698e48e commit 84e10b8

File tree

8 files changed

+99
-17
lines changed

8 files changed

+99
-17
lines changed

hadoop-common-project/hadoop-common/pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@
375375
<dependency>
376376
<groupId>org.bouncycastle</groupId>
377377
<artifactId>bcprov-jdk18on</artifactId>
378-
<scope>test</scope>
379378
</dependency>
380379
<dependency>
381380
<groupId>org.apache.kerby</groupId>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.crypto;
19+
20+
import org.apache.hadoop.classification.InterfaceAudience;
21+
import org.apache.hadoop.conf.Configuration;
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
25+
import java.lang.reflect.Field;
26+
import java.security.Provider;
27+
import java.security.Security;
28+
29+
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_ADD_DEFAULT;
30+
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_ADD_KEY;
31+
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY;
32+
33+
@InterfaceAudience.Private
34+
public class CryptoUtils {
35+
static final Logger LOG = LoggerFactory.getLogger(CryptoUtils.class);
36+
37+
private static final String BOUNCY_CASTLE_PROVIDER_CLASS
38+
= "org.bouncycastle.jce.provider.BouncyCastleProvider";
39+
private static final String PROVIDER_NAME_FIELD = "PROVIDER_NAME";
40+
41+
private static void addProvider(String provider) {
42+
if (provider == null || provider.isEmpty()) {
43+
return;
44+
}
45+
try {
46+
// For backward compatible, try to auto-add BOUNCY_CASTLE_PROVIDER_CLASS.
47+
final Class<?> clazz = Class.forName(BOUNCY_CASTLE_PROVIDER_CLASS);
48+
final Field provider_name = clazz.getField("PROVIDER_NAME");
49+
if (provider.equals(provider_name.get(null))) {
50+
Security.addProvider((Provider) clazz.getConstructor().newInstance());
51+
LOG.debug("Successfully added security provider {}", provider);
52+
}
53+
} catch (ClassNotFoundException e) {
54+
LOG.warn("Failed to load " + BOUNCY_CASTLE_PROVIDER_CLASS, e);
55+
} catch (NoSuchFieldException e) {
56+
LOG.warn("Failed to get field " + PROVIDER_NAME_FIELD
57+
+ " from class " + BOUNCY_CASTLE_PROVIDER_CLASS, e);
58+
} catch (Exception e) {
59+
LOG.warn("Failed to add security provider for {}", provider, e);
60+
}
61+
}
62+
63+
public static String getJceProvider(Configuration conf) {
64+
final String jceProvider = conf.get(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY);
65+
if (conf.getBoolean(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_ADD_KEY,
66+
HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_ADD_DEFAULT)) {
67+
CryptoUtils.addProvider(jceProvider);
68+
}
69+
return jceProvider;
70+
}
71+
}

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/JceCtrCryptoCodec.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import javax.crypto.spec.SecretKeySpec;
3232
import org.slf4j.Logger;
3333

34-
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY;
3534
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_KEY;
3635
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_DEFAULT;
3736

@@ -46,10 +45,6 @@ public String getProvider() {
4645
return provider;
4746
}
4847

49-
public void setProvider(String provider) {
50-
this.provider = provider;
51-
}
52-
5348
public void calculateIV(byte[] initIV, long counter,
5449
byte[] iv, int blockSize) {
5550
Preconditions.checkArgument(initIV.length == blockSize);
@@ -80,7 +75,8 @@ public Configuration getConf() {
8075

8176
public void setConf(Configuration conf) {
8277
this.conf = conf;
83-
setProvider(conf.get(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY));
78+
this.provider = CryptoUtils.getJceProvider(conf);
79+
8480
final String secureRandomAlg =
8581
conf.get(
8682
HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_KEY,

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.apache.hadoop.classification.InterfaceAudience;
4040
import org.apache.hadoop.classification.InterfaceStability;
4141
import org.apache.hadoop.conf.Configuration;
42+
import org.apache.hadoop.crypto.CryptoUtils;
4243
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
4344

4445
import javax.crypto.KeyGenerator;
@@ -407,6 +408,7 @@ public KeyProvider(Configuration conf) {
407408
JCEKS_KEY_SERIALFILTER_DEFAULT);
408409
System.setProperty(JCEKS_KEY_SERIAL_FILTER, serialFilter);
409410
}
411+
CryptoUtils.getJceProvider(conf);
410412
}
411413

412414
/**

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,9 @@ public class CommonConfigurationKeysPublic {
773773
*/
774774
public static final String HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY =
775775
"hadoop.security.crypto.jce.provider";
776+
public static final String HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_ADD_KEY =
777+
"hadoop.security.crypto.jce.provider.add";
778+
public static final boolean HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_ADD_DEFAULT = true;
776779
/**
777780
* @see
778781
* <a href="{@docRoot}/../hadoop-project-dist/hadoop-common/core-default.xml">

hadoop-common-project/hadoop-common/src/main/resources/core-default.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3625,7 +3625,19 @@ The switch to turn S3A auditing on or off.
36253625
The JCE provider name used in CryptoCodec.
36263626
If this value is set, the corresponding provider must be added to the provider list.
36273627
The provider may be added statically in the java.security file, or
3628-
added dynamically by calling the java.security.Security.addProvider(..) method.
3628+
dynamically by calling the java.security.Security.addProvider(..) method, or
3629+
automatically (only for org.bouncycastle.jce.provider.BouncyCastleProvider)
3630+
by setting "hadoop.security.crypto.jce.provider.add" to true
3631+
</description>
3632+
</property>
3633+
3634+
<property>
3635+
<name>hadoop.security.crypto.jce.provider.add</name>
3636+
<value>true</value>
3637+
<description>
3638+
Automatically add the org.bouncycastle.jce.provider.BouncyCastleProvider
3639+
when the value in "hadoop.security.crypto.jce.provider" is set to
3640+
BouncyCastleProvider.PROVIDER_NAME.
36293641
</description>
36303642
</property>
36313643

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/TestCryptoCodec.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.math.BigInteger;
3333
import java.security.GeneralSecurityException;
3434
import java.security.SecureRandom;
35-
import java.security.Security;
3635
import java.util.Arrays;
3736
import java.util.HashMap;
3837
import java.util.Map;
@@ -105,11 +104,6 @@ public void testJceAesCtrCryptoCodec() throws Exception {
105104
jceAesCodecClass, opensslAesCodecClass, iv);
106105
}
107106

108-
static void initBouncyCastleProvider(Configuration conf) {
109-
conf.set(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY, BouncyCastleProvider.PROVIDER_NAME);
110-
Security.addProvider(new BouncyCastleProvider());
111-
}
112-
113107
@Test(timeout=120000)
114108
public void testJceSm4CtrCryptoCodec() throws Exception {
115109
GenericTestUtils.assumeInNativeProfile();
@@ -120,7 +114,8 @@ public void testJceSm4CtrCryptoCodec() throws Exception {
120114
conf.set(HADOOP_SECURITY_CRYPTO_CIPHER_SUITE_KEY, "SM4/CTR/NoPadding");
121115
conf.set(HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_SM4_CTR_NOPADDING_KEY,
122116
JceSm4CtrCryptoCodec.class.getName());
123-
initBouncyCastleProvider(conf);
117+
conf.set(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY,
118+
BouncyCastleProvider.PROVIDER_NAME);
124119
Assert.assertEquals(null, OpensslCipher.getLoadingFailureReason());
125120
cryptoCodecTest(conf, seed, 0,
126121
jceSm4CodecClass, jceSm4CodecClass, iv);
@@ -169,7 +164,8 @@ public void testOpensslSm4CtrCryptoCodec() throws Exception {
169164
LOG.warn("Skipping test since openSSL library not loaded");
170165
Assume.assumeTrue(false);
171166
}
172-
initBouncyCastleProvider(conf);
167+
conf.set(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY,
168+
BouncyCastleProvider.PROVIDER_NAME);
173169
Assert.assertEquals(null, OpensslCipher.getLoadingFailureReason());
174170
cryptoCodecTest(conf, seed, 0,
175171
opensslSm4CodecClass, opensslSm4CodecClass, iv);

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/TestCryptoStreamsWithJceSm4CtrCryptoCodec.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.apache.hadoop.crypto;
1919

20+
import org.bouncycastle.jce.provider.BouncyCastleProvider;
2021
import org.apache.hadoop.conf.Configuration;
2122
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
2223
import org.junit.BeforeClass;
@@ -25,6 +26,7 @@
2526
HADOOP_SECURITY_CRYPTO_CIPHER_SUITE_KEY;
2627
import static org.assertj.core.api.Assertions.assertThat;
2728

29+
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY;
2830

2931
public class TestCryptoStreamsWithJceSm4CtrCryptoCodec extends
3032
TestCryptoStreams {
@@ -33,7 +35,8 @@ public class TestCryptoStreamsWithJceSm4CtrCryptoCodec extends
3335
public static void init() throws Exception {
3436
Configuration conf = new Configuration();
3537
conf.set(HADOOP_SECURITY_CRYPTO_CIPHER_SUITE_KEY, "SM4/CTR/NoPadding");
36-
TestCryptoCodec.initBouncyCastleProvider(conf);
38+
conf.set(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY,
39+
BouncyCastleProvider.PROVIDER_NAME);
3740
conf.set(
3841
CommonConfigurationKeysPublic.
3942
HADOOP_SECURITY_CRYPTO_CODEC_CLASSES_SM4_CTR_NOPADDING_KEY,

0 commit comments

Comments
 (0)