43#include <openssl/err.h>
44#include <openssl/ssl.h>
51 while ((opt = getopt(argc, argv,
"V:")) != EOF) {
53 if (!strncmp(
"LOG_NULL", optarg, 8))
55 else if (!strncmp(
"LOG_NOTICE", optarg, 10))
57 else if (!strncmp(
"LOG_INFO", optarg, 8))
59 else if (!strncmp(
"LOG_ERR", optarg, 7))
61 else if (!strncmp(
"LOG_DEBUG", optarg, 9))
69#if N_OSSL_OPENSSL_ATLEAST(0x10101000L)
96static const client_case cases[] = {
97 {
"TLS 1.1 client refused", TLS1_1_VERSION, NULL, 0, NULL},
98 {
"TLS 1.2 RSA key exchange (no forward secrecy) refused", TLS1_2_VERSION,
"AES128-GCM-SHA256:AES256-GCM-SHA384", 0, NULL},
99 {
"TLS 1.2 CBC cipher refused", TLS1_2_VERSION,
"ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA", 0, NULL},
100 {
"TLS 1.2 ECDHE-GCM accepted", TLS1_2_VERSION,
"ECDHE-RSA-AES128-GCM-SHA256", 1,
"TLSv1.2"},
101 {
"default client gets TLS 1.3", 0, NULL, 1,
"TLSv1.3"},
107static SSL_CTX* client_ctx(
const client_case* c) {
108 SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
113 SSL_CTX_set_security_level(ctx, 0);
114 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
116 SSL_CTX_set_max_proto_version(ctx, c->max_version);
118 SSL_CTX_set_cipher_list(ctx, c->ciphers);
119 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
129static int bio_handshake(SSL_CTX* sctx, SSL_CTX* cctx,
char* version,
size_t vsz) {
130 SSL* s = SSL_new(sctx);
131 SSL* c = SSL_new(cctx);
132 BIO *bs = NULL, *bc = NULL;
133 int i, done_s = 0, done_c = 0, ok = 0;
134 if (!s || !c || BIO_new_bio_pair(&bs, 0, &bc, 0) != 1)
136 SSL_set_bio(s, bs, bs);
137 SSL_set_bio(c, bc, bc);
138 SSL_set_accept_state(s);
139 SSL_set_connect_state(c);
140 for (i = 0; i < 64 && !(done_s && done_c); i++) {
141 int rc = SSL_do_handshake(c), rs;
144 else if (SSL_get_error(c, rc) != SSL_ERROR_WANT_READ && SSL_get_error(c, rc) != SSL_ERROR_WANT_WRITE)
146 rs = SSL_do_handshake(s);
149 else if (SSL_get_error(s, rs) != SSL_ERROR_WANT_READ && SSL_get_error(s, rs) != SSL_ERROR_WANT_WRITE)
152 ok = done_s && done_c;
154 snprintf(version, vsz,
"%s", SSL_get_version(c));
163static N_STR *ca_cert = NULL, *ca_key = NULL, *leaf_cert = NULL, *leaf_key = NULL;
166static void test_pem_context(
void) {
170 for (p = 18400; p < 18500 && !srv; p++) {
171 snprintf(
port,
sizeof(
port),
"%d", p);
180 STACK_OF(SSL_CIPHER)* list = SSL_CTX_get_ciphers(srv->
ctx);
181 int i, only_good = 1;
182 expect_true(
"minimum version is TLS 1.2", SSL_CTX_get_min_proto_version(srv->
ctx) == TLS1_2_VERSION);
183 expect_true(
"no compression", (SSL_CTX_get_options(srv->
ctx) & SSL_OP_NO_COMPRESSION) != 0);
184 expect_true(
"no session tickets", (SSL_CTX_get_options(srv->
ctx) & SSL_OP_NO_TICKET) != 0);
185 expect_true(
"server cipher order", (SSL_CTX_get_options(srv->
ctx) & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0);
186#ifdef SSL_OP_NO_RENEGOTIATION
187 expect_true(
"no renegotiation", (SSL_CTX_get_options(srv->
ctx) & SSL_OP_NO_RENEGOTIATION) != 0);
189 for (i = 0; list && i < sk_SSL_CIPHER_num(list); i++) {
190 const char* name = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(list, i));
191 int tls13 = strncmp(name,
"TLS_", 4) == 0;
192 int good12 = strncmp(name,
"ECDHE-", 6) == 0 && (strstr(name,
"GCM") || strstr(name,
"CHACHA20"));
193 if (!tls13 && !good12) {
198 expect_true(
"only forward-secret AEAD ciphers", only_good && list && sk_SSL_CIPHER_num(list) > 0);
199 for (i = 0; i < (int)(
sizeof(cases) /
sizeof(cases[0])); i++) {
201 SSL_CTX* cctx = client_ctx(&cases[i]);
202 int ok = cctx && bio_handshake(srv->
ctx, cctx, v,
sizeof(v));
203 expect_true(cases[i].what, ok == cases[i].expect_ok && (!ok || !cases[i].expect_v || strcmp(v, cases[i].expect_v) == 0));
222static int pick_cb(
const char* sni,
N_STR** cert_pem,
N_STR** key_pem,
void* user_data) {
225 *cert_pem =
nstrdup(leaf_cert);
227 return (*cert_pem && *key_pem) ? 0 : -1;
233static void* sni_server(
void* p) {
234 sni_srv* s = (sni_srv*)p;
236 s->accepted = c != NULL;
240 SSL_read(c->
ssl, b,
sizeof(b));
247static void test_sni_path(
void) {
251 for (p = 18500; p < 18600 && !listen; p++) {
252 snprintf(
port,
sizeof(
port),
"%d", p);
256 expect_true(
"SNI listening socket", listen != NULL);
259 for (i = 0; i < (int)(
sizeof(cases) /
sizeof(cases[0])); i++) {
260 sni_srv s = {listen, 0};
263 SSL_CTX* cctx = client_ctx(&cases[i]);
266 pthread_create(&th, NULL, sni_server, &s);
268 SSL* ssl = SSL_new(cctx);
269 SSL_set_fd(ssl, (
int)cli->
link.
sock);
270 SSL_set_tlsext_host_name(ssl,
"localhost");
271 ok = SSL_connect(ssl) == 1;
273 snprintf(v,
sizeof(v),
"%s", SSL_get_version(ssl));
279 pthread_join(th, NULL);
282 snprintf(what,
sizeof(what),
"SNI path: %s", cases[i].what);
283 expect_true(what, ok == cases[i].expect_ok && s.accepted == cases[i].expect_ok &&
284 (!ok || !cases[i].expect_v || strcmp(v, cases[i].expect_v) == 0));
297int main(
int argc,
char** argv) {
300#if !N_OSSL_OPENSSL_ATLEAST(0x10101000L)
301 n_log(
LOG_NOTICE,
"ex_network_tls_defaults: skipped, needs OpenSSL 1.1.1 or later");
void process_args(int argc, char **argv)
static void expect_true(const char *label, int cond)
static int pick_cb(const char *sni, N_STR **cert_pem, N_STR **key_pem, void *user_data)
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
#define LOG_NOTICE
normal but significant condition
#define LOG_NULL
no log output
#define LOG_INFO
informational
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
N_STR * nstrdup(N_STR *str)
Duplicate a N_STR.
A box including a string and his lenght.
int n_x509_generate_ca(const char *cn, int days, N_STR **ca_cert_pem, N_STR **ca_key_pem)
Generate a self-signed certificate authority (CA) keypair and cert.
int n_x509_mint_host_cert(const char *host, const N_STR *ca_cert_pem, const N_STR *ca_key_pem, int days, N_STR **leaf_cert_pem, N_STR **leaf_key_pem)
Mint a per-host leaf certificate signed by the given CA.
N_SOCKET link
networking socket
SOCKET sock
a normal socket
SSL_CTX * ctx
SSL context holder.
int netw_set_crypto_pem(NETWORK *netw, const char *key_pem, const char *cert_pem)
activate SSL encryption using PEM-formatted key and certificate strings loaded from memory
int netw_init_openssl(void)
Do not directly use, internal api.
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
int netw_unload_openssl(void)
Do not directly use, internal api.
#define NETWORK_IPALL
Flag for auto detection by OS of ip version to use.
NETWORK * netw_accept_ssl_with_sni_cb(NETWORK *listen, netw_sni_pick_cb pick, void *user_data)
accept a TLS connection, selecting the server certificate per client SNI
int netw_close(NETWORK **netw)
Closing a specified Network, destroy queues, free the structure.
int netw_connect(NETWORK **netw, char *host, char *port, int ip_version)
Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
Common headers and low-level functions & define.
N_STR and string function declaration.
X.509 helpers: self-signed CA generation and per-host leaf minting.