VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/asn1/asn1-dump.cpp@ 52600

Last change on this file since 52600 was 52600, checked in by vboxsync, 10 years ago

IPRT: Added support for microsoft timestamp counter signatures. This required making the PKCS #7 code accept some of the CMS (RFC-5652) stuff.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.6 KB
Line 
1/* $Id: asn1-dump.cpp 52600 2014-09-04 22:59:00Z vboxsync $ */
2/** @file
3 * IPRT - ASN.1, Structure Dumper.
4 */
5
6/*
7 * Copyright (C) 2006-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include "internal/iprt.h"
31#include <iprt/asn1.h>
32
33#include <iprt/err.h>
34#include <iprt/log.h>
35#ifdef IN_RING3
36# include <iprt/stream.h>
37#endif
38#include <iprt/string.h>
39
40#include <iprt/formats/asn1.h>
41
42
43/*******************************************************************************
44* Structures and Typedefs *
45*******************************************************************************/
46/**
47 * Dump data structure.
48 */
49typedef struct RTASN1DUMPDATA
50{
51 /** RTASN1DUMP_F_XXX. */
52 uint32_t fFlags;
53 /** The printfv like output function. */
54 PFNRTDUMPPRINTFV pfnPrintfV;
55 /** PrintfV user argument. */
56 void *pvUser;
57} RTASN1DUMPDATA;
58/** Pointer to a dump data structure. */
59typedef RTASN1DUMPDATA *PRTASN1DUMPDATA;
60
61
62/**
63 * Wrapper around FNRTASN1DUMPPRINTFV.
64 *
65 * @param pData The dump data structure.
66 * @param pszFormat Format string.
67 * @param ... Format arguments.
68 */
69static void rtAsn1DumpPrintf(PRTASN1DUMPDATA pData, const char *pszFormat, ...)
70{
71 va_list va;
72 va_start(va, pszFormat);
73 pData->pfnPrintfV(pData->pvUser, pszFormat, va);
74 va_end(va);
75}
76
77
78/**
79 * Prints indentation.
80 *
81 * @param pData The dump data structure.
82 * @param uDepth The indentation depth.
83 */
84static void rtAsn1DumpPrintIdent(PRTASN1DUMPDATA pData, uint32_t uDepth)
85{
86 uint32_t cchLeft = uDepth * 2;
87 while (cchLeft > 0)
88 {
89 static char const s_szSpaces[] = " ";
90 uint32_t cch = RT_MIN(cchLeft, sizeof(s_szSpaces) - 1);
91 rtAsn1DumpPrintf(pData, &s_szSpaces[sizeof(s_szSpaces) - 1 - cch]);
92 cchLeft -= cch;
93 }
94}
95
96
97/**
98 * Dumps UTC TIME and GENERALIZED TIME
99 *
100 * @param pData The dump data structure.
101 * @param pAsn1Core The ASN.1 core object representation.
102 * @param pszType The time type name.
103 */
104static void rtAsn1DumpTime(PRTASN1DUMPDATA pData, PCRTASN1CORE pAsn1Core, const char *pszType)
105{
106 if ((pAsn1Core->fFlags & RTASN1CORE_F_PRIMITE_TAG_STRUCT))
107 {
108 PCRTASN1TIME pTime = (PCRTASN1TIME)pAsn1Core;
109 rtAsn1DumpPrintf(pData, "%s -- %04u-%02u-%02u %02u:%02u:%02.%09Z\n",
110 pszType,
111 pTime->Time.i32Year, pTime->Time.u8Month, pTime->Time.u8MonthDay,
112 pTime->Time.u8Hour, pTime->Time.u8Minute, pTime->Time.u8Second,
113 pTime->Time.u32Nanosecond);
114 }
115 else if (pAsn1Core->cb > 0 && pAsn1Core->cb < 32 && pAsn1Core->uData.pch)
116 rtAsn1DumpPrintf(pData, "%s '%.*s'\n", pszType, (size_t)pAsn1Core->cb, pAsn1Core->uData.pch);
117 else
118 rtAsn1DumpPrintf(pData, "%s -- cb=%u\n", pszType, pAsn1Core->cb);
119}
120
121
122/**
123 * Dumps strings sharing the RTASN1STRING structure.
124 *
125 * @param pData The dump data structure.
126 * @param pAsn1Core The ASN.1 core object representation.
127 * @param pszType The string type name.
128 * @param uDepth The current identation level.
129 */
130static void rtAsn1DumpString(PRTASN1DUMPDATA pData, PCRTASN1CORE pAsn1Core, const char *pszType, uint32_t uDepth)
131{
132 rtAsn1DumpPrintf(pData, "%s", pszType);
133
134 const char *pszPostfix = "'\n";
135 bool fUtf8 = false;
136 const char *pch = pAsn1Core->uData.pch;
137 uint32_t cch = pAsn1Core->cb;
138 PCRTASN1STRING pString = (PCRTASN1STRING)pAsn1Core;
139 if ( (pAsn1Core->fFlags & RTASN1CORE_F_PRIMITE_TAG_STRUCT)
140 && pString->pszUtf8
141 && pString->cchUtf8)
142 {
143 fUtf8 = true;
144 pszPostfix = "' -- utf-8\n";
145 }
146
147 if (cch == 0 || !pch)
148 rtAsn1DumpPrintf(pData, "-- cb=%u\n", pszType, pAsn1Core->cb);
149 else
150 {
151 if (cch >= 48)
152 {
153 rtAsn1DumpPrintf(pData, "\n");
154 rtAsn1DumpPrintIdent(pData, uDepth + 1);
155 }
156 rtAsn1DumpPrintf(pData, " '");
157
158 /** @todo Handle BMP and UNIVERSIAL strings specially. */
159 do
160 {
161 const char *pchStart = pch;
162 while ( cch > 0
163 && (uint8_t)*pch >= 0x20
164 && (!fUtf8 ? (uint8_t)*pch < 0x7f : (uint8_t)*pch != 0x7f)
165 && *pch != '\'')
166 cch--, pch++;
167 if (pchStart != pch)
168 rtAsn1DumpPrintf(pData, "%.*s", pch - pchStart, pchStart);
169
170 while ( cch > 0
171 && ( (uint8_t)*pch < 0x20
172 || (!fUtf8 ? (uint8_t)*pch >= 0x7f : (uint8_t)*pch == 0x7f)
173 || (uint8_t)*pch == '\'') )
174 {
175 rtAsn1DumpPrintf(pData, "\\x%02x", *pch);
176 cch--;
177 pch++;
178 }
179 } while (cch > 0);
180
181 rtAsn1DumpPrintf(pData, pszPostfix);
182 }
183}
184
185
186/**
187 * Returns a name for the given object ID.
188 *
189 * This is just to make some of the dumps a little easier to read. It's no our
190 * intention to have the whole ODI repository encoded here.
191 *
192 * @returns Name if available, NULL if not.
193 * @param pszObjId The dotted object identifier string.
194 */
195static const char *rtAsn1DumpLookupObjIdName(const char *pszObjId)
196{
197#define STARTS_WITH_1(a_off, a_uValue) \
198 ( pszObjId[a_off] == (a_uValue) + '0' && pszObjId[a_off + 1] == '.' )
199#define STARTS_WITH_2(a_off, a_uValue) \
200 ( pszObjId[a_off] == (a_uValue) / 10 + '0' && pszObjId[a_off + 1] == (a_uValue) % 10 + '0' && pszObjId[a_off + 2] == '.' )
201#define STARTS_WITH_3(a_off, a_uValue) \
202 ( pszObjId[a_off] == (a_uValue) / 100 + '0' \
203 && pszObjId[a_off + 1] == ((a_uValue) % 100) / 10 + '0' \
204 && pszObjId[a_off + 2] == (a_uValue) % 10 + '0' \
205 && pszObjId[a_off + 3] == '.' )
206#define STARTS_WITH_6(a_off, a_uValue) \
207 ( pszObjId[a_off] == (a_uValue) / 100000 + '0' \
208 && pszObjId[a_off + 1] == ((a_uValue) % 100000) / 10000 + '0' \
209 && pszObjId[a_off + 2] == ((a_uValue) % 10000) / 1000 + '0' \
210 && pszObjId[a_off + 3] == ((a_uValue) % 1000) / 100 + '0' \
211 && pszObjId[a_off + 4] == ((a_uValue) % 100) / 10 + '0' \
212 && pszObjId[a_off + 5] == (a_uValue) % 10 + '0' \
213 && pszObjId[a_off + 6] == '.' )
214
215#define ENDS_WITH_1(a_off, a_uValue) \
216 ( pszObjId[a_off] == (a_uValue) + '0' && !pszObjId[a_off + 1] )
217#define ENDS_WITH_2(a_off, a_uValue) \
218 ( pszObjId[a_off] == (a_uValue) / 10 + '0' && pszObjId[a_off + 1] == (a_uValue) % 10 + '0' && !pszObjId[a_off + 2] )
219
220 if (STARTS_WITH_1(0, 0)) /* ITU-T assigned - top level 0. */
221 {
222
223 }
224 else if (STARTS_WITH_1(0, 1)) /* ISO assigned - top level 1. */
225 {
226 if (STARTS_WITH_1(2, 0)) /* ISO standard - 1.0. */
227 {
228 /* */
229 }
230 else if (STARTS_WITH_1(2, 2)) /* ISO member body - 1.2. */
231 {
232 if (STARTS_WITH_3(4, 840)) /* USA - 1.2.840. */
233 {
234 if (STARTS_WITH_6(8, 113549)) /* RSADSI / RSA Data Security inc - 1.2.840.113549. */
235 {
236 if (STARTS_WITH_1(15, 1)) /* PKCS - 1.2.840.113549.1. */
237 {
238 if (STARTS_WITH_1(17, 1)) /* PKCS-1 - 1.2.840.113549.1.1. */
239 {
240 if (ENDS_WITH_1(19, 1)) return "pkcs1-RsaEncryption";
241 else if (ENDS_WITH_1(19, 2)) return "pkcs1-Md2WithRsaEncryption";
242 else if (ENDS_WITH_1(19, 3)) return "pkcs1-Md4WithRsaEncryption";
243 else if (ENDS_WITH_1(19, 4)) return "pkcs1-Md5WithRsaEncryption";
244 else if (ENDS_WITH_1(19, 5)) return "pkcs1-Sha1WithRsaEncryption";
245 else if (ENDS_WITH_2(19, 10)) return "pkcs1-RsaPss";
246 else if (ENDS_WITH_2(19, 11)) return "pkcs1-Sha256WithRsaEncryption";
247 else if (ENDS_WITH_2(19, 12)) return "pkcs1-Sha384WithRsaEncryption";
248 else if (ENDS_WITH_2(19, 13)) return "pkcs1-Sha512WithRsaEncryption";
249 else if (ENDS_WITH_2(19, 14)) return "pkcs1-Sha224WithRsaEncryption";
250 }
251 else if (STARTS_WITH_1(17, 9)) /* PKCS-9 signatures - 1.2.840.113549.1.9. */
252 {
253 if (ENDS_WITH_1(19, 1)) return "pkcs9-EMailAddress";
254 else if (ENDS_WITH_1(19, 2)) return "pkcs9-UntrustedName";
255 else if (ENDS_WITH_1(19, 3)) return "pkcs9-ContentType";
256 else if (ENDS_WITH_1(19, 4)) return "pkcs9-MessageDigest";
257 else if (ENDS_WITH_1(19, 5)) return "pkcs9-SigningTime";
258 else if (ENDS_WITH_1(19, 6)) return "pkcs9-CounterSignature";
259 else if (ENDS_WITH_1(19, 7)) return "pkcs9-challengePassword";
260 else if (ENDS_WITH_1(19, 8)) return "pkcs9-UnstructuredAddress";
261 else if (ENDS_WITH_1(19, 9)) return "pkcs9-ExtendedCertificateAttributes";
262 else if (ENDS_WITH_2(19, 13)) return "pkcs9-SigningDescription";
263 else if (ENDS_WITH_2(19, 14)) return "pkcs9-ExtensionRequest";
264 else if (ENDS_WITH_2(19, 15)) return "pkcs9-SMimeCapabilities";
265 }
266 }
267 else if (STARTS_WITH_1(15, 2)) /* PKCS #2 - 1.2.840.113549.2. */
268 {
269 }
270 }
271 }
272 }
273 else if (STARTS_WITH_1(2, 3)) /* ISO identified organiziation - 1.3. */
274 {
275 if (STARTS_WITH_1(4, 6)) /* DOD - 1.3.6. */
276 {
277 if (STARTS_WITH_1(6, 1)) /* Internet - 1.3.6.1. */
278 {
279 if (STARTS_WITH_1(8, 4)) /* Private - 1.3.6.1.4. */
280 {
281 if (STARTS_WITH_1(10, 1)) /* IANA-registered Private Enterprises. */
282 {
283 if (STARTS_WITH_3(12, 311)) /* Microsoft - 1.3.6.1.4.1.311 */
284 {
285 if (STARTS_WITH_1(16, 1)) /* 1.3.6.1.4.1.311.1. */
286 {
287 }
288 else if (STARTS_WITH_1(16, 2)) /* 1.3.6.1.4.1.311.2 */
289 {
290 if (STARTS_WITH_1(18, 1)) /* 1.3.6.1.4.1.311.2.1. */
291 {
292 if (ENDS_WITH_1(20, 1)) return "Ms-??-2.1";
293 else if (ENDS_WITH_1(20, 4)) return "Ms-SpcIndirectDataContext";
294 else if (ENDS_WITH_2(20, 10)) return "Ms-SpcAgencyInfo";
295 else if (ENDS_WITH_2(20, 11)) return "Ms-SpcStatemntType";
296 else if (ENDS_WITH_2(20, 12)) return "Ms-SpcOpusInfo";
297 else if (ENDS_WITH_2(20, 14)) return "Ms-CertReqExtensions";
298 else if (ENDS_WITH_2(20, 15)) return "Ms-SpcPeImageData";
299 else if (ENDS_WITH_2(20, 18)) return "Ms-SpcRawFileData";
300 else if (ENDS_WITH_2(20, 19)) return "Ms-SpcStructuredStorageData";
301 else if (ENDS_WITH_2(20, 20)) return "Ms-SpcJavaClassDataType1";
302 else if (ENDS_WITH_2(20, 21)) return "Ms-SpcIndividualCodeSigning";
303 else if (ENDS_WITH_2(20, 22)) return "Ms-SpcCommericalSigning";
304 else if (ENDS_WITH_2(20, 25)) return "Ms-SpcLinkType2-Aka-CabData";
305 else if (ENDS_WITH_2(20, 26)) return "Ms-SpcMinimalCriterialInfo";
306 else if (ENDS_WITH_2(20, 27)) return "Ms-SpcFinacialCriterialInfo";
307 else if (ENDS_WITH_2(20, 28)) return "Ms-SpcLinkType3";
308 }
309 else if (STARTS_WITH_1(18, 3)) /* 1.3.6.1.4.1.311.2.3. */
310 {
311 if (ENDS_WITH_1(20, 1)) return "Ms-SpcPeImagePageHashesV1";
312 else if (ENDS_WITH_1(20, 2)) return "Ms-SpcPeImagePageHashesV2";
313 }
314 }
315 else if (STARTS_WITH_1(16, 3)) /* 1.3.6.1.4.1.311.3 */
316 {
317 if (STARTS_WITH_1(18, 3)) /* 1.3.6.1.4.1.311.3.3. */
318 {
319 if (ENDS_WITH_1(20, 1)) return "Ms-CounterSign";
320 else if (ENDS_WITH_1(20, 2)) return "Ms-??-3.2";
321 }
322 }
323 else if (STARTS_WITH_2(16, 10)) /* 1.3.6.1.4.1.311.10 */
324 {
325 if (STARTS_WITH_1(19, 3)) /* . */
326 {
327 if (ENDS_WITH_1(21, 1)) return "Ms-CertTrustListSigning";
328 else if (ENDS_WITH_1(21, 2)) return "Ms-TimeStampSigning";
329 else if (ENDS_WITH_1(21, 4)) return "Ms-EncryptedFileSystem";
330 else if (ENDS_WITH_1(21, 5)) return "Ms-WhqlCrypto";
331 else if (ENDS_WITH_1(21, 6)) return "Ms-Nt5Crypto";
332 else if (ENDS_WITH_1(21, 7)) return "Ms-OemWhqlCrypto";
333 else if (ENDS_WITH_1(21, 8)) return "Ms-EmbeddedNtCrypto";
334 else if (ENDS_WITH_1(21, 9)) return "Ms-RootListSigner";
335 else if (ENDS_WITH_2(21, 10)) return "Ms-QualifiedSubordination";
336 else if (ENDS_WITH_2(21, 11)) return "Ms-KeyRecovery";
337 else if (ENDS_WITH_2(21, 12)) return "Ms-DocumentSigning";
338 else if (ENDS_WITH_2(21, 13)) return "Ms-LifetimeSigning";
339 }
340 else if (STARTS_WITH_1(19, 5)) /* . */
341 {
342 if (ENDS_WITH_1(21, 1)) return "Ms-Drm";
343 else if (ENDS_WITH_1(21, 2)) return "Ms-DrmIndividualization";
344 }
345 else if (STARTS_WITH_1(19, 9)) /* . */
346 {
347 if (ENDS_WITH_1(21, 1)) return "Ms-CrossCertDistPoints";
348 }
349 }
350 else if (STARTS_WITH_2(16, 20)) /* 1.3.6.1.4.1.311.20 */
351 {
352 if (ENDS_WITH_1(19, 1)) return "Ms-AutoEnrollCtlUsage";
353 else if (ENDS_WITH_1(19, 2)) return "Ms-EnrollCerttypeExtension";
354 }
355 else if (STARTS_WITH_2(16, 21)) /* CertSrv Infrastructure - 1.3.6.1.4.1.311.21 */
356 {
357 if (ENDS_WITH_1(19, 1)) return "Ms-CaKeyCertIndexPair";
358 else if (ENDS_WITH_1(19, 2)) return "Ms-CertSrvPreviousCertHash";
359 else if (ENDS_WITH_1(19, 3)) return "Ms-CrlVirtualBase";
360 else if (ENDS_WITH_1(19, 4)) return "Ms-CrlNextPublish";
361 else if (ENDS_WITH_1(19, 6)) return "Ms-KeyRecovery";
362 else if (ENDS_WITH_1(19, 7)) return "Ms-CertificateTemplate";
363 else if (ENDS_WITH_1(19, 9)) return "Ms-DummySigner";
364 }
365 }
366 }
367 }
368 else if (STARTS_WITH_1(8, 5)) /* Security - 1.3.6.1.5. */
369 {
370 if (STARTS_WITH_1(10, 5)) /* Mechanisms - 1.3.6.1.5.5. */
371 {
372 if (STARTS_WITH_1(12, 7)) /* Public-Key Infrastructure (X.509) - 1.3.6.1.5.5.7. */
373 {
374 if (STARTS_WITH_1(14, 1)) /* Private Extension - 1.3.6.1.5.5.7.1. */
375 {
376 if (ENDS_WITH_1(16, 1)) return "pkix-AuthorityInfoAccess";
377 else if (ENDS_WITH_2(16, 12)) return "pkix-LogoType";
378 }
379 else if (STARTS_WITH_1(14, 2)) /* Private Extension - 1.3.6.1.5.5.7.2. */
380 {
381 if (ENDS_WITH_1(16, 1)) return "id-qt-CPS";
382 else if (ENDS_WITH_1(16, 2)) return "id-qt-UNotice";
383 else if (ENDS_WITH_1(16, 3)) return "id-qt-TextNotice";
384 else if (ENDS_WITH_1(16, 4)) return "id-qt-ACPS";
385 else if (ENDS_WITH_1(16, 5)) return "id-qt-ACUNotice";
386 }
387 else if (STARTS_WITH_1(14, 3)) /* Private Extension - 1.3.6.1.5.5.7.3. */
388 {
389 if (ENDS_WITH_1(16, 1)) return "id-kp-ServerAuth";
390 else if (ENDS_WITH_1(16, 2)) return "id-kp-ClientAuth";
391 else if (ENDS_WITH_1(16, 3)) return "id-kp-CodeSigning";
392 else if (ENDS_WITH_1(16, 4)) return "id-kp-EmailProtection";
393 else if (ENDS_WITH_1(16, 5)) return "id-kp-IPSecEndSystem";
394 else if (ENDS_WITH_1(16, 6)) return "id-kp-IPSecTunnel";
395 else if (ENDS_WITH_1(16, 7)) return "id-kp-IPSecUser";
396 else if (ENDS_WITH_1(16, 8)) return "id-kp-Timestamping";
397 else if (ENDS_WITH_1(16, 9)) return "id-kp-OCSPSigning";
398 else if (ENDS_WITH_2(16, 10)) return "id-kp-DVCS";
399 else if (ENDS_WITH_2(16, 11)) return "id-kp-SBGPCertAAServiceAuth";
400 else if (ENDS_WITH_2(16, 13)) return "id-kp-EAPOverPPP";
401 else if (ENDS_WITH_2(16, 14)) return "id-kp-EAPOverLAN";
402 }
403 }
404 }
405 }
406 }
407 }
408 else if (STARTS_WITH_2(4, 14)) /* 1.3.14. */
409 {
410 if (STARTS_WITH_1(7, 3)) /* OIW Security Special Interest Group - 1.3.14.3. */
411 {
412 if (STARTS_WITH_1(9, 2)) /* OIW SSIG algorithms - 1.3.14.3.2. */
413 {
414 if (ENDS_WITH_1(11, 2)) return "oiw-ssig-Md4WithRsa";
415 else if (ENDS_WITH_1(11, 3)) return "oiw-ssig-Md5WithRsa";
416 else if (ENDS_WITH_1(11, 4)) return "oiw-ssig-Md4WithRsaEncryption";
417 else if (ENDS_WITH_2(11, 15)) return "oiw-ssig-ShaWithRsaEncryption";
418 else if (ENDS_WITH_2(11, 24)) return "oiw-ssig-Md2WithRsaEncryption";
419 else if (ENDS_WITH_2(11, 25)) return "oiw-ssig-Md5WithRsaEncryption";
420 else if (ENDS_WITH_2(11, 26)) return "oiw-ssig-Sha1";
421 else if (ENDS_WITH_2(11, 29)) return "oiw-ssig-Sha1WithRsaEncryption";
422 }
423 }
424 }
425 }
426 }
427 else if (STARTS_WITH_1(0, 2)) /* Joint ISO/ITU-T assigned - top level 2.*/
428 {
429 if (STARTS_WITH_1(2, 1)) /* ASN.1 - 2.1. */
430 {
431 }
432 else if (STARTS_WITH_1(2, 5)) /* Directory (X.500) - 2.5. */
433 {
434 if (STARTS_WITH_1(4, 4)) /* X.500 Attribute types - 2.5.4. */
435 {
436 if (ENDS_WITH_1(6, 3)) return "x500-CommonName";
437 else if (ENDS_WITH_1(6, 6)) return "x500-CountryName";
438 else if (ENDS_WITH_1(6, 7)) return "x500-LocalityName";
439 else if (ENDS_WITH_1(6, 8)) return "x500-StatOrProvinceName";
440 else if (ENDS_WITH_2(6, 10)) return "x500-OrganizationName";
441 else if (ENDS_WITH_2(6, 11)) return "x500-OrganizationUnitName";
442 }
443 else if (STARTS_WITH_2(4, 29)) /* certificateExtension (id-ce) - 2.5.29. */
444 {
445 if (ENDS_WITH_1(7, 1)) return "id-ce-AuthorityKeyIdentifier-Deprecated";
446 else if (ENDS_WITH_1(7, 2)) return "id-ce-KeyAttributes-Deprecated";
447 else if (ENDS_WITH_1(7, 3)) return "id-ce-CertificatePolicies-Deprecated";
448 else if (ENDS_WITH_1(7, 4)) return "id-ce-KeyUsageRestriction-Deprecated";
449 else if (ENDS_WITH_1(7, 7)) return "id-ce-SubjectAltName-Deprecated";
450 else if (ENDS_WITH_1(7, 8)) return "id-ce-IssuerAltName-Deprecated";
451 else if (ENDS_WITH_2(7, 14)) return "id-ce-SubjectKeyIdentifier";
452 else if (ENDS_WITH_2(7, 15)) return "id-ce-KeyUsage";
453 else if (ENDS_WITH_2(7, 16)) return "id-ce-PrivateKeyUsagePeriod";
454 else if (ENDS_WITH_2(7, 17)) return "id-ce-SubjectAltName";
455 else if (ENDS_WITH_2(7, 18)) return "id-ce-issuerAltName";
456 else if (ENDS_WITH_2(7, 19)) return "id-ce-BasicConstraints";
457 else if (ENDS_WITH_2(7, 25)) return "id-ce-CrlDistributionPoints";
458 else if (ENDS_WITH_2(7, 29)) return "id-ce-CertificateIssuer";
459 else if (ENDS_WITH_2(7, 30)) return "id-ce-NameConstraints";
460 else if (ENDS_WITH_2(7, 31)) return "id-ce-CrlDistributionPoints";
461 else if (ENDS_WITH_2(7, 32)) return "id-ce-CertificatePolicies";
462 else if (STARTS_WITH_2(7, 32))
463 {
464 if (ENDS_WITH_1(10, 0)) return "id-ce-cp-anyPolicy";
465 }
466 else if (ENDS_WITH_2(7, 35)) return "id-ce-AuthorityKeyIdentifier";
467 else if (ENDS_WITH_2(7, 36)) return "id-ce-PolicyConstraints";
468 else if (ENDS_WITH_2(7, 37)) return "id-ce-ExtKeyUsage";
469 }
470 }
471 else if (STARTS_WITH_2(2, 16)) /* Join assignments by country - 2.16. */
472 {
473 if (0)
474 {
475 }
476 else if (STARTS_WITH_3(5, 840)) /* USA - 2.16.840. */
477 {
478 if (STARTS_WITH_1(9, 1)) /* US company arc. */
479 {
480 if (STARTS_WITH_3(11, 101)) /* US Government */
481 {
482 if (STARTS_WITH_1(15, 3)) /* Computer Security Objects Register */
483 {
484 if (STARTS_WITH_1(17, 4)) /* NIST Algorithms - 2.16.840.1.101.3.4. */
485 {
486 if (STARTS_WITH_1(19, 1)) /* AES - 2.16.840.1.101.3.4.1. */
487 {
488 }
489 else if (STARTS_WITH_1(19, 2)) /* Hash algorithms - 2.16.840.1.101.3.4.2. */
490 {
491 if (ENDS_WITH_1(21, 1)) return "nist-Sha256";
492 else if (ENDS_WITH_1(21, 2)) return "nist-Sha384";
493 else if (ENDS_WITH_1(21, 3)) return "nist-Sha512";
494 else if (ENDS_WITH_1(21, 4)) return "nist-Sha224";
495 }
496 }
497 }
498 }
499 else if (STARTS_WITH_6(11, 113730)) /* Netscape - 2.16.840.1.113730. */
500 {
501 if (STARTS_WITH_1(18, 1)) /* Netscape - 2.16.840.1.113730.1. */
502 {
503 if (ENDS_WITH_1(20, 1)) return "netscape-cert-type";
504 else if (ENDS_WITH_1(20, 2)) return "netscape-base-url";
505 else if (ENDS_WITH_1(20, 3)) return "netscape-revocation-url";
506 else if (ENDS_WITH_1(20, 4)) return "netscape-ca-revocation-url";
507 else if (ENDS_WITH_1(20, 7)) return "netscape-cert-renewal-url";
508 else if (ENDS_WITH_1(20, 8)) return "netscape-ca-policy-url";
509 else if (ENDS_WITH_1(20, 9)) return "netscape-HomePage-url";
510 else if (ENDS_WITH_2(20, 10)) return "netscape-EntityLogo";
511 else if (ENDS_WITH_2(20, 11)) return "netscape-UserPicture";
512 else if (ENDS_WITH_2(20, 12)) return "netscape-ssl-server-name";
513 else if (ENDS_WITH_2(20, 13)) return "netscape-comment";
514 }
515 else if (STARTS_WITH_1(18, 4)) /* Netscape - 2.16.840.1.113730.4. */
516 {
517 if (ENDS_WITH_1(20, 1)) return "netscape-eku-serverGatedCrypto";
518 }
519 }
520 else if (STARTS_WITH_6(11, 113733)) /* Verisign, Inc. - 2.16.840.1.113733. */
521 {
522 if (STARTS_WITH_1(18, 1)) /* Verisign PKI Sub Tree - 2.16.840.1.113733.1. */
523 {
524 if (ENDS_WITH_1(20, 6)) return "verisign-pki-extensions-subtree";
525 else if (STARTS_WITH_1(20, 6)) /* 2.16.840.1.113733.1.6. */
526 {
527 if (ENDS_WITH_1(22, 7)) return "verisign-pki-ext-RolloverID";
528 }
529 else if (ENDS_WITH_1(20, 7)) return "verisign-pki-policies";
530 else if (STARTS_WITH_1(20, 7)) /* 2.16.840.1.113733.1.7. */
531 {
532 if (ENDS_WITH_1(22, 9)) return "verisign-pki-policy-9";
533 else if (ENDS_WITH_2(22, 21)) return "verisign-pki-policy-21";
534 else if (ENDS_WITH_2(22, 23)) return "verisign-pki-policy-vtn-cp";
535 else if (STARTS_WITH_2(22, 23))
536 {
537 if (ENDS_WITH_1(25, 1)) return "verisign-pki-policy-vtn-cp-class1";
538 else if (ENDS_WITH_1(25, 2)) return "verisign-pki-policy-vtn-cp-class2";
539 else if (ENDS_WITH_1(25, 3)) return "verisign-pki-policy-vtn-cp-class3";
540 else if (ENDS_WITH_1(25, 4)) return "verisign-pki-policy-vtn-cp-class4";
541 else if (ENDS_WITH_1(25, 6)) return "verisign-pki-policy-vtn-cp-6";
542 }
543 }
544 else if (STARTS_WITH_1(20, 8)) /* 2.16.840.1.113733.1.8. */
545 {
546 if (ENDS_WITH_1(22, 1)) return "verisign-pki-eku-IssStrongCrypto";
547 }
548 else if (ENDS_WITH_2(22, 46)) return "verisign-pki-policy-cis";
549 else if (STARTS_WITH_2(22, 46))
550 {
551 if (ENDS_WITH_1(25, 1)) return "verisign-pki-policy-cis-type1";
552 else if (ENDS_WITH_1(25, 2)) return "verisign-pki-policy-cis-type2";
553 }
554 else if (ENDS_WITH_2(22, 48)) return "verisign-pki-policy-thawte";
555 else if (STARTS_WITH_2(22, 48))
556 {
557 if (ENDS_WITH_1(25, 1)) return "verisign-pki-policy-thawte-cps-1";
558 }
559 }
560 }
561 }
562 }
563 }
564 }
565 return NULL;
566}
567
568
569/**
570 * Dumps the type and value of an universal ASN.1 type.
571 *
572 * @returns True if it opens a child, false if not.
573 * @param pData The dumper data.
574 * @param pAsn1Core The ASN.1 object to dump.
575 * @param uDepth The current depth (for indentation).
576 */
577static bool rtAsn1DumpUniversalTypeAndValue(PRTASN1DUMPDATA pData, PCRTASN1CORE pAsn1Core, uint32_t uDepth)
578{
579 const char *pszValuePrefix = "-- value:";
580 const char *pszDefault = "";
581 if (pAsn1Core->fFlags & RTASN1CORE_F_DEFAULT)
582 {
583 pszValuePrefix = "DEFAULT";
584 pszDefault = "DEFAULT ";
585 }
586
587 bool fOpen = false;
588 switch (pAsn1Core->uRealTag)
589 {
590 case ASN1_TAG_BOOLEAN:
591 if (pAsn1Core->fFlags & RTASN1CORE_F_PRIMITE_TAG_STRUCT)
592 rtAsn1DumpPrintf(pData, "BOOLEAN %s %RTbool\n", pszValuePrefix, ((PCRTASN1BOOLEAN)pAsn1Core)->fValue);
593 else if (pAsn1Core->cb == 1 && pAsn1Core->uData.pu8)
594 rtAsn1DumpPrintf(pData, "BOOLEAN %s %u\n", pszValuePrefix, *pAsn1Core->uData.pu8);
595 else
596 rtAsn1DumpPrintf(pData, "BOOLEAN -- cb=%u\n", pAsn1Core->cb);
597 break;
598
599 case ASN1_TAG_INTEGER:
600 if ((pAsn1Core->fFlags & RTASN1CORE_F_PRIMITE_TAG_STRUCT) && pAsn1Core->cb <= 8)
601 rtAsn1DumpPrintf(pData, "INTEGER %s %llu / %#llx\n", pszValuePrefix,
602 ((PCRTASN1INTEGER)pAsn1Core)->uValue, ((PCRTASN1INTEGER)pAsn1Core)->uValue);
603 else if (pAsn1Core->cb == 0 || pAsn1Core->cb >= 512 || !pAsn1Core->uData.pu8)
604 rtAsn1DumpPrintf(pData, "INTEGER -- cb=%u\n", pAsn1Core->cb);
605 else if (pAsn1Core->cb <= 32)
606 rtAsn1DumpPrintf(pData, "INTEGER %s %.*Rhxs\n", pszValuePrefix, (size_t)pAsn1Core->cb, pAsn1Core->uData.pu8);
607 else
608 rtAsn1DumpPrintf(pData, "INTEGER %s\n%.*Rhxd\n", pszValuePrefix, (size_t)pAsn1Core->cb, pAsn1Core->uData.pu8);
609 break;
610
611 case ASN1_TAG_BIT_STRING:
612 if ((pAsn1Core->fFlags & RTASN1CORE_F_PRIMITE_TAG_STRUCT))
613 {
614 PCRTASN1BITSTRING pBitString = (PCRTASN1BITSTRING)pAsn1Core;
615 rtAsn1DumpPrintf(pData, "BIT STRING %s-- cb=%u cBits=%#x cMaxBits=%#x",
616 pszDefault, pBitString->Asn1Core.cb, pBitString->cBits, pBitString->cMaxBits);
617 if (pBitString->cBits <= 64)
618 rtAsn1DumpPrintf(pData, " value=%#llx\n", RTAsn1BitString_GetAsUInt64(pBitString));
619 else
620 rtAsn1DumpPrintf(pData, "\n");
621 }
622 else
623 rtAsn1DumpPrintf(pData, "BIT STRING %s-- cb=%u\n", pszDefault, pAsn1Core->cb);
624 fOpen = pAsn1Core->pOps != NULL;
625 break;
626
627 case ASN1_TAG_OCTET_STRING:
628 rtAsn1DumpPrintf(pData, "OCTET STRING %s-- cb=%u\n", pszDefault, pAsn1Core->cb);
629 fOpen = pAsn1Core->pOps != NULL;
630 break;
631
632 case ASN1_TAG_NULL:
633 rtAsn1DumpPrintf(pData, "NULL\n");
634 break;
635
636 case ASN1_TAG_OID:
637 if ((pAsn1Core->fFlags & RTASN1CORE_F_PRIMITE_TAG_STRUCT))
638 {
639 const char *pszObjIdName = rtAsn1DumpLookupObjIdName(((PCRTASN1OBJID)pAsn1Core)->szObjId);
640 if (pszObjIdName)
641 rtAsn1DumpPrintf(pData, "OBJECT IDENTIFIER %s%s ('%s')\n",
642 pszDefault, pszObjIdName, ((PCRTASN1OBJID)pAsn1Core)->szObjId);
643 else
644 rtAsn1DumpPrintf(pData, "OBJECT IDENTIFIER %s'%s'\n", pszDefault, ((PCRTASN1OBJID)pAsn1Core)->szObjId);
645 }
646 else
647 rtAsn1DumpPrintf(pData, "OBJECT IDENTIFIER %s -- cb=%u\n", pszDefault, pAsn1Core->cb);
648 break;
649
650 case ASN1_TAG_OBJECT_DESCRIPTOR:
651 rtAsn1DumpPrintf(pData, "OBJECT DESCRIPTOR -- cb=%u TODO\n", pAsn1Core->cb);
652 break;
653
654 case ASN1_TAG_EXTERNAL:
655 rtAsn1DumpPrintf(pData, "EXTERNAL -- cb=%u TODO\n", pAsn1Core->cb);
656 break;
657
658 case ASN1_TAG_REAL:
659 rtAsn1DumpPrintf(pData, "REAL -- cb=%u TODO\n", pAsn1Core->cb);
660 break;
661
662 case ASN1_TAG_ENUMERATED:
663 rtAsn1DumpPrintf(pData, "ENUMERATED -- cb=%u TODO\n", pAsn1Core->cb);
664 break;
665
666 case ASN1_TAG_EMBEDDED_PDV:
667 rtAsn1DumpPrintf(pData, "EMBEDDED PDV -- cb=%u TODO\n", pAsn1Core->cb);
668 break;
669
670 case ASN1_TAG_UTF8_STRING:
671 rtAsn1DumpString(pData, pAsn1Core, "UTF8 STRING", uDepth);
672 break;
673
674 case ASN1_TAG_RELATIVE_OID:
675 rtAsn1DumpPrintf(pData, "RELATIVE OBJECT IDENTIFIER -- cb=%u TODO\n", pAsn1Core->cb);
676 break;
677
678 case ASN1_TAG_SEQUENCE:
679 rtAsn1DumpPrintf(pData, "SEQUENCE -- cb=%u\n", pAsn1Core->cb);
680 fOpen = true;
681 break;
682 case ASN1_TAG_SET:
683 rtAsn1DumpPrintf(pData, "SET -- cb=%u\n", pAsn1Core->cb);
684 fOpen = true;
685 break;
686
687 case ASN1_TAG_NUMERIC_STRING:
688 rtAsn1DumpString(pData, pAsn1Core, "NUMERIC STRING", uDepth);
689 break;
690
691 case ASN1_TAG_PRINTABLE_STRING:
692 rtAsn1DumpString(pData, pAsn1Core, "PRINTABLE STRING", uDepth);
693 break;
694
695 case ASN1_TAG_T61_STRING:
696 rtAsn1DumpString(pData, pAsn1Core, "T61 STRING", uDepth);
697 break;
698
699 case ASN1_TAG_VIDEOTEX_STRING:
700 rtAsn1DumpString(pData, pAsn1Core, "VIDEOTEX STRING", uDepth);
701 break;
702
703 case ASN1_TAG_IA5_STRING:
704 rtAsn1DumpString(pData, pAsn1Core, "IA5 STRING", uDepth);
705 break;
706
707 case ASN1_TAG_GRAPHIC_STRING:
708 rtAsn1DumpString(pData, pAsn1Core, "GRAPHIC STRING", uDepth);
709 break;
710
711 case ASN1_TAG_VISIBLE_STRING:
712 rtAsn1DumpString(pData, pAsn1Core, "VISIBLE STRING", uDepth);
713 break;
714
715 case ASN1_TAG_GENERAL_STRING:
716 rtAsn1DumpString(pData, pAsn1Core, "GENERAL STRING", uDepth);
717 break;
718
719 case ASN1_TAG_UNIVERSAL_STRING:
720 rtAsn1DumpString(pData, pAsn1Core, "UNIVERSAL STRING", uDepth);
721 break;
722
723 case ASN1_TAG_BMP_STRING:
724 rtAsn1DumpString(pData, pAsn1Core, "BMP STRING", uDepth);
725 break;
726
727 case ASN1_TAG_UTC_TIME:
728 rtAsn1DumpTime(pData, pAsn1Core, "UTC TIME");
729 break;
730
731 case ASN1_TAG_GENERALIZED_TIME:
732 rtAsn1DumpTime(pData, pAsn1Core, "GENERALIZED TIME");
733 break;
734
735 case ASN1_TAG_CHARACTER_STRING:
736 rtAsn1DumpPrintf(pData, "CHARACTER STRING -- cb=%u TODO\n", pAsn1Core->cb);
737 break;
738
739 default:
740 rtAsn1DumpPrintf(pData, "[UNIVERSAL %u]\n", pAsn1Core->uTag);
741 break;
742 }
743 return fOpen;
744}
745
746
747/** @callback_method_impl{FNRTASN1ENUMCALLBACK} */
748static DECLCALLBACK(int) rtAsn1DumpEnumCallback(PRTASN1CORE pAsn1Core, const char *pszName, uint32_t uDepth, void *pvUser)
749{
750 PRTASN1DUMPDATA pData = (PRTASN1DUMPDATA)pvUser;
751 if (!pAsn1Core->fFlags)
752 return VINF_SUCCESS;
753
754 bool fOpen = false;
755 rtAsn1DumpPrintIdent(pData, uDepth);
756 switch (pAsn1Core->fClass & ASN1_TAGCLASS_MASK)
757 {
758 case ASN1_TAGCLASS_UNIVERSAL:
759 rtAsn1DumpPrintf(pData, "%-16s ", pszName);
760 fOpen = rtAsn1DumpUniversalTypeAndValue(pData, pAsn1Core, uDepth);
761 break;
762
763 case ASN1_TAGCLASS_CONTEXT:
764 if ((pAsn1Core->fRealClass & ASN1_TAGCLASS_MASK) == ASN1_TAGCLASS_UNIVERSAL)
765 {
766 rtAsn1DumpPrintf(pData, "%-16s [%u] ", pszName, pAsn1Core->uTag);
767 fOpen = rtAsn1DumpUniversalTypeAndValue(pData, pAsn1Core, uDepth);
768 }
769 else
770 {
771 rtAsn1DumpPrintf(pData, "%-16s [%u]\n", pszName, pAsn1Core->uTag);
772 fOpen = true;
773 }
774 break;
775
776 case ASN1_TAGCLASS_APPLICATION:
777 if ((pAsn1Core->fRealClass & ASN1_TAGCLASS_MASK) == ASN1_TAGCLASS_UNIVERSAL)
778 {
779 rtAsn1DumpPrintf(pData, "%-16s [APPLICATION %u] ", pszName, pAsn1Core->uTag);
780 fOpen = rtAsn1DumpUniversalTypeAndValue(pData, pAsn1Core, uDepth);
781 }
782 else
783 {
784 rtAsn1DumpPrintf(pData, "%-16s [APPLICATION %u]\n", pszName, pAsn1Core->uTag);
785 fOpen = true;
786 }
787 break;
788
789 case ASN1_TAGCLASS_PRIVATE:
790 if (RTASN1CORE_IS_DUMMY(pAsn1Core))
791 rtAsn1DumpPrintf(pData, "%-16s DUMMY\n", pszName);
792 else
793 {
794 rtAsn1DumpPrintf(pData, "%-16s [PRIVATE %u]\n", pszName, pAsn1Core->uTag);
795 fOpen = true;
796 }
797 break;
798 }
799 /** @todo {} */
800
801 /*
802 * Recurse.
803 */
804 if ( pAsn1Core->pOps
805 && pAsn1Core->pOps->pfnEnum)
806 pAsn1Core->pOps->pfnEnum(pAsn1Core, rtAsn1DumpEnumCallback, uDepth, pData);
807 return VINF_SUCCESS;
808}
809
810
811RTDECL(int) RTAsn1Dump(PCRTASN1CORE pAsn1Core, uint32_t fFlags, uint32_t uLevel, PFNRTDUMPPRINTFV pfnPrintfV, void *pvUser)
812{
813 if ( pAsn1Core->pOps
814 && pAsn1Core->pOps->pfnEnum)
815 {
816 RTASN1DUMPDATA Data;
817 Data.fFlags = fFlags;
818 Data.pfnPrintfV = pfnPrintfV;
819 Data.pvUser = pvUser;
820
821 return pAsn1Core->pOps->pfnEnum((PRTASN1CORE)pAsn1Core, rtAsn1DumpEnumCallback, uLevel, &Data);
822 }
823 return VINF_SUCCESS;
824}
825
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette