aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2009-11-22 11:33:00 +0000
committerLuke Howard <lukeh@padl.com>2009-11-22 11:33:00 +0000
commitbf53fa6f28a190c17cf6804789dd5fff8eac525d (patch)
treefe45ebe5c280df2d7706174910519cb532ab57fd
parent05fb2dc5956a77d60ed24fa1a3f8b9317e119118 (diff)
downloadkrb5-bf53fa6f28a190c17cf6804789dd5fff8eac525d.zip
krb5-bf53fa6f28a190c17cf6804789dd5fff8eac525d.tar.gz
krb5-bf53fa6f28a190c17cf6804789dd5fff8eac525d.tar.bz2
implement gss_pseudo_random()
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/gssextras@23302 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/gssapi/generic/gssapi.hin15
-rw-r--r--src/lib/gssapi/krb5/Makefile.in3
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h8
-rw-r--r--src/lib/gssapi/krb5/gssapi_err_krb5.et1
-rw-r--r--src/lib/gssapi/krb5/prf.c140
-rw-r--r--src/lib/gssapi/libgssapi_krb5.exports1
-rw-r--r--src/lib/gssapi/mechglue/Makefile.in3
-rw-r--r--src/lib/gssapi/mechglue/g_initialize.c2
-rw-r--r--src/lib/gssapi/mechglue/g_prf.c84
-rw-r--r--src/lib/gssapi/mechglue/mglueP.h10
-rw-r--r--src/lib/gssapi/spnego/gssapiP_spnego.h11
-rw-r--r--src/lib/gssapi/spnego/spnego_mech.c19
12 files changed, 297 insertions, 0 deletions
diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin
index 422b4db..d0ccb38 100644
--- a/src/lib/gssapi/generic/gssapi.hin
+++ b/src/lib/gssapi/generic/gssapi.hin
@@ -780,6 +780,21 @@ gss_canonicalize_name(
const gss_OID, /* mech_type */
gss_name_t *); /* output_name */
+/* RFC 4401 */
+
+#define GSS_C_PRF_KEY_FULL 0
+#define GSS_C_PRF_KEY_PARTIAL 1
+
+OM_uint32 KRB5_CALLCONV
+gss_pseudo_random(
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context */
+ int, /* prf_key */
+ const gss_buffer_t, /* prf_in */
+ ssize_t, /* desired_output_len */
+ gss_buffer_t); /* prf_out */
+
+
#if TARGET_OS_MAC
# pragma pack(pop)
#endif
diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in
index b84efa1..70bea38 100644
--- a/src/lib/gssapi/krb5/Makefile.in
+++ b/src/lib/gssapi/krb5/Makefile.in
@@ -70,6 +70,7 @@ SRCS = \
$(srcdir)/krb5_gss_glue.c \
$(srcdir)/lucid_context.c \
$(srcdir)/naming_exts.c \
+ $(srcdir)/prf.c \
$(srcdir)/process_context_token.c \
$(srcdir)/rel_cred.c \
$(srcdir)/rel_oid.c \
@@ -122,6 +123,7 @@ OBJS = \
$(OUTPRE)krb5_gss_glue.$(OBJEXT) \
$(OUTPRE)lucid_context.$(OBJEXT) \
$(OUTPRE)naming_exts.$(OBJEXT) \
+ $(OUTPRE)prf.$(OBJEXT) \
$(OUTPRE)process_context_token.$(OBJEXT) \
$(OUTPRE)rel_cred.$(OBJEXT) \
$(OUTPRE)rel_oid.$(OBJEXT) \
@@ -177,6 +179,7 @@ STLIBOBJS = \
krb5_gss_glue.o \
lucid_context.o \
naming_exts.o \
+ prf.o \
process_context_token.o \
rel_cred.o \
rel_oid.o \
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 13413b9..14ad126 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -909,6 +909,14 @@ krb5_gss_release_any_name_mapping(OM_uint32 *minor_status,
gss_buffer_t type_id,
gss_any_t *input);
+OM_uint32
+krb5_gss_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out);
+
/* s4u_gss_glue.c */
OM_uint32
kg_compose_deleg_cred(OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/krb5/gssapi_err_krb5.et b/src/lib/gssapi/krb5/gssapi_err_krb5.et
index c2a705c..4cfd68a 100644
--- a/src/lib/gssapi/krb5/gssapi_err_krb5.et
+++ b/src/lib/gssapi/krb5/gssapi_err_krb5.et
@@ -37,4 +37,5 @@ error_code KG_BAD_SEQ, "Sequence number in token is corrupt"
error_code KG_EMPTY_CCACHE, "Credential cache is empty"
error_code KG_NO_CTYPES, "Acceptor and Initiator share no checksum types"
error_code KG_LUCID_VERSION, "Requested lucid context version not supported"
+error_code KG_INPUT_TOO_LONG, "PRF input too long"
end
diff --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c
new file mode 100644
index 0000000..2c0f37e
--- /dev/null
+++ b/src/lib/gssapi/krb5/prf.c
@@ -0,0 +1,140 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * lib/gssapi/krb5/prf.c
+ *
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ */
+
+#include <assert.h>
+#include "k5-int.h" /* for zap() */
+#include "gssapiP_krb5.h"
+#include <stdarg.h>
+
+OM_uint32
+krb5_gss_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ krb5_error_code code;
+ krb5_key key = NULL;
+ krb5_gss_ctx_id_t ctx;
+ int i;
+ krb5_keyblock *keyblock = NULL;
+ OM_uint32 minor;
+ size_t prflen;
+ krb5_data t, ns;
+ unsigned char *p;
+
+ t.length = 0;
+ t.data = NULL;
+ ns.length = 0;
+ ns.data = NULL;
+
+ prf_out->length = 0;
+ prf_out->value = NULL;
+
+ if (!kg_validate_ctx_id(context)) {
+ *minor_status = G_VALIDATE_FAILED;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ ctx = (krb5_gss_ctx_id_t)context;
+
+ switch (prf_key) {
+ case GSS_C_PRF_KEY_FULL:
+ if (ctx->have_acceptor_subkey) {
+ key = ctx->acceptor_subkey;
+ break;
+ }
+ /* fallthrough */
+ case GSS_C_PRF_KEY_PARTIAL:
+ key = ctx->subkey;
+ break;
+ default:
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ if (key == NULL) {
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ prf_out->value = k5alloc(desired_output_len, &code);
+ if (prf_out->value == NULL) {
+ code = KG_INPUT_TOO_LONG;
+ goto cleanup;
+ }
+
+ code = krb5_c_prf_length(ctx->k5_context,
+ krb5_k_key_enctype(ctx->k5_context, key),
+ &prflen);
+ if (code != 0)
+ goto cleanup;
+
+ code = krb5_k_key_keyblock(ctx->k5_context, key, &keyblock);
+ if (code != 0)
+ goto cleanup;
+
+ ns.length = 4 + prf_in->length;
+ ns.data = k5alloc(ns.length, &code);
+ if (ns.data == NULL) {
+ code = KG_INPUT_TOO_LONG;
+ goto cleanup;
+ }
+
+ memcpy(ns.data + 4, prf_in->value, prf_in->length);
+ i = 0;
+ p = (unsigned char *)prf_out->value;
+ while (desired_output_len > 0) {
+ store_32_be(i, ns.data);
+
+ code = krb5_c_prf(ctx->k5_context, keyblock, &ns, &t);
+ if (code != 0)
+ goto cleanup;
+
+ memcpy(p, t.data, MIN(t.length, desired_output_len));
+
+ p += t.length;
+ desired_output_len -= t.length;
+ i++;
+
+ krb5_free_data_contents(ctx->k5_context, &t);
+ }
+
+cleanup:
+ if (code != 0)
+ gss_release_buffer(&minor, prf_out);
+ krb5_free_data_contents(ctx->k5_context, &ns);
+ krb5_free_data_contents(ctx->k5_context, &t);
+ krb5_free_keyblock(ctx->k5_context, keyblock);
+
+ *minor_status = (OM_uint32)code;
+ return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index 60754df..de063da 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -68,6 +68,7 @@ gss_nt_service_name_v2
gss_nt_string_uid_name
gss_nt_user_name
gss_oid_to_str
+gss_pseudo_random
gss_process_context_token
gss_release_any_name_mapping
gss_release_buffer_set
diff --git a/src/lib/gssapi/mechglue/Makefile.in b/src/lib/gssapi/mechglue/Makefile.in
index 61972ab..8edacf6 100644
--- a/src/lib/gssapi/mechglue/Makefile.in
+++ b/src/lib/gssapi/mechglue/Makefile.in
@@ -45,6 +45,7 @@ SRCS = \
$(srcdir)/g_mech_invoke.c \
$(srcdir)/g_mechname.c \
$(srcdir)/g_oid_ops.c \
+ $(srcdir)/g_prf.c \
$(srcdir)/g_process_context.c \
$(srcdir)/g_rel_buffer.c \
$(srcdir)/g_rel_cred.c \
@@ -98,6 +99,7 @@ OBJS = \
$(OUTPRE)g_mech_invoke.$(OBJEXT) \
$(OUTPRE)g_mechname.$(OBJEXT) \
$(OUTPRE)g_oid_ops.$(OBJEXT) \
+ $(OUTPRE)g_prf.$(OBJEXT) \
$(OUTPRE)g_process_context.$(OBJEXT) \
$(OUTPRE)g_rel_buffer.$(OBJEXT) \
$(OUTPRE)g_rel_cred.$(OBJEXT) \
@@ -151,6 +153,7 @@ STLIBOBJS = \
g_mech_invoke.o \
g_mechname.o \
g_oid_ops.o \
+ g_prf.o \
g_process_context.o \
g_rel_buffer.o \
g_rel_cred.o \
diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
index 3929f76..e01d174 100644
--- a/src/lib/gssapi/mechglue/g_initialize.c
+++ b/src/lib/gssapi/mechglue/g_initialize.c
@@ -773,6 +773,8 @@ build_dynamicMech(void *dl, const gss_OID mech_type)
GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_name_composite);
GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_map_name_to_any);
GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_release_any_name_mapping);
+ /* RFC 4401 (introduced in 1.8) */
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_pseudo_random);
assert(mech_type != GSS_C_NO_OID);
diff --git a/src/lib/gssapi/mechglue/g_prf.c b/src/lib/gssapi/mechglue/g_prf.c
new file mode 100644
index 0000000..74a3a21
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_prf.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * glue routine for gss_pseudo_random
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_pseudo_random (OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ if (prf_in == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ if (prf_out == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT;
+
+ prf_out->length = 0;
+ prf_out->value = NULL;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech != NULL) {
+ if (mech->gss_pseudo_random != NULL) {
+ status = mech->gss_pseudo_random(minor_status,
+ ctx->internal_ctx_id,
+ prf_key,
+ prf_in,
+ desired_output_len,
+ prf_out);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return status;
+ }
+
+ return GSS_S_BAD_MECH;
+}
diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
index f35ac14..517ca48 100644
--- a/src/lib/gssapi/mechglue/mglueP.h
+++ b/src/lib/gssapi/mechglue/mglueP.h
@@ -573,6 +573,16 @@ typedef struct gss_config {
gss_any_t * /* input */
/* */);
+ OM_uint32 (*gss_pseudo_random)
+ (
+ OM_uint32 *, /* minor_status */
+ gss_ctx_id_t, /* context */
+ int, /* prf_key */
+ const gss_buffer_t, /* prf_in */
+ ssize_t, /* desired_output_len */
+ gss_buffer_t /* prf_out */
+ /* */);
+
} *gss_mechanism;
/* This structure MUST NOT be used by any code outside libgss */
diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h
index 43b0049..80c23e2 100644
--- a/src/lib/gssapi/spnego/gssapiP_spnego.h
+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
@@ -519,6 +519,17 @@ spnego_gss_release_any_name_mapping
gss_any_t *input
);
+OM_uint32
+spnego_gss_pseudo_random
+(
+ OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out
+);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 2aa8ad5..6357f16 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -268,6 +268,7 @@ static struct gss_config spnego_mechanism =
spnego_gss_export_name_composite,
spnego_gss_map_name_to_any,
spnego_gss_release_any_name_mapping,
+ spnego_gss_pseudo_random,
};
#ifdef _GSS_STATIC_LINK
@@ -2485,6 +2486,24 @@ spnego_gss_release_any_name_mapping(OM_uint32 *minor_status,
return (ret);
}
+OM_uint32
+spnego_gss_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ OM_uint32 ret;
+ ret = gss_pseudo_random(minor_status,
+ context,
+ prf_key,
+ prf_in,
+ desired_output_len,
+ prf_out);
+ return (ret);
+}
+
/*
* We will release everything but the ctx_handle so that it
* can be passed back to init/accept context. This routine should