/*
 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (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 (strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1)
        != 0)
        return NULL;
    p += sizeof(ENGINE_SCHEME_COLON) - 1;

    /* 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)
        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
