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
__OID_equal(const gss_OID_desc * const oid1,const gss_OID_desc * const oid2)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
__OID_nel(const gss_OID_desc * const oid)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
__OID_copy_desc(gss_OID dest,const gss_OID_desc * const source)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
__OID_copy(gss_OID * dest,const gss_OID_desc * const source)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
__OID_is_member(gss_OID_set set,const gss_OID_desc * const element)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
__OID_copy_set(gss_OID_set * dest,gss_OID_set source)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
__OID_copy_set_from_array(gss_OID_set * dest,const gss_OID_desc * array[],size_t nel)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
__OID_to_OID_set(gss_OID_set * set,const gss_OID_desc * const oid)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