// File: akw0088[P]openssl/aes_download.cpp
// Function: main
int main(int argc, char *argv[])
{
	unsigned short port = 65535;
	unsigned int size = 0;
	unsigned char encrypted_key[256] = {0};
	char remote_hash[33] = {0};

	if (argc < 5)
	{
		printf("Usage: download ip port max_size prikey\r\n");
		printf("Example: ./aes_download 127.0.0.1 65535 536870912 id_rsa\r\n");
		return 0;
	}

	port = atoi(argv[2]);
	size = atoi(argv[3]);

	unsigned int prikey_size = 0;
	unsigned char *prikey = (unsigned char *)get_file(argv[4], &prikey_size);

	printf("Allocating %d bytes\r\n", size);
	char *response = (char *)malloc(size);
	if (response == NULL)
	{
		perror("malloc failed");
	}

	unsigned int download_size = 0;
	unsigned int final_size = 0;
	char file_name[128] = {0};

	printf("Attempting to download file from ip %s port %d\r\n", argv[1], (int)port);
	int ret = aes_file_download(argv[1], port, response, size, &download_size, file_name, final_size, remote_hash, encrypted_key);
	if (ret != 0 || download_size == 0)
	{
		printf("Download failed\r\n");
		return 0;
	}

	printf("Download complete\r\n");
	printf("Got %d bytes file name %s remote md5sum %s\r\n", download_size, file_name, remote_hash);


	char new_filename[256] = {0};
	char strip_filename[256] = {0};

	StripChars(file_name, strip_filename, (char *)".\\/;:*?\"<>|");

	sprintf(new_filename, "downloaded_%s", strip_filename);
	printf("Saving as file name %s\r\n", new_filename);
	write_file(new_filename, response, download_size);
	printf("Attempting to decrypt AES key with RSA\r\n");

	unsigned char decrypted[4098] = {0};

	RSA *rsa = createRSA(prikey, false);
	int decrypted_length = RSA_private_decrypt(256, encrypted_key, decrypted, rsa, RSA_PKCS1_PADDING);
	if (decrypted_length == -1)
	{
		char err[130];

		ERR_load_crypto_strings();
		ERR_error_string(ERR_get_error(), err);
		printf("ERROR: %s\n", err);
		free((void *)response);
		return -1;
	}
	RSA_free(rsa);

//	printf("Decrypted Text: %s\n", decrypted);
//	printf("Decrypted Length: %d\n", decrypted_length);

	if (decrypted_length != 16 + 32 + 1)
	{
		printf("Unexpected AES key string size\r\n");
		free((void *)response);
		return -1;
	}

	if (decrypted[16] != ' ')
	{
		printf("Unexpected AES key format: %s\r\n", decrypted);
		free((void *)response);
		return -1;
	}



	unsigned char key[128] = {0};
	unsigned char iv[128] = {0};

	ret = sscanf((char *)&decrypted[0], "%s %s", (char *)&iv[0], (char *)&key[0]);

	if (ret != 2)
	{
		printf("Unexpected AES key format: %s matched %d\r\n", decrypted, ret);
		free((void *)response);
		return -1;
	}

	printf("Decrypted AES Key successfully\r\n");

	printf("Attempting to decrypt file with remote hash %s\r\n", remote_hash);
	aes_decrypt(key, iv, new_filename, size, remote_hash);



	if (size == final_size)
	{
		printf("decrypted successfully\r\n");
		printf("Saved as %s_decrypted\r\n", new_filename);
	}
	free((void *)response);
	delete [] prikey;

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x15c0, %rsp           # imm = 0x15C0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movw $0xffff, -0x12(%rbp)    # imm = 0xFFFF
movl $0x0, -0x18(%rbp)
leaq -0x120(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2130
leaq -0x150(%rbp), %rdi
xorl %esi, %esi
movl $0x21, %edx
callq 0x2130
cmpl $0x5, -0x8(%rbp)
jge 0x2d2a
leaq 0x1532(%rip), %rdi      # 0x423b
movb $0x0, %al
callq 0x2060
leaq 0x154e(%rip), %rdi      # 0x4265
movb $0x0, %al
callq 0x2060
movl $0x0, -0x4(%rbp)
jmp 0x3185
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x22a0
movw %ax, -0x12(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x22a0
movl %eax, -0x18(%rbp)
movl $0x0, -0x154(%rbp)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdi
leaq -0x154(%rbp), %rsi
callq 0x24c0
movq %rax, -0x160(%rbp)
movl -0x18(%rbp), %esi
leaq 0x1526(%rip), %rdi      # 0x42a0
movb $0x0, %al
callq 0x2060
movl -0x18(%rbp), %eax
movl %eax, %edi
callq 0x2270
movq %rax, -0x168(%rbp)
cmpq $0x0, -0x168(%rbp)
jne 0x2da8
leaq 0x1442(%rip), %rdi      # 0x41e5
callq 0x21b0
movl $0x0, -0x16c(%rbp)
movl $0x0, -0x170(%rbp)
leaq -0x1f0(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x2130
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
movzwl -0x12(%rbp), %edx
leaq 0x14d4(%rip), %rdi      # 0x42b6
movb $0x0, %al
callq 0x2060
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movw -0x12(%rbp), %si
movq -0x168(%rbp), %rdx
movl -0x18(%rbp), %ecx
leaq -0x1f0(%rbp), %r9
leaq -0x150(%rbp), %r10
leaq -0x120(%rbp), %rax
leaq -0x16c(%rbp), %r8
leaq -0x170(%rbp), %r11
movzwl %si, %esi
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x2660
movl %eax, -0x1f4(%rbp)
cmpl $0x0, -0x1f4(%rbp)
jne 0x2e50
cmpl $0x0, -0x16c(%rbp)
jne 0x2e6a
leaq 0x1490(%rip), %rdi      # 0x42e7
movb $0x0, %al
callq 0x2060
movl $0x0, -0x4(%rbp)
jmp 0x3185
leaq 0x1488(%rip), %rdi      # 0x42f9
movb $0x0, %al
callq 0x2060
movl -0x16c(%rbp), %esi
leaq -0x1f0(%rbp), %rdx
leaq -0x150(%rbp), %rcx
leaq 0x147a(%rip), %rdi      # 0x430d
movb $0x0, %al
callq 0x2060
leaq -0x300(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2130
leaq -0x400(%rbp), %rdi
xorl %esi, %esi
movl $0x100, %edx            # imm = 0x100
callq 0x2130
leaq -0x1f0(%rbp), %rdi
leaq -0x400(%rbp), %rsi
leaq 0x1465(%rip), %rdx      # 0x433a
callq 0x2870
leaq -0x300(%rbp), %rdi
leaq -0x400(%rbp), %rdx
leaq 0x1457(%rip), %rsi      # 0x4346
movb $0x0, %al
callq 0x2080
leaq -0x300(%rbp), %rsi
leaq 0x1450(%rip), %rdi      # 0x4354
movb $0x0, %al
callq 0x2060
leaq -0x300(%rbp), %rdi
movq -0x168(%rbp), %rsi
movl -0x16c(%rbp), %edx
callq 0x25c0
leaq 0x1442(%rip), %rdi      # 0x436d
movb $0x0, %al
callq 0x2060
leaq -0x1410(%rbp), %rdi
xorl %esi, %esi
movl $0x1002, %edx           # imm = 0x1002
callq 0x2130
movq -0x160(%rbp), %rdi
xorl %esi, %esi
callq 0x2930
movq %rax, -0x1418(%rbp)
leaq -0x120(%rbp), %rsi
leaq -0x1410(%rbp), %rdx
movq -0x1418(%rbp), %rcx
movl $0x100, %edi            # imm = 0x100
movl $0x1, %r8d
callq 0x2190
movl %eax, -0x141c(%rbp)
cmpl $-0x1, -0x141c(%rbp)
jne 0x2fdd
movl $0x2, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x2110
callq 0x2260
movq %rax, %rdi
leaq -0x14a0(%rbp), %rsi
callq 0x20c0
leaq -0x14a0(%rbp), %rsi
leaq 0x13d8(%rip), %rdi      # 0x4396
movb $0x0, %al
callq 0x2060
movq -0x168(%rbp), %rdi
callq 0x2230
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x3185
movq -0x1418(%rbp), %rdi
callq 0x2210
cmpl $0x31, -0x141c(%rbp)
je 0x3018
leaq 0x13a8(%rip), %rdi      # 0x43a1
movb $0x0, %al
callq 0x2060
movq -0x168(%rbp), %rdi
callq 0x2230
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x3185
movzbl -0x1400(%rbp), %eax
cmpl $0x20, %eax
je 0x3051
leaq -0x1410(%rbp), %rsi
leaq 0x1390(%rip), %rdi      # 0x43c2
movb $0x0, %al
callq 0x2060
movq -0x168(%rbp), %rdi
callq 0x2230
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x3185
leaq -0x1520(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x2130
leaq -0x15a0(%rbp), %rdi
xorl %esi, %esi
movl $0x80, %edx
callq 0x2130
leaq -0x1410(%rbp), %rdi
leaq -0x15a0(%rbp), %rdx
leaq -0x1520(%rbp), %rcx
leaq 0x134f(%rip), %rsi      # 0x43e2
movb $0x0, %al
callq 0x21c0
movl %eax, -0x1f4(%rbp)
cmpl $0x2, -0x1f4(%rbp)
je 0x30dc
leaq -0x1410(%rbp), %rsi
movl -0x1f4(%rbp), %edx
leaq 0x132b(%rip), %rdi      # 0x43e8
movb $0x0, %al
callq 0x2060
movq -0x168(%rbp), %rdi
callq 0x2230
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x3185
leaq 0x1330(%rip), %rdi      # 0x4413
movb $0x0, %al
callq 0x2060
leaq -0x150(%rbp), %rsi
leaq 0x133c(%rip), %rdi      # 0x4434
movb $0x0, %al
callq 0x2060
leaq -0x1520(%rbp), %rdi
leaq -0x15a0(%rbp), %rsi
leaq -0x300(%rbp), %rdx
leaq -0x150(%rbp), %r8
leaq -0x18(%rbp), %rcx
callq 0x2af0
movl -0x18(%rbp), %eax
cmpl -0x170(%rbp), %eax
jne 0x3152
leaq 0x132f(%rip), %rdi      # 0x4465
movb $0x0, %al
callq 0x2060
leaq -0x300(%rbp), %rsi
leaq 0x1333(%rip), %rdi      # 0x447e
movb $0x0, %al
callq 0x2060
movq -0x168(%rbp), %rdi
callq 0x2230
movq -0x160(%rbp), %rax
movq %rax, -0x15a8(%rbp)
cmpq $0x0, %rax
je 0x317e
movq -0x15a8(%rbp), %rdi
callq 0x2250
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x15c0, %rsp           # imm = 0x15C0
popq %rbp
retq