]> git.saurik.com Git - apple/security.git/blame - SecuritySNACCRuntime/c++-lib/c++/asn-oid.cpp
Security-54.1.9.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c++-lib / c++ / asn-oid.cpp
CommitLineData
bac41a7b
A
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// file: .../c++-lib/src/asn-oid.C - OBJECT IDENTIFIER
20//
21// Mike Sample
22// 92/07/02
23// Copyright (C) 1992 Michael Sample and the University of British Columbia
24//
25// This library is free software; you can redistribute it and/or
26// modify it provided that this copyright/license information is retained
27// in original form.
28//
29// If you modify this file, you must clearly indicate your changes.
30//
31// This source code is distributed in the hope that it will be
32// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
33// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
34//
a66d0d4a 35// $Header: /cvs/root/Security/SecuritySNACCRuntime/c++-lib/c++/Attic/asn-oid.cpp,v 1.4 2002/03/21 05:38:45 dmitch Exp $
bac41a7b 36// $Log: asn-oid.cpp,v $
29654253
A
37// Revision 1.4 2002/03/21 05:38:45 dmitch
38// Radar 2868524: no more setjmp/longjmp in SNACC-generated code.
39//
40// Revision 1.3.44.1 2002/03/20 00:36:50 dmitch
41// Radar 2868524: SNACC-generated code now uses throw/catch instead of setjmp/longjmp.
42//
bac41a7b
A
43// Revision 1.3 2001/06/27 23:09:15 dmitch
44// Pusuant to Radar 2664258, avoid all cerr-based output in NDEBUG configuration.
45//
46// Revision 1.2 2001/06/21 19:51:43 dmitch
47// Made AsnOid::Set(unsigned long...) thread-safe by making static arc arrays local.
48//
49// Revision 1.1.1.1 2001/05/18 23:14:06 mb
50// Move from private repository to open source repository
51//
52// Revision 1.4 2001/05/05 00:59:19 rmurphy
53// Adding darwin license headers
54//
55// Revision 1.3 2000/06/08 20:05:35 dmitch
56// Mods for X port. These files are actually machine generated and probably don't need to be in CVS....
57//
58// Revision 1.1.1.1 2000/03/09 01:00:06 rmurphy
59// Base Fortissimo Tree
60//
61// Revision 1.3 1999/03/21 02:07:37 mb
62// Added Copy to every AsnType.
63//
64// Revision 1.2 1999/02/26 00:23:40 mb
65// Fixed for Mac OS 8
66//
67// Revision 1.1 1999/02/25 05:21:53 mb
68// Added snacc c++ library
69//
70// Revision 1.7 1997/02/28 13:39:46 wan
71// Modifications collected for new version 1.3: Bug fixes, tk4.2.
72//
73// Revision 1.6 1997/02/16 12:32:49 rj
74// name lookup of \for' scoping
75//
76// Revision 1.5 1995/08/17 15:31:14 rj
77// set Tcl's errorCode variable
78//
79// Revision 1.4 1995/07/24 20:25:38 rj
80// #if TCL ... #endif wrapped into #if META ... #endif
81//
82// call constructor with additional pdu and create arguments.
83//
84// changed `_' to `-' in file names.
85//
86// Revision 1.3 1994/10/08 04:18:28 rj
87// code for meta structures added (provides information about the generated code itself).
88//
89// code for Tcl interface added (makes use of the above mentioned meta code).
90//
91// virtual inline functions (the destructor, the Clone() function, BEnc(), BDec() and Print()) moved from inc/*.h to src/*.C because g++ turns every one of them into a static non-inline function in every file where the .h file gets included.
92//
93// made Print() const (and some other, mainly comparison functions).
94//
95// several `unsigned long int' turned into `size_t'.
96//
97// Revision 1.2 1994/08/28 10:01:17 rj
98// comment leader fixed.
99//
100// Revision 1.1 1994/08/28 09:21:06 rj
101// first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
102
103#include "asn-config.h"
104#if TCL
105#include <strstream.h>
106#endif
107#include "asn-len.h"
108#include "asn-tag.h"
109#include "asn-type.h"
110#include "asn-oid.h"
111#include "print.h"
112
113AsnOid::~AsnOid()
114{
115 delete oid;
116}
117
118AsnType *AsnOid::Clone() const
119{
120 return new AsnOid;
121}
122
123AsnType *AsnOid::Copy() const
124{
125 return new AsnOid (*this);
126}
127
128// Initializes an AsnOid with a string and it's length.
129// The string should hold the encoded OID.
130// The string is copied
131#ifndef _IBM_ENC_
132void AsnOid::Set (const char *encOid, size_t len)
133#else
134void AsnOid::Set (const char *encOid, const size_t len)
135#endif /* _IBM_ENC_ */
136{
137 if (encOid != oid)
138 {
139 octetLen = len;
140#ifndef _IBM_ENC_
141 oid = new char[octetLen];
142#else
143 oid = (char *) mem_mgr_ptr->Get (octetLen); /* Guido Grassel, 11.8.93 */
144#endif /* _IBM_ENC_ */
145 memcpy (oid, encOid, octetLen);
146 }
147}
148
149// Inits an AsnOid from another OID.
150// The oid string is copied.
151void AsnOid::Set (const AsnOid &o)
152{
153 if (&o != this)
154 {
155 octetLen = o.octetLen;
156#ifndef _IBM_ENC_
157 oid = new char[octetLen];
158#else
159 oid = (char *) mem_mgr_ptr->Get (octetLen); /* Guido Grassel, 11.8.93 */
160#endif /* _IBM_ENC_ */
161 memcpy (oid, o.oid, octetLen);
162 }
163}
164
165
166// Given some arc numbers, an AsnOid is built.
167// Set (1, 2, 3, 4, 5, -1, -1, -1, -1, -1, -1) results in
168// oid { 1 2 3 4 5 }. The first negative arc number represnts
169// the end of the arc numbers - at least 2 are required.
170// The prototype in the AsnOid class provides default -1 parameters
171// so you only need to provide the number of arc number in the oid
172// as params. (eg Set (1,2,3,4,5))
173void AsnOid::Set (unsigned long int a1, unsigned long int a2, long int a3, long int a4, long int a5, long int a6, long int a7, long int a8, long int a9, long int a10, long int a11)
174{
175 long int arcNumArr[11];
176 char buf[11*5]; /* make big enough for max oid with 11 arcs*/
177 char *tmpBuf;
178 size_t totalLen;
179 size_t elmtLen;
180 long int tmpArcNum;
181 long int headArcNum;
182
183 tmpBuf = buf;
184
185 arcNumArr[0] = a1;
186 arcNumArr[1] = a2;
187 arcNumArr[2] = a3;
188 arcNumArr[3] = a4;
189 arcNumArr[4] = a5;
190 arcNumArr[5] = a6;
191 arcNumArr[6] = a7;
192 arcNumArr[7] = a8;
193 arcNumArr[8] = a9;
194 arcNumArr[9] = a10;
195 arcNumArr[10] = a11;
196
197 // munge together first oid arc numbers
198 headArcNum = tmpArcNum = (arcNumArr[0] * 40) + arcNumArr[1];
199
200 // figure encoded length for this arc number
201 for (elmtLen = 1; (tmpArcNum >>= 7) != 0; elmtLen++)
202 ;
203
204 // write bytes except the last/least significant of the head arc number
205 // more bit is on
206 totalLen = elmtLen;
29654253 207 unsigned i;
bac41a7b
A
208 for (i = 1; i < elmtLen; i++)
209 {
210 *(tmpBuf++) = 0x80 | (headArcNum >> ((elmtLen-i)*7));
211 }
212
213 // write least significant (more bit is off)
214 *(tmpBuf++) = 0x7f & headArcNum;
215
216 // repeat for the rest of the arc numbers
217 for (i = 2; (i < 11) && (arcNumArr[i] > 0); i++)
218 {
219 tmpArcNum = arcNumArr[i];
220 for (elmtLen = 1; (tmpArcNum >>= 7) != 0; elmtLen++)
221 ;
222 totalLen += elmtLen;
223 tmpArcNum = arcNumArr[i];
29654253 224 for (unsigned j = 1; j < elmtLen; j++)
bac41a7b
A
225 {
226 *(tmpBuf++) = 0x80 | (tmpArcNum >> ((elmtLen-j)*7));
227 }
228 *(tmpBuf++) = 0x7f & tmpArcNum;
229 }
230
231#ifndef _IBM_ENC_
232 oid = Asn1Alloc (totalLen);
233#else
234 oid = (char *) mem_mgr_ptr->Get (totalLen); /* Guido Grassel, 11.8.93 */
235#endif /* _IBM_ENC_ */
236 memcpy (oid, buf, totalLen);
237 octetLen = totalLen;
238
239} /* AsnOid::Set */
240
241
242
243// Like Set except frees old oid value first
244#ifndef _IBM_ENC_
245void AsnOid::ReSet (const char *encOid, size_t len)
246#else
247void AsnOid::ReSet (const char *encOid, const size_t len)
248#endif /* _IBM_ENC_ */
249{
250 if (encOid != oid)
251 {
252#ifndef _IBM_ENC_
253 delete oid;
254#else
255 mem_mgr_ptr->Put ((void *) oid); /* Guido Grassel, 11.8.93 */
256#endif /* _IBM_ENC_ */
257 Set (encOid, len);
258 }
259}
260
261// Like Set except frees old oid value first
262void AsnOid::ReSet (const AsnOid &o)
263{
264 if (&o != this)
265 {
266#ifndef _IBM_ENC_
267 delete oid;
268#else
269 mem_mgr_ptr->Put ((void *) oid); /* Guido Grassel, 11.8.93 */
270#endif /* _IBM_ENC_ */
271 Set (o);
272 }
273}
274
275void AsnOid::ReSet (unsigned long int a1, unsigned long int a2, long int a3, long int a4, long int a5, long int a6, long int a7, long int a8, long int a9, long int a10, long int a11)
276{
277#ifndef _IBM_ENC_
278 delete oid;
279#else
280 mem_mgr_ptr->Put ((void *) oid); /* Guido Grassel, 11.8.93 */
281#endif /* _IBM_ENC_ */
282 Set (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
283}
284
285
286// returns the number of arc numbers in the OID value
287unsigned long int AsnOid::NumArcs() const
288{
29654253 289 unsigned i;
bac41a7b
A
290 int numArcs;
291
292 for (numArcs=0, i=0; i < octetLen; )
293 {
294 // skip octets in this arc num with the 'more' bit set
295 for (; (i < octetLen) && (oid[i] & 0x80); i++)
296 ;
297
298 // skip last octet in this arc num (no more bit)
299 i++;
300
301 numArcs++;
302 }
303
304 // add one to return value because the first two arcs are
305 // crunched together into a single one.
306 return numArcs +1;
307
308} /* AsnOid::NumArcs */
309
310int AsnOid::OidEquiv (const AsnOid &o) const
311{
312 return o.octetLen == octetLen && !strncmp (o.oid, oid, octetLen);
313}
314
315
316
317// Decodes the content of a BER OBJECT IDENTIFIER value and puts
318// the results in this AsnOid object.
319void AsnOid::BDecContent (BUF_TYPE b, AsnTag tagId, AsnLen elmtLen, AsnLen &bytesDecoded, ENV_TYPE env)
320{
321 /* treat like primitive octet string */
322 octetLen = elmtLen;
323#ifndef _IBM_ENC_
324 oid = Asn1Alloc (elmtLen);
325#else
326 oid = (char *) mem_mgr_ptr->Get (elmtLen); /* Guido Grassel, 11.8.93 */
327#endif /* _IBM_ENC_ */
328 b.CopyOut (oid, elmtLen);
329
330 if (b.ReadError())
331 {
332 Asn1Error << "BDecOctetString: ERROR - decoded past end of data" << endl;
29654253
A
333 #if SNACC_EXCEPTION_ENABLE
334 SnaccExcep::throwMe(-17);
335 #else
bac41a7b 336 longjmp (env, -17);
29654253 337 #endif
bac41a7b
A
338 }
339 bytesDecoded += elmtLen;
340} /* AsnOid::BDecContent */
341
342AsnLen AsnOid::BEnc (BUF_TYPE b)
343{
344 AsnLen l;
345 l = BEncContent (b);
346 l += BEncDefLen (b, l);
347 l += BEncTag1 (b, UNIV, PRIM, OID_TAG_CODE);
348 return l;
349}
350
351void AsnOid::BDec (BUF_TYPE b, AsnLen &bytesDecoded, ENV_TYPE env)
352{
353 AsnLen elmtLen;
354 if (BDecTag (b, bytesDecoded, env) != MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE))
355 {
356 Asn1Error << "AsnOid::BDec: ERROR tag on OBJECT IDENTIFIER is wrong." << endl;
29654253
A
357 #if SNACC_EXCEPTION_ENABLE
358 SnaccExcep::throwMe(-57);
359 #else
bac41a7b 360 longjmp (env,-57);
29654253 361 #endif
bac41a7b
A
362 }
363 elmtLen = BDecLen (b, bytesDecoded, env);
364
365 BDecContent (b, MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE), elmtLen, bytesDecoded, env);
366}
367
368AsnLen AsnOid::BEncContent (BUF_TYPE b)
369{
370 b.PutSegRvs (oid, octetLen);
371 return octetLen;
372}
373
374// Prints an AsnOid in ASN.1 Value Notation.
375// Decodes the oid to get the individual arc numbers
376void AsnOid::Print (ostream &os) const
377{
378#ifndef NDEBUG
379 unsigned short int firstArcNum;
380 unsigned long int arcNum;
29654253 381 unsigned i;
bac41a7b
A
382
383 // print oid in
384 os << "{";
385
386 if (oid)
387 {
388 // un-munge first two arc numbers
389 for (arcNum = 0, i=0; (i < octetLen) && (oid[i] & 0x80); i++)
390 arcNum = (arcNum << 7) + (oid[i] & 0x7f);
391
392 arcNum = (arcNum << 7) + (oid[i] & 0x7f);
393 i++;
394 firstArcNum = arcNum/40;
395 if (firstArcNum > 2)
396 firstArcNum = 2;
397
398 os << firstArcNum << " " << arcNum - (firstArcNum * 40);
399
400 for (; i < octetLen; )
401 {
402 for (arcNum = 0; (i < octetLen) && (oid[i] & 0x80); i++)
403 arcNum = (arcNum << 7) + (oid[i] & 0x7f);
404
405 arcNum = (arcNum << 7) + (oid[i] & 0x7f);
406 i++;
407 os << " " << arcNum;
408 }
409 }
410 else
411 os << "-- void --";
412
413 os << "}";
414#endif /* NDEBUG */
415} // AsnOid::Print
416
417#if META
418
419const AsnOidTypeDesc AsnOid::_desc (NULL, NULL, false, AsnTypeDesc::OBJECT_IDENTIFIER, NULL);
420
421const AsnTypeDesc *AsnOid::_getdesc() const
422{
423 return &_desc;
424}
425
426#if TCL
427
428int AsnOid::TclGetVal (Tcl_Interp *interp) const
429{
430 if (oid)
431 {
432 strstream buf;
433 buf << *this;
434 buf.str()[strlen(buf.str())-1] = '\0'; // chop the trailing '}'
435 Tcl_SetResult (interp, buf.str()+1, TCL_VOLATILE); // copy without leading '{'
436 }
437 return TCL_OK;
438}
439
440int AsnOid::TclSetVal (Tcl_Interp *interp, const char *valstr)
441{
442 if (!*valstr)
443 {
444 delete oid;
445 oid = NULL;
446 octetLen = 0;
447 return TCL_OK;
448 }
449
450 Args arc;
451 if (Tcl_SplitList (interp, (char*)valstr, &arc.c, &arc.v) != TCL_OK)
452 return TCL_ERROR;
453 if (arc.c < 2)
454 {
455 Tcl_AppendResult (interp, "oid arc must contain at least two numbers", NULL);
456 Tcl_SetErrorCode (interp, "SNACC", "ILLARC", "<2", NULL);
457 return TCL_ERROR;
458 }
459 if (arc.c > 11)
460 {
461 Tcl_AppendResult (interp, "snacc limits oid arcs to no more than 11 numbers", NULL);
462 Tcl_SetErrorCode (interp, "SNACC", "ILLARC", ">11", NULL);
463 return TCL_ERROR;
464 }
465
466 int na[11], i;
467 for (i=0; i<arc.c; i++)
468 if (Tcl_GetInt (interp, arc.v[i], na+i) != TCL_OK)
469 return TCL_ERROR;
470 while (i < 11)
471 na[i++] = -1;
472
473 ReSet (na[0], na[1], na[2], na[3], na[4], na[5], na[6], na[7], na[8], na[9], na[10]);
474
475 return TCL_OK;
476}
477
478#endif /* TCL */
479#endif /* META */