Port EVP raw key API from OpenSSL.
authorjsing <jsing@openbsd.org>
Thu, 10 Nov 2022 14:46:44 +0000 (14:46 +0000)
committerjsing <jsing@openbsd.org>
Thu, 10 Nov 2022 14:46:44 +0000 (14:46 +0000)
This will be needed to deal with Curve25519 based keys.

ok beck@ tb@

lib/libcrypto/asn1/asn1_locl.h
lib/libcrypto/evp/evp.h
lib/libcrypto/evp/evp_err.c
lib/libcrypto/evp/p_lib.c

index e15b98b..8180e9b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: asn1_locl.h,v 1.40 2022/11/08 12:56:00 beck Exp $ */
+/* $OpenBSD: asn1_locl.h,v 1.41 2022/11/10 14:46:44 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006.
  */
@@ -142,6 +142,15 @@ struct evp_pkey_asn1_method_st {
        int (*pkey_check)(const EVP_PKEY *pk);
        int (*pkey_public_check)(const EVP_PKEY *pk);
        int (*pkey_param_check)(const EVP_PKEY *pk);
+
+       int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *private_key,
+           size_t len);
+       int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *public_key,
+           size_t len);
+       int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *out_private_key,
+           size_t *out_len);
+       int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *out_public_key,
+           size_t *out_len);
 } /* EVP_PKEY_ASN1_METHOD */;
 
 /* Method to handle CRL access.
index ec6141e..31c26b4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp.h,v 1.108 2022/11/09 19:18:08 jsing Exp $ */
+/* $OpenBSD: evp.h,v 1.109 2022/11/10 14:46:44 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -399,6 +399,17 @@ unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx);
 unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx);
 #define EVP_CIPHER_CTX_mode(e)         (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE)
 
+#if defined(LIBRESSL_NEXT_API) || defined(LIBRESSL_INTERNAL)
+EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *engine,
+    const unsigned char *private_key, size_t len);
+EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *engine,
+    const unsigned char *public_key, size_t len);
+int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey,
+    unsigned char *out_private_key, size_t *out_len);
+int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey,
+    unsigned char *out_public_key, size_t *out_len);
+#endif
+
 #define EVP_ENCODE_LENGTH(l)   (((l+2)/3*4)+(l/48+1)*2+80)
 #define EVP_DECODE_LENGTH(l)   ((l+3)/4*3+80)
 
@@ -1414,6 +1425,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_EXPECTING_A_ECDSA_KEY                     141
 #define EVP_R_EXPECTING_A_EC_KEY                        142
 #define EVP_R_FIPS_MODE_NOT_SUPPORTED                   167
+#define EVP_R_GET_RAW_KEY_FAILED                        182
 #define EVP_R_INITIALIZATION_ERROR                      134
 #define EVP_R_INPUT_NOT_INITIALIZED                     111
 #define EVP_R_INVALID_DIGEST                            152
index 4feea1a..109d2d4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_err.c,v 1.28 2022/07/12 14:42:49 kn Exp $ */
+/* $OpenBSD: evp_err.c,v 1.29 2022/11/10 14:46:44 jsing Exp $ */
 /* ====================================================================
  * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
@@ -101,6 +101,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
        {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) , "expecting a ecdsa key"},
        {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    , "expecting a ec key"},
        {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+       {ERR_REASON(EVP_R_GET_RAW_KEY_FAILED)    , "get raw key failed"},
        {ERR_REASON(EVP_R_INITIALIZATION_ERROR)  , "initialization error"},
        {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) , "input not initialized"},
        {ERR_REASON(EVP_R_INVALID_DIGEST)        , "invalid digest"},
index b6cef5a..2e0830b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: p_lib.c,v 1.29 2022/06/27 12:36:05 tb Exp $ */
+/* $OpenBSD: p_lib.c,v 1.30 2022/11/10 14:46:44 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -278,6 +278,96 @@ EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
        return pkey_set_type(pkey, NULL, type, NULL, -1);
 }
 
+EVP_PKEY *
+EVP_PKEY_new_raw_private_key(int type, ENGINE *engine,
+    const unsigned char *private_key, size_t len)
+{
+       EVP_PKEY *ret;
+
+       if ((ret = EVP_PKEY_new()) == NULL)
+               goto err;
+
+       if (!pkey_set_type(ret, engine, type, NULL, -1))
+               goto err;
+
+       if (ret->ameth->set_priv_key == NULL) {
+               EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+               goto err;
+       }
+       if (!ret->ameth->set_priv_key(ret, private_key, len)) {
+               EVPerror(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 *engine,
+    const unsigned char *public_key, size_t len)
+{
+       EVP_PKEY *ret;
+
+       if ((ret = EVP_PKEY_new()) == NULL)
+               goto err;
+
+       if (!pkey_set_type(ret, engine, type, NULL, -1))
+               goto err;
+
+       if (ret->ameth->set_pub_key == NULL) {
+               EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+               goto err;
+       }
+       if (!ret->ameth->set_pub_key(ret, public_key, len)) {
+               EVPerror(EVP_R_KEY_SETUP_FAILED);
+               goto err;
+       }
+
+       return ret;
+
+ err:
+       EVP_PKEY_free(ret);
+
+       return NULL;
+}
+
+int
+EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey,
+    unsigned char *out_private_key, size_t *out_len)
+{
+       if (pkey->ameth->get_priv_key == NULL) {
+               EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+               return 0;
+       }
+       if (!pkey->ameth->get_priv_key(pkey, out_private_key, out_len)) {
+               EVPerror(EVP_R_GET_RAW_KEY_FAILED);
+               return 0;
+       }
+
+       return 1;
+}
+
+int
+EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey,
+    unsigned char *out_public_key, size_t *out_len)
+{
+       if (pkey->ameth->get_pub_key == NULL) {
+               EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+               return 0;
+       }
+       if (!pkey->ameth->get_pub_key(pkey, out_public_key, out_len)) {
+               EVPerror(EVP_R_GET_RAW_KEY_FAILED);
+               return 0;
+       }
+
+       return 1;
+}
+
 EVP_PKEY *
 EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len,
     const EVP_CIPHER *cipher)
@@ -581,4 +671,3 @@ EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
        return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
            0, pnid);
 }
-