Pārlūkot izejas kodu

finished implementation of extra encryption layer

cecylia 7 gadi atpakaļ
vecāks
revīzija
0d48c0f0aa
3 mainītis faili ar 113 papildinājumiem un 35 dzēšanām
  1. 84 23
      client/socks5proxy.c
  2. 15 4
      relay_station/crypto.c
  3. 14 8
      relay_station/relay.c

+ 84 - 23
client/socks5proxy.c

@@ -68,6 +68,12 @@ typedef struct super_data_st {
 
 static super_data *super;
 
+typedef struct data_block_st {
+	uint64_t count;
+	uint8_t *data;
+	struct data_block_st *next;
+} data_block;
+
 int main(void){
 	int listen_socket;
 	
@@ -77,7 +83,7 @@ int main(void){
 
 	mkfifo("OUS_out", 0666);
 
-	//randomly generate slitheen id
+	//generate Slitheen ID using Telex tagging method
 	uint8_t slitheen_id[SLITHEEN_ID_LEN];
 	RAND_bytes(slitheen_id, SLITHEEN_ID_LEN);
 	printf("Randomly generated slitheen id: ");
@@ -795,24 +801,24 @@ void *demultiplex_data(){
 	uint8_t *partial_block;
 	uint32_t partial_block_len = 0;
 	uint32_t resource_remaining = 0;
+	uint64_t expected_next_count = 1;
+	data_block *saved_data = NULL;
 
 	for(;;){
 		int32_t bytes_read = read(ous_fd, buffer, buffer_len-partial_block_len);
 		
 		if(bytes_read > 0){
 			int32_t bytes_remaining = bytes_read;
-			printf("Read in %d bytes from OUS_out\n", bytes_remaining);
+			//printf("Read in %d bytes from OUS_out\n", bytes_remaining);
 			p = buffer;
 
 			//the first value for a new resource will be the resource length,
 			//followed by a newline
 			if(resource_remaining > 0){
-				printf("Completing previously started resource. Reading in %d out of %d bytes remaining in resource\n", bytes_remaining, resource_remaining);
 				resource_remaining -= bytes_remaining;
 
 				if((bytes_remaining > 0) && (partial_block_len > 0)){
 					//process first part of slitheen info
-					printf("Completing previously read Slitheen block\n");
 					memmove(buffer+partial_block_len, buffer, bytes_read);
 					memcpy(buffer, partial_block, partial_block_len);
 					bytes_remaining += partial_block_len;
@@ -829,9 +835,6 @@ void *demultiplex_data(){
 					bytes_remaining -= (end_ptr - p) + 1;
 					p += (end_ptr - p) + 1;
 
-					printf("Reading in %d out of %d bytes of new resource\n",
-							bytes_remaining, resource_remaining);
-
 					if(resource_remaining < bytes_remaining){
 						resource_remaining = 0;
 						printf("UH OH, shouldn't be here\n");
@@ -869,14 +872,15 @@ void *demultiplex_data(){
 
 				struct slitheen_hdr *sl_hdr = (struct slitheen_hdr *) p;
 				//first see if sl_hdr corresponds to a valid stream. If not, ignore rest of read bytes
-//#ifdef DEBUG
+#ifdef DEBUG
 				printf("Slitheen header:\n");
 				int i;
 				for(i = 0; i< SLITHEEN_HEADER_LEN; i++){
 					printf("%02x ", p[i]);
 				}
 				printf("\n");
-//#endif
+#endif
+
 
 				if(ntohs(sl_hdr->len) > bytes_remaining){
 					printf("Received partial block\n");
@@ -891,9 +895,9 @@ void *demultiplex_data(){
 				bytes_remaining -= SLITHEEN_HEADER_LEN;
 
 				if((!sl_hdr->len) && (sl_hdr->garbage)){
-//#ifdef DEBUG
+#ifdef DEBUG
 					printf("%d Garbage bytes\n", ntohs(sl_hdr->garbage));
-//#endif
+#endif
 					p += ntohs(sl_hdr->garbage);
 					bytes_remaining -= ntohs(sl_hdr->garbage);
 					continue;
@@ -935,9 +939,58 @@ void *demultiplex_data(){
 					
 				p += 16; //IV
 
-				int32_t bytes_sent = write(pipe_fd, p, ntohs(sl_hdr->len) - padding);
-				if(bytes_sent <= 0){
-					printf("Error reading to pipe for stream id %d\n", sl_hdr->stream_id);
+				//check counter to see if we are missing data
+				if(sl_hdr->counter > expected_next_count){
+					//save any future data
+					printf("Received header with count %lu. Expected count %lu.\n",
+							sl_hdr->counter, expected_next_count);
+					if(saved_data == NULL){
+						saved_data = malloc(sizeof(data_block));
+						saved_data->count = sl_hdr->counter;
+						saved_data->data = malloc(ntohs(sl_hdr->len));
+						memcpy(saved_data->data, p, ntohs(sl_hdr->len));
+						saved_data->next = NULL;
+					} else {
+						data_block *last = saved_data;
+						while(last->next != NULL){
+							last = last->next;
+						}
+						data_block *new_block = malloc(sizeof(data_block));
+						new_block->count = sl_hdr->counter;
+						new_block->data = malloc(ntohs(sl_hdr->len));
+						memcpy(new_block->data, p, ntohs(sl_hdr->len));
+						new_block->next = NULL;
+
+						last->next = new_block;
+					}
+				} else {
+					int32_t bytes_sent = write(pipe_fd, p, ntohs(sl_hdr->len));
+					if(bytes_sent <= 0){
+						printf("Error reading to pipe for stream id %d\n",
+								sl_hdr->stream_id);
+					}
+
+					//increment expected counter
+					expected_next_count++;
+				}
+
+				//now check to see if there is saved data to write out
+				if(saved_data != NULL){
+					data_block *current_block = saved_data;
+					while((current_block != NULL) &&
+							(expected_next_count == current_block->count)){
+						printf("Writing out saved data with count %ld\n",
+								expected_next_count);
+						int32_t bytes_sent = write(pipe_fd, p, ntohs(sl_hdr->len));
+						if(bytes_sent <= 0){
+							printf("Error reading to pipe for stream id %d\n",
+									sl_hdr->stream_id);
+						}
+						expected_next_count++;
+						saved_data = current_block->next;
+						free(current_block);
+						current_block = saved_data;
+					}
 				}
 
 				p += ntohs(sl_hdr->len); //encrypted data
@@ -968,6 +1021,7 @@ void *demultiplex_data(){
 int super_decrypt(uint8_t *data){
 
 	EVP_CIPHER_CTX *bdy_ctx;
+	EVP_CIPHER_CTX *hdr_ctx;
 
 	uint8_t *p = data;
 	int32_t out_len, len;
@@ -975,18 +1029,31 @@ int super_decrypt(uint8_t *data){
 	size_t mac_len;
 	int i;
 
-	/*decrypt header
+	//decrypt header
+#ifdef DEBUG
 	printf("Encrypted header:\n");
 	for(i=0; i< SLITHEEN_HEADER_LEN; i++){
 		printf("%02x ", p[i]);
 	}
 	printf("\n");
+#endif
 
-	if(!EVP_CipherUpdate(super->header_ctx, p, &out_len, p, SLITHEEN_HEADER_LEN)){
+    hdr_ctx = EVP_CIPHER_CTX_new();
+
+    EVP_CipherInit_ex(hdr_ctx, EVP_aes_256_ecb(), NULL, super->header_key, NULL, 0);
+
+	if(!EVP_CipherUpdate(hdr_ctx, p, &out_len, p, SLITHEEN_HEADER_LEN)){
 		printf("Decryption failed!");
 		return 0;
 	}
-	*/
+
+	EVP_CIPHER_CTX_free(hdr_ctx);
+
+	struct slitheen_hdr *sl_hdr = (struct slitheen_hdr *) p;
+	len = htons(sl_hdr->len);
+	if(!sl_hdr->len){//there are no data to be decrypted
+		return 1;
+	}
 
 	printf("Decrypted header (%d bytes):\n", SLITHEEN_HEADER_LEN);
 	for(i=0; i< SLITHEEN_HEADER_LEN; i++){
@@ -995,12 +1062,6 @@ int super_decrypt(uint8_t *data){
 	printf("\n");
 	fflush(stdout);
 	
-	struct slitheen_hdr *sl_hdr = (struct slitheen_hdr *) p;
-	len = htons(sl_hdr->len);
-	if(!sl_hdr->len){//there are no data to be decrypted
-		return 1;
-	}
-
 	p += SLITHEEN_HEADER_LEN;
 
 	//compute mac

+ 15 - 4
relay_station/crypto.c

@@ -1022,6 +1022,9 @@ void generate_client_super_keys(uint8_t *secret, client *c){
 	int32_t total_len = 2*key_len + mac_len;
 	uint8_t *key_block = ecalloc(1, total_len);
 
+	//extract shared secret from SLITHEEN_ID
+	
+
 	PRF(NULL, secret, SLITHEEN_SUPER_SECRET_SIZE,
 			(uint8_t *) SLITHEEN_SUPER_CONST, SLITHEEN_SUPER_CONST_SIZE,
 			NULL, 0,
@@ -1081,7 +1084,7 @@ void generate_client_super_keys(uint8_t *secret, client *c){
 
 int super_encrypt(client *c, uint8_t *data, uint32_t len){
 
-	//EVP_CIPHER_CTX *hdr_ctx;
+	EVP_CIPHER_CTX *hdr_ctx;
 	EVP_CIPHER_CTX *bdy_ctx;
 	
 	int32_t out_len;
@@ -1090,14 +1093,18 @@ int super_encrypt(client *c, uint8_t *data, uint32_t len){
 
 	uint8_t output[EVP_MAX_MD_SIZE];
 
-	/*first encrypt the header	
+	//first encrypt the header	
 	printf("Plaintext Header:\n");
 	for(int i=0; i< SLITHEEN_HEADER_LEN; i++){
 		printf("%02x ", p[i]);
 	}
 	printf("\n");
 
-	if(!EVP_CipherUpdate(c->header_ctx, p, &out_len, p, SLITHEEN_HEADER_LEN)){
+	hdr_ctx = EVP_CIPHER_CTX_new();
+
+	EVP_CipherInit_ex(hdr_ctx, EVP_aes_256_cbc(), NULL, c->header_key, NULL, 1);
+	
+	if(!EVP_CipherUpdate(hdr_ctx, p, &out_len, p, SLITHEEN_HEADER_LEN)){
 		printf("Failed!\n");
 		return 0;
 	}
@@ -1107,7 +1114,10 @@ int super_encrypt(client *c, uint8_t *data, uint32_t len){
 		printf("%02x ", p[i]);
 	}
 	printf("\n");
-	*/
+
+	if(len == 0){ //only encrypt header: body contains garbage bytes
+		return 1;
+	}
 
 	//encrypt the body
 	p += SLITHEEN_HEADER_LEN;
@@ -1159,6 +1169,7 @@ int super_encrypt(client *c, uint8_t *data, uint32_t len){
 	}
 	printf("\n");
 	EVP_CIPHER_CTX_free(bdy_ctx);
+	EVP_CIPHER_CTX_free(hdr_ctx);
 
 	return 1;
 }

+ 14 - 8
relay_station/relay.c

@@ -679,14 +679,14 @@ void *proxy_covert_site(void *data){
 			int32_t bytes_read = read(thread_data->pipefd, buffer, buffer_len);
 
 			if(bytes_read > 0){
-#ifdef DEBUG
+//#ifdef DEBUG
 				printf("PROXY (id %d): read %d bytes from pipe\n", stream_id, bytes_read);
 				for(int i=0; i< bytes_read; i++){
 					printf("%02x ", buffer[i]);
 				}
 				printf("\n");
 				printf("%s\n", buffer);
-#endif
+//#endif
 				bytes_sent = send(handle, buffer,
 						bytes_read, 0);
 				if( bytes_sent <= 0){
@@ -708,13 +708,13 @@ void *proxy_covert_site(void *data){
 			if(bytes_read > 0){
 				uint8_t *new_data = emalloc(bytes_read);
 				memcpy(new_data, buffer, bytes_read);
-#ifdef DEBUG
+//#ifdef DEBUG
 				printf("PROXY (id %d): read %d bytes from censored site\n",stream_id, bytes_read);
 				for(int i=0; i< bytes_read; i++){
 					printf("%02x ", buffer[i]);
 				}
 				printf("\n");
-#endif
+//#endif
 
 				//make a new queue block
 				queue_block *new_block = emalloc(sizeof(queue_block));
@@ -1285,9 +1285,7 @@ int fill_with_downstream(flow *f, uint8_t *data, int32_t length){
 			p += padding;
 		}
 
-		//now encrypt
 		printf("Filled with %d bytes\n", sl_hdr->len);
-		super_encrypt(client_ptr, encrypted_data, sl_hdr->len + padding);
 		p += 16;
 		remaining -= 16;
 
@@ -1300,16 +1298,21 @@ int fill_with_downstream(flow *f, uint8_t *data, int32_t length){
 			remaining -= remaining;
 		}
 
+		int16_t data_len = sl_hdr->len;
 		sl_hdr->len = htons(sl_hdr->len);
 
+		//now encrypt
+		super_encrypt(client_ptr, encrypted_data, data_len + padding);
+
+
 //#ifdef DEBUG
 		printf("DWNSTRM: slitheen header: ");
 		for(int i=0; i< SLITHEEN_HEADER_LEN; i++){
 			printf("%02x ",((uint8_t *) sl_hdr)[i]);
 		}
 		printf("\n");
-		printf("Sending %d downstream bytes:", ntohs(sl_hdr->len));
-		for(int i=0; i< ntohs(sl_hdr->len)+16+16 + ntohs(sl_hdr->garbage); i++){
+		printf("Sending %d downstream bytes:", data_len);
+		for(int i=0; i< data_len+16+16; i++){
 			printf("%02x ", ((uint8_t *) sl_hdr)[i+SLITHEEN_HEADER_LEN]);
 		}
 		printf("\n");
@@ -1334,6 +1337,9 @@ int fill_with_downstream(flow *f, uint8_t *data, int32_t length){
 		printf("\n");
 //#endif
 
+		//encrypt slitheen header
+		super_encrypt(client_ptr, p, 0);
+
 		p += SLITHEEN_HEADER_LEN;
 		RAND_bytes(p, remaining);
 	} else if(remaining > 0){