org.whispersystems.libsignal.state.PreKeyBundle Java Examples

The following examples show how to use org.whispersystems.libsignal.state.PreKeyBundle. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SessionBuilderTest.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
public void testBasicPreKeyV2()
    throws InvalidKeyException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, UntrustedIdentityException, NoSessionException {
  SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

  SignalProtocolStore bobStore      = new TestInMemorySignalProtocolStore();
  ECKeyPair    bobPreKeyPair = Curve.generateKeyPair();
  PreKeyBundle bobPreKey     = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
                                                31337, bobPreKeyPair.getPublicKey(),
                                                0, null, null,
                                                bobStore.getIdentityKeyPair().getPublicKey());

  try {
    aliceSessionBuilder.process(bobPreKey);
    throw new AssertionError("Should fail with missing unsigned prekey!");
  } catch (InvalidKeyException e) {
    // Good!
    return;
  }
}
 
Example #2
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
private PreKeyBundle createBobPreKeyBundle(SignalProtocolStore bobStore) throws InvalidKeyException {
  ECKeyPair bobUnsignedPreKey   = Curve.generateKeyPair();
  int       bobUnsignedPreKeyId = new Random().nextInt(Medium.MAX_VALUE);
  byte[]    bobSignature        = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
                                                           bobSignedPreKey.getPublicKey().serialize());

  PreKeyBundle bobPreKeyBundle = new PreKeyBundle(1, 1,
                                                  bobUnsignedPreKeyId, bobUnsignedPreKey.getPublicKey(),
                                                  bobSignedPreKeyId, bobSignedPreKey.getPublicKey(),
                                                  bobSignature, bobStore.getIdentityKeyPair().getPublicKey());

  bobStore.storeSignedPreKey(bobSignedPreKeyId, new SignedPreKeyRecord(bobSignedPreKeyId, System.currentTimeMillis(), bobSignedPreKey, bobSignature));
  bobStore.storePreKey(bobUnsignedPreKeyId, new PreKeyRecord(bobUnsignedPreKeyId, bobUnsignedPreKey));

  return bobPreKeyBundle;
}
 
Example #3
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 6 votes vote down vote up
private PreKeyBundle createAlicePreKeyBundle(SignalProtocolStore aliceStore) throws InvalidKeyException {
  ECKeyPair aliceUnsignedPreKey   = Curve.generateKeyPair();
  int       aliceUnsignedPreKeyId = new Random().nextInt(Medium.MAX_VALUE);
  byte[]    aliceSignature        = Curve.calculateSignature(aliceStore.getIdentityKeyPair().getPrivateKey(),
                                                             aliceSignedPreKey.getPublicKey().serialize());

  PreKeyBundle alicePreKeyBundle = new PreKeyBundle(1, 1,
                                                    aliceUnsignedPreKeyId, aliceUnsignedPreKey.getPublicKey(),
                                                    aliceSignedPreKeyId, aliceSignedPreKey.getPublicKey(),
                                                    aliceSignature, aliceStore.getIdentityKeyPair().getPublicKey());

  aliceStore.storeSignedPreKey(aliceSignedPreKeyId, new SignedPreKeyRecord(aliceSignedPreKeyId, System.currentTimeMillis(), aliceSignedPreKey, aliceSignature));
  aliceStore.storePreKey(aliceUnsignedPreKeyId, new PreKeyRecord(aliceUnsignedPreKeyId, aliceUnsignedPreKey));

  return alicePreKeyBundle;
}
 
Example #4
Source File: PushServiceSocket.java    From mollyim-android with GNU General Public License v3.0 5 votes vote down vote up
public PreKeyBundle getPreKey(SignalServiceAddress destination, int deviceId) throws IOException {
  try {
    String path = String.format(PREKEY_DEVICE_PATH, destination.getIdentifier(), String.valueOf(deviceId));

    if (destination.getRelay().isPresent()) {
      path = path + "?relay=" + destination.getRelay().get();
    }

    String         responseText = makeServiceRequest(path, "GET", null);
    PreKeyResponse response     = JsonUtil.fromJson(responseText, PreKeyResponse.class);

    if (response.getDevices() == null || response.getDevices().size() < 1)
      throw new IOException("Empty prekey list");

    PreKeyResponseItem device                = response.getDevices().get(0);
    ECPublicKey        preKey                = null;
    ECPublicKey        signedPreKey          = null;
    byte[]             signedPreKeySignature = null;
    int                preKeyId              = -1;
    int                signedPreKeyId        = -1;

    if (device.getPreKey() != null) {
      preKeyId = device.getPreKey().getKeyId();
      preKey   = device.getPreKey().getPublicKey();
    }

    if (device.getSignedPreKey() != null) {
      signedPreKeyId        = device.getSignedPreKey().getKeyId();
      signedPreKey          = device.getSignedPreKey().getPublicKey();
      signedPreKeySignature = device.getSignedPreKey().getSignature();
    }

    return new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId, preKey,
                            signedPreKeyId, signedPreKey, signedPreKeySignature, response.getIdentityKey());
  } catch (NotFoundException nfe) {
    throw new UnregisteredUserException(destination.getIdentifier(), nfe);
  }
}
 
Example #5
Source File: PushServiceSocket.java    From libsignal-service-java with GNU General Public License v3.0 5 votes vote down vote up
public PreKeyBundle getPreKey(SignalServiceAddress destination, int deviceId) throws IOException {
  try {
    String path = String.format(PREKEY_DEVICE_PATH, destination.getIdentifier(),
                                String.valueOf(deviceId));

    if (destination.getRelay().isPresent()) {
      path = path + "?relay=" + destination.getRelay().get();
    }

    String         responseText = makeServiceRequest(path, "GET", null);
    PreKeyResponse response     = JsonUtil.fromJson(responseText, PreKeyResponse.class);

    if (response.getDevices() == null || response.getDevices().size() < 1)
      throw new IOException("Empty prekey list");

    PreKeyResponseItem device                = response.getDevices().get(0);
    ECPublicKey        preKey                = null;
    ECPublicKey        signedPreKey          = null;
    byte[]             signedPreKeySignature = null;
    int                preKeyId              = -1;
    int                signedPreKeyId        = -1;

    if (device.getPreKey() != null) {
      preKeyId = device.getPreKey().getKeyId();
      preKey   = device.getPreKey().getPublicKey();
    }

    if (device.getSignedPreKey() != null) {
      signedPreKeyId        = device.getSignedPreKey().getKeyId();
      signedPreKey          = device.getSignedPreKey().getPublicKey();
      signedPreKeySignature = device.getSignedPreKey().getSignature();
    }

    return new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId, preKey,
                            signedPreKeyId, signedPreKey, signedPreKeySignature, response.getIdentityKey());
  } catch (NotFoundException nfe) {
    throw new UnregisteredUserException(destination.getIdentifier(), nfe);
  }
}
 
Example #6
Source File: SignalOmemoService.java    From Smack with Apache License 2.0 5 votes vote down vote up
@Override
protected SignalOmemoRatchet instantiateOmemoRatchet(
        OmemoManager manager,
        OmemoStore<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord,
                SignalProtocolAddress, ECPublicKey, PreKeyBundle, SessionCipher> store) {

    return new SignalOmemoRatchet(manager, getOmemoStoreBackend());
}
 
Example #7
Source File: SignalOmemoRatchet.java    From Smack with Apache License 2.0 5 votes vote down vote up
SignalOmemoRatchet(OmemoManager omemoManager,
                          OmemoStore<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord,
                                         SessionRecord, SignalProtocolAddress, ECPublicKey, PreKeyBundle,
                                         SessionCipher> store) {
    super(omemoManager, store);
    this.storeConnector = new SignalOmemoStoreConnector(omemoManager, store);
}
 
Example #8
Source File: SessionBuilderTest.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
public void testRepeatBundleMessageV2() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException {
  SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

  SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

  ECKeyPair bobPreKeyPair            = Curve.generateKeyPair();
  ECKeyPair bobSignedPreKeyPair      = Curve.generateKeyPair();
  byte[]    bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
                                                                bobSignedPreKeyPair.getPublicKey().serialize());

  PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
                                            31337, bobPreKeyPair.getPublicKey(),
                                            0, null, null,
                                            bobStore.getIdentityKeyPair().getPublicKey());

  bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
  bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

  try {
    aliceSessionBuilder.process(bobPreKey);
    throw new AssertionError("Should fail with missing signed prekey!");
  } catch (InvalidKeyException e) {
    // Good!
    return;
  }
}
 
Example #9
Source File: SignalOmemoKeyUtil.java    From Smack with Apache License 2.0 5 votes vote down vote up
@Override
public PreKeyBundle bundleFromOmemoBundle(OmemoBundleElement bundle, OmemoDevice contact, int preKeyId)
        throws CorruptedOmemoKeyException {
    return new PreKeyBundle(0,
            contact.getDeviceId(),
            preKeyId,
            BUNDLE.preKeyPublic(bundle, preKeyId),
            BUNDLE.signedPreKeyId(bundle),
            BUNDLE.signedPreKeyPublic(bundle),
            BUNDLE.signedPreKeySignature(bundle),
            BUNDLE.identityKey(bundle));
}
 
Example #10
Source File: SignalOmemoStoreTest.java    From Smack with Apache License 2.0 4 votes vote down vote up
public SignalOmemoStoreTest(OmemoStore<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord, SignalProtocolAddress, ECPublicKey, PreKeyBundle, SessionCipher> store)
        throws XmppStringprepException {
    super(store);
}
 
Example #11
Source File: PushServiceSocket.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
public List<PreKeyBundle> getPreKeys(SignalServiceAddress destination,
                                     Optional<UnidentifiedAccess> unidentifiedAccess,
                                     int deviceIdInteger)
    throws IOException
{
  try {
    String deviceId = String.valueOf(deviceIdInteger);

    if (deviceId.equals("1"))
      deviceId = "*";

    String path = String.format(PREKEY_DEVICE_PATH, destination.getIdentifier(), deviceId);

    if (destination.getRelay().isPresent()) {
      path = path + "?relay=" + destination.getRelay().get();
    }

    String             responseText = makeServiceRequest(path, "GET", null, NO_HEADERS, unidentifiedAccess);
    PreKeyResponse     response     = JsonUtil.fromJson(responseText, PreKeyResponse.class);
    List<PreKeyBundle> bundles      = new LinkedList<>();

    for (PreKeyResponseItem device : response.getDevices()) {
      ECPublicKey preKey                = null;
      ECPublicKey signedPreKey          = null;
      byte[]      signedPreKeySignature = null;
      int         preKeyId              = -1;
      int         signedPreKeyId        = -1;

      if (device.getSignedPreKey() != null) {
        signedPreKey          = device.getSignedPreKey().getPublicKey();
        signedPreKeyId        = device.getSignedPreKey().getKeyId();
        signedPreKeySignature = device.getSignedPreKey().getSignature();
      }

      if (device.getPreKey() != null) {
        preKeyId = device.getPreKey().getKeyId();
        preKey   = device.getPreKey().getPublicKey();
      }

      bundles.add(new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId,
                                   preKey, signedPreKeyId, signedPreKey, signedPreKeySignature,
                                   response.getIdentityKey()));
    }

    return bundles;
  } catch (NotFoundException nfe) {
    throw new UnregisteredUserException(destination.getIdentifier(), nfe);
  }
}
 
Example #12
Source File: SignalOmemoKeyUtilTest.java    From Smack with Apache License 2.0 4 votes vote down vote up
public SignalOmemoKeyUtilTest(OmemoKeyUtil<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord, ECPublicKey, PreKeyBundle> keyUtil) {
    super(keyUtil);
}
 
Example #13
Source File: SignalOmemoService.java    From Smack with Apache License 2.0 4 votes vote down vote up
@Override
public OmemoStore<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord,
        SignalProtocolAddress, ECPublicKey, PreKeyBundle, SessionCipher>
createDefaultOmemoStoreBackend() {
    return new SignalCachingOmemoStore();
}
 
Example #14
Source File: SignalOmemoStoreConnector.java    From Smack with Apache License 2.0 4 votes vote down vote up
public SignalOmemoStoreConnector(OmemoManager omemoManager, OmemoStore<IdentityKeyPair,
        IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord, SignalProtocolAddress, ECPublicKey,
        PreKeyBundle, SessionCipher> store) {
    this.omemoManager = omemoManager;
    this.omemoStore = store;
}
 
Example #15
Source File: SignalOmemoStore.java    From Smack with Apache License 2.0 4 votes vote down vote up
@Override
public OmemoKeyUtil<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord, ECPublicKey, PreKeyBundle> keyUtil() {
    return signalKeyUtil;
}
 
Example #16
Source File: SignalFileBasedOmemoStore.java    From Smack with Apache License 2.0 4 votes vote down vote up
@Override
public OmemoKeyUtil<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord, ECPublicKey, PreKeyBundle> keyUtil() {
    return new SignalOmemoKeyUtil();
}
 
Example #17
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 4 votes vote down vote up
public void testSimultaneousInitiateLostMessage()
      throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException,
      InvalidMessageException, DuplicateMessageException, LegacyMessageException,
      InvalidKeyIdException, NoSessionException
  {
    SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
    SignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

    PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore);
    PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore);

    SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);
    SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, ALICE_ADDRESS);

    SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
    SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

    aliceSessionBuilder.process(bobPreKeyBundle);
    bobSessionBuilder.process(alicePreKeyBundle);

    CiphertextMessage messageForBob   = aliceSessionCipher.encrypt("hey there".getBytes());
    CiphertextMessage messageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

    assertTrue(messageForBob.getType() == CiphertextMessage.PREKEY_TYPE);
    assertTrue(messageForAlice.getType() == CiphertextMessage.PREKEY_TYPE);

    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    byte[] alicePlaintext = aliceSessionCipher.decrypt(new PreKeySignalMessage(messageForAlice.serialize()));
    byte[] bobPlaintext   = bobSessionCipher.decrypt(new PreKeySignalMessage(messageForBob.serialize()));

    assertTrue(new String(alicePlaintext).equals("sample message"));
    assertTrue(new String(bobPlaintext).equals("hey there"));

    assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);
    assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);

    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes());

    assertTrue(aliceResponse.getType() == CiphertextMessage.WHISPER_TYPE);

//    byte[] responsePlaintext = bobSessionCipher.decrypt(new WhisperMessage(aliceResponse.serialize()));
//
//    assertTrue(new String(responsePlaintext).equals("second message"));
//    assertTrue(isSessionIdEqual(aliceStore, bobStore));
    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    CiphertextMessage finalMessage = bobSessionCipher.encrypt("third message".getBytes());

    assertTrue(finalMessage.getType() == CiphertextMessage.WHISPER_TYPE);

    byte[] finalPlaintext = aliceSessionCipher.decrypt(new SignalMessage(finalMessage.serialize()));

    assertTrue(new String(finalPlaintext).equals("third message"));
    assertTrue(isSessionIdEqual(aliceStore, bobStore));
  }
 
Example #18
Source File: SessionBuilderTest.java    From libsignal-protocol-java with GNU General Public License v3.0 4 votes vote down vote up
public void testOptionalOneTimePreKey() throws Exception {
  SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

  SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

  ECKeyPair bobPreKeyPair            = Curve.generateKeyPair();
  ECKeyPair bobSignedPreKeyPair      = Curve.generateKeyPair();
  byte[]    bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
                                                                bobSignedPreKeyPair.getPublicKey().serialize());

  PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
                                            0, null,
                                            22, bobSignedPreKeyPair.getPublicKey(),
                                            bobSignedPreKeySignature,
                                            bobStore.getIdentityKeyPair().getPublicKey());

  aliceSessionBuilder.process(bobPreKey);

  assertTrue(aliceStore.containsSession(BOB_ADDRESS));
  assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);

  String            originalMessage    = "L'homme est condamné à être libre";
  SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  CiphertextMessage outgoingMessage    = aliceSessionCipher.encrypt(originalMessage.getBytes());

  assertTrue(outgoingMessage.getType() == CiphertextMessage.PREKEY_TYPE);

  PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessage.serialize());
  assertTrue(!incomingMessage.getPreKeyId().isPresent());

  bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
  bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

  SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);
  byte[]        plaintext        = bobSessionCipher.decrypt(incomingMessage);

  assertTrue(bobStore.containsSession(ALICE_ADDRESS));
  assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);
  assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getAliceBaseKey() != null);
  assertTrue(originalMessage.equals(new String(plaintext)));
}
 
Example #19
Source File: SessionBuilderTest.java    From libsignal-protocol-java with GNU General Public License v3.0 4 votes vote down vote up
public void testBadMessageBundle() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, DuplicateMessageException, LegacyMessageException, InvalidKeyIdException {
  SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

  SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

  ECKeyPair bobPreKeyPair            = Curve.generateKeyPair();
  ECKeyPair bobSignedPreKeyPair      = Curve.generateKeyPair();
  byte[]    bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
                                                                bobSignedPreKeyPair.getPublicKey().serialize());

  PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
                                            31337, bobPreKeyPair.getPublicKey(),
                                            22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
                                            bobStore.getIdentityKeyPair().getPublicKey());

  bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
  bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

  aliceSessionBuilder.process(bobPreKey);

  String            originalMessage    = "L'homme est condamné à être libre";
  SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes());

  assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE);

  byte[] goodMessage = outgoingMessageOne.serialize();
  byte[] badMessage  = new byte[goodMessage.length];
  System.arraycopy(goodMessage, 0, badMessage, 0, badMessage.length);

  badMessage[badMessage.length-10] ^= 0x01;

  PreKeySignalMessage incomingMessage  = new PreKeySignalMessage(badMessage);
  SessionCipher        bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

  byte[] plaintext = new byte[0];

  try {
    plaintext = bobSessionCipher.decrypt(incomingMessage);
    throw new AssertionError("Decrypt should have failed!");
  } catch (InvalidMessageException e) {
    // good.
  }

  assertTrue(bobStore.containsPreKey(31337));

  plaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(goodMessage));

  assertTrue(originalMessage.equals(new String(plaintext)));
  assertTrue(!bobStore.containsPreKey(31337));
}
 
Example #20
Source File: SessionBuilderTest.java    From libsignal-protocol-java with GNU General Public License v3.0 4 votes vote down vote up
public void testRepeatBundleMessageV3() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, InvalidKeyIdException, DuplicateMessageException, LegacyMessageException, NoSessionException {
  SignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);

  SignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

  ECKeyPair bobPreKeyPair            = Curve.generateKeyPair();
  ECKeyPair bobSignedPreKeyPair      = Curve.generateKeyPair();
  byte[]    bobSignedPreKeySignature = Curve.calculateSignature(bobStore.getIdentityKeyPair().getPrivateKey(),
                                                                bobSignedPreKeyPair.getPublicKey().serialize());

  PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.getLocalRegistrationId(), 1,
                                            31337, bobPreKeyPair.getPublicKey(),
                                            22, bobSignedPreKeyPair.getPublicKey(), bobSignedPreKeySignature,
                                            bobStore.getIdentityKeyPair().getPublicKey());

  bobStore.storePreKey(31337, new PreKeyRecord(bobPreKey.getPreKeyId(), bobPreKeyPair));
  bobStore.storeSignedPreKey(22, new SignedPreKeyRecord(22, System.currentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

  aliceSessionBuilder.process(bobPreKey);

  String            originalMessage    = "L'homme est condamné à être libre";
  SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  CiphertextMessage outgoingMessageOne = aliceSessionCipher.encrypt(originalMessage.getBytes());
  CiphertextMessage outgoingMessageTwo = aliceSessionCipher.encrypt(originalMessage.getBytes());

  assertTrue(outgoingMessageOne.getType() == CiphertextMessage.PREKEY_TYPE);
  assertTrue(outgoingMessageTwo.getType() == CiphertextMessage.PREKEY_TYPE);

  PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessageOne.serialize());

  SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

  byte[]        plaintext        = bobSessionCipher.decrypt(incomingMessage);
  assertTrue(originalMessage.equals(new String(plaintext)));

  CiphertextMessage bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());

  byte[] alicePlaintext = aliceSessionCipher.decrypt(new SignalMessage(bobOutgoingMessage.serialize()));
  assertTrue(originalMessage.equals(new String(alicePlaintext)));

  // The test

  PreKeySignalMessage incomingMessageTwo = new PreKeySignalMessage(outgoingMessageTwo.serialize());

  plaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(incomingMessageTwo.serialize()));
  assertTrue(originalMessage.equals(new String(plaintext)));

  bobOutgoingMessage = bobSessionCipher.encrypt(originalMessage.getBytes());
  alicePlaintext = aliceSessionCipher.decrypt(new SignalMessage(bobOutgoingMessage.serialize()));
  assertTrue(originalMessage.equals(new String(alicePlaintext)));

}
 
Example #21
Source File: SessionBuilder.java    From libsignal-protocol-java with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Build a new session from a {@link org.whispersystems.libsignal.state.PreKeyBundle} retrieved from
 * a server.
 *
 * @param preKey A PreKey for the destination recipient, retrieved from a server.
 * @throws InvalidKeyException when the {@link org.whispersystems.libsignal.state.PreKeyBundle} is
 *                             badly formatted.
 * @throws org.whispersystems.libsignal.UntrustedIdentityException when the sender's
 *                                                                  {@link IdentityKey} is not
 *                                                                  trusted.
 */
public void process(PreKeyBundle preKey) throws InvalidKeyException, UntrustedIdentityException {
  synchronized (SessionCipher.SESSION_LOCK) {
    if (!identityKeyStore.isTrustedIdentity(remoteAddress, preKey.getIdentityKey(), IdentityKeyStore.Direction.SENDING)) {
      throw new UntrustedIdentityException(remoteAddress.getName(), preKey.getIdentityKey());
    }

    if (preKey.getSignedPreKey() != null &&
        !Curve.verifySignature(preKey.getIdentityKey().getPublicKey(),
                               preKey.getSignedPreKey().serialize(),
                               preKey.getSignedPreKeySignature()))
    {
      throw new InvalidKeyException("Invalid signature on device key!");
    }

    if (preKey.getSignedPreKey() == null) {
      throw new InvalidKeyException("No signed prekey!");
    }

    SessionRecord         sessionRecord        = sessionStore.loadSession(remoteAddress);
    ECKeyPair             ourBaseKey           = Curve.generateKeyPair();
    ECPublicKey           theirSignedPreKey    = preKey.getSignedPreKey();
    Optional<ECPublicKey> theirOneTimePreKey   = Optional.fromNullable(preKey.getPreKey());
    Optional<Integer>     theirOneTimePreKeyId = theirOneTimePreKey.isPresent() ? Optional.of(preKey.getPreKeyId()) :
                                                                                  Optional.<Integer>absent();

    AliceSignalProtocolParameters.Builder parameters = AliceSignalProtocolParameters.newBuilder();

    parameters.setOurBaseKey(ourBaseKey)
              .setOurIdentityKey(identityKeyStore.getIdentityKeyPair())
              .setTheirIdentityKey(preKey.getIdentityKey())
              .setTheirSignedPreKey(theirSignedPreKey)
              .setTheirRatchetKey(theirSignedPreKey)
              .setTheirOneTimePreKey(theirOneTimePreKey);

    if (!sessionRecord.isFresh()) sessionRecord.archiveCurrentState();

    RatchetingSession.initializeSession(sessionRecord.getSessionState(), parameters.create());

    sessionRecord.getSessionState().setUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.getSignedPreKeyId(), ourBaseKey.getPublicKey());
    sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
    sessionRecord.getSessionState().setRemoteRegistrationId(preKey.getRegistrationId());
    sessionRecord.getSessionState().setAliceBaseKey(ourBaseKey.getPublicKey().serialize());

    identityKeyStore.saveIdentity(remoteAddress, preKey.getIdentityKey());
    sessionStore.storeSession(remoteAddress, sessionRecord);
  }
}
 
Example #22
Source File: SessionBuilder.java    From Silence with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Build a new session from a {@link org.whispersystems.libsignal.state.PreKeyBundle} retrieved from
 * a server.
 *
 * @param preKey A PreKey for the destination recipient, retrieved from a server.
 * @throws InvalidKeyException when the {@link org.whispersystems.libsignal.state.PreKeyBundle} is
 *                             badly formatted.
 * @throws org.whispersystems.libsignal.UntrustedIdentityException when the sender's
 *                                                                  {@link IdentityKey} is not
 *                                                                  trusted.
 */
public void process(PreKeyBundle preKey) throws InvalidKeyException, UntrustedIdentityException {
  synchronized (SessionCipher.SESSION_LOCK) {
    if (!identityKeyStore.isTrustedIdentity(remoteAddress, preKey.getIdentityKey(), IdentityKeyStore.Direction.SENDING)) {
      throw new UntrustedIdentityException(remoteAddress.getName(), preKey.getIdentityKey());
    }

    if (preKey.getSignedPreKey() != null &&
        !Curve.verifySignature(preKey.getIdentityKey().getPublicKey(),
                               preKey.getSignedPreKey().serialize(),
                               preKey.getSignedPreKeySignature()))
    {
      throw new InvalidKeyException("Invalid signature on device key!");
    }

    if (preKey.getSignedPreKey() == null) {
      throw new InvalidKeyException("No signed prekey!");
    }

    SessionRecord         sessionRecord        = sessionStore.loadSession(remoteAddress);
    ECKeyPair             ourBaseKey           = Curve.generateKeyPair();
    ECPublicKey           theirSignedPreKey    = preKey.getSignedPreKey();
    Optional<ECPublicKey> theirOneTimePreKey   = Optional.fromNullable(preKey.getPreKey());
    Optional<Integer>     theirOneTimePreKeyId = theirOneTimePreKey.isPresent() ? Optional.of(preKey.getPreKeyId()) :
                                                                                  Optional.<Integer>absent();

    AliceSignalProtocolParameters.Builder parameters = AliceSignalProtocolParameters.newBuilder();

    parameters.setOurBaseKey(ourBaseKey)
              .setOurIdentityKey(identityKeyStore.getIdentityKeyPair())
              .setTheirIdentityKey(preKey.getIdentityKey())
              .setTheirSignedPreKey(theirSignedPreKey)
              .setTheirRatchetKey(theirSignedPreKey)
              .setTheirOneTimePreKey(theirOneTimePreKey);

    if (!sessionRecord.isFresh()) sessionRecord.archiveCurrentState();

    RatchetingSession.initializeSession(sessionRecord.getSessionState(), parameters.create());

    sessionRecord.getSessionState().setUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.getSignedPreKeyId(), ourBaseKey.getPublicKey());
    sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
    sessionRecord.getSessionState().setRemoteRegistrationId(preKey.getRegistrationId());
    sessionRecord.getSessionState().setAliceBaseKey(ourBaseKey.getPublicKey().serialize());

    identityKeyStore.saveIdentity(remoteAddress, preKey.getIdentityKey());
    sessionStore.storeSession(remoteAddress, sessionRecord);
  }
}
 
Example #23
Source File: SignalIOCipherOmemoStore.java    From Zom-Android-XMPP with GNU General Public License v3.0 4 votes vote down vote up
@Override
public OmemoKeyUtil<IdentityKeyPair, IdentityKey, PreKeyRecord, SignedPreKeyRecord, SessionRecord, SignalProtocolAddress, ECPublicKey, PreKeyBundle, SessionCipher> keyUtil() {
    return new SignalOmemoKeyUtil();
}
 
Example #24
Source File: PushServiceSocket.java    From libsignal-service-java with GNU General Public License v3.0 4 votes vote down vote up
public List<PreKeyBundle> getPreKeys(SignalServiceAddress destination,
                                     Optional<UnidentifiedAccess> unidentifiedAccess,
                                     int deviceIdInteger)
    throws IOException
{
  try {
    String deviceId = String.valueOf(deviceIdInteger);

    if (deviceId.equals("1"))
      deviceId = "*";

    String path = String.format(PREKEY_DEVICE_PATH, destination.getIdentifier(), deviceId);

    if (destination.getRelay().isPresent()) {
      path = path + "?relay=" + destination.getRelay().get();
    }

    String             responseText = makeServiceRequest(path, "GET", null, NO_HEADERS, unidentifiedAccess);
    PreKeyResponse     response     = JsonUtil.fromJson(responseText, PreKeyResponse.class);
    List<PreKeyBundle> bundles      = new LinkedList<>();

    for (PreKeyResponseItem device : response.getDevices()) {
      ECPublicKey preKey                = null;
      ECPublicKey signedPreKey          = null;
      byte[]      signedPreKeySignature = null;
      int         preKeyId              = -1;
      int         signedPreKeyId        = -1;

      if (device.getSignedPreKey() != null) {
        signedPreKey          = device.getSignedPreKey().getPublicKey();
        signedPreKeyId        = device.getSignedPreKey().getKeyId();
        signedPreKeySignature = device.getSignedPreKey().getSignature();
      }

      if (device.getPreKey() != null) {
        preKeyId = device.getPreKey().getKeyId();
        preKey   = device.getPreKey().getPublicKey();
      }

      bundles.add(new PreKeyBundle(device.getRegistrationId(), device.getDeviceId(), preKeyId,
                                   preKey, signedPreKeyId, signedPreKey, signedPreKeySignature,
                                   response.getIdentityKey()));
    }

    return bundles;
  } catch (NotFoundException nfe) {
    throw new UnregisteredUserException(destination.getIdentifier(), nfe);
  }
}
 
Example #25
Source File: PushDecryptJob.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
private void handleCorruptMessage(@NonNull MasterSecretUnion masterSecret,
                                  @NonNull SignalServiceProtos.Envelope envelope) {
    ALog.i(TAG, "handleCorruptMessage");

    ThreadRepo threadRepo = repository.getThreadRepo();
    String dataJson = threadRepo.getDecryptFailData(envelope.getSource());
    DecryptFailData data;
    if (dataJson != null && !dataJson.isEmpty()) {
        data = GsonUtils.INSTANCE.fromJson(dataJson, DecryptFailData.class);
    } else {
        data = new DecryptFailData();
    }
    if (data.getLastDeleteSessionTime() + 50000 < System.currentTimeMillis()) {
        ALog.i(TAG, "Last delete session time is 5s ago. Delete Session.");
        SignalProtocolStore store = new SignalProtocolStoreImpl(context, accountContext);
        SignalProtocolAddress address = new SignalProtocolAddress(envelope.getSource(), SignalServiceAddress.DEFAULT_DEVICE_ID);
        if (store.containsSession(address)) {
            store.deleteSession(address);
        }
        try {
            Optional<String> relay = Optional.absent();
            if (envelope.hasRelay()) {
                relay = Optional.of(envelope.getRelay());
            }
            List<PreKeyBundle> preKeyBundles = ChatHttp.INSTANCE.get(accountContext).getPreKeys(new SignalServiceAddress(envelope.getSource(), relay), SignalServiceAddress.DEFAULT_DEVICE_ID);
            for (PreKeyBundle preKey : preKeyBundles) {

                String identityKeyString = new String(EncryptUtils.base64Encode(preKey.getIdentityKey().serialize()));
                if (!AddressUtil.INSTANCE.isValid(envelope.getSource(), identityKeyString)) {
                    ALog.e(TAG, "getPreKeys error identity key got");
                    continue;
                }

                SessionBuilder sessionBuilder = new SessionBuilder(store, new SignalProtocolAddress(envelope.getSource(), SignalServiceAddress.DEFAULT_DEVICE_ID));
                sessionBuilder.process(preKey);

            }
        } catch (Throwable ex) {
            ALog.w(TAG, "Untrusted identity key from handleMismatchedDevices");
        }
        data.setLastDeleteSessionTime(System.currentTimeMillis());
        threadRepo.setDecryptFailData(envelope.getSource(), data.toJson());
    }

    //If the decryption fails, do not insert the library, and send a new receipt directly
    long messageId = envelope.getTimestamp();
    Recipient recipient = Recipient.from(accountContext, envelope.getSource(), false);
    String message = new AmeGroupMessage<>(AmeGroupMessage.RECEIPT, new AmeGroupMessage.ReceiptContent(messageId)).toString();
    OutgoingLocationMessage outgoingLocationMessage = new OutgoingLocationMessage(recipient, message, 0);
    if (masterSecret.getMasterSecret().isPresent()) {
        long threadId = threadRepo.getThreadIdIfExist(recipient);
        MessageSender.sendHideMessage(AppContextHolder.APP_CONTEXT, threadId, accountContext, AmeGroupMessage.RECEIPT, outgoingLocationMessage);
    }
}
 
Example #26
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 2 votes vote down vote up
public void testSimultaneousInitiateRepeatedMessages()
    throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException,
    InvalidMessageException, DuplicateMessageException, LegacyMessageException,
    InvalidKeyIdException, NoSessionException
{
  SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
  SignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

  PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore);
  PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore);

  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);
  SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, ALICE_ADDRESS);

  SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

  aliceSessionBuilder.process(bobPreKeyBundle);
  bobSessionBuilder.process(alicePreKeyBundle);

  CiphertextMessage messageForBob   = aliceSessionCipher.encrypt("hey there".getBytes());
  CiphertextMessage messageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

  assertTrue(messageForBob.getType() == CiphertextMessage.PREKEY_TYPE);
  assertTrue(messageForAlice.getType() == CiphertextMessage.PREKEY_TYPE);

  assertFalse(isSessionIdEqual(aliceStore, bobStore));

  byte[] alicePlaintext = aliceSessionCipher.decrypt(new PreKeySignalMessage(messageForAlice.serialize()));
  byte[] bobPlaintext   = bobSessionCipher.decrypt(new PreKeySignalMessage(messageForBob.serialize()));

  assertTrue(new String(alicePlaintext).equals("sample message"));
  assertTrue(new String(bobPlaintext).equals("hey there"));

  assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);
  assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);

  assertFalse(isSessionIdEqual(aliceStore, bobStore));

  for (int i=0;i<50;i++) {
    CiphertextMessage messageForBobRepeat   = aliceSessionCipher.encrypt("hey there".getBytes());
    CiphertextMessage messageForAliceRepeat = bobSessionCipher.encrypt("sample message".getBytes());

    assertTrue(messageForBobRepeat.getType() == CiphertextMessage.WHISPER_TYPE);
    assertTrue(messageForAliceRepeat.getType() == CiphertextMessage.WHISPER_TYPE);

    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    byte[] alicePlaintextRepeat = aliceSessionCipher.decrypt(new SignalMessage(messageForAliceRepeat.serialize()));
    byte[] bobPlaintextRepeat   = bobSessionCipher.decrypt(new SignalMessage(messageForBobRepeat.serialize()));

    assertTrue(new String(alicePlaintextRepeat).equals("sample message"));
    assertTrue(new String(bobPlaintextRepeat).equals("hey there"));

    assertFalse(isSessionIdEqual(aliceStore, bobStore));
  }

  CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes());

  assertTrue(aliceResponse.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] responsePlaintext = bobSessionCipher.decrypt(new SignalMessage(aliceResponse.serialize()));

  assertTrue(new String(responsePlaintext).equals("second message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));

  CiphertextMessage finalMessage = bobSessionCipher.encrypt("third message".getBytes());

  assertTrue(finalMessage.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] finalPlaintext = aliceSessionCipher.decrypt(new SignalMessage(finalMessage.serialize()));

  assertTrue(new String(finalPlaintext).equals("third message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));
}
 
Example #27
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 2 votes vote down vote up
public void testRepeatedSimultaneousInitiateRepeatedMessages()
    throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException,
    InvalidMessageException, DuplicateMessageException, LegacyMessageException,
    InvalidKeyIdException, NoSessionException
{
  SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
  SignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();


  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);
  SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, ALICE_ADDRESS);

  SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

  for (int i=0;i<15;i++) {
    PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore);
    PreKeyBundle bobPreKeyBundle   = createBobPreKeyBundle(bobStore);

    aliceSessionBuilder.process(bobPreKeyBundle);
    bobSessionBuilder.process(alicePreKeyBundle);

    CiphertextMessage messageForBob = aliceSessionCipher.encrypt("hey there".getBytes());
    CiphertextMessage messageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

    assertTrue(messageForBob.getType() == CiphertextMessage.PREKEY_TYPE);
    assertTrue(messageForAlice.getType() == CiphertextMessage.PREKEY_TYPE);

    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    byte[] alicePlaintext = aliceSessionCipher.decrypt(new PreKeySignalMessage(messageForAlice.serialize()));
    byte[] bobPlaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(messageForBob.serialize()));

    assertTrue(new String(alicePlaintext).equals("sample message"));
    assertTrue(new String(bobPlaintext).equals("hey there"));

    assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);
    assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);

    assertFalse(isSessionIdEqual(aliceStore, bobStore));
  }

  for (int i=0;i<50;i++) {
    CiphertextMessage messageForBobRepeat   = aliceSessionCipher.encrypt("hey there".getBytes());
    CiphertextMessage messageForAliceRepeat = bobSessionCipher.encrypt("sample message".getBytes());

    assertTrue(messageForBobRepeat.getType() == CiphertextMessage.WHISPER_TYPE);
    assertTrue(messageForAliceRepeat.getType() == CiphertextMessage.WHISPER_TYPE);

    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    byte[] alicePlaintextRepeat = aliceSessionCipher.decrypt(new SignalMessage(messageForAliceRepeat.serialize()));
    byte[] bobPlaintextRepeat   = bobSessionCipher.decrypt(new SignalMessage(messageForBobRepeat.serialize()));

    assertTrue(new String(alicePlaintextRepeat).equals("sample message"));
    assertTrue(new String(bobPlaintextRepeat).equals("hey there"));

    assertFalse(isSessionIdEqual(aliceStore, bobStore));
  }

  CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes());

  assertTrue(aliceResponse.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] responsePlaintext = bobSessionCipher.decrypt(new SignalMessage(aliceResponse.serialize()));

  assertTrue(new String(responsePlaintext).equals("second message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));

  CiphertextMessage finalMessage = bobSessionCipher.encrypt("third message".getBytes());

  assertTrue(finalMessage.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] finalPlaintext = aliceSessionCipher.decrypt(new SignalMessage(finalMessage.serialize()));

  assertTrue(new String(finalPlaintext).equals("third message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));
}
 
Example #28
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 2 votes vote down vote up
public void testRepeatedSimultaneousInitiateLostMessageRepeatedMessages()
      throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException,
      InvalidMessageException, DuplicateMessageException, LegacyMessageException,
      InvalidKeyIdException, NoSessionException
  {
    SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
    SignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();


    SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);
    SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, ALICE_ADDRESS);

    SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
    SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

//    PreKeyBundle aliceLostPreKeyBundle = createAlicePreKeyBundle(aliceStore);
    PreKeyBundle bobLostPreKeyBundle   = createBobPreKeyBundle(bobStore);

    aliceSessionBuilder.process(bobLostPreKeyBundle);
//    bobSessionBuilder.process(aliceLostPreKeyBundle);

    CiphertextMessage lostMessageForBob   = aliceSessionCipher.encrypt("hey there".getBytes());
//    CiphertextMessage lostMessageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

    for (int i=0;i<15;i++) {
      PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore);
      PreKeyBundle bobPreKeyBundle   = createBobPreKeyBundle(bobStore);

      aliceSessionBuilder.process(bobPreKeyBundle);
      bobSessionBuilder.process(alicePreKeyBundle);

      CiphertextMessage messageForBob = aliceSessionCipher.encrypt("hey there".getBytes());
      CiphertextMessage messageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

      assertTrue(messageForBob.getType() == CiphertextMessage.PREKEY_TYPE);
      assertTrue(messageForAlice.getType() == CiphertextMessage.PREKEY_TYPE);

      assertFalse(isSessionIdEqual(aliceStore, bobStore));

      byte[] alicePlaintext = aliceSessionCipher.decrypt(new PreKeySignalMessage(messageForAlice.serialize()));
      byte[] bobPlaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(messageForBob.serialize()));

      assertTrue(new String(alicePlaintext).equals("sample message"));
      assertTrue(new String(bobPlaintext).equals("hey there"));

      assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);
      assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);

      assertFalse(isSessionIdEqual(aliceStore, bobStore));
    }

    for (int i=0;i<50;i++) {
      CiphertextMessage messageForBobRepeat   = aliceSessionCipher.encrypt("hey there".getBytes());
      CiphertextMessage messageForAliceRepeat = bobSessionCipher.encrypt("sample message".getBytes());

      assertTrue(messageForBobRepeat.getType() == CiphertextMessage.WHISPER_TYPE);
      assertTrue(messageForAliceRepeat.getType() == CiphertextMessage.WHISPER_TYPE);

      assertFalse(isSessionIdEqual(aliceStore, bobStore));

      byte[] alicePlaintextRepeat = aliceSessionCipher.decrypt(new SignalMessage(messageForAliceRepeat.serialize()));
      byte[] bobPlaintextRepeat   = bobSessionCipher.decrypt(new SignalMessage(messageForBobRepeat.serialize()));

      assertTrue(new String(alicePlaintextRepeat).equals("sample message"));
      assertTrue(new String(bobPlaintextRepeat).equals("hey there"));

      assertFalse(isSessionIdEqual(aliceStore, bobStore));
    }

    CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes());

    assertTrue(aliceResponse.getType() == CiphertextMessage.WHISPER_TYPE);

    byte[] responsePlaintext = bobSessionCipher.decrypt(new SignalMessage(aliceResponse.serialize()));

    assertTrue(new String(responsePlaintext).equals("second message"));
    assertTrue(isSessionIdEqual(aliceStore, bobStore));

    CiphertextMessage finalMessage = bobSessionCipher.encrypt("third message".getBytes());

    assertTrue(finalMessage.getType() == CiphertextMessage.WHISPER_TYPE);

    byte[] finalPlaintext = aliceSessionCipher.decrypt(new SignalMessage(finalMessage.serialize()));

    assertTrue(new String(finalPlaintext).equals("third message"));
    assertTrue(isSessionIdEqual(aliceStore, bobStore));

    byte[] lostMessagePlaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(lostMessageForBob.serialize()));
    assertTrue(new String(lostMessagePlaintext).equals("hey there"));

    assertFalse(isSessionIdEqual(aliceStore, bobStore));

    CiphertextMessage blastFromThePast          = bobSessionCipher.encrypt("unexpected!".getBytes());
    byte[]            blastFromThePastPlaintext = aliceSessionCipher.decrypt(new SignalMessage(blastFromThePast.serialize()));

    assertTrue(new String(blastFromThePastPlaintext).equals("unexpected!"));
    assertTrue(isSessionIdEqual(aliceStore, bobStore));
  }
 
Example #29
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 2 votes vote down vote up
public void testLostSimultaneousInitiate() throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException, InvalidMessageException, DuplicateMessageException, LegacyMessageException, InvalidKeyIdException, NoSessionException {
  SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
  SignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

  PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore);
  PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore);

  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);
  SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, ALICE_ADDRESS);

  SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

  aliceSessionBuilder.process(bobPreKeyBundle);
  bobSessionBuilder.process(alicePreKeyBundle);

  CiphertextMessage messageForBob   = aliceSessionCipher.encrypt("hey there".getBytes());
  CiphertextMessage messageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

  assertTrue(messageForBob.getType() == CiphertextMessage.PREKEY_TYPE);
  assertTrue(messageForAlice.getType() == CiphertextMessage.PREKEY_TYPE);

  assertFalse(isSessionIdEqual(aliceStore, bobStore));

  byte[] bobPlaintext   = bobSessionCipher.decrypt(new PreKeySignalMessage(messageForBob.serialize()));

  assertTrue(new String(bobPlaintext).equals("hey there"));
  assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);

  CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes());

  assertTrue(aliceResponse.getType() == CiphertextMessage.PREKEY_TYPE);

  byte[] responsePlaintext = bobSessionCipher.decrypt(new PreKeySignalMessage(aliceResponse.serialize()));

  assertTrue(new String(responsePlaintext).equals("second message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));

  CiphertextMessage finalMessage = bobSessionCipher.encrypt("third message".getBytes());

  assertTrue(finalMessage.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] finalPlaintext = aliceSessionCipher.decrypt(new SignalMessage(finalMessage.serialize()));

  assertTrue(new String(finalPlaintext).equals("third message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));
}
 
Example #30
Source File: SimultaneousInitiateTests.java    From libsignal-protocol-java with GNU General Public License v3.0 2 votes vote down vote up
public void testBasicSimultaneousInitiate()
    throws InvalidKeyException, UntrustedIdentityException, InvalidVersionException,
    InvalidMessageException, DuplicateMessageException, LegacyMessageException,
    InvalidKeyIdException, NoSessionException
{
  SignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
  SignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

  PreKeyBundle alicePreKeyBundle = createAlicePreKeyBundle(aliceStore);
  PreKeyBundle bobPreKeyBundle = createBobPreKeyBundle(bobStore);

  SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BOB_ADDRESS);
  SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, ALICE_ADDRESS);

  SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BOB_ADDRESS);
  SessionCipher bobSessionCipher = new SessionCipher(bobStore, ALICE_ADDRESS);

  aliceSessionBuilder.process(bobPreKeyBundle);
  bobSessionBuilder.process(alicePreKeyBundle);

  CiphertextMessage messageForBob   = aliceSessionCipher.encrypt("hey there".getBytes());
  CiphertextMessage messageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

  assertTrue(messageForBob.getType() == CiphertextMessage.PREKEY_TYPE);
  assertTrue(messageForAlice.getType() == CiphertextMessage.PREKEY_TYPE);

  assertFalse(isSessionIdEqual(aliceStore, bobStore));

  byte[] alicePlaintext = aliceSessionCipher.decrypt(new PreKeySignalMessage(messageForAlice.serialize()));
  byte[] bobPlaintext   = bobSessionCipher.decrypt(new PreKeySignalMessage(messageForBob.serialize()));

  assertTrue(new String(alicePlaintext).equals("sample message"));
  assertTrue(new String(bobPlaintext).equals("hey there"));

  assertTrue(aliceStore.loadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);
  assertTrue(bobStore.loadSession(ALICE_ADDRESS).getSessionState().getSessionVersion() == 3);

  assertFalse(isSessionIdEqual(aliceStore, bobStore));

  CiphertextMessage aliceResponse = aliceSessionCipher.encrypt("second message".getBytes());

  assertTrue(aliceResponse.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] responsePlaintext = bobSessionCipher.decrypt(new SignalMessage(aliceResponse.serialize()));

  assertTrue(new String(responsePlaintext).equals("second message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));

  CiphertextMessage finalMessage = bobSessionCipher.encrypt("third message".getBytes());

  assertTrue(finalMessage.getType() == CiphertextMessage.WHISPER_TYPE);

  byte[] finalPlaintext = aliceSessionCipher.decrypt(new SignalMessage(finalMessage.serialize()));

  assertTrue(new String(finalPlaintext).equals("third message"));
  assertTrue(isSessionIdEqual(aliceStore, bobStore));
}