#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
#include <openssl/engine.h>
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/core_names.h>
+#include <openssl/store.h>
+#endif
#include "openssl_shim.h"
}
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
-isc_result_t
-dst__openssl_fromlabel(const char *engine, const char *label, const char *pin,
- EVP_PKEY **ppub, EVP_PKEY **ppriv) {
+static isc_result_t
+dst__openssl_fromlabel_engine(int key_base_id, const char *engine,
+ const char *label, const char *pin,
+ EVP_PKEY **ppub, EVP_PKEY **ppriv) {
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
isc_result_t ret = ISC_R_SUCCESS;
ENGINE *e = NULL;
DST_RET(dst__openssl_toresult2("ENGINE_load_public_key",
DST_R_OPENSSLFAILURE));
}
+ if (EVP_PKEY_base_id(*ppub) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
*ppriv = ENGINE_load_private_key(e, label, NULL, NULL);
if (*ppriv == NULL) {
DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
DST_R_OPENSSLFAILURE));
}
+ if (EVP_PKEY_base_id(*ppriv) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
err:
return (ret);
#else /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+ UNUSED(key_base_id);
UNUSED(engine);
UNUSED(label);
UNUSED(pin);
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
}
+static isc_result_t
+dst__openssl_fromlabel_provider(int key_base_id, const char *engine,
+ const char *label, const char *pin,
+ EVP_PKEY **ppub, EVP_PKEY **ppriv) {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ isc_result_t ret = DST_R_OPENSSLFAILURE;
+ OSSL_STORE_CTX *ctx = NULL;
+
+ UNUSED(pin);
+ UNUSED(engine);
+
+ ctx = OSSL_STORE_open(label, NULL, NULL, NULL, NULL);
+ if (!ctx) {
+ DST_RET(dst__openssl_toresult2("OSSL_STORE_open_ex",
+ DST_R_OPENSSLFAILURE));
+ }
+
+ while (!OSSL_STORE_eof(ctx)) {
+ OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
+ if (info == NULL) {
+ continue;
+ }
+ switch (OSSL_STORE_INFO_get_type(info)) {
+ case OSSL_STORE_INFO_PKEY:
+ if (*ppriv != NULL) {
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ }
+ *ppriv = OSSL_STORE_INFO_get1_PKEY(info);
+ if (EVP_PKEY_get_base_id(*ppriv) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
+ break;
+ case OSSL_STORE_INFO_PUBKEY:
+ if (*ppub != NULL) {
+ DST_RET(DST_R_INVALIDPUBLICKEY);
+ }
+ *ppub = OSSL_STORE_INFO_get1_PUBKEY(info);
+ if (EVP_PKEY_get_base_id(*ppub) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
+ break;
+ }
+ OSSL_STORE_INFO_free(info);
+ }
+ if (*ppriv != NULL && *ppub != NULL) {
+ ret = ISC_R_SUCCESS;
+ }
+err:
+ OSSL_STORE_close(ctx);
+ return (ret);
+#else
+ UNUSED(key_base_id);
+ UNUSED(engine);
+ UNUSED(label);
+ UNUSED(pin);
+ UNUSED(ppub);
+ UNUSED(ppriv);
+ return (DST_R_OPENSSLFAILURE);
+#endif
+}
+
+isc_result_t
+dst__openssl_fromlabel(int key_base_id, const char *engine, const char *label,
+ const char *pin, EVP_PKEY **ppub, EVP_PKEY **ppriv) {
+ isc_result_t result;
+
+ result = dst__openssl_fromlabel_provider(key_base_id, engine, label,
+ pin, ppub, ppriv);
+ if (result != DST_R_OPENSSLFAILURE) {
+ return (result);
+ }
+
+ return (dst__openssl_fromlabel_engine(key_base_id, engine, label, pin,
+ ppub, ppriv));
+}
+
/*! \file */