Initial public key ASN1 method engine support. Not integrated yet.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 2 Jun 2006 17:52:27 +0000 (17:52 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 2 Jun 2006 17:52:27 +0000 (17:52 +0000)
CHANGES
crypto/engine/Makefile
crypto/engine/eng_err.c
crypto/engine/eng_int.h
crypto/engine/engine.h
crypto/engine/tb_asnmth.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index def2f8187b6a2d4e376aa1fff7b26600e75d9375..46d5cd8445412e9b5b2f62f8be3a21181ec873f5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,8 @@
 
  Changes between 0.9.8b and 0.9.9  [xx XXX xxxx]
 
+  *) Initial engine support for EVP_PKEY_ASN1_METHOD.
+
   *) Initial engine support for EVP_PKEY_METHOD. New functions to permit
      an engine to register a method. Add ENGINE lookups for methods and
      functional reference processing.
index 11a3f82246bf808a450154629b2a11ffc37881df..eb94fe6b671062098e7923f48a19882fbbd22493 100644 (file)
@@ -20,12 +20,12 @@ LIB=$(TOP)/libcrypto.a
 LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
        eng_table.c eng_pkey.c eng_fat.c eng_all.c \
        tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
-       tb_cipher.c tb_digest.c tb_pkmeth.c \
+       tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
        eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
 LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
        eng_table.o eng_pkey.o eng_fat.o eng_all.o \
        tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
-       tb_cipher.o tb_digest.o tb_pkmeth.o \
+       tb_cipher.o tb_digest.o tb_pkmeth.o tb_asnmth.o \
        eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
 
 SRC= $(LIBSRC)
index 8de1a4fb09d52222781f9e45caa33948c83ec6a6..70fbc4de1e0eefaac64ff3a74cec0e069d82a3f0 100644 (file)
@@ -86,6 +86,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
 {ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE),   "ENGINE_GET_DEFAULT_TYPE"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT),   "ENGINE_get_next"},
+{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH),      "ENGINE_get_pkey_meth"},
 {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV),   "ENGINE_get_prev"},
 {ERR_FUNC(ENGINE_F_ENGINE_INIT),       "ENGINE_init"},
index d93f5e5b178bab633aad2ceeffead1073123b024..8630597fe08f36c4ad362cb6274a2326327615c6 100644 (file)
@@ -166,6 +166,8 @@ struct engine_st
        ENGINE_DIGESTS_PTR digests;
        /* Public key handling via this callback */
        ENGINE_PKEY_METHS_PTR pkey_meths;
+       /* ASN1 public key handling via this callback */
+       ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
 
        ENGINE_GEN_INT_FUNC_PTR destroy;
 
index 7285c004c48defdd9e917bbc53a6288aeb2fc322..803ebf31b2b759e4292fbd51081c5c56438e0a59 100644 (file)
@@ -294,6 +294,7 @@ typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
 typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
 typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
 typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
 /* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
  * structures where the pointers have a "structural reference". This means that
  * their reference is to allowed access to the structure but it does not imply
@@ -467,6 +468,7 @@ int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
 int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
 int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
 int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
 int ENGINE_set_flags(ENGINE *e, int flags);
 int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
 /* These functions allow control over any per-structure ENGINE data. */
@@ -503,9 +505,11 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
 ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
 ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
 ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
 const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
 const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
 const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
 const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
 int ENGINE_get_flags(const ENGINE *e);
 
@@ -727,6 +731,7 @@ void ERR_load_ENGINE_strings(void);
 #define ENGINE_F_ENGINE_GET_DEFAULT_TYPE                177
 #define ENGINE_F_ENGINE_GET_DIGEST                      186
 #define ENGINE_F_ENGINE_GET_NEXT                        115
+#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH              193
 #define ENGINE_F_ENGINE_GET_PKEY_METH                   192
 #define ENGINE_F_ENGINE_GET_PREV                        116
 #define ENGINE_F_ENGINE_INIT                            119
diff --git a/crypto/engine/tb_asnmth.c b/crypto/engine/tb_asnmth.c
new file mode 100644 (file)
index 0000000..b2363a7
--- /dev/null
@@ -0,0 +1,166 @@
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "eng_int.h"
+
+/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the function
+ * that is used by EVP to hook in pkey_asn1_meth code and cache defaults (etc), will
+ * display brief debugging summaries to stderr with the 'nid'. */
+/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
+
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
+       {
+       engine_table_unregister(&pkey_asn1_meth_table, e);
+       }
+
+static void engine_unregister_all_pkey_asn1_meths(void)
+       {
+       engine_table_cleanup(&pkey_asn1_meth_table);
+       }
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e)
+       {
+       if(e->pkey_asn1_meths)
+               {
+               const int *nids;
+               int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+               if(num_nids > 0)
+                       return engine_table_register(&pkey_asn1_meth_table,
+                               engine_unregister_all_pkey_asn1_meths, e, nids,
+                                       num_nids, 0);
+               }
+       return 1;
+       }
+
+void ENGINE_register_all_pkey_asn1_meths()
+       {
+       ENGINE *e;
+
+       for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
+               ENGINE_register_pkey_asn1_meths(e);
+       }
+
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
+       {
+       if(e->pkey_asn1_meths)
+               {
+               const int *nids;
+               int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+               if(num_nids > 0)
+                       return engine_table_register(&pkey_asn1_meth_table,
+                               engine_unregister_all_pkey_asn1_meths, e, nids,
+                                       num_nids, 1);
+               }
+       return 1;
+       }
+
+/* Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_asn1_meth 'nid' */
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
+       {
+       return engine_table_select(&pkey_asn1_meth_table, nid);
+       }
+
+/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
+       {
+       EVP_PKEY_ASN1_METHOD *ret;
+       ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
+       if(!fn || !fn(e, &ret, NULL, nid))
+               {
+               ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
+                               ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+               return NULL;
+               }
+       return ret;
+       }
+
+/* Gets the pkey_asn1_meth callback from an ENGINE structure */
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
+       {
+       return e->pkey_asn1_meths;
+       }
+
+/* Sets the pkey_asn1_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
+       {
+       e->pkey_asn1_meths = f;
+       return 1;
+       }
+
+/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void engine_pkey_asn1_meths_free(ENGINE *e)
+       {
+       int i;
+       EVP_PKEY_ASN1_METHOD *pkm;
+       if (e->pkey_asn1_meths)
+               {
+               const int *pknids;
+               int npknids;
+               npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
+               for (i = 0; i < npknids; i++)
+                       {
+                       if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
+                               {
+                               EVP_PKEY_asn1_free(pkm);
+                               }
+                       }
+               }
+       }