mirror of https://github.com/openssl/openssl.git
				
				
				
			
		
			
				
	
	
		
			196 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright 2020-2025 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 <string.h> /* strcmp */
 | |
| 
 | |
| #include <openssl/types.h> /* Ensure we have the ENGINE type, regardless */
 | |
| #include <openssl/err.h>
 | |
| #ifndef OPENSSL_NO_ENGINE
 | |
| # include <openssl/engine.h>
 | |
| #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;
 | |
| }
 | |
| 
 | |
| #ifndef OPENSSL_NO_DEPRECATED_3_6
 | |
| 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;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 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;
 | |
| }
 |