Example #1
0
  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 PrivateKey getPrivateKey(PGPPrivateKey privKey) throws PGPException {
    PublicKeyPacket pubPk = privKey.getPublicKeyPacket();
    BCPGKey privPk = privKey.getPrivateKeyDataPacket();

    try {
      KeyFactory fact;

      switch (pubPk.getAlgorithm()) {
        case PGPPublicKey.RSA_ENCRYPT:
        case PGPPublicKey.RSA_GENERAL:
        case PGPPublicKey.RSA_SIGN:
          RSAPublicBCPGKey rsaPub = (RSAPublicBCPGKey) pubPk.getKey();
          RSASecretBCPGKey rsaPriv = (RSASecretBCPGKey) privPk;
          RSAPrivateCrtKeySpec rsaPrivSpec =
              new RSAPrivateCrtKeySpec(
                  rsaPriv.getModulus(),
                  rsaPub.getPublicExponent(),
                  rsaPriv.getPrivateExponent(),
                  rsaPriv.getPrimeP(),
                  rsaPriv.getPrimeQ(),
                  rsaPriv.getPrimeExponentP(),
                  rsaPriv.getPrimeExponentQ(),
                  rsaPriv.getCrtCoefficient());

          fact = helper.createKeyFactory("RSA");

          return fact.generatePrivate(rsaPrivSpec);
        case PGPPublicKey.DSA:
          DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey) pubPk.getKey();
          DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey) privPk;
          DSAPrivateKeySpec dsaPrivSpec =
              new DSAPrivateKeySpec(dsaPriv.getX(), dsaPub.getP(), dsaPub.getQ(), dsaPub.getG());

          fact = helper.createKeyFactory("DSA");

          return fact.generatePrivate(dsaPrivSpec);
        case PGPPublicKey.ELGAMAL_ENCRYPT:
        case PGPPublicKey.ELGAMAL_GENERAL:
          ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey) pubPk.getKey();
          ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey) privPk;
          ElGamalPrivateKeySpec elSpec =
              new ElGamalPrivateKeySpec(
                  elPriv.getX(), new ElGamalParameterSpec(elPub.getP(), elPub.getG()));

          fact = helper.createKeyFactory("ElGamal");

          return fact.generatePrivate(elSpec);
        default:
          throw new PGPException("unknown public key algorithm encountered");
      }
    } catch (PGPException e) {
      throw e;
    } catch (Exception e) {
      throw new PGPException("Exception constructing key", e);
    }
  }
  public TestResult perform() {
    try {
      String file = null;
      KeyFactory fact = KeyFactory.getInstance("DSA", "BC");
      PGPPublicKey pubKey = null;
      PrivateKey privKey = null;

      PGPUtil.setDefaultProvider("BC");

      //
      // 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, "BC");

      //
      // signature generation
      //
      String data = "hello world!";
      ByteArrayOutputStream bOut = new ByteArrayOutputStream();
      ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
      PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "BC");

      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, "BC");

      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("BC");
          pgpKeyID = pgpKey.getKeyID();

          //
          // verify the key
          //

        }
      }

      Cipher c = Cipher.getInstance("ElGamal/None/PKCS1Padding", "BC");

      c.init(Cipher.ENCRYPT_MODE, pKey);

      byte[] in = "hello world".getBytes();

      byte[] out = c.doFinal(in);

      pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC");

      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, "BC");

      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, "BC");

      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(), "BC");

      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(), "BC");
      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, "BC");

      clear = encP.getDataStream(pgpPrivKey, "BC");

      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());
    }
  }