More type-checking.
[openssl.git] / crypto / engine / tb_asnmth.c
index b2363a7f00c81121c30da6086bc2924152132696..75090339f7a2f762887056be58c56d2c9c20657c 100644 (file)
  */
 
 #include "eng_int.h"
+#include "asn1_locl.h"
+#include <openssl/evp.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'. */
+/* 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;
@@ -85,7 +88,7 @@ int ENGINE_register_pkey_asn1_meths(ENGINE *e)
        return 1;
        }
 
-void ENGINE_register_all_pkey_asn1_meths()
+void ENGINE_register_all_pkey_asn1_meths(void)
        {
        ENGINE *e;
 
@@ -164,3 +167,80 @@ void engine_pkey_asn1_meths_free(ENGINE *e)
                        }
                }
        }
+
+/* Find a method based on a string. This does a linear search through
+ * all implemented algorithms. This is OK in practice because only
+ * a small number of algorithms are likely to be implemented in an engine
+ * and it is not used for speed critical operations.
+ */
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+                                       const char *str, int len)
+       {
+       int i, nidcount;
+       const int *nids;
+       EVP_PKEY_ASN1_METHOD *ameth;
+       if (!e->pkey_asn1_meths)
+               return NULL;
+       if (len == -1)
+               len = strlen(str);
+       nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
+       for (i = 0; i < nidcount; i++)
+               {
+               e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
+               if (((int)strlen(ameth->pem_str) == len) && 
+                                       !strncasecmp(ameth->pem_str, str, len))
+                       return ameth;
+               }
+       return NULL;
+       }
+
+typedef struct 
+       {
+       ENGINE *e;
+       const EVP_PKEY_ASN1_METHOD *ameth;
+       const char *str;
+       int len;
+       } ENGINE_FIND_STR;
+
+static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
+       {
+       ENGINE_FIND_STR *lk = arg;
+       int i;
+       if (lk->ameth)
+               return;
+       for (i = 0; i < sk_ENGINE_num(sk); i++)
+               {
+               ENGINE *e = sk_ENGINE_value(sk, i);
+               EVP_PKEY_ASN1_METHOD *ameth;
+               e->pkey_asn1_meths(e, &ameth, NULL, nid);
+               if (((int)strlen(ameth->pem_str) == lk->len) && 
+                               !strncasecmp(ameth->pem_str, lk->str, lk->len))
+                       {
+                       lk->e = e;
+                       lk->ameth = ameth;
+                       return;
+                       }
+               }
+       }
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+                                       const char *str, int len)
+       {
+       ENGINE_FIND_STR fstr;
+       fstr.e = NULL;
+       fstr.ameth = NULL;
+       fstr.str = str;
+       fstr.len = len;
+       CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+       engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
+       /* If found obtain a structural reference to engine */
+       if (fstr.e)
+               {
+               fstr.e->struct_ref++;
+               engine_ref_debug(fstr.e, 0, 1)
+               }
+       *pe = fstr.e;
+       CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+       return fstr.ameth;
+       }