/*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
+#include <openssl/cmac.h>
#include <openssl/engine.h>
#include "internal/asn1_int.h"
if (mode >= 0)
pkey->save_parameters = mode;
- return (ret);
+ return ret;
}
#endif
#ifndef OPENSSL_NO_EC
if (mode >= 0)
pkey->save_parameters = mode;
- return (ret);
+ return ret;
}
#endif
- return (0);
+ return 0;
}
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
* is NULL just return 1 or 0 if the algorithm exists.
*/
-static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
+ int len)
{
const EVP_PKEY_ASN1_METHOD *ameth;
- ENGINE *e = NULL;
+ ENGINE **eptr = (e == NULL) ? &e : NULL;
+
if (pkey) {
if (pkey->pkey.ptr)
EVP_PKEY_free_it(pkey);
if ((type == pkey->save_type) && pkey->ameth)
return 1;
#ifndef OPENSSL_NO_ENGINE
- /* If we have an ENGINE release it */
+ /* If we have ENGINEs release them */
ENGINE_finish(pkey->engine);
pkey->engine = NULL;
+ ENGINE_finish(pkey->pmeth_engine);
+ pkey->pmeth_engine = NULL;
#endif
}
if (str)
- ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+ ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
else
- ameth = EVP_PKEY_asn1_find(&e, type);
+ ameth = EVP_PKEY_asn1_find(eptr, type);
#ifndef OPENSSL_NO_ENGINE
- if (pkey == NULL)
+ if (pkey == NULL && eptr != NULL)
ENGINE_finish(e);
#endif
if (ameth == NULL) {
return 1;
}
+EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
+ const unsigned char *priv,
+ size_t len)
+{
+ EVP_PKEY *ret = EVP_PKEY_new();
+
+ if (ret == NULL
+ || !pkey_set_type(ret, e, type, NULL, -1)) {
+ /* EVPerr already called */
+ goto err;
+ }
+
+ if (ret->ameth->set_priv_key == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ goto err;
+ }
+
+ if (!ret->ameth->set_priv_key(ret, priv, len)) {
+ EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED);
+ goto err;
+ }
+
+ return ret;
+
+ err:
+ EVP_PKEY_free(ret);
+ return NULL;
+}
+
+EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
+ const unsigned char *pub,
+ size_t len)
+{
+ EVP_PKEY *ret = EVP_PKEY_new();
+
+ if (ret == NULL
+ || !pkey_set_type(ret, e, type, NULL, -1)) {
+ /* EVPerr already called */
+ goto err;
+ }
+
+ if (ret->ameth->set_pub_key == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ goto err;
+ }
+
+ if (!ret->ameth->set_pub_key(ret, pub, len)) {
+ EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, EVP_R_KEY_SETUP_FAILED);
+ goto err;
+ }
+
+ return ret;
+
+ err:
+ EVP_PKEY_free(ret);
+ return NULL;
+}
+
+EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
+ size_t len, const EVP_CIPHER *cipher)
+{
+#ifndef OPENSSL_NO_CMAC
+ EVP_PKEY *ret = EVP_PKEY_new();
+ CMAC_CTX *cmctx = CMAC_CTX_new();
+
+ if (ret == NULL
+ || cmctx == NULL
+ || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) {
+ /* EVPerr already called */
+ goto err;
+ }
+
+ if (!CMAC_Init(cmctx, priv, len, cipher, e)) {
+ EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
+ goto err;
+ }
+
+ ret->pkey.ptr = cmctx;
+ return ret;
+
+ err:
+ EVP_PKEY_free(ret);
+ CMAC_CTX_free(cmctx);
+ return NULL;
+#else
+ EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return NULL;
+#endif
+}
+
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
{
- return pkey_set_type(pkey, type, NULL, -1);
+ return pkey_set_type(pkey, NULL, type, NULL, -1);
}
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
{
- return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+ return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
}
-
+#ifndef OPENSSL_NO_ENGINE
+int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
+{
+ if (e != NULL) {
+ if (!ENGINE_init(e)) {
+ EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB);
+ return 0;
+ }
+ if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
+ ENGINE_finish(e);
+ EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM);
+ return 0;
+ }
+ }
+ ENGINE_finish(pkey->pmeth_engine);
+ pkey->pmeth_engine = e;
+ return 1;
+}
+#endif
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
{
if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(x->engine);
x->engine = NULL;
+ ENGINE_finish(x->pmeth_engine);
+ x->pmeth_engine = NULL;
#endif
}