2 * compiler/core/oid.c - routines for:
3 * converting an arc number list to an ENC_OID
4 * converting an ENC_OID to an arc number list
5 * arcName mapping routine
7 * does not handle OID's with unresolved valueRefs instead of arcNums
11 * Copyright (C) 1991, 1992 Michael Sample
12 * and the University of British Columbia
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/oid.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
21 * Revision 1.1 2001/06/20 21:27:58 dmitch
22 * Adding missing snacc compiler files.
24 * Revision 1.1.1.1 1999/03/16 18:06:51 aram
25 * Originals from SMIME Free Library.
27 * Revision 1.3 1995/07/25 19:41:41 rj
28 * changed `_' to `-' in file names.
30 * Revision 1.2 1994/09/01 00:41:33 rj
31 * snacc_config.h removed; oid.h includet.
33 * Revision 1.1 1994/08/28 09:49:26 rj
34 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
38 #include <stdio.h> /* for FILE * */
43 typedef struct ArcNameMapElmt
51 * these are the CCITT and ISO pre-defined arc names for the
52 * OBJECT IDENTIFIER tree.
53 * Ref: CCITT X.208 1988 - Annexes B C and D
55 * NOTE: the last entry must have a NULL string and a
56 * -1 arcnumber to indicate the end of the array.
58 ArcNameMapElmt oidArcNameMapG
[] =
64 "registration-authority", 1,
66 "identified-organization", 3,
70 "network-operator", 3,
76 * returns the arcnum (>0) of the given name if it
77 * is a defined oid arc name like "iso" or "ccitt"
78 * returns -1 if the name was not found
80 * name must be null terminated.
83 OidArcNameToNum
PARAMS ((name
),
87 for (i
= 0; oidArcNameMapG
[i
].arcName
!= NULL
; i
++)
89 if (strcmp (name
, oidArcNameMapG
[i
].arcName
) == 0)
90 return oidArcNameMapG
[i
].arcNum
;
93 } /* OidArcNameToNum */
98 * Takes and OBJECT IDENTIFER in the linked format
99 * (produced by parser) and returns the number of octets
100 * that are needed to hold the encoded version of that
104 EncodedOidLen
PARAMS ((oid
),
107 unsigned long totalLen
;
108 unsigned long headArcNum
;
109 unsigned long tmpArcNum
;
113 * oid must have at least 2 elmts
115 if (oid
->next
== NULL
)
118 headArcNum
= (oid
->arcNum
* 40) + oid
->next
->arcNum
;
121 * figure out total encoded length of oid
123 tmpArcNum
= headArcNum
;
124 for (totalLen
= 1; (tmpArcNum
>>= 7) != 0; totalLen
++)
126 for (tmpOid
= oid
->next
->next
; tmpOid
!= NULL
; tmpOid
= tmpOid
->next
)
129 tmpArcNum
= tmpOid
->arcNum
;
130 for (; (tmpArcNum
>>= 7) != 0; totalLen
++)
136 } /* EncodedOidLen */
140 * Given an oid arc number list and a pre-allocated ENC_OID
141 * (use EncodedOidLen to figure out byte length needed)
142 * fills the ENC_OID with a BER encoded version
146 BuildEncodedOid
PARAMS ((oid
, result
),
151 unsigned long headArcNum
;
152 unsigned long tmpArcNum
;
160 * oid must have at least 2 elmts
162 if (oid
->next
== NULL
)
165 * munge together first two arcNum
166 * note first arcnum must be <= 2
167 * and second must be < 39 if first = 0 or 1
168 * see (X.209) for ref to this stupidity
170 headArcNum
= (oid
->arcNum
* 40) + oid
->next
->arcNum
;
172 tmpArcNum
= headArcNum
;
175 * calc # bytes needed for head arc num
177 for (len
= 0; (tmpArcNum
>>= 7) != 0; len
++)
181 * write more signifcant bytes (if any) of head arc num
182 * with 'more' bit set
184 for (i
=0; i
< len
; i
++)
185 *(buf
++) = 0x80 | (headArcNum
>> ((len
-i
)*7));
188 * write least significant byte of head arc num
190 *(buf
++) = 0x7f & headArcNum
;
194 * write following arc nums, if any
196 for (tmpOid
= oid
->next
->next
; tmpOid
!= NULL
; tmpOid
= tmpOid
->next
)
199 * figure out encoded length -1 of this arcNum
201 tmpArcNum
= tmpOid
->arcNum
;
202 for (len
= 0; (tmpArcNum
>>= 7) != 0; len
++)
207 * write more signifcant bytes (if any)
208 * with 'more' bit set
210 for (i
=0; i
< len
; i
++)
211 *(buf
++) = 0x80 | (tmpOid
->arcNum
>> ((len
-i
)*7));
214 * write least significant byte
216 *(buf
++) = 0x7f & tmpOid
->arcNum
;
219 } /* BuildEncodedOid */
223 * Given an ENC_OID, this routine converts it into a
227 UnbuildEncodedOid
PARAMS ((eoid
, result
),
238 for (arcNum
= 0, i
=0; (i
< eoid
->octetLen
) && (eoid
->octs
[i
] & 0x80);i
++)
239 arcNum
= (arcNum
<< 7) + (eoid
->octs
[i
] & 0x7f);
241 arcNum
= (arcNum
<< 7) + (eoid
->octs
[i
] & 0x7f);
244 firstArcNum
= arcNum
/ 40;
248 secondArcNum
= arcNum
- (firstArcNum
* 40);
250 headOid
= (OID
*)Malloc (sizeof (OID
));
251 headOid
->arcNum
= firstArcNum
;
252 headOid
->next
= (OID
*)Malloc (sizeof (OID
));
253 headOid
->next
->arcNum
= secondArcNum
;
254 nextOid
= &headOid
->next
->next
;
256 for ( ; i
< eoid
->octetLen
; )
258 for (arcNum
= 0; (i
< eoid
->octetLen
) && (eoid
->octs
[i
] & 0x80);i
++)
259 arcNum
= (arcNum
<< 7) + (eoid
->octs
[i
] & 0x7f);
261 arcNum
= (arcNum
<< 7) + (eoid
->octs
[i
] & 0x7f);
263 *nextOid
= (OID
*)Malloc (sizeof (OID
));
264 (*nextOid
)->arcNum
= arcNum
;
265 nextOid
= &(*nextOid
)->next
;
270 } /* UnbuildEncodedOid */