opnsense-src/apps/lib/engine_loader.c

204 lines
5.5 KiB
C
Raw Normal View History

openssl: Vendor import of OpenSSL-3.0.8 Summary: Release notes can be found at https://www.openssl.org/news/openssl-3.0-notes.html . Obtained from: https://www.openssl.org/source/openssl-3.0.8.tar.gz Differential Revision: https://reviews.freebsd.org/D38835 Test Plan: ``` $ git status On branch vendor/openssl-3.0 nothing to commit, working tree clean $ (cd ..; fetch http://www.openssl.org/source/openssl-${OSSLVER}.tar.gz http://www.openssl.org/source/openssl-${OSSLVER}.tar.gz.asc) openssl-3.0.8.tar.gz 14 MB 4507 kBps 04s openssl-3.0.8.tar.gz.asc 833 B 10 MBps 00s $ set | egrep '(XLIST|OSSLVER)=' OSSLVER=3.0.8 XLIST=FREEBSD-Xlist $ gpg --list-keys /home/ngie/.gnupg/pubring.kbx ----------------------------- pub rsa4096 2014-10-04 [SC] 7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C uid [ unknown] Richard Levitte <richard@levitte.org> uid [ unknown] Richard Levitte <levitte@lp.se> uid [ unknown] Richard Levitte <levitte@openssl.org> sub rsa4096 2014-10-04 [E] $ gpg --verify openssl-${OSSLVER}.tar.gz.asc openssl-${OSSLVER}.tar.gz gpg: Signature made Tue Feb 7 05:43:55 2023 PST gpg: using RSA key 7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C gpg: Good signature from "Richard Levitte <richard@levitte.org>" [unknown] gpg: aka "Richard Levitte <levitte@lp.se>" [unknown] gpg: aka "Richard Levitte <levitte@openssl.org>" [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 7953 AC1F BC3D C8B3 B292 393E D5E9 E43F 7DF9 EE8C $ (cd vendor.checkout/; git status; find . -type f -or -type l | cut -c 3- | sort > ../old) On branch vendor/openssl-3.0 nothing to commit, working tree clean $ tar -x -X $XLIST -f ../openssl-${OSSLVER}.tar.gz -C .. $ rsync --exclude FREEBSD.* --delete -avzz ../openssl-${OSSLVER}/* . $ cat .git gitdir: /home/ngie/git/freebsd-src/.git/worktrees/vendor.checkout $ diff -arq ../openssl-3.0.8 . Only in .: .git Only in .: FREEBSD-Xlist Only in .: FREEBSD-upgrade $ git status FREEBSD* On branch vendor/openssl-3.0 nothing to commit, working tree clean $ ``` Reviewers: emaste, jkim Subscribers: imp, andrew, dab Differential Revision: https://reviews.freebsd.org/D38835
2023-02-28 23:21:31 -05:00
/*
* 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 (OPENSSL_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 && 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