PROV: Add DERlib support for DSA
[openssl.git] / providers / common / provider_util.c
index 199544730a1c6e3e27e37ef08c61f01a3f7fd6f3..041d64929d0209e2caa60af9bf95942cac478ac2 100644 (file)
@@ -9,7 +9,8 @@
 
 #include <openssl/evp.h>
 #include <openssl/core_names.h>
-#include "internal/provider_util.h"
+#include <openssl/err.h>
+#include "prov/provider_util.h"
 
 void ossl_prov_cipher_reset(PROV_CIPHER *pc)
 {
@@ -17,7 +18,6 @@ void ossl_prov_cipher_reset(PROV_CIPHER *pc)
     pc->alloc_cipher = NULL;
     pc->cipher = NULL;
     pc->engine = NULL;
-    pc->name[0] = '\0';
 }
 
 int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
@@ -27,7 +27,6 @@ int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src)
     dst->engine = src->engine;
     dst->cipher = src->cipher;
     dst->alloc_cipher = src->alloc_cipher;
-    OPENSSL_strlcpy(dst->name, src->name, sizeof(dst->name));
     return 1;
 }
 
@@ -48,7 +47,7 @@ static int load_common(const OSSL_PARAM params[], const char **propquery,
     /* TODO legacy stuff, to be removed */
     /* Inside the FIPS module, we don't support legacy ciphers */
 #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
-    p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE);
+    p = OSSL_PARAM_locate_const(params, "engine");
     if (p != NULL) {
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
@@ -78,13 +77,17 @@ int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
         return 0;
 
     EVP_CIPHER_free(pc->alloc_cipher);
+    ERR_set_mark();
     pc->cipher = pc->alloc_cipher = EVP_CIPHER_fetch(ctx, p->data, propquery);
-    OPENSSL_strlcpy(pc->name, p->data, sizeof(pc->name));
     /* TODO legacy stuff, to be removed */
 #ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy ciphers */
     if (pc->cipher == NULL)
         pc->cipher = EVP_get_cipherbyname(p->data);
 #endif
+    if (pc->cipher != NULL)
+        ERR_pop_to_mark();
+    else
+        ERR_clear_last_mark();
     return pc->cipher != NULL;
 }
 
@@ -98,18 +101,12 @@ ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc)
     return pc->engine;
 }
 
-const char *ossl_prov_cipher_name(const PROV_CIPHER *pc)
-{
-    return pc->name;
-}
-
 void ossl_prov_digest_reset(PROV_DIGEST *pd)
 {
     EVP_MD_free(pd->alloc_md);
     pd->alloc_md = NULL;
     pd->md = NULL;
     pd->engine = NULL;
-    pd->name[0] = '\0';
 }
 
 int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
@@ -119,7 +116,6 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src)
     dst->engine = src->engine;
     dst->md = src->md;
     dst->alloc_md = src->alloc_md;
-    OPENSSL_strlcpy(dst->name, src->name, sizeof(dst->name));
     return 1;
 }
 
@@ -141,13 +137,17 @@ int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
         return 0;
 
     EVP_MD_free(pd->alloc_md);
+    ERR_set_mark();
     pd->md = pd->alloc_md = EVP_MD_fetch(ctx, p->data, propquery);
-    OPENSSL_strlcpy(pd->name, p->data, sizeof(pd->name));
     /* TODO legacy stuff, to be removed */
 #ifndef FIPS_MODE /* Inside the FIPS module, we don't support legacy digests */
     if (pd->md == NULL)
         pd->md = EVP_get_digestbyname(p->data);
 #endif
+    if (pd->md != NULL)
+        ERR_pop_to_mark();
+    else
+        ERR_clear_last_mark();
     return pd->md != NULL;
 }
 
@@ -161,7 +161,104 @@ ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd)
     return pd->engine;
 }
 
-const char *ossl_prov_digest_name(const PROV_DIGEST *pd)
+int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
+                                      const OSSL_PARAM params[],
+                                      const char *macname,
+                                      const char *ciphername,
+                                      const char *mdname,
+                                      OPENSSL_CTX *libctx)
 {
-    return pd->name;
+    const OSSL_PARAM *p;
+    OSSL_PARAM mac_params[5], *mp = mac_params;
+    const char *properties = NULL;
+
+    if (macname == NULL
+        && (p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        macname = p->data;
+    }
+    if ((p = OSSL_PARAM_locate_const(params,
+                                     OSSL_ALG_PARAM_PROPERTIES)) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        properties = p->data;
+    }
+
+    /* If we got a new mac name, we make a new EVP_MAC_CTX */
+    if (macname != NULL) {
+        EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties);
+
+        EVP_MAC_CTX_free(*macctx);
+        *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac);
+        /* The context holds on to the MAC */
+        EVP_MAC_free(mac);
+        if (*macctx == NULL)
+            return 0;
+    }
+
+    /*
+     * If there is no MAC yet (and therefore, no MAC context), we ignore
+     * all other parameters.
+     */
+    if (*macctx == NULL)
+        return 1;
+
+    if (mdname == NULL) {
+        if ((p = OSSL_PARAM_locate_const(params,
+                                         OSSL_ALG_PARAM_DIGEST)) != NULL) {
+            if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                return 0;
+            mdname = p->data;
+        }
+    }
+    if (ciphername == NULL) {
+        if ((p = OSSL_PARAM_locate_const(params,
+                                         OSSL_ALG_PARAM_CIPHER)) != NULL) {
+            if (p->data_type != OSSL_PARAM_UTF8_STRING)
+                return 0;
+            ciphername = p->data;
+        }
+    }
+
+    if (mdname != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+                                                 (char *)mdname, 0);
+    if (ciphername != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
+                                                 (char *)ciphername, 0);
+    if (properties != NULL)
+        *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES,
+                                                 (char *)properties, 0);
+
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
+    if ((p = OSSL_PARAM_locate_const(params, "engine")) != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
+            return 0;
+        *mp++ = OSSL_PARAM_construct_utf8_string("engine",
+                                                 p->data, p->data_size);
+    }
+#endif
+    *mp = OSSL_PARAM_construct_end();
+
+    if (EVP_MAC_CTX_set_params(*macctx, mac_params))
+        return 1;
+
+    EVP_MAC_CTX_free(*macctx);
+    *macctx = NULL;
+    return 0;
+}
+
+void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
+                                         OSSL_ALGORITHM *out)
+{
+    int i, j;
+
+    if (out[0].algorithm_names == NULL) {
+        for (i = j = 0; in[i].alg.algorithm_names != NULL; ++i) {
+            if (in[i].capable == NULL || in[i].capable())
+                out[j++] = in[i].alg;
+        }
+        out[j++] = in[i].alg;
+    }
 }