Search in sources :

Example 1 with OpenPgpContact

use of org.jivesoftware.smackx.ox.OpenPgpContact 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 2 with OpenPgpContact

use of org.jivesoftware.smackx.ox.OpenPgpContact 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)

Example 3 with OpenPgpContact

use of org.jivesoftware.smackx.ox.OpenPgpContact in project Smack by igniterealtime.

the class PainlessOpenPgpProvider method encrypt.

@Override
public OpenPgpElementAndMetadata encrypt(CryptElement element, OpenPgpSelf self, Collection<OpenPgpContact> recipients) throws IOException, PGPException {
    InputStream plainText = element.toInputStream();
    ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
    EncryptionOptions encOpts = EncryptionOptions.encryptCommunications();
    for (OpenPgpContact contact : recipients) {
        PGPPublicKeyRingCollection keys = contact.getTrustedAnnouncedKeys();
        if (keys == null) {
            LOGGER.log(Level.WARNING, "There are no suitable keys for contact " + contact.getJid());
        }
        encOpts.addRecipients(keys);
    }
    encOpts.addRecipients(self.getTrustedAnnouncedKeys());
    EncryptionStream cipherStream = PGPainless.encryptAndOrSign().onOutputStream(cipherText).withOptions(ProducerOptions.encrypt(encOpts).setAsciiArmor(false));
    Streams.pipeAll(plainText, cipherStream);
    plainText.close();
    cipherStream.flush();
    cipherStream.close();
    cipherText.close();
    String base64 = Base64.encodeToString(cipherText.toByteArray());
    OpenPgpElement openPgpElement = new OpenPgpElement(base64);
    return new OpenPgpElementAndMetadata(openPgpElement, cipherStream.getResult());
}
Also used : PGPPublicKeyRingCollection(org.bouncycastle.openpgp.PGPPublicKeyRingCollection) InputStream(java.io.InputStream) OpenPgpElement(org.jivesoftware.smackx.ox.element.OpenPgpElement) ByteArrayOutputStream(java.io.ByteArrayOutputStream) EncryptionOptions(org.pgpainless.encryption_signing.EncryptionOptions) EncryptionStream(org.pgpainless.encryption_signing.EncryptionStream) OpenPgpContact(org.jivesoftware.smackx.ox.OpenPgpContact)

Example 4 with OpenPgpContact

use of org.jivesoftware.smackx.ox.OpenPgpContact in project Smack by igniterealtime.

the class PainlessOpenPgpProvider method signAndEncrypt.

@Override
public OpenPgpElementAndMetadata signAndEncrypt(SigncryptElement element, OpenPgpSelf self, Collection<OpenPgpContact> recipients) throws IOException, PGPException {
    InputStream plainText = element.toInputStream();
    ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
    EncryptionOptions encOpts = EncryptionOptions.encryptCommunications();
    for (OpenPgpContact contact : recipients) {
        PGPPublicKeyRingCollection keys = contact.getTrustedAnnouncedKeys();
        if (keys == null) {
            LOGGER.log(Level.WARNING, "There are no suitable keys for contact " + contact.getJid());
        }
        encOpts.addRecipients(keys);
    }
    encOpts.addRecipients(self.getTrustedAnnouncedKeys());
    SigningOptions signOpts = new SigningOptions();
    signOpts.addInlineSignature(getStore().getKeyRingProtector(), self.getSigningKeyRing(), DocumentSignatureType.BINARY_DOCUMENT);
    EncryptionStream cipherStream = PGPainless.encryptAndOrSign().onOutputStream(cipherText).withOptions(ProducerOptions.signAndEncrypt(encOpts, signOpts).setAsciiArmor(false));
    Streams.pipeAll(plainText, cipherStream);
    plainText.close();
    cipherStream.flush();
    cipherStream.close();
    cipherText.close();
    String base64 = Base64.encodeToString(cipherText.toByteArray());
    OpenPgpElement openPgpElement = new OpenPgpElement(base64);
    return new OpenPgpElementAndMetadata(openPgpElement, cipherStream.getResult());
}
Also used : PGPPublicKeyRingCollection(org.bouncycastle.openpgp.PGPPublicKeyRingCollection) InputStream(java.io.InputStream) OpenPgpElement(org.jivesoftware.smackx.ox.element.OpenPgpElement) SigningOptions(org.pgpainless.encryption_signing.SigningOptions) ByteArrayOutputStream(java.io.ByteArrayOutputStream) EncryptionOptions(org.pgpainless.encryption_signing.EncryptionOptions) EncryptionStream(org.pgpainless.encryption_signing.EncryptionStream) OpenPgpContact(org.jivesoftware.smackx.ox.OpenPgpContact)

Example 5 with OpenPgpContact

use of org.jivesoftware.smackx.ox.OpenPgpContact in project Smack by igniterealtime.

the class AbstractOpenPgpStore method getOpenPgpContact.

@Override
public OpenPgpContact getOpenPgpContact(BareJid jid) {
    OpenPgpContact contact = contacts.get(jid);
    if (contact == null) {
        contact = new OpenPgpContact(jid, this);
        contacts.put(jid, contact);
    }
    return contact;
}
Also used : OpenPgpContact(org.jivesoftware.smackx.ox.OpenPgpContact)

Aggregations

OpenPgpContact (org.jivesoftware.smackx.ox.OpenPgpContact)6 PGPPublicKeyRingCollection (org.bouncycastle.openpgp.PGPPublicKeyRingCollection)3 SigncryptElement (org.jivesoftware.smackx.ox.element.SigncryptElement)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 InputStream (java.io.InputStream)2 Message (org.jivesoftware.smack.packet.Message)2 PainlessOpenPgpProvider (org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider)2 OpenPgpElement (org.jivesoftware.smackx.ox.element.OpenPgpElement)2 FileBasedOpenPgpStore (org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore)2 OpenPgpMetadata (org.pgpainless.decryption_verification.OpenPgpMetadata)2 EncryptionOptions (org.pgpainless.encryption_signing.EncryptionOptions)2 EncryptionStream (org.pgpainless.encryption_signing.EncryptionStream)2 File (java.io.File)1 Date (java.util.Date)1 HashSet (java.util.HashSet)1 SmackIntegrationTest (org.igniterealtime.smack.inttest.annotations.SmackIntegrationTest)1 SimpleResultSyncPoint (org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint)1 DummyConnection (org.jivesoftware.smack.DummyConnection)1 MessageBuilder (org.jivesoftware.smack.packet.MessageBuilder)1 OpenPgpManager (org.jivesoftware.smackx.ox.OpenPgpManager)1