]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c-lib/src/asn-oid.c
Security-54.1.7.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c-lib / src / asn-oid.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * asn_oid.c - BER encode, decode, print and free routines for the
21 * ASN.1 OBJECT IDENTIFIER type.
22 *
23 * MS 92
24 * Copyright (C) 1992 Michael Sample and the University of British Columbia
25 *
26 * This library is free software; you can redistribute it and/or
27 * modify it provided that this copyright/license information is retained
28 * in original form.
29 *
30 * If you modify this file, you must clearly indicate your changes.
31 *
32 * This source code is distributed in the hope that it will be
33 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
34 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
35 *
36 * $Header: /cvs/root/Security/SecuritySNACCRuntime/c-lib/src/Attic/asn-oid.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
37 * $Log: asn-oid.c,v $
38 * Revision 1.1.1.1 2001/05/18 23:14:08 mb
39 * Move from private repository to open source repository
40 *
41 * Revision 1.2 2001/05/05 00:59:25 rmurphy
42 * Adding darwin license headers
43 *
44 * Revision 1.1.1.1 1999/03/16 18:06:31 aram
45 * Originals from SMIME Free Library.
46 *
47 * Revision 1.3 1995/07/24 21:04:53 rj
48 * changed `_' to `-' in file names.
49 *
50 * Revision 1.2 1994/09/01 00:06:21 rj
51 * reduce the risk of unwanted surprises with macro expansion by properly separating the C tokens.
52 *
53 * Revision 1.1 1994/08/28 09:45:59 rj
54 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
55 *
56 */
57
58 #include "asn-config.h"
59 #include "asn-len.h"
60 #include "asn-tag.h"
61 #include "asn-octs.h"
62 #include "asn-oid.h"
63
64
65 /*
66 * encodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID
67 */
68 AsnLen
69 BEncAsnOid PARAMS ((b, data),
70 BUF_TYPE b _AND_
71 AsnOid *data)
72 {
73 AsnLen len;
74
75 len = BEncAsnOidContent (b, data);
76 len += BEncDefLen (b, len);
77 len += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
78 return len;
79 } /* BEncAsnOid */
80
81
82 /*
83 * decodes universal TAG LENGTH and Contents of and ASN.1 OBJECT ID
84 */
85 void
86 BDecAsnOid PARAMS ((b, result, bytesDecoded, env),
87 BUF_TYPE b _AND_
88 AsnOid *result _AND_
89 AsnLen *bytesDecoded _AND_
90 jmp_buf env)
91 {
92 AsnTag tag;
93 AsnLen elmtLen;
94
95 if ((tag = BDecTag (b, bytesDecoded, env)) != MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE))
96 {
97 Asn1Error ("BDecAsnOid: ERROR - wrong tag on OBJECT IDENTIFIER.\n");
98 longjmp (env, -40);
99 }
100
101 elmtLen = BDecLen (b, bytesDecoded, env);
102 BDecAsnOidContent (b, tag, elmtLen, result, bytesDecoded, env);
103
104 } /* BDecAsnOid */
105
106
107
108 /*
109 * Decodes just the content of the OID.
110 * AsnOid is handled the same as a primtive octet string
111 */
112 void
113 BDecAsnOidContent PARAMS ((b, tagId, len, result, bytesDecoded, env),
114 BUF_TYPE b _AND_
115 AsnTag tagId _AND_
116 AsnLen len _AND_
117 AsnOid *result _AND_
118 AsnLen *bytesDecoded _AND_
119 jmp_buf env)
120 {
121 result->octetLen = len;
122 result->octs = Asn1Alloc (len);
123 BufCopy (result->octs, b, len);
124 if (BufReadError (b))
125 {
126 Asn1Error ("BDecAsnOidContent: ERROR - decoded past end of data\n");
127 longjmp (env, -21);
128 }
129 (*bytesDecoded) += len;
130 } /* BDecAsnOidContent */
131
132
133
134 /*
135 * Prints the given OID to the given FILE * in ASN.1 Value Notation.
136 * Since the internal rep of an OID is 'encoded', this routine
137 * decodes each individual arc number to print it.
138 */
139 void
140 PrintAsnOid PARAMS ((f,v, indent),
141 FILE *f _AND_
142 AsnOid *v _AND_
143 unsigned short int indent)
144 {
145 unsigned short int firstArcNum;
146 unsigned long int arcNum;
147 int i;
148
149 fprintf (f,"{");
150
151 /* un-munge first two arc numbers */
152 for (arcNum = 0, i=0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
153 arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
154
155 arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
156 i++;
157 firstArcNum = arcNum/40;
158 if (firstArcNum > 2)
159 firstArcNum = 2;
160
161 fprintf (f,"%u %u", firstArcNum, arcNum - (firstArcNum * 40));
162
163 for (; i < v->octetLen; )
164 {
165 for (arcNum = 0; (i < v->octetLen) && (v->octs[i] & 0x80);i++)
166 arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
167
168 arcNum = (arcNum << 7) + (v->octs[i] & 0x7f);
169 i++;
170 fprintf (f," %u", arcNum);
171 }
172 fprintf (f,"}");
173
174 } /* PrintAsnOid */
175
176
177
178 /*
179 * given an OID, figures out the length for the encoded version
180 */
181 AsnLen
182 EncodedOidLen PARAMS ((oid),
183 OID *oid)
184 {
185 AsnLen totalLen;
186 unsigned long headArcNum;
187 unsigned long tmpArcNum;
188 OID *tmpOid;
189
190 /*
191 * oid must have at least 2 elmts
192 */
193 if (oid->next == NULL)
194 return 0;
195
196 headArcNum = (oid->arcNum * 40) + oid->next->arcNum;
197
198 /*
199 * figure out total encoded length of oid
200 */
201 tmpArcNum = headArcNum;
202 for (totalLen = 1; (tmpArcNum >>= 7) != 0; totalLen++)
203 ;
204 for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
205 {
206 totalLen++;
207 tmpArcNum = tmpOid->arcNum;
208 for (; (tmpArcNum >>= 7) != 0; totalLen++)
209 ;
210 }
211
212 return totalLen;
213
214 } /* EncodedOidLen */
215
216
217 /*
218 * given an oid list and a pre-allocated ENC_OID
219 * (use EncodedOidLen to figure out byte length needed)
220 * fills the ENC_OID with a BER encoded version
221 * of the oid.
222 */
223 void
224 BuildEncodedOid PARAMS ((oid, result),
225 OID *oid _AND_
226 AsnOid *result)
227 {
228 unsigned long len;
229 unsigned long headArcNum;
230 unsigned long tmpArcNum;
231 char *buf;
232 int i;
233 OID *tmpOid;
234
235 buf = result->octs;
236
237 /*
238 * oid must have at least 2 elmts
239 */
240 if (oid->next == NULL)
241 return;
242 /*
243 * munge together first two arcNum
244 * note first arcnum must be <= 2
245 * and second must be < 39 if first = 0 or 1
246 * see (X.209) for ref to this stupidity
247 */
248 headArcNum = (oid->arcNum * 40) + oid->next->arcNum;
249
250 tmpArcNum = headArcNum;
251
252 /*
253 * calc # bytes needed for head arc num
254 */
255 for (len = 0; (tmpArcNum >>= 7) != 0; len++)
256 ;
257
258 /*
259 * write more signifcant bytes (if any) of head arc num
260 * with 'more' bit set
261 */
262 for (i=0; i < len; i++)
263 *(buf++) = 0x80 | (headArcNum >> ((len-i)*7));
264
265 /*
266 * write least significant byte of head arc num
267 */
268 *(buf++) = 0x7f & headArcNum;
269
270
271 /*
272 * write following arc nums, if any
273 */
274 for (tmpOid = oid->next->next; tmpOid != NULL; tmpOid = tmpOid->next)
275 {
276 /*
277 * figure out encoded length -1 of this arcNum
278 */
279 tmpArcNum = tmpOid->arcNum;
280 for (len = 0; (tmpArcNum >>= 7) != 0; len++)
281 ;
282
283
284 /*
285 * write more signifcant bytes (if any)
286 * with 'more' bit set
287 */
288 for (i=0; i < len; i++)
289 *(buf++) = 0x80 | (tmpOid->arcNum >> ((len-i)*7));
290
291 /*
292 * write least significant byte
293 */
294 *(buf++) = 0x7f & tmpOid->arcNum;
295 }
296
297 } /* BuildEncodedOid */
298
299
300 /*
301 * convert an AsnOid into an OID (linked list)
302 * NOT RECOMMENDED for use in protocol implementations
303 */
304 void
305 UnbuildEncodedOid PARAMS ((eoid, result),
306 AsnOid *eoid _AND_
307 OID **result)
308 {
309 OID **nextOid;
310 OID *headOid;
311 int arcNum;
312 int i;
313 int firstArcNum;
314 int secondArcNum;
315
316 for (arcNum = 0, i=0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80);i++)
317 arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
318
319 arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
320 i++;
321
322 firstArcNum = arcNum / 40;
323 if (firstArcNum > 2)
324 firstArcNum = 2;
325
326 secondArcNum = arcNum - (firstArcNum * 40);
327
328 headOid = (OID*)malloc (sizeof (OID));
329 headOid->arcNum = firstArcNum;
330 headOid->next = (OID*)malloc (sizeof (OID));
331 headOid->next->arcNum = secondArcNum;
332 nextOid = &headOid->next->next;
333
334 for (; i < eoid->octetLen; )
335 {
336 for (arcNum = 0; (i < eoid->octetLen) && (eoid->octs[i] & 0x80); i++)
337 arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
338
339 arcNum = (arcNum << 7) + (eoid->octs[i] & 0x7f);
340 i++;
341 *nextOid = (OID*)malloc (sizeof (OID));
342 (*nextOid)->arcNum = arcNum;
343 nextOid = &(*nextOid)->next;
344 }
345
346 *result = headOid;
347
348 } /* UnbuildEncodedOid */