package org.bouncycastle.openpgp.test;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.SignatureException;
import java.security.spec.ECGenParameterSpec;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPKeyRingGenerator;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.test.SimpleTest;
public class PGPECDHTest
extends SimpleTest
{
byte[] testPubKey =
Base64.decode(
"mFIEUb4GwBMIKoZIzj0DAQcCAwS8p3TFaRAx58qCG63W+UNthXBPSJDnVDPTb/sT\n" +
"iXePaAZ/Gh1GKXTq7k6ab/67MMeVFp/EdySumqdWLtvceFKstFBUZXN0IEVDRFNB\n" +
"LUVDREggKEtleSBhbmQgc3Via2V5IGFyZSAyNTYgYml0cyBsb25nKSA8dGVzdC5l\n" +
"Y2RzYS5lY2RoQGV4YW1wbGUuY29tPoh6BBMTCAAiBQJRvgbAAhsDBgsJCAcDAgYV\n" +
"CAIJCgsEFgIDAQIeAQIXgAAKCRD3wDlWjFo9U5O2AQDi89NO6JbaIObC63jMMWsi\n" +
"AaQHrBCPkDZLibgNv73DLgD/faouH4YZJs+cONQBPVnP1baG1NpWR5ppN3JULFcr\n" +
"hcq4VgRRvgbAEggqhkjOPQMBBwIDBLtY8Nmfz0zSEa8C1snTOWN+VcT8pXPwgJRy\n" +
"z6kSP4nPt1xj1lPKj5zwPXKWxMkPO9ocqhKdg2mOh6/rc1ObIoMDAQgHiGEEGBMI\n" +
"AAkFAlG+BsACGwwACgkQ98A5VoxaPVN8cgEAj4dMNMNwRSg2ZBWunqUAHqIedVbS\n" +
"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==");
private void generate()
throws Exception
{
//
// Generate a master key
//
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
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", "BC");
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("BC").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");
}
}
public void performTest()
throws Exception
{
PGPUtil.setDefaultProvider("BC");
//
// Read the public key
//
PGPPublicKeyRing pubKeyRing = new PGPPublicKeyRing(testPubKey, new JcaKeyFingerprintCalculator());
doBasicKeyRingCheck(pubKeyRing);
//
// Read the private key
//
PGPSecretKeyRing secretKeyRing = new PGPSecretKeyRing(testPrivKey, new JcaKeyFingerprintCalculator());
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("BC"), 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());
}
}