1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2006-2021 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/* We need to use some deprecated APIs */ 11e1051a39Sopenharmony_ci#include "internal/deprecated.h" 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci#include "eng_local.h" 14e1051a39Sopenharmony_ci#include <openssl/evp.h> 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_cistatic ENGINE_TABLE *pkey_meth_table = NULL; 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_civoid ENGINE_unregister_pkey_meths(ENGINE *e) 19e1051a39Sopenharmony_ci{ 20e1051a39Sopenharmony_ci engine_table_unregister(&pkey_meth_table, e); 21e1051a39Sopenharmony_ci} 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_cistatic void engine_unregister_all_pkey_meths(void) 24e1051a39Sopenharmony_ci{ 25e1051a39Sopenharmony_ci engine_table_cleanup(&pkey_meth_table); 26e1051a39Sopenharmony_ci} 27e1051a39Sopenharmony_ci 28e1051a39Sopenharmony_ciint ENGINE_register_pkey_meths(ENGINE *e) 29e1051a39Sopenharmony_ci{ 30e1051a39Sopenharmony_ci if (e->pkey_meths) { 31e1051a39Sopenharmony_ci const int *nids; 32e1051a39Sopenharmony_ci int num_nids = e->pkey_meths(e, NULL, &nids, 0); 33e1051a39Sopenharmony_ci if (num_nids > 0) 34e1051a39Sopenharmony_ci return engine_table_register(&pkey_meth_table, 35e1051a39Sopenharmony_ci engine_unregister_all_pkey_meths, e, 36e1051a39Sopenharmony_ci nids, num_nids, 0); 37e1051a39Sopenharmony_ci } 38e1051a39Sopenharmony_ci return 1; 39e1051a39Sopenharmony_ci} 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_civoid ENGINE_register_all_pkey_meths(void) 42e1051a39Sopenharmony_ci{ 43e1051a39Sopenharmony_ci ENGINE *e; 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ci for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) 46e1051a39Sopenharmony_ci ENGINE_register_pkey_meths(e); 47e1051a39Sopenharmony_ci} 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ciint ENGINE_set_default_pkey_meths(ENGINE *e) 50e1051a39Sopenharmony_ci{ 51e1051a39Sopenharmony_ci if (e->pkey_meths) { 52e1051a39Sopenharmony_ci const int *nids; 53e1051a39Sopenharmony_ci int num_nids = e->pkey_meths(e, NULL, &nids, 0); 54e1051a39Sopenharmony_ci if (num_nids > 0) 55e1051a39Sopenharmony_ci return engine_table_register(&pkey_meth_table, 56e1051a39Sopenharmony_ci engine_unregister_all_pkey_meths, e, 57e1051a39Sopenharmony_ci nids, num_nids, 1); 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci return 1; 60e1051a39Sopenharmony_ci} 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci/* 63e1051a39Sopenharmony_ci * Exposed API function to get a functional reference from the implementation 64e1051a39Sopenharmony_ci * table (ie. try to get a functional reference from the tabled structural 65e1051a39Sopenharmony_ci * references) for a given pkey_meth 'nid' 66e1051a39Sopenharmony_ci */ 67e1051a39Sopenharmony_ciENGINE *ENGINE_get_pkey_meth_engine(int nid) 68e1051a39Sopenharmony_ci{ 69e1051a39Sopenharmony_ci return ossl_engine_table_select(&pkey_meth_table, nid, 70e1051a39Sopenharmony_ci OPENSSL_FILE, OPENSSL_LINE); 71e1051a39Sopenharmony_ci} 72e1051a39Sopenharmony_ci 73e1051a39Sopenharmony_ci/* Obtains a pkey_meth implementation from an ENGINE functional reference */ 74e1051a39Sopenharmony_ciconst EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) 75e1051a39Sopenharmony_ci{ 76e1051a39Sopenharmony_ci EVP_PKEY_METHOD *ret; 77e1051a39Sopenharmony_ci ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); 78e1051a39Sopenharmony_ci if (!fn || !fn(e, &ret, NULL, nid)) { 79e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); 80e1051a39Sopenharmony_ci return NULL; 81e1051a39Sopenharmony_ci } 82e1051a39Sopenharmony_ci return ret; 83e1051a39Sopenharmony_ci} 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci/* Gets the pkey_meth callback from an ENGINE structure */ 86e1051a39Sopenharmony_ciENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e) 87e1051a39Sopenharmony_ci{ 88e1051a39Sopenharmony_ci return e->pkey_meths; 89e1051a39Sopenharmony_ci} 90e1051a39Sopenharmony_ci 91e1051a39Sopenharmony_ci/* Sets the pkey_meth callback in an ENGINE structure */ 92e1051a39Sopenharmony_ciint ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) 93e1051a39Sopenharmony_ci{ 94e1051a39Sopenharmony_ci e->pkey_meths = f; 95e1051a39Sopenharmony_ci return 1; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci/* 99e1051a39Sopenharmony_ci * Internal function to free up EVP_PKEY_METHOD structures before an ENGINE 100e1051a39Sopenharmony_ci * is destroyed 101e1051a39Sopenharmony_ci */ 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_civoid engine_pkey_meths_free(ENGINE *e) 104e1051a39Sopenharmony_ci{ 105e1051a39Sopenharmony_ci int i; 106e1051a39Sopenharmony_ci EVP_PKEY_METHOD *pkm; 107e1051a39Sopenharmony_ci if (e->pkey_meths) { 108e1051a39Sopenharmony_ci const int *pknids; 109e1051a39Sopenharmony_ci int npknids; 110e1051a39Sopenharmony_ci npknids = e->pkey_meths(e, NULL, &pknids, 0); 111e1051a39Sopenharmony_ci for (i = 0; i < npknids; i++) { 112e1051a39Sopenharmony_ci if (e->pkey_meths(e, &pkm, NULL, pknids[i])) { 113e1051a39Sopenharmony_ci EVP_PKEY_meth_free(pkm); 114e1051a39Sopenharmony_ci } 115e1051a39Sopenharmony_ci } 116e1051a39Sopenharmony_ci } 117e1051a39Sopenharmony_ci} 118