Redesign the KEYMGMT libcrypto <-> provider interface - the basics
[openssl.git] / crypto / evp / p_lib.c
index 016bcf93c2eb186f6a7c07e05304c437bf3c0550..95dd96e86bce03b1071a30d263f073602210dbbc 100644 (file)
@@ -401,8 +401,19 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
 # endif
 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
 {
+    int alias = type;
+
+    if (EVP_PKEY_type(type) == EVP_PKEY_EC) {
+        const EC_GROUP *group = EC_KEY_get0_group(key);
+
+        if (group != NULL && EC_GROUP_get_curve_name(group) == NID_sm2)
+            alias = EVP_PKEY_SM2;
+    }
+
     if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
         return 0;
+    if (!EVP_PKEY_set_alias_type(pkey, alias))
+        return 0;
     pkey->pkey.ptr = key;
     return (key != NULL);
 }
@@ -519,7 +530,7 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
 
 EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
 {
-    if (pkey->type != EVP_PKEY_EC) {
+    if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
         EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
         return NULL;
     }
@@ -691,9 +702,39 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
                       pctx);
 }
 
+static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
+                                     int arg1, void *arg2)
+{
+    if (pkey->pkeys[0].keymgmt == NULL)
+        return 0;
+    switch (op) {
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        {
+            char mdname[80] = "";
+            int nid;
+            int rv = EVP_PKEY_get_default_digest_name(pkey, mdname,
+                                                      sizeof(mdname));
+
+            if (rv <= 0)
+                return rv;
+            nid = OBJ_sn2nid(mdname);
+            if (nid == NID_undef)
+                nid = OBJ_ln2nid(mdname);
+            if (nid == NID_undef)
+                return 0;
+            *(int *)arg2 = nid;
+            return 1;
+        }
+    default:
+        return -2;
+    }
+}
+
 static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
 {
-    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
+    if (pkey->ameth == NULL)
+        return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2);
+    if (pkey->ameth->pkey_ctrl == NULL)
         return -2;
     return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
 }
@@ -703,6 +744,45 @@ int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
     return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
 }
 
+int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
+                                     char *mdname, size_t mdname_sz)
+{
+    if (pkey->ameth == NULL) {
+        OSSL_PARAM params[3];
+        char mddefault[100] = "";
+        char mdmandatory[100] = "";
+
+        params[0] =
+            OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST,
+                                             mddefault, sizeof(mddefault));
+        params[1] =
+            OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST,
+                                             mdmandatory,
+                                             sizeof(mdmandatory));
+        params[2] = OSSL_PARAM_construct_end();
+        if (!evp_keymgmt_get_params(pkey->pkeys[0].keymgmt,
+                                    pkey->pkeys[0].keydata,
+                                    params))
+            return 0;
+        if (mdmandatory[0] != '\0') {
+            OPENSSL_strlcpy(mdname, mdmandatory, mdname_sz);
+            return 2;
+        }
+        OPENSSL_strlcpy(mdname, mddefault, mdname_sz);
+        return 1;
+    }
+
+    {
+        int nid = NID_undef;
+        int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid);
+        const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL;
+
+        if (rv > 0)
+            OPENSSL_strlcpy(mdname, name, mdname_sz);
+        return rv;
+    }
+}
+
 int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
 {
     int rv, default_nid;
@@ -784,7 +864,7 @@ static void evp_pkey_free_it(EVP_PKEY *x)
 {
     /* internal function; x is never NULL */
 
-    evp_keymgmt_clear_pkey_cache(x);
+    evp_keymgmt_util_clear_pkey_cache(x);
 
     if (x->ameth && x->ameth->pkey_free) {
         x->ameth->pkey_free(x);
@@ -830,12 +910,11 @@ int EVP_PKEY_size(const EVP_PKEY *pkey)
 }
 
 void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
-                             EVP_KEYMGMT **keymgmt, const char *propquery,
-                             int domainparams)
+                             EVP_KEYMGMT **keymgmt, const char *propquery)
 {
     EVP_KEYMGMT *allocated_keymgmt = NULL;
     EVP_KEYMGMT *tmp_keymgmt = NULL;
-    void *provdata = NULL;
+    void *keydata = NULL;
 
     if (pk == NULL)
         return NULL;
@@ -846,7 +925,7 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
     }
 
     if (tmp_keymgmt == NULL) {
-        EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk);
+        EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
 
         if (ctx != NULL && ctx->keytype != NULL)
             tmp_keymgmt = allocated_keymgmt =
@@ -855,20 +934,20 @@ void *evp_pkey_make_provided(EVP_PKEY *pk, OPENSSL_CTX *libctx,
     }
 
     if (tmp_keymgmt != NULL)
-        provdata =
-            evp_keymgmt_export_to_provider(pk, tmp_keymgmt, domainparams);
+        keydata =
+            evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
 
     /*
      * If nothing was exported, |tmp_keymgmt| might point at a freed
      * EVP_KEYMGMT, so we clear it to be safe.  It shouldn't be useful for
      * the caller either way in that case.
      */
-    if (provdata == NULL)
+    if (keydata == NULL)
         tmp_keymgmt = NULL;
 
     if (keymgmt != NULL)
         *keymgmt = tmp_keymgmt;
 
     EVP_KEYMGMT_free(allocated_keymgmt);
-    return provdata;
+    return keydata;
 }