[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Wed Oct 11 23:06:13 UTC 2017


The branch master has been updated
       via  8e826a339f8cda20a4311fa88a1de782972cf40d (commit)
       via  e3662075c3bf3db9b1d2dbf7e165b820873a55b4 (commit)
       via  3f8b368a270c928e92c6b06cbe8002c343aedfcf (commit)
       via  d19b01ad79f9e2aac5c87496b5ca5f80016daeb7 (commit)
       via  918a27facd3558444c69b1edbedb49478e82dff5 (commit)
       via  c2976edf4b22691d8bebb0e3ca2db18b3d0c71c6 (commit)
      from  e913d11f444e0b46ec1ebbf3340813693f4d869d (commit)


- Log -----------------------------------------------------------------
commit 8e826a339f8cda20a4311fa88a1de782972cf40d
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Tue Oct 10 13:42:24 2017 +0100

    Document EVP_PKEY_set1_engine()
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4503)

commit e3662075c3bf3db9b1d2dbf7e165b820873a55b4
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Oct 9 23:24:51 2017 +0100

    Add EVP_PKEY_METHOD redirection test
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4503)

commit 3f8b368a270c928e92c6b06cbe8002c343aedfcf
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Tue Oct 10 13:31:04 2017 +0100

    make update
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4503)

commit d19b01ad79f9e2aac5c87496b5ca5f80016daeb7
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Oct 9 15:21:11 2017 +0100

    Add EVP_PKEY_set1_engine() function.
    
    Add an ENGINE to EVP_PKEY structure which can be used for cryptographic
    operations: this will typically be used by an HSM key to redirect calls
    to a custom EVP_PKEY_METHOD.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4503)

commit 918a27facd3558444c69b1edbedb49478e82dff5
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Oct 9 23:24:26 2017 +0100

    Fix memory leak on lookup failure
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4503)

commit c2976edf4b22691d8bebb0e3ca2db18b3d0c71c6
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Oct 9 14:37:21 2017 +0100

    Don't ignore passed ENGINE.
    
    If we are passed an ENGINE to use in int_ctx_new e.g. via EVP_PKEY_CTX_new()
    use it instead of the default.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4503)

-----------------------------------------------------------------------

Summary of changes:
 crypto/err/openssl.txt            |   1 +
 crypto/evp/evp_err.c              |   2 +
 crypto/evp/p_lib.c                |  26 +++++-
 crypto/evp/pmeth_lib.c            |  10 ++-
 crypto/include/internal/evp_int.h |   1 +
 doc/man3/EVP_PKEY_set1_RSA.pod    |  19 ++++-
 include/openssl/evp.h             |   3 +
 include/openssl/evperr.h          |   1 +
 test/enginetest.c                 | 170 ++++++++++++++++++++++++++++++++++++++
 util/libcrypto.num                |   1 +
 10 files changed, 225 insertions(+), 9 deletions(-)

diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 58b9019..f711dac 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -689,6 +689,7 @@ EVP_F_EVP_PKEY_KEYGEN_INIT:147:EVP_PKEY_keygen_init
 EVP_F_EVP_PKEY_NEW:106:EVP_PKEY_new
 EVP_F_EVP_PKEY_PARAMGEN:148:EVP_PKEY_paramgen
 EVP_F_EVP_PKEY_PARAMGEN_INIT:149:EVP_PKEY_paramgen_init
+EVP_F_EVP_PKEY_SET1_ENGINE:187:EVP_PKEY_set1_engine
 EVP_F_EVP_PKEY_SIGN:140:EVP_PKEY_sign
 EVP_F_EVP_PKEY_SIGN_INIT:141:EVP_PKEY_sign_init
 EVP_F_EVP_PKEY_VERIFY:142:EVP_PKEY_verify
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index cc32a3b..bb3abe3 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -95,6 +95,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0),
      "EVP_PKEY_paramgen_init"},
+    {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0),
+     "EVP_PKEY_set1_engine"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN_INIT, 0), "EVP_PKEY_sign_init"},
     {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_VERIFY, 0), "EVP_PKEY_verify"},
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 7453937..f0c3075 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -188,9 +188,11 @@ static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
         if ((type == pkey->save_type) && pkey->ameth)
             return 1;
 #ifndef OPENSSL_NO_ENGINE
-        /* If we have an ENGINE release it */
+        /* If we have ENGINEs release them */
         ENGINE_finish(pkey->engine);
         pkey->engine = NULL;
+        ENGINE_finish(pkey->pmeth_engine);
+        pkey->pmeth_engine = NULL;
 #endif
     }
     if (str)
@@ -224,7 +226,25 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
 {
     return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
 }
-
+#ifndef OPENSSL_NO_ENGINE
+int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
+{
+    if (e != NULL) {
+        if (!ENGINE_init(e)) {
+            EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB);
+            return 0;
+        }
+        if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
+            ENGINE_finish(e);
+            EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM);
+            return 0;
+        }
+    }
+    ENGINE_finish(pkey->pmeth_engine);
+    pkey->pmeth_engine = e;
+    return 1;
+}
+#endif
 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
 {
     if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
@@ -443,6 +463,8 @@ static void EVP_PKEY_free_it(EVP_PKEY *x)
 #ifndef OPENSSL_NO_ENGINE
     ENGINE_finish(x->engine);
     x->engine = NULL;
+    ENGINE_finish(x->pmeth_engine);
+    x->pmeth_engine = NULL;
 #endif
 }
 
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 2b9b8a9..37c5e85 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -105,16 +105,17 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
         id = pkey->ameth->pkey_id;
     }
 #ifndef OPENSSL_NO_ENGINE
-    if (pkey && pkey->engine)
-        e = pkey->engine;
+    if (e == NULL && pkey != NULL)
+        e = pkey->pmeth_engine != NULL ? pkey->pmeth_engine : pkey->engine;
     /* Try to find an ENGINE which implements this method */
     if (e) {
         if (!ENGINE_init(e)) {
             EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
             return NULL;
         }
-    } else
+    } else {
         e = ENGINE_get_pkey_meth_engine(id);
+    }
 
     /*
      * If an ENGINE handled this method look it up. Otherwise use internal
@@ -128,6 +129,9 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
         pmeth = EVP_PKEY_meth_find(id);
 
     if (pmeth == NULL) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE_finish(e);
+#endif
         EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
         return NULL;
     }
diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h
index ccfa97c..f409400 100644
--- a/crypto/include/internal/evp_int.h
+++ b/crypto/include/internal/evp_int.h
@@ -369,6 +369,7 @@ struct evp_pkey_st {
     CRYPTO_REF_COUNT references;
     const EVP_PKEY_ASN1_METHOD *ameth;
     ENGINE *engine;
+    ENGINE *pmeth_engine; /* If not NULL public key ENGINE to use */
     union {
         void *ptr;
 # ifndef OPENSSL_NO_RSA
diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod
index e1b7110..884cf91 100644
--- a/doc/man3/EVP_PKEY_set1_RSA.pod
+++ b/doc/man3/EVP_PKEY_set1_RSA.pod
@@ -5,10 +5,9 @@
 EVP_PKEY_set1_RSA, EVP_PKEY_set1_DSA, EVP_PKEY_set1_DH, EVP_PKEY_set1_EC_KEY,
 EVP_PKEY_get1_RSA, EVP_PKEY_get1_DSA, EVP_PKEY_get1_DH, EVP_PKEY_get1_EC_KEY,
 EVP_PKEY_get0_RSA, EVP_PKEY_get0_DSA, EVP_PKEY_get0_DH, EVP_PKEY_get0_EC_KEY,
-EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH, EVP_PKEY_assign_EC_KEY,
-EVP_PKEY_get0_hmac,
-EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_base_id
-- EVP_PKEY assignment functions
+EVP_PKEY_assign_RSA, EVP_PKEY_assign_DSA, EVP_PKEY_assign_DH,
+EVP_PKEY_assign_EC_KEY, EVP_PKEY_get0_hmac, EVP_PKEY_type, EVP_PKEY_id,
+EVP_PKEY_base_id, EVP_PKEY_set1_engine - EVP_PKEY assignment functions
 
 =head1 SYNOPSIS
 
@@ -39,6 +38,8 @@ EVP_PKEY_type, EVP_PKEY_id, EVP_PKEY_base_id
  int EVP_PKEY_base_id(const EVP_PKEY *pkey);
  int EVP_PKEY_type(int type);
 
+ int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *engine);
+
 =head1 DESCRIPTION
 
 EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
@@ -72,6 +73,11 @@ often seen in practice.
 EVP_PKEY_type() returns the underlying type of the NID B<type>. For example
 EVP_PKEY_type(EVP_PKEY_RSA2) will return B<EVP_PKEY_RSA>.
 
+EVP_PKEY_set1_engine() sets the ENGINE handling B<pkey> to B<engine>. It
+must be called after the key algorithm and components are set up.
+If B<engine> does not include an B<EVP_PKEY_METHOD> for B<pkey> an
+error occurs.
+
 =head1 NOTES
 
 In accordance with the OpenSSL naming convention the key obtained
@@ -89,6 +95,9 @@ Previous versions of this document suggested using EVP_PKEY_type(pkey->type)
 to determine the type of a key. Since B<EVP_PKEY> is now opaque this
 is no longer possible: the equivalent is EVP_PKEY_base_id(pkey).
 
+EVP_PKEY_set1_engine() is typically used by an ENGINE returning an HSM
+key as part of its routine to load a private key.
+
 =head1 RETURN VALUES
 
 EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH() and
@@ -104,6 +113,8 @@ and EVP_PKEY_assign_EC_KEY() return 1 for success and 0 for failure.
 EVP_PKEY_base_id(), EVP_PKEY_id() and EVP_PKEY_type() return a key
 type or B<NID_undef> (equivalently B<EVP_PKEY_NONE>) on error.
 
+EVP_PKEY_set1_engine() returns 1 for success and 0 for failure.
+
 =head1 SEE ALSO
 
 L<EVP_PKEY_new(3)>
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 34c009a..40ed8d2 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -978,6 +978,9 @@ int EVP_PKEY_security_bits(const EVP_PKEY *pkey);
 int EVP_PKEY_size(EVP_PKEY *pkey);
 int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
 int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+# ifndef OPENSSL_NO_ENGINE
+int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e);
+# endif
 int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
 void *EVP_PKEY_get0(const EVP_PKEY *pkey);
 const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h
index 9bb2bca..222ba3f 100644
--- a/include/openssl/evperr.h
+++ b/include/openssl/evperr.h
@@ -82,6 +82,7 @@ int ERR_load_EVP_strings(void);
 # define EVP_F_EVP_PKEY_NEW                               106
 # define EVP_F_EVP_PKEY_PARAMGEN                          148
 # define EVP_F_EVP_PKEY_PARAMGEN_INIT                     149
+# define EVP_F_EVP_PKEY_SET1_ENGINE                       187
 # define EVP_F_EVP_PKEY_SIGN                              140
 # define EVP_F_EVP_PKEY_SIGN_INIT                         141
 # define EVP_F_EVP_PKEY_VERIFY                            142
diff --git a/test/enginetest.c b/test/enginetest.c
index 4e78277..be57f16 100644
--- a/test/enginetest.c
+++ b/test/enginetest.c
@@ -18,6 +18,7 @@
 # include <openssl/buffer.h>
 # include <openssl/crypto.h>
 # include <openssl/engine.h>
+# include <openssl/rsa.h>
 # include <openssl/err.h>
 
 static void display_engine_list(void)
@@ -175,6 +176,174 @@ static int test_engines(void)
         ENGINE_free(block[loop]);
     return to_return;
 }
+
+/* Test EVP_PKEY method */
+static EVP_PKEY_METHOD *test_rsa = NULL;
+
+static int called_encrypt = 0;
+
+/* Test function to check operation has been redirected */
+static int test_encrypt(EVP_PKEY_CTX *ctx, unsigned char *sig,
+                        size_t *siglen, const unsigned char *tbs, size_t tbslen)
+{
+    called_encrypt = 1;
+    return 1;
+}
+
+static int test_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+                           const int **pnids, int nid)
+{
+    static const int rnid = EVP_PKEY_RSA;
+    if (pmeth == NULL) {
+        *pnids = &rnid;
+        return 1;
+    }
+
+    if (nid == EVP_PKEY_RSA) {
+        *pmeth = test_rsa;
+        return 1;
+    }
+
+    *pmeth = NULL;
+    return 0;
+}
+
+/* Return a test EVP_PKEY value */
+
+static EVP_PKEY *get_test_pkey(void)
+{
+    static unsigned char n[] =
+        "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
+        "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
+        "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
+        "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
+        "\xF5";
+    static unsigned char e[] = "\x11";
+
+    RSA *rsa = RSA_new();
+    EVP_PKEY *pk = EVP_PKEY_new();
+
+    if (rsa == NULL || pk == NULL || !EVP_PKEY_assign_RSA(pk, rsa)) {
+        RSA_free(rsa);
+        EVP_PKEY_free(pk);
+        return NULL;
+    }
+
+    if (!RSA_set0_key(rsa, BN_bin2bn(n, sizeof(n)-1, NULL),
+                      BN_bin2bn(e, sizeof(e)-1, NULL), NULL)) {
+        EVP_PKEY_free(pk);
+        return NULL;
+    }
+
+    return pk;
+}
+
+static int test_redirect(void)
+{
+    const unsigned char pt[] = "Hello World\n";
+    unsigned char *tmp = NULL;
+    size_t len;
+    EVP_PKEY_CTX *ctx = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *pkey = NULL;
+
+    int to_return = 0;
+
+    if (!TEST_ptr(pkey = get_test_pkey()))
+        goto err;
+
+    len = EVP_PKEY_size(pkey);
+    if (!TEST_ptr(tmp = OPENSSL_malloc(len)))
+        goto err;
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
+        goto err;
+    TEST_info("EVP_PKEY_encrypt test: no redirection");
+    /* Encrypt some data: should succeed but not be redirected */
+    if (!TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
+            || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
+            || !TEST_false(called_encrypt))
+        goto err;
+    EVP_PKEY_CTX_free(ctx);
+    ctx = NULL;
+
+    /* Create a test ENGINE */
+    if (!TEST_ptr(e = ENGINE_new())
+            || !TEST_true(ENGINE_set_id(e, "Test redirect engine"))
+            || !TEST_true(ENGINE_set_name(e, "Test redirect engine")))
+        goto err;
+
+    /*
+     * Try to create a context for this engine and test key.
+     * Try setting test key engine. Both should fail because the
+     * engine has no public key methods.
+     */
+    if (!TEST_ptr_null(EVP_PKEY_CTX_new(pkey, e))
+            || !TEST_int_le(EVP_PKEY_set1_engine(pkey, e), 0))
+        goto err;
+
+    /* Setup an empty test EVP_PKEY_METHOD and set callback to return it */
+    if (!TEST_ptr(test_rsa = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0)))
+        goto err;
+    ENGINE_set_pkey_meths(e, test_pkey_meths);
+
+    /* Getting a context for test ENGINE should now succeed */
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, e)))
+        goto err;
+    /* Encrypt should fail because operation is not supported */
+    if (!TEST_int_le(EVP_PKEY_encrypt_init(ctx), 0))
+        goto err;
+    EVP_PKEY_CTX_free(ctx);
+    ctx = NULL;
+
+    /* Add test encrypt operation to method */
+    EVP_PKEY_meth_set_encrypt(test_rsa, 0, test_encrypt);
+
+    TEST_info("EVP_PKEY_encrypt test: redirection via EVP_PKEY_CTX_new()");
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, e)))
+        goto err;
+    /* Encrypt some data: should succeed and be redirected */
+    if (!TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
+            || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
+            || !TEST_true(called_encrypt))
+        goto err;
+
+    EVP_PKEY_CTX_free(ctx);
+    ctx = NULL;
+    called_encrypt = 0;
+
+    /* Create context with default engine: should not be redirected */
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))
+            || !TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
+            || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
+            || !TEST_false(called_encrypt))
+        goto err;
+
+    EVP_PKEY_CTX_free(ctx);
+    ctx = NULL;
+
+    /* Set engine explicitly for test key */
+    if (!TEST_true(EVP_PKEY_set1_engine(pkey, e)))
+        goto err;
+
+    TEST_info("EVP_PKEY_encrypt test: redirection via EVP_PKEY_set1_engine()");
+
+    /* Create context with default engine: should be redirected now */
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))
+            || !TEST_int_gt(EVP_PKEY_encrypt_init(ctx), 0)
+            || !TEST_int_gt(EVP_PKEY_encrypt(ctx, tmp, &len, pt, sizeof(pt)), 0)
+            || !TEST_true(called_encrypt))
+        goto err;
+
+    to_return = 1;
+
+ err:
+    EVP_PKEY_CTX_free(ctx);
+    EVP_PKEY_free(pkey);
+    ENGINE_free(e);
+    OPENSSL_free(tmp);
+    return to_return;
+}
 #endif
 
 int setup_tests(void)
@@ -183,6 +352,7 @@ int setup_tests(void)
     TEST_note("No ENGINE support");
 #else
     ADD_TEST(test_engines);
+    ADD_TEST(test_redirect);
 #endif
     return 1;
 }
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 5343aed..548716d 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4400,3 +4400,4 @@ EVP_PKEY_meth_remove                    4343	1_1_1	EXIST::FUNCTION:
 OPENSSL_sk_reserve                      4344	1_1_1	EXIST::FUNCTION:
 CRYPTO_atomic_read                      4345	1_1_1	EXIST::FUNCTION:
 CRYPTO_atomic_write                     4346	1_1_1	EXIST::FUNCTION:
+EVP_PKEY_set1_engine                    4347	1_1_0g	EXIST::FUNCTION:ENGINE


More information about the openssl-commits mailing list