Java Code Examples for org.whispersystems.libsignal.state.SessionRecord#archiveCurrentState()

The following examples show how to use org.whispersystems.libsignal.state.SessionRecord#archiveCurrentState() . 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: IdentityUtil.java    From mollyim-android with GNU General Public License v3.0 6 votes vote down vote up
public static void saveIdentity(Context context, String user, IdentityKey identityKey) {
  synchronized (SESSION_LOCK) {
    IdentityKeyStore      identityKeyStore = new TextSecureIdentityKeyStore(context);
    SessionStore          sessionStore     = new TextSecureSessionStore(context);
    SignalProtocolAddress address          = new SignalProtocolAddress(user, 1);

    if (identityKeyStore.saveIdentity(address, identityKey)) {
      if (sessionStore.containsSession(address)) {
        SessionRecord sessionRecord = sessionStore.loadSession(address);
        sessionRecord.archiveCurrentState();

        sessionStore.storeSession(address, sessionRecord);
      }
    }
  }
}
 
Example 2
Source File: IdentityUtil.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public static void saveIdentity(Context context, AccountContext accountContext, String number, IdentityKey identityKey, boolean nonBlockingApproval) {
    synchronized (SESSION_LOCK) {
        TextSecureIdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, accountContext);
        SessionStore sessionStore = new TextSecureSessionStore(context, accountContext);
        SignalProtocolAddress address = new SignalProtocolAddress(number, 1);

        if (identityKeyStore.saveIdentity(address, identityKey, nonBlockingApproval)) {
            if (sessionStore.containsSession(address)) {
                SessionRecord sessionRecord = sessionStore.loadSession(address);
                sessionRecord.archiveCurrentState();

                sessionStore.storeSession(address, sessionRecord);
            }
        }
    }
}
 
Example 3
Source File: IdentityUtil.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public static void saveIdentity(Context context, AccountContext accountContext, String number, IdentityKey identityKey) {
    synchronized (SESSION_LOCK) {
        IdentityKeyStore identityKeyStore = new TextSecureIdentityKeyStore(context, accountContext);
        SessionStore sessionStore = new TextSecureSessionStore(context, accountContext);
        SignalProtocolAddress address = new SignalProtocolAddress(number, 1);

        if (identityKeyStore.saveIdentity(address, identityKey)) {
            if (sessionStore.containsSession(address)) {
                SessionRecord sessionRecord = sessionStore.loadSession(address);
                sessionRecord.archiveCurrentState();

                sessionStore.storeSession(address, sessionRecord);
            }
        }
    }
}
 
Example 4
Source File: SessionUtil.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public static void archiveSiblingSessions(Context context, AccountContext accountContext, SignalProtocolAddress address) {
    SessionStore sessionStore = new TextSecureSessionStore(context, accountContext);
    List<Integer> devices = sessionStore.getSubDeviceSessions(address.getName());
    devices.add(1);

    for (int device : devices) {
        if (device != address.getDeviceId()) {
            SignalProtocolAddress sibling = new SignalProtocolAddress(address.getName(), device);

            if (sessionStore.containsSession(sibling)) {
                SessionRecord sessionRecord = sessionStore.loadSession(sibling);
                sessionRecord.archiveCurrentState();
                sessionStore.storeSession(sibling, sessionRecord);
            }
        }
    }
}
 
Example 5
Source File: TextSecureSessionStore.java    From bcm-android with GNU General Public License v3.0 6 votes vote down vote up
public void archiveAllSessions() {
    synchronized (FILE_LOCK) {
        File directory = getSessionDirectory();

        for (File session : directory.listFiles()) {
            if (session.isFile()) {
                SignalProtocolAddress address = getAddressName(session);

                if (address != null) {
                    SessionRecord sessionRecord = loadSession(address);
                    sessionRecord.archiveCurrentState();
                    storeSession(address, sessionRecord);
                }
            }
        }
    }
}
 
Example 6
Source File: SessionBuilder.java    From Silence with GNU General Public License v3.0 5 votes vote down vote up
private Optional<Integer> processV3(SessionRecord sessionRecord, PreKeySignalMessage message)
    throws UntrustedIdentityException, InvalidKeyIdException, InvalidKeyException
{

  if (sessionRecord.hasSessionState(message.getMessageVersion(), message.getBaseKey().serialize())) {
    Log.w(TAG, "We've already setup a session for this V3 message, letting bundled message fall through...");
    return Optional.absent();
  }

  ECKeyPair ourSignedPreKey = signedPreKeyStore.loadSignedPreKey(message.getSignedPreKeyId()).getKeyPair();

  BobSignalProtocolParameters.Builder parameters = BobSignalProtocolParameters.newBuilder();

  parameters.setTheirBaseKey(message.getBaseKey())
            .setTheirIdentityKey(message.getIdentityKey())
            .setOurIdentityKey(identityKeyStore.getIdentityKeyPair())
            .setOurSignedPreKey(ourSignedPreKey)
            .setOurRatchetKey(ourSignedPreKey);

  if (message.getPreKeyId().isPresent()) {
    parameters.setOurOneTimePreKey(Optional.of(preKeyStore.loadPreKey(message.getPreKeyId().get()).getKeyPair()));
  } else {
    parameters.setOurOneTimePreKey(Optional.<ECKeyPair>absent());
  }

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

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

  sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
  sessionRecord.getSessionState().setRemoteRegistrationId(message.getRegistrationId());
  sessionRecord.getSessionState().setAliceBaseKey(message.getBaseKey().serialize());

  if (message.getPreKeyId().isPresent() && message.getPreKeyId().get() != Medium.MAX_VALUE) {
    return message.getPreKeyId();
  } else {
    return Optional.absent();
  }
}
 
Example 7
Source File: SessionBuilder.java    From Silence with GNU General Public License v3.0 5 votes vote down vote up
private void processResponse(KeyExchangeMessage message)
    throws StaleKeyExchangeException, InvalidKeyException
{
  SessionRecord sessionRecord                  = sessionStore.loadSession(remoteAddress);
  SessionState  sessionState                   = sessionRecord.getSessionState();
  boolean       hasPendingKeyExchange          = sessionState.hasPendingKeyExchange();
  boolean       isSimultaneousInitiateResponse = message.isResponseForSimultaneousInitiate();

  if (!hasPendingKeyExchange || sessionState.getPendingKeyExchangeSequence() != message.getSequence()) {
    Log.w(TAG, "No matching sequence for response. Is simultaneous initiate response: " + isSimultaneousInitiateResponse);
    if (!isSimultaneousInitiateResponse) throw new StaleKeyExchangeException();
    else                                 return;
  }

  SymmetricSignalProtocolParameters.Builder parameters = SymmetricSignalProtocolParameters.newBuilder();

  parameters.setOurBaseKey(sessionRecord.getSessionState().getPendingKeyExchangeBaseKey())
            .setOurRatchetKey(sessionRecord.getSessionState().getPendingKeyExchangeRatchetKey())
            .setOurIdentityKey(sessionRecord.getSessionState().getPendingKeyExchangeIdentityKey())
            .setTheirBaseKey(message.getBaseKey())
            .setTheirRatchetKey(message.getRatchetKey())
            .setTheirIdentityKey(message.getIdentityKey());

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

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

  if (!Curve.verifySignature(message.getIdentityKey().getPublicKey(),
                             message.getBaseKey().serialize(),
                             message.getBaseKeySignature()))
  {
    throw new InvalidKeyException("Base key signature doesn't match!");
  }

  identityKeyStore.saveIdentity(remoteAddress, message.getIdentityKey());
  sessionStore.storeSession(remoteAddress, sessionRecord);
}
 
Example 8
Source File: SessionBuilder.java    From libsignal-protocol-java with GNU General Public License v3.0 5 votes vote down vote up
private Optional<Integer> processV3(SessionRecord sessionRecord, PreKeySignalMessage message)
    throws UntrustedIdentityException, InvalidKeyIdException, InvalidKeyException
{

  if (sessionRecord.hasSessionState(message.getMessageVersion(), message.getBaseKey().serialize())) {
    Log.w(TAG, "We've already setup a session for this V3 message, letting bundled message fall through...");
    return Optional.absent();
  }

  ECKeyPair ourSignedPreKey = signedPreKeyStore.loadSignedPreKey(message.getSignedPreKeyId()).getKeyPair();

  BobSignalProtocolParameters.Builder parameters = BobSignalProtocolParameters.newBuilder();

  parameters.setTheirBaseKey(message.getBaseKey())
            .setTheirIdentityKey(message.getIdentityKey())
            .setOurIdentityKey(identityKeyStore.getIdentityKeyPair())
            .setOurSignedPreKey(ourSignedPreKey)
            .setOurRatchetKey(ourSignedPreKey);

  if (message.getPreKeyId().isPresent()) {
    parameters.setOurOneTimePreKey(Optional.of(preKeyStore.loadPreKey(message.getPreKeyId().get()).getKeyPair()));
  } else {
    parameters.setOurOneTimePreKey(Optional.<ECKeyPair>absent());
  }

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

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

  sessionRecord.getSessionState().setLocalRegistrationId(identityKeyStore.getLocalRegistrationId());
  sessionRecord.getSessionState().setRemoteRegistrationId(message.getRegistrationId());
  sessionRecord.getSessionState().setAliceBaseKey(message.getBaseKey().serialize());

  if (message.getPreKeyId().isPresent()) {
    return message.getPreKeyId();
  } else {
    return Optional.absent();
  }
}
 
Example 9
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 10
Source File: SessionBuilder.java    From Silence with GNU General Public License v3.0 4 votes vote down vote up
private KeyExchangeMessage processInitiate(KeyExchangeMessage message) throws InvalidKeyException {
  int           flags         = KeyExchangeMessage.RESPONSE_FLAG;
  SessionRecord sessionRecord = sessionStore.loadSession(remoteAddress);

  if (!Curve.verifySignature(message.getIdentityKey().getPublicKey(),
                             message.getBaseKey().serialize(),
                             message.getBaseKeySignature()))
  {
    throw new InvalidKeyException("Bad signature!");
  }

  SymmetricSignalProtocolParameters.Builder builder = SymmetricSignalProtocolParameters.newBuilder();

  if (!sessionRecord.getSessionState().hasPendingKeyExchange()) {
    builder.setOurIdentityKey(identityKeyStore.getIdentityKeyPair())
           .setOurBaseKey(Curve.generateKeyPair())
           .setOurRatchetKey(Curve.generateKeyPair());
  } else {
    builder.setOurIdentityKey(sessionRecord.getSessionState().getPendingKeyExchangeIdentityKey())
           .setOurBaseKey(sessionRecord.getSessionState().getPendingKeyExchangeBaseKey())
           .setOurRatchetKey(sessionRecord.getSessionState().getPendingKeyExchangeRatchetKey());
    flags |= KeyExchangeMessage.SIMULTAENOUS_INITIATE_FLAG;
  }

  builder.setTheirBaseKey(message.getBaseKey())
         .setTheirRatchetKey(message.getRatchetKey())
         .setTheirIdentityKey(message.getIdentityKey());

  SymmetricSignalProtocolParameters parameters = builder.create();

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

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

  identityKeyStore.saveIdentity(remoteAddress, message.getIdentityKey());
  sessionStore.storeSession(remoteAddress, sessionRecord);

  byte[] baseKeySignature = Curve.calculateSignature(parameters.getOurIdentityKey().getPrivateKey(),
                                                     parameters.getOurBaseKey().getPublicKey().serialize());

  return new KeyExchangeMessage(sessionRecord.getSessionState().getSessionVersion(),
                                message.getSequence(), flags,
                                parameters.getOurBaseKey().getPublicKey(),
                                baseKeySignature, parameters.getOurRatchetKey().getPublicKey(),
                                parameters.getOurIdentityKey().getPublicKey());
}
 
Example 11
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);
  }
}