Update obsolete email address...
[openssl.git] / crypto / evp / pmeth_lib.c
index 6caf7955e458adb29537637c942818c1c597c248..c7491785eddb6b07aec69e3f9d7768d04c074882 100644 (file)
@@ -1,5 +1,5 @@
 /* pmeth_lib.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006.
  */
 /* ====================================================================
 #include "evp_locl.h"
 
 typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
-STACK *app_pkey_methods = NULL;
 
-extern EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth, ec_pkey_meth;
+DECLARE_STACK_OF(EVP_PKEY_METHOD)
+STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth;
 
 static const EVP_PKEY_METHOD *standard_methods[] =
        {
        &rsa_pkey_meth,
        &dh_pkey_meth,
        &dsa_pkey_meth,
-       &ec_pkey_meth
+       &ec_pkey_meth,
+       &hmac_pkey_meth,
        };
 
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+                          pmeth);
+
 static int pmeth_cmp(const EVP_PKEY_METHOD * const *a,
-                const EVP_PKEY_METHOD * const *b)
+                    const EVP_PKEY_METHOD * const *b)
        {
         return ((*a)->pkey_id - (*b)->pkey_id);
        }
 
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+                            pmeth);
+
 const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
        {
-       EVP_PKEY_METHOD tmp, *t = &tmp, **ret;
+       EVP_PKEY_METHOD tmp;
+       const EVP_PKEY_METHOD *t = &tmp, **ret;
        tmp.pkey_id = type;
        if (app_pkey_methods)
                {
                int idx;
-               idx = sk_find(app_pkey_methods, (char *)&tmp);
+               idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
                if (idx >= 0)
-                       return (EVP_PKEY_METHOD *)
-                               sk_value(app_pkey_methods, idx);
+                       return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
                }
-       ret = (EVP_PKEY_METHOD **) OBJ_bsearch((char *)&t,
-                       (char *)standard_methods,
-                       sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *),
-                       sizeof(EVP_PKEY_METHOD *),
-                       (int (*)(const void *, const void *))pmeth_cmp);
+       ret = OBJ_bsearch_pmeth(&t, standard_methods,
+                         sizeof(standard_methods)/sizeof(EVP_PKEY_METHOD *));
        if (!ret || !*ret)
                return NULL;
        return *ret;
@@ -126,12 +133,12 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
                        EVPerr(EVP_F_INT_CTX_NEW,ERR_R_ENGINE_LIB);
                        return NULL;
                        }
-               else
-                       e = ENGINE_get_pkey_meth_engine(id);
                }
+       else
+               e = ENGINE_get_pkey_meth_engine(id);
 
        /* If an ENGINE handled this method look it up. Othewise
-        * use internal table.S
+        * use internal tables.
         */
 
        if (e)
@@ -140,9 +147,19 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
                pmeth = EVP_PKEY_meth_find(id);
 
        if (pmeth == NULL)
+               {
+               EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
                return NULL;
+               }
 
        ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
+       if (!ret)
+               {
+               if (e)
+                       ENGINE_finish(e);
+               EVPerr(EVP_F_INT_CTX_NEW,ERR_R_MALLOC_FAILURE);
+               return NULL;
+               }
        ret->engine = e;
        ret->pmeth = pmeth;
        ret->operation = EVP_PKEY_OP_UNDEFINED;
@@ -242,23 +259,21 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
 #endif
 
        if (pctx->pkey)
-               {
                CRYPTO_add(&pctx->pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
-               rctx->pkey = pctx->pkey;
-               }
+
+       rctx->pkey = pctx->pkey;
 
        if (pctx->peerkey)
-               {
                CRYPTO_add(&pctx->peerkey->references,1,CRYPTO_LOCK_EVP_PKEY);
-               rctx->peerkey = pctx->peerkey;
-               }
+
+       rctx->peerkey = pctx->peerkey;
 
        rctx->data = NULL;
        rctx->app_data = NULL;
        rctx->operation = pctx->operation;
 
        if (pctx->pmeth->copy(rctx, pctx) > 0)
-               return pctx;
+               return rctx;
 
        EVP_PKEY_CTX_free(rctx);
        return NULL;
@@ -269,18 +284,20 @@ int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
        {
        if (app_pkey_methods == NULL)
                {
-               app_pkey_methods = sk_new((sk_cmp_fn_type *)pmeth_cmp);
+               app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
                if (!app_pkey_methods)
                        return 0;
                }
-       if (!sk_push(app_pkey_methods, (char *)pmeth))
+       if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
                return 0;
-       sk_sort(app_pkey_methods);
+       sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
        return 1;
        }
 
 void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
        {
+       if (ctx == NULL)
+               return;
        if (ctx->pmeth && ctx->pmeth->cleanup)
                ctx->pmeth->cleanup(ctx);
        if (ctx->pkey)
@@ -378,6 +395,11 @@ EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
        return ctx->pkey;
        }
 
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+       {
+       return ctx->peerkey;
+       }
+       
 void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
        {
        ctx->app_data = data;