// File: luigix25[P]SSLP/client_files/client.cpp
// Function: initial_protocol(NetSocket&)
bool initial_protocol(NetSocket &server_socket){

	//read my certificate from file
	FILE* cacert_file = fopen(CERT_CLIENT_PATH, "r");
	if(!cacert_file){ cerr << "Error: cannot open file '" << CERT_CLIENT_PATH << "' (missing?)\n"; exit(1); }
	X509* client_cert = PEM_read_X509(cacert_file, NULL, NULL, NULL);
	fclose(cacert_file);
	if(!client_cert){ cerr << "Error: PEM_read_X509 returned NULL\n"; exit(1); }

	//serialize it

	unsigned char* cert_buf= NULL; 
	int cert_size = i2d_X509(client_cert, &cert_buf); 
	if(cert_size< 0) { /* handle error */ } 
	
	//send through the socket

	if(!server_socket.sendInt(cert_size)){
		X509_free(client_cert);
		OPENSSL_free(cert_buf);
		return false;
	} 								//chiedere perazzo


	if(!server_socket.sendData((const char*)cert_buf,cert_size)){
		OPENSSL_free(cert_buf);
		X509_free(client_cert);
		return false;
	} 

	OPENSSL_free(cert_buf);
	X509_free(client_cert);

	//I receive the server's certificate

	if(!server_socket.recvInt(cert_size)) 		return false;

	if(cert_size < 0 || cert_size > MAX_CERT_LENGTH)
		return false;

	char *server_cert_data = server_socket.recvData(cert_size);
	if(server_cert_data == NULL)
		return false;

	char *old_ptr = server_cert_data;

	X509 *server_cert = d2i_X509(NULL,(const unsigned char **)&server_cert_data,cert_size);
	delete[] old_ptr;


	if(!server_cert)
		return false;


	CertificateManager cm(CERT_CA_PATH,CERT_CA_CRL_PATH);
	if(!cm.verifyCertificate(server_cert)){
		cout<<"[Error] verifying certificate"<<endl;
		X509_free(server_cert);
		return false;
	}

	string name;
	if(!cm.extractCommonName(server_cert,name)){
		X509_free(server_cert);
		cout<<"[Error] extractCommonName"<<endl;
		return false;
	}

	if(name != SERVER_NAME){
		X509_free(server_cert);
		return false;
	}

	public_key_rsa.setKey(cm.extractPubKey(server_cert));
	X509_free(server_cert);


	cout<<"Connection established with: "<<name<<endl;

	DHManager dh(DH_PARAMS_PATH);
	int pub_key_len;
	char *pub_key = dh.generatePublicKey(pub_key_len);
	if(pub_key == NULL){
		exit(-1);
	}

	char *opponent_pub_key;
	int opponent_pub_key_len;

	RSASignManager sign(CLIENT_PRIVKEY_PATH);


	if(!server_socket.recvInt(opponent_pub_key_len)) 	return false;

	if(!sign.RSAUpdate((const char*)&opponent_pub_key_len,sizeof(uint32_t)))			return false;


	//add check to int received
	opponent_pub_key = server_socket.recvData(opponent_pub_key_len);
	if(opponent_pub_key == NULL)
		return false;

	if(!sign.RSAUpdate((const char*)opponent_pub_key,opponent_pub_key_len))			return false;

	if(!sign.RSAUpdate((const char*)&pub_key_len,sizeof(uint32_t)))			return false;
	if(!server_socket.sendInt(pub_key_len)) 			return false;

	if(!sign.RSAUpdate((const char*)pub_key,pub_key_len))			return false;
	if(!server_socket.sendData(pub_key,pub_key_len)) 	return false;

	delete[] pub_key;

	int key_length;
	char *simmetric_key = dh.computeSimmetricKey(opponent_pub_key,opponent_pub_key_len,key_length);

	delete[] opponent_pub_key;



	HashManager keys;
	keys.HashUpdate(simmetric_key,key_length);

	memset_s(simmetric_key,0,key_length);
	delete[] simmetric_key;

	char* digest_keys = keys.HashFinal();

	char AES_symmetric_key[AES_KEY_SIZE];
	memcpy(AES_symmetric_key,digest_keys,AES_KEY_SIZE);

	char HMAC_key[HMAC_KEY_SIZE];
	memcpy(HMAC_key,&digest_keys[HMAC_KEY_SIZE],HMAC_KEY_SIZE);

	memset_s(digest_keys,0,HASH_SIZE);
	delete[] digest_keys;

	KeyManager::setAESKey(AES_symmetric_key);
	KeyManager::setHMACKey(HMAC_key);

	memset_s(AES_symmetric_key,0,AES_KEY_SIZE);
	memset_s(HMAC_key,0,HMAC_KEY_SIZE);

	char *revc_IV = server_socket.recvData(AES_BLOCK);
	if(revc_IV == NULL){
		//delete robbba
		return false;
	}
	if(!sign.RSAUpdate((const char*)revc_IV,AES_BLOCK))			return false;



	KeyManager::setAESIV(revc_IV);
	delete[] revc_IV;

	RAND_poll();

	uint32_t local_nonce = 0;
	RAND_bytes((unsigned char*)&local_nonce,sizeof(uint32_t));

	Chunk c;
	EncryptedChunk ec;

	int remote_nonce_size; 
	if(!server_socket.recvInt(remote_nonce_size)) return false;

	if(!sign.RSAUpdate((const char*)&remote_nonce_size,sizeof(uint32_t)))			return false;


	char *recv_data = server_socket.recvData(remote_nonce_size);

	if(recv_data == NULL){
		//delete robba
		return false;
	}

	ec.setCipherText(recv_data);
	ec.size = remote_nonce_size;

	DecryptManager dm;
	if(!dm.DecryptUpdate(c,ec))			return false;
	if(!dm.DecryptFinal(c))				return false;

	int remote_nonce = c.getInt();

	if(!sign.RSAUpdate((const char*)&remote_nonce,sizeof(uint32_t)))			return false;

	//delete[] c.plaintext;
	//delete[] ec.ciphertext;

 	c.setInt(local_nonce);
	c.size = sizeof(uint32_t);

	EncryptManager em;
	if(!em.EncryptUpdate(ec,c)){
		return false;
	}

	if(!em.EncryptFinal(ec)) return false;

	if(!server_socket.sendInt(ec.size)) return false;
	
	if(!sign.RSAUpdate((const char*)&ec.size,sizeof(uint32_t)))			return false;
	if(!sign.RSAUpdate((const char*)&local_nonce,sizeof(uint32_t)))			return false;


	if(!server_socket.sendData(ec.getCipherText(),ec.size)){
		//delete robba
		return false;
	}

	uint32_t sign_final_len;
	char* sign_final = sign.RSAFinal(sign_final_len);
	if(sign_final == NULL) return false;

	HMACManager::setLocalNonce(local_nonce);
	HMACManager::setRemoteNonce(remote_nonce);

	if(!sendDataHMAC(server_socket,sign_final,sign_final_len))			return false;

	int32_t received_sign_len;
	char *received_sign = recvDataHMAC(server_socket,received_sign_len);
	if(received_sign == NULL)
		return false;

	RSAVerifyManager verify(public_key_rsa);
	if(!verify.RSAUpdate(sign_final,sign_final_len)){
		delete[] sign_final;
		return false;
	}

	int result = verify.RSAFinal(received_sign);

	delete[] received_sign;

	delete[] sign_final;

	return result;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x300, %rsp            # imm = 0x300
movq %rdi, -0x10(%rbp)
leaq 0x7f54(%rip), %rdi      # 0xe22a
leaq 0x804c(%rip), %rsi      # 0xe329
callq 0x45f0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x6328
movq 0xccf4(%rip), %rdi      # 0x12fe8
leaq 0x7f50(%rip), %rsi      # 0xe24b
callq 0x44a0
movq %rax, %rdi
leaq 0x7f20(%rip), %rsi      # 0xe22a
callq 0x44a0
movq %rax, %rdi
leaq 0x7f4c(%rip), %rsi      # 0xe265
callq 0x44a0
movl $0x1, %edi
callq 0x4640
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x4730
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x44b0
cmpq $0x0, -0x20(%rbp)
jne 0x636c
movq 0xcc92(%rip), %rdi      # 0x12fe8
leaq 0x7f16(%rip), %rsi      # 0xe273
callq 0x44a0
movl $0x1, %edi
callq 0x4640
movq $0x0, -0x28(%rbp)
movq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x43a0
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
jge 0x638c
jmp 0x638c
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0x7e90
testb $0x1, %al
jne 0x63c3
movq -0x20(%rbp), %rdi
callq 0x4250
movq -0x28(%rbp), %rdi
leaq 0x7ee7(%rip), %rsi      # 0xe297
movl $0x11a, %edx            # imm = 0x11A
callq 0x4330
movb $0x0, -0x1(%rbp)
jmp 0x7210
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x8060
testb $0x1, %al
jne 0x63fe
movq -0x28(%rbp), %rdi
leaq 0x7eb5(%rip), %rsi      # 0xe297
movl $0x120, %edx            # imm = 0x120
callq 0x4330
movq -0x20(%rbp), %rdi
callq 0x4250
movb $0x0, -0x1(%rbp)
jmp 0x7210
movq -0x28(%rbp), %rdi
leaq 0x7e8e(%rip), %rsi      # 0xe297
movl $0x125, %edx            # imm = 0x125
callq 0x4330
movq -0x20(%rbp), %rdi
callq 0x4250
movq -0x10(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x8100
testb $0x1, %al
jne 0x6436
movb $0x0, -0x1(%rbp)
jmp 0x7210
cmpl $0x0, -0x2c(%rbp)
jl 0x6445
cmpl $0xbb8, -0x2c(%rbp)     # imm = 0xBB8
jle 0x644e
movb $0x0, -0x1(%rbp)
jmp 0x7210
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0x8090
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x646e
movb $0x0, -0x1(%rbp)
jmp 0x7210
movq -0x38(%rbp), %rax
movq %rax, -0x40(%rbp)
movslq -0x2c(%rbp), %rdx
xorl %eax, %eax
movl %eax, %edi
leaq -0x38(%rbp), %rsi
callq 0x40e0
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x1d0(%rbp)
cmpq $0x0, %rax
je 0x64a8
movq -0x1d0(%rbp), %rdi
callq 0x46d0
cmpq $0x0, -0x48(%rbp)
jne 0x64b8
movb $0x0, -0x1(%rbp)
jmp 0x7210
leaq 0x7df0(%rip), %rsi      # 0xe2af
leaq 0x7e06(%rip), %rdx      # 0xe2cc
leaq -0x50(%rbp), %rdi
movq %rdi, -0x1e0(%rbp)
callq 0xc4c0
movq -0x1e0(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0xc840
movb %al, -0x1d1(%rbp)
jmp 0x64ee
movb -0x1d1(%rbp), %al
testb $0x1, %al
jne 0x6557
jmp 0x64fa
movq 0xcab7(%rip), %rdi      # 0x12fb8
leaq 0x7de0(%rip), %rsi      # 0xe2e8
callq 0x44a0
movq %rax, -0x1e8(%rbp)
jmp 0x6516
movq -0x1e8(%rbp), %rdi
movq 0xca84(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0x652b
movq -0x48(%rbp), %rdi
callq 0x4250
jmp 0x6536
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x7205
leaq -0x80(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x4780
movq -0x1f8(%rbp), %rdx
movq -0x48(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xc9e0
movb %al, -0x1e9(%rbp)
jmp 0x6583
movb -0x1e9(%rbp), %al
testb $0x1, %al
jne 0x65ec
jmp 0x658f
movq -0x48(%rbp), %rdi
callq 0x4250
jmp 0x659a
movq 0xca17(%rip), %rdi      # 0x12fb8
leaq 0x7d5e(%rip), %rsi      # 0xe306
callq 0x44a0
movq %rax, -0x200(%rbp)
jmp 0x65b6
movq -0x200(%rbp), %rdi
movq 0xc9e4(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0x65cb
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x71ef
leaq 0x7d2d(%rip), %rsi      # 0xe320
leaq -0x80(%rbp), %rdi
callq 0x78f0
movb %al, -0x201(%rbp)
jmp 0x6604
movb -0x201(%rbp), %al
testb $0x1, %al
jne 0x6610
jmp 0x662b
movq -0x48(%rbp), %rdi
callq 0x4250
jmp 0x661b
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71e4
movq -0x48(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xcb10
movq %rax, -0x210(%rbp)
jmp 0x6641
movq -0x210(%rbp), %rsi
leaq 0xcfc9(%rip), %rdi      # 0x13618
callq 0xd5e0
jmp 0x6656
movq -0x48(%rbp), %rdi
callq 0x4250
jmp 0x6661
movq 0xc950(%rip), %rdi      # 0x12fb8
leaq 0x7cbc(%rip), %rsi      # 0xe32b
callq 0x44a0
movq %rax, -0x218(%rbp)
jmp 0x667d
movq -0x218(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x4470
movq %rax, -0x220(%rbp)
jmp 0x6696
movq -0x220(%rbp), %rdi
movq 0xc904(%rip), %rsi      # 0x12fa8
callq 0x4500
jmp 0x66ab
leaq 0x7c97(%rip), %rsi      # 0xe349
leaq -0x88(%rbp), %rdi
callq 0xd050
jmp 0x66c0
leaq -0x88(%rbp), %rdi
leaq -0x8c(%rbp), %rsi
callq 0xd180
movq %rax, -0x228(%rbp)
jmp 0x66dc
movq -0x228(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0x670f
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x4640
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x71d6
leaq 0x7a9a(%rip), %rsi      # 0xe1b0
leaq -0xd8(%rbp), %rdi
callq 0xaff0
jmp 0x6724
movq -0x10(%rbp), %rdi
leaq -0xa4(%rbp), %rsi
callq 0x8100
movb %al, -0x229(%rbp)
jmp 0x673c
movb -0x229(%rbp), %al
testb $0x1, %al
jne 0x6769
jmp 0x6748
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x71ca
leaq -0xd8(%rbp), %rdi
leaq -0xa4(%rbp), %rsi
movl $0x4, %edx
callq 0xb120
movb %al, -0x22a(%rbp)
jmp 0x6789
movb -0x22a(%rbp), %al
testb $0x1, %al
jne 0x67a5
jmp 0x6795
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq -0x10(%rbp), %rdi
movl -0xa4(%rbp), %esi
callq 0x8090
movq %rax, -0x238(%rbp)
jmp 0x67bd
movq -0x238(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0xa0(%rbp)
jne 0x67e5
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq -0xa0(%rbp), %rsi
movl -0xa4(%rbp), %edx
leaq -0xd8(%rbp), %rdi
callq 0xb120
movb %al, -0x239(%rbp)
jmp 0x6806
movb -0x239(%rbp), %al
testb $0x1, %al
jne 0x6822
jmp 0x6812
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
leaq -0xd8(%rbp), %rdi
leaq -0x8c(%rbp), %rsi
movl $0x4, %edx
callq 0xb120
movb %al, -0x23a(%rbp)
jmp 0x6842
movb -0x23a(%rbp), %al
testb $0x1, %al
jne 0x685e
jmp 0x684e
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq -0x10(%rbp), %rdi
movl -0x8c(%rbp), %esi
callq 0x7e90
movb %al, -0x23b(%rbp)
jmp 0x6875
movb -0x23b(%rbp), %al
testb $0x1, %al
jne 0x6891
jmp 0x6881
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq -0x98(%rbp), %rsi
movl -0x8c(%rbp), %edx
leaq -0xd8(%rbp), %rdi
callq 0xb120
movb %al, -0x23c(%rbp)
jmp 0x68b2
movb -0x23c(%rbp), %al
testb $0x1, %al
jne 0x68ce
jmp 0x68be
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq -0x10(%rbp), %rdi
movq -0x98(%rbp), %rsi
movl -0x8c(%rbp), %edx
callq 0x8060
movb %al, -0x23d(%rbp)
jmp 0x68ec
movb -0x23d(%rbp), %al
testb $0x1, %al
jne 0x6908
jmp 0x68f8
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x71b0
movq -0x98(%rbp), %rax
movq %rax, -0x248(%rbp)
cmpq $0x0, %rax
je 0x6928
movq -0x248(%rbp), %rdi
callq 0x46d0
movq -0xa0(%rbp), %rsi
movl -0xa4(%rbp), %edx
leaq -0x88(%rbp), %rdi
leaq -0xdc(%rbp), %rcx
callq 0xd260
movq %rax, -0x250(%rbp)
jmp 0x6951
movq -0x250(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x258(%rbp)
cmpq $0x0, %rax
je 0x697f
movq -0x258(%rbp), %rdi
callq 0x46d0
leaq -0xf0(%rbp), %rdi
callq 0xd440
jmp 0x698d
movq -0xe8(%rbp), %rsi
movl -0xdc(%rbp), %edx
leaq -0xf0(%rbp), %rdi
callq 0xd4a0
jmp 0x69a8
movq -0xe8(%rbp), %rdi
movl -0xdc(%rbp), %edx
xorl %esi, %esi
callq 0x8af0
jmp 0x69be
movq -0xe8(%rbp), %rax
movq %rax, -0x260(%rbp)
cmpq $0x0, %rax
je 0x69de
movq -0x260(%rbp), %rdi
callq 0x46d0
leaq -0xf0(%rbp), %rdi
callq 0xd4f0
movq %rax, -0x268(%rbp)
jmp 0x69f3
movq -0x268(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0xf8(%rbp), %rax
movups (%rax), %xmm0
movaps %xmm0, -0x110(%rbp)
movq -0xf8(%rbp), %rax
movups 0x10(%rax), %xmm0
movaps %xmm0, -0x120(%rbp)
movq -0xf8(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x8af0
jmp 0x6a39
movq -0xf8(%rbp), %rax
movq %rax, -0x270(%rbp)
cmpq $0x0, %rax
je 0x6a59
movq -0x270(%rbp), %rdi
callq 0x46d0
leaq -0x110(%rbp), %rdi
callq 0xd330
jmp 0x6a67
leaq -0x120(%rbp), %rdi
callq 0xd390
jmp 0x6a75
leaq -0x110(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x8af0
jmp 0x6a8a
leaq -0x120(%rbp), %rdi
xorl %esi, %esi
movl $0x10, %edx
callq 0x8af0
jmp 0x6a9f
movq -0x10(%rbp), %rdi
movl $0x10, %esi
callq 0x8090
movq %rax, -0x278(%rbp)
jmp 0x6ab6
movq -0x278(%rbp), %rax
movq %rax, -0x128(%rbp)
cmpq $0x0, -0x128(%rbp)
jne 0x6aef
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7194
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x71a2
movq -0x128(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
movl $0x10, %edx
callq 0xb120
movb %al, -0x279(%rbp)
jmp 0x6b0f
movb -0x279(%rbp), %al
testb $0x1, %al
jne 0x6b2b
jmp 0x6b1b
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7194
movq -0x128(%rbp), %rdi
callq 0xd360
jmp 0x6b39
movq -0x128(%rbp), %rax
movq %rax, -0x288(%rbp)
cmpq $0x0, %rax
je 0x6b59
movq -0x288(%rbp), %rdi
callq 0x46d0
callq 0x47b0
jmp 0x6b60
movl $0x0, -0x12c(%rbp)
leaq -0x12c(%rbp), %rdi
movl $0x4, %esi
callq 0x47d0
jmp 0x6b7d
leaq -0x148(%rbp), %rdi
callq 0xd6b0
jmp 0x6b8b
leaq -0x160(%rbp), %rdi
callq 0xd860
jmp 0x6b99
movq -0x10(%rbp), %rdi
leaq -0x164(%rbp), %rsi
callq 0x8100
movb %al, -0x289(%rbp)
jmp 0x6bb1
movb -0x289(%rbp), %al
testb $0x1, %al
jne 0x6bef
jmp 0x6bbd
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7160
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x7186
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x717a
leaq -0xd8(%rbp), %rdi
leaq -0x164(%rbp), %rsi
movl $0x4, %edx
callq 0xb120
movb %al, -0x28a(%rbp)
jmp 0x6c0f
movb -0x28a(%rbp), %al
testb $0x1, %al
jne 0x6c2b
jmp 0x6c1b
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7160
movq -0x10(%rbp), %rdi
movl -0x164(%rbp), %esi
callq 0x8090
movq %rax, -0x298(%rbp)
jmp 0x6c43
movq -0x298(%rbp), %rax
movq %rax, -0x170(%rbp)
cmpq $0x0, -0x170(%rbp)
jne 0x6c6b
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7160
movq -0x170(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0xd930
jmp 0x6c80
movl -0x164(%rbp), %eax
movl %eax, -0x150(%rbp)
leaq -0x178(%rbp), %rdi
callq 0xa600
jmp 0x6c9a
leaq -0x178(%rbp), %rdi
leaq -0x148(%rbp), %rsi
leaq -0x160(%rbp), %rdx
callq 0xa700
movb %al, -0x299(%rbp)
jmp 0x6cbc
movb -0x299(%rbp), %al
testb $0x1, %al
jne 0x6ce9
jmp 0x6cc8
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7144
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x7152
leaq -0x178(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0xa8c0
movb %al, -0x29a(%rbp)
jmp 0x6d04
movb -0x29a(%rbp), %al
testb $0x1, %al
jne 0x6d20
jmp 0x6d10
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7144
leaq -0x148(%rbp), %rdi
callq 0xd840
movl %eax, -0x2a0(%rbp)
jmp 0x6d34
movl -0x2a0(%rbp), %eax
movl %eax, -0x17c(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0x17c(%rbp), %rsi
movl $0x4, %edx
callq 0xb120
movb %al, -0x2a1(%rbp)
jmp 0x6d60
movb -0x2a1(%rbp), %al
testb $0x1, %al
jne 0x6d7c
jmp 0x6d6c
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7144
leaq -0x148(%rbp), %rdi
leaq -0x12c(%rbp), %rsi
callq 0xd800
jmp 0x6d91
movl $0x4, -0x138(%rbp)
leaq -0x188(%rbp), %rdi
callq 0xa300
jmp 0x6da9
leaq -0x188(%rbp), %rdi
leaq -0x160(%rbp), %rsi
leaq -0x148(%rbp), %rdx
callq 0xa490
movb %al, -0x2a2(%rbp)
jmp 0x6dcb
movb -0x2a2(%rbp), %al
testb $0x1, %al
jne 0x6df8
jmp 0x6dd7
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x7136
leaq -0x188(%rbp), %rdi
leaq -0x160(%rbp), %rsi
callq 0xa550
movb %al, -0x2a3(%rbp)
jmp 0x6e13
movb -0x2a3(%rbp), %al
testb $0x1, %al
jne 0x6e2f
jmp 0x6e1f
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
movq -0x10(%rbp), %rdi
movl -0x150(%rbp), %esi
callq 0x7e90
movb %al, -0x2a4(%rbp)
jmp 0x6e46
movb -0x2a4(%rbp), %al
testb $0x1, %al
jne 0x6e62
jmp 0x6e52
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
leaq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
movl $0x4, %edx
callq 0xb120
movb %al, -0x2a5(%rbp)
jmp 0x6e82
movb -0x2a5(%rbp), %al
testb $0x1, %al
jne 0x6e9e
jmp 0x6e8e
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
leaq -0xd8(%rbp), %rdi
leaq -0x12c(%rbp), %rsi
movl $0x4, %edx
callq 0xb120
movb %al, -0x2a6(%rbp)
jmp 0x6ebe
movb -0x2a6(%rbp), %al
testb $0x1, %al
jne 0x6eda
jmp 0x6eca
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
movq -0x10(%rbp), %rax
movq %rax, -0x2b8(%rbp)
leaq -0x160(%rbp), %rdi
callq 0xd970
movq %rax, -0x2b0(%rbp)
jmp 0x6efa
movq -0x2b0(%rbp), %rsi
movq -0x2b8(%rbp), %rdi
movl -0x150(%rbp), %edx
callq 0x8060
movb %al, -0x2b9(%rbp)
jmp 0x6f1b
movb -0x2b9(%rbp), %al
testb $0x1, %al
jne 0x6f37
jmp 0x6f27
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
leaq -0xd8(%rbp), %rdi
leaq -0x18c(%rbp), %rsi
callq 0xb1f0
movq %rax, -0x2c8(%rbp)
jmp 0x6f53
movq -0x2c8(%rbp), %rax
movq %rax, -0x198(%rbp)
cmpq $0x0, -0x198(%rbp)
jne 0x6f7b
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
movl -0x12c(%rbp), %edi
callq 0xac20
jmp 0x6f88
movl -0x17c(%rbp), %edi
callq 0xac50
jmp 0x6f95
movq -0x10(%rbp), %rdi
movq -0x198(%rbp), %rsi
movl -0x18c(%rbp), %edx
callq 0x87a0
movb %al, -0x2c9(%rbp)
jmp 0x6fb3
movb -0x2c9(%rbp), %al
testb $0x1, %al
jne 0x6fcf
jmp 0x6fbf
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
movq -0x10(%rbp), %rdi
leaq -0x19c(%rbp), %rsi
callq 0x88c0
movq %rax, -0x2d8(%rbp)
jmp 0x6fe8
movq -0x2d8(%rbp), %rax
movq %rax, -0x1a8(%rbp)
cmpq $0x0, -0x1a8(%rbp)
jne 0x7010
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x7128
leaq 0xc601(%rip), %rsi      # 0x13618
leaq -0x1c0(%rbp), %rdi
callq 0xada0
jmp 0x7025
movq -0x198(%rbp), %rsi
movl -0x18c(%rbp), %edx
leaq -0x1c0(%rbp), %rdi
callq 0xae90
movb %al, -0x2d9(%rbp)
jmp 0x7046
movb -0x2d9(%rbp), %al
testb $0x1, %al
jne 0x709f
jmp 0x7052
movq -0x198(%rbp), %rax
movq %rax, -0x2e8(%rbp)
cmpq $0x0, %rax
je 0x7072
movq -0x2e8(%rbp), %rdi
callq 0x46d0
movb $0x0, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x711c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0xaf90
jmp 0x7136
movq -0x1a8(%rbp), %rsi
leaq -0x1c0(%rbp), %rdi
callq 0xaf40
movl %eax, -0x2ec(%rbp)
jmp 0x70ba
movl -0x2ec(%rbp), %eax
movl %eax, -0x1c4(%rbp)
movq -0x1a8(%rbp), %rax
movq %rax, -0x2f8(%rbp)
cmpq $0x0, %rax
je 0x70e6
movq -0x2f8(%rbp), %rdi
callq 0x46d0
movq -0x198(%rbp), %rax
movq %rax, -0x300(%rbp)
cmpq $0x0, %rax
je 0x7106
movq -0x300(%rbp), %rdi
callq 0x46d0
cmpl $0x0, -0x1c4(%rbp)
setne %al
andb $0x1, %al
movb %al, -0x1(%rbp)
movl $0x1, -0x60(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0xaf90
leaq -0x188(%rbp), %rdi
callq 0xa3d0
jmp 0x7144
leaq -0x188(%rbp), %rdi
callq 0xa3d0
jmp 0x7152
leaq -0x178(%rbp), %rdi
callq 0xa6d0
jmp 0x7160
leaq -0x178(%rbp), %rdi
callq 0xa6d0
jmp 0x717a
leaq -0x160(%rbp), %rdi
callq 0xd880
leaq -0x148(%rbp), %rdi
callq 0xd6d0
jmp 0x7194
leaq -0x160(%rbp), %rdi
callq 0xd880
leaq -0x148(%rbp), %rdi
callq 0xd6d0
jmp 0x71a2
leaq -0xf0(%rbp), %rdi
callq 0xd570
jmp 0x71b0
leaq -0xf0(%rbp), %rdi
callq 0xd570
jmp 0x71ca
leaq -0xd8(%rbp), %rdi
callq 0xb370
leaq -0x88(%rbp), %rdi
callq 0xd300
jmp 0x71e4
leaq -0xd8(%rbp), %rdi
callq 0xb370
leaq -0x88(%rbp), %rdi
callq 0xd300
jmp 0x71ef
leaq -0x80(%rbp), %rdi
callq 0x42b0
jmp 0x71fa
leaq -0x80(%rbp), %rdi
callq 0x42b0
jmp 0x7205
leaq -0x50(%rbp), %rdi
callq 0xc810
jmp 0x7210
leaq -0x50(%rbp), %rdi
callq 0xc810
jmp 0x721e
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x300, %rsp            # imm = 0x300
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x4900
nopw (%rax,%rax)