HADOOP-11060. Create a CryptoCodec test that verifies interoperability between the JCE and OpenSSL implementations. (hitliuyi via tucu)

This commit is contained in:
Alejandro Abdelnur 2014-09-04 09:22:00 -07:00
parent 70b218748b
commit b69a48c988
3 changed files with 55 additions and 19 deletions

View File

@ -501,6 +501,9 @@ Release 2.6.0 - UNRELEASED
HADOOP-11015. Http server/client utils to propagate and recreate HADOOP-11015. Http server/client utils to propagate and recreate
Exceptions from server to client. (tucu) Exceptions from server to client. (tucu)
HADOOP-11060. Create a CryptoCodec test that verifies interoperability
between the JCE and OpenSSL implementations. (hitliuyi via tucu)
OPTIMIZATIONS OPTIMIZATIONS
HADOOP-10838. Byte array native checksumming. (James Thomas via todd) HADOOP-10838. Byte array native checksumming. (James Thomas via todd)

View File

@ -52,35 +52,40 @@ public class TestCryptoCodec {
private Configuration conf = new Configuration(); private Configuration conf = new Configuration();
private int count = 10000; private int count = 10000;
private int seed = new Random().nextInt(); private int seed = new Random().nextInt();
private final String jceCodecClass =
"org.apache.hadoop.crypto.JceAesCtrCryptoCodec";
private final String opensslCodecClass =
"org.apache.hadoop.crypto.OpensslAesCtrCryptoCodec";
@Test(timeout=120000) @Test(timeout=120000)
public void testJceAesCtrCryptoCodec() throws Exception { public void testJceAesCtrCryptoCodec() throws Exception {
cryptoCodecTest(conf, seed, 0, Assume.assumeTrue(NativeCodeLoader.buildSupportsOpenssl());
"org.apache.hadoop.crypto.JceAesCtrCryptoCodec"); Assert.assertEquals(null, OpensslCipher.getLoadingFailureReason());
cryptoCodecTest(conf, seed, count, cryptoCodecTest(conf, seed, 0, jceCodecClass, jceCodecClass);
"org.apache.hadoop.crypto.JceAesCtrCryptoCodec"); cryptoCodecTest(conf, seed, count, jceCodecClass, jceCodecClass);
cryptoCodecTest(conf, seed, count, jceCodecClass, opensslCodecClass);
} }
@Test(timeout=1200000) @Test(timeout=120000)
public void testOpensslAesCtrCryptoCodec() throws Exception { public void testOpensslAesCtrCryptoCodec() throws Exception {
Assume.assumeTrue(NativeCodeLoader.buildSupportsOpenssl()); Assume.assumeTrue(NativeCodeLoader.buildSupportsOpenssl());
Assert.assertEquals(null, OpensslCipher.getLoadingFailureReason()); Assert.assertEquals(null, OpensslCipher.getLoadingFailureReason());
cryptoCodecTest(conf, seed, 0, cryptoCodecTest(conf, seed, 0, opensslCodecClass, opensslCodecClass);
"org.apache.hadoop.crypto.OpensslAesCtrCryptoCodec"); cryptoCodecTest(conf, seed, count, opensslCodecClass, opensslCodecClass);
cryptoCodecTest(conf, seed, count, cryptoCodecTest(conf, seed, count, opensslCodecClass, jceCodecClass);
"org.apache.hadoop.crypto.OpensslAesCtrCryptoCodec");
} }
private void cryptoCodecTest(Configuration conf, int seed, int count, private void cryptoCodecTest(Configuration conf, int seed, int count,
String codecClass) throws IOException, GeneralSecurityException { String encCodecClass, String decCodecClass) throws IOException,
CryptoCodec codec = null; GeneralSecurityException {
CryptoCodec encCodec = null;
try { try {
codec = (CryptoCodec)ReflectionUtils.newInstance( encCodec = (CryptoCodec)ReflectionUtils.newInstance(
conf.getClassByName(codecClass), conf); conf.getClassByName(encCodecClass), conf);
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
throw new IOException("Illegal crypto codec!"); throw new IOException("Illegal crypto codec!");
} }
LOG.info("Created a Codec object of type: " + codecClass); LOG.info("Created a Codec object of type: " + encCodecClass);
// Generate data // Generate data
DataOutputBuffer data = new DataOutputBuffer(); DataOutputBuffer data = new DataOutputBuffer();
@ -98,18 +103,27 @@ private void cryptoCodecTest(Configuration conf, int seed, int count,
// Encrypt data // Encrypt data
DataOutputBuffer encryptedDataBuffer = new DataOutputBuffer(); DataOutputBuffer encryptedDataBuffer = new DataOutputBuffer();
CryptoOutputStream out = new CryptoOutputStream(encryptedDataBuffer, CryptoOutputStream out = new CryptoOutputStream(encryptedDataBuffer,
codec, bufferSize, key, iv); encCodec, bufferSize, key, iv);
out.write(data.getData(), 0, data.getLength()); out.write(data.getData(), 0, data.getLength());
out.flush(); out.flush();
out.close(); out.close();
LOG.info("Finished encrypting data"); LOG.info("Finished encrypting data");
CryptoCodec decCodec = null;
try {
decCodec = (CryptoCodec)ReflectionUtils.newInstance(
conf.getClassByName(decCodecClass), conf);
} catch (ClassNotFoundException cnfe) {
throw new IOException("Illegal crypto codec!");
}
LOG.info("Created a Codec object of type: " + decCodecClass);
// Decrypt data // Decrypt data
DataInputBuffer decryptedDataBuffer = new DataInputBuffer(); DataInputBuffer decryptedDataBuffer = new DataInputBuffer();
decryptedDataBuffer.reset(encryptedDataBuffer.getData(), 0, decryptedDataBuffer.reset(encryptedDataBuffer.getData(), 0,
encryptedDataBuffer.getLength()); encryptedDataBuffer.getLength());
CryptoInputStream in = new CryptoInputStream(decryptedDataBuffer, CryptoInputStream in = new CryptoInputStream(decryptedDataBuffer,
codec, bufferSize, key, iv); decCodec, bufferSize, key, iv);
DataInputStream dataIn = new DataInputStream(new BufferedInputStream(in)); DataInputStream dataIn = new DataInputStream(new BufferedInputStream(in));
// Check // Check
@ -146,7 +160,7 @@ private void cryptoCodecTest(Configuration conf, int seed, int count,
decryptedDataBuffer.reset(encryptedDataBuffer.getData(), 0, decryptedDataBuffer.reset(encryptedDataBuffer.getData(), 0,
encryptedDataBuffer.getLength()); encryptedDataBuffer.getLength());
in = new CryptoInputStream(decryptedDataBuffer, in = new CryptoInputStream(decryptedDataBuffer,
codec, bufferSize, key, iv); decCodec, bufferSize, key, iv);
// Check // Check
originalIn = new DataInputStream(new BufferedInputStream(originalData)); originalIn = new DataInputStream(new BufferedInputStream(originalData));
@ -157,10 +171,29 @@ private void cryptoCodecTest(Configuration conf, int seed, int count,
expected, in.read()); expected, in.read());
} while (expected != -1); } while (expected != -1);
// Seek to a certain position and decrypt
originalData.reset(data.getData(), 0, data.getLength());
decryptedDataBuffer.reset(encryptedDataBuffer.getData(), 0,
encryptedDataBuffer.getLength());
in = new CryptoInputStream(new TestCryptoStreams.FakeInputStream(
decryptedDataBuffer), decCodec, bufferSize, key, iv);
int seekPos = data.getLength() / 3;
in.seek(seekPos);
// Check
TestCryptoStreams.FakeInputStream originalInput =
new TestCryptoStreams.FakeInputStream(originalData);
originalInput.seek(seekPos);
do {
expected = originalInput.read();
assertEquals("Decrypted stream read by byte does not match",
expected, in.read());
} while (expected != -1);
LOG.info("SUCCESS! Completed checking " + count + " records"); LOG.info("SUCCESS! Completed checking " + count + " records");
// Check secure random generator // Check secure random generator
testSecureRandom(codec); testSecureRandom(encCodec);
} }
/** Test secure random generator */ /** Test secure random generator */

View File

@ -159,7 +159,7 @@ private void checkStream() throws IOException {
} }
} }
private class FakeInputStream extends InputStream implements public static class FakeInputStream extends InputStream implements
Seekable, PositionedReadable, ByteBufferReadable, HasFileDescriptor, Seekable, PositionedReadable, ByteBufferReadable, HasFileDescriptor,
CanSetDropBehind, CanSetReadahead, HasEnhancedByteBufferAccess { CanSetDropBehind, CanSetReadahead, HasEnhancedByteBufferAccess {
private final byte[] oneByteBuf = new byte[1]; private final byte[] oneByteBuf = new byte[1];