/*
 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/core_dispatch.h>
#include "bio_local.h"
#include "internal/cryptlib.h"

typedef struct {
    OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex;
    OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex;
    OSSL_FUNC_BIO_gets_fn *c_bio_gets;
    OSSL_FUNC_BIO_puts_fn *c_bio_puts;
    OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl;
    OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref;
    OSSL_FUNC_BIO_free_fn *c_bio_free;
} BIO_CORE_GLOBALS;

static void bio_core_globals_free(void *vbcg)
{
    OPENSSL_free(vbcg);
}

static void *bio_core_globals_new(OSSL_LIB_CTX *ctx)
{
    return OPENSSL_zalloc(sizeof(BIO_CORE_GLOBALS));
}

static const OSSL_LIB_CTX_METHOD bio_core_globals_method = {
    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
    bio_core_globals_new,
    bio_core_globals_free,
};

static ossl_inline BIO_CORE_GLOBALS *get_globals(OSSL_LIB_CTX *libctx)
{
    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_BIO_CORE_INDEX,
                                 &bio_core_globals_method);
}

static int bio_core_read_ex(BIO *bio, char *data, size_t data_len,
                            size_t *bytes_read)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);

    if (bcgbl == NULL || bcgbl->c_bio_read_ex == NULL)
        return 0;
    return bcgbl->c_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read);
}

static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len,
                             size_t *written)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);

    if (bcgbl == NULL || bcgbl->c_bio_write_ex == NULL)
        return 0;
    return bcgbl->c_bio_write_ex(BIO_get_data(bio), data, data_len, written);
}

static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);

    if (bcgbl == NULL || bcgbl->c_bio_ctrl == NULL)
        return -1;
    return bcgbl->c_bio_ctrl(BIO_get_data(bio), cmd, num, ptr);
}

static int bio_core_gets(BIO *bio, char *buf, int size)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);

    if (bcgbl == NULL || bcgbl->c_bio_gets == NULL)
        return -1;
    return bcgbl->c_bio_gets(BIO_get_data(bio), buf, size);
}

static int bio_core_puts(BIO *bio, const char *str)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);

    if (bcgbl == NULL || bcgbl->c_bio_puts == NULL)
        return -1;
    return bcgbl->c_bio_puts(BIO_get_data(bio), str);
}

static int bio_core_new(BIO *bio)
{
    BIO_set_init(bio, 1);

    return 1;
}

static int bio_core_free(BIO *bio)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(bio->libctx);

    if (bcgbl == NULL)
        return 0;

    BIO_set_init(bio, 0);
    bcgbl->c_bio_free(BIO_get_data(bio));

    return 1;
}

static const BIO_METHOD corebiometh = {
    BIO_TYPE_CORE_TO_PROV,
    "BIO to Core filter",
    bio_core_write_ex,
    NULL,
    bio_core_read_ex,
    NULL,
    bio_core_puts,
    bio_core_gets,
    bio_core_ctrl,
    bio_core_new,
    bio_core_free,
    NULL,
};

const BIO_METHOD *BIO_s_core(void)
{
    return &corebiometh;
}

BIO *BIO_new_from_core_bio(OSSL_LIB_CTX *libctx, OSSL_CORE_BIO *corebio)
{
    BIO *outbio;
    BIO_CORE_GLOBALS *bcgbl = get_globals(libctx);

    /* Check the library context has been initialised with the callbacks */
    if (bcgbl == NULL || (bcgbl->c_bio_write_ex == NULL && bcgbl->c_bio_read_ex == NULL))
        return NULL;

    if ((outbio = BIO_new_ex(libctx, BIO_s_core())) == NULL)
        return NULL;

    if (!bcgbl->c_bio_up_ref(corebio)) {
        BIO_free(outbio);
        return NULL;
    }
    BIO_set_data(outbio, corebio);
    return outbio;
}

int ossl_bio_init_core(OSSL_LIB_CTX *libctx, const OSSL_DISPATCH *fns)
{
    BIO_CORE_GLOBALS *bcgbl = get_globals(libctx);

    if (bcgbl == NULL)
	    return 0;

    for (; fns->function_id != 0; fns++) {
        switch (fns->function_id) {
        case OSSL_FUNC_BIO_READ_EX:
            if (bcgbl->c_bio_read_ex == NULL)
                bcgbl->c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns);
            break;
        case OSSL_FUNC_BIO_WRITE_EX:
            if (bcgbl->c_bio_write_ex == NULL)
                bcgbl->c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns);
            break;
        case OSSL_FUNC_BIO_GETS:
            if (bcgbl->c_bio_gets == NULL)
                bcgbl->c_bio_gets = OSSL_FUNC_BIO_gets(fns);
            break;
        case OSSL_FUNC_BIO_PUTS:
            if (bcgbl->c_bio_puts == NULL)
                bcgbl->c_bio_puts = OSSL_FUNC_BIO_puts(fns);
            break;
        case OSSL_FUNC_BIO_CTRL:
            if (bcgbl->c_bio_ctrl == NULL)
                bcgbl->c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns);
            break;
        case OSSL_FUNC_BIO_UP_REF:
            if (bcgbl->c_bio_up_ref == NULL)
                bcgbl->c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns);
            break;
        case OSSL_FUNC_BIO_FREE:
            if (bcgbl->c_bio_free == NULL)
                bcgbl->c_bio_free = OSSL_FUNC_BIO_free(fns);
            break;
        }
    }

    return 1;
}
