sanon: Fix flags and ctx export/import confusion

We were passing SANON flags to _gss_mg_import_rfc4121_context(), which
wants GSS flags.  Meanwhile, I broke gss_inquire_context() on imported
SAnon contexts when I did my review of SAnon.

This commit fixes both issues and removes SANON_FLAG_*, which were only
ever needed because of a flag to track whether a context was locally
initiated or accepted.  Now we use a separate int field of the sanon_ctx
to track whether a context was locally initiated.  Once an SAnon context
is fully established, we rely on gss_inquire_context() on the rfc4121
sub-context for all metadata that isn't the initiator and acceptor names
nor the mechanism OID.
This commit is contained in:
Nicolas Williams
2020-04-26 00:53:29 -05:00
parent 51fdb4bc04
commit 2cb40ed97c
7 changed files with 34 additions and 72 deletions

View File

@@ -49,7 +49,6 @@ _gss_sanon_accept_sec_context(OM_uint32 *minor,
sanon_ctx sc = (sanon_ctx)*context_handle;
gss_buffer_desc mech_input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc hok_mic = GSS_C_EMPTY_BUFFER;
OM_uint32 flags;
gss_buffer_desc session_key = GSS_C_EMPTY_BUFFER;
if (output_token == GSS_C_NO_BUFFER) {
@@ -94,11 +93,10 @@ _gss_sanon_accept_sec_context(OM_uint32 *minor,
if (major != GSS_S_COMPLETE)
goto out;
flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG |
sc->flags |= GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG |
GSS_C_INTEG_FLAG | GSS_C_ANON_FLAG | GSS_C_TRANS_FLAG;
flags |= sanon_to_rfc4757_flags(sc->flags);
major = _gss_sanon_import_rfc4121_context(minor, sc, flags, &session_key);
major = _gss_sanon_import_rfc4121_context(minor, sc, &session_key);
if (major != GSS_S_COMPLETE)
goto out;
@@ -126,7 +124,7 @@ _gss_sanon_accept_sec_context(OM_uint32 *minor,
if (src_name)
*src_name = _gss_sanon_anonymous_identity;
if (ret_flags)
*ret_flags = flags;
*ret_flags = sc->flags;
if (time_rec)
*time_rec = GSS_C_INDEFINITE;

View File

@@ -278,7 +278,7 @@ _gss_sanon_curve25519(OM_uint32 *minor,
p = kdf_context.data;
if (sc->flags & SANON_FLAG_INITIATOR) {
if (sc->is_initiator) {
memcpy(p, sc->pk, sizeof(sc->pk));
memcpy(&p[pk->length], pk->value, pk->length);
} else {
@@ -318,14 +318,10 @@ _gss_sanon_curve25519(OM_uint32 *minor,
OM_uint32
_gss_sanon_import_rfc4121_context(OM_uint32 *minor,
sanon_ctx sc,
OM_uint32 flags,
gss_const_buffer_t session_key)
{
return _gss_mg_import_rfc4121_context(minor,
!!(sc->flags & SANON_FLAG_INITIATOR),
flags,
return _gss_mg_import_rfc4121_context(minor, sc->is_initiator, sc->flags,
KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
session_key,
&sc->rfc4121);
session_key, &sc->rfc4121);
}

View File

@@ -46,9 +46,7 @@ _gss_sanon_export_sec_context(OM_uint32 *minor,
}
major = gss_export_sec_context(minor, &sc->rfc4121, interprocess_token);
if (major == GSS_S_COMPLETE) {
_gss_sanon_delete_sec_context(minor, context_handle,
GSS_C_NO_BUFFER);
}
if (major == GSS_S_COMPLETE)
_gss_sanon_delete_sec_context(minor, context_handle, GSS_C_NO_BUFFER);
return major;
}

View File

@@ -117,7 +117,8 @@ _gss_sanon_init_sec_context(OM_uint32 *minor,
goto out;
}
sc->flags = SANON_FLAG_INITIATOR | rfc4757_to_sanon_flags(req_flags);
sc->is_initiator = 1;
sc->flags = req_flags;
/* compute public and secret keys */
major = _gss_sanon_curve25519_base(minor, sc);
@@ -144,8 +145,7 @@ _gss_sanon_init_sec_context(OM_uint32 *minor,
input_token->length < crypto_scalarmult_curve25519_BYTES) {
major = GSS_S_DEFECTIVE_TOKEN;
goto out;
} else if (sc->rfc4121 != GSS_C_NO_CONTEXT ||
!(sc->flags & SANON_FLAG_INITIATOR)) {
} else if (sc->rfc4121 != GSS_C_NO_CONTEXT || !(sc->is_initiator)) {
major = GSS_S_BAD_STATUS;
goto out;
}
@@ -159,8 +159,9 @@ _gss_sanon_init_sec_context(OM_uint32 *minor,
goto out;
flags |= GSS_C_TRANS_FLAG;
sc->flags |= GSS_C_TRANS_FLAG;
major = _gss_sanon_import_rfc4121_context(minor, sc, flags, &session_key);
major = _gss_sanon_import_rfc4121_context(minor, sc, &session_key);
if (major != GSS_S_COMPLETE)
goto out;

View File

@@ -43,6 +43,7 @@ _gss_sanon_inquire_context(OM_uint32 *minor,
int *open_context)
{
const sanon_ctx sc = (const sanon_ctx)context_handle;
OM_uint32 major = GSS_S_COMPLETE;
*minor = 0;
@@ -57,13 +58,17 @@ _gss_sanon_inquire_context(OM_uint32 *minor,
*lifetime_rec = GSS_C_INDEFINITE;
if (mech_type)
*mech_type = GSS_SANON_X25519_MECHANISM;
if (ctx_flags)
gss_inquire_context(minor, sc->rfc4121,
NULL, NULL, NULL, NULL,
ctx_flags, NULL, NULL);
if (sc->rfc4121 == GSS_C_NO_CONTEXT) {
if (locally_initiated)
*locally_initiated = !!(sc->flags & SANON_FLAG_INITIATOR);
*locally_initiated = sc->is_initiator;
if (open_context)
*open_context = !!(sc->rfc4121 != GSS_C_NO_CONTEXT);
return GSS_S_COMPLETE;
*open_context = 0;
if (ctx_flags)
*ctx_flags = sc->flags;
} else {
major = gss_inquire_context(minor, sc->rfc4121, NULL, NULL, NULL,
NULL, ctx_flags, locally_initiated,
open_context);
}
return major;
}

View File

@@ -64,7 +64,7 @@ _gss_sanon_inquire_negoex_key(OM_uint32 *minor,
return GSS_S_UNAVAILABLE;
}
initiator_key = !!(sc->flags & SANON_FLAG_INITIATOR);
initiator_key = !!(sc->is_initiator);
if (gss_oid_equal(desired_object, GSS_C_INQ_NEGOEX_VERIFY_KEY))
initiator_key ^= 1;
@@ -193,7 +193,8 @@ _gssspi_sanon_exchange_meta_data(OM_uint32 *minor,
if (major != GSS_S_COMPLETE)
return major;
sc->flags |= rfc4757_to_sanon_flags(init_flags);
init_flags &= ~(GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG);
sc->flags |= init_flags | req_flags;
return GSS_S_COMPLETE;
}

View File

@@ -43,23 +43,16 @@
#include "mech/mech_locl.h"
/* context is initiator context */
#define SANON_FLAG_INITIATOR 0x0001
/* RFC 4757 extended flags */
#define SANON_FLAG_DCE_STYLE 0x1000
#define SANON_FLAG_IDENTIFY 0x2000
#define SANON_FLAG_EXTENDED_ERROR 0x4000
typedef struct sanon_ctx_desc {
/* X25519 ECDH secret key */
uint8_t sk[crypto_scalarmult_curve25519_BYTES];
/* X25519 ECDH public key */
uint8_t pk[crypto_scalarmult_curve25519_BYTES];
/* SANON_FLAG_xxx */
/* GSS_C_*_FLAG */
uint32_t flags;
/* krb5 context for message protection/PRF */
gss_ctx_id_t rfc4121;
int is_initiator;
} *sanon_ctx;
extern gss_name_t _gss_sanon_anonymous_identity;
@@ -87,34 +80,4 @@ buffer_equal_p(gss_const_buffer_t b1, gss_const_buffer_t b2)
memcmp(b1->value, b2->value, b2->length) == 0;
}
static inline OM_uint32
sanon_to_rfc4757_flags(uint32_t flags)
{
OM_uint32 ret = 0;
if (flags & SANON_FLAG_DCE_STYLE)
ret |= GSS_C_DCE_STYLE;
if (flags & SANON_FLAG_IDENTIFY)
ret |= GSS_C_IDENTIFY_FLAG;
if (flags & SANON_FLAG_EXTENDED_ERROR)
ret |= GSS_C_EXTENDED_ERROR_FLAG;
return ret;
}
static inline uint32_t
rfc4757_to_sanon_flags(OM_uint32 flags)
{
uint32_t ret = 0;
if (flags & GSS_C_DCE_STYLE)
ret |= SANON_FLAG_DCE_STYLE;
if (flags & GSS_C_IDENTIFY_FLAG)
ret |= SANON_FLAG_IDENTIFY;
if (flags & GSS_C_EXTENDED_ERROR_FLAG)
ret |= SANON_FLAG_EXTENDED_ERROR;
return ret;
}
#endif /* SANON_LOCL_H */