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!
  }
  private void createSignature(OutputStream out) throws Exception {
    PGPSecretKey pgpSec = readSecretKey();
    PGPPrivateKey pgpPrivKey =
        pgpSec.extractPrivateKey(
            new JcePBESecretKeyDecryptorBuilder()
                .setProvider(getProvider())
                .build("sdude".toCharArray()));
    PGPSignatureGenerator sGen =
        new PGPSignatureGenerator(
            new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1)
                .setProvider(getProvider()));

    sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);

    BCPGOutputStream bOut = new BCPGOutputStream(out);

    InputStream fIn = new ByteArrayInputStream("Test Signature".getBytes("UTF-8"));

    int ch;
    while ((ch = fIn.read()) >= 0) {
      sGen.update((byte) ch);
    }

    fIn.close();

    sGen.generate().encode(bOut);
  }
Exemple #3
0
  /**
   * Reads private key from the provided InputStream
   *
   * @param input InputStream of the private key
   * @return PGPSecretKey
   * @throws LRException NO_KEY error if the key cannot be obtained from the input stream
   */
  private PGPSecretKey readSecretKey(InputStream input) throws LRException {
    PGPSecretKeyRingCollection pgpSec;

    try {
      pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input));
    } catch (Exception e) {
      throw new LRException(LRException.NO_KEY);
    }

    java.util.Iterator keyRingIter = pgpSec.getKeyRings();
    while (keyRingIter.hasNext()) {
      PGPSecretKeyRing keyRing = (PGPSecretKeyRing) keyRingIter.next();

      java.util.Iterator keyIter = keyRing.getSecretKeys();
      while (keyIter.hasNext()) {
        PGPSecretKey key = (PGPSecretKey) keyIter.next();

        if (key.isSigningKey()) {
          return key;
        }
      }
    }

    throw new LRException(LRException.NO_KEY);
  }
Exemple #4
0
  /**
   * Encodes the provided message with the private key and pass phrase set in configuration
   *
   * @param message Message to encode
   * @return Encoded message
   * @throws LRException SIGNING_FAILED if the document cannot be signed, NO_KEY if the key cannot
   *     be obtained
   */
  private String signEnvelopeData(String message) throws LRException {
    // Get an InputStream for the private key
    InputStream privateKeyStream = getPrivateKeyStream(privateKey);

    // Get an OutputStream for the result
    ByteArrayOutputStream result = new ByteArrayOutputStream();
    ArmoredOutputStream aOut = new ArmoredOutputStream(result);

    // Get the pass phrase
    char[] privateKeyPassword = passPhrase.toCharArray();

    try {
      // Get the private key from the InputStream
      PGPSecretKey sk = readSecretKey(privateKeyStream);
      PGPPrivateKey pk = sk.extractPrivateKey(privateKeyPassword, "BC");
      PGPSignatureGenerator pgp =
          new PGPSignatureGenerator(sk.getPublicKey().getAlgorithm(), PGPUtil.SHA256, "BC");
      PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();

      // Clear sign the message
      java.util.Iterator it = sk.getPublicKey().getUserIDs();
      if (it.hasNext()) {
        spGen.setSignerUserID(false, (String) it.next());
        pgp.setHashedSubpackets(spGen.generate());
      }
      aOut.beginClearText(PGPUtil.SHA256);
      pgp.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, pk);
      byte[] msg = message.getBytes();
      pgp.update(msg, 0, msg.length);
      aOut.write(msg, 0, msg.length);
      BCPGOutputStream bOut = new BCPGOutputStream(aOut);
      aOut.endClearText();
      pgp.generate().encode(bOut);
      String strResult = result.toString("utf8");
      return strResult;
    } catch (Exception e) {
      throw new LRException(LRException.SIGNING_FAILED);
    } finally {
      try {
        if (privateKeyStream != null) {
          privateKeyStream.close();
        }
        aOut.close();
        result.close();
      } catch (IOException e) {
        // Could not close the streams
      }
    }
  }
  /** Creates a {@link PersonalKey} from private and public key byte buffers. */
  @SuppressWarnings("unchecked")
  public static PersonalKey load(byte[] privateKeyData, char[] passphrase, byte[] bridgeCertData)
      throws KonException, IOException, PGPException, CertificateException,
          NoSuchProviderException {
    PGPSecretKeyRing secRing = new PGPSecretKeyRing(privateKeyData, PGPUtils.FP_CALC);

    PGPSecretKey authKey = null;
    PGPSecretKey signKey = null;
    PGPSecretKey encrKey = null;

    // assign from key ring
    Iterator<PGPSecretKey> skeys = secRing.getSecretKeys();
    while (skeys.hasNext()) {
      PGPSecretKey key = skeys.next();
      if (key.isMasterKey()) {
        // master key: authentication / legacy: signing
        authKey = key;
      } else {
        // sub keys: encryption and signing / legacy: only encryption
        int keyFlags = PGPUtils.getKeyFlags(key.getPublicKey());
        if ((keyFlags & PGPKeyFlags.CAN_SIGN) == PGPKeyFlags.CAN_SIGN) signKey = key;
        else encrKey = key;
      }
    }
    // legacy: auth key is actually signing key
    if (signKey == null && authKey != null && authKey.isSigningKey()) {
      LOGGER.info("loading legacy key");
      signKey = authKey;
    }

    if (authKey == null || signKey == null || encrKey == null)
      throw new KonException(
          KonException.Error.LOAD_KEY, new PGPException("could not found all keys in key data"));

    // decrypt private
    PGPDigestCalculatorProvider calcProv = new JcaPGPDigestCalculatorProviderBuilder().build();
    PBESecretKeyDecryptor decryptor =
        new JcePBESecretKeyDecryptorBuilder(calcProv)
            .setProvider(PGPUtils.PROVIDER)
            .build(passphrase);
    PGPKeyPair authKeyPair = PGPUtils.decrypt(authKey, decryptor);
    PGPKeyPair signKeyPair = PGPUtils.decrypt(signKey, decryptor);
    PGPKeyPair encryptKeyPair = PGPUtils.decrypt(encrKey, decryptor);

    // X.509 bridge certificate
    X509Certificate bridgeCert = PGPUtils.loadX509Cert(bridgeCertData);

    return new PersonalKey(authKeyPair, signKeyPair, encryptKeyPair, bridgeCert);
  }
  /**
   * Replace the passed the public key on the passed in secret key.
   *
   * @param secretKey secret key to change
   * @param publicKey new public key.
   * @return a new secret key.
   * @throws IllegalArgumentException if keyIDs do not match.
   */
  public static PGPSecretKey replacePublicKey(PGPSecretKey secretKey, PGPPublicKey publicKey) {
    if (publicKey.getKeyID() != secretKey.getKeyID()) {
      throw new IllegalArgumentException("keyIDs do not match");
    }

    return new PGPSecretKey(secretKey.secret, publicKey);
  }
Exemple #7
0
  /**
   * Create a clear sign signature over the input data. (Not detached)
   *
   * @param input the content to be signed
   * @param keyring the keyring
   * @param keyId the 4 bytes identifier of the key, in hexadecimal format
   * @param passphrase the passphrase to retrieve the private key
   * @param output the output destination of the signature
   */
  public static void clearSign(
      InputStream input, InputStream keyring, String keyId, String passphrase, OutputStream output)
      throws IOException, PGPException, GeneralSecurityException {
    PGPSecretKey secretKey = getSecretKey(keyring, keyId);
    PGPPrivateKey privateKey =
        secretKey.extractPrivateKey(
            new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider())
                .build(passphrase.toCharArray()));

    int digest = PGPUtil.SHA1;

    PGPSignatureGenerator signatureGenerator =
        new PGPSignatureGenerator(
            new BcPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), digest));
    signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privateKey);

    ArmoredOutputStream armoredOutput = new ArmoredOutputStream(output);
    armoredOutput.beginClearText(digest);

    BufferedReader reader = new BufferedReader(new InputStreamReader(input));

    String line;
    while ((line = reader.readLine()) != null) {
      // trailing spaces must be removed for signature calculation (see
      // http://tools.ietf.org/html/rfc4880#section-7.1)
      byte[] data = trim(line).getBytes("UTF-8");

      armoredOutput.write(data);
      armoredOutput.write(EOL);

      signatureGenerator.update(data);
      signatureGenerator.update(EOL);
    }

    armoredOutput.endClearText();

    PGPSignature signature = signatureGenerator.generate();
    signature.encode(new BCPGOutputStream(armoredOutput));

    armoredOutput.close();
  }
  static PGPSecretKey readSecretKey() throws Exception {
    InputStream input = new ByteArrayInputStream(getSecKeyRing());
    PGPSecretKeyRingCollection pgpSec =
        new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input));

    @SuppressWarnings("rawtypes")
    Iterator keyRingIter = pgpSec.getKeyRings();
    while (keyRingIter.hasNext()) {
      PGPSecretKeyRing keyRing = (PGPSecretKeyRing) keyRingIter.next();

      @SuppressWarnings("rawtypes")
      Iterator keyIter = keyRing.getSecretKeys();
      while (keyIter.hasNext()) {
        PGPSecretKey key = (PGPSecretKey) keyIter.next();

        if (key.isSigningKey()) {
          return key;
        }
      }
    }

    throw new IllegalArgumentException("Can't find signing key in key ring.");
  }
Exemple #9
0
  /**
   * Returns the secret key matching the specified identifier.
   *
   * @param input the input stream containing the keyring collection
   * @param keyId the 4 bytes identifier of the key
   */
  private static PGPSecretKey getSecretKey(InputStream input, String keyId)
      throws IOException, PGPException {
    PGPSecretKeyRingCollection keyrings =
        new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input));

    Iterator rIt = keyrings.getKeyRings();

    while (rIt.hasNext()) {
      PGPSecretKeyRing kRing = (PGPSecretKeyRing) rIt.next();
      Iterator kIt = kRing.getSecretKeys();

      while (kIt.hasNext()) {
        PGPSecretKey key = (PGPSecretKey) kIt.next();

        if (key.isSigningKey()
            && Long.toHexString(key.getKeyID() & 0xFFFFFFFFL).equals(keyId.toLowerCase())) {
          return key;
        }
      }
    }

    return null;
  }
  /**
   * Return a copy of the passed in secret key, encrypted using a new password and the passed in
   * algorithm.
   *
   * @param key the PGPSecretKey to be copied.
   * @param oldKeyDecryptor the current decryptor based on the current password for key.
   * @param newKeyEncryptor a new encryptor based on a new password for encrypting the secret key
   *     material.
   */
  public static PGPSecretKey copyWithNewPassword(
      PGPSecretKey key,
      PBESecretKeyDecryptor oldKeyDecryptor,
      PBESecretKeyEncryptor newKeyEncryptor)
      throws PGPException {
    if (key.isPrivateKeyEmpty()) {
      throw new PGPException("no private key in this SecretKey - public key present only.");
    }

    byte[] rawKeyData = key.extractKeyData(oldKeyDecryptor);
    int s2kUsage = key.secret.getS2KUsage();
    byte[] iv = null;
    S2K s2k = null;
    byte[] keyData;
    int newEncAlgorithm = SymmetricKeyAlgorithmTags.NULL;

    if (newKeyEncryptor == null
        || (newKeyEncryptor.getAlgorithm() == SymmetricKeyAlgorithmTags.NULL
            && !(newKeyEncryptor instanceof GnuDivertToCardSecretKeyEncryptor))) {
      s2kUsage = SecretKeyPacket.USAGE_NONE;
      if (key.secret.getS2KUsage()
          == SecretKeyPacket.USAGE_SHA1) // SHA-1 hash, need to rewrite checksum
      {
        keyData = new byte[rawKeyData.length - 18];

        System.arraycopy(rawKeyData, 0, keyData, 0, keyData.length - 2);

        byte[] check = checksum(null, keyData, keyData.length - 2);

        keyData[keyData.length - 2] = check[0];
        keyData[keyData.length - 1] = check[1];
      } else {
        keyData = rawKeyData;
      }
    } else {
      if (key.secret.getPublicKeyPacket().getVersion() < 4) {
        // Version 2 or 3 - RSA Keys only

        byte[] encKey = newKeyEncryptor.getKey();
        keyData = new byte[rawKeyData.length];

        if (newKeyEncryptor.getHashAlgorithm() != HashAlgorithmTags.MD5) {
          throw new PGPException("MD5 Digest Calculator required for version 3 key encryptor.");
        }

        //
        // process 4 numbers
        //
        int pos = 0;
        for (int i = 0; i != 4; i++) {
          int encLen = (((rawKeyData[pos] << 8) | (rawKeyData[pos + 1] & 0xff)) + 7) / 8;

          keyData[pos] = rawKeyData[pos];
          keyData[pos + 1] = rawKeyData[pos + 1];

          byte[] tmp;
          if (i == 0) {
            tmp = newKeyEncryptor.encryptKeyData(encKey, rawKeyData, pos + 2, encLen);
            iv = newKeyEncryptor.getCipherIV();

          } else {
            byte[] tmpIv = new byte[iv.length];

            System.arraycopy(keyData, pos - iv.length, tmpIv, 0, tmpIv.length);
            tmp = newKeyEncryptor.encryptKeyData(encKey, tmpIv, rawKeyData, pos + 2, encLen);
          }

          System.arraycopy(tmp, 0, keyData, pos + 2, tmp.length);
          pos += 2 + encLen;
        }

        //
        // copy in checksum.
        //
        keyData[pos] = rawKeyData[pos];
        keyData[pos + 1] = rawKeyData[pos + 1];

        s2k = newKeyEncryptor.getS2K();
        newEncAlgorithm = newKeyEncryptor.getAlgorithm();
      } else {
        if (s2kUsage == SecretKeyPacket.USAGE_NONE) {
          s2kUsage = SecretKeyPacket.USAGE_SHA1;
        }
        keyData = newKeyEncryptor.encryptKeyData(rawKeyData, 0, rawKeyData.length);

        iv = newKeyEncryptor.getCipherIV();

        s2k = newKeyEncryptor.getS2K();

        newEncAlgorithm = newKeyEncryptor.getAlgorithm();
      }
    }

    SecretKeyPacket secret;
    if (key.secret instanceof SecretSubkeyPacket) {
      secret =
          new SecretSubkeyPacket(
              key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData);
    } else {
      secret =
          new SecretKeyPacket(
              key.secret.getPublicKeyPacket(), newEncAlgorithm, s2kUsage, s2k, iv, keyData);
    }

    return new PGPSecretKey(secret, key.pub);
  }