public void establishKey() throws RdesktopException, IOException, CryptoException { RdpPacket_Localised buffer; int flags = SEC_CLIENT_RANDOM; if (readCert) { // RDP5-style encryption, use old code for now int length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE; buffer = this.init(flags, 76); buffer.setLittleEndian32(length); buffer.copyFromByteArray(this.sec_crypted_random, 0, buffer.getPosition(), SEC_MODULUS_SIZE); buffer.incrementPosition(SEC_MODULUS_SIZE); } else { int length = server_public_key_len + SEC_PADDING_SIZE; buffer = this.init(flags, length + 4); buffer.setLittleEndian32(length); buffer.copyFromByteArray( this.sec_crypted_random, 0, buffer.getPosition(), server_public_key_len); buffer.incrementPosition(server_public_key_len); } buffer.incrementPosition(SEC_PADDING_SIZE); buffer.markEnd(); this.send(buffer, flags); }
/** * 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); }
/** * Receive a Secure layer PDU from the MCS layer * * @return Packet representing received Secure PDU * @throws RdesktopException * @throws IOException * @throws CryptoException * @throws OrderException */ public RdpPacket_Localised receive() throws RdesktopException, IOException, CryptoException, OrderException { int sec_flags = 0; RdpPacket_Localised buffer = null; while (true) { int[] channel = new int[1]; buffer = McsLayer.receive(channel); if (buffer == null) return null; buffer.setHeader(RdpPacket.SECURE_HEADER); if (Constants.encryption || (!this.licenceIssued)) { sec_flags = buffer.getLittleEndian32(); if ((sec_flags & SEC_LICENCE_NEG) != 0) { licence.process(buffer); continue; } if ((sec_flags & SEC_ENCRYPT) != 0) { buffer.incrementPosition(8); // signature byte[] data = new byte[buffer.size() - buffer.getPosition()]; buffer.copyToByteArray(data, 0, buffer.getPosition(), data.length); byte[] packet = this.decrypt(data); buffer.copyFromByteArray(packet, 0, buffer.getPosition(), packet.length); // buffer.setStart(buffer.getPosition()); // return buffer; } } if (channel[0] != MCS.MCS_GLOBAL_CHANNEL) { channels.channel_process(buffer, channel[0]); continue; } buffer.setStart(buffer.getPosition()); return buffer; } }