The branch, master has been updated
       via  d55265beb8e third_party:heimdal: import 
lorikeet-heimdal-202508180154
      from  0db0aff37cf s3:shadow_copy: CID 1449539 talloc_realloc and error 
handling

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d55265beb8e8915fdad22ee597b4bb9a2898545f
Author: Gary Lockyer <g...@catalyst.net.nz>
Date:   Mon Aug 18 13:59:17 2025 +1200

    third_party:heimdal: import lorikeet-heimdal-202508180154
    
    Import lorikeet-heimdal-202508180154 commits:
        beffefde5c6767589603cca98065378250eaae2c
        2073647157adb2791aa8b524e88e1a2d47268e5a
        dedeffb96b24288f6c3387cf48d82c7b9c3bbbf7
    
    Add support for MS Key Trust Authentication
    
    Signed-off-by: Gary Lockyer <g...@catalyst.net.nz>
    Reviewed-by: Jennifer Sutton <jennifersut...@catalyst.net.nz>
    
    Autobuild-User(master): Jennifer Sutton <jsut...@samba.org>
    Autobuild-Date(master): Mon Sep  8 02:27:53 UTC 2025 on atb-devel-224

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

Summary of changes:
 third_party/heimdal/kdc/kerberos5.c                |   7 +-
 third_party/heimdal/kdc/pkinit.c                   | 141 +++++++++++++++++++--
 third_party/heimdal/lib/hdb/Makefile.am            |   1 +
 third_party/heimdal/lib/hdb/hdb.asn1               |   5 +
 third_party/heimdal/lib/hdb/version-script.map     |   1 +
 third_party/heimdal/tests/plugin/kdc_test_plugin.c |   2 +-
 6 files changed, 145 insertions(+), 12 deletions(-)


Changeset truncated at 500 lines:

diff --git a/third_party/heimdal/kdc/kerberos5.c 
b/third_party/heimdal/kdc/kerberos5.c
index 4c0362c8fd5..d0c646c328c 100644
--- a/third_party/heimdal/kdc/kerberos5.c
+++ b/third_party/heimdal/kdc/kerberos5.c
@@ -32,6 +32,7 @@
  */
 
 #include "kdc_locl.h"
+#include "krb5_err.h"
 
 #ifdef TIME_T_SIGNED
 #if SIZEOF_TIME_T == 4
@@ -558,8 +559,10 @@ pa_pkinit_validate(astgs_request_t r, const PA_DATA *pa)
 
     ret = _kdc_pk_rd_padata(r, pa, &pkp);
     if (ret || pkp == NULL) {
-       if (ret == HX509_CERT_REVOKED) {
-           ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;      
+       if (ret == HX509_CERT_REVOKED ||
+           ret == KRB5_KDC_ERR_CLIENT_NOT_TRUSTED) {
+
+           ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
        } else {
            ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
        }
diff --git a/third_party/heimdal/kdc/pkinit.c b/third_party/heimdal/kdc/pkinit.c
index 9f1f4b106f0..6fdae939f8c 100644
--- a/third_party/heimdal/kdc/pkinit.c
+++ b/third_party/heimdal/kdc/pkinit.c
@@ -33,6 +33,7 @@
  * SUCH DAMAGE.
  */
 
+#include "hdb_asn1.h"
 #include "kdc_locl.h"
 
 #ifdef PKINIT
@@ -384,6 +385,85 @@ get_dh_param(krb5_context context,
     return ret;
 }
 
+/**
+ * @brief Check to see if the certificate's public key matches any
+ *        of the trusted keys for this client.
+ *
+ * @param context[in] krb5_context
+ * @param client[in]  client hdb record
+ * @param cert[in]    certificate used to sign the request.
+ *
+ * @return 0 no error
+ *         KRB5_KDC_ERR_CLIENT_NOT_TRUSTED certificate public key does not
+ *                                         match any of the trusted keys for
+ *                                         this client
+ *         otherwise an error occurred processing the request.
+ */
+static krb5_error_code
+pk_check_key_trust( krb5_context context, hdb_entry *client, hx509_cert *cert)
+{
+
+    krb5_error_code ret = 0;
+    SubjectPublicKeyInfo spki;
+    HDB_extension *ext = NULL;
+    krb5_data buf;
+    size_t size = 0;
+    HDB_Ext_KeyTrust keys;
+    unsigned int i = 0;
+    krb5_boolean matched = FALSE;
+
+    memset(&spki, 0, sizeof(spki));
+    memset(&buf, 0, sizeof(buf));
+    memset(&keys, 0, sizeof(keys));
+
+    ext = hdb_find_extension(client, choice_HDB_extension_data_key_trust);
+    if (ext == NULL) {
+       ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
+       krb5_set_error_message(context, ret, "Client has no public keys");
+       goto out;
+    }
+    ret = hx509_cert_get_SPKI(context->hx509ctx, *cert, &spki);
+    if (ret) {
+       ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
+       krb5_set_error_message(
+           context, ret, "Unable to get certificate public key");
+       goto out1;
+    }
+
+    /*
+     * Does the certificates public key match any of the trusted public
+     * keys for this client?
+     */
+    ASN1_MALLOC_ENCODE(
+       SubjectPublicKeyInfo, buf.data , buf.length, &spki, &size, ret);
+    if (ret) {
+       krb5_set_error_message(
+           context, ret, "Unable to encode certificate public key");
+       goto out2;
+    }
+
+    keys = ext->data.u.key_trust;
+    for (i = 0; i < keys.len; i++) {
+       if (der_heim_octet_string_cmp(&buf, &keys.val[i].pub_key) == 0) {
+           matched = TRUE;
+           break;
+       }
+    }
+    if (!matched) {
+       ret = KRB5_KDC_ERR_CLIENT_NOT_TRUSTED;
+       krb5_set_error_message(
+           context, ret, "Client public keys do not match");
+    }
+    der_free_octet_string(&buf);
+
+out2:
+    free_SubjectPublicKeyInfo(&spki);
+out1:
+    free_HDB_extension(ext);
+out:
+    return ret;
+}
+
 krb5_error_code
 _kdc_pk_rd_padata(astgs_request_t priv,
                  const PA_DATA *pa,
@@ -634,21 +714,64 @@ _kdc_pk_rd_padata(astgs_request_t priv,
                                      &eContentType,
                                      &eContent,
                                      &signer_certs);
-       if (ret) {
+       if (ret == 0) {
+           if (signer_certs) {
+               ret = hx509_get_one_cert(
+                   context->hx509ctx, signer_certs, &cp->cert);
+               hx509_certs_free(&signer_certs);
+           }
+           if (ret) {
+               goto out;
+           }
+       } else if (ret == HX509_CMS_NO_RECIPIENT_CERTIFICATE ||
+                  ret == HX509_ISSUER_NOT_FOUND) {
+           /*
+            * Certificate not in the chain of trust,
+            * however it could be a self signed certificate for key trust
+            * logon.
+           */
+           int f = flags;
+           f |= HX509_CMS_VS_NO_VALIDATE;
+           ret = hx509_cms_verify_signed(context->hx509ctx,
+                                         cp->verify_ctx,
+                                         f,
+                                         signed_content.data,
+                                         signed_content.length,
+                                         NULL,
+                                         kdc_identity->certpool,
+                                         &eContentType,
+                                         &eContent,
+                                         &signer_certs);
+           if (ret != 0) {
+               char *s = hx509_get_error_string(context->hx509ctx, ret);
+               krb5_warnx(context,
+                          "PKINIT: failed to verify signature: %s: %d",
+                          s,
+                          ret);
+               free(s);
+               goto out;
+           }
+           if (signer_certs == NULL) {
+               ret = HX509_CMS_NO_RECIPIENT_CERTIFICATE;
+               goto out;
+           }
+           ret = hx509_get_one_cert(
+               context->hx509ctx, signer_certs, &cp->cert);
+           hx509_certs_free(&signer_certs);
+           if (ret != 0) {
+               goto out;
+           }
+           ret = pk_check_key_trust(context, client, &cp->cert);
+           if (ret) {
+               goto out;
+           }
+       } else {
            char *s = hx509_get_error_string(context->hx509ctx, ret);
            krb5_warnx(context, "PKINIT: failed to verify signature: %s: %d",
                       s, ret);
            free(s);
            goto out;
        }
-
-       if (signer_certs) {
-           ret = hx509_get_one_cert(context->hx509ctx, signer_certs,
-                                    &cp->cert);
-           hx509_certs_free(&signer_certs);
-       }
-       if (ret)
-           goto out;
     }
 
     /* Signature is correct, now verify the signed message */
diff --git a/third_party/heimdal/lib/hdb/Makefile.am 
b/third_party/heimdal/lib/hdb/Makefile.am
index 1a6155be40a..d36e6faecd3 100644
--- a/third_party/heimdal/lib/hdb/Makefile.am
+++ b/third_party/heimdal/lib/hdb/Makefile.am
@@ -29,6 +29,7 @@ gen_files_hdb = \
        asn1_HDB_Ext_Constrained_delegation_acl.c \
        asn1_HDB_Ext_KeyRotation.c \
        asn1_HDB_Ext_KeySet.c \
+       asn1_HDB_Ext_KeyTrust.c \
        asn1_HDB_Ext_Lan_Manager_OWF.c \
        asn1_HDB_Ext_Password.c \
        asn1_HDB_Ext_PKINIT_acl.c \
diff --git a/third_party/heimdal/lib/hdb/hdb.asn1 
b/third_party/heimdal/lib/hdb/hdb.asn1
index 35b5e29e936..9102e2b8f94 100644
--- a/third_party/heimdal/lib/hdb/hdb.asn1
+++ b/third_party/heimdal/lib/hdb/hdb.asn1
@@ -192,6 +192,10 @@ KeyRotation ::= SEQUENCE {
 
 HDB-Ext-KeyRotation ::= SEQUENCE SIZE (1..3) OF KeyRotation
 
+HDB-Ext-KeyTrust ::= SEQUENCE OF SEQUENCE {
+       pub_key[0] OCTET STRING
+}
+
 HDB-extension ::= SEQUENCE {
         mandatory[0]    BOOLEAN,        -- kdc MUST understand this extension,
                                         --   if not the whole entry must
@@ -213,6 +217,7 @@ HDB-extension ::= SEQUENCE {
                principal-id[13]                
INTEGER(-9223372036854775808..9223372036854775807),
                key-rotation[14]                HDB-Ext-KeyRotation,
                krb5-config[15]                 OCTET STRING,
+               key-trust[16]                   HDB-Ext-KeyTrust,
                ...
        },
        ...
diff --git a/third_party/heimdal/lib/hdb/version-script.map 
b/third_party/heimdal/lib/hdb/version-script.map
index 058060dae0c..6ef67410b2d 100644
--- a/third_party/heimdal/lib/hdb/version-script.map
+++ b/third_party/heimdal/lib/hdb/version-script.map
@@ -159,6 +159,7 @@ HEIMDAL_HDB_1.0 {
                free_HDB_extensions;
                free_HDB_Ext_KeyRotation;
                free_HDB_Ext_KeySet;
+               free_HDB_Ext_KeyTrust;
                free_HDB_Ext_PKINIT_acl;
                free_hdb_keyset;
                free_HDB_keyset;
diff --git a/third_party/heimdal/tests/plugin/kdc_test_plugin.c 
b/third_party/heimdal/tests/plugin/kdc_test_plugin.c
index 45855d7c949..33d7b910227 100644
--- a/third_party/heimdal/tests/plugin/kdc_test_plugin.c
+++ b/third_party/heimdal/tests/plugin/kdc_test_plugin.c
@@ -162,7 +162,7 @@ audit(void *ctx, astgs_request_t r)
 }
 
 static krb5plugin_kdc_ftable kdc_plugin = {
-    KRB5_PLUGIN_KDC_VERSION_11,
+    KRB5_PLUGIN_KDC_VERSION_12,
     init,
     fini,
     pac_generate,


-- 
Samba Shared Repository

Reply via email to