sanon: Fix flags and ctx export/import confusion
authorNicolas Williams <nico@twosigma.com>
Sun, 26 Apr 2020 05:53:29 +0000 (00:53 -0500)
committerNicolas Williams <nico@twosigma.com>
Sun, 26 Apr 2020 06:30:37 +0000 (01:30 -0500)
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.

lib/gssapi/sanon/accept_sec_context.c
lib/gssapi/sanon/crypto.c
lib/gssapi/sanon/export_sec_context.c
lib/gssapi/sanon/init_sec_context.c
lib/gssapi/sanon/inquire_context.c
lib/gssapi/sanon/negoex.c
lib/gssapi/sanon/sanon_locl.h

index cd0b7fd44574a27a7c4bff096b29b939f944bc2e..bcaa3316d3b036f7712f38d6d2c702b1801d2ca0 100644 (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 |
-           GSS_C_INTEG_FLAG | GSS_C_ANON_FLAG | GSS_C_TRANS_FLAG;
-    flags |= sanon_to_rfc4757_flags(sc->flags);
+    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;
 
-    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;
 
index 2a4d8e8747ab0e1997197401c0294fc1394b0328..69d175476b3f65d1a9202adab3d2b99bf9923c6c 100644 (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,
-                                         KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
-                                         session_key,
-                                         &sc->rfc4121);
+    return _gss_mg_import_rfc4121_context(minor, sc->is_initiator, sc->flags,
+                                          KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128,
+                                          session_key, &sc->rfc4121);
 }
 
index f788dae883a7e101a50f9a427818257cfae3c6f6..52ba6fbfb2ec59fc944291f3c52c2024ff73eef6 100644 (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;
 }
index 08f630e5484862bd1d4e7f8088fff082eef6332c..c553bbdb42796a0290f85bd291a1931dfbb22bf2 100644 (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;
 
index 1f540da9be6b217d1279359a6411fb04cc5740eb..bec1d5088777d5fc62aecedf18cfc63515e7fda7 100644 (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 (locally_initiated)
-       *locally_initiated = !!(sc->flags & SANON_FLAG_INITIATOR);
-    if (open_context)
-       *open_context = !!(sc->rfc4121 != GSS_C_NO_CONTEXT);
-    return GSS_S_COMPLETE;
+    if (sc->rfc4121 == GSS_C_NO_CONTEXT) {
+        if (locally_initiated)
+            *locally_initiated = sc->is_initiator;
+        if (open_context)
+            *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;
 }
index b1c5eac4f0e2b0f2371bfd7cb06623dfbcc1249f..86df155aa4b690544a011e7e0ab946ccc4a97134 100644 (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;
 }
index 7fab880eb4f9c07fcbaaaa5c25b140c21c09da2a..9d853b6fcde72cb511d5180d731b38a3f526ad62 100644 (file)
 
 #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 */