krb5 commit: Add GSS_KRB5_NT_X509_CERT name type
Greg Hudson
ghudson at mit.edu
Wed Jul 1 13:17:16 EDT 2020
https://github.com/krb5/krb5/commit/f2e28f13156785851819fc74cae52100e0521690
commit f2e28f13156785851819fc74cae52100e0521690
Author: Isaac Boukris <iboukris at gmail.com>
Date: Mon Aug 12 11:13:07 2019 +0000
Add GSS_KRB5_NT_X509_CERT name type
If this name type is used for the desired_name parameter of
gss_acquire_cred_impersonate_name(), identify the S4U2Self user by
certificate. Co-authored with Purand Chand <pchand at vmware.com>.
[ghudson at mit.edu: added documentation; updated to use a boolean at the
GSS layer rather than a new krb5 name type; rewrote commit message]
ticket: 8923 (new)
doc/appdev/gssapi.rst | 6 ++++++
src/lib/gssapi/krb5/gssapiP_krb5.h | 1 +
src/lib/gssapi/krb5/gssapi_krb5.c | 3 +++
src/lib/gssapi/krb5/gssapi_krb5.h | 5 +++++
src/lib/gssapi/krb5/import_name.c | 12 +++++++++++-
src/lib/gssapi/krb5/s4u_gss_glue.c | 9 ++++++---
src/lib/gssapi/libgssapi_krb5.exports | 1 +
src/lib/gssapi32.def | 2 ++
src/tests/gssapi/common.c | 4 +++-
src/tests/gssapi/t_imp_name.c | 2 ++
src/tests/gssapi/t_s4u.py | 10 ++++++++++
11 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/doc/appdev/gssapi.rst b/doc/appdev/gssapi.rst
index 66561fd..452ead2 100644
--- a/doc/appdev/gssapi.rst
+++ b/doc/appdev/gssapi.rst
@@ -61,6 +61,12 @@ name types are supported by the krb5 mechanism:
is defined in the ``<gssapi/gssapi_krb5.h>`` header. (New in
release 1.17.)
+* **GSS_KRB5_NT_X509_CERT**: The value should be an X.509 certificate
+ encoded according to :rfc:`5280`. This name form can be used for
+ the desired_name parameter of gss_acquire_cred_impersonate_name(),
+ to identify the S4U2Self user by certificate. (New in release
+ 1.19.)
+
Initiator credentials
---------------------
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 2e2c775..53d077a 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -163,6 +163,7 @@ typedef struct _krb5_gss_name_rec {
krb5_principal princ; /* immutable */
char *service; /* immutable */
char *host; /* immutable */
+ int is_cert; /* immutable */
k5_mutex_t lock; /* protects ad_context only for now */
krb5_authdata_context ad_context;
} krb5_gss_name_rec, *krb5_gss_name_t;
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index 128ffff..a96d7ce 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -152,6 +152,8 @@ const gss_OID_desc krb5_gss_oid_array[] = {
{GET_CRED_IMPERSONATOR_OID_LENGTH, GET_CRED_IMPERSONATOR_OID},
/* GSS_KRB5_NT_ENTERPRISE_NAME */
{10, "\052\206\110\206\367\022\001\002\002\006"},
+ /* GSS_KRB5_NT_X509_CERT */
+ {10, "\052\206\110\206\367\022\001\002\002\007"},
{ 0, 0 }
};
@@ -170,6 +172,7 @@ const gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &kg_oids[5];
const gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &kg_oids[7];
const gss_OID GSS_KRB5_GET_CRED_IMPERSONATOR = &kg_oids[8];
const gss_OID GSS_KRB5_NT_ENTERPRISE_NAME = &kg_oids[9];
+const gss_OID GSS_KRB5_NT_X509_CERT = &kg_oids[10];
static const gss_OID_set_desc oidsets[] = {
{1, &kg_oids[0]}, /* RFC OID */
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h
index e266b59..8141f41 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.h
+++ b/src/lib/gssapi/krb5/gssapi_krb5.h
@@ -78,6 +78,11 @@ GSS_DLLIMP extern const gss_OID GSS_KRB5_NT_ENTERPRISE_NAME;
/* {iso(1) member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
* krb5(2) krb5-enterprise-name(6)}. */
+/* Kerberos X.509 DER-encoded certificate */
+GSS_DLLIMP extern const gss_OID GSS_KRB5_NT_X509_CERT;
+/* {iso(1) member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5-x509-cert(7)}. */
+
GSS_DLLIMP extern const gss_OID gss_mech_krb5;
GSS_DLLIMP extern const gss_OID gss_mech_krb5_old;
GSS_DLLIMP extern const gss_OID gss_mech_krb5_wrong;
diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c
index 21023dd..f64635a 100644
--- a/src/lib/gssapi/krb5/import_name.c
+++ b/src/lib/gssapi/krb5/import_name.c
@@ -136,7 +136,7 @@ krb5_gss_import_name(minor_status, input_name_buffer,
#ifndef NO_PASSWORD
struct passwd *pw;
#endif
- int is_composite = 0;
+ int is_composite = 0, is_cert = 0;
krb5_authdata_context ad_context = NULL;
OM_uint32 status = GSS_S_FAILURE;
krb5_gss_name_t name;
@@ -188,6 +188,14 @@ krb5_gss_import_name(minor_status, input_name_buffer,
&princ);
if (code)
goto cleanup;
+ } else if ((input_name_type != NULL) &&
+ g_OID_equal(input_name_type, GSS_KRB5_NT_X509_CERT)) {
+ code = krb5_build_principal_ext(context, &princ, 0, NULL,
+ input_name_buffer->length,
+ input_name_buffer->value, 0);
+ if (code)
+ goto cleanup;
+ is_cert = 1;
} else {
#ifndef NO_PASSWORD
uid_t uid;
@@ -315,6 +323,8 @@ krb5_gss_import_name(minor_status, input_name_buffer,
KG_INIT_NAME_NO_COPY, &name);
if (code)
goto cleanup;
+ name->is_cert = is_cert;
+
princ = NULL;
ad_context = NULL;
service = host = NULL;
diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c
index 126ca97..7dcfe4e 100644
--- a/src/lib/gssapi/krb5/s4u_gss_glue.c
+++ b/src/lib/gssapi/krb5/s4u_gss_glue.c
@@ -48,11 +48,15 @@ kg_impersonate_name(OM_uint32 *minor_status,
OM_uint32 major_status;
krb5_error_code code;
krb5_creds in_creds, *out_creds = NULL;
+ krb5_data *subject_cert = NULL;
*output_cred = NULL;
memset(&in_creds, 0, sizeof(in_creds));
- in_creds.client = user->princ;
+ if (user->is_cert)
+ subject_cert = user->princ->data;
+ else
+ in_creds.client = user->princ;
in_creds.server = impersonator_cred->name->princ;
if (impersonator_cred->req_enctypes != NULL)
@@ -77,8 +81,7 @@ kg_impersonate_name(OM_uint32 *minor_status,
code = krb5_get_credentials_for_user(context,
KRB5_GC_CANONICALIZE | KRB5_GC_NO_STORE,
impersonator_cred->ccache,
- &in_creds,
- NULL, &out_creds);
+ &in_creds, subject_cert, &out_creds);
if (code != 0) {
krb5_free_authdata(context, in_creds.authdata);
*minor_status = code;
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index 166acfa..fd4fced 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -12,6 +12,7 @@ GSS_C_NT_STRING_UID_NAME
GSS_C_NT_USER_NAME
GSS_KRB5_NT_PRINCIPAL_NAME
GSS_KRB5_NT_ENTERPRISE_NAME
+GSS_KRB5_NT_X509_CERT
GSS_KRB5_CRED_NO_CI_FLAGS_X
GSS_KRB5_GET_CRED_IMPERSONATOR
GSS_C_MA_MECH_CONCRETE
diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def
index e6b1479..a5a1e4a 100644
--- a/src/lib/gssapi32.def
+++ b/src/lib/gssapi32.def
@@ -187,3 +187,5 @@ EXPORTS
GSS_C_SEC_CONTEXT_SASL_SSF @149 DATA
; Added in 1.17
GSS_KRB5_NT_ENTERPRISE_NAME @150 DATA
+; Added in 1.19
+ GSS_KRB5_NT_X509_CERT @151 DATA
diff --git a/src/tests/gssapi/common.c b/src/tests/gssapi/common.c
index 7ba72f7..b49c13d 100644
--- a/src/tests/gssapi/common.c
+++ b/src/tests/gssapi/common.c
@@ -99,10 +99,12 @@ import_name(const char *str)
nametype = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
else if (*str == 'e')
nametype = (gss_OID)GSS_KRB5_NT_ENTERPRISE_NAME;
+ else if (*str == 'c')
+ nametype = (gss_OID)GSS_KRB5_NT_X509_CERT;
else if (*str == 'h')
nametype = GSS_C_NT_HOSTBASED_SERVICE;
if (nametype == NULL || str[1] != ':')
- errout("names must begin with u: or p: or e: or h:");
+ errout("names must begin with u: or p: or e: or c: or h:");
buf.value = (char *)str + 2;
buf.length = strlen(str) - 2;
major = gss_import_name(&minor, &buf, nametype, &name);
diff --git a/src/tests/gssapi/t_imp_name.c b/src/tests/gssapi/t_imp_name.c
index 3d73dc8..e7dbcc4 100644
--- a/src/tests/gssapi/t_imp_name.c
+++ b/src/tests/gssapi/t_imp_name.c
@@ -41,6 +41,8 @@ oid_str(char type)
return "{ 1 2 840 113554 1 2 2 1 }";
case 'e': /* GSS_KRB5_NT_ENTERPRISE_NAME */
return "{ 1 2 840 113554 1 2 2 6 }";
+ case 'c': /* GSS_KRB5_NT_X509_CERT */
+ return "{ 1 2 840 113554 1 2 2 7 }";
case 'h': /* GSS_C_NT_HOSTBASED_SERVICE */
return "{ 1 2 840 113554 1 2 1 4 }";
}
diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py
index 8077d8c..67eba44 100755
--- a/src/tests/gssapi/t_s4u.py
+++ b/src/tests/gssapi/t_s4u.py
@@ -277,6 +277,16 @@ msgs = ('Getting initial credentials for enterprise\\@abc at SREALM',
r1.run([kvno, '-U', 'enterprise at abc', '-F', cert_path, r1.user_princ],
expected_trace=msgs)
+shutil.copyfile(savefile, r1.ccache)
+
+mark('S4U2Self using X509 certificate (GSSAPI)')
+
+r1.run(['./t_s4u', 'c:other', '-', r1.keytab])
+r1.run(['./t_s4u', 'c:user at UREALM', '-', r1.keytab])
+
+r1.run(['./t_s4u', '--spnego', 'c:other', '-', r1.keytab])
+r1.run(['./t_s4u', '--spnego', 'c:user at UREALM', '-', r1.keytab])
+
r1.stop()
r2.stop()
More information about the cvs-krb5
mailing list