HADOOP-10803. Update OpensslCipher#getInstance to accept CipherSuite#name format. (yliu)
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/fs-encryption@1609403 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7aa07912dc
commit
d90671137e
@ -28,6 +28,12 @@ fs-encryption (Unreleased)
|
|||||||
HADOOP-10713. Refactor CryptoCodec#generateSecureRandom to take a byte[].
|
HADOOP-10713. Refactor CryptoCodec#generateSecureRandom to take a byte[].
|
||||||
(wang via yliu)
|
(wang via yliu)
|
||||||
|
|
||||||
|
HADOOP-10693. Implementation of AES-CTR CryptoCodec using JNI to OpenSSL.
|
||||||
|
(Yi Liu via cmccabe)
|
||||||
|
|
||||||
|
HADOOP-10803. Update OpensslCipher#getInstance to accept CipherSuite#name
|
||||||
|
format. (Yi Liu)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
@ -70,8 +70,7 @@ private static class OpensslAesCtrCipher implements Encryptor, Decryptor {
|
|||||||
|
|
||||||
public OpensslAesCtrCipher(int mode) throws GeneralSecurityException {
|
public OpensslAesCtrCipher(int mode) throws GeneralSecurityException {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
cipher = OpensslCipher.getInstance(OpensslCipher.AES_CTR,
|
cipher = OpensslCipher.getInstance(SUITE.getName());
|
||||||
OpensslCipher.PADDING_NOPADDING);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
import javax.crypto.BadPaddingException;
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
@ -45,11 +46,34 @@ public final class OpensslCipher {
|
|||||||
public static final int DECRYPT_MODE = 0;
|
public static final int DECRYPT_MODE = 0;
|
||||||
|
|
||||||
/** Currently only support AES/CTR/NoPadding. */
|
/** Currently only support AES/CTR/NoPadding. */
|
||||||
public static final int AES_CTR = 0;
|
private static enum AlgMode {
|
||||||
public static final int PADDING_NOPADDING = 0;
|
AES_CTR;
|
||||||
|
|
||||||
|
static int get(String algorithm, String mode)
|
||||||
|
throws NoSuchAlgorithmException {
|
||||||
|
try {
|
||||||
|
return AlgMode.valueOf(algorithm + "_" + mode).ordinal();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new NoSuchAlgorithmException("Doesn't support algorithm: " +
|
||||||
|
algorithm + " and mode: " + mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static enum Padding {
|
||||||
|
NoPadding;
|
||||||
|
|
||||||
|
static int get(String padding) throws NoSuchPaddingException {
|
||||||
|
try {
|
||||||
|
return Padding.valueOf(padding).ordinal();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new NoSuchPaddingException("Doesn't support padding: " + padding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private long context = 0;
|
private long context = 0;
|
||||||
private final int algorithm;
|
private final int alg;
|
||||||
private final int padding;
|
private final int padding;
|
||||||
|
|
||||||
private static boolean nativeCipherLoaded = false;
|
private static boolean nativeCipherLoaded = false;
|
||||||
@ -69,26 +93,71 @@ public static boolean isNativeCodeLoaded() {
|
|||||||
return nativeCipherLoaded;
|
return nativeCipherLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OpensslCipher(long context, int algorithm, int padding) {
|
private OpensslCipher(long context, int alg, int padding) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.algorithm = algorithm;
|
this.alg = alg;
|
||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an <code>OpensslCipher<code> object that implements the specified
|
* Return an <code>OpensslCipher<code> object that implements the specified
|
||||||
* algorithm.
|
* transformation.
|
||||||
*
|
*
|
||||||
* @param algorithm currently only supports {@link #AES_CTR}
|
* @param transformation the name of the transformation, e.g.,
|
||||||
* @param padding currently only supports {@link #PADDING_NOPADDING}
|
* AES/CTR/NoPadding.
|
||||||
* @return OpensslCipher an <code>OpensslCipher<code> object
|
* @return OpensslCipher an <code>OpensslCipher<code> object
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException if <code>transformation</code> is null,
|
||||||
* @throws NoSuchPaddingException
|
* empty, in an invalid format, or if Openssl doesn't implement the
|
||||||
|
* specified algorithm.
|
||||||
|
* @throws NoSuchPaddingException if <code>transformation</code> contains
|
||||||
|
* a padding scheme that is not available.
|
||||||
*/
|
*/
|
||||||
public static final OpensslCipher getInstance(int algorithm,
|
public static final OpensslCipher getInstance(String transformation)
|
||||||
int padding) throws NoSuchAlgorithmException, NoSuchPaddingException {
|
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||||
long context = initContext(algorithm, padding);
|
Transform transform = tokenizeTransformation(transformation);
|
||||||
return new OpensslCipher(context, algorithm, padding);
|
int algMode = AlgMode.get(transform.alg, transform.mode);
|
||||||
|
int padding = Padding.get(transform.padding);
|
||||||
|
long context = initContext(algMode, padding);
|
||||||
|
return new OpensslCipher(context, algMode, padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Nested class for algorithm, mode and padding. */
|
||||||
|
private static class Transform {
|
||||||
|
final String alg;
|
||||||
|
final String mode;
|
||||||
|
final String padding;
|
||||||
|
|
||||||
|
public Transform(String alg, String mode, String padding) {
|
||||||
|
this.alg = alg;
|
||||||
|
this.mode = mode;
|
||||||
|
this.padding = padding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Transform tokenizeTransformation(String transformation)
|
||||||
|
throws NoSuchAlgorithmException {
|
||||||
|
if (transformation == null) {
|
||||||
|
throw new NoSuchAlgorithmException("No transformation given.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Array containing the components of a Cipher transformation:
|
||||||
|
*
|
||||||
|
* index 0: algorithm (e.g., AES)
|
||||||
|
* index 1: mode (e.g., CTR)
|
||||||
|
* index 2: padding (e.g., NoPadding)
|
||||||
|
*/
|
||||||
|
String[] parts = new String[3];
|
||||||
|
int count = 0;
|
||||||
|
StringTokenizer parser = new StringTokenizer(transformation, "/");
|
||||||
|
while (parser.hasMoreTokens() && count < 3) {
|
||||||
|
parts[count++] = parser.nextToken().trim();
|
||||||
|
}
|
||||||
|
if (count != 3 || parser.hasMoreTokens()) {
|
||||||
|
throw new NoSuchAlgorithmException("Invalid transformation format: " +
|
||||||
|
transformation);
|
||||||
|
}
|
||||||
|
return new Transform(parts[0], parts[1], parts[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +168,7 @@ public static final OpensslCipher getInstance(int algorithm,
|
|||||||
* @param iv crypto iv
|
* @param iv crypto iv
|
||||||
*/
|
*/
|
||||||
public void init(int mode, byte[] key, byte[] iv) {
|
public void init(int mode, byte[] key, byte[] iv) {
|
||||||
context = init(context, mode, algorithm, padding, key, iv);
|
context = init(context, mode, alg, padding, key, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,21 +38,18 @@ public void testGetInstance() throws Exception {
|
|||||||
if (!OpensslCipher.isNativeCodeLoaded()) {
|
if (!OpensslCipher.isNativeCodeLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OpensslCipher cipher = OpensslCipher.getInstance(OpensslCipher.AES_CTR,
|
OpensslCipher cipher = OpensslCipher.getInstance("AES/CTR/NoPadding");
|
||||||
OpensslCipher.PADDING_NOPADDING);
|
|
||||||
Assert.assertTrue(cipher != null);
|
Assert.assertTrue(cipher != null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cipher = OpensslCipher.getInstance(OpensslCipher.AES_CTR + 100,
|
cipher = OpensslCipher.getInstance("AES2/CTR/NoPadding");
|
||||||
OpensslCipher.PADDING_NOPADDING);
|
|
||||||
Assert.fail("Should specify correct algorithm.");
|
Assert.fail("Should specify correct algorithm.");
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// Expect NoSuchAlgorithmException
|
// Expect NoSuchAlgorithmException
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cipher = OpensslCipher.getInstance(OpensslCipher.AES_CTR,
|
cipher = OpensslCipher.getInstance("AES/CTR/NoPadding2");
|
||||||
OpensslCipher.PADDING_NOPADDING + 100);
|
|
||||||
Assert.fail("Should specify correct padding.");
|
Assert.fail("Should specify correct padding.");
|
||||||
} catch (NoSuchPaddingException e) {
|
} catch (NoSuchPaddingException e) {
|
||||||
// Expect NoSuchPaddingException
|
// Expect NoSuchPaddingException
|
||||||
@ -64,8 +61,7 @@ public void testUpdateArguments() throws Exception {
|
|||||||
if (!OpensslCipher.isNativeCodeLoaded()) {
|
if (!OpensslCipher.isNativeCodeLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OpensslCipher cipher = OpensslCipher.getInstance(OpensslCipher.AES_CTR,
|
OpensslCipher cipher = OpensslCipher.getInstance("AES/CTR/NoPadding");
|
||||||
OpensslCipher.PADDING_NOPADDING);
|
|
||||||
Assert.assertTrue(cipher != null);
|
Assert.assertTrue(cipher != null);
|
||||||
|
|
||||||
cipher.init(OpensslCipher.ENCRYPT_MODE, key, iv);
|
cipher.init(OpensslCipher.ENCRYPT_MODE, key, iv);
|
||||||
@ -100,8 +96,7 @@ public void testDoFinalArguments() throws Exception {
|
|||||||
if (!OpensslCipher.isNativeCodeLoaded()) {
|
if (!OpensslCipher.isNativeCodeLoaded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OpensslCipher cipher = OpensslCipher.getInstance(OpensslCipher.AES_CTR,
|
OpensslCipher cipher = OpensslCipher.getInstance("AES/CTR/NoPadding");
|
||||||
OpensslCipher.PADDING_NOPADDING);
|
|
||||||
Assert.assertTrue(cipher != null);
|
Assert.assertTrue(cipher != null);
|
||||||
|
|
||||||
cipher.init(OpensslCipher.ENCRYPT_MODE, key, iv);
|
cipher.init(OpensslCipher.ENCRYPT_MODE, key, iv);
|
||||||
|
@ -8,9 +8,6 @@ fs-encryption (Unreleased)
|
|||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
|
|
||||||
HADOOP-10693. Implementation of AES-CTR CryptoCodec using JNI to OpenSSL
|
|
||||||
(hitliuyi via cmccabe)
|
|
||||||
|
|
||||||
HDFS-6387. HDFS CLI admin tool for creating & deleting an
|
HDFS-6387. HDFS CLI admin tool for creating & deleting an
|
||||||
encryption zone. (clamb)
|
encryption zone. (clamb)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user