forked from Telodendria/Telodendria
Define TLS API, update HttpClient to support optional TLS.
Also added a LibreSSL TLS implementation. Client is verified to work; server has not been tested yet.
This commit is contained in:
parent
d1b4ecff48
commit
996356832e
6 changed files with 340 additions and 9 deletions
6
TODO.txt
6
TODO.txt
|
@ -16,11 +16,12 @@ Milestone: v0.3.0
|
|||
[x] Convert all code that deals with I/O
|
||||
[!] Multi-output (proof of concept)
|
||||
[!] Memory streams (proof of concept)
|
||||
[ ] TLS
|
||||
[~] TLS
|
||||
[ ] SOCKS
|
||||
[x] Move/convert UtilStreamCopy()
|
||||
[ ] Io man page
|
||||
[ ] Stream man page
|
||||
[ ] Tls man page
|
||||
[~] HTTP Client API
|
||||
[x] Document HttpParseHeaders()
|
||||
[ ] HttpClient man page
|
||||
|
@ -42,6 +43,9 @@ Milestone: v0.3.0
|
|||
[x] json man page
|
||||
[ ] Update man pages for tp and send-patch
|
||||
|
||||
[ ] Proper HTTP request router
|
||||
- Support regex matching
|
||||
|
||||
[ ] Move configuration to database
|
||||
[ ] Initial configuration
|
||||
[ ] If no config, create one-time use registration token that
|
||||
|
|
46
contrib/TlsImplTemplate.c
Normal file
46
contrib/TlsImplTemplate.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Telodendria TLS Implementation Template File.
|
||||
*
|
||||
* This file can serve as a baseline for new TLS implementations.
|
||||
* Please consult the Tls(3) man page for details.
|
||||
*/
|
||||
#include <Tls.h>
|
||||
|
||||
#if TLS_IMPL == TLS_TEMPLATE /* Set your TLS_* implementation flag here */
|
||||
|
||||
/*
|
||||
* #include statements and any implementation structures
|
||||
* needed should go here.
|
||||
*/
|
||||
|
||||
void *
|
||||
TlsInitClient(int fd, const char *serverName)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
TlsInitServer(int fd, const char *crt, const char *key)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
TlsRead(void *cookie, void *buf, size_t nBytes)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
TlsWrite(void *cookie, void *buf, size_t nBytes)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
TlsClose(void *cookie)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -36,12 +36,12 @@
|
|||
#include <Http.h>
|
||||
#include <Memory.h>
|
||||
#include <Util.h>
|
||||
#include <Tls.h>
|
||||
|
||||
struct HttpClientContext
|
||||
{
|
||||
HashMap *responseHeaders;
|
||||
Stream *stream;
|
||||
int sd;
|
||||
};
|
||||
|
||||
HttpClientContext *
|
||||
|
@ -60,6 +60,13 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef TLS_IMPL
|
||||
if (flags & HTTP_TLS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!port)
|
||||
{
|
||||
if (flags & HTTP_TLS)
|
||||
|
@ -76,11 +83,6 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host
|
|||
sprintf(serv, "%hu", port);
|
||||
}
|
||||
|
||||
/* TODO: Not supported yet */
|
||||
if (flags & HTTP_TLS)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context = Malloc(sizeof(HttpClientContext));
|
||||
if (!context)
|
||||
|
@ -127,8 +129,19 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host
|
|||
|
||||
freeaddrinfo(res0);
|
||||
|
||||
context->sd = sd;
|
||||
#ifdef TLS_IMPL
|
||||
if (flags & HTTP_TLS)
|
||||
{
|
||||
context->stream = TlsClientStream(sd, host);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->stream = StreamFd(sd);
|
||||
}
|
||||
#else
|
||||
context->stream = StreamFd(sd);
|
||||
#endif
|
||||
|
||||
if (!context->stream)
|
||||
{
|
||||
Free(context);
|
||||
|
@ -185,7 +198,6 @@ HttpRequestSend(HttpClientContext * context)
|
|||
}
|
||||
|
||||
StreamFlush(context->stream);
|
||||
shutdown(context->sd, SHUT_WR);
|
||||
|
||||
lineLen = UtilGetLine(&line, &lineSize, context->stream);
|
||||
|
||||
|
|
62
src/Tls.c
Normal file
62
src/Tls.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include <Tls.h>
|
||||
|
||||
#ifdef TLS_IMPL
|
||||
|
||||
#include <Io.h>
|
||||
#include <Stream.h>
|
||||
|
||||
Stream *
|
||||
TlsClientStream(int fd, const char *serverName)
|
||||
{
|
||||
Io *io;
|
||||
void *cookie;
|
||||
IoFunctions funcs;
|
||||
|
||||
cookie = TlsInitClient(fd, serverName);
|
||||
if (!cookie)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
funcs.read = TlsRead;
|
||||
funcs.write = TlsWrite;
|
||||
funcs.seek = NULL;
|
||||
funcs.close = TlsClose;
|
||||
|
||||
io = IoCreate(cookie, funcs);
|
||||
if (!io)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return StreamIo(io);
|
||||
}
|
||||
|
||||
Stream *
|
||||
TlsServerStream(int fd, const char *crt, const char *key)
|
||||
{
|
||||
Io *io;
|
||||
void *cookie;
|
||||
IoFunctions funcs;
|
||||
|
||||
cookie = TlsInitServer(fd, crt, key);
|
||||
if (!cookie)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
funcs.read = TlsRead;
|
||||
funcs.write = TlsWrite;
|
||||
funcs.seek = NULL;
|
||||
funcs.close = TlsClose;
|
||||
|
||||
io = IoCreate(cookie, funcs);
|
||||
if (!io)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return StreamIo(io);
|
||||
}
|
||||
|
||||
#endif
|
172
src/Tls/TlsLibreSSL.c
Normal file
172
src/Tls/TlsLibreSSL.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
#include <Tls.h>
|
||||
|
||||
#if TLS_IMPL == TLS_LIBRESSL
|
||||
|
||||
#include <Memory.h>
|
||||
#include <tls.h> /* LibreSSL TLS */
|
||||
|
||||
typedef struct LibreSSLCookie
|
||||
{
|
||||
int fd;
|
||||
struct tls *ctx;
|
||||
struct tls *cctx;
|
||||
struct tls_config *cfg;
|
||||
} LibreSSLCookie;
|
||||
|
||||
void *
|
||||
TlsInitClient(int fd, const char *serverName)
|
||||
{
|
||||
LibreSSLCookie *cookie = Malloc(sizeof(LibreSSLCookie));
|
||||
|
||||
if (!cookie)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cookie->ctx = tls_client();
|
||||
cookie->cctx = NULL;
|
||||
cookie->cfg = tls_config_new();
|
||||
cookie->fd = fd;
|
||||
|
||||
|
||||
if (!cookie->ctx || !cookie->cfg)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_config_set_ca_file(cookie->cfg, tls_default_ca_cert_file()) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_configure(cookie->ctx, cookie->cfg) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_connect_socket(cookie->ctx, fd, serverName) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
return cookie;
|
||||
|
||||
error:
|
||||
if (cookie->ctx)
|
||||
{
|
||||
tls_free(cookie->ctx);
|
||||
}
|
||||
|
||||
if (cookie->cfg)
|
||||
{
|
||||
tls_config_free(cookie->cfg);
|
||||
}
|
||||
|
||||
Free(cookie);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
TlsInitServer(int fd, const char *crt, const char *key)
|
||||
{
|
||||
LibreSSLCookie *cookie = Malloc(sizeof(LibreSSLCookie));
|
||||
|
||||
if (!cookie)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cookie->ctx = tls_server();
|
||||
cookie->cctx = NULL;
|
||||
cookie->cfg = tls_config_new();
|
||||
cookie->fd = fd;
|
||||
|
||||
if (!cookie->ctx || !cookie->cfg)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_config_set_cert_file(cookie->cfg, crt) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_config_set_key_file(cookie->cfg, key) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_configure(cookie->ctx, cookie->cfg) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tls_accept_socket(cookie->ctx, &cookie->cctx, fd) == -1)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
return cookie;
|
||||
|
||||
error:
|
||||
if (cookie->ctx)
|
||||
{
|
||||
tls_free(cookie->ctx);
|
||||
}
|
||||
|
||||
if (cookie->cctx)
|
||||
{
|
||||
tls_free(cookie->cctx);
|
||||
}
|
||||
|
||||
if (cookie->cfg)
|
||||
{
|
||||
tls_config_free(cookie->cfg);
|
||||
}
|
||||
|
||||
Free(cookie);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
TlsRead(void *cookie, void *buf, size_t nBytes)
|
||||
{
|
||||
LibreSSLCookie *tls = cookie;
|
||||
|
||||
return tls_read(tls->cctx ? tls->cctx : tls->ctx, buf, nBytes);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
TlsWrite(void *cookie, void *buf, size_t nBytes)
|
||||
{
|
||||
LibreSSLCookie *tls = cookie;
|
||||
|
||||
return tls_write(tls->cctx ? tls->cctx : tls->ctx, buf, nBytes);
|
||||
}
|
||||
|
||||
int
|
||||
TlsClose(void *cookie)
|
||||
{
|
||||
LibreSSLCookie *tls = cookie;
|
||||
|
||||
int tlsRet = tls_close(tls->cctx ? tls->cctx : tls->ctx);
|
||||
int sdRet;
|
||||
|
||||
if (tls->cctx)
|
||||
{
|
||||
tls_free(tls->cctx);
|
||||
}
|
||||
|
||||
tls_free(tls->ctx);
|
||||
tls_config_free(tls->cfg);
|
||||
|
||||
sdRet = close(tls->fd);
|
||||
|
||||
Free(tls);
|
||||
|
||||
return (tlsRet == -1 || sdRet == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
#endif
|
35
src/include/Tls.h
Normal file
35
src/include/Tls.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef TELODENDRIA_TLS_H
|
||||
#define TELODENDRIA_TLS_H
|
||||
|
||||
#define TLS_LIBRESSL 1
|
||||
#define TLS_MBEDTLS 2
|
||||
#define TLS_OPENSSL 3
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
extern Stream *
|
||||
TlsClientStream(int, const char *);
|
||||
|
||||
extern Stream *
|
||||
TlsServerStream(int, const char *, const char *);
|
||||
|
||||
/*
|
||||
* These are provided by individual TLS implementations.
|
||||
*/
|
||||
|
||||
extern void *
|
||||
TlsInitClient(int, const char *);
|
||||
|
||||
extern void *
|
||||
TlsInitServer(int, const char *, const char *);
|
||||
|
||||
extern ssize_t
|
||||
TlsRead(void *, void *, size_t);
|
||||
|
||||
extern ssize_t
|
||||
TlsWrite(void *, void *, size_t);
|
||||
|
||||
extern int
|
||||
TlsClose(void *);
|
||||
|
||||
#endif /* TELODENDRIA_TLS_H */
|
Loading…
Reference in a new issue