// -----------------------------------------------------------------------------
// Perform global setup. This must be called exactly once for a given process.
//
// private_key: If non-NULL, this must be a 32-byte private key. Otherwise, the
// private key is taken from /dev/urandom. The private key is free form
// random data. It will be tweaked to be a valid private key.
// -----------------------------------------------------------------------------
void obstcp_init(const void *private_key);
// -----------------------------------------------------------------------------
// Write the current private key to the given buffer. Note that the private key
// may not be exactly equal to the private key given to obstcp_init because not
// every random string is a valid private key.
//
// private_key: a 32-byte buffer
// -----------------------------------------------------------------------------
void obstcp_private_key_get(void *private_key);
// -----------------------------------------------------------------------------
// Write the current public key to the given buffer
//
// public_key: a 32-byte buffer
// -----------------------------------------------------------------------------
void obstcp_public_key_get(void *public_key);
// -----------------------------------------------------------------------------
// For a client connection:
// * Create an obstcp_ctx object, either on the stack or on the heap. This
// must persist for the length of the connection.
// * Call obstcp_ctx_init_client with a socket, before connect()ing the
// socket
// * You must complete key exchange before the server can write to you.
// This involves writing a small amount of data. If you use obstcp_write,
// it will happen automatically. Otherwise you can call obstcp_kx_write to
// write the data. Once the kernel has accepted the data,
// obstcp_kx_complete will return non-zero.
// * Then use obstcp_read and obstcp_write just as you would use read and
// write. If the server doesn't support obfuscation, these are just pass
// through functions.
//
// For a server connection:
// * Create and bind a socket
// * Call obstcp_setup_listening on the socket.
// * Accept a connection.
// * Create an obstcp_ctx object, either on the stack or on the heap. This
// must persist for the length of the connection.
// * Call obstcp_ctx_init_server on the *accepted* socket.
// * Use obstcp_read and obstcp_write as you would use read and write. If
// anything was unsupported or failed, these will just work in pass through
// mode.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// The per-connection state.
//
// Multithreading: no two threads can be using the same obstcp_ctx at the same
// time. It's up to the user to ensure this.
// -----------------------------------------------------------------------------
struct obstcp_ctx {
uint8_t state;
uint8_t reason;
uint32_t input[16];
uint8_t in_keystream[128];
unsigned in_used;
uint64_t in_seq;
uint8_t out_keystream[128];
unsigned out_used;
uint64_t out_seq;
};
// -----------------------------------------------------------------------------
// Setup a socket (after bind, but before listen) to enable obfuscation.
//
// Returns: non-zero if the kernel doesn't support obsfuscation. You can ignore
// this because everything else will drop into pass through mode in this
// case.
// -----------------------------------------------------------------------------
char obstcp_setup_listening(int fd);
// -----------------------------------------------------------------------------
// Setup a context structure to start processing a new connection.
//
// fd: a file descriptor to a TCP socket, freshly accepted.
// -----------------------------------------------------------------------------
void obstcp_ctx_init_client(struct obstcp_ctx *ctx, int fd);
// -----------------------------------------------------------------------------
// Setup a server socket (after bind, but before listen) to support
// obfuscation.
// -----------------------------------------------------------------------------
void obstcp_ctx_init_server(struct obstcp_ctx *ctx, int fd);
// -----------------------------------------------------------------------------
// Read from the given file descriptor and decrypt. Note that, at the beginning
// of the connection, this function may return -1 and set errno to EAGAIN to
// reflect the fact that some network data is consumed by key setup. All other
// behaviour matches read(2).
// -----------------------------------------------------------------------------
ssize_t obstcp_read(struct obstcp_ctx *ctx, int fd, void *buf, size_t count);
// -----------------------------------------------------------------------------
// Encrypt the data to a buffer on the stack and write to the network. All
// other behaviour matches write(2)
// -----------------------------------------------------------------------------
ssize_t obstcp_write(struct obstcp_ctx *ctx, int fd, const void *buf,
size_t count);
// -----------------------------------------------------------------------------
// If obstcp_kx_complete returns zero, we still need to write data to complete
// the key exchange. To write as much as possible, call this function.
// Afterwards one can call obstcp_kx_complete to see if the exchange is
// complete.
// -----------------------------------------------------------------------------
void obstcp_kx_write(int fd, struct obstcp_ctx *ctx);
// -----------------------------------------------------------------------------
// Return non-zero iff key exchange has completed, or failed. Either way, the
// host doesn't need to read/write any more data for key exchange.
// -----------------------------------------------------------------------------
char obstcp_kx_complete(const struct obstcp_ctx *ctx);
#define OBSTCP_NOT_ESTABLISHED 0
#define OBSTCP_MAYBE 1
#define OBSTCP_ESTABLISHED 2
// -----------------------------------------------------------------------------
// Return if obfuscation is active on the given connection.
//
// Returns:
// OBSTCP_NOT_ESTABLISHED: Connection is pass through mode. Call
// obstcp_failure_reason to find out why
// OBSTCP_MAYBE: (client side) Key exchange hasn't completed yet.
// OBSTCP_ESTABLISHED: Key exchange complete. The connection will be
// obfuscated
// -----------------------------------------------------------------------------
char obstcp_established(const struct obstcp_ctx *ctx);
#define OBSTCP_NO_KERNEL 0
#define OBSTCP_NOT_OFFERED 1
#define OBSTCP_KX_FAILURE 2
// -----------------------------------------------------------------------------
// If obstcp_established returned OBSTCP_NOT_ESTABLISHED, then one can call
// this function to find out what went wrong.
//
// Returns:
// OBSTCP_NO_KERNEL: The kernel doesn't support obfuscation
// OBSTCP_NOT_OFFERED: (server side) client didn't request obfuscation
// OBSTCP_KX_FAILURE: key exchange failed (protocol error)
// -----------------------------------------------------------------------------
char obstcp_failure_reason(const struct obstcp_ctx *ctx);
Tuesday, July 8, 2008
I like header files which tell you everything you need to know about the library. Here's the libobstcp one:
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment