[tor-commits] [stegotorus/master] b64 encoding support for http cookies

zwol at torproject.org zwol at torproject.org
Fri Jul 20 23:17:07 UTC 2012


commit 696648906b49690340ea16517060a932d61e1e2e
Author: Vinod Yegneswaran <vinod at safdef.isc.org>
Date:   Tue Feb 14 12:21:51 2012 -0800

    b64 encoding support for http cookies
---
 src/steg/b64cookies.cc |  233 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/steg/b64cookies.h  |   20 ++++
 src/steg/b64decode.cc  |   88 ++++++++++++++++++
 src/steg/b64decode.h   |   66 ++++++++++++++
 src/steg/b64encode.cc  |  139 ++++++++++++++++++++++++++++
 src/steg/b64encode.h   |   75 +++++++++++++++
 6 files changed, 621 insertions(+), 0 deletions(-)

diff --git a/src/steg/b64cookies.cc b/src/steg/b64cookies.cc
new file mode 100644
index 0000000..975c201
--- /dev/null
+++ b/src/steg/b64cookies.cc
@@ -0,0 +1,233 @@
+
+#include "b64cookies.h"
+#include <string.h>
+
+int unwrap_b64_cookie(char* inbuf, char* outbuf, int buflen) {
+  int i,j;
+  j = 0;
+
+  for (i=0; i < buflen; i++) {
+    char c  = inbuf[i];
+
+    if (c != ' ' && c != ';' && c != '=')
+      outbuf[j++] = c; 
+  }
+
+  return j;
+
+}
+
+
+
+
+
+int gen_one_b64cookie(char* outbuf, int& cookielen, char* data, int datalen) {
+  int sofar = 0;
+  int namelen;
+  int data_consumed = 0;
+
+  cookielen = 4 + rand() % (datalen - 3);
+  
+  if (cookielen > 13)
+    namelen = rand() % 10 + 1;
+  else 
+    namelen = rand() % (cookielen - 3) + 1;
+
+  
+  while (sofar < namelen) {
+    outbuf[sofar++] = data[data_consumed++];
+  }
+
+
+  outbuf[sofar++] = '=';
+
+  while (sofar < cookielen) {
+    outbuf[sofar++] = data[data_consumed++];
+  }
+  
+  return data_consumed;
+
+}
+
+
+
+
+/* returns length of cookie */ 
+int gen_b64_cookie_field(char* outbuf, char* data, int datalen) {
+  int onecookielen;
+  int consumed = 0;
+  int cookielen = 0;
+  
+  
+
+
+  while (datalen - consumed  > 0) {
+   int cnt = gen_one_b64cookie(outbuf, onecookielen, data + consumed, datalen - consumed);
+
+    if (cnt < 0) {
+      fprintf(stderr, "error: couldn't create cookie %d\n", cnt);
+      return cnt;
+    }
+
+    consumed += cnt;
+    outbuf += onecookielen;
+    cookielen += onecookielen;
+    
+    if (datalen - consumed < 5) {
+      memcpy(outbuf, data+consumed, datalen-consumed);
+      return cookielen + datalen - consumed;
+    }
+
+
+    if (datalen - consumed > 0) {
+      outbuf[0] = ';';
+      outbuf++;
+      cookielen++;
+    }
+  }
+
+
+  return cookielen;
+}
+
+
+
+void sanitize_b64(char* input, int len) {
+  char* i = strchr(input, '/');
+  int eqcnt = 0;
+
+  printf("len = %d\n", len);
+  
+  while (i != NULL) {
+    *i = '_';
+    i = strchr(i+1, '/');
+  }
+
+  i = strchr(input, '+');
+
+  while (i != NULL) {
+    *i = '.';
+    i = strchr(i+1, '+');
+  }
+
+  if (input[len-2] == '=')
+    eqcnt = 2;
+  else if (input[len-1] == '=')
+    eqcnt = 1;
+
+
+  while (eqcnt > 0) {
+    int pos = rand() % (len - 1) + 1;
+    if (pos >= len - eqcnt) {
+      input[pos] = '-';
+      eqcnt--;
+      continue;
+    }
+    
+    //shift characters up and insert '-' in the middle
+    for (int j=len-eqcnt; j > pos; j--)
+      input[j] = input[j-1];
+
+    input[pos] = '-';
+    eqcnt--;
+
+  }
+  
+}
+
+
+void desanitize_b64(char* input, int len) {
+  char* i = strchr(input, '_');
+
+
+  printf("len = %d\n", len);
+  while (i != NULL) {
+    *i = '/';
+    i = strchr(i+1, '_');
+  }
+
+  i = strchr(input, '.');
+
+  while (i != NULL) {
+    *i = '+';
+    i = strchr(i+1, '.');
+  }
+
+  
+  i = strchr(input, '-');
+  if (i != NULL) {
+    int j;
+    for (j=i-input; j < len-1; j++)
+      input[j] = input[j+1];
+    input[len-1] = '=';
+
+
+    i = strchr(input, '-');
+
+    if (i != NULL) {
+      for (j=i-input; j < len-2; j++)
+	input[j] = input[j+1];
+      input[len-2] = '=';
+    }
+    
+  }
+
+}
+
+
+
+
+
+// int main () {
+//   char outbuf[200];
+
+//   char data[56] = "ba239023820389023802380389abc2322132321932847203aedfasd";
+//   char data2[200];
+//   int cookielen;
+
+//   srand(time(NULL));
+
+//   bzero(data2, sizeof(data2));
+//   bzero(outbuf, sizeof(outbuf));
+
+//   base64::encoder E;
+//   E.encode(data, strlen(data), data2);
+//   E.encode_end(data2+strlen(data2));
+//   printf("%s", data2);
+//   // remove trailing newline
+//   data2[strlen(data2) - 1] = 0;
+
+//   // /* substitute / with _, + with ., = with - that maybe inserted anywhere in the middle */
+
+//   sanitize_b64(data2, strlen(data2));
+//   printf("%s\n", data2);
+
+//   cookielen = gen_b64_cookie_field((char*) outbuf, (char*) data2, strlen(data2));
+//   printf("cookie=%s\n", outbuf);
+
+//   bzero(data2, sizeof(data2));
+//   cookielen = unwrap_b64_cookie((char*) outbuf, (char*) data2, strlen(outbuf));
+
+
+//   desanitize_b64(data2, cookielen);
+//   printf("%s\n", data2);
+//   printf("%d\n", cookielen);
+
+//   data2[strlen(data2)] = '\n';
+
+
+//   bzero(outbuf, 200);
+
+
+  
+//   base64::decoder D;
+//   D.decode(data2, strlen(data2), outbuf);
+//   printf("%s\n", outbuf);
+
+
+
+// }
+
+
+
+
diff --git a/src/steg/b64cookies.h b/src/steg/b64cookies.h
new file mode 100644
index 0000000..d0c6e6d
--- /dev/null
+++ b/src/steg/b64cookies.h
@@ -0,0 +1,20 @@
+#ifndef _B64_COOKIES_H
+#define _B64_COOKIES_H
+
+
+
+#include <stdio.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <string.h>
+#include "b64encode.h"
+#include "b64decode.h"
+
+int unwrap_b64_cookie( char* inbuf,  char* outbuf, int buflen);
+int gen_b64_cookie_field( char* outbuf,  char* data, int datalen);
+int gen_one_b64cookie( char* outbuf, int& cookielen,  char* data, int datalen);
+void sanitize_b64(char* input, int len);
+void desanitize_b64(char* input, int len);
+
+
+#endif
diff --git a/src/steg/b64decode.cc b/src/steg/b64decode.cc
new file mode 100755
index 0000000..3beffba
--- /dev/null
+++ b/src/steg/b64decode.cc
@@ -0,0 +1,88 @@
+/*
+cdecoder.c - c source to a base64 decoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#include "b64decode.h"
+
+int base64_decode_value(char value_in)
+{
+	static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
+	static const char decoding_size = sizeof(decoding);
+	value_in -= 43;
+	if (value_in < 0 || value_in > decoding_size) return -1;
+	return decoding[(int)value_in];
+}
+
+void base64_init_decodestate(base64_decodestate* state_in)
+{
+	state_in->step = step_a;
+	state_in->plainchar = 0;
+}
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in)
+{
+	const char* codechar = code_in;
+	char* plainchar = plaintext_out;
+	char fragment;
+	
+	*plainchar = state_in->plainchar;
+	
+	switch (state_in->step)
+	{
+		while (1)
+		{
+	case step_a:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_a;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar    = (fragment & 0x03f) << 2;
+	case step_b:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_b;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar++ |= (fragment & 0x030) >> 4;
+			*plainchar    = (fragment & 0x00f) << 4;
+	case step_c:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_c;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar++ |= (fragment & 0x03c) >> 2;
+			*plainchar    = (fragment & 0x003) << 6;
+	case step_d:
+			do {
+				if (codechar == code_in+length_in)
+				{
+					state_in->step = step_d;
+					state_in->plainchar = *plainchar;
+					return plainchar - plaintext_out;
+				}
+				fragment = (char)base64_decode_value(*codechar++);
+			} while (fragment < 0);
+			*plainchar++   |= (fragment & 0x03f);
+		}
+	}
+	/* control should not reach here */
+	return plainchar - plaintext_out;
+}
+
diff --git a/src/steg/b64decode.h b/src/steg/b64decode.h
new file mode 100755
index 0000000..9514c87
--- /dev/null
+++ b/src/steg/b64decode.h
@@ -0,0 +1,66 @@
+/*
+cdecode.h - c header for a base64 decoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#ifndef BASE64_CDECODE_H
+#define BASE64_CDECODE_H
+
+#include <iostream>
+#include "b64encode.h"
+
+typedef enum
+{
+	step_a, step_b, step_c, step_d
+} base64_decodestep;
+
+typedef struct
+{
+	base64_decodestep step;
+	char plainchar;
+} base64_decodestate;
+
+void base64_init_decodestate(base64_decodestate* state_in);
+
+int base64_decode_value(char value_in);
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
+
+
+
+
+namespace base64
+{
+
+	struct decoder
+	{
+		base64_decodestate _state;
+		int _buffersize;
+
+		decoder(int buffersize_in = BUFFERSIZE)
+		: _buffersize(buffersize_in)
+		{
+		}
+
+		int decode(char value_in)
+		{
+
+		  return base64_decode_value(value_in);
+		}
+
+		int decode(const char* code_in, const int length_in, char* plaintext_out)
+	        {
+		  base64_init_decodestate(&_state);
+		  return base64_decode_block(code_in, length_in, plaintext_out, &_state);
+		}
+
+	};
+
+} // namespace base64
+
+
+
+
+#endif /* BASE64_CDECODE_H */
diff --git a/src/steg/b64encode.cc b/src/steg/b64encode.cc
new file mode 100755
index 0000000..1f1352d
--- /dev/null
+++ b/src/steg/b64encode.cc
@@ -0,0 +1,139 @@
+/*
+cencoder.c - c source to a base64 encoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+
+#include "b64encode.h"
+#include "b64decode.h"
+
+
+const int CHARS_PER_LINE = 72;
+
+void base64_init_encodestate(base64_encodestate* state_in)
+{
+	state_in->step = step_A;
+	state_in->result = 0;
+	state_in->stepcount = 0;
+}
+
+char base64_encode_value(char value_in)
+{
+	static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	if (value_in > 63) return '=';
+	return encoding[(int)value_in];
+}
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
+{
+	const char* plainchar = plaintext_in;
+	const char* const plaintextend = plaintext_in + length_in;
+	char* codechar = code_out;
+	char result;
+	char fragment;
+
+	result = state_in->result;
+
+	switch (state_in->step)
+	{
+		while (1)
+		{
+	case step_A:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_A;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result = (fragment & 0x0fc) >> 2;
+			*codechar++ = base64_encode_value(result);
+			result = (fragment & 0x003) << 4;
+	case step_B:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_B;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result |= (fragment & 0x0f0) >> 4;
+			*codechar++ = base64_encode_value(result);
+			result = (fragment & 0x00f) << 2;
+	case step_C:
+			if (plainchar == plaintextend)
+			{
+				state_in->result = result;
+				state_in->step = step_C;
+				return codechar - code_out;
+			}
+			fragment = *plainchar++;
+			result |= (fragment & 0x0c0) >> 6;
+			*codechar++ = base64_encode_value(result);
+			result  = (fragment & 0x03f) >> 0;
+			*codechar++ = base64_encode_value(result);
+			
+			++(state_in->stepcount);
+			if (state_in->stepcount == CHARS_PER_LINE/4)
+			{
+				*codechar++ = '\n';
+				state_in->stepcount = 0;
+			}
+		}
+	}
+
+
+		
+
+	/* control should not reach here */
+	return codechar - code_out;
+}
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
+{
+	char* codechar = code_out;
+	
+	switch (state_in->step)
+	{
+	case step_B:
+		*codechar++ = base64_encode_value(state_in->result);
+		*codechar++ = '=';
+		*codechar++ = '=';
+		break;
+	case step_C:
+		*codechar++ = base64_encode_value(state_in->result);
+		*codechar++ = '=';
+		break;
+	case step_A:
+		break;
+	}
+	*codechar++ = '\n';
+	
+	return codechar - code_out;
+}
+
+
+
+
+/*
+int main() {
+
+  char foo[12] = "AbcdwefA#";
+  char foo2[22];
+
+  base64::encoder E;
+ 
+  printf("%d\n", (int) strlen(foo));
+  E.encode(foo, strlen(foo), foo2);
+  printf("%s\n", foo2);
+  printf("%d\n", E.encode_end(foo2+strlen(foo2)));
+  printf("%s\n", foo2);
+
+  base64::decoder D;
+  D.decode(foo2, strlen(foo2), foo);
+  printf("%s\n", foo);
+}
+
+*/
diff --git a/src/steg/b64encode.h b/src/steg/b64encode.h
new file mode 100755
index 0000000..be8c666
--- /dev/null
+++ b/src/steg/b64encode.h
@@ -0,0 +1,75 @@
+/*
+cencode.h - c header for a base64 encoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+#ifndef BASE64_CENCODE_H
+#define BASE64_CENCODE_H
+#include <iostream>
+
+
+typedef enum
+{
+	step_A, step_B, step_C
+} base64_encodestep;
+
+typedef struct
+{
+	base64_encodestep step;
+	char result;
+	int stepcount;
+} base64_encodestate;
+
+void base64_init_encodestate(base64_encodestate* state_in);
+
+char base64_encode_value(char value_in);
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
+
+
+
+
+
+static int BUFFERSIZE = 16777216;
+
+namespace base64
+{
+
+	struct encoder
+	{
+		base64_encodestate _state;
+		int _buffersize;
+
+		encoder(int buffersize_in = BUFFERSIZE)
+		: _buffersize(buffersize_in)
+		{}
+
+		int encode(char value_in)
+		{
+		  		  
+		  return base64_encode_value(value_in);
+		}
+
+		int encode(const char* code_in, const int length_in, char* plaintext_out)
+		{
+		  base64_init_encodestate(&_state);
+		  
+		  return base64_encode_block(code_in, length_in, plaintext_out, &_state);
+		}
+
+		int encode_end(char* plaintext_out)
+		{
+			return base64_encode_blockend(plaintext_out, &_state);
+		}
+
+	};
+
+} // namespace base64
+
+
+
+#endif /* BASE64_CENCODE_H */





More information about the tor-commits mailing list