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