|
|
665228 |
From c7c702a9fee22a0f5173d94d8b1d5c2fac975f5c Mon Sep 17 00:00:00 2001
|
|
|
665228 |
From: Greg Hudson <ghudson@mit.edu>
|
|
|
665228 |
Date: Thu, 22 Mar 2018 20:07:17 -0400
|
|
|
665228 |
Subject: [PATCH] Return UPN SANs as strings
|
|
|
665228 |
|
|
|
665228 |
(cherry picked from commit fd3c824e3be56a1fa77d140fd7e93934bfd6e565)
|
|
|
665228 |
---
|
|
|
665228 |
src/plugins/preauth/pkinit/pkinit_crypto.h | 4 +--
|
|
|
665228 |
.../preauth/pkinit/pkinit_crypto_openssl.c | 28 +++++++------------
|
|
|
665228 |
src/plugins/preauth/pkinit/pkinit_matching.c | 16 ++---------
|
|
|
665228 |
src/plugins/preauth/pkinit/pkinit_srv.c | 21 +++++++++-----
|
|
|
665228 |
4 files changed, 29 insertions(+), 40 deletions(-)
|
|
|
665228 |
|
|
|
665228 |
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
|
|
665228 |
index c14f4456a..b6e4e0ac3 100644
|
|
|
665228 |
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
|
|
665228 |
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
|
|
665228 |
@@ -101,7 +101,7 @@ typedef struct _pkinit_cert_matching_data {
|
|
|
665228 |
unsigned int ku_bits; /* key usage information */
|
|
|
665228 |
unsigned int eku_bits; /* extended key usage information */
|
|
|
665228 |
krb5_principal *sans; /* Null-terminated array of PKINIT SANs */
|
|
|
665228 |
- krb5_principal *upns; /* Null-terimnated array of UPN SANs */
|
|
|
665228 |
+ char **upns; /* Null-terimnated array of UPN SANs */
|
|
|
665228 |
} pkinit_cert_matching_data;
|
|
|
665228 |
|
|
|
665228 |
/*
|
|
|
665228 |
@@ -253,7 +253,7 @@ krb5_error_code crypto_retrieve_cert_sans
|
|
|
665228 |
if non-NULL, a null-terminated array of
|
|
|
665228 |
id-pkinit-san values found in the certificate
|
|
|
665228 |
are returned */
|
|
|
665228 |
- krb5_principal **upn_sans, /* OUT
|
|
|
665228 |
+ char ***upn_sans, /* OUT
|
|
|
665228 |
if non-NULL, a null-terminated array of
|
|
|
665228 |
id-ms-upn-san values found in the certificate
|
|
|
665228 |
are returned */
|
|
|
665228 |
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
|
665228 |
index a38738f45..3f106973c 100644
|
|
|
665228 |
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
|
665228 |
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
|
|
665228 |
@@ -29,6 +29,7 @@
|
|
|
665228 |
* SUCH DAMAGES.
|
|
|
665228 |
*/
|
|
|
665228 |
|
|
|
665228 |
+#include "k5-int.h"
|
|
|
665228 |
#include "pkinit_crypto_openssl.h"
|
|
|
665228 |
#include "k5-buf.h"
|
|
|
665228 |
#include <dlfcn.h>
|
|
|
665228 |
@@ -2095,15 +2096,14 @@ crypto_retrieve_X509_sans(krb5_context context,
|
|
|
665228 |
pkinit_plg_crypto_context plgctx,
|
|
|
665228 |
pkinit_req_crypto_context reqctx,
|
|
|
665228 |
X509 *cert,
|
|
|
665228 |
- krb5_principal **princs_ret,
|
|
|
665228 |
- krb5_principal **upn_ret,
|
|
|
665228 |
+ krb5_principal **princs_ret, char ***upn_ret,
|
|
|
665228 |
unsigned char ***dns_ret)
|
|
|
665228 |
{
|
|
|
665228 |
krb5_error_code retval = EINVAL;
|
|
|
665228 |
char buf[DN_BUF_LEN];
|
|
|
665228 |
int p = 0, u = 0, d = 0, ret = 0, l;
|
|
|
665228 |
krb5_principal *princs = NULL;
|
|
|
665228 |
- krb5_principal *upns = NULL;
|
|
|
665228 |
+ char **upns = NULL;
|
|
|
665228 |
unsigned char **dnss = NULL;
|
|
|
665228 |
unsigned int i, num_found = 0, num_sans = 0;
|
|
|
665228 |
X509_EXTENSION *ext = NULL;
|
|
|
665228 |
@@ -2153,7 +2153,7 @@ crypto_retrieve_X509_sans(krb5_context context,
|
|
|
665228 |
}
|
|
|
665228 |
}
|
|
|
665228 |
if (upn_ret != NULL) {
|
|
|
665228 |
- upns = calloc(num_sans + 1, sizeof(krb5_principal));
|
|
|
665228 |
+ upns = calloc(num_sans + 1, sizeof(*upns));
|
|
|
665228 |
if (upns == NULL) {
|
|
|
665228 |
retval = ENOMEM;
|
|
|
665228 |
goto cleanup;
|
|
|
665228 |
@@ -2196,16 +2196,9 @@ crypto_retrieve_X509_sans(krb5_context context,
|
|
|
665228 |
/* Prevent abuse of embedded null characters. */
|
|
|
665228 |
if (memchr(name.data, '\0', name.length))
|
|
|
665228 |
break;
|
|
|
665228 |
- ret = krb5_parse_name_flags(context, name.data,
|
|
|
665228 |
- KRB5_PRINCIPAL_PARSE_ENTERPRISE,
|
|
|
665228 |
- &upns[u]);
|
|
|
665228 |
- if (ret) {
|
|
|
665228 |
- pkiDebug("%s: failed parsing ms-upn san value\n",
|
|
|
665228 |
- __FUNCTION__);
|
|
|
665228 |
- } else {
|
|
|
665228 |
- u++;
|
|
|
665228 |
- num_found++;
|
|
|
665228 |
- }
|
|
|
665228 |
+ upns[u] = k5memdup0(name.data, name.length, &ret;;
|
|
|
665228 |
+ if (upns[u] == NULL)
|
|
|
665228 |
+ goto cleanup;
|
|
|
665228 |
} else {
|
|
|
665228 |
pkiDebug("%s: unrecognized othername oid in SAN\n",
|
|
|
665228 |
__FUNCTION__);
|
|
|
665228 |
@@ -2257,7 +2250,7 @@ cleanup:
|
|
|
665228 |
krb5_free_principal(context, princs[i]);
|
|
|
665228 |
free(princs);
|
|
|
665228 |
for (i = 0; upns != NULL && upns[i] != NULL; i++)
|
|
|
665228 |
- krb5_free_principal(context, upns[i]);
|
|
|
665228 |
+ free(upns[i]);
|
|
|
665228 |
free(upns);
|
|
|
665228 |
for (i = 0; dnss != NULL && dnss[i] != NULL; i++)
|
|
|
665228 |
free(dnss[i]);
|
|
|
665228 |
@@ -2281,8 +2274,7 @@ crypto_retrieve_cert_sans(krb5_context context,
|
|
|
665228 |
pkinit_plg_crypto_context plgctx,
|
|
|
665228 |
pkinit_req_crypto_context reqctx,
|
|
|
665228 |
pkinit_identity_crypto_context idctx,
|
|
|
665228 |
- krb5_principal **princs_ret,
|
|
|
665228 |
- krb5_principal **upn_ret,
|
|
|
665228 |
+ krb5_principal **princs_ret, char ***upn_ret,
|
|
|
665228 |
unsigned char ***dns_ret)
|
|
|
665228 |
{
|
|
|
665228 |
krb5_error_code retval = EINVAL;
|
|
|
665228 |
@@ -5111,7 +5103,7 @@ crypto_cert_free_matching_data(krb5_context context,
|
|
|
665228 |
krb5_free_principal(context, md->sans[i]);
|
|
|
665228 |
free(md->sans);
|
|
|
665228 |
for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++)
|
|
|
665228 |
- krb5_free_principal(context, md->upns[i]);
|
|
|
665228 |
+ free(md->upns[i]);
|
|
|
665228 |
free(md->upns);
|
|
|
665228 |
free(md);
|
|
|
665228 |
}
|
|
|
665228 |
diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c
|
|
|
665228 |
index fe1e0f386..d929fb3c0 100644
|
|
|
665228 |
--- a/src/plugins/preauth/pkinit/pkinit_matching.c
|
|
|
665228 |
+++ b/src/plugins/preauth/pkinit/pkinit_matching.c
|
|
|
665228 |
@@ -490,11 +490,7 @@ component_match(krb5_context context,
|
|
|
665228 |
break;
|
|
|
665228 |
}
|
|
|
665228 |
for (i = 0; md->upns != NULL && md->upns[i] != NULL; i++) {
|
|
|
665228 |
- krb5_unparse_name_flags(context, md->upns[i],
|
|
|
665228 |
- KRB5_PRINCIPAL_UNPARSE_NO_REALM,
|
|
|
665228 |
- &princ_string);
|
|
|
665228 |
- match = regexp_match(context, rc, princ_string);
|
|
|
665228 |
- krb5_free_unparsed_name(context, princ_string);
|
|
|
665228 |
+ match = regexp_match(context, rc, md->upns[i]);
|
|
|
665228 |
if (match)
|
|
|
665228 |
break;
|
|
|
665228 |
}
|
|
|
665228 |
@@ -584,14 +580,8 @@ check_all_certs(krb5_context context,
|
|
|
665228 |
pkiDebug("%s: PKINIT san: '%s'\n", __FUNCTION__, san_string);
|
|
|
665228 |
krb5_free_unparsed_name(context, san_string);
|
|
|
665228 |
}
|
|
|
665228 |
- for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++) {
|
|
|
665228 |
- char *san_string;
|
|
|
665228 |
- krb5_unparse_name_flags(context, md->upns[j],
|
|
|
665228 |
- KRB5_PRINCIPAL_UNPARSE_NO_REALM,
|
|
|
665228 |
- &san_string);
|
|
|
665228 |
- pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, san_string);
|
|
|
665228 |
- krb5_free_unparsed_name(context, san_string);
|
|
|
665228 |
- }
|
|
|
665228 |
+ for (j = 0; md->upns != NULL && md->upns[j] != NULL; j++)
|
|
|
665228 |
+ pkiDebug("%s: UPN san: '%s'\n", __FUNCTION__, md->upns[j]);
|
|
|
665228 |
#endif
|
|
|
665228 |
certs_checked++;
|
|
|
665228 |
for (rc = rs->crs; rc != NULL; rc = rc->next) {
|
|
|
665228 |
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
|
|
|
665228 |
index 143d331a2..42ad45fe4 100644
|
|
|
665228 |
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
|
|
|
665228 |
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
|
|
|
665228 |
@@ -174,8 +174,9 @@ verify_client_san(krb5_context context,
|
|
|
665228 |
int *valid_san)
|
|
|
665228 |
{
|
|
|
665228 |
krb5_error_code retval;
|
|
|
665228 |
- krb5_principal *princs = NULL;
|
|
|
665228 |
- krb5_principal *upns = NULL;
|
|
|
665228 |
+ krb5_principal *princs = NULL, upn;
|
|
|
665228 |
+ krb5_boolean match;
|
|
|
665228 |
+ char **upns = NULL;
|
|
|
665228 |
int i;
|
|
|
665228 |
#ifdef DEBUG_SAN_INFO
|
|
|
665228 |
char *client_string = NULL, *san_string;
|
|
|
665228 |
@@ -251,12 +252,18 @@ verify_client_san(krb5_context context,
|
|
|
665228 |
pkiDebug("%s: Checking upn sans\n", __FUNCTION__);
|
|
|
665228 |
for (i = 0; upns[i] != NULL; i++) {
|
|
|
665228 |
#ifdef DEBUG_SAN_INFO
|
|
|
665228 |
- krb5_unparse_name(context, upns[i], &san_string);
|
|
|
665228 |
pkiDebug("%s: Comparing client '%s' to upn san value '%s'\n",
|
|
|
665228 |
- __FUNCTION__, client_string, san_string);
|
|
|
665228 |
- krb5_free_unparsed_name(context, san_string);
|
|
|
665228 |
+ __FUNCTION__, client_string, upns[i]);
|
|
|
665228 |
#endif
|
|
|
665228 |
- if (cb->match_client(context, rock, upns[i])) {
|
|
|
665228 |
+ retval = krb5_parse_name_flags(context, upns[i],
|
|
|
665228 |
+ KRB5_PRINCIPAL_PARSE_ENTERPRISE, &upn;;
|
|
|
665228 |
+ if (retval) {
|
|
|
665228 |
+ /* XXX trace */
|
|
|
665228 |
+ continue;
|
|
|
665228 |
+ }
|
|
|
665228 |
+ match = cb->match_client(context, rock, upn);
|
|
|
665228 |
+ krb5_free_principal(context, upn);
|
|
|
665228 |
+ if (match) {
|
|
|
665228 |
TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(context);
|
|
|
665228 |
*valid_san = 1;
|
|
|
665228 |
retval = 0;
|
|
|
665228 |
@@ -282,7 +289,7 @@ out:
|
|
|
665228 |
}
|
|
|
665228 |
if (upns != NULL) {
|
|
|
665228 |
for (i = 0; upns[i] != NULL; i++)
|
|
|
665228 |
- krb5_free_principal(context, upns[i]);
|
|
|
665228 |
+ free(upns[i]);
|
|
|
665228 |
free(upns);
|
|
|
665228 |
}
|
|
|
665228 |
#ifdef DEBUG_SAN_INFO
|