All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.whispersystems.libaxolotl.state.SessionState Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2014 Open Whisper Systems
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

package org.whispersystems.libaxolotl.state;


import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.whispersystems.libaxolotl.IdentityKey;
import org.whispersystems.libaxolotl.IdentityKeyPair;
import org.whispersystems.libaxolotl.InvalidKeyException;
import org.whispersystems.libaxolotl.ecc.Curve;
import org.whispersystems.libaxolotl.ecc.ECKeyPair;
import org.whispersystems.libaxolotl.ecc.ECPrivateKey;
import org.whispersystems.libaxolotl.ecc.ECPublicKey;
import org.whispersystems.libaxolotl.kdf.HKDF;
import org.whispersystems.libaxolotl.logging.Log;
import org.whispersystems.libaxolotl.ratchet.ChainKey;
import org.whispersystems.libaxolotl.ratchet.MessageKeys;
import org.whispersystems.libaxolotl.ratchet.RootKey;
import org.whispersystems.libaxolotl.state.protos.SessionStructure;
import org.whispersystems.libaxolotl.j2me.AssertionError;
import org.whispersystems.libaxolotl.util.Pair;
import org.whispersystems.libaxolotl.util.guava.Optional;

import java.util.Vector;

public class SessionState {

  private SessionStructure sessionStructure;

  public SessionState() {
    this.sessionStructure = new SessionStructure();
  }

  public SessionState(SessionStructure sessionStructure) {
    this.sessionStructure = sessionStructure;
  }

  public SessionState(SessionState copy) {
    this.sessionStructure = SessionStructure.fromBytes(copy.sessionStructure.toBytes());
  }

  public SessionStructure getStructure() {
    return sessionStructure;
  }

  public byte[] getAliceBaseKey() {
    return this.sessionStructure.getAlicebasekey();
  }

  public void setAliceBaseKey(byte[] aliceBaseKey) {
    this.sessionStructure.setAlicebasekey(aliceBaseKey);
  }

  public void setSessionVersion(int version) {
    this.sessionStructure.setSessionversion(version);;
  }

  public int getSessionVersion() {
    int sessionVersion = this.sessionStructure.getSessionversion();

    if (sessionVersion == 0) return 2;
    else                     return sessionVersion;
  }

  public void setRemoteIdentityKey(IdentityKey identityKey) {
    this.sessionStructure.setRemoteidentitypublic(identityKey.serialize());
  }

  public void setLocalIdentityKey(IdentityKey identityKey) {
    this.sessionStructure.setLocalidentitypublic(identityKey.serialize());
  }

  public IdentityKey getRemoteIdentityKey() {
    try {
      if (this.sessionStructure.getRemoteidentitypublic() == null) {
        return null;
      }

      return new IdentityKey(this.sessionStructure.getRemoteidentitypublic(), 0);
    } catch (InvalidKeyException e) {
      Log.w("SessionRecordV2", e);
      return null;
    }
  }

  public IdentityKey getLocalIdentityKey() {
    try {
      return new IdentityKey(this.sessionStructure.getLocalidentitypublic(), 0);
    } catch (InvalidKeyException e) {
      throw new AssertionError(e);
    }
  }

  public int getPreviousCounter() {
    return sessionStructure.getPreviouscounter();
  }

  public void setPreviousCounter(int previousCounter) {
    this.sessionStructure.setPreviouscounter(previousCounter);
  }

  public RootKey getRootKey() {
    return new RootKey(HKDF.createFor(getSessionVersion()),
                       this.sessionStructure.getRootkey());
  }

  public void setRootKey(RootKey rootKey) {
    this.sessionStructure.setRootkey(rootKey.getKeyBytes());
  }

  public ECPublicKey getSenderRatchetKey() {
    try {
      return Curve.decodePoint(sessionStructure.getSenderchain().getSenderratchetkey(), 0);
    } catch (InvalidKeyException e) {
      throw new AssertionError(e);
    }
  }

  public ECKeyPair getSenderRatchetKeyPair() {
    ECPublicKey  publicKey  = getSenderRatchetKey();
    ECPrivateKey privateKey = Curve.decodePrivatePoint(sessionStructure.getSenderchain()
                                                                       .getSenderratchetkeyprivate());

    return new ECKeyPair(publicKey, privateKey);
  }

  public boolean hasReceiverChain(ECPublicKey senderEphemeral) {
    return getReceiverChain(senderEphemeral) != null;
  }

  public boolean hasSenderChain() {
    return sessionStructure.hasSenderchain();
  }

  private Pair getReceiverChain(ECPublicKey senderEphemeral) {
    Vector receiverChains = sessionStructure.getReceiverchainsVector();
    int    index          = 0;

    for (int i=0;i 5) {
      this.sessionStructure.getReceiverchainsVector().removeElementAt(0);
    }
  }

  public void setSenderChain(ECKeyPair senderRatchetKeyPair, ChainKey chainKey) {
    SessionStructure.Chain.ChainKey chainKeyStructure = new SessionStructure.Chain.ChainKey();
    chainKeyStructure.setKey(chainKey.getKey());
    chainKeyStructure.setIndex(chainKey.getIndex());

    SessionStructure.Chain senderChain = new SessionStructure.Chain();
    senderChain.setSenderratchetkey(senderRatchetKeyPair.getPublicKey().serialize());
    senderChain.setSenderratchetkeyprivate(senderRatchetKeyPair.getPrivateKey().serialize());
    senderChain.setChainkey(chainKeyStructure);

    this.sessionStructure.setSenderchain(senderChain);
  }

  public ChainKey getSenderChainKey() {
    SessionStructure.Chain.ChainKey chainKeyStructure = sessionStructure.getSenderchain().getChainkey();
    return new ChainKey(HKDF.createFor(getSessionVersion()),
                        chainKeyStructure.getKey(), chainKeyStructure.getIndex());
  }


  public void setSenderChainKey(ChainKey nextChainKey) {
    SessionStructure.Chain.ChainKey chainKey = new SessionStructure.Chain.ChainKey();
    chainKey.setKey(nextChainKey.getKey());
    chainKey.setIndex(nextChainKey.getIndex());

    sessionStructure.getSenderchain().setChainkey(chainKey);
  }

  public boolean hasMessageKeys(ECPublicKey senderEphemeral, int counter) {
    Pair                   chainAndIndex = getReceiverChain(senderEphemeral);
    SessionStructure.Chain chain         = (SessionStructure.Chain) chainAndIndex.first();

    if (chain == null) {
      return false;
    }

    Vector messageKeyList = chain.getMessagekeysVector();

    for (int i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy