/* * Copyright 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 */ /* * Here is a set of wrappers for the ENGINE API, which are no-ops when the * ENGINE API is disabled / removed. * We need to suppress deprecation warnings to make this work. */ #define OPENSSL_SUPPRESS_DEPRECATED #include /* strcmp */ #include /* Ensure we have the ENGINE type, regardless */ #include #ifndef OPENSSL_NO_ENGINE # include #endif #include "apps.h" #ifndef OPENSSL_NO_ENGINE /* Try to load an engine in a shareable library */ static ENGINE *try_load_engine(const char *engine) { ENGINE *e = NULL; if ((e = ENGINE_by_id("dynamic")) != NULL) { if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { ENGINE_free(e); e = NULL; } } return e; } #endif ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug) { ENGINE *e = NULL; #ifndef OPENSSL_NO_ENGINE if (id != NULL) { if (strcmp(id, "auto") == 0) { BIO_printf(bio_err, "Enabling auto ENGINE support\n"); ENGINE_register_all_complete(); return NULL; } if ((e = ENGINE_by_id(id)) == NULL && (e = try_load_engine(id)) == NULL) { BIO_printf(bio_err, "Invalid engine \"%s\"\n", id); ERR_print_errors(bio_err); return NULL; } if (debug) (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, (void *)get_ui_method(), 0, 1) || !ENGINE_set_default(e, methods)) { BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e)); ERR_print_errors(bio_err); ENGINE_free(e); return NULL; } BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e)); } #endif return e; } void release_engine(ENGINE *e) { #ifndef OPENSSL_NO_ENGINE /* Free our "structural" reference. */ ENGINE_free(e); #endif } int init_engine(ENGINE *e) { int rv = 1; #ifndef OPENSSL_NO_ENGINE rv = ENGINE_init(e); #endif return rv; } int finish_engine(ENGINE *e) { int rv = 1; #ifndef OPENSSL_NO_ENGINE rv = ENGINE_finish(e); #endif return rv; } char *make_engine_uri(ENGINE *e, const char *key_id, const char *desc) { char *new_uri = NULL; #ifndef OPENSSL_NO_ENGINE if (e == NULL) { BIO_printf(bio_err, "No engine specified for loading %s\n", desc); } else if (key_id == NULL) { BIO_printf(bio_err, "No engine key id specified for loading %s\n", desc); } else { const char *engineid = ENGINE_get_id(e); size_t uri_sz = sizeof(ENGINE_SCHEME_COLON) - 1 + strlen(engineid) + 1 /* : */ + strlen(key_id) + 1 /* \0 */ ; new_uri = OPENSSL_malloc(uri_sz); if (new_uri != NULL) { OPENSSL_strlcpy(new_uri, ENGINE_SCHEME_COLON, uri_sz); OPENSSL_strlcat(new_uri, engineid, uri_sz); OPENSSL_strlcat(new_uri, ":", uri_sz); OPENSSL_strlcat(new_uri, key_id, uri_sz); } } #else BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); #endif return new_uri; } int get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e) { const EVP_PKEY_ASN1_METHOD *ameth; ENGINE *tmpeng = NULL; int pkey_id = NID_undef; ERR_set_mark(); ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); #if !defined(OPENSSL_NO_ENGINE) ENGINE_finish(tmpeng); if (ameth == NULL && e != NULL) ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); else #endif /* We're only interested if it comes from an ENGINE */ if (tmpeng == NULL) ameth = NULL; ERR_pop_to_mark(); if (ameth == NULL) return NID_undef; EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); return pkey_id; } const EVP_MD *get_digest_from_engine(const char *name) { #ifndef OPENSSL_NO_ENGINE ENGINE *eng; eng = ENGINE_get_digest_engine(OBJ_sn2nid(name)); if (eng != NULL) { ENGINE_finish(eng); return EVP_get_digestbyname(name); } #endif return NULL; } const EVP_CIPHER *get_cipher_from_engine(const char *name) { #ifndef OPENSSL_NO_ENGINE ENGINE *eng; eng = ENGINE_get_cipher_engine(OBJ_sn2nid(name)); if (eng != NULL) { ENGINE_finish(eng); return EVP_get_cipherbyname(name); } #endif return NULL; }