diff options
author | Roberto Tyley <roberto.tyley@gmail.com> | 2014-07-15 01:38:01 +0400 |
---|---|---|
committer | Roberto Tyley <roberto.tyley@gmail.com> | 2014-07-26 11:23:17 +0400 |
commit | 7cb752aaf746dc0b473afeb9e892b7fbc12666c5 (patch) | |
tree | cc4f91ddc18332b5adbe82e3fcb040d976c90105 /pg/src/test/java/org/spongycastle/openpgp/test/BcPGPPBETest.java | |
parent | 551830f8ea5177042af2c7dd1fc90888bc67387d (diff) |
Execute become-spongy.sh
https://github.com/rtyley/spongycastle/blob/3040af/become-spongy.sh
Diffstat (limited to 'pg/src/test/java/org/spongycastle/openpgp/test/BcPGPPBETest.java')
-rw-r--r-- | pg/src/test/java/org/spongycastle/openpgp/test/BcPGPPBETest.java | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/pg/src/test/java/org/spongycastle/openpgp/test/BcPGPPBETest.java b/pg/src/test/java/org/spongycastle/openpgp/test/BcPGPPBETest.java new file mode 100644 index 00000000..9a394d30 --- /dev/null +++ b/pg/src/test/java/org/spongycastle/openpgp/test/BcPGPPBETest.java @@ -0,0 +1,500 @@ +package org.spongycastle.openpgp.test; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.SecureRandom; +import java.security.Security; +import java.util.Date; + +import org.spongycastle.jce.provider.BouncyCastleProvider; +import org.spongycastle.openpgp.PGPCompressedData; +import org.spongycastle.openpgp.PGPCompressedDataGenerator; +import org.spongycastle.openpgp.PGPEncryptedData; +import org.spongycastle.openpgp.PGPEncryptedDataGenerator; +import org.spongycastle.openpgp.PGPEncryptedDataList; +import org.spongycastle.openpgp.PGPLiteralData; +import org.spongycastle.openpgp.PGPLiteralDataGenerator; +import org.spongycastle.openpgp.PGPPBEEncryptedData; +import org.spongycastle.openpgp.jcajce.JcaPGPObjectFactory; +import org.spongycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory; +import org.spongycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator; +import org.spongycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.spongycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.spongycastle.util.encoders.Base64; +import org.spongycastle.util.encoders.Hex; +import org.spongycastle.util.test.SimpleTest; +import org.spongycastle.util.test.UncloseableOutputStream; + +public class BcPGPPBETest + extends SimpleTest +{ + private static final Date TEST_DATE = new Date(1062200111000L); + + byte[] enc1 = Base64.decode( + "jA0EAwMC5M5wWBP2HBZgySvUwWFAmMRLn7dWiZN6AkQMvpE3b6qwN3SSun7zInw2" + + "hxxdgFzVGfbjuB8w"); + + byte[] enc1crc = Base64.decode("H66L"); + + char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' }; + + /** + * Message with both PBE and symmetric + */ + byte[] testPBEAsym = Base64.decode( + "hQIOA/ZlQEFWB5vuEAf/covEUaBve7NlWWdiO5NZubdtTHGElEXzG9hyBycp9At8" + + "nZGi27xOZtEGFQo7pfz4JySRc3O0s6w7PpjJSonFJyNSxuze2LuqRwFWBYYcbS8/" + + "7YcjB6PqutrT939OWsozfNqivI9/QyZCjBvFU89pp7dtUngiZ6MVv81ds2I+vcvk" + + "GlIFcxcE1XoCIB3EvbqWNaoOotgEPT60unnB2BeDV1KD3lDRouMIYHfZ3SzBwOOI" + + "6aK39sWnY5sAK7JjFvnDAMBdueOiI0Fy+gxbFD/zFDt4cWAVSAGTC4w371iqppmT" + + "25TM7zAtCgpiq5IsELPlUZZnXKmnYQ7OCeysF0eeVwf+OFB9fyvCEv/zVQocJCg8" + + "fWxfCBlIVFNeNQpeGygn/ZmRaILvB7IXDWP0oOw7/F2Ym66IdYYIp2HeEZv+jFwa" + + "l41w5W4BH/gtbwGjFQ6CvF/m+lfUv6ZZdzsMIeEOwhP5g7rXBxrbcnGBaU+PXbho" + + "gjDqaYzAWGlrmAd6aPSj51AGeYXkb2T1T/yoJ++M3GvhH4C4hvitamDkksh/qRnM" + + "M/s8Nku6z1+RXO3M6p5QC1nlAVqieU8esT43945eSoC77K8WyujDNbysDyUCUTzt" + + "p/aoQwe/HgkeOTJNelKR9y2W3xinZLFzep0SqpNI/e468yB/2/LGsykIyQa7JX6r" + + "BYwuBAIDAkOKfv5rK8v0YDfnN+eFqwhTcrfBj5rDH7hER6nW3lNWcMataUiHEaMg" + + "o6Q0OO1vptIGxW8jClTD4N1sCNwNu9vKny8dKYDDHbCjE06DNTv7XYVW3+JqTL5E" + + "BnidvGgOmA=="); + + /** + * decrypt the passed in message stream + */ + private byte[] decryptMessage( + byte[] message, + Date date) + throws Exception + { + JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(message); + PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); + PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); + + InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); + + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clear); + PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); + + pgpFact = new JcaPGPObjectFactory(cData.getDataStream()); + + PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + if (!ld.getFileName().equals("test.txt") + && !ld.getFileName().equals("_CONSOLE")) + { + fail("wrong filename in packet"); + } + if (!ld.getModificationTime().equals(date)) + { + fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); + } + + InputStream unc = ld.getInputStream(); + int ch; + + while ((ch = unc.read()) >= 0) + { + bOut.write(ch); + } + + if (pbe.isIntegrityProtected() && !pbe.verify()) + { + fail("integrity check failed"); + } + + return bOut.toByteArray(); + } + + /** + * decrypt the passed in message stream, verifying the algorithm used. + */ + private byte[] decryptMessageCheck( + int algorithm, + byte[] message, + Date date) + throws Exception + { + JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(message); + PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); + PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); + + if (algorithm != pbe.getSymmetricAlgorithm(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider()))) + { + fail("algorithm mismatch"); + } + + InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); + + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clear); + PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); + + pgpFact = new JcaPGPObjectFactory(cData.getDataStream()); + + PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + if (!ld.getFileName().equals("test.txt") + && !ld.getFileName().equals("_CONSOLE")) + { + fail("wrong filename in packet"); + } + if (!ld.getModificationTime().equals(date)) + { + fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); + } + + InputStream unc = ld.getInputStream(); + int ch; + + while ((ch = unc.read()) >= 0) + { + bOut.write(ch); + } + + if (pbe.isIntegrityProtected() && !pbe.verify()) + { + fail("integrity check failed"); + } + + return bOut.toByteArray(); + } + + private byte[] decryptMessageBuffered( + byte[] message, + Date date) + throws Exception + { + JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(message); + PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); + PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); + + InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); + + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clear); + PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject(); + + pgpFact = new JcaPGPObjectFactory(cData.getDataStream()); + + PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + if (!ld.getFileName().equals("test.txt") + && !ld.getFileName().equals("_CONSOLE")) + { + fail("wrong filename in packet"); + } + if (!ld.getModificationTime().equals(date)) + { + fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); + } + + InputStream unc = ld.getInputStream(); + byte[] buf = new byte[1024]; + int len; + + while ((len = unc.read(buf)) >= 0) + { + bOut.write(buf, 0, len); + } + + if (pbe.isIntegrityProtected() && !pbe.verify()) + { + fail("integrity check failed"); + } + + return bOut.toByteArray(); + } + + public void performTest() + throws Exception + { + byte[] out = decryptMessage(enc1, TEST_DATE); + + if (out[0] != 'h' || out[1] != 'e' || out[2] != 'l') + { + fail("wrong plain text in packet"); + } + + // + // create a PBE encrypted message and read it back. + // + byte[] text = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)' ', (byte)'w', (byte)'o', (byte)'r', (byte)'l', (byte)'d', (byte)'!', (byte)'\n' }; + + // + // encryption step - convert to literal data, compress, encode. + // + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( + PGPCompressedData.ZIP); + + Date cDate = new Date((System.currentTimeMillis() / 1000) * 1000); + PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); + OutputStream comOut = comData.open(new UncloseableOutputStream(bOut)); + OutputStream ldOut = lData.open( + new UncloseableOutputStream(comOut), + PGPLiteralData.BINARY, + PGPLiteralData.CONSOLE, + text.length, + cDate); + + ldOut.write(text); + + ldOut.close(); + + comOut.close(); + + // + // encrypt - with stream close + // + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + + cOut.write(bOut.toByteArray()); + + cOut.close(); + + out = decryptMessage(cbOut.toByteArray(), cDate); + + if (!areEqual(out, text)) + { + fail("wrong plain text in generated packet"); + } + + // + // encrypt - with generator close + // + cbOut = new ByteArrayOutputStream(); + cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(new SecureRandom())); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); + + cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + + cOut.write(bOut.toByteArray()); + + cPk.close(); + + out = decryptMessage(cbOut.toByteArray(), cDate); + + if (!areEqual(out, text)) + { + fail("wrong plain text in generated packet"); + } + + // + // encrypt - partial packet style. + // + SecureRandom rand = new SecureRandom(); + byte[] test = new byte[1233]; + + rand.nextBytes(test); + + bOut = new ByteArrayOutputStream(); + + comData = new PGPCompressedDataGenerator( + PGPCompressedData.ZIP); + comOut = comData.open(bOut); + lData = new PGPLiteralDataGenerator(); + + ldOut = lData.open(new UncloseableOutputStream(comOut), + PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, TEST_DATE, + new byte[16]); + + + ldOut.write(test); + + ldOut.close(); + + comOut.close(); + + cbOut = new ByteArrayOutputStream(); + cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setSecureRandom(rand)); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); + + cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); + + cOut.write(bOut.toByteArray()); + + cOut.close(); + + out = decryptMessage(cbOut.toByteArray(), TEST_DATE); + if (!areEqual(out, test)) + { + fail("wrong plain text in generated packet"); + } + + // + // with integrity packet + // + cbOut = new ByteArrayOutputStream(); + cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); + + cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); + + cOut.write(bOut.toByteArray()); + + cOut.close(); + + out = decryptMessage(cbOut.toByteArray(), TEST_DATE); + if (!areEqual(out, test)) + { + fail("wrong plain text in generated packet"); + } + + // + // decrypt with buffering + // + out = decryptMessageBuffered(cbOut.toByteArray(), TEST_DATE); + if (!areEqual(out, test)) + { + fail("wrong plain text in buffer generated packet"); + } + + // + // sample message + // + JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(testPBEAsym); + + PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpFact.nextObject(); + + PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(1); + + InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory("password".toCharArray(), new BcPGPDigestCalculatorProvider())); + + pgpFact = new JcaPGPObjectFactory(clear); + + PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); + + bOut = new ByteArrayOutputStream(); + InputStream unc = ld.getInputStream(); + int ch; + + while ((ch = unc.read()) >= 0) + { + bOut.write(ch); + } + + if (!areEqual(bOut.toByteArray(), Hex.decode("5361742031302e30322e30370d0a"))) + { + fail("data mismatch on combined PBE"); + } + + // + // with integrity packet - one byte message + // + byte[] msg = new byte[1]; + bOut = new ByteArrayOutputStream(); + + comData = new PGPCompressedDataGenerator( + PGPCompressedData.ZIP); + + lData = new PGPLiteralDataGenerator(); + comOut = comData.open(new UncloseableOutputStream(bOut)); + ldOut = lData.open( + new UncloseableOutputStream(comOut), + PGPLiteralData.BINARY, + PGPLiteralData.CONSOLE, + msg.length, + cDate); + + ldOut.write(msg); + + ldOut.close(); + + comOut.close(); + + cbOut = new ByteArrayOutputStream(); + cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(true).setSecureRandom(rand)); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); + + cOut = cPk.open(new UncloseableOutputStream(cbOut), new byte[16]); + + cOut.write(bOut.toByteArray()); + + cOut.close(); + + out = decryptMessage(cbOut.toByteArray(), cDate); + if (!areEqual(out, msg)) + { + fail("wrong plain text in generated packet"); + } + + // + // decrypt with buffering + // + out = decryptMessageBuffered(cbOut.toByteArray(), cDate); + if (!areEqual(out, msg)) + { + fail("wrong plain text in buffer generated packet"); + } + + tryAlgorithm(PGPEncryptedData.AES_128, text); + //tryAlgorithm(PGPEncryptedData.CAMELLIA_128, text); + } + + private void tryAlgorithm(int algorithm, byte[] text) + throws Exception + { + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( + PGPCompressedData.ZIP); + + Date cDate = new Date((System.currentTimeMillis() / 1000) * 1000); + PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); + OutputStream comOut = comData.open(new UncloseableOutputStream(bOut)); + OutputStream ldOut = lData.open( + new UncloseableOutputStream(comOut), + PGPLiteralData.BINARY, + PGPLiteralData.CONSOLE, + text.length, + cDate); + + ldOut.write(text); + + ldOut.close(); + + comOut.close(); + + ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); + PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(algorithm).setSecureRandom(new SecureRandom())); + + cPk.addMethod(new BcPBEKeyEncryptionMethodGenerator(pass)); + + OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length); + + cOut.write(bOut.toByteArray()); + + cOut.close(); + + byte[] out = decryptMessageCheck(algorithm, cbOut.toByteArray(), cDate); + + if (!areEqual(out, text)) + { + fail("wrong plain text in generated packet"); + } + } + + public String getName() + { + return "BcPGPPBETest"; + } + + public static void main( + String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new BcPGPPBETest()); + } +} |