Browse Source

Merge branch 'master' of https://lars.pandikow@git.tk.informatik.tu-darmstadt.de/scm-ssi-student-hostage.git

Lars Pandikow 10 years ago
parent
commit
9f3612b8ec
1 changed files with 282 additions and 297 deletions
  1. 282 297
      src/de/tudarmstadt/informatik/hostage/protocol/SSH.java

+ 282 - 297
src/de/tudarmstadt/informatik/hostage/protocol/SSH.java

@@ -37,36 +37,10 @@ public class SSH implements Protocol {
 		NONE, SERVER_VERSION, CLIENT_VERSION, KEX_INIT, NEW_KEYS, USERAUTH, CONNECTION, CHANNEL, TERMINAL_CMD, TERMINAL_ENTER, CLOSED
 	}
 
-	/**
-	 * Converts a byte[] to int
-	 * 
-	 * @param bytes
-	 *            that are converted
-	 * @return converted byte[] as int
-	 */
-	private int byteToInt(byte[] bytes) {
-		int convertedInteger = 0;
-		for (int i = 0; i < bytes.length; i++) {
-			convertedInteger <<= 8;
-			convertedInteger |= bytes[i] & 0xFF;
-		}
-		return convertedInteger;
-	}
-
-	private String initSshType() {
-		SecureRandom rnd = new SecureRandom();
-		int majorVersion = rnd.nextInt(possibleSshTypes.length);
-		return "OpenSSH_"
-				+ possibleSshTypes[majorVersion][0][0]
-				+ possibleSshTypes[majorVersion][1][rnd
-						.nextInt(possibleSshTypes[majorVersion][1].length)];
-	}
-
 	/**
 	 * Denotes in which state the protocol is right now.
 	 */
 	private STATE state = STATE.NONE;
-
 	private boolean useEncryption = false;
 
 	// version stuff
@@ -76,70 +50,60 @@ public class SSH implements Protocol {
 			{ { "5." }, { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } },
 			{ { "6." }, { "0", "1", "2", "3", "4" } } };
 
-	// server infos
-	private String serverVersion = "SSH-2.0-";
+	private String initSshType() {
+		SecureRandom rnd = new SecureRandom();
+		int majorVersion = rnd.nextInt(possibleSshTypes.length);
+		return "OpenSSH_"
+				+ possibleSshTypes[majorVersion][0][0]
+				+ possibleSshTypes[majorVersion][1][rnd
+						.nextInt(possibleSshTypes[majorVersion][1].length)];
+	}
 
+	// server infos
+	private static final String serverVersion = "SSH-2.0-";
 	private String serverType = initSshType();
-
 	private String serverName = HelperUtils.getRandomString(16, false);
-
 	private int packetNumber = 0;
-
 	private int recipientChannel;
-
 	private String userName;
-
 	private String terminalPrefix;
-
 	private StringBuffer command = new StringBuffer();
-
 	private SecureRandom random = new SecureRandom();
 
 	// SSH Parameters for Kex etc.
 	private byte[] V_S = (serverVersion + serverType).getBytes();
-
 	private byte[] V_C;
-
 	private byte[] I_S;
-
 	private byte[] I_C;
-
 	private byte[] e;
-
 	private BigInteger f;
-
 	private byte[] h;
-
 	private BigInteger k;
-
 	private byte[] K_S;
-
 	private byte[] signature;
 
 	// allowed algorithms for kexinit
 	private static final String KEX_ALG = "diffie-hellman-group1-sha1";
-
 	private static final String SERVER_ALG = "ssh-dss";
-
 	private static final String ENCRYPT_ALG_C = "3des-cbc";
-
 	private static final String ENCRYPT_ALG_S = "3des-cbc";
-
 	private static final String MAC_ALG_C = "hmac-sha1";
 	private static final String MAC_ALG_S = "hmac-sha1";
 	private static final String COMP_ALG_C = "none";
 	private static final String COMP_ALG_S = "none";
+
 	private int cipherBlockSize = 16;
+
 	// for en- and decryption
 	private DESede desEncryption;
 	private DESede desDecryption;
 	private CBCMode cbcEncryption;
 	private CBCMode cbcDecryption;
-
 	private MAC macEncryption;
 	// private MAC macDec;
+
 	// dsa private key
-	private final char[] dsaPem = ("-----BEGIN DSA PRIVATE KEY-----\n"
+	private static final char[] dsaPem = ("-----BEGIN DSA PRIVATE KEY-----\n"
 			+ "MIIBugIBAAKBgQCDZ9R2vfCPwjv5vKF1igIv9drrZ7G0dhMkGT9AZTjgI34Qm4w0\n"
 			+ "0iWeCqO7SmqiaMIjbRIm91MeDed4ObAq4sAkqRE/2P4mTbzFx5KhEczRRiDoqQBX\n"
 			+ "xYa0yWKJpeZ94SGM6DEPuBTxKo0T4uMjbq2FzHL2FXT1/WoNCmRU6gFSiwIVAMK4\n"
@@ -158,13 +122,8 @@ public class SSH implements Protocol {
 	}
 
 	@Override
-	public boolean isClosed() {
-		return (state == STATE.CLOSED);
-	}
-
-	@Override
-	public boolean isSecure() {
-		return false;
+	public TALK_FIRST whoTalksFirst() {
+		return TALK_FIRST.SERVER;
 	}
 
 	@Override
@@ -179,19 +138,18 @@ public class SSH implements Protocol {
 		}
 		switch (state) {
 		case NONE:
-			responsePackets
-					.add(new Packet(serverVersion + serverType + "\r\n", toString()));
-			responsePackets.add(kexInit());
+			responsePackets.add(new Packet(serverVersion + serverType + "\r\n",
+					toString()));
 			state = STATE.SERVER_VERSION;
 			break;
 		case SERVER_VERSION:
 			extractType(request);
 			extractPayload(request);
-			extractPubKey(request);
-			responsePackets.add(dhKexReply());
-			state = STATE.KEX_INIT;
+			responsePackets.add(kexInit());
+			state = STATE.CLIENT_VERSION;
 			break;
 		case CLIENT_VERSION:
+			extractPubKey(request);
 			responsePackets.add(dhKexReply());
 			state = STATE.KEX_INIT;
 			break;
@@ -231,87 +189,84 @@ public class SSH implements Protocol {
 	}
 
 	@Override
-	public String toString() {
-		return "SSH";
+	public boolean isClosed() {
+		return (state == STATE.CLOSED);
 	}
 
 	@Override
-	public TALK_FIRST whoTalksFirst() {
-		return TALK_FIRST.CLIENT;
+	public boolean isSecure() {
+		return false;
+	}
+
+	@Override
+	public String toString() {
+		return "SSH";
 	}
 
 	/**
-	 * Channel Open Reply.
+	 * Wraps the packets with packet length and padding.
 	 * 
-	 * @param request
-	 *            from client.
-	 * @return Channel Open Reply.
+	 * @param response
+	 *            content that is wrapped.
+	 * @return wrapped packet.
 	 */
-	private Packet channelOpenReply(byte[] request) {
-		if (!(HelperUtils.byteToStr(request).contains("session"))) {
-			return disconnectReply(2); // if contains "session" ok else disc
-		}
-		TypesReader tr = new TypesReader(request, 6);
-		TypesWriter tw = new TypesWriter();
-		try {
-			tr.readString();
-			recipientChannel = tr.readUINT32();
-			int senderChannel = recipientChannel;
-			int initialWindowSize = tr.readUINT32();
-			int maximumPacketSize = tr.readUINT32();
+	private Packet wrapPacket(byte[] response) {
+		// 4 byte packet length, 1 byte padding length, payload length
+		int packetLength = 5 + response.length;
+		int paddingLengthCBS = cipherBlockSize
+				- (packetLength % cipherBlockSize);
+		int paddingLength8 = 8 - (packetLength % 8);
+		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS
+				: paddingLength8;
+		if (paddingLength < 4)
+			paddingLength += cipherBlockSize;
+		// add padding string length to packet length
+		packetLength = packetLength + paddingLength - 4;
 
-			tw.writeByte(0x5b); // msgcode
-			tw.writeUINT32(recipientChannel);
-			tw.writeUINT32(senderChannel);
-			tw.writeUINT32(initialWindowSize);
-			tw.writeUINT32(maximumPacketSize);
-		} catch (IOException e) {
-			e.printStackTrace();
+		byte[] packetLen = ByteBuffer.allocate(4).putInt(packetLength).array();
+		byte[] paddingLen = { (byte) paddingLength };
+		byte[] paddingString = HelperUtils.randomBytes(paddingLength);
+		byte[] wrappedResponse = HelperUtils.concat(packetLen, paddingLen,
+				response, paddingString);
+		if (useEncryption) {
+			byte[] mac = createMac(wrappedResponse);
+			byte[] responseEnc = encryptBytes(wrappedResponse);
+			wrappedResponse = HelperUtils.concat(responseEnc, mac);
 		}
+		packetNumber++;
 
-		return wrapPacket(tw.getBytes());
+		return new Packet(wrappedResponse, toString());
 	}
 
 	/**
-	 * Channel Success Reply.
+	 * Encrypts a request with triple DES.
 	 * 
 	 * @param request
-	 *            from client.
-	 * @return Channel Success Reply.
+	 *            that is encrypted.
+	 * @return encrypted request.
 	 */
-	private Packet channelSuccessReply(byte[] request) {
-		if (!(HelperUtils.byteToStr(request)).contains("pty-req")) {
-			return disconnectReply(2);
+	private byte[] encryptBytes(byte[] bytes) {
+		byte[] responseEncrypted = new byte[bytes.length];
+		for (int i = 0; i < bytes.length; i += 8) {
+			cbcEncryption.transformBlock(bytes, i, responseEncrypted, i);
 		}
-		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x63); // msgcode
-		tw.writeUINT32(recipientChannel);
-
-		return wrapPacket(tw.getBytes());
+		return responseEncrypted;
 	}
 
 	/**
-	 * Userauth ssh-connection reply.
+	 * Decrypts a request with triple DES.
 	 * 
 	 * @param request
-	 *            from the client.
-	 * @return ssh-connection reply.
+	 *            that is decrypted.
+	 * @return decrypted request.
 	 */
-	private Packet connectionReply(byte[] request) {
-		if (request[5] != 0x32
-				&& !(HelperUtils.byteToStr(request).contains("ssh-connection"))) {
-			return disconnectReply(14);// disconnect because its not
-										// servicerequest ssh-connect
-		}
-		try {
-			TypesReader tr = new TypesReader(request, 6);
-			userName = tr.readString();
-			terminalPrefix = "[" + userName + "@" + serverName + " ~]$ ";
-		} catch (IOException e) {
-			e.printStackTrace();
+	private byte[] decryptBytes(byte[] request) {
+		byte[] decryptedRequest = new byte[request.length
+				- ((request.length % 8 == 0) ? 0 : 20)];
+		for (int i = 0; i < decryptedRequest.length; i += 8) {
+			cbcDecryption.transformBlock(request, i, decryptedRequest, i);
 		}
-		byte[] msgcode = { 0x34 };
-		return wrapPacket(msgcode);
+		return decryptedRequest;
 	}
 
 	/**
@@ -330,19 +285,36 @@ public class SSH implements Protocol {
 	}
 
 	/**
-	 * Decrypts a request with triple DES.
+	 * Builds the Kex Init packet that contains all the allowed algorithms by
+	 * the server.
 	 * 
-	 * @param request
-	 *            that is decrypted.
-	 * @return decrypted request.
+	 * @return Kex Init packet.
 	 */
-	private byte[] decryptBytes(byte[] request) {
-		byte[] decryptedRequest = new byte[request.length
-				- ((request.length % 8 == 0) ? 0 : 20)];
-		for (int i = 0; i < decryptedRequest.length; i += 8) { // -12 wegen MAC
-			cbcDecryption.transformBlock(request, i, decryptedRequest, i);
-		}
-		return decryptedRequest;
+	private Packet kexInit() {
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x14);
+		// cookie
+		tw.writeBytes(HelperUtils.randomBytes(16));
+		tw.writeString(KEX_ALG);
+		tw.writeString(SERVER_ALG);
+		tw.writeString(ENCRYPT_ALG_C);
+		tw.writeString(ENCRYPT_ALG_S);
+		tw.writeString(MAC_ALG_C);
+		tw.writeString(MAC_ALG_S);
+		tw.writeString(COMP_ALG_C);
+		tw.writeString(COMP_ALG_S);
+		// language client to server
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 });
+		// language server to client
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 });
+		// no guess from server
+		tw.writeByte(0x00);
+		// reserved
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 });
+		byte[] response = tw.getBytes();
+		I_S = response;
+
+		return wrapPacket(response);
 	}
 
 	/**
@@ -372,9 +344,10 @@ public class SSH implements Protocol {
 			response = tw.getBytes();
 
 			// init for decryption and encryption
+			// KeyMaterial: alg, h, k, keylength, blocklength, maclength,
+			// keylength, blocklength, maclength
 			KeyMaterial km = KeyMaterial.create("SHA1", h, k, h, 24, 8, 20, 24,
-					8, 20); // alg, h, k, keylength, blocklength, maclength,
-							// keylength, blocklength, maclength
+					8, 20);
 			desEncryption = new DESede();
 			desDecryption = new DESede();
 			desEncryption.init(true, km.enc_key_server_to_client);
@@ -388,181 +361,121 @@ public class SSH implements Protocol {
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-		return wrapPacket(response);
-	}
 
-	/**
-	 * Disconnect Reply using the given number as reason code.
-	 * 
-	 * @param reasonCode
-	 *            for disconnect reply. Must be between 1 and 15, default is 2.
-	 * @return Disconnect Reply.
-	 */
-	private Packet disconnectReply(int reasonCode) {
-		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x01);
-		switch (reasonCode) {
-		case 1:
-			tw.writeUINT32(1);
-			tw.writeString("SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT");
-			break;
-		case 7:
-			tw.writeUINT32(7);
-			tw.writeString("SSH_DISCONNECT_SERVICE_NOT_AVAILABLE");
-			break;
-		case 14:
-			tw.writeUINT32(14);
-			tw.writeString("SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE");
-			break;
-		default:
-			tw.writeUINT32(2);
-			tw.writeString("SSH_DISCONNECT_PROTOCOL_ERROR");
-			break;
-		}
-		return wrapPacket(tw.getBytes());
+		return wrapPacket(response);
 	}
 
 	/**
-	 * Encrypts a request with triple DES.
+	 * New Keys response.
 	 * 
-	 * @param request
-	 *            that is encrypted.
-	 * @return encrypted request.
+	 * @return New Keys response.
 	 */
-	private byte[] encryptBytes(byte[] bytes) {
-		byte[] responseEncrypted = new byte[bytes.length];
-		for (int i = 0; i < bytes.length; i += 8) {
-			cbcEncryption.transformBlock(bytes, i, responseEncrypted, i);
-		}
-		return responseEncrypted;
+	private Packet newKeys() {
+		byte[] msgCode = { 0x15 };
+		return wrapPacket(msgCode);
 	}
 
 	/**
-	 * Extracts the payload of a packet and writes it in I_C.
+	 * Service ssh-userauth reply.
 	 * 
 	 * @param request
-	 *            packet of which the payload is extracted.
+	 *            from the client.
+	 * @return Service reply.
 	 */
-	private void extractPayload(byte[] request) {
-		int position = 0;
-		if (request[5] != 0x14) {
-			position = 1;
-			for (int i = 0; i < request.length; i++, position++) {
-				if (request[i] == 0x0a)
-					break;
-			}
+	private Packet serviceReply(byte[] request) {
+		byte[] message;
+		// if newkeys request is included in the same packet remove it
+		if (request[5] == 0x15) {
+			message = new byte[request.length - 16];
+			System.arraycopy(request, 16, message, 0, request.length - 16);
+		} else {
+			message = request;
 		}
-		int packetLength = byteToInt(new byte[] { request[position],
-				request[1 + position], request[2 + position],
-				request[3 + position] });
-		int paddingLength = byteToInt(new byte[] { request[4 + position] });
-		byte[] payload = new byte[packetLength - paddingLength - 1];
-		for (int i = 6; i < packetLength - paddingLength - 1; i++) {
-			payload[i - 6] = request[i + position];
+		if (message[5] != 0x05
+				&& !(HelperUtils.byteToStr(message).contains("ssh-userauth"))) {
+			// disconnect because its not servicerequest ssh-userauth
+			return disconnectReply(7);
 		}
-		I_C = payload;
-		System.out.println(HelperUtils.bytesToHexString(I_C));
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x06);
+		tw.writeString("ssh-userauth");
+		return wrapPacket(tw.getBytes());
 	}
 
 	/**
-	 * Extracts the public key from the DH Kex Request
+	 * Userauth ssh-connection reply.
 	 * 
 	 * @param request
-	 *            containing the clients public key
+	 *            from the client.
+	 * @return ssh-connection reply.
 	 */
-	private void extractPubKey(byte[] request) {
-		int packetLength = byteToInt(new byte[] { request[0],
-				request[1], request[2],
-				request[3] });
-		int paddingLength = byteToInt(new byte[] { request[4] });
-		byte[] len = new byte[] { request[2+packetLength + paddingLength], request[3+ packetLength + paddingLength], request[4 + paddingLength + packetLength],
-				request[5 + packetLength + paddingLength] };
-		e = new byte[byteToInt(len)];
-		for (int i = 0; i < e.length; i++) {
-			e[i] = request[i+packetLength + paddingLength+6];
+	private Packet connectionReply(byte[] request) {
+		if (request[5] != 0x32
+				&& !(HelperUtils.byteToStr(request).contains("ssh-connection"))) {
+			// disconnect because its not servicerequest ssh-connect
+			return disconnectReply(14);
 		}
+		try {
+			TypesReader tr = new TypesReader(request, 6);
+			userName = tr.readString();
+			terminalPrefix = "[" + userName + "@" + serverName + " ~]$ ";
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		byte[] msgcode = { 0x34 };
+		return wrapPacket(msgcode);
 	}
 
 	/**
-	 * Extracts the type of the client
+	 * Channel Open Reply.
 	 * 
 	 * @param request
-	 *            containing the clients type
+	 *            from client.
+	 * @return Channel Open Reply.
 	 */
-	private void extractType(byte[] request) {
-		int length = 0;
-		for (int i = 0; i < request.length; i++, length++) {
-			if (request[i] == 0x0d)
-				break; // find the end of the type: '\r'
+	private Packet channelOpenReply(byte[] request) {
+		if (!(HelperUtils.byteToStr(request).contains("session"))) {
+			// if contains "session" ok else disc
+			return disconnectReply(2);
 		}
-		V_C = new byte[length];
-		System.arraycopy(request, 0, V_C, 0, length);
-	}
-
-	/**
-	 * Builds the Kex Init packet that contains all the allowed algorithms by
-	 * the server.
-	 * 
-	 * @return Kex Init packet.
-	 */
-	private Packet kexInit() {
+		TypesReader tr = new TypesReader(request, 6);
 		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x14);
-		tw.writeBytes(HelperUtils.randomBytes(16)); // cookie
-		tw.writeString(KEX_ALG);
-		tw.writeString(SERVER_ALG);
-		tw.writeString(ENCRYPT_ALG_C);
-		tw.writeString(ENCRYPT_ALG_S);
-		tw.writeString(MAC_ALG_C);
-		tw.writeString(MAC_ALG_S);
-		tw.writeString(COMP_ALG_C);
-		tw.writeString(COMP_ALG_S);
-		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language client
-																// to server
-		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language server
-																// to client
-		tw.writeByte(0x00); // no guess from server
-		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // reserved
-		byte[] response = tw.getBytes();
-		I_S = response;
+		try {
+			tr.readString();
+			recipientChannel = tr.readUINT32();
+			int senderChannel = recipientChannel;
+			int initialWindowSize = tr.readUINT32();
+			int maximumPacketSize = tr.readUINT32();
 
-		return wrapPacket(response);
-	}
+			// msgcode
+			tw.writeByte(0x5b);
+			tw.writeUINT32(recipientChannel);
+			tw.writeUINT32(senderChannel);
+			tw.writeUINT32(initialWindowSize);
+			tw.writeUINT32(maximumPacketSize);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
 
-	/**
-	 * New Keys response.
-	 * 
-	 * @return New Keys response.
-	 */
-	private Packet newKeys() {
-		byte[] msgCode = { 0x15 };
-		return wrapPacket(msgCode);
+		return wrapPacket(tw.getBytes());
 	}
 
 	/**
-	 * Service ssh-userauth reply.
+	 * Channel Success Reply.
 	 * 
 	 * @param request
-	 *            from the client.
-	 * @return Service reply.
+	 *            from client.
+	 * @return Channel Success Reply.
 	 */
-	private Packet serviceReply(byte[] request) {
-		byte[] message;
-		if (request[5] == 0x15) { // if newkeys request is included in the same
-									// packet
-			message = new byte[request.length - 16]; // remove it
-			System.arraycopy(request, 16, message, 0, request.length - 16);
-		} else {
-			message = request;
-		}
-		if (message[5] != 0x05
-				&& !(HelperUtils.byteToStr(message).contains("ssh-userauth"))) {
-			return disconnectReply(7); // disconnect because its not
-										// servicerequest ssh-userauth
+	private Packet channelSuccessReply(byte[] request) {
+		if (!(HelperUtils.byteToStr(request)).contains("pty-req")) {
+			return disconnectReply(2);
 		}
 		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x06);
-		tw.writeString("ssh-userauth");
+		// msgcode
+		tw.writeByte(0x63);
+		tw.writeUINT32(recipientChannel);
+
 		return wrapPacket(tw.getBytes());
 	}
 
@@ -595,7 +508,7 @@ public class SSH implements Protocol {
 			message = tr.readString();
 			if (message.contains("\r")) {
 				if (command.toString().contains("exit")) {
-					state = STATE.CLOSED; // ugly style
+					state = STATE.CLOSED;
 					return disconnectReply(2);
 				}
 				message = "\r\nbash: " + command + " :command not found\r\n"
@@ -612,43 +525,115 @@ public class SSH implements Protocol {
 			e.printStackTrace();
 		}
 		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x5e); // msgcode
+		// msgcode
+		tw.writeByte(0x5e);
 		tw.writeUINT32(recipientChannel);
 		tw.writeString(message);
 		return wrapPacket(tw.getBytes());
 	}
 
 	/**
-	 * Wraps the packets with packet length and padding.
+	 * Disconnect Reply using the given number as reason code.
 	 * 
-	 * @param response
-	 *            content that is wrapped.
-	 * @return wrapped packet.
+	 * @param reasonCode
+	 *            for disconnect reply. Must be between 1 and 15, default is 2.
+	 * @return Disconnect Reply.
 	 */
-	private Packet wrapPacket(byte[] response) {
-		// 4 byte packet length, 1 byte padding length, payload length
-		int packetLength = 5 + response.length;
-		int paddingLengthCBS = cipherBlockSize
-				- (packetLength % cipherBlockSize);
-		int paddingLength8 = 8 - (packetLength % 8);
-		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS
-				: paddingLength8;
-		if (paddingLength < 4)
-			paddingLength += cipherBlockSize;
-		// add padding string length to packet length
-		packetLength = packetLength + paddingLength - 4; 
-		byte[] packetLen = ByteBuffer.allocate(4).putInt(packetLength).array();
-		byte[] paddingLen = { (byte) paddingLength };
-		byte[] paddingString = HelperUtils.randomBytes(paddingLength);
-		byte[] wrappedResponse = HelperUtils.concat(packetLen, paddingLen,
-				response, paddingString);
-		if (useEncryption) {
-			byte[] mac = createMac(wrappedResponse);
-			byte[] responseEnc = encryptBytes(wrappedResponse);
-			wrappedResponse = HelperUtils.concat(responseEnc, mac);
+	private Packet disconnectReply(int reasonCode) {
+		TypesWriter tw = new TypesWriter();
+		tw.writeByte(0x01);
+		switch (reasonCode) {
+		case 1:
+			tw.writeUINT32(1);
+			tw.writeString("SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT");
+			break;
+		case 7:
+			tw.writeUINT32(7);
+			tw.writeString("SSH_DISCONNECT_SERVICE_NOT_AVAILABLE");
+			break;
+		case 14:
+			tw.writeUINT32(14);
+			tw.writeString("SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE");
+			break;
+		default:
+			tw.writeUINT32(2);
+			tw.writeString("SSH_DISCONNECT_PROTOCOL_ERROR");
+			break;
 		}
-		packetNumber++;
+		return wrapPacket(tw.getBytes());
+	}
 
-		return new Packet(wrappedResponse, toString());
+	/**
+	 * Extracts the type of the client
+	 * 
+	 * @param request
+	 *            containing the clients type
+	 */
+	private void extractType(byte[] request) {
+		int length = 0;
+		for (int i = 0; i < request.length; i++, length++) {
+			// find the end of the type: '\r'
+			if (request[i] == 0x0d)
+				break;
+		}
+		V_C = new byte[length];
+		System.arraycopy(request, 0, V_C, 0, length);
 	}
+
+	/**
+	 * Extracts the payload of a packet and writes it in I_C.
+	 * 
+	 * @param request
+	 *            packet of which the payload is extracted.
+	 */
+	private void extractPayload(byte[] request) {
+		int position = 0;
+		if (request[5] != 0x14) {
+			position = 1;
+			for (int i = 0; i < request.length; i++, position++) {
+				if (request[i] == 0x0a)
+					break;
+			}
+		}
+		int packetLength = byteToInt(new byte[] { request[position],
+				request[1 + position], request[2 + position],
+				request[3 + position] });
+		int paddingLength = byteToInt(new byte[] { request[4 + position] });
+		byte[] payload = new byte[packetLength - paddingLength - 1];
+		for (int i = 5; i < packetLength - paddingLength - 1; i++) {
+			payload[i - 5] = request[i + position];
+		}
+		I_C = payload;
+	}
+
+	/**
+	 * Extracts the public key from the DH Kex Request
+	 * 
+	 * @param request
+	 *            containing the clients public key
+	 */
+	private void extractPubKey(byte[] request) {
+		e = new byte[byteToInt(new byte[] { request[6], request[7], request[8],
+				request[9] })];
+		for (int i = 0; i < e.length; i++) {
+			e[i] = request[i + 10];
+		}
+	}
+
+	/**
+	 * Converts a byte[] to int
+	 * 
+	 * @param bytes
+	 *            that are converted
+	 * @return converted byte[] as int
+	 */
+	private static int byteToInt(byte[] bytes) {
+		int convertedInteger = 0;
+		for (int i = 0; i < bytes.length; i++) {
+			convertedInteger <<= 8;
+			convertedInteger |= bytes[i] & 0xFF;
+		}
+		return convertedInteger;
+	}
+
 }