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
|
[x] Convert all code that deals with I/O
|
||||||
[!] Multi-output (proof of concept)
|
[!] Multi-output (proof of concept)
|
||||||
[!] Memory streams (proof of concept)
|
[!] Memory streams (proof of concept)
|
||||||
[ ] TLS
|
[~] TLS
|
||||||
[ ] SOCKS
|
[ ] SOCKS
|
||||||
[x] Move/convert UtilStreamCopy()
|
[x] Move/convert UtilStreamCopy()
|
||||||
[ ] Io man page
|
[ ] Io man page
|
||||||
[ ] Stream man page
|
[ ] Stream man page
|
||||||
|
[ ] Tls man page
|
||||||
[~] HTTP Client API
|
[~] HTTP Client API
|
||||||
[x] Document HttpParseHeaders()
|
[x] Document HttpParseHeaders()
|
||||||
[ ] HttpClient man page
|
[ ] HttpClient man page
|
||||||
|
@ -42,6 +43,9 @@ Milestone: v0.3.0
|
||||||
[x] json man page
|
[x] json man page
|
||||||
[ ] Update man pages for tp and send-patch
|
[ ] Update man pages for tp and send-patch
|
||||||
|
|
||||||
|
[ ] Proper HTTP request router
|
||||||
|
- Support regex matching
|
||||||
|
|
||||||
[ ] Move configuration to database
|
[ ] Move configuration to database
|
||||||
[ ] Initial configuration
|
[ ] Initial configuration
|
||||||
[ ] If no config, create one-time use registration token that
|
[ ] 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 <Http.h>
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
#include <Util.h>
|
#include <Util.h>
|
||||||
|
#include <Tls.h>
|
||||||
|
|
||||||
struct HttpClientContext
|
struct HttpClientContext
|
||||||
{
|
{
|
||||||
HashMap *responseHeaders;
|
HashMap *responseHeaders;
|
||||||
Stream *stream;
|
Stream *stream;
|
||||||
int sd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpClientContext *
|
HttpClientContext *
|
||||||
|
@ -60,6 +60,13 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TLS_IMPL
|
||||||
|
if (flags & HTTP_TLS)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!port)
|
if (!port)
|
||||||
{
|
{
|
||||||
if (flags & HTTP_TLS)
|
if (flags & HTTP_TLS)
|
||||||
|
@ -76,11 +83,6 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host
|
||||||
sprintf(serv, "%hu", port);
|
sprintf(serv, "%hu", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Not supported yet */
|
|
||||||
if (flags & HTTP_TLS)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
context = Malloc(sizeof(HttpClientContext));
|
context = Malloc(sizeof(HttpClientContext));
|
||||||
if (!context)
|
if (!context)
|
||||||
|
@ -127,8 +129,19 @@ HttpRequest(HttpRequestMethod method, int flags, unsigned short port, char *host
|
||||||
|
|
||||||
freeaddrinfo(res0);
|
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);
|
context->stream = StreamFd(sd);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!context->stream)
|
if (!context->stream)
|
||||||
{
|
{
|
||||||
Free(context);
|
Free(context);
|
||||||
|
@ -185,7 +198,6 @@ HttpRequestSend(HttpClientContext * context)
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamFlush(context->stream);
|
StreamFlush(context->stream);
|
||||||
shutdown(context->sd, SHUT_WR);
|
|
||||||
|
|
||||||
lineLen = UtilGetLine(&line, &lineSize, context->stream);
|
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