Example usage for org.bouncycastle.openpgp PGPEncryptedDataList getEncryptedDataObjects

List of usage examples for org.bouncycastle.openpgp PGPEncryptedDataList getEncryptedDataObjects

Introduction

In this page you can find the example usage for org.bouncycastle.openpgp PGPEncryptedDataList getEncryptedDataObjects.

Prototype

public Iterator getEncryptedDataObjects() 

Source Link

Document

Returns an iterator over the encryption method objects held in this list, in the order they appeared in the stream they are read from.

Usage

From source file:org.apache.gobblin.crypto.GPGFileDecryptor.java

License:Apache License

/**
 * Taking in a file inputstream, keyring inputstream and a passPhrase, generate a decrypted file inputstream.
 * @param inputStream file inputstream/*  w  ww .  j  a  v a 2s . c  o  m*/
 * @param keyIn keyring inputstream. This InputStream is owned by the caller.
 * @param passPhrase passPhrase
 * @return an {@link InputStream} for the decrypted content
 * @throws IOException
 */
public InputStream decryptFile(InputStream inputStream, InputStream keyIn, String passPhrase)
        throws IOException {
    try {
        PGPEncryptedDataList enc = getPGPEncryptedDataList(inputStream);
        Iterator it = enc.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;
        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn),
                new BcKeyFingerprintCalculator());

        while (sKey == null && it.hasNext()) {
            pbe = (PGPPublicKeyEncryptedData) it.next();
            sKey = findSecretKey(pgpSec, pbe.getKeyID(), passPhrase);
        }

        if (sKey == null) {
            throw new IllegalArgumentException("secret key for message not found.");
        }

        InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(sKey));
        JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clear);

        return new LazyMaterializeDecryptorInputStream(pgpFact);
    } catch (PGPException e) {
        throw new IOException(e);
    }
}

From source file:org.kontalk.crypto.Coder.java

License:Open Source License

private static DecryptionResult decryptAndVerify(InputStream encryptedStream, PersonalKey myKey,
        PGPPublicKey senderKey) {//from   w ww .j  a  v a 2  s. co  m
    // note: the signature is inside the encrypted data

    DecryptionResult result = new DecryptionResult();

    PGPObjectFactory pgpFactory = new PGPObjectFactory(encryptedStream);

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

    try { // catch all IO and PGP exceptions

        // the first object might be a PGP marker packet
        Object o = pgpFactory.nextObject(); // nullable
        if (!(o instanceof PGPEncryptedDataList)) {
            o = pgpFactory.nextObject(); // nullable
        }

        if (!(o instanceof PGPEncryptedDataList)) {
            LOGGER.warning("can't find encrypted data list in data");
            result.errors.add(Error.INVALID_DATA);
            return result;
        }
        PGPEncryptedDataList encDataList = (PGPEncryptedDataList) o;

        // check if secret key matches our encryption keyID
        Iterator<?> it = encDataList.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;
        long myKeyID = myKey.getPrivateEncryptionKey().getKeyID();
        while (sKey == null && it.hasNext()) {
            Object i = it.next();
            if (!(i instanceof PGPPublicKeyEncryptedData))
                continue;
            pbe = (PGPPublicKeyEncryptedData) i;
            if (pbe.getKeyID() == myKeyID)
                sKey = myKey.getPrivateEncryptionKey();
        }
        if (sKey == null || pbe == null) {
            LOGGER.warning("private key for message not found");
            result.errors.add(Error.INVALID_PRIVATE_KEY);
            return result;
        }

        InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

        PGPObjectFactory plainFactory = new PGPObjectFactory(clear);

        Object object = plainFactory.nextObject(); // nullable

        if (!(object instanceof PGPCompressedData)) {
            LOGGER.warning("data packet not compressed");
            result.errors.add(Error.INVALID_DATA);
            return result;
        }

        PGPCompressedData cData = (PGPCompressedData) object;
        PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());

        object = pgpFact.nextObject(); // nullable

        // the first object could be the signature list
        // get signature from it
        PGPOnePassSignature ops = null;
        if (object instanceof PGPOnePassSignatureList) {
            PGPOnePassSignatureList signatureList = (PGPOnePassSignatureList) object;
            // there is a signature list, so we assume the message is signed
            // (makes sense)
            result.signing = Signing.SIGNED;

            if (signatureList.isEmpty()) {
                LOGGER.warning("signature list is empty");
                result.errors.add(Error.INVALID_SIGNATURE_DATA);
            } else {
                ops = signatureList.get(0);
                ops.init(new BcPGPContentVerifierBuilderProvider(), senderKey);
            }
            object = pgpFact.nextObject(); // nullable
        } else {
            LOGGER.warning("signature list not found");
            result.signing = Signing.NOT;
        }

        if (!(object instanceof PGPLiteralData)) {
            LOGGER.warning("unknown packet type: " + object.getClass().getName());
            result.errors.add(Error.INVALID_DATA);
            return result;
        }

        PGPLiteralData ld = (PGPLiteralData) object;
        InputStream unc = ld.getInputStream();
        int ch;
        while ((ch = unc.read()) >= 0) {
            outputStream.write(ch);
            if (ops != null)
                try {
                    ops.update((byte) ch);
                } catch (SignatureException ex) {
                    LOGGER.log(Level.WARNING, "can't read signature", ex);
                }
        }

        result.decryptedStream = Optional.of(outputStream);

        if (ops != null) {
            result = verifySignature(result, pgpFact, ops);
        }

        // verify message integrity
        if (pbe.isIntegrityProtected()) {
            if (!pbe.verify()) {
                LOGGER.warning("message integrity check failed");
                result.errors.add(Error.INVALID_INTEGRITY);
            }
        } else {
            LOGGER.warning("message is not integrity protected");
            result.errors.add(Error.NO_INTEGRITY);
        }

    } catch (IOException | PGPException ex) {
        LOGGER.log(Level.WARNING, "can't decrypt message", ex);
        result.errors.add(Error.UNKNOWN_ERROR);
    }

    return result;
}

From source file:org.mule.module.pgp.DecryptStreamTransformer.java

License:Open Source License

/**
 * {@inheritDoc}//from   w  w w .  j a va  2s . com
 */
@Override
public void initialize(OutputStream out) throws Exception {
    InputStream decodedInputStream = PGPUtil.getDecoderStream(this.toBeDecrypted);
    PGPObjectFactory pgpF = new PGPObjectFactory(decodedInputStream);
    Object o = pgpF.nextObject();

    if (o == null) {
        throw new IllegalArgumentException("Invalid PGP message");
    }

    // the first object might be a PGP marker packet.
    PGPEncryptedDataList enc;
    if (o instanceof PGPEncryptedDataList) {
        enc = (PGPEncryptedDataList) o;

    } else {
        enc = (PGPEncryptedDataList) pgpF.nextObject();
    }

    // This loop looks like it is ready for multiple encrypted
    // objects, but really only one is expected.
    Iterator<?> it = enc.getEncryptedDataObjects();
    PGPPublicKeyEncryptedData pbe = null;
    PGPPrivateKey privateKey = null;
    while (privateKey == null && it.hasNext()) {
        pbe = (PGPPublicKeyEncryptedData) it.next();
        privateKey = getPrivateKey(pbe.getKeyID(), this.password);
        if (privateKey == null) {
            throw new IllegalArgumentException("Failed to find private key with ID " + pbe.getKeyID());
        }
    }

    clearStream = pbe.getDataStream(privateKey, "BC");
    PGPObjectFactory plainFact = new PGPObjectFactory(clearStream);

    o = plainFact.nextObject();
    PGPOnePassSignature signature = null;
    if (o instanceof PGPOnePassSignatureList) {
        PGPOnePassSignatureList list = (PGPOnePassSignatureList) o;
        signature = list.get(0);
        signature.initVerify(this.publicKey, "BC");
        // TODO verify signature
        // signature.verify(null);
        o = plainFact.nextObject();
    }

    compressedStream = null;
    if (o instanceof PGPCompressedData) {
        PGPCompressedData cData = (PGPCompressedData) o;
        compressedStream = new BufferedInputStream(cData.getDataStream());
        PGPObjectFactory pgpFact = new PGPObjectFactory(compressedStream);
        Object streamData = pgpFact.nextObject();
        o = streamData;
    }

    if (o instanceof PGPLiteralData) {
        PGPLiteralData ld = (PGPLiteralData) o;
        uncStream = ld.getInputStream();
    } else {
        throw new PGPException("input is not PGPLiteralData - type unknown.");
    }
}

From source file:org.opentestsystem.delivery.testreg.transformer.GpgVerifier.java

License:Open Source License

public byte[] decryptAndVerify(File encryptedSignedFile) throws IOException, SignatureException, PGPException {

    byte[] output = null;

    InputStream in = PGPUtil.getDecoderStream(new FileInputStream(encryptedSignedFile));
    InputStream publicKeyIn = encryptor.getStreamForPath(publicKeyringLocation);

    ByteArrayOutputStream fOut = new ByteArrayOutputStream();

    PGPObjectFactory pgpF = new PGPObjectFactory(in);
    PGPEncryptedDataList enc;

    Object o = pgpF.nextObject();
    ///*  w w  w  .  j  a  va 2s .co m*/
    // the first object might be a PGP marker packet.
    //

    while (!(o instanceof PGPEncryptedDataList)) {
        o = pgpF.nextObject();
    }

    if (o instanceof PGPEncryptedDataList) {
        enc = (PGPEncryptedDataList) o;
    } else {
        enc = (PGPEncryptedDataList) pgpF.nextObject();
    }

    //
    // find the secret key
    //
    Iterator<?> it = enc.getEncryptedDataObjects();
    PGPPrivateKey sKey = null;
    PGPPublicKeyEncryptedData pbe = null;

    while (sKey == null && it.hasNext()) {
        pbe = (PGPPublicKeyEncryptedData) it.next();
        InputStream secretKeyringInputStream = encryptor.getStreamForPath(secretKeyringLocation);

        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
                PGPUtil.getDecoderStream(secretKeyringInputStream));
        PGPSecretKey pgpSecKey = pgpSec.getSecretKey(pbe.getKeyID());
        if (pgpSecKey == null) {
            fail("could not find secret key");
        }

        PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(
                new BcPGPDigestCalculatorProvider()).build(LANDINGZONE_PASS);

        sKey = pgpSecKey.extractPrivateKey(decryptor);
    }

    if (sKey == null) {
        throw new IllegalArgumentException("secret key for message not found.");
    }

    InputStream clear = pbe
            .getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));

    PGPObjectFactory plainFact = new PGPObjectFactory(clear);

    Object message = null;

    PGPOnePassSignatureList onePassSignatureList = null;
    PGPSignatureList signatureList = null;
    PGPCompressedData compressedData = null;

    message = plainFact.nextObject();
    ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();

    while (message != null) {
        LOGGER.debug("decrypted message: " + message.toString());
        if (message instanceof PGPCompressedData) {
            compressedData = (PGPCompressedData) message;
            plainFact = new PGPObjectFactory(compressedData.getDataStream());
            message = plainFact.nextObject();
        }

        if (message instanceof PGPLiteralData) {
            // have to read it and keep it somewhere.
            Streams.pipeAll(((PGPLiteralData) message).getInputStream(), actualOutput);
        } else if (message instanceof PGPOnePassSignatureList) {
            onePassSignatureList = (PGPOnePassSignatureList) message;
        } else if (message instanceof PGPSignatureList) {
            signatureList = (PGPSignatureList) message;
        } else {
            throw new PGPException("message unknown message type.");
        }
        message = plainFact.nextObject();
    }
    actualOutput.close();
    PGPPublicKey publicKey = null;
    output = actualOutput.toByteArray();

    if (onePassSignatureList == null || signatureList == null) {
        throw new PGPException("Signatures not found.");
    } else {

        for (int i = 0; i < onePassSignatureList.size(); i++) {
            PGPOnePassSignature ops = onePassSignatureList.get(0);
            LOGGER.debug("verifier : " + ops.getKeyID());
            PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(
                    PGPUtil.getDecoderStream(publicKeyIn));
            publicKey = pgpRing.getPublicKey(ops.getKeyID());
            if (publicKey != null) {
                ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);
                ops.update(output);
                PGPSignature signature = signatureList.get(i);
                // apparently the signature can only be verified once?? if the verify method is called a 2nd time it
                // will fail
                boolean signatureVerified = ops.verify(signature);
                assertThat(signatureVerified, is(true));
                if (signatureVerified) {
                    Iterator<?> userIds = publicKey.getUserIDs();
                    while (userIds.hasNext()) {
                        String userId = (String) userIds.next();
                        LOGGER.debug("Signed by " + userId);
                    }
                    LOGGER.debug("Signature verified");
                } else {
                    throw new SignatureException("Signature verification failed");
                }
            }
        }

    }

    if (pbe.isIntegrityProtected() && !pbe.verify()) {
        throw new PGPException("Data is integrity protected but integrity is lost.");
    } else if (publicKey == null) {
        throw new SignatureException("Signature not found");
    } else {
        fOut.write(output);
        fOut.flush();
        fOut.close();

        LOGGER.debug("decrypt and verify output: " + fOut.toString());
    }

    return output;
}

From source file:org.pgptool.gui.encryption.implpgp.EncryptionServicePgpImpl.java

License:Open Source License

@SuppressWarnings("rawtypes")
@Override/* w  w w.ja v a  2s  .  c  o m*/
public Set<String> findKeyIdsForDecryption(InputStream inputStream) {
    Preconditions.checkArgument(inputStream != null, "Input stream must not be null");

    try {
        PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(inputStream),
                KeyFilesOperationsPgpImpl.fingerprintCalculator);

        for (Iterator iter = factory.iterator(); iter.hasNext();) {
            Object section = iter.next();
            log.debug(section);

            if (section instanceof PGPEncryptedDataList) {
                PGPEncryptedDataList d = (PGPEncryptedDataList) section;
                HashSet<String> ret = new HashSet<>();
                for (Iterator dataIter = d.getEncryptedDataObjects(); dataIter.hasNext();) {
                    PGPPublicKeyEncryptedData data = (PGPPublicKeyEncryptedData) dataIter.next();
                    ret.add(KeyDataPgp.buildKeyIdStr(data.getKeyID()));
                }
                log.debug("Possible decryption with IDS: " + Arrays.toString(ret.toArray()));
                return ret;
            }
        }
        throw new RuntimeException("Information about decryption methods was not found");
    } catch (Throwable t) {
        throw new RuntimeException("This file doesn't look like encrypted file OR format is not supported", t);
    }
}

From source file:org.pgptool.gui.encryption.implpgp.EncryptionServicePgpImpl.java

License:Open Source License

@SuppressWarnings("rawtypes")
private PGPPublicKeyEncryptedData getPublicKeyEncryptedDataByKeyId(InputStream in, PGPSecretKey secretKey) {
    try {/* ww w .  j a v a2s.  co  m*/
        PGPObjectFactory factory = new PGPObjectFactory(PGPUtil.getDecoderStream(in),
                KeyFilesOperationsPgpImpl.fingerprintCalculator);

        for (Iterator iter = factory.iterator(); iter.hasNext();) {
            Object section = iter.next();
            if (section instanceof PGPEncryptedDataList) {
                PGPEncryptedDataList d = (PGPEncryptedDataList) section;
                for (Iterator dataIter = d.getEncryptedDataObjects(); dataIter.hasNext();) {
                    PGPPublicKeyEncryptedData data = (PGPPublicKeyEncryptedData) dataIter.next();
                    if (data.getKeyID() == secretKey.getKeyID()) {
                        return data;
                    }
                }
            }
        }
        // NOTE: That is actually should NEVER happen since secret key we're
        // supposed to use here was taken exactly same way as we're looking
        // for PGPPublicKeyEncryptedData now
        throw new RuntimeException("Encryption data matching given key "
                + KeyDataPgp.buildKeyIdStr(secretKey.getKeyID()) + " wasn't found");
    } catch (Throwable t) {
        throw new RuntimeException("Failed to find Encryption data section in encrypted file", t);
    }
}

From source file:org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyOperation.java

License:Open Source License

private EncryptStreamResult handleEncryptedPacket(PgpDecryptVerifyInputParcel input,
        CryptoInputParcel cryptoInput, PGPEncryptedDataList enc, OperationLog log, int indent,
        boolean useBackupCode) throws PGPException {

    EncryptStreamResult result = new EncryptStreamResult();

    boolean asymmetricPacketFound = false;
    boolean symmetricPacketFound = false;
    boolean anyPacketFound = false;
    boolean decryptedSessionKeyAvailable = false;

    PGPPublicKeyEncryptedData encryptedDataAsymmetric = null;
    PGPPBEEncryptedData encryptedDataSymmetric = null;
    CanonicalizedSecretKey decryptionKey = null;
    CachingDataDecryptorFactory cachedKeyDecryptorFactory = new CachingDataDecryptorFactory(
            Constants.BOUNCY_CASTLE_PROVIDER_NAME, cryptoInput.getCryptoData());
    ;//from w w  w .  j a  va 2 s  .  com

    Passphrase passphrase = null;

    Iterator<?> it = enc.getEncryptedDataObjects();

    // go through all objects and find one we can decrypt
    while (it.hasNext()) {
        Object obj = it.next();
        if (obj instanceof PGPPublicKeyEncryptedData) {
            anyPacketFound = true;

            PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
            long subKeyId = encData.getKeyID();

            log.add(LogType.MSG_DC_ASYM, indent, KeyFormattingUtils.convertKeyIdToHex(subKeyId));

            decryptedSessionKeyAvailable = cachedKeyDecryptorFactory.hasCachedSessionData(encData);
            if (decryptedSessionKeyAvailable) {
                asymmetricPacketFound = true;
                encryptedDataAsymmetric = encData;
                break;
            }

            CachedPublicKeyRing cachedPublicKeyRing;
            try {
                // get actual keyring object based on master key id
                cachedPublicKeyRing = mProviderHelper
                        .getCachedPublicKeyRing(KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(subKeyId));
                long masterKeyId = cachedPublicKeyRing.getMasterKeyId();

                // allow only specific keys for decryption?
                if (input.getAllowedKeyIds() != null) {
                    Log.d(Constants.TAG, "encData.getKeyID(): " + subKeyId);
                    Log.d(Constants.TAG, "mAllowedKeyIds: " + input.getAllowedKeyIds());
                    Log.d(Constants.TAG, "masterKeyId: " + masterKeyId);

                    if (!input.getAllowedKeyIds().contains(masterKeyId)) {
                        // this key is in our db, but NOT allowed!
                        // continue with the next packet in the while loop
                        result.skippedDisallowedKey = true;
                        log.add(LogType.MSG_DC_ASKIP_NOT_ALLOWED, indent + 1);
                        continue;
                    }
                }

                SecretKeyType secretKeyType = cachedPublicKeyRing.getSecretKeyType(subKeyId);
                if (!secretKeyType.isUsable()) {
                    decryptionKey = null;
                    log.add(LogType.MSG_DC_ASKIP_UNAVAILABLE, indent + 1);
                    continue;
                }

                // get actual subkey which has been used for this encryption packet
                CanonicalizedSecretKeyRing canonicalizedSecretKeyRing = mProviderHelper
                        .getCanonicalizedSecretKeyRing(masterKeyId);
                CanonicalizedSecretKey candidateDecryptionKey = canonicalizedSecretKeyRing
                        .getSecretKey(subKeyId);

                if (!candidateDecryptionKey.canEncrypt()) {
                    log.add(LogType.MSG_DC_ASKIP_BAD_FLAGS, indent + 1);
                    continue;
                }

                if (secretKeyType == SecretKeyType.DIVERT_TO_CARD) {
                    passphrase = null;
                } else if (secretKeyType == SecretKeyType.PASSPHRASE_EMPTY) {
                    passphrase = new Passphrase("");
                } else if (cryptoInput.hasPassphrase()) {
                    passphrase = cryptoInput.getPassphrase();
                } else {
                    // if no passphrase was explicitly set try to get it from the cache service
                    try {
                        // returns "" if key has no passphrase
                        passphrase = getCachedPassphrase(subKeyId);
                        log.add(LogType.MSG_DC_PASS_CACHED, indent + 1);
                    } catch (PassphraseCacheInterface.NoSecretKeyException e) {
                        log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
                        return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log));
                    }

                    // if passphrase was not cached, return here indicating that a passphrase is missing!
                    if (passphrase == null) {
                        log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
                        return result.with(new DecryptVerifyResult(log,
                                RequiredInputParcel.createRequiredDecryptPassphrase(masterKeyId, subKeyId),
                                cryptoInput));
                    }
                }

                // check for insecure encryption key
                if (!PgpSecurityConstants.isSecureKey(candidateDecryptionKey)) {
                    log.add(LogType.MSG_DC_INSECURE_KEY, indent + 1);
                    result.insecureEncryptionKey = true;
                }

                // we're good, write down the data for later
                asymmetricPacketFound = true;
                encryptedDataAsymmetric = encData;
                decryptionKey = candidateDecryptionKey;

            } catch (PgpKeyNotFoundException | ProviderHelper.NotFoundException e) {
                // continue with the next packet in the while loop
                log.add(LogType.MSG_DC_ASKIP_NO_KEY, indent + 1);
                continue;
            }

            // break out of while, only decrypt the first packet where we have a key
            break;

        } else if (obj instanceof PGPPBEEncryptedData) {
            anyPacketFound = true;

            log.add(LogType.MSG_DC_SYM, indent);

            if (!input.isAllowSymmetricDecryption()) {
                log.add(LogType.MSG_DC_SYM_SKIP, indent + 1);
                continue;
            }

            /*
             * When mAllowSymmetricDecryption == true and we find a data packet here,
             * we do not search for other available asymmetric packets!
             */
            symmetricPacketFound = true;

            encryptedDataSymmetric = (PGPPBEEncryptedData) obj;

            // if no passphrase is given, return here
            // indicating that a passphrase is missing!
            if (!cryptoInput.hasPassphrase()) {

                try {
                    passphrase = getCachedPassphrase(key.symmetric);
                    log.add(LogType.MSG_DC_PASS_CACHED, indent + 1);
                } catch (PassphraseCacheInterface.NoSecretKeyException e) {
                    // nvm
                }

                if (passphrase == null) {
                    log.add(LogType.MSG_DC_PENDING_PASSPHRASE, indent + 1);
                    RequiredInputParcel requiredInputParcel = useBackupCode
                            ? RequiredInputParcel.createRequiredBackupCode()
                            : RequiredInputParcel.createRequiredSymmetricPassphrase();
                    return result.with(new DecryptVerifyResult(log, requiredInputParcel, cryptoInput));
                }

            } else {
                passphrase = cryptoInput.getPassphrase();
            }

            // break out of while, only decrypt the first packet
            break;
        }
    }

    // More data, just acknowledge and ignore.
    while (it.hasNext()) {
        Object obj = it.next();
        if (obj instanceof PGPPublicKeyEncryptedData) {
            PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) obj;
            long subKeyId = encData.getKeyID();
            log.add(LogType.MSG_DC_TRAIL_ASYM, indent, KeyFormattingUtils.convertKeyIdToHex(subKeyId));
        } else if (obj instanceof PGPPBEEncryptedData) {
            log.add(LogType.MSG_DC_TRAIL_SYM, indent);
        } else {
            log.add(LogType.MSG_DC_TRAIL_UNKNOWN, indent);
        }
    }

    // we made sure above one of these two would be true
    if (symmetricPacketFound) {
        PGPDigestCalculatorProvider digestCalcProvider = new JcaPGPDigestCalculatorProviderBuilder()
                .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build();
        PBEDataDecryptorFactory decryptorFactory = new JcePBEDataDecryptorFactoryBuilder(digestCalcProvider)
                .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(passphrase.getCharArray());

        try {
            result.cleartextStream = encryptedDataSymmetric.getDataStream(decryptorFactory);
        } catch (PGPDataValidationException e) {
            log.add(LogType.MSG_DC_ERROR_SYM_PASSPHRASE, indent + 1);
            RequiredInputParcel requiredInputParcel = useBackupCode
                    ? RequiredInputParcel.createRequiredBackupCode()
                    : RequiredInputParcel.createRequiredSymmetricPassphrase();
            return result.with(new DecryptVerifyResult(log, requiredInputParcel, cryptoInput));
        }

        result.encryptedData = encryptedDataSymmetric;

        result.symmetricEncryptionAlgo = encryptedDataSymmetric.getSymmetricAlgorithm(decryptorFactory);
    } else if (asymmetricPacketFound) {
        CachingDataDecryptorFactory decryptorFactory;
        if (decryptedSessionKeyAvailable) {
            decryptorFactory = cachedKeyDecryptorFactory;
        } else {
            try {
                log.add(LogType.MSG_DC_UNLOCKING, indent + 1);
                if (!decryptionKey.unlock(passphrase)) {
                    log.add(LogType.MSG_DC_ERROR_BAD_PASSPHRASE, indent + 1);
                    return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log));
                }
            } catch (PgpGeneralException e) {
                log.add(LogType.MSG_DC_ERROR_EXTRACT_KEY, indent + 1);
                return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log));
            }

            decryptorFactory = decryptionKey.getCachingDecryptorFactory(cryptoInput);

            // special case: if the decryptor does not have a session key cached for this encrypted
            // data, and can't actually decrypt on its own, return a pending intent
            if (!decryptorFactory.canDecrypt()
                    && !decryptorFactory.hasCachedSessionData(encryptedDataAsymmetric)) {

                log.add(LogType.MSG_DC_PENDING_NFC, indent + 1);
                return result.with(new DecryptVerifyResult(log,
                        RequiredInputParcel.createSecurityTokenDecryptOperation(
                                decryptionKey.getRing().getMasterKeyId(), decryptionKey.getKeyId(),
                                encryptedDataAsymmetric.getSessionKey()[0]),
                        cryptoInput));
            }
        }

        try {
            result.cleartextStream = encryptedDataAsymmetric.getDataStream(decryptorFactory);
        } catch (PGPKeyValidationException | ArrayIndexOutOfBoundsException e) {
            log.add(LogType.MSG_DC_ERROR_CORRUPT_DATA, indent + 1);
            return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log));
        }

        result.symmetricEncryptionAlgo = encryptedDataAsymmetric.getSymmetricAlgorithm(decryptorFactory);
        result.encryptedData = encryptedDataAsymmetric;

        Map<ByteBuffer, byte[]> cachedSessionKeys = decryptorFactory.getCachedSessionKeys();
        cryptoInput.addCryptoData(cachedSessionKeys);
        if (cachedSessionKeys.size() >= 1) {
            Entry<ByteBuffer, byte[]> entry = cachedSessionKeys.entrySet().iterator().next();
            result.sessionKey = entry.getKey().array();
            result.decryptedSessionKey = entry.getValue();
        }
    } else {
        // there wasn't even any useful data
        if (!anyPacketFound) {
            log.add(LogType.MSG_DC_ERROR_NO_DATA, indent + 1);
            return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_NO_DATA, log));
        }
        // there was data but key wasn't allowed
        if (result.skippedDisallowedKey) {
            log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
            return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_KEY_DISALLOWED, log));
        }
        // no packet has been found where we have the corresponding secret key in our db
        log.add(LogType.MSG_DC_ERROR_NO_KEY, indent + 1);
        return result.with(new DecryptVerifyResult(DecryptVerifyResult.RESULT_ERROR, log));
    }

    return result;

}

From source file:org.tramaci.onionmail.PGP.java

License:Open Source License

@SuppressWarnings({ "rawtypes", "deprecation" })
public static byte[] decrypt(byte[] encrypted, InputStream keyIn, char[] password) throws Exception {
    InputStream inb = new ByteArrayInputStream(encrypted);
    InputStream in = PGPUtil.getDecoderStream(inb);

    try {/*  w ww  .j  a v a  2  s .  c o  m*/
        PGPObjectFactory pgpF = new PGPObjectFactory(in);
        PGPEncryptedDataList enc = null;
        Object o = pgpF.nextObject();
        if (o == null)
            throw new Exception("@550 No data in message");

        if (o instanceof PGPEncryptedDataList)
            enc = (PGPEncryptedDataList) o;
        else
            enc = (PGPEncryptedDataList) pgpF.nextObject();

        //deadcode: if (o==null) throw new Exception("@550 No dataList in message");

        Iterator it = enc.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;
        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn));

        while (sKey == null && it.hasNext()) {
            pbe = (PGPPublicKeyEncryptedData) it.next();
            sKey = findSecretKey(pgpSec, pbe.getKeyID(), password);
        }

        if (sKey == null)
            throw new IllegalArgumentException("@550 SecretKey not found");
        InputStream clear = pbe.getDataStream(sKey, "BC");
        PGPObjectFactory pgpFact = new PGPObjectFactory(clear);
        PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject();
        pgpFact = new PGPObjectFactory(cData.getDataStream());
        PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
        InputStream unc = ld.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        int ch;
        while ((ch = unc.read()) >= 0) {
            out.write(ch);
        }

        byte[] rs = out.toByteArray();
        try {
            in.close();
        } catch (Exception I) {
        }
        try {
            inb.close();
        } catch (Exception I) {
        }
        out.close();
        return rs;

    } catch (Exception E) {
        try {
            in.close();
        } catch (Exception I) {
        }
        try {
            inb.close();
        } catch (Exception I) {
        }
        throw E;
    }
}

From source file:uk.co.platosys.dinigma.CryptoEngine.java

License:GNU General Public License

/**
 *  Decrypts an InputStream to a Document
 *
 * @param inputStream//from   www  .j a  v  a2 s  .  c o m
 * @param key
 * @param passphrase
 * @return
 * @throws Exception
 */

public static String decrypt(InputStream inputStream, Key key, char[] passphrase)
        throws MinigmaException, DecryptionException, java.io.IOException {
    InputStream in;
    PGPObjectFactory pgpObjectFactory;
    PGPEncryptedDataList pgpEncryptedDataList = null;
    PGPPrivateKey privateKey = null;
    PGPPublicKeyEncryptedData pgpPublicKeyEncryptedData = null;
    Object compressedObject = null;
    PGPLiteralData literalData = null;
    //First get a  PGPEncryptedDataList from the input stream.
    try {
        in = PGPUtil.getDecoderStream(inputStream);
        pgpObjectFactory = new PGPObjectFactory(in, new JcaKeyFingerprintCalculator());
        Object object = pgpObjectFactory.nextObject();
        if (object instanceof PGPEncryptedDataList) {
            //the EncryptedDataList is either the first object;
            pgpEncryptedDataList = (PGPEncryptedDataList) object;
        } else {
            //or the next
            pgpEncryptedDataList = (PGPEncryptedDataList) pgpObjectFactory.nextObject();
        }

        if (pgpEncryptedDataList == null) {
            throw new MinigmaException("couldn't find encrypted data list");
        }
    } catch (Exception e) {
        //Log.d(TAG,"Minigma-unLock() 1: error reading encrypted data list", e);
        throw new MinigmaException("error reading encrypted data list", e);
    }
    // now get encrypted objects from the list.
    try {
        //Log.d(TAG, "Minigma-unLock() 2 start");
        @SuppressWarnings("unchecked")
        Iterator<PGPPublicKeyEncryptedData> it = pgpEncryptedDataList.getEncryptedDataObjects();
        //Log.d(TAG, "Minigma-unLock() 2: EncryptedDataList size = "+Integer.toString(pgpEncryptedDataList.size())+", now got its iterator");
        JcePBESecretKeyDecryptorBuilder keyDecryptorBuilder = new JcePBESecretKeyDecryptorBuilder();
        keyDecryptorBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME);
        while (it.hasNext() && privateKey == null) {
            pgpPublicKeyEncryptedData = it.next();
            long keyID = pgpPublicKeyEncryptedData.getKeyID();
            //Log.d(TAG, "Minigma-unLock() 2: data was encrypted with key:"+ Long.toHexString(keyID));
            PGPSecretKey secretKey = key.getDecryptionKey(keyID);
            if (secretKey == null) {
                //Log.d(TAG, "Minigma-unLock() 2: bad key, no decryption key");
                throw new DecryptionException("2: bad key, no decryption key");
            }
            if (secretKey.getKeyID() == keyID) {
                privateKey = key.getDecryptionKey(keyID)
                        .extractPrivateKey(keyDecryptorBuilder.build(passphrase));
                //Log.d(TAG,"Minigma-unLock() 2: got private key");
            } else {
                //Log.d(TAG, "Engima-unLock() 2: not this time, round again.");
            }
        }
        if (privateKey == null) {

            throw new DecryptionException("Minigma-unLock() 2: decryption key doesn't fit any of the locks");
        }
    } catch (Exception e) {

        throw new MinigmaException("A problem arose during decryption", e);
    }

    try {

        PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(privateKey);
        InputStream decryptedStream = pgpPublicKeyEncryptedData.getDataStream(dataDecryptorFactory);
        JcaPGPObjectFactory compressedFactory = new JcaPGPObjectFactory(decryptedStream);
        compressedObject = compressedFactory.nextObject();

    } catch (Exception e) {

        throw new MinigmaException("Minigma-unLock() 3: error reading encrypted data stream", e);
    }
    try {

        PGPCompressedData clearCompressedData = (PGPCompressedData) compressedObject;
        Object uncompressedObject = null;
        JcaPGPObjectFactory uncompressedFactory = null;

        InputStream inputStream2 = clearCompressedData.getDataStream();

        uncompressedFactory = new JcaPGPObjectFactory(inputStream2);

        uncompressedObject = uncompressedFactory.nextObject();

        if (uncompressedObject instanceof PGPOnePassSignatureList) {
            // and the next object should be literal data:
            uncompressedObject = uncompressedFactory.nextObject();
            if (uncompressedObject instanceof PGPLiteralData) {
                literalData = (PGPLiteralData) uncompressedObject;
            } else {
                //unrecognised object;
                throw new MinigmaException("Minigma-unLock() 4: unrecognised object: A "
                        + uncompressedObject.getClass().getName());

            }
            uncompressedObject = uncompressedFactory.nextObject();
            if (uncompressedObject instanceof PGPSignatureList) {
            } else {
                //unrecognised object;
                throw new MinigmaException(
                        "Minigma-unlock() 4: unrecognised object B " + uncompressedObject.getClass().getName());
            }
        } else if (uncompressedObject instanceof PGPLiteralData) {
            literalData = (PGPLiteralData) uncompressedObject;
        } else {
            //unrecognised object
            throw new MinigmaException(
                    "Minigma-unLock() 4: unrecognised object C " + uncompressedObject.getClass().getName());

        }
    } catch (Exception e) {
        throw new MinigmaException("Minigma-unLock() 4: error getting decompressed object", e);

    }

    InputStream inputStream1 = literalData.getDataStream();
    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream1.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }
    return result.toString("UTF-8");
}