]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - test/keymgmt_internal_test.c
Implement EVP_PKEY_dup() function
[thirdparty/openssl.git] / test / keymgmt_internal_test.c
index 5ef238ccf1d7eef89e3943ba5068896014f79a80..32e82d5b7732332aa30ac10c448abc3c0e17de85 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -7,6 +7,12 @@
  * https://www.openssl.org/source/license.html
  */
 
+/*
+ * RSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
 #include <string.h>
 
 #include <openssl/bio.h>
@@ -21,9 +27,9 @@
 #include "testutil.h"
 
 typedef struct {
-    OPENSSL_CTX *ctx1;
+    OSSL_LIB_CTX *ctx1;
     OSSL_PROVIDER *prov1;
-    OPENSSL_CTX *ctx2;
+    OSSL_LIB_CTX *ctx2;
     OSSL_PROVIDER *prov2;
 } FIXTURE;
 
@@ -32,8 +38,8 @@ static void tear_down(FIXTURE *fixture)
     if (fixture != NULL) {
         OSSL_PROVIDER_unload(fixture->prov1);
         OSSL_PROVIDER_unload(fixture->prov2);
-        OPENSSL_CTX_free(fixture->ctx1);
-        OPENSSL_CTX_free(fixture->ctx2);
+        OSSL_LIB_CTX_free(fixture->ctx1);
+        OSSL_LIB_CTX_free(fixture->ctx2);
         OPENSSL_free(fixture);
     }
 }
@@ -43,10 +49,10 @@ static FIXTURE *set_up(const char *testcase_name)
     FIXTURE *fixture;
 
     if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))
-        || !TEST_ptr(fixture->ctx1 = OPENSSL_CTX_new())
+        || !TEST_ptr(fixture->ctx1 = OSSL_LIB_CTX_new())
         || !TEST_ptr(fixture->prov1 = OSSL_PROVIDER_load(fixture->ctx1,
                                                          "default"))
-        || !TEST_ptr(fixture->ctx2 = OPENSSL_CTX_new())
+        || !TEST_ptr(fixture->ctx2 = OSSL_LIB_CTX_new())
         || !TEST_ptr(fixture->prov2 = OSSL_PROVIDER_load(fixture->ctx2,
                                                          "default"))) {
         tear_down(fixture);
@@ -66,7 +72,7 @@ static FIXTURE *set_up(const char *testcase_name)
 #define DQ      7
 #define E3      8                /* Extra exponent */
 #define QINV    9
-#define C3      10               /* Extra coefficient */
+#define C2      10               /* Extra coefficient */
 
 /*
  * We have to do this because OSSL_PARAM_get_ulong() can't handle params
@@ -92,10 +98,6 @@ static int export_cb(const OSSL_PARAM *params, void *arg)
 {
     unsigned long *keydata = arg;
     const OSSL_PARAM *p = NULL;
-    int factors_idx;
-    int exponents_idx;
-    int coefficients_idx;
-    int ret = 1;                 /* Ever so hopeful */
 
     if (keydata == NULL)
         return 0;
@@ -106,35 +108,31 @@ static int export_cb(const OSSL_PARAM *params, void *arg)
         || !TEST_true(get_ulong_via_BN(p, &keydata[E]))
         || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D))
         || !TEST_true(get_ulong_via_BN(p, &keydata[D])))
-        ret = 0;
+        return 0;
 
-    for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR),
-             factors_idx = P;
-         p != NULL && factors_idx <= F3;
-         p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_FACTOR),
-         factors_idx++)
-        if (!TEST_true(get_ulong_via_BN(p, &keydata[factors_idx])))
-            ret = 0;
-    for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT),
-             exponents_idx = DP;
-         p != NULL && exponents_idx <= E3;
-         p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_EXPONENT),
-         exponents_idx++)
-        if (!TEST_true(get_ulong_via_BN(p, &keydata[exponents_idx])))
-            ret = 0;
-    for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT),
-             coefficients_idx = QINV;
-         p != NULL && coefficients_idx <= C3;
-         p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_COEFFICIENT),
-         coefficients_idx++)
-        if (!TEST_true(get_ulong_via_BN(p, &keydata[coefficients_idx])))
-            ret = 0;
-
-    if (!TEST_int_le(factors_idx, F3)
-        || !TEST_int_le(exponents_idx, E3)
-        || !TEST_int_le(coefficients_idx, C3))
-        ret = 0;
-    return ret;
+    if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[P]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[Q]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR3))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[F3])))
+        return 0;
+
+    if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT1))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[DP]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT2))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[DQ]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT3))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[E3])))
+        return 0;
+
+    if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT1))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[QINV]))
+        || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT2))
+        || !TEST_true(get_ulong_via_BN(p, &keydata[C2])))
+        return 0;
+
+    return 1;
 }
 
 static int test_pass_rsa(FIXTURE *fixture)
@@ -143,12 +141,16 @@ static int test_pass_rsa(FIXTURE *fixture)
     int ret = 0;
     RSA *rsa = NULL;
     BIGNUM *bn1 = NULL, *bn2 = NULL, *bn3 = NULL;
-    EVP_PKEY *pk = NULL;
-    EVP_KEYMGMT *km1 = NULL, *km2 = NULL;
-    void *provkey = NULL;
+    EVP_PKEY *pk = NULL, *dup_pk = NULL;
+    EVP_KEYMGMT *km = NULL, *km1 = NULL, *km2 = NULL, *km3 = NULL;
+    void *provkey = NULL, *provkey2 = NULL;
+    BIGNUM *bn_primes[1] = { NULL };
+    BIGNUM *bn_exps[1] = { NULL };
+    BIGNUM *bn_coeffs[1] = { NULL };
     /*
      * 32-bit RSA key, extracted from this command,
      * executed with OpenSSL 1.0.2:
+     * An extra factor was added just for testing purposes.
      *
      * openssl genrsa 32 | openssl rsa -text
      */
@@ -158,12 +160,12 @@ static int test_pass_rsa(FIXTURE *fixture)
         0x7b133399,              /* D */
         0xe963,                  /* P */
         0xceb7,                  /* Q */
-        0,                       /* F3 */
+        1,                       /* F3 */
         0x8599,                  /* DP */
         0xbd87,                  /* DQ */
-        0,                       /* E3 */
+        2,                       /* E3 */
         0xcc3b,                  /* QINV */
-        0,                       /* C3 */
+        3,                       /* C3 */
         0                        /* Extra, should remain zero */
     };
     static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
@@ -197,6 +199,16 @@ static int test_pass_rsa(FIXTURE *fixture)
         goto err;
     bn1 = bn2 = bn3 = NULL;
 
+    if (!TEST_ptr(bn_primes[0] = BN_new())
+        || !TEST_true(BN_set_word(bn_primes[0], expected[F3]))
+        || !TEST_ptr(bn_exps[0] = BN_new())
+        || !TEST_true(BN_set_word(bn_exps[0], expected[E3]))
+        || !TEST_ptr(bn_coeffs[0] = BN_new())
+        || !TEST_true(BN_set_word(bn_coeffs[0], expected[C2]))
+        || !TEST_true(RSA_set0_multi_prime_params(rsa, bn_primes, bn_exps,
+                                                  bn_coeffs, 1)))
+        goto err;
+
     if (!TEST_ptr(pk = EVP_PKEY_new())
         || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
         goto err;
@@ -204,35 +216,51 @@ static int test_pass_rsa(FIXTURE *fixture)
 
     if (!TEST_ptr(km1 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA", NULL))
         || !TEST_ptr(km2 = EVP_KEYMGMT_fetch(fixture->ctx2, "RSA", NULL))
+        || !TEST_ptr(km3 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA-PSS", NULL))
         || !TEST_ptr_ne(km1, km2))
         goto err;
 
-    if (!TEST_ptr(evp_pkey_export_to_provider(pk, NULL, &km1, NULL))
-        || !TEST_ptr(evp_pkey_upgrade_to_provider(pk, NULL, &km1, NULL))
-        || !TEST_ptr(provkey = evp_keymgmt_util_export_to_provider(pk, km2)))
-        goto err;
-
-    if (!TEST_true(evp_keymgmt_export(km2, provkey,
-                                      OSSL_KEYMGMT_SELECT_KEYPAIR,
-                                      &export_cb, keydata)))
-        goto err;
-
-    /*
-     * At this point, the hope is that keydata will have all the numbers
-     * from the key.
-     */
-
-    for (i = 0; i < OSSL_NELEM(expected); i++) {
-        int rv = TEST_int_eq(expected[i], keydata[i]);
-
-        if (!rv)
-            TEST_info("i = %zu", i);
-        else
-            ret++;
+    while (dup_pk == NULL) {
+        ret = 0;
+        km = km3;
+        /* Check that we can't export an RSA key into a RSA-PSS keymanager */
+        if (!TEST_ptr_null(provkey2 = evp_pkey_export_to_provider(pk, NULL,
+                                                                  &km,
+                                                                  NULL)))
+            goto err;
+
+        if (!TEST_ptr(provkey = evp_pkey_export_to_provider(pk, NULL, &km1,
+                                                            NULL))
+            || !TEST_true(evp_keymgmt_export(km2, provkey,
+                                             OSSL_KEYMGMT_SELECT_KEYPAIR,
+                                             &export_cb, keydata)))
+            goto err;
+
+        /*
+         * At this point, the hope is that keydata will have all the numbers
+         * from the key.
+         */
+
+        for (i = 0; i < OSSL_NELEM(expected); i++) {
+            int rv = TEST_int_eq(expected[i], keydata[i]);
+
+            if (!rv)
+                TEST_info("i = %zu", i);
+            else
+                ret++;
+        }
+
+        ret = (ret == OSSL_NELEM(expected));
+        if (!ret || !TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
+            goto err;
+
+        ret = TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
+        EVP_PKEY_free(pk);
+        pk = dup_pk;
+        if (!ret)
+            goto err;
     }
 
-    ret = (ret == OSSL_NELEM(expected));
-
  err:
     RSA_free(rsa);
     BN_free(bn1);
@@ -241,6 +269,7 @@ static int test_pass_rsa(FIXTURE *fixture)
     EVP_PKEY_free(pk);
     EVP_KEYMGMT_free(km1);
     EVP_KEYMGMT_free(km2);
+    EVP_KEYMGMT_free(km3);
 
     return ret;
 }