39#include <openssl/ssl.h>
40#include <openssl/x509.h>
43#define SNI_HOST "test.host.example"
63 while ((opt = getopt(argc, argv,
"hvV:")) != EOF) {
66 if (!strncmp(
"LOG_NULL", optarg, 8))
68 else if (!strncmp(
"LOG_NOTICE", optarg, 10))
70 else if (!strncmp(
"LOG_INFO", optarg, 8))
72 else if (!strncmp(
"LOG_ERR", optarg, 7))
74 else if (!strncmp(
"LOG_DEBUG", optarg, 9))
77 fprintf(stderr,
"Unknown log level %s\n", optarg);
82 fprintf(stderr,
"ex_network_sni\n");
86 fprintf(stderr,
"usage: %s [-V LOG_LEVEL]\n", argv[0]);
95 const char* host = (sni && sni[0]) ? sni :
"localhost";
106 char reply[] =
"hello-from-server";
121 for (p = 18300; p < 18400; p++) {
124 snprintf(ps,
sizeof(ps),
"%d", p);
126 snprintf(port_out, port_out_len,
"%s", ps);
135int main(
int argc,
char** argv) {
167 pthread_create(&th, NULL,
server_fn, &srv);
178 char msg[] =
"hello-from-client";
185 peer = SSL_get1_peer_certificate(cli->
ssl);
191 X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, cn,
sizeof(cn));
194 n_log(
LOG_ERR,
"certificate CN does not match the requested SNI host");
200 char vrerr[128] =
"";
204 n_log(
LOG_NOTICE,
"verify result: trusted=%d reason='%s'", trusted, vrerr);
205 if (trusted != FALSE) {
206 n_log(
LOG_ERR,
"private-CA leaf was unexpectedly trusted");
209 if (vrerr[0] ==
'\0') {
210 n_log(
LOG_ERR,
"verify failure did not report a reason");
218 pthread_join(th, NULL);
void process_args(int argc, char **argv)
#define MSG_LEN
fixed exchange message length (both messages are 17 chars + NUL)
static void * server_fn(void *p)
static NETWORK * bind_free(char *port_out, size_t port_out_len)
static int pick_cb(const char *sni, N_STR **cert_pem, N_STR **key_pem, void *user_data)
#define SNI_HOST
the host name the client requests via SNI
CA used by the server to mint per-host leaves.
#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
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.
int netw_ssl_get_verify_result(NETWORK *netw, const char *expected_host, char *errbuf, size_t errsz)
evaluate the peer certificate of a completed TLS client connection
ssize_t send_ssl_data(void *netw, char *buf, uint32_t n)
send data onto the socket
int netw_ssl_set_verify(NETWORK *netw, int enable)
enable or disable SSL peer certificate verification
int netw_init_openssl(void)
Do not directly use, internal api.
ssize_t recv_ssl_data(void *netw, char *buf, uint32_t n)
recv data from the socket
int netw_make_listening(NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
Make a NETWORK be a Listening network.
int netw_ssl_do_handshake(NETWORK *netw, const char *sni_hostname)
Complete the SSL handshake on an already-connected 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.
int netw_ssl_connect_client_to(NETWORK **netw, char *host, char *port, int ip_version, int connect_timeout_ms)
Connect as an SSL client without providing a client certificate.
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.
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.