Add some OID manipulation functions
authorLuke Howard <lukeh@padl.com>
Wed, 8 Sep 2010 12:26:33 +0000 (14:26 +0200)
committerLuke Howard <lukeh@padl.com>
Wed, 8 Sep 2010 12:26:33 +0000 (14:26 +0200)
Makefile.am
gssapiP_eap.h
gssapi_eap.h
mech_eap.exports
release_oid.c [new file with mode: 0644]
util.h
util_context.c
util_mech.c [new file with mode: 0644]
util_oid.c [new file with mode: 0644]
util_token.c

index a347b7a..37aa441 100644 (file)
@@ -44,6 +44,7 @@ libmech_eap_la_SOURCES =                      \
        release_any_name_mapping.c              \
        release_cred.c                          \
        release_name.c                          \
+       release_oid.c                           \
        set_name_attribute.c                    \
        set_cred_option.c                       \
        set_sec_context_option.c                \
@@ -54,7 +55,9 @@ libmech_eap_la_SOURCES =                      \
        util_cksum.c                            \
        util_cred.c                             \
        util_crypt.c                            \
+       util_mech.c                             \
        util_name.c                             \
+       util_oid.c                              \
        util_ordering.c                         \
        util_token.c                            \
        verify_mic.c                            \
index 806c5dd..9bb77d3 100644 (file)
@@ -53,7 +53,6 @@
 
 /* Kerberos includes */
 #include <krb5.h>
-#include "util.h"
 
 struct gss_name_struct {
     OM_uint32 flags;
@@ -171,4 +170,6 @@ gssEapUnwrapOrVerifyMIC(OM_uint32 *minor_status,
                         enum gss_eap_token_type toktype);
 
 
+#include "util.h"
+
 #endif /* _GSSAPIP_EAP_H_ */
index 5f4884b..20533d6 100644 (file)
 extern "C" {
 #endif /* __cplusplus */
 
+/* preferred mechanism */
 extern const gss_OID_desc *const gss_mech_eap;
+
+/* concrete mechanisms */
 extern const gss_OID_desc *const gss_mech_eap_aes128_cts_hmac_sha1_96;
 extern const gss_OID_desc *const gss_mech_eap_aes256_cts_hmac_sha1_96;
 
index a6e2e77..e84fef7 100644 (file)
@@ -28,6 +28,7 @@ gss_process_context_token
 gss_pseudo_random
 gss_release_any_name_mapping
 gss_release_cred
+gss_internal_release_oid
 gss_release_name
 gss_set_name_attribute
 gss_store_cred
diff --git a/release_oid.c b/release_oid.c
new file mode 100644 (file)
index 0000000..874efc2
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * 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 "gssapiP_eap.h"
+
+OM_uint32
+gss_internal_release_oid(OM_uint32 *minor,
+                         gss_OID *oid)
+{
+    OM_uint32 major;
+    gss_OID internalizedOid = GSS_C_NO_OID;
+
+    gssEapInternalizeOid(*oid, &internalizedOid);
+
+    if (*oid != internalizedOid) {
+        /* OID was internalized, so we can mark it as "freed" */
+        *oid = GSS_C_NO_OID;
+        return GSS_S_COMPLETE;
+    }
+
+    /* we don't know about this OID */
+    return GSS_S_CONTINUE_NEEDED;
+}
diff --git a/util.h b/util.h
index 246da38..cc56fe3 100644 (file)
--- a/util.h
+++ b/util.h
 #ifndef _UTIL_H_
 #define _UTIL_H_ 1
 
-/* Helper APIs */
+#define KRB_KEYTYPE(key)        ((key)->enctype)
+
+int
+gssEapSign(krb5_context context,
+           krb5_cksumtype type,
+           size_t rrc,
+           krb5_keyblock *key,
+           krb5_keyusage sign_usage,
+           gss_iov_buffer_desc *iov,
+           int iov_count);
+
+int
+gssEapVerify(krb5_context context,
+             krb5_cksumtype type,
+             size_t rrc,  
+             krb5_keyblock *key,
+             krb5_keyusage sign_usage,
+             gss_iov_buffer_desc *iov,
+             int iov_count,
+             int *valid);
+
+/* util_context.c */
 OM_uint32 gssEapAllocContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
 OM_uint32 gssEapReleaseContext(OM_uint32 *minor, gss_ctx_id_t *pCtx);
 
-OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName);
-OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName);
-
+/* util_cred.c */
 OM_uint32 gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred);
 OM_uint32 gssEapReleaseCred(OM_uint32 *minor, gss_cred_id_t *pCred);
 
-/* Kerberos token services */
-#define KRB_KEYTYPE(key)        ((key)->enctype)
-
 /* util_crypt.c */
 int
 gssEapEncrypt(krb5_context context, int dce_style, size_t ec,
@@ -104,25 +120,54 @@ gssEapIsIntegrityOnly(gss_iov_buffer_desc *iov, int iov_count);
 int
 gssEapAllocIov(gss_iov_buffer_t iov, size_t size);
 
-/* util_cksum.c */
-int
-gssEapSign(krb5_context context,
-           krb5_cksumtype type,
-           size_t rrc,
-           krb5_keyblock *key,
-           krb5_keyusage sign_usage,
-           gss_iov_buffer_desc *iov,
-           int iov_count);
+/* util_mech.c */
+void
+gssEapInternalizeOid(const gss_OID oid,
+                     gss_OID *const pInternalizedOid);
 
-int
-gssEapVerify(krb5_context context,
-             krb5_cksumtype type,
-             size_t rrc,  
-             krb5_keyblock *key,
-             krb5_keyusage sign_usage,
-             gss_iov_buffer_desc *iov,
-             int iov_count,
-             int *valid);
+OM_uint32
+gssEapDefaultMech(OM_uint32 *minor,
+                  gss_OID *oid);
+
+OM_uint32
+gssEapIndicateMechs(OM_uint32 *minor,
+                    gss_OID_set *mechs);
+
+OM_uint32
+gssEapEnctypeToOid(OM_uint32 *minor,
+                   krb5_enctype enctype,
+                   gss_OID *pOid);
+
+OM_uint32
+gssEapOidToEnctype(OM_uint32 *minor,
+                   const gss_OID oid,
+                   krb5_enctype *enctype);
+
+/* util_name.c */
+OM_uint32 gssEapAllocName(OM_uint32 *minor, gss_name_t *pName);
+OM_uint32 gssEapReleaseName(OM_uint32 *minor, gss_name_t *pName);
+
+/* util_oid.c */
+OM_uint32
+composeOid(OM_uint32 *minor_status,
+           const char *prefix,
+           size_t prefix_len,
+           int suffix,  
+           gss_OID_desc *oid);
+
+OM_uint32
+decomposeOid(OM_uint32 *minor_status,
+             const char *prefix,
+             size_t prefix_len,
+             gss_OID_desc *oid,
+             int *suffix) ;
+
+static inline int
+oidEqual(const gss_OID_desc *o1, const gss_OID_desc  *o2)
+{
+    return (o1->length == o2->length &&
+            memcmp(o1->elements, o2->elements, o1->length) == 0);
+}
 
 /* util_ordering.c */
 int
@@ -148,6 +193,19 @@ sequenceInit(void **vqueue, uint64_t seqnum,
 size_t
 tokenSize(const gss_OID_desc *mech, size_t body_size);
 
+void
+makeTokenHeader(const gss_OID_desc *mech,
+                size_t body_size,
+                unsigned char **buf,
+                enum gss_eap_token_type tok_type);
+
+int
+verifyTokenHeader(const gss_OID_desc * mech,
+                  size_t *body_size,
+                  unsigned char **buf_in,
+                  size_t toksize_in,
+                  enum gss_eap_token_type tok_type);
+
 /* Helper macros */
 #define GSSEAP_CALLOC(count, size)      (calloc((count), (size)))
 #define GSSEAP_FREE(ptr)                (free((ptr)))
@@ -222,11 +280,4 @@ load_uint64_be(const void *cvp)
     return ((uint64_t)load_uint32_be(p) << 32) | load_uint32_be(p + 4);
 }
 
-static inline int
-oidEqual(const gss_OID_desc *o1, const gss_OID_desc  *o2)
-{
-    return (o1->length == o2->length &&
-            memcmp(o1->elements, o2->elements, o1->length) == 0);
-}
-
 #endif /* _UTIL_H_ */
index a29bd7e..d7a87d3 100644 (file)
@@ -97,7 +97,7 @@ gssEapReleaseContext(OM_uint32 *minor,
 
     gssEapReleaseName(&tmpMinor, &ctx->initiatorName);
     gssEapReleaseName(&tmpMinor, &ctx->acceptorName);
-
+    gss_release_oid(&tmpMinor, &ctx->mechanismUsed);
     sequenceFree(ctx->seqState);
 
     memset(ctx, 0, sizeof(*ctx));
diff --git a/util_mech.c b/util_mech.c
new file mode 100644 (file)
index 0000000..7d7990a
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2010, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * 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 "gssapiP_eap.h"
+
+/*
+ * 1.3.6.1.4.1.5322(padl)
+ *      gssEap(21)
+ *       mechanisms(1)
+ *        eap-aes128-cts-hmac-sha1-96(17)
+ *        eap-aes256-cts-hmac-sha1-96(18)
+ *       nameTypes(2)
+ *       apiExtensions(3)
+ *        inquireSecContextByOid(1)
+ *        inquireCredByOid(2)
+ *        setSecContextOption(3)
+ *        setCredOption(4)
+ *        mechInvoke(5)
+ */
+
+/*
+ * Prefix for GSS EAP mechanisms. A Kerberos encryption type is
+ * concatenated with this to form a concrete mechanism OID.
+ */
+static const gss_OID_desc gssEapMechPrefix = {
+    /* 1.3.6.1.4.1.5322.21.1 */
+    11, "\x06\x09\x2B\x06\x01\x04\x01\xA9\x4A\x15\x01"
+};
+
+const gss_OID_desc *const gss_mech_eap = &gssEapMechPrefix;
+
+static const gss_OID_desc gssEapConcreteMechs[] = {
+    /* 1.3.6.1.4.1.5322.21.1.17 */
+    { 12, "\x06\x0A\x2B\x06\x01\x04\x01\xA9\x4A\x15\x01\x11" },
+    /* 1.3.6.1.4.1.5322.21.1.18 */
+    { 12, "\x06\x0A\x2B\x06\x01\x04\x01\xA9\x4A\x15\x01\x12" }
+};
+
+const gss_OID_desc *const gss_mech_eap_aes128_cts_hmac_sha1_96 =
+    &gssEapConcreteMechs[0];
+const gss_OID_desc *const gss_mech_eap_aes256_cts_hmac_sha1_96 =
+    &gssEapConcreteMechs[1];
+
+OM_uint32
+gssEapOidToEnctype(OM_uint32 *minor,
+                   const gss_OID oid,
+                   krb5_enctype *enctype)
+{
+    OM_uint32 major;
+    int suffix;
+
+    major = decomposeOid(minor,
+                         gssEapMechPrefix.elements,
+                         gssEapMechPrefix.length,
+                         oid,
+                         &suffix);
+    if (major == GSS_S_COMPLETE)
+        *enctype = suffix;
+
+    return major;
+}
+
+OM_uint32
+gssEapEnctypeToOid(OM_uint32 *minor,
+                   krb5_enctype enctype,
+                   gss_OID *pOid)
+{
+    OM_uint32 major;
+    gss_OID oid;
+
+    *pOid = NULL;
+
+    oid = (gss_OID)GSSEAP_MALLOC(sizeof(*oid));
+    if (oid == NULL) {
+        *minor = ENOMEM;
+        return GSS_S_FAILURE;
+    }
+
+    oid->elements = GSSEAP_MALLOC(gssEapMechPrefix.length + 2);
+    if (oid->elements == NULL) {
+        *minor = ENOMEM;
+        free(oid);
+        return GSS_S_FAILURE;
+    }
+
+    major = composeOid(minor,
+                       gssEapMechPrefix.elements,
+                       gssEapMechPrefix.length,
+                       enctype,
+                       oid);
+    if (major == GSS_S_COMPLETE) {
+        gssEapInternalizeOid(oid, pOid);
+        *pOid = oid;
+    } else {
+        free(oid->elements);
+        free(oid);
+    }
+
+    return major;
+}
+
+OM_uint32
+gssEapIndicateMechs(OM_uint32 *minor,
+                    gss_OID_set *mechs)
+{
+    krb5_context context;
+    OM_uint32 major, tmpMinor;
+    krb5_enctype *etypes;
+    int i;
+
+    *minor = krb5_init_context(&context);
+    if (*minor != 0) {
+        return GSS_S_FAILURE;
+    }
+
+    *minor = krb5_get_permitted_enctypes(context, &etypes);
+    if (*minor != 0) {
+        krb5_free_context(context);
+        return GSS_S_FAILURE;
+    }
+
+    major = gss_create_empty_oid_set(minor, mechs);
+    if (GSS_ERROR(major)) {
+        krb5_free_context(context);
+        GSSEAP_FREE(etypes); /* XXX */
+        return major;
+    }
+
+    for (i = 0; etypes[i] != ENCTYPE_NULL; i++) {
+        gss_OID mechOid;
+
+        major = gssEapEnctypeToOid(minor, etypes[i], &mechOid);
+        if (GSS_ERROR(major))
+            break;
+
+        major = gss_add_oid_set_member(minor, mechOid, mechs);
+        if (GSS_ERROR(major))
+            break;
+
+        gss_release_oid(&tmpMinor, &mechOid);
+    }
+
+    GSSEAP_FREE(etypes); /* XXX */
+    krb5_free_context(context);
+
+    return major;
+}
+
+OM_uint32
+gssEapDefaultMech(OM_uint32 *minor,
+                  gss_OID *oid)
+{
+    gss_OID_set mechs;
+    OM_uint32 major, tmpMinor;
+
+    major = gssEapIndicateMechs(minor, &mechs);
+    if (GSS_ERROR(major)) {
+        return major;
+    }
+
+    if (mechs->count == 0) {
+        gss_release_oid_set(&tmpMinor, &mechs);
+        return GSS_S_BAD_MECH;
+    }
+
+    gssEapInternalizeOid(&mechs->elements[0], oid);
+    if (*oid == &mechs->elements[0]) {
+        /* don't double-free if we didn't internalize it */
+        mechs->elements[0].length = 0;
+        mechs->elements[0].elements = NULL;
+    }
+
+    gss_release_oid_set(&tmpMinor, &mechs);
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
+void
+gssEapInternalizeOid(const gss_OID oid,
+                     gss_OID *const pInternalizedOid)
+{
+    int i;
+
+    *pInternalizedOid = GSS_C_NO_OID;
+
+    if (oidEqual(oid, &gssEapMechPrefix)) {
+        *pInternalizedOid = (const gss_OID)&gssEapMechPrefix;
+    } else {
+        for (i = 0;
+             i < sizeof(gssEapConcreteMechs) / sizeof(gssEapConcreteMechs[0]);
+             i++) {
+            if (oidEqual(oid, &gssEapConcreteMechs[i])) {
+                *pInternalizedOid = (const gss_OID)&gssEapConcreteMechs[i];
+                break;
+            }
+        }
+    }
+
+    if (*pInternalizedOid == GSS_C_NO_OID) {
+        *pInternalizedOid = oid;
+    }
+}
diff --git a/util_oid.c b/util_oid.c
new file mode 100644 (file)
index 0000000..34b7c7b
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2010, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * 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.
+ */
+/*
+ * Copyright 1995-2010 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.
+ *
+ */
+
+#include "gssapiP_eap.h"
+
+#if 0
+OM_uint32
+copyOid(OM_uint32 *minor_status,
+        const gss_OID_desc * const oid,
+        gss_OID *new_oid)
+{
+    gss_OID         p;
+
+    *minor_status = 0;
+
+    p = (gss_OID) malloc(sizeof(gss_OID_desc));
+    if (!p) {
+        *minor_status = ENOMEM;
+        return GSS_S_FAILURE;
+    }
+    p->length = oid->length;
+    p->elements = malloc(p->length);
+    if (!p->elements) {
+        free(p);
+        return GSS_S_FAILURE;
+    }
+    memcpy(p->elements, oid->elements, p->length);
+    *new_oid = p;
+    return(GSS_S_COMPLETE);
+}
+#endif
+
+/* Compose an OID of a prefix and an integer suffix */
+OM_uint32
+composeOid(OM_uint32 *minor_status,
+           const char *prefix,
+           size_t prefix_len,
+           int suffix,
+           gss_OID_desc *oid)
+{
+    int osuffix, i;
+    size_t nbytes;
+    unsigned char *op;
+
+    if (oid == GSS_C_NO_OID) {
+        *minor_status = EINVAL;
+        return GSS_S_FAILURE;
+    }
+    if (oid->length < prefix_len) {
+        *minor_status = ERANGE;
+        return GSS_S_FAILURE;
+    }
+
+    memcpy(oid->elements, prefix, prefix_len);
+
+    nbytes = 0;
+    osuffix = suffix;
+    while (suffix) {
+        nbytes++;
+        suffix >>= 7;
+    }
+    suffix = osuffix;
+
+    if (oid->length < prefix_len + nbytes) {
+        *minor_status = ERANGE;
+        return GSS_S_FAILURE;
+    }
+
+    op = (unsigned char *) oid->elements + prefix_len + nbytes;
+    i = -1;
+    while (suffix) {
+        op[i] = (unsigned char)suffix & 0x7f;
+        if (i != -1)
+            op[i] |= 0x80;
+        i--;
+        suffix >>= 7;
+    }
+
+    oid->length = prefix_len + nbytes;
+
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32
+decomposeOid(OM_uint32 *minor_status,
+             const char *prefix,
+             size_t prefix_len,
+             gss_OID_desc *oid,
+             int *suffix)
+{
+    size_t i, slen;
+    unsigned char *op;
+
+    if (oid->length < prefix_len ||
+        memcmp(oid->elements, prefix, prefix_len) != 0) {
+        return GSS_S_BAD_MECH;
+    }
+
+    op = (unsigned char *) oid->elements + prefix_len;
+
+    *suffix = 0;
+
+    slen = oid->length - prefix_len;
+
+    for (i = 0; i < slen; i++) {
+        *suffix = (*suffix << 7) | (op[i] & 0x7f);
+        if (i + 1 != slen && (op[i] & 0x80) == 0) {
+            *minor_status = EINVAL;
+            return GSS_S_FAILURE;
+        }
+    }
+
+    return GSS_S_COMPLETE;
+}
+
+#if 0
+OM_uint32
+gssEapReleaseOid(OM_uint32 *minor, gss_OID *oid)
+{
+    OM_uint32 major;
+
+    major = gss_internal_release_oid(minor, oid);
+    if (major == GSS_S_CONTINUE_NEEDED) {
+        GSSEAP_FREE(oid->elements);
+        GSSEAP_FREE(oid);
+        *oid = GSS_C_NO_OID;
+        major = GSS_S_COMPLETE;
+    }
+
+    return major;
+}
+#endif
index 11ae346..bb7ef7a 100644 (file)
@@ -89,19 +89,19 @@ static size_t
 der_length_size(size_t length)
 {
     if (length < (1<<7))
-        return(1);
+        return 1;
     else if (length < (1<<8))
-        return(2);
+        return 2;
 #if INT_MAX == 0x7fff
     else
-        return(3);
+        return 3;
 #else
     else if (length < (1<<16))
-        return(3);
+        return 3;
     else if (length < (1<<24))
-        return(4);
+        return 4;
     else
-        return(5);
+        return 5;
 #endif
 }
 
@@ -140,9 +140,9 @@ der_read_length(unsigned char **buf, ssize_t *bufsize)
     (*bufsize)--;
     if (sf & 0x80) {
         if ((sf &= 0x7f) > ((*bufsize)-1))
-            return(-1);
+            return -1;
         if (sf > sizeof(int))
-            return (-1);
+            return -1;
         ret = 0;
         for (; sf; sf--) {
             ret = (ret<<8) + (*(*buf)++);
@@ -162,7 +162,7 @@ tokenSize(const gss_OID_desc *mech, size_t body_size)
 {
     /* set body_size to sequence contents size */
     body_size += 4 + (size_t) mech->length;         /* NEED overflow check */
-    return (1 + der_length_size(body_size) + body_size);
+    return 1 + der_length_size(body_size) + body_size;
 }
 
 /* fills in a buffer with the token header.  The buffer is assumed to
@@ -246,7 +246,7 @@ verifyTokenHeader(
         if (toksize -= 2 < 0)
             return EINVAL;
 
-        if ((*buf++ != ((tok_type>>8) & 0xff)) ||
+        if ((*buf++ != ((tok_type >> 8) & 0xff)) ||
             (*buf++ != (tok_type & 0xff)))
             return EINVAL;
     }