use of org.jivesoftware.smackx.ox.OpenPgpMessage 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.jivesoftware.smackx.ox.OpenPgpMessage in project Smack by igniterealtime.
the class OXInstantMessagingManagerTest method test.
@Test
public void test() throws IOException, PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException, SmackException, MissingUserIdOnKeyException, InterruptedException, XMPPException, XmlPullParserException {
DummyConnection aliceCon = new DummyConnection();
aliceCon.connect().login();
DummyConnection bobCon = new DummyConnection();
bobCon.connect().login();
FileBasedOpenPgpStore aliceStore = new FileBasedOpenPgpStore(new File(basePath, "alice"));
FileBasedOpenPgpStore bobStore = new FileBasedOpenPgpStore(new File(basePath, "bob"));
PainlessOpenPgpProvider aliceProvider = new PainlessOpenPgpProvider(aliceStore);
PainlessOpenPgpProvider bobProvider = new PainlessOpenPgpProvider(bobStore);
OpenPgpManager aliceOpenPgp = OpenPgpManager.getInstanceFor(aliceCon);
OpenPgpManager bobOpenPgp = OpenPgpManager.getInstanceFor(bobCon);
aliceOpenPgp.setOpenPgpProvider(aliceProvider);
bobOpenPgp.setOpenPgpProvider(bobProvider);
OXInstantMessagingManager aliceOxim = OXInstantMessagingManager.getInstanceFor(aliceCon);
OpenPgpSelf aliceSelf = aliceOpenPgp.getOpenPgpSelf();
OpenPgpSelf bobSelf = bobOpenPgp.getOpenPgpSelf();
assertFalse(aliceSelf.hasSecretKeyAvailable());
assertFalse(bobSelf.hasSecretKeyAvailable());
// Generate keys
aliceOpenPgp.generateAndImportKeyPair(aliceSelf.getJid());
bobOpenPgp.generateAndImportKeyPair(bobSelf.getJid());
assertTrue(aliceSelf.hasSecretKeyAvailable());
assertTrue(bobSelf.hasSecretKeyAvailable());
assertTrue(aliceSelf.isTrusted(aliceSelf.getSigningKeyFingerprint()));
assertTrue(bobSelf.isTrusted(bobSelf.getSigningKeyFingerprint()));
assertTrue(aliceSelf.getTrustedFingerprints().contains(aliceSelf.getSigningKeyFingerprint()));
// Exchange keys
aliceStore.importPublicKey(bobSelf.getJid(), bobSelf.getAnnouncedPublicKeys().iterator().next());
bobStore.importPublicKey(aliceSelf.getJid(), aliceSelf.getAnnouncedPublicKeys().iterator().next());
// Simulate key announcement
bobStore.setAnnouncedFingerprintsOf(bobSelf.getJid(), Collections.singletonMap(bobSelf.getSigningKeyFingerprint(), new Date()));
bobStore.setAnnouncedFingerprintsOf(aliceSelf.getJid(), Collections.singletonMap(aliceSelf.getSigningKeyFingerprint(), new Date()));
aliceStore.setAnnouncedFingerprintsOf(aliceSelf.getJid(), Collections.singletonMap(aliceSelf.getSigningKeyFingerprint(), new Date()));
aliceStore.setAnnouncedFingerprintsOf(bobSelf.getJid(), Collections.singletonMap(bobSelf.getSigningKeyFingerprint(), new Date()));
OpenPgpContact aliceForBob = bobOpenPgp.getOpenPgpContact((EntityBareJid) aliceSelf.getJid());
OpenPgpContact bobForAlice = aliceOpenPgp.getOpenPgpContact((EntityBareJid) bobSelf.getJid());
assertTrue(aliceForBob.hasUndecidedKeys());
assertTrue(bobForAlice.hasUndecidedKeys());
assertTrue(aliceForBob.getUndecidedFingerprints().contains(aliceSelf.getSigningKeyFingerprint()));
assertTrue(bobForAlice.getUndecidedFingerprints().contains(bobSelf.getSigningKeyFingerprint()));
bobForAlice.trust(bobSelf.getSigningKeyFingerprint());
aliceForBob.trust(aliceSelf.getSigningKeyFingerprint());
assertFalse(aliceForBob.hasUndecidedKeys());
assertFalse(bobForAlice.hasUndecidedKeys());
MessageBuilder messageBuilder = StanzaBuilder.buildMessage();
assertFalse(ExplicitMessageEncryptionElement.hasProtocol(messageBuilder.build(), ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0));
aliceOxim.addOxMessage(messageBuilder, bobForAlice, Collections.singletonList(new Message.Body(null, "Hello World!")));
Message message = messageBuilder.build();
assertTrue(ExplicitMessageEncryptionElement.hasProtocol(message, ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0));
assertNotNull(OpenPgpElement.fromStanza(message));
OpenPgpMessage decrypted = bobOpenPgp.decryptOpenPgpElement(OpenPgpElement.fromStanza(message), aliceForBob);
assertEquals(OpenPgpMessage.State.signcrypt, decrypted.getState());
SigncryptElement signcryptElement = (SigncryptElement) decrypted.getOpenPgpContentElement();
Message.Body body = signcryptElement.getExtension(Message.Body.ELEMENT, Message.Body.NAMESPACE);
assertNotNull(body);
assertEquals("Hello World!", body.getMessage());
OpenPgpMetadata metadata = decrypted.getMetadata();
assertTrue(metadata.isSigned() && metadata.isEncrypted());
// Check, if one of Bobs keys was used for decryption
assertNotNull(bobSelf.getSigningKeyRing().getPublicKey(metadata.getDecryptionKey().getKeyId()));
// TODO: I observed this assertTrue() to fail sporadically. As a first attempt to diagnose this, a message was
// added to the assertion. However since most (all?) objects used in the message do not implement a proper
// toString() this is probably not really helpful as it is.
PGPPublicKeyRingCollection pubKeys = aliceForBob.getTrustedAnnouncedKeys();
// Check if one of Alice' keys was used for signing
assertTrue(metadata.containsVerifiedSignatureFrom(pubKeys.iterator().next()), metadata + " did not contain one of alice' keys " + pubKeys);
}
Aggregations