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