package org.bouncycastle.openpgp.test; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.openpgp.PGPCompressedData; import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignature; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.util.test.UncloseableOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.Security; import java.util.Date; /** * GPG compatability test vectors */ public class DSA2Test extends TestCase { private static final String TEST_DATA_HOME = "bc.test.data.home"; public void setUp() { if (Security.getProvider("BC") == null) { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } } public void testK1024H160() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-160-sign.gpg"); } public void testK1024H224() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-224-sign.gpg"); } public void testK1024H256() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-256-sign.gpg"); } public void testK1024H384() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-384-sign.gpg"); } public void testK1024H512() throws Exception { doSigVerifyTest("DSA-1024-160.pub", "dsa-1024-512-sign.gpg"); } public void testK2048H224() throws Exception { doSigVerifyTest("DSA-2048-224.pub", "dsa-2048-224-sign.gpg"); } public void testK3072H256() throws Exception { doSigVerifyTest("DSA-3072-256.pub", "dsa-3072-256-sign.gpg"); } public void testK7680H384() throws Exception { doSigVerifyTest("DSA-7680-384.pub", "dsa-7680-384-sign.gpg"); } public void testK15360H512() throws Exception { doSigVerifyTest("DSA-15360-512.pub", "dsa-15360-512-sign.gpg"); } public void testGenerateK1024H224() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA224); } public void testGenerateK1024H256() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA256); } public void testGenerateK1024H384() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA384); } public void testGenerateK1024H512() throws Exception { doSigGenerateTest("DSA-1024-160.sec", "DSA-1024-160.pub", PGPUtil.SHA512); } public void testGenerateK2048H256() throws Exception { doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", PGPUtil.SHA256); } public void testGenerateK2048H512() throws Exception { doSigGenerateTest("DSA-2048-224.sec", "DSA-2048-224.pub", PGPUtil.SHA512); } private void doSigGenerateTest(String privateKeyFile, String publicKeyFile, int digest) throws Exception { PGPSecretKeyRing secRing = loadSecretKey(privateKeyFile); PGPPublicKeyRing pubRing = loadPublicKey(publicKeyFile); String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, digest, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, secRing.getSecretKey().extractPrivateKey("test".toCharArray(), "BC")); BCPGOutputStream bcOut = new BCPGOutputStream(bOut); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bcOut); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); assertEquals(digest, ops.getHashAlgorithm()); assertEquals(PublicKeyAlgorithmTags.DSA, ops.getKeyAlgorithm()); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.initVerify(pubRing.getPublicKey(), "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); assertEquals(digest, sig.getHashAlgorithm()); assertEquals(PublicKeyAlgorithmTags.DSA, sig.getKeyAlgorithm()); assertTrue(ops.verify(sig)); } private void doSigVerifyTest( String publicKeyFile, String sigFile) throws Exception { PGPPublicKeyRing publicKey = loadPublicKey(publicKeyFile); PGPObjectFactory pgpFact = loadSig(sigFile); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); ops.initVerify(publicKey.getPublicKey(), "BC"); int ch; while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); assertTrue(ops.verify(p3.get(0))); } private PGPObjectFactory loadSig( String sigName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/sigs/" + sigName); return new PGPObjectFactory(fIn); } private PGPPublicKeyRing loadPublicKey( String keyName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/keys/" + keyName); return new PGPPublicKeyRing(fIn); } private PGPSecretKeyRing loadSecretKey( String keyName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/keys/" + keyName); return new PGPSecretKeyRing(fIn); } private String getDataHome() { String dataHome = System.getProperty(TEST_DATA_HOME); if (dataHome == null) { throw new IllegalStateException(TEST_DATA_HOME + " property not set"); } return dataHome + "/openpgp/dsa"; } public static void main (String[] args) throws Exception { junit.textui.TestRunner.run(suite()); } public static Test suite() throws Exception { TestSuite suite = new TestSuite("GPG DSA2 tests"); suite.addTestSuite(DSA2Test.class); return suite; } }