91bbbda
From 5072bfdfaddae762680d0f9d97afa6dbf8274760 Mon Sep 17 00:00:00 2001
91bbbda
From: Robbie Harwood <rharwood@redhat.com>
91bbbda
Date: Sat, 15 May 2021 18:04:58 -0400
91bbbda
Subject: [PATCH] Remove deprecated OpenSSL calls from softpkcs11
91bbbda
91bbbda
Rewrite add_pubkey_info() in terms of the EVP_PKEY interface.  In this
91bbbda
process, fix its unchecked allocations and fail fast for non-RSA keys.
91bbbda
91bbbda
(cherry picked from commit d6bf42279675100e3e4fe7c6e08eef74d49624cb)
91bbbda
---
91bbbda
 src/configure.ac            |   1 +
91bbbda
 src/tests/softpkcs11/main.c | 106 ++++++++++++++++++++++++------------
91bbbda
 2 files changed, 72 insertions(+), 35 deletions(-)
91bbbda
91bbbda
diff --git a/src/configure.ac b/src/configure.ac
91bbbda
index ea708491b..477819091 100644
91bbbda
--- a/src/configure.ac
91bbbda
+++ b/src/configure.ac
91bbbda
@@ -1118,6 +1118,7 @@ int i = 1;
91bbbda
 ])], k5_cv_openssl_version_okay=yes, k5_cv_openssl_version_okay=no)])
91bbbda
   old_LIBS="$LIBS"
91bbbda
   AC_CHECK_LIB(crypto, PKCS7_get_signer_info)
91bbbda
+  AC_CHECK_FUNCS(EVP_PKEY_get_bn_param)
91bbbda
   LIBS="$old_LIBS"
91bbbda
 fi
91bbbda
 if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then
91bbbda
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
91bbbda
index caa537b68..86b4ef711 100644
91bbbda
--- a/src/tests/softpkcs11/main.c
91bbbda
+++ b/src/tests/softpkcs11/main.c
91bbbda
@@ -413,47 +413,83 @@ add_object_attribute(struct st_object *o,
91bbbda
     return CKR_OK;
91bbbda
 }
91bbbda
 
91bbbda
+#ifdef HAVE_EVP_PKEY_GET_BN_PARAM
91bbbda
+
91bbbda
+/* Declare owner pointers since EVP_PKEY_get_bn_param() gives us copies. */
91bbbda
+#define DECLARE_BIGNUM(name) BIGNUM *name = NULL
91bbbda
+#define RELEASE_BIGNUM(bn) BN_clear_free(bn)
91bbbda
 static CK_RV
91bbbda
-add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
91bbbda
+get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e)
91bbbda
 {
91bbbda
-    switch (key_type) {
91bbbda
-    case CKK_RSA: {
91bbbda
-        CK_BYTE *modulus = NULL;
91bbbda
-        size_t modulus_len = 0;
91bbbda
-        CK_ULONG modulus_bits = 0;
91bbbda
-        CK_BYTE *exponent = NULL;
91bbbda
-        size_t exponent_len = 0;
91bbbda
-        const RSA *rsa;
91bbbda
-        const BIGNUM *n, *e;
91bbbda
+    if (EVP_PKEY_get_bn_param(key, "n", n) == 0 ||
91bbbda
+        EVP_PKEY_get_bn_param(key, "e", e) == 0)
91bbbda
+        return CKR_DEVICE_ERROR;
91bbbda
 
91bbbda
-        rsa = EVP_PKEY_get0_RSA(key);
91bbbda
-        RSA_get0_key(rsa, &n, &e, NULL);
91bbbda
-        modulus_bits = BN_num_bits(n);
91bbbda
-
91bbbda
-        modulus_len = BN_num_bytes(n);
91bbbda
-        modulus = malloc(modulus_len);
91bbbda
-        BN_bn2bin(n, modulus);
91bbbda
-
91bbbda
-        exponent_len = BN_num_bytes(e);
91bbbda
-        exponent = malloc(exponent_len);
91bbbda
-        BN_bn2bin(e, exponent);
91bbbda
-
91bbbda
-        add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
91bbbda
-        add_object_attribute(o, 0, CKA_MODULUS_BITS,
91bbbda
-                             &modulus_bits, sizeof(modulus_bits));
91bbbda
-        add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
91bbbda
-                             exponent, exponent_len);
91bbbda
-
91bbbda
-        free(modulus);
91bbbda
-        free(exponent);
91bbbda
-    }
91bbbda
-    default:
91bbbda
-        /* XXX */
91bbbda
-        break;
91bbbda
-    }
91bbbda
     return CKR_OK;
91bbbda
 }
91bbbda
 
91bbbda
+#else
91bbbda
+
91bbbda
+/* Declare const pointers since the old API gives us aliases. */
91bbbda
+#define DECLARE_BIGNUM(name) const BIGNUM *name
91bbbda
+#define RELEASE_BIGNUM(bn)
91bbbda
+static CK_RV
91bbbda
+get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e)
91bbbda
+{
91bbbda
+    const RSA *rsa;
91bbbda
+
91bbbda
+    rsa = EVP_PKEY_get0_RSA(key);
91bbbda
+    RSA_get0_key(rsa, n, e, NULL);
91bbbda
+
91bbbda
+    return CKR_OK;
91bbbda
+}
91bbbda
+
91bbbda
+#endif
91bbbda
+
91bbbda
+static CK_RV
91bbbda
+add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
91bbbda
+{
91bbbda
+    CK_BYTE *modulus = NULL, *exponent = 0;
91bbbda
+    size_t modulus_len = 0, exponent_len = 0;
91bbbda
+    CK_ULONG modulus_bits = 0;
91bbbda
+    CK_RV ret;
91bbbda
+    DECLARE_BIGNUM(n);
91bbbda
+    DECLARE_BIGNUM(e);
91bbbda
+
91bbbda
+    if (key_type != CKK_RSA)
91bbbda
+        abort();
91bbbda
+
91bbbda
+    ret = get_bignums(key, &n, &e);
91bbbda
+    if (ret != CKR_OK)
91bbbda
+        goto done;
91bbbda
+
91bbbda
+    modulus_bits = BN_num_bits(n);
91bbbda
+    modulus_len = BN_num_bytes(n);
91bbbda
+    exponent_len = BN_num_bytes(e);
91bbbda
+
91bbbda
+    modulus = malloc(modulus_len);
91bbbda
+    exponent = malloc(exponent_len);
91bbbda
+    if (modulus == NULL || exponent == NULL) {
91bbbda
+        ret = CKR_DEVICE_MEMORY;
91bbbda
+        goto done;
91bbbda
+    }
91bbbda
+
91bbbda
+    BN_bn2bin(n, modulus);
91bbbda
+    BN_bn2bin(e, exponent);
91bbbda
+
91bbbda
+    add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
91bbbda
+    add_object_attribute(o, 0, CKA_MODULUS_BITS, &modulus_bits,
91bbbda
+                         sizeof(modulus_bits));
91bbbda
+    add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, exponent, exponent_len);
91bbbda
+
91bbbda
+    ret = CKR_OK;
91bbbda
+done:
91bbbda
+    free(modulus);
91bbbda
+    free(exponent);
91bbbda
+    RELEASE_BIGNUM(n);
91bbbda
+    RELEASE_BIGNUM(e);
91bbbda
+    return ret;
91bbbda
+}
91bbbda
 
91bbbda
 static int
91bbbda
 pem_callback(char *buf, int num, int w, void *key)