int s2n_connection_set_config()

in tls/s2n_connection.c [375:449]


int s2n_connection_set_config(struct s2n_connection *conn, struct s2n_config *config)
{
    POSIX_ENSURE_REF(conn);
    POSIX_ENSURE_REF(config);

    if (conn->config == config) {
        return 0;
    }

    /* We only support one client certificate */
    if (s2n_config_get_num_default_certs(config) > 1 && conn->mode == S2N_CLIENT) {
        POSIX_BAIL(S2N_ERR_TOO_MANY_CERTIFICATES);
    }

    s2n_x509_validator_wipe(&conn->x509_validator);

    s2n_cert_auth_type auth_type = config->client_cert_auth_type;

    if (conn->client_cert_auth_type_overridden) {
        auth_type = conn->client_cert_auth_type;
    }

    int8_t dont_need_x509_validation = (conn->mode == S2N_SERVER) && (auth_type == S2N_CERT_AUTH_NONE);

    if (config->disable_x509_validation || dont_need_x509_validation) {
        POSIX_GUARD(s2n_x509_validator_init_no_x509_validation(&conn->x509_validator));
    }
    else {
        POSIX_GUARD(s2n_x509_validator_init(&conn->x509_validator, &config->trust_store, config->check_ocsp));
        if (!conn->verify_host_fn_overridden) {
            if (config->verify_host != NULL) {
                conn->verify_host_fn = config->verify_host;
                conn->data_for_verify_host = config->data_for_verify_host;
            } else {
                conn->verify_host_fn = s2n_default_verify_host;
                conn->data_for_verify_host = conn;
            }
        }

        if (config->max_verify_cert_chain_depth_set) {
            POSIX_GUARD(s2n_x509_validator_set_max_chain_depth(&conn->x509_validator, config->max_verify_cert_chain_depth));
        }
    }
    conn->tickets_to_send = config->initial_tickets_to_send;

    if (conn->psk_params.psk_list.len == 0 && !conn->psk_mode_overridden) {
        POSIX_GUARD(s2n_connection_set_psk_mode(conn, config->psk_mode));
        conn->psk_mode_overridden = false;
    }

    /* If at least one certificate does not have a private key configured,
     * the config must provide an async pkey callback.
     * The handshake could still fail if the callback doesn't offload the
     * signature, but this at least catches configuration mistakes.
     */
    if (config->no_signing_key) {
        POSIX_ENSURE(config->async_pkey_cb, S2N_ERR_NO_PRIVATE_KEY);
    }

    if (config->quic_enabled) {
        /* If QUIC is ever enabled for a connection via the config,
         * we should enforce that it can never be disabled by
         * changing the config.
         *
         * Enabling QUIC indicates that the connection is being used by
         * a QUIC implementation, which never changes. Disabling QUIC
         * partially through a connection could also potentially be
         * dangerous, as QUIC handles encryption.
         */
        POSIX_GUARD(s2n_connection_enable_quic(conn));
    }

    conn->config = config;
    return S2N_SUCCESS;
}