Beispiel #1
0
  private void send_client_DH_inner_data(long retry_id) {
    byte[] b_data = new byte[256];
    Common.random.nextBytes(b_data);

    BigInteger b = new BigInteger(1, b_data);
    BigInteger g_b = g.modPow(b, dh_prime);
    Common.logError(
        "g_b length: " + g_b.toByteArray().length + " -> " + Common.toBytes(g_b).length);

    BigInteger akey = g_a.modPow(b, dh_prime);
    Common.logError("auth_key: " + akey.toString());
    setAuthKey(Common.toBytes(akey));

    // gen data (client_DH_inner_data)
    TL.Object data_obj = TL.newObject("client_DH_inner_data", cl_nonce, sv_nonce, retry_id, g_b);
    byte[] data = data_obj.serialize();
    byte[] hash = Common.getSHA1(data);

    byte[] data_with_hash = new byte[(hash.length + data.length + 15) / 16 * 16];
    System.arraycopy(hash, 0, data_with_hash, 0, hash.length);
    System.arraycopy(data, 0, data_with_hash, hash.length, data.length);

    // send set_client_DH_params
    TL.Object req_obj =
        TL.newObject("set_client_DH_params", cl_nonce, sv_nonce, aes.IGE(data_with_hash, true));
    send(req_obj, false, false);
  }
Beispiel #2
0
  public void setAuthKey(byte[] value) {
    if (value == null || value.length == 0) {
      auth_key = new byte[0];
      auth_key_aux_hash = auth_key_id = 0;
      return;
    }
    auth_key = value;
    dcState.set("auth_key", auth_key);

    byte[] auth_hash = Common.getSHA1(auth_key);
    auth_key_aux_hash = Common.toLong(Common.ASUB(auth_hash, 0, 8));
    auth_key_id = Common.toLong(Common.ASUB(auth_hash, 12, 8));
  }
Beispiel #3
0
  private void TL_ResPQ(TL.Object obj) {
    sv_nonce = obj.getBytes("server_nonce");
    BigInteger pq = new BigInteger(1, obj.getBytes("pq"));
    TL.Vector v_fp = obj.getVector("server_public_key_fingerprints");
    fp = v_fp.getLong(0);
    Common.logError("pq: " + pq.toString());

    // prime factorization for pq
    BigInteger q = Common.rho(pq);
    BigInteger p = pq.divide(q);
    if (p.compareTo(q) > 0) {
      BigInteger t = p;
      p = q;
      q = t;
    }
    SecureRandom rnd = new SecureRandom();
    new_nonce = new byte[32];
    rnd.nextBytes(new_nonce);

    // generate encrypted_data
    TL.Object data_obj = TL.newObject("p_q_inner_data", pq, p, q, cl_nonce, sv_nonce, new_nonce);

    byte[] data = data_obj.serialize();
    byte[] hash = Common.getSHA1(data);

    byte[] data_with_hash = new byte[255];
    System.arraycopy(hash, 0, data_with_hash, 0, hash.length);
    System.arraycopy(data, 0, data_with_hash, hash.length, data.length);
    GEN_random_bytes(data_with_hash, data.length + hash.length, 255);

    byte[] encrypted_data = Common.RSA(RSA_MODULUS, RSA_EXPONENT, data_with_hash);

    // req_DH_params
    TL.Object req_obj = TL.newObject("req_DH_params", cl_nonce, sv_nonce, p, q, fp, encrypted_data);
    send(req_obj, false, false);
  }
Beispiel #4
0
  public synchronized boolean sendMessage(Message msg) {
    if (msg == null) return false;

    if (!connected || (msg.encrypted && (auth_key == null || auth_key.length == 0)) || bad_seq) {
      Common.logError("add to queue " + connected + " " + msg.encrypted);
      TLMessageQueue.add(msg);
      return false;
    }
    ByteBuffer b = null;

    Common.logInfo("message send: " + msg.obj.name + ":" + msg.obj.type);
    byte[] msg_data = msg.obj.serialize();

    /*
    if (msg_data.length > 255) {
    	Common.logError("compress...");
    	byte[] data = Common.gzipDeflate(msg_data); // TODO: compress message data
    	if (data.length < msg_data.length && data.length > 32)
    		msg_data = TL.newObject("gzip_packed", data).serialize();
    }
    */

    if (msg.encrypted) {
      long message_id = GEN_message_id();
      TLMessage.put(message_id, msg);

      int size_real = 32 + msg_data.length;
      int size_padding = (size_real + 15) / 16 * 16;

      ByteBuffer p = BufferAlloc(size_padding);
      p.putLong(server_salt);
      p.putLong(session);
      p.putLong(message_id);

      if (msg.accept) seqno++;
      p.putInt(seqno);
      if (msg.accept) seqno++;

      p.putInt(msg_data.length);
      p.put(msg_data);
      byte[] data = p.array();
      GEN_random_bytes(data, p.position(), data.length);

      // encrypt data
      byte[] msg_key = Common.ASUB(Common.getSHA1(Common.ASUB(data, 0, size_real)), 4, 16);

      synchronized (aes) {
        aes.prepare(true, msg_key, auth_key);
        data = aes.IGE(data, true);
      }

      // write encrypted packet
      b = BufferAlloc(24 + data.length);
      b.putLong(auth_key_id);
      b.put(msg_key);
      b.put(data);
    } else {
      b = BufferAlloc(20 + msg_data.length);
      b.putLong(0);
      b.putLong(GEN_message_id());
      b.putInt(msg_data.length);
      b.put(msg_data);
    }

    try {
      synchronized (transport) {
        transport.send(b.array());
        return true;
      }
    } catch (Exception e) {
      return false;
    }
  }