Skip to content

Commit

Permalink
TLS implementation and basic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuriy Vountesmery committed Aug 29, 2024
1 parent 19f0cf1 commit daf3620
Show file tree
Hide file tree
Showing 5 changed files with 544 additions and 115 deletions.
164 changes: 142 additions & 22 deletions nngd/nngd.d
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,21 @@ struct NNGSocket {
return -1;
}
}

version(withtls) {
int listener_set_tls ( NNGTLS* tls ) {
if(tls.mode == nng_tls_mode.NNG_TLS_MODE_SERVER){
auto rc = nng_listener_set_ptr(m_listener, toStringz(NNG_OPT_TLS_CONFIG), tls.tls);
if(rc != 0){
m_errno = cast(nng_errno)rc;
return rc;
}
return 0;
} else {
return -1;
}
}
}

int listener_start( const bool nonblock = false ) @safe {
m_errno = cast(nng_errno)0;
Expand Down Expand Up @@ -750,6 +765,21 @@ struct NNGSocket {
return -1;
}
}

version(withtls) {
int dialer_set_tls ( NNGTLS* tls ) {
if(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT){
auto rc = nng_dialer_set_ptr(m_dialer, toStringz(NNG_OPT_TLS_CONFIG), tls.tls);
if(rc != 0){
m_errno = cast(nng_errno)rc;
return rc;
}
return 0;
} else {
return -1;
}
}
}

int dialer_start( const bool nonblock = false ) @safe nothrow {
m_errno = cast(nng_errno)0;
Expand Down Expand Up @@ -1409,40 +1439,53 @@ version(withtls) {
alias nng_tls_auth_mode = libnng.nng_tls_auth_mode;
alias nng_tls_version = libnng.nng_tls_version;

struct WebTLS {
struct NNGTLS {
nng_tls_config* tls;
nng_tls_mode _mode;

@disable this();

this(ref return scope WebTLS rhs) {}
this(ref return scope NNGTLS rhs) {}

this( nng_tls_mode imode ) {
int rc;
_mode = imode;
rc = nng_tls_config_alloc(&tls, imode);
enforce(rc == 0, "TLS config init");
nng_tls_config_hold(tls);
}


~this() {
nng_tls_config_free(tls);
}

void set_server_name ( string iname ) {
auto rc = nng_tls_config_server_name(tls, iname.toStringz());
enforce(_mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
auto rc = nng_tls_config_server_name(tls, toStringz(iname));
enforce(rc == 0);
}

void set_ca_chain ( string pem, string crl = "" ) {
auto rc = nng_tls_config_ca_chain(tls, pem.toStringz(), crl.toStringz());
auto rc = nng_tls_config_ca_chain(tls, toStringz(pem), crl == "" ? null : toStringz(crl));
enforce(rc == 0);
}

void set_ca_chain_file_load( string filename, string crl = "" ) {
string ca = std.file.readText(filename);
set_ca_chain ( ca, crl );
}

void set_own_cert ( string pem, string key, string pwd = "" ) {
auto rc = nng_tls_config_own_cert(tls, pem.toStringz(), key.toStringz(), pwd.toStringz());
auto rc = nng_tls_config_own_cert(tls, pem.toStringz(), toStringz(key), pwd == "" ? null : toStringz(pwd));
enforce(rc == 0);
}

void set_own_cert_load ( string pemfilename, string keyfilename, string pwd = "" ){
string pem = std.file.readText(pemfilename);
string key = std.file.readText(keyfilename);
set_own_cert ( pem, key, pwd );
}

// TODO: check why this two excluded from the lib
/*
void set_pass ( string ipass ) {
Expand All @@ -1456,21 +1499,20 @@ version(withtls) {
}
*/

void set_auth_mode ( nng_tls_auth_mode imode ) {
auto rc = nng_tls_config_auth_mode(tls, imode);
enforce(rc == 0);
}

void set_ca_file ( string ica ) {
auto rc = nng_tls_config_ca_file(tls, ica.toStringz());
void set_ca_file ( string icafile ) {
auto rc = nng_tls_config_ca_file(tls, toStringz(icafile));
enforce(rc == 0);
}

void set_cert_key_file ( string ipem , string ikey ) {
auto rc = nng_tls_config_cert_key_file(tls, ipem.toStringz(), ikey.toStringz());
writeln("TDEBUG: ", nng_errstr(rc));
void set_cert_key_file ( string ipemkeyfile, string ipass ) {
auto rc = nng_tls_config_cert_key_file(tls, toStringz(ipemkeyfile), toStringz(ipass)); // pemkey file should contain both cert and key delimited with \r\n
enforce(rc == 0);
}

void set_auth_mode ( nng_tls_auth_mode imode ) {
auto rc = nng_tls_config_auth_mode(tls, imode);
enforce(rc == 0);
}

void set_version( nng_tls_version iminversion, nng_tls_version imaxversion ) {
auto rc = nng_tls_config_version(tls, iminversion, imaxversion);
Expand All @@ -1490,6 +1532,21 @@ version(withtls) {
bool fips_mode() {
return nng_tls_engine_fips_mode();
}

nng_tls_mode mode() {
return _mode;
}

string toString(){
return "\r\n------------------------<NNGTLS>\r\n"
~format("engine name: %s\r\n", engine_name)
~format("engine description: %s\r\n", engine_description)
~format("FIPS: %s\r\n", fips_mode)
~format("mode: %s\r\n", mode)
~"------------------------------</NNGTLS>\r\n"
;
}

}

}
Expand Down Expand Up @@ -1995,7 +2052,8 @@ struct WebApp {
}

version(withtls) {
void set_tls ( WebTLS tls ) {
void set_tls ( NNGTLS* tls ) {
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_SERVER);
auto rc = nng_http_server_set_tls(server, tls.tls);
enforce(rc==0, "server set tls");
}
Expand Down Expand Up @@ -2239,8 +2297,16 @@ struct WebClient {
nng_http_res_free(res);
}

version(withtls) {
void set_tls ( NNGTLS* tls ) {
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
auto rc = nng_http_client_set_tls(cli, tls.tls);
enforce(rc==0, "client set tls");
}
}

// static sync get
static WebData get ( string uri, string[string] headers, Duration timeout = 30000.msecs ) {
static WebData get ( string uri, string[string] headers, Duration timeout = 30000.msecs, void* ptls = null ) {
int rc;
nng_http_client *cli;
nng_url *url;
Expand All @@ -2259,6 +2325,15 @@ struct WebClient {
rc = nng_aio_alloc(&aio, null, null);
enforce(rc == 0);
nng_aio_set_timeout(aio, cast(nng_duration)timeout.total!"msecs");

version(withtls) {
if(ptls) {
NNGTLS *tls = cast(NNGTLS*) ptls;
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
rc = nng_http_client_set_tls(cli, tls.tls);
enforce(rc==0, "client set tls");
}
}

scope(exit) {
nng_http_client_free(cli);
Expand Down Expand Up @@ -2287,7 +2362,8 @@ struct WebClient {
}

// static sync post
static WebData post ( string uri, const ubyte[] data, const string[string] headers, Duration timeout = 30000.msecs ) {
static WebData post ( string uri, const ubyte[] data, const string[string] headers, Duration timeout = 30000.msecs, void *ptls = null )
{
int rc;
nng_http_client *cli;
nng_url *url;
Expand All @@ -2306,6 +2382,16 @@ struct WebClient {
rc = nng_aio_alloc(&aio, null, null);
enforce(rc == 0);
nng_aio_set_timeout(aio, cast(nng_duration)timeout.total!"msecs");

version(withtls) {
if(ptls) {
NNGTLS *tls = cast(NNGTLS*) ptls;
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
rc = nng_http_client_set_tls(cli, tls.tls);
enforce(rc==0, "client set tls");
}
}

scope(exit) {
nng_http_client_free(cli);
nng_url_free(url);
Expand Down Expand Up @@ -2335,7 +2421,8 @@ struct WebClient {
}

// static async get
static NNGAio get_async ( string uri, const string[string] headers, const webclienthandler handler, Duration timeout = 30000.msecs, void *context = null ) {
static NNGAio get_async ( string uri, const string[string] headers, const webclienthandler handler, Duration timeout = 30000.msecs, void *context = null, void *ptls = null )
{
int rc;
nng_aio *aio;
nng_http_client *cli;
Expand All @@ -2352,6 +2439,17 @@ struct WebClient {
enforce(rc == 0);
rc = nng_aio_alloc(&aio, null, null);
enforce(rc == 0);

version(withtls) {
if(ptls) {
NNGTLS *tls = cast(NNGTLS*) ptls;
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
rc = nng_http_client_set_tls(cli, tls.tls);
enforce(rc==0, "client set tls");
}
}


nng_aio_set_timeout(aio, cast(nng_duration)timeout.total!"msecs");
WebClientAsync *a = new WebClientAsync();
a.uri = cast(char*)uri.dup.toStringz();
Expand All @@ -2373,7 +2471,8 @@ struct WebClient {
}

// static async post
static NNGAio post_async ( string uri, const ubyte[] data, const string[string] headers, const webclienthandler handler, Duration timeout = 30000.msecs, void *context = null ) {
static NNGAio post_async ( string uri, const ubyte[] data, const string[string] headers, const webclienthandler handler, Duration timeout = 30000.msecs, void *context = null, void *ptls = null )
{
int rc;
nng_aio *aio;
nng_http_client *cli;
Expand All @@ -2390,6 +2489,16 @@ struct WebClient {
enforce(rc == 0);
rc = nng_aio_alloc(&aio, null, null);
enforce(rc == 0);

version(withtls) {
if(ptls) {
NNGTLS *tls = cast(NNGTLS*) ptls;
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
rc = nng_http_client_set_tls(cli, tls.tls);
enforce(rc==0, "client set tls");
}
}

nng_aio_set_timeout(aio, cast(nng_duration)timeout.total!"msecs");
WebClientAsync *a = new WebClientAsync();
a.uri = cast(char*)uri.dup.toStringz();
Expand Down Expand Up @@ -2424,7 +2533,8 @@ struct WebClient {
webclienthandler onsuccess,
webclienthandler onerror,
Duration timeout = 30000.msecs,
void *context = null )
void *context = null,
void *ptls = null )
{
int rc;
nng_aio *aio;
Expand All @@ -2442,6 +2552,16 @@ struct WebClient {
enforce(rc == 0);
rc = nng_aio_alloc(&aio, null, null);
enforce(rc == 0);

version(withtls) {
if(ptls) {
NNGTLS *tls = cast(NNGTLS*) ptls;
enforce(tls.mode == nng_tls_mode.NNG_TLS_MODE_CLIENT);
rc = nng_http_client_set_tls(cli, tls.tls);
enforce(rc==0, "client set tls");
}
}

nng_aio_set_timeout(aio, cast(nng_duration)timeout.total!"msecs");
WebClientAsync *a = new WebClientAsync();
a.uri = cast(char*)uri.dup.toStringz();
Expand Down
51 changes: 51 additions & 0 deletions tests/ssl/certkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIUfEYJ3h6+SldFrjkyJSeo36AoY4YwDQYJKoZIhvcNAQEL
BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X
DTIzMTAyMjIzNDExN1oXDTI0MTAyMTIzNDExN1owWTELMAkGA1UEBhMCQVUxEzAR
BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5
IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEAnW4FjuDs4ArONUyGAvgVniYETptQOzvmOdY9RLMOyieUhee1FaML
UMUY8lkUTwTMwbjPALyOxhHrRltDoSuDdhOsBkQFNDZ58x/vBEc5zIOGtofDsPdy
EVznul0wFrb/8gHwDXSoewvWzhKSlDBzu0sqCa1QmwuIpjr9JuRXP0KNtphw6rju
iNE1P0x7lb7uZCjvOxzhMINc4aAlc4ZQ6IOgfVcadvXESRT35w73Q3tz4pmyXfHC
1NCWSe0hfeN2xZh0DtlvTni4dW/XBjT+TAbW1wOqw6T2H/RUr4cpmc6lI2x/+xRh
qBfbevj3lUDCfMU0Y0mM27ZFXu8eydwTGQIDAQABo1MwUTAdBgNVHQ4EFgQULuKO
TaxsGGzgjAGmkiXwbzmxSsUwHwYDVR0jBBgwFoAULuKOTaxsGGzgjAGmkiXwbzmx
SsUwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAaqidX9YdiCmK
0wbqfsW3A6GVq4xIfhQE711GaiWCJQE2dUFnf6OQbkr7cpuB9DF/q4IVb86pjUj/
kEWYvyZEj0jwemVZy+tjK4vmgKtl8n856xobTj3U+mdczzk8/wn80n7YyTmGoyQ5
hyuxgMfkNrqwT5fjmC9eDnqLu7ZOFwscWschmpYjH7yaBVBZTe3ItRcOJIOTI1pA
0FfBXrmnoMb0uofYrM8WunvSOkCncqsxArb8reJ3uWZyWAsJIsw0x/VH5D446AxV
m9d5tTCycc8m+DpFxoEGrYlwWQCxCg2GGETSfr9WV3iInRyCPcil4BOXsR87eKx5
O6WZ/9epkQ==
-----END CERTIFICATE-----

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCdbgWO4OzgCs41
TIYC+BWeJgROm1A7O+Y51j1Esw7KJ5SF57UVowtQxRjyWRRPBMzBuM8AvI7GEetG
W0OhK4N2E6wGRAU0NnnzH+8ERznMg4a2h8Ow93IRXOe6XTAWtv/yAfANdKh7C9bO
EpKUMHO7SyoJrVCbC4imOv0m5Fc/Qo22mHDquO6I0TU/THuVvu5kKO87HOEwg1zh
oCVzhlDog6B9Vxp29cRJFPfnDvdDe3PimbJd8cLU0JZJ7SF943bFmHQO2W9OeLh1
b9cGNP5MBtbXA6rDpPYf9FSvhymZzqUjbH/7FGGoF9t6+PeVQMJ8xTRjSYzbtkVe
7x7J3BMZAgMBAAECggEAAIr6le2Mo5El+OUUqTn1yR/Ub/j1I98nAhgNCgmcCXJt
frC33SU8ysCDP4KzITqhAiIDBLuhumkhaJKz/wBJacTTmQnvAqkVbpMznc4pEt15
P3PkZt3TlN+/JNNhcRKce1cqXsGCOzplOTyzKLOqEoFF2daxKne1tu0JJnMvIda1
h/C61qwwyIiuuX8mxEOObhrFpiNONOi2ZaZ3b7VZPEPrkfgIcrcyHSs0rqrCiCCi
2stDM6OhezxgD7Dy4Z4q/nS6SsAVCDY+jjJV4CjM2w8sGXfbA0QRJkPuax3SSeyX
L1/bvHpGags7fYNYhfFgNaesXynv1sx9bXvkPM9eIQKBgQDJQ+rCe1X/RFj0d12y
giwWX/H56fzg5yGvj8kyrILQ1b0J8irlBaygJxbNxCLeXVAQx/V4LlNmcMjmfBsP
kNlDzOJRDaf2hedmvFSROv64N/fZLRePLGoD7t39Al/SwdDaksHjZHK4aCa+LAJj
WrSs/SadjYYanXBv9AKvBBeGpQKBgQDIPkbaJ/2an7G66g40N3SbO313rzG8FDvz
I404zy+9rckKNYifEonmjT3EVWUTXOrXShWBqQMJ2f9rw51Qt76+uZfWkcK1nlfQ
Fz9wRwxYXIW/xSi7K4eAinuDzJlJifgA+fZhTh+EpAYIEx0NGvHbsZfDMkyBRLJS
DItWDrXkZQKBgHxYc7AYVzdQ2Myg+siQ2AAy4uMOh2fEJPG8mgeuwVuY0iRU899v
NAn2XIZgSVKswAy+HZBUvr4prFWKE4X4beMPsDt3fnA2ppK4hF793eWe3ofU7htM
y2sGpyvrzZv+lrSTuypsItx/rIAN3KPZpIrEFJl+mH3VC2R/kzDiDE7pAoGANtXv
GzDWXzCaQEB2UVBaa2Q4ML1WVlYIMMYsl0ENptjfdB9C4aT3BJ7rKkfkXRAV840D
JLW+8kSzkLRJ8V/QKXSzovvZoVjSXVbwdXPPaqczrVd1lwQNoGLL/kTaOWxB8SqC
kRUOxokQaceqLfuR/gK9N6QflUrVtmhfA9sVbo0CgYEAkFlv+2QyZOO5IvX5AQIb
XCkh1feANoUztaUMQzW9HSF8IWpm002i+jt6KVhWqjvuSV7quE+m7sgruVK7izlt
K4N4tesmoY+wyFV/ZWHCA/fJosVBMZKQfNLIDxXFNqMpKeAxa6od7WxR+kQu29nO
Oe/HPc/aL0FrIF63svAb88s=
-----END PRIVATE KEY-----
Loading

0 comments on commit daf3620

Please sign in to comment.