From 8924d4bbbf82a29f1d6bf524a416d6e44b694734 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Thu, 22 Mar 2018 19:46:22 -0400 Subject: [PATCH] Save SANs separately and unparse them with NO_REALM (cherry picked from commit 23ea8d6a9617d17ae5a529c23174d77adac39055) --- src/plugins/preauth/pkinit/pkinit_crypto.h | 4 +-- src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 37 +++------------------- src/plugins/preauth/pkinit/pkinit_matching.c | 30 +++++++++++++----- 3 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h index 2d3733bbc..c7ff29fb2 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto.h +++ b/src/plugins/preauth/pkinit/pkinit_crypto.h @@ -97,8 +97,8 @@ typedef struct _pkinit_cert_matching_data { char *issuer_dn; /* rfc2253-style issuer name string */ unsigned int ku_bits; /* key usage information */ unsigned int eku_bits; /* extended key usage information */ - krb5_principal *sans; /* Null-terminated array of subject alternative - name info (pkinit and ms-upn) */ + krb5_principal *sans; /* Null-terminated array of PKINIT SANs */ + krb5_principal *upns; /* Null-terimnated array of UPN SANs */ } pkinit_cert_matching_data; /* diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c index 4f21f90d2..bc6de7ae8 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c @@ -5093,6 +5093,9 @@ crypto_cert_free_matching_data(krb5_context context, for (i = 0; md->sans != NULL && md->sans[i] != NULL; i++) krb5_free_principal(context, md->sans[i]); free(md->sans); + for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) + krb5_free_principal(context, md->upns[i]); + free(md->upns); free(md); } @@ -5121,8 +5124,6 @@ get_matching_data(krb5_context context, { krb5_error_code ret = ENOMEM; pkinit_cert_matching_data *md = NULL; - krb5_principal *pkinit_sans = NULL, *upn_sans = NULL; - size_t i, j; *md_out = NULL; @@ -5139,40 +5140,10 @@ get_matching_data(krb5_context context, /* Get the SAN data. */ ret = crypto_retrieve_X509_sans(context, plg_cryptoctx, req_cryptoctx, - cert, &pkinit_sans, &upn_sans, NULL); + cert, &md->sans, &md->upns, NULL); if (ret) goto cleanup; - j = 0; - if (pkinit_sans != NULL) { - for (i = 0; pkinit_sans[i] != NULL; i++) - j++; - } - if (upn_sans != NULL) { - for (i = 0; upn_sans[i] != NULL; i++) - j++; - } - if (j != 0) { - md->sans = calloc((size_t)j+1, sizeof(*md->sans)); - if (md->sans == NULL) { - ret = ENOMEM; - goto cleanup; - } - j = 0; - if (pkinit_sans != NULL) { - for (i = 0; pkinit_sans[i] != NULL; i++) - md->sans[j++] = pkinit_sans[i]; - free(pkinit_sans); - } - if (upn_sans != NULL) { - for (i = 0; upn_sans[i] != NULL; i++) - md->sans[j++] = upn_sans[i]; - free(upn_sans); - } - md->sans[j] = NULL; - } else - md->sans = NULL; - /* Get the KU and EKU data. */ ret = crypto_retrieve_X509_key_usage(context, plg_cryptoctx, req_cryptoctx, cert, &md->ku_bits, diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c index c1ce84b82..37bd0251a 100644 --- a/src/plugins/preauth/pkinit/pkinit_matching.c +++ b/src/plugins/preauth/pkinit/pkinit_matching.c @@ -470,7 +470,6 @@ component_match(krb5_context context, { int match = 0; int i; - krb5_principal p; char *princ_string; switch (rc->kwval_type) { @@ -483,10 +482,17 @@ component_match(krb5_context context, match = regexp_match(context, rc, md->issuer_dn); break; case kw_san: - if (md->sans == NULL) - break; - for (i = 0, p = md->sans[i]; p != NULL; p = md->sans[++i]) { - krb5_unparse_name(context, p, &princ_string); + for (i = 0; md->sans != NULL && md->sans[i] != NULL; i++) { + krb5_unparse_name(context, md->sans[i], &princ_string); + match = regexp_match(context, rc, princ_string); + krb5_free_unparsed_name(context, princ_string); + if (match) + break; + } + for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) { + krb5_unparse_name_flags(context, md->upns[i], + KRB5_PRINCIPAL_UNPARSE_NO_REALM, + &princ_string); match = regexp_match(context, rc, princ_string); krb5_free_unparsed_name(context, princ_string); if (match) @@ -572,10 +578,18 @@ check_all_certs(krb5_context context, pkiDebug("%s: subject: '%s'\n", __FUNCTION__, md->subject_dn); #if 0 pkiDebug("%s: issuer: '%s'\n", __FUNCTION__, md->subject_dn); - for (j = 0, p = md->sans[j]; p != NULL; p = md->sans[++j]) { + for (j = 0; md->sans != NULL && md->sans[j] != NULL; j++) { char *san_string; - krb5_unparse_name(context, p, &san_string); - pkiDebug("%s: san: '%s'\n", __FUNCTION__, san_string); + krb5_unparse_name(context, md->sans[j], &san_string); + pkiDebug("%s: PKINIT san: '%s'\n", __FUNCTION__, san_string); + krb5_free_unparsed_name(context, san_string); + } + for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++) { + char *san_string; + krb5_unparse_name_flags(context, md->upns[j], + KRB5_PRINCIPAL_UNPARSE_NO_REALM, + &san_string); + pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, san_string); krb5_free_unparsed_name(context, san_string); } #endif