]> git.saurik.com Git - apple/security.git/blob - libsecurity_keychain/libDER/libDERUtils/printFields.c
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_keychain / libDER / libDERUtils / printFields.c
1 /* Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. */
2
3 /*
4 * printFeilds.h - print various DER objects
5 *
6 * Created Nov. 9 2005 by dmitch
7 */
8
9 #include <libDERUtils/printFields.h>
10 #include <libDER/DER_Decode.h>
11 #include <libDER/asn1Types.h>
12 #include <libDER/DER_Keys.h>
13 #include <libDERUtils/libDERUtils.h>
14 #include <stdlib.h>
15 #include <strings.h>
16 #include <stdio.h>
17
18 static int indentLevel = 0;
19
20 void doIndent()
21 {
22 int i;
23 for (i = 0; i<indentLevel; i++) {
24 putchar(' ');
25 }
26 } /* indent */
27
28 void incrIndent()
29 {
30 indentLevel += 3;
31 }
32
33 void decrIndent()
34 {
35 indentLevel -= 3;
36 }
37
38 #define TO_PRINT_MAX 12
39
40 void printHex(
41 DERItem *item)
42 {
43 unsigned dex;
44 unsigned toPrint = item->length;
45
46 printf("<%u> ", item->length);
47 if(toPrint > TO_PRINT_MAX) {
48 toPrint = TO_PRINT_MAX;
49 }
50 for(dex=0; dex<toPrint; dex++) {
51 printf("%02x ", item->data[dex]);
52 }
53 if(item->length > TO_PRINT_MAX) {
54 printf("...");
55 }
56 printf("\n");
57 }
58
59 void printBitString(
60 DERItem *item)
61 {
62 unsigned dex;
63 unsigned toPrint = item->length;
64 DERItem bitStringBytes;
65 DERByte numUnused;
66 DERReturn drtn;
67
68 drtn = DERParseBitString(item, &bitStringBytes, &numUnused);
69 if(drtn) {
70 DERPerror("DERParseBitString", drtn);
71 return;
72 }
73
74 printf("<%u, %u> ", bitStringBytes.length, numUnused);
75 toPrint = bitStringBytes.length;
76 if(toPrint > TO_PRINT_MAX) {
77 toPrint = TO_PRINT_MAX;
78 }
79 for(dex=0; dex<toPrint; dex++) {
80 printf("%02x ", bitStringBytes.data[dex]);
81 }
82 if(item->length > TO_PRINT_MAX) {
83 printf("...");
84 }
85 printf("\n");
86 }
87
88 void printString(
89 DERItem *item)
90 {
91 unsigned dex;
92 char *cp = (char *)item->data;
93 printf("'");
94 for(dex=0; dex<item->length; dex++) {
95 putchar(*cp++);
96 }
97 printf("'\n");
98
99 }
100
101 #define COLON_COLUMN 20
102
103 /*
104 * Print line header, with current indent, followed by specified label, followed
105 * by a ':' in column COLON_COLUMN, followed by one space.
106 */
107 void printHeader(
108 const char *label)
109 {
110 unsigned numPrinted;
111
112 doIndent();
113 printf("%s", label);
114 numPrinted = indentLevel + strlen(label);
115 if(numPrinted < COLON_COLUMN) {
116 unsigned numSpaces = COLON_COLUMN - numPrinted;
117 unsigned dex;
118 for(dex=0; dex<numSpaces; dex++) {
119 putchar(' ');
120 }
121 }
122 printf(": ");
123 }
124
125 void printItem(
126 const char *label,
127 ItemType itemType,
128 int verbose,
129 DERTag tag, // maybe from decoding, maybe the real tag underlying
130 // an implicitly tagged item
131 DERItem *item) // content
132 {
133 DERTag tagClass = tag & ASN1_CLASS_MASK;
134 DERTag tagNum = tag & ASN1_TAGNUM_MASK;
135 char printable = 0;
136 char *asnType = NULL;
137
138 printHeader(label);
139
140 if((itemType == IT_Branch) && !verbose) {
141 printf("\n");
142 return;
143 }
144 switch(tagClass) {
145 case ASN1_UNIVERSAL:
146 break; // proceed with normal tags */
147 case ASN1_APPLICATION:
148 printf("APPLICATION (tag %u) ", tagNum);
149 printHex(item);
150 return;
151 case ASN1_CONTEXT_SPECIFIC:
152 printf("CONTEXT SPECIFIC (tag %u) ", tagNum);
153 printHex(item);
154 return;
155 case ASN1_PRIVATE:
156 printf("PRIVATE (tag %u) ", tagNum);
157 printHex(item);
158 return;
159 }
160 switch(tagNum) {
161 case ASN1_BOOLEAN:
162 asnType = "BOOLEAN";
163 break;
164 case ASN1_INTEGER:
165 asnType = "INTEGER";
166 break;
167 case ASN1_BIT_STRING:
168 /* special case here... */
169 printf("BIT STRING ");
170 printBitString(item);
171 return;
172 case ASN1_OCTET_STRING:
173 asnType = "OCTET STRING";
174 break;
175 case ASN1_NULL:
176 asnType = "NULL";
177 break;
178 case ASN1_OBJECT_ID:
179 asnType = "OID";
180 break;
181 case ASN1_OBJECT_DESCRIPTOR:
182 asnType = "OBJECT_DESCRIPTOR";
183 break;
184 case ASN1_REAL:
185 asnType = "REAL";
186 break;
187 case ASN1_ENUMERATED:
188 asnType = "ENUM";
189 break;
190 case ASN1_EMBEDDED_PDV:
191 asnType = "EMBEDDED_PDV";
192 break;
193 case ASN1_UTF8_STRING:
194 asnType = "UTF8 STRING";
195 /* FIXME print these too */
196 break;
197 case ASN1_SEQUENCE:
198 asnType = "SEQ";
199 break;
200 case ASN1_SET:
201 asnType = "SET";
202 break;
203 case ASN1_NUMERIC_STRING:
204 asnType = "NUMERIC_STRING";
205 break;
206 case ASN1_PRINTABLE_STRING:
207 asnType = "PRINTABLE_STRING";
208 printable = 1;
209 break;
210 case ASN1_T61_STRING:
211 asnType = "T61_STRING";
212 printable = 1;
213 break;
214 case ASN1_VIDEOTEX_STRING:
215 asnType = "VIDEOTEX_STRING";
216 printable = 1;
217 break;
218 case ASN1_IA5_STRING:
219 asnType = "IA5_STRING";
220 printable = 1;
221 break;
222 case ASN1_UTC_TIME:
223 asnType = "UTC_TIME";
224 printable = 1;
225 break;
226 case ASN1_GENERALIZED_TIME:
227 asnType = "GENERALIZED_TIME";
228 printable = 1;
229 break;
230 case ASN1_GRAPHIC_STRING:
231 asnType = "GRAPHIC_STRING";
232 break;
233 case ASN1_VISIBLE_STRING:
234 asnType = "VISIBLE_STRING";
235 break;
236 case ASN1_GENERAL_STRING:
237 asnType = "GENERAL_STRING";
238 break;
239 case ASN1_UNIVERSAL_STRING:
240 asnType = "UNIVERSAL_STRING";
241 break;
242 case ASN1_BMP_STRING:
243 asnType = "BMP_STRING";
244 break;
245 default:
246 asnType = "[unknown]";
247 break;
248 }
249 printf("%s ", asnType);
250 if(printable) {
251 printString(item);
252 }
253 else {
254 printHex(item);
255 }
256 }
257
258 void printAlgId(
259 const DERItem *content,
260 int verbose)
261 {
262 DERReturn drtn;
263 DERAlgorithmId algId;
264
265 drtn = DERParseSequenceContent(content,
266 DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs,
267 &algId, sizeof(algId));
268 if(drtn) {
269 DERPerror("DERParseSequenceContent(algId)", drtn);
270 return;
271 }
272 printItem("alg", IT_Leaf, verbose, ASN1_OBJECT_ID, &algId.oid);
273 if(algId.params.data) {
274 printItem("params", IT_Leaf, verbose, algId.params.data[0], &algId.params);
275 }
276 }
277
278 void printSubjPubKeyInfo(
279 const DERItem *content,
280 int verbose)
281 {
282 DERReturn drtn;
283 DERSubjPubKeyInfo pubKeyInfo;
284 DERRSAPubKeyPKCS1 pkcs1Key;
285 DERItem bitStringContents;
286 DERByte numUnused;
287
288 drtn = DERParseSequenceContent(content,
289 DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs,
290 &pubKeyInfo, sizeof(pubKeyInfo));
291 if(drtn) {
292 DERPerror("DERParseSequenceContent(pubKeyInfo)", drtn);
293 return;
294 }
295 printItem("algId", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &pubKeyInfo.algId);
296 incrIndent();
297 printAlgId(&pubKeyInfo.algId, verbose);
298 decrIndent();
299
300 printItem("pubKey", IT_Branch, verbose, ASN1_BIT_STRING, &pubKeyInfo.pubKey);
301
302 /*
303 * The contents of that bit string are a PKCS1 format RSA key.
304 */
305 drtn = DERParseBitString(&pubKeyInfo.pubKey, &bitStringContents, &numUnused);
306 if(drtn) {
307 DERPerror("DERParseBitString(pubKeyInfo.pubKey)", drtn);
308 decrIndent();
309 return;
310 }
311 drtn = DERParseSequence(&bitStringContents,
312 DERNumRSAPubKeyPKCS1ItemSpecs, DERRSAPubKeyPKCS1ItemSpecs,
313 &pkcs1Key, sizeof(pkcs1Key));
314 if(drtn) {
315 DERPerror("DERParseSequenceContent(pubKeyBits)", drtn);
316 decrIndent();
317 return;
318 }
319 incrIndent();
320 printItem("modulus", IT_Leaf, verbose, ASN1_INTEGER, &pkcs1Key.modulus);
321 printItem("pubExponent", IT_Leaf, verbose, ASN1_INTEGER, &pkcs1Key.pubExponent);
322
323 decrIndent();
324 }
325
326 /* decode one item and print it */
327 void decodePrintItem(
328 const char *label,
329 ItemType itemType,
330 int verbose,
331 DERItem *derItem)
332 {
333 DERDecodedInfo decoded;
334 DERReturn drtn;
335
336 drtn = DERDecodeItem(derItem, &decoded);
337 if(drtn) {
338 DERPerror("DERDecodeItem()", drtn);
339 return;
340 }
341 printItem(label, IT_Leaf, 0, decoded.tag, &decoded.content);
342 }
343