Package com.subgraph.orchid.circuits

Source Code of com.subgraph.orchid.circuits.NTorCircuitExtender

package com.subgraph.orchid.circuits;

import java.util.logging.Logger;

import com.subgraph.orchid.CircuitNode;
import com.subgraph.orchid.RelayCell;
import com.subgraph.orchid.Router;
import com.subgraph.orchid.TorException;
import com.subgraph.orchid.crypto.TorMessageDigest;
import com.subgraph.orchid.crypto.TorNTorKeyAgreement;

public class NTorCircuitExtender {
  private final static Logger logger = Logger.getLogger(NTorCircuitExtender.class.getName());
 
  private final CircuitExtender extender;
  private final Router router;
  private final TorNTorKeyAgreement kex;
 
  public NTorCircuitExtender(CircuitExtender extender, Router router) {
    this.extender = extender;
    this.router = router;
    this.kex = new TorNTorKeyAgreement(router.getIdentityHash(), router.getNTorOnionKey());
  }

  CircuitNode extendTo() {
    final byte[] onion = kex.createOnionSkin();
    if(finalRouterSupportsExtend2()) {
      logger.fine("Extending circuit to "+ router.getNickname() + " with NTor inside RELAY_EXTEND2");
      return extendWithExtend2(onion);
    } else {
      logger.fine("Extending circuit to "+ router.getNickname() + " with NTor inside RELAY_EXTEND");
      return extendWithTunneledExtend(onion);
    }
  }
 
  private CircuitNode extendWithExtend2(byte[] onion) {
    final RelayCell cell = createExtend2Cell(onion);
    extender.sendRelayCell(cell);
    final RelayCell response = extender.receiveRelayResponse(RelayCell.RELAY_EXTENDED2, router);
    return processExtended2(response);
  }
 
  private CircuitNode extendWithTunneledExtend(byte[] onion) {
    final RelayCell cell = createExtendCell(onion, kex.getNtorCreateMagic());
    extender.sendRelayCell(cell);
    final RelayCell response = extender.receiveRelayResponse(RelayCell.RELAY_EXTENDED, router);
    return processExtended(response);
  }
 
  private boolean finalRouterSupportsExtend2() {
    return extender.getFinalRouter().getNTorOnionKey() != null;
  }
 
  private RelayCell createExtend2Cell(byte[] ntorOnionskin) {
    final RelayCell cell = extender.createRelayCell(RelayCell.RELAY_EXTEND2);

    cell.putByte(2);
     
    cell.putByte(0);
    cell.putByte(6);
    cell.putByteArray(router.getAddress().getAddressDataBytes());
    cell.putShort(router.getOnionPort());
     
    cell.putByte(2);
    cell.putByte(20);
    cell.putByteArray(router.getIdentityHash().getRawBytes());
     
    cell.putShort(0x0002);
    cell.putShort(ntorOnionskin.length);
    cell.putByteArray(ntorOnionskin);
    return cell;
  }
 
  private RelayCell createExtendCell(byte[] ntorOnionskin, byte[] ntorMagic) {
    final RelayCell cell = extender.createRelayCell(RelayCell.RELAY_EXTEND);
    cell.putByteArray(router.getAddress().getAddressDataBytes());
    cell.putShort(router.getOnionPort());
    final int paddingLength = CircuitExtender.TAP_ONIONSKIN_LEN - (ntorOnionskin.length + ntorMagic.length);
    final byte[] padding = new byte[paddingLength];
    cell.putByteArray(ntorMagic);
    cell.putByteArray(ntorOnionskin);
    cell.putByteArray(padding);
    cell.putByteArray(router.getIdentityHash().getRawBytes());
    return cell;
  }
 
  private CircuitNode processExtended(RelayCell cell) {
    byte[] payload = new byte[CircuitExtender.TAP_ONIONSKIN_REPLY_LEN];
    cell.getByteArray(payload);
   
    return processPayload(payload);
  }
 

  private CircuitNode processExtended2(RelayCell cell) {
    final int payloadLength = cell.getShort();
    if(payloadLength > cell.cellBytesRemaining()) {
      throw new TorException("Incorrect payload length value in RELAY_EXTENED2 cell");
    }
    byte[] payload = new byte[payloadLength];
    cell.getByteArray(payload);

    return processPayload(payload);
  }
 
  private CircuitNode processPayload(byte[] payload) {
    final byte[] keyMaterial = new byte[CircuitNodeCryptoState.KEY_MATERIAL_SIZE];
    final byte[] verifyDigest = new byte[TorMessageDigest.TOR_DIGEST_SIZE];
    if(!kex.deriveKeysFromHandshakeResponse(payload, keyMaterial, verifyDigest)) {
      return null;
    }
    return extender.createNewNode(router, keyMaterial, verifyDigest);
  }
}
TOP

Related Classes of com.subgraph.orchid.circuits.NTorCircuitExtender

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.