[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