Linux-Event
view release on metacpan or search on metacpan
xstls/TLS.xs view on Meta::CPAN
server_name_ok = !verify
|| X509_VERIFY_PARAM_set1_ip_asc(
SSL_get0_param(tls->ssl), server_name) == 1;
} else {
server_name_ok = SSL_set_tlsext_host_name(tls->ssl, server_name) == 1
&& (!verify || SSL_set1_host(tls->ssl, server_name) == 1);
}
if (!server_name_ok) {
let_set_error(tls, "failed to configure TLS server name");
snprintf(construction_error, sizeof(construction_error), "%s", tls->error);
SSL_free(tls->ssl);
SSL_CTX_free(tls->ctx);
free(tls);
croak("%s", construction_error);
}
alpn = (const unsigned char *)SvPVbyte(alpn_sv, alpn_len);
let_copy_alpn(tls, alpn, alpn_len);
if (tls->alpn_len
&& SSL_set_alpn_protos(tls->ssl, tls->alpn, tls->alpn_len) != 0) {
SSL_free(tls->ssl);
SSL_CTX_free(tls->ctx);
free(tls->alpn);
free(tls);
croak("failed to configure client ALPN");
}
SSL_set_connect_state(tls->ssl);
RETVAL = sv_setref_pv(newSV(0), CLASS, (void *)tls);
OUTPUT:
RETVAL
SV *
_new_server(CLASS, cert_file, key_file, alpn_sv, handshake_timeout, shutdown_timeout)
const char *CLASS
const char *cert_file
const char *key_file
SV *alpn_sv
NV handshake_timeout
NV shutdown_timeout
PREINIT:
let_tls_t *tls;
STRLEN alpn_len;
const unsigned char *alpn;
char construction_error[512];
CODE:
tls = (let_tls_t *)calloc(1, sizeof(*tls));
if (!tls) croak("calloc TLS provider failed");
tls->fd = -1;
tls->deadline_fd = -1;
tls->role = 2;
tls->handshake_timeout = (double)handshake_timeout;
tls->shutdown_timeout = (double)shutdown_timeout;
tls->ctx = SSL_CTX_new(TLS_server_method());
if (!tls->ctx) {
free(tls);
croak("SSL_CTX_new server failed");
}
SSL_CTX_set_min_proto_version(tls->ctx, TLS1_2_VERSION);
if (SSL_CTX_use_certificate_chain_file(tls->ctx, cert_file) != 1
|| SSL_CTX_use_PrivateKey_file(tls->ctx, key_file,
SSL_FILETYPE_PEM) != 1
|| SSL_CTX_check_private_key(tls->ctx) != 1) {
let_set_error(tls, "failed to load TLS server identity");
snprintf(construction_error, sizeof(construction_error), "%s", tls->error);
SSL_CTX_free(tls->ctx);
free(tls);
croak("%s", construction_error);
}
alpn = (const unsigned char *)SvPVbyte(alpn_sv, alpn_len);
let_copy_alpn(tls, alpn, alpn_len);
if (tls->alpn_len)
SSL_CTX_set_alpn_select_cb(tls->ctx, let_server_alpn_select, tls);
tls->ssl = SSL_new(tls->ctx);
if (!tls->ssl) {
SSL_CTX_free(tls->ctx);
free(tls->alpn);
free(tls);
croak("SSL_new server failed");
}
SSL_set_mode(tls->ssl,
SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_set_accept_state(tls->ssl);
RETVAL = sv_setref_pv(newSV(0), CLASS, (void *)tls);
OUTPUT:
RETVAL
SV *
_new_server_template(CLASS, cert_file, key_file, alpn_sv, handshake_timeout, shutdown_timeout)
const char *CLASS
const char *cert_file
const char *key_file
SV *alpn_sv
NV handshake_timeout
NV shutdown_timeout
PREINIT:
let_tls_t *tls;
let_server_config_t *config;
STRLEN alpn_len;
const unsigned char *alpn;
char construction_error[512];
CODE:
tls = (let_tls_t *)calloc(1, sizeof(*tls));
if (!tls) croak("calloc TLS server template failed");
tls->fd = -1;
tls->deadline_fd = -1;
tls->role = 2;
tls->handshake_timeout = (double)handshake_timeout;
tls->shutdown_timeout = (double)shutdown_timeout;
tls->ctx = SSL_CTX_new(TLS_server_method());
if (!tls->ctx) {
free(tls);
croak("SSL_CTX_new prepared server failed");
}
SSL_CTX_set_min_proto_version(tls->ctx, TLS1_2_VERSION);
if (SSL_CTX_use_certificate_chain_file(tls->ctx, cert_file) != 1
|| SSL_CTX_use_PrivateKey_file(tls->ctx, key_file,
SSL_FILETYPE_PEM) != 1
|| SSL_CTX_check_private_key(tls->ctx) != 1) {
let_set_error(tls, "failed to load prepared TLS server identity");
snprintf(construction_error, sizeof(construction_error), "%s", tls->error);
SSL_CTX_free(tls->ctx);
free(tls);
croak("%s", construction_error);
}
alpn = (const unsigned char *)SvPVbyte(alpn_sv, alpn_len);
config = let_server_config_new(alpn, alpn_len);
if (!config) {
SSL_CTX_free(tls->ctx);
free(tls);
croak("malloc prepared TLS server configuration failed");
}
tls->server_config = config;
if (config->alpn_len)
SSL_CTX_set_alpn_select_cb(tls->ctx,
let_prepared_server_alpn_select, config);
RETVAL = sv_setref_pv(newSV(0), CLASS, (void *)tls);
OUTPUT:
RETVAL
SV *
_clone_server(object)
SV *object
PREINIT:
let_tls_t *template;
let_tls_t *tls;
CODE:
template = let_from_sv(object);
if (!template || !template->ctx || template->role != 2
|| template->ssl || !template->server_config)
croak("not a prepared Linux::Event TLS server context");
tls = (let_tls_t *)calloc(1, sizeof(*tls));
if (!tls) croak("calloc TLS server connection failed");
tls->fd = -1;
tls->deadline_fd = -1;
tls->role = 2;
tls->handshake_timeout = template->handshake_timeout;
tls->shutdown_timeout = template->shutdown_timeout;
if (SSL_CTX_up_ref(template->ctx) != 1) {
free(tls);
croak("SSL_CTX_up_ref prepared server failed");
}
tls->ctx = template->ctx;
tls->server_config = template->server_config;
let_server_config_retain(tls->server_config);
tls->ssl = SSL_new(tls->ctx);
if (!tls->ssl) {
SSL_CTX_free(tls->ctx);
let_server_config_release(tls->server_config);
free(tls);
croak("SSL_new prepared server connection failed");
}
SSL_set_mode(tls->ssl,
SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_set_accept_state(tls->ssl);
RETVAL = sv_setref_pv(newSV(0), "Linux::Event::TLS", (void *)tls);
OUTPUT:
RETVAL
( run in 0.589 second using v1.01-cache-2.11-cpan-8dfa8b56332 )