2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * oid.c
2N/A *
2N/A * Copyright (c) 1997, by Sun Microsystems, Inc.
2N/A * All rights reserved.
2N/A *
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A#include <string.h>
2N/A#include "dh_gssapi.h"
2N/A
2N/A/*
2N/A * These are private mech_dh oid support routines.
2N/A */
2N/A
2N/A/* See if two oids have the same value */
2N/Aint
2N/A__OID_equal(const gss_OID_desc * const oid1, const gss_OID_desc * const oid2)
2N/A{
2N/A if (oid1->length != oid2->length)
2N/A return (0);
2N/A return (memcmp(oid1->elements, oid2->elements, oid1->length) == 0);
2N/A}
2N/A
2N/A
2N/A/* Count the number of elements in an oid. Return -1 on badly formed OID */
2N/Aint
2N/A__OID_nel(const gss_OID_desc * const oid)
2N/A{
2N/A int i;
2N/A unsigned char *p = (unsigned char *)oid->elements;
2N/A unsigned char *e = p + oid->length;
2N/A
2N/A /* For each byte */
2N/A for (i = 0; p < e; i++) {
2N/A /* If the upper bit is set it is part of this element */
2N/A while (*p & 0x80) {
2N/A p++;
2N/A if (p == e)
2N/A return (-1);
2N/A }
2N/A p++;
2N/A }
2N/A
2N/A return (i);
2N/A}
2N/A
2N/A/* Copy an oid to an allocated gss_OID_desc */
2N/AOM_uint32
2N/A__OID_copy_desc(gss_OID dest, const gss_OID_desc * const source)
2N/A{
2N/A dest->length = 0;
2N/A /* Allocate the elements of the new OID */
2N/A dest->elements = (void *)New(char, source->length);
2N/A if (dest->elements == NULL)
2N/A return (DH_NOMEM_FAILURE);
2N/A
2N/A /* Set the length */
2N/A dest->length = source->length;
2N/A
2N/A /* And copy the elements */
2N/A memcpy(dest->elements, source->elements, dest->length);
2N/A
2N/A return (DH_SUCCESS);
2N/A}
2N/A
2N/A/* Copy an oid, allocating storage */
2N/AOM_uint32
2N/A__OID_copy(gss_OID *dest, const gss_OID_desc * const source)
2N/A{
2N/A /* Allocate a new OID */
2N/A gss_OID oid = New(gss_OID_desc, 1);
2N/A
2N/A /* Clear the destination */
2N/A *dest = NULL;
2N/A
2N/A /* return failure if no memory for oid */
2N/A if (oid == NULL)
2N/A return (DH_NOMEM_FAILURE);
2N/A
2N/A /* Copy the soure oid in to the new OID */
2N/A if (__OID_copy_desc(oid, source) != DH_SUCCESS) {
2N/A Free(oid);
2N/A return (DH_NOMEM_FAILURE);
2N/A }
2N/A
2N/A /* Set the destination oid */
2N/A *dest = oid;
2N/A return (DH_SUCCESS);
2N/A}
2N/A
2N/A/* Check if an oid is a member of an oid set */
2N/Aint
2N/A__OID_is_member(gss_OID_set set, const gss_OID_desc * const element)
2N/A{
2N/A int i;
2N/A
2N/A /* For each member in the set ... */
2N/A for (i = 0; i < set->count; i++)
2N/A if (__OID_equal(element, &set->elements[i]))
2N/A return (TRUE);
2N/A
2N/A return (FALSE);
2N/A}
2N/A
2N/A/* Copy oid set to a newly allocated set */
2N/AOM_uint32
2N/A__OID_copy_set(gss_OID_set *dest, gss_OID_set source)
2N/A{
2N/A gss_OID_set set;
2N/A int i;
2N/A
2N/A /* Clear the destination */
2N/A *dest = GSS_C_NO_OID_SET;
2N/A
2N/A /* Allocate a new container for the set */
2N/A set = New(gss_OID_set_desc, 1);
2N/A if (set == NULL)
2N/A return (DH_NOMEM_FAILURE);
2N/A
2N/A /* Allocate storage for the elements of the set */
2N/A set->elements = New(gss_OID_desc, source->count);
2N/A if (set->elements == NULL) {
2N/A Free(set);
2N/A return (DH_NOMEM_FAILURE);
2N/A }
2N/A /* set the number of elements in the set */
2N/A set->count = source->count;
2N/A
2N/A /* Add each member of the source set to the new set */
2N/A for (i = 0; i < source->count; i++)
2N/A if (__OID_copy_desc(&set->elements[i], &source->elements[i])
2N/A != DH_SUCCESS)
2N/A break;
2N/A
2N/A /* Free partially allocated set on error */
2N/A if (i != source->count) {
2N/A for (; i >= 0; i--)
2N/A Free(set->elements[i].elements);
2N/A Free(set->elements);
2N/A Free(set);
2N/A return (DH_NOMEM_FAILURE);
2N/A }
2N/A
2N/A /* Set the destination to the set */
2N/A *dest = set;
2N/A
2N/A return (DH_SUCCESS);
2N/A}
2N/A
2N/A/*
2N/A * Form a gss_OID_set from an array of gss_OID_desc.
2N/A */
2N/AOM_uint32
2N/A__OID_copy_set_from_array(gss_OID_set *dest,
2N/A const gss_OID_desc *array[], size_t nel)
2N/A{
2N/A gss_OID_set set;
2N/A int i;
2N/A
2N/A /* Clear the output set */
2N/A *dest = GSS_C_NO_OID_SET;
2N/A
2N/A /* Allocate the set */
2N/A set = New(gss_OID_set_desc, 1);
2N/A if (set == NULL)
2N/A return (DH_NOMEM_FAILURE);
2N/A
2N/A /* And space for the members */
2N/A set->elements = New(gss_OID_desc, nel);
2N/A if (set->elements == NULL) {
2N/A Free(set);
2N/A return (DH_NOMEM_FAILURE);
2N/A }
2N/A /* Set the set count */
2N/A set->count = nel;
2N/A
2N/A /* For each element in the array, addit to the set */
2N/A for (i = 0; i < set->count; i++)
2N/A if (__OID_copy_desc(&set->elements[i], array[i])
2N/A != DH_SUCCESS)
2N/A break;
2N/A
2N/A /* if we failed recover memory */
2N/A if (i != set->count) {
2N/A for (; i >= 0; i--)
2N/A Free(set->elements[i].elements);
2N/A Free(set->elements);
2N/A Free(set);
2N/A return (DH_NOMEM_FAILURE);
2N/A }
2N/A
2N/A /* Set the destination */
2N/A *dest = set;
2N/A
2N/A return (DH_SUCCESS);
2N/A}
2N/A
2N/A/*
2N/A * Given an oid create a GSS_OID_set with a copy of that oid as its
2N/A * sole member.
2N/A */
2N/AOM_uint32
2N/A__OID_to_OID_set(gss_OID_set *set, const gss_OID_desc * const oid)
2N/A{
2N/A int rc;
2N/A gss_OID_set s;
2N/A
2N/A /* Nothing to do */
2N/A if (set == NULL)
2N/A return (DH_SUCCESS);
2N/A
2N/A /* Allocate a set description */
2N/A if ((s = New(gss_OID_set_desc, 1)) == NULL)
2N/A return (DH_NOMEM_FAILURE);
2N/A
2N/A /* Add the OID to the set */
2N/A s->count = 1;
2N/A if (rc = __OID_copy(&s->elements, oid)) {
2N/A Free(s);
2N/A return (rc);
2N/A }
2N/A
2N/A /* return the set */
2N/A *set = s;
2N/A
2N/A return (DH_SUCCESS);
2N/A}