Example usage for org.bouncycastle.openpgp PGPPublicKeyEncryptedData getDataStream

List of usage examples for org.bouncycastle.openpgp PGPPublicKeyEncryptedData getDataStream

Introduction

In this page you can find the example usage for org.bouncycastle.openpgp PGPPublicKeyEncryptedData getDataStream.

Prototype

public InputStream getDataStream(PublicKeyDataDecryptorFactory dataDecryptorFactory) throws PGPException 

Source Link

Document

Open an input stream which will provide the decrypted data protected by this object.

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//from  www  . j a v a  2  s . 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) {/*ww  w . j ava 2  s .c  om*/
    // 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.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;//from  ww  w.jav  a 2 s  . c o m

    Object o = pgpF.nextObject();
    //
    // 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

/**
 * decrypt the passed in message stream.
 * /*from w  w  w. jav  a 2 s  .c  o m*/
 * Inspired by
 * https://github.com/bcgit/bc-java/blob/master/pg/src/main/java/org/bouncycastle/openpgp/examples/KeyBasedFileProcessor.java
 * 
 * @param countingStream
 *            this stream is passed for progress reporting only, must not be
 *            used to actually read data
 */
private void decryptStream(PGPPublicKeyEncryptedData pbe, PGPPrivateKey privateKey, OutputStream outputStream,
        Updater optionalProgress, CountingInputStream countingStream)
        throws UserRequestedCancellationException {
    try {
        InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey));

        BcPGPObjectFactory plainFact = new BcPGPObjectFactory(clear);
        Object message = plainFact.nextObject();
        if (message instanceof PGPMarker) {
            message = plainFact.nextObject();
        }

        BcPGPObjectFactory pgpFactory = null;
        if (message instanceof PGPCompressedData) {
            PGPCompressedData cData = (PGPCompressedData) message;
            pgpFactory = new BcPGPObjectFactory(cData.getDataStream());
            message = pgpFactory.nextObject();
        }

        int watchDog = 0;
        while (message != null) {
            Preconditions.checkState(watchDog++ < 100, "Inifinite loop watch dog just hit");

            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;

                // NOTE: We know initial file name (in case we need it):
                // ld.getFileName();
                InputStream unc = ld.getInputStream();
                OutputStream fOut = new BufferedOutputStream(outputStream);
                if (optionalProgress != null) {
                    optionalProgress.updateStepInfo("progress.decrypting");
                }

                pipeStream(unc, fOut, BUFFER_SIZE, optionalProgress, countingStream);
                fOut.close();
                unc.close();

                if (pbe.isIntegrityProtected()) {
                    if (!pbe.verify()) {
                        throw new RuntimeException("message failed integrity check");
                    }
                }
                return;
            } else if (message instanceof PGPOnePassSignatureList) {
                log.info("PGPOnePassSignatureList is not implemented yet. Skipping signature validation");
                // NOTE: Here is a place to copyright from
                // http://stackoverflow.com/questions/19173181/bouncycastle-pgp-decrypt-and-verify
                Preconditions.checkArgument(pgpFactory != null,
                        "File format is not supported. pgpFact is supposed to be initialized by that time");
                message = pgpFactory.nextObject();
            } else if (message instanceof PGPSignatureList) {
                log.info("PGPSignatureList is not implemented yet. Skipping signature validation");
                Preconditions.checkArgument(pgpFactory != null,
                        "File format is not supported. pgpFact is supposed to be initialized by that time");
                message = pgpFactory.nextObject();
            } else {
                throw new PGPException(
                        "Don't know how to decrypt the input file. Encountered unexpected block: " + message);
            }
        }
    } catch (Throwable e) {
        Throwables.throwIfInstanceOf(e, UserRequestedCancellationException.class);
        throw new RuntimeException("Decryption failed", e);
    }
}

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

License:Open Source License

private String getInitialFileName(PGPPublicKeyEncryptedData pbe, PGPPrivateKey privateKey) {
    InputStream clear = null;/*from   w  w  w . ja va 2 s  . c o  m*/
    try {
        clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey));

        BcPGPObjectFactory plainFact = new BcPGPObjectFactory(clear);
        Object message = plainFact.nextObject();
        if (message instanceof PGPMarker) {
            message = plainFact.nextObject();
        }

        BcPGPObjectFactory pgpFactory = null;
        if (message instanceof PGPCompressedData) {
            PGPCompressedData cData = (PGPCompressedData) message;
            pgpFactory = new BcPGPObjectFactory(cData.getDataStream());
            message = pgpFactory.nextObject();
        }

        int watchDog = 0;
        while (message != null) {
            Preconditions.checkState(watchDog++ < 100, "Inifinite loop watch dog just hit");
            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;
                return ld.getFileName();
            } else if (message instanceof PGPOnePassSignatureList) {
                Preconditions.checkState(pgpFactory != null, "pgpFactory supposed to be not null");
                message = pgpFactory.nextObject();
            } else if (message instanceof PGPSignatureList) {
                Preconditions.checkState(pgpFactory != null, "pgpFactory supposed to be not null");
                message = pgpFactory.nextObject();
            } else {
                throw new PGPException(
                        "Don't know how to decrypt the input file. Encountered unexpected block: " + message);
            }
        }
        throw new IllegalStateException("Unknown file format, cannot determine initial file name");
    } catch (Throwable e) {
        throw new RuntimeException("Failed to get initial file name", e);
    } finally {
        IoStreamUtils.safeClose(clear);
    }
}

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   www . j ava2  s .  co m

    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:ubicrypt.core.crypto.PGPEC.java

License:Open Source License

public static InputStream decrypt(final PGPPrivateKey privateKey, final InputStream cipherText)
        throws PGPException {
    final JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(cipherText);

    try {//from   www.  j a  va 2 s  .  co m
        final PGPEncryptedDataList encList = (PGPEncryptedDataList) pgpF.nextObject();
        log.trace("decrypt with sk:{}", privateKey.getKeyID());

        final PGPPublicKeyEncryptedData encP = toStream(
                (Iterator<PGPPublicKeyEncryptedData>) encList.iterator())
                        .filter((PGPPublicKeyEncryptedData ed) -> {
                            log.debug("pgp message encrypted with key:{}", ed.getKeyID());
                            return ed.getKeyID() == privateKey.getKeyID();
                        }).findFirst().orElseThrow(() -> new PGPException(
                                "the message is not encrypted with the related public key"));

        try (InputStream clear = encP.getDataStream(
                new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(privateKey))) {
            Object next = new JcaPGPObjectFactory(clear).nextObject();
            if (next instanceof PGPCompressedData) {
                next = new JcaPGPObjectFactory(((PGPCompressedData) next).getDataStream()).nextObject();
            }
            return ((PGPLiteralData) next).getInputStream();
        }
    } catch (final PGPException e) {
        throw e;
    } catch (final Exception e) {
        Throwables.propagate(e);
    }
    return null;
}

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

License:GNU General Public License

/**
 *  Decrypts an InputStream to a Document
 *
 * @param inputStream/*from   www  .  jav a2s.  co  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");
}