krb5 commit [krb5-1.12]: Test SPNEGO acceptor response to MS krb5 mech OID

Tom Yu tlyu at MIT.EDU
Thu Jun 26 16:36:08 EDT 2014


https://github.com/krb5/krb5/commit/292b7807bab19d917caa13860da5bae3738f80c6
commit 292b7807bab19d917caa13860da5bae3738f80c6
Author: Greg Hudson <ghudson at mit.edu>
Date:   Mon Feb 3 20:59:54 2014 -0500

    Test SPNEGO acceptor response to MS krb5 mech OID
    
    In t_spnego.c, add code to make a SPNEGO request with the erroneous
    Microsoft OID value and examine the response to make sure that it uses
    the same OID value as the request did.  The token and tmp variables
    were unused, so rename them to itok and atok for the purpose of the
    new test code.
    
    (cherry picked from commit 53cfb8327c452bd72a8e915338fb5ec838079cd3)
    
    ticket: 7858
    version_fixed: 1.12.2
    status: resolved

 src/tests/gssapi/t_spnego.c |   64 ++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/src/tests/gssapi/t_spnego.c b/src/tests/gssapi/t_spnego.c
index cbf720b..ca05848 100644
--- a/src/tests/gssapi/t_spnego.c
+++ b/src/tests/gssapi/t_spnego.c
@@ -27,9 +27,15 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 
 #include "common.h"
 
+static gss_OID_desc mech_krb5_wrong = {
+    9, "\052\206\110\202\367\022\001\002\002"
+};
+gss_OID_set_desc mechset_krb5_wrong = { 1, &mech_krb5_wrong };
+
 /*
  * Test program for SPNEGO and gss_set_neg_mechs
  *
@@ -44,11 +50,13 @@ main(int argc, char *argv[])
 {
     OM_uint32 minor, major, flags;
     gss_cred_id_t verifier_cred_handle = GSS_C_NO_CREDENTIAL;
+    gss_cred_id_t initiator_cred_handle = GSS_C_NO_CREDENTIAL;
     gss_OID_set actual_mechs = GSS_C_NO_OID_SET;
-    gss_buffer_desc token = GSS_C_EMPTY_BUFFER, tmp = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER;
     gss_ctx_id_t initiator_context, acceptor_context;
     gss_name_t target_name, source_name = GSS_C_NO_NAME;
     gss_OID mech = GSS_C_NO_OID;
+    const unsigned char *atok_oid;
 
     if (argc < 2 || argc > 3) {
         fprintf(stderr, "Usage: %s target_name [keytab]\n", argv[0]);
@@ -83,10 +91,58 @@ main(int argc, char *argv[])
     (void)gss_delete_sec_context(&minor, &initiator_context, NULL);
     (void)gss_delete_sec_context(&minor, &acceptor_context, NULL);
     (void)gss_release_name(&minor, &source_name);
-    (void)gss_release_name(&minor, &target_name);
-    (void)gss_release_buffer(&minor, &token);
-    (void)gss_release_buffer(&minor, &tmp);
     (void)gss_release_cred(&minor, &verifier_cred_handle);
     (void)gss_release_oid_set(&minor, &actual_mechs);
+
+    /*
+     * Test that the SPNEGO acceptor code properly reflects back the erroneous
+     * Microsoft mech OID in the supportedMech field of the NegTokenResp
+     * message.  Our initiator code doesn't care (it treats all variants of the
+     * krb5 mech as equivalent when comparing the supportedMech response to its
+     * first-choice mech), so we have to look directly at the DER encoding of
+     * the response token.  If we don't request mutual authentication, the
+     * SPNEGO reply will contain no underlying mech token, so the encoding of
+     * the correct NegotiationToken response is completely predictable:
+     *
+     *   A1 14 (choice 1, length 20, meaning negTokenResp)
+     *     30 12 (sequence, length 18)
+     *       A0 03 (context tag 0, length 3)
+     *         0A 01 00 (enumerated value 0, meaning accept-completed)
+     *       A1 0B (context tag 1, length 11)
+     *         06 09 (object identifier, length 9)
+     *            2A 86 48 82 F7 12 01 02 02 (the erroneous krb5 OID)
+     *
+     * So we can just compare the length to 22 and the nine bytes at offset 13
+     * to the expected OID.
+     */
+    major = gss_acquire_cred(&minor, GSS_C_NO_NAME, GSS_C_INDEFINITE,
+                             &mechset_spnego, GSS_C_INITIATE,
+                             &initiator_cred_handle, NULL, NULL);
+    check_gsserr("gss_acquire_cred(2)", major, minor);
+    major = gss_set_neg_mechs(&minor, initiator_cred_handle,
+                              &mechset_krb5_wrong);
+    check_gsserr("gss_set_neg_mechs(2)", major, minor);
+    major = gss_init_sec_context(&minor, initiator_cred_handle,
+                                 &initiator_context, target_name, &mech_spnego,
+                                 flags, GSS_C_INDEFINITE,
+                                 GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL, &itok,
+                                 NULL, NULL);
+    check_gsserr("gss_init_sec_context", major, minor);
+    assert(major == GSS_S_CONTINUE_NEEDED);
+    major = gss_accept_sec_context(&minor, &acceptor_context,
+                                   GSS_C_NO_CREDENTIAL, &itok,
+                                   GSS_C_NO_CHANNEL_BINDINGS, NULL,
+                                   NULL, &atok, NULL, NULL, NULL);
+    assert(atok.length == 22);
+    atok_oid = (unsigned char *)atok.value + 13;
+    assert(memcmp(atok_oid, mech_krb5_wrong.elements, 9) == 0);
+    check_gsserr("gss_accept_sec_context", major, minor);
+
+    (void)gss_delete_sec_context(&minor, &initiator_context, NULL);
+    (void)gss_delete_sec_context(&minor, &acceptor_context, NULL);
+    (void)gss_release_cred(&minor, &initiator_cred_handle);
+    (void)gss_release_name(&minor, &target_name);
+    (void)gss_release_buffer(&minor, &itok);
+    (void)gss_release_buffer(&minor, &atok);
     return 0;
 }


More information about the cvs-krb5 mailing list