Blame SOURCES/0008-Set-reasonable-supportedCMSTypes-in-PKINIT.patch

d1ad9f
From 3cc9ef956342f55cc9ae283e30fc3ba080248cf3 Mon Sep 17 00:00:00 2001
d1ad9f
From: Julien Rische <jrische@redhat.com>
d1ad9f
Date: Wed, 1 Jun 2022 18:02:04 +0200
d1ad9f
Subject: [PATCH] Set reasonable supportedCMSTypes in PKINIT
d1ad9f
d1ad9f
The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know
d1ad9f
the algorithms it supports for verification of the CMS data signature.
d1ad9f
(The MIT krb5 KDC currently ignores this list, but other
d1ad9f
implementations use it.)
d1ad9f
d1ad9f
Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption.
d1ad9f
d1ad9f
[ghudson@mit.edu: simplified code and used appropriate helpers; edited
d1ad9f
commit message]
d1ad9f
d1ad9f
ticket: 9066 (new)
d1ad9f
---
d1ad9f
 src/plugins/preauth/pkinit/pkinit_constants.c | 33 ++++++++++++-
d1ad9f
 src/plugins/preauth/pkinit/pkinit_crypto.h    |  4 ++
d1ad9f
 .../preauth/pkinit/pkinit_crypto_openssl.c    | 49 ++++++++++---------
d1ad9f
 3 files changed, 60 insertions(+), 26 deletions(-)
d1ad9f
d1ad9f
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
d1ad9f
index 652897fa14..1da482e0b4 100644
d1ad9f
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
d1ad9f
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
d1ad9f
@@ -32,9 +32,14 @@
d1ad9f
 
d1ad9f
 #include "pkinit.h"
d1ad9f
 
d1ad9f
-/* statically declare OID constants for all three algorithms */
d1ad9f
-static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01};
d1ad9f
+/* RFC 8636 id-pkinit-kdf-ah-sha1: iso(1) identified-organization(3) dod(6)
d1ad9f
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha1(1) */
d1ad9f
+static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
d1ad9f
+/* RFC 8636 id-pkinit-kdf-ah-sha256: iso(1) identified-organization(3) dod(6)
d1ad9f
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha256(2) */
d1ad9f
 static char sha256_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
d1ad9f
+/* RFC 8636 id-pkinit-kdf-ah-sha512: iso(1) identified-organization(3) dod(6)
d1ad9f
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha512(3) */
d1ad9f
 static char sha512_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
d1ad9f
 
d1ad9f
 const krb5_data sha1_id = { KV5M_DATA, sizeof(sha1_oid), sha1_oid };
d1ad9f
@@ -48,6 +53,30 @@ krb5_data const * const supported_kdf_alg_ids[] = {
d1ad9f
     NULL
d1ad9f
 };
d1ad9f
 
d1ad9f
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
d1ad9f
+ * rsadsi(113549) pkcs(1) 1 11 */
d1ad9f
+static char sha256WithRSAEncr_oid[9] = {
d1ad9f
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
d1ad9f
+};
d1ad9f
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
d1ad9f
+ * rsadsi(113549) pkcs(1) 1 13 */
d1ad9f
+static char sha512WithRSAEncr_oid[9] = {
d1ad9f
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
d1ad9f
+};
d1ad9f
+
d1ad9f
+const krb5_data sha256WithRSAEncr_id = {
d1ad9f
+    KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
d1ad9f
+};
d1ad9f
+const krb5_data sha512WithRSAEncr_id = {
d1ad9f
+    KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
d1ad9f
+};
d1ad9f
+
d1ad9f
+krb5_data const * const supported_cms_algs[] = {
d1ad9f
+    &sha512WithRSAEncr_id,
d1ad9f
+    &sha256WithRSAEncr_id,
d1ad9f
+    NULL
d1ad9f
+};
d1ad9f
+
d1ad9f
 /* RFC 2412 section E.2 (well-known group 2) parameters, DER-encoded as
d1ad9f
  * DomainParameters (RFC 3279 section 2.3.3). */
d1ad9f
 static const uint8_t o1024[] = {
d1ad9f
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
d1ad9f
index 65f6210727..64300da856 100644
d1ad9f
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
d1ad9f
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
d1ad9f
@@ -620,6 +620,10 @@ extern const krb5_data oakley_4096;
d1ad9f
  */
d1ad9f
 extern krb5_data const * const supported_kdf_alg_ids[];
d1ad9f
 
d1ad9f
+/* CMS signature algorithms supported by this implementation, in order of
d1ad9f
+ * decreasing preference. */
d1ad9f
+extern krb5_data const * const supported_cms_algs[];
d1ad9f
+
d1ad9f
 krb5_error_code
d1ad9f
 crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,
d1ad9f
 		       uint8_t **der_out, size_t *der_len);
d1ad9f
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
d1ad9f
index d500455dec..1c2aa02827 100644
d1ad9f
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
d1ad9f
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
d1ad9f
@@ -5475,37 +5475,38 @@ create_krb5_supportedCMSTypes(krb5_context context,
d1ad9f
                               pkinit_plg_crypto_context plg_cryptoctx,
d1ad9f
                               pkinit_req_crypto_context req_cryptoctx,
d1ad9f
                               pkinit_identity_crypto_context id_cryptoctx,
d1ad9f
-                              krb5_algorithm_identifier ***oids)
d1ad9f
+                              krb5_algorithm_identifier ***algs_out)
d1ad9f
 {
d1ad9f
+    krb5_error_code ret;
d1ad9f
+    krb5_algorithm_identifier **algs = NULL;
d1ad9f
+    size_t i, count;
d1ad9f
 
d1ad9f
-    krb5_error_code retval = ENOMEM;
d1ad9f
-    krb5_algorithm_identifier **loids = NULL;
d1ad9f
-    krb5_data des3oid = {0, 8, "\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
d1ad9f
+    *algs_out = NULL;
d1ad9f
 
d1ad9f
-    *oids = NULL;
d1ad9f
-    loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
d1ad9f
-    if (loids == NULL)
d1ad9f
-        goto cleanup;
d1ad9f
-    loids[1] = NULL;
d1ad9f
-    loids[0] = malloc(sizeof(krb5_algorithm_identifier));
d1ad9f
-    if (loids[0] == NULL) {
d1ad9f
-        free(loids);
d1ad9f
-        goto cleanup;
d1ad9f
-    }
d1ad9f
-    retval = pkinit_copy_krb5_data(&loids[0]->algorithm, &des3oid);
d1ad9f
-    if (retval) {
d1ad9f
-        free(loids[0]);
d1ad9f
-        free(loids);
d1ad9f
+    /* Count supported OIDs and allocate list (including null terminator). */
d1ad9f
+    for (count = 0; supported_cms_algs[count] != NULL; count++);
d1ad9f
+    algs = k5calloc(count + 1, sizeof(*algs), &ret;;
d1ad9f
+    if (algs == NULL)
d1ad9f
         goto cleanup;
d1ad9f
+
d1ad9f
+    /* Add an algorithm identifier for each OID, with no parameters. */
d1ad9f
+    for (i = 0; i < count; i++) {
d1ad9f
+        algs[i] = k5alloc(sizeof(*algs[i]), &ret;;
d1ad9f
+        if (algs[i] == NULL)
d1ad9f
+            goto cleanup;
d1ad9f
+        ret = krb5int_copy_data_contents(context, supported_cms_algs[i],
d1ad9f
+                                         &algs[i]->algorithm);
d1ad9f
+        if (ret)
d1ad9f
+            goto cleanup;
d1ad9f
+        algs[i]->parameters = empty_data();
d1ad9f
     }
d1ad9f
-    loids[0]->parameters.length = 0;
d1ad9f
-    loids[0]->parameters.data = NULL;
d1ad9f
 
d1ad9f
-    *oids = loids;
d1ad9f
-    retval = 0;
d1ad9f
-cleanup:
d1ad9f
+    *algs_out = algs;
d1ad9f
+    algs = NULL;
d1ad9f
 
d1ad9f
-    return retval;
d1ad9f
+cleanup:
d1ad9f
+    free_krb5_algorithm_identifiers(&algs);
d1ad9f
+    return ret;
d1ad9f
 }
d1ad9f
 
d1ad9f
 krb5_error_code
d1ad9f
-- 
d1ad9f
2.38.1
d1ad9f