189 lines
6.5 KiB
C
189 lines
6.5 KiB
C
|
|
#include "verify.h"
|
|
|
|
static int verify_simple_pack_unit_size = 2000;
|
|
|
|
typedef struct verify_simple_local_data {
|
|
char * recv_buffer;
|
|
int recv_buffer_size;
|
|
}verify_simple_local_data;
|
|
|
|
void verify_simple_local_data_init(verify_simple_local_data* local) {
|
|
local->recv_buffer = (char*)malloc(16384);
|
|
local->recv_buffer_size = 0;
|
|
}
|
|
|
|
obfs * verify_simple_new_obfs() {
|
|
obfs * self = new_obfs();
|
|
self->l_data = malloc(sizeof(verify_simple_local_data));
|
|
verify_simple_local_data_init((verify_simple_local_data*)self->l_data);
|
|
return self;
|
|
}
|
|
|
|
void verify_simple_dispose(obfs *self) {
|
|
verify_simple_local_data *local = (verify_simple_local_data*)self->l_data;
|
|
if (local->recv_buffer != NULL) {
|
|
free(local->recv_buffer);
|
|
local->recv_buffer = NULL;
|
|
}
|
|
free(local);
|
|
self->l_data = NULL;
|
|
dispose_obfs(self);
|
|
}
|
|
|
|
int verify_simple_pack_data(char *data, int datalength, char *outdata) {
|
|
unsigned char rand_len = (xorshift128plus() & 0xF) + 1;
|
|
int out_size = rand_len + datalength + 6;
|
|
outdata[0] = out_size >> 8;
|
|
outdata[1] = out_size;
|
|
outdata[2] = rand_len;
|
|
memmove(outdata + rand_len + 2, data, datalength);
|
|
fillcrc32((unsigned char *)outdata, out_size);
|
|
return out_size;
|
|
}
|
|
|
|
int verify_simple_client_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) {
|
|
char *plaindata = *pplaindata;
|
|
//verify_simple_local_data *local = (verify_simple_local_data*)self->l_data;
|
|
char * out_buffer = (char*)malloc(datalength * 2 + 32);
|
|
char * buffer = out_buffer;
|
|
char * data = plaindata;
|
|
int len = datalength;
|
|
int pack_len;
|
|
while ( len > verify_simple_pack_unit_size ) {
|
|
pack_len = verify_simple_pack_data(data, verify_simple_pack_unit_size, buffer);
|
|
buffer += pack_len;
|
|
data += verify_simple_pack_unit_size;
|
|
len -= verify_simple_pack_unit_size;
|
|
}
|
|
if (len > 0) {
|
|
pack_len = verify_simple_pack_data(data, len, buffer);
|
|
buffer += pack_len;
|
|
}
|
|
len = buffer - out_buffer;
|
|
if (*capacity < len) {
|
|
*pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2);
|
|
plaindata = *pplaindata;
|
|
}
|
|
memmove(plaindata, out_buffer, len);
|
|
free(out_buffer);
|
|
return len;
|
|
}
|
|
|
|
int verify_simple_client_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) {
|
|
char *plaindata = *pplaindata;
|
|
verify_simple_local_data *local = (verify_simple_local_data*)self->l_data;
|
|
uint8_t * recv_buffer = (uint8_t *)local->recv_buffer;
|
|
if (local->recv_buffer_size + datalength > 16384)
|
|
return -1;
|
|
memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength);
|
|
local->recv_buffer_size += datalength;
|
|
|
|
char * out_buffer = (char*)malloc(local->recv_buffer_size);
|
|
char * buffer = out_buffer;
|
|
while (local->recv_buffer_size > 2) {
|
|
int length = ((int)recv_buffer[0] << 8) | recv_buffer[1];
|
|
if (length >= 8192 || length < 7) {
|
|
free(out_buffer);
|
|
local->recv_buffer_size = 0;
|
|
return -1;
|
|
}
|
|
if (length > local->recv_buffer_size)
|
|
break;
|
|
|
|
int crc = crc32((unsigned char*)recv_buffer, length);
|
|
if (crc != -1) {
|
|
free(out_buffer);
|
|
local->recv_buffer_size = 0;
|
|
return -1;
|
|
}
|
|
int data_size = length - recv_buffer[2] - 6;
|
|
memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size);
|
|
buffer += data_size;
|
|
memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length);
|
|
}
|
|
int len = buffer - out_buffer;
|
|
if (*capacity < len) {
|
|
*pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2);
|
|
plaindata = *pplaindata;
|
|
}
|
|
memmove(plaindata, out_buffer, len);
|
|
free(out_buffer);
|
|
return len;
|
|
}
|
|
|
|
int verify_simple_server_pre_encrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) {
|
|
char *plaindata = *pplaindata;
|
|
//verify_simple_local_data *local = (verify_simple_local_data*)self->l_data;
|
|
char * out_buffer = (char*)malloc(datalength * 2 + 32);
|
|
char * buffer = out_buffer;
|
|
char * data = plaindata;
|
|
int len = datalength;
|
|
int pack_len;
|
|
while ( len > verify_simple_pack_unit_size ) {
|
|
pack_len = verify_simple_pack_data(data, verify_simple_pack_unit_size, buffer);
|
|
buffer += pack_len;
|
|
data += verify_simple_pack_unit_size;
|
|
len -= verify_simple_pack_unit_size;
|
|
}
|
|
if (len > 0) {
|
|
pack_len = verify_simple_pack_data(data, len, buffer);
|
|
buffer += pack_len;
|
|
}
|
|
len = buffer - out_buffer;
|
|
if (*capacity < len) {
|
|
*pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2);
|
|
plaindata = *pplaindata;
|
|
}
|
|
memmove(plaindata, out_buffer, len);
|
|
free(out_buffer);
|
|
return len;
|
|
}
|
|
|
|
int verify_simple_server_post_decrypt(obfs *self, char **pplaindata, int datalength, size_t *capacity) {
|
|
char *plaindata = *pplaindata;
|
|
verify_simple_local_data *local = (verify_simple_local_data*)self->l_data;
|
|
uint8_t * recv_buffer = (uint8_t *)local->recv_buffer;
|
|
if (local->recv_buffer_size + datalength > 16384)
|
|
{
|
|
LOGE("verify_simple: wrong buf length %d", local->recv_buffer_size + datalength);
|
|
return -1;
|
|
}
|
|
memmove(recv_buffer + local->recv_buffer_size, plaindata, datalength);
|
|
local->recv_buffer_size += datalength;
|
|
|
|
char * out_buffer = (char*)malloc(local->recv_buffer_size);
|
|
char * buffer = out_buffer;
|
|
while (local->recv_buffer_size > 2) {
|
|
int length = ((int)recv_buffer[0] << 8) | recv_buffer[1];
|
|
if (length >= 8192 || length < 7) {
|
|
free(out_buffer);
|
|
local->recv_buffer_size = 0;
|
|
LOGE("verify_simple: wrong length %d", length);
|
|
return -1;
|
|
}
|
|
if (length > local->recv_buffer_size)
|
|
break;
|
|
|
|
int crc = crc32((unsigned char*)recv_buffer, length);
|
|
if (crc != -1) {
|
|
free(out_buffer);
|
|
local->recv_buffer_size = 0;
|
|
LOGE("verify_simple: wrong crc");
|
|
return -1;
|
|
}
|
|
int data_size = length - recv_buffer[2] - 6;
|
|
memmove(buffer, recv_buffer + 2 + recv_buffer[2], data_size);
|
|
buffer += data_size;
|
|
memmove(recv_buffer, recv_buffer + length, local->recv_buffer_size -= length);
|
|
}
|
|
int len = buffer - out_buffer;
|
|
if (*capacity < len) {
|
|
*pplaindata = (char*)realloc(*pplaindata, *capacity = len * 2);
|
|
plaindata = *pplaindata;
|
|
}
|
|
memmove(plaindata, out_buffer, len);
|
|
free(out_buffer);
|
|
return len;
|
|
}
|