Blob Blame History Raw
From 3cc9ef956342f55cc9ae283e30fc3ba080248cf3 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 1 Jun 2022 18:02:04 +0200
Subject: [PATCH] Set reasonable supportedCMSTypes in PKINIT

The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know
the algorithms it supports for verification of the CMS data signature.
(The MIT krb5 KDC currently ignores this list, but other
implementations use it.)

Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption.

[ghudson@mit.edu: simplified code and used appropriate helpers; edited
commit message]

ticket: 9066 (new)
---
 src/plugins/preauth/pkinit/pkinit_constants.c | 33 ++++++++++++-
 src/plugins/preauth/pkinit/pkinit_crypto.h    |  4 ++
 .../preauth/pkinit/pkinit_crypto_openssl.c    | 49 ++++++++++---------
 3 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
index 652897fa14..1da482e0b4 100644
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
@@ -32,9 +32,14 @@
 
 #include "pkinit.h"
 
-/* statically declare OID constants for all three algorithms */
-static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01};
+/* RFC 8636 id-pkinit-kdf-ah-sha1: iso(1) identified-organization(3) dod(6)
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha1(1) */
+static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
+/* RFC 8636 id-pkinit-kdf-ah-sha256: iso(1) identified-organization(3) dod(6)
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha256(2) */
 static char sha256_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
+/* RFC 8636 id-pkinit-kdf-ah-sha512: iso(1) identified-organization(3) dod(6)
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha512(3) */
 static char sha512_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
 
 const krb5_data sha1_id = { KV5M_DATA, sizeof(sha1_oid), sha1_oid };
@@ -48,6 +53,30 @@ krb5_data const * const supported_kdf_alg_ids[] = {
     NULL
 };
 
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
+ * rsadsi(113549) pkcs(1) 1 11 */
+static char sha256WithRSAEncr_oid[9] = {
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
+};
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
+ * rsadsi(113549) pkcs(1) 1 13 */
+static char sha512WithRSAEncr_oid[9] = {
+    0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
+};
+
+const krb5_data sha256WithRSAEncr_id = {
+    KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
+};
+const krb5_data sha512WithRSAEncr_id = {
+    KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
+};
+
+krb5_data const * const supported_cms_algs[] = {
+    &sha512WithRSAEncr_id,
+    &sha256WithRSAEncr_id,
+    NULL
+};
+
 /* RFC 2412 section E.2 (well-known group 2) parameters, DER-encoded as
  * DomainParameters (RFC 3279 section 2.3.3). */
 static const uint8_t o1024[] = {
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
index 65f6210727..64300da856 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
@@ -620,6 +620,10 @@ extern const krb5_data oakley_4096;
  */
 extern krb5_data const * const supported_kdf_alg_ids[];
 
+/* CMS signature algorithms supported by this implementation, in order of
+ * decreasing preference. */
+extern krb5_data const * const supported_cms_algs[];
+
 krb5_error_code
 crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,
 		       uint8_t **der_out, size_t *der_len);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index d500455dec..1c2aa02827 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -5475,37 +5475,38 @@ create_krb5_supportedCMSTypes(krb5_context context,
                               pkinit_plg_crypto_context plg_cryptoctx,
                               pkinit_req_crypto_context req_cryptoctx,
                               pkinit_identity_crypto_context id_cryptoctx,
-                              krb5_algorithm_identifier ***oids)
+                              krb5_algorithm_identifier ***algs_out)
 {
+    krb5_error_code ret;
+    krb5_algorithm_identifier **algs = NULL;
+    size_t i, count;
 
-    krb5_error_code retval = ENOMEM;
-    krb5_algorithm_identifier **loids = NULL;
-    krb5_data des3oid = {0, 8, "\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
+    *algs_out = NULL;
 
-    *oids = NULL;
-    loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
-    if (loids == NULL)
-        goto cleanup;
-    loids[1] = NULL;
-    loids[0] = malloc(sizeof(krb5_algorithm_identifier));
-    if (loids[0] == NULL) {
-        free(loids);
-        goto cleanup;
-    }
-    retval = pkinit_copy_krb5_data(&loids[0]->algorithm, &des3oid);
-    if (retval) {
-        free(loids[0]);
-        free(loids);
+    /* Count supported OIDs and allocate list (including null terminator). */
+    for (count = 0; supported_cms_algs[count] != NULL; count++);
+    algs = k5calloc(count + 1, sizeof(*algs), &ret);
+    if (algs == NULL)
         goto cleanup;
+
+    /* Add an algorithm identifier for each OID, with no parameters. */
+    for (i = 0; i < count; i++) {
+        algs[i] = k5alloc(sizeof(*algs[i]), &ret);
+        if (algs[i] == NULL)
+            goto cleanup;
+        ret = krb5int_copy_data_contents(context, supported_cms_algs[i],
+                                         &algs[i]->algorithm);
+        if (ret)
+            goto cleanup;
+        algs[i]->parameters = empty_data();
     }
-    loids[0]->parameters.length = 0;
-    loids[0]->parameters.data = NULL;
 
-    *oids = loids;
-    retval = 0;
-cleanup:
+    *algs_out = algs;
+    algs = NULL;
 
-    return retval;
+cleanup:
+    free_krb5_algorithm_identifiers(&algs);
+    return ret;
 }
 
 krb5_error_code
-- 
2.38.1