<commit_before>/*
 * SSL/TLS configuration.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "ssl_factory.h"
#include "ssl_config.h"
#include "pool.h"

#include <inline/compiler.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <assert.h>
#include <stdbool.h>

struct ssl_factory {
    SSL_CTX *ssl_ctx;
};

static int
verify_callback(int ok, gcc_unused X509_STORE_CTX *ctx)
{
    return ok;
}

static bool
apply_config(SSL_CTX *ssl_ctx, const struct ssl_config *config,
             GError **error_r)
{
    ERR_clear_error();

    if (SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, config->key_file,
                                       SSL_FILETYPE_PEM) != 1) {
        ERR_print_errors_fp(stderr);
        g_set_error(error_r, ssl_quark(), 0,
                    "Failed to load key file %s", config->key_file);
        return false;
    }

    if (SSL_CTX_use_certificate_chain_file(ssl_ctx, config->cert_file) != 1) {
        ERR_print_errors_fp(stderr);
        g_set_error(error_r, ssl_quark(), 0,
                    "Failed to load certificate file %s", config->cert_file);
        return false;
    }

    if (config->ca_cert_file != NULL) {
        if (SSL_CTX_load_verify_locations(ssl_ctx, config->ca_cert_file,
                                          NULL) != 1) {
            g_set_error(error_r, ssl_quark(), 0,
                        "Failed to load CA certificate file %s",
                        config->ca_cert_file);
            return false;
        }

        /* send all certificates from this file to the client (list of
           acceptable CA certificates) */

        STACK_OF(X509_NAME) *list =
            SSL_load_client_CA_file(config->ca_cert_file);
        if (list == NULL) {
            g_set_error(error_r, ssl_quark(), 0,
                        "Failed to load CA certificate list from file %s",
                        config->ca_cert_file);
            return false;
        }

        SSL_CTX_set_client_CA_list(ssl_ctx, list);
    }

    if (config->verify != SSL_VERIFY_NO) {
        /* enable client certificates */
        int mode = SSL_VERIFY_PEER;

        if (config->verify == SSL_VERIFY_YES)
            mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;

        SSL_CTX_set_verify(ssl_ctx, mode, verify_callback);
    }

    return true;
}

struct ssl_factory *
ssl_factory_new(struct pool *pool, const struct ssl_config *config,
                GError **error_r)
{
    assert(pool != NULL);
    assert(config != NULL);
    assert(config->cert_file != NULL);
    assert(config->key_file != NULL);

    struct ssl_factory *factory = p_malloc(pool, sizeof(*factory));
    factory->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
    if (factory->ssl_ctx == NULL) {
        g_set_error(error_r, ssl_quark(), 0, "SSL_CTX_new() failed");
        return NULL;
    }

    if (!apply_config(factory->ssl_ctx, config, error_r)) {
        SSL_CTX_free(factory->ssl_ctx);
        return NULL;
    }

    return factory;
}

void
ssl_factory_free(struct ssl_factory *factory)
{
    SSL_CTX_free(factory->ssl_ctx);
}

SSL *
ssl_factory_make(struct ssl_factory *factory)
{
    return SSL_new(factory->ssl_ctx);
}<commit_msg>ssl_factory: add local SSL_CTX variable<commit_after>/*
 * SSL/TLS configuration.
 *
 * author: <NAME> <<EMAIL>>
 */

#include "ssl_factory.h"
#include "ssl_config.h"
#include "pool.h"

#include <inline/compiler.h>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <assert.h>
#include <stdbool.h>

struct ssl_factory {
    SSL_CTX *ssl_ctx;
};

static int
verify_callback(int ok, gcc_unused X509_STORE_CTX *ctx)
{
    return ok;
}

static bool
apply_config(SSL_CTX *ssl_ctx, const struct ssl_config *config,
             GError **error_r)
{
    ERR_clear_error();

    if (SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, config->key_file,
                                       SSL_FILETYPE_PEM) != 1) {
        ERR_print_errors_fp(stderr);
        g_set_error(error_r, ssl_quark(), 0,
                    "Failed to load key file %s", config->key_file);
        return false;
    }

    if (SSL_CTX_use_certificate_chain_file(ssl_ctx, config->cert_file) != 1) {
        ERR_print_errors_fp(stderr);
        g_set_error(error_r, ssl_quark(), 0,
                    "Failed to load certificate file %s", config->cert_file);
        return false;
    }

    if (config->ca_cert_file != NULL) {
        if (SSL_CTX_load_verify_locations(ssl_ctx, config->ca_cert_file,
                                          NULL) != 1) {
            g_set_error(error_r, ssl_quark(), 0,
                        "Failed to load CA certificate file %s",
                        config->ca_cert_file);
            return false;
        }

        /* send all certificates from this file to the client (list of
           acceptable CA certificates) */

        STACK_OF(X509_NAME) *list =
            SSL_load_client_CA_file(config->ca_cert_file);
        if (list == NULL) {
            g_set_error(error_r, ssl_quark(), 0,
                        "Failed to load CA certificate list from file %s",
                        config->ca_cert_file);
            return false;
        }

        SSL_CTX_set_client_CA_list(ssl_ctx, list);
    }

    if (config->verify != SSL_VERIFY_NO) {
        /* enable client certificates */
        int mode = SSL_VERIFY_PEER;

        if (config->verify == SSL_VERIFY_YES)
            mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;

        SSL_CTX_set_verify(ssl_ctx, mode, verify_callback);
    }

    return true;
}

struct ssl_factory *
ssl_factory_new(struct pool *pool, const struct ssl_config *config,
                GError **error_r)
{
    assert(pool != NULL);
    assert(config != NULL);
    assert(config->cert_file != NULL);
    assert(config->key_file != NULL);

    struct ssl_factory *factory = p_malloc(pool, sizeof(*factory));
    SSL_CTX *ssl_ctx = factory->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
    if (ssl_ctx == NULL) {
        g_set_error(error_r, ssl_quark(), 0, "SSL_CTX_new() failed");
        return NULL;
    }

    if (!apply_config(ssl_ctx, config, error_r)) {
        SSL_CTX_free(ssl_ctx);
        return NULL;
    }

    return factory;
}

void
ssl_factory_free(struct ssl_factory *factory)
{
    SSL_CTX_free(factory->ssl_ctx);
}

SSL *
ssl_factory_make(struct ssl_factory *factory)
{
    return SSL_new(factory->ssl_ctx);
}
{'fraction_non_alphanumeric': 0.111198738170347, 'fraction_numerical': 0.005047318611987382, 'mean_word_length': 2.4036500268384327, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2924583', 'n_tokens_mistral': 2158, 'n_tokens_neox': 2064, 'n_words': 434}