/*
 * Copyright 2006-2020 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/objects.h>
#include "obj_xref.h"
#include "internal/nelem.h"
#include "internal/thread_once.h"
#include <openssl/err.h>

static STACK_OF(nid_triple) *sig_app, *sigx_app;
static CRYPTO_RWLOCK *sig_lock;

static int sig_cmp(const nid_triple *a, const nid_triple *b)
{
    return a->sign_id - b->sign_id;
}

DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);

static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b)
{
    return (*a)->sign_id - (*b)->sign_id;
}

DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);

static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b)
{
    int ret;

    ret = (*a)->hash_id - (*b)->hash_id;
    if (ret != 0)
        return ret;
    return (*a)->pkey_id - (*b)->pkey_id;
}

IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);

static CRYPTO_ONCE sig_init = CRYPTO_ONCE_STATIC_INIT;

DEFINE_RUN_ONCE_STATIC(o_sig_init)
{
    sig_lock = CRYPTO_THREAD_lock_new();
    return sig_lock != NULL;
}

static ossl_inline int obj_sig_init(void)
{
    return RUN_ONCE(&sig_init, o_sig_init);
}

static int ossl_obj_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid,
                                    int lock)
{
    nid_triple tmp;
    const nid_triple *rv;
    int idx;

    if (signid == NID_undef)
        return 0;

    tmp.sign_id = signid;
    rv = OBJ_bsearch_sig(&tmp, sigoid_srt, OSSL_NELEM(sigoid_srt));
    if (rv == NULL) {
        if (!obj_sig_init())
            return 0;
        if (lock && !CRYPTO_THREAD_read_lock(sig_lock)) {
            ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
            return 0;
        }
        if (sig_app != NULL) {
            idx = sk_nid_triple_find(sig_app, &tmp);
            if (idx >= 0)
                rv = sk_nid_triple_value(sig_app, idx);
        }
        if (lock)
            CRYPTO_THREAD_unlock(sig_lock);
        if (rv == NULL)
            return 0;
    }

    if (pdig_nid != NULL)
        *pdig_nid = rv->hash_id;
    if (ppkey_nid != NULL)
        *ppkey_nid = rv->pkey_id;
    return 1;
}

int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
{
    return ossl_obj_find_sigid_algs(signid, pdig_nid, ppkey_nid, 1);
}

int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
{
    nid_triple tmp;
    const nid_triple *t = &tmp;
    const nid_triple **rv;
    int idx;

    if (dig_nid == NID_undef || pkey_nid == NID_undef)
        return 0;

    tmp.hash_id = dig_nid;
    tmp.pkey_id = pkey_nid;

    rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, OSSL_NELEM(sigoid_srt_xref));
    if (rv == NULL) {
        if (!obj_sig_init())
            return 0;
        if (!CRYPTO_THREAD_read_lock(sig_lock)) {
            ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_READ_LOCK);
            return 0;
        }
        if (sigx_app != NULL) {
            idx = sk_nid_triple_find(sigx_app, &tmp);
            if (idx >= 0) {
                t = sk_nid_triple_value(sigx_app, idx);
                rv = &t;
            }
        }
        CRYPTO_THREAD_unlock(sig_lock);
        if (rv == NULL)
            return 0;
    }

    if (psignid != NULL)
        *psignid = (*rv)->sign_id;
    return 1;
}

int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
{
    nid_triple *ntr;
    int dnid = NID_undef, pnid = NID_undef, ret = 0;

    if (signid == NID_undef || pkey_id == NID_undef)
        return 0;

    if (!obj_sig_init())
        return 0;

    if ((ntr = OPENSSL_malloc(sizeof(*ntr))) == NULL) {
        ERR_raise(ERR_LIB_OBJ, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    ntr->sign_id = signid;
    ntr->hash_id = dig_id;
    ntr->pkey_id = pkey_id;

    if (!CRYPTO_THREAD_write_lock(sig_lock)) {
        ERR_raise(ERR_LIB_OBJ, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
        OPENSSL_free(ntr);
        return 0;
    }

    /* Check that the entry doesn't exist or exists as desired */
    if (ossl_obj_find_sigid_algs(signid, &dnid, &pnid, 0)) {
        ret = dnid == dig_id && pnid == pkey_id;
        goto err;
    }

    if (sig_app == NULL) {
        sig_app = sk_nid_triple_new(sig_sk_cmp);
        if (sig_app == NULL)
            goto err;
    }
    if (sigx_app == NULL) {
        sigx_app = sk_nid_triple_new(sigx_cmp);
        if (sigx_app == NULL)
            goto err;
    }

    /*
     * Better might be to find where to insert the element and insert it there.
     * This would avoid the sorting steps below.
     */
    if (!sk_nid_triple_push(sig_app, ntr))
        goto err;
    if (!sk_nid_triple_push(sigx_app, ntr)) {
        ntr = NULL;             /* This is referenced by sig_app still */
        goto err;
    }

    sk_nid_triple_sort(sig_app);
    sk_nid_triple_sort(sigx_app);

    ntr = NULL;
    ret = 1;
 err:
    OPENSSL_free(ntr);
    CRYPTO_THREAD_unlock(sig_lock);
    return ret;
}

static void sid_free(nid_triple *tt)
{
    OPENSSL_free(tt);
}

void OBJ_sigid_free(void)
{
    sk_nid_triple_pop_free(sig_app, sid_free);
    sk_nid_triple_free(sigx_app);
    CRYPTO_THREAD_lock_free(sig_lock);
    sig_app = NULL;
    sigx_app = NULL;
    sig_lock = NULL;
}
