コード例 #1
0
ファイル: Secure.java プロジェクト: frenche/properJavaRDP-1
  /**
   * Read in a public key from a provided Secure layer PDU, and store in this.exponent and
   * this.modulus
   *
   * @param data Secure layer PDU containing key data
   * @return True if key successfully read
   * @throws RdesktopException
   */
  public boolean parsePublicKey(RdpPacket_Localised data) throws RdesktopException {
    int magic = 0, modulus_length = 0;

    magic = data.getLittleEndian32();

    if (magic != SEC_RSA_MAGIC) {
      throw new RdesktopException("Wrong magic! Expected" + SEC_RSA_MAGIC + "got:" + magic);
    }

    modulus_length = data.getLittleEndian32() - SEC_PADDING_SIZE;

    if (modulus_length < 64 || modulus_length > SEC_MAX_MODULUS_SIZE) {
      throw new RdesktopException(
          "Bad server public key size (" + (modulus_length * 8) + " bites)");
    }

    data.incrementPosition(8); // unknown modulus bits
    this.exponent = new byte[SEC_EXPONENT_SIZE];
    data.copyToByteArray(this.exponent, 0, data.getPosition(), SEC_EXPONENT_SIZE);
    data.incrementPosition(SEC_EXPONENT_SIZE);
    this.modulus = new byte[modulus_length];
    data.copyToByteArray(this.modulus, 0, data.getPosition(), modulus_length);
    data.incrementPosition(modulus_length);
    data.incrementPosition(SEC_PADDING_SIZE);
    this.server_public_key_len = modulus_length;

    if (data.getPosition() <= data.getEnd()) {
      return true;
    } else {
      return false;
    }
  }
コード例 #2
0
ファイル: Secure.java プロジェクト: frenche/properJavaRDP-1
  /**
   * Prepare data as a Secure PDU and pass down to the MCS layer
   *
   * @param sec_data Data to send
   * @param flags Encryption flags
   * @param channel Channel over which to send data
   * @throws RdesktopException
   * @throws IOException
   * @throws CryptoException
   */
  public void send_to_channel(RdpPacket_Localised sec_data, int flags, int channel)
      throws RdesktopException, IOException, CryptoException {
    int datalength = 0;
    byte[] signature = null;
    byte[] data;
    byte[] buffer;

    sec_data.setPosition(sec_data.getHeader(RdpPacket.SECURE_HEADER));

    if (this.licenceIssued == false || (flags & SEC_ENCRYPT) != 0) {
      sec_data.setLittleEndian32(flags);
    }

    if (Options.debug_hexdump) {
      int length = sec_data.getEnd() - sec_data.getPosition();
      byte[] packet = new byte[length];
      sec_data.copyToByteArray(
          packet, 0, sec_data.getPosition(), sec_data.getEnd() - sec_data.getPosition());
      System.out.println("Sending packet:");
      System.out.println(net.propero.rdp.tools.HexDump.dumpHexString(packet));
    }

    if ((flags & SEC_ENCRYPT) != 0) {
      flags &= ~SEC_ENCRYPT;
      datalength = sec_data.getEnd() - sec_data.getPosition() - 8;
      data = new byte[datalength];
      buffer = null;
      sec_data.copyToByteArray(data, 0, sec_data.getPosition() + 8, datalength);
      signature = this.sign(this.sec_sign_key, 8, this.keylength, data, datalength);

      buffer = this.encrypt(data, datalength);

      sec_data.copyFromByteArray(signature, 0, sec_data.getPosition(), 8);
      sec_data.copyFromByteArray(buffer, 0, sec_data.getPosition() + 8, datalength);
    }
    // McsLayer.send(sec_data);
    McsLayer.send_to_channel(sec_data, channel);
  }
コード例 #3
0
ファイル: Secure.java プロジェクト: frenche/properJavaRDP-1
  /**
   * Handle MCS info from server (server info, encryption info and channel information)
   *
   * @param mcs_data Data received from server
   */
  public void processMcsData(RdpPacket_Localised mcs_data)
      throws RdesktopException, CryptoException {
    logger.debug("Secure.processMcsData");
    int tag = 0, len = 0, length = 0, nexttag = 0;

    mcs_data.incrementPosition(21); // header (T.124 stuff, probably)
    len = mcs_data.get8();

    if ((len & 0x00000080) != 0) {
      len = mcs_data.get8();
    }

    while (mcs_data.getPosition() < mcs_data.getEnd()) {
      tag = mcs_data.getLittleEndian16();
      length = mcs_data.getLittleEndian16();

      if (length <= 4) return;

      nexttag = mcs_data.getPosition() + length - 4;

      switch (tag) {
        case (Secure.SEC_TAG_SRV_INFO):
          processSrvInfo(mcs_data);
          break;
        case (Secure.SEC_TAG_SRV_CRYPT):
          this.processCryptInfo(mcs_data);
          break;
        case (Secure.SEC_TAG_SRV_CHANNELS):
          /*
           * FIXME: We should parse this information and use it to map
           * RDP5 channels to MCS channels
           */
          break;

        default:
          throw new RdesktopException("Not implemented! Tag:" + tag + "not recognized!");
      }

      mcs_data.setPosition(nexttag);
    }
  }
コード例 #4
0
ファイル: Secure.java プロジェクト: frenche/properJavaRDP-1
  /**
   * Read encryption information from a Secure layer PDU, obtaining and storing level of encryption
   * and any keys received
   *
   * @param data Packet to read encryption information from
   * @return Size of RC4 key
   * @throws RdesktopException
   */
  public int parseCryptInfo(RdpPacket_Localised data) throws RdesktopException {
    logger.debug("Secure.parseCryptInfo");
    int encryption_level = 0, random_length = 0, RSA_info_length = 0;
    int tag = 0, length = 0;
    int next_tag = 0, end = 0;
    int rc4_key_size = 0;

    rc4_key_size = data.getLittleEndian32(); // 1 = 40-Bit 2 = 128 Bit
    encryption_level = data.getLittleEndian32(); // 1 = low, 2 = medium,
    // 3 = high
    if (encryption_level == 0) { // no encryption
      return 0;
    }
    random_length = data.getLittleEndian32();
    RSA_info_length = data.getLittleEndian32();

    if (random_length != SEC_RANDOM_SIZE) {
      throw new RdesktopException(
          "Wrong Size of Random! Got" + random_length + "expected" + SEC_RANDOM_SIZE);
    }
    this.server_random = new byte[random_length];
    data.copyToByteArray(this.server_random, 0, data.getPosition(), random_length);
    data.incrementPosition(random_length);

    end = data.getPosition() + RSA_info_length;

    if (end > data.getEnd()) {
      logger.debug("Reached end of crypt info prematurely ");
      return 0;
    }

    // data.incrementPosition(12); // unknown bytes
    int flags = data.getLittleEndian32(); // in_uint32_le(s, flags); // 1
    // = RDP4-style, 0x80000002 =
    // X.509
    logger.debug("Flags = 0x" + Integer.toHexString(flags));
    if ((flags & 1) != 0) {
      logger.debug(("We're going for the RDP4-style encryption"));
      data.incrementPosition(8); // in_uint8s(s, 8); // unknown

      while (data.getPosition() < data.getEnd()) {
        tag = data.getLittleEndian16();
        length = data.getLittleEndian16();

        next_tag = data.getPosition() + length;

        switch (tag) {
          case (Secure.SEC_TAG_PUBKEY):
            if (!parsePublicKey(data)) {
              return 0;
            }

            break;
          case (Secure.SEC_TAG_KEYSIG):
            // Microsoft issued a key but we don't care
            break;

          default:
            throw new RdesktopException("Unimplemented decrypt tag " + tag);
        }
        data.setPosition(next_tag);
      }

      if (data.getPosition() == data.getEnd()) {
        return rc4_key_size;
      } else {
        logger.warn("End not reached!");
        return 0;
      }

    } else {
      logger.debug(("We're going for the RDP5-style encryption"));
      // data.incrementPosition(4); // number of certificates
      int num_certs = data.getLittleEndian32();

      int cacert_len = data.getLittleEndian32();
      data.incrementPosition(cacert_len);
      int cert_len = data.getLittleEndian32();
      data.incrementPosition(cert_len);

      readCert = true;

      return rc4_key_size;
    }
  }