diff options
author | Luke Howard <lukeh@padl.com> | 2009-11-22 11:33:00 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2009-11-22 11:33:00 +0000 |
commit | bf53fa6f28a190c17cf6804789dd5fff8eac525d (patch) | |
tree | fe45ebe5c280df2d7706174910519cb532ab57fd | |
parent | 05fb2dc5956a77d60ed24fa1a3f8b9317e119118 (diff) | |
download | krb5-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.hin | 15 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/Makefile.in | 3 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/gssapiP_krb5.h | 8 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/gssapi_err_krb5.et | 1 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/prf.c | 140 | ||||
-rw-r--r-- | src/lib/gssapi/libgssapi_krb5.exports | 1 | ||||
-rw-r--r-- | src/lib/gssapi/mechglue/Makefile.in | 3 | ||||
-rw-r--r-- | src/lib/gssapi/mechglue/g_initialize.c | 2 | ||||
-rw-r--r-- | src/lib/gssapi/mechglue/g_prf.c | 84 | ||||
-rw-r--r-- | src/lib/gssapi/mechglue/mglueP.h | 10 | ||||
-rw-r--r-- | src/lib/gssapi/spnego/gssapiP_spnego.h | 11 | ||||
-rw-r--r-- | src/lib/gssapi/spnego/spnego_mech.c | 19 |
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 |