VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp@ 67808

Last change on this file since 67808 was 64883, checked in by vboxsync, 8 years ago

IPRT/ASN.1: Refactored array handling (SET OF, SEQUENCE OF) to use a pointer array instead of an object instance array. The old approach would move objects around in memory after they'd be initialized/decoded, making certain core optimziations involving pointers to object members impossible, as well as causing potentially causing trouble when modifying structures that takes down pointers after decoding. Fixed validation bug in rtCrX509Name_CheckSanityExtra where it didn't check that the RDNs had subitems but instead checked the parent twice (slight risk).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
  • Property svn:mergeinfo set to (toggle deleted branches)
    /branches/VBox-3.0/src/VBox/Runtime/common/asn1/asn1-basics.cpp58652,​70973
    /branches/VBox-3.2/src/VBox/Runtime/common/asn1/asn1-basics.cpp66309,​66318
    /branches/VBox-4.0/src/VBox/Runtime/common/asn1/asn1-basics.cpp70873
    /branches/VBox-4.1/src/VBox/Runtime/common/asn1/asn1-basics.cpp74233,​78414,​78691,​81841,​82127,​85941,​85944-85947,​85949-85950,​85953,​86701,​86728,​87009
    /branches/VBox-4.2/src/VBox/Runtime/common/asn1/asn1-basics.cpp86229-86230,​86234,​86529,​91503-91504,​91506-91508,​91510,​91514-91515,​91521
    /branches/VBox-4.3/src/VBox/Runtime/common/asn1/asn1-basics.cpp91223
    /branches/VBox-4.3/trunk/src/VBox/Runtime/common/asn1/asn1-basics.cpp91223
    /branches/andy/draganddrop/src/VBox/Runtime/common/asn1/asn1-basics.cpp90781-91268
    /branches/andy/guestctrl20/src/VBox/Runtime/common/asn1/asn1-basics.cpp78916,​78930
    /branches/dsen/gui/src/VBox/Runtime/common/asn1/asn1-basics.cpp79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
    /branches/dsen/gui2/src/VBox/Runtime/common/asn1/asn1-basics.cpp79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
    /branches/dsen/gui3/src/VBox/Runtime/common/asn1/asn1-basics.cpp79645-79692
File size: 22.0 KB
Line 
1/* $Id: asn1-cursor.cpp 64883 2016-12-15 15:26:20Z vboxsync $ */
2/** @file
3 * IPRT - ASN.1, Basic Operations.
4 */
5
6/*
7 * Copyright (C) 2006-2016 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/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/asn1.h>
33
34#include <iprt/alloca.h>
35#include <iprt/err.h>
36#include <iprt/string.h>
37#include <iprt/ctype.h>
38
39#include <iprt/formats/asn1.h>
40
41
42/*********************************************************************************************************************************
43* Defined Constants And Macros *
44*********************************************************************************************************************************/
45/** @def RTASN1_MAX_NESTING
46 * The maximum nesting depth we allow. This limit is enforced to avoid running
47 * out of stack due to malformed ASN.1 input.
48 *
49 * For reference, 'RTSignTool verify-exe RTSignTool.exe', requires a value of 15
50 * to work without hitting the limit for signatures with simple timestamps, and
51 * 23 (amd64/rel = ~3KB) for the new microsoft timestamp counter signatures.
52 */
53#ifdef IN_RING3
54# define RTASN1_MAX_NESTING 64
55#else
56# define RTASN1_MAX_NESTING 32
57#endif
58
59
60
61RTDECL(PRTASN1CURSOR) RTAsn1CursorInitPrimary(PRTASN1CURSORPRIMARY pPrimaryCursor, void const *pvFirst, uint32_t cb,
62 PRTERRINFO pErrInfo, PCRTASN1ALLOCATORVTABLE pAllocator, uint32_t fFlags,
63 const char *pszErrorTag)
64{
65 pPrimaryCursor->Cursor.pbCur = (uint8_t const *)pvFirst;
66 pPrimaryCursor->Cursor.cbLeft = cb;
67 pPrimaryCursor->Cursor.fFlags = (uint8_t)fFlags; Assert(fFlags <= UINT8_MAX);
68 pPrimaryCursor->Cursor.cDepth = 0;
69 pPrimaryCursor->Cursor.abReserved[0] = 0;
70 pPrimaryCursor->Cursor.abReserved[1] = 0;
71 pPrimaryCursor->Cursor.pPrimary = pPrimaryCursor;
72 pPrimaryCursor->Cursor.pUp = NULL;
73 pPrimaryCursor->Cursor.pszErrorTag = pszErrorTag;
74 pPrimaryCursor->pErrInfo = pErrInfo;
75 pPrimaryCursor->pAllocator = pAllocator;
76 return &pPrimaryCursor->Cursor;
77}
78
79
80RTDECL(int) RTAsn1CursorInitSub(PRTASN1CURSOR pParent, uint32_t cb, PRTASN1CURSOR pChild, const char *pszErrorTag)
81{
82 AssertReturn(pParent->pPrimary, VERR_ASN1_INTERNAL_ERROR_1);
83 AssertReturn(pParent->pbCur, VERR_ASN1_INTERNAL_ERROR_2);
84
85 pChild->pbCur = pParent->pbCur;
86 pChild->cbLeft = cb;
87 pChild->fFlags = pParent->fFlags;
88 pChild->cDepth = pParent->cDepth + 1;
89 AssertReturn(pChild->cDepth < RTASN1_MAX_NESTING, VERR_ASN1_TOO_DEEPLY_NESTED);
90 pChild->abReserved[0] = 0;
91 pChild->abReserved[1] = 0;
92 pChild->pPrimary = pParent->pPrimary;
93 pChild->pUp = pParent;
94 pChild->pszErrorTag = pszErrorTag;
95
96 AssertReturn(pParent->cbLeft >= cb, VERR_ASN1_INTERNAL_ERROR_3);
97 pParent->pbCur += cb;
98 pParent->cbLeft -= cb;
99
100 return VINF_SUCCESS;
101}
102
103
104RTDECL(int) RTAsn1CursorInitSubFromCore(PRTASN1CURSOR pParent, PRTASN1CORE pAsn1Core,
105 PRTASN1CURSOR pChild, const char *pszErrorTag)
106{
107 AssertReturn(pParent->pPrimary, VERR_ASN1_INTERNAL_ERROR_1);
108 AssertReturn(pParent->pbCur, VERR_ASN1_INTERNAL_ERROR_2);
109
110 pChild->pbCur = pAsn1Core->uData.pu8;
111 pChild->cbLeft = pAsn1Core->cb;
112 pChild->fFlags = pParent->fFlags;
113 pChild->cDepth = pParent->cDepth + 1;
114 AssertReturn(pChild->cDepth < RTASN1_MAX_NESTING, VERR_ASN1_TOO_DEEPLY_NESTED);
115 pChild->abReserved[0] = 0;
116 pChild->abReserved[1] = 0;
117 pChild->pPrimary = pParent->pPrimary;
118 pChild->pUp = pParent;
119 pChild->pszErrorTag = pszErrorTag;
120
121 return VINF_SUCCESS;
122}
123
124
125RTDECL(int) RTAsn1CursorSetInfoV(PRTASN1CURSOR pCursor, int rc, const char *pszMsg, va_list va)
126{
127 PRTERRINFO pErrInfo = pCursor->pPrimary->pErrInfo;
128 if (pErrInfo)
129 {
130 /* Format the message. */
131 RTErrInfoSetV(pErrInfo, rc, pszMsg, va);
132
133 /* Add the prefixes. This isn't the fastest way, but it's the one
134 which eats the least stack. */
135 char *pszBuf = pErrInfo->pszMsg;
136 size_t cbBuf = pErrInfo->cbMsg;
137 if (pszBuf && cbBuf > 32)
138 {
139 size_t cbMove = strlen(pszBuf) + 1;
140
141 /* Make sure there is a ': '. */
142 bool fFirst = false;
143 if (pszMsg[0] != '%' || pszMsg[1] != 's' || pszMsg[2] != ':')
144 {
145 if (cbMove + 2 < cbBuf)
146 {
147 memmove(pszBuf + 2, pszBuf, cbMove);
148 pszBuf[0] = ':';
149 pszBuf[1] = ' ';
150 cbMove += 2;
151 fFirst = true;
152 }
153 }
154
155 /* Add the prefixes from the cursor chain. */
156 while (pCursor)
157 {
158 if (pCursor->pszErrorTag)
159 {
160 size_t cchErrorTag = strlen(pCursor->pszErrorTag);
161 if (cchErrorTag + !fFirst + cbMove > cbBuf)
162 break;
163 memmove(pszBuf + cchErrorTag + !fFirst, pszBuf, cbMove);
164 memcpy(pszBuf, pCursor->pszErrorTag, cchErrorTag);
165 if (!fFirst)
166 pszBuf[cchErrorTag] = '.';
167 cbMove += cchErrorTag + !fFirst;
168 fFirst = false;
169 }
170 pCursor = pCursor->pUp;
171 }
172 }
173 }
174
175 return rc;
176}
177
178
179RTDECL(int) RTAsn1CursorSetInfo(PRTASN1CURSOR pCursor, int rc, const char *pszMsg, ...)
180{
181 va_list va;
182 va_start(va, pszMsg);
183 rc = RTAsn1CursorSetInfoV(pCursor, rc, pszMsg, va);
184 va_end(va);
185 return rc;
186}
187
188
189RTDECL(int) RTAsn1CursorCheckEnd(PRTASN1CURSOR pCursor)
190{
191 if (pCursor->cbLeft == 0)
192 return VINF_SUCCESS;
193 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
194 "%u (%#x) bytes left over", pCursor->cbLeft, pCursor->cbLeft);
195}
196
197
198RTDECL(PRTASN1ALLOCATION) RTAsn1CursorInitAllocation(PRTASN1CURSOR pCursor, PRTASN1ALLOCATION pAllocation)
199{
200 pAllocation->cbAllocated = 0;
201 pAllocation->cReallocs = 0;
202 pAllocation->uReserved0 = 0;
203 pAllocation->pAllocator = pCursor->pPrimary->pAllocator;
204 return pAllocation;
205}
206
207
208RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1CursorInitArrayAllocation(PRTASN1CURSOR pCursor, PRTASN1ARRAYALLOCATION pAllocation,
209 size_t cbEntry)
210{
211 Assert(cbEntry >= sizeof(RTASN1CORE));
212 Assert(cbEntry < _1M);
213 Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry);
214 pAllocation->cbEntry = (uint32_t)cbEntry;
215 pAllocation->cPointersAllocated = 0;
216 pAllocation->cEntriesAllocated = 0;
217 pAllocation->cResizeCalls = 0;
218 pAllocation->uReserved0 = 0;
219 pAllocation->pAllocator = pCursor->pPrimary->pAllocator;
220 return pAllocation;
221}
222
223
224RTDECL(int) RTAsn1CursorReadHdr(PRTASN1CURSOR pCursor, PRTASN1CORE pAsn1Core, const char *pszErrorTag)
225{
226 /*
227 * Initialize the return structure in case of failure.
228 */
229 pAsn1Core->uTag = 0;
230 pAsn1Core->fClass = 0;
231 pAsn1Core->uRealTag = 0;
232 pAsn1Core->fRealClass = 0;
233 pAsn1Core->cbHdr = 0;
234 pAsn1Core->cb = 0;
235 pAsn1Core->fFlags = 0;
236 pAsn1Core->uData.pv = NULL;
237 pAsn1Core->pOps = NULL;
238
239 /*
240 * The header has at least two bytes: Type & length.
241 */
242 if (pCursor->cbLeft >= 2)
243 {
244 uint32_t uTag = pCursor->pbCur[0];
245 uint32_t cb = pCursor->pbCur[1];
246 pCursor->cbLeft -= 2;
247 pCursor->pbCur += 2;
248
249 pAsn1Core->uRealTag = pAsn1Core->uTag = uTag & ASN1_TAG_MASK;
250 pAsn1Core->fRealClass = pAsn1Core->fClass = uTag & ~ASN1_TAG_MASK;
251 pAsn1Core->cbHdr = 2;
252 if ((uTag & ASN1_TAG_MASK) == ASN1_TAG_USE_LONG_FORM)
253 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_LONG_TAG,
254 "%s: Implement parsing of tags > 30: %#x (length=%#x)", pszErrorTag, uTag, cb);
255
256 /* Extended length field? */
257 if (cb & RT_BIT(7))
258 {
259 if (cb != RT_BIT(7))
260 {
261 /* Definite form. */
262 uint8_t cbEnc = cb & 0x7f;
263 if (cbEnc > pCursor->cbLeft)
264 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING,
265 "%s: Extended BER length field longer than available data: %#x vs %#x (uTag=%#x)",
266 pszErrorTag, cbEnc, pCursor->cbLeft, uTag);
267 switch (cbEnc)
268 {
269 case 1:
270 cb = pCursor->pbCur[0];
271 break;
272 case 2:
273 cb = RT_MAKE_U16(pCursor->pbCur[1], pCursor->pbCur[0]);
274 break;
275 case 3:
276 cb = RT_MAKE_U32_FROM_U8(pCursor->pbCur[2], pCursor->pbCur[1], pCursor->pbCur[0], 0);
277 break;
278 case 4:
279 cb = RT_MAKE_U32_FROM_U8(pCursor->pbCur[3], pCursor->pbCur[2], pCursor->pbCur[1], pCursor->pbCur[0]);
280 break;
281 default:
282 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING,
283 "%s: Too long/short extended BER length field: %#x (uTag=%#x)",
284 pszErrorTag, cbEnc, uTag);
285 }
286 pCursor->cbLeft -= cbEnc;
287 pCursor->pbCur += cbEnc;
288 pAsn1Core->cbHdr += cbEnc;
289
290 /* Check the length encoding efficiency (T-REC-X.690-200811 10.1, 9.1). */
291 if (pCursor->fFlags & (RTASN1CURSOR_FLAGS_DER | RTASN1CURSOR_FLAGS_CER))
292 {
293 if (cb <= 0x7f)
294 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING,
295 "%s: Invalid DER/CER length encoding: cbEnc=%u cb=%#x uTag=%#x",
296 pszErrorTag, cbEnc, cb, uTag);
297 uint8_t cbNeeded;
298 if (cb <= 0x000000ff) cbNeeded = 1;
299 else if (cb <= 0x0000ffff) cbNeeded = 2;
300 else if (cb <= 0x00ffffff) cbNeeded = 3;
301 else cbNeeded = 4;
302 if (cbNeeded != cbEnc)
303 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_LENGTH_ENCODING,
304 "%s: Invalid DER/CER length encoding: cb=%#x uTag=%#x cbEnc=%u cbNeeded=%u",
305 pszErrorTag, cb, uTag, cbEnc, cbNeeded);
306 }
307 }
308 /* Indefinite form. */
309 else if (pCursor->fFlags & RTASN1CURSOR_FLAGS_DER)
310 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_IDEFINITE_LENGTH,
311 "%s: Indefinite length form not allowed in DER mode (uTag=%#x).", pszErrorTag, uTag);
312 else
313 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_IDEFINITE_LENGTH_NOT_SUP,
314 "%s: Indefinite BER/CER length not supported (uTag=%#x)", pszErrorTag, uTag);
315 }
316
317 /* Check if the length makes sense. */
318 if (cb > pCursor->cbLeft)
319 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_BAD_LENGTH,
320 "%s: BER value length out of bounds: %#x (max=%#x uTag=%#x)",
321 pszErrorTag, cb, pCursor->cbLeft, uTag);
322
323 pAsn1Core->fFlags |= RTASN1CORE_F_PRESENT | RTASN1CORE_F_DECODED_CONTENT;
324 pAsn1Core->cb = cb;
325 pAsn1Core->uData.pv = (void *)pCursor->pbCur;
326 return VINF_SUCCESS;
327 }
328
329 if (pCursor->cbLeft)
330 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_TOO_LITTLE_DATA_LEFT,
331 "%s: Too little data left to form a valid BER header", pszErrorTag);
332 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NO_MORE_DATA,
333 "%s: No more data reading BER header", pszErrorTag);
334}
335
336
337RTDECL(int) RTAsn1CursorMatchTagClassFlagsEx(PRTASN1CURSOR pCursor, PRTASN1CORE pAsn1Core, uint32_t uTag, uint32_t fClass,
338 bool fString, uint32_t fFlags, const char *pszErrorTag, const char *pszWhat)
339{
340 if (pAsn1Core->uTag == uTag)
341 {
342 if (pAsn1Core->fClass == fClass)
343 return VINF_SUCCESS;
344 if ( fString
345 && pAsn1Core->fClass == (fClass | ASN1_TAGFLAG_CONSTRUCTED))
346 {
347 if (!(pCursor->fFlags & (RTASN1CURSOR_FLAGS_DER | RTASN1CURSOR_FLAGS_CER)))
348 return VINF_SUCCESS;
349 if (pCursor->fFlags & RTASN1CURSOR_FLAGS_CER)
350 {
351 if (pAsn1Core->cb > 1000)
352 return VINF_SUCCESS;
353 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_CONSTRUCTED_STRING,
354 "%s: Constructed %s only allowed for >1000 byte in CER encoding: cb=%#x uTag=%#x fClass=%#x",
355 pszErrorTag, pszWhat, pAsn1Core->cb, pAsn1Core->uTag, pAsn1Core->fClass);
356 }
357 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_CONSTRUCTED_STRING,
358 "%s: DER encoding does not allow constructed %s (cb=%#x uTag=%#x fClass=%#x)",
359 pszErrorTag, pszWhat, pAsn1Core->cb, pAsn1Core->uTag, pAsn1Core->fClass);
360 }
361 }
362
363 if (fFlags & RTASN1CURSOR_GET_F_IMPLICIT)
364 {
365 pAsn1Core->fFlags |= RTASN1CORE_F_TAG_IMPLICIT;
366 pAsn1Core->uRealTag = uTag;
367 pAsn1Core->fRealClass = fClass;
368 return VINF_SUCCESS;
369 }
370
371 return RTAsn1CursorSetInfo(pCursor, pAsn1Core->uTag != uTag ? VERR_ASN1_CURSOR_TAG_MISMATCH : VERR_ASN1_CURSOR_TAG_FLAG_CLASS_MISMATCH,
372 "%s: Unexpected %s type/flags: %#x/%#x (expected %#x/%#x)",
373 pszErrorTag, pszWhat, pAsn1Core->uTag, pAsn1Core->fClass, uTag, fClass);
374}
375
376
377
378static int rtAsn1CursorGetXxxxCursor(PRTASN1CURSOR pCursor, uint32_t fFlags, uint32_t uTag, uint8_t fClass,
379 PRTASN1CORE pAsn1Core, PRTASN1CURSOR pRetCursor,
380 const char *pszErrorTag, const char *pszWhat)
381{
382 int rc = RTAsn1CursorReadHdr(pCursor, pAsn1Core, pszErrorTag);
383 if (RT_SUCCESS(rc))
384 {
385 if ( pAsn1Core->uTag == uTag
386 && pAsn1Core->fClass == fClass)
387 rc = VINF_SUCCESS;
388 else if (fFlags & RTASN1CURSOR_GET_F_IMPLICIT)
389 {
390 pAsn1Core->fFlags |= RTASN1CORE_F_TAG_IMPLICIT;
391 pAsn1Core->uRealTag = uTag;
392 pAsn1Core->fRealClass = fClass;
393 rc = VINF_SUCCESS;
394 }
395 else
396 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_ILLEGAL_CONSTRUCTED_STRING,
397 "%s: Unexpected %s type/flags: %#x/%#x (expected %#x/%#x)",
398 pszErrorTag, pszWhat, pAsn1Core->uTag, pAsn1Core->fClass, uTag, fClass);
399 rc = RTAsn1CursorInitSub(pCursor, pAsn1Core->cb, pRetCursor, pszErrorTag);
400 if (RT_SUCCESS(rc))
401 {
402 pAsn1Core->fFlags |= RTASN1CORE_F_PRIMITE_TAG_STRUCT;
403 return VINF_SUCCESS;
404 }
405 }
406 return rc;
407}
408
409
410RTDECL(int) RTAsn1CursorGetSequenceCursor(PRTASN1CURSOR pCursor, uint32_t fFlags,
411 PRTASN1SEQUENCECORE pSeqCore, PRTASN1CURSOR pSeqCursor, const char *pszErrorTag)
412{
413 return rtAsn1CursorGetXxxxCursor(pCursor, fFlags, ASN1_TAG_SEQUENCE, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED,
414 &pSeqCore->Asn1Core, pSeqCursor, pszErrorTag, "sequence");
415}
416
417
418RTDECL(int) RTAsn1CursorGetSetCursor(PRTASN1CURSOR pCursor, uint32_t fFlags,
419 PRTASN1SETCORE pSetCore, PRTASN1CURSOR pSetCursor, const char *pszErrorTag)
420{
421 return rtAsn1CursorGetXxxxCursor(pCursor, fFlags, ASN1_TAG_SET, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED,
422 &pSetCore->Asn1Core, pSetCursor, pszErrorTag, "set");
423}
424
425
426RTDECL(int) RTAsn1CursorGetContextTagNCursor(PRTASN1CURSOR pCursor, uint32_t fFlags, uint32_t uExpectedTag,
427 PCRTASN1COREVTABLE pVtable, PRTASN1CONTEXTTAG pCtxTag, PRTASN1CURSOR pCtxTagCursor,
428 const char *pszErrorTag)
429{
430 int rc = rtAsn1CursorGetXxxxCursor(pCursor, fFlags, uExpectedTag, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED,
431 &pCtxTag->Asn1Core, pCtxTagCursor, pszErrorTag, "ctx tag");
432 pCtxTag->Asn1Core.pOps = pVtable;
433 return rc;
434}
435
436
437RTDECL(int) RTAsn1CursorPeek(PRTASN1CURSOR pCursor, PRTASN1CORE pAsn1Core)
438{
439 uint32_t cbSavedLeft = pCursor->cbLeft;
440 uint8_t const *pbSavedCur = pCursor->pbCur;
441 PRTERRINFO pErrInfo = pCursor->pPrimary->pErrInfo;
442 pCursor->pPrimary->pErrInfo = NULL;
443
444 int rc = RTAsn1CursorReadHdr(pCursor, pAsn1Core, "peek");
445
446 pCursor->pPrimary->pErrInfo = pErrInfo;
447 pCursor->pbCur = pbSavedCur;
448 pCursor->cbLeft = cbSavedLeft;
449 return rc;
450}
451
452
453RTDECL(bool) RTAsn1CursorIsNextEx(PRTASN1CURSOR pCursor, uint32_t uTag, uint8_t fClass)
454{
455 RTASN1CORE Asn1Core;
456 int rc = RTAsn1CursorPeek(pCursor, &Asn1Core);
457 if (RT_SUCCESS(rc))
458 return uTag == Asn1Core.uTag
459 && fClass == Asn1Core.fClass;
460 return false;
461}
462
463
464/** @name Legacy Interfaces.
465 * @{ */
466RTDECL(int) RTAsn1CursorGetCore(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1CORE pAsn1Core, const char *pszErrorTag)
467{
468 return RTAsn1Core_DecodeAsn1(pCursor, fFlags, pAsn1Core, pszErrorTag);
469}
470
471
472RTDECL(int) RTAsn1CursorGetNull(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1NULL pNull, const char *pszErrorTag)
473{
474 return RTAsn1Null_DecodeAsn1(pCursor, fFlags, pNull, pszErrorTag);
475}
476
477
478RTDECL(int) RTAsn1CursorGetInteger(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1INTEGER pInteger, const char *pszErrorTag)
479{
480 return RTAsn1Integer_DecodeAsn1(pCursor, fFlags, pInteger, pszErrorTag);
481}
482
483
484RTDECL(int) RTAsn1CursorGetBoolean(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1BOOLEAN pBoolean, const char *pszErrorTag)
485{
486 return RTAsn1Boolean_DecodeAsn1(pCursor, fFlags, pBoolean, pszErrorTag);
487}
488
489
490RTDECL(int) RTAsn1CursorGetObjId(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1OBJID pObjId, const char *pszErrorTag)
491{
492 return RTAsn1ObjId_DecodeAsn1(pCursor, fFlags, pObjId, pszErrorTag);
493}
494
495
496RTDECL(int) RTAsn1CursorGetTime(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1TIME pTime, const char *pszErrorTag)
497{
498 return RTAsn1Time_DecodeAsn1(pCursor, fFlags, pTime, pszErrorTag);
499}
500
501
502RTDECL(int) RTAsn1CursorGetBitStringEx(PRTASN1CURSOR pCursor, uint32_t fFlags, uint32_t cMaxBits, PRTASN1BITSTRING pBitString,
503 const char *pszErrorTag)
504{
505 return RTAsn1BitString_DecodeAsn1Ex(pCursor, fFlags, cMaxBits, pBitString, pszErrorTag);
506}
507
508
509RTDECL(int) RTAsn1CursorGetBitString(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1BITSTRING pBitString, const char *pszErrorTag)
510{
511 return RTAsn1BitString_DecodeAsn1(pCursor, fFlags, pBitString, pszErrorTag);
512}
513
514
515RTDECL(int) RTAsn1CursorGetOctetString(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1OCTETSTRING pOctetString,
516 const char *pszErrorTag)
517{
518 return RTAsn1OctetString_DecodeAsn1(pCursor, fFlags, pOctetString, pszErrorTag);
519}
520
521
522RTDECL(int) RTAsn1CursorGetString(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1STRING pString, const char *pszErrorTag)
523{
524 return RTAsn1String_DecodeAsn1(pCursor, fFlags, pString, pszErrorTag);
525}
526
527
528RTDECL(int) RTAsn1CursorGetIa5String(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1STRING pString, const char *pszErrorTag)
529{
530 return RTAsn1Ia5String_DecodeAsn1(pCursor, fFlags, pString, pszErrorTag);
531}
532
533
534RTDECL(int) RTAsn1CursorGetUtf8String(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1STRING pString, const char *pszErrorTag)
535{
536 return RTAsn1Utf8String_DecodeAsn1(pCursor, fFlags, pString, pszErrorTag);
537}
538
539
540RTDECL(int) RTAsn1CursorGetBmpString(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1STRING pString, const char *pszErrorTag)
541{
542 return RTAsn1BmpString_DecodeAsn1(pCursor, fFlags, pString, pszErrorTag);
543}
544
545
546RTDECL(int) RTAsn1CursorGetDynType(PRTASN1CURSOR pCursor, uint32_t fFlags, PRTASN1DYNTYPE pDynType, const char *pszErrorTag)
547{
548 return RTAsn1DynType_DecodeAsn1(pCursor, fFlags, pDynType, pszErrorTag);
549}
550/** @} */
551
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