use of org.pgpainless.decryption_verification.DecryptionStream in project Smack by igniterealtime.
the class PainlessOpenPgpProvider method decryptAndOrVerify.
@Override
public OpenPgpMessage decryptAndOrVerify(XMPPConnection connection, OpenPgpElement element, final OpenPgpSelf self, final OpenPgpContact sender) throws IOException, PGPException {
ByteArrayOutputStream plainText = new ByteArrayOutputStream();
InputStream cipherText = element.toInputStream();
PGPPublicKeyRingCollection announcedPublicKeys = sender.getAnnouncedPublicKeys();
if (announcedPublicKeys == null) {
try {
sender.updateKeys(connection);
announcedPublicKeys = sender.getAnnouncedPublicKeys();
} catch (InterruptedException | NotALeafNodeException | NotAPubSubNodeException | NotConnectedException | NoResponseException | XMPPErrorException e) {
throw new PGPException("Abort decryption due to lack of keys", e);
}
}
MissingPublicKeyCallback missingPublicKeyCallback = new MissingPublicKeyCallback() {
@Override
public PGPPublicKeyRing onMissingPublicKeyEncountered(Long keyId) {
try {
sender.updateKeys(connection);
PGPPublicKeyRingCollection anyKeys = sender.getAnyPublicKeys();
for (PGPPublicKeyRing ring : anyKeys) {
if (ring.getPublicKey(keyId) != null) {
return ring;
}
}
return null;
} catch (InterruptedException | NotALeafNodeException | NotAPubSubNodeException | NotConnectedException | NoResponseException | XMPPErrorException | IOException | PGPException e) {
LOGGER.log(Level.WARNING, "Cannot fetch missing key " + keyId, e);
return null;
}
}
};
DecryptionStream cipherStream = PGPainless.decryptAndOrVerify().onInputStream(cipherText).withOptions(new ConsumerOptions().addDecryptionKeys(self.getSecretKeys(), getStore().getKeyRingProtector()).addVerificationCerts(announcedPublicKeys).setMissingCertificateCallback(missingPublicKeyCallback));
Streams.pipeAll(cipherStream, plainText);
cipherText.close();
cipherStream.close();
plainText.close();
OpenPgpMetadata info = cipherStream.getResult();
OpenPgpMessage.State state;
if (info.isSigned()) {
if (info.isEncrypted()) {
state = OpenPgpMessage.State.signcrypt;
} else {
state = OpenPgpMessage.State.sign;
}
} else if (info.isEncrypted()) {
state = OpenPgpMessage.State.crypt;
} else {
throw new PGPException("Received message appears to be neither encrypted, nor signed.");
}
return new OpenPgpMessage(plainText.toByteArray(), state, info);
}
use of org.pgpainless.decryption_verification.DecryptionStream in project Smack by igniterealtime.
the class SecretKeyBackupHelper method restoreSecretKeyBackup.
/**
* Decrypt a secret key backup and return the {@link PGPSecretKeyRing} contained in it.
* TODO: Return a PGPSecretKeyRingCollection instead?
*
* @param backup encrypted {@link SecretkeyElement} containing the backup
* @param backupCode passphrase for decrypting the {@link SecretkeyElement}.
* @return the TODO javadoc me please
* @throws InvalidBackupCodeException in case the provided backup code is invalid.
* @throws IOException IO is dangerous.
* @throws PGPException PGP is brittle.
*/
public static PGPSecretKeyRing restoreSecretKeyBackup(SecretkeyElement backup, OpenPgpSecretKeyBackupPassphrase backupCode) throws InvalidBackupCodeException, IOException, PGPException {
byte[] encrypted = Base64.decode(backup.getB64Data());
InputStream encryptedIn = new ByteArrayInputStream(encrypted);
ByteArrayOutputStream plaintextOut = new ByteArrayOutputStream();
try {
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify().onInputStream(encryptedIn).withOptions(new ConsumerOptions().addDecryptionPassphrase(Passphrase.fromPassword(backupCode.toString())));
Streams.pipeAll(decryptionStream, plaintextOut);
decryptionStream.close();
} catch (MissingDecryptionMethodException e) {
throw new InvalidBackupCodeException("Could not decrypt secret key backup. Possibly wrong passphrase?", e);
}
byte[] decrypted = plaintextOut.toByteArray();
return PGPainless.readKeyRing().secretKeyRing(decrypted);
}
Aggregations