1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * Here is a set of wrappers for the ENGINE API, which are no-ops when the 12e1051a39Sopenharmony_ci * ENGINE API is disabled / removed. 13e1051a39Sopenharmony_ci * We need to suppress deprecation warnings to make this work. 14e1051a39Sopenharmony_ci */ 15e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <string.h> /* strcmp */ 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci#include <openssl/types.h> /* Ensure we have the ENGINE type, regardless */ 20e1051a39Sopenharmony_ci#include <openssl/err.h> 21e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 22e1051a39Sopenharmony_ci# include <openssl/engine.h> 23e1051a39Sopenharmony_ci#endif 24e1051a39Sopenharmony_ci#include "apps.h" 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 27e1051a39Sopenharmony_ci/* Try to load an engine in a shareable library */ 28e1051a39Sopenharmony_cistatic ENGINE *try_load_engine(const char *engine) 29e1051a39Sopenharmony_ci{ 30e1051a39Sopenharmony_ci ENGINE *e = NULL; 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci if ((e = ENGINE_by_id("dynamic")) != NULL) { 33e1051a39Sopenharmony_ci if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) 34e1051a39Sopenharmony_ci || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { 35e1051a39Sopenharmony_ci ENGINE_free(e); 36e1051a39Sopenharmony_ci e = NULL; 37e1051a39Sopenharmony_ci } 38e1051a39Sopenharmony_ci } 39e1051a39Sopenharmony_ci return e; 40e1051a39Sopenharmony_ci} 41e1051a39Sopenharmony_ci#endif 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ciENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug) 44e1051a39Sopenharmony_ci{ 45e1051a39Sopenharmony_ci ENGINE *e = NULL; 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 48e1051a39Sopenharmony_ci if (id != NULL) { 49e1051a39Sopenharmony_ci if (strcmp(id, "auto") == 0) { 50e1051a39Sopenharmony_ci BIO_printf(bio_err, "Enabling auto ENGINE support\n"); 51e1051a39Sopenharmony_ci ENGINE_register_all_complete(); 52e1051a39Sopenharmony_ci return NULL; 53e1051a39Sopenharmony_ci } 54e1051a39Sopenharmony_ci if ((e = ENGINE_by_id(id)) == NULL 55e1051a39Sopenharmony_ci && (e = try_load_engine(id)) == NULL) { 56e1051a39Sopenharmony_ci BIO_printf(bio_err, "Invalid engine \"%s\"\n", id); 57e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 58e1051a39Sopenharmony_ci return NULL; 59e1051a39Sopenharmony_ci } 60e1051a39Sopenharmony_ci if (debug) 61e1051a39Sopenharmony_ci (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); 62e1051a39Sopenharmony_ci if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, 63e1051a39Sopenharmony_ci (void *)get_ui_method(), 0, 1) 64e1051a39Sopenharmony_ci || !ENGINE_set_default(e, methods)) { 65e1051a39Sopenharmony_ci BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e)); 66e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 67e1051a39Sopenharmony_ci ENGINE_free(e); 68e1051a39Sopenharmony_ci return NULL; 69e1051a39Sopenharmony_ci } 70e1051a39Sopenharmony_ci 71e1051a39Sopenharmony_ci BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e)); 72e1051a39Sopenharmony_ci } 73e1051a39Sopenharmony_ci#endif 74e1051a39Sopenharmony_ci return e; 75e1051a39Sopenharmony_ci} 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_civoid release_engine(ENGINE *e) 78e1051a39Sopenharmony_ci{ 79e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 80e1051a39Sopenharmony_ci /* Free our "structural" reference. */ 81e1051a39Sopenharmony_ci ENGINE_free(e); 82e1051a39Sopenharmony_ci#endif 83e1051a39Sopenharmony_ci} 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ciint init_engine(ENGINE *e) 86e1051a39Sopenharmony_ci{ 87e1051a39Sopenharmony_ci int rv = 1; 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 90e1051a39Sopenharmony_ci rv = ENGINE_init(e); 91e1051a39Sopenharmony_ci#endif 92e1051a39Sopenharmony_ci return rv; 93e1051a39Sopenharmony_ci} 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ciint finish_engine(ENGINE *e) 96e1051a39Sopenharmony_ci{ 97e1051a39Sopenharmony_ci int rv = 1; 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 100e1051a39Sopenharmony_ci rv = ENGINE_finish(e); 101e1051a39Sopenharmony_ci#endif 102e1051a39Sopenharmony_ci return rv; 103e1051a39Sopenharmony_ci} 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_cichar *make_engine_uri(ENGINE *e, const char *key_id, const char *desc) 106e1051a39Sopenharmony_ci{ 107e1051a39Sopenharmony_ci char *new_uri = NULL; 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 110e1051a39Sopenharmony_ci if (e == NULL) { 111e1051a39Sopenharmony_ci BIO_printf(bio_err, "No engine specified for loading %s\n", desc); 112e1051a39Sopenharmony_ci } else if (key_id == NULL) { 113e1051a39Sopenharmony_ci BIO_printf(bio_err, "No engine key id specified for loading %s\n", desc); 114e1051a39Sopenharmony_ci } else { 115e1051a39Sopenharmony_ci const char *engineid = ENGINE_get_id(e); 116e1051a39Sopenharmony_ci size_t uri_sz = 117e1051a39Sopenharmony_ci sizeof(ENGINE_SCHEME_COLON) - 1 118e1051a39Sopenharmony_ci + strlen(engineid) 119e1051a39Sopenharmony_ci + 1 /* : */ 120e1051a39Sopenharmony_ci + strlen(key_id) 121e1051a39Sopenharmony_ci + 1 /* \0 */ 122e1051a39Sopenharmony_ci ; 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci new_uri = OPENSSL_malloc(uri_sz); 125e1051a39Sopenharmony_ci if (new_uri != NULL) { 126e1051a39Sopenharmony_ci OPENSSL_strlcpy(new_uri, ENGINE_SCHEME_COLON, uri_sz); 127e1051a39Sopenharmony_ci OPENSSL_strlcat(new_uri, engineid, uri_sz); 128e1051a39Sopenharmony_ci OPENSSL_strlcat(new_uri, ":", uri_sz); 129e1051a39Sopenharmony_ci OPENSSL_strlcat(new_uri, key_id, uri_sz); 130e1051a39Sopenharmony_ci } 131e1051a39Sopenharmony_ci } 132e1051a39Sopenharmony_ci#else 133e1051a39Sopenharmony_ci BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); 134e1051a39Sopenharmony_ci#endif 135e1051a39Sopenharmony_ci return new_uri; 136e1051a39Sopenharmony_ci} 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ciint get_legacy_pkey_id(OSSL_LIB_CTX *libctx, const char *algname, ENGINE *e) 139e1051a39Sopenharmony_ci{ 140e1051a39Sopenharmony_ci const EVP_PKEY_ASN1_METHOD *ameth; 141e1051a39Sopenharmony_ci ENGINE *tmpeng = NULL; 142e1051a39Sopenharmony_ci int pkey_id = NID_undef; 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ci ERR_set_mark(); 145e1051a39Sopenharmony_ci ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ENGINE) 148e1051a39Sopenharmony_ci ENGINE_finish(tmpeng); 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_ci if (ameth == NULL && e != NULL) 151e1051a39Sopenharmony_ci ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); 152e1051a39Sopenharmony_ci else 153e1051a39Sopenharmony_ci#endif 154e1051a39Sopenharmony_ci /* We're only interested if it comes from an ENGINE */ 155e1051a39Sopenharmony_ci if (tmpeng == NULL) 156e1051a39Sopenharmony_ci ameth = NULL; 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci ERR_pop_to_mark(); 159e1051a39Sopenharmony_ci if (ameth == NULL) 160e1051a39Sopenharmony_ci return NID_undef; 161e1051a39Sopenharmony_ci 162e1051a39Sopenharmony_ci EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_ci return pkey_id; 165e1051a39Sopenharmony_ci} 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ciconst EVP_MD *get_digest_from_engine(const char *name) 168e1051a39Sopenharmony_ci{ 169e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 170e1051a39Sopenharmony_ci ENGINE *eng; 171e1051a39Sopenharmony_ci 172e1051a39Sopenharmony_ci eng = ENGINE_get_digest_engine(OBJ_sn2nid(name)); 173e1051a39Sopenharmony_ci if (eng != NULL) { 174e1051a39Sopenharmony_ci ENGINE_finish(eng); 175e1051a39Sopenharmony_ci return EVP_get_digestbyname(name); 176e1051a39Sopenharmony_ci } 177e1051a39Sopenharmony_ci#endif 178e1051a39Sopenharmony_ci return NULL; 179e1051a39Sopenharmony_ci} 180e1051a39Sopenharmony_ci 181e1051a39Sopenharmony_ciconst EVP_CIPHER *get_cipher_from_engine(const char *name) 182e1051a39Sopenharmony_ci{ 183e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 184e1051a39Sopenharmony_ci ENGINE *eng; 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci eng = ENGINE_get_cipher_engine(OBJ_sn2nid(name)); 187e1051a39Sopenharmony_ci if (eng != NULL) { 188e1051a39Sopenharmony_ci ENGINE_finish(eng); 189e1051a39Sopenharmony_ci return EVP_get_cipherbyname(name); 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci#endif 192e1051a39Sopenharmony_ci return NULL; 193e1051a39Sopenharmony_ci} 194