mech/gss_release_name.c \
mech/gss_release_oid.c \
mech/gss_release_oid_set.c \
+ mech/gss_rfc4121.c \
mech/gss_seal.c \
mech/gss_set_cred_option.c \
mech/gss_set_name_attribute.c \
mech/gss_release_name.c \
mech/gss_release_oid.c \
mech/gss_release_oid_set.c \
+ mech/gss_rfc4121.c \
mech/gss_seal.c \
mech/gss_set_cred_option.c \
mech/gss_set_name_attribute.c \
$(OBJ)\mech/gss_release_name.obj \
$(OBJ)\mech/gss_release_oid.obj \
$(OBJ)\mech/gss_release_oid_set.obj \
+ $(OBJ)\mech/gss_rfc4121.obj \
$(OBJ)\mech/gss_seal.obj \
$(OBJ)\mech/gss_set_cred_option.obj \
$(OBJ)\mech/gss_set_name_attribute.obj \
extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc;
#define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc)
+extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_rfc4121_context_x_oid_desc;
+#define GSS_KRB5_IMPORT_RFC4121_CONTEXT_X (&__gss_krb5_import_rfc4121_context_x_oid_desc)
+
/* glue for gss_inquire_saslname_for_mech */
extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ma_sasl_mech_name_oid_desc;
#define GSS_C_MA_SASL_MECH_NAME (&__gss_c_ma_sasl_mech_name_oid_desc)
return GSS_S_COMPLETE;
}
+/*
+ * GSS_KRB5_IMPORT_RFC4121_CONTEXT_X is an internal, private interface
+ * to allow SAnon to create a skeletal context for using RFC4121 message
+ * protection services.
+ *
+ * rfc4121_args ::= initiator_flag || flags || enctype || session key
+ */
+static OM_uint32
+make_rfc4121_context(OM_uint32 *minor,
+ krb5_context context,
+ gss_ctx_id_t *context_handle,
+ gss_const_buffer_t rfc4121_args)
+{
+ OM_uint32 major = GSS_S_FAILURE, tmp;
+ krb5_error_code ret;
+ krb5_storage *sp = NULL;
+ gsskrb5_ctx ctx = NULL;
+ uint8_t initiator_flag;
+ int32_t enctype;
+ size_t keysize;
+ krb5_keyblock *key;
+
+ *minor = 0;
+
+ sp = krb5_storage_from_readonly_mem(rfc4121_args->value, rfc4121_args->length);
+ if (sp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_HOST);
+
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_ret_uint8(sp, &initiator_flag);
+ if (ret != 0)
+ goto out;
+
+ ret = krb5_ret_uint32(sp, &ctx->flags);
+ if (ret != 0)
+ goto out;
+
+ ctx->more_flags = IS_CFX | ACCEPTOR_SUBKEY | OPEN;
+ if (initiator_flag)
+ ctx->more_flags |= LOCAL;
+
+ ctx->state = initiator_flag ? INITIATOR_READY : ACCEPTOR_READY;
+
+ ret = krb5_ret_int32(sp, &enctype);
+ if (ret != 0)
+ goto out;
+
+ ret = krb5_enctype_keysize(context, enctype, &keysize);
+ if (ret != 0)
+ goto out;
+
+ ctx->auth_context = calloc(1, sizeof(*ctx->auth_context));
+ if (ctx->auth_context == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ key = calloc(1, sizeof(*key));
+ if (key == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ if (initiator_flag)
+ ctx->auth_context->remote_subkey = key;
+ else
+ ctx->auth_context->local_subkey = key;
+
+ key->keytype = enctype;
+ key->keyvalue.data = malloc(keysize);
+ if (key->keyvalue.data == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ if (krb5_storage_read(sp, key->keyvalue.data, keysize) != keysize) {
+ ret = EINVAL;
+ goto out;
+ }
+ key->keyvalue.length = keysize;
+
+ ret = krb5_crypto_init(context, key, 0, &ctx->crypto);
+ if (ret != 0)
+ goto out;
+
+ major = _gssapi_msg_order_create(minor, &ctx->order,
+ _gssapi_msg_order_f(ctx->flags),
+ 0, 0, 1);
+ if (major != GSS_S_COMPLETE)
+ goto out;
+
+out:
+ krb5_storage_free(sp);
+
+ if (major != GSS_S_COMPLETE) {
+ if (*minor == 0)
+ *minor = ret;
+ _gsskrb5_delete_sec_context(&tmp, (gss_ctx_id_t *)&ctx, GSS_C_NO_BUFFER);
+ } else {
+ *context_handle = (gss_ctx_id_t)ctx;
+ }
+
+ return major;
+}
+
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_set_sec_context_option
(OM_uint32 *minor_status,
*minor_status = 0;
return GSS_S_COMPLETE;
+ } else if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_RFC4121_CONTEXT_X)) {
+ return make_rfc4121_context(minor_status, context, context_handle, value);
}
*minor_status = EINVAL;
/* GSS_KRB5_IMPORT_CRED_X - 1.2.752.43.13.30 */
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1e") };
+/* GSS_KRB5_IMPORT_RFC4121_CONTEXT_X - 1.2.752.43.13.31 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_rfc4121_context_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1f") };
+
/* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") };
&__gss_c_ntlm_force_v1_oid_desc,
&__gss_krb5_cred_no_ci_flags_x_oid_desc,
&__gss_krb5_import_cred_x_oid_desc,
+ &__gss_krb5_import_rfc4121_context_x_oid_desc,
&__gss_c_ma_sasl_mech_name_oid_desc,
&__gss_c_ma_mech_name_oid_desc,
&__gss_c_ma_mech_description_oid_desc,
--- /dev/null
+/*
+ * Copyright (c) 2019-2020, AuriStor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "mech_locl.h"
+
+/*
+ * An internal API (for now) to return a mechglue context handle given
+ * a session key that can provide RFC 4121 compatible message protection
+ * and PRF services. Used by SAnon. The implementation of those services
+ * is currently provided by the krb5 GSS mechanism but that is opaque to
+ * the caller (minor status codes notwithstanding).
+ */
+OM_uint32
+_gss_mg_import_rfc4121_context(OM_uint32 *minor,
+ uint8_t initiator_flag,
+ OM_uint32 gss_flags,
+ int32_t rfc3961_enctype,
+ gss_const_buffer_t session_key,
+ gss_ctx_id_t *rfc4121_context_handle)
+{
+ OM_uint32 major = GSS_S_FAILURE, tmpMinor;
+ krb5_storage *sp;
+ krb5_error_code ret;
+ krb5_data d;
+ gss_buffer_desc rfc4121_args = GSS_C_EMPTY_BUFFER;
+
+ krb5_data_zero(&d);
+
+ *minor = 0;
+ *rfc4121_context_handle = GSS_C_NO_CONTEXT;
+
+ sp = krb5_storage_emem();
+ if (sp == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_HOST);
+
+ /*
+ * The arguments GSS_KRB5_IMPORT_RFC4121_CONTEXT_X are the serialized
+ * form of initiator_flag || flags || keytype || session_key. The session
+ * key length is inferred from the keytype.
+ */
+ ret = krb5_store_uint8(sp, initiator_flag);
+ if (ret != 0)
+ goto out;
+
+ ret = krb5_store_uint32(sp, gss_flags);
+ if (ret != 0)
+ goto out;
+
+ ret = krb5_store_int32(sp, rfc3961_enctype);
+ if (ret != 0)
+ goto out;
+
+ if (krb5_storage_write(sp, session_key->value, session_key->length)
+ != session_key->length) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ret = krb5_storage_to_data(sp, &d);
+ if (ret != 0)
+ goto out;
+
+ rfc4121_args.length = d.length;
+ rfc4121_args.value = d.data;
+
+ major = gss_set_sec_context_option(minor, rfc4121_context_handle,
+ GSS_KRB5_IMPORT_RFC4121_CONTEXT_X,
+ &rfc4121_args);
+
+out:
+ _gss_secure_release_buffer(&tmpMinor, &rfc4121_args);
+ krb5_storage_free(sp);
+
+ if (major == GSS_S_FAILURE && *minor == 0)
+ *minor = ret;
+
+ return major;
+}
+
void _gss_mg_decode_le_uint16(const void *ptr, uint16_t *n);
void _gss_mg_encode_be_uint16(uint16_t n, uint8_t *p);
void _gss_mg_decode_be_uint16(const void *ptr, uint16_t *n);
+
+OM_uint32
+_gss_mg_import_rfc4121_context(OM_uint32 *minor,
+ uint8_t initiator_flag,
+ OM_uint32 gss_flags,
+ int32_t rfc3961_enctype,
+ gss_const_buffer_t session_key,
+ gss_ctx_id_t *rfc4121_context_handle);
oid base GSS_C_NTLM_FORCE_V1 1.2.752.43.13.28
oid base GSS_KRB5_CRED_NO_CI_FLAGS_X 1.2.752.43.13.29
oid base GSS_KRB5_IMPORT_CRED_X 1.2.752.43.13.30
+oid base GSS_KRB5_IMPORT_RFC4121_CONTEXT_X 1.2.752.43.13.31
# /* glue for gss_inquire_saslname_for_mech */
oid base GSS_C_MA_SASL_MECH_NAME 1.2.752.43.13.100