public Object unmarshal(Exchange exchange, InputStream encryptedStream) throws Exception {
if (encryptedStream == null) {
return null;
}
InputStream in = PGPUtil.getDecoderStream(encryptedStream);
PGPObjectFactory pgpFactory = new PGPObjectFactory(in);
Object o = pgpFactory.nextObject();
// the first object might be a PGP marker packet
PGPEncryptedDataList enc;
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpFactory.nextObject();
}
PGPPublicKeyEncryptedData pbe = null;
PGPPrivateKey key = null;
// find encrypted data for which a private key exists in the secret key ring
for (int i = 0; i < enc.size() && key == null; i++) {
pbe = (PGPPublicKeyEncryptedData) enc.get(i);
key = PGPDataFormatUtil.findPrivateKeyWithKeyId(exchange.getContext(), findKeyFileName(exchange),
findEncryptionKeyRing(exchange), pbe.getKeyID(), findKeyPassword(exchange), getPassphraseAccessor(), getProvider());
}
if (key == null) {
throw new PGPException("Provided input is encrypted with unknown pair of keys.");
}
InputStream encData = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(getProvider()).build(key));
pgpFactory = new PGPObjectFactory(encData);
PGPCompressedData comData = (PGPCompressedData) pgpFactory.nextObject();
pgpFactory = new PGPObjectFactory(comData.getDataStream());
Object object = pgpFactory.nextObject();
PGPOnePassSignature signature;
if (object instanceof PGPOnePassSignatureList) {
signature = getSignature(exchange, (PGPOnePassSignatureList) object);
object = pgpFactory.nextObject();
} else {
signature = null;
}
PGPLiteralData ld = (PGPLiteralData) object;
InputStream litData = ld.getInputStream();
// enable streaming via OutputStreamCache
CachedOutputStream cos;
ByteArrayOutputStream bos;
OutputStream os;
if (exchange.getContext().getStreamCachingStrategy().isEnabled()) {
cos = new CachedOutputStream(exchange);
bos = null;
os = cos;
} else {
cos = null;
bos = new ByteArrayOutputStream();
os = bos;
}
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = litData.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
if (signature != null) {
signature.update(buffer, 0, bytesRead);
}
os.flush();
}
} finally {
IOHelper.close(os, litData, encData, in);
}
if (signature != null) {
PGPSignatureList sigList = (PGPSignatureList) pgpFactory.nextObject();
if (!signature.verify(getSignatureWithKeyId(signature.getKeyID(), sigList))) {
throw new SignatureException("Cannot verify PGP signature");
}
}