aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gssapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r--src/lib/gssapi/ChangeLog4
-rw-r--r--src/lib/gssapi/Makefile.in2
-rw-r--r--src/lib/gssapi/generic/ChangeLog29
-rw-r--r--src/lib/gssapi/generic/disp_com_err_status.c5
-rw-r--r--src/lib/gssapi/generic/gssapi.hin157
-rw-r--r--src/lib/gssapi/generic/gssapiP_generic.h34
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.c118
-rw-r--r--src/lib/gssapi/generic/gssapi_generic.h10
-rw-r--r--src/lib/gssapi/krb5/3des.txt274
-rw-r--r--src/lib/gssapi/krb5/ChangeLog150
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c434
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c43
-rw-r--r--src/lib/gssapi/krb5/add_cred.c46
-rw-r--r--src/lib/gssapi/krb5/disp_status.c5
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h78
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c22
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.h50
-rw-r--r--src/lib/gssapi/krb5/import_sec_context.c2
-rw-r--r--src/lib/gssapi/krb5/init_sec_context.c472
-rw-r--r--src/lib/gssapi/krb5/inq_cred.c32
-rw-r--r--src/lib/gssapi/krb5/k5seal.c852
-rw-r--r--src/lib/gssapi/krb5/k5unseal.c1086
-rw-r--r--src/lib/gssapi/krb5/ser_sctx.c5
-rw-r--r--src/lib/gssapi/krb5/util_cksum.c1
-rw-r--r--src/lib/gssapi/krb5/util_crypt.c34
-rw-r--r--src/lib/gssapi/krb5/util_seed.c2
-rw-r--r--src/lib/gssapi/krb5/util_seqnum.c4
-rw-r--r--src/lib/gssapi/krb5/wrap_size_limit.c130
28 files changed, 1945 insertions, 2136 deletions
diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog
index 1e0213f..060c2e7 100644
--- a/src/lib/gssapi/ChangeLog
+++ b/src/lib/gssapi/ChangeLog
@@ -1,3 +1,7 @@
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * Makefile.in(LIBMINOR): Bump library version.
+
Tue Feb 22 10:23:19 2000 Ezra Peisach <epeisach@mit.edu>
* Makefile.in (clean-unix): Add clean-libobjs.
diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in
index bee2b85..20936da 100644
--- a/src/lib/gssapi/Makefile.in
+++ b/src/lib/gssapi/Makefile.in
@@ -24,7 +24,7 @@ SRCS=\
LIB=gssapi_krb5
LIBMAJOR=2
-LIBMINOR=1
+LIBMINOR=2
STOBJLISTS=OBJS.ST generic/OBJS.ST krb5/OBJS.ST
SHLIB_EXPDEPS=\
$(TOPLIBD)/libkrb5$(SHLIBEXT) \
diff --git a/src/lib/gssapi/generic/ChangeLog b/src/lib/gssapi/generic/ChangeLog
index 234c953..db4ab13 100644
--- a/src/lib/gssapi/generic/ChangeLog
+++ b/src/lib/gssapi/generic/ChangeLog
@@ -1,3 +1,32 @@
+2000-11-19 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_generic.h: Fixed check for Mac OS X includes.
+
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * gssapi.hin, gssapi_generic.h, gssapi_generic.c:
+ added oids from rfc 2744. Kept old oids for compatibility.
+ * gssapi.hin: Changed KerberosConditionalMacros.h to
+ KerberosSupport.h.
+ * gssapi.hin: Fixed Mac OS preprocessor test
+ * gssapi_generic.h: corrected Mac OS include to <GSS/gssapi.h>
+ * gssapiP_generic.h: use "" include for krb5.h
+ * disp_com_err_status.c, gssapi.hin: Updated Mac OS #defines
+ and #includes for new header layout and Mac OS X frameworks
+ * gssapi_generic.h: Added check for Mac OS X includes. This will
+ not break autoconf-style builds because they do not include
+ ConditionalMacros.h.
+
+2001-10-20 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_generic.h (g_*): For every g_ function declared here,
+ first define the name as a macro using a gssint_ prefix to avoid
+ conflicting with glib function names.
+
+2000-09-11 Alexandra Ellwood <lxs@mit.edu>
+ * gssapi_generic.h: Added check for Mac OS X includes. This will
+ not break autoconf-style builds because they do not include
+ ConditionalMacros.h.
+
1999-10-26 Tom Yu <tlyu@mit.edu>
* Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES,
diff --git a/src/lib/gssapi/generic/disp_com_err_status.c b/src/lib/gssapi/generic/disp_com_err_status.c
index c4db913..d09c914 100644
--- a/src/lib/gssapi/generic/disp_com_err_status.c
+++ b/src/lib/gssapi/generic/disp_com_err_status.c
@@ -25,7 +25,12 @@
*/
#include "gssapiP_generic.h"
+
+#if TARGET_OS_MAC
+#include <KerberosComErr/KerberosComErr.h>
+#else
#include "com_err.h"
+#endif
/* XXXX internationalization!! */
diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin
index f6a0f57..9e2d597 100644
--- a/src/lib/gssapi/generic/gssapi.hin
+++ b/src/lib/gssapi/generic/gssapi.hin
@@ -27,13 +27,22 @@
* Determine platform-dependent configuration.
*/
-#if defined(_MSDOS) || defined(_WIN32) || defined(macintosh)
-#include <win-mac.h>
-
-/* Macintoh CFM-68K magic incantation */
-#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
-#pragma import on
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+ #include <KerberosSupport/KerberosSupport.h>
+
+ #if TARGET_API_MAC_OS8 || (TARGET_API_MAC_CARBON && !TARGET_API_MAC_OSX)
+ #include <Kerberos5/win-mac.h>
+ #endif
+
+ /* This is an API divergence in 1.2.3. This will be reconciled in 1.3, when
+ all platforms will have RFC-compliant OID declarations. */
+ #define GSS_RFC_COMPLIANT_OIDS 1
+#else
+ #define GSS_RFC_COMPLIANT_OIDS 0
#endif
+
+#if defined(_MSDOS) || defined(_WIN32)
+#include <win-mac.h>
#endif
#ifndef KRB5_CALLCONV
@@ -329,8 +338,122 @@ typedef int gss_cred_usage_t;
#ifdef __cplusplus
extern "C" {
+#endif /* __cplusplus */
+
+/* Macintoh CFM-68K magic incantation */
+#if PRAGMA_IMPORT
+#pragma import on
+#endif
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack(2)
#endif
+/* RFC-compliant GSS_oids will be present on all platforms in 1.3 */
+#if GSS_RFC_COMPLIANT_OIDS
+
+/* Reserved static storage for GSS_oids. Comments are quotes from RFC 2744.
+ *
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ * "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_ANONYMOUS;
+
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
+/* Function Prototypes */
+
GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_acquire_cred
PROTOTYPE( (OM_uint32 FAR *, /* minor_status */
gss_name_t, /* desired_name */
@@ -684,9 +807,24 @@ PROTOTYPE( (OM_uint32 *, /* minor_status */
gss_name_t * /* output_name */
));
+/* Macintosh CFM-68K magic incantation */
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack()
+#endif
+
+#ifdef PRAGMA_IMPORT_OFF
+#pragma import off
+#elif PRAGMA_IMPORT
+#pragma import reset
+#endif
+
#ifdef __cplusplus
}
-#endif
+#endif /* __cplusplus */
/* XXXX these are not part of the GSSAPI C bindings! (but should be) */
@@ -700,9 +838,4 @@ PROTOTYPE( (OM_uint32 *, /* minor_status */
/* XXXX This is a necessary evil until the spec is fixed */
#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
-/* Macintoh CFM-68K magic incantation */
-#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
-#pragma import reset
-#endif
-
#endif /* _GSSAPI_H_ */
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index a0fa7c4..3f7fd75 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -28,7 +28,7 @@
*/
#if (defined(_MSDOS) || defined(_WIN32) || defined(macintosh))
-#include <k5-int.h>
+#include "k5-int.h"
#else
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -97,6 +97,38 @@
/** helper functions **/
+/* hide names from applications, especially glib applications */
+#define g_set_init gssint_g_set_init
+#define g_set_destroy gssint_g_set_destroy
+#define g_set_entry_add gssint_g_set_entry_add
+#define g_set_entry_delete gssint_g_set_entry_delete
+#define g_set_entry_get gssint_g_set_entry_get
+#define g_save_name gssint_g_save_name
+#define g_save_cred_id gssint_g_save_cred_id
+#define g_save_ctx_id gssint_g_save_ctx_id
+#define g_validate_name gssint_g_validate_name
+#define g_validate_cred_id gssint_g_validate_cred_id
+#define g_validate_ctx_id gssint_g_validate_ctx_id
+#define g_delete_name gssint_g_delete_name
+#define g_delete_cred_id gssint_g_delete_cred_id
+#define g_delete_ctx_id gssint_g_delete_ctx_id
+#define g_make_string_buffer gssint_g_make_string_buffer
+#define g_copy_OID_set gssint_g_copy_OID_set
+#define g_token_size gssint_g_token_size
+#define g_make_token_header gssint_g_make_token_header
+#define g_verify_token_header gssint_g_verify_token_header
+#define g_display_major_status gssint_g_display_major_status
+#define g_display_com_err_status gssint_g_display_com_err_status
+#define g_order_init gssint_g_order_init
+#define g_order_check gssint_g_order_check
+#define g_order_free gssint_g_order_free
+#define g_queue_size gssint_g_queue_size
+#define g_queue_externalize gssint_g_queue_externalize
+#define g_queue_internalize gssint_g_queue_internalize
+#define g_canonicalize_host gssint_g_canonicalize_host
+#define g_local_host_name gssint_g_local_host_name
+#define g_strdup gssint_g_strdup
+
typedef struct _g_set *g_set;
int g_set_init PROTOTYPE((g_set *s));
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
index 10cc4d7..ea7cb82 100644
--- a/src/lib/gssapi/generic/gssapi_generic.c
+++ b/src/lib/gssapi/generic/gssapi_generic.c
@@ -53,17 +53,111 @@
*/
static gss_OID_desc oids[] = {
- {10, "\052\206\110\206\367\022\001\002\001\001"},
- {10, "\052\206\110\206\367\022\001\002\001\002"},
- {10, "\052\206\110\206\367\022\001\002\001\003"},
- {10, "\052\206\110\206\367\022\001\002\001\004"},
- { 6, "\053\006\001\005\006\004"},
- { 6, "\053\006\001\005\006\002"},
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}. The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)). The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc. This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"},
+ /* corresponding to an object-identifier value of
+ * {iso(1) member-body(2) Unites States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) service_name(4)}.
+ * The constant GSS_C_NT_HOSTBASED_SERVICE should be
+ * initialized to point to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ /* corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}. The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+
+ /*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value */
+ {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ /* corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}. The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
};
-GSS_DLLIMP gss_OID gss_nt_user_name = oids+0;
-GSS_DLLIMP gss_OID gss_nt_machine_uid_name = oids+1;
-GSS_DLLIMP gss_OID gss_nt_string_uid_name = oids+2;
-GSS_DLLIMP gss_OID gss_nt_service_name = oids+3;
-GSS_DLLIMP gss_OID gss_nt_exported_name = oids+4;
-GSS_DLLIMP gss_OID gss_nt_service_name_v2 = oids+5;
+/* Here are the constants which point to the static structure above.
+ *
+ * Constants of the form GSS_C_NT_* are specified by rfc 2744.
+ *
+ * Constants of the form gss_nt_* are the original MIT krb5 names
+ * found in gssapi_generic.h. They are provided for compatibility. */
+
+#if GSS_RFC_COMPLIANT_OIDS
+GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = oids+0;
+GSS_DLLIMP gss_OID GSS_C_NT_MACHINE_UID_NAME = oids+1;
+GSS_DLLIMP gss_OID GSS_C_NT_STRING_UID_NAME = oids+2;
+GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = oids+3;
+GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE = oids+4;
+GSS_DLLIMP gss_OID GSS_C_NT_ANONYMOUS = oids+5;
+GSS_DLLIMP gss_OID GSS_C_NT_EXPORT_NAME = oids+6;
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
+GSS_DLLIMP gss_OID gss_nt_user_name = oids+0;
+GSS_DLLIMP gss_OID gss_nt_machine_uid_name = oids+1;
+GSS_DLLIMP gss_OID gss_nt_string_uid_name = oids+2;
+GSS_DLLIMP gss_OID gss_nt_service_name_v2 = oids+3;
+GSS_DLLIMP gss_OID gss_nt_service_name = oids+4;
+GSS_DLLIMP gss_OID gss_nt_exported_name = oids+6;
diff --git a/src/lib/gssapi/generic/gssapi_generic.h b/src/lib/gssapi/generic/gssapi_generic.h
index 8317cad..af85b7c 100644
--- a/src/lib/gssapi/generic/gssapi_generic.h
+++ b/src/lib/gssapi/generic/gssapi_generic.h
@@ -27,17 +27,21 @@
* $Id$
*/
-#if defined(__MWERKS__) || defined(applec) || defined(THINK_C)
-#include <gssapi.h>
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <GSS/gssapi.h>
#else
#include <gssapi/gssapi.h>
#endif
+/* Deprecated MIT krb5 oid names provided for compatibility.
+ * The correct oids (GSS_C_NT_USER_NAME, etc) from rfc 2744
+ * are defined in gssapi.h. */
+
GSS_DLLIMP extern gss_OID gss_nt_user_name;
GSS_DLLIMP extern gss_OID gss_nt_machine_uid_name;
GSS_DLLIMP extern gss_OID gss_nt_string_uid_name;
+GSS_DLLIMP extern gss_OID gss_nt_service_name_v2;
GSS_DLLIMP extern gss_OID gss_nt_service_name;
GSS_DLLIMP extern gss_OID gss_nt_exported_name;
-GSS_DLLIMP extern gss_OID gss_nt_service_name_v2;
#endif /* _GSSAPI_GENERIC_H_ */
diff --git a/src/lib/gssapi/krb5/3des.txt b/src/lib/gssapi/krb5/3des.txt
new file mode 100644
index 0000000..f39c6fc
--- /dev/null
+++ b/src/lib/gssapi/krb5/3des.txt
@@ -0,0 +1,274 @@
+CAT Working Group K. Raeburn
+Internet-draft MIT
+Category: June xx, 2000
+Updates: RFC 1964
+Document: draft-raeburn-gssapi-krb5-3des-XX.txt
+
+ Triple-DES Support for the Kerberos 5 GSSAPI Mechanism
+
+Status of this Memo
+
+ This document is an Internet-Draft and is in full conformance with
+ all provisions of Section 10 of RFC2026 [1]. Internet-Drafts are
+ working documents of the Internet Engineering Task Force (IETF),
+ its areas, and its working groups. Note that other groups may also
+ distribute working documents as Internet-Drafts. Internet-Drafts
+ are draft documents valid for a maximum of six months and may be
+ updated, replaced, or obsoleted by other documents at any time. It
+ is inappropriate to use Internet-Drafts as reference material or to
+ cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/ietf/1id-abstracts.txt
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html.
+
+1. Abstract
+
+ The MIT Kerberos 5 release version 1.2 includes support for
+ triple-DES with key derivation [KrbRev]. Recent work by the EFF
+ [EFF] has demonstrated the vulnerability of single-DES mechanisms
+ to brute-force attacks by sufficiently motivated and well-funded
+ parties.
+
+ The GSSAPI Kerberos 5 mechanism definition [GSSAPI-KRB5]
+ specifically enumerates encryption and checksum types,
+ independently of how such schemes may be used in Kerberos. In the
+ long run, a new Kerberos-based mechanism, which does not require
+ separately enumerating for the GSSAPI mechanism each of the various
+ encryption types defined by Kerberos, is a better approach.
+ Efforts to produce such a specification are under way.
+
+ In the interest of providing increased security in the near term,
+ however, MIT is adding support for triple-DES to the existing
+ mechanism implementation we ship, as described here.
+
+2. New Algorithm Identifiers
+
+ One new sealing algorithm is defined, for use in WRAP tokens:
+
+ 02 00 - DES3-KD
+
+ This algorithm uses triple-DES with key derivation, with a usage
+ value KG_USAGE_SEAL. Padding is still to 8-byte multiples, and the
+ IV for encrypting application data is zero.
+
+ One new signing algorithm is defined, for use in MIC, Wrap, and
+ Delete tokens:
+
+ 04 00 - HMAC SHA1 DES3-KD
+
+ This algorithm generates an HMAC using SHA-1 and a derived DES3 key
+ with usage KG_USAGE_SIGN, as (should be described) in [KrbRev].
+ [XXX: The current [KrbRev] description refers to out-of-date I-Ds
+ from Marc Horowitz. The text in [KrbRev] may be inadequate to
+ produce an interoperable implementation.]
+
+ The checksum size for this algorithm is 20 octets. See section 4.3
+ below for the use of checksum lengths of other than eight bytes.
+
+3. Key Derivation
+
+ For purposes of key derivation, we add three new usage values to the
+ list defined in [KrbRev]; one for signing messages, one for
+ sealing messages, and one for encrypting sequence numbers:
+
+ #define KG_USAGE_SEAL 22
+ #define KG_USAGE_SIGN 23
+ #define KG_USAGE_SEQ 24
+
+4. Adjustments to Previous Definitions
+
+4.1. Quality of Protection
+
+ The GSSAPI specification [GSSAPI] says that a zero QOP value
+ indicates the "default". The original specification for the
+ Kerberos 5 mechanism says that a zero QOP value (or a QOP value
+ with the appropriate bits clear) means DES encryption.
+
+ Rather than continue to force the use of plain DES when the
+ application doesn't use mechanism-specific QOP values, the better
+ choice appears to be to redefine the DES QOP value as some non-zero
+ value, and define a triple-DES value as well. Then a zero value
+ continues to imply the default, which would be triple-DES
+ protection when given a triple-DES session key.
+
+ Our values are:
+
+ GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 0x0004
+ /* SHA-1 checksum encrypted with key derivation */
+
+ GSS_KRB5_CONF_C_QOP_DES 0x0100
+ /* plain DES encryption */
+ GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200
+ /* triple-DES with key derivation */
+
+ Rather than open the question of whether to specify means for
+ deriving a key of one type given a key of another type, and the
+ security implications of whether to generate a long key from a
+ shorter one, our implementation will simply return an error if the
+ QOP value specified does not correspond to the session key type.
+
+ [XXX: Not implemented yet. Currently an error is reported for all
+ non-zero values. This should be changed before the release, so an
+ application can insist on getting no less than triple-DES
+ protection.]
+
+4.2. MIC Sequence Number Encryption
+
+ The sequence numbers are encrypted in the context key (as defined
+ in [GSSAPI-KRB5] -- this will be either the Kerberos session key or
+ asubkey provided by the context initiator), using whatever
+ encryption system is designated by the type of that context key.
+ The IV is formed from the first N bytes of the SGN_CKSUM field,
+ where N is the number of bytes needed for the IV. (With all
+ algorithms described here and in [GSSAPI-KRB5], the checksum is at
+ least as large as the IV.)
+
+4.3. Message Layout
+
+ Both MIC and Wrap tokens, as defined in [GSSAPI-KRB5], contain an
+ checksum field SGN_CKSUM. In [GSSAPI-KRB5], this field was
+ specified as being 8 bytes long. We now change this size to be
+ "defined by the checksum algorithm", and retroactively amend the
+ descriptions of all the checksum algorithms described in
+ [GSSAPI-KRB5] to explicitly specify 8-byte output. Application
+ data continues to immediately follow the checksum field in the Wrap
+ token.
+
+ The revised message descriptions are thus:
+
+ MIC:
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ 2..3 SGN_ALG Integrity algorithm indicator.
+ 4..7 Filler Contains ff ff ff ff
+ 8..15 SND_SEQ Sequence number field.
+ 16..s+15 SGN_CKSUM Checksum of "to-be-signed data",
+ calculated according to algorithm
+ specified in SGN_ALG field.
+
+ Wrap:
+
+ Byte no Name Description
+ 0..1 TOK_ID Identification field.
+ Tokens emitted by GSS_Wrap() contain
+ the hex value 02 01 in this field.
+ 2..3 SGN_ALG Checksum algorithm indicator.
+ 4..5 SEAL_ALG Sealing algorithm indicator.
+ 6..7 Filler Contains ff ff
+ 8..15 SND_SEQ Encrypted sequence number field.
+ 16..s+15 SGN_CKSUM Checksum of plaintext padded data,
+ calculated according to algorithm
+ specified in SGN_ALG field.
+ s+16..last Data encrypted or plaintext padded data
+
+ Where "s" indicates the size of the checksum.
+
+ As indicated above in section 2, we define the HMAC SHA1 DES3-KD
+ checksum algorithm to produce a 20-byte output, so encrypted data
+ begins at byte 36.
+
+5. Backwards Compatibility Considerations
+
+ The context initiator should request of the KDC credentials using
+ session-key cryptosystem types supported by that implementation; if
+ the only types returned by the KDC are not supported by the
+ mechanism implementation, it should indicate a failure. This may
+ seem obvious, but early implementations of both Kerberos and the
+ GSSAPI Kerberos mechanism supported only DES keys, so the
+ cryptosystem compatibility question was easy to overlook.
+
+ Under the current mechanism, no negotiation of algorithm types
+ occurs, so server-side (acceptor) implementations cannot request
+ that clients not use algorithm types not understood by the server.
+ However, administration of the server's Kerberos data has to be
+ done in communication with the KDC, and it is from the KDC that the
+ client will request credentials. The KDC could therefore be tasked
+ with limiting session keys for a given service to types actually
+ supported by the Kerberos and GSSAPI software on the server.
+
+ This does have a drawback for cases where a service principal name
+ is used both for GSSAPI-based and non-GSSAPI-based communication,
+ if the GSSAPI implementation does not understand triple-DES but the
+ Kerberos implementation does. It means that triple-DES session
+ keys cannot be issued for that service principal, which keeps the
+ protection of non-GSSAPI services weaker than necessary. However,
+ in the most recent MIT releases thus far, while triple-DES support
+ has been present, it has required additional work to enable, so it
+ should not be in use for many services.
+
+ It would also be possible to have clients attempt to get single-DES
+ session keys before trying to get triple-DES session keys, and have
+ the KDC refuse to issue the single-DES keys only for the most
+ critical of services, for which single-DES protection is considered
+ inadequate. However, that would eliminate the possibility of
+ connecting with the more secure cryptosystem to any service that
+ can be accessed with the weaker cryptosystem.
+
+ We have chosen to go with the former approach, putting the burden
+ on the KDC administration and gaining the best protection possible
+ for GSSAPI services, possibly at the cost of protection of
+ non-GSSAPI Kerberos services running earlier versions of the
+ software.
+ [XXX: Actually, we haven't entirely decided and cast it in stone
+ yet, it's just what I've implemented; it's easy to change.]
+
+6. Security Considerations
+
+ Various tradeoffs arise regarding the mixing of new and old
+ software, or GSSAPI-based and non-GSSAPI Kerberos authentication.
+ They are discussed in section 4.
+
+7. References
+
+ [EFF] Electronic Frontier Foundation, "Cracking DES: Secrets of
+ Encryption Research, Wiretap Politics, and Chip Design", O'Reilly &
+ Associates, Inc., May, 1998.
+
+ [GSSAPI] Linn, J., "Generic Security Service Application Program
+ Interface Version 2, Update 1", RFC 2743, January, 2000.
+
+ [GSSAPI-KRB5] Linn, J., "The Kerberos Version 5 GSS-API Mechanism",
+ RFC 1964, June, 1996.
+
+ [KrbRev] Neuman, C., Kohl, J., Ts'o, T., "The Kerberos Network
+ Authentication Service (V5)",
+ draft-ietf-cat-kerberos-revisions-05.txt, March 10, 2000.
+
+8. Author's Address
+
+ Kenneth Raeburn
+ Massachusetts Institute of Technology
+ 77 Massachusetts Avenue
+ Cambridge, MA 02139
+
+9. Full Copyright Statement
+
+ Copyright (C) The Internet Society (2000). All Rights Reserved.
+
+ This document and translations of it may be copied and furnished to
+ others, and derivative works that comment on or otherwise explain it
+ or assist in its implementation may be prepared, copied, published
+ and distributed, in whole or in part, without restriction of any
+ kind, provided that the above copyright notice and this paragraph
+ are included on all such copies and derivative works. However, this
+ document itself may not be modified in any way, such as by removing
+ the copyright notice or references to the Internet Society or other
+ Internet organizations, except as needed for the purpose of
+ developing Internet standards in which case the procedures for
+ copyrights defined in the Internet Standards process must be
+ followed, or as required to translate it into languages other than
+ English.
+
+ The limited permissions granted above are perpetual and will not be
+ revoked by the Internet Society or its successors or assigns.
+
+ This document and the information contained herein is provided on an
+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog
index 06639d4..3bffb7c 100644
--- a/src/lib/gssapi/krb5/ChangeLog
+++ b/src/lib/gssapi/krb5/ChangeLog
@@ -1,4 +1,152 @@
-2000-01-27 Ken Raeburn <raeburn@raeburn.org>
+2001-10-29 Miro Jurisic <meeroh@mit.edu>
+ * pullup from krb5-1-2 branch after krb5-1-2-2-bp
+ * add_cred.c (krb5_gss_add_cred): Added constness to some char*s to make
+ them compiler with strict compilers.
+ * gssapi_krb5.h, gssapi_krb5.c: Added oids from rfc 1964 using the
+ suggested names.
+ * gssapi_krb5.h: Added #include of KerberosSupport.h in case this header
+ is included by itself.
+ * disp-status.c, gssapiP_krb5.h, gssapi_krb5.h: Updated Mac OS #defines
+ and #includes for new header layout and Mac OS X frameworks
+
+2001-10-04 Tom Yu <tlyu@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): Ignore
+ unrecognized options properly. [krb5-libs/738]
+
+2001-10-01 Tom Yu <tlyu@mit.edu>
+
+ * accept_sec_context.c (rd_and_store_for_creds): Handle error
+ returns from krb5_rd_cred more sanely.
+
+2001-01-30 Ezra Peisach <epeisach@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): If an error
+ occurs after the auth_context is established, but before the
+ krb5_gss_ctx_id_rec is established, release our pointer to the
+ replay cache and invoke krb5_auth_con_free(). [krb5-libs/855]
+
+2000-09-19 Miro Jurisic <meeroh@mit.edu>
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context)
+ * acquire_cred.c (krb5_gss_acquire_cred)
+ * import_sec_context.c (krb5_gss_convert_static_mech_oid)
+ * init_sec_context.c (krb5_gss_init_sec_context)
+ * inq_cred.c (krb5_gss_inquire_cred)
+ Cast away constness from gss_OID where necessary to compile
+ with strict compilers
+
+2000-06-27 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): Add initial iteration of
+ krb5_get_credentials in order to differentiate between an actual
+ missing credential and merely a bad match based on enctype. This
+ was causing problems with kadmin.
+
+2000-06-09 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): The KDC as well as the
+ ccache may indicate that an enctype is not supported; reflect that
+ in the loop breakout condition.
+
+2000-06-07 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): Rework the enctype loop
+ again.
+
+ * accept_sec_context.c (krb5_gss_accept_sec_context): Remove
+ explicit check of mech OID against credential.
+
+2000-06-04 Tom Yu <tlyu@mit.edu>
+
+ * init_sec_context.c (get_credentials): Reverse sense of test;
+ break out of enctype loop if one succeeds.
+
+2000-06-03 Tom Yu <tlyu@mit.edu>
+
+ * util_crypt.c (kg_encrypt): Copy ivec, since c_encrypt() now
+ updates ivecs.
+ (kg_decrypt): Copy ivec, since c_decrypt() now updates ivecs.
+
+2000-06-02 Ken Raeburn <raeburn@mit.edu>
+
+ * init_sec_context.c (get_credentials): Don't check each enctype
+ against a list from the krb5 library; instead, just try to use it,
+ and go on to the next if the error code indicates we can't use it.
+
+2000-05-31 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_krb5.h (KG_USAGE_SEQ): New value.
+ (enum qop): New type, derived from spec but currently not used.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Added key derivation
+ usage value as an argument. Prototypes and callers updated; all
+ callers use KG_USAGE_SEAL, except KG_USAGE_SEQ when encrypting
+ sequence numbers.
+ * 3des.txt: New file.
+
+2000-5-19 Alexandra Ellwood <lxs@mit.edu>
+
+ * acquire_cred.c: Changed to use krb5int_cc_default. This function
+ supports the Kerberos Login Library and pops up a dialog if the cache does
+ not contain valid tickets. This is used to automatically get a tgt before
+ obtaining service tickets. Note that this should be an internal function
+ because callers don't expect krb5_cc_default to pop up a dialog!
+ (We found this out the hard way :-)
+
+2000-05-03 Nalin Dahyabhai <nalin@redhat.com>
+
+ * add_cred.c (krb5_gss_add_cred): Don't overflow buffers "ktboth"
+ or "ccboth".
+
+2000-04-21 Ken Raeburn <raeburn@mit.edu>
+
+ * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Delete field
+ gsskrb5_version.
+ (struct _krb5_gss_cred_id_rec): Delete field rfcv2_mech.
+ * accept_sec_context.c, acquire_cred.c, add_cred.c, inq_cred.c,
+ k5seal.c, k5unseal.c, ser_ctx.c:
+ Delete krb5-mech2 support.
+
+ * init_sec_context.c (get_credentials): Enctype argument is now a
+ pointer to a list of enctypes. Explicitly try each in order until
+ success or an error other than cryptosystem not being supported.
+ (krb5_gss_init_sec_context): Pass list of cryptosystems, starting
+ with 3DES.
+
+ * gssapiP_krb5.h (enum sgn_alg, enum seal_alg): New types,
+ giving symbolic names for values from RFC 1964, a Microsoft win2k
+ I-D, and our proposed 3des-sha1 values.
+ (KG_USAGE_SEAL, KG_USAGE_SIGN): New macros.
+
+ * accept_sec_context.c (rd_req_keyproc): Already-disabled routine
+ deleted.
+ (krb5_gss_accept_sec_context): Use sgn_alg and seal_alg symbolic
+ names. Add a case for des3-hmac-sha1.
+ * k5seal.c (make_seal_token_v1): Likewise. Do key derivation for
+ checksums.
+ * k5unseal.c (kg_unseal_v1): Likewise.
+ * util_crypt.c (kg_encrypt, kg_decrypt): Do key derivation for
+ encryption.
+
+ * util_crypt.c (zeros): Unused variable deleted.
+
+2000-04-18 Ken Raeburn <raeburn@mit.edu>
+
+ * wrap_size_limit.c: Remove mech2 support. Add MIT copyright.
+
+2000-04-08 Tom Yu <tlyu@mit.edu>
+
+ * wrap_size_limit.c (krb5_gss_wrap_size_limit): Fix up
+ wrap_size_limit() to deal with integrity wrap tokens properly.
+ The rfc1964 mech always pads and confounds regardless of whether
+ confidentiality is requested.
+
+2000-03-20 Ken Raeburn <raeburn@mit.edu>
+
+ * accept_sec_context.c, init_sec_context.c: Disable krb5-mech2
+ stuff for now. (Tom Yu's krb5-1.1 patch.)
+
+2000-01-27 Ken Raeburn <raeburn@mit.edu>
* init_sec_context.c (krb5_gss_init_sec_context): Default to
des-cbc-crc.
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index fc920ec..ba2d96a 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -49,39 +73,12 @@
#include "k5-int.h"
#include "gssapiP_krb5.h"
#include <memory.h>
+#include <assert.h>
/*
* $Id$
*/
-#if 0
-
-/* XXXX This widen/narrow stuff is bletcherous, but it seems to be
- necessary. Perhaps there is a "better" way, but I don't know what it
- is */
-
-#include <krb5/widen.h>
-static krb5_error_code
-rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server,
- krb5_kvno kvno, krb5_keyblock **keyblock)
-#include <krb5/narrow.h>
-{
- krb5_error_code code;
- krb5_keytab_entry ktentry;
-
- if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno,
- &ktentry))
- return(code);
-
- code = krb5_copy_keyblock(&ktentry.key, keyblock);
-
- (void) krb5_kt_free_entry(&ktentry);
-
- return(code);
-}
-
-#endif
-
/* Decode, decrypt and store the forwarded creds in the local ccache. */
static krb5_error_code
rd_and_store_for_creds(context, inbuf, out_cred)
@@ -89,9 +86,9 @@ rd_and_store_for_creds(context, inbuf, out_cred)
krb5_data *inbuf;
krb5_gss_cred_id_t *out_cred;
{
- krb5_creds ** creds;
+ krb5_creds ** creds = NULL;
krb5_error_code retval;
- krb5_ccache ccache;
+ krb5_ccache ccache = NULL;
krb5_gss_cred_id_t cred = NULL;
extern krb5_cc_ops krb5_mcc_ops;
krb5_auth_context auth_context = NULL;
@@ -145,7 +142,6 @@ rd_and_store_for_creds(context, inbuf, out_cred)
/* cred->princ already set */
cred->prerfc_mech = 1; /* this cred will work with all three mechs */
cred->rfc_mech = 1;
- cred->rfcv2_mech = 1;
cred->keytab = NULL; /* no keytab associated with this... */
cred->ccache = ccache; /* but there is a credential cache */
cred->tgt_expire = creds[0]->times.endtime; /* store the end time */
@@ -157,7 +153,8 @@ rd_and_store_for_creds(context, inbuf, out_cred)
goto cleanup;
*/
cleanup:
- krb5_free_tgt_creds(context, creds);
+ if (creds)
+ krb5_free_tgt_creds(context, creds);
if (!cred && ccache)
(void)krb5_cc_close(context, ccache);
@@ -206,11 +203,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
krb5_ui_4 gss_flags = 0;
int decode_req_message = 0;
krb5_gss_ctx_id_rec *ctx = 0;
-#if 0
krb5_enctype enctype;
-#endif
krb5_timestamp now;
gss_buffer_desc token;
+ int err;
krb5_auth_context auth_context = NULL;
krb5_ticket * ticket = NULL;
int option_id;
@@ -222,7 +218,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
gss_cred_id_t cred_handle = NULL;
krb5_gss_cred_id_t deleg_cred = NULL;
int token_length;
- int gsskrb5_vers;
int nctypes;
krb5_cksumtype *ctypes = 0;
struct kg2_option fwcred;
@@ -296,13 +291,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
&(ap_req.length),
&ptr, KG_TOK_CTX_AP_REQ,
input_token->length))) {
- if (! cred->rfc_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
mech_used = gss_mech_krb5;
- gsskrb5_vers = 1000;
} else if ((code == G_WRONG_MECH) &&
!(code = g_verify_token_header((gss_OID) gss_mech_krb5_old,
&(ap_req.length),
@@ -315,56 +304,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
* compatibility, and use it to decide when to use the
* old behavior.
*/
- if (! cred->prerfc_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
mech_used = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- } else if ((code == G_WRONG_MECH) &&
- !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2,
- &token_length,
- &ptr, KG2_TOK_INITIAL,
- input_token->length))) {
- if (! cred->rfcv2_mech) {
- code = G_WRONG_MECH;
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
- mech_used = gss_mech_krb5_v2;
- gsskrb5_vers = 2000;
} else {
major_status = GSS_S_DEFECTIVE_TOKEN;
goto fail;
}
- if (gsskrb5_vers == 2000) {
- /* gss krb5 v2 */
-
- fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION;
- fwcred.data = NULL;
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(&code, ptr, token_length,
- &gss_flags, &nctypes, &ctypes,
- delegated_cred_handle?1:0,
- &fwcred, &ap_req, NULL))) {
- goto fail;
- }
-
- gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3];
-
- gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag;
- if there's a delegation, we'll
- set it below */
- } else {
- /* gss krb5 v1 */
-
- sptr = (char *) ptr;
- TREAD_STR(sptr, ap_req.data, ap_req.length);
- decode_req_message = 1;
- }
+ sptr = (char *) ptr;
+ TREAD_STR(sptr, ap_req.data, ap_req.length);
+ decode_req_message = 1;
/* construct the sender_addr */
@@ -416,9 +364,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
#endif
- if (gsskrb5_vers == 2000) {
- bigend = 1;
- } else {
+ {
/* gss krb5 v1 */
/* stash this now, for later. */
@@ -502,21 +448,31 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
i = authdat->checksum->length - 24;
- while(i>0) {
+ while (i >= 4) {
TREAD_INT16(ptr, option_id, bigend);
- switch(option_id) {
+ TREAD_INT16(ptr, option.length, bigend);
- case KRB5_GSS_FOR_CREDS_OPTION:
+ i -= 4;
+
+ /* have to use ptr2, since option.data is wrong type and
+ macro uses ptr as both lvalue and rvalue */
- TREAD_INT16(ptr, option.length, bigend);
+ if (i < option.length || option.length < 0) {
+ code = KG_BAD_LENGTH;
+ major_status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ TREAD_STR(ptr, ptr2, bigend);
+ option.data = (char FAR *) ptr2;
- /* have to use ptr2, since option.data is wrong type and
- macro uses ptr as both lvalue and rvalue */
+ i -= option.length;
- TREAD_STR(ptr, ptr2, bigend);
- option.data = (char FAR *) ptr2;
+ switch(option_id) {
+
+ case KRB5_GSS_FOR_CREDS_OPTION:
/* store the delegated credential */
@@ -527,8 +483,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- i -= option.length + 4;
-
gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */
break;
@@ -551,13 +505,12 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
}
memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
- ctx->mech_used = mech_used;
+ ctx->mech_used = (gss_OID) mech_used;
ctx->auth_context = auth_context;
ctx->initiate = 0;
ctx->gss_flags = KG_IMPLFLAGS(gss_flags);
ctx->seed_init = 0;
ctx->big_endian = bigend;
- ctx->gsskrb5_version = gsskrb5_vers;
/* Intern the ctx pointer so that delete_sec_context works */
if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) {
@@ -603,114 +556,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- if (gsskrb5_vers == 2000) {
- int cblen;
- krb5_boolean valid;
-
- /* intersect the token ctypes with the local ctypes */
-
- if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype,
- &ctx->nctypes, &ctx->ctypes))
- goto fail;
-
- if (nctypes == 0) {
- code = KRB5_CRYPTO_INTERNAL;
- goto fail;
- }
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
-
- if (nctypes == 0) {
- code = KG_NO_CTYPES;
- goto fail;
- }
-
- /* process the delegated cred, if any */
-
- if (fwcred.data) {
- krb5_data option;
-
- option.length = fwcred.length;
- option.data = fwcred.data;
-
- if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */
- }
+ switch(ctx->subkey->enctype) {
+ case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_CRC:
+ ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
+ ctx->cksum_size = 8;
+ ctx->sealalg = SEAL_ALG_DES;
- /* construct the checksum buffer */
-
- cblen = 4*5;
- if (input_chan_bindings)
- cblen += (input_chan_bindings->initiator_address.length+
- input_chan_bindings->acceptor_address.length+
- input_chan_bindings->application_data.length);
-
- cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2));
+ /* fill in the encryption descriptors */
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- ptr2 = cksumdata.data;
-
- if (input_chan_bindings) {
- TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1);
- TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1);
- TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1);
- } else {
- memset(ptr2, 0, cblen);
- ptr2 += cblen;
- }
-
- memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2)));
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &cksumdata, authdat->checksum,
- &valid)) {
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
- free(cksumdata.data);
- cksumdata.data = 0;
-
- if (!valid) {
- code = 0;
- major_status = GSS_S_BAD_SIG;
- goto fail;
- }
- } else {
- /* gss krb5 v1 */
+ break;
- switch(ctx->subkey->enctype) {
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES_CBC_CRC:
- ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
- ctx->cksum_size = 8;
- ctx->sealalg = 0;
- break;
-#if 0
- case ENCTYPE_DES3_CBC_MD5:
- enctype = ENCTYPE_DES3_CBC_RAW;
- ctx->signalg = 3;
- ctx->cksum_size = 16;
- ctx->sealalg = 1;
- break;
-#endif
- default:
- code = KRB5_BAD_ENCTYPE;
- goto fail;
- }
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
/* fill in the encryption descriptors */
@@ -719,14 +595,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
goto fail;
}
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) {
major_status = GSS_S_FAILURE;
goto fail;
}
+
+ break;
+
+ default:
+ code = KRB5_BAD_ENCTYPE;
+ goto fail;
}
ctx->endtime = ticket->enc_part2->times.endtime;
@@ -769,122 +647,22 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
/* the reply token hasn't been sent yet, but that's ok. */
ctx->established = 1;
- if (ctx->gsskrb5_version == 2000) {
- krb5_ui_4 tok_flags;
-
- tok_flags =
- (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0;
-
- cksumdata.length = 8 + 4*ctx->nctypes + 4;
-
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) {
- code = ENOMEM;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /* construct the token fields */
-
- ptr = cksumdata.data;
-
- ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff;
- ptr[1] = KG2_TOK_RESPONSE & 0xff;
-
- ptr[2] = (tok_flags >> 24) & 0xff;
- ptr[3] = (tok_flags >> 16) & 0xff;
- ptr[4] = (tok_flags >> 8) & 0xff;
- ptr[5] = tok_flags & 0xff;
-
- ptr[6] = (ctx->nctypes >> 8) & 0xff;
- ptr[7] = ctx->nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<ctx->nctypes; i++) {
- ptr[i] = (ctx->ctypes[i] >> 24) & 0xff;
- ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff;
- ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff;
- ptr[i+3] = ctx->ctypes[i] & 0xff;
-
- ptr += 4;
- }
-
- memset(ptr, 0, 4);
-
- /* make the MIC token */
+ token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
- {
- gss_buffer_desc text, token;
-
- text.length = cksumdata.length;
- text.value = cksumdata.data;
-
- /* ctx->seq_send must be set before this call */
-
- if (GSS_ERROR(major_status =
- krb5_gss_get_mic(&code, ctx,
- GSS_C_QOP_DEFAULT,
- &text, &token)))
- goto fail;
-
- mic.length = token.length;
- mic.data = token.value;
- }
-
- token.length = g_token_size((gss_OID) mech_used,
- (cksumdata.length-2)+4+ap_rep.length+
- mic.length);
-
- if ((token.value = (unsigned char *) xmalloc(token.length))
- == NULL) {
- code = ENOMEM;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
- ptr = token.value;
- g_make_token_header((gss_OID) mech_used,
- (cksumdata.length-2)+4+ap_rep.length+mic.length,
- &ptr, KG2_TOK_RESPONSE);
-
- memcpy(ptr, cksumdata.data+2, cksumdata.length-2);
- ptr += cksumdata.length-2;
-
- ptr[0] = (ap_rep.length >> 8) & 0xff;
- ptr[1] = ap_rep.length & 0xff;
- memcpy(ptr+2, ap_rep.data, ap_rep.length);
-
- ptr += (2+ap_rep.length);
-
- ptr[0] = (mic.length >> 8) & 0xff;
- ptr[1] = mic.length & 0xff;
- memcpy(ptr+2, mic.data, mic.length);
-
- ptr += (2+mic.length);
-
- free(cksumdata.data);
- cksumdata.data = 0;
-
- /* gss krb5 v2 */
- } else {
- /* gss krb5 v1 */
-
- token.length = g_token_size((gss_OID) mech_used, ap_rep.length);
-
- if ((token.value = (unsigned char *) xmalloc(token.length))
- == NULL) {
- major_status = GSS_S_FAILURE;
- code = ENOMEM;
- goto fail;
- }
- ptr = token.value;
- g_make_token_header((gss_OID) mech_used, ap_rep.length,
- &ptr, KG_TOK_CTX_AP_REP);
+ if ((token.value = (unsigned char *) xmalloc(token.length))
+ == NULL) {
+ major_status = GSS_S_FAILURE;
+ code = ENOMEM;
+ goto fail;
+ }
+ ptr = token.value;
+ g_make_token_header((gss_OID) mech_used, ap_rep.length,
+ &ptr, KG_TOK_CTX_AP_REP);
- TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
+ TWRITE_STR(ptr, ap_rep.data, ap_rep.length);
- ctx->established = 1;
+ ctx->established = 1;
- }
} else {
token.length = 0;
token.value = NULL;
@@ -943,6 +721,11 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
free(ctypes);
if (authdat)
krb5_free_authenticator(context, authdat);
+ /* The ctx structure has the handle of the auth_context */
+ if (auth_context && !ctx) {
+ (void)krb5_auth_con_setrcache(context, auth_context, NULL);
+ krb5_auth_con_free(context, auth_context);
+ }
if (reqcksum.contents)
xfree(reqcksum.contents);
if (ap_rep.data)
@@ -1014,13 +797,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
if (code)
return (major_status);
- if (gsskrb5_vers == 2000) {
- tmsglen = 12+scratch.length;
- toktype = KG2_TOK_RESPONSE;
- } else {
- tmsglen = scratch.length;
- toktype = KG_TOK_CTX_ERROR;
- }
+ tmsglen = scratch.length;
+ toktype = KG_TOK_CTX_ERROR;
token.length = g_token_size((gss_OID) mech_used, tmsglen);
token.value = (unsigned char *) xmalloc(token.length);
@@ -1030,24 +808,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle,
ptr = token.value;
g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype);
- if (gsskrb5_vers == 2000) {
- krb5_ui_4 flags;
-
- flags = KG2_RESP_FLAG_ERROR;
-
- ptr[0] = (flags << 24) & 0xff;
- ptr[1] = (flags << 16) & 0xff;
- ptr[2] = (flags << 8) & 0xff;
- ptr[3] = flags & 0xff;
-
- memset(ptr+4, 0, 6);
-
- ptr[10] = (scratch.length << 8) & 0xff;
- ptr[11] = scratch.length & 0xff;
-
- ptr += 12;
- }
-
TWRITE_STR(ptr, scratch.data, scratch.length);
xfree(scratch.data);
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index b67eb4f..c2921f2 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -154,7 +178,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred)
/* open the default credential cache */
- if ((code = krb5_cc_default(context, &ccache))) {
+ if ((code = krb5int_cc_default(context, &ccache))) {
*minor_status = code;
return(GSS_S_CRED_UNAVAIL);
}
@@ -283,7 +307,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
size_t i;
krb5_gss_cred_id_t cred;
gss_OID_set ret_mechs;
- int req_old, req_new, req_v2;
+ int req_old, req_new;
OM_uint32 ret;
krb5_error_code code;
@@ -313,22 +337,18 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
if (desired_mechs == GSS_C_NULL_OID_SET) {
req_old = 1;
req_new = 1;
- req_v2 = 1;
} else {
req_old = 0;
req_new = 0;
- req_v2 = 0;
for (i=0; i<desired_mechs->count; i++) {
if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i])))
req_old++;
if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i])))
req_new++;
- if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i])))
- req_v2++;
}
- if (!req_old && !req_new && !req_v2) {
+ if (!req_old && !req_new) {
*minor_status = 0;
return(GSS_S_BAD_MECH);
}
@@ -347,7 +367,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
cred->princ = NULL;
cred->prerfc_mech = req_old;
cred->rfc_mech = req_new;
- cred->rfcv2_mech = req_v2;
cred->keytab = NULL;
cred->ccache = NULL;
@@ -442,15 +461,11 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req,
&ret_mechs)) ||
(cred->prerfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_old,
+ (gss_OID) gss_mech_krb5_old,
&ret_mechs))) ||
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5,
- &ret_mechs))) ||
- (cred->rfcv2_mech &&
- GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_v2,
+ (gss_OID) gss_mech_krb5,
&ret_mechs)))) {
if (cred->ccache)
(void)krb5_cc_close(context, cred->ccache);
diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c
index 2a6fdb4..a13ba52 100644
--- a/src/lib/gssapi/krb5/add_cred.c
+++ b/src/lib/gssapi/krb5/add_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright (C) 1998 by the FundsXpress, INC.
*
* All rights reserved.
@@ -110,8 +134,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* check that desired_mech isn't already in the credential */
if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) ||
- (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) ||
- (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) {
+ (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) {
*minor_status = 0;
return(GSS_S_DUPLICATE_ELEMENT);
}
@@ -143,7 +166,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
/* make a copy */
krb5_gss_cred_id_t new_cred;
char *kttype, ktboth[1024];
- char *cctype, *ccname, ccboth[1024];
+ char ccboth[1024];
+ const char *ccname;
+ const char *cctype;
if ((new_cred =
(krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec)))
@@ -156,7 +181,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
new_cred->usage = cred_usage;
new_cred->prerfc_mech = cred->prerfc_mech;
new_cred->rfc_mech = cred->rfc_mech;
- new_cred->rfcv2_mech = cred->rfcv2_mech;
new_cred->tgt_expire = cred->tgt_expire;
if (code = krb5_copy_principal(context, cred->princ,
@@ -177,8 +201,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ktboth, kttype);
- strcat(ktboth, ":");
+ strncpy(ktboth, kttype, sizeof(ktboth) - 1);
+ ktboth[sizeof(ktboth) - 1] = '\0';
+ strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth));
if (code = krb5_kt_get_name(context, cred->keytab,
ktboth+strlen(ktboth),
@@ -234,9 +259,10 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
return(GSS_S_FAILURE);
}
- strcpy(ccboth, cctype);
- strcat(ccboth, ":");
- strcat(ccboth, ccname);
+ strncpy(ccboth, cctype, sizeof(ccboth) - 1);
+ ccboth[sizeof(ccboth) - 1] = '\0';
+ strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth));
+ strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth));
if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) {
if (new_cred->rcache)
@@ -280,8 +306,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle,
cred->prerfc_mech = 1;
else if (g_OID_equal(desired_mech, gss_mech_krb5))
cred->rfc_mech = 1;
- else if (g_OID_equal(desired_mech, gss_mech_krb5_v2))
- cred->rfcv2_mech = 1;
/* set the outputs */
diff --git a/src/lib/gssapi/krb5/disp_status.c b/src/lib/gssapi/krb5/disp_status.c
index 3a6ba7b..0229296 100644
--- a/src/lib/gssapi/krb5/disp_status.c
+++ b/src/lib/gssapi/krb5/disp_status.c
@@ -21,7 +21,12 @@
*/
#include "gssapiP_krb5.h"
+
+#if TARGET_OS_MAC
+#include <KerberosComErr/KerberosComErr.h>
+#else
#include "com_err.h"
+#endif
/* XXXX internationalization!! */
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index e344b4f..080176b 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -27,7 +51,12 @@
* $Id$
*/
+#if TARGET_OS_MAC
+#include <Kerberos5/Kerberos5.h>
+#else
#include <krb5.h>
+#endif
+
#include <memory.h>
/* work around sunos braindamage */
@@ -79,6 +108,39 @@
#define KG2_RESP_FLAG_ERROR 0x0001
#define KG2_RESP_FLAG_DELEG_OK 0x0002
+/* These are to be stored in little-endian order, i.e., des-mac is
+ stored as 02 00. */
+enum sgn_alg {
+ SGN_ALG_DES_MAC_MD5 = 0x0000,
+ SGN_ALG_MD2_5 = 0x0001,
+ SGN_ALG_DES_MAC = 0x0002,
+ SGN_ALG_3 = 0x0003, /* not published */
+ SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
+ SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
+};
+enum seal_alg {
+ SEAL_ALG_NONE = 0xffff,
+ SEAL_ALG_DES = 0x0000,
+ SEAL_ALG_1 = 0x0001, /* not published */
+ SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */
+ SEAL_ALG_DES3KD = 0x0002
+};
+
+#define KG_USAGE_SEAL 22
+#define KG_USAGE_SIGN 23
+#define KG_USAGE_SEQ 24
+
+enum qop {
+ GSS_KRB5_INTEG_C_QOP_MD5 = 0x0001, /* *partial* MD5 = "MD2.5" */
+ GSS_KRB5_INTEG_C_QOP_DES_MD5 = 0x0002,
+ GSS_KRB5_INTEG_C_QOP_DES_MAC = 0x0003,
+ GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 = 0x0004,
+ GSS_KRB5_INTEG_C_QOP_MASK = 0x00ff,
+ GSS_KRB5_CONF_C_QOP_DES = 0x0100,
+ GSS_KRB5_CONF_C_QOP_DES3_KD = 0x0200,
+ GSS_KRB5_CONF_C_QOP_MASK = 0xff00
+};
+
/** internal types **/
typedef krb5_principal krb5_gss_name_t;
@@ -89,7 +151,6 @@ typedef struct _krb5_gss_cred_id_rec {
krb5_principal princ; /* this is not interned as a gss_name_t */
int prerfc_mech;
int rfc_mech;
- int rfcv2_mech;
/* keytab (accept) data */
krb5_keytab keytab;
@@ -125,7 +186,6 @@ typedef struct _krb5_gss_ctx_id_rec {
int big_endian;
krb5_auth_context auth_context;
gss_OID_desc *mech_used;
- int gsskrb5_version;
int nctypes;
krb5_cksumtype *ctypes;
} krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t;
@@ -190,12 +250,18 @@ int kg_encrypt_size PROTOTYPE((krb5_context context,
krb5_keyblock *key, int n));
krb5_error_code kg_encrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
krb5_error_code kg_decrypt PROTOTYPE((krb5_context context,
- krb5_keyblock *key,
- krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length));
+ krb5_keyblock *key, int usage,
+ krb5_pointer iv,
+ krb5_pointer in,
+ krb5_pointer out,
+ int length));
OM_uint32 kg_seal PROTOTYPE((krb5_context context,
OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index e700bb8..5f84b59 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -90,16 +90,28 @@ const gss_OID_desc krb5_gss_oid_array[] = {
/* this is the v2 assigned OID */
{9, "\052\206\110\206\367\022\001\002\003"},
/* these two are name type OID's */
+
+ /* 2.1.1. Kerberos Principal Name Form: (rfc 1964)
+ * This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
{10, "\052\206\110\206\367\022\001\002\002\001"},
+
+ /* gss_nt_krb5_principal. Object identifier for a krb5_principal. Do not use. */
{10, "\052\206\110\206\367\022\001\002\002\002"},
{ 0, 0 }
};
-const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0;
-const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1;
-const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2;
-const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+3;
-const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4;
+const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0;
+const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1;
+const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2;
+const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+3;
+const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4;
+#if GSS_RFC_COMPLIANT_OIDS
+const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+3;
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
static const gss_OID_set_desc oidsets[] = {
{1, (gss_OID) krb5_gss_oid_array+0},
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.h b/src/lib/gssapi/krb5/gssapi_krb5.h
index e4bac76..8995924 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.h
+++ b/src/lib/gssapi/krb5/gssapi_krb5.h
@@ -23,13 +23,63 @@
#ifndef _GSSAPI_KRB5_H_
#define _GSSAPI_KRB5_H_
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+ #include <KerberosSupport/KerberosSupport.h>
+#endif
+
+#if TARGET_OS_MAC
+#include <Kerberos5/Kerberos5.h>
+#else
#include <krb5.h>
+#endif
/* C++ friendlyness */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
+#if GSS_RFC_COMPLIANT_OIDS
+/* Reserved static storage for GSS_oids. See rfc 1964 for more details. */
+
+/* 2.1.1. Kerberos Principal Name Form: */
+GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME;
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}. The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
+
+/* 2.1.2. Host-Based Service Name Form */
+#define GSS_KRB5_NT_HOSTBASED_SERVICE_NAME GSS_C_NT_HOSTBASED_SERVICE
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}. The previously recommended symbolic
+ * name for this type is "GSS_KRB5_NT_HOSTBASED_SERVICE_NAME". The
+ * currently preferred symbolic name for this type is
+ * "GSS_C_NT_HOSTBASED_SERVICE". */
+
+/* 2.2.1. User Name Form */
+#define GSS_KRB5_NT_USER_NAME GSS_C_NT_USER_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) user_name(1)}. The recommended symbolic name for this
+ * type is "GSS_KRB5_NT_USER_NAME". */
+
+/* 2.2.2. Machine UID Form */
+#define GSS_KRB5_NT_MACHINE_UID_NAME GSS_C_NT_MACHINE_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) machine_uid_name(2)}. The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". */
+
+/* 2.2.3. String UID Form */
+#define GSS_KRB5_NT_STRING_UID_NAME GSS_C_NT_STRING_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) string_uid_name(3)}. The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_STRING_UID_NAME". */
+
+#endif /* GSS_RFC_COMPLIANT_OIDS */
+
extern const gss_OID_desc * const gss_mech_krb5;
extern const gss_OID_desc * const gss_mech_krb5_old;
extern const gss_OID_desc * const gss_mech_krb5_v2;
diff --git a/src/lib/gssapi/krb5/import_sec_context.c b/src/lib/gssapi/krb5/import_sec_context.c
index fd5415a..659cdc2 100644
--- a/src/lib/gssapi/krb5/import_sec_context.c
+++ b/src/lib/gssapi/krb5/import_sec_context.c
@@ -44,7 +44,7 @@ gss_OID krb5_gss_convert_static_mech_oid(oid)
if ((oid->length == p->length) &&
(memcmp(oid->elements, p->elements, p->length) == 0)) {
gss_release_oid(&minor_status, &oid);
- return p;
+ return (gss_OID) p;
}
}
return oid;
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index d0c8bc9..8cc1294 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -49,6 +73,7 @@
#include "gssapiP_krb5.h"
#include <memory.h>
#include <stdlib.h>
+#include <assert.h>
/*
* $Id$
@@ -63,17 +88,18 @@ int krb5_gss_dbg_client_expcreds = 0;
* ccache.
*/
static krb5_error_code get_credentials(context, cred, server, now,
- endtime, enctype, out_creds)
+ endtime, enctypes, out_creds)
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_principal server;
krb5_timestamp now;
krb5_timestamp endtime;
- krb5_enctype enctype;
+ const krb5_enctype *enctypes;
krb5_creds **out_creds;
{
krb5_error_code code;
krb5_creds in_creds;
+ int i;
memset((char *) &in_creds, 0, sizeof(krb5_creds));
@@ -82,10 +108,15 @@ static krb5_error_code get_credentials(context, cred, server, now,
if ((code = krb5_copy_principal(context, server, &in_creds.server)))
goto cleanup;
in_creds.times.endtime = endtime;
- in_creds.keyblock.enctype = enctype;
- if ((code = krb5_get_credentials(context, 0, cred->ccache,
- &in_creds, out_creds)))
+ in_creds.keyblock.enctype = 0;
+
+ code = krb5_set_default_tgs_enctypes (context, enctypes);
+ if (code)
+ goto cleanup;
+ code = krb5_get_credentials(context, 0, cred->ccache,
+ &in_creds, out_creds);
+ if (code)
goto cleanup;
/*
@@ -93,7 +124,8 @@ static krb5_error_code get_credentials(context, cred, server, now,
* boundaries) because accept_sec_context code is also similarly
* non-forgiving.
*/
- if (!krb5_gss_dbg_client_expcreds && (*out_creds)->times.endtime < now) {
+ if (!krb5_gss_dbg_client_expcreds && *out_creds != NULL &&
+ (*out_creds)->times.endtime < now) {
code = KRB5KRB_AP_ERR_TKT_EXPIRED;
goto cleanup;
}
@@ -117,196 +149,8 @@ make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token)
gss_OID mech_type;
gss_buffer_t token;
{
- krb5_flags mk_req_flags = 0;
- krb5_int32 con_flags;
- krb5_error_code code;
- krb5_data credmsg, cksumdata, ap_req;
- int i, tlen, cblen, nctypes;
- krb5_cksumtype *ctypes;
- unsigned char *t, *ptr;
-
- credmsg.data = 0;
- cksumdata.data = 0;
- ap_req.data = 0;
- ctypes = 0;
-
- /* create the option data if necessary */
- if (ctx->gss_flags & GSS_C_DELEG_FLAG) {
- /* first get KRB_CRED message, so we know its length */
-
- /* clear the time check flag that was set in krb5_auth_con_init() */
- krb5_auth_con_getflags(context, ctx->auth_context, &con_flags);
- krb5_auth_con_setflags(context, ctx->auth_context,
- con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME);
-
- code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0,
- cred->princ, ctx->there, cred->ccache, 1,
- &credmsg);
-
- /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */
- krb5_auth_con_setflags(context, ctx->auth_context, con_flags);
-
- if (code) {
- /* don't fail here; just don't accept/do the delegation
- request */
- ctx->gss_flags &= ~GSS_C_DELEG_FLAG;
- } else {
- if (credmsg.length > KRB5_INT16_MAX) {
- krb5_free_data_contents(context, &credmsg);
- return(KRB5KRB_ERR_FIELD_TOOLONG);
- }
- }
- } else {
- credmsg.length = 0;
- }
-
- /* construct the list of compatible cksum types */
-
- if ((code = krb5_c_keyed_checksum_types(context,
- k_cred->keyblock.enctype,
- &nctypes, &ctypes)))
- goto cleanup;
-
- if (nctypes == 0) {
- code = KRB5_CRYPTO_INTERNAL;
- goto cleanup;
- }
-
- /* construct the checksum fields */
-
- cblen = 4*5;
- if (chan_bindings)
- cblen += (chan_bindings->initiator_address.length+
- chan_bindings->acceptor_address.length+
- chan_bindings->application_data.length);
-
- cksumdata.length = cblen + 8 + 4*nctypes + 4;
- if (credmsg.length)
- cksumdata.length += 4 + credmsg.length;
-
- if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL)
- goto cleanup;
-
- /* helper macros. This code currently depends on a long being 32
- bits, and htonl dtrt. */
-
- ptr = cksumdata.data;
-
- if (chan_bindings) {
- TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1);
- TWRITE_BUF(ptr, chan_bindings->initiator_address, 1);
- TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1);
- TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1);
- TWRITE_BUF(ptr, chan_bindings->application_data, 1);
- } else {
- memset(ptr, 0, cblen);
- ptr += cblen;
- }
-
- /* construct the token fields */
-
- ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff;
- ptr[1] = KG2_TOK_INITIAL & 0xff;
-
- ptr[2] = (ctx->gss_flags >> 24) & 0xff;
- ptr[3] = (ctx->gss_flags >> 16) & 0xff;
- ptr[4] = (ctx->gss_flags >> 8) & 0xff;
- ptr[5] = ctx->gss_flags & 0xff;
-
- ptr[6] = (nctypes >> 8) & 0xff;
- ptr[7] = nctypes & 0xff;
-
- ptr += 8;
-
- for (i=0; i<nctypes; i++) {
- ptr[0] = (ctypes[i] >> 24) & 0xff;
- ptr[1] = (ctypes[i] >> 16) & 0xff;
- ptr[2] = (ctypes[i] >> 8) & 0xff;
- ptr[3] = ctypes[i] & 0xff;
-
- ptr += 4;
- }
-
- if (credmsg.length) {
- ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff;
- ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff;
-
- ptr[2] = (credmsg.length >> 8) & 0xff;
- ptr[3] = credmsg.length & 0xff;
-
- ptr += 4;
-
- memcpy(ptr, credmsg.data, credmsg.length);
-
- ptr += credmsg.length;
- }
-
- memset(ptr, 0, 4);
-
- /* call mk_req. subkey and ap_req need to be used or destroyed */
-
- mk_req_flags = AP_OPTS_USE_SUBKEY;
-
- if (ctx->gss_flags & GSS_C_MUTUAL_FLAG)
- mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED;
-
- if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags,
- &cksumdata, k_cred, &ap_req)))
- goto cleanup;
-
- /* store the interesting stuff from creds and authent */
- ctx->endtime = k_cred->times.endtime;
- ctx->krb_flags = k_cred->ticket_flags;
-
- /* build up the token */
-
- /* allocate space for the token */
- tlen = g_token_size((gss_OID) mech_type,
- (cksumdata.length-(2+cblen))+2+ap_req.length);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
-
- ptr = t;
-
- g_make_token_header((gss_OID) mech_type,
- (cksumdata.length-(2+cblen))+2+ap_req.length,
- &ptr, KG2_TOK_INITIAL);
-
- /* skip over the channel bindings and the token id */
- memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2));
- ptr += cksumdata.length-(cblen+2);
- ptr[0] = (ap_req.length >> 8) & 0xff;
- ptr[1] = ap_req.length & 0xff;
- ptr += 2;
- memcpy(ptr, ap_req.data, ap_req.length);
-
- /* pass allocated data back */
-
- ctx->nctypes = nctypes;
- ctx->ctypes = ctypes;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (code) {
- if (ctypes)
- krb5_free_cksumtypes(context, ctypes);
- }
-
- if (credmsg.data)
- free(credmsg.data);
- if (ap_req.data)
- free(ap_req.data);
- if (cksumdata.data)
- free(cksumdata.data);
-
- return(code);
+ int krb5_mech2_supported = 0;
+ assert(krb5_mech2_supported);
}
static krb5_error_code
@@ -480,13 +324,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
krb5_context context;
krb5_gss_cred_id_t cred;
krb5_creds *k_cred = 0;
- krb5_enctype enctype = ENCTYPE_DES_CBC_CRC;
+ static const krb5_enctype wanted_enctypes[] = {
+#if 1
+ ENCTYPE_DES3_CBC_SHA1,
+#endif
+ ENCTYPE_DES_CBC_CRC,
+ ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
+ 0
+ };
krb5_error_code code;
krb5_gss_ctx_id_rec *ctx, *ctx_free;
krb5_timestamp now;
gss_buffer_desc token;
- int gsskrb5_vers = 0;
- int i, err;
+ int i, j, err;
int default_mech = 0;
krb5_ui_4 resp_flags;
OM_uint32 major_status;
@@ -528,32 +378,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
err = 0;
if (mech_type == GSS_C_NULL_OID) {
default_mech = 1;
- if (cred->rfcv2_mech) {
- mech_type = gss_mech_krb5_v2;
- gsskrb5_vers = 2000;
- } else if (cred->rfc_mech) {
- mech_type = gss_mech_krb5;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
+ if (cred->rfc_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
} else if (cred->prerfc_mech) {
- mech_type = gss_mech_krb5_old;
- gsskrb5_vers = 1000;
- enctype = ENCTYPE_DES_CBC_CRC;
+ mech_type = (gss_OID) gss_mech_krb5_old;
} else {
err = 1;
}
- } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) {
- if (!cred->rfcv2_mech)
- err = 1;
- gsskrb5_vers = 2000;
} else if (g_OID_equal(mech_type, gss_mech_krb5)) {
if (!cred->rfc_mech)
err = 1;
- gsskrb5_vers = 1000;
} else if (g_OID_equal(mech_type, gss_mech_krb5_old)) {
if (!cred->prerfc_mech)
err = 1;
- gsskrb5_vers = 1000;
} else {
err = 1;
}
@@ -607,7 +444,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ctx->seed_init = 0;
ctx->big_endian = 0; /* all initiators do little-endian, as per spec */
ctx->seqstate = 0;
- ctx->gsskrb5_version = gsskrb5_vers;
ctx->nctypes = 0;
ctx->ctypes = 0;
@@ -628,27 +464,12 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
goto fail;
if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
+ ctx->endtime, wanted_enctypes, &k_cred)))
goto fail;
- /*
- * If the default mechanism was requested, and the keytype is
- * DES_CBC, force the old mechanism
- */
- if (default_mech &&
- ((k_cred->keyblock.enctype == ENCTYPE_DES_CBC_CRC) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD4) ||
- (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD5))) {
- ctx->gsskrb5_version = gsskrb5_vers = 1000;
- mech_type = gss_mech_krb5;
- if (k_cred->keyblock.enctype != ENCTYPE_DES_CBC_CRC) {
- krb5_free_creds(context, k_cred);
- enctype = ENCTYPE_DES_CBC_CRC;
- if ((code = get_credentials(context, cred, ctx->there, now,
- ctx->endtime, enctype, &k_cred)))
- goto fail;
- }
- }
+ if (default_mech) {
+ mech_type = (gss_OID) gss_mech_krb5;
+ }
if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used)
!= GSS_S_COMPLETE) {
@@ -660,24 +481,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
*/
ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used);
- if (ctx->gsskrb5_version == 2000) {
- /* gsskrb5 v2 */
- if ((code = make_ap_req_v2(context, ctx,
- cred, k_cred, input_chan_bindings,
- mech_type, &token))) {
- if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) ||
- (code == KG_EMPTY_CCACHE))
- major_status = GSS_S_NO_CRED;
- if (code == KRB5KRB_AP_ERR_TKT_EXPIRED)
- major_status = GSS_S_CREDENTIALS_EXPIRED;
- goto fail;
- }
-
- krb5_auth_con_getlocalseqnumber(context, ctx->auth_context,
- &ctx->seq_send);
- krb5_auth_con_getlocalsubkey(context, ctx->auth_context,
- &ctx->subkey);
- } else {
+ {
/* gsskrb5 v1 */
if ((code = make_ap_req_v1(context, ctx,
cred, k_cred, input_chan_bindings,
@@ -699,11 +503,41 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
switch(ctx->subkey->enctype) {
case ENCTYPE_DES_CBC_MD5:
+ case ENCTYPE_DES_CBC_MD4:
case ENCTYPE_DES_CBC_CRC:
ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW;
- ctx->signalg = 0;
+ ctx->signalg = SGN_ALG_DES_MAC_MD5;
ctx->cksum_size = 8;
- ctx->sealalg = 0;
+ ctx->sealalg = SEAL_ALG_DES;
+
+ /* The encryption key is the session key XOR
+ 0xf0f0f0f0f0f0f0f0. */
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
+ goto fail;
+
+ for (i=0; i<ctx->enc->length; i++)
+ /*SUPPRESS 113*/
+ ctx->enc->contents[i] ^= 0xf0;
+
+ if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
+ goto fail;
+
+ break;
+
+ case ENCTYPE_DES3_CBC_SHA1:
+ ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW;
+ ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD;
+ ctx->cksum_size = 20;
+ ctx->sealalg = SEAL_ALG_DES3KD;
+
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc);
+ if (code)
+ goto fail;
+ code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq);
+ if (code) {
+ krb5_free_keyblock (context, ctx->enc);
+ goto fail;
+ }
break;
#if 0
case ENCTYPE_DES3_CBC_MD5:
@@ -714,20 +548,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
break;
#endif
default:
+ *minor_status = KRB5_BAD_ENCTYPE;
return GSS_S_FAILURE;
}
- /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc)))
- goto fail;
-
- for (i=0; i<ctx->enc->length; i++)
- /*SUPPRESS 113*/
- ctx->enc->contents[i] ^= 0xf0;
-
- if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq)))
- goto fail;
}
if (k_cred) {
@@ -824,94 +648,38 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
ptr = (unsigned char *) input_token->value;
- if (ctx->gsskrb5_version == 2000) {
- int token_length;
- int nctypes;
- krb5_cksumtype *ctypes = 0;
-
- /* gsskrb5 v2 */
-
- if ((code = g_verify_token_header((gss_OID) ctx->mech_used,
- &token_length,
- &ptr, KG2_TOK_RESPONSE,
- input_token->length))) {
- major_status = GSS_S_DEFECTIVE_TOKEN;
- goto fail;
- }
-
- if (GSS_ERROR(major_status =
- kg2_parse_token(minor_status, ptr, token_length,
- &resp_flags, &nctypes, &ctypes,
- 0, NULL, &ap_rep, &mic))) {
- if (ctypes)
- free(ctypes);
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
-
- kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes);
+ if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_AP_REP,
+ input_token->length))) {
+ if (g_verify_token_header((gss_OID) ctx->mech_used,
+ &(ap_rep.length),
+ &ptr, KG_TOK_CTX_ERROR,
+ input_token->length) == 0) {
- free(ctypes);
-
- if (ctx->nctypes == 0) {
- code = KG_NO_CTYPES;
- goto fail;
- }
+ /* Handle a KRB_ERROR message from the server */
- if (resp_flags & KG2_RESP_FLAG_ERROR) {
- if ((code = krb5_rd_error(context, &ap_rep, &krb_error)))
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
+ code = krb5_rd_error(context, &ap_rep, &krb_error);
+ if (code)
goto fail;
-
if (krb_error->error)
code = krb_error->error + ERROR_TABLE_BASE_krb5;
else
code = 0;
-
krb5_free_error(context, krb_error);
goto fail;
+ } else {
+ *minor_status = 0;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
-
- if (resp_flags & KG2_RESP_FLAG_DELEG_OK)
- ctx->gss_flags |= GSS_C_DELEG_FLAG;
-
- /* drop through to ap_rep handling */
- } else {
- /* gsskrb5 v1 */
-
- if ((err = g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_AP_REP,
- input_token->length))) {
- if (g_verify_token_header((gss_OID) ctx->mech_used,
- &(ap_rep.length),
- &ptr, KG_TOK_CTX_ERROR,
- input_token->length) == 0) {
-
- /* Handle a KRB_ERROR message from the server */
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
-
- code = krb5_rd_error(context, &ap_rep, &krb_error);
- if (code)
- goto fail;
- if (krb_error->error)
- code = krb_error->error + ERROR_TABLE_BASE_krb5;
- else
- code = 0;
- krb5_free_error(context, krb_error);
- goto fail;
- } else {
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
- }
-
- sptr = (char *) ptr; /* PC compiler bug */
- TREAD_STR(sptr, ap_rep.data, ap_rep.length);
}
+ sptr = (char *) ptr; /* PC compiler bug */
+ TREAD_STR(sptr, ap_rep.data, ap_rep.length);
+
/* decode the ap_rep */
if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep,
&ap_rep_data))) {
@@ -938,26 +706,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle,
/* set established */
ctx->established = 1;
- if (ctx->gsskrb5_version == 2000) {
- gss_buffer_desc mic_data, mic_token;
-
- /* start with the token id */
- mic_data.value = ptr-2;
- /* end before the ap-rep length */
- mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2));
-
- mic_token.length = mic.length;
- mic_token.value = mic.data;
-
- if (GSS_ERROR(major_status =
- krb5_gss_verify_mic(minor_status, *context_handle,
- &mic_data, &mic_token, NULL))) {
- code = *minor_status;
- goto fail;
- }
- major_status = GSS_S_FAILURE;
- }
-
/* set returns */
if (time_rec) {
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
index c800012..6fbbadc 100644
--- a/src/lib/gssapi/krb5/inq_cred.c
+++ b/src/lib/gssapi/krb5/inq_cred.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -116,15 +140,11 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
&mechs)) ||
(cred->prerfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_old,
+ (gss_OID) gss_mech_krb5_old,
&mechs))) ||
(cred->rfc_mech &&
GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5,
- &mechs))) ||
- (cred->rfcv2_mech &&
- GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status,
- gss_mech_krb5_v2,
+ (gss_OID) gss_mech_krb5,
&mechs)))) {
krb5_free_principal(context, ret_name);
/* *minor_status set above */
diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c
index ae8cc75..1ca108e 100644
--- a/src/lib/gssapi/krb5/k5seal.c
+++ b/src/lib/gssapi/krb5/k5seal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* 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
@@ -40,7 +40,7 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
@@ -49,196 +49,280 @@
#include "gssapiP_krb5.h"
static krb5_error_code
-make_priv_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
+make_seal_token_v1 PROTOTYPE((krb5_context context,
+ krb5_keyblock *enc,
+ krb5_keyblock *seq,
krb5_int32 *seqnum,
int direction,
gss_buffer_t text,
gss_buffer_t token,
+ int signalg,
+ int cksum_size,
+ int sealalg,
+ int encrypt,
+ int toktype,
+ int bigend,
gss_OID oid));
static krb5_error_code
-make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid)
- krb5_context context;
- krb5_keyblock *subkey;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- gss_OID oid;
-{
- krb5_data plain;
- krb5_enc_data cipher;
- krb5_error_code code;
- size_t enclen;
- int tlen;
- unsigned char *t, *ptr;
-
- plain.data = 0;
- cipher.ciphertext.data = 0;
- t = 0;
-
- plain.length = 7+text->length;
- if ((plain.data = (void *) malloc(plain.length)) == NULL) {
- code = ENOMEM;
- goto cleanup;
- }
-
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
-
- plain.data[4] = direction?0:0xff;
-
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
-
- memcpy(plain.data+7, text->value, text->length);
-
- if (code = krb5_c_encrypt_length(context, subkey->enctype,
- plain.length, &enclen))
- goto cleanup;
-
- tlen = g_token_size((gss_OID) oid, 2+enclen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 2+enclen, &ptr,
- KG2_TOK_WRAP_PRIV);
-
- ptr[0] = (enclen >> 8) & 0xff;
- ptr[1] = enclen & 0xff;
-
- cipher.ciphertext.length = enclen;
- cipher.ciphertext.data = ptr+2;
-
- if (code = krb5_c_encrypt(context, subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV,
- 0, &plain, &cipher))
- goto cleanup;
-
- /* that's it. return the token */
-
- (*seqnum)++;
-
- token->length = tlen;
- token->value = (void *) t;
-
- code = 0;
-
-cleanup:
- if (plain.data)
- free(plain.data);
- if (code) {
- if (t)
- free(t);
- }
-
- return(code);
-}
-
-static krb5_error_code
-make_integ_token_v2 PROTOTYPE((krb5_context context,
- krb5_keyblock *subkey,
- krb5_cksumtype ctype,
- krb5_int32 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int toktype,
- gss_OID oid));
-
-static krb5_error_code
-make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
- toktype, oid)
- krb5_context context;
- krb5_keyblock *subkey;
- krb5_cksumtype ctype;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- int toktype;
- gss_OID oid;
+make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
+ signalg, cksum_size, sealalg, encrypt, toktype,
+ bigend, oid)
+ krb5_context context;
+ krb5_keyblock *enc;
+ krb5_keyblock *seq;
+ krb5_int32 *seqnum;
+ int direction;
+ gss_buffer_t text;
+ gss_buffer_t token;
+ int signalg;
+ int cksum_size;
+ int sealalg;
+ int encrypt;
+ int toktype;
+ int bigend;
+ gss_OID oid;
{
krb5_error_code code;
- int tmp, tlen;
- unsigned char *t, *ptr;
- krb5_data plain;
+ size_t sumlen;
+ char *data_ptr;
+ krb5_data plaind;
+ krb5_checksum md5cksum;
krb5_checksum cksum;
+ int conflen=0, tmsglen, tlen;
+ unsigned char *t, *ptr;
- plain.data = 0;
- t = 0;
- cksum.contents = 0;
+ int encblksize, sumblksize;
+
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ sumblksize = 1;
+ break;
+ case SGN_ALG_DES_MAC:
+ sumblksize = 8;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ sumblksize = 1;
+ break;
+ default:
+ abort ();
+ return 123; /* find error code */
+ }
- /* assemble the checksum buffer and compute the checksum */
+ switch (sealalg) {
+ case SEAL_ALG_NONE:
+ case SEAL_ALG_DES:
+ case SEAL_ALG_DES3KD:
+ encblksize = 8;
+ break;
+ default:
+ abort ();
+ return 12345654321;
+ }
- plain.length = 7+text->length;
+ /* create the token buffer */
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- code = errno;
- goto cleanup;
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (bigend && !encrypt) {
+ tmsglen = text->length;
+ } else {
+ conflen = kg_confounder_size(context, enc);
+ /* XXX knows that des block size is 8 */
+ tmsglen = (conflen+text->length+8)&(~7);
+ }
+ } else {
+ tmsglen = 0;
}
- plain.data[0] = (*seqnum >> 24) & 0xff;
- plain.data[1] = (*seqnum >> 16) & 0xff;
- plain.data[2] = (*seqnum >> 8) & 0xff;
- plain.data[3] = *seqnum & 0xff;
+ tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
- plain.data[4] = direction?0:0xff;
+ if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
+ return(ENOMEM);
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ /*** fill in the token */
- memcpy(plain.data+7, text->value, text->length);
+ ptr = t;
- if (code = krb5_c_make_checksum(context, ctype, subkey,
- (toktype == KG2_TOK_WRAP_INTEG)?
- KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG:
- KRB5_KEYUSAGE_GSS_TOK_MIC,
- &plain, &cksum))
- goto cleanup;
+ g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
- /* assemble the token itself */
+ /* 0..1 SIGN_ALG */
- if (toktype == KG2_TOK_WRAP_INTEG)
- tmp = 4+(7+text->length)+2+cksum.length;
- else
- tmp = 4+(5)+2+cksum.length;
+ ptr[0] = signalg & 0xff;
+ ptr[1] = (signalg >> 8) & 0xff;
- tlen = g_token_size((gss_OID) oid, tmp);
+ /* 2..3 SEAL_ALG or Filler */
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
+ if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
+ ptr[2] = sealalg & 0xff;
+ ptr[3] = (sealalg >> 8) & 0xff;
+ } else {
+ /* No seal */
+ ptr[2] = 0xff;
+ ptr[3] = 0xff;
+ }
- ptr = t;
+ /* 4..5 Filler */
+
+ ptr[4] = 0xff;
+ ptr[5] = 0xff;
+
+ /* pad the plaintext, encrypt if needed, and stick it in the token */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ case SGN_ALG_DES_MAC:
+ abort ();
+ }
- g_make_token_header((gss_OID) oid, tmp, &ptr, toktype);
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
+
+ if (toktype == KG_TOK_SEAL_MSG) {
+ unsigned char *plain;
+ unsigned char pad;
+
+ if (!bigend || encrypt) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ xfree(t);
+ return(ENOMEM);
+ }
+
+ if ((code = kg_make_confounder(context, enc, plain))) {
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+
+ memcpy(plain+conflen, text->value, text->length);
+
+ /* XXX 8 is DES cblock size */
+ pad = 8-(text->length%8);
+
+ memset(plain+conflen+text->length, pad, pad);
+ } else {
+ /* plain is never used in the bigend && !encrypt case */
+ plain = NULL;
+ }
+
+ if (encrypt) {
+ if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL,
+ (krb5_pointer) plain,
+ (krb5_pointer) (ptr+cksum_size+14),
+ tmsglen))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
+ } else {
+ if (bigend)
+ memcpy(ptr+14+cksum_size, text->value, text->length);
+ else
+ memcpy(ptr+14+cksum_size, plain, tmsglen);
+ }
+
+ /* compute the checksum */
+
+ /* 8 = head of token body as specified by mech spec */
+ if (! (data_ptr =
+ (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ if (bigend)
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ else
+ (void) memcpy(data_ptr+8, plain, tmsglen);
+ plaind.length = 8 + (bigend ? text->length : tmsglen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (plain)
+ xfree(plain);
+ xfree(t);
+ return(code);
+ }
- ptr[0] = (ctype >> 24) & 0xff;
- ptr[1] = (ctype >> 16) & 0xff;
- ptr[2] = (ctype >> 8) & 0xff;
- ptr[3] = ctype & 0xff;
+ if (plain)
+ xfree(plain);
+ } else {
+ /* Sign only. */
+ /* compute the checksum */
- ptr += 4;
+ if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
+ xfree(t);
+ return(ENOMEM);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, text->value, text->length);
+ plaind.length = 8 + text->length;
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq,
+ KG_USAGE_SIGN, &plaind, &md5cksum);
+ xfree(data_ptr);
+ if (code) {
+ xfree(t);
+ return(code);
+ }
+ }
- if (toktype == KG2_TOK_WRAP_INTEG) {
- memcpy(ptr, plain.data, 7+text->length);
- ptr += 7+text->length;
- } else {
- memcpy(ptr, plain.data, 5);
- ptr += 5;
+ switch(signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case 3:
+
+ if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL,
+ (g_OID_equal(oid, gss_mech_krb5_old) ?
+ seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ xfree(t);
+ return code;
+ }
+
+ cksum.length = cksum_size;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
+
+ memcpy(ptr+14, cksum.contents, cksum.length);
+ break;
+
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /*
+ * Using key derivation, the call to krb5_c_make_checksum
+ * already dealt with encrypting.
+ */
+ if (md5cksum.length != cksum_size)
+ abort ();
+ memcpy (ptr+14, md5cksum.contents, md5cksum.length);
+ break;
}
- ptr[0] = (cksum.length >> 8) & 0xff;
- ptr[1] = cksum.length & 0xff;
- ptr += 2;
+ xfree(md5cksum.contents);
+
+ /* create the seq_num */
- memcpy(ptr, cksum.contents, cksum.length);
+ if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
+ ptr+14, ptr+6))) {
+ xfree(t);
+ return(code);
+ }
/* that's it. return the token */
@@ -247,372 +331,110 @@ make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token,
token->length = tlen;
token->value = (void *) t;
- code = 0;
-
-cleanup:
- if (plain.data)
- free(plain.data);
- if (cksum.contents)
- krb5_free_checksum_contents(context, &cksum);
- if (code) {
- if (t)
- free(t);
- }
-
- return(code);
+ return(0);
}
-static krb5_error_code
-make_seal_token_v1 PROTOTYPE((krb5_context context,
- krb5_keyblock *enc,
- krb5_keyblock *seq,
- krb5_int32 *seqnum,
- int direction,
- gss_buffer_t text,
- gss_buffer_t token,
- int signalg,
- int cksum_size,
- int sealalg,
- int encrypt,
- int toktype,
- int bigend,
- gss_OID oid));
+/* if signonly is true, ignore conf_req, conf_state,
+ and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
-static krb5_error_code
-make_seal_token_v1(context, enc, seq, seqnum, direction, text, token,
- signalg, cksum_size, sealalg, encrypt, toktype,
- bigend, oid)
- krb5_context context;
- krb5_keyblock *enc;
- krb5_keyblock *seq;
- krb5_int32 *seqnum;
- int direction;
- gss_buffer_t text;
- gss_buffer_t token;
- int signalg;
- int cksum_size;
- int sealalg;
- int encrypt;
- int toktype;
- int bigend;
- gss_OID oid;
+OM_uint32
+kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
+ input_message_buffer, conf_state, output_message_buffer, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ int conf_req_flag;
+ int qop_req;
+ gss_buffer_t input_message_buffer;
+ int *conf_state;
+ gss_buffer_t output_message_buffer;
+ int toktype;
{
- krb5_error_code code;
- size_t sumlen;
- char *data_ptr;
- krb5_data plaind;
- krb5_checksum md5cksum;
- krb5_checksum cksum;
- int conflen=0, tmsglen, tlen;
- unsigned char *t, *ptr;
-
- /* create the token buffer */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (bigend && !encrypt) {
- tmsglen = text->length;
- } else {
- conflen = kg_confounder_size(context, enc);
- /* XXX knows that des block size is 8 */
- tmsglen = (conflen+text->length+8)&(~7);
- }
- } else {
- tmsglen = 0;
- }
-
- tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen);
-
- if ((t = (unsigned char *) xmalloc(tlen)) == NULL)
- return(ENOMEM);
-
- /*** fill in the token */
-
- ptr = t;
-
- g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype);
-
- /* 0..1 SIGN_ALG */
-
- ptr[0] = signalg;
- ptr[1] = 0;
-
- /* 2..3 SEAL_ALG or Filler */
-
- if ((toktype == KG_TOK_SEAL_MSG) && encrypt) {
- ptr[2] = sealalg;
- ptr[3] = 0;
- } else {
- /* No seal */
- ptr[2] = 0xff;
- ptr[3] = 0xff;
- }
-
- /* 4..5 Filler */
-
- ptr[4] = 0xff;
- ptr[5] = 0xff;
-
- /* pad the plaintext, encrypt if needed, and stick it in the token */
-
- /* initialize the the cksum */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
- return(code);
-
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- md5cksum.length = sumlen;
- if (toktype == KG_TOK_SEAL_MSG) {
- unsigned char *plain;
- unsigned char pad;
-
- if (!bigend || encrypt) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- xfree(t);
- return(ENOMEM);
- }
-
- if ((code = kg_make_confounder(context, enc, plain))) {
- xfree(plain);
- xfree(t);
- return(code);
- }
-
- memcpy(plain+conflen, text->value, text->length);
-
- /* XXX 8 is DES cblock size */
- pad = 8-(text->length%8);
-
- memset(plain+conflen+text->length, pad, pad);
- } else {
- /* plain is never used in the bigend && !encrypt case */
- plain = NULL;
- }
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_error_code code;
+ krb5_timestamp now;
- if (encrypt) {
- if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain,
- (krb5_pointer) (ptr+cksum_size+14),
- tmsglen))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- }
- } else {
- if (bigend)
- memcpy(ptr+14+cksum_size, text->value, text->length);
- else
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- /* compute the checksum */
-
- /* 8 = head of token body as specified by mech spec */
- if (! (data_ptr =
- (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- if (bigend)
- (void) memcpy(data_ptr+8, text->value, text->length);
- else
- (void) memcpy(data_ptr+8, plain, tmsglen);
- plaind.length = 8 + (bigend ? text->length : tmsglen);
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type,
- 0, 0, &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (plain)
- xfree(plain);
- xfree(t);
- return(code);
- memcpy(ptr+14+cksum_size, plain, tmsglen);
- }
-
- if (plain)
- xfree(plain);
- } else {
- /* compute the checksum */
-
- if (! (data_ptr = (char *) xmalloc(8 + text->length))) {
- xfree(t);
- return(ENOMEM);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, text->value, text->length);
- plaind.length = 8 + text->length;
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
- if (code) {
- xfree(t);
- return(code);
- }
- }
-
- switch(signalg) {
- case 0:
- case 3:
+ output_message_buffer->length = 0;
+ output_message_buffer->value = NULL;
+ /* only default qop or matching established cryptosystem is allowed */
+
#if 0
- /* XXX this depends on the key being a single-des key */
-
- /* DES CBC doesn't use a zero IV like it should in some
- krb5 implementations (beta5+). So we just do the
- DES encryption the long way, and keep the last block
- as the MAC */
-
- /* XXX not converted to new api since it's inside an #if 0 */
-
- /* initialize the the cksum and allocate the contents buffer */
- cksum.checksum_type = CKSUMTYPE_DESCBC;
- cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC);
- if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL)
- return(ENOMEM);
-
- /* XXX not converted to new api since it's inside an #if 0 */
- if (code = krb5_calculate_checksum(context, cksum.checksum_type,
- md5cksum.contents, 16,
- seq->contents,
- seq->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- xfree(t);
- return(code);
- }
-
- memcpy(ptr+14, cksum.contents, 8);
-
- xfree(cksum.contents);
+ switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ unknown_qop:
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ case GSS_KRB5_CONF_C_QOP_DES:
+ if (ctx->sealalg != SEAL_ALG_DES) {
+ bad_qop:
+ *minor_status = (OM_uint32) G_BAD_QOP;
+ return GSS_S_FAILURE;
+ }
+ break;
+ case GSS_KRB5_CONF_C_QOP_DES3:
+ if (ctx->sealalg != SEAL_ALG_DES3)
+ goto bad_qop;
+ break;
+ }
+ switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) {
+ case GSS_C_QOP_DEFAULT:
+ break;
+ default:
+ goto unknown_qop;
+ case GSS_KRB5_INTEG_C_QOP_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MD5:
+ case GSS_KRB5_INTEG_C_QOP_DES_MAC:
+ if (ctx->sealalg != SEAL_ALG_DES)
+ goto bad_qop;
+ break;
+ case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1:
+ if (ctx->sealalg != SEAL_ALG_DES3KD)
+ goto bad_qop;
+ break;
+ }
#else
- if ((code = kg_encrypt(context, seq,
- (g_OID_equal(oid, gss_mech_krb5_old) ?
- seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- xfree(t);
- return code;
- }
-
- cksum.length = cksum_size;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
-
- memcpy(ptr+14, cksum.contents, cksum.length);
+ if (qop_req != 0) {
+ *minor_status = (OM_uint32) G_UNKNOWN_QOP;
+ return GSS_S_FAILURE;
+ }
#endif
- break;
- }
-
- xfree(md5cksum.contents);
-
- /* create the seq_num */
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum,
- ptr+14, ptr+6))) {
- xfree(t);
- return(code);
- }
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
- /* that's it. return the token */
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
- (*seqnum)++;
+ if ((code = krb5_timeofday(context, &now))) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- token->length = tlen;
- token->value = (void *) t;
+ code = make_seal_token_v1(context, ctx->enc, ctx->seq,
+ &ctx->seq_send, ctx->initiate,
+ input_message_buffer, output_message_buffer,
+ ctx->signalg, ctx->cksum_size, ctx->sealalg,
+ conf_req_flag, toktype, ctx->big_endian,
+ ctx->mech_used);
- return(0);
-}
+ if (code) {
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
-/* if signonly is true, ignore conf_req, conf_state,
- and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */
+ if (conf_state)
+ *conf_state = conf_req_flag;
-OM_uint32
-kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req,
- input_message_buffer, conf_state, output_message_buffer, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- int conf_req_flag;
- int qop_req;
- gss_buffer_t input_message_buffer;
- int *conf_state;
- gss_buffer_t output_message_buffer;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- krb5_error_code code;
- krb5_timestamp now;
-
- output_message_buffer->length = 0;
- output_message_buffer->value = NULL;
-
- /* only default qop is allowed */
- if (qop_req != GSS_C_QOP_DEFAULT) {
- *minor_status = (OM_uint32) G_UNKNOWN_QOP;
- return(GSS_S_FAILURE);
- }
-
- /* validate the context handle */
- if (! kg_validate_ctx_id(context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (! ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (ctx->gsskrb5_version == 2000) {
- if (toktype == KG_TOK_WRAP_MSG) {
- if (conf_req_flag)
- toktype = KG2_TOK_WRAP_PRIV;
- else
- toktype = KG2_TOK_WRAP_INTEG;
- } else {
- toktype = KG2_TOK_MIC;
- }
-
- if (conf_req_flag) {
- code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send,
- ctx->initiate, input_message_buffer,
- output_message_buffer, ctx->mech_used);
- } else {
- code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0],
- &ctx->seq_send, ctx->initiate,
- input_message_buffer,
- output_message_buffer, toktype,
- ctx->mech_used);
- }
- } else {
- code = make_seal_token_v1(context, ctx->enc, ctx->seq,
- &ctx->seq_send, ctx->initiate,
- input_message_buffer, output_message_buffer,
- ctx->signalg, ctx->cksum_size, ctx->sealalg,
- conf_req_flag, toktype, ctx->big_endian,
- ctx->mech_used);
- }
-
- if (code) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (conf_state)
- *conf_state = conf_req_flag;
-
- *minor_status = 0;
- return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
+ *minor_status = 0;
+ return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
}
diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c
index 64a9539..9e4d353 100644
--- a/src/lib/gssapi/krb5/k5unseal.c
+++ b/src/lib/gssapi/krb5/k5unseal.c
@@ -1,6 +1,6 @@
/*
* Copyright 1993 by OpenVision Technologies, Inc.
- *
+ *
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appears in all copies and
@@ -10,7 +10,7 @@
* without specific, written prior permission. OpenVision makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
- *
+ *
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
@@ -22,14 +22,14 @@
/*
* Copyright (C) 1998 by the FundsXpress, INC.
- *
+ *
* 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
@@ -40,7 +40,7 @@
* permission. FundsXpress makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
@@ -53,834 +53,438 @@
* $Id$
*/
-static OM_uint32
-kg2_verify_mic(context, minor_status, ctx, ptr, bodysize,
- text, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t text;
- gss_qop_t *qop_state;
+/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
+ conf_state is only valid if SEAL. */
+
+OM_uint32
+kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
+ conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- size_t cksumlen;
krb5_error_code code;
- krb5_data plain;
- krb5_cksumtype tctype;
- krb5_ui_4 tseqnum;
- int tdirection;
+ int tmsglen;
+ int conflen = 0;
+ int signalg;
+ int sealalg;
+ gss_buffer_desc token;
krb5_checksum cksum;
- krb5_boolean ckvalid;
+ krb5_checksum md5cksum;
+ krb5_data plaind;
+ char *data_ptr;
krb5_timestamp now;
+ unsigned char *plain;
+ int cksum_len = 0;
+ int plainlen;
+ int direction;
+ krb5_int32 seqnum;
OM_uint32 retval;
+ size_t sumlen;
- plain.data = 0;
- cksum.contents = 0;
-
- /* verify the header */
-
- if (bodysize < 11) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ if (toktype == KG_TOK_SEAL_MSG) {
+ message_buffer->length = 0;
+ message_buffer->value = NULL;
}
- /* allocate the checksum buffer */
-
- plain.length = 7+text->length;
-
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ /* get the sign and seal algorithms */
- /* suck out the body parts from the token */
+ signalg = ptr[0] + (ptr[1]<<8);
+ sealalg = ptr[2] + (ptr[3]<<8);
- tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
+ /* Sanity checks */
- memcpy(plain.data, ptr, 5);
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
-
- cksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
-
- if (cksum.length != bodysize) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- cksum.contents = ptr;
- cksum.checksum_type = tctype;
+ if ((toktype != KG_TOK_SEAL_MSG) &&
+ (sealalg != 0xffff)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- /* finish assembling the checksum buffer and compute the checksum */
+ /* in the current spec, there is only one valid seal algorithm per
+ key type, so a simple comparison is ok */
- plain.data[5] = (text->length >> 8) & 0xff;
- plain.data[6] = text->length & 0xff;
+ if ((toktype == KG_TOK_SEAL_MSG) &&
+ !((sealalg == 0xffff) ||
+ (sealalg == ctx->sealalg))) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
- memcpy(plain.data+7, text->value, text->length);
+ /* there are several mappings of seal algorithms to sign algorithms,
+ but few enough that we can try them all. */
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_MIC,
- &plain, &cksum, &ckvalid)) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
+ if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+ (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+ (ctx->sealalg == SEAL_ALG_DES3KD &&
+ signalg != SGN_ALG_HMAC_SHA1_DES3_KD)) {
+ *minor_status = 0;
+ return GSS_S_DEFECTIVE_TOKEN;
}
- if (!ckvalid) {
- free(plain.data);
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ cksum_len = 8;
+ break;
+ case SGN_ALG_3:
+ cksum_len = 16;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ cksum_len = 20;
+ break;
+ default:
*minor_status = 0;
- return(GSS_S_BAD_SIG);
+ return GSS_S_DEFECTIVE_TOKEN;
}
- /* check context expiry */
+ if (toktype == KG_TOK_SEAL_MSG)
+ tmsglen = bodysize-(14+cksum_len);
- if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
+ /* get the token parameters */
- if (now > ctx->endtime) {
- free(plain.data);
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
+ /* decode the message, if SEAL */
- /* do sequencing checks */
+ if (toktype == KG_TOK_SEAL_MSG) {
+ if (sealalg != 0xffff) {
+ if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
+ if ((code = kg_decrypt(context, ctx->enc, KG_USAGE_SEAL, NULL,
+ ptr+14+cksum_len, plain, tmsglen))) {
+ xfree(plain);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
+ } else {
+ plain = ptr+14+cksum_len;
+ }
- retval = g_order_check(&(ctx->seqstate), tseqnum);
+ plainlen = tmsglen;
- free(plain.data);
+ if ((sealalg == 0xffff) && ctx->big_endian) {
+ token.length = tmsglen;
+ } else {
+ conflen = kg_confounder_size(context, ctx->enc);
+ token.length = tmsglen - conflen - plain[tmsglen-1];
+ }
- if (retval) {
- *minor_status = 0;
- return(retval);
- }
+ if (token.length) {
+ if ((token.value = (void *) xmalloc(token.length)) == NULL) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ memcpy(token.value, plain+conflen, token.length);
+ }
+ } else if (toktype == KG_TOK_SIGN_MSG) {
+ token = *message_buffer;
+ plain = token.value;
+ plainlen = token.length;
+ } else {
+ token.length = 0;
+ token.value = NULL;
+ plain = token.value;
+ plainlen = token.length;
+ }
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ /* compute the checksum of the message */
+
+ /* initialize the the cksum */
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_MD2_5:
+ case SGN_ALG_HMAC_MD5:
+ case SGN_ALG_DES_MAC:
+ case SGN_ALG_3:
+ md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
+ break;
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3;
+ break;
+ default:
+ abort ();
+ }
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen))
+ return(code);
+ md5cksum.length = sumlen;
-static OM_uint32
-kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t output;
- gss_qop_t *qop_state;
-{
- krb5_error_code code;
- OM_uint32 retval;
- krb5_ui_4 tseqnum;
- int tdirection;
- int tmsglen;
- unsigned char *tmsg;
- krb5_data plain;
- krb5_checksum tcksum;
- krb5_boolean ckvalid;
- krb5_timestamp now;
+ switch (signalg) {
+ case SGN_ALG_DES_MAC_MD5:
+ case SGN_ALG_3:
+ /* compute the checksum of the message */
- output->length = 0;
- output->value = NULL;
+ /* 8 = bytes of token body to be checksummed according to spec */
- /* read the body parts out of the message */
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 11) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ (void) memcpy(data_ptr, ptr-2, 8);
- tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) |
- (ptr[2]<<8) | ptr[3]);
- ptr += 4;
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- plain.data = ptr;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL,
+ (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
+ ctx->seq->contents : NULL),
+ md5cksum.contents, md5cksum.contents, 16))) {
+ xfree(md5cksum.contents);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 11;
+ if (signalg == 0)
+ cksum.length = 8;
+ else
+ cksum.length = 16;
+ cksum.contents = md5cksum.contents + 16 - cksum.length;
- if (bodysize < tmsglen) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ code = memcmp(cksum.contents, ptr+14, cksum.length);
+ break;
- tmsg = ptr;
- ptr += tmsglen;
- bodysize -= tmsglen;
+ case SGN_ALG_MD2_5:
+ if (!ctx->seed_init &&
+ (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
- plain.length = ((char*)ptr) - ((char *)plain.data);
+ if (! (data_ptr = (void *)
+ xmalloc(sizeof(ctx->seed) + 8 +
+ (ctx->big_endian ? token.length : plainlen)))) {
+ xfree(md5cksum.contents);
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
+ (void) memcpy(data_ptr, ptr-2, 8);
+ (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8+sizeof(ctx->seed),
+ plain, plainlen);
+ plaind.length = 8 + sizeof(ctx->seed) +
+ (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ xfree(md5cksum.contents);
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
+
+ if (code) {
+ if (sealalg == 0)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- tcksum.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
+ code = memcmp(md5cksum.contents, ptr+14, 8);
+ /* Falls through to defective-token?? */
- if (bodysize != tcksum.length) {
- *minor_status = G_TOK_TRUNC;
+ default:
+ *minor_status = 0;
return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tcksum.contents = ptr;
- /* verify the MIC */
+ case SGN_ALG_HMAC_SHA1_DES3_KD:
+ /* compute the checksum of the message */
- if (code = krb5_c_verify_checksum(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG,
- &plain, &tcksum, &ckvalid)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
+ /* 8 = bytes of token body to be checksummed according to spec */
- if (!ckvalid) {
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
+ if (! (data_ptr = (void *)
+ xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
+ if (sealalg != 0xffff)
+ xfree(plain);
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+ }
- /* check context expiry */
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (now > ctx->endtime) {
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
-
- /* do sequencing checks */
-
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- if (retval = g_order_check(&(ctx->seqstate), tseqnum)) {
- *minor_status = 0;
- return(retval);
- }
-
- if (tmsglen) {
- if ((output->value = (void *) malloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(output->value, tmsg, tmsglen);
- output->length = tmsglen;
- }
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- *minor_status = 0;
- return(GSS_S_COMPLETE);
-}
+ (void) memcpy(data_ptr, ptr-2, 8);
-static OM_uint32
-kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t output;
- gss_qop_t *qop_state;
-{
- krb5_error_code code;
- OM_uint32 retval;
- krb5_enc_data cipher;
- krb5_data plain;
- krb5_ui_4 tseqnum;
- int tdirection;
- int tmsglen;
- unsigned char *tmsg;
- krb5_timestamp now;
+ if (ctx->big_endian)
+ (void) memcpy(data_ptr+8, token.value, token.length);
+ else
+ (void) memcpy(data_ptr+8, plain, plainlen);
- output->length = 0;
- output->value = NULL;
+ plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
+ plaind.data = data_ptr;
+ code = krb5_c_make_checksum(context, md5cksum.checksum_type,
+ ctx->seq, KG_USAGE_SIGN,
+ &plaind, &md5cksum);
+ xfree(data_ptr);
- /* read the body parts out of the message */
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
+ return(GSS_S_FAILURE);
+ }
- if (bodysize < 2) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
+ code = memcmp(md5cksum.contents, ptr+14, md5cksum.length);
+ break;
}
- cipher.ciphertext.length = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 2;
+ xfree(md5cksum.contents);
+ if (sealalg != 0xffff)
+ xfree(plain);
- if (bodysize != cipher.ciphertext.length) {
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ /* compare the computed checksum against the transmitted checksum */
- cipher.ciphertext.data = ptr;
- cipher.enctype = ENCTYPE_UNKNOWN;
-
- plain.length = cipher.ciphertext.length;
- if ((plain.data = (char *) malloc(plain.length)) == NULL) {
+ if (code) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
*minor_status = 0;
- return(GSS_S_FAILURE);
- }
-
- /* decrypt (and implicitly verify) the encrypted data */
-
- if (code = krb5_c_decrypt(context, ctx->subkey,
- KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV,
- 0, &cipher, &plain)) {
- free(plain.data);
- *minor_status = code;
- return(GSS_S_FAILURE);
+ return(GSS_S_BAD_SIG);
}
- /* parse out the encrypted fields */
- ptr = plain.data;
- bodysize = plain.length;
+ /* it got through unscathed. Make sure the context is unexpired */
- if (bodysize < 7) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
+ if (toktype == KG_TOK_SEAL_MSG)
+ *message_buffer = token;
- tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]);
- ptr += 4;
- tdirection = ptr[0];
- ptr += 1;
+ if (conf_state)
+ *conf_state = (sealalg != 0xffff);
- tmsglen = (ptr[0]<<8) | ptr[1];
- ptr += 2;
- bodysize -= 7;
-
- /* check context expiry */
+ if (qop_state)
+ *qop_state = GSS_C_QOP_DEFAULT;
if ((code = krb5_timeofday(context, &now))) {
- free(plain.data);
*minor_status = code;
return(GSS_S_FAILURE);
}
if (now > ctx->endtime) {
- free(plain.data);
*minor_status = 0;
return(GSS_S_CONTEXT_EXPIRED);
}
/* do sequencing checks */
- if ((ctx->initiate && tdirection != 0xff) ||
- (!ctx->initiate && tdirection != 0)) {
- free(plain.data);
- *minor_status = G_BAD_DIRECTION;
+ if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
+ &seqnum))) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = code;
return(GSS_S_BAD_SIG);
}
- if (retval = g_order_check(&(ctx->seqstate), tseqnum)) {
- free(plain.data);
- *minor_status = 0;
- return(retval);
- }
-
- /* now copy out the data. can't do a strict equality check here,
- since the output could be padded. */
-
- if (bodysize < tmsglen) {
- free(plain.data);
- *minor_status = G_TOK_TRUNC;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- tmsg = ptr;
-
- if (tmsglen) {
- if ((output->value = (void *) malloc(tmsglen)) == NULL) {
- free(plain.data);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(output->value, tmsg, tmsglen);
- output->length = tmsglen;
+ if ((ctx->initiate && direction != 0xff) ||
+ (!ctx->initiate && direction != 0)) {
+ if (toktype == KG_TOK_SEAL_MSG)
+ xfree(token.value);
+ *minor_status = G_BAD_DIRECTION;
+ return(GSS_S_BAD_SIG);
}
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
+ retval = g_order_check(&(ctx->seqstate), seqnum);
- free(plain.data);
+ /* success or ordering violation */
*minor_status = 0;
- return(GSS_S_COMPLETE);
+ return(retval);
}
/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
conf_state is only valid if SEAL. */
OM_uint32
-kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer,
- conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
+kg_unseal(context, minor_status, context_handle, input_token_buffer,
+ message_buffer, conf_state, qop_state, toktype)
+ krb5_context context;
+ OM_uint32 *minor_status;
+ gss_ctx_id_t context_handle;
+ gss_buffer_t input_token_buffer;
+ gss_buffer_t message_buffer;
+ int *conf_state;
+ int *qop_state;
+ int toktype;
{
- krb5_error_code code;
- int tmsglen;
- int conflen = 0;
- int signalg;
- int sealalg;
- gss_buffer_desc token;
- krb5_checksum cksum;
- krb5_checksum desmac;
- krb5_checksum md5cksum;
- krb5_data plaind;
- char *data_ptr;
- krb5_timestamp now;
- unsigned char *plain;
- int cksum_len = 0;
- int plainlen;
- int err;
- int direction;
- krb5_int32 seqnum;
- OM_uint32 retval;
- size_t sumlen;
-
- if (toktype == KG_TOK_SEAL_MSG) {
- message_buffer->length = 0;
- message_buffer->value = NULL;
- }
-
- /* get the sign and seal algorithms */
-
- signalg = ptr[0] + (ptr[1]<<8);
- sealalg = ptr[2] + (ptr[3]<<8);
-
- /* Sanity checks */
-
- if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- if ((toktype != KG_TOK_SEAL_MSG) &&
- (sealalg != 0xffff)) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* in the current spec, there is only one valid seal algorithm per
- key type, so a simple comparison is ok */
-
- if ((toktype == KG_TOK_SEAL_MSG) &&
- !((sealalg == 0xffff) ||
- (sealalg == ctx->sealalg))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- /* there are several mappings of seal algorithms to sign algorithms,
- but few enough that we can try them all. */
-
- if (((ctx->sealalg == 0) &&
- (signalg > 1)) ||
- ((ctx->sealalg == 1) &&
- (signalg != 3))) {
- *minor_status = 0;
- return GSS_S_DEFECTIVE_TOKEN;
- }
-
- switch (signalg) {
- case 0:
- case 1:
- cksum_len = 8;
- break;
- case 3:
- cksum_len = 16;
- break;
- }
-
- if (toktype == KG_TOK_SEAL_MSG)
- tmsglen = bodysize-(14+cksum_len);
-
- /* get the token parameters */
-
- /* decode the message, if SEAL */
-
- if (toktype == KG_TOK_SEAL_MSG) {
- if (sealalg != 0xffff) {
- if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) {
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
+ krb5_gss_ctx_id_rec *ctx;
+ unsigned char *ptr;
+ int bodysize;
+ int err;
+
+ /* validate the context handle */
+ if (! kg_validate_ctx_id(context_handle)) {
+ *minor_status = (OM_uint32) G_VALIDATE_FAILED;
+ return(GSS_S_NO_CONTEXT);
+ }
- if ((code = kg_decrypt(context, ctx->enc, NULL,
- ptr+14+cksum_len, plain, tmsglen))) {
- xfree(plain);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- } else {
- plain = ptr+14+cksum_len;
- }
-
- plainlen = tmsglen;
-
- if ((sealalg == 0xffff) && ctx->big_endian) {
- token.length = tmsglen;
- } else {
- conflen = kg_confounder_size(context, ctx->enc);
- token.length = tmsglen - conflen - plain[tmsglen-1];
- }
-
- if (token.length) {
- if ((token.value = (void *) xmalloc(token.length)) == NULL) {
- if (sealalg != 0xffff)
- xfree(plain);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- memcpy(token.value, plain+conflen, token.length);
- }
- } else if (toktype == KG_TOK_SIGN_MSG) {
- token = *message_buffer;
- plain = token.value;
- plainlen = token.length;
- } else {
- token.length = 0;
- token.value = NULL;
- plain = token.value;
- plainlen = token.length;
- }
-
- /* compute the checksum of the message */
-
- /* initialize the the cksum */
- if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen))
- return(code);
-
- md5cksum.checksum_type = CKSUMTYPE_RSA_MD5;
- md5cksum.length = sumlen;
-
- switch (signalg) {
- case 0:
- case 3:
- /* compute the checksum of the message */
-
- /* 8 = bytes of token body to be checksummed according to spec */
-
- if (! (data_ptr = (void *)
- xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) {
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- (void) memcpy(data_ptr, ptr-2, 8);
-
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8, token.value, token.length);
- else
- (void) memcpy(data_ptr+8, plain, plainlen);
-
- plaind.length = 8 + (ctx->big_endian ? token.length : plainlen);
- plaind.data = data_ptr;
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
-#if 0
- /* XXX this depends on the key being a single-des key, but that's
- all that kerberos supports right now */
-
- /* initialize the the cksum and allocate the contents buffer */
- cksum.checksum_type = CKSUMTYPE_DESCBC;
- cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC);
- if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
-
- /* XXX not converted to new api since it's inside an #if 0 */
- if (code = krb5_calculate_checksum(context, cksum.checksum_type,
- md5cksum.contents, 16,
- ctx->seq.key->contents,
- ctx->seq.key->length,
- &cksum)) {
- xfree(cksum.contents);
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-
- xfree(cksum.contents);
-#else
- if ((code = kg_encrypt(context, ctx->seq,
- (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ?
- ctx->seq->contents : NULL),
- md5cksum.contents, md5cksum.contents, 16))) {
- xfree(md5cksum.contents);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
-
- if (signalg == 0)
- cksum.length = 8;
- else
- cksum.length = 16;
- cksum.contents = md5cksum.contents + 16 - cksum.length;
-
- code = memcmp(cksum.contents, ptr+14, cksum.length);
-#endif
- break;
-
- case 1:
- if (!ctx->seed_init &&
- (code = kg_make_seed(context, ctx->subkey, ctx->seed))) {
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return GSS_S_FAILURE;
- }
-
- if (! (data_ptr = (void *)
- xmalloc(sizeof(ctx->seed) + 8 +
- (ctx->big_endian ? token.length : plainlen)))) {
- xfree(md5cksum.contents);
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = ENOMEM;
- return(GSS_S_FAILURE);
- }
- (void) memcpy(data_ptr, ptr-2, 8);
- (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed));
- if (ctx->big_endian)
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- token.value, token.length);
- else
- (void) memcpy(data_ptr+8+sizeof(ctx->seed),
- plain, plainlen);
- plaind.length = 8 + sizeof(ctx->seed) +
- (ctx->big_endian ? token.length : plainlen);
- plaind.data = data_ptr;
- xfree(md5cksum.contents);
- code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0,
- &plaind, &md5cksum);
- xfree(data_ptr);
-
- if (code) {
- if (sealalg == 0)
- xfree(plain);
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- code = memcmp(md5cksum.contents, ptr+14, 8);
-
- default:
- *minor_status = 0;
- return(GSS_S_DEFECTIVE_TOKEN);
- }
-
- xfree(md5cksum.contents);
- if (sealalg != 0xffff)
- xfree(plain);
-
- /* compare the computed checksum against the transmitted checksum */
-
- if (code) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = 0;
- return(GSS_S_BAD_SIG);
- }
-
-
- /* it got through unscathed. Make sure the context is unexpired */
-
- if (toktype == KG_TOK_SEAL_MSG)
- *message_buffer = token;
-
- if (conf_state)
- *conf_state = (sealalg != 0xffff);
-
- if (qop_state)
- *qop_state = GSS_C_QOP_DEFAULT;
-
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- if (now > ctx->endtime) {
- *minor_status = 0;
- return(GSS_S_CONTEXT_EXPIRED);
- }
-
- /* do sequencing checks */
-
- if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction,
- &seqnum))) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = code;
- return(GSS_S_BAD_SIG);
- }
-
- if ((ctx->initiate && direction != 0xff) ||
- (!ctx->initiate && direction != 0)) {
- if (toktype == KG_TOK_SEAL_MSG)
- xfree(token.value);
- *minor_status = G_BAD_DIRECTION;
- return(GSS_S_BAD_SIG);
- }
-
- retval = g_order_check(&(ctx->seqstate), seqnum);
-
- /* success or ordering violation */
-
- *minor_status = 0;
- return(retval);
-}
+ ctx = (krb5_gss_ctx_id_rec *) context_handle;
-/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
- conf_state is only valid if SEAL. */
+ if (! ctx->established) {
+ *minor_status = KG_CTX_INCOMPLETE;
+ return(GSS_S_NO_CONTEXT);
+ }
-OM_uint32
-kg_unseal(context, minor_status, context_handle, input_token_buffer,
- message_buffer, conf_state, qop_state, toktype)
- krb5_context context;
- OM_uint32 *minor_status;
- gss_ctx_id_t context_handle;
- gss_buffer_t input_token_buffer;
- gss_buffer_t message_buffer;
- int *conf_state;
- int *qop_state;
- int toktype;
-{
- krb5_gss_ctx_id_rec *ctx;
- unsigned char *ptr;
- int bodysize;
- int err;
- OM_uint32 retval;
-
- /* validate the context handle */
- if (! kg_validate_ctx_id(context_handle)) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- return(GSS_S_NO_CONTEXT);
- }
-
- ctx = (krb5_gss_ctx_id_rec *) context_handle;
-
- if (! ctx->established) {
- *minor_status = KG_CTX_INCOMPLETE;
- return(GSS_S_NO_CONTEXT);
- }
-
- /* parse the token, leave the data in message_buffer, setting conf_state */
-
- /* verify the header */
-
- ptr = (unsigned char *) input_token_buffer->value;
-
- if (ctx->gsskrb5_version == 2000) {
- if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr, KG2_TOK_MIC,
- input_token_buffer->length))) {
- return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize,
- message_buffer, qop_state));
- } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr,
- KG2_TOK_WRAP_INTEG,
- input_token_buffer->length))) {
- if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status,
- ctx, ptr, bodysize,
- message_buffer, qop_state)))
- return(retval);
-
- if (conf_state)
- *conf_state = 0;
- return(GSS_S_COMPLETE);
- } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr,
- KG2_TOK_WRAP_PRIV,
- input_token_buffer->length))) {
- if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status,
- ctx, ptr, bodysize,
- message_buffer, qop_state)))
- return(retval);
-
- if (conf_state)
- *conf_state = 1;
- return(GSS_S_COMPLETE);
- }
- } else {
- if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
- &bodysize, &ptr, toktype,
- input_token_buffer->length))) {
- return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
- message_buffer, conf_state, qop_state,
- toktype));
- }
- }
-
- *minor_status = err;
- return(GSS_S_DEFECTIVE_TOKEN);
+ /* parse the token, leave the data in message_buffer, setting conf_state */
+
+ /* verify the header */
+
+ ptr = (unsigned char *) input_token_buffer->value;
+
+ if (!(err = g_verify_token_header((gss_OID) ctx->mech_used,
+ &bodysize, &ptr, toktype,
+ input_token_buffer->length))) {
+ return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize,
+ message_buffer, conf_state, qop_state,
+ toktype));
+ }
+
+ *minor_status = err;
+ return(GSS_S_DEFECTIVE_TOKEN);
}
diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c
index 2a6231e..1989a7d 100644
--- a/src/lib/gssapi/krb5/ser_sctx.c
+++ b/src/lib/gssapi/krb5/ser_sctx.c
@@ -233,7 +233,6 @@ kg_ctx_size(kcontext, arg, sizep)
* krb5_int32 for seq_recv.
* krb5_int32 for established.
* krb5_int32 for big_endian.
- * krb5_int32 for gsskrb5_version.
* krb5_int32 for nctypes.
* krb5_int32 for trailer.
*/
@@ -349,8 +348,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain)
&bp, &remain);
(void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
&bp, &remain);
- (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version,
- &bp, &remain);
(void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes,
&bp, &remain);
@@ -477,8 +474,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain)
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ctx->big_endian = (int) ibuf;
(void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
- ctx->gsskrb5_version = (int) ibuf;
- (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
ctx->nctypes = (int) ibuf;
if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp,
diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c
index 10e6b65..47ffc5b 100644
--- a/src/lib/gssapi/krb5/util_cksum.c
+++ b/src/lib/gssapi/krb5/util_cksum.c
@@ -27,6 +27,7 @@
#include "gssapiP_krb5.h"
#include <memory.h>
+/* Checksumming the channel bindings always uses plain MD5. */
krb5_error_code
kg_checksum_channel_bindings(context, cb, cksum, bigend)
krb5_context context;
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index 93d4694..049e4d6 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -54,8 +54,6 @@
* $Id$
*/
-static unsigned char zeros[8] = {0,0,0,0,0,0,0,0};
-
int
kg_confounder_size(context, key)
krb5_context context;
@@ -105,9 +103,10 @@ kg_encrypt_size(context, key, n)
}
krb5_error_code
-kg_encrypt(context, key, iv, in, out, length)
+kg_encrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -123,7 +122,10 @@ kg_encrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -135,18 +137,19 @@ kg_encrypt(context, key, iv, in, out, length)
outputd.ciphertext.length = length;
outputd.ciphertext.data = out;
- return(krb5_c_encrypt(context, key,
- /* XXX this routine is only used for the old
- bare-des stuff which doesn't use the
- key usage */ 0, pivd, &inputd, &outputd));
+ code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
/* length is the length of the cleartext. */
krb5_error_code
-kg_decrypt(context, key, iv, in, out, length)
+kg_decrypt(context, key, usage, iv, in, out, length)
krb5_context context;
krb5_keyblock *key;
+ int usage;
krb5_pointer iv;
krb5_pointer in;
krb5_pointer out;
@@ -162,7 +165,10 @@ kg_decrypt(context, key, iv, in, out, length)
return(code);
ivd.length = blocksize;
- ivd.data = iv;
+ ivd.data = malloc(ivd.length);
+ if (ivd.data == NULL)
+ return ENOMEM;
+ memcpy(ivd.data, iv, ivd.length);
pivd = &ivd;
} else {
pivd = NULL;
@@ -175,8 +181,8 @@ kg_decrypt(context, key, iv, in, out, length)
outputd.length = length;
outputd.data = out;
- return(krb5_c_decrypt(context, key,
- /* XXX this routine is only used for the old
- bare-des stuff which doesn't use the
- key usage */ 0, pivd, &inputd, &outputd));
+ code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd);
+ if (pivd != NULL)
+ krb5_free_data_contents(context, pivd);
+ return code;
}
diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c
index 206ee68..b4a9044 100644
--- a/src/lib/gssapi/krb5/util_seed.c
+++ b/src/lib/gssapi/krb5/util_seed.c
@@ -47,7 +47,7 @@ kg_make_seed(context, key, seed)
for (i=0; i<tmpkey->length; i++)
tmpkey->contents[i] = key->contents[key->length - 1 - i];
- code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16);
+ code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16);
krb5_free_keyblock(context, tmpkey);
diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c
index e14b2f3..b8f2b38 100644
--- a/src/lib/gssapi/krb5/util_seqnum.c
+++ b/src/lib/gssapi/krb5/util_seqnum.c
@@ -47,7 +47,7 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf)
plain[6] = direction;
plain[7] = direction;
- return(kg_encrypt(context, key, cksum, plain, buf, 8));
+ return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8));
}
krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
@@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum)
krb5_error_code code;
unsigned char plain[8];
- if (code = kg_decrypt(context, key, cksum, buf, plain, 8))
+ if (code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8))
return(code);
if ((plain[4] != plain[5]) ||
diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c
index f7fee73..55d4bce 100644
--- a/src/lib/gssapi/krb5/wrap_size_limit.c
+++ b/src/lib/gssapi/krb5/wrap_size_limit.c
@@ -1,4 +1,28 @@
/*
+ * Copyright 2000 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.
+ *
+ */
+/*
* Copyright 1993 by OpenVision Technologies, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
@@ -66,6 +90,9 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
krb5_context context;
krb5_gss_ctx_id_rec *ctx;
krb5_error_code code;
+ OM_uint32 data_size, conflen;
+ OM_uint32 ohlen;
+ int overhead;
if (GSS_ERROR(kg_get_context(minor_status, &context)))
return(GSS_S_FAILURE);
@@ -88,92 +115,23 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag,
return(GSS_S_NO_CONTEXT);
}
- if (ctx->gsskrb5_version == 2000) {
- if (conf_req_flag) {
- /* this is pretty gross. take the max output, and call
- krb5_c_encrypt_length to see how much overhead is added
- on. subtract that much, and see if it fits in the
- requested space. If not, start subtracting 1 until it
- does. This doesn't necessarily give us the optimal
- packing, but I think that's ok (I could start adding 1
- until I went over, but that seems like it's not worth
- the effort). This is probably O(blocksize), but that's
- never going to be large. */
-
- OM_uint32 headerlen, plainlen;
- size_t enclen;
-
- headerlen = g_token_size((gss_OID) ctx->mech_used, 2);
- plainlen = req_output_size - headerlen;
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- plainlen -= plainlen - (enclen - plainlen);
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- while (headerlen + enclen > req_output_size) {
- plainlen--;
-
- if (code = krb5_c_encrypt_length(context, ctx->enc->enctype,
- plainlen, &enclen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
- }
-
- /* subtract off the fixed size inside the encrypted part */
-
- plainlen -= 7;
-
- *max_input_size = plainlen;
- } else {
- size_t cksumlen;
- OM_uint32 headerlen;
-
- if (code = krb5_c_checksum_length(context, ctx->ctypes[0],
- &cksumlen)) {
- *minor_status = code;
- return(GSS_S_FAILURE);
- }
-
- headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen);
-
- *max_input_size = req_output_size - headerlen;
- }
- } else {
- OM_uint32 data_size, conflen;
- OM_uint32 ohlen;
- int overhead;
-
- /* Calculate the token size and subtract that from the output size */
- overhead = 7 + ctx->mech_used->length;
- data_size = req_output_size;
- if (conf_req_flag) {
- conflen = kg_confounder_size(context, ctx->enc);
- data_size = (conflen + data_size + 8) & (~7);
- }
- ohlen = g_token_size((gss_OID) ctx->mech_used,
- (unsigned int) (data_size + ctx->cksum_size + 14))
- - req_output_size;
-
- if (ohlen+overhead < req_output_size)
- /*
- * Cannot have trailer length that will cause us to pad over
- * our length
- */
- *max_input_size = (req_output_size - ohlen - overhead) & (~7);
- else
- *max_input_size = 0;
- }
+ /* Calculate the token size and subtract that from the output size */
+ overhead = 7 + ctx->mech_used->length;
+ data_size = req_output_size;
+ conflen = kg_confounder_size(context, ctx->enc);
+ data_size = (conflen + data_size + 8) & (~(OM_uint32)7);
+ ohlen = g_token_size((gss_OID) ctx->mech_used,
+ (unsigned int) (data_size + ctx->cksum_size + 14))
+ - req_output_size;
+
+ if (ohlen+overhead < req_output_size)
+ /*
+ * Cannot have trailer length that will cause us to pad over our
+ * length.
+ */
+ *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7);
+ else
+ *max_input_size = 0;
*minor_status = 0;
return(GSS_S_COMPLETE);