Example #1
0
  /**
   * Takes a byte array containing serialized and concatenated MPIs and converts it to an array of
   * MPIs. The buffer is assumed to consist of a 4-byte int containing the number of MPIs in the
   * array, followed by {size, data} pairs for each MPI.
   *
   * @throws OTRException
   */
  public static MPI[] unserializeMPIArray(byte[] buffer) throws OTRException {
    InBuf ibuf = new InBuf(buffer);

    int count = (int) ibuf.readUInt();

    if (count <= 0) throw new OTRException("Invalid count");

    MPI[] mpis = new MPI[count];

    for (int i = 0; i < count; i++) {
      mpis[i] = MPI.readMPI(ibuf);
    }

    return mpis;
  }
Example #2
0
  /** Hash one or two MPIs. To hash only one MPI, b may be set to NULL. */
  public static MPI hash(int version, MPI a, MPI b, Provider prov) throws OTRException {
    int totalsize = 1 + 4 + a.getLength();
    if (b != null) {
      totalsize += 4 + b.getLength();
    }
    byte[] buf = new byte[totalsize];
    OutBuf obuf = new OutBuf(buf);

    obuf.writeByte((byte) version);
    obuf.writeUInt(a.getLength());
    a.writeRaw(obuf);

    if (b != null) {
      obuf.writeUInt(b.getLength());
      b.writeRaw(obuf);
    }
    byte[] out = obuf.getBytes();
    SHA256 sha = prov.getSHA256();
    byte[] digest = sha.hash(out);
    return new MPI(digest);
  }
Example #3
0
  void goEncrypted(OTRCallbacks callback) throws OTRException {

    // See if we're talking to ourselves
    byte[] theiry = auth.their_pub.serialize();
    byte[] their_trim = new byte[theiry.length - 4];
    System.arraycopy(theiry, 4, their_trim, 0, their_trim.length);
    byte[] oury = auth.our_dh.getPublicKey().serialize();
    byte[] our_trim = new byte[oury.length - 4];
    System.arraycopy(oury, 4, our_trim, 0, our_trim.length);

    if (prov.compareMPI(new MPI(their_trim), new MPI(our_trim)) == 0) {
      // Yes, we are.
      callback.handleMsgEvent(OTRCallbacks.OTRL_MSGEVENT_MSG_REFLECTED, this, null);
      throw new OTRException("Message reflected");
    }

    // Find the fingerprint
    FingerPrint found_print = this.findFingerPrint(auth.their_fingerprint, true, callback);

    /* Is this a new session or just a refresh of an existing one? */
    if (this.msgState.getCurState() == MsgState.ST_ENCRYPTED
        && Util.arrayEquals(this.activeFingerprint.fingerPrint, found_print.fingerPrint)
        && this.our_keyid - 1 == this.auth.our_keyid
        && prov.compareMPI(
                MPI.readMPI(new InBuf(this.our_old_dh_key.getPublicKey().serialize())),
                MPI.readMPI(new InBuf(this.auth.our_dh.getPublicKey().serialize())))
            == 0
        && ((this.their_keyid > 0
                && this.their_keyid == auth.their_keyid
                && prov.compareMPI(
                        MPI.readMPI(new InBuf(this.their_y.serialize())),
                        MPI.readMPI(new InBuf(this.auth.their_pub.serialize())))
                    == 0)
            || (this.their_keyid > 1
                && this.their_keyid - 1 == this.auth.their_keyid
                && this.their_old_y != null
                && prov.compareMPI(
                        MPI.readMPI(new InBuf(this.their_y.serialize())),
                        MPI.readMPI(new InBuf(this.auth.their_pub.serialize())))
                    == 0))) {
      /* This is just a refresh of the existing session. */
      callback.stillSecure(this, auth.initiated);
      ignore_message = 1;
      return;
    }

    // Copy the information from the auth into the context
    System.arraycopy(auth.secure_session_id, 0, this.sessionId, 0, 20);
    this.sessionid_len = auth.sessionid_len;

    // Copy the keys
    this.their_keyid = auth.their_keyid;
    this.their_y = auth.their_pub;
    this.their_old_y = null;

    if (our_keyid - 1 != auth.our_keyid) {
      this.our_old_dh_key = auth.our_dh;
      this.our_dh_key = prov.getDHKeyPairGenerator().generateKeyPair();
      this.our_keyid = auth.our_keyid + 1;
    }

    // Create the session keys from the DH keys
    this.sesskeys[0][0] = new DHSesskeys(prov);
    this.sesskeys[1][0] = new DHSesskeys(prov);
    this.sesskeys[0][0].computeSession(this.our_dh_key, this.their_y);
    this.sesskeys[1][0].computeSession(this.our_old_dh_key, this.their_y);

    this.generation++;
    this.activeFingerprint = found_print;
    int oldstate = msgState.getCurState();
    msgState.processEvent(MsgState.EVT_AUTHENTICATED);
    callback.updateContextList();
    if (oldstate == MsgState.ST_ENCRYPTED
        && Util.arrayEquals(this.activeFingerprint.fingerPrint, found_print.fingerPrint)) {
      callback.stillSecure(this, this.auth.initiated);
    } else {
      callback.goneSecure(this);
    }
    this.gone_encrypted = 1;
  }