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 #include <string.h> 31 #include "dh_gssapi.h" 32 33 /* 34 * These are private mech_dh oid support routines. 35 */ 36 37 /* See if two oids have the same value */ 38 int 39 __OID_equal(const gss_OID_desc * const oid1, const gss_OID_desc * const oid2) 40 { 41 if (oid1->length != oid2->length) 42 return (0); 43 return (memcmp(oid1->elements, oid2->elements, oid1->length) == 0); 44 } 45 46 47 /* Count the number of elements in an oid. Return -1 on badly formed OID */ 48 int 49 __OID_nel(const gss_OID_desc * const oid) 50 { 51 int i; 52 unsigned char *p = (unsigned char *)oid->elements; 53 unsigned char *e = p + oid->length; 54 55 /* For each byte */ 56 for (i = 0; p < e; i++) { 57 /* If the upper bit is set it is part of this element */ 58 while (*p & 0x80) { 59 p++; 60 if (p == e) 61 return (-1); 62 } 63 p++; 64 } 65 66 return (i); 67 } 68 69 /* Copy an oid to an allocated gss_OID_desc */ 70 OM_uint32 71 __OID_copy_desc(gss_OID dest, const gss_OID_desc * const source) 72 { 73 dest->length = 0; 74 /* Allocate the elements of the new OID */ 75 dest->elements = (void *)New(char, source->length); 76 if (dest->elements == NULL) 77 return (DH_NOMEM_FAILURE); 78 79 /* Set the length */ 80 dest->length = source->length; 81 82 /* And copy the elements */ 83 memcpy(dest->elements, source->elements, dest->length); 84 85 return (DH_SUCCESS); 86 } 87 88 /* Copy an oid, allocating storage */ 89 OM_uint32 90 __OID_copy(gss_OID *dest, const gss_OID_desc * const source) 91 { 92 /* Allocate a new OID */ 93 gss_OID oid = New(gss_OID_desc, 1); 94 95 /* Clear the destination */ 96 *dest = NULL; 97 98 /* return failure if no memory for oid */ 99 if (oid == NULL) 100 return (DH_NOMEM_FAILURE); 101 102 /* Copy the soure oid in to the new OID */ 103 if (__OID_copy_desc(oid, source) != DH_SUCCESS) { 104 Free(oid); 105 return (DH_NOMEM_FAILURE); 106 } 107 108 /* Set the destination oid */ 109 *dest = oid; 110 return (DH_SUCCESS); 111 } 112 113 /* Check if an oid is a member of an oid set */ 114 int 115 __OID_is_member(gss_OID_set set, const gss_OID_desc * const element) 116 { 117 int i; 118 119 /* For each member in the set ... */ 120 for (i = 0; i < set->count; i++) 121 if (__OID_equal(element, &set->elements[i])) 122 return (TRUE); 123 124 return (FALSE); 125 } 126 127 /* Copy oid set to a newly allocated set */ 128 OM_uint32 129 __OID_copy_set(gss_OID_set *dest, gss_OID_set source) 130 { 131 gss_OID_set set; 132 int i; 133 134 /* Clear the destination */ 135 *dest = GSS_C_NO_OID_SET; 136 137 /* Allocate a new container for the set */ 138 set = New(gss_OID_set_desc, 1); 139 if (set == NULL) 140 return (DH_NOMEM_FAILURE); 141 142 /* Allocate storage for the elements of the set */ 143 set->elements = New(gss_OID_desc, source->count); 144 if (set->elements == NULL) { 145 Free(set); 146 return (DH_NOMEM_FAILURE); 147 } 148 /* set the number of elements in the set */ 149 set->count = source->count; 150 151 /* Add each member of the source set to the new set */ 152 for (i = 0; i < source->count; i++) 153 if (__OID_copy_desc(&set->elements[i], &source->elements[i]) 154 != DH_SUCCESS) 155 break; 156 157 /* Free partially allocated set on error */ 158 if (i != source->count) { 159 for (; i >= 0; i--) 160 Free(set->elements[i].elements); 161 Free(set->elements); 162 Free(set); 163 return (DH_NOMEM_FAILURE); 164 } 165 166 /* Set the destination to the set */ 167 *dest = set; 168 169 return (DH_SUCCESS); 170 } 171 172 /* 173 * Form a gss_OID_set from an array of gss_OID_desc. 174 */ 175 OM_uint32 176 __OID_copy_set_from_array(gss_OID_set *dest, 177 const gss_OID_desc *array[], size_t nel) 178 { 179 gss_OID_set set; 180 int i; 181 182 /* Clear the output set */ 183 *dest = GSS_C_NO_OID_SET; 184 185 /* Allocate the set */ 186 set = New(gss_OID_set_desc, 1); 187 if (set == NULL) 188 return (DH_NOMEM_FAILURE); 189 190 /* And space for the members */ 191 set->elements = New(gss_OID_desc, nel); 192 if (set->elements == NULL) { 193 Free(set); 194 return (DH_NOMEM_FAILURE); 195 } 196 /* Set the set count */ 197 set->count = nel; 198 199 /* For each element in the array, addit to the set */ 200 for (i = 0; i < set->count; i++) 201 if (__OID_copy_desc(&set->elements[i], array[i]) 202 != DH_SUCCESS) 203 break; 204 205 /* if we failed recover memory */ 206 if (i != set->count) { 207 for (; i >= 0; i--) 208 Free(set->elements[i].elements); 209 Free(set->elements); 210 Free(set); 211 return (DH_NOMEM_FAILURE); 212 } 213 214 /* Set the destination */ 215 *dest = set; 216 217 return (DH_SUCCESS); 218 } 219 220 /* 221 * Given an oid create a GSS_OID_set with a copy of that oid as its 222 * sole member. 223 */ 224 OM_uint32 225 __OID_to_OID_set(gss_OID_set *set, const gss_OID_desc * const oid) 226 { 227 int rc; 228 gss_OID_set s; 229 230 /* Nothing to do */ 231 if (set == NULL) 232 return (DH_SUCCESS); 233 234 /* Allocate a set description */ 235 if ((s = New(gss_OID_set_desc, 1)) == NULL) 236 return (DH_NOMEM_FAILURE); 237 238 /* Add the OID to the set */ 239 s->count = 1; 240 if (rc = __OID_copy(&s->elements, oid)) { 241 Free(s); 242 return (rc); 243 } 244 245 /* return the set */ 246 *set = s; 247 248 return (DH_SUCCESS); 249 } 250