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 )