// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x14e8, %rsp           # imm = 0x14E8
movq %rsi, %r13
movl %edi, %ebx
leaq -0x400(%rbp), %rdi
xorl %r15d, %r15d
movl $0x100, %edx            # imm = 0x100
xorl %esi, %esi
callq 0x2120
xorps %xmm0, %xmm0
movaps %xmm0, -0x60(%rbp)
movaps %xmm0, -0x70(%rbp)
movb $0x0, -0x50(%rbp)
cmpl $0x4, %ebx
jg 0x2b0c
leaq 0x8fb(%rip), %rdi       # 0x33f1
callq 0x2290
leaq 0x918(%rip), %rdi       # 0x341a
callq 0x2290
jmp 0x2e93
movq 0x10(%r13), %rdi
callq 0x22a0
movl %eax, %r15d
movq 0x18(%r13), %rdi
callq 0x22a0
movl %eax, %r14d
movl %eax, -0x34(%rbp)
leaq -0x44(%rbp), %rsi
movl $0x0, (%rsi)
movq 0x20(%r13), %rdi
callq 0x24a1
movq %rax, -0x40(%rbp)
leaq 0x5b0(%rip), %rdi       # 0x30f5
xorl %r12d, %r12d
movl %r14d, %esi
xorl %eax, %eax
callq 0x2060
movl %r14d, %edi
callq 0x2260
movq %rax, %rbx
testq %rax, %rax
je 0x2ea8
leaq -0x30(%rbp), %rax
movl %r12d, (%rax)
leaq -0x2c(%rbp), %rax
movl %r12d, (%rax)
xorps %xmm0, %xmm0
leaq -0x200(%rbp), %r12
movaps %xmm0, 0x70(%r12)
movaps %xmm0, 0x60(%r12)
movaps %xmm0, 0x50(%r12)
movaps %xmm0, 0x40(%r12)
movaps %xmm0, 0x30(%r12)
movaps %xmm0, 0x20(%r12)
movaps %xmm0, 0x10(%r12)
movaps %xmm0, (%r12)
movq 0x8(%r13), %rsi
movzwl %r15w, %edx
leaq 0x54f(%rip), %rdi       # 0x310b
xorl %eax, %eax
callq 0x2060
movq 0x8(%r13), %rdi
subq $0x8, %rsp
leaq -0x70(%rbp), %rax
movzwl %r15w, %esi
movq %rbx, %rdx
movl %r14d, %ecx
leaq -0x30(%rbp), %r14
movq %r14, %r8
movq %r12, %r9
leaq -0x400(%rbp), %r10
pushq %r10
pushq %rax
leaq -0x2c(%rbp), %rax
pushq %rax
callq 0x25d0
addq $0x20, %rsp
testl %eax, %eax
setne %al
movl (%r14), %r15d
testl %r15d, %r15d
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0x2c24
leaq 0x7c9(%rip), %rdi       # 0x33e0
callq 0x2290
xorl %r15d, %r15d
jmp 0x2e93
movq %rbx, %r13
leaq 0x71f(%rip), %rdi       # 0x334d
callq 0x2290
leaq 0x502(%rip), %rdi       # 0x313c
leaq -0x200(%rbp), %r14
leaq -0x70(%rbp), %rcx
movl %r15d, %esi
movq %r14, %rdx
xorl %eax, %eax
callq 0x2060
leaq -0x300(%rbp), %rbx
movl $0x100, %edx            # imm = 0x100
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2120
leaq -0x500(%rbp), %r12
movl $0x100, %edx            # imm = 0x100
movq %r12, %rdi
xorl %esi, %esi
callq 0x2120
leaq 0x4e4(%rip), %rdx       # 0x3169
movq %r14, %rdi
movq %r12, %rsi
callq 0x2786
leaq 0x4de(%rip), %rsi       # 0x3175
movq %rbx, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x2070
leaq 0x4d8(%rip), %rdi       # 0x3183
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2060
movq %rbx, %rdi
movq %r13, %rsi
movl %r15d, %edx
callq 0x2553
leaq 0x696(%rip), %rdi       # 0x3360
callq 0x2290
leaq -0x1510(%rbp), %r14
movl $0x1002, %edx           # imm = 0x1002
movq %r14, %rdi
xorl %esi, %esi
callq 0x2120
movq -0x40(%rbp), %r12
movq %r12, %rdi
xorl %esi, %esi
callq 0x27e1
movq %rax, %rbx
leaq -0x400(%rbp), %rsi
movl $0x100, %edi            # imm = 0x100
movq %r14, %rdx
movq %rax, %rcx
movl $0x1, %r8d
callq 0x2180
cmpl $-0x1, %eax
je 0x2e33
movl %eax, %r14d
movq %rbx, %rdi
callq 0x2200
cmpl $0x31, %r14d
jne 0x2e62
cmpb $0x20, -0x1500(%rbp)
jne 0x2e70
xorps %xmm0, %xmm0
leaq -0x100(%rbp), %rcx
movaps %xmm0, 0x70(%rcx)
movaps %xmm0, 0x60(%rcx)
movaps %xmm0, 0x50(%rcx)
movaps %xmm0, 0x40(%rcx)
movaps %xmm0, 0x30(%rcx)
movaps %xmm0, 0x20(%rcx)
movaps %xmm0, 0x10(%rcx)
movaps %xmm0, (%rcx)
leaq -0x180(%rbp), %rdx
movaps %xmm0, 0x70(%rdx)
movaps %xmm0, 0x60(%rdx)
movaps %xmm0, 0x50(%rdx)
movaps %xmm0, 0x40(%rdx)
movaps %xmm0, 0x30(%rdx)
movaps %xmm0, 0x20(%rdx)
movaps %xmm0, 0x10(%rdx)
movaps %xmm0, (%rdx)
leaq 0x433(%rip), %rsi       # 0x31c7
leaq -0x1510(%rbp), %rdi
xorl %eax, %eax
callq 0x21b0
cmpl $0x2, %eax
jne 0x2eb9
leaq 0x5d6(%rip), %rdi       # 0x3388
callq 0x2290
leaq 0x43a(%rip), %rdi       # 0x31f8
xorl %r15d, %r15d
leaq -0x70(%rbp), %rbx
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2060
leaq -0x100(%rbp), %rdi
leaq -0x180(%rbp), %rsi
leaq -0x300(%rbp), %rdx
leaq -0x34(%rbp), %r14
movq %r14, %rcx
movq %rbx, %r8
callq 0x2930
movl (%r14), %eax
cmpl -0x2c(%rbp), %eax
jne 0x2e1c
leaq 0x5a6(%rip), %rdi       # 0x33a8
callq 0x2290
leaq 0x41b(%rip), %rdi       # 0x3229
leaq -0x300(%rbp), %rsi
xorl %eax, %eax
callq 0x2060
movq %r13, %rdi
callq 0x2220
testq %r12, %r12
je 0x2e93
movq %r12, %rdi
callq 0x2240
jmp 0x2e93
movl $0x2, %edi
xorl %esi, %esi
callq 0x2100
callq 0x2250
leaq -0x100(%rbp), %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x20b0
leaq 0x33f(%rip), %rdi       # 0x319c
movq %rbx, %rsi
jmp 0x2e7e
leaq 0x557(%rip), %rdi       # 0x33c0
callq 0x2290
jmp 0x2e85
leaq 0x330(%rip), %rdi       # 0x31a7
leaq -0x1510(%rbp), %rsi
xorl %eax, %eax
callq 0x2060
movq %r13, %rdi
callq 0x2220
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movl %r15d, %eax
addq $0x14e8, %rsp           # imm = 0x14E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1f0(%rip), %rdi       # 0x309f
callq 0x21a0
jmp 0x2b66
leaq 0x30d(%rip), %rdi       # 0x31cd
leaq -0x1510(%rbp), %rsi
movl %eax, %edx
xorl %eax, %eax
callq 0x2060
jmp 0x2e85