Add spongy castle sources to libraries folder
This commit is contained in:
@@ -0,0 +1,415 @@
|
||||
package org.spongycastle.openpgp.examples.test;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.spongycastle.openpgp.examples.ClearSignedFileProcessor;
|
||||
import org.spongycastle.openpgp.examples.DSAElGamalKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.examples.KeyBasedFileProcessor;
|
||||
import org.spongycastle.openpgp.examples.KeyBasedLargeFileProcessor;
|
||||
import org.spongycastle.openpgp.examples.PBEFileProcessor;
|
||||
import org.spongycastle.openpgp.examples.RSAKeyPairGenerator;
|
||||
import org.spongycastle.openpgp.examples.SignedFileProcessor;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class AllTests
|
||||
extends TestCase
|
||||
{
|
||||
byte[] clearSignedPublicKey = Base64.decode(
|
||||
"mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+"
|
||||
+ "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1"
|
||||
+ "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO"
|
||||
+ "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7"
|
||||
+ "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4"
|
||||
+ "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp"
|
||||
+ "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD"
|
||||
+ "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR"
|
||||
+ "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch"
|
||||
+ "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg"
|
||||
+ "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r"
|
||||
+ "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1"
|
||||
+ "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz"
|
||||
+ "oztls8tuWA0OGHba9XfX9rfgorACAAM=");
|
||||
|
||||
String crOnlyMessage =
|
||||
"\r"
|
||||
+ " hello world!\r"
|
||||
+ "\r"
|
||||
+ "- dash\r";
|
||||
|
||||
String nlOnlyMessage =
|
||||
"\n"
|
||||
+ " hello world!\n"
|
||||
+ "\n"
|
||||
+ "- dash\n";
|
||||
|
||||
String crNlMessage =
|
||||
"\r\n"
|
||||
+ " hello world!\r\n"
|
||||
+ "\r\n"
|
||||
+ "- dash\r\n";
|
||||
|
||||
String crNlMessageTrailingWhiteSpace =
|
||||
"\r\n"
|
||||
+ " hello world! \t\r\n"
|
||||
+ "\r\n"
|
||||
+ "\r\n";
|
||||
|
||||
String crOnlySignedMessage =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\r"
|
||||
+ "Hash: SHA256\r"
|
||||
+ "\r"
|
||||
+ "\r"
|
||||
+ " hello world!\r"
|
||||
+ "\r"
|
||||
+ "- - dash\r"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\r"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r"
|
||||
+ "\r"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r"
|
||||
+ "=84Nd\r"
|
||||
+ "-----END PGP SIGNATURE-----\r";
|
||||
|
||||
|
||||
String nlOnlySignedMessage =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\n"
|
||||
+ "Hash: SHA256\n"
|
||||
+ "\n"
|
||||
+ "\n"
|
||||
+ " hello world!\n"
|
||||
+ "\n"
|
||||
+ "- - dash\n"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\n"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\n"
|
||||
+ "\n"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n"
|
||||
+ "=84Nd\n"
|
||||
+ "-----END PGP SIGNATURE-----\n";
|
||||
|
||||
String crNlSignedMessage =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
|
||||
+ "Hash: SHA256\r\n"
|
||||
+ "\r\n"
|
||||
+ "\r\n"
|
||||
+ " hello world!\r\n"
|
||||
+ "\r\n"
|
||||
+ "- - dash\r\n"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\r\n"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
|
||||
+ "\r\n"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
|
||||
+ "=84Nd\r"
|
||||
+ "-----END PGP SIGNATURE-----\r\n";
|
||||
|
||||
String crNlSignedMessageTrailingWhiteSpace =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
|
||||
+ "Hash: SHA256\r\n"
|
||||
+ "\r\n"
|
||||
+ "\r\n"
|
||||
+ " hello world! \t\r\n"
|
||||
+ "\r\n"
|
||||
+ "- - dash\r\n"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\r\n"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
|
||||
+ "\r\n"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
|
||||
+ "=84Nd\r"
|
||||
+ "-----END PGP SIGNATURE-----\r\n";
|
||||
|
||||
private PrintStream _oldOut;
|
||||
private PrintStream _oldErr;
|
||||
|
||||
private ByteArrayOutputStream _currentOut;
|
||||
private ByteArrayOutputStream _currentErr;
|
||||
|
||||
public void setUp()
|
||||
throws Exception
|
||||
{
|
||||
_oldOut = System.out;
|
||||
_oldErr = System.err;
|
||||
_currentOut = new ByteArrayOutputStream();
|
||||
_currentErr = new ByteArrayOutputStream();
|
||||
|
||||
System.setOut(new PrintStream(_currentOut));
|
||||
System.setErr(new PrintStream(_currentErr));
|
||||
}
|
||||
|
||||
public void tearDown()
|
||||
{
|
||||
System.setOut(_oldOut);
|
||||
System.setErr(_oldErr);
|
||||
}
|
||||
|
||||
public void testRSAKeyGeneration()
|
||||
throws Exception
|
||||
{
|
||||
RSAKeyPairGenerator.main(new String[] { "test", "password" });
|
||||
|
||||
createSmallTestInput();
|
||||
createLargeTestInput();
|
||||
|
||||
checkSigning("bpg");
|
||||
checkKeyBasedEncryption("bpg");
|
||||
checkLargeKeyBasedEncryption("bpg");
|
||||
|
||||
RSAKeyPairGenerator.main(new String[] { "-a", "test", "password" });
|
||||
|
||||
checkSigning("asc");
|
||||
checkKeyBasedEncryption("asc");
|
||||
checkLargeKeyBasedEncryption("asc");
|
||||
}
|
||||
|
||||
public void testDSAElGamaleKeyGeneration()
|
||||
throws Exception
|
||||
{
|
||||
DSAElGamalKeyRingGenerator.main(new String[] { "test", "password" });
|
||||
|
||||
createSmallTestInput();
|
||||
createLargeTestInput();
|
||||
|
||||
checkSigning("bpg");
|
||||
checkKeyBasedEncryption("bpg");
|
||||
checkLargeKeyBasedEncryption("bpg");
|
||||
|
||||
DSAElGamalKeyRingGenerator.main(new String[] { "-a", "test", "password" });
|
||||
|
||||
checkSigning("asc");
|
||||
checkKeyBasedEncryption("asc");
|
||||
checkLargeKeyBasedEncryption("asc");
|
||||
}
|
||||
|
||||
public void testPBEEncryption()
|
||||
throws Exception
|
||||
{
|
||||
_currentErr.reset();
|
||||
|
||||
PBEFileProcessor.main(new String[] { "-e", "test.txt", "password" });
|
||||
|
||||
PBEFileProcessor.main(new String[] { "-d", "test.txt.bpg", "password" });
|
||||
|
||||
assertEquals("no message integrity check", getLine(_currentErr));
|
||||
|
||||
PBEFileProcessor.main(new String[] { "-e", "-i", "test.txt", "password" });
|
||||
|
||||
PBEFileProcessor.main(new String[] { "-d", "test.txt.bpg", "password" });
|
||||
|
||||
assertEquals("message integrity check passed", getLine(_currentErr));
|
||||
|
||||
PBEFileProcessor.main(new String[] { "-e", "-ai", "test.txt", "password" });
|
||||
|
||||
PBEFileProcessor.main(new String[] { "-d", "test.txt.asc", "password" });
|
||||
|
||||
assertEquals("message integrity check passed", getLine(_currentErr));
|
||||
}
|
||||
|
||||
public void testClearSigned()
|
||||
throws Exception
|
||||
{
|
||||
createTestFile(clearSignedPublicKey, "pub.bpg");
|
||||
|
||||
checkClearSignedVerify(nlOnlySignedMessage);
|
||||
checkClearSignedVerify(crOnlySignedMessage);
|
||||
checkClearSignedVerify(crNlSignedMessage);
|
||||
checkClearSignedVerify(crNlSignedMessageTrailingWhiteSpace);
|
||||
|
||||
ClearSignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub.bpg" });
|
||||
|
||||
RSAKeyPairGenerator.main(new String[] { "test", "password" });
|
||||
|
||||
checkClearSigned(crOnlyMessage);
|
||||
checkClearSigned(nlOnlyMessage);
|
||||
checkClearSigned(crNlMessage);
|
||||
checkClearSigned(crNlMessageTrailingWhiteSpace);
|
||||
}
|
||||
|
||||
public void testClearSignedBogusInput()
|
||||
throws Exception
|
||||
{
|
||||
createTestFile(clearSignedPublicKey, "test.txt");
|
||||
|
||||
ClearSignedFileProcessor.main(new String[] { "-s", "test.txt", "secret.bpg", "password" });
|
||||
}
|
||||
|
||||
private void checkClearSignedVerify(String message)
|
||||
throws Exception
|
||||
{
|
||||
createTestData(message, "test.txt.asc");
|
||||
|
||||
ClearSignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub.bpg" });
|
||||
}
|
||||
|
||||
private void checkClearSigned(String message)
|
||||
throws Exception
|
||||
{
|
||||
createTestData(message, "test.txt");
|
||||
|
||||
ClearSignedFileProcessor.main(new String[] { "-s", "test.txt", "secret.bpg", "password" });
|
||||
ClearSignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub.bpg" });
|
||||
}
|
||||
|
||||
private void checkSigning(String type)
|
||||
throws Exception
|
||||
{
|
||||
_currentOut.reset();
|
||||
|
||||
SignedFileProcessor.main(new String[] { "-s", "test.txt", "secret." + type, "password" });
|
||||
|
||||
SignedFileProcessor.main(new String[] { "-v", "test.txt.bpg", "pub." + type });
|
||||
|
||||
assertEquals("signature verified.", getLine(_currentOut));
|
||||
|
||||
SignedFileProcessor.main(new String[] { "-s", "-a", "test.txt", "secret." + type, "password" });
|
||||
|
||||
SignedFileProcessor.main(new String[] { "-v", "test.txt.asc", "pub." + type });
|
||||
|
||||
assertEquals("signature verified.", getLine(_currentOut));
|
||||
}
|
||||
|
||||
private void checkKeyBasedEncryption(String type)
|
||||
throws Exception
|
||||
{
|
||||
_currentErr.reset();
|
||||
|
||||
KeyBasedFileProcessor.main(new String[] { "-e", "test.txt", "pub." + type });
|
||||
|
||||
KeyBasedFileProcessor.main(new String[] { "-d", "test.txt.bpg", "secret." + type, "password" });
|
||||
|
||||
assertEquals("no message integrity check", getLine(_currentErr));
|
||||
|
||||
KeyBasedFileProcessor.main(new String[] { "-e", "-i", "test.txt", "pub." + type });
|
||||
|
||||
KeyBasedFileProcessor.main(new String[] { "-d", "test.txt.bpg", "secret." + type, "password" });
|
||||
|
||||
assertEquals("message integrity check passed", getLine(_currentErr));
|
||||
|
||||
KeyBasedFileProcessor.main(new String[] { "-e", "-ai", "test.txt", "pub." + type });
|
||||
|
||||
KeyBasedFileProcessor.main(new String[] { "-d", "test.txt.asc", "secret." + type, "password" });
|
||||
|
||||
assertEquals("message integrity check passed", getLine(_currentErr));
|
||||
}
|
||||
|
||||
private void checkLargeKeyBasedEncryption(String type)
|
||||
throws Exception
|
||||
{
|
||||
_currentErr.reset();
|
||||
|
||||
KeyBasedLargeFileProcessor.main(new String[] { "-e", "large.txt", "pub." + type });
|
||||
|
||||
KeyBasedLargeFileProcessor.main(new String[] { "-d", "large.txt.bpg", "secret." + type, "password" });
|
||||
|
||||
assertEquals("no message integrity check", getLine(_currentErr));
|
||||
|
||||
KeyBasedLargeFileProcessor.main(new String[] { "-e", "-i", "large.txt", "pub." + type });
|
||||
|
||||
KeyBasedLargeFileProcessor.main(new String[] { "-d", "large.txt.bpg", "secret." + type, "password" });
|
||||
|
||||
assertEquals("message integrity check passed", getLine(_currentErr));
|
||||
|
||||
KeyBasedLargeFileProcessor.main(new String[] { "-e", "-ai", "large.txt", "pub." + type });
|
||||
|
||||
KeyBasedLargeFileProcessor.main(new String[] { "-d", "large.txt.asc", "secret." + type, "password" });
|
||||
|
||||
assertEquals("message integrity check passed", getLine(_currentErr));
|
||||
}
|
||||
|
||||
private void createSmallTestInput()
|
||||
throws IOException
|
||||
{
|
||||
BufferedWriter bfOut = new BufferedWriter(new FileWriter("test.txt"));
|
||||
|
||||
bfOut.write("hello world!");
|
||||
bfOut.newLine();
|
||||
|
||||
bfOut.close();
|
||||
}
|
||||
|
||||
private void createLargeTestInput()
|
||||
throws IOException
|
||||
{
|
||||
BufferedWriter bfOut = new BufferedWriter(new FileWriter("large.txt"));
|
||||
|
||||
for (int i = 0; i != 2000; i++)
|
||||
{
|
||||
bfOut.write("hello world!");
|
||||
bfOut.newLine();
|
||||
}
|
||||
|
||||
bfOut.close();
|
||||
}
|
||||
|
||||
private void createTestData(String testData, String name)
|
||||
throws IOException
|
||||
{
|
||||
BufferedWriter bfOut = new BufferedWriter(new FileWriter(name));
|
||||
|
||||
bfOut.write(testData);
|
||||
|
||||
bfOut.close();
|
||||
}
|
||||
|
||||
private void createTestFile(byte[] keyData, String name)
|
||||
throws IOException
|
||||
{
|
||||
FileOutputStream fOut = new FileOutputStream(name);
|
||||
|
||||
fOut.write(keyData);
|
||||
|
||||
fOut.close();
|
||||
}
|
||||
|
||||
private String getLine(
|
||||
ByteArrayOutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
BufferedReader bRd = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(out.toByteArray())));
|
||||
|
||||
out.reset();
|
||||
|
||||
return bRd.readLine();
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite("OpenPGP Example Tests");
|
||||
|
||||
suite.addTestSuite(AllTests.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.util.test.SimpleTestResult;
|
||||
|
||||
public class AllTests
|
||||
extends TestCase
|
||||
{
|
||||
public void testPGP()
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
org.spongycastle.util.test.Test[] tests = RegressionTest.tests;
|
||||
|
||||
for (int i = 0; i != tests.length; i++)
|
||||
{
|
||||
SimpleTestResult result = (SimpleTestResult)tests[i].perform();
|
||||
|
||||
if (!result.isSuccessful())
|
||||
{
|
||||
fail(result.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite("OpenPGP Tests");
|
||||
|
||||
suite.addTestSuite(AllTests.class);
|
||||
suite.addTestSuite(DSA2Test.class);
|
||||
suite.addTestSuite(PGPUnicodeTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameterGenerator;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.crypto.AsymmetricBlockCipher;
|
||||
import org.spongycastle.crypto.encodings.PKCS1Encoding;
|
||||
import org.spongycastle.crypto.engines.ElGamalEngine;
|
||||
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.jce.spec.ElGamalParameterSpec;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPKeyConverter;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class BcPGPDSAElGamalTest
|
||||
extends SimpleTest
|
||||
{
|
||||
|
||||
byte[] testPubKeyRing =
|
||||
Base64.decode(
|
||||
"mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv"
|
||||
+ "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH"
|
||||
+ "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK"
|
||||
+ "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2"
|
||||
+ "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH"
|
||||
+ "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB"
|
||||
+ "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2"
|
||||
+ "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN"
|
||||
+ "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+"
|
||||
+ "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC"
|
||||
+ "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk"
|
||||
+ "JVCXP0/Szm05GB+WN+MOCT2wAgAA");
|
||||
|
||||
byte[] testPrivKeyRing =
|
||||
Base64.decode(
|
||||
"lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r"
|
||||
+ "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF"
|
||||
+ "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn"
|
||||
+ "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn"
|
||||
+ "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r"
|
||||
+ "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj"
|
||||
+ "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya"
|
||||
+ "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF"
|
||||
+ "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq"
|
||||
+ "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk"
|
||||
+ "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs"
|
||||
+ "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs"
|
||||
+ "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA"
|
||||
+ "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg"
|
||||
+ "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA");
|
||||
|
||||
byte[] encMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c"
|
||||
+ "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o"
|
||||
+ "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv"
|
||||
+ "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f"
|
||||
+ "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy"
|
||||
+ "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL"
|
||||
+ "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp"
|
||||
+ "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw==");
|
||||
|
||||
byte[] signedAndEncMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn"
|
||||
+ "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy"
|
||||
+ "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C"
|
||||
+ "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T"
|
||||
+ "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum"
|
||||
+ "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK"
|
||||
+ "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3"
|
||||
+ "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm"
|
||||
+ "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht"
|
||||
+ "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM=");
|
||||
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKey pubKey;
|
||||
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing);
|
||||
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject();
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
if (pubKey.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator());
|
||||
PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
//
|
||||
// signature generation
|
||||
//
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1));
|
||||
|
||||
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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);
|
||||
|
||||
cGen.close();
|
||||
|
||||
//
|
||||
// verify generated signature
|
||||
//
|
||||
pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
|
||||
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();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
InputStream dIn = p2.getInputStream();
|
||||
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey);
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// test encryption
|
||||
//
|
||||
|
||||
//
|
||||
// find a key suitable for encryption
|
||||
//
|
||||
long pgpKeyID = 0;
|
||||
AsymmetricKeyParameter pKey = null;
|
||||
BcPGPKeyConverter keyConverter = new BcPGPKeyConverter();
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT
|
||||
|| pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL)
|
||||
{
|
||||
pKey = keyConverter.getPublicKey(pgpKey);
|
||||
pgpKeyID = pgpKey.getKeyID();
|
||||
if (pgpKey.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
//
|
||||
// verify the key
|
||||
//
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
AsymmetricBlockCipher c = new PKCS1Encoding(new ElGamalEngine());
|
||||
|
||||
c.init(true, pKey);
|
||||
|
||||
byte[] in = "hello world".getBytes();
|
||||
|
||||
byte[] out = c.processBlock(in, 0, in.length);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
c.init(false, keyConverter.getPrivateKey(pgpPrivKey));
|
||||
|
||||
out = c.processBlock(out, 0, out.length);
|
||||
|
||||
if (!areEqual(in, out))
|
||||
{
|
||||
fail("decryption failed.");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypted message
|
||||
//
|
||||
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' };
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(encMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
InputStream inLd = ld.getDataStream();
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
fail("wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// signed and encrypted message
|
||||
//
|
||||
pgpF = new PGPObjectFactory(signedAndEncMessage);
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
|
||||
ops = p1.get(0);
|
||||
|
||||
ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
inLd = ld.getDataStream();
|
||||
|
||||
//
|
||||
// note: we use the DSA public key here.
|
||||
//
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey());
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed signature check");
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
fail("wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypt
|
||||
//
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom()));
|
||||
PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey();
|
||||
|
||||
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK));
|
||||
|
||||
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
bOut.reset();
|
||||
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
out = bOut.toByteArray();
|
||||
|
||||
if (!areEqual(out, text))
|
||||
{
|
||||
fail("wrong plain text in generated packet");
|
||||
}
|
||||
|
||||
//
|
||||
// use of PGPKeyPair
|
||||
//
|
||||
BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
|
||||
BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "SC");
|
||||
|
||||
ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
|
||||
|
||||
kpg.initialize(elParams);
|
||||
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp.getPublic(), kp.getPrivate(), new Date());
|
||||
|
||||
PGPPublicKey k1 = pgpKp.getPublicKey();
|
||||
|
||||
PGPPrivateKey k2 = pgpKp.getPrivateKey();
|
||||
|
||||
|
||||
|
||||
// Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!)
|
||||
SecureRandom random = new SecureRandom();
|
||||
for (int pSize = 257; pSize < 264; ++pSize)
|
||||
{
|
||||
// Generate some parameters of the given size
|
||||
AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "SC");
|
||||
a.init(pSize, new SecureRandom());
|
||||
AlgorithmParameters params = a.generateParameters();
|
||||
|
||||
DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "SC");
|
||||
|
||||
keyGen.initialize(elP);
|
||||
|
||||
|
||||
// Run a short encrypt/decrypt test with random key for the given parameters
|
||||
kp = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair elGamalKeyPair = new PGPKeyPair(
|
||||
PublicKeyAlgorithmTags.ELGAMAL_GENERAL, kp, new Date());
|
||||
|
||||
cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(random));
|
||||
|
||||
puK = elGamalKeyPair.getPublicKey();
|
||||
|
||||
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK));
|
||||
|
||||
cbOut = new ByteArrayOutputStream();
|
||||
|
||||
cOut = cPk.open(cbOut, text.length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = elGamalKeyPair.getPrivateKey();
|
||||
|
||||
// Note: This is where an exception would be expected if the P size causes problems
|
||||
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
ByteArrayOutputStream dec = new ByteArrayOutputStream();
|
||||
|
||||
int b;
|
||||
while ((b = clear.read()) >= 0)
|
||||
{
|
||||
dec.write(b);
|
||||
}
|
||||
|
||||
byte[] decText = dec.toByteArray();
|
||||
|
||||
if (!areEqual(text, decText))
|
||||
{
|
||||
fail("decrypted message incorrect");
|
||||
}
|
||||
}
|
||||
|
||||
// check sub key encoding
|
||||
|
||||
it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (!pgpKey.isMasterKey())
|
||||
{
|
||||
byte[] kEnc = pgpKey.getEncoded();
|
||||
|
||||
PGPObjectFactory objF = new PGPObjectFactory(kEnc);
|
||||
|
||||
PGPPublicKey k = (PGPPublicKey)objF.nextObject();
|
||||
|
||||
pKey = keyConverter.getPublicKey(k);
|
||||
pgpKeyID = k.getKeyID();
|
||||
if (k.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
if (objF.nextObject() != null)
|
||||
{
|
||||
fail("failed - stream not fully parsed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
fail("exception: " + e.getMessage(), e.getUnderlyingException());
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPDSAElGamalTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new BcPGPDSAElGamalTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
|
||||
import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class BcPGPDSATest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
|
||||
+ "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
|
||||
+ "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
|
||||
+ "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
|
||||
+ "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
|
||||
+ "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
|
||||
+ "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
|
||||
+ "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
|
||||
+ "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp"
|
||||
+ "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC"
|
||||
+ "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s"
|
||||
+ "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng==");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
|
||||
+ "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
|
||||
+ "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
|
||||
+ "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
|
||||
+ "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
|
||||
+ "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
|
||||
+ "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
|
||||
+ "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
|
||||
+ "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC"
|
||||
+ "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu"
|
||||
+ "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh"
|
||||
+ "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j"
|
||||
+ "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD"
|
||||
+ "4nXkHg==");
|
||||
|
||||
byte[] testPrivKey2 =
|
||||
Base64.decode(
|
||||
"lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj"
|
||||
+ "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++"
|
||||
+ "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2"
|
||||
+ "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv"
|
||||
+ "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI"
|
||||
+ "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe"
|
||||
+ "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys"
|
||||
+ "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm"
|
||||
+ "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH"
|
||||
+ "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp"
|
||||
+ "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8"
|
||||
+ "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX"
|
||||
+ "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK"
|
||||
+ "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/"
|
||||
+ "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j"
|
||||
+ "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb"
|
||||
+ "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x"
|
||||
+ "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU"
|
||||
+ "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv"
|
||||
+ "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3"
|
||||
+ "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8"
|
||||
+ "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB"
|
||||
+ "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA=");
|
||||
|
||||
byte[] sig1 =
|
||||
Base64.decode(
|
||||
"owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq"
|
||||
+ "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW"
|
||||
+ "GtP/XeDqX4fORDUA");
|
||||
|
||||
byte[] sig1crc = Base64.decode("OZa/");
|
||||
|
||||
byte[] testPubWithUserAttr =
|
||||
Base64.decode(
|
||||
"mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy"
|
||||
+ "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB"
|
||||
+ "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1"
|
||||
+ "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31"
|
||||
+ "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ"
|
||||
+ "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE"
|
||||
+ "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v"
|
||||
+ "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561"
|
||||
+ "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz"
|
||||
+ "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb"
|
||||
+ "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO"
|
||||
+ "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT"
|
||||
+ "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T"
|
||||
+ "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+"
|
||||
+ "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA"
|
||||
+ "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ"
|
||||
+ "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/"
|
||||
+ "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7"
|
||||
+ "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB"
|
||||
+ "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID"
|
||||
+ "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0"
|
||||
+ "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT"
|
||||
+ "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl"
|
||||
+ "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL"
|
||||
+ "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB"
|
||||
+ "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj"
|
||||
+ "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3"
|
||||
+ "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR"
|
||||
+ "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV"
|
||||
+ "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p"
|
||||
+ "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec"
|
||||
+ "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB"
|
||||
+ "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"
|
||||
+ "7DGrzw==");
|
||||
|
||||
byte[] aesSecretKey = Base64.decode(
|
||||
"lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN"
|
||||
+ "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj"
|
||||
+ "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA"
|
||||
+ "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo"
|
||||
+ "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5"
|
||||
+ "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN"
|
||||
+ "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X"
|
||||
+ "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF"
|
||||
+ "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV"
|
||||
+ "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj"
|
||||
+ "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF"
|
||||
+ "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu"
|
||||
+ "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX"
|
||||
+ "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH"
|
||||
+ "zxK1FfdcG2HEDs3YEVawAgAA");
|
||||
|
||||
byte[] aesPublicKey = Base64.decode(
|
||||
"mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN"
|
||||
+ "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj"
|
||||
+ "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA"
|
||||
+ "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo"
|
||||
+ "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5"
|
||||
+ "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN"
|
||||
+ "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X"
|
||||
+ "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF"
|
||||
+ "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV"
|
||||
+ "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt"
|
||||
+ "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0"
|
||||
+ "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua"
|
||||
+ "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA==");
|
||||
|
||||
byte[] twofishSecretKey = Base64.decode(
|
||||
"lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc"
|
||||
+ "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8"
|
||||
+ "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p"
|
||||
+ "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/"
|
||||
+ "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2"
|
||||
+ "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG"
|
||||
+ "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK"
|
||||
+ "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v"
|
||||
+ "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj"
|
||||
+ "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf"
|
||||
+ "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF"
|
||||
+ "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91"
|
||||
+ "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC"
|
||||
+ "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u"
|
||||
+ "A/ynoqnC1O8HNlbjPdlVsAIAAA==");
|
||||
|
||||
byte[] twofishPublicKey = Base64.decode(
|
||||
"mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc"
|
||||
+ "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8"
|
||||
+ "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p"
|
||||
+ "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/"
|
||||
+ "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2"
|
||||
+ "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG"
|
||||
+ "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK"
|
||||
+ "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v"
|
||||
+ "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj"
|
||||
+ "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt"
|
||||
+ "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS"
|
||||
+ "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd"
|
||||
+ "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA=");
|
||||
|
||||
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
/**
|
||||
* Generated signature test
|
||||
*
|
||||
* @param sKey
|
||||
* @param pgpPrivKey
|
||||
*/
|
||||
public void generateTest(
|
||||
PGPSecretKeyRing sKey,
|
||||
PGPPublicKey pgpPubKey,
|
||||
PGPPrivateKey pgpPrivKey)
|
||||
throws Exception
|
||||
{
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1));
|
||||
|
||||
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
||||
|
||||
Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs();
|
||||
String primaryUserID = (String)it.next();
|
||||
|
||||
spGen.setSignerUserID(true, primaryUserID);
|
||||
|
||||
sGen.setHashedSubpackets(spGen.generate());
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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);
|
||||
|
||||
cGen.close();
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
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();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
InputStream dIn = p2.getInputStream();
|
||||
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey);
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
String file = null;
|
||||
KeyFactory fact = KeyFactory.getInstance("DSA", "SC");
|
||||
PGPPublicKey pubKey = null;
|
||||
PrivateKey privKey = null;
|
||||
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator());
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator());
|
||||
PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
//
|
||||
// test signature message
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(sig1);
|
||||
|
||||
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();
|
||||
int ch;
|
||||
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey);
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// signature generation
|
||||
//
|
||||
generateTest(sKey, pubKey, pgpPrivKey);
|
||||
|
||||
//
|
||||
// signature generation - canonical text
|
||||
//
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1));
|
||||
|
||||
sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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.TEXT,
|
||||
"_CONSOLE",
|
||||
data.getBytes().length,
|
||||
testDate);
|
||||
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
lGen.close();
|
||||
|
||||
sGen.generate().encode(bcOut);
|
||||
|
||||
cGen.close();
|
||||
|
||||
//
|
||||
// verify generated signature - canconical text
|
||||
//
|
||||
pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
|
||||
ops = p1.get(0);
|
||||
|
||||
p2 = (PGPLiteralData)pgpFact.nextObject();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
dIn = p2.getInputStream();
|
||||
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey);
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// Read the public key with user attributes
|
||||
//
|
||||
pgpPub = new PGPPublicKeyRing(testPubWithUserAttr, new BcKeyFingerprintCalculator());
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
Iterator it = pubKey.getUserAttributes();
|
||||
int count = 0;
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next();
|
||||
|
||||
Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes);
|
||||
int sigCount = 0;
|
||||
while (sigs.hasNext())
|
||||
{
|
||||
sigs.next();
|
||||
|
||||
sigCount++;
|
||||
}
|
||||
|
||||
if (sigCount != 1)
|
||||
{
|
||||
fail("Failed user attributes signature check");
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
fail("Failed user attributes check");
|
||||
}
|
||||
|
||||
byte[] pgpPubBytes = pgpPub.getEncoded();
|
||||
|
||||
pgpPub = new PGPPublicKeyRing(pgpPubBytes, new BcKeyFingerprintCalculator());
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
it = pubKey.getUserAttributes();
|
||||
count = 0;
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
fail("Failed user attributes reread");
|
||||
}
|
||||
|
||||
//
|
||||
// reading test extra data - key with edge condition for DSA key password.
|
||||
//
|
||||
char [] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
|
||||
sKey = new PGPSecretKeyRing(testPrivKey2, new BcKeyFingerprintCalculator());
|
||||
pgpPrivKey = sKey.getSecretKey().extractPrivateKey(passPhrase, "SC");
|
||||
|
||||
byte[] bytes = pgpPrivKey.getKey().getEncoded();
|
||||
|
||||
//
|
||||
// reading test - aes256 encrypted passphrase.
|
||||
//
|
||||
sKey = new PGPSecretKeyRing(aesSecretKey, new BcKeyFingerprintCalculator());
|
||||
pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
bytes = pgpPrivKey.getKey().getEncoded();
|
||||
|
||||
//
|
||||
// reading test - twofish encrypted passphrase.
|
||||
//
|
||||
sKey = new PGPSecretKeyRing(twofishSecretKey, new BcKeyFingerprintCalculator());
|
||||
pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
bytes = pgpPrivKey.getKey().getEncoded();
|
||||
|
||||
//
|
||||
// use of PGPKeyPair
|
||||
//
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "SC");
|
||||
|
||||
kpg.initialize(512);
|
||||
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.DSA , kp.getPublic(), kp.getPrivate(), new Date());
|
||||
|
||||
PGPPublicKey k1 = pgpKp.getPublicKey();
|
||||
|
||||
PGPPrivateKey k2 = pgpKp.getPrivateKey();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "BcPGPDSATest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new BcPGPDSATest());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,400 @@
|
||||
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.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPBEEncryptedData;
|
||||
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
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(message);
|
||||
PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0);
|
||||
|
||||
InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider()));
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
|
||||
PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(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
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(message);
|
||||
PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0);
|
||||
|
||||
InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider()));
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
|
||||
PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(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
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(testPBEAsym);
|
||||
|
||||
PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpFact.nextObject();
|
||||
|
||||
PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(1);
|
||||
|
||||
InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory("password".toCharArray(), new BcPGPDigestCalculatorProvider()));
|
||||
|
||||
pgpFact = new PGPObjectFactory(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");
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "BcPGPPBETest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new BcPGPPBETest());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,290 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.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("SC") == null)
|
||||
{
|
||||
Security.addProvider(new org.spongycastle.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, "SC");
|
||||
|
||||
sGen.initSign(PGPSignature.BINARY_DOCUMENT, secRing.getSecretKey().extractPrivateKey("test".toCharArray(), "SC"));
|
||||
|
||||
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(), "SC");
|
||||
|
||||
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(), "SC");
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
|
||||
public class PGPArmoredTest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] sample = Base64.decode(
|
||||
"mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
|
||||
+ "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
|
||||
+ "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf"
|
||||
+ "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ"
|
||||
+ "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G"
|
||||
+ "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ"
|
||||
+ "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG"
|
||||
+ "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP"
|
||||
+ "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif"
|
||||
+ "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh"
|
||||
+ "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB"
|
||||
+ "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p"
|
||||
+ "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5"
|
||||
+ "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN"
|
||||
+ "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE"
|
||||
+ "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1"
|
||||
+ "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu"
|
||||
+ "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y"
|
||||
+ "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB"
|
||||
+ "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u"
|
||||
+ "ZJhfg0htdgAfIy8ppm05vLACAAA=");
|
||||
|
||||
byte[] marker = Hex.decode("2d2d2d2d2d454e4420504750205055424c4943204b455920424c4f434b2d2d2d2d2d");
|
||||
|
||||
// Contains "Hello World!" as an armored message
|
||||
// The 'blank line' after the headers contains (legal) whitespace - see RFC2440 6.2
|
||||
private static final String blankLineData =
|
||||
"-----BEGIN PGP MESSAGE-----\n"
|
||||
+ "Version: BCPG v1.32\n"
|
||||
+ "Comment: A dummy message\n"
|
||||
+ " \t \t\n"
|
||||
+ "SGVsbG8gV29ybGQh\n"
|
||||
+ "=d9Xi\n"
|
||||
+ "-----END PGP MESSAGE-----\n";
|
||||
|
||||
private int markerCount(
|
||||
byte[] data)
|
||||
{
|
||||
int ind = 0;
|
||||
int matches = 0;
|
||||
|
||||
while (ind < data.length)
|
||||
{
|
||||
if (data[ind] == 0x2d)
|
||||
{
|
||||
int count = 0;
|
||||
while (count < marker.length)
|
||||
{
|
||||
if (data[ind + count] != marker[count])
|
||||
{
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == marker.length)
|
||||
{
|
||||
matches++;
|
||||
}
|
||||
|
||||
ind += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
ind++;
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
private void blankLineTest() throws Exception
|
||||
{
|
||||
byte[] blankLineBytes = Strings.toByteArray(blankLineData);
|
||||
ByteArrayInputStream bIn = new ByteArrayInputStream(blankLineBytes);
|
||||
ArmoredInputStream aIn = new ArmoredInputStream(bIn, true);
|
||||
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
int c;
|
||||
while ((c = aIn.read()) >= 0)
|
||||
{
|
||||
bOut.write(c);
|
||||
}
|
||||
|
||||
byte[] expected = Strings.toByteArray("Hello World!");
|
||||
|
||||
if (!Arrays.areEqual(expected, bOut.toByteArray()))
|
||||
{
|
||||
fail("Incorrect message retrieved in blank line test.");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
//
|
||||
// test immediate close
|
||||
//
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ArmoredOutputStream aOut = new ArmoredOutputStream(bOut);
|
||||
|
||||
aOut.close();
|
||||
|
||||
byte[] data = bOut.toByteArray();
|
||||
|
||||
if (data.length != 0)
|
||||
{
|
||||
fail("No data should have been written");
|
||||
}
|
||||
|
||||
//
|
||||
// multiple close
|
||||
//
|
||||
bOut = new ByteArrayOutputStream();
|
||||
aOut = new ArmoredOutputStream(bOut);
|
||||
|
||||
aOut.write(sample);
|
||||
|
||||
aOut.close();
|
||||
|
||||
aOut.close();
|
||||
|
||||
int mc = markerCount(bOut.toByteArray());
|
||||
|
||||
if (mc < 1)
|
||||
{
|
||||
fail("No end marker found");
|
||||
}
|
||||
|
||||
if (mc > 1)
|
||||
{
|
||||
fail("More than one end marker found");
|
||||
}
|
||||
|
||||
//
|
||||
// writing and reading single objects
|
||||
//
|
||||
bOut = new ByteArrayOutputStream();
|
||||
aOut = new ArmoredOutputStream(bOut);
|
||||
|
||||
aOut.write(sample);
|
||||
|
||||
aOut.close();
|
||||
|
||||
ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(bOut.toByteArray()));
|
||||
|
||||
PGPObjectFactory fact = new PGPObjectFactory(aIn);
|
||||
int count = 0;
|
||||
|
||||
while (fact.nextObject() != null)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
fail("wrong number of objects found: " + count);
|
||||
}
|
||||
|
||||
//
|
||||
// writing and reading multiple objects - in single block
|
||||
//
|
||||
bOut = new ByteArrayOutputStream();
|
||||
aOut = new ArmoredOutputStream(bOut);
|
||||
|
||||
aOut.write(sample);
|
||||
aOut.write(sample);
|
||||
|
||||
aOut.close();
|
||||
|
||||
aIn = new ArmoredInputStream(new ByteArrayInputStream(bOut.toByteArray()));
|
||||
|
||||
fact = new PGPObjectFactory(aIn);
|
||||
count = 0;
|
||||
|
||||
while (fact.nextObject() != null)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 2)
|
||||
{
|
||||
fail("wrong number of objects found: " + count);
|
||||
}
|
||||
|
||||
//
|
||||
// writing and reading multiple objects - in single block
|
||||
//
|
||||
bOut = new ByteArrayOutputStream();
|
||||
aOut = new ArmoredOutputStream(bOut);
|
||||
|
||||
aOut.write(sample);
|
||||
|
||||
aOut.close(); // does not close underlying stream
|
||||
|
||||
aOut = new ArmoredOutputStream(bOut);
|
||||
|
||||
aOut.write(sample);
|
||||
|
||||
aOut.close();
|
||||
|
||||
aIn = new ArmoredInputStream(new ByteArrayInputStream(bOut.toByteArray()));
|
||||
|
||||
count = 0;
|
||||
boolean atLeastOne;
|
||||
do
|
||||
{
|
||||
atLeastOne = false;
|
||||
fact = new PGPObjectFactory(aIn);
|
||||
|
||||
while (fact.nextObject() != null)
|
||||
{
|
||||
atLeastOne = true;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
while (atLeastOne);
|
||||
|
||||
if (count != 2)
|
||||
{
|
||||
fail("wrong number of objects found: " + count);
|
||||
}
|
||||
|
||||
blankLineTest();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPArmoredTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
runTest(new PGPArmoredTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRingCollection;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class PGPClearSignedSignatureTest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] publicKey = Base64.decode(
|
||||
"mQELBEQh2+wBCAD26kte0hO6flr7Y2aetpPYutHY4qsmDPy+GwmmqVeCDkX+"
|
||||
+ "r1g7DuFbMhVeu0NkKDnVl7GsJ9VarYsFYyqu0NzLa9XS2qlTIkmJV+2/xKa1"
|
||||
+ "tzjn18fT/cnAWL88ZLCOWUr241aPVhLuIc6vpHnySpEMkCh4rvMaimnTrKwO"
|
||||
+ "42kgeDGd5cXfs4J4ovRcTbc4hmU2BRVsRjiYMZWWx0kkyL2zDVyaJSs4yVX7"
|
||||
+ "Jm4/LSR1uC/wDT0IJJuZT/gQPCMJNMEsVCziRgYkAxQK3OWojPSuv4rXpyd4"
|
||||
+ "Gvo6IbvyTgIskfpSkCnQtORNLIudQSuK7pW+LkL62N+ohuKdMvdxauOnAAYp"
|
||||
+ "tBNnZ2dnZ2dnZyA8Z2dnQGdnZ2c+iQE2BBMBAgAgBQJEIdvsAhsDBgsJCAcD"
|
||||
+ "AgQVAggDBBYCAwECHgECF4AACgkQ4M/Ier3f9xagdAf/fbKWBjLQM8xR7JkR"
|
||||
+ "P4ri8YKOQPhK+VrddGUD59/wzVnvaGyl9MZE7TXFUeniQq5iXKnm22EQbYch"
|
||||
+ "v2Jcxyt2H9yptpzyh4tP6tEHl1C887p2J4qe7F2ATua9CzVGwXQSUbKtj2fg"
|
||||
+ "UZP5SsNp25guhPiZdtkf2sHMeiotmykFErzqGMrvOAUThrO63GiYsRk4hF6r"
|
||||
+ "cQ01d+EUVpY/sBcCxgNyOiB7a84sDtrxnX5BTEZDTEj8LvuEyEV3TMUuAjx1"
|
||||
+ "7Eyd+9JtKzwV4v3hlTaWOvGro9nPS7YaPuG+RtufzXCUJPbPfTjTvtGOqvEz"
|
||||
+ "oztls8tuWA0OGHba9XfX9rfgorACAAM=");
|
||||
|
||||
byte[] secretKey = Base64.decode(
|
||||
"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");
|
||||
|
||||
String crOnlyMessage =
|
||||
"\r"
|
||||
+ " hello world!\r"
|
||||
+ "\r"
|
||||
+ "- dash\r";
|
||||
|
||||
String nlOnlyMessage =
|
||||
"\n"
|
||||
+ " hello world!\n"
|
||||
+ "\n"
|
||||
+ "- dash\n";
|
||||
|
||||
String crNlMessage =
|
||||
"\r\n"
|
||||
+ " hello world!\r\n"
|
||||
+ "\r\n"
|
||||
+ "- dash\r\n";
|
||||
|
||||
String crOnlySignedMessage =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\r"
|
||||
+ "Hash: SHA256\r"
|
||||
+ "\r"
|
||||
+ "\r"
|
||||
+ " hello world!\r"
|
||||
+ "\r"
|
||||
+ "- - dash\r"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\r"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r"
|
||||
+ "\r"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r"
|
||||
+ "=84Nd\r"
|
||||
+ "-----END PGP SIGNATURE-----\r";
|
||||
|
||||
|
||||
String nlOnlySignedMessage =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\n"
|
||||
+ "Hash: SHA256\n"
|
||||
+ "\n"
|
||||
+ "\n"
|
||||
+ " hello world!\n"
|
||||
+ "\n"
|
||||
+ "- - dash\n"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\n"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\n"
|
||||
+ "\n"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\n"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\n"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\n"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\n"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\n"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\n"
|
||||
+ "=84Nd\n"
|
||||
+ "-----END PGP SIGNATURE-----\n";
|
||||
|
||||
String crNlSignedMessage =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
|
||||
+ "Hash: SHA256\r\n"
|
||||
+ "\r\n"
|
||||
+ "\r\n"
|
||||
+ " hello world!\r\n"
|
||||
+ "\r\n"
|
||||
+ "- - dash\r\n"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\r\n"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
|
||||
+ "\r\n"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
|
||||
+ "=84Nd\r"
|
||||
+ "-----END PGP SIGNATURE-----\r\n";
|
||||
|
||||
String crNlSignedMessageTrailingWhiteSpace =
|
||||
"-----BEGIN PGP SIGNED MESSAGE-----\r\n"
|
||||
+ "Hash: SHA256\r\n"
|
||||
+ "\r\n"
|
||||
+ "\r\n"
|
||||
+ " hello world! \t\r\n"
|
||||
+ "\r\n"
|
||||
+ "- - dash\r\n"
|
||||
+ "-----BEGIN PGP SIGNATURE-----\r\n"
|
||||
+ "Version: GnuPG v1.4.2.1 (GNU/Linux)\r\n"
|
||||
+ "\r\n"
|
||||
+ "iQEVAwUBRCNS8+DPyHq93/cWAQi6SwgAj3ItmSLr/sd/ixAQLW7/12jzEjfNmFDt\r\n"
|
||||
+ "WOZpJFmXj0fnMzTrOILVnbxHv2Ru+U8Y1K6nhzFSR7d28n31/XGgFtdohDEaFJpx\r\n"
|
||||
+ "Fl+KvASKIonnpEDjFJsPIvT1/G/eCPalwO9IuxaIthmKj0z44SO1VQtmNKxdLAfK\r\n"
|
||||
+ "+xTnXGawXS1WUE4CQGPM45mIGSqXcYrLtJkAg3jtRa8YRUn2d7b2BtmWH+jVaVuC\r\n"
|
||||
+ "hNrXYv7iHFOu25yRWhUQJisvdC13D/gKIPRvARXPgPhAC2kovIy6VS8tDoyG6Hm5\r\n"
|
||||
+ "dMgLEGhmqsgaetVq1ZIuBZj5S4j2apBJCDpF6GBfpBOfwIZs0Tpmlw==\r\n"
|
||||
+ "=84Nd\r"
|
||||
+ "-----END PGP SIGNATURE-----\r\n";
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPClearSignedSignature";
|
||||
}
|
||||
|
||||
private void messageTest(
|
||||
String message,
|
||||
String type)
|
||||
throws Exception
|
||||
{
|
||||
ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes()));
|
||||
|
||||
String[] headers = aIn.getArmorHeaders();
|
||||
|
||||
if (headers == null || headers.length != 1)
|
||||
{
|
||||
fail("wrong number of headers found");
|
||||
}
|
||||
|
||||
if (!"Hash: SHA256".equals(headers[0]))
|
||||
{
|
||||
fail("header value wrong: " + headers[0]);
|
||||
}
|
||||
|
||||
//
|
||||
// read the input, making sure we ingore the last newline.
|
||||
//
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
int ch;
|
||||
|
||||
while ((ch = aIn.read()) >= 0 && aIn.isClearText())
|
||||
{
|
||||
bOut.write((byte)ch);
|
||||
}
|
||||
|
||||
PGPPublicKeyRingCollection pgpRings = new PGPPublicKeyRingCollection(publicKey);
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(aIn);
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
PGPSignature sig = p3.get(0);
|
||||
|
||||
sig.initVerify(pgpRings.getPublicKey(sig.getKeyID()), "SC");
|
||||
|
||||
ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
|
||||
InputStream sigIn = new ByteArrayInputStream(bOut.toByteArray());
|
||||
int lookAhead = readInputLine(lineOut, sigIn);
|
||||
|
||||
processLine(sig, lineOut.toByteArray());
|
||||
|
||||
if (lookAhead != -1)
|
||||
{
|
||||
do
|
||||
{
|
||||
lookAhead = readInputLine(lineOut, lookAhead, sigIn);
|
||||
|
||||
sig.update((byte)'\r');
|
||||
sig.update((byte)'\n');
|
||||
|
||||
processLine(sig, lineOut.toByteArray());
|
||||
}
|
||||
while (lookAhead != -1);
|
||||
}
|
||||
|
||||
if (!sig.verify())
|
||||
{
|
||||
fail("signature failed to verify in " + type);
|
||||
}
|
||||
}
|
||||
|
||||
private PGPSecretKey readSecretKey(
|
||||
InputStream in)
|
||||
throws IOException, PGPException
|
||||
{
|
||||
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in);
|
||||
|
||||
PGPSecretKey key = null;
|
||||
|
||||
//
|
||||
// iterate through the key rings.
|
||||
//
|
||||
Iterator rIt = pgpSec.getKeyRings();
|
||||
|
||||
while (key == null && rIt.hasNext())
|
||||
{
|
||||
PGPSecretKeyRing kRing = (PGPSecretKeyRing)rIt.next();
|
||||
Iterator kIt = kRing.getSecretKeys();
|
||||
|
||||
while (key == null && kIt.hasNext())
|
||||
{
|
||||
PGPSecretKey k = (PGPSecretKey)kIt.next();
|
||||
|
||||
if (k.isSigningKey())
|
||||
{
|
||||
key = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Can't find signing key in key ring.");
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
private void generateTest(
|
||||
String message,
|
||||
String type)
|
||||
throws Exception
|
||||
{
|
||||
PGPSecretKey pgpSecKey = readSecretKey(new ByteArrayInputStream(secretKey));
|
||||
PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey("".toCharArray(), "SC");
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSecKey.getPublicKey().getAlgorithm(), PGPUtil.SHA256, "SC");
|
||||
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
||||
|
||||
sGen.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey);
|
||||
|
||||
Iterator it = pgpSecKey.getPublicKey().getUserIDs();
|
||||
if (it.hasNext())
|
||||
{
|
||||
spGen.setSignerUserID(false, (String)it.next());
|
||||
sGen.setHashedSubpackets(spGen.generate());
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ArmoredOutputStream aOut = new ArmoredOutputStream(bOut);
|
||||
ByteArrayInputStream bIn = new ByteArrayInputStream(message.getBytes());
|
||||
|
||||
aOut.beginClearText(PGPUtil.SHA256);
|
||||
|
||||
//
|
||||
// note the last \n in the file is ignored
|
||||
//
|
||||
ByteArrayOutputStream lineOut = new ByteArrayOutputStream();
|
||||
int lookAhead = readInputLine(lineOut, bIn);
|
||||
|
||||
processLine(aOut, sGen, lineOut.toByteArray());
|
||||
|
||||
if (lookAhead != -1)
|
||||
{
|
||||
do
|
||||
{
|
||||
lookAhead = readInputLine(lineOut, lookAhead, bIn);
|
||||
|
||||
sGen.update((byte)'\r');
|
||||
sGen.update((byte)'\n');
|
||||
|
||||
processLine(aOut, sGen, lineOut.toByteArray());
|
||||
}
|
||||
while (lookAhead != -1);
|
||||
}
|
||||
|
||||
aOut.endClearText();
|
||||
|
||||
BCPGOutputStream bcpgOut = new BCPGOutputStream(aOut);
|
||||
|
||||
sGen.generate().encode(bcpgOut);
|
||||
|
||||
aOut.close();
|
||||
|
||||
messageTest(new String(bOut.toByteArray()), type);
|
||||
}
|
||||
|
||||
private static int readInputLine(ByteArrayOutputStream bOut, InputStream fIn)
|
||||
throws IOException
|
||||
{
|
||||
bOut.reset();
|
||||
|
||||
int lookAhead = -1;
|
||||
int ch;
|
||||
|
||||
while ((ch = fIn.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
if (ch == '\r' || ch == '\n')
|
||||
{
|
||||
lookAhead = readPassedEOL(bOut, ch, fIn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lookAhead;
|
||||
}
|
||||
|
||||
private static int readInputLine(ByteArrayOutputStream bOut, int lookAhead, InputStream fIn)
|
||||
throws IOException
|
||||
{
|
||||
bOut.reset();
|
||||
|
||||
int ch = lookAhead;
|
||||
|
||||
do
|
||||
{
|
||||
bOut.write(ch);
|
||||
if (ch == '\r' || ch == '\n')
|
||||
{
|
||||
lookAhead = readPassedEOL(bOut, ch, fIn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((ch = fIn.read()) >= 0);
|
||||
|
||||
return lookAhead;
|
||||
}
|
||||
|
||||
private static int readPassedEOL(ByteArrayOutputStream bOut, int lastCh, InputStream fIn)
|
||||
throws IOException
|
||||
{
|
||||
int lookAhead = fIn.read();
|
||||
|
||||
if (lastCh == '\r' && lookAhead == '\n')
|
||||
{
|
||||
bOut.write(lookAhead);
|
||||
lookAhead = fIn.read();
|
||||
}
|
||||
|
||||
return lookAhead;
|
||||
}
|
||||
|
||||
private static void processLine(PGPSignature sig, byte[] line)
|
||||
throws SignatureException, IOException
|
||||
{
|
||||
int length = getLengthWithoutWhiteSpace(line);
|
||||
if (length > 0)
|
||||
{
|
||||
sig.update(line, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
private static void processLine(OutputStream aOut, PGPSignatureGenerator sGen, byte[] line)
|
||||
throws SignatureException, IOException
|
||||
{
|
||||
int length = getLengthWithoutWhiteSpace(line);
|
||||
if (length > 0)
|
||||
{
|
||||
sGen.update(line, 0, length);
|
||||
}
|
||||
|
||||
aOut.write(line, 0, line.length);
|
||||
}
|
||||
|
||||
private static int getLengthWithoutWhiteSpace(byte[] line)
|
||||
{
|
||||
int end = line.length - 1;
|
||||
|
||||
while (end >= 0 && isWhiteSpace(line[end]))
|
||||
{
|
||||
end--;
|
||||
}
|
||||
|
||||
return end + 1;
|
||||
}
|
||||
|
||||
private static boolean isWhiteSpace(byte b)
|
||||
{
|
||||
return b == '\r' || b == '\n' || b == '\t' || b == ' ';
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
messageTest(crOnlySignedMessage, "\\r");
|
||||
messageTest(nlOnlySignedMessage, "\\n");
|
||||
messageTest(crNlSignedMessage, "\\r\\n");
|
||||
messageTest(crNlSignedMessageTrailingWhiteSpace, "\\r\\n");
|
||||
|
||||
generateTest(nlOnlyMessage, "\\r");
|
||||
generateTest(crOnlyMessage, "\\n");
|
||||
generateTest(crNlMessage, "\\r\\n");
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
runTest(new PGPClearSignedSignatureTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.Security;
|
||||
|
||||
public class PGPCompressionTest
|
||||
extends SimpleTest
|
||||
{
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
testCompression(PGPCompressedData.UNCOMPRESSED);
|
||||
testCompression(PGPCompressedData.ZIP);
|
||||
testCompression(PGPCompressedData.ZLIB);
|
||||
testCompression(PGPCompressedData.BZIP2);
|
||||
|
||||
//
|
||||
// new style - using stream close
|
||||
//
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
PGPCompressedDataGenerator cPacket = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
OutputStream out = cPacket.open(new UncloseableOutputStream(bOut), new byte[4]);
|
||||
|
||||
out.write("hello world! !dlrow olleh".getBytes());
|
||||
|
||||
out.close();
|
||||
|
||||
validateData(bOut.toByteArray());
|
||||
|
||||
try
|
||||
{
|
||||
out.close();
|
||||
cPacket.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail("Redundant close() should be ignored");
|
||||
}
|
||||
|
||||
//
|
||||
// new style - using generator close
|
||||
//
|
||||
bOut = new ByteArrayOutputStream();
|
||||
cPacket = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
out = cPacket.open(new UncloseableOutputStream(bOut), new byte[4]);
|
||||
|
||||
out.write("hello world! !dlrow olleh".getBytes());
|
||||
|
||||
cPacket.close();
|
||||
|
||||
validateData(bOut.toByteArray());
|
||||
|
||||
try
|
||||
{
|
||||
out.close();
|
||||
cPacket.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
fail("Redundant close() should be ignored");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateData(byte[] data)
|
||||
throws IOException, PGPException
|
||||
{
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(data);
|
||||
PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
InputStream pIn = c1.getDataStream();
|
||||
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
int ch;
|
||||
while ((ch = pIn.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), "hello world! !dlrow olleh".getBytes()))
|
||||
{
|
||||
fail("compression test failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void testCompression(
|
||||
int type)
|
||||
throws IOException, PGPException
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
PGPCompressedDataGenerator cPacket = new PGPCompressedDataGenerator(type);
|
||||
|
||||
OutputStream out = cPacket.open(new UncloseableOutputStream(bOut));
|
||||
|
||||
out.write("hello world!".getBytes());
|
||||
|
||||
out.close();
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
InputStream pIn = c1.getDataStream();
|
||||
|
||||
bOut.reset();
|
||||
|
||||
int ch;
|
||||
while ((ch = pIn.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), "hello world!".getBytes()))
|
||||
{
|
||||
fail("compression test failed");
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPCompressionTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPCompressionTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameterGenerator;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.jce.spec.ElGamalParameterSpec;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class PGPDSAElGamalTest
|
||||
extends SimpleTest
|
||||
{
|
||||
|
||||
byte[] testPubKeyRing =
|
||||
Base64.decode(
|
||||
"mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv"
|
||||
+ "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH"
|
||||
+ "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK"
|
||||
+ "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2"
|
||||
+ "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH"
|
||||
+ "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB"
|
||||
+ "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2"
|
||||
+ "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN"
|
||||
+ "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+"
|
||||
+ "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC"
|
||||
+ "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk"
|
||||
+ "JVCXP0/Szm05GB+WN+MOCT2wAgAA");
|
||||
|
||||
byte[] testPrivKeyRing =
|
||||
Base64.decode(
|
||||
"lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r"
|
||||
+ "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF"
|
||||
+ "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn"
|
||||
+ "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn"
|
||||
+ "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r"
|
||||
+ "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj"
|
||||
+ "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya"
|
||||
+ "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF"
|
||||
+ "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq"
|
||||
+ "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk"
|
||||
+ "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs"
|
||||
+ "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs"
|
||||
+ "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA"
|
||||
+ "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg"
|
||||
+ "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA");
|
||||
|
||||
byte[] encMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c"
|
||||
+ "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o"
|
||||
+ "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv"
|
||||
+ "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f"
|
||||
+ "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy"
|
||||
+ "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL"
|
||||
+ "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp"
|
||||
+ "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw==");
|
||||
|
||||
byte[] signedAndEncMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn"
|
||||
+ "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy"
|
||||
+ "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C"
|
||||
+ "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T"
|
||||
+ "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum"
|
||||
+ "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK"
|
||||
+ "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3"
|
||||
+ "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm"
|
||||
+ "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht"
|
||||
+ "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM=");
|
||||
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKey pubKey = null;
|
||||
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing);
|
||||
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject();
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
if (pubKey.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing);
|
||||
PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "SC");
|
||||
|
||||
//
|
||||
// signature generation
|
||||
//
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "SC");
|
||||
|
||||
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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);
|
||||
|
||||
cGen.close();
|
||||
|
||||
//
|
||||
// verify generated signature
|
||||
//
|
||||
pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
|
||||
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();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
InputStream dIn = p2.getInputStream();
|
||||
|
||||
ops.initVerify(pubKey, "SC");
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// test encryption
|
||||
//
|
||||
|
||||
//
|
||||
// find a key suitable for encryption
|
||||
//
|
||||
long pgpKeyID = 0;
|
||||
PublicKey pKey = null;
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT
|
||||
|| pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL)
|
||||
{
|
||||
pKey = pgpKey.getKey("SC");
|
||||
pgpKeyID = pgpKey.getKeyID();
|
||||
if (pgpKey.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
//
|
||||
// verify the key
|
||||
//
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Cipher c = Cipher.getInstance("ElGamal/None/PKCS1Padding", "SC");
|
||||
|
||||
c.init(Cipher.ENCRYPT_MODE, pKey);
|
||||
|
||||
byte[] in = "hello world".getBytes();
|
||||
|
||||
byte[] out = c.doFinal(in);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "SC");
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey());
|
||||
|
||||
out = c.doFinal(out);
|
||||
|
||||
if (!areEqual(in, out))
|
||||
{
|
||||
fail("decryption failed.");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypted message
|
||||
//
|
||||
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' };
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(encMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
InputStream inLd = ld.getDataStream();
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
fail("wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// signed and encrypted message
|
||||
//
|
||||
pgpF = new PGPObjectFactory(signedAndEncMessage);
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
|
||||
ops = p1.get(0);
|
||||
|
||||
ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
inLd = ld.getDataStream();
|
||||
|
||||
//
|
||||
// note: we use the DSA public key here.
|
||||
//
|
||||
ops.initVerify(pgpPub.getPublicKey(), "SC");
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed signature check");
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
fail("wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypt
|
||||
//
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.TRIPLE_DES, new SecureRandom(), "SC");
|
||||
PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey();
|
||||
|
||||
cPk.addMethod(puK);
|
||||
|
||||
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "SC");
|
||||
|
||||
clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
bOut.reset();
|
||||
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
out = bOut.toByteArray();
|
||||
|
||||
if (!areEqual(out, text))
|
||||
{
|
||||
fail("wrong plain text in generated packet");
|
||||
}
|
||||
|
||||
//
|
||||
// use of PGPKeyPair
|
||||
//
|
||||
BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
|
||||
BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "SC");
|
||||
|
||||
ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
|
||||
|
||||
kpg.initialize(elParams);
|
||||
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp.getPublic(), kp.getPrivate(), new Date());
|
||||
|
||||
PGPPublicKey k1 = pgpKp.getPublicKey();
|
||||
|
||||
PGPPrivateKey k2 = pgpKp.getPrivateKey();
|
||||
|
||||
|
||||
|
||||
// Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!)
|
||||
SecureRandom random = new SecureRandom();
|
||||
for (int pSize = 257; pSize < 264; ++pSize)
|
||||
{
|
||||
// Generate some parameters of the given size
|
||||
AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "SC");
|
||||
a.init(pSize, new SecureRandom());
|
||||
AlgorithmParameters params = a.generateParameters();
|
||||
|
||||
DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "SC");
|
||||
|
||||
keyGen.initialize(elP);
|
||||
|
||||
|
||||
// Run a short encrypt/decrypt test with random key for the given parameters
|
||||
kp = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair elGamalKeyPair = new PGPKeyPair(
|
||||
PublicKeyAlgorithmTags.ELGAMAL_GENERAL, kp, new Date());
|
||||
|
||||
cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.CAST5, random, "SC");
|
||||
|
||||
puK = elGamalKeyPair.getPublicKey();
|
||||
|
||||
cPk.addMethod(puK);
|
||||
|
||||
cbOut = new ByteArrayOutputStream();
|
||||
|
||||
cOut = cPk.open(cbOut, text.length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = elGamalKeyPair.getPrivateKey();
|
||||
|
||||
// Note: This is where an exception would be expected if the P size causes problems
|
||||
clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
ByteArrayOutputStream dec = new ByteArrayOutputStream();
|
||||
|
||||
int b;
|
||||
while ((b = clear.read()) >= 0)
|
||||
{
|
||||
dec.write(b);
|
||||
}
|
||||
|
||||
byte[] decText = dec.toByteArray();
|
||||
|
||||
if (!areEqual(text, decText))
|
||||
{
|
||||
fail("decrypted message incorrect");
|
||||
}
|
||||
}
|
||||
|
||||
// check sub key encoding
|
||||
|
||||
it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (!pgpKey.isMasterKey())
|
||||
{
|
||||
byte[] kEnc = pgpKey.getEncoded();
|
||||
|
||||
PGPObjectFactory objF = new PGPObjectFactory(kEnc);
|
||||
|
||||
PGPPublicKey k = (PGPPublicKey)objF.nextObject();
|
||||
|
||||
pKey = k.getKey("SC");
|
||||
pgpKeyID = k.getKeyID();
|
||||
if (k.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
if (objF.nextObject() != null)
|
||||
{
|
||||
fail("failed - stream not fully parsed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
fail("exception: " + e.getMessage(), e.getUnderlyingException());
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPDSAElGamalTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPDSAElGamalTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,628 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
|
||||
import org.spongycastle.openpgp.PGPUserAttributeSubpacketVector;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class PGPDSATest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mQGiBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
|
||||
+ "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
|
||||
+ "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
|
||||
+ "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
|
||||
+ "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
|
||||
+ "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
|
||||
+ "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
|
||||
+ "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
|
||||
+ "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbLQzRXJpYyBFY2hp"
|
||||
+ "ZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExEC"
|
||||
+ "ABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j9enEyjRDAlwAn2rrom0s"
|
||||
+ "MhufWK5vIRwg7gj5qsLEAJ4vnT5dPBVblofsG+pDoCVeJXGGng==");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
|
||||
+ "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
|
||||
+ "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
|
||||
+ "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
|
||||
+ "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
|
||||
+ "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
|
||||
+ "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
|
||||
+ "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
|
||||
+ "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC"
|
||||
+ "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu"
|
||||
+ "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh"
|
||||
+ "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j"
|
||||
+ "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD"
|
||||
+ "4nXkHg==");
|
||||
|
||||
byte[] testPrivKey2 =
|
||||
Base64.decode(
|
||||
"lQHhBEAnoewRBADRvKgDhbV6pMzqYfUgBsLxSHzmycpuxGbjMrpyKHDOEemj"
|
||||
+ "iQb6TyyBKUoR28/pfshFP9R5urtKIT7wjVrDuOkxYkgRhNm+xmPXW2Lw3D++"
|
||||
+ "MQrC5VWe8ywBltz6T9msmChsaKo2hDhIiRI/mg9Q6rH9pJKtVGi4R7CgGxM2"
|
||||
+ "STQ5fwCgub38qGS1W2O4hUsa+3gva5gaNZUEAItegda4/H4t88XdWxW3D8pv"
|
||||
+ "RnFz26/ADdImVaQlBoumD15VmcgYoT1Djizey7X8vfV+pntudESzLbn3GHlI"
|
||||
+ "6C09seH4e8eYP63t7KU/qbUCDomlSswd1OgQ/RxfN86q765K2t3K1i3wDSxe"
|
||||
+ "EgSRyGKee0VNvOBFOFhuWt+patXaBADE1riNkUxg2P4lBNWwu8tEZRmsl/Ys"
|
||||
+ "DBIzXBshoMzZCvS5PnNXMW4G3SAaC9OC9jvKSx9IEWhKjfjs3QcWzXR28mcm"
|
||||
+ "5na0bTxeOMlaPPhBdkTCmFl0IITWlH/pFlR2ah9WYoWYhZEL2tqB82wByzxH"
|
||||
+ "SkSeD9V5oeSCdCcqiqkEmv4DAwLeNsQ2XGJVRmA4lld+CR5vRxpT/+/2xklp"
|
||||
+ "lxVf/nx0+thrHDpro3u/nINIIObk0gh59+zaEEe3APlHqbQVYWFhIGJiYiA8"
|
||||
+ "Y2NjQGRkZC5lZWU+iFoEExECABoFAkAnoewFCwcDAgEDFQIDAxYCAQIeAQIX"
|
||||
+ "gAAKCRA5nBpCS63az85BAKCbPfU8ATrFvkXhzGNGlc1BJo6DWQCgnK125xVK"
|
||||
+ "lWLpt6ZJJ7TXcx3nkm6wAgAAnQFXBEAnoe0QBACsQxPvaeBcv2TkbgU/5Wc/"
|
||||
+ "tO222dPE1mxFbXjGTKfb+6ge96iyD8kTRLrKCkEEeVBa8AZqMSoXUVN6tV8j"
|
||||
+ "/zD8Bc76o5iJ6wgpg3Mmy2GxInVfsfZN6/G3Y2ukmouz+CDNvQdUw8cTguIb"
|
||||
+ "QoV3XhQ03MLbfVmNcHsku9F4CuKNWwADBQP0DSSe8v5PXF9CSCXOIxBDcQ5x"
|
||||
+ "RKjyYOveqoH/4lbOV0YNUbIDZq4RaUdotpADuPREFmWf0zTB6KV/WIiag8XU"
|
||||
+ "WU9zdDvLKR483Bo6Do5pDBcN+NqfQ+ntGY9WJ7BSFnhQ3+07i1K+NsfFTRfv"
|
||||
+ "hf9X3MP75rCf7MxAIWHTabEmUf4DAwLeNsQ2XGJVRmA8DssBUCghogG9n8T3"
|
||||
+ "qfBeKsplGyCcF+JjPeQXkKQaoYGJ0aJz36qFP9d8DuWtT9soQcqIxVf6mTa8"
|
||||
+ "kN1594hGBBgRAgAGBQJAJ6HtAAoJEDmcGkJLrdrPpMkAnRyjQSKugz0YJqOB"
|
||||
+ "yGasMLQLxd2OAKCEIlhtCarlufVQNGZsuWxHVbU8crACAAA=");
|
||||
|
||||
byte[] sig1 =
|
||||
Base64.decode(
|
||||
"owGbwMvMwCR4VvnryyOnTJwZ10gncZSkFpfolVSU2Ltz78hIzcnJVyjPL8pJUeTq"
|
||||
+ "sGdmZQCJwpQLMq3ayTA/0Fj3xf4jbwPfK/H3zj55Z9L1n2k/GOapKJrvMZ4tLiCW"
|
||||
+ "GtP/XeDqX4fORDUA");
|
||||
|
||||
byte[] sig1crc = Base64.decode("OZa/");
|
||||
|
||||
byte[] testPubWithUserAttr =
|
||||
Base64.decode(
|
||||
"mQGiBD2Rqv0RBADqKCkhVEtB/lEEr/9CubuHEy2oN/yU5j+2GXSdcNdVnRI/rwFy"
|
||||
+ "fHEQIk3uU7zHSUKFrC59yDm0sODYyjEdE3BVb0xvEJ5LE/OdndcIMXT1DungZ1vB"
|
||||
+ "zIK/3lr33W/PHixYxv9jduH3WrTehBpiKkgMZp8XloSFj2Cnw9LDyfqB7QCg/8K1"
|
||||
+ "o2k75NkOd9ZjnA9ye7Ri3bEEAKyr61Mo7viPWBK1joWAEsxG0OBWM+iSlG7kwh31"
|
||||
+ "8efgC/7Os6x4Y0jzs8mpcbBjeZtZjS9lRbfp7RinhF269xL0TZ3JxIdtaAV/6yDQ"
|
||||
+ "9NXfZY9dskN++HIR/5GCEEgq/qTJZt6ti5k7aV19ZFfO6wiK3NUy08wOrVsdOkVE"
|
||||
+ "w9IcBADaplhpcel3201uU3OCboogJtw81R5MJMZ4Y9cKL/ca2jGISn0nA7KrAw9v"
|
||||
+ "ShheSixGO4BV9JECkLEbtg7i+W/j/De6S+x2GLNcphuTP3UmgtKbhs0ItRqzW561"
|
||||
+ "s6gLkqi6aWmgaFLd8E1pMJcd9DSY95P13EYB9VJIUxFNUopzo7QcUmFsZiBIYXVz"
|
||||
+ "ZXIgPGhhdXNlckBhY20ub3JnPokAWAQQEQIAGAUCPZGq/QgLAwkIBwIBCgIZAQUb"
|
||||
+ "AwAAAAAKCRAqIBiOh4JvOKg4AJ9j14yygOqqzqiLKeaasIzqT8LCIgCggx14WuLO"
|
||||
+ "wOUTUswTaVKMFnU7tseJAJwEEAECAAYFAj2Rqx8ACgkQ9aWTKMpUDFV+9QP/RiWT"
|
||||
+ "5FAF5Rgb7beaApsgXsME+Pw7HEYFtqGa6VcXEpbcUXO6rjaXsgMgY90klWlWCF1T"
|
||||
+ "HOyKITvj2FdhE+0j8NQn4vaGpiTwORW/zMf/BZ0abdSWQybp10Yjs8gXw30UheO+"
|
||||
+ "F1E524MC+s2AeUi2hwHMiS+AVYd4WhxWHmWuBpTRypP/AAALTgEQAAEBAAAAAQAA"
|
||||
+ "AAABAAAA/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQ"
|
||||
+ "Dg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/"
|
||||
+ "2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7"
|
||||
+ "Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCABqAF0DASIAAhEBAxEB/8QAHwAAAQUB"
|
||||
+ "AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID"
|
||||
+ "AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0"
|
||||
+ "NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT"
|
||||
+ "lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl"
|
||||
+ "5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL"
|
||||
+ "/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB"
|
||||
+ "CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpj"
|
||||
+ "ZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3"
|
||||
+ "uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR"
|
||||
+ "AxEAPwD2aiiq9xcxWsRllcKqjOT06E/0oAsVm6jrmm6VGXvLuOPGflz8x+grzXxV"
|
||||
+ "8U51u5LXRgBGowZHXknnkc9OQcV51caneXdw9xPOXlckl2AJHY4J6cD1oA9J1z4p"
|
||||
+ "TRkrYQhRyQ0hIY5/2QRx7k9ulczN8SvEEshdZkX0UorDrznI759a5Mksckkknqec"
|
||||
+ "mkoA7WD4oavEoEttbTepYEZ+mCMVv6H8SLTULhbe/gFozAYkD5Unp3Ax/kV5XRQB"
|
||||
+ "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"
|
||||
+ "7DGrzw==");
|
||||
|
||||
byte[] aesSecretKey = Base64.decode(
|
||||
"lQHpBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN"
|
||||
+ "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj"
|
||||
+ "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA"
|
||||
+ "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo"
|
||||
+ "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5"
|
||||
+ "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN"
|
||||
+ "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X"
|
||||
+ "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF"
|
||||
+ "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV"
|
||||
+ "jTxKmrLYnZz5w5qyVpvRyv4JAwKyWlhdblPudWBFXNkW5ydKn0AV2f51wEtj"
|
||||
+ "Zy0aLIeutVMSJf1ytLqjFqrnFe6pdJrHO3G00TE8OuFhftWosLGLbEGytDtF"
|
||||
+ "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gQUVTMjU2KSA8ZXJpY0Bib3Vu"
|
||||
+ "Y3ljYXN0bGUub3JnPohZBBMRAgAZBQJAUnSGBAsHAwIDFQIDAxYCAQIeAQIX"
|
||||
+ "gAAKCRBYt1NnUiCgeFKaAKCiqtOO+NQES1gJW6XuOGmSkXt8bQCfcuW7SXZH"
|
||||
+ "zxK1FfdcG2HEDs3YEVawAgAA");
|
||||
|
||||
byte[] aesPublicKey = Base64.decode(
|
||||
"mQGiBEBSdIYRBADpd7MeIxRk4RsvyMnJNIYe4FiVv6i7I7+LPRvnIjDct0bN"
|
||||
+ "1gCV48QFej7g/PsvXRjYSowV3VIvchWX8OERd/5i10cLbcs7X52EP1vwYaLj"
|
||||
+ "uRfNUBg8Q51RQsKR+/rBmnVsi68rjU4yTH6wpo6FOO4pz4wFV+tWwGOwOitA"
|
||||
+ "K31L4wCgqh59eFFBrOlRFAbDvaL7emoCIR8EAOLxDKiLQJYQrKZfXdZnifeo"
|
||||
+ "dhEP0uuV4O5TG6nrqkhWffzC9cSoFD0BhMl979d8IB2Uft4FNvQc2u8hbJL5"
|
||||
+ "7OCGDCUAidlB9jSdu0/J+kfRaTGhYDjBgw7AA42576BBSMNouJg/aOOQENEN"
|
||||
+ "Nn4n7NxR3viBzIsL/OIeU8HSkBgaA/41PsvcgZ3kwpdltJ/FVRWhmMmv/q/X"
|
||||
+ "qp1YOnF8xPU9bv2ofELrxJfRsbS4GW1etzD+nXs/woW4Vfixs01x+cutR4iF"
|
||||
+ "3hw+eU+yLToMPmmo8D2LUvX1SRODJpx5yBBeRIYv6nz9H3sQRDx3kaLASxDV"
|
||||
+ "jTxKmrLYnZz5w5qyVpvRyrQ7RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt"
|
||||
+ "IEFFUzI1NikgPGVyaWNAYm91bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ0"
|
||||
+ "hgQLBwMCAxUCAwMWAgECHgECF4AACgkQWLdTZ1IgoHhSmgCfU83BLBF2nCua"
|
||||
+ "zk2dXB9zO1l6XS8AnA07U4cq5W0GrKM6/kP9HWtPhgOFsAIAAA==");
|
||||
|
||||
byte[] twofishSecretKey = Base64.decode(
|
||||
"lQHpBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc"
|
||||
+ "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8"
|
||||
+ "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p"
|
||||
+ "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/"
|
||||
+ "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2"
|
||||
+ "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG"
|
||||
+ "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK"
|
||||
+ "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v"
|
||||
+ "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj"
|
||||
+ "KJs01YT3L6f0iIj03hCeV/4KAwLcGrxT3X0qR2CZyZYSVBdjXeNYKXuGBtOf"
|
||||
+ "ood26WOtwLw4+l9sHVoiXNv0LomkO58ndJRPGCeZWZEDMVrfkS7rcOlktDxF"
|
||||
+ "cmljIEguIEVjaGlkbmEgKHRlc3Qga2V5IC0gdHdvZmlzaCkgPGVyaWNAYm91"
|
||||
+ "bmN5Y2FzdGxlLm9yZz6IWQQTEQIAGQUCQFJ20gQLBwMCAxUCAwMWAgECHgEC"
|
||||
+ "F4AACgkQaCCMaHh9zR2+RQCghcQwlt4B4YmNxp2b3v6rP3E8M0kAn2Gspi4u"
|
||||
+ "A/ynoqnC1O8HNlbjPdlVsAIAAA==");
|
||||
|
||||
byte[] twofishPublicKey = Base64.decode(
|
||||
"mQGiBEBSdtIRBACf7WfrqTl8F051+EbaljPf/8/ajFpAfMq/7p3Hri8OCsuc"
|
||||
+ "fJJIufEEOV1/Lt/wkN67MmSyrU0fUCsRbEckRiB4EJ0zGHVFfAnku2lzdgc8"
|
||||
+ "AVounqcHOmqA/gliFDEnhYOx3bOIAOav+yiOqfKVBhWRCpFdOTE+w/XoDM+p"
|
||||
+ "p8bH5wCgmP2FuWpzfSut7GVKp51xNEBRNuED/3t2Q+Mq834FVynmLKEmeXB/"
|
||||
+ "qtIz5reHEQR8eMogsOoJS3bXs6v3Oblj4in1gLyTVfcID5tku6kLP20xMRM2"
|
||||
+ "zx2oRbz7TyOCrs15IpRXyqqJxUWD8ipgJPkPXE7hK8dh4YSTUi4i5a1ug8xG"
|
||||
+ "314twlPzrchpWZiutDvZ+ks1rzOtBACHrEFG2frUu+qVkL43tySE0cV2bnuK"
|
||||
+ "LVhXbpzF3Qdkfxou2nuzsCbl6m87OWocJX8uYcQGlHLKv8Q2cfxZyieLFg6v"
|
||||
+ "06LSFdE9drGBWz7mbrT4OJjxPyvnkffPfLOOqae3PMYIIuscvswuhm4X5aoj"
|
||||
+ "KJs01YT3L6f0iIj03hCeV7Q8RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSAt"
|
||||
+ "IHR3b2Zpc2gpIDxlcmljQGJvdW5jeWNhc3RsZS5vcmc+iFkEExECABkFAkBS"
|
||||
+ "dtIECwcDAgMVAgMDFgIBAh4BAheAAAoJEGggjGh4fc0dvkUAn2QGdNk8Wrrd"
|
||||
+ "+DvKECrO5+yoPRx3AJ91DhCMme6uMrQorKSDYxHlgc7iT7ACAAA=");
|
||||
|
||||
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
/**
|
||||
* Generated signature test
|
||||
*
|
||||
* @param sKey
|
||||
* @param pgpPrivKey
|
||||
*/
|
||||
public void generateTest(
|
||||
PGPSecretKeyRing sKey,
|
||||
PGPPublicKey pgpPubKey,
|
||||
PGPPrivateKey pgpPrivKey)
|
||||
throws Exception
|
||||
{
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, "SC");
|
||||
|
||||
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
|
||||
|
||||
Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs();
|
||||
String primaryUserID = (String)it.next();
|
||||
|
||||
spGen.setSignerUserID(true, primaryUserID);
|
||||
|
||||
sGen.setHashedSubpackets(spGen.generate());
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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);
|
||||
|
||||
cGen.close();
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
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();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
InputStream dIn = p2.getInputStream();
|
||||
|
||||
ops.initVerify(pgpPubKey, "SC");
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
String file = null;
|
||||
KeyFactory fact = KeyFactory.getInstance("DSA", "SC");
|
||||
PGPPublicKey pubKey = null;
|
||||
PrivateKey privKey = null;
|
||||
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey);
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKey);
|
||||
PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "SC");
|
||||
|
||||
//
|
||||
// test signature message
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(sig1);
|
||||
|
||||
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();
|
||||
int ch;
|
||||
|
||||
ops.initVerify(pubKey, "SC");
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// signature generation
|
||||
//
|
||||
generateTest(sKey, pubKey, pgpPrivKey);
|
||||
|
||||
//
|
||||
// signature generation - canonical text
|
||||
//
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "SC");
|
||||
|
||||
sGen.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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.TEXT,
|
||||
"_CONSOLE",
|
||||
data.getBytes().length,
|
||||
testDate);
|
||||
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
lGen.close();
|
||||
|
||||
sGen.generate().encode(bcOut);
|
||||
|
||||
cGen.close();
|
||||
|
||||
//
|
||||
// verify generated signature - canconical text
|
||||
//
|
||||
pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
|
||||
ops = p1.get(0);
|
||||
|
||||
p2 = (PGPLiteralData)pgpFact.nextObject();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
dIn = p2.getInputStream();
|
||||
|
||||
ops.initVerify(pubKey, "SC");
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// Read the public key with user attributes
|
||||
//
|
||||
pgpPub = new PGPPublicKeyRing(testPubWithUserAttr);
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
Iterator it = pubKey.getUserAttributes();
|
||||
int count = 0;
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next();
|
||||
|
||||
Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes);
|
||||
int sigCount = 0;
|
||||
while (sigs.hasNext())
|
||||
{
|
||||
sigs.next();
|
||||
|
||||
sigCount++;
|
||||
}
|
||||
|
||||
if (sigCount != 1)
|
||||
{
|
||||
fail("Failed user attributes signature check");
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
fail("Failed user attributes check");
|
||||
}
|
||||
|
||||
byte[] pgpPubBytes = pgpPub.getEncoded();
|
||||
|
||||
pgpPub = new PGPPublicKeyRing(pgpPubBytes);
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
it = pubKey.getUserAttributes();
|
||||
count = 0;
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
fail("Failed user attributes reread");
|
||||
}
|
||||
|
||||
//
|
||||
// reading test extra data - key with edge condition for DSA key password.
|
||||
//
|
||||
char [] passPhrase = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
|
||||
sKey = new PGPSecretKeyRing(testPrivKey2);
|
||||
pgpPrivKey = sKey.getSecretKey().extractPrivateKey(passPhrase, "SC");
|
||||
|
||||
byte[] bytes = pgpPrivKey.getKey().getEncoded();
|
||||
|
||||
//
|
||||
// reading test - aes256 encrypted passphrase.
|
||||
//
|
||||
sKey = new PGPSecretKeyRing(aesSecretKey);
|
||||
pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "SC");
|
||||
|
||||
bytes = pgpPrivKey.getKey().getEncoded();
|
||||
|
||||
//
|
||||
// reading test - twofish encrypted passphrase.
|
||||
//
|
||||
sKey = new PGPSecretKeyRing(twofishSecretKey);
|
||||
pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "SC");
|
||||
|
||||
bytes = pgpPrivKey.getKey().getEncoded();
|
||||
|
||||
//
|
||||
// use of PGPKeyPair
|
||||
//
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "SC");
|
||||
|
||||
kpg.initialize(512);
|
||||
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.DSA , kp.getPublic(), kp.getPrivate(), new Date());
|
||||
|
||||
PGPPublicKey k1 = pgpKp.getPublicKey();
|
||||
|
||||
PGPPrivateKey k2 = pgpKp.getPrivateKey();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPDSATest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPDSATest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class PGPECDHTest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mFIEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
|
||||
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKstFBUZXN0IEVDRFNB" +
|
||||
"LUVDREggKEtleSBhbmQgc3Via2V5IGFyZSAyNTYgYml0cyBsb25nKSA8dGVzdC5l" +
|
||||
"Y2RzYS5lY2RoQGV4YW1wbGUuY29tPoh6BBMTCAAiBQJRvgbAAhsDBgsJCAcDAgYV" +
|
||||
"CAIJCgsEFgIDAQIeAQIXgAAKCRD3wDlWjFo9U5O2AQDi89NO6JbaIObC63jMMWsi" +
|
||||
"AaQHrBCPkDZLibgNv73DLgD/faouH4YZJs+cONQBPVnP1baG1NpWR5ppN3JULFcr" +
|
||||
"hcq4VgRRvgbAEggqhkjOPQMBBwIDBLtY8Nmfz0zSEa8C1snTOWN+VcT8pXPwgJRy" +
|
||||
"z6kSP4nPt1xj1lPKj5zwPXKWxMkPO9ocqhKdg2mOh6/rc1ObIoMDAQgHiGEEGBMI" +
|
||||
"AAkFAlG+BsACGwwACgkQ98A5VoxaPVN8cgEAj4dMNMNwRSg2ZBWunqUAHqIedVbS" +
|
||||
"dmwmbysD192L3z4A/ReXEa0gtv8OFWjuALD1ovEK8TpDORLUb6IuUb5jUIzY");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lKUEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
|
||||
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKs/gcDAo11YYCae/K2" +
|
||||
"1uKGJ/uU4b4QHYnPIsAdYpuo5HIdoAOL/WwduRa8C6vSFrtMJLDqPK3BUpMz3CXN" +
|
||||
"GyMhjuaHKP5MPbBZkIfgUGZO5qvU9+i0UFRlc3QgRUNEU0EtRUNESCAoS2V5IGFu" +
|
||||
"ZCBzdWJrZXkgYXJlIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhLmVjZGhAZXhh" +
|
||||
"bXBsZS5jb20+iHoEExMIACIFAlG+BsACGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B" +
|
||||
"AheAAAoJEPfAOVaMWj1Tk7YBAOLz007oltog5sLreMwxayIBpAesEI+QNkuJuA2/" +
|
||||
"vcMuAP99qi4fhhkmz5w41AE9Wc/VtobU2lZHmmk3clQsVyuFyg==");
|
||||
|
||||
byte[] testMessage =
|
||||
Base64.decode(
|
||||
"hH4Dp5+FdoujIBwSAgMErx4BSvgXY3irwthgxU8zPoAoR+8rhmxdpwbw6ZJAO2GX" +
|
||||
"azWJ85JNcobHKDeGeUq6wkTFu+g6yG99gIX8J5xJAjBRhyCRcaFgwbdDV4orWTe3" +
|
||||
"iewiT8qs4BQ23e0c8t+thdKoK4thMsCJy7wSKqY0sJTSVAELroNbCOi2lcO15YmW" +
|
||||
"6HiuFH7VKWcxPUBjXwf5+Z3uOKEp28tBgNyDrdbr1BbqlgYzIKq/pe9zUbUXfitn" +
|
||||
"vFc6HcGhvmRQreQ+Yw1x3x0HJeoPwg==");
|
||||
|
||||
private void generate()
|
||||
throws Exception
|
||||
{
|
||||
//
|
||||
// Generate a master key
|
||||
//
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "SC");
|
||||
|
||||
keyGen.initialize(new ECGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpSign = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDSA, kpSign, new Date());
|
||||
|
||||
//
|
||||
// Generate an encryption key
|
||||
//
|
||||
keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
|
||||
|
||||
keyGen.initialize(new ECGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpEnc = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdhKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDH, kpEnc, new Date());
|
||||
|
||||
//
|
||||
// generate a key ring
|
||||
//
|
||||
char[] passPhrase = "test".toCharArray();
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||
PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, ecdsaKeyPair,
|
||||
"test@bouncycastle.org", sha1Calc, null, null,
|
||||
new JcaPGPContentSignerBuilder(ecdsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
|
||||
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("SC").build(passPhrase));
|
||||
|
||||
keyRingGen.addSubKey(ecdhKeyPair);
|
||||
|
||||
PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing();
|
||||
|
||||
// TODO: add check of KdfParameters
|
||||
doBasicKeyRingCheck(pubRing);
|
||||
|
||||
PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing();
|
||||
|
||||
KeyFingerPrintCalculator fingerCalc = new JcaKeyFingerprintCalculator();
|
||||
|
||||
PGPPublicKeyRing pubRingEnc = new PGPPublicKeyRing(pubRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(pubRing.getEncoded(), pubRingEnc.getEncoded()))
|
||||
{
|
||||
fail("public key ring encoding failed");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing secRingEnc = new PGPSecretKeyRing(secRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(secRing.getEncoded(), secRingEnc.getEncoded()))
|
||||
{
|
||||
fail("secret key ring encoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void testDecrypt(PGPSecretKeyRing secretKeyRing)
|
||||
throws Exception
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(testMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
PGPSecretKey secretKey = secretKeyRing.getSecretKey(); // secretKeyRing.getSecretKey(encP.getKeyID());
|
||||
//
|
||||
// PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey()extractPrivateKey(null);
|
||||
//
|
||||
// clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
//
|
||||
// bOut.reset();
|
||||
//
|
||||
// while ((ch = clear.read()) >= 0)
|
||||
// {
|
||||
// bOut.write(ch);
|
||||
// }
|
||||
//
|
||||
// out = bOut.toByteArray();
|
||||
//
|
||||
// if (!areEqual(out, text))
|
||||
// {
|
||||
// fail("wrong plain text in generated packet");
|
||||
// }
|
||||
}
|
||||
|
||||
private void encryptDecryptTest()
|
||||
throws Exception
|
||||
{
|
||||
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' };
|
||||
|
||||
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
|
||||
|
||||
keyGen.initialize(new ECGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpEnc = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdhKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDH, kpEnc, new Date());
|
||||
|
||||
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
|
||||
ByteArrayOutputStream ldOut = new ByteArrayOutputStream();
|
||||
OutputStream pOut = lData.open(ldOut, PGPLiteralDataGenerator.UTF8, PGPLiteralData.CONSOLE, text.length, new Date());
|
||||
|
||||
pOut.write(text);
|
||||
|
||||
pOut.close();
|
||||
|
||||
byte[] data = ldOut.toByteArray();
|
||||
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setProvider("SC").setSecureRandom(new SecureRandom()));
|
||||
|
||||
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(ecdhKeyPair.getPublicKey()).setProvider("SC"));
|
||||
|
||||
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), data.length);
|
||||
|
||||
cOut.write(data);
|
||||
|
||||
cOut.close();
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("SC").build(ecdhKeyPair.getPrivateKey()));
|
||||
|
||||
pgpF = new PGPObjectFactory(clear);
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpF.nextObject();
|
||||
|
||||
clear = ld.getInputStream();
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
int ch;
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
byte[] out = bOut.toByteArray();
|
||||
|
||||
if (!areEqual(out, text))
|
||||
{
|
||||
fail("wrong plain text in generated packet");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
doBasicKeyRingCheck(pubKeyRing);
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
testDecrypt(secretKeyRing);
|
||||
|
||||
encryptDecryptTest();
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
private void doBasicKeyRingCheck(PGPPublicKeyRing pubKeyRing)
|
||||
throws PGPException, SignatureException
|
||||
{
|
||||
for (Iterator it = pubKeyRing.getPublicKeys(); it.hasNext();)
|
||||
{
|
||||
PGPPublicKey pubKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pubKey.isMasterKey())
|
||||
{
|
||||
if (pubKey.isEncryptionKey())
|
||||
{
|
||||
fail("master key showed as encryption key!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pubKey.isEncryptionKey())
|
||||
{
|
||||
fail("sub key not encryption key!");
|
||||
}
|
||||
|
||||
for (Iterator sigIt = pubKeyRing.getPublicKey().getSignatures(); sigIt.hasNext();)
|
||||
{
|
||||
PGPSignature certification = (PGPSignature)sigIt.next();
|
||||
|
||||
certification.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKeyRing.getPublicKey());
|
||||
|
||||
if (!certification.verifyCertification((String)pubKeyRing.getPublicKey().getUserIDs().next(), pubKeyRing.getPublicKey()))
|
||||
{
|
||||
fail("subkey certification does not verify");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPECDHTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPECDHTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.Security;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
|
||||
public class PGPECDSATest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mFIEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
|
||||
"zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8FetDVFQ0RTQSAoS2V5" +
|
||||
"IGlzIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhQGV4YW1wbGUuY29tPoh6BBMT" +
|
||||
"CAAiBQJRvgeoAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDqO46kgPLi" +
|
||||
"vN1hAP4n0UApR36ziS5D8KUt7wEpBujQE4G3+efATJ+DMmY/SgEA+wbdDynFf/V8" +
|
||||
"pQs0+FtCYQ9schzIur+peRvol7OrNnc=");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lKUEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
|
||||
"zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8Fe/gcDAqTWSUiFpEno" +
|
||||
"1n8izmLaWTy8GYw5/lK4R2t6D347YGgTtIiXfoNPOcosmU+3OibyTm2hc/WyG4fL" +
|
||||
"a0nxFtj02j0Bt/Fw0N4VCKJwKL/QJT+0NUVDRFNBIChLZXkgaXMgMjU2IGJpdHMg" +
|
||||
"bG9uZykgPHRlc3QuZWNkc2FAZXhhbXBsZS5jb20+iHoEExMIACIFAlG+B6gCGwMG" +
|
||||
"CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOo7jqSA8uK83WEA/ifRQClHfrOJ" +
|
||||
"LkPwpS3vASkG6NATgbf558BMn4MyZj9KAQD7Bt0PKcV/9XylCzT4W0JhD2xyHMi6" +
|
||||
"v6l5G+iXs6s2dw==");
|
||||
|
||||
private void generateAndSign()
|
||||
throws Exception
|
||||
{
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "SC");
|
||||
|
||||
keyGen.initialize(new ECGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpSign = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDSA, kpSign, new Date());
|
||||
|
||||
//
|
||||
// try a signature
|
||||
//
|
||||
PGPSignatureGenerator signGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PGPPublicKey.ECDSA, HashAlgorithmTags.SHA256).setProvider("SC"));
|
||||
|
||||
signGen.init(PGPSignature.BINARY_DOCUMENT, ecdsaKeyPair.getPrivateKey());
|
||||
|
||||
signGen.update("hello world!".getBytes());
|
||||
|
||||
PGPSignature sig = signGen.generate();
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), ecdsaKeyPair.getPublicKey());
|
||||
|
||||
sig.update("hello world!".getBytes());
|
||||
|
||||
if (!sig.verify())
|
||||
{
|
||||
fail("signature failed to verify!");
|
||||
}
|
||||
|
||||
//
|
||||
// generate a key ring
|
||||
//
|
||||
char[] passPhrase = "test".toCharArray();
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||
PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, ecdsaKeyPair,
|
||||
"test@bouncycastle.org", sha1Calc, null, null, new JcaPGPContentSignerBuilder(ecdsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("SC").build(passPhrase));
|
||||
|
||||
PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing();
|
||||
|
||||
PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing();
|
||||
|
||||
KeyFingerPrintCalculator fingerCalc = new JcaKeyFingerprintCalculator();
|
||||
|
||||
PGPPublicKeyRing pubRingEnc = new PGPPublicKeyRing(pubRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(pubRing.getEncoded(), pubRingEnc.getEncoded()))
|
||||
{
|
||||
fail("public key ring encoding failed");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing secRingEnc = new PGPSecretKeyRing(secRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(secRing.getEncoded(), secRingEnc.getEncoded()))
|
||||
{
|
||||
fail("secret key ring encoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
for (Iterator it = pubKeyRing.getPublicKey().getSignatures(); it.hasNext();)
|
||||
{
|
||||
PGPSignature certification = (PGPSignature)it.next();
|
||||
|
||||
certification.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKeyRing.getPublicKey());
|
||||
|
||||
if (!certification.verifyCertification((String)pubKeyRing.getPublicKey().getUserIDs().next(), pubKeyRing.getPublicKey()))
|
||||
{
|
||||
fail("self certification does not verify");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
|
||||
generateAndSign();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPECDSATest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPECDSATest());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,105 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPMarker;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTestResult;
|
||||
import org.spongycastle.util.test.Test;
|
||||
import org.spongycastle.util.test.TestResult;
|
||||
|
||||
public class PGPMarkerTest
|
||||
implements Test
|
||||
{
|
||||
private byte[] message1 = Base64.decode(
|
||||
"qANQR1DBwU4DdrlXatQSHgoQCADWlhY3bWWaOTm4t2espRWPFQmETeinnieHce64"
|
||||
+ "lmEIFzaryEWeSdQc8XGfDzcb7sxq7b5b9Hm6OrACcCbSp2KGEJNG5kJmo2A16UPq"
|
||||
+ "JdK4xNelpJRh3KcJPv+N/9VJrMdj4C+DRnGNFg1hTQf3RKsX+ms2V0OBC5vGlOZY"
|
||||
+ "zX+XZz/7hl1PXVLN23u4npZI/1xETI2VtRoM76S6oykGXxMtT3+sGU1fAVEKVS45"
|
||||
+ "pyQHWbBqApkWrURq0xBqpVfDwOgGw09dJxt2igW9hjvNAd9tJiMGrMF5o2OLlub7"
|
||||
+ "c7FiK+dWLLcw+nx7Hl6FQmo9E8qyW8x1Cb78HjR/JXMgH/ngB/4gba6xX+s5TJkW"
|
||||
+ "H2Wpp5ePTw39EqHosUMrm05R+C0ha3EyyaJIvKj2WWmImKu5PWo1t37Pi6KHFNC3"
|
||||
+ "wsYJMRKnnNtd34luMTOgLpDcdgClzfp2p6EqHMoB7Uj3etlLmbN+vpGgz9qkLBRV"
|
||||
+ "7MpR1yE9qrZNeGgbkry6N31w5E7HoAHu5JNcwxgzbJoj2lI8uvs6Gf7fEoQOuAPE"
|
||||
+ "W/SGlfR2BdBPiJ1yErMElc2O8LVS0wTwwifHpEsMV+1ntl1EC5d052lo+6q7zNqD"
|
||||
+ "uYt1/2if6h9W9fe+S9mzr0ZAtxIN2ZGOFJJRnqzjDQ4siB9nnwr6YgvUVRSr/lQB"
|
||||
+ "hDTd0bmjyWacCt0PPMJWchO6A5tzqKUpTWSYibpdks80kLQogQHsJTZd/kpS0I6f"
|
||||
+ "gD0HYYlMssZwhg2J2TWwXDpDTgQ6mzFKbGSdOSk/deTJj2+EubzxaZcxZEocCJA8"
|
||||
+ "bppCj4kLBnCj1LjYx7A=");
|
||||
|
||||
private byte[] message2 = Base64.decode(
|
||||
"qANQR1DBwU4DZlTzKj+E4aMQCADruFAojUIlHGcnswLIekvhbVnaHnbCt6Kp"
|
||||
+ "IL2zppmEIYJ9n1xCO1k+3Y5j9vNATbqCVWs1HD0aAL3PRI1eZ1l8GkIBCd2z"
|
||||
+ "tcZpSI/uyI/JCzVW2stCH0gpP2V7zcjk8HaIuBz4ZsyU9m7v6LwCDPB4CTrb"
|
||||
+ "Z5nn5Jm3eowonQsRL/3TpJtG+IjTaw29NbCBNNX8quM5LwfIsfWovqNv28r1"
|
||||
+ "aX8FsqoTRsWEfQ7dMV/swVGqv0PgKxqErdnZVJ2yOJqjLk+lBJT6zhqPijGV"
|
||||
+ "10pc68hdZxxLU1KZq25DAjS12xcAgagjRkOmYE/H1oEjGZlXfS4y/xQ7skHa"
|
||||
+ "HI+b04vECACTpQPwCXhxYiNWnf4XhJPONIGyrsXVtsTNwzOShFPmeUvpipP4"
|
||||
+ "HknakBkBuUY49xcffQogW/NlGCZnQOulDLE6fCH/krkSmI8WVP5Vhf6bM1Qm"
|
||||
+ "92dHZFoTrrcQ9NVGaCNHHWf7KXkNfKdTkE23LdggoVrVAzO4WcdqVc6s/or7"
|
||||
+ "jQYP9zXLeu8+GGFMxe/9FCtoIWbujGQHsdDEkCK4h+D44EVDPzbvWj39ZB4w"
|
||||
+ "hHoab8RLHd7njcrPeoCPdYkFVCKOSuLdxxYZDbbmgpISaafrafwefkkESeGu"
|
||||
+ "JzbNhmyS8zfOiejWzndaLYWUSE/sqISK9Pg+xKundnFPk04+AhIRyYEoUjG3"
|
||||
+ "LgGVyM49mrM8E7QwAGU0m/VCJLoOu+N74Z1rp1wFdA5yCllFlONNM4Czhd1D"
|
||||
+ "ZMyLFqGXiKlyVCPlUTN2uVisYQGr6iNGYSPxpKjwiAzdeeQBPOETG0vd3nTO"
|
||||
+ "MN4BMKcG+kRJd5FU72SRfmbGwPPjd1gts9xFvtj4Tvpkam8=");
|
||||
|
||||
public TestResult perform()
|
||||
{
|
||||
try
|
||||
{
|
||||
//
|
||||
// test encrypted message
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(message1);
|
||||
|
||||
Object o;
|
||||
|
||||
if (pgpFact.nextObject() instanceof PGPMarker)
|
||||
{
|
||||
if (pgpFact.nextObject() instanceof PGPEncryptedDataList)
|
||||
{
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": error processing after marker.");
|
||||
}
|
||||
}
|
||||
|
||||
pgpFact = new PGPObjectFactory(message2);
|
||||
|
||||
if (pgpFact.nextObject() instanceof PGPMarker)
|
||||
{
|
||||
if (pgpFact.nextObject() instanceof PGPEncryptedDataList)
|
||||
{
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": error processing after marker.");
|
||||
}
|
||||
}
|
||||
|
||||
return new SimpleTestResult(false, getName() + ": marker not found");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPMarkerTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Test test = new PGPMarkerTest();
|
||||
TestResult result = test.perform();
|
||||
|
||||
System.out.println(result.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
|
||||
public class PGPNoPrivateKeyTest
|
||||
extends SimpleTest
|
||||
{
|
||||
String pgpOldPass = "test";
|
||||
String pgpNewPass = "newtest";
|
||||
String BOUNCY_CASTLE_PROVIDER_NAME = "SC";
|
||||
|
||||
byte[] pgpPrivateEmpty = Base64.decode(
|
||||
"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"
|
||||
+ "+b3JLdM=");
|
||||
|
||||
byte[] pgpPrivateFull = Base64.decode(
|
||||
"lQH+BFGSNGwBBACwABZRIEW/4vDQajcO0FW39yNDcsHBDwPkGT95D7jiVTTRoSs6"
|
||||
+ "ACWRAAwGlz4V62U0+nEgasxpifHnu6jati5zxwS16qNvBcxcqZrdZWdvolzCWWsr"
|
||||
+ "pFd0juhwesrvvUb5dN/xCJKyLPkp6A+uwv35/cxVSOHFvbW7nnronwinYQARAQAB"
|
||||
+ "/gIDAuqTuDp/Chfq0TKnSxmm2ZpDuiHD+NFVnCyNuJpvCQk0PnVwmGMH4xvsAZB2"
|
||||
+ "TOrfh2XHf/n9J4vjxB6p6Zs1kGBgg9hcHoWf+oEf1Tz/PE/c1tUXG2Hz9wlAgstU"
|
||||
+ "my2NpDTYUjQs45p+LaM+WFtLNXzBeqELKlMevs8Xb7n+VHwiTuM3KfXETLCoLz0Q"
|
||||
+ "3GmmpOuNnvXBdza7RsDwke0r66HzwX4Le8cMH9Pe7kSMakx9S1UR/uIsxsZYZOKb"
|
||||
+ "BieGEumxiAnew0Ri5/8wTd5yYC7BWbYvBUgdMQ1gzkzmJcVky8NVfoZKQ0GkdvMo"
|
||||
+ "fMThIVXN1U6+aqzAuUMFCPYQ7fEpfoNLhCnzQPv3RE7Wo2vFMjWBod2J4MSLhBuq"
|
||||
+ "Ut+FYLqYqU21Qe4PEyPmGnkVu7Wd8FGjBF+IKZg+ycPi++h/twloD/h7LEaq907C"
|
||||
+ "4R3rdOzjZnefDfxVWjLLhqKSSuXxtjSSKwMNdbjYVVJ/tB5UZXN0IFRlc3RlcnNv"
|
||||
+ "biA8dGVzdEB0ZXN0Lm5ldD6IuAQTAQIAIgUCUZI0bAIbAwYLCQgHAwIGFQgCCQoL"
|
||||
+ "BBYCAwECHgECF4AACgkQ0q+h4fbbpOTXyAP+IjDxfZNv+ymp1pLDawaoSnprMiO4"
|
||||
+ "S08QML/gAPQdKzjtkKCWHvTo7ip9ffXzTiT7AIMMu6JLw3t0AFM91gPRpYITOUk2"
|
||||
+ "L6JxSbZe6OJMo3GeBztmSOQXXOTvYut0AKzb+NKlafvgNzH/td8+3H7Srn49Lzn8"
|
||||
+ "OmHmsi1V3FeIfeSdAf4EUZI0jQEEANpd3WZxRWF2A6DR89XDl+O/OwmynQSH4gCx"
|
||||
+ "X3W8kOk82JAkyU51QmZULNmnsq3HU0mVMTeMvW4oeJ3yfLkSskLy5ujtLumxtepF"
|
||||
+ "Aw558JbBp97r0131MJ0j6vKRWNmnHXumRjdub3szStUegu5FN/qbjR6gSEQDXx07"
|
||||
+ "ARJWg9ldABEBAAH+AgMCFCNPkJcAVRXTWkv6aTsEobexq9fQCuEh3vdlVgypwgTz"
|
||||
+ "dlt74TODXGUkAldqIhDCNGpC2duo6gokZQL04y0lQ4aNa1Fm2ksRXypQ0DW8QiSp"
|
||||
+ "TEHlX27FlyTHg5J9QIT67tzwS5emNY6HHbyFTO2kLoDUJcBLhVoLWXjg8XIAX19p"
|
||||
+ "UHhDCL9ALVkwDLejFU/AIJxaoqguPteLdI9ghz9oagg6+c8PYHqwGENBdNzkt+Lw"
|
||||
+ "5uGOQ5kBY8gdOUDtnCDeA2fYCYPDQEE/j/m8Fkd/4vaU6tyJzZKItrk+NTpx7GFo"
|
||||
+ "CqBEJ+tgQ8Y27zt+fXK1IqvVb0udr9lF4W+mfnxdz6F17KG0tUEMEz1wHgP5pQH5"
|
||||
+ "U6fh65HJGrWOw4FmzjdUkp+GdV3FjygUmHqUufvdE4928mbzey2o+tWZV1Qb1N8e"
|
||||
+ "8+jGgWQ3+OO/X5JXFJydd7/j+rhp0yOGBEOaT4x59XQ6g9jZfGVvbnyvaT2JAT0E"
|
||||
+ "GAECAAkFAlGSNI0CGwIAqAkQ0q+h4fbbpOSdIAQZAQIABgUCUZI0jQAKCRDyFO8C"
|
||||
+ "eVrNitBdA/4x8eI62au0gr+vf+IYnLY4M5zTRUjpttP26x1zAXaeqfZgardvFlPH"
|
||||
+ "4EZMUtJs/tYu1TU7+mcFF2sH08jlQj0eQUBAvhQPi73V9FHCQSaWvbU+JKM9SQcZ"
|
||||
+ "qaccS2HUtgObLJTw+SH/EB1GjjBF/TtSPkqN6xId/g7oUI/PBVLhvLiQA/917aX/"
|
||||
+ "+ZxKYISzmXUP+0JCwqEWZO38IwoUDRUiVOcYmW2fxrEr1NSKgD/zWQZgTtKg5uZu"
|
||||
+ "2oV8u9TtWzBbWolGsNjG+3cKqg76aW4yATh3SIUpwKK0S3J45vM+dUFTMx5oLyre"
|
||||
+ "f3tatX87Fc82ug1rWK9l/9VbLqLkgtbs9Zz3YJ0B/gRRkjSeAQQAtypYkJXIbNK3"
|
||||
+ "LbF24QPxhH4jtLPbQIFbHyS9T1lJAvtujMgW6pFYOUVfienck0nk+nAyPDzLvFxT"
|
||||
+ "zuh9llnaL37O1/StZcX5zVsUAdi+rdsa3l8har07GBBbhr2JmzclGLwPnWhw9Mal"
|
||||
+ "/FKwtCek2IOYnuSOvOV/IBSlRLRmBv8AEQEAAf4CAwLjLd+IXHST19N7gY/S7Y3J"
|
||||
+ "6zDS8hez1Sb+MAVxLe0/SqfHGGfNEsaXdtdSx844Ij4NZJJCJifSHtamz2Y3Pbco"
|
||||
+ "hn+O5tEyDkZyrcDW9mDfrCi6amfonp307L3NLsrlRlvvDwreNPTPUfvtKuurMb29"
|
||||
+ "6Cgads7K9wWxmiErODlcWNi/LlN7eY/aYqinVdl04lfTmSftn9WrtbTMITT841Se"
|
||||
+ "Bh+d08XsEpLIUSU2bcNqLlCZHQP24s3zTvV2GL1fLFtfwEntXZzrPgDQxs7ps0gN"
|
||||
+ "NHVj0r3lEa6BvmbVV1YJGpCSbQ8HQGLrT5EptvHJ7JdTpqwSj6JweTd7g405auer"
|
||||
+ "44tXdheboAF00w+T6bYjC9cBAf06rESUV7mOwy8vvIrpDlTsqFcOt1DF9u2FM+tS"
|
||||
+ "SWWHAe1NvIDXkcgbJ0xG45r7XqBbGJ2hoDsIHPtWceK0HWRKsWUZn8JolIBxsiPT"
|
||||
+ "qb6FWkyLgyKg3dmUVoifBBgBAgAJBQJRkjSeAhsMAAoJENKvoeH226TknLIEAJjM"
|
||||
+ "pknwJpbZx0Myq+ZNhr5QKiM5fTKilZvcANAsd4K8Mz2oqpn7KTyLnkPD4XsYsunc"
|
||||
+ "Hz68DaCpyThIzOv7DnFhJi4iKGIvv6EI1Nds8KIDn80/9YT6Ruc7PhgRl+LKKwiu"
|
||||
+ "utz7qL8AhKDa1pvu5yLX08HZxWrzbo+7OPm9yS3T");
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPSecretKeyRing pgpSecRing = new PGPSecretKeyRing(pgpPrivateFull, new JcaKeyFingerprintCalculator());
|
||||
PGPSecretKey pgpSecKey = pgpSecRing.getSecretKey();
|
||||
boolean isFullEmpty = pgpSecKey.isPrivateKeyEmpty();
|
||||
|
||||
pgpSecRing = new PGPSecretKeyRing(pgpPrivateEmpty, new JcaKeyFingerprintCalculator());
|
||||
pgpSecKey = pgpSecRing.getSecretKey();
|
||||
boolean isEmptyEmpty = pgpSecKey.isPrivateKeyEmpty();
|
||||
|
||||
//
|
||||
// Check isPrivateKeyEmpty() is public
|
||||
//
|
||||
|
||||
if (isFullEmpty || !isEmptyEmpty)
|
||||
{
|
||||
fail("Empty private keys not detected correctly.");
|
||||
}
|
||||
|
||||
//
|
||||
// Check copyWithNewPassword doesn't throw an exception for secret
|
||||
// keys without private keys (PGPException: unknown S2K type: 101).
|
||||
//
|
||||
|
||||
try
|
||||
{
|
||||
PGPSecretKey pgpChangedKey = PGPSecretKey.copyWithNewPassword(pgpSecKey,
|
||||
new JcePBESecretKeyDecryptorBuilder(
|
||||
new JcaPGPDigestCalculatorProviderBuilder().setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build()).setProvider(BOUNCY_CASTLE_PROVIDER_NAME).build(pgpOldPass.toCharArray()),
|
||||
new JcePBESecretKeyEncryptorBuilder(pgpSecKey.getKeyEncryptionAlgorithm()).build(pgpNewPass.toCharArray()));
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
if (!e.getMessage().equals("no private key in this SecretKey - public key present only."))
|
||||
{
|
||||
fail("wrong exception.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPNoPrivateKeyTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPNoPrivateKeyTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
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.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPBEEncryptedData;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
|
||||
public class PGPPBETest
|
||||
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
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(message);
|
||||
PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0);
|
||||
|
||||
InputStream clear = pbe.getDataStream(pass, "SC");
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
|
||||
PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(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
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(message);
|
||||
PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0);
|
||||
|
||||
InputStream clear = pbe.getDataStream(pass, "SC");
|
||||
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
|
||||
PGPCompressedData cData = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(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(PGPEncryptedData.CAST5, new SecureRandom(), "SC");
|
||||
|
||||
cPk.addMethod(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(PGPEncryptedData.CAST5, new SecureRandom(), "SC");
|
||||
|
||||
cPk.addMethod(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(PGPEncryptedData.CAST5, rand, "SC");
|
||||
|
||||
cPk.addMethod(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(PGPEncryptedData.CAST5, true, rand, "SC");
|
||||
|
||||
cPk.addMethod(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
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(testPBEAsym);
|
||||
|
||||
PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpFact.nextObject();
|
||||
|
||||
PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(1);
|
||||
|
||||
InputStream clear = pbe.getDataStream("password".toCharArray(), "SC");
|
||||
|
||||
pgpFact = new PGPObjectFactory(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(PGPEncryptedData.CAST5, true, rand, "SC");
|
||||
|
||||
cPk.addMethod(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");
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPPBETest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPPBETest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Random;
|
||||
|
||||
public class PGPPacketTest
|
||||
extends SimpleTest
|
||||
{
|
||||
private static int MAX = 32000;
|
||||
|
||||
private void readBackTest(
|
||||
PGPLiteralDataGenerator generator)
|
||||
throws IOException
|
||||
{
|
||||
Random rand = new Random();
|
||||
byte[] buf = new byte[MAX];
|
||||
|
||||
rand.nextBytes(buf);
|
||||
|
||||
for (int i = 1; i <= 200; i++)
|
||||
{
|
||||
bufferTest(generator, buf, i);
|
||||
}
|
||||
|
||||
bufferTest(generator, buf, 8382);
|
||||
bufferTest(generator, buf, 8383);
|
||||
bufferTest(generator, buf, 8384);
|
||||
bufferTest(generator, buf, 8385);
|
||||
|
||||
for (int i = 200; i < MAX; i += 100)
|
||||
{
|
||||
bufferTest(generator, buf, i);
|
||||
}
|
||||
}
|
||||
|
||||
private void bufferTest(
|
||||
PGPLiteralDataGenerator generator,
|
||||
byte[] buf,
|
||||
int i)
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
OutputStream out = generator.open(
|
||||
new UncloseableOutputStream(bOut),
|
||||
PGPLiteralData.BINARY,
|
||||
PGPLiteralData.CONSOLE,
|
||||
i,
|
||||
new Date());
|
||||
|
||||
out.write(buf, 0, i);
|
||||
|
||||
generator.close();
|
||||
|
||||
PGPObjectFactory fact = new PGPObjectFactory(bOut.toByteArray());
|
||||
PGPLiteralData data = (PGPLiteralData)fact.nextObject();
|
||||
InputStream in = data.getInputStream();
|
||||
|
||||
for (int count = 0; count != i; count++)
|
||||
{
|
||||
if (in.read() != (buf[count] & 0xff))
|
||||
{
|
||||
fail("failed readback test - length = " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws IOException
|
||||
{
|
||||
PGPLiteralDataGenerator oldGenerator = new PGPLiteralDataGenerator(true);
|
||||
|
||||
readBackTest(oldGenerator);
|
||||
|
||||
PGPLiteralDataGenerator newGenerator = new PGPLiteralDataGenerator(false);
|
||||
|
||||
readBackTest(newGenerator);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPPacketTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPPacketTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
|
||||
public class PGPParsingTest
|
||||
extends SimpleTest
|
||||
{
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPPublicKeyRingCollection pubRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(this.getClass().getResourceAsStream("bigpub.asc")));
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPParsingTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPParsingTest());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,905 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SignatureSubpacketTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||
import org.spongycastle.bcpg.sig.NotationData;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
import org.spongycastle.openpgp.PGPV3SignatureGenerator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.io.Streams;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class PGPSignatureTest
|
||||
extends SimpleTest
|
||||
{
|
||||
private static final int[] NO_PREFERENCES = null;
|
||||
private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[] { SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.TRIPLE_DES };
|
||||
private static final int[] PREFERRED_HASH_ALGORITHMS = new int[] { HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA256 };
|
||||
private static final int[] PREFERRED_COMPRESSION_ALGORITHMS = new int[] { CompressionAlgorithmTags.ZLIB };
|
||||
|
||||
private static final int TEST_EXPIRATION_TIME = 10000;
|
||||
private static final String TEST_USER_ID = "test user id";
|
||||
private static final byte[] TEST_DATA = "hello world!\nhello world!\n".getBytes();
|
||||
private static final byte[] TEST_DATA_WITH_CRLF = "hello world!\r\nhello world!\r\n".getBytes();
|
||||
|
||||
byte[] dsaKeyRing = Base64.decode(
|
||||
"lQHhBD9HBzURBACzkxRCVGJg5+Ld9DU4Xpnd4LCKgMq7YOY7Gi0EgK92gbaa6+zQ"
|
||||
+ "oQFqz1tt3QUmpz3YVkm/zLESBBtC1ACIXGggUdFMUr5I87+1Cb6vzefAtGt8N5VV"
|
||||
+ "1F/MXv1gJz4Bu6HyxL/ncfe71jsNhav0i4yAjf2etWFj53zK6R+Ojg5H6wCgpL9/"
|
||||
+ "tXVfGP8SqFvyrN/437MlFSUEAIN3V6j/MUllyrZglrtr2+RWIwRrG/ACmrF6hTug"
|
||||
+ "Ol4cQxaDYNcntXbhlTlJs9MxjTH3xxzylyirCyq7HzGJxZzSt6FTeh1DFYzhJ7Qu"
|
||||
+ "YR1xrSdA6Y0mUv0ixD5A4nPHjupQ5QCqHGeRfFD/oHzD4zqBnJp/BJ3LvQ66bERJ"
|
||||
+ "mKl5A/4uj3HoVxpb0vvyENfRqKMmGBISycY4MoH5uWfb23FffsT9r9KL6nJ4syLz"
|
||||
+ "aRR0gvcbcjkc9Z3epI7gr3jTrb4d8WPxsDbT/W1tv9bG/EHawomLcihtuUU68Uej"
|
||||
+ "6/wZot1XJqu2nQlku57+M/V2X1y26VKsipolPfja4uyBOOyvbP4DAwIDIBTxWjkC"
|
||||
+ "GGAWQO2jy9CTvLHJEoTO7moHrp1FxOVpQ8iJHyRqZzLllO26OzgohbiPYz8u9qCu"
|
||||
+ "lZ9Xn7QzRXJpYyBFY2hpZG5hIChEU0EgVGVzdCBLZXkpIDxlcmljQGJvdW5jeWNh"
|
||||
+ "c3RsZS5vcmc+iFkEExECABkFAj9HBzUECwcDAgMVAgMDFgIBAh4BAheAAAoJEM0j"
|
||||
+ "9enEyjRDAlwAnjTjjt57NKIgyym7OTCwzIU3xgFpAJ0VO5m5PfQKmGJRhaewLSZD"
|
||||
+ "4nXkHg==");
|
||||
|
||||
char[] dsaPass = "hello world".toCharArray();
|
||||
|
||||
byte[] rsaKeyRing = Base64.decode(
|
||||
"lQIEBEBXUNMBBADScQczBibewnbCzCswc/9ut8R0fwlltBRxMW0NMdKJY2LF"
|
||||
+ "7k2COeLOCIU95loJGV6ulbpDCXEO2Jyq8/qGw1qD3SCZNXxKs3GS8Iyh9Uwd"
|
||||
+ "VL07nMMYl5NiQRsFB7wOb86+94tYWgvikVA5BRP5y3+O3GItnXnpWSJyREUy"
|
||||
+ "6WI2QQAGKf4JAwIVmnRs4jtTX2DD05zy2mepEQ8bsqVAKIx7lEwvMVNcvg4Y"
|
||||
+ "8vFLh9Mf/uNciwL4Se/ehfKQ/AT0JmBZduYMqRU2zhiBmxj4cXUQ0s36ysj7"
|
||||
+ "fyDngGocDnM3cwPxaTF1ZRBQHSLewP7dqE7M73usFSz8vwD/0xNOHFRLKbsO"
|
||||
+ "RqDlLA1Cg2Yd0wWPS0o7+qqk9ndqrjjSwMM8ftnzFGjShAdg4Ca7fFkcNePP"
|
||||
+ "/rrwIH472FuRb7RbWzwXA4+4ZBdl8D4An0dwtfvAO+jCZSrLjmSpxEOveJxY"
|
||||
+ "GduyR4IA4lemvAG51YHTHd4NXheuEqsIkn1yarwaaj47lFPnxNOElOREMdZb"
|
||||
+ "nkWQb1jfgqO24imEZgrLMkK9bJfoDnlF4k6r6hZOp5FSFvc5kJB4cVo1QJl4"
|
||||
+ "pwCSdoU6luwCggrlZhDnkGCSuQUUW45NE7Br22NGqn4/gHs0KCsWbAezApGj"
|
||||
+ "qYUCfX1bcpPzUMzUlBaD5rz2vPeO58CDtBJ0ZXN0ZXIgPHRlc3RAdGVzdD6I"
|
||||
+ "sgQTAQIAHAUCQFdQ0wIbAwQLBwMCAxUCAwMWAgECHgECF4AACgkQs8JyyQfH"
|
||||
+ "97I1QgP8Cd+35maM2cbWV9iVRO+c5456KDi3oIUSNdPf1NQrCAtJqEUhmMSt"
|
||||
+ "QbdiaFEkPrORISI/2htXruYn0aIpkCfbUheHOu0sef7s6pHmI2kOQPzR+C/j"
|
||||
+ "8D9QvWsPOOso81KU2axUY8zIer64Uzqc4szMIlLw06c8vea27RfgjBpSCryw"
|
||||
+ "AgAA");
|
||||
|
||||
char[] rsaPass = "2002 Buffalo Sabres".toCharArray();
|
||||
|
||||
byte[] nullPacketsSubKeyBinding = Base64.decode(
|
||||
"iDYEGBECAAAAACp9AJ9PlJCrFpi+INwG7z61eku2Wg1HaQCgl33X5Egj+Kf7F9CXIWj2iFCvQDo=");
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
//
|
||||
// RSA tests
|
||||
//
|
||||
PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(rsaKeyRing, new JcaKeyFingerprintCalculator());
|
||||
PGPSecretKey secretKey = pgpPriv.getSecretKey();
|
||||
PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("SC").build(rsaPass));
|
||||
|
||||
try
|
||||
{
|
||||
testSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
|
||||
fail("RSA wrong key test failed.");
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
testSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
|
||||
fail("RSA V3 wrong key test failed.");
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
//
|
||||
// certifications
|
||||
//
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1).setProvider("SC"));
|
||||
|
||||
sGen.init(PGPSignature.KEY_REVOCATION, pgpPrivKey);
|
||||
|
||||
PGPSignature sig = sGen.generateCertification(secretKey.getPublicKey());
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), secretKey.getPublicKey());
|
||||
|
||||
if (!sig.verifyCertification(secretKey.getPublicKey()))
|
||||
{
|
||||
fail("revocation verification failed.");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing pgpDSAPriv = new PGPSecretKeyRing(dsaKeyRing, new JcaKeyFingerprintCalculator());
|
||||
PGPSecretKey secretDSAKey = pgpDSAPriv.getSecretKey();
|
||||
PGPPrivateKey pgpPrivDSAKey = secretDSAKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("SC").build(dsaPass));
|
||||
|
||||
sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).setProvider("SC"));
|
||||
|
||||
sGen.init(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey);
|
||||
|
||||
PGPSignatureSubpacketGenerator unhashedGen = new PGPSignatureSubpacketGenerator();
|
||||
PGPSignatureSubpacketGenerator hashedGen = new PGPSignatureSubpacketGenerator();
|
||||
|
||||
hashedGen.setSignatureExpirationTime(false, TEST_EXPIRATION_TIME);
|
||||
hashedGen.setSignerUserID(true, TEST_USER_ID);
|
||||
hashedGen.setPreferredCompressionAlgorithms(false, PREFERRED_COMPRESSION_ALGORITHMS);
|
||||
hashedGen.setPreferredHashAlgorithms(false, PREFERRED_HASH_ALGORITHMS);
|
||||
hashedGen.setPreferredSymmetricAlgorithms(false, PREFERRED_SYMMETRIC_ALGORITHMS);
|
||||
|
||||
sGen.setHashedSubpackets(hashedGen.generate());
|
||||
sGen.setUnhashedSubpackets(unhashedGen.generate());
|
||||
|
||||
sig = sGen.generateCertification(secretDSAKey.getPublicKey(), secretKey.getPublicKey());
|
||||
|
||||
byte[] sigBytes = sig.getEncoded();
|
||||
|
||||
PGPObjectFactory f = new PGPObjectFactory(sigBytes);
|
||||
|
||||
sig = ((PGPSignatureList) f.nextObject()).get(0);
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), secretDSAKey.getPublicKey());
|
||||
|
||||
if (!sig.verifyCertification(secretDSAKey.getPublicKey(), secretKey.getPublicKey()))
|
||||
{
|
||||
fail("subkey binding verification failed.");
|
||||
}
|
||||
|
||||
PGPSignatureSubpacketVector hashedPcks = sig.getHashedSubPackets();
|
||||
PGPSignatureSubpacketVector unhashedPcks = sig.getUnhashedSubPackets();
|
||||
|
||||
if (hashedPcks.size() != 6)
|
||||
{
|
||||
fail("wrong number of hashed packets found.");
|
||||
}
|
||||
|
||||
if (unhashedPcks.size() != 1)
|
||||
{
|
||||
fail("wrong number of unhashed packets found.");
|
||||
}
|
||||
|
||||
if (!hashedPcks.getSignerUserID().equals(TEST_USER_ID))
|
||||
{
|
||||
fail("test userid not matching");
|
||||
}
|
||||
|
||||
if (hashedPcks.getSignatureExpirationTime() != TEST_EXPIRATION_TIME)
|
||||
{
|
||||
fail("test signature expiration time not matching");
|
||||
}
|
||||
|
||||
if (unhashedPcks.getIssuerKeyID() != secretDSAKey.getKeyID())
|
||||
{
|
||||
fail("wrong issuer key ID found in certification");
|
||||
}
|
||||
|
||||
int[] prefAlgs = hashedPcks.getPreferredCompressionAlgorithms();
|
||||
preferredAlgorithmCheck("compression", PREFERRED_COMPRESSION_ALGORITHMS, prefAlgs);
|
||||
|
||||
prefAlgs = hashedPcks.getPreferredHashAlgorithms();
|
||||
preferredAlgorithmCheck("hash", PREFERRED_HASH_ALGORITHMS, prefAlgs);
|
||||
|
||||
prefAlgs = hashedPcks.getPreferredSymmetricAlgorithms();
|
||||
preferredAlgorithmCheck("symmetric", PREFERRED_SYMMETRIC_ALGORITHMS, prefAlgs);
|
||||
|
||||
int[] criticalHashed = hashedPcks.getCriticalTags();
|
||||
|
||||
if (criticalHashed.length != 1)
|
||||
{
|
||||
fail("wrong number of critical packets found.");
|
||||
}
|
||||
|
||||
if (criticalHashed[0] != SignatureSubpacketTags.SIGNER_USER_ID)
|
||||
{
|
||||
fail("wrong critical packet found in tag list.");
|
||||
}
|
||||
|
||||
//
|
||||
// no packets passed
|
||||
//
|
||||
sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).setProvider("SC"));
|
||||
|
||||
sGen.init(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey);
|
||||
|
||||
sGen.setHashedSubpackets(null);
|
||||
sGen.setUnhashedSubpackets(null);
|
||||
|
||||
sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey());
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), secretDSAKey.getPublicKey());
|
||||
|
||||
if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey()))
|
||||
{
|
||||
fail("subkey binding verification failed.");
|
||||
}
|
||||
|
||||
hashedPcks = sig.getHashedSubPackets();
|
||||
|
||||
if (hashedPcks.size() != 1)
|
||||
{
|
||||
fail("found wrong number of hashed packets");
|
||||
}
|
||||
|
||||
unhashedPcks = sig.getUnhashedSubPackets();
|
||||
|
||||
if (unhashedPcks.size() != 1)
|
||||
{
|
||||
fail("found wrong number of unhashed packets");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sig.verifyCertification(secretKey.getPublicKey());
|
||||
|
||||
fail("failed to detect non-key signature.");
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
//
|
||||
// override hash packets
|
||||
//
|
||||
sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1).setProvider("SC"));
|
||||
|
||||
sGen.init(PGPSignature.SUBKEY_BINDING, pgpPrivDSAKey);
|
||||
|
||||
hashedGen = new PGPSignatureSubpacketGenerator();
|
||||
|
||||
hashedGen.setSignatureCreationTime(false, new Date(0L));
|
||||
|
||||
sGen.setHashedSubpackets(hashedGen.generate());
|
||||
|
||||
sGen.setUnhashedSubpackets(null);
|
||||
|
||||
sig = sGen.generateCertification(TEST_USER_ID, secretKey.getPublicKey());
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), secretDSAKey.getPublicKey());
|
||||
|
||||
if (!sig.verifyCertification(TEST_USER_ID, secretKey.getPublicKey()))
|
||||
{
|
||||
fail("subkey binding verification failed.");
|
||||
}
|
||||
|
||||
hashedPcks = sig.getHashedSubPackets();
|
||||
|
||||
if (hashedPcks.size() != 1)
|
||||
{
|
||||
fail("found wrong number of hashed packets in override test");
|
||||
}
|
||||
|
||||
if (!hashedPcks.hasSubpacket(SignatureSubpacketTags.CREATION_TIME))
|
||||
{
|
||||
fail("hasSubpacket test for creation time failed");
|
||||
}
|
||||
|
||||
if (!hashedPcks.getSignatureCreationTime().equals(new Date(0L)))
|
||||
{
|
||||
fail("creation of overriden date failed.");
|
||||
}
|
||||
|
||||
prefAlgs = hashedPcks.getPreferredCompressionAlgorithms();
|
||||
preferredAlgorithmCheck("compression", NO_PREFERENCES, prefAlgs);
|
||||
|
||||
prefAlgs = hashedPcks.getPreferredHashAlgorithms();
|
||||
preferredAlgorithmCheck("hash", NO_PREFERENCES, prefAlgs);
|
||||
|
||||
prefAlgs = hashedPcks.getPreferredSymmetricAlgorithms();
|
||||
preferredAlgorithmCheck("symmetric", NO_PREFERENCES, prefAlgs);
|
||||
|
||||
if (hashedPcks.getKeyExpirationTime() != 0)
|
||||
{
|
||||
fail("unexpected key expiration time found");
|
||||
}
|
||||
|
||||
if (hashedPcks.getSignatureExpirationTime() != 0)
|
||||
{
|
||||
fail("unexpected signature expiration time found");
|
||||
}
|
||||
|
||||
if (hashedPcks.getSignerUserID() != null)
|
||||
{
|
||||
fail("unexpected signer user ID found");
|
||||
}
|
||||
|
||||
criticalHashed = hashedPcks.getCriticalTags();
|
||||
|
||||
if (criticalHashed.length != 0)
|
||||
{
|
||||
fail("critical packets found when none expected");
|
||||
}
|
||||
|
||||
unhashedPcks = sig.getUnhashedSubPackets();
|
||||
|
||||
if (unhashedPcks.size() != 1)
|
||||
{
|
||||
fail("found wrong number of unhashed packets in override test");
|
||||
}
|
||||
|
||||
//
|
||||
// general signatures
|
||||
//
|
||||
testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA256, secretKey.getPublicKey(), pgpPrivKey);
|
||||
testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA384, secretKey.getPublicKey(), pgpPrivKey);
|
||||
testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA512, secretKey.getPublicKey(), pgpPrivKey);
|
||||
testSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
testTextSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
|
||||
testTextSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
|
||||
testTextSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
|
||||
testTextSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
|
||||
|
||||
//
|
||||
// DSA Tests
|
||||
//
|
||||
pgpPriv = new PGPSecretKeyRing(dsaKeyRing, new JcaKeyFingerprintCalculator());
|
||||
secretKey = pgpPriv.getSecretKey();
|
||||
pgpPrivKey = secretKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("SC").build(dsaPass));
|
||||
|
||||
try
|
||||
{
|
||||
testSig(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
|
||||
fail("DSA wrong key test failed.");
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
testSigV3(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
|
||||
fail("DSA V3 wrong key test failed.");
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
// expected
|
||||
}
|
||||
|
||||
testSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
testSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey);
|
||||
testTextSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
|
||||
testTextSig(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
|
||||
testTextSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA_WITH_CRLF, TEST_DATA_WITH_CRLF);
|
||||
testTextSigV3(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1, secretKey.getPublicKey(), pgpPrivKey, TEST_DATA, TEST_DATA_WITH_CRLF);
|
||||
|
||||
// special cases
|
||||
//
|
||||
testMissingSubpackets(nullPacketsSubKeyBinding);
|
||||
|
||||
testMissingSubpackets(generateV3BinarySig(pgpPrivKey, PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1));
|
||||
|
||||
// keyflags
|
||||
testKeyFlagsValues();
|
||||
|
||||
testSubpacketGenerator();
|
||||
}
|
||||
|
||||
private void testSubpacketGenerator()
|
||||
{
|
||||
PGPSignatureSubpacketGenerator sGen = new PGPSignatureSubpacketGenerator();
|
||||
|
||||
String name1 = genString(64);
|
||||
String value1 = genString(72);
|
||||
|
||||
sGen.setNotationData(true, true, name1, value1);
|
||||
|
||||
PGPSignatureSubpacketVector sVec = sGen.generate();
|
||||
|
||||
NotationData[] nd = sVec.getNotationDataOccurences();
|
||||
|
||||
if (nd.length != 1 || !nd[0].isHumanReadable())
|
||||
{
|
||||
fail("length and readability test 1 failed");
|
||||
}
|
||||
|
||||
if (!nd[0].getNotationName().equals(name1) || !nd[0].getNotationValue().equals(value1))
|
||||
{
|
||||
fail("name/value test 1 failed");
|
||||
}
|
||||
|
||||
String name2 = genString(256);
|
||||
String value2 = genString(264);
|
||||
|
||||
sGen.setNotationData(true, false, name2, value2);
|
||||
|
||||
sVec = sGen.generate();
|
||||
|
||||
nd = sVec.getNotationDataOccurences();
|
||||
|
||||
if (nd.length != 2 || !nd[0].isHumanReadable() || nd[1].isHumanReadable())
|
||||
{
|
||||
fail("length and readability test 2 failed");
|
||||
}
|
||||
|
||||
if (!nd[0].getNotationName().equals(name1) || !nd[0].getNotationValue().equals(value1))
|
||||
{
|
||||
fail("name/value test 2.1 failed");
|
||||
}
|
||||
|
||||
if (!nd[1].getNotationName().equals(name2) || !nd[1].getNotationValue().equals(value2))
|
||||
{
|
||||
fail("name/value test 2.2 failed");
|
||||
}
|
||||
|
||||
String name3 = genString(0xffff);
|
||||
String value3 = genString(0xffff);
|
||||
|
||||
sGen.setNotationData(true, false, name3, value3);
|
||||
|
||||
sVec = sGen.generate();
|
||||
|
||||
nd = sVec.getNotationDataOccurences();
|
||||
|
||||
if (nd.length != 3 || !nd[0].isHumanReadable() || nd[1].isHumanReadable() || nd[2].isHumanReadable())
|
||||
{
|
||||
fail("length and readability test 3 failed");
|
||||
}
|
||||
|
||||
if (!nd[0].getNotationName().equals(name1) || !nd[0].getNotationValue().equals(value1))
|
||||
{
|
||||
fail("name/value test 3.1 failed");
|
||||
}
|
||||
|
||||
if (!nd[1].getNotationName().equals(name2) || !nd[1].getNotationValue().equals(value2))
|
||||
{
|
||||
fail("name/value test 3.2 failed");
|
||||
}
|
||||
|
||||
if (!nd[2].getNotationName().equals(name3) || !nd[2].getNotationValue().equals(value3))
|
||||
{
|
||||
fail("name/value test 3.3 failed");
|
||||
}
|
||||
|
||||
String name4 = genString(0xffff1);
|
||||
String value4 = genString(0xfffff);
|
||||
|
||||
try
|
||||
{
|
||||
sGen.setNotationData(true, false, name4, value4);
|
||||
fail("truncation occurs silently");
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
if (!"notationName exceeds maximum length.".equals(e.getMessage()))
|
||||
{
|
||||
fail("wrong message");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sGen.setNotationData(true, false, name3, value4);
|
||||
fail("truncation occurs silently");
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
if (!"notationValue exceeds maximum length.".equals(e.getMessage()))
|
||||
{
|
||||
fail("wrong message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String genString(int length)
|
||||
{
|
||||
char[] chars = new char[length];
|
||||
|
||||
for (int i = 0; i != length; i++)
|
||||
{
|
||||
chars[i] = (char)('a' + (i % 26));
|
||||
}
|
||||
|
||||
return new String(chars);
|
||||
}
|
||||
|
||||
private void testKeyFlagsValues()
|
||||
{
|
||||
checkValue(KeyFlags.CERTIFY_OTHER, 0x01);
|
||||
checkValue(KeyFlags.SIGN_DATA, 0x02);
|
||||
checkValue(KeyFlags.ENCRYPT_COMMS, 0x04);
|
||||
checkValue(KeyFlags.ENCRYPT_STORAGE, 0x08);
|
||||
checkValue(KeyFlags.SPLIT, 0x10);
|
||||
checkValue(KeyFlags.AUTHENTICATION, 0x20);
|
||||
checkValue(KeyFlags.SHARED, 0x80);
|
||||
|
||||
// yes this actually happens
|
||||
checkValue(new byte[] { 4, 0, 0, 0 }, 0x04);
|
||||
checkValue(new byte[] { 4, 0, 0 }, 0x04);
|
||||
checkValue(new byte[] { 4, 0 }, 0x04);
|
||||
checkValue(new byte[] { 4 }, 0x04);
|
||||
}
|
||||
|
||||
private void checkValue(int flag, int value)
|
||||
{
|
||||
KeyFlags f = new KeyFlags(true, flag);
|
||||
|
||||
if (f.getFlags() != value)
|
||||
{
|
||||
fail("flag value mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkValue(byte[] flag, int value)
|
||||
{
|
||||
KeyFlags f = new KeyFlags(true, flag);
|
||||
|
||||
if (f.getFlags() != value)
|
||||
{
|
||||
fail("flag value mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
private void testMissingSubpackets(byte[] signature)
|
||||
throws IOException
|
||||
{
|
||||
PGPObjectFactory f = new PGPObjectFactory(signature);
|
||||
Object obj = f.nextObject();
|
||||
|
||||
while (!(obj instanceof PGPSignatureList))
|
||||
{
|
||||
obj = f.nextObject();
|
||||
if (obj instanceof PGPLiteralData)
|
||||
{
|
||||
InputStream in = ((PGPLiteralData)obj).getDataStream();
|
||||
Streams.drain(in);
|
||||
}
|
||||
}
|
||||
|
||||
PGPSignature sig = ((PGPSignatureList)obj).get(0);
|
||||
|
||||
if (sig.getVersion() > 3)
|
||||
{
|
||||
PGPSignatureSubpacketVector v = sig.getHashedSubPackets();
|
||||
|
||||
if (v.getKeyExpirationTime() != 0)
|
||||
{
|
||||
fail("key expiration time not zero for missing subpackets");
|
||||
}
|
||||
|
||||
if (!sig.hasSubpackets())
|
||||
{
|
||||
fail("hasSubpackets() returns false with packets");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sig.getHashedSubPackets() != null)
|
||||
{
|
||||
fail("hashed sub packets found when none expected");
|
||||
}
|
||||
if (sig.getUnhashedSubPackets() != null)
|
||||
{
|
||||
fail("unhashed sub packets found when none expected");
|
||||
}
|
||||
|
||||
if (sig.hasSubpackets())
|
||||
{
|
||||
fail("hasSubpackets() returns true with no packets");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void preferredAlgorithmCheck(
|
||||
String type,
|
||||
int[] expected,
|
||||
int[] prefAlgs)
|
||||
{
|
||||
if (expected == null)
|
||||
{
|
||||
if (prefAlgs != null)
|
||||
{
|
||||
fail("preferences for " + type + " found when none expected");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prefAlgs.length != expected.length)
|
||||
{
|
||||
fail("wrong number of preferred " + type + " algorithms found");
|
||||
}
|
||||
|
||||
for (int i = 0; i != expected.length; i++)
|
||||
{
|
||||
if (expected[i] != prefAlgs[i])
|
||||
{
|
||||
fail("wrong algorithm found for " + type + ": expected " + expected[i] + " got " + prefAlgs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testSig(
|
||||
int encAlgorithm,
|
||||
int hashAlgorithm,
|
||||
PGPPublicKey pubKey,
|
||||
PGPPrivateKey privKey)
|
||||
throws Exception
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(TEST_DATA);
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(encAlgorithm, hashAlgorithm).setProvider("SC"));
|
||||
|
||||
sGen.init(PGPSignature.BINARY_DOCUMENT, privKey);
|
||||
sGen.generateOnePassVersion(false).encode(bOut);
|
||||
|
||||
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
|
||||
OutputStream lOut = lGen.open(
|
||||
new UncloseableOutputStream(bOut),
|
||||
PGPLiteralData.BINARY,
|
||||
"_CONSOLE",
|
||||
TEST_DATA.length * 2,
|
||||
new Date());
|
||||
|
||||
int ch;
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
lOut.write(TEST_DATA);
|
||||
sGen.update(TEST_DATA);
|
||||
|
||||
lGen.close();
|
||||
|
||||
sGen.generate().encode(bOut);
|
||||
|
||||
verifySignature(bOut.toByteArray(), hashAlgorithm, pubKey, TEST_DATA);
|
||||
}
|
||||
|
||||
private void testTextSig(
|
||||
int encAlgorithm,
|
||||
int hashAlgorithm,
|
||||
PGPPublicKey pubKey,
|
||||
PGPPrivateKey privKey,
|
||||
byte[] data,
|
||||
byte[] canonicalData)
|
||||
throws Exception
|
||||
{
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(encAlgorithm, HashAlgorithmTags.SHA1).setProvider("SC"));
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data);
|
||||
Date creationTime = new Date();
|
||||
|
||||
sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privKey);
|
||||
sGen.generateOnePassVersion(false).encode(bOut);
|
||||
|
||||
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
|
||||
OutputStream lOut = lGen.open(
|
||||
new UncloseableOutputStream(bOut),
|
||||
PGPLiteralData.TEXT,
|
||||
"_CONSOLE",
|
||||
data.length * 2,
|
||||
creationTime);
|
||||
|
||||
int ch;
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
lOut.write(data);
|
||||
sGen.update(data);
|
||||
|
||||
lGen.close();
|
||||
|
||||
PGPSignature sig = sGen.generate();
|
||||
|
||||
if (sig.getCreationTime().getTime() == 0)
|
||||
{
|
||||
fail("creation time not set in v4 signature");
|
||||
}
|
||||
|
||||
sig.encode(bOut);
|
||||
|
||||
verifySignature(bOut.toByteArray(), hashAlgorithm, pubKey, canonicalData);
|
||||
}
|
||||
|
||||
private void testSigV3(
|
||||
int encAlgorithm,
|
||||
int hashAlgorithm,
|
||||
PGPPublicKey pubKey,
|
||||
PGPPrivateKey privKey)
|
||||
throws Exception
|
||||
{
|
||||
byte[] bytes = generateV3BinarySig(privKey, encAlgorithm, hashAlgorithm);
|
||||
|
||||
verifySignature(bytes, hashAlgorithm, pubKey, TEST_DATA);
|
||||
}
|
||||
|
||||
private byte[] generateV3BinarySig(PGPPrivateKey privKey, int encAlgorithm, int hashAlgorithm)
|
||||
throws Exception
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(TEST_DATA);
|
||||
PGPV3SignatureGenerator sGen = new PGPV3SignatureGenerator(new JcaPGPContentSignerBuilder(encAlgorithm, hashAlgorithm).setProvider("SC"));
|
||||
|
||||
sGen.init(PGPSignature.BINARY_DOCUMENT, privKey);
|
||||
sGen.generateOnePassVersion(false).encode(bOut);
|
||||
|
||||
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
|
||||
OutputStream lOut = lGen.open(
|
||||
new UncloseableOutputStream(bOut),
|
||||
PGPLiteralData.BINARY,
|
||||
"_CONSOLE",
|
||||
TEST_DATA.length * 2,
|
||||
new Date());
|
||||
|
||||
int ch;
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
lOut.write(TEST_DATA);
|
||||
sGen.update(TEST_DATA);
|
||||
|
||||
lGen.close();
|
||||
|
||||
sGen.generate().encode(bOut);
|
||||
|
||||
return bOut.toByteArray();
|
||||
}
|
||||
|
||||
private void testTextSigV3(
|
||||
int encAlgorithm,
|
||||
int hashAlgorithm,
|
||||
PGPPublicKey pubKey,
|
||||
PGPPrivateKey privKey,
|
||||
byte[] data,
|
||||
byte[] canonicalData)
|
||||
throws Exception
|
||||
{
|
||||
PGPV3SignatureGenerator sGen = new PGPV3SignatureGenerator(new JcaPGPContentSignerBuilder(encAlgorithm, HashAlgorithmTags.SHA1).setProvider("SC"));
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data);
|
||||
|
||||
sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privKey);
|
||||
sGen.generateOnePassVersion(false).encode(bOut);
|
||||
|
||||
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
|
||||
OutputStream lOut = lGen.open(
|
||||
new UncloseableOutputStream(bOut),
|
||||
PGPLiteralData.TEXT,
|
||||
"_CONSOLE",
|
||||
data.length * 2,
|
||||
new Date());
|
||||
|
||||
int ch;
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
lOut.write(data);
|
||||
sGen.update(data);
|
||||
|
||||
lGen.close();
|
||||
|
||||
PGPSignature sig = sGen.generate();
|
||||
|
||||
if (sig.getCreationTime().getTime() == 0)
|
||||
{
|
||||
fail("creation time not set in v3 signature");
|
||||
}
|
||||
|
||||
sig.encode(bOut);
|
||||
|
||||
verifySignature(bOut.toByteArray(), hashAlgorithm, pubKey, canonicalData);
|
||||
}
|
||||
|
||||
private void verifySignature(
|
||||
byte[] encodedSig,
|
||||
int hashAlgorithm,
|
||||
PGPPublicKey pubKey,
|
||||
byte[] original)
|
||||
throws IOException, PGPException, NoSuchProviderException, SignatureException
|
||||
{
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(encodedSig);
|
||||
PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
PGPOnePassSignature ops = p1.get(0);
|
||||
PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject();
|
||||
InputStream dIn = p2.getInputStream();
|
||||
|
||||
ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKey);
|
||||
|
||||
int ch;
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
PGPSignature sig = p3.get(0);
|
||||
|
||||
Date creationTime = sig.getCreationTime();
|
||||
Date now = new Date();
|
||||
|
||||
// Check creationTime is recent
|
||||
if (creationTime.after(now)
|
||||
|| creationTime.before(new Date(now.getTime() - 10 * 60 * 1000)))
|
||||
{
|
||||
fail("bad creation time in signature: " + creationTime);
|
||||
}
|
||||
|
||||
if (sig.getKeyID() != pubKey.getKeyID())
|
||||
{
|
||||
fail("key id mismatch in signature");
|
||||
}
|
||||
|
||||
if (!ops.verify(sig))
|
||||
{
|
||||
fail("Failed generated signature check - " + hashAlgorithm);
|
||||
}
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKey);
|
||||
|
||||
for (int i = 0; i != original.length; i++)
|
||||
{
|
||||
sig.update(original[i]);
|
||||
}
|
||||
|
||||
sig.update(original);
|
||||
|
||||
if (!sig.verify())
|
||||
{
|
||||
fail("Failed generated signature check against original data");
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPSignatureTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPSignatureTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.Security;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRingCollection;
|
||||
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculatorProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||
|
||||
public class PGPUnicodeTest
|
||||
extends TestCase
|
||||
{
|
||||
private static final String TEST_DATA_HOME = "bc.test.data.home";
|
||||
|
||||
public void setUp()
|
||||
{
|
||||
if (Security.getProvider("SC") == null)
|
||||
{
|
||||
Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());
|
||||
}
|
||||
}
|
||||
|
||||
public void test_key(BigInteger keyId, String passphrase)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
PGPSecretKeyRingCollection secretKeyRing = loadSecretKeyCollection("secring.gpg");
|
||||
|
||||
PGPSecretKeyRing secretKey = secretKeyRing.getSecretKeyRing(keyId.longValue());
|
||||
assertNotNull("Could not locate secret keyring with Id=" + keyId.toString(16), secretKey);
|
||||
|
||||
PGPSecretKey key = secretKey.getSecretKey();
|
||||
assertNotNull("Could not locate secret key!", key);
|
||||
|
||||
try
|
||||
{
|
||||
PGPDigestCalculatorProvider calcProvider = new JcaPGPDigestCalculatorProviderBuilder()
|
||||
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build();
|
||||
|
||||
PBESecretKeyDecryptor decryptor = new JcePBESecretKeyDecryptorBuilder(calcProvider)
|
||||
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passphrase.toCharArray());
|
||||
|
||||
PGPPrivateKey privateKey = key.extractPrivateKey(decryptor);
|
||||
|
||||
assertTrue(privateKey.getKeyID() == keyId.longValue());
|
||||
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
throw new PGPException("Password incorrect!", e);
|
||||
}
|
||||
|
||||
// all fine!
|
||||
}
|
||||
|
||||
public void test_UmlautPassphrase()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
BigInteger keyId = new BigInteger("362961283C48132B9F14C5C3EC87272EFCB986D2", 16);
|
||||
|
||||
String passphrase = new String("Händle".getBytes("UTF-16"), "UTF-16");
|
||||
// FileInputStream passwordFile = new FileInputStream("testdata/passphrase_for_test.txt");
|
||||
// byte[] password = new byte[passwordFile.available()];
|
||||
// passwordFile.read(password);
|
||||
// passwordFile.close();
|
||||
// String passphrase = new String(password);
|
||||
|
||||
test_key(keyId, passphrase);
|
||||
|
||||
// all fine!
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void test_ASCIIPassphrase()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
BigInteger keyId = new BigInteger("A392B7310C64026022405257AA2AAAC7CB417459", 16);
|
||||
|
||||
String passphrase = "Admin123";
|
||||
|
||||
test_key(keyId, passphrase);
|
||||
|
||||
// all fine!
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void test_CyrillicPassphrase()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
BigInteger keyId = new BigInteger("B7773AF32BE4EC1806B1BACC4680E7F3960C44E7", 16);
|
||||
|
||||
// XXX The password text file must not have the UTF-8 BOM !
|
||||
// Ref: http://stackoverflow.com/questions/2223882/whats-different-between-utf-8-and-utf-8-without-bom
|
||||
|
||||
FileInputStream passwordFile = new FileInputStream(getDataHome() + "passphrase_cyr.txt");
|
||||
Reader reader = new InputStreamReader(passwordFile, Charset.forName("UTF-8"));
|
||||
BufferedReader in = new BufferedReader(reader);
|
||||
String passphrase = in.readLine();
|
||||
in.close();
|
||||
passwordFile.close();
|
||||
|
||||
test_key(keyId, passphrase);
|
||||
|
||||
// all fine!
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private PGPSecretKeyRingCollection loadSecretKeyCollection(
|
||||
String keyName)
|
||||
throws Exception
|
||||
{
|
||||
FileInputStream fIn = new FileInputStream(getDataHome() + keyName);
|
||||
|
||||
return new PGPSecretKeyRingCollection(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/unicode/";
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
throws Exception
|
||||
{
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
throws Exception
|
||||
{
|
||||
TestSuite suite = new TestSuite("Unicode Password tests");
|
||||
|
||||
suite.addTestSuite(PGPUnicodeTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import org.spongycastle.util.test.Test;
|
||||
import org.spongycastle.util.test.TestResult;
|
||||
|
||||
public class RegressionTest
|
||||
{
|
||||
public static Test[] tests = {
|
||||
new BcPGPKeyRingTest(),
|
||||
new PGPKeyRingTest(),
|
||||
new BcPGPRSATest(),
|
||||
new PGPRSATest(),
|
||||
new BcPGPDSATest(),
|
||||
new PGPDSATest(),
|
||||
new BcPGPDSAElGamalTest(),
|
||||
new PGPDSAElGamalTest(),
|
||||
new BcPGPPBETest(),
|
||||
new PGPPBETest(),
|
||||
new PGPMarkerTest(),
|
||||
new PGPPacketTest(),
|
||||
new PGPArmoredTest(),
|
||||
new PGPSignatureTest(),
|
||||
new PGPClearSignedSignatureTest(),
|
||||
new PGPCompressionTest(),
|
||||
new PGPNoPrivateKeyTest(),
|
||||
new PGPECDSATest(),
|
||||
new PGPECDHTest(),
|
||||
new PGPParsingTest()
|
||||
};
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());
|
||||
|
||||
for (int i = 0; i != tests.length; i++)
|
||||
{
|
||||
TestResult result = tests[i].perform();
|
||||
System.out.println(result);
|
||||
if (result.getException() != null)
|
||||
{
|
||||
result.getException().printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,564 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameterGenerator;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.crypto.spec.DHParameterSpec;
|
||||
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.crypto.AsymmetricBlockCipher;
|
||||
import org.spongycastle.crypto.encodings.PKCS1Encoding;
|
||||
import org.spongycastle.crypto.engines.ElGamalEngine;
|
||||
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.jce.spec.ElGamalParameterSpec;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPGPKeyConverter;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
||||
import org.spongycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class BcPGPDSAElGamalTest
|
||||
extends SimpleTest
|
||||
{
|
||||
|
||||
byte[] testPubKeyRing =
|
||||
Base64.decode(
|
||||
"mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv"
|
||||
+ "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH"
|
||||
+ "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK"
|
||||
+ "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2"
|
||||
+ "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH"
|
||||
+ "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB"
|
||||
+ "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2"
|
||||
+ "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN"
|
||||
+ "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+"
|
||||
+ "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC"
|
||||
+ "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk"
|
||||
+ "JVCXP0/Szm05GB+WN+MOCT2wAgAA");
|
||||
|
||||
byte[] testPrivKeyRing =
|
||||
Base64.decode(
|
||||
"lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r"
|
||||
+ "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF"
|
||||
+ "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn"
|
||||
+ "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn"
|
||||
+ "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r"
|
||||
+ "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj"
|
||||
+ "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya"
|
||||
+ "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF"
|
||||
+ "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq"
|
||||
+ "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk"
|
||||
+ "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs"
|
||||
+ "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs"
|
||||
+ "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA"
|
||||
+ "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg"
|
||||
+ "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA");
|
||||
|
||||
byte[] encMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c"
|
||||
+ "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o"
|
||||
+ "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv"
|
||||
+ "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f"
|
||||
+ "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy"
|
||||
+ "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL"
|
||||
+ "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp"
|
||||
+ "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw==");
|
||||
|
||||
byte[] signedAndEncMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn"
|
||||
+ "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy"
|
||||
+ "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C"
|
||||
+ "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T"
|
||||
+ "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum"
|
||||
+ "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK"
|
||||
+ "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3"
|
||||
+ "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm"
|
||||
+ "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht"
|
||||
+ "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM=");
|
||||
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKey pubKey;
|
||||
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing);
|
||||
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject();
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
if (pubKey.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing, new BcKeyFingerprintCalculator());
|
||||
PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
//
|
||||
// signature generation
|
||||
//
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.DSA, PGPUtil.SHA1));
|
||||
|
||||
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(
|
||||
cGen.open(new UncloseableOutputStream(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);
|
||||
|
||||
cGen.close();
|
||||
|
||||
//
|
||||
// verify generated signature
|
||||
//
|
||||
pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
|
||||
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();
|
||||
if (!p2.getModificationTime().equals(testDate))
|
||||
{
|
||||
fail("Modification time not preserved");
|
||||
}
|
||||
|
||||
InputStream dIn = p2.getInputStream();
|
||||
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pubKey);
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed generated signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// test encryption
|
||||
//
|
||||
|
||||
//
|
||||
// find a key suitable for encryption
|
||||
//
|
||||
long pgpKeyID = 0;
|
||||
AsymmetricKeyParameter pKey = null;
|
||||
BcPGPKeyConverter keyConverter = new BcPGPKeyConverter();
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT
|
||||
|| pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL)
|
||||
{
|
||||
pKey = keyConverter.getPublicKey(pgpKey);
|
||||
pgpKeyID = pgpKey.getKeyID();
|
||||
if (pgpKey.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
//
|
||||
// verify the key
|
||||
//
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
AsymmetricBlockCipher c = new PKCS1Encoding(new ElGamalEngine());
|
||||
|
||||
c.init(true, pKey);
|
||||
|
||||
byte[] in = "hello world".getBytes();
|
||||
|
||||
byte[] out = c.processBlock(in, 0, in.length);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
c.init(false, keyConverter.getPrivateKey(pgpPrivKey));
|
||||
|
||||
out = c.processBlock(out, 0, out.length);
|
||||
|
||||
if (!areEqual(in, out))
|
||||
{
|
||||
fail("decryption failed.");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypted message
|
||||
//
|
||||
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' };
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(encMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
InputStream inLd = ld.getDataStream();
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
fail("wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// signed and encrypted message
|
||||
//
|
||||
pgpF = new PGPObjectFactory(signedAndEncMessage);
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
|
||||
ops = p1.get(0);
|
||||
|
||||
ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
inLd = ld.getDataStream();
|
||||
|
||||
//
|
||||
// note: we use the DSA public key here.
|
||||
//
|
||||
ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey());
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
fail("Failed signature check");
|
||||
}
|
||||
|
||||
if (!areEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
fail("wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypt
|
||||
//
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom()));
|
||||
PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey();
|
||||
|
||||
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK));
|
||||
|
||||
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), bOut.toByteArray().length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
|
||||
|
||||
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
bOut.reset();
|
||||
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
out = bOut.toByteArray();
|
||||
|
||||
if (!areEqual(out, text))
|
||||
{
|
||||
fail("wrong plain text in generated packet");
|
||||
}
|
||||
|
||||
//
|
||||
// use of PGPKeyPair
|
||||
//
|
||||
BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
|
||||
BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ElGamal", "SC");
|
||||
|
||||
ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g);
|
||||
|
||||
kpg.initialize(512);
|
||||
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.ELGAMAL_GENERAL , kp.getPublic(), kp.getPrivate(), new Date());
|
||||
|
||||
PGPPublicKey k1 = pgpKp.getPublicKey();
|
||||
|
||||
PGPPrivateKey k2 = pgpKp.getPrivateKey();
|
||||
|
||||
|
||||
|
||||
// Test bug with ElGamal P size != 0 mod 8 (don't use these sizes at home!)
|
||||
SecureRandom random = new SecureRandom();
|
||||
for (int pSize = 257; pSize < 264; ++pSize)
|
||||
{
|
||||
// Generate some parameters of the given size
|
||||
AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "SC");
|
||||
a.init(pSize, new SecureRandom());
|
||||
AlgorithmParameters params = a.generateParameters();
|
||||
|
||||
DHParameterSpec elP = (DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ElGamal", "SC");
|
||||
|
||||
keyGen.initialize(512);
|
||||
|
||||
|
||||
// Run a short encrypt/decrypt test with random key for the given parameters
|
||||
kp = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair elGamalKeyPair = new PGPKeyPair(
|
||||
PublicKeyAlgorithmTags.ELGAMAL_GENERAL, kp, new Date());
|
||||
|
||||
cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(random));
|
||||
|
||||
puK = elGamalKeyPair.getPublicKey();
|
||||
|
||||
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK));
|
||||
|
||||
cbOut = new ByteArrayOutputStream();
|
||||
|
||||
cOut = cPk.open(cbOut, text.length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = elGamalKeyPair.getPrivateKey();
|
||||
|
||||
// Note: This is where an exception would be expected if the P size causes problems
|
||||
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
|
||||
|
||||
ByteArrayOutputStream dec = new ByteArrayOutputStream();
|
||||
|
||||
int b;
|
||||
while ((b = clear.read()) >= 0)
|
||||
{
|
||||
dec.write(b);
|
||||
}
|
||||
|
||||
byte[] decText = dec.toByteArray();
|
||||
|
||||
if (!areEqual(text, decText))
|
||||
{
|
||||
fail("decrypted message incorrect");
|
||||
}
|
||||
}
|
||||
|
||||
// check sub key encoding
|
||||
|
||||
it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (!pgpKey.isMasterKey())
|
||||
{
|
||||
byte[] kEnc = pgpKey.getEncoded();
|
||||
|
||||
PGPObjectFactory objF = new PGPObjectFactory(kEnc);
|
||||
|
||||
PGPPublicKey k = (PGPPublicKey)objF.nextObject();
|
||||
|
||||
pKey = keyConverter.getPublicKey(k);
|
||||
pgpKeyID = k.getKeyID();
|
||||
if (k.getBitStrength() != 1024)
|
||||
{
|
||||
fail("failed - key strength reported incorrectly.");
|
||||
}
|
||||
|
||||
if (objF.nextObject() != null)
|
||||
{
|
||||
fail("failed - stream not fully parsed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (PGPException e)
|
||||
{
|
||||
fail("exception: " + e.getMessage(), e.getUnderlyingException());
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPDSAElGamalTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new BcPGPDSAElGamalTest());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,451 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.jce.spec.ElGamalParameterSpec;
|
||||
import org.spongycastle.openpgp.PGPCompressedData;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPCompressedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignature;
|
||||
import org.spongycastle.openpgp.PGPOnePassSignatureList;
|
||||
import org.spongycastle.openpgp.PGPPrivateKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPSignatureList;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTestResult;
|
||||
import org.spongycastle.util.test.Test;
|
||||
import org.spongycastle.util.test.TestResult;
|
||||
|
||||
public class PGPDSAElGamalTest implements Test
|
||||
{
|
||||
|
||||
byte[] testPubKeyRing =
|
||||
Base64.decode(
|
||||
"mQGiBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzLQ3RXJpYyBILiBFY2hpZG5hICh0ZXN0IGtleSBv"
|
||||
+ "bmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3JnPohZBBMRAgAZBQJAEfI2BAsH"
|
||||
+ "AwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgnkDdnAKC/CfLWikSBdbngY6OK"
|
||||
+ "5UN3+o7q1ACcDRqjT3yjBU3WmRUNlxBg3tSuljmwAgAAuQENBEAR8jgQBAC2"
|
||||
+ "kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVjei/3yVfT/fuCVtGHOmYLEBqH"
|
||||
+ "bn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya43RtcubqMc7eKw4k0JnnoYgB"
|
||||
+ "ocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhFBYfaBmGU75cQgwADBQP/XxR2"
|
||||
+ "qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSqAi0zeAMdrRsBN7kyzYVVpWwN"
|
||||
+ "5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxkbipnwh2RR4xCXFDhJrJFQUm+"
|
||||
+ "4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXsNi1tRbTmRhqIRgQYEQIABgUC"
|
||||
+ "QBHyOAAKCRAOtk6iUOgnkBStAJoCZBVM61B1LG2xip294MZecMtCwQCbBbsk"
|
||||
+ "JVCXP0/Szm05GB+WN+MOCT2wAgAA");
|
||||
|
||||
byte[] testPrivKeyRing =
|
||||
Base64.decode(
|
||||
"lQHhBEAR8jYRBADNifuSopd20JOQ5x30ljIaY0M6927+vo09NeNxS3KqItba"
|
||||
+ "nz9o5e2aqdT0W1xgdHYZmdElOHTTsugZxdXTEhghyxoo3KhVcNnTABQyrrvX"
|
||||
+ "qouvmP2fEDEw0Vpyk+90BpyY9YlgeX/dEA8OfooRLCJde/iDTl7r9FT+mts8"
|
||||
+ "g3azjwCgx+pOLD9LPBF5E4FhUOdXISJ0f4EEAKXSOi9nZzajpdhe8W2ZL9gc"
|
||||
+ "BpzZi6AcrRZBHOEMqd69gtUxA4eD8xycUQ42yH89imEcwLz8XdJ98uHUxGJi"
|
||||
+ "qp6hq4oakmw8GQfiL7yQIFgaM0dOAI9Afe3m84cEYZsoAFYpB4/s9pVMpPRH"
|
||||
+ "NsVspU0qd3NHnSZ0QXs8L8DXGO1uBACjDUj+8GsfDCIP2QF3JC+nPUNa0Y5t"
|
||||
+ "wKPKl+T8hX/0FBD7fnNeC6c9j5Ir/Fp/QtdaDAOoBKiyNLh1JaB1NY6US5zc"
|
||||
+ "qFks2seZPjXEiE6OIDXYra494mjNKGUobA4hqT2peKWXt/uBcuL1mjKOy8Qf"
|
||||
+ "JxgEd0MOcGJO+1PFFZWGzP4DAwLeUcsVxIC2s2Bb9ab2XD860TQ2BI2rMD/r"
|
||||
+ "7/psx9WQ+Vz/aFAT3rXkEJ97nFeqEACgKmUCAEk9939EwLQ3RXJpYyBILiBF"
|
||||
+ "Y2hpZG5hICh0ZXN0IGtleSBvbmx5KSA8ZXJpY0Bib3VuY3ljYXN0bGUub3Jn"
|
||||
+ "PohZBBMRAgAZBQJAEfI2BAsHAwIDFQIDAxYCAQIeAQIXgAAKCRAOtk6iUOgn"
|
||||
+ "kDdnAJ9Ala3OcwEV1DbK906CheYWo4zIQwCfUqUOLMp/zj6QAk02bbJAhV1r"
|
||||
+ "sAewAgAAnQFYBEAR8jgQBAC2kr57iuOaV7Ga1xcU14MNbKcA0PVembRCjcVj"
|
||||
+ "ei/3yVfT/fuCVtGHOmYLEBqHbn5aaJ0P/6vMbLCHKuN61NZlts+LEctfwoya"
|
||||
+ "43RtcubqMc7eKw4k0JnnoYgBocLXOtloCb7jfubOsnfORvrUkK0+Ne6anRhF"
|
||||
+ "BYfaBmGU75cQgwADBQP/XxR2qGHiwn+0YiMioRDRiIAxp6UiC/JQIri2AKSq"
|
||||
+ "Ai0zeAMdrRsBN7kyzYVVpWwN5u13gPdQ2HnJ7d4wLWAuizUdKIQxBG8VoCxk"
|
||||
+ "bipnwh2RR4xCXFDhJrJFQUm+4nKx9JvAmZTBIlI5Wsi5qxst/9p5MgP3flXs"
|
||||
+ "Ni1tRbTmRhr+AwMC3lHLFcSAtrNg/EiWFLAnKNXH27zjwuhje8u2r+9iMTYs"
|
||||
+ "GjbRxaxRY0GKRhttCwqe2BC0lHhzifdlEcc9yjIjuKfepG2fnnSIRgQYEQIA"
|
||||
+ "BgUCQBHyOAAKCRAOtk6iUOgnkBStAJ9HFejVtVJ/A9LM/mDPe0ExhEXt/QCg"
|
||||
+ "m/KM7hJ/JrfnLQl7IaZsdg1F6vCwAgAA");
|
||||
|
||||
byte[] encMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP/dgCkMtPB6mIgjFvNiotjaoh4sAXf4vFNkSeehQ2c"
|
||||
+ "r+IMt9CgIYodJI3FoJXxOuTcwesqTp5hRzgUBJS0adLDJwcNubFMy0M2tp5o"
|
||||
+ "KTWpXulIiqyO6f5jI/oEDHPzFoYgBmR4x72l/YpMy8UoYGtNxNvR7LVOfqJv"
|
||||
+ "uDY/71KMtPQEAIadOWpf1P5Td+61Zqn2VH2UV7H8eI6hGa6Lsy4sb9iZNE7f"
|
||||
+ "c+spGJlgkiOt8TrQoq3iOK9UN9nHZLiCSIEGCzsEn3uNuorD++Qs065ij+Oy"
|
||||
+ "36TKeuJ+38CfT7u47dEshHCPqWhBKEYrxZWHUJU/izw2Q1Yxd2XRxN+nafTL"
|
||||
+ "X1fQ0lABQUASa18s0BkkEERIdcKQXVLEswWcGqWNv1ZghC7xO2VDBX4HrPjp"
|
||||
+ "drjL63p2UHzJ7/4gPWGGtnqq1Xita/1mrImn7pzLThDWiT55vjw6Hw==");
|
||||
|
||||
byte[] signedAndEncMessage =
|
||||
Base64.decode(
|
||||
"hQEOAynbo4lhNjcHEAP+K20MVhzdX57hf/cU8TH0prP0VePr9mmeBedzqqMn"
|
||||
+ "fp2p8Zb68zmcMlI/WiL5XMNLYRmCgEcXyWbKdP/XV9m9LDBe1CMAGrkCeGBy"
|
||||
+ "je69IQQ5LS9vDPyEMF4iAAv/EqACjqHkizdY/a/FRx/t2ioXYdEC2jA6kS9C"
|
||||
+ "McpsNz16DE8EAIk3uKn4bGo/+15TXkyFYzW5Cf71SfRoHNmU2zAI93zhjN+T"
|
||||
+ "B7mGJwWXzsMkIO6FkMU5TCSrwZS3DBWCIaJ6SYoaawE/C/2j9D7bX1Jv8kum"
|
||||
+ "4cq+eZM7z6JYs6xend+WAwittpUxbEiyC2AJb3fBSXPAbLqWd6J6xbZZ7GDK"
|
||||
+ "r2Ca0pwBxwGhbMDyi2zpHLzw95H7Ah2wMcGU6kMLB+hzBSZ6mSTGFehqFQE3"
|
||||
+ "2BnAj7MtnbghiefogacJ891jj8Y2ggJeKDuRz8j2iICaTOy+Y2rXnnJwfYzm"
|
||||
+ "BMWcd2h1C5+UeBJ9CrrLniCCI8s5u8z36Rno3sfhBnXdRmWSxExXtocbg1Ht"
|
||||
+ "dyiThf6TK3W29Yy/T6x45Ws5zOasaJdsFKM=");
|
||||
char[] pass = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
private boolean notEqual(
|
||||
byte[] b1,
|
||||
byte[] b2)
|
||||
{
|
||||
if (b1.length != b2.length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i != b2.length; i++)
|
||||
{
|
||||
if (b1[i] != b2[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TestResult perform()
|
||||
{
|
||||
try
|
||||
{
|
||||
String file = null;
|
||||
KeyFactory fact = KeyFactory.getInstance("DSA", "SC");
|
||||
PGPPublicKey pubKey = null;
|
||||
PrivateKey privKey = null;
|
||||
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing);
|
||||
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)pgpFact.nextObject();
|
||||
|
||||
pubKey = pgpPub.getPublicKey();
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing);
|
||||
PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "SC");
|
||||
|
||||
//
|
||||
// signature generation
|
||||
//
|
||||
String data = "hello world!";
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
|
||||
PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "SC");
|
||||
|
||||
sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
|
||||
|
||||
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
|
||||
PGPCompressedData.ZIP);
|
||||
|
||||
BCPGOutputStream bcOut = new BCPGOutputStream(cGen.open(bOut));
|
||||
|
||||
sGen.generateOnePassVersion(false).encode(bcOut);
|
||||
|
||||
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
|
||||
OutputStream lOut = lGen.open(bcOut, PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, new Date());
|
||||
int ch;
|
||||
|
||||
while ((ch = testIn.read()) >= 0)
|
||||
{
|
||||
lOut.write(ch);
|
||||
sGen.update((byte)ch);
|
||||
}
|
||||
|
||||
sGen.generate().encode(bcOut);
|
||||
|
||||
lGen.close();
|
||||
|
||||
cGen.close();
|
||||
|
||||
//
|
||||
// verify generated signature
|
||||
//
|
||||
pgpFact = new PGPObjectFactory(bOut.toByteArray());
|
||||
|
||||
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(pubKey, "SC");
|
||||
|
||||
while ((ch = dIn.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
}
|
||||
|
||||
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": Failed generated signature check");
|
||||
}
|
||||
|
||||
//
|
||||
// test encryption
|
||||
//
|
||||
|
||||
//
|
||||
// find a key sutiable for encryption
|
||||
//
|
||||
long pgpKeyID = 0;
|
||||
PublicKey pKey = null;
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pgpKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT
|
||||
|| pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL)
|
||||
{
|
||||
pKey = pgpKey.getKey("SC");
|
||||
pgpKeyID = pgpKey.getKeyID();
|
||||
|
||||
//
|
||||
// verify the key
|
||||
//
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Cipher c = Cipher.getInstance("ElGamal/None/PKCS1Padding", "SC");
|
||||
|
||||
c.init(Cipher.ENCRYPT_MODE, pKey);
|
||||
|
||||
byte[] in = "hello world".getBytes();
|
||||
|
||||
byte[] out = c.doFinal(in);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "SC");
|
||||
|
||||
c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey());
|
||||
|
||||
out = c.doFinal(out);
|
||||
|
||||
if (notEqual(in, out))
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": decryption failed.");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypted message
|
||||
//
|
||||
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' };
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(encMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
InputStream inLd = ld.getDataStream();
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
if (notEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// signed and encrypted message
|
||||
//
|
||||
pgpF = new PGPObjectFactory(signedAndEncMessage);
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
pgpFact = new PGPObjectFactory(clear);
|
||||
|
||||
c1 = (PGPCompressedData)pgpFact.nextObject();
|
||||
|
||||
pgpFact = new PGPObjectFactory(c1.getDataStream());
|
||||
|
||||
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
|
||||
|
||||
ops = p1.get(0);
|
||||
|
||||
ld = (PGPLiteralData)pgpFact.nextObject();
|
||||
|
||||
bOut = new ByteArrayOutputStream();
|
||||
|
||||
if (!ld.getFileName().equals("test.txt"))
|
||||
{
|
||||
throw new RuntimeException("wrong filename in packet");
|
||||
}
|
||||
|
||||
inLd = ld.getDataStream();
|
||||
|
||||
//
|
||||
// note: we use the DSA public key here.
|
||||
//
|
||||
ops.initVerify(pgpPub.getPublicKey(), "SC");
|
||||
|
||||
while ((ch = inLd.read()) >= 0)
|
||||
{
|
||||
ops.update((byte)ch);
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
p3 = (PGPSignatureList)pgpFact.nextObject();
|
||||
|
||||
if (!ops.verify(p3.get(0)))
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": Failed signature check");
|
||||
}
|
||||
|
||||
if (notEqual(bOut.toByteArray(), text))
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong plain text in decrypted packet");
|
||||
}
|
||||
|
||||
//
|
||||
// encrypt
|
||||
//
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(SymmetricKeyAlgorithmTags.TRIPLE_DES, new SecureRandom(), "SC");
|
||||
PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey();
|
||||
|
||||
cPk.addMethod(puK);
|
||||
|
||||
OutputStream cOut = cPk.open(cbOut, bOut.toByteArray().length);
|
||||
|
||||
cOut.write(text);
|
||||
|
||||
cOut.close();
|
||||
|
||||
pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "SC");
|
||||
|
||||
clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
|
||||
bOut.reset();
|
||||
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
out = bOut.toByteArray();
|
||||
|
||||
if (notEqual(out, text))
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong plain text in generated packet");
|
||||
}
|
||||
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
if (e instanceof PGPException)
|
||||
{
|
||||
((PGPException)e).getUnderlyingException().printStackTrace();
|
||||
}
|
||||
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPDSAElGamalTest";
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
Test test = new PGPDSAElGamalTest();
|
||||
TestResult result = test.perform();
|
||||
|
||||
System.out.println(result.toString());
|
||||
if (result.getException() != null)
|
||||
{
|
||||
result.getException().printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import org.spongycastle.jce.spec.ECNamedCurveGenParameterSpec;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class PGPECDHTest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mFIEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
|
||||
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKstFBUZXN0IEVDRFNB" +
|
||||
"LUVDREggKEtleSBhbmQgc3Via2V5IGFyZSAyNTYgYml0cyBsb25nKSA8dGVzdC5l" +
|
||||
"Y2RzYS5lY2RoQGV4YW1wbGUuY29tPoh6BBMTCAAiBQJRvgbAAhsDBgsJCAcDAgYV" +
|
||||
"CAIJCgsEFgIDAQIeAQIXgAAKCRD3wDlWjFo9U5O2AQDi89NO6JbaIObC63jMMWsi" +
|
||||
"AaQHrBCPkDZLibgNv73DLgD/faouH4YZJs+cONQBPVnP1baG1NpWR5ppN3JULFcr" +
|
||||
"hcq4VgRRvgbAEggqhkjOPQMBBwIDBLtY8Nmfz0zSEa8C1snTOWN+VcT8pXPwgJRy" +
|
||||
"z6kSP4nPt1xj1lPKj5zwPXKWxMkPO9ocqhKdg2mOh6/rc1ObIoMDAQgHiGEEGBMI" +
|
||||
"AAkFAlG+BsACGwwACgkQ98A5VoxaPVN8cgEAj4dMNMNwRSg2ZBWunqUAHqIedVbS" +
|
||||
"dmwmbysD192L3z4A/ReXEa0gtv8OFWjuALD1ovEK8TpDORLUb6IuUb5jUIzY");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lKUEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
|
||||
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKs/gcDAo11YYCae/K2" +
|
||||
"1uKGJ/uU4b4QHYnPIsAdYpuo5HIdoAOL/WwduRa8C6vSFrtMJLDqPK3BUpMz3CXN" +
|
||||
"GyMhjuaHKP5MPbBZkIfgUGZO5qvU9+i0UFRlc3QgRUNEU0EtRUNESCAoS2V5IGFu" +
|
||||
"ZCBzdWJrZXkgYXJlIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhLmVjZGhAZXhh" +
|
||||
"bXBsZS5jb20+iHoEExMIACIFAlG+BsACGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B" +
|
||||
"AheAAAoJEPfAOVaMWj1Tk7YBAOLz007oltog5sLreMwxayIBpAesEI+QNkuJuA2/" +
|
||||
"vcMuAP99qi4fhhkmz5w41AE9Wc/VtobU2lZHmmk3clQsVyuFyg==");
|
||||
|
||||
byte[] testMessage =
|
||||
Base64.decode(
|
||||
"hH4Dp5+FdoujIBwSAgMErx4BSvgXY3irwthgxU8zPoAoR+8rhmxdpwbw6ZJAO2GX" +
|
||||
"azWJ85JNcobHKDeGeUq6wkTFu+g6yG99gIX8J5xJAjBRhyCRcaFgwbdDV4orWTe3" +
|
||||
"iewiT8qs4BQ23e0c8t+thdKoK4thMsCJy7wSKqY0sJTSVAELroNbCOi2lcO15YmW" +
|
||||
"6HiuFH7VKWcxPUBjXwf5+Z3uOKEp28tBgNyDrdbr1BbqlgYzIKq/pe9zUbUXfitn" +
|
||||
"vFc6HcGhvmRQreQ+Yw1x3x0HJeoPwg==");
|
||||
|
||||
private void generate()
|
||||
throws Exception
|
||||
{
|
||||
//
|
||||
// Generate a master key
|
||||
//
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "SC");
|
||||
|
||||
keyGen.initialize(256);
|
||||
|
||||
KeyPair kpSign = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDSA, kpSign, new Date());
|
||||
|
||||
//
|
||||
// Generate an encryption key
|
||||
//
|
||||
keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
|
||||
|
||||
keyGen.initialize(256);
|
||||
|
||||
KeyPair kpEnc = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdhKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDH, kpEnc, new Date());
|
||||
|
||||
//
|
||||
// generate a key ring
|
||||
//
|
||||
char[] passPhrase = "test".toCharArray();
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||
PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, ecdsaKeyPair,
|
||||
"test@bouncycastle.org", sha1Calc, null, null,
|
||||
new JcaPGPContentSignerBuilder(ecdsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
|
||||
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("SC").build(passPhrase));
|
||||
|
||||
keyRingGen.addSubKey(ecdhKeyPair);
|
||||
|
||||
PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing();
|
||||
|
||||
// TODO: add check of KdfParameters
|
||||
doBasicKeyRingCheck(pubRing);
|
||||
|
||||
PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing();
|
||||
|
||||
KeyFingerPrintCalculator fingerCalc = new JcaKeyFingerprintCalculator();
|
||||
|
||||
PGPPublicKeyRing pubRingEnc = new PGPPublicKeyRing(pubRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(pubRing.getEncoded(), pubRingEnc.getEncoded()))
|
||||
{
|
||||
fail("public key ring encoding failed");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing secRingEnc = new PGPSecretKeyRing(secRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(secRing.getEncoded(), secRingEnc.getEncoded()))
|
||||
{
|
||||
fail("secret key ring encoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void testDecrypt(PGPSecretKeyRing secretKeyRing)
|
||||
throws Exception
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(testMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
PGPSecretKey secretKey = secretKeyRing.getSecretKey(); // secretKeyRing.getSecretKey(encP.getKeyID());
|
||||
//
|
||||
// PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey()extractPrivateKey(null);
|
||||
//
|
||||
// clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
//
|
||||
// bOut.reset();
|
||||
//
|
||||
// while ((ch = clear.read()) >= 0)
|
||||
// {
|
||||
// bOut.write(ch);
|
||||
// }
|
||||
//
|
||||
// out = bOut.toByteArray();
|
||||
//
|
||||
// if (!areEqual(out, text))
|
||||
// {
|
||||
// fail("wrong plain text in generated packet");
|
||||
// }
|
||||
}
|
||||
|
||||
private void encryptDecryptTest()
|
||||
throws Exception
|
||||
{
|
||||
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' };
|
||||
|
||||
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
|
||||
|
||||
keyGen.initialize(256);
|
||||
|
||||
KeyPair kpEnc = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdhKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDH, kpEnc, new Date());
|
||||
|
||||
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
|
||||
ByteArrayOutputStream ldOut = new ByteArrayOutputStream();
|
||||
OutputStream pOut = lData.open(ldOut, PGPLiteralDataGenerator.UTF8, PGPLiteralData.CONSOLE, text.length, new Date());
|
||||
|
||||
pOut.write(text);
|
||||
|
||||
pOut.close();
|
||||
|
||||
byte[] data = ldOut.toByteArray();
|
||||
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setProvider("SC").setSecureRandom(new SecureRandom()));
|
||||
|
||||
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(ecdhKeyPair.getPublicKey()).setProvider("SC"));
|
||||
|
||||
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), data.length);
|
||||
|
||||
cOut.write(data);
|
||||
|
||||
cOut.close();
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("SC").build(ecdhKeyPair.getPrivateKey()));
|
||||
|
||||
pgpF = new PGPObjectFactory(clear);
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpF.nextObject();
|
||||
|
||||
clear = ld.getInputStream();
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
int ch;
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
byte[] out = bOut.toByteArray();
|
||||
|
||||
if (!areEqual(out, text))
|
||||
{
|
||||
fail("wrong plain text in generated packet");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
doBasicKeyRingCheck(pubKeyRing);
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
testDecrypt(secretKeyRing);
|
||||
|
||||
encryptDecryptTest();
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
private void doBasicKeyRingCheck(PGPPublicKeyRing pubKeyRing)
|
||||
throws PGPException, SignatureException
|
||||
{
|
||||
for (Iterator it = pubKeyRing.getPublicKeys(); it.hasNext();)
|
||||
{
|
||||
PGPPublicKey pubKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pubKey.isMasterKey())
|
||||
{
|
||||
if (pubKey.isEncryptionKey())
|
||||
{
|
||||
fail("master key showed as encryption key!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pubKey.isEncryptionKey())
|
||||
{
|
||||
fail("sub key not encryption key!");
|
||||
}
|
||||
|
||||
for (Iterator sigIt = pubKeyRing.getPublicKey().getSignatures(); sigIt.hasNext();)
|
||||
{
|
||||
PGPSignature certification = (PGPSignature)sigIt.next();
|
||||
|
||||
certification.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKeyRing.getPublicKey());
|
||||
|
||||
if (!certification.verifyCertification((String)pubKeyRing.getPublicKey().getUserIDs().next(), pubKeyRing.getPublicKey()))
|
||||
{
|
||||
fail("subkey certification does not verify");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPECDHTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPECDHTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.Security;
|
||||
import org.spongycastle.jce.spec.ECNamedCurveGenParameterSpec;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
|
||||
public class PGPECDSATest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mFIEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
|
||||
"zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8FetDVFQ0RTQSAoS2V5" +
|
||||
"IGlzIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhQGV4YW1wbGUuY29tPoh6BBMT" +
|
||||
"CAAiBQJRvgeoAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDqO46kgPLi" +
|
||||
"vN1hAP4n0UApR36ziS5D8KUt7wEpBujQE4G3+efATJ+DMmY/SgEA+wbdDynFf/V8" +
|
||||
"pQs0+FtCYQ9schzIur+peRvol7OrNnc=");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lKUEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
|
||||
"zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8Fe/gcDAqTWSUiFpEno" +
|
||||
"1n8izmLaWTy8GYw5/lK4R2t6D347YGgTtIiXfoNPOcosmU+3OibyTm2hc/WyG4fL" +
|
||||
"a0nxFtj02j0Bt/Fw0N4VCKJwKL/QJT+0NUVDRFNBIChLZXkgaXMgMjU2IGJpdHMg" +
|
||||
"bG9uZykgPHRlc3QuZWNkc2FAZXhhbXBsZS5jb20+iHoEExMIACIFAlG+B6gCGwMG" +
|
||||
"CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOo7jqSA8uK83WEA/ifRQClHfrOJ" +
|
||||
"LkPwpS3vASkG6NATgbf558BMn4MyZj9KAQD7Bt0PKcV/9XylCzT4W0JhD2xyHMi6" +
|
||||
"v6l5G+iXs6s2dw==");
|
||||
|
||||
private void generateAndSign()
|
||||
throws Exception
|
||||
{
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "SC");
|
||||
|
||||
keyGen.initialize(256);
|
||||
|
||||
KeyPair kpSign = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDSA, kpSign, new Date());
|
||||
|
||||
//
|
||||
// try a signature
|
||||
//
|
||||
PGPSignatureGenerator signGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PGPPublicKey.ECDSA, HashAlgorithmTags.SHA256).setProvider("SC"));
|
||||
|
||||
signGen.init(PGPSignature.BINARY_DOCUMENT, ecdsaKeyPair.getPrivateKey());
|
||||
|
||||
signGen.update("hello world!".getBytes());
|
||||
|
||||
PGPSignature sig = signGen.generate();
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), ecdsaKeyPair.getPublicKey());
|
||||
|
||||
sig.update("hello world!".getBytes());
|
||||
|
||||
if (!sig.verify())
|
||||
{
|
||||
fail("signature failed to verify!");
|
||||
}
|
||||
|
||||
//
|
||||
// generate a key ring
|
||||
//
|
||||
char[] passPhrase = "test".toCharArray();
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||
PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, ecdsaKeyPair,
|
||||
"test@bouncycastle.org", sha1Calc, null, null, new JcaPGPContentSignerBuilder(ecdsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("SC").build(passPhrase));
|
||||
|
||||
PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing();
|
||||
|
||||
PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing();
|
||||
|
||||
KeyFingerPrintCalculator fingerCalc = new JcaKeyFingerprintCalculator();
|
||||
|
||||
PGPPublicKeyRing pubRingEnc = new PGPPublicKeyRing(pubRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(pubRing.getEncoded(), pubRingEnc.getEncoded()))
|
||||
{
|
||||
fail("public key ring encoding failed");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing secRingEnc = new PGPSecretKeyRing(secRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(secRing.getEncoded(), secRingEnc.getEncoded()))
|
||||
{
|
||||
fail("secret key ring encoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
for (Iterator it = pubKeyRing.getPublicKey().getSignatures(); it.hasNext();)
|
||||
{
|
||||
PGPSignature certification = (PGPSignature)it.next();
|
||||
|
||||
certification.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKeyRing.getPublicKey());
|
||||
|
||||
if (!certification.verifyCertification((String)pubKeyRing.getPublicKey().getUserIDs().next(), pubKeyRing.getPublicKey()))
|
||||
{
|
||||
fail("self certification does not verify");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
|
||||
generateAndSign();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPECDSATest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPECDSATest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,968 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRingCollection;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTestResult;
|
||||
import org.spongycastle.util.test.Test;
|
||||
import org.spongycastle.util.test.TestResult;
|
||||
|
||||
public class PGPKeyRingTest
|
||||
implements Test
|
||||
{
|
||||
byte[] pub1 = Base64.decode(
|
||||
"mQGiBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
|
||||
+ "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
|
||||
+ "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf"
|
||||
+ "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ"
|
||||
+ "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G"
|
||||
+ "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ"
|
||||
+ "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG"
|
||||
+ "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP"
|
||||
+ "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif"
|
||||
+ "IIeLOTI5Dc4XKeV32a+bWrQidGVzdCAoVGVzdCBrZXkpIDx0ZXN0QHViaWNh"
|
||||
+ "bGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB4TOABgsJCAcDAgMVAgMDFgIB"
|
||||
+ "Ah4BAheAAAoJEJh8Njfhe8KmGDcAoJWr8xgPr75y/Cp1kKn12oCCOb8zAJ4p"
|
||||
+ "xSvk4K6tB2jYbdeSrmoWBZLdMLACAAC5AQ0EQDzfARAEAJeUAPvUzJJbKcc5"
|
||||
+ "5Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj47UPAD/tQxwz8VAwJySx82ggN"
|
||||
+ "LxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j2BVqZAaX3q79a3eMiql1T0oE"
|
||||
+ "AGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOHAAQNBACD0mVMlAUgd7REYy/1"
|
||||
+ "mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWaHz6CN1XptdwpDeSYEOFZ0PSu"
|
||||
+ "qH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85efMBA9jUv/DeBOzRWMFG6sC6y"
|
||||
+ "k8NGG7Swea7EHKeQI40G3jgO/+xANtMyTIhPBBgRAgAPBQJAPN8BAhsMBQkB"
|
||||
+ "4TOAAAoJEJh8Njfhe8KmG7kAn00mTPGJCWqmskmzgdzeky5fWd7rAKCNCp3u"
|
||||
+ "ZJhfg0htdgAfIy8ppm05vLACAAA=");
|
||||
|
||||
byte[] sec1 = Base64.decode(
|
||||
"lQHhBEA83v0RBADzKVLVCnpWQxX0LCsevw/3OLs0H7MOcLBQ4wMO9sYmzGYn"
|
||||
+ "xpVj+4e4PiCP7QBayWyy4lugL6Lnw7tESvq3A4v3fefcxaCTkJrryiKn4+Cg"
|
||||
+ "y5rIBbrSKNtCEhVi7xjtdnDjP5kFKgHYjVOeIKn4Cz/yzPG3qz75kDknldLf"
|
||||
+ "yHxp2wCgwW1vAE5EnZU4/UmY7l8kTNkMltMEAJP4/uY4zcRwLI9Q2raPqAOJ"
|
||||
+ "TYLd7h+3k/BxI0gIw96niQ3KmUZDlobbWBI+VHM6H99vcttKU3BgevNf8M9G"
|
||||
+ "x/AbtW3SS4De64wNSU3189XDG8vXf0vuyW/K6Pcrb8exJWY0E1zZQ1WXT0gZ"
|
||||
+ "W0kH3g5ro//Tusuil9q2lVLF2ovJA/0W+57bPzi318dWeNs0tTq6Njbc/GTG"
|
||||
+ "FUAVJ8Ss5v2u6h7gyJ1DB334ExF/UdqZGldp0ugkEXaSwBa2R7d3HBgaYcoP"
|
||||
+ "Ck1TrovZzEY8gm7JNVy7GW6mdOZuDOHTxyADEEP2JPxh6eRcZbzhGuJuYIif"
|
||||
+ "IIeLOTI5Dc4XKeV32a+bWv4CAwJ5KgazImo+sGBfMhDiBcBTqyDGhKHNgHic"
|
||||
+ "0Pky9FeRvfXTc2AO+jGmFPjcs8BnTWuDD0/jkQnRZpp1TrQidGVzdCAoVGVz"
|
||||
+ "dCBrZXkpIDx0ZXN0QHViaWNhbGwuY29tPohkBBMRAgAkBQJAPN79AhsDBQkB"
|
||||
+ "4TOABgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEJh8Njfhe8KmGDcAn3XeXDMg"
|
||||
+ "BZgrZzFWU2IKtA/5LG2TAJ0Vf/jjyq0jZNZfGfoqGTvD2MAl0rACAACdAVgE"
|
||||
+ "QDzfARAEAJeUAPvUzJJbKcc55Iyb13+Gfb8xBWE3HinQzhGr1v6A1aIZbRj4"
|
||||
+ "7UPAD/tQxwz8VAwJySx82ggNLxCk4jW9YtTL3uZqfczsJngV25GoIN10f4/j"
|
||||
+ "2BVqZAaX3q79a3eMiql1T0oEAGmD7tO1LkTvWfm3VvA0+t8/6ZeRLEiIqAOH"
|
||||
+ "AAQNBACD0mVMlAUgd7REYy/1mL99Zlu9XU0uKyUex99sJNrcx1aj8rIiZtWa"
|
||||
+ "Hz6CN1XptdwpDeSYEOFZ0PSuqH9ByM3OfjU/ya0//xdvhwYXupn6P1Kep85e"
|
||||
+ "fMBA9jUv/DeBOzRWMFG6sC6yk8NGG7Swea7EHKeQI40G3jgO/+xANtMyTP4C"
|
||||
+ "AwJ5KgazImo+sGBl2C7CFuI+5KM4ZhbtVie7l+OiTpr5JW2z5VgnV3EX9p04"
|
||||
+ "LcGKfQvD65+ELwli6yh8B2zGcipqTaYk3QoYNIhPBBgRAgAPBQJAPN8BAhsM"
|
||||
+ "BQkB4TOAAAoJEJh8Njfhe8KmG7kAniuRkaFFv1pdCBN8JJXpcorHmyouAJ9L"
|
||||
+ "xxmusffR6OI7WgD3XZ0AL8zUC7ACAAA=");
|
||||
|
||||
char[] pass1 = "qwertzuiop".toCharArray();
|
||||
|
||||
byte[] pub2 = Base64.decode(
|
||||
"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");
|
||||
|
||||
byte[] sec2 = Base64.decode(
|
||||
"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"
|
||||
+ "Nifs+ljmsAFn");
|
||||
|
||||
|
||||
char[] sec2pass1 = "sandhya".toCharArray();
|
||||
char[] sec2pass2 = "psai".toCharArray();
|
||||
|
||||
byte[] pub3 = Base64.decode(
|
||||
"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"
|
||||
+ "n3FaE6UZE9GMDmCIAjhI+0X9aH6CsAIAAw==");
|
||||
|
||||
byte[] sec3 = Base64.decode(
|
||||
"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"
|
||||
+ "oNCOMplSnYTuh5ikKeBWtz36gC1psAIAAA==");
|
||||
|
||||
char[] sec3pass1 = "123456".toCharArray();
|
||||
|
||||
//
|
||||
// GPG comment packets.
|
||||
//
|
||||
byte[] sec4 = Base64.decode(
|
||||
"lQG7BD0PbK8RBAC0cW4Y2MZXmAmqYp5Txyw0kSQsFvwZKHNMFRv996IsN57URVF5"
|
||||
+ "BGMVPRBi9dNucWbjiSYpiYN13wE9IuLZsvVaQojV4XWGRDc+Rxz9ElsXnsYQ3mZU"
|
||||
+ "7H1bNQEofstChk4z+dlvPBN4GFahrIzn/CeVUn6Ut7dVdYbiTqviANqNXwCglfVA"
|
||||
+ "2OEePvqFnGxs1jhJyPSOnTED/RwRvsLH/k43mk6UEvOyN1RIpBXN+Ieqs7h1gFrQ"
|
||||
+ "kB+WMgeP5ZUsotTffVDSUS9UMxRQggVUW1Xml0geGwQsNfkr/ztWMs/T4xp1v5j+"
|
||||
+ "QyJx6OqNlkGdqOsoqkzJx0SQ1zBxdinFyyC4H95SDAb/RQOu5LQmxFG7quexztMs"
|
||||
+ "infEA/9cVc9+qCo92yRAaXRqKNVVQIQuPxeUsGMyVeJQvJBD4An8KTMCdjpF10Cp"
|
||||
+ "qA3t+n1S0zKr5WRUtvS6y60MOONO+EJWVWBNkx8HJDaIMNkfoqQoz3Krn7w6FE/v"
|
||||
+ "/5uwMd6jY3N3yJZn5nDZT9Yzv9Nx3j+BrY+henRlSU0c6xDc9QAAnjJYg0Z83VJG"
|
||||
+ "6HrBcgc4+4K6lHulCqH9JiM6RFNBX2ZhY3RvcjoAAK9hV206agp99GI6x5qE9+pU"
|
||||
+ "vs6O+Ich/SYjOkRTQV9mYWN0b3I6AACvYAfGn2FGrpBYbjnpTuFOHJMS/T5xg/0m"
|
||||
+ "IzpEU0FfZmFjdG9yOgAAr0dAQz6XxMwxWIn8xIZR/v2iN2L9C6O0EkZvbyBCYXIg"
|
||||
+ "PGJhekBxdXV4PohXBBMRAgAXBQI9D2yvBQsHCgMEAxUDAgMWAgECF4AACgkQUGLI"
|
||||
+ "YCIktfoGogCfZiXMJUKrScqozv5tMwzTTk2AaT8AniM5iRr0Du/Y08SL/NMhtF6H"
|
||||
+ "hJ89nO4EPQ9ssRADAI6Ggxj6ZBfoavuXd/ye99osW8HsNlbqhXObu5mCMNySX2wa"
|
||||
+ "HoWyRUEaUkI9eQw+MlHzIwzA32E7y2mU3OQBKdgLcBg4jxtcWVEg8ESKF9MpFXxl"
|
||||
+ "pExxWrr4DFBfCRcsTwAFEQL9G3OvwJuEZXgx2JSS41D3pG4/qiHYICVa0u3p/14i"
|
||||
+ "cq0kXajIk5ZJ6frCIAHIzuQ3n7jjzr05yR8s/qCrNbBA+nlkVNa/samk+jCzxxxa"
|
||||
+ "cR/Dbh2wkvTFuDFFETwQYLuZAADcDck4YGQAmHivVT2NNDCf/aTz0+CJWl+xRc2l"
|
||||
+ "Qw7D/SQjOkVMR19mYWN0b3I6AACbBnv9m5/bb/pjYAm2PtDp0CysQ9X9JCM6RUxH"
|
||||
+ "X2ZhY3RvcjoAAJsFyHnSmaWguTFf6lJ/j39LtUNtmf0kIzpFTEdfZmFjdG9yOgAA"
|
||||
+ "mwfwMD3LxmWtuCWBE9BptWMNH07Z/SQjOkVMR19mYWN0b3I6AACbBdhBrbSiM4UN"
|
||||
+ "y7khDW2Sk0e4v9mIRgQYEQIABgUCPQ9ssQAKCRBQYshgIiS1+jCMAJ9txwHnb1Kl"
|
||||
+ "6i/fSoDs8SkdM7w48wCdFvPEV0sSxE73073YhBgPZtMWbBo=");
|
||||
|
||||
//
|
||||
// PGP freeware version 7
|
||||
//
|
||||
byte[] pub5 = Base64.decode(
|
||||
"mQENBEBrBE4BCACjXVcNIFDQSofaIyZnALb2CRg+WY9uUqgHEEAOlPe03Cs5STM5"
|
||||
+ "HDlNmrh4TdFceJ46rxk1mQOjULES1YfHay8lCIzrD7FX4oj0r4DC14Fs1vXaSar2"
|
||||
+ "1szIpttOw3obL4A1e0p6N4jjsoG7N/pA0fEL0lSw92SoBrMbAheXRg4qNTZvdjOR"
|
||||
+ "grcuOuwgJRvPLtRXlhyLBoyhkd5mmrIDGv8QHJ/UjpeIcRXY9kn9oGXnEYcRbMaU"
|
||||
+ "VwXB4pLzWqz3ZejFI3lOxRWjm760puPOnGYlzSVBxlt2LgzUgSj1Mn+lIpWmAzsa"
|
||||
+ "xEiU4xUwEomQns72yYRZ6D3euNCibcte4SeXABEBAAG0KXBhbGFzaCBrYXNvZGhh"
|
||||
+ "biA8cGthc29kaGFuQHRpYWEtY3JlZi5vcmc+iQEuBBABAgAYBQJAawROCAsBAwkI"
|
||||
+ "BwIKAhkBBRsDAAAAAAoJEOfelumuiOrYqPEH+wYrdP5Tq5j+E5yN1pyCg1rwbSOt"
|
||||
+ "Dka0y0p7Oq/VIGLk692IWPItLEunnBXQtGBcWqklrvogvlhxtf16FgoyScfLJx1e"
|
||||
+ "1cJa+QQnVuH+VOESN6iS9Gp9lUfVOHv74mEMXw0l2Djfy/lnrkAMBatggyGnF9xF"
|
||||
+ "VXOLk1J2WVFm9KUE23o6qdB7RGkf31pN2eA7SWmkdJSkUH7o/QSFBI+UTRZ/IY5P"
|
||||
+ "ZIJpsdiIOqd9YMG/4RoSZuPqNRR6x7BSs8nQVR9bYs4PPlp4GfdRnOcRonoTeJCZ"
|
||||
+ "83RnsraWJnJTg34gRLBcqumhTuFKc8nuCNK98D6zkQESdcHLLTquCOaF5L+5AQ0E"
|
||||
+ "QGsETwEIAOVwNCTaDZvW4dowPbET1bI5UeYY8rAGLYsWSUfgaFv2srMiApyBVltf"
|
||||
+ "i6OLcPjcUCHDBjCv4pwx/C4qcHWb8av4xQIpqQXOpO9NxYE1eZnel/QB7DtH12ZO"
|
||||
+ "nrDNmHtaXlulcKNGe1i1utlFhgzfFx6rWkRL0ENmkTkaQmPY4gTGymJTUhBbsSRq"
|
||||
+ "2ivWqQA1TPwBuda73UgslIAHRd/SUaxjXoLpMbGOTeqzcKGjr5XMPTs7/YgBpWPP"
|
||||
+ "UxMlEQIiU3ia1bxpEhx05k97ceK6TSH2oCPQA7gumjxOSjKT+jEm+8jACVzymEmc"
|
||||
+ "XRy4D5Ztqkw/Z16pvNcu1DI5m6xHwr8AEQEAAYkBIgQYAQIADAUCQGsETwUbDAAA"
|
||||
+ "AAAKCRDn3pbprojq2EynB/4/cEOtKbI5UisUd3vkTzvWOcqWUqGqi5wjjioNtIM5"
|
||||
+ "pur2nFvhQE7SZ+PbAa87HRJU/4WcWMcoLkHD48JrQwHCHOLHSV5muYowb78X4Yh9"
|
||||
+ "epYtSJ0uUahcn4Gp48p4BkhgsPYXkxEImSYzAOWStv21/7WEMqItMYl89BV6Upm8"
|
||||
+ "HyTJx5MPTDbMR7X51hRg3OeQs6po3WTCWRzFIMyGm1rd/VK1L5ZDFPqO3S6YUJ0z"
|
||||
+ "cxecYruvfK0Wp7q834wE8Zkl/PQ3NhfEPL1ZiLr/L00Ty+77/FZqt8SHRCICzOfP"
|
||||
+ "OawcVGI+xHVXW6lijMpB5VaVIH8i2KdBMHXHtduIkPr9");
|
||||
|
||||
byte[] sec5 = Base64.decode(
|
||||
"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");
|
||||
|
||||
|
||||
|
||||
char[] sec5pass1 = "12345678".toCharArray();
|
||||
|
||||
private boolean notEqual(
|
||||
byte[] b1,
|
||||
byte[] b2)
|
||||
{
|
||||
if (b1.length != b2.length)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i != b2.length; i++)
|
||||
{
|
||||
if (b1[i] != b2[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TestResult test1()
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub1);
|
||||
|
||||
int count = 0;
|
||||
|
||||
Iterator rIt = pubRings.getKeyRings();
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpPub.getEncoded();
|
||||
|
||||
pgpPub = new PGPPublicKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
it.next();
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keyrings");
|
||||
}
|
||||
|
||||
PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec1);
|
||||
|
||||
rIt = secretRings.getKeyRings();
|
||||
count = 0;
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpSec.getEncoded();
|
||||
|
||||
pgpSec = new PGPSecretKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpSec.getSecretKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
PGPSecretKey k = (PGPSecretKey)it.next();
|
||||
PGPPublicKey pk = k.getPublicKey();
|
||||
|
||||
byte[] pkBytes = pk.getEncoded();
|
||||
|
||||
PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes);
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings");
|
||||
}
|
||||
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof PGPException)
|
||||
{
|
||||
if (((PGPException)e).getUnderlyingException() != null)
|
||||
{
|
||||
((PGPException)e).getUnderlyingException().printStackTrace();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public TestResult test2()
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub2);
|
||||
|
||||
int count = 0;
|
||||
|
||||
byte[] encRing = pubRings.getEncoded();
|
||||
|
||||
pubRings = new PGPPublicKeyRingCollection(encRing);
|
||||
|
||||
Iterator rIt = pubRings.getKeyRings();
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpPub.getEncoded();
|
||||
|
||||
pgpPub = new PGPPublicKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
PGPPublicKey pk = (PGPPublicKey)it.next();
|
||||
|
||||
byte[] pkBytes = pk.getEncoded();
|
||||
|
||||
PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes);
|
||||
|
||||
keyCount++;
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keyrings");
|
||||
}
|
||||
|
||||
PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec2);
|
||||
|
||||
rIt = secretRings.getKeyRings();
|
||||
count = 0;
|
||||
|
||||
encRing = secretRings.getEncoded();
|
||||
|
||||
secretRings = new PGPSecretKeyRingCollection(encRing);
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpSec.getEncoded();
|
||||
|
||||
pgpSec = new PGPSecretKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpSec.getSecretKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
PGPSecretKey k = (PGPSecretKey)it.next();
|
||||
PGPPublicKey pk = k.getPublicKey();
|
||||
|
||||
byte[] pkBytes = pk.getEncoded();
|
||||
|
||||
PGPPublicKeyRing pkR = new PGPPublicKeyRing(pkBytes);
|
||||
|
||||
if (k.getKeyID() == -4049084404703773049L
|
||||
|| k.getKeyID() == -1413891222336124627L)
|
||||
{
|
||||
k.extractPrivateKey(sec2pass1, "SC");
|
||||
}
|
||||
else if (k.getKeyID() == -6498553574938125416L
|
||||
|| k.getKeyID() == 59034765524361024L)
|
||||
{
|
||||
k.extractPrivateKey(sec2pass2, "SC");
|
||||
}
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings");
|
||||
}
|
||||
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof PGPException)
|
||||
{
|
||||
if (((PGPException)e).getUnderlyingException() != null)
|
||||
{
|
||||
((PGPException)e).getUnderlyingException().printStackTrace();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new SimpleTestResult(false, getName() + ": exception - "+ e);
|
||||
}
|
||||
}
|
||||
|
||||
public TestResult test3()
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub3);
|
||||
|
||||
int count = 0;
|
||||
|
||||
byte[] encRing = pubRings.getEncoded();
|
||||
|
||||
pubRings = new PGPPublicKeyRingCollection(encRing);
|
||||
|
||||
Iterator rIt = pubRings.getKeyRings();
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpPub.getEncoded();
|
||||
|
||||
pgpPub = new PGPPublicKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
it.next();
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keyrings");
|
||||
}
|
||||
|
||||
PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec3);
|
||||
|
||||
rIt = secretRings.getKeyRings();
|
||||
count = 0;
|
||||
|
||||
encRing = secretRings.getEncoded();
|
||||
|
||||
secretRings = new PGPSecretKeyRingCollection(encRing);
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpSec.getEncoded();
|
||||
|
||||
pgpSec = new PGPSecretKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpSec.getSecretKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
PGPSecretKey k = (PGPSecretKey)it.next();
|
||||
|
||||
k.extractPrivateKey(sec3pass1, "SC");
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings");
|
||||
}
|
||||
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof PGPException)
|
||||
{
|
||||
if (((PGPException)e).getUnderlyingException() != null)
|
||||
{
|
||||
((PGPException)e).getUnderlyingException().printStackTrace();
|
||||
}
|
||||
}
|
||||
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public TestResult test4()
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec4);
|
||||
|
||||
Iterator rIt = secretRings.getKeyRings();
|
||||
int count = 0;
|
||||
|
||||
byte[] encRing = secretRings.getEncoded();
|
||||
|
||||
secretRings = new PGPSecretKeyRingCollection(encRing);
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpSec.getEncoded();
|
||||
|
||||
pgpSec = new PGPSecretKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpSec.getSecretKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
PGPSecretKey k = (PGPSecretKey)it.next();
|
||||
|
||||
k.extractPrivateKey(sec3pass1, "SC");
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings");
|
||||
}
|
||||
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof PGPException)
|
||||
{
|
||||
if (((PGPException)e).getUnderlyingException() != null)
|
||||
{
|
||||
((PGPException)e).getUnderlyingException().printStackTrace();
|
||||
}
|
||||
}
|
||||
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public TestResult test5()
|
||||
{
|
||||
try
|
||||
{
|
||||
PGPPublicKeyRingCollection pubRings = new PGPPublicKeyRingCollection(pub5);
|
||||
|
||||
int count = 0;
|
||||
|
||||
byte[] encRing = pubRings.getEncoded();
|
||||
|
||||
pubRings = new PGPPublicKeyRingCollection(encRing);
|
||||
|
||||
Iterator rIt = pubRings.getKeyRings();
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPPublicKeyRing pgpPub = (PGPPublicKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpPub.getEncoded();
|
||||
|
||||
pgpPub = new PGPPublicKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpPub.getPublicKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
it.next();
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of public keyrings");
|
||||
}
|
||||
|
||||
PGPSecretKeyRingCollection secretRings = new PGPSecretKeyRingCollection(sec5);
|
||||
|
||||
rIt = secretRings.getKeyRings();
|
||||
count = 0;
|
||||
|
||||
encRing = secretRings.getEncoded();
|
||||
|
||||
secretRings = new PGPSecretKeyRingCollection(encRing);
|
||||
|
||||
while (rIt.hasNext())
|
||||
{
|
||||
PGPSecretKeyRing pgpSec = (PGPSecretKeyRing)rIt.next();
|
||||
|
||||
count++;
|
||||
|
||||
int keyCount = 0;
|
||||
|
||||
byte[] bytes = pgpSec.getEncoded();
|
||||
|
||||
pgpSec = new PGPSecretKeyRing(bytes);
|
||||
|
||||
Iterator it = pgpSec.getSecretKeys();
|
||||
while (it.hasNext())
|
||||
{
|
||||
keyCount++;
|
||||
|
||||
PGPSecretKey k = (PGPSecretKey)it.next();
|
||||
|
||||
k.extractPrivateKey(sec5pass1, "SC");
|
||||
}
|
||||
|
||||
if (keyCount != 2)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keys");
|
||||
}
|
||||
}
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
return new SimpleTestResult(false, getName() + ": wrong number of secret keyrings");
|
||||
}
|
||||
|
||||
return new SimpleTestResult(true, getName() + ": Okay");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e instanceof PGPException)
|
||||
{
|
||||
if (((PGPException)e).getUnderlyingException() != null)
|
||||
{
|
||||
((PGPException)e).getUnderlyingException().printStackTrace();
|
||||
}
|
||||
}
|
||||
return new SimpleTestResult(false, getName() + ": exception - " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public TestResult perform()
|
||||
{
|
||||
TestResult res = test1();
|
||||
if (!res.isSuccessful())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
res = test2();
|
||||
if (!res.isSuccessful())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
res = test3();
|
||||
if (!res.isSuccessful())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
res = test4();
|
||||
if (!res.isSuccessful())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
res = test5();
|
||||
if (!res.isSuccessful())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPKeyRingTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Test test = new PGPKeyRingTest();
|
||||
TestResult result = test.perform();
|
||||
|
||||
System.out.println(result.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.util.test.SimpleTestResult;
|
||||
|
||||
public class AllTests
|
||||
extends TestCase
|
||||
{
|
||||
public void testPGP()
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
org.spongycastle.util.test.Test[] tests = RegressionTest.tests;
|
||||
|
||||
for (int i = 0; i != tests.length; i++)
|
||||
{
|
||||
SimpleTestResult result = (SimpleTestResult)tests[i].perform();
|
||||
|
||||
if (!result.isSuccessful())
|
||||
{
|
||||
fail(result.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main (String[] args)
|
||||
{
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
{
|
||||
TestSuite suite = new TestSuite("OpenPGP Tests");
|
||||
|
||||
suite.addTestSuite(AllTests.class);
|
||||
suite.addTestSuite(DSA2Test.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.security.SignatureException;
|
||||
import org.spongycastle.jce.spec.ECNamedCurveGenParameterSpec;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPEncryptedDataList;
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPLiteralData;
|
||||
import org.spongycastle.openpgp.PGPLiteralDataGenerator;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
import org.spongycastle.util.test.UncloseableOutputStream;
|
||||
|
||||
public class PGPECDHTest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mFIEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
|
||||
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKstFBUZXN0IEVDRFNB" +
|
||||
"LUVDREggKEtleSBhbmQgc3Via2V5IGFyZSAyNTYgYml0cyBsb25nKSA8dGVzdC5l" +
|
||||
"Y2RzYS5lY2RoQGV4YW1wbGUuY29tPoh6BBMTCAAiBQJRvgbAAhsDBgsJCAcDAgYV" +
|
||||
"CAIJCgsEFgIDAQIeAQIXgAAKCRD3wDlWjFo9U5O2AQDi89NO6JbaIObC63jMMWsi" +
|
||||
"AaQHrBCPkDZLibgNv73DLgD/faouH4YZJs+cONQBPVnP1baG1NpWR5ppN3JULFcr" +
|
||||
"hcq4VgRRvgbAEggqhkjOPQMBBwIDBLtY8Nmfz0zSEa8C1snTOWN+VcT8pXPwgJRy" +
|
||||
"z6kSP4nPt1xj1lPKj5zwPXKWxMkPO9ocqhKdg2mOh6/rc1ObIoMDAQgHiGEEGBMI" +
|
||||
"AAkFAlG+BsACGwwACgkQ98A5VoxaPVN8cgEAj4dMNMNwRSg2ZBWunqUAHqIedVbS" +
|
||||
"dmwmbysD192L3z4A/ReXEa0gtv8OFWjuALD1ovEK8TpDORLUb6IuUb5jUIzY");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lKUEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT" +
|
||||
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKs/gcDAo11YYCae/K2" +
|
||||
"1uKGJ/uU4b4QHYnPIsAdYpuo5HIdoAOL/WwduRa8C6vSFrtMJLDqPK3BUpMz3CXN" +
|
||||
"GyMhjuaHKP5MPbBZkIfgUGZO5qvU9+i0UFRlc3QgRUNEU0EtRUNESCAoS2V5IGFu" +
|
||||
"ZCBzdWJrZXkgYXJlIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhLmVjZGhAZXhh" +
|
||||
"bXBsZS5jb20+iHoEExMIACIFAlG+BsACGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4B" +
|
||||
"AheAAAoJEPfAOVaMWj1Tk7YBAOLz007oltog5sLreMwxayIBpAesEI+QNkuJuA2/" +
|
||||
"vcMuAP99qi4fhhkmz5w41AE9Wc/VtobU2lZHmmk3clQsVyuFyg==");
|
||||
|
||||
byte[] testMessage =
|
||||
Base64.decode(
|
||||
"hH4Dp5+FdoujIBwSAgMErx4BSvgXY3irwthgxU8zPoAoR+8rhmxdpwbw6ZJAO2GX" +
|
||||
"azWJ85JNcobHKDeGeUq6wkTFu+g6yG99gIX8J5xJAjBRhyCRcaFgwbdDV4orWTe3" +
|
||||
"iewiT8qs4BQ23e0c8t+thdKoK4thMsCJy7wSKqY0sJTSVAELroNbCOi2lcO15YmW" +
|
||||
"6HiuFH7VKWcxPUBjXwf5+Z3uOKEp28tBgNyDrdbr1BbqlgYzIKq/pe9zUbUXfitn" +
|
||||
"vFc6HcGhvmRQreQ+Yw1x3x0HJeoPwg==");
|
||||
|
||||
private void generate()
|
||||
throws Exception
|
||||
{
|
||||
//
|
||||
// Generate a master key
|
||||
//
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "SC");
|
||||
|
||||
keyGen.initialize(new ECNamedCurveGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpSign = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDSA, kpSign, new Date());
|
||||
|
||||
//
|
||||
// Generate an encryption key
|
||||
//
|
||||
keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
|
||||
|
||||
keyGen.initialize(new ECNamedCurveGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpEnc = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdhKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDH, kpEnc, new Date());
|
||||
|
||||
//
|
||||
// generate a key ring
|
||||
//
|
||||
char[] passPhrase = "test".toCharArray();
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||
PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, ecdsaKeyPair,
|
||||
"test@bouncycastle.org", sha1Calc, null, null,
|
||||
new JcaPGPContentSignerBuilder(ecdsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
|
||||
new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("SC").build(passPhrase));
|
||||
|
||||
keyRingGen.addSubKey(ecdhKeyPair);
|
||||
|
||||
PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing();
|
||||
|
||||
// TODO: add check of KdfParameters
|
||||
doBasicKeyRingCheck(pubRing);
|
||||
|
||||
PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing();
|
||||
|
||||
KeyFingerPrintCalculator fingerCalc = new JcaKeyFingerprintCalculator();
|
||||
|
||||
PGPPublicKeyRing pubRingEnc = new PGPPublicKeyRing(pubRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(pubRing.getEncoded(), pubRingEnc.getEncoded()))
|
||||
{
|
||||
fail("public key ring encoding failed");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing secRingEnc = new PGPSecretKeyRing(secRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(secRing.getEncoded(), secRingEnc.getEncoded()))
|
||||
{
|
||||
fail("secret key ring encoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
private void testDecrypt(PGPSecretKeyRing secretKeyRing)
|
||||
throws Exception
|
||||
{
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(testMessage);
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
PGPSecretKey secretKey = secretKeyRing.getSecretKey(); // secretKeyRing.getSecretKey(encP.getKeyID());
|
||||
//
|
||||
// PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey()extractPrivateKey(null);
|
||||
//
|
||||
// clear = encP.getDataStream(pgpPrivKey, "SC");
|
||||
//
|
||||
// bOut.reset();
|
||||
//
|
||||
// while ((ch = clear.read()) >= 0)
|
||||
// {
|
||||
// bOut.write(ch);
|
||||
// }
|
||||
//
|
||||
// out = bOut.toByteArray();
|
||||
//
|
||||
// if (!areEqual(out, text))
|
||||
// {
|
||||
// fail("wrong plain text in generated packet");
|
||||
// }
|
||||
}
|
||||
|
||||
private void encryptDecryptTest()
|
||||
throws Exception
|
||||
{
|
||||
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' };
|
||||
|
||||
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH", "SC");
|
||||
|
||||
keyGen.initialize(new ECNamedCurveGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpEnc = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdhKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDH, kpEnc, new Date());
|
||||
|
||||
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
|
||||
ByteArrayOutputStream ldOut = new ByteArrayOutputStream();
|
||||
OutputStream pOut = lData.open(ldOut, PGPLiteralDataGenerator.UTF8, PGPLiteralData.CONSOLE, text.length, new Date());
|
||||
|
||||
pOut.write(text);
|
||||
|
||||
pOut.close();
|
||||
|
||||
byte[] data = ldOut.toByteArray();
|
||||
|
||||
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
|
||||
|
||||
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setProvider("SC").setSecureRandom(new SecureRandom()));
|
||||
|
||||
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(ecdhKeyPair.getPublicKey()).setProvider("SC"));
|
||||
|
||||
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), data.length);
|
||||
|
||||
cOut.write(data);
|
||||
|
||||
cOut.close();
|
||||
|
||||
PGPObjectFactory pgpF = new PGPObjectFactory(cbOut.toByteArray());
|
||||
|
||||
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
|
||||
|
||||
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
|
||||
|
||||
InputStream clear = encP.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("SC").build(ecdhKeyPair.getPrivateKey()));
|
||||
|
||||
pgpF = new PGPObjectFactory(clear);
|
||||
|
||||
PGPLiteralData ld = (PGPLiteralData)pgpF.nextObject();
|
||||
|
||||
clear = ld.getInputStream();
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
int ch;
|
||||
while ((ch = clear.read()) >= 0)
|
||||
{
|
||||
bOut.write(ch);
|
||||
}
|
||||
|
||||
byte[] out = bOut.toByteArray();
|
||||
|
||||
if (!areEqual(out, text))
|
||||
{
|
||||
fail("wrong plain text in generated packet");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
doBasicKeyRingCheck(pubKeyRing);
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
testDecrypt(secretKeyRing);
|
||||
|
||||
encryptDecryptTest();
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
private void doBasicKeyRingCheck(PGPPublicKeyRing pubKeyRing)
|
||||
throws PGPException, SignatureException
|
||||
{
|
||||
for (Iterator it = pubKeyRing.getPublicKeys(); it.hasNext();)
|
||||
{
|
||||
PGPPublicKey pubKey = (PGPPublicKey)it.next();
|
||||
|
||||
if (pubKey.isMasterKey())
|
||||
{
|
||||
if (pubKey.isEncryptionKey())
|
||||
{
|
||||
fail("master key showed as encryption key!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pubKey.isEncryptionKey())
|
||||
{
|
||||
fail("sub key not encryption key!");
|
||||
}
|
||||
|
||||
for (Iterator sigIt = pubKeyRing.getPublicKey().getSignatures(); sigIt.hasNext();)
|
||||
{
|
||||
PGPSignature certification = (PGPSignature)sigIt.next();
|
||||
|
||||
certification.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKeyRing.getPublicKey());
|
||||
|
||||
if (!certification.verifyCertification((String)pubKeyRing.getPublicKey().getUserIDs().next(), pubKeyRing.getPublicKey()))
|
||||
{
|
||||
fail("subkey certification does not verify");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPECDHTest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPECDHTest());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package org.spongycastle.openpgp.test;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.Security;
|
||||
import org.spongycastle.jce.spec.ECNamedCurveGenParameterSpec;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.spongycastle.bcpg.HashAlgorithmTags;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.openpgp.PGPEncryptedData;
|
||||
import org.spongycastle.openpgp.PGPKeyPair;
|
||||
import org.spongycastle.openpgp.PGPKeyRingGenerator;
|
||||
import org.spongycastle.openpgp.PGPPublicKey;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.spongycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||
import org.spongycastle.openpgp.operator.PGPDigestCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
|
||||
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Base64;
|
||||
import org.spongycastle.util.test.SimpleTest;
|
||||
|
||||
public class PGPECDSATest
|
||||
extends SimpleTest
|
||||
{
|
||||
byte[] testPubKey =
|
||||
Base64.decode(
|
||||
"mFIEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
|
||||
"zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8FetDVFQ0RTQSAoS2V5" +
|
||||
"IGlzIDI1NiBiaXRzIGxvbmcpIDx0ZXN0LmVjZHNhQGV4YW1wbGUuY29tPoh6BBMT" +
|
||||
"CAAiBQJRvgeoAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDqO46kgPLi" +
|
||||
"vN1hAP4n0UApR36ziS5D8KUt7wEpBujQE4G3+efATJ+DMmY/SgEA+wbdDynFf/V8" +
|
||||
"pQs0+FtCYQ9schzIur+peRvol7OrNnc=");
|
||||
|
||||
byte[] testPrivKey =
|
||||
Base64.decode(
|
||||
"lKUEUb4HqBMIKoZIzj0DAQcCAwSQynmjwsGJHYJakAEVYxrm3tt/1h8g9Uksx32J" +
|
||||
"zG/ZH4RwaD0PbjzEe5EVBmCwSErRZxt/5AxXa0TEHWjya8Fe/gcDAqTWSUiFpEno" +
|
||||
"1n8izmLaWTy8GYw5/lK4R2t6D347YGgTtIiXfoNPOcosmU+3OibyTm2hc/WyG4fL" +
|
||||
"a0nxFtj02j0Bt/Fw0N4VCKJwKL/QJT+0NUVDRFNBIChLZXkgaXMgMjU2IGJpdHMg" +
|
||||
"bG9uZykgPHRlc3QuZWNkc2FAZXhhbXBsZS5jb20+iHoEExMIACIFAlG+B6gCGwMG" +
|
||||
"CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOo7jqSA8uK83WEA/ifRQClHfrOJ" +
|
||||
"LkPwpS3vASkG6NATgbf558BMn4MyZj9KAQD7Bt0PKcV/9XylCzT4W0JhD2xyHMi6" +
|
||||
"v6l5G+iXs6s2dw==");
|
||||
|
||||
private void generateAndSign()
|
||||
throws Exception
|
||||
{
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "SC");
|
||||
|
||||
keyGen.initialize(new ECNamedCurveGenParameterSpec("P-256"));
|
||||
|
||||
KeyPair kpSign = keyGen.generateKeyPair();
|
||||
|
||||
PGPKeyPair ecdsaKeyPair = new JcaPGPKeyPair(PGPPublicKey.ECDSA, kpSign, new Date());
|
||||
|
||||
//
|
||||
// try a signature
|
||||
//
|
||||
PGPSignatureGenerator signGen = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PGPPublicKey.ECDSA, HashAlgorithmTags.SHA256).setProvider("SC"));
|
||||
|
||||
signGen.init(PGPSignature.BINARY_DOCUMENT, ecdsaKeyPair.getPrivateKey());
|
||||
|
||||
signGen.update("hello world!".getBytes());
|
||||
|
||||
PGPSignature sig = signGen.generate();
|
||||
|
||||
sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), ecdsaKeyPair.getPublicKey());
|
||||
|
||||
sig.update("hello world!".getBytes());
|
||||
|
||||
if (!sig.verify())
|
||||
{
|
||||
fail("signature failed to verify!");
|
||||
}
|
||||
|
||||
//
|
||||
// generate a key ring
|
||||
//
|
||||
char[] passPhrase = "test".toCharArray();
|
||||
PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build().get(HashAlgorithmTags.SHA1);
|
||||
PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, ecdsaKeyPair,
|
||||
"test@bouncycastle.org", sha1Calc, null, null, new JcaPGPContentSignerBuilder(ecdsaKeyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha1Calc).setProvider("SC").build(passPhrase));
|
||||
|
||||
PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing();
|
||||
|
||||
PGPSecretKeyRing secRing = keyRingGen.generateSecretKeyRing();
|
||||
|
||||
KeyFingerPrintCalculator fingerCalc = new JcaKeyFingerprintCalculator();
|
||||
|
||||
PGPPublicKeyRing pubRingEnc = new PGPPublicKeyRing(pubRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(pubRing.getEncoded(), pubRingEnc.getEncoded()))
|
||||
{
|
||||
fail("public key ring encoding failed");
|
||||
}
|
||||
|
||||
PGPSecretKeyRing secRingEnc = new PGPSecretKeyRing(secRing.getEncoded(), fingerCalc);
|
||||
|
||||
if (!Arrays.areEqual(secRing.getEncoded(), secRingEnc.getEncoded()))
|
||||
{
|
||||
fail("secret key ring encoding failed");
|
||||
}
|
||||
}
|
||||
|
||||
public void performTest()
|
||||
throws Exception
|
||||
{
|
||||
PGPUtil.setDefaultProvider("SC");
|
||||
|
||||
//
|
||||
// Read the public key
|
||||
//
|
||||
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
for (Iterator it = pubKeyRing.getPublicKey().getSignatures(); it.hasNext();)
|
||||
{
|
||||
PGPSignature certification = (PGPSignature)it.next();
|
||||
|
||||
certification.init(new JcaPGPContentVerifierBuilderProvider().setProvider("SC"), pubKeyRing.getPublicKey());
|
||||
|
||||
if (!certification.verifyCertification((String)pubKeyRing.getPublicKey().getUserIDs().next(), pubKeyRing.getPublicKey()))
|
||||
{
|
||||
fail("self certification does not verify");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read the private key
|
||||
//
|
||||
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
|
||||
|
||||
|
||||
generateAndSign();
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "PGPECDSATest";
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
runTest(new PGPECDSATest());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user