commit d2f65a45028ba2c2d808b2002babdb1e83ecf92e Author: George Kadianakis desnacked@gmail.com Date: Thu Mar 17 22:21:42 2011 +0100
* Moved crypt.{c,h} to the plugins directory, since it's obfs2 stuff. * Stripped off dependencies to obfs2 from the obfsproxy code. --- Makefile.am | 8 +- src/crypt.c | 206 ------------------------------------------ src/crypt.h | 62 ------------- src/main.c | 1 - src/network.c | 9 ++- src/plugins/obfs2.c | 15 +++- src/plugins/obfs2.h | 2 +- src/plugins/obfs2_crypt.c | 206 ++++++++++++++++++++++++++++++++++++++++++ src/plugins/obfs2_crypt.h | 62 +++++++++++++ src/protocol.c | 11 +-- src/protocol.h | 2 +- src/socks.c | 3 +- src/test/unittest.c | 2 +- src/test/unittest_crypt.c | 2 +- src/test/unittest_protocol.c | 2 +- src/test/unittest_socks.c | 2 +- 16 files changed, 300 insertions(+), 295 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 9376df3..67cd34d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,12 +8,12 @@ noinst_LIBRARIES = libobfsproxy.a noinst_PROGRAMS = unittests
libobfsproxy_a_SOURCES = \ - src/crypt.c \ src/network.c \ src/protocol.c \ src/socks.c \ src/util.c \ - src/plugins/obfs2.c + src/plugins/obfs2.c \ + src/plugins/obfs2_crypt.c
obfsproxy_SOURCES = \ src/main.c @@ -28,14 +28,14 @@ unittests_SOURCES = \ unittests_LDADD = @libevent_LIBS@ @openssl_LIBS@ libobfsproxy.a
noinst_HEADERS = \ - src/crypt.h \ src/network.h \ src/protocol.h \ src/socks.h \ src/util.h \ src/test/tinytest.h \ src/test/tinytest_macros.h \ - src/plugins/obfs2.h + src/plugins/obfs2.h \ + src/plugins/obfs2_crypt.h
EXTRA_DIST = doc/protocol-spec.txt src/sha256.c
diff --git a/src/crypt.c b/src/crypt.c deleted file mode 100644 index 1192364..0000000 --- a/src/crypt.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright 2011 Nick Mathewson - - You may do anything with this work that copyright law would normally - restrict, so long as you retain the above notice(s) and this license - in all redistributed copies and derived works. There is no warranty. -*/ - -#include "config.h" - -#include <assert.h> -#include <string.h> -#include <stdlib.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif - -#include <openssl/opensslv.h> -#include <openssl/aes.h> -#include <openssl/rand.h> -#include <openssl/err.h> - -#define CRYPT_PRIVATE -#include "crypt.h" - -#if OPENSSL_VERSION_NUMBER >= 0x0090800f -#define USE_OPENSSL_RANDPOLL 1 -#define USE_OPENSSL_SHA256 1 -#include <openssl/sha.h> -#else -#define STMT_BEGIN do { -#define STMT_END } while (0) -static void -set_uint32(void *ptr, uint32_t val) -{ - memcpy(ptr, &val, 4); -} -static uint32_t -get_uint32(const void *ptr) -{ - uint32_t val; - memcpy(&val, ptr, 4); - return val; -} -#define LTC_ARGCHK(x) assert((x)) -#include "sha256.c" -#endif - -int -initialize_crypto(void) -{ - ERR_load_crypto_strings(); - -#ifdef USE_OPENSSL_RANDPOLL - return RAND_poll() == 1 ? 0 : -1; -#else - /* XXX Or maybe fall back to the arc4random implementation in libevent2? */ - { - char buf[32]; - int fd, n; - fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) { - perror("open"); - return -1; - } - n = read(fd, buf, sizeof(buf)); - if (n != sizeof(buf)) { - close(fd); - return -1; - } - RAND_seed(buf, sizeof(buf)); - close(fd); - return 0; - } -#endif -} - -void -cleanup_crypto(void) -{ - ERR_free_strings(); -} - -/* ===== - Digests - ===== */ - -#ifdef USE_OPENSSL_SHA256 -struct digest_t { - SHA256_CTX ctx; -}; -digest_t * -digest_new(void) -{ - digest_t *d = malloc(sizeof(digest_t)); - SHA256_Init(&d->ctx); - return d; -} -void -digest_update(digest_t *d, const uchar *buf, size_t len) -{ - SHA256_Update(&d->ctx, buf, len); -} -size_t -digest_getdigest(digest_t *d, uchar *buf, size_t len) -{ - uchar tmp[32]; - int n = 32; - SHA256_Final(tmp, &d->ctx); - if (len < 32) - n = len; - memcpy(buf, tmp, n); - memset(tmp, 0, sizeof(tmp)); - return n; -} -#else -struct digest_t { - sha256_state ctx; -}; -digest_t * -digest_new(void) -{ - digest_t *d = malloc(sizeof(digest_t)); - sha256_init(&d->ctx); - return d; -} -void -digest_update(digest_t *d, const uchar *buf, size_t len) -{ - sha256_process(&d->ctx, buf, len); -} -size_t -digest_getdigest(digest_t *d, uchar *buf, size_t len) -{ - uchar tmp[32]; - int n = 32; - sha256_done(&d->ctx, tmp); - if (len < 32) - n = len; - memcpy(buf, tmp, n); - memset(tmp, 0, sizeof(tmp)); - return n; -} -#endif - -void -digest_free(digest_t *d) -{ - memset(d, 0, sizeof(digest_t)); - free(d); -} - -/* ===== - Stream crypto - ===== */ - -crypt_t * -crypt_new(const uchar *key, size_t keylen) -{ - crypt_t *k; - if (keylen < AES_BLOCK_SIZE) - return NULL; - - k = calloc(1, sizeof(crypt_t)); - if (k == NULL) - return NULL; - - AES_set_encrypt_key(key, 128, &k->key); - - return k; -} -void -crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen) -{ - assert(ivlen == sizeof(key->ivec)); - memcpy(key->ivec, iv, ivlen); -} -void -stream_crypt(crypt_t *key, uchar *buf, size_t len) -{ - AES_ctr128_encrypt(buf, buf, /* XXX make sure this is okay to do. */ - len, - &key->key, key->ivec, key->ecount_buf, - &key->pos); -} -void -crypt_free(crypt_t *key) -{ - memset(key, 0, sizeof(key)); - free(key); -} - -/* ===== - PRNG - ===== */ - -int -random_bytes(uchar *buf, size_t buflen) -{ - return RAND_bytes(buf, buflen) == 1 ? 0 : -1; -} diff --git a/src/crypt.h b/src/crypt.h deleted file mode 100644 index 59876b1..0000000 --- a/src/crypt.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2011 Nick Mathewson - - You may do anything with this work that copyright law would normally - restrict, so long as you retain the above notice(s) and this license - in all redistributed copies and derived works. There is no warranty. -*/ - -#ifndef CRYPT_H -#define CRYPT_H - -#include <sys/types.h> - -/* Stream cipher state */ -typedef struct crypt_t crypt_t; -/* Digest state */ -typedef struct digest_t digest_t; - -typedef unsigned char uchar; - -/** Initialize global crypto state. Returrn 0 on success, -1 on failure */ -int initialize_crypto(void); -/** Clean up global crypto state */ -void cleanup_crypto(void); - -/** Return a newly allocated digest state, or NULL on failure. */ -digest_t *digest_new(void); -/** Add n bytes from b to the digest state. */ -void digest_update(digest_t *, const uchar *b, size_t n); -/** Get a digest from the digest state. Put it in up the first n bytes of the -buffer b. Return the number of bytes actually written.*/ -size_t digest_getdigest(digest_t *, uchar *b, size_t n); -/** Clear and free a digest state */ -void digest_free(digest_t *); - -/** Return a new stream cipher state taking key and IV from the data provided. - * The data length must be exactly 32 */ -crypt_t *crypt_new(const uchar *, size_t); -void crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen); - -/** Encrypt n bytes of data in the buffer b, in place. */ -void stream_crypt(crypt_t *, uchar *b, size_t n); -/** Clear and free a stream cipher state. */ -void crypt_free(crypt_t *); - -/** Set b to contain n random bytes. */ -int random_bytes(uchar *b, size_t n); - -#ifdef CRYPT_PRIVATE -/* ========== - These definitions are not part of the crypt interface. - They're exposed here so that the unit tests can use them. - ========== -*/ -struct crypt_t { - AES_KEY key; - uchar ivec[AES_BLOCK_SIZE]; - uchar ecount_buf[AES_BLOCK_SIZE]; - unsigned int pos; -}; -#endif - -#endif diff --git a/src/main.c b/src/main.c index de5cd61..93d5820 100644 --- a/src/main.c +++ b/src/main.c @@ -11,7 +11,6 @@ #include <signal.h>
#include <event2/event.h> -#include "crypt.h" #include "network.h" #include "util.h" #include "protocol.h" diff --git a/src/network.c b/src/network.c index 9350a61..833b939 100644 --- a/src/network.c +++ b/src/network.c @@ -23,16 +23,16 @@ #include <errno.h> #include <event2/util.h>
-#include "plugins/obfs2.h" - struct listener_t { struct evconnlistener *listener; struct sockaddr_storage target_address; int target_address_len; struct protocol_t *proto; /* Protocol that this listener can speak. */ int mode; - char shared_secret[SHARED_SECRET_LENGTH]; + /* ASN */ + /* char shared_secret[SHARED_SECRET_LENGTH]; unsigned int have_shared_secret : 1; + */ };
static void simple_listener_cb(struct evconnlistener *evcl, @@ -79,11 +79,14 @@ listener_new(struct event_base *base, } else { assert(lsn->mode == LSN_SOCKS_CLIENT); } + /* ASN */ + /* assert(shared_secret == NULL || shared_secret_len == SHARED_SECRET_LENGTH); if (shared_secret) { memcpy(lsn->shared_secret, shared_secret, SHARED_SECRET_LENGTH); lsn->have_shared_secret = 1; } + */
lsn->listener = evconnlistener_new_bind(base, simple_listener_cb, lsn, flags, diff --git a/src/plugins/obfs2.c b/src/plugins/obfs2.c index c0cdc1e..01c74f3 100644 --- a/src/plugins/obfs2.c +++ b/src/plugins/obfs2.c @@ -15,12 +15,16 @@
#define CRYPT_PROTOCOL_PRIVATE
-#include "../crypt.h" +#include "obfs2_crypt.h" #include "obfs2.h" #include "../util.h" #include "../protocol.h"
-void * +/* Sets the function table for the obfs2 protocol and + calls initialize_crypto(). + Returns 0 on success, -1 on fail. +*/ +int obfs2_new(struct protocol_t *proto_struct) { proto_struct->destroy = (void *)obfs2_state_free; proto_struct->init = (void *)obfs2_state_new; @@ -28,7 +32,12 @@ obfs2_new(struct protocol_t *proto_struct) { proto_struct->send = (void *)obfs2_send; proto_struct->recv = (void *)obfs2_recv;
- return NULL; + if (initialize_crypto() < 0) { + fprintf(stderr, "Can't initialize crypto; failing\n"); + return -1; + } + + return 0; }
/** Return true iff the OBFUSCATE_SEED_LENGTH-byte seed in 'seed' is nonzero */ diff --git a/src/plugins/obfs2.h b/src/plugins/obfs2.h index dd0c842..2d1d24e 100644 --- a/src/plugins/obfs2.h +++ b/src/plugins/obfs2.h @@ -26,7 +26,7 @@ int obfs2_send(obfs2_state_t *state, int obfs2_recv(obfs2_state_t *state, struct evbuffer *source, struct evbuffer *dest);
-void *obfs2_new(struct protocol_t *proto_struct); +int obfs2_new(struct protocol_t *proto_struct);
#ifdef CRYPT_PROTOCOL_PRIVATE diff --git a/src/plugins/obfs2_crypt.c b/src/plugins/obfs2_crypt.c new file mode 100644 index 0000000..0121c93 --- /dev/null +++ b/src/plugins/obfs2_crypt.c @@ -0,0 +1,206 @@ +/* Copyright 2011 Nick Mathewson + + You may do anything with this work that copyright law would normally + restrict, so long as you retain the above notice(s) and this license + in all redistributed copies and derived works. There is no warranty. +*/ + +#include "config.h" + +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + +#include <openssl/opensslv.h> +#include <openssl/aes.h> +#include <openssl/rand.h> +#include <openssl/err.h> + +#define CRYPT_PRIVATE +#include "obfs2_crypt.h" + +#if OPENSSL_VERSION_NUMBER >= 0x0090800f +#define USE_OPENSSL_RANDPOLL 1 +#define USE_OPENSSL_SHA256 1 +#include <openssl/sha.h> +#else +#define STMT_BEGIN do { +#define STMT_END } while (0) +static void +set_uint32(void *ptr, uint32_t val) +{ + memcpy(ptr, &val, 4); +} +static uint32_t +get_uint32(const void *ptr) +{ + uint32_t val; + memcpy(&val, ptr, 4); + return val; +} +#define LTC_ARGCHK(x) assert((x)) +#include "sha256.c" +#endif + +int +initialize_crypto(void) +{ + ERR_load_crypto_strings(); + +#ifdef USE_OPENSSL_RANDPOLL + return RAND_poll() == 1 ? 0 : -1; +#else + /* XXX Or maybe fall back to the arc4random implementation in libevent2? */ + { + char buf[32]; + int fd, n; + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) { + perror("open"); + return -1; + } + n = read(fd, buf, sizeof(buf)); + if (n != sizeof(buf)) { + close(fd); + return -1; + } + RAND_seed(buf, sizeof(buf)); + close(fd); + return 0; + } +#endif +} + +void +cleanup_crypto(void) +{ + ERR_free_strings(); +} + +/* ===== + Digests + ===== */ + +#ifdef USE_OPENSSL_SHA256 +struct digest_t { + SHA256_CTX ctx; +}; +digest_t * +digest_new(void) +{ + digest_t *d = malloc(sizeof(digest_t)); + SHA256_Init(&d->ctx); + return d; +} +void +digest_update(digest_t *d, const uchar *buf, size_t len) +{ + SHA256_Update(&d->ctx, buf, len); +} +size_t +digest_getdigest(digest_t *d, uchar *buf, size_t len) +{ + uchar tmp[32]; + int n = 32; + SHA256_Final(tmp, &d->ctx); + if (len < 32) + n = len; + memcpy(buf, tmp, n); + memset(tmp, 0, sizeof(tmp)); + return n; +} +#else +struct digest_t { + sha256_state ctx; +}; +digest_t * +digest_new(void) +{ + digest_t *d = malloc(sizeof(digest_t)); + sha256_init(&d->ctx); + return d; +} +void +digest_update(digest_t *d, const uchar *buf, size_t len) +{ + sha256_process(&d->ctx, buf, len); +} +size_t +digest_getdigest(digest_t *d, uchar *buf, size_t len) +{ + uchar tmp[32]; + int n = 32; + sha256_done(&d->ctx, tmp); + if (len < 32) + n = len; + memcpy(buf, tmp, n); + memset(tmp, 0, sizeof(tmp)); + return n; +} +#endif + +void +digest_free(digest_t *d) +{ + memset(d, 0, sizeof(digest_t)); + free(d); +} + +/* ===== + Stream crypto + ===== */ + +crypt_t * +crypt_new(const uchar *key, size_t keylen) +{ + crypt_t *k; + if (keylen < AES_BLOCK_SIZE) + return NULL; + + k = calloc(1, sizeof(crypt_t)); + if (k == NULL) + return NULL; + + AES_set_encrypt_key(key, 128, &k->key); + + return k; +} +void +crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen) +{ + assert(ivlen == sizeof(key->ivec)); + memcpy(key->ivec, iv, ivlen); +} +void +stream_crypt(crypt_t *key, uchar *buf, size_t len) +{ + AES_ctr128_encrypt(buf, buf, /* XXX make sure this is okay to do. */ + len, + &key->key, key->ivec, key->ecount_buf, + &key->pos); +} +void +crypt_free(crypt_t *key) +{ + memset(key, 0, sizeof(key)); + free(key); +} + +/* ===== + PRNG + ===== */ + +int +random_bytes(uchar *buf, size_t buflen) +{ + return RAND_bytes(buf, buflen) == 1 ? 0 : -1; +} diff --git a/src/plugins/obfs2_crypt.h b/src/plugins/obfs2_crypt.h new file mode 100644 index 0000000..c9841d8 --- /dev/null +++ b/src/plugins/obfs2_crypt.h @@ -0,0 +1,62 @@ +/* Copyright 2011 Nick Mathewson + + You may do anything with this work that copyright law would normally + restrict, so long as you retain the above notice(s) and this license + in all redistributed copies and derived works. There is no warranty. +*/ + +#ifndef OBFS2_CRYPT_H +#define OBFS2_CRYPT_H + +#include <sys/types.h> + +/* Stream cipher state */ +typedef struct crypt_t crypt_t; +/* Digest state */ +typedef struct digest_t digest_t; + +typedef unsigned char uchar; + +/** Initialize global crypto state. Returrn 0 on success, -1 on failure */ +int initialize_crypto(void); +/** Clean up global crypto state */ +void cleanup_crypto(void); + +/** Return a newly allocated digest state, or NULL on failure. */ +digest_t *digest_new(void); +/** Add n bytes from b to the digest state. */ +void digest_update(digest_t *, const uchar *b, size_t n); +/** Get a digest from the digest state. Put it in up the first n bytes of the +buffer b. Return the number of bytes actually written.*/ +size_t digest_getdigest(digest_t *, uchar *b, size_t n); +/** Clear and free a digest state */ +void digest_free(digest_t *); + +/** Return a new stream cipher state taking key and IV from the data provided. + * The data length must be exactly 32 */ +crypt_t *crypt_new(const uchar *, size_t); +void crypt_set_iv(crypt_t *key, const uchar *iv, size_t ivlen); + +/** Encrypt n bytes of data in the buffer b, in place. */ +void stream_crypt(crypt_t *, uchar *b, size_t n); +/** Clear and free a stream cipher state. */ +void crypt_free(crypt_t *); + +/** Set b to contain n random bytes. */ +int random_bytes(uchar *b, size_t n); + +#ifdef CRYPT_PRIVATE +/* ========== + These definitions are not part of the crypt interface. + They're exposed here so that the unit tests can use them. + ========== +*/ +struct crypt_t { + AES_KEY key; + uchar ivec[AES_BLOCK_SIZE]; + uchar ecount_buf[AES_BLOCK_SIZE]; + unsigned int pos; +}; +#endif + +#endif diff --git a/src/protocol.c b/src/protocol.c index 6530fe0..6df93ca 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -3,7 +3,6 @@ #include <assert.h>
#include "protocol.h" -#include "crypt.h" #include "network.h"
#include "plugins/obfs2.h" @@ -18,14 +17,8 @@ set_up_protocol(int protocol) {
if (protocol == BRL_PROTOCOL) { proto->new = &obfs2_new; - proto->new(proto); - - if (initialize_crypto() < 0) { - fprintf(stderr, "Can't initialize crypto; failing\n"); - return NULL; - } - - printf("Protocol constructed\n"); + if (proto->new(proto)) + printf("Protocol constructed\n"); } /* elif { other protocols } */
diff --git a/src/protocol.h b/src/protocol.h index 4de5c70..9e58ea8 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -16,7 +16,7 @@ int proto_recv(struct protocol_t *proto, void *source, void *dest); /* ASN Why the hell do half of them return int? FIXME */ struct protocol_t { /* Constructor: creates the protocol; sets up functions etc. */ - void *(*new)(struct protocol_t *self); + int (*new)(struct protocol_t *self); /* Destructor */ void (*destroy)(void *state);
diff --git a/src/socks.c b/src/socks.c index 13bc391..8f432e1 100644 --- a/src/socks.c +++ b/src/socks.c @@ -9,7 +9,6 @@
#define SOCKS_PRIVATE #include "socks.h" -#include "crypt.h" #include "util.h"
#include <event2/buffer.h> @@ -40,6 +39,8 @@ static int socks5_do_negotiation(struct evbuffer *dest, unsigned int neg_was_success);
+typedef unsigned char uchar; + socks_state_t * socks_state_new(void) { diff --git a/src/test/unittest.c b/src/test/unittest.c index 4e1368c..494e90b 100644 --- a/src/test/unittest.c +++ b/src/test/unittest.c @@ -7,7 +7,7 @@ #include <stdlib.h>
#include "tinytest.h" -#include "../crypt.h" +#include "../plugins/obfs2_crypt.h"
extern struct testcase_t crypt_tests[]; extern struct testcase_t protocol_tests[]; diff --git a/src/test/unittest_crypt.c b/src/test/unittest_crypt.c index f2822fe..b624e15 100644 --- a/src/test/unittest_crypt.c +++ b/src/test/unittest_crypt.c @@ -12,7 +12,7 @@
#include <openssl/aes.h>
-#include "../crypt.h" +#include "../plugins/obfs2_crypt.h"
struct crypt_t { AES_KEY key; diff --git a/src/test/unittest_protocol.c b/src/test/unittest_protocol.c index 334591c..ceb666d 100644 --- a/src/test/unittest_protocol.c +++ b/src/test/unittest_protocol.c @@ -17,7 +17,7 @@
#define CRYPT_PROTOCOL_PRIVATE #define CRYPT_PRIVATE -#include "../crypt.h" +#include "../plugins/obfs2_crypt.h" #include "../util.h" #include "../protocol.h" #include "../plugins/obfs2.h" diff --git a/src/test/unittest_socks.c b/src/test/unittest_socks.c index ec24e5f..db91188 100644 --- a/src/test/unittest_socks.c +++ b/src/test/unittest_socks.c @@ -9,7 +9,7 @@
#define SOCKS_PRIVATE #include "../socks.h" -#include "../crypt.h" +#include "../plugins/obfs2_crypt.h" #include "../util.h" #include "../plugins/obfs2.h"
tor-commits@lists.torproject.org