Search in sources :

Example 1 with OpenPgpMetadata

use of org.pgpainless.decryption_verification.OpenPgpMetadata 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);
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) XMPPErrorException(org.jivesoftware.smack.XMPPException.XMPPErrorException) NotALeafNodeException(org.jivesoftware.smackx.pubsub.PubSubException.NotALeafNodeException) NotConnectedException(org.jivesoftware.smack.SmackException.NotConnectedException) InputStream(java.io.InputStream) ConsumerOptions(org.pgpainless.decryption_verification.ConsumerOptions) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) DecryptionStream(org.pgpainless.decryption_verification.DecryptionStream) PGPException(org.bouncycastle.openpgp.PGPException) PGPPublicKeyRingCollection(org.bouncycastle.openpgp.PGPPublicKeyRingCollection) NotAPubSubNodeException(org.jivesoftware.smackx.pubsub.PubSubException.NotAPubSubNodeException) OpenPgpMessage(org.jivesoftware.smackx.ox.OpenPgpMessage) NoResponseException(org.jivesoftware.smack.SmackException.NoResponseException) MissingPublicKeyCallback(org.pgpainless.decryption_verification.MissingPublicKeyCallback) OpenPgpMetadata(org.pgpainless.decryption_verification.OpenPgpMetadata)

Example 2 with OpenPgpMetadata

use of org.pgpainless.decryption_verification.OpenPgpMetadata 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);
}
Also used : SigncryptElement(org.jivesoftware.smackx.ox.element.SigncryptElement) OpenPgpMessage(org.jivesoftware.smackx.ox.OpenPgpMessage) Message(org.jivesoftware.smack.packet.Message) DummyConnection(org.jivesoftware.smack.DummyConnection) OpenPgpSelf(org.jivesoftware.smackx.ox.OpenPgpSelf) Date(java.util.Date) FileBasedOpenPgpStore(org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore) PGPPublicKeyRingCollection(org.bouncycastle.openpgp.PGPPublicKeyRingCollection) MessageBuilder(org.jivesoftware.smack.packet.MessageBuilder) OpenPgpMessage(org.jivesoftware.smackx.ox.OpenPgpMessage) File(java.io.File) PainlessOpenPgpProvider(org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider) OpenPgpManager(org.jivesoftware.smackx.ox.OpenPgpManager) OpenPgpContact(org.jivesoftware.smackx.ox.OpenPgpContact) OpenPgpMetadata(org.pgpainless.decryption_verification.OpenPgpMetadata) Test(org.junit.jupiter.api.Test)

Example 3 with OpenPgpMetadata

use of org.pgpainless.decryption_verification.OpenPgpMetadata in project Smack by igniterealtime.

the class OXInstantMessagingIntegrationTest method basicInstantMessagingTest.

@SmackIntegrationTest
public void basicInstantMessagingTest() throws Exception {
    final SimpleResultSyncPoint bobReceivedMessage = new SimpleResultSyncPoint();
    final String body = "Writing integration tests is an annoying task, but it has to be done, so lets do it!!!";
    FileBasedOpenPgpStore aliceStore = new FileBasedOpenPgpStore(aliceStorePath);
    aliceStore.setKeyRingProtector(new UnprotectedKeysProtector());
    FileBasedOpenPgpStore bobStore = new FileBasedOpenPgpStore(bobStorePath);
    bobStore.setKeyRingProtector(new UnprotectedKeysProtector());
    PainlessOpenPgpProvider aliceProvider = new PainlessOpenPgpProvider(aliceStore);
    PainlessOpenPgpProvider bobProvider = new PainlessOpenPgpProvider(bobStore);
    aliceOpenPgp = OpenPgpManager.getInstanceFor(aliceConnection);
    bobOpenPgp = OpenPgpManager.getInstanceFor(bobConnection);
    OXInstantMessagingManager aliceInstantMessaging = OXInstantMessagingManager.getInstanceFor(aliceConnection);
    OXInstantMessagingManager bobInstantMessaging = OXInstantMessagingManager.getInstanceFor(bobConnection);
    bobInstantMessaging.addOxMessageListener(new OxMessageListener() {

        @Override
        public void newIncomingOxMessage(OpenPgpContact contact, Message originalMessage, SigncryptElement decryptedPayload, OpenPgpMetadata metadata) {
            if (((Message.Body) decryptedPayload.getExtension(Message.Body.NAMESPACE)).getMessage().equals(body)) {
                bobReceivedMessage.signal();
            } else {
                bobReceivedMessage.signalFailure();
            }
        }
    });
    aliceOpenPgp.setOpenPgpProvider(aliceProvider);
    bobOpenPgp.setOpenPgpProvider(bobProvider);
    aliceFingerprint = aliceOpenPgp.generateAndImportKeyPair(alice);
    bobFingerprint = bobOpenPgp.generateAndImportKeyPair(bob);
    aliceOpenPgp.announceSupportAndPublish();
    bobOpenPgp.announceSupportAndPublish();
    OpenPgpContact bobForAlice = aliceOpenPgp.getOpenPgpContact(bob.asEntityBareJidIfPossible());
    OpenPgpContact aliceForBob = bobOpenPgp.getOpenPgpContact(alice.asEntityBareJidIfPossible());
    bobForAlice.updateKeys(aliceConnection);
    assertFalse(bobForAlice.isTrusted(bobFingerprint));
    assertFalse(aliceForBob.isTrusted(aliceFingerprint));
    bobForAlice.trust(bobFingerprint);
    aliceForBob.trust(aliceFingerprint);
    assertTrue(bobForAlice.isTrusted(bobFingerprint));
    assertTrue(aliceForBob.isTrusted(aliceFingerprint));
    aliceInstantMessaging.sendOxMessage(bobForAlice, body);
    bobReceivedMessage.waitForResult(timeout);
}
Also used : SigncryptElement(org.jivesoftware.smackx.ox.element.SigncryptElement) Message(org.jivesoftware.smack.packet.Message) FileBasedOpenPgpStore(org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore) UnprotectedKeysProtector(org.pgpainless.key.protection.UnprotectedKeysProtector) SimpleResultSyncPoint(org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint) PainlessOpenPgpProvider(org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider) OpenPgpContact(org.jivesoftware.smackx.ox.OpenPgpContact) OpenPgpMetadata(org.pgpainless.decryption_verification.OpenPgpMetadata) SmackIntegrationTest(org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest)

Aggregations

OpenPgpMetadata (org.pgpainless.decryption_verification.OpenPgpMetadata)3 PGPPublicKeyRingCollection (org.bouncycastle.openpgp.PGPPublicKeyRingCollection)2 Message (org.jivesoftware.smack.packet.Message)2 OpenPgpContact (org.jivesoftware.smackx.ox.OpenPgpContact)2 OpenPgpMessage (org.jivesoftware.smackx.ox.OpenPgpMessage)2 PainlessOpenPgpProvider (org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider)2 SigncryptElement (org.jivesoftware.smackx.ox.element.SigncryptElement)2 FileBasedOpenPgpStore (org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 File (java.io.File)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Date (java.util.Date)1 PGPException (org.bouncycastle.openpgp.PGPException)1 PGPPublicKeyRing (org.bouncycastle.openpgp.PGPPublicKeyRing)1 SmackIntegrationTest (org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest)1 SimpleResultSyncPoint (org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint)1 DummyConnection (org.jivesoftware.smack.DummyConnection)1 NoResponseException (org.jivesoftware.smack.SmackException.NoResponseException)1 NotConnectedException (org.jivesoftware.smack.SmackException.NotConnectedException)1