1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * oid.c 24 * 25 * Copyright (c) 1997, by Sun Microsystems, Inc. 26 * All rights reserved. 27 * 28 */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <string.h> 33 #include "dh_gssapi.h" 34 35 /* 36 * These are private mech_dh oid support routines. 37 */ 38 39 /* See if two oids have the same value */ 40 int 41 __OID_equal(const gss_OID_desc * const oid1, const gss_OID_desc * const oid2) 42 { 43 if (oid1->length != oid2->length) 44 return (0); 45 return (memcmp(oid1->elements, oid2->elements, oid1->length) == 0); 46 } 47 48 49 /* Count the number of elements in an oid. Return -1 on badly formed OID */ 50 int 51 __OID_nel(const gss_OID_desc * const oid) 52 { 53 int i; 54 unsigned char *p = (unsigned char *)oid->elements; 55 unsigned char *e = p + oid->length; 56 57 /* For each byte */ 58 for (i = 0; p < e; i++) { 59 /* If the upper bit is set it is part of this element */ 60 while (*p & 0x80) { 61 p++; 62 if (p == e) 63 return (-1); 64 } 65 p++; 66 } 67 68 return (i); 69 } 70 71 /* Copy an oid to an allocated gss_OID_desc */ 72 OM_uint32 73 __OID_copy_desc(gss_OID dest, const gss_OID_desc * const source) 74 { 75 dest->length = 0; 76 /* Allocate the elements of the new OID */ 77 dest->elements = (void *)New(char, source->length); 78 if (dest->elements == NULL) 79 return (DH_NOMEM_FAILURE); 80 81 /* Set the length */ 82 dest->length = source->length; 83 84 /* And copy the elements */ 85 memcpy(dest->elements, source->elements, dest->length); 86 87 return (DH_SUCCESS); 88 } 89 90 /* Copy an oid, allocating storage */ 91 OM_uint32 92 __OID_copy(gss_OID *dest, const gss_OID_desc * const source) 93 { 94 /* Allocate a new OID */ 95 gss_OID oid = New(gss_OID_desc, 1); 96 97 /* Clear the destination */ 98 *dest = NULL; 99 100 /* return failure if no memory for oid */ 101 if (oid == NULL) 102 return (DH_NOMEM_FAILURE); 103 104 /* Copy the soure oid in to the new OID */ 105 if (__OID_copy_desc(oid, source) != DH_SUCCESS) { 106 Free(oid); 107 return (DH_NOMEM_FAILURE); 108 } 109 110 /* Set the destination oid */ 111 *dest = oid; 112 return (DH_SUCCESS); 113 } 114 115 /* Check if an oid is a member of an oid set */ 116 int 117 __OID_is_member(gss_OID_set set, const gss_OID_desc * const element) 118 { 119 int i; 120 121 /* For each member in the set ... */ 122 for (i = 0; i < set->count; i++) 123 if (__OID_equal(element, &set->elements[i])) 124 return (TRUE); 125 126 return (FALSE); 127 } 128 129 /* Copy oid set to a newly allocated set */ 130 OM_uint32 131 __OID_copy_set(gss_OID_set *dest, gss_OID_set source) 132 { 133 gss_OID_set set; 134 int i; 135 136 /* Clear the destination */ 137 *dest = GSS_C_NO_OID_SET; 138 139 /* Allocate a new container for the set */ 140 set = New(gss_OID_set_desc, 1); 141 if (set == NULL) 142 return (DH_NOMEM_FAILURE); 143 144 /* Allocate storage for the elements of the set */ 145 set->elements = New(gss_OID_desc, source->count); 146 if (set->elements == NULL) { 147 Free(set); 148 return (DH_NOMEM_FAILURE); 149 } 150 /* set the number of elements in the set */ 151 set->count = source->count; 152 153 /* Add each member of the source set to the new set */ 154 for (i = 0; i < source->count; i++) 155 if (__OID_copy_desc(&set->elements[i], &source->elements[i]) 156 != DH_SUCCESS) 157 break; 158 159 /* Free partially allocated set on error */ 160 if (i != source->count) { 161 for (; i >= 0; i--) 162 Free(set->elements[i].elements); 163 Free(set->elements); 164 Free(set); 165 return (DH_NOMEM_FAILURE); 166 } 167 168 /* Set the destination to the set */ 169 *dest = set; 170 171 return (DH_SUCCESS); 172 } 173 174 /* 175 * Form a gss_OID_set from an array of gss_OID_desc. 176 */ 177 OM_uint32 178 __OID_copy_set_from_array(gss_OID_set *dest, 179 const gss_OID_desc *array[], size_t nel) 180 { 181 gss_OID_set set; 182 int i; 183 184 /* Clear the output set */ 185 *dest = GSS_C_NO_OID_SET; 186 187 /* Allocate the set */ 188 set = New(gss_OID_set_desc, 1); 189 if (set == NULL) 190 return (DH_NOMEM_FAILURE); 191 192 /* And space for the members */ 193 set->elements = New(gss_OID_desc, nel); 194 if (set->elements == NULL) { 195 Free(set); 196 return (DH_NOMEM_FAILURE); 197 } 198 /* Set the set count */ 199 set->count = nel; 200 201 /* For each element in the array, addit to the set */ 202 for (i = 0; i < set->count; i++) 203 if (__OID_copy_desc(&set->elements[i], array[i]) 204 != DH_SUCCESS) 205 break; 206 207 /* if we failed recover memory */ 208 if (i != set->count) { 209 for (; i >= 0; i--) 210 Free(set->elements[i].elements); 211 Free(set->elements); 212 Free(set); 213 return (DH_NOMEM_FAILURE); 214 } 215 216 /* Set the destination */ 217 *dest = set; 218 219 return (DH_SUCCESS); 220 } 221 222 /* 223 * Given an oid create a GSS_OID_set with a copy of that oid as its 224 * sole member. 225 */ 226 OM_uint32 227 __OID_to_OID_set(gss_OID_set *set, const gss_OID_desc * const oid) 228 { 229 int rc; 230 gss_OID_set s; 231 232 /* Nothing to do */ 233 if (set == NULL) 234 return (DH_SUCCESS); 235 236 /* Allocate a set description */ 237 if ((s = New(gss_OID_set_desc, 1)) == NULL) 238 return (DH_NOMEM_FAILURE); 239 240 /* Add the OID to the set */ 241 s->count = 1; 242 if (rc = __OID_copy(&s->elements, oid)) { 243 Free(s); 244 return (rc); 245 } 246 247 /* return the set */ 248 *set = s; 249 250 return (DH_SUCCESS); 251 } 252