Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendecode.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2005-2009 Juan Lang 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 * 00018 * This file implements ASN.1 DER decoding of a limited set of types. 00019 * It isn't a full ASN.1 implementation. Microsoft implements BER 00020 * encoding of many of the basic types in msasn1.dll, but that interface isn't 00021 * implemented, so I implement them here. 00022 * 00023 * References: 00024 * "A Layman's Guide to a Subset of ASN.1, BER, and DER", by Burton Kaliski 00025 * (available online, look for a PDF copy as the HTML versions tend to have 00026 * translation errors.) 00027 * 00028 * RFC3280, http://www.faqs.org/rfcs/rfc3280.html 00029 * 00030 * MSDN, especially "Constants for CryptEncodeObject and CryptDecodeObject" 00031 */ 00032 00033 #include "config.h" 00034 #include "wine/port.h" 00035 00036 #include <assert.h> 00037 #include <stdarg.h> 00038 #include <stdio.h> 00039 #include <stdlib.h> 00040 00041 #define NONAMELESSUNION 00042 00043 #include "windef.h" 00044 #include "winbase.h" 00045 #include "wincrypt.h" 00046 #include "winnls.h" 00047 #include "snmp.h" 00048 #include "wine/debug.h" 00049 #include "wine/exception.h" 00050 #include "crypt32_private.h" 00051 00052 /* This is a bit arbitrary, but to set some limit: */ 00053 #define MAX_ENCODED_LEN 0x02000000 00054 00055 #define ASN_FLAGS_MASK 0xe0 00056 #define ASN_TYPE_MASK 0x1f 00057 00058 WINE_DEFAULT_DEBUG_CHANNEL(cryptasn); 00059 WINE_DECLARE_DEBUG_CHANNEL(crypt); 00060 00061 typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *, 00062 DWORD, DWORD, void *, DWORD *); 00063 typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *, 00064 DWORD, DWORD, PCRYPT_DECODE_PARA, void *, DWORD *); 00065 00066 /* Internal decoders don't do memory allocation or exception handling, and 00067 * they report how many bytes they decoded. 00068 */ 00069 typedef BOOL (*InternalDecodeFunc)(const BYTE *pbEncoded, DWORD cbEncoded, 00070 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 00071 00072 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded, 00073 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00074 DWORD *pcbDecoded); 00075 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded, 00076 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00077 DWORD *pcbDecoded); 00078 /* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time. 00079 */ 00080 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, 00081 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 00082 /* Assumes algo->Parameters.pbData is set ahead of time. */ 00083 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded, 00084 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 00085 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded, 00086 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 00087 /* Assumes the CRYPT_DATA_BLOB's pbData member has been initialized */ 00088 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded, 00089 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00090 DWORD *pcbDecoded); 00091 /* Doesn't check the tag, assumes the caller does so */ 00092 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded, 00093 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 00094 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded, 00095 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); 00096 /* Like CRYPT_AsnDecodeInteger, but assumes the CRYPT_INTEGER_BLOB's pbData 00097 * member has been initialized, doesn't do exception handling, and doesn't do 00098 * memory allocation. Also doesn't check tag, assumes the caller has checked 00099 * it. 00100 */ 00101 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded, 00102 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00103 DWORD *pcbDecoded); 00104 /* Like CRYPT_AsnDecodeInteger, but unsigned. */ 00105 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded, 00106 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00107 DWORD *pcbDecoded); 00108 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, 00109 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00110 DWORD *pcbDecoded); 00111 00112 /* Gets the number of length bytes from the given (leading) length byte */ 00113 #define GET_LEN_BYTES(b) ((b) <= 0x80 ? 1 : 1 + ((b) & 0x7f)) 00114 00115 /* Helper function to get the encoded length of the data starting at pbEncoded, 00116 * where pbEncoded[0] is the tag. If the data are too short to contain a 00117 * length or if the length is too large for cbEncoded, sets an appropriate 00118 * error code and returns FALSE. If the encoded length is unknown due to 00119 * indefinite length encoding, *len is set to CMSG_INDEFINITE_LENGTH. 00120 */ 00121 static BOOL CRYPT_GetLengthIndefinite(const BYTE *pbEncoded, DWORD cbEncoded, 00122 DWORD *len) 00123 { 00124 BOOL ret; 00125 00126 if (cbEncoded <= 1) 00127 { 00128 SetLastError(CRYPT_E_ASN1_CORRUPT); 00129 ret = FALSE; 00130 } 00131 else if (pbEncoded[1] <= 0x7f) 00132 { 00133 if (pbEncoded[1] + 1 > cbEncoded) 00134 { 00135 SetLastError(CRYPT_E_ASN1_EOD); 00136 ret = FALSE; 00137 } 00138 else 00139 { 00140 *len = pbEncoded[1]; 00141 ret = TRUE; 00142 } 00143 } 00144 else if (pbEncoded[1] == 0x80) 00145 { 00146 *len = CMSG_INDEFINITE_LENGTH; 00147 ret = TRUE; 00148 } 00149 else 00150 { 00151 BYTE lenLen = GET_LEN_BYTES(pbEncoded[1]); 00152 00153 if (lenLen > sizeof(DWORD) + 1) 00154 { 00155 SetLastError(CRYPT_E_ASN1_LARGE); 00156 ret = FALSE; 00157 } 00158 else if (lenLen + 2 > cbEncoded) 00159 { 00160 SetLastError(CRYPT_E_ASN1_CORRUPT); 00161 ret = FALSE; 00162 } 00163 else 00164 { 00165 DWORD out = 0; 00166 00167 pbEncoded += 2; 00168 while (--lenLen) 00169 { 00170 out <<= 8; 00171 out |= *pbEncoded++; 00172 } 00173 if (out + lenLen + 1 > cbEncoded) 00174 { 00175 SetLastError(CRYPT_E_ASN1_EOD); 00176 ret = FALSE; 00177 } 00178 else 00179 { 00180 *len = out; 00181 ret = TRUE; 00182 } 00183 } 00184 } 00185 return ret; 00186 } 00187 00188 /* Like CRYPT_GetLengthIndefinite, but disallows indefinite-length encoding. */ 00189 static BOOL CRYPT_GetLen(const BYTE *pbEncoded, DWORD cbEncoded, DWORD *len) 00190 { 00191 BOOL ret; 00192 00193 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, len)) && 00194 *len == CMSG_INDEFINITE_LENGTH) 00195 { 00196 SetLastError(CRYPT_E_ASN1_CORRUPT); 00197 ret = FALSE; 00198 } 00199 return ret; 00200 } 00201 00202 /* Helper function to check *pcbStructInfo, set it to the required size, and 00203 * optionally to allocate memory. Assumes pvStructInfo is not NULL. 00204 * If CRYPT_DECODE_ALLOC_FLAG is set in dwFlags, *pvStructInfo will be set to a 00205 * pointer to the newly allocated memory. 00206 */ 00207 static BOOL CRYPT_DecodeEnsureSpace(DWORD dwFlags, 00208 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, 00209 DWORD bytesNeeded) 00210 { 00211 BOOL ret = TRUE; 00212 00213 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 00214 { 00215 if (pDecodePara && pDecodePara->pfnAlloc) 00216 *(BYTE **)pvStructInfo = pDecodePara->pfnAlloc(bytesNeeded); 00217 else 00218 *(BYTE **)pvStructInfo = LocalAlloc(0, bytesNeeded); 00219 if (!*(BYTE **)pvStructInfo) 00220 ret = FALSE; 00221 else 00222 *pcbStructInfo = bytesNeeded; 00223 } 00224 else if (*pcbStructInfo < bytesNeeded) 00225 { 00226 *pcbStructInfo = bytesNeeded; 00227 SetLastError(ERROR_MORE_DATA); 00228 ret = FALSE; 00229 } 00230 else 00231 *pcbStructInfo = bytesNeeded; 00232 return ret; 00233 } 00234 00235 static void CRYPT_FreeSpace(const CRYPT_DECODE_PARA *pDecodePara, LPVOID pv) 00236 { 00237 if (pDecodePara && pDecodePara->pfnFree) 00238 pDecodePara->pfnFree(pv); 00239 else 00240 LocalFree(pv); 00241 } 00242 00243 /* Helper function to check *pcbStructInfo and set it to the required size. 00244 * Assumes pvStructInfo is not NULL. 00245 */ 00246 static BOOL CRYPT_DecodeCheckSpace(DWORD *pcbStructInfo, DWORD bytesNeeded) 00247 { 00248 BOOL ret; 00249 00250 if (*pcbStructInfo < bytesNeeded) 00251 { 00252 *pcbStructInfo = bytesNeeded; 00253 SetLastError(ERROR_MORE_DATA); 00254 ret = FALSE; 00255 } 00256 else 00257 { 00258 *pcbStructInfo = bytesNeeded; 00259 ret = TRUE; 00260 } 00261 return ret; 00262 } 00263 00264 /* tag: 00265 * The expected tag of the item. If tag is 0, decodeFunc is called 00266 * regardless of the tag value seen. 00267 * offset: 00268 * A sequence is decoded into a struct. The offset member is the 00269 * offset of this item within that struct. 00270 * decodeFunc: 00271 * The decoder function to use. If this is NULL, then the member isn't 00272 * decoded, but minSize space is reserved for it. 00273 * minSize: 00274 * The minimum amount of space occupied after decoding. You must set this. 00275 * optional: 00276 * If true, and the tag doesn't match the expected tag for this item, 00277 * or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is 00278 * filled with 0 for this member. 00279 * hasPointer, pointerOffset: 00280 * If the item has dynamic data, set hasPointer to TRUE, pointerOffset to 00281 * the offset within the struct of the data pointer (or to the 00282 * first data pointer, if more than one exist). 00283 * size: 00284 * Used by CRYPT_AsnDecodeSequence, not for your use. 00285 */ 00286 struct AsnDecodeSequenceItem 00287 { 00288 BYTE tag; 00289 DWORD offset; 00290 InternalDecodeFunc decodeFunc; 00291 DWORD minSize; 00292 BOOL optional; 00293 BOOL hasPointer; 00294 DWORD pointerOffset; 00295 DWORD size; 00296 }; 00297 00298 #define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member)) 00299 #define MEMBERSIZE(s, member, nextmember) \ 00300 (offsetof(s, nextmember) - offsetof(s, member)) 00301 00302 /* Decodes the items in a sequence, where the items are described in items, 00303 * the encoded data are in pbEncoded with length cbEncoded. Decodes into 00304 * pvStructInfo. nextData is a pointer to the memory location at which the 00305 * first decoded item with a dynamic pointer should point. 00306 * Upon decoding, *cbDecoded is the total number of bytes decoded. 00307 * Each item decoder is never called with CRYPT_DECODE_ALLOC_FLAG set. 00308 */ 00309 static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], 00310 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 00311 void *pvStructInfo, BYTE *nextData, DWORD *cbDecoded) 00312 { 00313 BOOL ret; 00314 DWORD i, decoded = 0; 00315 const BYTE *ptr = pbEncoded; 00316 00317 TRACE("%p, %d, %p, %d, %08x, %p, %p, %p\n", items, cItem, pbEncoded, 00318 cbEncoded, dwFlags, pvStructInfo, nextData, cbDecoded); 00319 00320 for (i = 0, ret = TRUE; ret && i < cItem; i++) 00321 { 00322 if (cbEncoded - (ptr - pbEncoded) != 0) 00323 { 00324 DWORD itemLen; 00325 00326 if ((ret = CRYPT_GetLengthIndefinite(ptr, 00327 cbEncoded - (ptr - pbEncoded), &itemLen))) 00328 { 00329 BYTE itemLenBytes = GET_LEN_BYTES(ptr[1]); 00330 00331 if (ptr[0] == items[i].tag || !items[i].tag) 00332 { 00333 DWORD itemEncodedLen; 00334 00335 if (itemLen == CMSG_INDEFINITE_LENGTH) 00336 itemEncodedLen = cbEncoded - (ptr - pbEncoded); 00337 else 00338 itemEncodedLen = 1 + itemLenBytes + itemLen; 00339 if (nextData && pvStructInfo && items[i].hasPointer) 00340 { 00341 TRACE("Setting next pointer to %p\n", 00342 nextData); 00343 *(BYTE **)((BYTE *)pvStructInfo + 00344 items[i].pointerOffset) = nextData; 00345 } 00346 if (items[i].decodeFunc) 00347 { 00348 DWORD itemDecoded; 00349 00350 if (pvStructInfo) 00351 TRACE("decoding item %d\n", i); 00352 else 00353 TRACE("sizing item %d\n", i); 00354 ret = items[i].decodeFunc(ptr, itemEncodedLen, 00355 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, 00356 pvStructInfo ? (BYTE *)pvStructInfo + items[i].offset 00357 : NULL, &items[i].size, &itemDecoded); 00358 if (ret) 00359 { 00360 if (items[i].size < items[i].minSize) 00361 items[i].size = items[i].minSize; 00362 else if (items[i].size > items[i].minSize) 00363 { 00364 /* Account for alignment padding */ 00365 items[i].size = ALIGN_DWORD_PTR(items[i].size); 00366 } 00367 TRACE("item %d size: %d\n", i, items[i].size); 00368 if (nextData && items[i].hasPointer && 00369 items[i].size > items[i].minSize) 00370 nextData += items[i].size - items[i].minSize; 00371 if (itemDecoded > itemEncodedLen) 00372 { 00373 WARN("decoded length %d exceeds encoded %d\n", 00374 itemDecoded, itemEncodedLen); 00375 SetLastError(CRYPT_E_ASN1_CORRUPT); 00376 ret = FALSE; 00377 } 00378 else 00379 { 00380 ptr += itemDecoded; 00381 decoded += itemDecoded; 00382 TRACE("item %d: decoded %d bytes\n", i, 00383 itemDecoded); 00384 } 00385 } 00386 else if (items[i].optional && 00387 GetLastError() == CRYPT_E_ASN1_BADTAG) 00388 { 00389 TRACE("skipping optional item %d\n", i); 00390 items[i].size = items[i].minSize; 00391 SetLastError(NOERROR); 00392 ret = TRUE; 00393 } 00394 else 00395 TRACE("item %d failed: %08x\n", i, 00396 GetLastError()); 00397 } 00398 else if (itemLen == CMSG_INDEFINITE_LENGTH) 00399 { 00400 ERR("can't use indefinite length encoding without a decoder\n"); 00401 SetLastError(CRYPT_E_ASN1_CORRUPT); 00402 ret = FALSE; 00403 } 00404 else 00405 { 00406 TRACE("item %d: decoded %d bytes\n", i, itemEncodedLen); 00407 ptr += itemEncodedLen; 00408 decoded += itemEncodedLen; 00409 items[i].size = items[i].minSize; 00410 } 00411 } 00412 else if (items[i].optional) 00413 { 00414 TRACE("skipping optional item %d\n", i); 00415 items[i].size = items[i].minSize; 00416 } 00417 else 00418 { 00419 TRACE("item %d: tag %02x doesn't match expected %02x\n", 00420 i, ptr[0], items[i].tag); 00421 SetLastError(CRYPT_E_ASN1_BADTAG); 00422 ret = FALSE; 00423 } 00424 } 00425 } 00426 else if (items[i].optional) 00427 { 00428 TRACE("missing optional item %d, skipping\n", i); 00429 items[i].size = items[i].minSize; 00430 } 00431 else 00432 { 00433 TRACE("not enough bytes for item %d, failing\n", i); 00434 SetLastError(CRYPT_E_ASN1_CORRUPT); 00435 ret = FALSE; 00436 } 00437 } 00438 if (cbDecoded) 00439 *cbDecoded = decoded; 00440 TRACE("returning %d\n", ret); 00441 return ret; 00442 } 00443 00444 /* This decodes an arbitrary sequence into a contiguous block of memory 00445 * (basically, a struct.) Each element being decoded is described by a struct 00446 * AsnDecodeSequenceItem, see above. 00447 * startingPointer is an optional pointer to the first place where dynamic 00448 * data will be stored. If you know the starting offset, you may pass it 00449 * here. Otherwise, pass NULL, and one will be inferred from the items. 00450 */ 00451 static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], 00452 DWORD cItem, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 00453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, 00454 DWORD *pcbDecoded, void *startingPointer) 00455 { 00456 BOOL ret; 00457 00458 TRACE("%p, %d, %p, %d, %08x, %p, %p, %d, %p\n", items, cItem, pbEncoded, 00459 cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, 00460 startingPointer); 00461 00462 if (!cbEncoded) 00463 { 00464 SetLastError(CRYPT_E_ASN1_EOD); 00465 return FALSE; 00466 } 00467 if (pbEncoded[0] == ASN_SEQUENCE) 00468 { 00469 DWORD dataLen; 00470 00471 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) 00472 { 00473 DWORD lenBytes = GET_LEN_BYTES(pbEncoded[1]), cbDecoded; 00474 const BYTE *ptr = pbEncoded + 1 + lenBytes; 00475 BOOL indefinite = FALSE; 00476 00477 cbEncoded -= 1 + lenBytes; 00478 if (dataLen == CMSG_INDEFINITE_LENGTH) 00479 { 00480 dataLen = cbEncoded; 00481 indefinite = TRUE; 00482 } 00483 else if (cbEncoded < dataLen) 00484 { 00485 TRACE("dataLen %d exceeds cbEncoded %d, failing\n", dataLen, 00486 cbEncoded); 00487 SetLastError(CRYPT_E_ASN1_CORRUPT); 00488 ret = FALSE; 00489 } 00490 if (ret) 00491 { 00492 ret = CRYPT_AsnDecodeSequenceItems(items, cItem, 00493 ptr, dataLen, dwFlags, NULL, NULL, &cbDecoded); 00494 if (ret && dataLen == CMSG_INDEFINITE_LENGTH) 00495 { 00496 if (cbDecoded > cbEncoded - 2) 00497 { 00498 /* Not enough space for 0 TLV */ 00499 SetLastError(CRYPT_E_ASN1_CORRUPT); 00500 ret = FALSE; 00501 } 00502 else if (*(ptr + cbDecoded) != 0 || 00503 *(ptr + cbDecoded + 1) != 0) 00504 { 00505 TRACE("expected 0 TLV\n"); 00506 SetLastError(CRYPT_E_ASN1_CORRUPT); 00507 ret = FALSE; 00508 } 00509 else 00510 cbDecoded += 2; 00511 } 00512 } 00513 if (ret && !indefinite && cbDecoded != dataLen) 00514 { 00515 TRACE("expected %d decoded, got %d, failing\n", dataLen, 00516 cbDecoded); 00517 SetLastError(CRYPT_E_ASN1_CORRUPT); 00518 ret = FALSE; 00519 } 00520 if (ret) 00521 { 00522 DWORD i, bytesNeeded = 0, structSize = 0; 00523 00524 for (i = 0; i < cItem; i++) 00525 { 00526 if (items[i].size > items[i].minSize) 00527 bytesNeeded += items[i].size - items[i].minSize; 00528 structSize = max( structSize, items[i].offset + items[i].minSize ); 00529 } 00530 bytesNeeded += structSize; 00531 if (pcbDecoded) 00532 *pcbDecoded = 1 + lenBytes + cbDecoded; 00533 if (!pvStructInfo) 00534 *pcbStructInfo = bytesNeeded; 00535 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, 00536 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) 00537 { 00538 BYTE *nextData; 00539 00540 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 00541 pvStructInfo = *(BYTE **)pvStructInfo; 00542 if (startingPointer) 00543 nextData = startingPointer; 00544 else 00545 nextData = (BYTE *)pvStructInfo + structSize; 00546 memset(pvStructInfo, 0, structSize); 00547 ret = CRYPT_AsnDecodeSequenceItems(items, cItem, 00548 ptr, dataLen, dwFlags, pvStructInfo, nextData, 00549 &cbDecoded); 00550 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 00551 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 00552 } 00553 } 00554 } 00555 } 00556 else 00557 { 00558 SetLastError(CRYPT_E_ASN1_BADTAG); 00559 ret = FALSE; 00560 } 00561 TRACE("returning %d (%08x)\n", ret, GetLastError()); 00562 return ret; 00563 } 00564 00565 /* tag: 00566 * The expected tag of the entire encoded array (usually a variant 00567 * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called 00568 * regardless of the tag seen. 00569 * countOffset: 00570 * The offset within the outer structure at which the count exists. 00571 * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0, 00572 * while CRYPT_ATTRIBUTE has countOffset == 00573 * offsetof(CRYPT_ATTRIBUTE, cValue). 00574 * arrayOffset: 00575 * The offset within the outer structure at which the array pointer exists. 00576 * For example, CRYPT_ATTRIBUTES has arrayOffset == 00577 * offsetof(CRYPT_ATTRIBUTES, rgAttr). 00578 * minArraySize: 00579 * The minimum size of the decoded array. On WIN32, this is always 8: 00580 * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to 00581 * alignment. 00582 * decodeFunc: 00583 * used to decode each item in the array 00584 * itemSize: 00585 * is the minimum size of each decoded item 00586 * hasPointer: 00587 * indicates whether each item has a dynamic pointer 00588 * pointerOffset: 00589 * indicates the offset within itemSize at which the pointer exists 00590 */ 00591 struct AsnArrayDescriptor 00592 { 00593 BYTE tag; 00594 DWORD countOffset; 00595 DWORD arrayOffset; 00596 DWORD minArraySize; 00597 InternalDecodeFunc decodeFunc; 00598 DWORD itemSize; 00599 BOOL hasPointer; 00600 DWORD pointerOffset; 00601 }; 00602 00603 struct AsnArrayItemSize 00604 { 00605 DWORD encodedLen; 00606 DWORD size; 00607 }; 00608 00609 /* Decodes an array of like types into a structure described by a struct 00610 * AsnArrayDescriptor. 00611 */ 00612 static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, 00613 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 00614 const CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, 00615 DWORD *pcbDecoded) 00616 { 00617 BOOL ret = TRUE; 00618 00619 TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded, 00620 cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 00621 00622 if (!cbEncoded) 00623 { 00624 SetLastError(CRYPT_E_ASN1_EOD); 00625 ret = FALSE; 00626 } 00627 else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag) 00628 { 00629 DWORD dataLen; 00630 00631 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) 00632 { 00633 DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded; 00634 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 00635 /* There can be arbitrarily many items, but there is often only one. 00636 */ 00637 struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize; 00638 00639 decoded = 1 + lenBytes; 00640 if (dataLen) 00641 { 00642 const BYTE *ptr; 00643 BOOL doneDecoding = FALSE; 00644 00645 for (ptr = pbEncoded + 1 + lenBytes; ret && !doneDecoding; ) 00646 { 00647 if (dataLen == CMSG_INDEFINITE_LENGTH) 00648 { 00649 if (ptr[0] == 0) 00650 { 00651 doneDecoding = TRUE; 00652 if (ptr[1] != 0) 00653 { 00654 SetLastError(CRYPT_E_ASN1_CORRUPT); 00655 ret = FALSE; 00656 } 00657 else 00658 decoded += 2; 00659 } 00660 } 00661 else if (ptr - pbEncoded - 1 - lenBytes >= dataLen) 00662 doneDecoding = TRUE; 00663 if (!doneDecoding) 00664 { 00665 DWORD itemEncoded, itemDataLen, itemDecoded, size = 0; 00666 00667 /* Each item decoded may not tolerate extraneous bytes, 00668 * so get the length of the next element if known. 00669 */ 00670 if ((ret = CRYPT_GetLengthIndefinite(ptr, 00671 cbEncoded - (ptr - pbEncoded), &itemDataLen))) 00672 { 00673 if (itemDataLen == CMSG_INDEFINITE_LENGTH) 00674 itemEncoded = cbEncoded - (ptr - pbEncoded); 00675 else 00676 itemEncoded = 1 + GET_LEN_BYTES(ptr[1]) + 00677 itemDataLen; 00678 } 00679 if (ret) 00680 ret = arrayDesc->decodeFunc(ptr, itemEncoded, 00681 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &size, 00682 &itemDecoded); 00683 if (ret) 00684 { 00685 cItems++; 00686 if (itemSizes != &itemSize) 00687 itemSizes = CryptMemRealloc(itemSizes, 00688 cItems * sizeof(struct AsnArrayItemSize)); 00689 else if (cItems > 1) 00690 { 00691 itemSizes = 00692 CryptMemAlloc( 00693 cItems * sizeof(struct AsnArrayItemSize)); 00694 if (itemSizes) 00695 memcpy(itemSizes, &itemSize, 00696 sizeof(itemSize)); 00697 } 00698 if (itemSizes) 00699 { 00700 decoded += itemDecoded; 00701 itemSizes[cItems - 1].encodedLen = itemEncoded; 00702 itemSizes[cItems - 1].size = size; 00703 bytesNeeded += size; 00704 ptr += itemEncoded; 00705 } 00706 else 00707 ret = FALSE; 00708 } 00709 } 00710 } 00711 } 00712 if (ret) 00713 { 00714 if (pcbDecoded) 00715 *pcbDecoded = decoded; 00716 if (!pvStructInfo) 00717 *pcbStructInfo = bytesNeeded; 00718 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 00719 pvStructInfo, pcbStructInfo, bytesNeeded))) 00720 { 00721 DWORD i, *pcItems; 00722 BYTE *nextData; 00723 const BYTE *ptr; 00724 void *rgItems; 00725 00726 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 00727 pvStructInfo = *(void **)pvStructInfo; 00728 pcItems = pvStructInfo; 00729 *pcItems = cItems; 00730 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 00731 { 00732 rgItems = (BYTE *)pvStructInfo + 00733 arrayDesc->minArraySize; 00734 *(void **)((BYTE *)pcItems - 00735 arrayDesc->countOffset + arrayDesc->arrayOffset) = 00736 rgItems; 00737 } 00738 else 00739 rgItems = *(void **)((BYTE *)pcItems - 00740 arrayDesc->countOffset + arrayDesc->arrayOffset); 00741 nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize; 00742 for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret && 00743 i < cItems && ptr - pbEncoded - 1 - lenBytes < 00744 dataLen; i++) 00745 { 00746 DWORD itemDecoded; 00747 00748 if (arrayDesc->hasPointer) 00749 *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize 00750 + arrayDesc->pointerOffset) = nextData; 00751 ret = arrayDesc->decodeFunc(ptr, 00752 itemSizes[i].encodedLen, 00753 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, 00754 (BYTE *)rgItems + i * arrayDesc->itemSize, 00755 &itemSizes[i].size, &itemDecoded); 00756 if (ret) 00757 { 00758 nextData += itemSizes[i].size - arrayDesc->itemSize; 00759 ptr += itemDecoded; 00760 } 00761 } 00762 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 00763 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 00764 } 00765 } 00766 if (itemSizes != &itemSize) 00767 CryptMemFree(itemSizes); 00768 } 00769 } 00770 else 00771 { 00772 SetLastError(CRYPT_E_ASN1_BADTAG); 00773 ret = FALSE; 00774 } 00775 return ret; 00776 } 00777 00778 /* Decodes a DER-encoded BLOB into a CRYPT_DER_BLOB struct pointed to by 00779 * pvStructInfo. The BLOB must be non-empty, otherwise the last error is set 00780 * to CRYPT_E_ASN1_CORRUPT. 00781 * Warning: assumes the CRYPT_DER_BLOB pointed to by pvStructInfo has pbData 00782 * set! 00783 */ 00784 static BOOL CRYPT_AsnDecodeDerBlob(const BYTE *pbEncoded, DWORD cbEncoded, 00785 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 00786 { 00787 BOOL ret; 00788 DWORD dataLen; 00789 00790 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 00791 { 00792 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 00793 DWORD bytesNeeded = sizeof(CRYPT_DER_BLOB); 00794 00795 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 00796 bytesNeeded += 1 + lenBytes + dataLen; 00797 00798 if (pcbDecoded) 00799 *pcbDecoded = 1 + lenBytes + dataLen; 00800 if (!pvStructInfo) 00801 *pcbStructInfo = bytesNeeded; 00802 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, bytesNeeded))) 00803 { 00804 CRYPT_DER_BLOB *blob; 00805 00806 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 00807 pvStructInfo = *(BYTE **)pvStructInfo; 00808 blob = pvStructInfo; 00809 blob->cbData = 1 + lenBytes + dataLen; 00810 if (blob->cbData) 00811 { 00812 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 00813 blob->pbData = (BYTE *)pbEncoded; 00814 else 00815 { 00816 assert(blob->pbData); 00817 memcpy(blob->pbData, pbEncoded, blob->cbData); 00818 } 00819 } 00820 else 00821 { 00822 SetLastError(CRYPT_E_ASN1_CORRUPT); 00823 ret = FALSE; 00824 } 00825 } 00826 } 00827 return ret; 00828 } 00829 00830 /* Like CRYPT_AsnDecodeBitsInternal, but swaps the bytes */ 00831 static BOOL CRYPT_AsnDecodeBitsSwapBytes(const BYTE *pbEncoded, 00832 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00833 DWORD *pcbDecoded) 00834 { 00835 BOOL ret; 00836 00837 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags, 00838 pvStructInfo, *pcbStructInfo, pcbDecoded); 00839 00840 /* Can't use the CRYPT_DECODE_NOCOPY_FLAG, because we modify the bytes in- 00841 * place. 00842 */ 00843 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded, 00844 dwFlags & ~CRYPT_DECODE_NOCOPY_FLAG, pvStructInfo, pcbStructInfo, 00845 pcbDecoded); 00846 if (ret && pvStructInfo) 00847 { 00848 CRYPT_BIT_BLOB *blob = pvStructInfo; 00849 00850 if (blob->cbData) 00851 { 00852 DWORD i; 00853 BYTE temp; 00854 00855 for (i = 0; i < blob->cbData / 2; i++) 00856 { 00857 temp = blob->pbData[i]; 00858 blob->pbData[i] = blob->pbData[blob->cbData - i - 1]; 00859 blob->pbData[blob->cbData - i - 1] = temp; 00860 } 00861 } 00862 } 00863 TRACE("returning %d (%08x)\n", ret, GetLastError()); 00864 return ret; 00865 } 00866 00867 static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType, 00868 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 00869 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 00870 { 00871 BOOL ret = TRUE; 00872 00873 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 00874 pDecodePara, pvStructInfo, *pcbStructInfo); 00875 00876 __TRY 00877 { 00878 struct AsnDecodeSequenceItem items[] = { 00879 { 0, offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned), 00880 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_DER_BLOB), FALSE, TRUE, 00881 offsetof(CERT_SIGNED_CONTENT_INFO, ToBeSigned.pbData), 0 }, 00882 { ASN_SEQUENCEOF, offsetof(CERT_SIGNED_CONTENT_INFO, 00883 SignatureAlgorithm), CRYPT_AsnDecodeAlgorithmId, 00884 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, 00885 offsetof(CERT_SIGNED_CONTENT_INFO, SignatureAlgorithm.pszObjId), 0 }, 00886 { ASN_BITSTRING, offsetof(CERT_SIGNED_CONTENT_INFO, Signature), 00887 CRYPT_AsnDecodeBitsSwapBytes, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 00888 offsetof(CERT_SIGNED_CONTENT_INFO, Signature.pbData), 0 }, 00889 }; 00890 00891 if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG) 00892 items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal; 00893 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 00894 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 00895 pcbStructInfo, NULL, NULL); 00896 } 00897 __EXCEPT_PAGE_FAULT 00898 { 00899 SetLastError(STATUS_ACCESS_VIOLATION); 00900 ret = FALSE; 00901 } 00902 __ENDTRY 00903 00904 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 00905 return ret; 00906 } 00907 00908 static BOOL CRYPT_AsnDecodeCertVersion(const BYTE *pbEncoded, DWORD cbEncoded, 00909 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 00910 { 00911 BOOL ret; 00912 DWORD dataLen; 00913 00914 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 00915 { 00916 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 00917 00918 ret = CRYPT_AsnDecodeIntInternal(pbEncoded + 1 + lenBytes, dataLen, 00919 dwFlags, pvStructInfo, pcbStructInfo, NULL); 00920 if (pcbDecoded) 00921 *pcbDecoded = 1 + lenBytes + dataLen; 00922 } 00923 return ret; 00924 } 00925 00926 static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded, 00927 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 00928 { 00929 BOOL ret; 00930 00931 struct AsnDecodeSequenceItem items[] = { 00932 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotBefore), 00933 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, 00934 { 0, offsetof(CERT_PRIVATE_KEY_VALIDITY, NotAfter), 00935 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, 00936 }; 00937 00938 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 00939 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 00940 pcbDecoded, NULL); 00941 return ret; 00942 } 00943 00944 static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded, 00945 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00946 DWORD *pcbDecoded) 00947 { 00948 BOOL ret = TRUE; 00949 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 00950 offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension), 00951 FINALMEMBERSIZE(CERT_INFO, cExtension), 00952 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 00953 offsetof(CERT_EXTENSION, pszObjId) }; 00954 00955 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 00956 pvStructInfo, *pcbStructInfo, pcbDecoded); 00957 00958 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 00959 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 00960 return ret; 00961 } 00962 00963 static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded, 00964 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 00965 DWORD *pcbDecoded) 00966 { 00967 BOOL ret; 00968 DWORD dataLen; 00969 00970 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 00971 { 00972 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 00973 00974 ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes, 00975 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); 00976 if (ret && pcbDecoded) 00977 *pcbDecoded = 1 + lenBytes + dataLen; 00978 } 00979 return ret; 00980 } 00981 00982 static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, 00983 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 00984 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 00985 { 00986 BOOL ret = TRUE; 00987 struct AsnDecodeSequenceItem items[] = { 00988 { ASN_CONTEXT | ASN_CONSTRUCTOR, offsetof(CERT_INFO, dwVersion), 00989 CRYPT_AsnDecodeCertVersion, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 00990 { ASN_INTEGER, offsetof(CERT_INFO, SerialNumber), 00991 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, 00992 TRUE, offsetof(CERT_INFO, SerialNumber.pbData), 0 }, 00993 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SignatureAlgorithm), 00994 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 00995 FALSE, TRUE, offsetof(CERT_INFO, SignatureAlgorithm.pszObjId), 0 }, 00996 { 0, offsetof(CERT_INFO, Issuer), CRYPT_AsnDecodeDerBlob, 00997 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO, 00998 Issuer.pbData) }, 00999 { ASN_SEQUENCEOF, offsetof(CERT_INFO, NotBefore), 01000 CRYPT_AsnDecodeValidity, sizeof(CERT_PRIVATE_KEY_VALIDITY), FALSE, 01001 FALSE, 0 }, 01002 { 0, offsetof(CERT_INFO, Subject), CRYPT_AsnDecodeDerBlob, 01003 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_INFO, 01004 Subject.pbData) }, 01005 { ASN_SEQUENCEOF, offsetof(CERT_INFO, SubjectPublicKeyInfo), 01006 CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO), 01007 FALSE, TRUE, offsetof(CERT_INFO, 01008 SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 }, 01009 { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId), 01010 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, 01011 offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 }, 01012 { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId), 01013 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, 01014 offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 }, 01015 { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension), 01016 CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension), 01017 TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 }, 01018 }; 01019 01020 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01021 pDecodePara, pvStructInfo, *pcbStructInfo); 01022 01023 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 01024 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, 01025 NULL, NULL); 01026 if (ret && pvStructInfo) 01027 { 01028 CERT_INFO *info; 01029 01030 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 01031 info = *(CERT_INFO **)pvStructInfo; 01032 else 01033 info = pvStructInfo; 01034 if (!info->SerialNumber.cbData || !info->Issuer.cbData || 01035 !info->Subject.cbData) 01036 { 01037 SetLastError(CRYPT_E_ASN1_CORRUPT); 01038 /* Don't need to deallocate, because it should have failed on the 01039 * first pass (and no memory was allocated.) 01040 */ 01041 ret = FALSE; 01042 } 01043 } 01044 01045 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 01046 return ret; 01047 } 01048 01049 static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, 01050 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01051 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01052 { 01053 BOOL ret = FALSE; 01054 01055 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01056 pDecodePara, pvStructInfo, *pcbStructInfo); 01057 01058 __TRY 01059 { 01060 DWORD size = 0; 01061 01062 /* Unless told not to, first try to decode it as a signed cert. */ 01063 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG)) 01064 { 01065 PCERT_SIGNED_CONTENT_INFO signedCert = NULL; 01066 01067 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType, 01068 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, 01069 &signedCert, &size); 01070 if (ret) 01071 { 01072 size = 0; 01073 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType, 01074 X509_CERT_TO_BE_SIGNED, signedCert->ToBeSigned.pbData, 01075 signedCert->ToBeSigned.cbData, dwFlags, pDecodePara, 01076 pvStructInfo, pcbStructInfo); 01077 LocalFree(signedCert); 01078 } 01079 } 01080 /* Failing that, try it as an unsigned cert */ 01081 if (!ret) 01082 { 01083 size = 0; 01084 ret = CRYPT_AsnDecodeCertInfo(dwCertEncodingType, 01085 X509_CERT_TO_BE_SIGNED, pbEncoded, cbEncoded, dwFlags, 01086 pDecodePara, pvStructInfo, pcbStructInfo); 01087 } 01088 } 01089 __EXCEPT_PAGE_FAULT 01090 { 01091 SetLastError(STATUS_ACCESS_VIOLATION); 01092 } 01093 __ENDTRY 01094 01095 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 01096 return ret; 01097 } 01098 01099 static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded, 01100 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 01101 DWORD *pcbDecoded) 01102 { 01103 BOOL ret = TRUE; 01104 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 01105 offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension), 01106 FINALMEMBERSIZE(CRL_ENTRY, cExtension), 01107 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 01108 offsetof(CERT_EXTENSION, pszObjId) }; 01109 01110 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 01111 pvStructInfo, *pcbStructInfo, pcbDecoded); 01112 01113 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 01114 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 01115 return ret; 01116 } 01117 01118 static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded, 01119 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01120 { 01121 BOOL ret; 01122 struct AsnDecodeSequenceItem items[] = { 01123 { ASN_INTEGER, offsetof(CRL_ENTRY, SerialNumber), 01124 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, TRUE, 01125 offsetof(CRL_ENTRY, SerialNumber.pbData), 0 }, 01126 { 0, offsetof(CRL_ENTRY, RevocationDate), 01127 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, 01128 { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension), 01129 CRYPT_AsnDecodeCRLEntryExtensions, 01130 FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE, 01131 offsetof(CRL_ENTRY, rgExtension), 0 }, 01132 }; 01133 PCRL_ENTRY entry = pvStructInfo; 01134 01135 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, 01136 *pcbStructInfo); 01137 01138 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 01139 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded, 01140 entry ? entry->SerialNumber.pbData : NULL); 01141 if (ret && entry && !entry->SerialNumber.cbData) 01142 { 01143 WARN("empty CRL entry serial number\n"); 01144 SetLastError(CRYPT_E_ASN1_CORRUPT); 01145 ret = FALSE; 01146 } 01147 return ret; 01148 } 01149 01150 /* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO 01151 * whose rgCRLEntry member has been set prior to calling. 01152 */ 01153 static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded, 01154 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01155 { 01156 BOOL ret; 01157 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 01158 offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry), 01159 MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension), 01160 CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE, 01161 offsetof(CRL_ENTRY, SerialNumber.pbData) }; 01162 01163 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 01164 pvStructInfo, *pcbStructInfo, pcbDecoded); 01165 01166 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 01167 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 01168 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 01169 return ret; 01170 } 01171 01172 static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded, 01173 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 01174 DWORD *pcbDecoded) 01175 { 01176 BOOL ret = TRUE; 01177 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 01178 offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension), 01179 FINALMEMBERSIZE(CRL_INFO, cExtension), 01180 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 01181 offsetof(CERT_EXTENSION, pszObjId) }; 01182 01183 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 01184 pvStructInfo, *pcbStructInfo, pcbDecoded); 01185 01186 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 01187 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 01188 return ret; 01189 } 01190 01191 static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded, 01192 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 01193 DWORD *pcbDecoded) 01194 { 01195 BOOL ret; 01196 DWORD dataLen; 01197 01198 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 01199 { 01200 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 01201 01202 ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes, 01203 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); 01204 if (ret && pcbDecoded) 01205 *pcbDecoded = 1 + lenBytes + dataLen; 01206 } 01207 return ret; 01208 } 01209 01210 static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType, 01211 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01212 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01213 { 01214 struct AsnDecodeSequenceItem items[] = { 01215 { ASN_INTEGER, offsetof(CRL_INFO, dwVersion), 01216 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 01217 { ASN_SEQUENCEOF, offsetof(CRL_INFO, SignatureAlgorithm), 01218 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 01219 FALSE, TRUE, offsetof(CRL_INFO, SignatureAlgorithm.pszObjId), 0 }, 01220 { 0, offsetof(CRL_INFO, Issuer), CRYPT_AsnDecodeDerBlob, 01221 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CRL_INFO, 01222 Issuer.pbData) }, 01223 { 0, offsetof(CRL_INFO, ThisUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal, 01224 sizeof(FILETIME), FALSE, FALSE, 0 }, 01225 { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal, 01226 sizeof(FILETIME), TRUE, FALSE, 0 }, 01227 { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry), 01228 CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension), 01229 TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 }, 01230 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension), 01231 CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension), 01232 TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 }, 01233 }; 01234 BOOL ret = TRUE; 01235 01236 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01237 pDecodePara, pvStructInfo, *pcbStructInfo); 01238 01239 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 01240 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, 01241 NULL, NULL); 01242 01243 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 01244 return ret; 01245 } 01246 01247 static BOOL WINAPI CRYPT_AsnDecodeCRL(DWORD dwCertEncodingType, 01248 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01249 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01250 { 01251 BOOL ret = FALSE; 01252 01253 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01254 pDecodePara, pvStructInfo, *pcbStructInfo); 01255 01256 __TRY 01257 { 01258 DWORD size = 0; 01259 01260 /* Unless told not to, first try to decode it as a signed crl. */ 01261 if (!(dwFlags & CRYPT_DECODE_TO_BE_SIGNED_FLAG)) 01262 { 01263 PCERT_SIGNED_CONTENT_INFO signedCrl = NULL; 01264 01265 ret = CRYPT_AsnDecodeCertSignedContent(dwCertEncodingType, 01266 X509_CERT, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, 01267 &signedCrl, &size); 01268 if (ret) 01269 { 01270 size = 0; 01271 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType, 01272 X509_CERT_CRL_TO_BE_SIGNED, signedCrl->ToBeSigned.pbData, 01273 signedCrl->ToBeSigned.cbData, dwFlags, pDecodePara, 01274 pvStructInfo, pcbStructInfo); 01275 LocalFree(signedCrl); 01276 } 01277 } 01278 /* Failing that, try it as an unsigned crl */ 01279 if (!ret) 01280 { 01281 size = 0; 01282 ret = CRYPT_AsnDecodeCRLInfo(dwCertEncodingType, 01283 X509_CERT_CRL_TO_BE_SIGNED, pbEncoded, cbEncoded, 01284 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); 01285 } 01286 } 01287 __EXCEPT_PAGE_FAULT 01288 { 01289 SetLastError(STATUS_ACCESS_VIOLATION); 01290 } 01291 __ENDTRY 01292 01293 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 01294 return ret; 01295 } 01296 01297 static BOOL CRYPT_AsnDecodeOidIgnoreTag(const BYTE *pbEncoded, DWORD cbEncoded, 01298 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01299 { 01300 BOOL ret = TRUE; 01301 DWORD dataLen; 01302 01303 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01304 pvStructInfo, *pcbStructInfo); 01305 01306 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 01307 { 01308 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 01309 DWORD bytesNeeded = sizeof(LPSTR); 01310 01311 if (dataLen) 01312 { 01313 /* The largest possible string for the first two components 01314 * is 2.175 (= 2 * 40 + 175 = 255), so this is big enough. 01315 */ 01316 char firstTwo[6]; 01317 const BYTE *ptr; 01318 01319 snprintf(firstTwo, sizeof(firstTwo), "%d.%d", 01320 pbEncoded[1 + lenBytes] / 40, 01321 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 40) 01322 * 40); 01323 bytesNeeded += strlen(firstTwo) + 1; 01324 for (ptr = pbEncoded + 2 + lenBytes; ret && 01325 ptr - pbEncoded - 1 - lenBytes < dataLen; ) 01326 { 01327 /* large enough for ".4000000" */ 01328 char str[9]; 01329 int val = 0; 01330 01331 while (ptr - pbEncoded - 1 - lenBytes < dataLen && 01332 (*ptr & 0x80)) 01333 { 01334 val <<= 7; 01335 val |= *ptr & 0x7f; 01336 ptr++; 01337 } 01338 if (ptr - pbEncoded - 1 - lenBytes >= dataLen || 01339 (*ptr & 0x80)) 01340 { 01341 SetLastError(CRYPT_E_ASN1_CORRUPT); 01342 ret = FALSE; 01343 } 01344 else 01345 { 01346 val <<= 7; 01347 val |= *ptr++; 01348 snprintf(str, sizeof(str), ".%d", val); 01349 bytesNeeded += strlen(str); 01350 } 01351 } 01352 } 01353 if (pcbDecoded) 01354 *pcbDecoded = 1 + lenBytes + dataLen; 01355 if (!pvStructInfo) 01356 *pcbStructInfo = bytesNeeded; 01357 else if (*pcbStructInfo < bytesNeeded) 01358 { 01359 *pcbStructInfo = bytesNeeded; 01360 SetLastError(ERROR_MORE_DATA); 01361 ret = FALSE; 01362 } 01363 else 01364 { 01365 if (dataLen) 01366 { 01367 const BYTE *ptr; 01368 LPSTR pszObjId = *(LPSTR *)pvStructInfo; 01369 01370 *pszObjId = 0; 01371 sprintf(pszObjId, "%d.%d", pbEncoded[1 + lenBytes] / 40, 01372 pbEncoded[1 + lenBytes] - (pbEncoded[1 + lenBytes] / 01373 40) * 40); 01374 pszObjId += strlen(pszObjId); 01375 for (ptr = pbEncoded + 2 + lenBytes; ret && 01376 ptr - pbEncoded - 1 - lenBytes < dataLen; ) 01377 { 01378 int val = 0; 01379 01380 while (ptr - pbEncoded - 1 - lenBytes < dataLen && 01381 (*ptr & 0x80)) 01382 { 01383 val <<= 7; 01384 val |= *ptr & 0x7f; 01385 ptr++; 01386 } 01387 val <<= 7; 01388 val |= *ptr++; 01389 sprintf(pszObjId, ".%d", val); 01390 pszObjId += strlen(pszObjId); 01391 } 01392 } 01393 else 01394 *(LPSTR *)pvStructInfo = NULL; 01395 *pcbStructInfo = bytesNeeded; 01396 } 01397 } 01398 return ret; 01399 } 01400 01401 static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded, 01402 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01403 { 01404 BOOL ret; 01405 01406 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01407 pvStructInfo, *pcbStructInfo); 01408 01409 if (pbEncoded[0] == ASN_OBJECTIDENTIFIER) 01410 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, dwFlags, 01411 pvStructInfo, pcbStructInfo, pcbDecoded); 01412 else 01413 { 01414 SetLastError(CRYPT_E_ASN1_BADTAG); 01415 ret = FALSE; 01416 } 01417 return ret; 01418 } 01419 01420 static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, 01421 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01422 { 01423 struct AsnDecodeSequenceItem items[] = { 01424 { ASN_OBJECTIDENTIFIER, offsetof(CERT_EXTENSION, pszObjId), 01425 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 01426 offsetof(CERT_EXTENSION, pszObjId), 0 }, 01427 { ASN_BOOL, offsetof(CERT_EXTENSION, fCritical), CRYPT_AsnDecodeBool, 01428 sizeof(BOOL), TRUE, FALSE, 0, 0 }, 01429 { ASN_OCTETSTRING, offsetof(CERT_EXTENSION, Value), 01430 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_OBJID_BLOB), FALSE, TRUE, 01431 offsetof(CERT_EXTENSION, Value.pbData) }, 01432 }; 01433 BOOL ret = TRUE; 01434 PCERT_EXTENSION ext = pvStructInfo; 01435 01436 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, ext, 01437 *pcbStructInfo); 01438 01439 if (ext) 01440 TRACE("ext->pszObjId is %p\n", ext->pszObjId); 01441 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 01442 pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo, 01443 pcbDecoded, ext ? ext->pszObjId : NULL); 01444 if (ext) 01445 TRACE("ext->pszObjId is %p (%s)\n", ext->pszObjId, 01446 debugstr_a(ext->pszObjId)); 01447 TRACE("returning %d (%08x)\n", ret, GetLastError()); 01448 return ret; 01449 } 01450 01451 static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType, 01452 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01453 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01454 { 01455 BOOL ret = TRUE; 01456 01457 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01458 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 01459 01460 __TRY 01461 { 01462 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 01463 offsetof(CERT_EXTENSIONS, cExtension), 01464 offsetof(CERT_EXTENSIONS, rgExtension), 01465 sizeof(CERT_EXTENSIONS), 01466 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 01467 offsetof(CERT_EXTENSION, pszObjId) }; 01468 CERT_EXTENSIONS *exts = pvStructInfo; 01469 01470 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 01471 exts->rgExtension = (CERT_EXTENSION *)(exts + 1); 01472 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 01473 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 01474 } 01475 __EXCEPT_PAGE_FAULT 01476 { 01477 SetLastError(STATUS_ACCESS_VIOLATION); 01478 ret = FALSE; 01479 } 01480 __ENDTRY 01481 return ret; 01482 } 01483 01484 /* Warning: this assumes the address of value->Value.pbData is already set, in 01485 * order to avoid overwriting memory. (In some cases, it may change it, if it 01486 * doesn't copy anything to memory.) Be sure to set it correctly! 01487 */ 01488 static BOOL CRYPT_AsnDecodeNameValueInternal(const BYTE *pbEncoded, 01489 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 01490 DWORD *pcbDecoded) 01491 { 01492 BOOL ret = TRUE; 01493 DWORD dataLen; 01494 CERT_NAME_VALUE *value = pvStructInfo; 01495 01496 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 01497 { 01498 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 01499 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType; 01500 01501 switch (pbEncoded[0]) 01502 { 01503 case ASN_OCTETSTRING: 01504 valueType = CERT_RDN_OCTET_STRING; 01505 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01506 bytesNeeded += dataLen; 01507 break; 01508 case ASN_NUMERICSTRING: 01509 valueType = CERT_RDN_NUMERIC_STRING; 01510 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01511 bytesNeeded += dataLen; 01512 break; 01513 case ASN_PRINTABLESTRING: 01514 valueType = CERT_RDN_PRINTABLE_STRING; 01515 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01516 bytesNeeded += dataLen; 01517 break; 01518 case ASN_IA5STRING: 01519 valueType = CERT_RDN_IA5_STRING; 01520 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01521 bytesNeeded += dataLen; 01522 break; 01523 case ASN_T61STRING: 01524 valueType = CERT_RDN_T61_STRING; 01525 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01526 bytesNeeded += dataLen; 01527 break; 01528 case ASN_VIDEOTEXSTRING: 01529 valueType = CERT_RDN_VIDEOTEX_STRING; 01530 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01531 bytesNeeded += dataLen; 01532 break; 01533 case ASN_GRAPHICSTRING: 01534 valueType = CERT_RDN_GRAPHIC_STRING; 01535 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01536 bytesNeeded += dataLen; 01537 break; 01538 case ASN_VISIBLESTRING: 01539 valueType = CERT_RDN_VISIBLE_STRING; 01540 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01541 bytesNeeded += dataLen; 01542 break; 01543 case ASN_GENERALSTRING: 01544 valueType = CERT_RDN_GENERAL_STRING; 01545 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01546 bytesNeeded += dataLen; 01547 break; 01548 case ASN_UNIVERSALSTRING: 01549 FIXME("ASN_UNIVERSALSTRING: unimplemented\n"); 01550 SetLastError(CRYPT_E_ASN1_BADTAG); 01551 return FALSE; 01552 case ASN_BMPSTRING: 01553 valueType = CERT_RDN_BMP_STRING; 01554 bytesNeeded += dataLen; 01555 break; 01556 case ASN_UTF8STRING: 01557 valueType = CERT_RDN_UTF8_STRING; 01558 bytesNeeded += MultiByteToWideChar(CP_UTF8, 0, 01559 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) * 2; 01560 break; 01561 default: 01562 SetLastError(CRYPT_E_ASN1_BADTAG); 01563 return FALSE; 01564 } 01565 01566 if (pcbDecoded) 01567 *pcbDecoded = 1 + lenBytes + dataLen; 01568 if (!value) 01569 *pcbStructInfo = bytesNeeded; 01570 else if (*pcbStructInfo < bytesNeeded) 01571 { 01572 *pcbStructInfo = bytesNeeded; 01573 SetLastError(ERROR_MORE_DATA); 01574 ret = FALSE; 01575 } 01576 else 01577 { 01578 *pcbStructInfo = bytesNeeded; 01579 value->dwValueType = valueType; 01580 if (dataLen) 01581 { 01582 DWORD i; 01583 01584 assert(value->Value.pbData); 01585 switch (pbEncoded[0]) 01586 { 01587 case ASN_OCTETSTRING: 01588 case ASN_NUMERICSTRING: 01589 case ASN_PRINTABLESTRING: 01590 case ASN_IA5STRING: 01591 case ASN_T61STRING: 01592 case ASN_VIDEOTEXSTRING: 01593 case ASN_GRAPHICSTRING: 01594 case ASN_VISIBLESTRING: 01595 case ASN_GENERALSTRING: 01596 value->Value.cbData = dataLen; 01597 if (dataLen) 01598 { 01599 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 01600 memcpy(value->Value.pbData, 01601 pbEncoded + 1 + lenBytes, dataLen); 01602 else 01603 value->Value.pbData = (LPBYTE)pbEncoded + 1 + 01604 lenBytes; 01605 } 01606 break; 01607 case ASN_BMPSTRING: 01608 { 01609 LPWSTR str = (LPWSTR)value->Value.pbData; 01610 01611 value->Value.cbData = dataLen; 01612 for (i = 0; i < dataLen / 2; i++) 01613 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | 01614 pbEncoded[1 + lenBytes + 2 * i + 1]; 01615 break; 01616 } 01617 case ASN_UTF8STRING: 01618 { 01619 LPWSTR str = (LPWSTR)value->Value.pbData; 01620 01621 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, 01622 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 01623 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; 01624 break; 01625 } 01626 } 01627 } 01628 else 01629 { 01630 value->Value.cbData = 0; 01631 value->Value.pbData = NULL; 01632 } 01633 } 01634 } 01635 return ret; 01636 } 01637 01638 static BOOL WINAPI CRYPT_AsnDecodeNameValue(DWORD dwCertEncodingType, 01639 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01640 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01641 { 01642 BOOL ret = TRUE; 01643 01644 __TRY 01645 { 01646 ret = CRYPT_AsnDecodeNameValueInternal(pbEncoded, cbEncoded, 01647 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 01648 if (ret && pvStructInfo) 01649 { 01650 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 01651 pcbStructInfo, *pcbStructInfo); 01652 if (ret) 01653 { 01654 CERT_NAME_VALUE *value; 01655 01656 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 01657 pvStructInfo = *(BYTE **)pvStructInfo; 01658 value = pvStructInfo; 01659 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE)); 01660 ret = CRYPT_AsnDecodeNameValueInternal( pbEncoded, cbEncoded, 01661 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 01662 pcbStructInfo, NULL); 01663 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 01664 CRYPT_FreeSpace(pDecodePara, value); 01665 } 01666 } 01667 } 01668 __EXCEPT_PAGE_FAULT 01669 { 01670 SetLastError(STATUS_ACCESS_VIOLATION); 01671 ret = FALSE; 01672 } 01673 __ENDTRY 01674 return ret; 01675 } 01676 01677 static BOOL CRYPT_AsnDecodeUnicodeNameValueInternal(const BYTE *pbEncoded, 01678 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 01679 DWORD *pcbDecoded) 01680 { 01681 BOOL ret = TRUE; 01682 DWORD dataLen; 01683 CERT_NAME_VALUE *value = pvStructInfo; 01684 01685 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 01686 { 01687 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 01688 DWORD bytesNeeded = sizeof(CERT_NAME_VALUE), valueType; 01689 01690 switch (pbEncoded[0]) 01691 { 01692 case ASN_NUMERICSTRING: 01693 valueType = CERT_RDN_NUMERIC_STRING; 01694 if (dataLen) 01695 bytesNeeded += (dataLen + 1) * 2; 01696 break; 01697 case ASN_PRINTABLESTRING: 01698 valueType = CERT_RDN_PRINTABLE_STRING; 01699 if (dataLen) 01700 bytesNeeded += (dataLen + 1) * 2; 01701 break; 01702 case ASN_IA5STRING: 01703 valueType = CERT_RDN_IA5_STRING; 01704 if (dataLen) 01705 bytesNeeded += (dataLen + 1) * 2; 01706 break; 01707 case ASN_T61STRING: 01708 valueType = CERT_RDN_T61_STRING; 01709 if (dataLen) 01710 bytesNeeded += (dataLen + 1) * 2; 01711 break; 01712 case ASN_VIDEOTEXSTRING: 01713 valueType = CERT_RDN_VIDEOTEX_STRING; 01714 if (dataLen) 01715 bytesNeeded += (dataLen + 1) * 2; 01716 break; 01717 case ASN_GRAPHICSTRING: 01718 valueType = CERT_RDN_GRAPHIC_STRING; 01719 if (dataLen) 01720 bytesNeeded += (dataLen + 1) * 2; 01721 break; 01722 case ASN_VISIBLESTRING: 01723 valueType = CERT_RDN_VISIBLE_STRING; 01724 if (dataLen) 01725 bytesNeeded += (dataLen + 1) * 2; 01726 break; 01727 case ASN_GENERALSTRING: 01728 valueType = CERT_RDN_GENERAL_STRING; 01729 if (dataLen) 01730 bytesNeeded += (dataLen + 1) * 2; 01731 break; 01732 case ASN_UNIVERSALSTRING: 01733 valueType = CERT_RDN_UNIVERSAL_STRING; 01734 if (dataLen) 01735 bytesNeeded += dataLen / 2 + sizeof(WCHAR); 01736 break; 01737 case ASN_BMPSTRING: 01738 valueType = CERT_RDN_BMP_STRING; 01739 if (dataLen) 01740 bytesNeeded += dataLen + sizeof(WCHAR); 01741 break; 01742 case ASN_UTF8STRING: 01743 valueType = CERT_RDN_UTF8_STRING; 01744 if (dataLen) 01745 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0, 01746 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2; 01747 break; 01748 default: 01749 SetLastError(CRYPT_E_ASN1_BADTAG); 01750 return FALSE; 01751 } 01752 01753 if (pcbDecoded) 01754 *pcbDecoded = 1 + lenBytes + dataLen; 01755 if (!value) 01756 *pcbStructInfo = bytesNeeded; 01757 else if (*pcbStructInfo < bytesNeeded) 01758 { 01759 *pcbStructInfo = bytesNeeded; 01760 SetLastError(ERROR_MORE_DATA); 01761 ret = FALSE; 01762 } 01763 else 01764 { 01765 *pcbStructInfo = bytesNeeded; 01766 value->dwValueType = valueType; 01767 if (dataLen) 01768 { 01769 DWORD i; 01770 LPWSTR str = (LPWSTR)value->Value.pbData; 01771 01772 assert(value->Value.pbData); 01773 switch (pbEncoded[0]) 01774 { 01775 case ASN_NUMERICSTRING: 01776 case ASN_PRINTABLESTRING: 01777 case ASN_IA5STRING: 01778 case ASN_T61STRING: 01779 case ASN_VIDEOTEXSTRING: 01780 case ASN_GRAPHICSTRING: 01781 case ASN_VISIBLESTRING: 01782 case ASN_GENERALSTRING: 01783 value->Value.cbData = dataLen * 2; 01784 for (i = 0; i < dataLen; i++) 01785 str[i] = pbEncoded[1 + lenBytes + i]; 01786 str[i] = 0; 01787 break; 01788 case ASN_UNIVERSALSTRING: 01789 value->Value.cbData = dataLen / 2; 01790 for (i = 0; i < dataLen / 4; i++) 01791 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8) 01792 | pbEncoded[1 + lenBytes + 2 * i + 3]; 01793 str[i] = 0; 01794 break; 01795 case ASN_BMPSTRING: 01796 value->Value.cbData = dataLen; 01797 for (i = 0; i < dataLen / 2; i++) 01798 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | 01799 pbEncoded[1 + lenBytes + 2 * i + 1]; 01800 str[i] = 0; 01801 break; 01802 case ASN_UTF8STRING: 01803 value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0, 01804 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 01805 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR); 01806 *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0; 01807 value->Value.cbData += sizeof(WCHAR); 01808 break; 01809 } 01810 } 01811 else 01812 { 01813 value->Value.cbData = 0; 01814 value->Value.pbData = NULL; 01815 } 01816 } 01817 } 01818 return ret; 01819 } 01820 01821 static BOOL WINAPI CRYPT_AsnDecodeUnicodeNameValue(DWORD dwCertEncodingType, 01822 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01823 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01824 { 01825 BOOL ret = TRUE; 01826 01827 __TRY 01828 { 01829 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, cbEncoded, 01830 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 01831 if (ret && pvStructInfo) 01832 { 01833 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 01834 pcbStructInfo, *pcbStructInfo); 01835 if (ret) 01836 { 01837 CERT_NAME_VALUE *value; 01838 01839 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 01840 pvStructInfo = *(BYTE **)pvStructInfo; 01841 value = pvStructInfo; 01842 value->Value.pbData = ((BYTE *)value + sizeof(CERT_NAME_VALUE)); 01843 ret = CRYPT_AsnDecodeUnicodeNameValueInternal(pbEncoded, 01844 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 01845 pcbStructInfo, NULL); 01846 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 01847 CRYPT_FreeSpace(pDecodePara, value); 01848 } 01849 } 01850 } 01851 __EXCEPT_PAGE_FAULT 01852 { 01853 SetLastError(STATUS_ACCESS_VIOLATION); 01854 ret = FALSE; 01855 } 01856 __ENDTRY 01857 return ret; 01858 } 01859 01860 static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded, 01861 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01862 { 01863 BOOL ret; 01864 struct AsnDecodeSequenceItem items[] = { 01865 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId), 01866 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 01867 offsetof(CERT_RDN_ATTR, pszObjId), 0 }, 01868 { 0, offsetof(CERT_RDN_ATTR, dwValueType), 01869 CRYPT_AsnDecodeNameValueInternal, sizeof(CERT_NAME_VALUE), 01870 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 }, 01871 }; 01872 CERT_RDN_ATTR *attr = pvStructInfo; 01873 01874 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01875 pvStructInfo, *pcbStructInfo); 01876 01877 if (attr) 01878 TRACE("attr->pszObjId is %p\n", attr->pszObjId); 01879 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 01880 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded, 01881 attr ? attr->pszObjId : NULL); 01882 if (attr) 01883 { 01884 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, 01885 debugstr_a(attr->pszObjId)); 01886 TRACE("attr->dwValueType is %d\n", attr->dwValueType); 01887 } 01888 TRACE("returning %d (%08x)\n", ret, GetLastError()); 01889 return ret; 01890 } 01891 01892 static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded, 01893 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01894 { 01895 BOOL ret = TRUE; 01896 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 01897 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr), 01898 sizeof(CERT_RDN), 01899 CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, 01900 offsetof(CERT_RDN_ATTR, pszObjId) }; 01901 01902 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 01903 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 01904 return ret; 01905 } 01906 01907 static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType, 01908 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 01909 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 01910 { 01911 BOOL ret = TRUE; 01912 01913 __TRY 01914 { 01915 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 01916 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN), 01917 sizeof(CERT_NAME_INFO), 01918 CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE, 01919 offsetof(CERT_RDN, rgRDNAttr) }; 01920 DWORD bytesNeeded; 01921 01922 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 01923 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded, 01924 NULL); 01925 if (ret) 01926 { 01927 if (!pvStructInfo) 01928 *pcbStructInfo = bytesNeeded; 01929 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 01930 pvStructInfo, pcbStructInfo, bytesNeeded))) 01931 { 01932 CERT_NAME_INFO *info; 01933 01934 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 01935 pvStructInfo = *(BYTE **)pvStructInfo; 01936 info = pvStructInfo; 01937 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo + 01938 sizeof(CERT_NAME_INFO)); 01939 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 01940 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo, 01941 &bytesNeeded, NULL); 01942 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 01943 CRYPT_FreeSpace(pDecodePara, info); 01944 } 01945 } 01946 } 01947 __EXCEPT_PAGE_FAULT 01948 { 01949 SetLastError(STATUS_ACCESS_VIOLATION); 01950 ret = FALSE; 01951 } 01952 __ENDTRY 01953 return ret; 01954 } 01955 01956 static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded, 01957 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 01958 DWORD *pcbDecoded) 01959 { 01960 BOOL ret; 01961 struct AsnDecodeSequenceItem items[] = { 01962 { ASN_OBJECTIDENTIFIER, offsetof(CERT_RDN_ATTR, pszObjId), 01963 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 01964 offsetof(CERT_RDN_ATTR, pszObjId), 0 }, 01965 { 0, offsetof(CERT_RDN_ATTR, dwValueType), 01966 CRYPT_AsnDecodeUnicodeNameValueInternal, sizeof(CERT_NAME_VALUE), 01967 FALSE, TRUE, offsetof(CERT_RDN_ATTR, Value.pbData), 0 }, 01968 }; 01969 CERT_RDN_ATTR *attr = pvStructInfo; 01970 01971 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 01972 pvStructInfo, *pcbStructInfo); 01973 01974 if (attr) 01975 TRACE("attr->pszObjId is %p\n", attr->pszObjId); 01976 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 01977 pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded, 01978 attr ? attr->pszObjId : NULL); 01979 if (attr) 01980 { 01981 TRACE("attr->pszObjId is %p (%s)\n", attr->pszObjId, 01982 debugstr_a(attr->pszObjId)); 01983 TRACE("attr->dwValueType is %d\n", attr->dwValueType); 01984 } 01985 TRACE("returning %d (%08x)\n", ret, GetLastError()); 01986 return ret; 01987 } 01988 01989 static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded, 01990 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 01991 { 01992 BOOL ret = TRUE; 01993 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 01994 offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr), 01995 sizeof(CERT_RDN), 01996 CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, 01997 offsetof(CERT_RDN_ATTR, pszObjId) }; 01998 01999 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 02000 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02001 return ret; 02002 } 02003 02004 static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType, 02005 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 02006 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 02007 { 02008 BOOL ret = TRUE; 02009 02010 __TRY 02011 { 02012 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 02013 offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN), 02014 sizeof(CERT_NAME_INFO), 02015 CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE, 02016 offsetof(CERT_RDN, rgRDNAttr) }; 02017 DWORD bytesNeeded; 02018 02019 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02020 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded, 02021 NULL); 02022 if (ret) 02023 { 02024 if (!pvStructInfo) 02025 *pcbStructInfo = bytesNeeded; 02026 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 02027 pvStructInfo, pcbStructInfo, bytesNeeded))) 02028 { 02029 CERT_NAME_INFO *info; 02030 02031 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 02032 pvStructInfo = *(BYTE **)pvStructInfo; 02033 info = pvStructInfo; 02034 info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo + 02035 sizeof(CERT_NAME_INFO)); 02036 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02037 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo, 02038 &bytesNeeded, NULL); 02039 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 02040 CRYPT_FreeSpace(pDecodePara, info); 02041 } 02042 } 02043 } 02044 __EXCEPT_PAGE_FAULT 02045 { 02046 SetLastError(STATUS_ACCESS_VIOLATION); 02047 ret = FALSE; 02048 } 02049 __ENDTRY 02050 return ret; 02051 } 02052 02053 static BOOL CRYPT_FindEncodedLen(const BYTE *pbEncoded, DWORD cbEncoded, 02054 DWORD *pcbDecoded) 02055 { 02056 BOOL ret = TRUE, done = FALSE; 02057 DWORD indefiniteNestingLevels = 0, decoded = 0; 02058 02059 TRACE("(%p, %d)\n", pbEncoded, cbEncoded); 02060 02061 do { 02062 DWORD dataLen; 02063 02064 if (!cbEncoded) 02065 done = TRUE; 02066 else if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, 02067 &dataLen))) 02068 { 02069 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 02070 02071 if (dataLen == CMSG_INDEFINITE_LENGTH) 02072 { 02073 indefiniteNestingLevels++; 02074 pbEncoded += 1 + lenBytes; 02075 cbEncoded -= 1 + lenBytes; 02076 decoded += 1 + lenBytes; 02077 TRACE("indefiniteNestingLevels = %d\n", 02078 indefiniteNestingLevels); 02079 } 02080 else 02081 { 02082 if (pbEncoded[0] == 0 && pbEncoded[1] == 0 && 02083 indefiniteNestingLevels) 02084 { 02085 indefiniteNestingLevels--; 02086 TRACE("indefiniteNestingLevels = %d\n", 02087 indefiniteNestingLevels); 02088 } 02089 pbEncoded += 1 + lenBytes + dataLen; 02090 cbEncoded -= 1 + lenBytes + dataLen; 02091 decoded += 1 + lenBytes + dataLen; 02092 if (!indefiniteNestingLevels) 02093 done = TRUE; 02094 } 02095 } 02096 } while (ret && !done); 02097 /* If we haven't found all 0 TLVs, we haven't found the end */ 02098 if (ret && indefiniteNestingLevels) 02099 { 02100 SetLastError(CRYPT_E_ASN1_EOD); 02101 ret = FALSE; 02102 } 02103 if (ret) 02104 *pcbDecoded = decoded; 02105 TRACE("returning %d (%d)\n", ret, ret ? *pcbDecoded : 0); 02106 return ret; 02107 } 02108 02109 static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded, 02110 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02111 DWORD *pcbDecoded) 02112 { 02113 BOOL ret = TRUE; 02114 DWORD bytesNeeded = sizeof(CRYPT_OBJID_BLOB), encodedLen = 0; 02115 02116 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02117 pvStructInfo, *pcbStructInfo); 02118 02119 if ((ret = CRYPT_FindEncodedLen(pbEncoded, cbEncoded, &encodedLen))) 02120 { 02121 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 02122 bytesNeeded += encodedLen; 02123 if (!pvStructInfo) 02124 *pcbStructInfo = bytesNeeded; 02125 else if (*pcbStructInfo < bytesNeeded) 02126 { 02127 SetLastError(ERROR_MORE_DATA); 02128 *pcbStructInfo = bytesNeeded; 02129 ret = FALSE; 02130 } 02131 else 02132 { 02133 PCRYPT_OBJID_BLOB blob = pvStructInfo; 02134 02135 *pcbStructInfo = bytesNeeded; 02136 blob->cbData = encodedLen; 02137 if (encodedLen) 02138 { 02139 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 02140 blob->pbData = (LPBYTE)pbEncoded; 02141 else 02142 { 02143 assert(blob->pbData); 02144 memcpy(blob->pbData, pbEncoded, blob->cbData); 02145 } 02146 } 02147 else 02148 blob->pbData = NULL; 02149 } 02150 if (pcbDecoded) 02151 *pcbDecoded = encodedLen; 02152 } 02153 return ret; 02154 } 02155 02156 static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded, 02157 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 02158 { 02159 BOOL ret; 02160 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 02161 offsetof(CTL_USAGE, cUsageIdentifier), 02162 offsetof(CTL_USAGE, rgpszUsageIdentifier), 02163 sizeof(CTL_USAGE), 02164 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 }; 02165 02166 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 02167 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02168 return ret; 02169 } 02170 02171 static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded, 02172 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02173 DWORD *pcbDecoded) 02174 { 02175 struct AsnArrayDescriptor arrayDesc = { 0, 02176 offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute), 02177 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), 02178 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE, 02179 offsetof(CRYPT_ATTRIBUTE, pszObjId) }; 02180 BOOL ret; 02181 02182 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02183 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02184 return ret; 02185 } 02186 02187 static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded, 02188 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 02189 { 02190 struct AsnDecodeSequenceItem items[] = { 02191 { ASN_OCTETSTRING, offsetof(CTL_ENTRY, SubjectIdentifier), 02192 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE, 02193 offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 }, 02194 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute), 02195 CRYPT_AsnDecodeCTLEntryAttributes, 02196 FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE, 02197 offsetof(CTL_ENTRY, rgAttribute), 0 }, 02198 }; 02199 BOOL ret = TRUE; 02200 CTL_ENTRY *entry = pvStructInfo; 02201 02202 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry, 02203 *pcbStructInfo); 02204 02205 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02206 pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, 02207 pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL); 02208 return ret; 02209 } 02210 02211 static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded, 02212 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 02213 { 02214 BOOL ret; 02215 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 02216 offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry), 02217 FINALMEMBERSIZE(CTL_INFO, cExtension), 02218 CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE, 02219 offsetof(CTL_ENTRY, SubjectIdentifier.pbData) }; 02220 02221 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 02222 pvStructInfo, *pcbStructInfo, pcbDecoded); 02223 02224 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02225 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02226 return ret; 02227 } 02228 02229 static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded, 02230 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02231 DWORD *pcbDecoded) 02232 { 02233 BOOL ret = TRUE; 02234 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 02235 offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension), 02236 FINALMEMBERSIZE(CTL_INFO, cExtension), 02237 CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, 02238 offsetof(CERT_EXTENSION, pszObjId) }; 02239 02240 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 02241 pvStructInfo, *pcbStructInfo, pcbDecoded); 02242 02243 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02244 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02245 return ret; 02246 } 02247 02248 static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded, 02249 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02250 DWORD *pcbDecoded) 02251 { 02252 BOOL ret; 02253 DWORD dataLen; 02254 02255 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 02256 { 02257 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 02258 02259 ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes, 02260 dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); 02261 if (ret && pcbDecoded) 02262 *pcbDecoded = 1 + lenBytes + dataLen; 02263 } 02264 return ret; 02265 } 02266 02267 static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType, 02268 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 02269 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 02270 { 02271 BOOL ret = FALSE; 02272 02273 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02274 pDecodePara, pvStructInfo, *pcbStructInfo); 02275 02276 __TRY 02277 { 02278 struct AsnDecodeSequenceItem items[] = { 02279 { ASN_INTEGER, offsetof(CTL_INFO, dwVersion), 02280 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 02281 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectUsage), 02282 CRYPT_AsnDecodeCTLUsage, sizeof(CTL_USAGE), FALSE, TRUE, 02283 offsetof(CTL_INFO, SubjectUsage.rgpszUsageIdentifier), 0 }, 02284 { ASN_OCTETSTRING, offsetof(CTL_INFO, ListIdentifier), 02285 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), TRUE, 02286 TRUE, offsetof(CTL_INFO, ListIdentifier.pbData), 0 }, 02287 { ASN_INTEGER, offsetof(CTL_INFO, SequenceNumber), 02288 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), 02289 TRUE, TRUE, offsetof(CTL_INFO, SequenceNumber.pbData), 0 }, 02290 { 0, offsetof(CTL_INFO, ThisUpdate), 02291 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 02292 0 }, 02293 { 0, offsetof(CTL_INFO, NextUpdate), 02294 CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE, 02295 0 }, 02296 { ASN_SEQUENCEOF, offsetof(CTL_INFO, SubjectAlgorithm), 02297 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 02298 FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 }, 02299 { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry), 02300 CRYPT_AsnDecodeCTLEntries, 02301 MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension), 02302 TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 }, 02303 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension), 02304 CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension), 02305 TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 }, 02306 }; 02307 02308 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02309 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 02310 pcbStructInfo, NULL, NULL); 02311 } 02312 __EXCEPT_PAGE_FAULT 02313 { 02314 SetLastError(STATUS_ACCESS_VIOLATION); 02315 } 02316 __ENDTRY 02317 return ret; 02318 } 02319 02320 static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded, 02321 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02322 DWORD *pcbDecoded) 02323 { 02324 BOOL ret; 02325 struct AsnDecodeSequenceItem items[] = { 02326 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 02327 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 02328 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId), 0 }, 02329 { 0, offsetof(CRYPT_SMIME_CAPABILITY, Parameters), 02330 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 02331 offsetof(CRYPT_SMIME_CAPABILITY, Parameters.pbData), 0 }, 02332 }; 02333 PCRYPT_SMIME_CAPABILITY capability = pvStructInfo; 02334 02335 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02336 pvStructInfo, *pcbStructInfo); 02337 02338 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02339 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 02340 pcbDecoded, capability ? capability->pszObjId : NULL); 02341 TRACE("returning %d\n", ret); 02342 return ret; 02343 } 02344 02345 static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType, 02346 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 02347 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 02348 { 02349 BOOL ret = FALSE; 02350 02351 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02352 pDecodePara, pvStructInfo, *pcbStructInfo); 02353 02354 __TRY 02355 { 02356 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 02357 offsetof(CRYPT_SMIME_CAPABILITIES, cCapability), 02358 offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability), 02359 sizeof(CRYPT_SMIME_CAPABILITIES), 02360 CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE, 02361 offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) }; 02362 CRYPT_SMIME_CAPABILITIES *capabilities = pvStructInfo; 02363 02364 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 02365 capabilities->rgCapability = (CRYPT_SMIME_CAPABILITY *)(capabilities + 1); 02366 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02367 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 02368 } 02369 __EXCEPT_PAGE_FAULT 02370 { 02371 SetLastError(STATUS_ACCESS_VIOLATION); 02372 } 02373 __ENDTRY 02374 TRACE("returning %d\n", ret); 02375 return ret; 02376 } 02377 02378 static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded, 02379 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02380 DWORD *pcbDecoded) 02381 { 02382 BOOL ret = TRUE; 02383 DWORD dataLen; 02384 LPSTR *pStr = pvStructInfo; 02385 02386 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 02387 { 02388 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 02389 DWORD bytesNeeded = sizeof(LPSTR) + sizeof(char); 02390 02391 if (pbEncoded[0] != ASN_IA5STRING) 02392 { 02393 SetLastError(CRYPT_E_ASN1_CORRUPT); 02394 ret = FALSE; 02395 } 02396 else 02397 { 02398 bytesNeeded += dataLen; 02399 if (pcbDecoded) 02400 *pcbDecoded = 1 + lenBytes + dataLen; 02401 if (!pvStructInfo) 02402 *pcbStructInfo = bytesNeeded; 02403 else if (*pcbStructInfo < bytesNeeded) 02404 { 02405 *pcbStructInfo = bytesNeeded; 02406 SetLastError(ERROR_MORE_DATA); 02407 ret = FALSE; 02408 } 02409 else 02410 { 02411 *pcbStructInfo = bytesNeeded; 02412 if (dataLen) 02413 { 02414 LPSTR str = *pStr; 02415 02416 assert(str); 02417 memcpy(str, pbEncoded + 1 + lenBytes, dataLen); 02418 str[dataLen] = 0; 02419 } 02420 else 02421 *pStr = NULL; 02422 } 02423 } 02424 } 02425 return ret; 02426 } 02427 02428 static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded, 02429 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02430 DWORD *pcbDecoded) 02431 { 02432 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 02433 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), 02434 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers), 02435 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), 02436 CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 }; 02437 BOOL ret; 02438 02439 TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, 02440 pvStructInfo, pvStructInfo ? *pcbDecoded : 0); 02441 02442 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02443 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02444 TRACE("returning %d\n", ret); 02445 return ret; 02446 } 02447 02448 static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded, 02449 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02450 DWORD *pcbDecoded) 02451 { 02452 BOOL ret; 02453 struct AsnDecodeSequenceItem items[] = { 02454 { ASN_IA5STRING, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, 02455 pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE, 02456 offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 }, 02457 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, 02458 cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers, 02459 FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), 02460 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, 02461 rgNoticeNumbers), 0 }, 02462 }; 02463 DWORD bytesNeeded; 02464 02465 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02466 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 02467 02468 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02469 pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded, 02470 NULL); 02471 if (ret) 02472 { 02473 /* The caller is expecting a pointer to a 02474 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE to be decoded, whereas 02475 * CRYPT_AsnDecodeSequence is decoding a 02476 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. Increment the bytes 02477 * needed, and decode again if the requisite space is available. 02478 */ 02479 bytesNeeded += sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE); 02480 if (!pvStructInfo) 02481 *pcbStructInfo = bytesNeeded; 02482 else if (*pcbStructInfo < bytesNeeded) 02483 { 02484 *pcbStructInfo = bytesNeeded; 02485 SetLastError(ERROR_MORE_DATA); 02486 ret = FALSE; 02487 } 02488 else 02489 { 02490 PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE noticeRef; 02491 02492 *pcbStructInfo = bytesNeeded; 02493 /* The pointer (pvStructInfo) passed in points to the first dynamic 02494 * pointer, so use it as the pointer to the 02495 * CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, and create the 02496 * appropriate offset for the first dynamic pointer within the 02497 * notice reference by pointing to the first memory location past 02498 * the CERT_POLICY_QUALIFIER_NOTICE_REFERENCE. 02499 */ 02500 noticeRef = 02501 *(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo; 02502 noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef + 02503 sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE)); 02504 ret = CRYPT_AsnDecodeSequence(items, 02505 sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, 02506 NULL, noticeRef, &bytesNeeded, pcbDecoded, 02507 noticeRef->pszOrganization); 02508 } 02509 } 02510 TRACE("returning %d\n", ret); 02511 return ret; 02512 } 02513 02514 static BOOL CRYPT_AsnDecodeUnicodeString(const BYTE *pbEncoded, 02515 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02516 DWORD *pcbDecoded) 02517 { 02518 BOOL ret = TRUE; 02519 DWORD dataLen; 02520 02521 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 02522 { 02523 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 02524 DWORD bytesNeeded = sizeof(LPWSTR); 02525 02526 switch (pbEncoded[0]) 02527 { 02528 case ASN_NUMERICSTRING: 02529 if (dataLen) 02530 bytesNeeded += (dataLen + 1) * 2; 02531 break; 02532 case ASN_PRINTABLESTRING: 02533 if (dataLen) 02534 bytesNeeded += (dataLen + 1) * 2; 02535 break; 02536 case ASN_IA5STRING: 02537 if (dataLen) 02538 bytesNeeded += (dataLen + 1) * 2; 02539 break; 02540 case ASN_T61STRING: 02541 if (dataLen) 02542 bytesNeeded += (dataLen + 1) * 2; 02543 break; 02544 case ASN_VIDEOTEXSTRING: 02545 if (dataLen) 02546 bytesNeeded += (dataLen + 1) * 2; 02547 break; 02548 case ASN_GRAPHICSTRING: 02549 if (dataLen) 02550 bytesNeeded += (dataLen + 1) * 2; 02551 break; 02552 case ASN_VISIBLESTRING: 02553 if (dataLen) 02554 bytesNeeded += (dataLen + 1) * 2; 02555 break; 02556 case ASN_GENERALSTRING: 02557 if (dataLen) 02558 bytesNeeded += (dataLen + 1) * 2; 02559 break; 02560 case ASN_UNIVERSALSTRING: 02561 if (dataLen) 02562 bytesNeeded += dataLen / 2 + sizeof(WCHAR); 02563 break; 02564 case ASN_BMPSTRING: 02565 if (dataLen) 02566 bytesNeeded += dataLen + sizeof(WCHAR); 02567 break; 02568 case ASN_UTF8STRING: 02569 if (dataLen) 02570 bytesNeeded += (MultiByteToWideChar(CP_UTF8, 0, 02571 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, NULL, 0) + 1) * 2; 02572 break; 02573 default: 02574 SetLastError(CRYPT_E_ASN1_BADTAG); 02575 return FALSE; 02576 } 02577 02578 if (pcbDecoded) 02579 *pcbDecoded = 1 + lenBytes + dataLen; 02580 if (!pvStructInfo) 02581 *pcbStructInfo = bytesNeeded; 02582 else if (*pcbStructInfo < bytesNeeded) 02583 { 02584 *pcbStructInfo = bytesNeeded; 02585 SetLastError(ERROR_MORE_DATA); 02586 ret = FALSE; 02587 } 02588 else 02589 { 02590 LPWSTR *pStr = pvStructInfo; 02591 02592 *pcbStructInfo = bytesNeeded; 02593 if (dataLen) 02594 { 02595 DWORD i; 02596 LPWSTR str = *(LPWSTR *)pStr; 02597 02598 assert(str); 02599 switch (pbEncoded[0]) 02600 { 02601 case ASN_NUMERICSTRING: 02602 case ASN_PRINTABLESTRING: 02603 case ASN_IA5STRING: 02604 case ASN_T61STRING: 02605 case ASN_VIDEOTEXSTRING: 02606 case ASN_GRAPHICSTRING: 02607 case ASN_VISIBLESTRING: 02608 case ASN_GENERALSTRING: 02609 for (i = 0; i < dataLen; i++) 02610 str[i] = pbEncoded[1 + lenBytes + i]; 02611 str[i] = 0; 02612 break; 02613 case ASN_UNIVERSALSTRING: 02614 for (i = 0; i < dataLen / 4; i++) 02615 str[i] = (pbEncoded[1 + lenBytes + 2 * i + 2] << 8) 02616 | pbEncoded[1 + lenBytes + 2 * i + 3]; 02617 str[i] = 0; 02618 break; 02619 case ASN_BMPSTRING: 02620 for (i = 0; i < dataLen / 2; i++) 02621 str[i] = (pbEncoded[1 + lenBytes + 2 * i] << 8) | 02622 pbEncoded[1 + lenBytes + 2 * i + 1]; 02623 str[i] = 0; 02624 break; 02625 case ASN_UTF8STRING: 02626 { 02627 int len = MultiByteToWideChar(CP_UTF8, 0, 02628 (LPCSTR)pbEncoded + 1 + lenBytes, dataLen, 02629 str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2; 02630 str[len] = 0; 02631 break; 02632 } 02633 } 02634 } 02635 else 02636 *pStr = NULL; 02637 } 02638 } 02639 return ret; 02640 } 02641 02642 static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal( 02643 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, 02644 DWORD *pcbStructInfo, DWORD *pcbDecoded) 02645 { 02646 BOOL ret; 02647 struct AsnDecodeSequenceItem items[] = { 02648 { ASN_SEQUENCE, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, 02649 pNoticeReference), CRYPT_AsnDecodeNoticeReference, 02650 sizeof(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE), TRUE, TRUE, 02651 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pNoticeReference), 0 }, 02652 { 0, offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 02653 CRYPT_AsnDecodeUnicodeString, sizeof(LPWSTR), TRUE, TRUE, 02654 offsetof(CERT_POLICY_QUALIFIER_USER_NOTICE, pszDisplayText), 0 }, 02655 }; 02656 PCERT_POLICY_QUALIFIER_USER_NOTICE notice = pvStructInfo; 02657 02658 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02659 pvStructInfo, *pcbStructInfo); 02660 02661 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02662 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 02663 pcbDecoded, notice ? notice->pNoticeReference : NULL); 02664 TRACE("returning %d\n", ret); 02665 return ret; 02666 } 02667 02668 static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice( 02669 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, 02670 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, 02671 void *pvStructInfo, DWORD *pcbStructInfo) 02672 { 02673 BOOL ret = FALSE; 02674 02675 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02676 pDecodePara, pvStructInfo, *pcbStructInfo); 02677 02678 __TRY 02679 { 02680 DWORD bytesNeeded; 02681 02682 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(pbEncoded, 02683 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, 02684 NULL); 02685 if (ret) 02686 { 02687 if (!pvStructInfo) 02688 *pcbStructInfo = bytesNeeded; 02689 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 02690 pvStructInfo, pcbStructInfo, bytesNeeded))) 02691 { 02692 PCERT_POLICY_QUALIFIER_USER_NOTICE notice; 02693 02694 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 02695 pvStructInfo = *(BYTE **)pvStructInfo; 02696 notice = pvStructInfo; 02697 notice->pNoticeReference = 02698 (PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE) 02699 ((BYTE *)pvStructInfo + 02700 sizeof(CERT_POLICY_QUALIFIER_USER_NOTICE)); 02701 ret = CRYPT_AsnDecodePolicyQualifierUserNoticeInternal( 02702 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, 02703 pvStructInfo, &bytesNeeded, NULL); 02704 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 02705 CRYPT_FreeSpace(pDecodePara, notice); 02706 } 02707 } 02708 } 02709 __EXCEPT_PAGE_FAULT 02710 { 02711 SetLastError(STATUS_ACCESS_VIOLATION); 02712 } 02713 __ENDTRY 02714 TRACE("returning %d\n", ret); 02715 return ret; 02716 } 02717 02718 static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded, 02719 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02720 DWORD *pcbDecoded) 02721 { 02722 BOOL ret; 02723 struct AsnArrayDescriptor arrayDesc = { 0, 02724 offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue), 02725 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), 02726 CRYPT_AsnDecodeCopyBytes, 02727 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; 02728 02729 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 02730 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); 02731 02732 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02733 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02734 return ret; 02735 } 02736 02737 static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, 02738 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02739 DWORD *pcbDecoded) 02740 { 02741 BOOL ret; 02742 struct AsnDecodeSequenceItem items[] = { 02743 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ATTRIBUTE, pszObjId), 02744 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 02745 offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 }, 02746 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue), 02747 CRYPT_AsnDecodePKCSAttributeValue, 02748 FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE, 02749 TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 }, 02750 }; 02751 PCRYPT_ATTRIBUTE attr = pvStructInfo; 02752 02753 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02754 pvStructInfo, *pcbStructInfo); 02755 02756 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02757 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 02758 pcbDecoded, attr ? attr->pszObjId : NULL); 02759 TRACE("returning %d\n", ret); 02760 return ret; 02761 } 02762 02763 static BOOL WINAPI CRYPT_AsnDecodePKCSAttribute(DWORD dwCertEncodingType, 02764 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 02765 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 02766 { 02767 BOOL ret = FALSE; 02768 02769 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02770 pDecodePara, pvStructInfo, *pcbStructInfo); 02771 02772 __TRY 02773 { 02774 DWORD bytesNeeded; 02775 02776 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded, 02777 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); 02778 if (ret) 02779 { 02780 if (!pvStructInfo) 02781 *pcbStructInfo = bytesNeeded; 02782 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 02783 pvStructInfo, pcbStructInfo, bytesNeeded))) 02784 { 02785 PCRYPT_ATTRIBUTE attr; 02786 02787 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 02788 pvStructInfo = *(BYTE **)pvStructInfo; 02789 attr = pvStructInfo; 02790 attr->pszObjId = (LPSTR)((BYTE *)pvStructInfo + 02791 sizeof(CRYPT_ATTRIBUTE)); 02792 ret = CRYPT_AsnDecodePKCSAttributeInternal(pbEncoded, cbEncoded, 02793 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, &bytesNeeded, 02794 NULL); 02795 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 02796 CRYPT_FreeSpace(pDecodePara, attr); 02797 } 02798 } 02799 } 02800 __EXCEPT_PAGE_FAULT 02801 { 02802 SetLastError(STATUS_ACCESS_VIOLATION); 02803 } 02804 __ENDTRY 02805 TRACE("returning %d\n", ret); 02806 return ret; 02807 } 02808 02809 static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded, 02810 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02811 DWORD *pcbDecoded) 02812 { 02813 struct AsnArrayDescriptor arrayDesc = { 0, 02814 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr), 02815 sizeof(CRYPT_ATTRIBUTES), 02816 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE, 02817 offsetof(CRYPT_ATTRIBUTE, pszObjId) }; 02818 BOOL ret; 02819 02820 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 02821 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 02822 return ret; 02823 } 02824 02825 static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType, 02826 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 02827 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 02828 { 02829 BOOL ret = FALSE; 02830 02831 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 02832 pDecodePara, pvStructInfo, *pcbStructInfo); 02833 02834 __TRY 02835 { 02836 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 02837 offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr), 02838 sizeof(CRYPT_ATTRIBUTES), 02839 CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), 02840 TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) }; 02841 CRYPT_ATTRIBUTES *attrs = pvStructInfo; 02842 02843 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 02844 attrs->rgAttr = (CRYPT_ATTRIBUTE *)(attrs + 1); 02845 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 02846 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 02847 } 02848 __EXCEPT_PAGE_FAULT 02849 { 02850 SetLastError(STATUS_ACCESS_VIOLATION); 02851 } 02852 __ENDTRY 02853 TRACE("returning %d\n", ret); 02854 return ret; 02855 } 02856 02857 static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded, 02858 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 02859 { 02860 CRYPT_ALGORITHM_IDENTIFIER *algo = pvStructInfo; 02861 BOOL ret = TRUE; 02862 struct AsnDecodeSequenceItem items[] = { 02863 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 02864 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 02865 offsetof(CRYPT_ALGORITHM_IDENTIFIER, pszObjId), 0 }, 02866 { 0, offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters), 02867 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 02868 offsetof(CRYPT_ALGORITHM_IDENTIFIER, Parameters.pbData), 0 }, 02869 }; 02870 02871 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 02872 pvStructInfo, *pcbStructInfo, pcbDecoded); 02873 02874 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02875 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 02876 pcbDecoded, algo ? algo->pszObjId : NULL); 02877 if (ret && pvStructInfo) 02878 { 02879 TRACE("pszObjId is %p (%s)\n", algo->pszObjId, 02880 debugstr_a(algo->pszObjId)); 02881 } 02882 return ret; 02883 } 02884 02885 static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded, 02886 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 02887 DWORD *pcbDecoded) 02888 { 02889 BOOL ret = TRUE; 02890 struct AsnDecodeSequenceItem items[] = { 02891 { ASN_SEQUENCEOF, offsetof(CERT_PUBLIC_KEY_INFO, Algorithm), 02892 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 02893 FALSE, TRUE, offsetof(CERT_PUBLIC_KEY_INFO, 02894 Algorithm.pszObjId) }, 02895 { ASN_BITSTRING, offsetof(CERT_PUBLIC_KEY_INFO, PublicKey), 02896 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 02897 offsetof(CERT_PUBLIC_KEY_INFO, PublicKey.pbData) }, 02898 }; 02899 PCERT_PUBLIC_KEY_INFO info = pvStructInfo; 02900 02901 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 02902 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 02903 pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL); 02904 return ret; 02905 } 02906 02907 static BOOL WINAPI CRYPT_AsnDecodePubKeyInfo(DWORD dwCertEncodingType, 02908 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 02909 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 02910 { 02911 BOOL ret = TRUE; 02912 02913 __TRY 02914 { 02915 DWORD bytesNeeded; 02916 02917 if ((ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded, 02918 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL))) 02919 { 02920 if (!pvStructInfo) 02921 *pcbStructInfo = bytesNeeded; 02922 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 02923 pvStructInfo, pcbStructInfo, bytesNeeded))) 02924 { 02925 PCERT_PUBLIC_KEY_INFO info; 02926 02927 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 02928 pvStructInfo = *(BYTE **)pvStructInfo; 02929 info = pvStructInfo; 02930 info->Algorithm.Parameters.pbData = (BYTE *)pvStructInfo + 02931 sizeof(CERT_PUBLIC_KEY_INFO); 02932 ret = CRYPT_AsnDecodePubKeyInfoInternal(pbEncoded, cbEncoded, 02933 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 02934 &bytesNeeded, NULL); 02935 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 02936 CRYPT_FreeSpace(pDecodePara, info); 02937 } 02938 } 02939 } 02940 __EXCEPT_PAGE_FAULT 02941 { 02942 SetLastError(STATUS_ACCESS_VIOLATION); 02943 ret = FALSE; 02944 } 02945 __ENDTRY 02946 return ret; 02947 } 02948 02949 static BOOL CRYPT_AsnDecodeBool(const BYTE *pbEncoded, DWORD cbEncoded, 02950 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 02951 { 02952 BOOL ret; 02953 02954 if (cbEncoded < 3) 02955 { 02956 SetLastError(CRYPT_E_ASN1_CORRUPT); 02957 return FALSE; 02958 } 02959 if (GET_LEN_BYTES(pbEncoded[1]) > 1) 02960 { 02961 SetLastError(CRYPT_E_ASN1_CORRUPT); 02962 return FALSE; 02963 } 02964 if (pbEncoded[1] > 1) 02965 { 02966 SetLastError(CRYPT_E_ASN1_CORRUPT); 02967 return FALSE; 02968 } 02969 if (pcbDecoded) 02970 *pcbDecoded = 3; 02971 if (!pvStructInfo) 02972 { 02973 *pcbStructInfo = sizeof(BOOL); 02974 ret = TRUE; 02975 } 02976 else if (*pcbStructInfo < sizeof(BOOL)) 02977 { 02978 *pcbStructInfo = sizeof(BOOL); 02979 SetLastError(ERROR_MORE_DATA); 02980 ret = FALSE; 02981 } 02982 else 02983 { 02984 *pcbStructInfo = sizeof(BOOL); 02985 *(BOOL *)pvStructInfo = pbEncoded[2] ? TRUE : FALSE; 02986 ret = TRUE; 02987 } 02988 TRACE("returning %d (%08x)\n", ret, GetLastError()); 02989 return ret; 02990 } 02991 02992 static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, 02993 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 02994 { 02995 PCERT_ALT_NAME_ENTRY entry = pvStructInfo; 02996 DWORD dataLen, lenBytes, bytesNeeded = sizeof(CERT_ALT_NAME_ENTRY); 02997 BOOL ret; 02998 02999 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03000 pvStructInfo, *pcbStructInfo); 03001 03002 if (cbEncoded < 2) 03003 { 03004 SetLastError(CRYPT_E_ASN1_CORRUPT); 03005 return FALSE; 03006 } 03007 lenBytes = GET_LEN_BYTES(pbEncoded[1]); 03008 if (1 + lenBytes > cbEncoded) 03009 { 03010 SetLastError(CRYPT_E_ASN1_CORRUPT); 03011 return FALSE; 03012 } 03013 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 03014 { 03015 switch (pbEncoded[0] & ASN_TYPE_MASK) 03016 { 03017 case 1: /* rfc822Name */ 03018 case 2: /* dNSName */ 03019 case 6: /* uniformResourceIdentifier */ 03020 if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen)) 03021 { 03022 SetLastError(CRYPT_E_ASN1_RULE); 03023 ret = FALSE; 03024 } 03025 else 03026 bytesNeeded += (dataLen + 1) * sizeof(WCHAR); 03027 break; 03028 case 4: /* directoryName */ 03029 case 7: /* iPAddress */ 03030 bytesNeeded += dataLen; 03031 break; 03032 case 8: /* registeredID */ 03033 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, NULL, 03034 &dataLen, NULL); 03035 if (ret) 03036 { 03037 /* FIXME: ugly, shouldn't need to know internals of OID decode 03038 * function to use it. 03039 */ 03040 bytesNeeded += dataLen - sizeof(LPSTR); 03041 } 03042 break; 03043 case 0: /* otherName */ 03044 FIXME("%d: stub\n", pbEncoded[0] & ASN_TYPE_MASK); 03045 SetLastError(CRYPT_E_ASN1_BADTAG); 03046 ret = FALSE; 03047 break; 03048 case 3: /* x400Address, unimplemented */ 03049 case 5: /* ediPartyName, unimplemented */ 03050 TRACE("type %d unimplemented\n", pbEncoded[0] & ASN_TYPE_MASK); 03051 SetLastError(CRYPT_E_ASN1_BADTAG); 03052 ret = FALSE; 03053 break; 03054 default: 03055 TRACE("type %d bad\n", pbEncoded[0] & ASN_TYPE_MASK); 03056 SetLastError(CRYPT_E_ASN1_CORRUPT); 03057 ret = FALSE; 03058 } 03059 if (ret) 03060 { 03061 if (pcbDecoded) 03062 *pcbDecoded = 1 + lenBytes + dataLen; 03063 if (!entry) 03064 *pcbStructInfo = bytesNeeded; 03065 else if (*pcbStructInfo < bytesNeeded) 03066 { 03067 *pcbStructInfo = bytesNeeded; 03068 SetLastError(ERROR_MORE_DATA); 03069 ret = FALSE; 03070 } 03071 else 03072 { 03073 *pcbStructInfo = bytesNeeded; 03074 /* MS used values one greater than the asn1 ones.. sigh */ 03075 entry->dwAltNameChoice = (pbEncoded[0] & ASN_TYPE_MASK) + 1; 03076 switch (pbEncoded[0] & ASN_TYPE_MASK) 03077 { 03078 case 1: /* rfc822Name */ 03079 case 2: /* dNSName */ 03080 case 6: /* uniformResourceIdentifier */ 03081 { 03082 DWORD i; 03083 03084 for (i = 0; i < dataLen; i++) 03085 entry->u.pwszURL[i] = 03086 (WCHAR)pbEncoded[1 + lenBytes + i]; 03087 entry->u.pwszURL[i] = 0; 03088 TRACE("URL is %p (%s)\n", entry->u.pwszURL, 03089 debugstr_w(entry->u.pwszURL)); 03090 break; 03091 } 03092 case 4: /* directoryName */ 03093 /* The data are memory-equivalent with the IPAddress case, 03094 * fall-through 03095 */ 03096 case 7: /* iPAddress */ 03097 /* The next data pointer is in the pwszURL spot, that is, 03098 * the first 4 bytes. Need to move it to the next spot. 03099 */ 03100 entry->u.IPAddress.pbData = (LPBYTE)entry->u.pwszURL; 03101 entry->u.IPAddress.cbData = dataLen; 03102 memcpy(entry->u.IPAddress.pbData, pbEncoded + 1 + lenBytes, 03103 dataLen); 03104 break; 03105 case 8: /* registeredID */ 03106 ret = CRYPT_AsnDecodeOidIgnoreTag(pbEncoded, cbEncoded, 0, 03107 &entry->u.pszRegisteredID, &dataLen, NULL); 03108 break; 03109 } 03110 } 03111 } 03112 } 03113 return ret; 03114 } 03115 03116 static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded, 03117 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03118 DWORD *pcbDecoded) 03119 { 03120 BOOL ret; 03121 struct AsnArrayDescriptor arrayDesc = { 0, 03122 offsetof(CERT_ALT_NAME_INFO, cAltEntry), 03123 offsetof(CERT_ALT_NAME_INFO, rgAltEntry), 03124 sizeof(CERT_ALT_NAME_INFO), 03125 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, 03126 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; 03127 03128 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 03129 pvStructInfo, *pcbStructInfo, pcbDecoded); 03130 03131 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, 03132 NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 03133 return ret; 03134 } 03135 03136 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType, 03137 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03138 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03139 { 03140 BOOL ret; 03141 03142 __TRY 03143 { 03144 struct AsnDecodeSequenceItem items[] = { 03145 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId), 03146 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), 03147 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID_INFO, KeyId.pbData), 0 }, 03148 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1, 03149 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer), 03150 CRYPT_AsnDecodeOctetsInternal, sizeof(CERT_NAME_BLOB), TRUE, TRUE, 03151 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertIssuer.pbData), 0 }, 03152 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID_INFO, 03153 CertSerialNumber), CRYPT_AsnDecodeIntegerInternal, 03154 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE, 03155 offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 }, 03156 }; 03157 03158 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03159 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 03160 pcbStructInfo, NULL, NULL); 03161 } 03162 __EXCEPT_PAGE_FAULT 03163 { 03164 SetLastError(STATUS_ACCESS_VIOLATION); 03165 ret = FALSE; 03166 } 03167 __ENDTRY 03168 return ret; 03169 } 03170 03171 static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType, 03172 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03173 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03174 { 03175 BOOL ret; 03176 03177 __TRY 03178 { 03179 struct AsnDecodeSequenceItem items[] = { 03180 { ASN_CONTEXT | 0, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId), 03181 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), 03182 TRUE, TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, KeyId.pbData), 0 }, 03183 { ASN_CONTEXT | ASN_CONSTRUCTOR| 1, 03184 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, AuthorityCertIssuer), 03185 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, 03186 TRUE, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, 03187 AuthorityCertIssuer.rgAltEntry), 0 }, 03188 { ASN_CONTEXT | 2, offsetof(CERT_AUTHORITY_KEY_ID2_INFO, 03189 AuthorityCertSerialNumber), CRYPT_AsnDecodeIntegerInternal, 03190 sizeof(CRYPT_INTEGER_BLOB), TRUE, TRUE, 03191 offsetof(CERT_AUTHORITY_KEY_ID2_INFO, 03192 AuthorityCertSerialNumber.pbData), 0 }, 03193 }; 03194 03195 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03196 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 03197 pcbStructInfo, NULL, NULL); 03198 } 03199 __EXCEPT_PAGE_FAULT 03200 { 03201 SetLastError(STATUS_ACCESS_VIOLATION); 03202 ret = FALSE; 03203 } 03204 __ENDTRY 03205 return ret; 03206 } 03207 03208 static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded, 03209 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03210 DWORD *pcbDecoded) 03211 { 03212 struct AsnDecodeSequenceItem items[] = { 03213 { 0, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 03214 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE, 03215 offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod), 0 }, 03216 { 0, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation), 03217 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), FALSE, 03218 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, AccessLocation.u.pwszURL), 0 }, 03219 }; 03220 CERT_ACCESS_DESCRIPTION *descr = pvStructInfo; 03221 03222 return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03223 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 03224 pcbDecoded, descr ? descr->pszAccessMethod : NULL); 03225 } 03226 03227 static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType, 03228 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03229 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03230 { 03231 BOOL ret; 03232 03233 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03234 pDecodePara, pvStructInfo, *pcbStructInfo); 03235 03236 __TRY 03237 { 03238 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 03239 offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr), 03240 offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr), 03241 sizeof(CERT_AUTHORITY_INFO_ACCESS), 03242 CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION), 03243 TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) }; 03244 CERT_AUTHORITY_INFO_ACCESS *info = pvStructInfo; 03245 03246 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 03247 info->rgAccDescr = (CERT_ACCESS_DESCRIPTION *)(info + 1); 03248 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 03249 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 03250 } 03251 __EXCEPT_PAGE_FAULT 03252 { 03253 SetLastError(STATUS_ACCESS_VIOLATION); 03254 ret = FALSE; 03255 } 03256 __ENDTRY 03257 return ret; 03258 } 03259 03260 static BOOL CRYPT_AsnDecodePKCSContent(const BYTE *pbEncoded, DWORD cbEncoded, 03261 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 03262 { 03263 BOOL ret; 03264 DWORD dataLen; 03265 03266 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 03267 pvStructInfo, *pcbStructInfo, pcbDecoded); 03268 03269 /* The caller has already checked the tag, no need to check it again. 03270 * Check the outer length is valid: 03271 */ 03272 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) 03273 { 03274 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 03275 DWORD innerLen; 03276 03277 pbEncoded += 1 + lenBytes; 03278 cbEncoded -= 1 + lenBytes; 03279 if (dataLen == CMSG_INDEFINITE_LENGTH) 03280 cbEncoded -= 2; /* space for 0 TLV */ 03281 /* Check the inner length is valid: */ 03282 if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &innerLen))) 03283 { 03284 DWORD decodedLen; 03285 03286 ret = CRYPT_AsnDecodeCopyBytes(pbEncoded, cbEncoded, dwFlags, 03287 pvStructInfo, pcbStructInfo, &decodedLen); 03288 if (dataLen == CMSG_INDEFINITE_LENGTH) 03289 { 03290 if (*(pbEncoded + decodedLen) != 0 || 03291 *(pbEncoded + decodedLen + 1) != 0) 03292 { 03293 TRACE("expected 0 TLV, got {%02x,%02x}\n", 03294 *(pbEncoded + decodedLen), 03295 *(pbEncoded + decodedLen + 1)); 03296 SetLastError(CRYPT_E_ASN1_CORRUPT); 03297 ret = FALSE; 03298 } 03299 else 03300 decodedLen += 2; 03301 } 03302 if (ret && pcbDecoded) 03303 { 03304 *pcbDecoded = 1 + lenBytes + decodedLen; 03305 TRACE("decoded %d bytes\n", *pcbDecoded); 03306 } 03307 } 03308 } 03309 return ret; 03310 } 03311 03312 static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded, 03313 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03314 DWORD *pcbDecoded) 03315 { 03316 CRYPT_CONTENT_INFO *info = pvStructInfo; 03317 struct AsnDecodeSequenceItem items[] = { 03318 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_CONTENT_INFO, pszObjId), 03319 CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, 03320 offsetof(CRYPT_CONTENT_INFO, pszObjId), 0 }, 03321 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, 03322 offsetof(CRYPT_CONTENT_INFO, Content), CRYPT_AsnDecodePKCSContent, 03323 sizeof(CRYPT_DER_BLOB), TRUE, TRUE, 03324 offsetof(CRYPT_CONTENT_INFO, Content.pbData), 0 }, 03325 }; 03326 BOOL ret; 03327 03328 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 03329 pvStructInfo, *pcbStructInfo, pcbDecoded); 03330 03331 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03332 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 03333 pcbDecoded, info ? info->pszObjId : NULL); 03334 return ret; 03335 } 03336 03337 static BOOL WINAPI CRYPT_AsnDecodePKCSContentInfo(DWORD dwCertEncodingType, 03338 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03339 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03340 { 03341 BOOL ret = FALSE; 03342 03343 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03344 pDecodePara, pvStructInfo, *pcbStructInfo); 03345 03346 __TRY 03347 { 03348 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, cbEncoded, 03349 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 03350 if (ret && pvStructInfo) 03351 { 03352 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 03353 pcbStructInfo, *pcbStructInfo); 03354 if (ret) 03355 { 03356 CRYPT_CONTENT_INFO *info; 03357 03358 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 03359 pvStructInfo = *(BYTE **)pvStructInfo; 03360 info = pvStructInfo; 03361 info->pszObjId = (LPSTR)((BYTE *)info + 03362 sizeof(CRYPT_CONTENT_INFO)); 03363 ret = CRYPT_AsnDecodePKCSContentInfoInternal(pbEncoded, 03364 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 03365 pcbStructInfo, NULL); 03366 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 03367 CRYPT_FreeSpace(pDecodePara, info); 03368 } 03369 } 03370 } 03371 __EXCEPT_PAGE_FAULT 03372 { 03373 SetLastError(STATUS_ACCESS_VIOLATION); 03374 } 03375 __ENDTRY 03376 return ret; 03377 } 03378 03379 BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded, 03380 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, 03381 CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData) 03382 { 03383 BOOL ret; 03384 struct AsnDecodeSequenceItem items[] = { 03385 { ASN_INTEGER, offsetof(CRYPT_DIGESTED_DATA, version), 03386 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 03387 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm), 03388 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 03389 FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, DigestAlgorithm.pszObjId), 03390 0 }, 03391 { ASN_SEQUENCEOF, offsetof(CRYPT_DIGESTED_DATA, ContentInfo), 03392 CRYPT_AsnDecodePKCSContentInfoInternal, 03393 sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_DIGESTED_DATA, 03394 ContentInfo.pszObjId), 0 }, 03395 { ASN_OCTETSTRING, offsetof(CRYPT_DIGESTED_DATA, hash), 03396 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_HASH_BLOB), FALSE, TRUE, 03397 offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 }, 03398 }; 03399 03400 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03401 pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData, 03402 NULL, NULL); 03403 return ret; 03404 } 03405 03406 static BOOL WINAPI CRYPT_AsnDecodeAltName(DWORD dwCertEncodingType, 03407 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03408 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03409 { 03410 BOOL ret = TRUE; 03411 03412 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03413 pDecodePara, pvStructInfo, *pcbStructInfo); 03414 03415 __TRY 03416 { 03417 DWORD bytesNeeded; 03418 03419 if ((ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded, 03420 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL))) 03421 { 03422 if (!pvStructInfo) 03423 *pcbStructInfo = bytesNeeded; 03424 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 03425 pvStructInfo, pcbStructInfo, bytesNeeded))) 03426 { 03427 CERT_ALT_NAME_INFO *name; 03428 03429 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 03430 pvStructInfo = *(BYTE **)pvStructInfo; 03431 name = pvStructInfo; 03432 name->rgAltEntry = (PCERT_ALT_NAME_ENTRY) 03433 ((BYTE *)pvStructInfo + sizeof(CERT_ALT_NAME_INFO)); 03434 ret = CRYPT_AsnDecodeAltNameInternal(pbEncoded, cbEncoded, 03435 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 03436 &bytesNeeded, NULL); 03437 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 03438 CRYPT_FreeSpace(pDecodePara, name); 03439 } 03440 } 03441 } 03442 __EXCEPT_PAGE_FAULT 03443 { 03444 SetLastError(STATUS_ACCESS_VIOLATION); 03445 ret = FALSE; 03446 } 03447 __ENDTRY 03448 return ret; 03449 } 03450 03451 struct PATH_LEN_CONSTRAINT 03452 { 03453 BOOL fPathLenConstraint; 03454 DWORD dwPathLenConstraint; 03455 }; 03456 03457 static BOOL CRYPT_AsnDecodePathLenConstraint(const BYTE *pbEncoded, 03458 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03459 DWORD *pcbDecoded) 03460 { 03461 BOOL ret = TRUE; 03462 DWORD bytesNeeded = sizeof(struct PATH_LEN_CONSTRAINT), size; 03463 03464 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 03465 pvStructInfo, *pcbStructInfo, pcbDecoded); 03466 03467 if (!pvStructInfo) 03468 { 03469 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, NULL, 03470 &size, pcbDecoded); 03471 *pcbStructInfo = bytesNeeded; 03472 } 03473 else if (*pcbStructInfo < bytesNeeded) 03474 { 03475 SetLastError(ERROR_MORE_DATA); 03476 *pcbStructInfo = bytesNeeded; 03477 ret = FALSE; 03478 } 03479 else 03480 { 03481 struct PATH_LEN_CONSTRAINT *constraint = pvStructInfo; 03482 03483 *pcbStructInfo = bytesNeeded; 03484 size = sizeof(constraint->dwPathLenConstraint); 03485 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, 03486 &constraint->dwPathLenConstraint, &size, pcbDecoded); 03487 if (ret) 03488 constraint->fPathLenConstraint = TRUE; 03489 TRACE("got an int, dwPathLenConstraint is %d\n", 03490 constraint->dwPathLenConstraint); 03491 } 03492 TRACE("returning %d (%08x)\n", ret, GetLastError()); 03493 return ret; 03494 } 03495 03496 static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded, 03497 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03498 DWORD *pcbDecoded) 03499 { 03500 BOOL ret; 03501 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 03502 offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), 03503 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 03504 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), 03505 CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE, 03506 offsetof(CERT_NAME_BLOB, pbData) }; 03507 03508 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 03509 pvStructInfo, *pcbStructInfo, pcbDecoded); 03510 03511 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 03512 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 03513 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 03514 return ret; 03515 } 03516 03517 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType, 03518 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03519 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03520 { 03521 BOOL ret; 03522 03523 __TRY 03524 { 03525 struct AsnDecodeSequenceItem items[] = { 03526 { ASN_BITSTRING, offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType), 03527 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), FALSE, TRUE, 03528 offsetof(CERT_BASIC_CONSTRAINTS_INFO, SubjectType.pbData), 0 }, 03529 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS_INFO, 03530 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint, 03531 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 }, 03532 { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO, 03533 cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints, 03534 FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), 03535 TRUE, TRUE, 03536 offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 }, 03537 }; 03538 03539 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03540 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 03541 pcbStructInfo, NULL, NULL); 03542 } 03543 __EXCEPT_PAGE_FAULT 03544 { 03545 SetLastError(STATUS_ACCESS_VIOLATION); 03546 ret = FALSE; 03547 } 03548 __ENDTRY 03549 return ret; 03550 } 03551 03552 static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType, 03553 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03554 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03555 { 03556 BOOL ret; 03557 03558 __TRY 03559 { 03560 struct AsnDecodeSequenceItem items[] = { 03561 { ASN_BOOL, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, fCA), 03562 CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0, 0 }, 03563 { ASN_INTEGER, offsetof(CERT_BASIC_CONSTRAINTS2_INFO, 03564 fPathLenConstraint), CRYPT_AsnDecodePathLenConstraint, 03565 sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 }, 03566 }; 03567 03568 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03569 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 03570 pcbStructInfo, NULL, NULL); 03571 } 03572 __EXCEPT_PAGE_FAULT 03573 { 03574 SetLastError(STATUS_ACCESS_VIOLATION); 03575 ret = FALSE; 03576 } 03577 __ENDTRY 03578 return ret; 03579 } 03580 03581 static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded, 03582 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03583 DWORD *pcbDecoded) 03584 { 03585 struct AsnDecodeSequenceItem items[] = { 03586 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_QUALIFIER_INFO, 03587 pszPolicyQualifierId), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), 03588 FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId), 03589 0 }, 03590 { 0, offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier), 03591 CRYPT_AsnDecodeDerBlob, sizeof(CRYPT_OBJID_BLOB), TRUE, TRUE, 03592 offsetof(CERT_POLICY_QUALIFIER_INFO, Qualifier.pbData), 0 }, 03593 }; 03594 BOOL ret; 03595 CERT_POLICY_QUALIFIER_INFO *qualifier = pvStructInfo; 03596 03597 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03598 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03599 03600 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03601 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 03602 pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL); 03603 return ret; 03604 } 03605 03606 static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded, 03607 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03608 DWORD *pcbDecoded) 03609 { 03610 BOOL ret; 03611 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 03612 offsetof(CERT_POLICY_INFO, cPolicyQualifier), 03613 offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 03614 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), 03615 CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE, 03616 offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) }; 03617 03618 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03619 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03620 03621 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 03622 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 03623 TRACE("Returning %d (%08x)\n", ret, GetLastError()); 03624 return ret; 03625 } 03626 03627 static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded, 03628 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 03629 { 03630 struct AsnDecodeSequenceItem items[] = { 03631 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 03632 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE, 03633 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 }, 03634 { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier), 03635 CRYPT_AsnDecodePolicyQualifiers, 03636 FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE, 03637 TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 }, 03638 }; 03639 CERT_POLICY_INFO *info = pvStructInfo; 03640 BOOL ret; 03641 03642 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03643 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03644 03645 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03646 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 03647 pcbDecoded, info ? info->pszPolicyIdentifier : NULL); 03648 return ret; 03649 } 03650 03651 static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType, 03652 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03653 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03654 { 03655 BOOL ret = FALSE; 03656 03657 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03658 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03659 03660 __TRY 03661 { 03662 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 03663 offsetof(CERT_POLICIES_INFO, cPolicyInfo), 03664 offsetof(CERT_POLICIES_INFO, rgPolicyInfo), 03665 sizeof(CERT_POLICIES_INFO), 03666 CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE, 03667 offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) }; 03668 CERT_POLICIES_INFO *info = pvStructInfo; 03669 03670 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 03671 info->rgPolicyInfo = (CERT_POLICY_INFO *)(info + 1); 03672 03673 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 03674 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 03675 } 03676 __EXCEPT_PAGE_FAULT 03677 { 03678 SetLastError(STATUS_ACCESS_VIOLATION); 03679 } 03680 __ENDTRY 03681 return ret; 03682 } 03683 03684 static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded, 03685 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03686 DWORD *pcbDecoded) 03687 { 03688 struct AsnDecodeSequenceItem items[] = { 03689 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING, 03690 pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), 03691 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 }, 03692 { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING, 03693 pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), 03694 FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 }, 03695 }; 03696 CERT_POLICY_MAPPING *mapping = pvStructInfo; 03697 BOOL ret; 03698 03699 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03700 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03701 03702 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03703 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 03704 pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL); 03705 return ret; 03706 } 03707 03708 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType, 03709 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03710 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03711 { 03712 BOOL ret = FALSE; 03713 03714 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03715 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03716 03717 __TRY 03718 { 03719 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 03720 offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping), 03721 offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping), 03722 sizeof(CERT_POLICY_MAPPING), 03723 CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE, 03724 offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) }; 03725 CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo; 03726 03727 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 03728 info->rgPolicyMapping = (CERT_POLICY_MAPPING *)(info + 1); 03729 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 03730 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 03731 } 03732 __EXCEPT_PAGE_FAULT 03733 { 03734 SetLastError(STATUS_ACCESS_VIOLATION); 03735 } 03736 __ENDTRY 03737 return ret; 03738 } 03739 03740 static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded, 03741 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03742 DWORD *pcbDecoded) 03743 { 03744 BOOL ret; 03745 DWORD skip, size = sizeof(skip); 03746 03747 if (!cbEncoded) 03748 { 03749 SetLastError(CRYPT_E_ASN1_EOD); 03750 return FALSE; 03751 } 03752 if (pbEncoded[0] != (ASN_CONTEXT | 0)) 03753 { 03754 SetLastError(CRYPT_E_ASN1_BADTAG); 03755 return FALSE; 03756 } 03757 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, 03758 &skip, &size, pcbDecoded))) 03759 { 03760 DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, 03761 fRequireExplicitPolicy, fInhibitPolicyMapping); 03762 03763 if (!pvStructInfo) 03764 *pcbStructInfo = bytesNeeded; 03765 else if (*pcbStructInfo < bytesNeeded) 03766 { 03767 *pcbStructInfo = bytesNeeded; 03768 SetLastError(ERROR_MORE_DATA); 03769 ret = FALSE; 03770 } 03771 else 03772 { 03773 CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo, 03774 CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy); 03775 03776 *pcbStructInfo = bytesNeeded; 03777 /* The BOOL is implicit: if the integer is present, then it's 03778 * TRUE. 03779 */ 03780 info->fRequireExplicitPolicy = TRUE; 03781 info->dwRequireExplicitPolicySkipCerts = skip; 03782 } 03783 } 03784 return ret; 03785 } 03786 03787 static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded, 03788 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03789 DWORD *pcbDecoded) 03790 { 03791 BOOL ret; 03792 DWORD skip, size = sizeof(skip); 03793 03794 if (!cbEncoded) 03795 { 03796 SetLastError(CRYPT_E_ASN1_EOD); 03797 return FALSE; 03798 } 03799 if (pbEncoded[0] != (ASN_CONTEXT | 1)) 03800 { 03801 SetLastError(CRYPT_E_ASN1_BADTAG); 03802 return FALSE; 03803 } 03804 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, 03805 &skip, &size, pcbDecoded))) 03806 { 03807 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, 03808 fInhibitPolicyMapping); 03809 03810 if (!pvStructInfo) 03811 *pcbStructInfo = bytesNeeded; 03812 else if (*pcbStructInfo < bytesNeeded) 03813 { 03814 *pcbStructInfo = bytesNeeded; 03815 SetLastError(ERROR_MORE_DATA); 03816 ret = FALSE; 03817 } 03818 else 03819 { 03820 CERT_POLICY_CONSTRAINTS_INFO *info = CONTAINING_RECORD(pvStructInfo, 03821 CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping); 03822 03823 *pcbStructInfo = bytesNeeded; 03824 /* The BOOL is implicit: if the integer is present, then it's 03825 * TRUE. 03826 */ 03827 info->fInhibitPolicyMapping = TRUE; 03828 info->dwInhibitPolicyMappingSkipCerts = skip; 03829 } 03830 } 03831 return ret; 03832 } 03833 03834 static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints( 03835 DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, 03836 DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, 03837 void *pvStructInfo, DWORD *pcbStructInfo) 03838 { 03839 BOOL ret = FALSE; 03840 03841 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 03842 pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); 03843 03844 __TRY 03845 { 03846 struct AsnDecodeSequenceItem items[] = { 03847 { ASN_CONTEXT | 0, 03848 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy), 03849 CRYPT_AsnDecodeRequireExplicit, 03850 MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy, 03851 fInhibitPolicyMapping), TRUE, FALSE, 0, 0 }, 03852 { ASN_CONTEXT | 1, 03853 offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping), 03854 CRYPT_AsnDecodeInhibitMapping, 03855 FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping), 03856 TRUE, FALSE, 0, 0 }, 03857 }; 03858 03859 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03860 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 03861 pcbStructInfo, NULL, NULL); 03862 } 03863 __EXCEPT_PAGE_FAULT 03864 { 03865 SetLastError(STATUS_ACCESS_VIOLATION); 03866 } 03867 __ENDTRY 03868 return ret; 03869 } 03870 03871 #define RSA1_MAGIC 0x31415352 03872 03873 struct DECODED_RSA_PUB_KEY 03874 { 03875 DWORD pubexp; 03876 CRYPT_INTEGER_BLOB modulus; 03877 }; 03878 03879 static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType, 03880 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03881 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03882 { 03883 BOOL ret; 03884 03885 __TRY 03886 { 03887 struct AsnDecodeSequenceItem items[] = { 03888 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, modulus), 03889 CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), 03890 FALSE, TRUE, offsetof(struct DECODED_RSA_PUB_KEY, modulus.pbData), 03891 0 }, 03892 { ASN_INTEGER, offsetof(struct DECODED_RSA_PUB_KEY, pubexp), 03893 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 03894 }; 03895 struct DECODED_RSA_PUB_KEY *decodedKey = NULL; 03896 DWORD size = 0; 03897 03898 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 03899 pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey, 03900 &size, NULL, NULL); 03901 if (ret) 03902 { 03903 DWORD bytesNeeded = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + 03904 decodedKey->modulus.cbData; 03905 03906 if (!pvStructInfo) 03907 { 03908 *pcbStructInfo = bytesNeeded; 03909 ret = TRUE; 03910 } 03911 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 03912 pvStructInfo, pcbStructInfo, bytesNeeded))) 03913 { 03914 BLOBHEADER *hdr; 03915 RSAPUBKEY *rsaPubKey; 03916 03917 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 03918 pvStructInfo = *(BYTE **)pvStructInfo; 03919 hdr = pvStructInfo; 03920 hdr->bType = PUBLICKEYBLOB; 03921 hdr->bVersion = CUR_BLOB_VERSION; 03922 hdr->reserved = 0; 03923 hdr->aiKeyAlg = CALG_RSA_KEYX; 03924 rsaPubKey = (RSAPUBKEY *)((BYTE *)pvStructInfo + 03925 sizeof(BLOBHEADER)); 03926 rsaPubKey->magic = RSA1_MAGIC; 03927 rsaPubKey->pubexp = decodedKey->pubexp; 03928 rsaPubKey->bitlen = decodedKey->modulus.cbData * 8; 03929 memcpy((BYTE *)pvStructInfo + sizeof(BLOBHEADER) + 03930 sizeof(RSAPUBKEY), decodedKey->modulus.pbData, 03931 decodedKey->modulus.cbData); 03932 } 03933 LocalFree(decodedKey); 03934 } 03935 } 03936 __EXCEPT_PAGE_FAULT 03937 { 03938 SetLastError(STATUS_ACCESS_VIOLATION); 03939 ret = FALSE; 03940 } 03941 __ENDTRY 03942 return ret; 03943 } 03944 03945 static BOOL CRYPT_AsnDecodeOctetsInternal(const BYTE *pbEncoded, 03946 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 03947 DWORD *pcbDecoded) 03948 { 03949 BOOL ret; 03950 DWORD bytesNeeded, dataLen; 03951 03952 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 03953 pvStructInfo, *pcbStructInfo, pcbDecoded); 03954 03955 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 03956 { 03957 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 03958 03959 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 03960 bytesNeeded = sizeof(CRYPT_DATA_BLOB); 03961 else 03962 bytesNeeded = dataLen + sizeof(CRYPT_DATA_BLOB); 03963 if (pcbDecoded) 03964 *pcbDecoded = 1 + lenBytes + dataLen; 03965 if (!pvStructInfo) 03966 *pcbStructInfo = bytesNeeded; 03967 else if (*pcbStructInfo < bytesNeeded) 03968 { 03969 SetLastError(ERROR_MORE_DATA); 03970 *pcbStructInfo = bytesNeeded; 03971 ret = FALSE; 03972 } 03973 else 03974 { 03975 CRYPT_DATA_BLOB *blob; 03976 03977 *pcbStructInfo = bytesNeeded; 03978 blob = pvStructInfo; 03979 blob->cbData = dataLen; 03980 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 03981 blob->pbData = (BYTE *)pbEncoded + 1 + lenBytes; 03982 else 03983 { 03984 assert(blob->pbData); 03985 if (blob->cbData) 03986 memcpy(blob->pbData, pbEncoded + 1 + lenBytes, 03987 blob->cbData); 03988 } 03989 } 03990 } 03991 return ret; 03992 } 03993 03994 static BOOL WINAPI CRYPT_AsnDecodeOctets(DWORD dwCertEncodingType, 03995 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 03996 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 03997 { 03998 BOOL ret; 03999 04000 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 04001 pDecodePara, pvStructInfo, *pcbStructInfo); 04002 04003 __TRY 04004 { 04005 DWORD bytesNeeded; 04006 04007 if (!cbEncoded) 04008 { 04009 SetLastError(CRYPT_E_ASN1_CORRUPT); 04010 ret = FALSE; 04011 } 04012 else if (pbEncoded[0] != ASN_OCTETSTRING) 04013 { 04014 SetLastError(CRYPT_E_ASN1_BADTAG); 04015 ret = FALSE; 04016 } 04017 else if ((ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, 04018 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL))) 04019 { 04020 if (!pvStructInfo) 04021 *pcbStructInfo = bytesNeeded; 04022 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04023 pvStructInfo, pcbStructInfo, bytesNeeded))) 04024 { 04025 CRYPT_DATA_BLOB *blob; 04026 04027 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04028 pvStructInfo = *(BYTE **)pvStructInfo; 04029 blob = pvStructInfo; 04030 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_DATA_BLOB); 04031 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, 04032 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 04033 &bytesNeeded, NULL); 04034 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04035 CRYPT_FreeSpace(pDecodePara, blob); 04036 } 04037 } 04038 } 04039 __EXCEPT_PAGE_FAULT 04040 { 04041 SetLastError(STATUS_ACCESS_VIOLATION); 04042 ret = FALSE; 04043 } 04044 __ENDTRY 04045 return ret; 04046 } 04047 04048 static BOOL CRYPT_AsnDecodeBitsInternal(const BYTE *pbEncoded, DWORD cbEncoded, 04049 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 04050 { 04051 BOOL ret; 04052 DWORD bytesNeeded, dataLen; 04053 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 04054 04055 TRACE("(%p, %d, 0x%08x, %p, %d, %p)\n", pbEncoded, cbEncoded, dwFlags, 04056 pvStructInfo, *pcbStructInfo, pcbDecoded); 04057 04058 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 04059 { 04060 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 04061 bytesNeeded = sizeof(CRYPT_BIT_BLOB); 04062 else 04063 bytesNeeded = dataLen - 1 + sizeof(CRYPT_BIT_BLOB); 04064 if (pcbDecoded) 04065 *pcbDecoded = 1 + lenBytes + dataLen; 04066 if (!pvStructInfo) 04067 *pcbStructInfo = bytesNeeded; 04068 else if (*pcbStructInfo < bytesNeeded) 04069 { 04070 *pcbStructInfo = bytesNeeded; 04071 SetLastError(ERROR_MORE_DATA); 04072 ret = FALSE; 04073 } 04074 else 04075 { 04076 CRYPT_BIT_BLOB *blob; 04077 04078 *pcbStructInfo = bytesNeeded; 04079 blob = pvStructInfo; 04080 blob->cbData = dataLen - 1; 04081 blob->cUnusedBits = *(pbEncoded + 1 + lenBytes); 04082 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 04083 { 04084 blob->pbData = (BYTE *)pbEncoded + 2 + lenBytes; 04085 } 04086 else 04087 { 04088 assert(blob->pbData); 04089 if (blob->cbData) 04090 { 04091 BYTE mask = 0xff << blob->cUnusedBits; 04092 04093 memcpy(blob->pbData, pbEncoded + 2 + lenBytes, 04094 blob->cbData); 04095 blob->pbData[blob->cbData - 1] &= mask; 04096 } 04097 } 04098 } 04099 } 04100 return ret; 04101 } 04102 04103 static BOOL WINAPI CRYPT_AsnDecodeBits(DWORD dwCertEncodingType, 04104 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04105 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04106 { 04107 BOOL ret; 04108 04109 TRACE("(%p, %d, 0x%08x, %p, %p, %p)\n", pbEncoded, cbEncoded, dwFlags, 04110 pDecodePara, pvStructInfo, pcbStructInfo); 04111 04112 __TRY 04113 { 04114 DWORD bytesNeeded; 04115 04116 if (!cbEncoded) 04117 { 04118 SetLastError(CRYPT_E_ASN1_CORRUPT); 04119 ret = FALSE; 04120 } 04121 else if (pbEncoded[0] != ASN_BITSTRING) 04122 { 04123 SetLastError(CRYPT_E_ASN1_BADTAG); 04124 ret = FALSE; 04125 } 04126 else if ((ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded, 04127 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL))) 04128 { 04129 if (!pvStructInfo) 04130 *pcbStructInfo = bytesNeeded; 04131 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04132 pvStructInfo, pcbStructInfo, bytesNeeded))) 04133 { 04134 CRYPT_BIT_BLOB *blob; 04135 04136 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04137 pvStructInfo = *(BYTE **)pvStructInfo; 04138 blob = pvStructInfo; 04139 blob->pbData = (BYTE *)pvStructInfo + sizeof(CRYPT_BIT_BLOB); 04140 ret = CRYPT_AsnDecodeBitsInternal(pbEncoded, cbEncoded, 04141 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 04142 &bytesNeeded, NULL); 04143 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04144 CRYPT_FreeSpace(pDecodePara, blob); 04145 } 04146 } 04147 } 04148 __EXCEPT_PAGE_FAULT 04149 { 04150 SetLastError(STATUS_ACCESS_VIOLATION); 04151 ret = FALSE; 04152 } 04153 __ENDTRY 04154 TRACE("returning %d (%08x)\n", ret, GetLastError()); 04155 return ret; 04156 } 04157 04158 /* Ignores tag. Only allows integers 4 bytes or smaller in size. */ 04159 static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded, 04160 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 04161 { 04162 BOOL ret; 04163 DWORD dataLen; 04164 04165 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 04166 { 04167 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 04168 04169 if (pcbDecoded) 04170 *pcbDecoded = 1 + lenBytes + dataLen; 04171 if (dataLen > sizeof(int)) 04172 { 04173 SetLastError(CRYPT_E_ASN1_LARGE); 04174 ret = FALSE; 04175 } 04176 else if (!pvStructInfo) 04177 *pcbStructInfo = sizeof(int); 04178 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int)))) 04179 { 04180 int val, i; 04181 04182 if (dataLen && pbEncoded[1 + lenBytes] & 0x80) 04183 { 04184 /* initialize to a negative value to sign-extend */ 04185 val = -1; 04186 } 04187 else 04188 val = 0; 04189 for (i = 0; i < dataLen; i++) 04190 { 04191 val <<= 8; 04192 val |= pbEncoded[1 + lenBytes + i]; 04193 } 04194 memcpy(pvStructInfo, &val, sizeof(int)); 04195 } 04196 } 04197 return ret; 04198 } 04199 04200 static BOOL WINAPI CRYPT_AsnDecodeInt(DWORD dwCertEncodingType, 04201 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04202 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04203 { 04204 BOOL ret; 04205 04206 __TRY 04207 { 04208 DWORD bytesNeeded; 04209 04210 if (!cbEncoded) 04211 { 04212 SetLastError(CRYPT_E_ASN1_EOD); 04213 ret = FALSE; 04214 } 04215 else if (pbEncoded[0] != ASN_INTEGER) 04216 { 04217 SetLastError(CRYPT_E_ASN1_BADTAG); 04218 ret = FALSE; 04219 } 04220 else 04221 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, 04222 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); 04223 if (ret) 04224 { 04225 if (!pvStructInfo) 04226 *pcbStructInfo = bytesNeeded; 04227 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04228 pvStructInfo, pcbStructInfo, bytesNeeded))) 04229 { 04230 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04231 pvStructInfo = *(BYTE **)pvStructInfo; 04232 ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, 04233 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 04234 &bytesNeeded, NULL); 04235 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04236 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 04237 } 04238 } 04239 } 04240 __EXCEPT_PAGE_FAULT 04241 { 04242 SetLastError(STATUS_ACCESS_VIOLATION); 04243 ret = FALSE; 04244 } 04245 __ENDTRY 04246 return ret; 04247 } 04248 04249 static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded, 04250 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 04251 DWORD *pcbDecoded) 04252 { 04253 BOOL ret; 04254 DWORD bytesNeeded, dataLen; 04255 04256 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 04257 { 04258 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 04259 04260 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB); 04261 if (pcbDecoded) 04262 *pcbDecoded = 1 + lenBytes + dataLen; 04263 if (!pvStructInfo) 04264 *pcbStructInfo = bytesNeeded; 04265 else if (*pcbStructInfo < bytesNeeded) 04266 { 04267 *pcbStructInfo = bytesNeeded; 04268 SetLastError(ERROR_MORE_DATA); 04269 ret = FALSE; 04270 } 04271 else 04272 { 04273 CRYPT_INTEGER_BLOB *blob = pvStructInfo; 04274 04275 *pcbStructInfo = bytesNeeded; 04276 blob->cbData = dataLen; 04277 assert(blob->pbData); 04278 if (blob->cbData) 04279 { 04280 DWORD i; 04281 04282 for (i = 0; i < blob->cbData; i++) 04283 { 04284 blob->pbData[i] = *(pbEncoded + 1 + lenBytes + 04285 dataLen - i - 1); 04286 } 04287 } 04288 } 04289 } 04290 return ret; 04291 } 04292 04293 static BOOL WINAPI CRYPT_AsnDecodeInteger(DWORD dwCertEncodingType, 04294 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04295 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04296 { 04297 BOOL ret; 04298 04299 __TRY 04300 { 04301 DWORD bytesNeeded; 04302 04303 if (pbEncoded[0] != ASN_INTEGER) 04304 { 04305 SetLastError(CRYPT_E_ASN1_BADTAG); 04306 ret = FALSE; 04307 } 04308 else 04309 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 04310 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); 04311 if (ret) 04312 { 04313 if (!pvStructInfo) 04314 *pcbStructInfo = bytesNeeded; 04315 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04316 pvStructInfo, pcbStructInfo, bytesNeeded))) 04317 { 04318 CRYPT_INTEGER_BLOB *blob; 04319 04320 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04321 pvStructInfo = *(BYTE **)pvStructInfo; 04322 blob = pvStructInfo; 04323 blob->pbData = (BYTE *)pvStructInfo + 04324 sizeof(CRYPT_INTEGER_BLOB); 04325 ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 04326 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo, 04327 &bytesNeeded, NULL); 04328 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04329 CRYPT_FreeSpace(pDecodePara, blob); 04330 } 04331 } 04332 } 04333 __EXCEPT_PAGE_FAULT 04334 { 04335 SetLastError(STATUS_ACCESS_VIOLATION); 04336 ret = FALSE; 04337 } 04338 __ENDTRY 04339 return ret; 04340 } 04341 04342 static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded, 04343 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 04344 DWORD *pcbDecoded) 04345 { 04346 BOOL ret; 04347 04348 if (pbEncoded[0] == ASN_INTEGER) 04349 { 04350 DWORD bytesNeeded, dataLen; 04351 04352 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 04353 { 04354 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 04355 04356 if (pcbDecoded) 04357 *pcbDecoded = 1 + lenBytes + dataLen; 04358 bytesNeeded = dataLen + sizeof(CRYPT_INTEGER_BLOB); 04359 if (!pvStructInfo) 04360 *pcbStructInfo = bytesNeeded; 04361 else if (*pcbStructInfo < bytesNeeded) 04362 { 04363 *pcbStructInfo = bytesNeeded; 04364 SetLastError(ERROR_MORE_DATA); 04365 ret = FALSE; 04366 } 04367 else 04368 { 04369 CRYPT_INTEGER_BLOB *blob = pvStructInfo; 04370 04371 *pcbStructInfo = bytesNeeded; 04372 blob->cbData = dataLen; 04373 assert(blob->pbData); 04374 /* remove leading zero byte if it exists */ 04375 if (blob->cbData && *(pbEncoded + 1 + lenBytes) == 0) 04376 { 04377 blob->cbData--; 04378 blob->pbData++; 04379 } 04380 if (blob->cbData) 04381 { 04382 DWORD i; 04383 04384 for (i = 0; i < blob->cbData; i++) 04385 { 04386 blob->pbData[i] = *(pbEncoded + 1 + lenBytes + 04387 dataLen - i - 1); 04388 } 04389 } 04390 } 04391 } 04392 } 04393 else 04394 { 04395 SetLastError(CRYPT_E_ASN1_BADTAG); 04396 ret = FALSE; 04397 } 04398 return ret; 04399 } 04400 04401 static BOOL WINAPI CRYPT_AsnDecodeUnsignedInteger(DWORD dwCertEncodingType, 04402 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04403 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04404 { 04405 BOOL ret; 04406 04407 __TRY 04408 { 04409 DWORD bytesNeeded; 04410 04411 if ((ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, cbEncoded, 04412 dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL))) 04413 { 04414 if (!pvStructInfo) 04415 *pcbStructInfo = bytesNeeded; 04416 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04417 pvStructInfo, pcbStructInfo, bytesNeeded))) 04418 { 04419 CRYPT_INTEGER_BLOB *blob; 04420 04421 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04422 pvStructInfo = *(BYTE **)pvStructInfo; 04423 blob = pvStructInfo; 04424 blob->pbData = (BYTE *)pvStructInfo + 04425 sizeof(CRYPT_INTEGER_BLOB); 04426 ret = CRYPT_AsnDecodeUnsignedIntegerInternal(pbEncoded, 04427 cbEncoded, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pvStructInfo, 04428 &bytesNeeded, NULL); 04429 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04430 CRYPT_FreeSpace(pDecodePara, blob); 04431 } 04432 } 04433 } 04434 __EXCEPT_PAGE_FAULT 04435 { 04436 SetLastError(STATUS_ACCESS_VIOLATION); 04437 ret = FALSE; 04438 } 04439 __ENDTRY 04440 return ret; 04441 } 04442 04443 static BOOL WINAPI CRYPT_AsnDecodeEnumerated(DWORD dwCertEncodingType, 04444 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04445 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04446 { 04447 BOOL ret; 04448 04449 if (!pvStructInfo) 04450 { 04451 *pcbStructInfo = sizeof(int); 04452 return TRUE; 04453 } 04454 __TRY 04455 { 04456 if (pbEncoded[0] == ASN_ENUMERATED) 04457 { 04458 unsigned int val = 0, i; 04459 04460 if (cbEncoded <= 1) 04461 { 04462 SetLastError(CRYPT_E_ASN1_EOD); 04463 ret = FALSE; 04464 } 04465 else if (pbEncoded[1] == 0) 04466 { 04467 SetLastError(CRYPT_E_ASN1_CORRUPT); 04468 ret = FALSE; 04469 } 04470 else 04471 { 04472 /* A little strange looking, but we have to accept a sign byte: 04473 * 0xffffffff gets encoded as 0a 05 00 ff ff ff ff. Also, 04474 * assuming a small length is okay here, it has to be in short 04475 * form. 04476 */ 04477 if (pbEncoded[1] > sizeof(unsigned int) + 1) 04478 { 04479 SetLastError(CRYPT_E_ASN1_LARGE); 04480 return FALSE; 04481 } 04482 for (i = 0; i < pbEncoded[1]; i++) 04483 { 04484 val <<= 8; 04485 val |= pbEncoded[2 + i]; 04486 } 04487 if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04488 pvStructInfo, pcbStructInfo, sizeof(unsigned int)))) 04489 { 04490 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04491 pvStructInfo = *(BYTE **)pvStructInfo; 04492 memcpy(pvStructInfo, &val, sizeof(unsigned int)); 04493 } 04494 } 04495 } 04496 else 04497 { 04498 SetLastError(CRYPT_E_ASN1_BADTAG); 04499 ret = FALSE; 04500 } 04501 } 04502 __EXCEPT_PAGE_FAULT 04503 { 04504 SetLastError(STATUS_ACCESS_VIOLATION); 04505 ret = FALSE; 04506 } 04507 __ENDTRY 04508 return ret; 04509 } 04510 04511 /* Modifies word, pbEncoded, and len, and magically sets a value ret to FALSE 04512 * if it fails. 04513 */ 04514 #define CRYPT_TIME_GET_DIGITS(pbEncoded, len, numDigits, word) \ 04515 do { \ 04516 BYTE i; \ 04517 \ 04518 (word) = 0; \ 04519 for (i = 0; (len) > 0 && i < (numDigits); i++, (len)--) \ 04520 { \ 04521 if (!isdigit(*(pbEncoded))) \ 04522 { \ 04523 SetLastError(CRYPT_E_ASN1_CORRUPT); \ 04524 ret = FALSE; \ 04525 } \ 04526 else \ 04527 { \ 04528 (word) *= 10; \ 04529 (word) += *(pbEncoded)++ - '0'; \ 04530 } \ 04531 } \ 04532 } while (0) 04533 04534 static BOOL CRYPT_AsnDecodeTimeZone(const BYTE *pbEncoded, DWORD len, 04535 SYSTEMTIME *sysTime) 04536 { 04537 BOOL ret = TRUE; 04538 04539 if (len >= 3 && (*pbEncoded == '+' || *pbEncoded == '-')) 04540 { 04541 WORD hours, minutes = 0; 04542 BYTE sign = *pbEncoded++; 04543 04544 len--; 04545 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, hours); 04546 if (ret && hours >= 24) 04547 { 04548 SetLastError(CRYPT_E_ASN1_CORRUPT); 04549 ret = FALSE; 04550 } 04551 else if (len >= 2) 04552 { 04553 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, minutes); 04554 if (ret && minutes >= 60) 04555 { 04556 SetLastError(CRYPT_E_ASN1_CORRUPT); 04557 ret = FALSE; 04558 } 04559 } 04560 if (ret) 04561 { 04562 if (sign == '+') 04563 { 04564 sysTime->wHour += hours; 04565 sysTime->wMinute += minutes; 04566 } 04567 else 04568 { 04569 if (hours > sysTime->wHour) 04570 { 04571 sysTime->wDay--; 04572 sysTime->wHour = 24 - (hours - sysTime->wHour); 04573 } 04574 else 04575 sysTime->wHour -= hours; 04576 if (minutes > sysTime->wMinute) 04577 { 04578 sysTime->wHour--; 04579 sysTime->wMinute = 60 - (minutes - sysTime->wMinute); 04580 } 04581 else 04582 sysTime->wMinute -= minutes; 04583 } 04584 } 04585 } 04586 return ret; 04587 } 04588 04589 #define MIN_ENCODED_TIME_LENGTH 10 04590 04591 static BOOL CRYPT_AsnDecodeUtcTimeInternal(const BYTE *pbEncoded, 04592 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 04593 DWORD *pcbDecoded) 04594 { 04595 BOOL ret = FALSE; 04596 04597 if (pbEncoded[0] == ASN_UTCTIME) 04598 { 04599 if (cbEncoded <= 1) 04600 SetLastError(CRYPT_E_ASN1_EOD); 04601 else if (pbEncoded[1] > 0x7f) 04602 { 04603 /* long-form date strings really can't be valid */ 04604 SetLastError(CRYPT_E_ASN1_CORRUPT); 04605 } 04606 else 04607 { 04608 SYSTEMTIME sysTime = { 0 }; 04609 BYTE len = pbEncoded[1]; 04610 04611 if (len < MIN_ENCODED_TIME_LENGTH) 04612 SetLastError(CRYPT_E_ASN1_CORRUPT); 04613 else 04614 { 04615 ret = TRUE; 04616 if (pcbDecoded) 04617 *pcbDecoded = 2 + len; 04618 pbEncoded += 2; 04619 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wYear); 04620 if (sysTime.wYear >= 50) 04621 sysTime.wYear += 1900; 04622 else 04623 sysTime.wYear += 2000; 04624 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth); 04625 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay); 04626 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour); 04627 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMinute); 04628 if (ret && len > 0) 04629 { 04630 if (len >= 2 && isdigit(*pbEncoded) && 04631 isdigit(*(pbEncoded + 1))) 04632 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, 04633 sysTime.wSecond); 04634 else if (isdigit(*pbEncoded)) 04635 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 1, 04636 sysTime.wSecond); 04637 if (ret) 04638 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len, 04639 &sysTime); 04640 } 04641 if (ret) 04642 { 04643 if (!pvStructInfo) 04644 *pcbStructInfo = sizeof(FILETIME); 04645 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, 04646 sizeof(FILETIME)))) 04647 ret = SystemTimeToFileTime(&sysTime, pvStructInfo); 04648 } 04649 } 04650 } 04651 } 04652 else 04653 SetLastError(CRYPT_E_ASN1_BADTAG); 04654 return ret; 04655 } 04656 04657 static BOOL WINAPI CRYPT_AsnDecodeUtcTime(DWORD dwCertEncodingType, 04658 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04659 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04660 { 04661 BOOL ret = FALSE; 04662 04663 __TRY 04664 { 04665 DWORD bytesNeeded; 04666 04667 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded, 04668 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); 04669 if (ret) 04670 { 04671 if (!pvStructInfo) 04672 *pcbStructInfo = bytesNeeded; 04673 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, 04674 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) 04675 { 04676 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04677 pvStructInfo = *(BYTE **)pvStructInfo; 04678 ret = CRYPT_AsnDecodeUtcTimeInternal(pbEncoded, cbEncoded, 04679 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 04680 &bytesNeeded, NULL); 04681 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04682 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 04683 } 04684 } 04685 } 04686 __EXCEPT_PAGE_FAULT 04687 { 04688 SetLastError(STATUS_ACCESS_VIOLATION); 04689 } 04690 __ENDTRY 04691 return ret; 04692 } 04693 04694 static BOOL CRYPT_AsnDecodeGeneralizedTime(const BYTE *pbEncoded, 04695 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 04696 DWORD *pcbDecoded) 04697 { 04698 BOOL ret = FALSE; 04699 04700 if (pbEncoded[0] == ASN_GENERALTIME) 04701 { 04702 if (cbEncoded <= 1) 04703 SetLastError(CRYPT_E_ASN1_EOD); 04704 else if (pbEncoded[1] > 0x7f) 04705 { 04706 /* long-form date strings really can't be valid */ 04707 SetLastError(CRYPT_E_ASN1_CORRUPT); 04708 } 04709 else 04710 { 04711 BYTE len = pbEncoded[1]; 04712 04713 if (len < MIN_ENCODED_TIME_LENGTH) 04714 SetLastError(CRYPT_E_ASN1_CORRUPT); 04715 else 04716 { 04717 SYSTEMTIME sysTime = { 0 }; 04718 04719 ret = TRUE; 04720 if (pcbDecoded) 04721 *pcbDecoded = 2 + len; 04722 pbEncoded += 2; 04723 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 4, sysTime.wYear); 04724 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wMonth); 04725 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wDay); 04726 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, sysTime.wHour); 04727 if (ret && len > 0) 04728 { 04729 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, 04730 sysTime.wMinute); 04731 if (ret && len > 0) 04732 CRYPT_TIME_GET_DIGITS(pbEncoded, len, 2, 04733 sysTime.wSecond); 04734 if (ret && len > 0 && (*pbEncoded == '.' || 04735 *pbEncoded == ',')) 04736 { 04737 BYTE digits; 04738 04739 pbEncoded++; 04740 len--; 04741 /* workaround macro weirdness */ 04742 digits = min(len, 3); 04743 CRYPT_TIME_GET_DIGITS(pbEncoded, len, digits, 04744 sysTime.wMilliseconds); 04745 } 04746 if (ret) 04747 ret = CRYPT_AsnDecodeTimeZone(pbEncoded, len, 04748 &sysTime); 04749 } 04750 if (ret) 04751 { 04752 if (!pvStructInfo) 04753 *pcbStructInfo = sizeof(FILETIME); 04754 else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, 04755 sizeof(FILETIME)))) 04756 ret = SystemTimeToFileTime(&sysTime, pvStructInfo); 04757 } 04758 } 04759 } 04760 } 04761 else 04762 SetLastError(CRYPT_E_ASN1_BADTAG); 04763 return ret; 04764 } 04765 04766 static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded, 04767 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 04768 DWORD *pcbDecoded) 04769 { 04770 BOOL ret; 04771 InternalDecodeFunc decode = NULL; 04772 04773 if (pbEncoded[0] == ASN_UTCTIME) 04774 decode = CRYPT_AsnDecodeUtcTimeInternal; 04775 else if (pbEncoded[0] == ASN_GENERALTIME) 04776 decode = CRYPT_AsnDecodeGeneralizedTime; 04777 if (decode) 04778 ret = decode(pbEncoded, cbEncoded, dwFlags, pvStructInfo, 04779 pcbStructInfo, pcbDecoded); 04780 else 04781 { 04782 SetLastError(CRYPT_E_ASN1_BADTAG); 04783 ret = FALSE; 04784 } 04785 return ret; 04786 } 04787 04788 static BOOL WINAPI CRYPT_AsnDecodeChoiceOfTime(DWORD dwCertEncodingType, 04789 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04790 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04791 { 04792 BOOL ret; 04793 04794 __TRY 04795 { 04796 DWORD bytesNeeded; 04797 04798 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded, 04799 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, NULL); 04800 if (ret) 04801 { 04802 if (!pvStructInfo) 04803 *pcbStructInfo = bytesNeeded; 04804 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04805 pvStructInfo, pcbStructInfo, bytesNeeded))) 04806 { 04807 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04808 pvStructInfo = *(BYTE **)pvStructInfo; 04809 ret = CRYPT_AsnDecodeChoiceOfTimeInternal(pbEncoded, cbEncoded, 04810 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 04811 &bytesNeeded, NULL); 04812 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04813 CRYPT_FreeSpace(pDecodePara, pvStructInfo); 04814 } 04815 } 04816 } 04817 __EXCEPT_PAGE_FAULT 04818 { 04819 SetLastError(STATUS_ACCESS_VIOLATION); 04820 ret = FALSE; 04821 } 04822 __ENDTRY 04823 return ret; 04824 } 04825 04826 static BOOL WINAPI CRYPT_AsnDecodeSequenceOfAny(DWORD dwCertEncodingType, 04827 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 04828 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 04829 { 04830 BOOL ret = TRUE; 04831 04832 __TRY 04833 { 04834 if (pbEncoded[0] == ASN_SEQUENCEOF) 04835 { 04836 DWORD bytesNeeded, dataLen, remainingLen, cValue; 04837 04838 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 04839 { 04840 BYTE lenBytes; 04841 const BYTE *ptr; 04842 04843 lenBytes = GET_LEN_BYTES(pbEncoded[1]); 04844 bytesNeeded = sizeof(CRYPT_SEQUENCE_OF_ANY); 04845 cValue = 0; 04846 ptr = pbEncoded + 1 + lenBytes; 04847 remainingLen = dataLen; 04848 while (ret && remainingLen) 04849 { 04850 DWORD nextLen; 04851 04852 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen); 04853 if (ret) 04854 { 04855 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]); 04856 04857 remainingLen -= 1 + nextLenBytes + nextLen; 04858 ptr += 1 + nextLenBytes + nextLen; 04859 bytesNeeded += sizeof(CRYPT_DER_BLOB); 04860 if (!(dwFlags & CRYPT_DECODE_NOCOPY_FLAG)) 04861 bytesNeeded += 1 + nextLenBytes + nextLen; 04862 cValue++; 04863 } 04864 } 04865 if (ret) 04866 { 04867 CRYPT_SEQUENCE_OF_ANY *seq; 04868 BYTE *nextPtr; 04869 DWORD i; 04870 04871 if (!pvStructInfo) 04872 *pcbStructInfo = bytesNeeded; 04873 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 04874 pvStructInfo, pcbStructInfo, bytesNeeded))) 04875 { 04876 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 04877 pvStructInfo = *(BYTE **)pvStructInfo; 04878 seq = pvStructInfo; 04879 seq->cValue = cValue; 04880 seq->rgValue = (CRYPT_DER_BLOB *)((BYTE *)seq + 04881 sizeof(*seq)); 04882 nextPtr = (BYTE *)seq->rgValue + 04883 cValue * sizeof(CRYPT_DER_BLOB); 04884 ptr = pbEncoded + 1 + lenBytes; 04885 remainingLen = dataLen; 04886 i = 0; 04887 while (ret && remainingLen) 04888 { 04889 DWORD nextLen; 04890 04891 ret = CRYPT_GetLen(ptr, remainingLen, &nextLen); 04892 if (ret) 04893 { 04894 DWORD nextLenBytes = GET_LEN_BYTES(ptr[1]); 04895 04896 seq->rgValue[i].cbData = 1 + nextLenBytes + 04897 nextLen; 04898 if (dwFlags & CRYPT_DECODE_NOCOPY_FLAG) 04899 seq->rgValue[i].pbData = (BYTE *)ptr; 04900 else 04901 { 04902 seq->rgValue[i].pbData = nextPtr; 04903 memcpy(nextPtr, ptr, 1 + nextLenBytes + 04904 nextLen); 04905 nextPtr += 1 + nextLenBytes + nextLen; 04906 } 04907 remainingLen -= 1 + nextLenBytes + nextLen; 04908 ptr += 1 + nextLenBytes + nextLen; 04909 i++; 04910 } 04911 } 04912 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 04913 CRYPT_FreeSpace(pDecodePara, seq); 04914 } 04915 } 04916 } 04917 } 04918 else 04919 { 04920 SetLastError(CRYPT_E_ASN1_BADTAG); 04921 ret = FALSE; 04922 } 04923 } 04924 __EXCEPT_PAGE_FAULT 04925 { 04926 SetLastError(STATUS_ACCESS_VIOLATION); 04927 ret = FALSE; 04928 } 04929 __ENDTRY 04930 return ret; 04931 } 04932 04933 static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, 04934 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 04935 DWORD *pcbDecoded) 04936 { 04937 BOOL ret; 04938 04939 if (pbEncoded[0] == (ASN_CONTEXT | ASN_CONSTRUCTOR | 0)) 04940 { 04941 DWORD bytesNeeded, dataLen; 04942 04943 if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) 04944 { 04945 struct AsnArrayDescriptor arrayDesc = { 04946 ASN_CONTEXT | ASN_CONSTRUCTOR | 0, 04947 offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry), 04948 offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry), 04949 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u), 04950 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, 04951 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; 04952 BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); 04953 DWORD nameLen; 04954 04955 if (dataLen) 04956 { 04957 ret = CRYPT_AsnDecodeArray(&arrayDesc, 04958 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, 04959 dwFlags, NULL, NULL, &nameLen, NULL); 04960 bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen - 04961 FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u); 04962 } 04963 else 04964 bytesNeeded = sizeof(CRL_DIST_POINT_NAME); 04965 if (pcbDecoded) 04966 *pcbDecoded = 1 + lenBytes + dataLen; 04967 if (!pvStructInfo) 04968 *pcbStructInfo = bytesNeeded; 04969 else if (*pcbStructInfo < bytesNeeded) 04970 { 04971 *pcbStructInfo = bytesNeeded; 04972 SetLastError(ERROR_MORE_DATA); 04973 ret = FALSE; 04974 } 04975 else 04976 { 04977 CRL_DIST_POINT_NAME *name = pvStructInfo; 04978 04979 *pcbStructInfo = bytesNeeded; 04980 if (dataLen) 04981 { 04982 name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; 04983 ret = CRYPT_AsnDecodeArray(&arrayDesc, 04984 pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, 04985 dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen, 04986 NULL); 04987 } 04988 else 04989 name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME; 04990 } 04991 } 04992 } 04993 else 04994 { 04995 SetLastError(CRYPT_E_ASN1_BADTAG); 04996 ret = FALSE; 04997 } 04998 return ret; 04999 } 05000 05001 static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded, 05002 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 05003 { 05004 struct AsnDecodeSequenceItem items[] = { 05005 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_DIST_POINT, 05006 DistPointName), CRYPT_AsnDecodeDistPointName, 05007 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, offsetof(CRL_DIST_POINT, 05008 DistPointName.u.FullName.rgAltEntry), 0 }, 05009 { ASN_CONTEXT | 1, offsetof(CRL_DIST_POINT, ReasonFlags), 05010 CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, 05011 offsetof(CRL_DIST_POINT, ReasonFlags.pbData), 0 }, 05012 { ASN_CONTEXT | ASN_CONSTRUCTOR | 2, offsetof(CRL_DIST_POINT, CRLIssuer), 05013 CRYPT_AsnDecodeAltNameInternal, sizeof(CERT_ALT_NAME_INFO), TRUE, TRUE, 05014 offsetof(CRL_DIST_POINT, CRLIssuer.rgAltEntry), 0 }, 05015 }; 05016 CRL_DIST_POINT *point = pvStructInfo; 05017 BOOL ret; 05018 05019 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05020 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05021 pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL); 05022 return ret; 05023 } 05024 05025 static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType, 05026 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 05027 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 05028 { 05029 BOOL ret; 05030 05031 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05032 pDecodePara, pvStructInfo, *pcbStructInfo); 05033 05034 __TRY 05035 { 05036 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 05037 offsetof(CRL_DIST_POINTS_INFO, cDistPoint), 05038 offsetof(CRL_DIST_POINTS_INFO, rgDistPoint), 05039 sizeof(CRL_DIST_POINTS_INFO), 05040 CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE, 05041 offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) }; 05042 CRL_DIST_POINTS_INFO *info = pvStructInfo; 05043 05044 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 05045 info->rgDistPoint = (CRL_DIST_POINT *)(info + 1); 05046 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05047 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 05048 } 05049 __EXCEPT_PAGE_FAULT 05050 { 05051 SetLastError(STATUS_ACCESS_VIOLATION); 05052 ret = FALSE; 05053 } 05054 __ENDTRY 05055 return ret; 05056 } 05057 05058 static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType, 05059 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 05060 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 05061 { 05062 BOOL ret; 05063 05064 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05065 pDecodePara, pvStructInfo, *pcbStructInfo); 05066 05067 __TRY 05068 { 05069 struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, 05070 offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier), 05071 offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier), 05072 sizeof(CERT_ENHKEY_USAGE), 05073 CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 }; 05074 CERT_ENHKEY_USAGE *usage = pvStructInfo; 05075 05076 if (pvStructInfo && !(dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 05077 usage->rgpszUsageIdentifier = (LPSTR *)(usage + 1); 05078 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05079 dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); 05080 } 05081 __EXCEPT_PAGE_FAULT 05082 { 05083 SetLastError(STATUS_ACCESS_VIOLATION); 05084 ret = FALSE; 05085 } 05086 __ENDTRY 05087 return ret; 05088 } 05089 05090 static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType, 05091 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 05092 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 05093 { 05094 BOOL ret; 05095 05096 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05097 pDecodePara, pvStructInfo, *pcbStructInfo); 05098 05099 __TRY 05100 { 05101 struct AsnDecodeSequenceItem items[] = { 05102 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_ISSUING_DIST_POINT, 05103 DistPointName), CRYPT_AsnDecodeDistPointName, 05104 sizeof(CRL_DIST_POINT_NAME), TRUE, TRUE, 05105 offsetof(CRL_ISSUING_DIST_POINT, 05106 DistPointName.u.FullName.rgAltEntry), 0 }, 05107 { ASN_CONTEXT | 1, offsetof(CRL_ISSUING_DIST_POINT, 05108 fOnlyContainsUserCerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, 05109 FALSE, 0 }, 05110 { ASN_CONTEXT | 2, offsetof(CRL_ISSUING_DIST_POINT, 05111 fOnlyContainsCACerts), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, 05112 FALSE, 0 }, 05113 { ASN_CONTEXT | 3, offsetof(CRL_ISSUING_DIST_POINT, 05114 OnlySomeReasonFlags), CRYPT_AsnDecodeBitsInternal, 05115 sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CRL_ISSUING_DIST_POINT, 05116 OnlySomeReasonFlags.pbData), 0 }, 05117 { ASN_CONTEXT | 4, offsetof(CRL_ISSUING_DIST_POINT, 05118 fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 }, 05119 }; 05120 05121 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05122 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 05123 pcbStructInfo, NULL, NULL); 05124 } 05125 __EXCEPT_PAGE_FAULT 05126 { 05127 SetLastError(STATUS_ACCESS_VIOLATION); 05128 ret = FALSE; 05129 } 05130 __ENDTRY 05131 return ret; 05132 } 05133 05134 static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded, 05135 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05136 DWORD *pcbDecoded) 05137 { 05138 BOOL ret; 05139 DWORD max, size = sizeof(max); 05140 05141 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05142 pvStructInfo, *pcbStructInfo, pcbDecoded); 05143 05144 if (!cbEncoded) 05145 { 05146 SetLastError(CRYPT_E_ASN1_EOD); 05147 return FALSE; 05148 } 05149 if (pbEncoded[0] != (ASN_CONTEXT | 1)) 05150 { 05151 SetLastError(CRYPT_E_ASN1_BADTAG); 05152 return FALSE; 05153 } 05154 if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, 05155 &max, &size, pcbDecoded))) 05156 { 05157 DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum); 05158 05159 if (!pvStructInfo) 05160 *pcbStructInfo = bytesNeeded; 05161 else if (*pcbStructInfo < bytesNeeded) 05162 { 05163 *pcbStructInfo = bytesNeeded; 05164 SetLastError(ERROR_MORE_DATA); 05165 ret = FALSE; 05166 } 05167 else 05168 { 05169 CERT_GENERAL_SUBTREE *subtree = CONTAINING_RECORD(pvStructInfo, 05170 CERT_GENERAL_SUBTREE, fMaximum); 05171 05172 *pcbStructInfo = bytesNeeded; 05173 /* The BOOL is implicit: if the integer is present, then it's 05174 * TRUE. 05175 */ 05176 subtree->fMaximum = TRUE; 05177 subtree->dwMaximum = max; 05178 } 05179 } 05180 TRACE("returning %d\n", ret); 05181 return ret; 05182 } 05183 05184 static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded, 05185 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05186 DWORD *pcbDecoded) 05187 { 05188 BOOL ret; 05189 struct AsnDecodeSequenceItem items[] = { 05190 { 0, offsetof(CERT_GENERAL_SUBTREE, Base), 05191 CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, TRUE, 05192 offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL), 0 }, 05193 { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum), 05194 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, 05195 { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum), 05196 CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum), 05197 TRUE, FALSE, 0, 0 }, 05198 }; 05199 CERT_GENERAL_SUBTREE *subtree = pvStructInfo; 05200 05201 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05202 pvStructInfo, *pcbStructInfo, pcbDecoded); 05203 05204 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05205 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05206 pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL); 05207 if (pcbDecoded) 05208 { 05209 TRACE("%d\n", *pcbDecoded); 05210 if (*pcbDecoded < cbEncoded) 05211 TRACE("%02x %02x\n", *(pbEncoded + *pcbDecoded), 05212 *(pbEncoded + *pcbDecoded + 1)); 05213 } 05214 TRACE("returning %d\n", ret); 05215 return ret; 05216 } 05217 05218 static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded, 05219 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05220 DWORD *pcbDecoded) 05221 { 05222 BOOL ret = TRUE; 05223 struct AsnArrayDescriptor arrayDesc = { 0, 05224 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree), 05225 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 05226 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree, 05227 cExcludedSubtree), 05228 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE, 05229 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) }; 05230 05231 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05232 pvStructInfo, *pcbStructInfo, pcbDecoded); 05233 05234 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05235 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 05236 return ret; 05237 } 05238 05239 static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded, 05240 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05241 DWORD *pcbDecoded) 05242 { 05243 BOOL ret = TRUE; 05244 struct AsnArrayDescriptor arrayDesc = { 0, 05245 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), 05246 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 05247 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), 05248 CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE, 05249 offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) }; 05250 05251 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05252 pvStructInfo, *pcbStructInfo, pcbDecoded); 05253 05254 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05255 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 05256 return ret; 05257 } 05258 05259 static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType, 05260 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 05261 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 05262 { 05263 BOOL ret = FALSE; 05264 05265 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05266 pDecodePara, pvStructInfo, *pcbStructInfo); 05267 05268 __TRY 05269 { 05270 struct AsnDecodeSequenceItem items[] = { 05271 { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, 05272 offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree), 05273 CRYPT_AsnDecodePermittedSubtree, 05274 MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree, 05275 cExcludedSubtree), TRUE, TRUE, 05276 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 }, 05277 { ASN_CONTEXT | ASN_CONSTRUCTOR | 1, 05278 offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), 05279 CRYPT_AsnDecodeExcludedSubtree, 05280 FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), 05281 TRUE, TRUE, 05282 offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 }, 05283 }; 05284 05285 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05286 pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, 05287 pcbStructInfo, NULL, NULL); 05288 } 05289 __EXCEPT_PAGE_FAULT 05290 { 05291 SetLastError(STATUS_ACCESS_VIOLATION); 05292 } 05293 __ENDTRY 05294 return ret; 05295 } 05296 05297 static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded, 05298 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05299 DWORD *pcbDecoded) 05300 { 05301 BOOL ret; 05302 struct AsnDecodeSequenceItem items[] = { 05303 { 0, offsetof(CERT_ISSUER_SERIAL_NUMBER, Issuer), CRYPT_AsnDecodeDerBlob, 05304 sizeof(CRYPT_DER_BLOB), FALSE, TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, 05305 Issuer.pbData) }, 05306 { ASN_INTEGER, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber), 05307 CRYPT_AsnDecodeIntegerInternal, sizeof(CRYPT_INTEGER_BLOB), FALSE, 05308 TRUE, offsetof(CERT_ISSUER_SERIAL_NUMBER, SerialNumber.pbData), 0 }, 05309 }; 05310 CERT_ISSUER_SERIAL_NUMBER *issuerSerial = pvStructInfo; 05311 05312 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05313 pvStructInfo, *pcbStructInfo, pcbDecoded); 05314 05315 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05316 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05317 pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL); 05318 if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData) 05319 { 05320 SetLastError(CRYPT_E_ASN1_CORRUPT); 05321 ret = FALSE; 05322 } 05323 TRACE("returning %d\n", ret); 05324 return ret; 05325 } 05326 05327 static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded, 05328 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05329 DWORD *pcbDecoded) 05330 { 05331 CMSG_SIGNER_INFO *info = pvStructInfo; 05332 struct AsnDecodeSequenceItem items[] = { 05333 { ASN_INTEGER, offsetof(CMSG_SIGNER_INFO, dwVersion), 05334 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 05335 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, Issuer), 05336 CRYPT_AsnDecodeIssuerSerialNumber, sizeof(CERT_ISSUER_SERIAL_NUMBER), 05337 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, Issuer.pbData), 0 }, 05338 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashAlgorithm), 05339 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 05340 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, HashAlgorithm.pszObjId), 0 }, 05341 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0, 05342 offsetof(CMSG_SIGNER_INFO, AuthAttrs), 05343 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), 05344 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, AuthAttrs.rgAttr), 0 }, 05345 { ASN_SEQUENCEOF, offsetof(CMSG_SIGNER_INFO, HashEncryptionAlgorithm), 05346 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 05347 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, 05348 HashEncryptionAlgorithm.pszObjId), 0 }, 05349 { ASN_OCTETSTRING, offsetof(CMSG_SIGNER_INFO, EncryptedHash), 05350 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB), 05351 FALSE, TRUE, offsetof(CMSG_SIGNER_INFO, EncryptedHash.pbData), 0 }, 05352 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1, 05353 offsetof(CMSG_SIGNER_INFO, UnauthAttrs), 05354 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), 05355 TRUE, TRUE, offsetof(CMSG_SIGNER_INFO, UnauthAttrs.rgAttr), 0 }, 05356 }; 05357 BOOL ret; 05358 05359 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05360 pvStructInfo, *pcbStructInfo); 05361 05362 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05363 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05364 pcbDecoded, info ? info->Issuer.pbData : NULL); 05365 return ret; 05366 } 05367 05368 static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType, 05369 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 05370 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 05371 { 05372 BOOL ret = FALSE; 05373 05374 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05375 pDecodePara, pvStructInfo, *pcbStructInfo); 05376 05377 __TRY 05378 { 05379 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, cbEncoded, 05380 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 05381 if (ret && pvStructInfo) 05382 { 05383 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 05384 pcbStructInfo, *pcbStructInfo); 05385 if (ret) 05386 { 05387 CMSG_SIGNER_INFO *info; 05388 05389 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 05390 pvStructInfo = *(BYTE **)pvStructInfo; 05391 info = pvStructInfo; 05392 info->Issuer.pbData = ((BYTE *)info + 05393 sizeof(CMSG_SIGNER_INFO)); 05394 ret = CRYPT_AsnDecodePKCSSignerInfoInternal(pbEncoded, 05395 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 05396 pcbStructInfo, NULL); 05397 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 05398 CRYPT_FreeSpace(pDecodePara, info); 05399 } 05400 } 05401 } 05402 __EXCEPT_PAGE_FAULT 05403 { 05404 SetLastError(STATUS_ACCESS_VIOLATION); 05405 } 05406 __ENDTRY 05407 TRACE("returning %d\n", ret); 05408 return ret; 05409 } 05410 05411 static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded, 05412 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05413 DWORD *pcbDecoded) 05414 { 05415 BOOL ret; 05416 struct AsnArrayDescriptor arrayDesc = { 0, 05417 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), 05418 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 05419 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), 05420 CRYPT_AsnDecodeCopyBytes, 05421 sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; 05422 05423 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05424 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); 05425 05426 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05427 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 05428 return ret; 05429 } 05430 05431 static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded, 05432 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05433 DWORD *pcbDecoded) 05434 { 05435 BOOL ret; 05436 struct AsnArrayDescriptor arrayDesc = { 0, 05437 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), 05438 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 05439 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), 05440 CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB), 05441 TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; 05442 05443 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05444 pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); 05445 05446 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05447 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 05448 return ret; 05449 } 05450 05451 static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded, 05452 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05453 DWORD *pcbDecoded) 05454 { 05455 CERT_ID *id = pvStructInfo; 05456 BOOL ret = FALSE; 05457 05458 if (*pbEncoded == ASN_SEQUENCEOF) 05459 { 05460 ret = CRYPT_AsnDecodeIssuerSerialNumber(pbEncoded, cbEncoded, dwFlags, 05461 id ? &id->u.IssuerSerialNumber : NULL, pcbStructInfo, pcbDecoded); 05462 if (ret) 05463 { 05464 if (id) 05465 id->dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 05466 if (*pcbStructInfo > sizeof(CERT_ISSUER_SERIAL_NUMBER)) 05467 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo - 05468 sizeof(CERT_ISSUER_SERIAL_NUMBER); 05469 else 05470 *pcbStructInfo = sizeof(CERT_ID); 05471 } 05472 } 05473 else if (*pbEncoded == (ASN_CONTEXT | 0)) 05474 { 05475 ret = CRYPT_AsnDecodeOctetsInternal(pbEncoded, cbEncoded, dwFlags, 05476 id ? &id->u.KeyId : NULL, pcbStructInfo, pcbDecoded); 05477 if (ret) 05478 { 05479 if (id) 05480 id->dwIdChoice = CERT_ID_KEY_IDENTIFIER; 05481 if (*pcbStructInfo > sizeof(CRYPT_DATA_BLOB)) 05482 *pcbStructInfo = sizeof(CERT_ID) + *pcbStructInfo - 05483 sizeof(CRYPT_DATA_BLOB); 05484 else 05485 *pcbStructInfo = sizeof(CERT_ID); 05486 } 05487 } 05488 else 05489 SetLastError(CRYPT_E_ASN1_BADTAG); 05490 return ret; 05491 } 05492 05493 static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded, 05494 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05495 DWORD *pcbDecoded) 05496 { 05497 CMSG_CMS_SIGNER_INFO *info = pvStructInfo; 05498 struct AsnDecodeSequenceItem items[] = { 05499 { ASN_INTEGER, offsetof(CMSG_CMS_SIGNER_INFO, dwVersion), 05500 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 05501 { 0, offsetof(CMSG_CMS_SIGNER_INFO, SignerId), 05502 CRYPT_AsnDecodeCMSSignerId, sizeof(CERT_ID), FALSE, TRUE, 05503 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData), 0 }, 05504 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm), 05505 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 05506 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, HashAlgorithm.pszObjId), 0 }, 05507 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0, 05508 offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs), 05509 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), 05510 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, AuthAttrs.rgAttr), 0 }, 05511 { ASN_SEQUENCEOF, offsetof(CMSG_CMS_SIGNER_INFO, HashEncryptionAlgorithm), 05512 CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), 05513 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, 05514 HashEncryptionAlgorithm.pszObjId), 0 }, 05515 { ASN_OCTETSTRING, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash), 05516 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DER_BLOB), 05517 FALSE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, EncryptedHash.pbData), 0 }, 05518 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1, 05519 offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs), 05520 CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), 05521 TRUE, TRUE, offsetof(CMSG_CMS_SIGNER_INFO, UnauthAttrs.rgAttr), 0 }, 05522 }; 05523 BOOL ret; 05524 05525 TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05526 pvStructInfo, *pcbStructInfo); 05527 05528 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05529 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05530 pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL); 05531 return ret; 05532 } 05533 05534 static BOOL WINAPI CRYPT_AsnDecodeCMSSignerInfo(DWORD dwCertEncodingType, 05535 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 05536 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 05537 { 05538 BOOL ret = FALSE; 05539 05540 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05541 pDecodePara, pvStructInfo, *pcbStructInfo); 05542 05543 __TRY 05544 { 05545 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, cbEncoded, 05546 dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); 05547 if (ret && pvStructInfo) 05548 { 05549 ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, 05550 pcbStructInfo, *pcbStructInfo); 05551 if (ret) 05552 { 05553 CMSG_CMS_SIGNER_INFO *info; 05554 05555 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 05556 pvStructInfo = *(BYTE **)pvStructInfo; 05557 info = pvStructInfo; 05558 info->SignerId.u.KeyId.pbData = ((BYTE *)info + 05559 sizeof(CMSG_CMS_SIGNER_INFO)); 05560 ret = CRYPT_AsnDecodeCMSSignerInfoInternal(pbEncoded, 05561 cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, 05562 pcbStructInfo, NULL); 05563 if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) 05564 CRYPT_FreeSpace(pDecodePara, info); 05565 } 05566 } 05567 } 05568 __EXCEPT_PAGE_FAULT 05569 { 05570 SetLastError(STATUS_ACCESS_VIOLATION); 05571 } 05572 __ENDTRY 05573 TRACE("returning %d\n", ret); 05574 return ret; 05575 } 05576 05577 static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded, 05578 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 05579 { 05580 BOOL ret; 05581 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 05582 offsetof(CRYPT_SIGNED_INFO, cSignerInfo), 05583 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 05584 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), 05585 CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE, 05586 offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) }; 05587 05588 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05589 pvStructInfo, *pcbStructInfo, pcbDecoded); 05590 05591 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05592 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 05593 return ret; 05594 } 05595 05596 BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded, 05597 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, 05598 CRYPT_SIGNED_INFO *signedInfo, DWORD *pcbSignedInfo) 05599 { 05600 BOOL ret = FALSE; 05601 struct AsnDecodeSequenceItem items[] = { 05602 { ASN_INTEGER, offsetof(CRYPT_SIGNED_INFO, version), 05603 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 05604 /* Placeholder for the hash algorithms - redundant with those in the 05605 * signers, so just ignore them. 05606 */ 05607 { ASN_CONSTRUCTOR | ASN_SETOF, 0, NULL, 0, TRUE, FALSE, 0, 0 }, 05608 { ASN_SEQUENCE, offsetof(CRYPT_SIGNED_INFO, content), 05609 CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO), 05610 FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 }, 05611 { ASN_CONSTRUCTOR | ASN_CONTEXT | 0, 05612 offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded, 05613 MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE, 05614 offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 }, 05615 { ASN_CONSTRUCTOR | ASN_CONTEXT | 1, 05616 offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded, 05617 MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE, 05618 offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 }, 05619 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo), 05620 CRYPT_DecodeSignerArray, 05621 FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE, 05622 offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 }, 05623 }; 05624 05625 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05626 pDecodePara, signedInfo, *pcbSignedInfo); 05627 05628 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05629 pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo, 05630 NULL, NULL); 05631 TRACE("returning %d\n", ret); 05632 return ret; 05633 } 05634 05635 static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded, 05636 DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) 05637 { 05638 BOOL ret; 05639 CMSG_KEY_TRANS_RECIPIENT_INFO *info = pvStructInfo; 05640 struct AsnDecodeSequenceItem items[] = { 05641 { ASN_INTEGER, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, dwVersion), 05642 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 05643 { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, 05644 RecipientId.u.IssuerSerialNumber), CRYPT_AsnDecodeIssuerSerialNumber, 05645 sizeof(CERT_ISSUER_SERIAL_NUMBER), FALSE, TRUE, 05646 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, 05647 RecipientId.u.IssuerSerialNumber.Issuer.pbData), 0 }, 05648 { ASN_SEQUENCEOF, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, 05649 KeyEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId, 05650 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, 05651 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, 05652 KeyEncryptionAlgorithm.pszObjId), 0 }, 05653 { ASN_OCTETSTRING, offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey), 05654 CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE, 05655 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, EncryptedKey.pbData), 0 }, 05656 }; 05657 05658 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05659 pvStructInfo, *pcbStructInfo, pcbDecoded); 05660 05661 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05662 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05663 pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData : 05664 NULL); 05665 if (info) 05666 info->RecipientId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; 05667 TRACE("returning %d\n", ret); 05668 return ret; 05669 } 05670 05671 static BOOL CRYPT_DecodeRecipientInfoArray(const BYTE *pbEncoded, 05672 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05673 DWORD *pcbDecoded) 05674 { 05675 BOOL ret; 05676 struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, 05677 offsetof(CRYPT_ENVELOPED_DATA, cRecipientInfo), 05678 offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo), 05679 MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo), 05680 CRYPT_AsnDecodeRecipientInfo, sizeof(CMSG_KEY_TRANS_RECIPIENT_INFO), TRUE, 05681 offsetof(CMSG_KEY_TRANS_RECIPIENT_INFO, 05682 RecipientId.u.IssuerSerialNumber.Issuer.pbData) }; 05683 05684 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05685 pvStructInfo, *pcbStructInfo, pcbDecoded); 05686 05687 ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, 05688 dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); 05689 TRACE("returning %d\n", ret); 05690 return ret; 05691 } 05692 05693 static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded, 05694 DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, 05695 DWORD *pcbDecoded) 05696 { 05697 BOOL ret; 05698 CRYPT_ENCRYPTED_CONTENT_INFO *info = pvStructInfo; 05699 struct AsnDecodeSequenceItem items[] = { 05700 { ASN_OBJECTIDENTIFIER, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, 05701 contentType), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), 05702 FALSE, TRUE, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, 05703 contentType), 0 }, 05704 { ASN_SEQUENCEOF, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, 05705 contentEncryptionAlgorithm), CRYPT_AsnDecodeAlgorithmId, 05706 sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, 05707 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, 05708 contentEncryptionAlgorithm.pszObjId), 0 }, 05709 { ASN_CONTEXT | 0, offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, 05710 encryptedContent), CRYPT_AsnDecodeOctetsInternal, 05711 sizeof(CRYPT_DATA_BLOB), TRUE, TRUE, 05712 offsetof(CRYPT_ENCRYPTED_CONTENT_INFO, encryptedContent.pbData) }, 05713 }; 05714 05715 TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, 05716 pvStructInfo, *pcbStructInfo, pcbDecoded); 05717 05718 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05719 pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, 05720 pcbDecoded, info ? info->contentType : NULL); 05721 TRACE("returning %d\n", ret); 05722 return ret; 05723 } 05724 05725 BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded, 05726 DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, 05727 CRYPT_ENVELOPED_DATA *envelopedData, DWORD *pcbEnvelopedData) 05728 { 05729 BOOL ret; 05730 struct AsnDecodeSequenceItem items[] = { 05731 { ASN_INTEGER, offsetof(CRYPT_ENVELOPED_DATA, version), 05732 CRYPT_AsnDecodeIntInternal, sizeof(DWORD), FALSE, FALSE, 0, 0 }, 05733 { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ENVELOPED_DATA, 05734 cRecipientInfo), CRYPT_DecodeRecipientInfoArray, 05735 MEMBERSIZE(CRYPT_ENVELOPED_DATA, cRecipientInfo, encryptedContentInfo), 05736 FALSE, TRUE, offsetof(CRYPT_ENVELOPED_DATA, rgRecipientInfo), 0 }, 05737 { ASN_SEQUENCEOF, offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo), 05738 CRYPT_AsnDecodeEncryptedContentInfo, 05739 sizeof(CRYPT_ENCRYPTED_CONTENT_INFO), FALSE, TRUE, 05740 offsetof(CRYPT_ENVELOPED_DATA, encryptedContentInfo.contentType), 0 }, 05741 }; 05742 05743 TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, 05744 pDecodePara, envelopedData, *pcbEnvelopedData); 05745 05746 ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), 05747 pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData, 05748 pcbEnvelopedData, NULL, NULL); 05749 TRACE("returning %d\n", ret); 05750 return ret; 05751 } 05752 05753 static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, 05754 LPCSTR lpszStructType) 05755 { 05756 CryptDecodeObjectExFunc decodeFunc = NULL; 05757 05758 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING 05759 && (dwCertEncodingType & CMSG_ENCODING_TYPE_MASK) != PKCS_7_ASN_ENCODING) 05760 { 05761 SetLastError(ERROR_FILE_NOT_FOUND); 05762 return NULL; 05763 } 05764 if (IS_INTOID(lpszStructType)) 05765 { 05766 switch (LOWORD(lpszStructType)) 05767 { 05768 case LOWORD(X509_CERT): 05769 decodeFunc = CRYPT_AsnDecodeCertSignedContent; 05770 break; 05771 case LOWORD(X509_CERT_TO_BE_SIGNED): 05772 decodeFunc = CRYPT_AsnDecodeCert; 05773 break; 05774 case LOWORD(X509_CERT_CRL_TO_BE_SIGNED): 05775 decodeFunc = CRYPT_AsnDecodeCRL; 05776 break; 05777 case LOWORD(X509_EXTENSIONS): 05778 decodeFunc = CRYPT_AsnDecodeExtensions; 05779 break; 05780 case LOWORD(X509_NAME_VALUE): 05781 decodeFunc = CRYPT_AsnDecodeNameValue; 05782 break; 05783 case LOWORD(X509_NAME): 05784 decodeFunc = CRYPT_AsnDecodeName; 05785 break; 05786 case LOWORD(X509_PUBLIC_KEY_INFO): 05787 decodeFunc = CRYPT_AsnDecodePubKeyInfo; 05788 break; 05789 case LOWORD(X509_AUTHORITY_KEY_ID): 05790 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId; 05791 break; 05792 case LOWORD(X509_ALTERNATE_NAME): 05793 decodeFunc = CRYPT_AsnDecodeAltName; 05794 break; 05795 case LOWORD(X509_BASIC_CONSTRAINTS): 05796 decodeFunc = CRYPT_AsnDecodeBasicConstraints; 05797 break; 05798 case LOWORD(X509_BASIC_CONSTRAINTS2): 05799 decodeFunc = CRYPT_AsnDecodeBasicConstraints2; 05800 break; 05801 case LOWORD(X509_CERT_POLICIES): 05802 decodeFunc = CRYPT_AsnDecodeCertPolicies; 05803 break; 05804 case LOWORD(RSA_CSP_PUBLICKEYBLOB): 05805 decodeFunc = CRYPT_AsnDecodeRsaPubKey; 05806 break; 05807 case LOWORD(X509_UNICODE_NAME): 05808 decodeFunc = CRYPT_AsnDecodeUnicodeName; 05809 break; 05810 case LOWORD(PKCS_ATTRIBUTE): 05811 decodeFunc = CRYPT_AsnDecodePKCSAttribute; 05812 break; 05813 case LOWORD(X509_UNICODE_NAME_VALUE): 05814 decodeFunc = CRYPT_AsnDecodeUnicodeNameValue; 05815 break; 05816 case LOWORD(X509_OCTET_STRING): 05817 decodeFunc = CRYPT_AsnDecodeOctets; 05818 break; 05819 case LOWORD(X509_BITS): 05820 case LOWORD(X509_KEY_USAGE): 05821 decodeFunc = CRYPT_AsnDecodeBits; 05822 break; 05823 case LOWORD(X509_INTEGER): 05824 decodeFunc = CRYPT_AsnDecodeInt; 05825 break; 05826 case LOWORD(X509_MULTI_BYTE_INTEGER): 05827 decodeFunc = CRYPT_AsnDecodeInteger; 05828 break; 05829 case LOWORD(X509_MULTI_BYTE_UINT): 05830 decodeFunc = CRYPT_AsnDecodeUnsignedInteger; 05831 break; 05832 case LOWORD(X509_ENUMERATED): 05833 decodeFunc = CRYPT_AsnDecodeEnumerated; 05834 break; 05835 case LOWORD(X509_CHOICE_OF_TIME): 05836 decodeFunc = CRYPT_AsnDecodeChoiceOfTime; 05837 break; 05838 case LOWORD(X509_AUTHORITY_KEY_ID2): 05839 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2; 05840 break; 05841 case LOWORD(X509_AUTHORITY_INFO_ACCESS): 05842 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess; 05843 break; 05844 case LOWORD(PKCS_CONTENT_INFO): 05845 decodeFunc = CRYPT_AsnDecodePKCSContentInfo; 05846 break; 05847 case LOWORD(X509_SEQUENCE_OF_ANY): 05848 decodeFunc = CRYPT_AsnDecodeSequenceOfAny; 05849 break; 05850 case LOWORD(PKCS_UTC_TIME): 05851 decodeFunc = CRYPT_AsnDecodeUtcTime; 05852 break; 05853 case LOWORD(X509_CRL_DIST_POINTS): 05854 decodeFunc = CRYPT_AsnDecodeCRLDistPoints; 05855 break; 05856 case LOWORD(X509_ENHANCED_KEY_USAGE): 05857 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage; 05858 break; 05859 case LOWORD(PKCS_CTL): 05860 decodeFunc = CRYPT_AsnDecodeCTL; 05861 break; 05862 case LOWORD(PKCS_SMIME_CAPABILITIES): 05863 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities; 05864 break; 05865 case LOWORD(X509_PKIX_POLICY_QUALIFIER_USERNOTICE): 05866 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice; 05867 break; 05868 case LOWORD(PKCS_ATTRIBUTES): 05869 decodeFunc = CRYPT_AsnDecodePKCSAttributes; 05870 break; 05871 case LOWORD(X509_ISSUING_DIST_POINT): 05872 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint; 05873 break; 05874 case LOWORD(X509_NAME_CONSTRAINTS): 05875 decodeFunc = CRYPT_AsnDecodeNameConstraints; 05876 break; 05877 case LOWORD(X509_POLICY_MAPPINGS): 05878 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; 05879 break; 05880 case LOWORD(X509_POLICY_CONSTRAINTS): 05881 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints; 05882 break; 05883 case LOWORD(PKCS7_SIGNER_INFO): 05884 decodeFunc = CRYPT_AsnDecodePKCSSignerInfo; 05885 break; 05886 case LOWORD(CMS_SIGNER_INFO): 05887 decodeFunc = CRYPT_AsnDecodeCMSSignerInfo; 05888 break; 05889 } 05890 } 05891 else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS)) 05892 decodeFunc = CRYPT_AsnDecodeExtensions; 05893 else if (!strcmp(lpszStructType, szOID_RSA_signingTime)) 05894 decodeFunc = CRYPT_AsnDecodeUtcTime; 05895 else if (!strcmp(lpszStructType, szOID_RSA_SMIMECapabilities)) 05896 decodeFunc = CRYPT_AsnDecodeSMIMECapabilities; 05897 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER)) 05898 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId; 05899 else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS)) 05900 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; 05901 else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2)) 05902 decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2; 05903 else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE)) 05904 decodeFunc = CRYPT_AsnDecodeEnumerated; 05905 else if (!strcmp(lpszStructType, szOID_KEY_USAGE)) 05906 decodeFunc = CRYPT_AsnDecodeBits; 05907 else if (!strcmp(lpszStructType, szOID_SUBJECT_KEY_IDENTIFIER)) 05908 decodeFunc = CRYPT_AsnDecodeOctets; 05909 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS)) 05910 decodeFunc = CRYPT_AsnDecodeBasicConstraints; 05911 else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2)) 05912 decodeFunc = CRYPT_AsnDecodeBasicConstraints2; 05913 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME)) 05914 decodeFunc = CRYPT_AsnDecodeAltName; 05915 else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2)) 05916 decodeFunc = CRYPT_AsnDecodeAltName; 05917 else if (!strcmp(lpszStructType, szOID_NEXT_UPDATE_LOCATION)) 05918 decodeFunc = CRYPT_AsnDecodeAltName; 05919 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME)) 05920 decodeFunc = CRYPT_AsnDecodeAltName; 05921 else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2)) 05922 decodeFunc = CRYPT_AsnDecodeAltName; 05923 else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS)) 05924 decodeFunc = CRYPT_AsnDecodeCRLDistPoints; 05925 else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) 05926 decodeFunc = CRYPT_AsnDecodeCertPolicies; 05927 else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS)) 05928 decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; 05929 else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS)) 05930 decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints; 05931 else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE)) 05932 decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage; 05933 else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) 05934 decodeFunc = CRYPT_AsnDecodeIssuingDistPoint; 05935 else if (!strcmp(lpszStructType, szOID_NAME_CONSTRAINTS)) 05936 decodeFunc = CRYPT_AsnDecodeNameConstraints; 05937 else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS)) 05938 decodeFunc = CRYPT_AsnDecodeAuthorityInfoAccess; 05939 else if (!strcmp(lpszStructType, szOID_PKIX_POLICY_QUALIFIER_USERNOTICE)) 05940 decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice; 05941 else if (!strcmp(lpszStructType, szOID_CTL)) 05942 decodeFunc = CRYPT_AsnDecodeCTL; 05943 return decodeFunc; 05944 } 05945 05946 static CryptDecodeObjectFunc CRYPT_LoadDecoderFunc(DWORD dwCertEncodingType, 05947 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc) 05948 { 05949 static HCRYPTOIDFUNCSET set = NULL; 05950 CryptDecodeObjectFunc decodeFunc = NULL; 05951 05952 if (!set) 05953 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_FUNC, 0); 05954 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0, 05955 (void **)&decodeFunc, hFunc); 05956 return decodeFunc; 05957 } 05958 05959 static CryptDecodeObjectExFunc CRYPT_LoadDecoderExFunc(DWORD dwCertEncodingType, 05960 LPCSTR lpszStructType, HCRYPTOIDFUNCADDR *hFunc) 05961 { 05962 static HCRYPTOIDFUNCSET set = NULL; 05963 CryptDecodeObjectExFunc decodeFunc = NULL; 05964 05965 if (!set) 05966 set = CryptInitOIDFunctionSet(CRYPT_OID_DECODE_OBJECT_EX_FUNC, 0); 05967 CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0, 05968 (void **)&decodeFunc, hFunc); 05969 return decodeFunc; 05970 } 05971 05972 BOOL WINAPI CryptDecodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType, 05973 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, 05974 DWORD *pcbStructInfo) 05975 { 05976 BOOL ret = FALSE; 05977 CryptDecodeObjectFunc pCryptDecodeObject = NULL; 05978 CryptDecodeObjectExFunc pCryptDecodeObjectEx = NULL; 05979 HCRYPTOIDFUNCADDR hFunc = NULL; 05980 05981 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p)\n", dwCertEncodingType, 05982 debugstr_a(lpszStructType), pbEncoded, cbEncoded, dwFlags, 05983 pvStructInfo, pcbStructInfo); 05984 05985 if (!pvStructInfo && !pcbStructInfo) 05986 { 05987 SetLastError(ERROR_INVALID_PARAMETER); 05988 return FALSE; 05989 } 05990 if (cbEncoded > MAX_ENCODED_LEN) 05991 { 05992 SetLastError(CRYPT_E_ASN1_LARGE); 05993 return FALSE; 05994 } 05995 05996 if (!(pCryptDecodeObjectEx = CRYPT_GetBuiltinDecoder(dwCertEncodingType, 05997 lpszStructType))) 05998 { 05999 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n", 06000 debugstr_a(lpszStructType)); 06001 pCryptDecodeObject = CRYPT_LoadDecoderFunc(dwCertEncodingType, 06002 lpszStructType, &hFunc); 06003 if (!pCryptDecodeObject) 06004 pCryptDecodeObjectEx = CRYPT_LoadDecoderExFunc(dwCertEncodingType, 06005 lpszStructType, &hFunc); 06006 } 06007 if (pCryptDecodeObject) 06008 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, 06009 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo); 06010 else if (pCryptDecodeObjectEx) 06011 ret = pCryptDecodeObjectEx(dwCertEncodingType, lpszStructType, 06012 pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, 06013 pvStructInfo, pcbStructInfo); 06014 if (hFunc) 06015 CryptFreeOIDFunctionAddress(hFunc, 0); 06016 TRACE_(crypt)("returning %d\n", ret); 06017 return ret; 06018 } 06019 06020 BOOL WINAPI CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, 06021 const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, 06022 PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) 06023 { 06024 BOOL ret = FALSE; 06025 CryptDecodeObjectExFunc decodeFunc; 06026 HCRYPTOIDFUNCADDR hFunc = NULL; 06027 06028 TRACE_(crypt)("(0x%08x, %s, %p, %d, 0x%08x, %p, %p, %p)\n", 06029 dwCertEncodingType, debugstr_a(lpszStructType), pbEncoded, 06030 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); 06031 06032 if (!pvStructInfo && !pcbStructInfo) 06033 { 06034 SetLastError(ERROR_INVALID_PARAMETER); 06035 return FALSE; 06036 } 06037 if (cbEncoded > MAX_ENCODED_LEN) 06038 { 06039 SetLastError(CRYPT_E_ASN1_LARGE); 06040 return FALSE; 06041 } 06042 06043 SetLastError(NOERROR); 06044 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 06045 { 06046 if (!pvStructInfo) 06047 { 06048 SetLastError(ERROR_INVALID_PARAMETER); 06049 return FALSE; 06050 } 06051 *(BYTE **)pvStructInfo = NULL; 06052 } 06053 decodeFunc = CRYPT_GetBuiltinDecoder(dwCertEncodingType, lpszStructType); 06054 if (!decodeFunc) 06055 { 06056 TRACE_(crypt)("OID %s not found or unimplemented, looking for DLL\n", 06057 debugstr_a(lpszStructType)); 06058 decodeFunc = CRYPT_LoadDecoderExFunc(dwCertEncodingType, lpszStructType, 06059 &hFunc); 06060 } 06061 if (decodeFunc) 06062 ret = decodeFunc(dwCertEncodingType, lpszStructType, pbEncoded, 06063 cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo); 06064 else 06065 { 06066 CryptDecodeObjectFunc pCryptDecodeObject = 06067 CRYPT_LoadDecoderFunc(dwCertEncodingType, lpszStructType, &hFunc); 06068 06069 /* Try CryptDecodeObject function. Don't call CryptDecodeObject 06070 * directly, as that could cause an infinite loop. 06071 */ 06072 if (pCryptDecodeObject) 06073 { 06074 if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) 06075 { 06076 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, 06077 pbEncoded, cbEncoded, dwFlags, NULL, pcbStructInfo); 06078 if (ret && (ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, 06079 pvStructInfo, pcbStructInfo, *pcbStructInfo))) 06080 { 06081 ret = pCryptDecodeObject(dwCertEncodingType, 06082 lpszStructType, pbEncoded, cbEncoded, dwFlags, 06083 *(BYTE **)pvStructInfo, pcbStructInfo); 06084 if (!ret) 06085 CRYPT_FreeSpace(pDecodePara, *(BYTE **)pvStructInfo); 06086 } 06087 } 06088 else 06089 ret = pCryptDecodeObject(dwCertEncodingType, lpszStructType, 06090 pbEncoded, cbEncoded, dwFlags, pvStructInfo, pcbStructInfo); 06091 } 06092 } 06093 if (hFunc) 06094 CryptFreeOIDFunctionAddress(hFunc, 0); 06095 TRACE_(crypt)("returning %d\n", ret); 06096 return ret; 06097 } 06098 06099 BOOL WINAPI PFXIsPFXBlob(CRYPT_DATA_BLOB *pPFX) 06100 { 06101 BOOL ret; 06102 06103 TRACE_(crypt)("(%p)\n", pPFX); 06104 06105 /* A PFX blob is an asn.1-encoded sequence, consisting of at least a 06106 * version integer of length 1 (3 encoded byes) and at least one other 06107 * datum (two encoded bytes), plus at least two bytes for the outer 06108 * sequence. Thus, even an empty PFX blob is at least 7 bytes in length. 06109 */ 06110 if (pPFX->cbData < 7) 06111 ret = FALSE; 06112 else if (pPFX->pbData[0] == ASN_SEQUENCE) 06113 { 06114 DWORD len; 06115 06116 if ((ret = CRYPT_GetLengthIndefinite(pPFX->pbData, pPFX->cbData, &len))) 06117 { 06118 BYTE lenLen = GET_LEN_BYTES(pPFX->pbData[1]); 06119 06120 /* Need at least three bytes for the integer version */ 06121 if (pPFX->cbData < 1 + lenLen + 3) 06122 ret = FALSE; 06123 else if (pPFX->pbData[1 + lenLen] != ASN_INTEGER || /* Tag */ 06124 pPFX->pbData[1 + lenLen + 1] != 1 || /* Definite length */ 06125 pPFX->pbData[1 + lenLen + 2] != 3) /* PFX version */ 06126 ret = FALSE; 06127 } 06128 } 06129 else 06130 ret = FALSE; 06131 return ret; 06132 } 06133 06134 HCERTSTORE WINAPI PFXImportCertStore(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, 06135 DWORD dwFlags) 06136 { 06137 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags); 06138 return NULL; 06139 } 06140 06141 BOOL WINAPI PFXVerifyPassword(CRYPT_DATA_BLOB *pPFX, LPCWSTR szPassword, 06142 DWORD dwFlags) 06143 { 06144 FIXME_(crypt)("(%p, %p, %08x): stub\n", pPFX, szPassword, dwFlags); 06145 return FALSE; 06146 } Generated on Sun May 27 2012 04:23:13 for ReactOS by
1.7.6.1
|