Example usage for org.bouncycastle.bcpg ArmoredOutputStream setHeader

List of usage examples for org.bouncycastle.bcpg ArmoredOutputStream setHeader

Introduction

In this page you can find the example usage for org.bouncycastle.bcpg ArmoredOutputStream setHeader.

Prototype

public void setHeader(String name, String value) 

Source Link

Document

Set an additional header entry.

Usage

From source file:org.eclipse.packagedrone.repo.signing.pgp.internal.AbstractSecretKeySigningService.java

License:Open Source License

@Override
public void printPublicKey(final OutputStream out) throws IOException {
    final ArmoredOutputStream armoredOutput = new ArmoredOutputStream(out);
    armoredOutput.setHeader("Version", VersionInformation.VERSIONED_PRODUCT);

    final PGPPublicKey pubKey = this.secretKey.getPublicKey();
    pubKey.encode(new BCPGOutputStream(armoredOutput));
    armoredOutput.close();/*from w  ww .  j  av a 2  s .c  o m*/
}

From source file:org.eclipse.packagedrone.repo.signing.pgp.internal.AbstractSecretKeySigningService.java

License:Open Source License

@Override
public void sign(final InputStream in, final OutputStream out, final boolean inline) throws Exception {
    final int digest = HashAlgorithmTags.SHA1;
    final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
            new BcPGPContentSignerBuilder(this.privateKey.getPublicKeyPacket().getAlgorithm(), digest));

    if (inline) {
        signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, this.privateKey);
    } else {/*ww w . java  2 s.  c om*/
        signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, this.privateKey);
    }

    final ArmoredOutputStream armoredOutput = new ArmoredOutputStream(out);
    armoredOutput.setHeader("Version", VersionInformation.VERSIONED_PRODUCT);

    if (inline) {
        armoredOutput.beginClearText(digest);

        final LineNumberReader lnr = new LineNumberReader(new InputStreamReader(in, StandardCharsets.UTF_8));

        String line;
        while ((line = lnr.readLine()) != null) {
            if (lnr.getLineNumber() > 1) {
                signatureGenerator.update(NL_DATA);
            }

            final byte[] data = trimTrailing(line).getBytes(StandardCharsets.UTF_8);

            if (inline) {
                armoredOutput.write(data);
                armoredOutput.write(NL_DATA);
            }
            signatureGenerator.update(data);
        }

        armoredOutput.endClearText();
    } else {

        final byte[] buffer = new byte[4096];
        int rc;
        while ((rc = in.read(buffer)) >= 0) {
            signatureGenerator.update(buffer, 0, rc);
        }
    }

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

    armoredOutput.close();
}

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

License:Open Source License

/**
 * Signs and/or encrypts data based on parameters of class
 *//*  ww w.  j a  va2 s  .  com*/
private PgpSignEncryptResult executeInternal(PgpSignEncryptInputParcel input, CryptoInputParcel cryptoInput,
        InputData inputData, OutputStream outputStream) {

    int indent = 0;
    OperationLog log = new OperationLog();

    log.add(LogType.MSG_PSE, indent);
    indent += 1;

    PgpSignEncryptData data = input.getData();
    boolean enableSignature = data.getSignatureMasterKeyId() != Constants.key.none;
    boolean enableEncryption = ((data.getEncryptionMasterKeyIds() != null
            && data.getEncryptionMasterKeyIds().length > 0) || data.getSymmetricPassphrase() != null);
    boolean enableCompression = (data.getCompressionAlgorithm() != CompressionAlgorithmTags.UNCOMPRESSED);

    Log.d(Constants.TAG,
            "enableSignature:" + enableSignature + "\nenableEncryption:" + enableEncryption
                    + "\nenableCompression:" + enableCompression + "\nenableAsciiArmorOutput:"
                    + data.isEnableAsciiArmorOutput() + "\nisHiddenRecipients:" + data.isHiddenRecipients());

    // add additional key id to encryption ids (mostly to do self-encryption)
    if (enableEncryption && data.getAdditionalEncryptId() != Constants.key.none) {
        data.setEncryptionMasterKeyIds(
                Arrays.copyOf(data.getEncryptionMasterKeyIds(), data.getEncryptionMasterKeyIds().length + 1));
        data.getEncryptionMasterKeyIds()[data.getEncryptionMasterKeyIds().length - 1] = data
                .getAdditionalEncryptId();
    }

    ArmoredOutputStream armorOut = null;
    OutputStream out;
    if (data.isEnableAsciiArmorOutput()) {
        armorOut = new ArmoredOutputStream(new BufferedOutputStream(outputStream, 1 << 16));
        if (data.getVersionHeader() != null) {
            armorOut.setHeader("Version", data.getVersionHeader());
        }
        // if we have a charset, put it in the header
        if (data.getCharset() != null) {
            armorOut.setHeader("Charset", data.getCharset());
        }
        // add proprietary header to indicate that this is a key backup
        if (data.isAddBackupHeader()) {
            armorOut.setHeader("BackupVersion", "2");
        }
        out = armorOut;
    } else {
        out = outputStream;
    }

    /* Get keys for signature generation for later usage */
    CanonicalizedSecretKey signingKey = null;
    if (enableSignature) {

        updateProgress(R.string.progress_extracting_signature_key, 0, 100);

        try {
            long signingMasterKeyId = data.getSignatureMasterKeyId();
            long signingSubKeyId = data.getSignatureSubKeyId();

            CanonicalizedSecretKeyRing signingKeyRing = mProviderHelper
                    .getCanonicalizedSecretKeyRing(signingMasterKeyId);
            signingKey = signingKeyRing.getSecretKey(data.getSignatureSubKeyId());

            // Make sure key is not expired or revoked
            if (signingKeyRing.isExpired() || signingKeyRing.isRevoked() || signingKey.isExpired()
                    || signingKey.isRevoked()) {
                log.add(LogType.MSG_PSE_ERROR_REVOKED_OR_EXPIRED, indent);
                return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
            }

            // Make sure we are allowed to sign here!
            if (!signingKey.canSign()) {
                log.add(LogType.MSG_PSE_ERROR_KEY_SIGN, indent);
                return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
            }

            switch (mProviderHelper.getCachedPublicKeyRing(signingMasterKeyId)
                    .getSecretKeyType(signingSubKeyId)) {
            case DIVERT_TO_CARD:
            case PASSPHRASE_EMPTY: {
                if (!signingKey.unlock(new Passphrase())) {
                    throw new AssertionError(
                            "PASSPHRASE_EMPTY/DIVERT_TO_CARD keyphrase not unlocked with empty passphrase."
                                    + " This is a programming error!");
                }
                break;
            }

            case PIN:
            case PATTERN:
            case PASSPHRASE: {
                Passphrase localPassphrase = cryptoInput.getPassphrase();
                if (localPassphrase == null) {
                    try {
                        localPassphrase = getCachedPassphrase(signingMasterKeyId, signingKey.getKeyId());
                    } catch (PassphraseCacheInterface.NoSecretKeyException ignored) {
                    }
                }
                if (localPassphrase == null) {
                    log.add(LogType.MSG_PSE_PENDING_PASSPHRASE, indent + 1);
                    return new PgpSignEncryptResult(log,
                            RequiredInputParcel.createRequiredSignPassphrase(signingMasterKeyId,
                                    signingKey.getKeyId(), cryptoInput.getSignatureTime()),
                            cryptoInput);
                }
                if (!signingKey.unlock(localPassphrase)) {
                    log.add(LogType.MSG_PSE_ERROR_BAD_PASSPHRASE, indent);
                    return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
                }
                break;
            }

            case GNU_DUMMY: {
                log.add(LogType.MSG_PSE_ERROR_UNLOCK, indent);
                return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
            }
            default: {
                throw new AssertionError("Unhandled SecretKeyType! (should not happen)");
            }

            }

        } catch (ProviderHelper.NotFoundException e) {
            log.add(LogType.MSG_PSE_ERROR_SIGN_KEY, indent);
            return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
        } catch (PgpGeneralException e) {
            log.add(LogType.MSG_PSE_ERROR_UNLOCK, indent);
            return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
        }

        // Use requested hash algo
        int requestedAlgorithm = data.getSignatureHashAlgorithm();
        if (requestedAlgorithm == PgpSecurityConstants.OpenKeychainHashAlgorithmTags.USE_DEFAULT) {
            data.setSignatureHashAlgorithm(PgpSecurityConstants.DEFAULT_HASH_ALGORITHM);
        }
    }
    updateProgress(R.string.progress_preparing_streams, 2, 100);

    /* Initialize PGPEncryptedDataGenerator for later usage */
    PGPEncryptedDataGenerator cPk = null;
    if (enableEncryption) {

        // Use requested encryption algo
        int algo = data.getSymmetricEncryptionAlgorithm();
        if (algo == PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.USE_DEFAULT) {
            algo = PgpSecurityConstants.DEFAULT_SYMMETRIC_ALGORITHM;
        }
        JcePGPDataEncryptorBuilder encryptorBuilder = new JcePGPDataEncryptorBuilder(algo)
                .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME)
                .setWithIntegrityPacket(data.isIntegrityProtected());

        cPk = new PGPEncryptedDataGenerator(encryptorBuilder);

        if (data.getSymmetricPassphrase() != null) {
            // Symmetric encryption
            log.add(LogType.MSG_PSE_SYMMETRIC, indent);

            JcePBEKeyEncryptionMethodGenerator symmetricEncryptionGenerator = new JcePBEKeyEncryptionMethodGenerator(
                    data.getSymmetricPassphrase().getCharArray());
            cPk.addMethod(symmetricEncryptionGenerator);
        } else {
            log.add(LogType.MSG_PSE_ASYMMETRIC, indent);

            // Asymmetric encryption
            for (long id : data.getEncryptionMasterKeyIds()) {
                try {
                    CanonicalizedPublicKeyRing keyRing = mProviderHelper
                            .getCanonicalizedPublicKeyRing(KeyRings.buildUnifiedKeyRingUri(id));
                    Set<Long> encryptSubKeyIds = keyRing.getEncryptIds();
                    for (Long subKeyId : encryptSubKeyIds) {
                        CanonicalizedPublicKey key = keyRing.getPublicKey(subKeyId);
                        cPk.addMethod(key.getPubKeyEncryptionGenerator(data.isHiddenRecipients()));
                        log.add(LogType.MSG_PSE_KEY_OK, indent + 1,
                                KeyFormattingUtils.convertKeyIdToHex(subKeyId));
                    }
                    if (encryptSubKeyIds.isEmpty()) {
                        log.add(LogType.MSG_PSE_KEY_WARN, indent + 1, KeyFormattingUtils.convertKeyIdToHex(id));
                        return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
                    }
                    // Make sure key is not expired or revoked
                    if (keyRing.isExpired() || keyRing.isRevoked()) {
                        log.add(LogType.MSG_PSE_ERROR_REVOKED_OR_EXPIRED, indent);
                        return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
                    }
                } catch (ProviderHelper.NotFoundException e) {
                    log.add(LogType.MSG_PSE_KEY_UNKNOWN, indent + 1, KeyFormattingUtils.convertKeyIdToHex(id));
                    return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
                }
            }
        }
    }

    /* Initialize signature generator object for later usage */
    PGPSignatureGenerator signatureGenerator = null;
    if (enableSignature) {
        updateProgress(R.string.progress_preparing_signature, 4, 100);

        try {
            boolean cleartext = data.isCleartextSignature() && data.isEnableAsciiArmorOutput()
                    && !enableEncryption;
            signatureGenerator = signingKey.getDataSignatureGenerator(data.getSignatureHashAlgorithm(),
                    cleartext, cryptoInput.getCryptoData(), cryptoInput.getSignatureTime());
        } catch (PgpGeneralException e) {
            log.add(LogType.MSG_PSE_ERROR_NFC, indent);
            return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
        }
    }

    ProgressScaler progressScaler = new ProgressScaler(mProgressable, 8, 95, 100);
    PGPCompressedDataGenerator compressGen = null;
    OutputStream pOut;
    OutputStream encryptionOut = null;
    BCPGOutputStream bcpgOut;

    ByteArrayOutputStream detachedByteOut = null;
    ArmoredOutputStream detachedArmorOut = null;
    BCPGOutputStream detachedBcpgOut = null;

    long opTime, startTime = System.currentTimeMillis();

    try {

        if (enableEncryption) {
            /* actual encryption */
            updateProgress(R.string.progress_encrypting, 8, 100);
            log.add(enableSignature ? LogType.MSG_PSE_SIGCRYPTING : LogType.MSG_PSE_ENCRYPTING, indent);
            indent += 1;

            encryptionOut = cPk.open(out, new byte[1 << 16]);

            if (enableCompression) {
                log.add(LogType.MSG_PSE_COMPRESSING, indent);

                // Use preferred compression algo
                int algo = data.getCompressionAlgorithm();
                if (algo == PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {
                    algo = PgpSecurityConstants.DEFAULT_COMPRESSION_ALGORITHM;
                }
                compressGen = new PGPCompressedDataGenerator(algo);
                bcpgOut = new BCPGOutputStream(compressGen.open(encryptionOut));
            } else {
                bcpgOut = new BCPGOutputStream(encryptionOut);
            }

            if (enableSignature) {
                signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);
            }

            PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
            char literalDataFormatTag;
            if (data.isCleartextSignature()) {
                literalDataFormatTag = PGPLiteralData.UTF8;
            } else {
                literalDataFormatTag = PGPLiteralData.BINARY;
            }
            pOut = literalGen.open(bcpgOut, literalDataFormatTag, inputData.getOriginalFilename(), new Date(),
                    new byte[1 << 16]);

            long alreadyWritten = 0;
            int length;
            byte[] buffer = new byte[1 << 16];
            InputStream in = new BufferedInputStream(inputData.getInputStream());
            while ((length = in.read(buffer)) > 0) {
                pOut.write(buffer, 0, length);

                // update signature buffer if signature is requested
                if (enableSignature) {
                    signatureGenerator.update(buffer, 0, length);
                }

                alreadyWritten += length;
                if (inputData.getSize() > 0) {
                    long progress = 100 * alreadyWritten / inputData.getSize();
                    progressScaler.setProgress((int) progress, 100);
                }
            }

            literalGen.close();
            indent -= 1;

        } else if (enableSignature && data.isCleartextSignature() && data.isEnableAsciiArmorOutput()) {
            /* cleartext signature: sign-only of ascii text */

            updateProgress(R.string.progress_signing, 8, 100);
            log.add(LogType.MSG_PSE_SIGNING_CLEARTEXT, indent);

            // write -----BEGIN PGP SIGNED MESSAGE-----
            armorOut.beginClearText(data.getSignatureHashAlgorithm());

            InputStream in = new BufferedInputStream(inputData.getInputStream());
            final BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            // update signature buffer with first line
            processLine(reader.readLine(), armorOut, signatureGenerator);

            // TODO: progress: fake annealing?
            while (true) {
                String line = reader.readLine();

                // end cleartext signature with newline, see http://tools.ietf.org/html/rfc4880#section-7
                if (line == null) {
                    armorOut.write(NEW_LINE);
                    break;
                }

                armorOut.write(NEW_LINE);

                // update signature buffer with input line
                signatureGenerator.update(NEW_LINE);
                processLine(line, armorOut, signatureGenerator);
            }

            armorOut.endClearText();

            pOut = new BCPGOutputStream(armorOut);
        } else if (enableSignature && data.isDetachedSignature()) {
            /* detached signature */

            updateProgress(R.string.progress_signing, 8, 100);
            log.add(LogType.MSG_PSE_SIGNING_DETACHED, indent);

            InputStream in = new BufferedInputStream(inputData.getInputStream());

            // handle output stream separately for detached signatures
            detachedByteOut = new ByteArrayOutputStream();
            OutputStream detachedOut = detachedByteOut;
            if (data.isEnableAsciiArmorOutput()) {
                detachedArmorOut = new ArmoredOutputStream(new BufferedOutputStream(detachedOut, 1 << 16));
                if (data.getVersionHeader() != null) {
                    detachedArmorOut.setHeader("Version", data.getVersionHeader());
                }

                detachedOut = detachedArmorOut;
            }
            detachedBcpgOut = new BCPGOutputStream(detachedOut);

            long alreadyWritten = 0;
            int length;
            byte[] buffer = new byte[1 << 16];
            while ((length = in.read(buffer)) > 0) {
                // no output stream is written, no changed to original data!

                signatureGenerator.update(buffer, 0, length);

                alreadyWritten += length;
                if (inputData.getSize() > 0) {
                    long progress = 100 * alreadyWritten / inputData.getSize();
                    progressScaler.setProgress((int) progress, 100);
                }
            }

            pOut = null;
        } else if (enableSignature && !data.isCleartextSignature() && !data.isDetachedSignature()) {
            /* sign-only binary (files/data stream) */

            updateProgress(R.string.progress_signing, 8, 100);
            log.add(LogType.MSG_PSE_SIGNING, indent);

            InputStream in = new BufferedInputStream(inputData.getInputStream());

            if (enableCompression) {
                // Use preferred compression algo
                int algo = data.getCompressionAlgorithm();
                if (algo == PgpSecurityConstants.OpenKeychainCompressionAlgorithmTags.USE_DEFAULT) {
                    algo = PgpSecurityConstants.DEFAULT_COMPRESSION_ALGORITHM;
                }

                compressGen = new PGPCompressedDataGenerator(algo);
                bcpgOut = new BCPGOutputStream(compressGen.open(out));
            } else {
                bcpgOut = new BCPGOutputStream(out);
            }

            signatureGenerator.generateOnePassVersion(false).encode(bcpgOut);

            PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
            pOut = literalGen.open(bcpgOut, PGPLiteralData.BINARY, inputData.getOriginalFilename(), new Date(),
                    new byte[1 << 16]);

            long alreadyWritten = 0;
            int length;
            byte[] buffer = new byte[1 << 16];
            while ((length = in.read(buffer)) > 0) {
                pOut.write(buffer, 0, length);

                signatureGenerator.update(buffer, 0, length);

                alreadyWritten += length;
                if (inputData.getSize() > 0) {
                    long progress = 100 * alreadyWritten / inputData.getSize();
                    progressScaler.setProgress((int) progress, 100);
                }
            }

            literalGen.close();
        } else {
            throw new AssertionError("cannot clearsign in non-ascii armored text, this is a bug!");
        }

        if (enableSignature) {
            updateProgress(R.string.progress_generating_signature, 95, 100);
            try {
                if (detachedBcpgOut != null) {
                    signatureGenerator.generate().encode(detachedBcpgOut);
                } else {
                    signatureGenerator.generate().encode(pOut);
                }
            } catch (NfcSyncPGPContentSignerBuilder.NfcInteractionNeeded e) {
                // this secret key diverts to a OpenPGP card, throw exception with hash that will be signed
                log.add(LogType.MSG_PSE_PENDING_NFC, indent);
                return new PgpSignEncryptResult(log,
                        RequiredInputParcel.createSecurityTokenSignOperation(
                                signingKey.getRing().getMasterKeyId(), signingKey.getKeyId(), e.hashToSign,
                                e.hashAlgo, cryptoInput.getSignatureTime()),
                        cryptoInput);
            }
        }

        opTime = System.currentTimeMillis() - startTime;
        Log.d(Constants.TAG, "sign/encrypt time taken: " + String.format("%.2f", opTime / 1000.0) + "s");

        // closing outputs
        // NOTE: closing needs to be done in the correct order!
        if (encryptionOut != null) {
            if (compressGen != null) {
                compressGen.close();
            }

            encryptionOut.close();
        }
        // Note: Closing ArmoredOutputStream does not close the underlying stream
        if (armorOut != null) {
            armorOut.close();
        }
        // Note: Closing ArmoredOutputStream does not close the underlying stream
        if (detachedArmorOut != null) {
            detachedArmorOut.close();
        }
        // Also closes detachedBcpgOut
        if (detachedByteOut != null) {
            detachedByteOut.close();
        }
        if (out != null) {
            out.close();
        }
        if (outputStream != null) {
            outputStream.close();
        }

    } catch (SignatureException e) {
        log.add(LogType.MSG_PSE_ERROR_SIG, indent);
        return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
    } catch (PGPException e) {
        log.add(LogType.MSG_PSE_ERROR_PGP, indent);
        return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
    } catch (IOException e) {
        log.add(LogType.MSG_PSE_ERROR_IO, indent);
        return new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_ERROR, log);
    }

    updateProgress(R.string.progress_done, 100, 100);

    log.add(LogType.MSG_PSE_OK, indent);
    PgpSignEncryptResult result = new PgpSignEncryptResult(PgpSignEncryptResult.RESULT_OK, log);
    result.mOperationTime = opTime;
    if (detachedByteOut != null) {
        try {
            detachedByteOut.flush();
            detachedByteOut.close();
        } catch (IOException e) {
            // silently catch
        }
        result.setDetachedSignature(detachedByteOut.toByteArray());
        try {
            String digestName = PGPUtil.getDigestName(data.getSignatureHashAlgorithm());
            // construct micalg parameter according to https://tools.ietf.org/html/rfc3156#section-5
            result.setMicAlgDigestName("pgp-" + digestName.toLowerCase());
        } catch (PGPException e) {
            Log.e(Constants.TAG, "error setting micalg parameter!", e);
        }
    }
    return result;
}

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

License:Open Source License

public void encodeArmored(OutputStream out, String version) throws IOException {
    ArmoredOutputStream aos = new ArmoredOutputStream(out);
    if (version != null) {
        aos.setHeader("Version", version);
    }/* w w w.  j  a va 2  s.  c o  m*/
    aos.write(mRing.getEncoded());
    aos.close();
}