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