/*
 * Copyright 2018-2022 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
 */

/*
 * Here is an STORE loader for ENGINE backed keys.  It relies on deprecated
 * functions, and therefore need to have deprecation warnings suppressed.
 * This file is not compiled at all in a '--api=3 no-deprecated' configuration.
 */
#define OPENSSL_SUPPRESS_DEPRECATED

#include "apps.h"

#ifndef OPENSSL_NO_ENGINE

# include <stdarg.h>
# include <string.h>
# include <openssl/engine.h>
# include <openssl/store.h>

/*
 * Support for legacy private engine keys via the 'org.openssl.engine:' scheme
 *
 * org.openssl.engine:{engineid}:{keyid}
 *
 * Note: we ONLY support ENGINE_load_private_key() and ENGINE_load_public_key()
 * Note 2: This scheme has a precedent in code in PKIX-SSH. for exactly
 * this sort of purpose.
 */

/* Local definition of OSSL_STORE_LOADER_CTX */
struct ossl_store_loader_ctx_st {
    ENGINE *e;                   /* Structural reference */
    char *keyid;
    int expected;
    int loaded;                  /* 0 = key not loaded yet, 1 = key loaded */
};

static OSSL_STORE_LOADER_CTX *OSSL_STORE_LOADER_CTX_new(ENGINE *e, char *keyid)
{
    OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));

    if (ctx != NULL) {
        ctx->e = e;
        ctx->keyid = keyid;
    }
    return ctx;
}

static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx)
{
    if (ctx != NULL) {
        ENGINE_free(ctx->e);
        OPENSSL_free(ctx->keyid);
        OPENSSL_free(ctx);
    }
}

static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader,
                                          const char *uri,
                                          const UI_METHOD *ui_method,
                                          void *ui_data)
{
    const char *p = uri, *q;
    ENGINE *e = NULL;
    char *keyid = NULL;
    OSSL_STORE_LOADER_CTX *ctx = NULL;

    if (!CHECK_AND_SKIP_CASE_PREFIX(p, ENGINE_SCHEME_COLON))
        return NULL;

    /* Look for engine ID */
    q = strchr(p, ':');
    if (q != NULL                /* There is both an engine ID and a key ID */
        && p[0] != ':'           /* The engine ID is at least one character */
        && q[1] != '\0') {       /* The key ID is at least one character */
        char engineid[256];
        size_t engineid_l = q - p;

        strncpy(engineid, p, engineid_l);
        engineid[engineid_l] = '\0';
        e = ENGINE_by_id(engineid);

        keyid = OPENSSL_strdup(q + 1);
    }

    if (e != NULL && keyid != NULL)
        ctx = OSSL_STORE_LOADER_CTX_new(e, keyid);

    if (ctx == NULL) {
        OPENSSL_free(keyid);
        ENGINE_free(e);
    }

    return ctx;
}

static int engine_expect(OSSL_STORE_LOADER_CTX *ctx, int expected)
{
    if (expected == 0
        || expected == OSSL_STORE_INFO_PUBKEY
        || expected == OSSL_STORE_INFO_PKEY) {
        ctx->expected = expected;
        return 1;
    }
    return 0;
}

static OSSL_STORE_INFO *engine_load(OSSL_STORE_LOADER_CTX *ctx,
                                    const UI_METHOD *ui_method, void *ui_data)
{
    EVP_PKEY *pkey = NULL, *pubkey = NULL;
    OSSL_STORE_INFO *info = NULL;

    if (ctx->loaded == 0) {
        if (ENGINE_init(ctx->e)) {
            if (ctx->expected == 0
                || ctx->expected == OSSL_STORE_INFO_PKEY)
                pkey =
                    ENGINE_load_private_key(ctx->e, ctx->keyid,
                                            (UI_METHOD *)ui_method, ui_data);
            if ((pkey == NULL && ctx->expected == 0)
                || ctx->expected == OSSL_STORE_INFO_PUBKEY)
                pubkey =
                    ENGINE_load_public_key(ctx->e, ctx->keyid,
                                           (UI_METHOD *)ui_method, ui_data);
            ENGINE_finish(ctx->e);
        }
    }

    ctx->loaded = 1;

    if (pubkey != NULL)
        info = OSSL_STORE_INFO_new_PUBKEY(pubkey);
    else if (pkey != NULL)
        info = OSSL_STORE_INFO_new_PKEY(pkey);
    if (info == NULL) {
        EVP_PKEY_free(pkey);
        EVP_PKEY_free(pubkey);
    }
    return info;
}

static int engine_eof(OSSL_STORE_LOADER_CTX *ctx)
{
    return ctx->loaded != 0;
}

static int engine_error(OSSL_STORE_LOADER_CTX *ctx)
{
    return 0;
}

static int engine_close(OSSL_STORE_LOADER_CTX *ctx)
{
    OSSL_STORE_LOADER_CTX_free(ctx);
    return 1;
}

int setup_engine_loader(void)
{
    OSSL_STORE_LOADER *loader = NULL;

    if ((loader = OSSL_STORE_LOADER_new(NULL, ENGINE_SCHEME)) == NULL
        || !OSSL_STORE_LOADER_set_open(loader, engine_open)
        || !OSSL_STORE_LOADER_set_expect(loader, engine_expect)
        || !OSSL_STORE_LOADER_set_load(loader, engine_load)
        || !OSSL_STORE_LOADER_set_eof(loader, engine_eof)
        || !OSSL_STORE_LOADER_set_error(loader, engine_error)
        || !OSSL_STORE_LOADER_set_close(loader, engine_close)
        || !OSSL_STORE_register_loader(loader)) {
        OSSL_STORE_LOADER_free(loader);
        loader = NULL;
    }

    return loader != NULL;
}

void destroy_engine_loader(void)
{
    OSSL_STORE_LOADER *loader = OSSL_STORE_unregister_loader(ENGINE_SCHEME);
    OSSL_STORE_LOADER_free(loader);
}

#else  /* !OPENSSL_NO_ENGINE */

int setup_engine_loader(void)
{
    return 0;
}

void destroy_engine_loader(void)
{
}

#endif
