Example usage for org.bouncycastle.openpgp PGPSignatureGenerator update

List of usage examples for org.bouncycastle.openpgp PGPSignatureGenerator update

Introduction

In this page you can find the example usage for org.bouncycastle.openpgp PGPSignatureGenerator update.

Prototype

public void update(byte[] b, int off, int len) throws PGPSignatureException 

Source Link

Usage

From source file:com.arcusx.simplepgp.PgpDataEncryptor.java

public void encryptAndSign(InputStream dataIn, InputStream recipientPublicKeyFileIn, String dataFileName,
        InputStream senderPrivateKeyFileIn, OutputStream dataOut, boolean isArmoredOutput)
        throws IOException, PGPException {
    PGPCompressedDataGenerator comData = null;
    try {//from  ww  w.  j a  va  2  s  .c o m
        OutputStream out = dataOut;
        PGPPublicKey recipientPublicKey = PgpKeyUtils.readPublicKey(recipientPublicKeyFileIn);

        if (isArmoredOutput) {
            out = new ArmoredOutputStream(out);
        }

        BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.TRIPLE_DES);
        dataEncryptor.setWithIntegrityPacket(true);
        dataEncryptor.setSecureRandom(new SecureRandom());

        PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
        encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(recipientPublicKey));

        OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[BUFFER_SIZE]);

        // Initialize compressed data generator
        PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(
                PGPCompressedData.ZIP);
        OutputStream compressedOut = compressedDataGenerator.open(encryptedOut, new byte[BUFFER_SIZE]);

        // Initialize signature generator
        final PGPSecretKey senderSecretKey = PgpKeyUtils.findSecretKey(senderPrivateKeyFileIn);
        PGPPrivateKey privateKey = PgpKeyUtils.getPrivateKeyFrom(senderSecretKey);

        PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(
                senderSecretKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);

        PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(signerBuilder);
        signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);

        PGPSignatureSubpacketGenerator signatureSubpacketGenerator = new PGPSignatureSubpacketGenerator();
        signatureSubpacketGenerator.setSignerUserID(false, PgpKeyUtils.getUserIdFrom(senderSecretKey));
        signatureGenerator.setHashedSubpackets(signatureSubpacketGenerator.generate());
        signatureGenerator.generateOnePassVersion(false).encode(compressedOut);

        // Initialize literal data generator
        PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
        OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, dataFileName,
                new Date(), new byte[BUFFER_SIZE]);

        byte[] buf = new byte[BUFFER_SIZE];
        int len;
        while ((len = dataIn.read(buf)) > 0) {
            literalOut.write(buf, 0, len);
            signatureGenerator.update(buf, 0, len);
        }
        dataIn.close();
        literalDataGenerator.close();

        // generate the signature, compress, encrypt and write to the "out" stream
        signatureGenerator.generate().encode(compressedOut);
        compressedDataGenerator.close();
        encryptedDataGenerator.close();
        if (isArmoredOutput) {
            out.close();
        }
    } finally {
        if (comData != null) {
            comData.close();
        }
        IOUtils.closeQuietly(dataOut);
    }
}

From source file:com.goodvikings.cryptim.api.KeyRing.java

License:BEER-WARE LICENSE

public void signEncryptMessage(InputStream in, OutputStream out, String jid)
        throws IOException, PGPException, SignatureException {
    out = new ArmoredOutputStream(out);

    PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(SYMM_ALG)
            .setWithIntegrityPacket(true).setSecureRandom(rand).setProvider(PROVIDER));
    encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(keys.get(jid)).setProvider(PROVIDER));

    OutputStream encryptedOut = encGen.open(out, new byte[BUFFER_SIZE]);
    OutputStream compressedData = new PGPCompressedDataGenerator(COMP_ALG).open(encryptedOut);

    PGPSignatureGenerator sGen = new PGPSignatureGenerator(
            new JcaPGPContentSignerBuilder(kp.getPrivateKey().getPublicKeyPacket().getAlgorithm(), HASH_ALG)
                    .setProvider(PROVIDER));
    sGen.init(PGPSignature.BINARY_DOCUMENT, kp.getPrivateKey());
    sGen.generateOnePassVersion(false).encode(compressedData);

    OutputStream finalOut = new PGPLiteralDataGenerator().open(compressedData, PGPLiteralData.BINARY, "",
            new Date(), new byte[BUFFER_SIZE]);

    byte[] buf = new byte[BUFFER_SIZE];
    int len;/*  w w  w .ja v  a 2s  .c o m*/
    while ((len = in.read(buf)) > 0) {
        finalOut.write(buf, 0, len);
        sGen.update(buf, 0, len);
    }

    in.close();

    finalOut.close();
    sGen.generate().encode(compressedData);
    compressedData.close();
    encryptedOut.close();
    out.close();
}

From source file:com.lyndir.lhunath.opal.crypto.gpg.GPG.java

License:Apache License

/**
 * PGP sign a stream./* www .  ja va2 s . c  o  m*/
 *
 * @param data       The stream that contains the data to sign.
 * @param privateKey The private key to use for signing.
 * @param passPhrase The passphrase that the private key is locked with.
 * @param armoured   {@code true}: ASCII armor the signature.
 *
 * @return The signature.
 *
 * @throws NoSuchAlgorithmException
 * @throws NoSuchProviderException
 * @throws SignatureException
 * @throws FileNotFoundException
 * @throws PGPException
 * @throws IOException
 */
public static InputStream sign(final InputStream data, final PGPSecretKey privateKey, final String passPhrase,
        final boolean armoured) throws NoSuchAlgorithmException, NoSuchProviderException, PGPException,
        SignatureException, IOException {

    /* Build the signature generator. */
    PGPSignatureGenerator signer = new PGPSignatureGenerator(privateKey.getPublicKey().getAlgorithm(),
            HashAlgorithmTags.SHA1, BouncyCastleProvider.PROVIDER_NAME);
    signer.initSign(PGPSignature.BINARY_DOCUMENT,
            privateKey.extractPrivateKey(passPhrase.toCharArray(), BouncyCastleProvider.PROVIDER_NAME));

    /* Write the data into the generator. */
    byte[] buffer = new byte[4096];
    for (int read; (read = data.read(buffer)) >= 0;)
        signer.update(buffer, 0, read);

    /* Create the signature output stream, armour if necessary. */
    try (ByteArrayOutputStream signatureByteStream = new ByteArrayOutputStream();
            OutputStream signatureStream = armoured ? new ArmoredOutputStream(signatureByteStream)
                    : signatureByteStream) {

        /* Create and write out the signature. */
        PGPSignature signature = signer.generate();
        signature.encode(signatureStream);

        return new ByteArrayInputStream(signatureByteStream.toByteArray());
    }
}

From source file:com.navnorth.learningregistry.LRSigner.java

License:Apache License

/**
 * Encodes the provided message with the private key and pass phrase set in configuration
 *
 * @param message Message to encode/* w w  w  .jav  a 2s.com*/
 * @return Encoded message
 * @throws LRException SIGNING_FAILED if the document cannot be signed, NO_KEY if the key cannot be obtained
 */
private String signEnvelopeData(String message) throws LRException {
    // Throw an exception if any of the required fields are null
    if (passPhrase == null || publicKeyLocation == null || privateKey == null) {
        throw new LRException(LRException.NULL_FIELD);
    }

    // Add the provider here so that after signing, we can remove the provider.
    // This allows using this code from multiple separate class loaders while Bouncy Castle is on a separate class loader
    BouncyCastleProvider provider = new BouncyCastleProvider();
    Security.addProvider(provider);

    try {

        // Get an InputStream for the private key
        InputStream privateKeyStream = getPrivateKeyStream(privateKey);

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

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

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

            // Clear sign the message
            java.util.Iterator it = sk.getPublicKey().getUserIDs();
            if (it.hasNext()) {
                spGen.setSignerUserID(false, (String) it.next());
                sGen.setHashedSubpackets(spGen.generate());
            }
            aOut.beginClearText(PGPUtil.SHA256);
            sGen.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, pk);
            byte[] msg = message.getBytes();
            sGen.update(msg, 0, msg.length);
            aOut.write(msg, 0, msg.length);
            BCPGOutputStream bOut = new BCPGOutputStream(aOut);
            aOut.endClearText();
            sGen.generate().encode(bOut);
            aOut.close();

            String strResult = result.toString("utf8");

            // for whatever reason, bouncycastle is failing to put a linebreak before "-----BEGIN PGP SIGNATURE"
            strResult = strResult.replaceAll("([a-z0-9])-----BEGIN PGP SIGNATURE-----",
                    "$1\n-----BEGIN PGP SIGNATURE-----");

            return strResult;
        } catch (Exception e) {
            throw new LRException(LRException.SIGNING_FAILED, e);
        } finally {
            try {
                if (privateKeyStream != null) {
                    privateKeyStream.close();
                }

                result.close();
            } catch (IOException e) {
                //Could not close the streams
            }
        }
    } finally {
        Security.removeProvider(provider.getName());
    }
}

From source file:com.zwitserloot.ivyplusplus.mavencentral.CreateDetachedSignatures_.java

License:Open Source License

void signFile(InputStream fileData, PGPSecretKey signingKey, String passphrase, OutputStream out)
        throws IOException, NoSuchProviderException, PGPException, NoSuchAlgorithmException,
        SignatureException {/*w w w.  java2 s .  com*/
    PGPPrivateKey privKey = signingKey.extractPrivateKey(passphrase.toCharArray(), "BC");
    PGPSignatureGenerator sigGen = new PGPSignatureGenerator(signingKey.getPublicKey().getAlgorithm(),
            PGPUtil.SHA1, "BC");
    sigGen.initSign(PGPSignature.BINARY_DOCUMENT, privKey);
    out = new ArmoredOutputStream(out);
    BCPGOutputStream bOut = new BCPGOutputStream(out);
    byte[] b = new byte[4096];
    while (true) {
        int r = fileData.read(b);
        if (r == -1)
            break;
        sigGen.update(b, 0, r);
    }

    sigGen.generate().encode(bOut);
    bOut.close();
    out.close();
}

From source file:de.dentrassi.pm.signing.pgp.internal.PgpSigningService.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));
    signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, this.privateKey);

    final ArmoredOutputStream armoredOutput = new ArmoredOutputStream(out);

    if (inline) {
        armoredOutput.beginClearText(digest);
    }//from  w  w  w.  ja v a 2s .  c om

    final byte[] buffer = new byte[4096];

    int rc;
    while ((rc = in.read(buffer)) >= 0) {
        if (inline) {
            armoredOutput.write(buffer, 0, rc);
        }
        signatureGenerator.update(buffer, 0, rc);
    }

    armoredOutput.endClearText();

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

    armoredOutput.close();
}

From source file:dorkbox.util.crypto.CryptoPGP.java

License:Apache License

/**
 * Sign a message using our private PGP key file, with a variety of options
 *///from w  w w.  ja  va2  s.  c  om
@SuppressWarnings("Duplicates")
public static byte[] sign(InputStream privateKeyInputStream, String userId, char[] password,
        InputStream message, int signatureType, boolean compressSignature, boolean asciiArmoredOutput,
        boolean includeDataInSignature, boolean generateUserIdSubPacket, boolean generateOnePassVersion)
        throws PGPException {

    List<PGPSecretKey> secretKeys = getSecretKeys(privateKeyInputStream, userId);
    PGPSignatureGenerator signature = createSignature(secretKeys, password, signatureType,
            generateUserIdSubPacket);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    OutputStream outputStream = byteArrayOutputStream;
    if (asciiArmoredOutput) {
        outputStream = new ArmoredOutputStream(byteArrayOutputStream);
    }

    PGPCompressedDataGenerator compressedDataGenerator = null;
    BCPGOutputStream bcOutputStream;

    if (compressSignature) {
        compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB);
        try {
            bcOutputStream = new BCPGOutputStream(compressedDataGenerator.open(outputStream));
        } catch (IOException e) {
            throw new PGPException("Unable to open compression stream in the signature", e);
        }
    } else {
        bcOutputStream = new BCPGOutputStream(outputStream);
    }

    if (generateOnePassVersion) {
        try {
            signature.generateOnePassVersion(false).encode(bcOutputStream);
        } catch (IOException e) {
            throw new PGPException("Unable to generate OnePass signature header", e);
        }
    }

    PGPLiteralDataGenerator literalDataGenerator = null;
    OutputStream literalDataOutput = null;

    if (includeDataInSignature) {
        literalDataGenerator = new PGPLiteralDataGenerator();
        try {
            literalDataOutput = literalDataGenerator.open(bcOutputStream, PGPLiteralData.BINARY, "_CONSOLE",
                    message.available(), new Date());
        } catch (IOException e1) {
            throw new PGPException("Unable to generate Literal Data signature header", e1);
        }
    }

    try {
        byte[] buffer = new byte[4096];
        int read;

        // update bytes in the streams
        if (literalDataOutput != null) {
            while ((read = message.read(buffer)) > 0) {
                literalDataOutput.write(buffer, 0, read);
                signature.update(buffer, 0, read);
            }
            literalDataOutput.flush();
        } else {

            while ((read = message.read(buffer)) > 0) {
                signature.update(buffer, 0, read);
            }
        }

        // close generators and update signature
        if (literalDataGenerator != null) {
            literalDataGenerator.close();
        }

        signature.generate().encode(bcOutputStream);

        if (compressedDataGenerator != null) {
            compressedDataGenerator.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        IO.close(bcOutputStream);
        IO.close(outputStream);
        IO.close(literalDataOutput);
    }

    return byteArrayOutputStream.toByteArray();
}

From source file:dorkbox.util.crypto.CryptoPGP.java

License:Apache License

/**
 * Sign a message using our private PGP key file, with a variety of options
 *//*from www . j  av  a  2 s .  c  om*/
@SuppressWarnings("Duplicates")
public static byte[] sign(InputStream privateKeyInputStream, String userId, char[] password, File fileMessage,
        int signatureType, boolean compressSignature, boolean asciiArmoredOutput,
        boolean includeDataInSignature, boolean generateUserIdSubPacket, boolean generateOnePassVersion)
        throws PGPException {

    List<PGPSecretKey> secretKeys = getSecretKeys(privateKeyInputStream, userId);
    PGPSignatureGenerator signature = createSignature(secretKeys, password, signatureType,
            generateUserIdSubPacket);

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    OutputStream outputStream = byteArrayOutputStream;
    if (asciiArmoredOutput) {
        outputStream = new ArmoredOutputStream(byteArrayOutputStream);
    }

    PGPCompressedDataGenerator compressedDataGenerator = null;
    BCPGOutputStream bcOutputStream;

    if (compressSignature) {
        compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB);
        try {
            bcOutputStream = new BCPGOutputStream(compressedDataGenerator.open(outputStream));
        } catch (IOException e) {
            throw new PGPException("Unable to open compression stream in the signature", e);
        }
    } else {
        bcOutputStream = new BCPGOutputStream(outputStream);
    }

    if (generateOnePassVersion) {
        try {
            signature.generateOnePassVersion(false).encode(bcOutputStream);
        } catch (IOException e) {
            throw new PGPException("Unable to generate OnePass signature header", e);
        }
    }

    PGPLiteralDataGenerator literalDataGenerator = null;
    OutputStream literalDataOutput = null;

    if (includeDataInSignature) {
        literalDataGenerator = new PGPLiteralDataGenerator();
        try {
            literalDataOutput = literalDataGenerator.open(bcOutputStream, PGPLiteralData.BINARY, fileMessage);
        } catch (IOException e1) {
            throw new PGPException("Unable to generate Literal Data signature header", e1);
        }
    }

    try {
        final FileInputStream fileInputStream = new FileInputStream(fileMessage);

        byte[] buffer = new byte[4096];
        int read;

        // update bytes in the streams
        if (literalDataOutput != null) {
            while ((read = fileInputStream.read(buffer)) > 0) {
                literalDataOutput.write(buffer, 0, read);
                signature.update(buffer, 0, read);
            }
            literalDataOutput.flush();
        } else {

            while ((read = fileInputStream.read(buffer)) > 0) {
                signature.update(buffer, 0, read);
            }
        }

        // close generators and update signature
        if (literalDataGenerator != null) {
            literalDataGenerator.close();
        }

        signature.generate().encode(bcOutputStream);

        if (compressedDataGenerator != null) {
            compressedDataGenerator.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        IO.close(bcOutputStream);
        IO.close(outputStream);
        IO.close(literalDataOutput);
    }

    return byteArrayOutputStream.toByteArray();
}

From source file:org.apache.camel.converter.crypto.PGPDataFormat.java

License:Apache License

public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception {
    List<String> userids = determineEncryptionUserIds(exchange);
    List<PGPPublicKey> keys = PGPDataFormatUtil.findPublicKeys(exchange.getContext(), findKeyFileName(exchange),
            findEncryptionKeyRing(exchange), userids, true);
    if (keys.isEmpty()) {
        throw new IllegalArgumentException(
                "Cannot PGP encrypt message. No public encryption key found for the User Ids " + userids
                        + " in the public keyring. Either specify other User IDs or add correct public keys to the keyring.");
    }/*from  w  w  w  .ja v  a 2 s  .  c o m*/

    InputStream input = ExchangeHelper.convertToMandatoryType(exchange, InputStream.class, graph);

    if (armored) {
        outputStream = new ArmoredOutputStream(outputStream);
    }

    PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
            new JcePGPDataEncryptorBuilder(findAlgorithm(exchange)).setWithIntegrityPacket(integrity)
                    .setSecureRandom(new SecureRandom()).setProvider(getProvider()));
    // several keys can be added
    for (PGPPublicKey key : keys) {
        encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(key));
    }
    OutputStream encOut = encGen.open(outputStream, new byte[BUFFER_SIZE]);

    PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(findCompressionAlgorithm(exchange));
    OutputStream comOut = new BufferedOutputStream(comData.open(encOut));

    PGPSignatureGenerator sigGen = createSignatureGenerator(exchange, comOut);

    PGPLiteralDataGenerator litData = new PGPLiteralDataGenerator();
    String fileName = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);
    if (ObjectHelper.isEmpty(fileName)) {
        // This marks the file as For Your Eyes Only... may cause problems for the receiver if they use
        // an automated process to decrypt as the filename is appended with _CONSOLE
        fileName = PGPLiteralData.CONSOLE;
    }
    OutputStream litOut = litData.open(comOut, PGPLiteralData.BINARY, fileName, new Date(),
            new byte[BUFFER_SIZE]);

    try {
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            litOut.write(buffer, 0, bytesRead);
            if (sigGen != null) {
                sigGen.update(buffer, 0, bytesRead);
            }
            litOut.flush();
        }
    } finally {
        IOHelper.close(litOut);
        if (sigGen != null) {
            sigGen.generate().encode(comOut);
        }
        IOHelper.close(comOut, encOut, outputStream, input);
    }
}

From source file:org.apache.camel.converter.crypto.PGPKeyAccessDataFormat.java

License:Apache License

public void marshal(Exchange exchange, Object graph, OutputStream outputStream) throws Exception {
    List<String> userids = determineEncryptionUserIds(exchange);
    List<PGPPublicKey> keys = publicKeyAccessor.getEncryptionKeys(exchange, userids);
    if (keys.isEmpty()) {
        throw new IllegalArgumentException(
                "Cannot PGP encrypt message. No public encryption key found for the User Ids " + userids
                        + " in the public keyring. Either specify other User IDs or add correct public keys to the keyring.");
    }//from  w  ww.jav  a  2  s .co m
    exchange.getOut().setHeader(NUMBER_OF_ENCRYPTION_KEYS, Integer.valueOf(keys.size()));

    InputStream input = ExchangeHelper.convertToMandatoryType(exchange, InputStream.class, graph);

    if (armored) {
        outputStream = new ArmoredOutputStream(outputStream);
    }

    PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
            new JcePGPDataEncryptorBuilder(findAlgorithm(exchange)).setWithIntegrityPacket(integrity)
                    .setSecureRandom(new SecureRandom()).setProvider(getProvider()));
    // several keys can be added
    for (PGPPublicKey key : keys) {
        encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(key));
    }
    OutputStream encOut = encGen.open(outputStream, new byte[BUFFER_SIZE]);

    PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(findCompressionAlgorithm(exchange));
    OutputStream comOut = new BufferedOutputStream(comData.open(encOut));

    List<PGPSignatureGenerator> sigGens = createSignatureGenerator(exchange, comOut);

    PGPLiteralDataGenerator litData = new PGPLiteralDataGenerator();
    String fileName = exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);
    if (ObjectHelper.isEmpty(fileName)) {
        // This marks the file as For Your Eyes Only... may cause problems for the receiver if they use
        // an automated process to decrypt as the filename is appended with _CONSOLE
        fileName = PGPLiteralData.CONSOLE;
    }
    OutputStream litOut = litData.open(comOut, PGPLiteralData.BINARY, fileName, new Date(),
            new byte[BUFFER_SIZE]);

    try {
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            litOut.write(buffer, 0, bytesRead);
            if (sigGens != null && !sigGens.isEmpty()) {
                for (PGPSignatureGenerator sigGen : sigGens) {
                    // not nested therefore it is the same for all
                    // can this be improved that we only do it for one sigGen and set the result on the others?
                    sigGen.update(buffer, 0, bytesRead);
                }
            }
            litOut.flush();
        }
    } finally {
        IOHelper.close(litOut);
        if (sigGens != null && !sigGens.isEmpty()) {
            // reverse order
            for (int i = sigGens.size() - 1; i > -1; i--) {
                PGPSignatureGenerator sigGen = sigGens.get(i);
                sigGen.generate().encode(comOut);
            }
        }
        IOHelper.close(comOut, encOut, outputStream, input);
    }
}