public List<TLV> initRespondSmp(String question,String secret,boolean initiating) throws OtrException {
  if (question != null && !initiating)   throw new IllegalArgumentException("Only supply a question if initiating");
  byte[] our_fp=Hex.decode(keyManager.getLocalFingerprint(sessionID));
  String remoteFingerprint=keyManager.getRemoteFingerprint(sessionID);
  if (remoteFingerprint == null)   throw new OtrException("no fingerprint for remote user");
  byte[] their_fp=Hex.decode(remoteFingerprint);
  byte[] sessionId;
  try {
    sessionId=computeSessionId(session.getS());
  }
 catch (  SMException ex) {
    throw new OtrException(ex);
  }
  byte[] bytes=secret.getBytes(SerializationUtils.UTF8);
  int combined_buf_len=41 + sessionId.length + bytes.length;
  byte[] combined_buf=new byte[combined_buf_len];
  combined_buf[0]=1;
  if (initiating) {
    System.arraycopy(our_fp,0,combined_buf,1,20);
    System.arraycopy(their_fp,0,combined_buf,21,20);
  }
 else {
    System.arraycopy(their_fp,0,combined_buf,1,20);
    System.arraycopy(our_fp,0,combined_buf,21,20);
  }
  System.arraycopy(sessionId,0,combined_buf,41,sessionId.length);
  System.arraycopy(bytes,0,combined_buf,41 + sessionId.length,bytes.length);
  MessageDigest sha256;
  try {
    sha256=MessageDigest.getInstance("SHA-256");
  }
 catch (  NoSuchAlgorithmException ex) {
    throw new OtrException(ex);
  }
  byte[] combined_secret=sha256.digest(combined_buf);
  byte[] smpmsg;
  try {
    if (initiating) {
      smpmsg=SM.step1(smstate,combined_secret);
    }
 else {
      smpmsg=SM.step2b(smstate,combined_secret);
    }
  }
 catch (  SMException ex) {
    throw new OtrException(ex);
  }
  if (question != null) {
    bytes=question.getBytes(SerializationUtils.UTF8);
    byte[] qsmpmsg=new byte[bytes.length + 1 + smpmsg.length];
    System.arraycopy(bytes,0,qsmpmsg,0,bytes.length);
    System.arraycopy(smpmsg,0,qsmpmsg,bytes.length + 1,smpmsg.length);
    smpmsg=qsmpmsg;
  }
  TLV sendtlv=new TLV(initiating ? (question != null ? TLV.SMP1Q : TLV.SMP1) : TLV.SMP2,smpmsg);
  smstate.nextExpected=initiating ? SM.EXPECT2 : SM.EXPECT3;
  return makeTlvList(sendtlv);
}

public List < TLV > initRespondSmp ( String question , String secret , boolean initiating ) throws OtrException { if ( question != null && ! initiating ) throw new IllegalArgumentException ( "Only supply a question if initiating" ) ; byte [ ] our_fp = Hex . decode ( keyManager . getLocalFingerprint ( sessionID ) ) ; String remoteFingerprint = keyManager . getRemoteFingerprint ( sessionID ) ; if ( remoteFingerprint == null ) throw new OtrException ( "no fingerprint for remote user" ) ; byte [ ] their_fp = Hex . decode ( remoteFingerprint ) ; byte [ ] sessionId ; try { sessionId = computeSessionId ( session . getS ( ) ) ; } catch ( SMException ex ) { throw new OtrException ( ex ) ; } byte [ ] bytes = secret . getBytes ( SerializationUtils . UTF8 ) ; int combined_buf_len = 41 + sessionId . length + bytes . length ; byte [ ] combined_buf = new byte [ combined_buf_len ] ; combined_buf [ 0 ] = 1 ; if ( initiating ) { System . arraycopy ( our_fp , 0 , combined_buf , 1 , 20 ) ; System . arraycopy ( their_fp , 0 , combined_buf , 21 , 20 ) ; } else { System . arraycopy ( their_fp , 0 , combined_buf , 1 , 20 ) ; System . arraycopy ( our_fp , 0 , combined_buf , 21 , 20 ) ; } System . arraycopy ( sessionId , 0 , combined_buf , 41 , sessionId . length ) ; System . arraycopy ( bytes , 0 , combined_buf , 41 + sessionId . length , bytes . length ) ; MessageDigest sha256 ; try { sha256 = MessageDigest . getInstance ( "SHA-256" ) ; } catch ( NoSuchAlgorithmException ex ) { throw new OtrException ( ex ) ; } byte [ ] combined_secret = sha256 . digest ( combined_buf ) ; byte [ ] smpmsg ; try { if ( initiating ) { smpmsg = SM . step1 ( smstate , combined_secret ) ; } else { smpmsg = SM . step2b ( smstate , combined_secret ) ; } } catch ( SMException ex ) { throw new OtrException ( ex ) ; } if ( question != null ) { bytes = question . getBytes ( SerializationUtils . UTF8 ) ; byte [ ] qsmpmsg = new byte [ bytes . length + 1 + smpmsg . length ] ; System . arraycopy ( bytes , 0 , qsmpmsg , 0 , bytes . length ) ; System . arraycopy ( smpmsg , 0 , qsmpmsg , bytes . length + 1 , smpmsg . length ) ; smpmsg = qsmpmsg ; } TLV sendtlv = new TLV ( initiating ? ( question != null ? TLV . SMP1Q : TLV . SMP1 ) : TLV . SMP2 , smpmsg ) ; smstate . nextExpected = initiating ? SM . EXPECT2 : SM . EXPECT3 ; return makeTlvList ( sendtlv ) ; }
respond to or initiate an smp negotiation
