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