OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 /* | 5 /* |
6 Optimized ASN.1 DER decoder | 6 Optimized ASN.1 DER decoder |
7 | 7 |
8 */ | 8 */ |
9 | 9 |
10 #include "secerr.h" | 10 #include "secerr.h" |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 /* XXX also enforce ASN.1 requirement that tags be | 326 /* XXX also enforce ASN.1 requirement that tags be |
327 distinct for consecutive optional components */ | 327 distinct for consecutive optional components */ |
328 | 328 |
329 return rv; | 329 return rv; |
330 } | 330 } |
331 | 331 |
332 #endif | 332 #endif |
333 | 333 |
334 static SECStatus DecodeItem(void* dest, | 334 static SECStatus DecodeItem(void* dest, |
335 const SEC_ASN1Template* templateEntry, | 335 const SEC_ASN1Template* templateEntry, |
336 SECItem* src, PRArenaPool* arena, PRBool checkTag); | 336 SECItem* src, PLArenaPool* arena, PRBool checkTag); |
337 | 337 |
338 static SECStatus DecodeSequence(void* dest, | 338 static SECStatus DecodeSequence(void* dest, |
339 const SEC_ASN1Template* templateEntry, | 339 const SEC_ASN1Template* templateEntry, |
340 SECItem* src, PRArenaPool* arena) | 340 SECItem* src, PLArenaPool* arena) |
341 { | 341 { |
342 SECStatus rv = SECSuccess; | 342 SECStatus rv = SECSuccess; |
343 SECItem source; | 343 SECItem source; |
344 SECItem sequence; | 344 SECItem sequence; |
345 const SEC_ASN1Template* sequenceTemplate = &(templateEntry[1]); | 345 const SEC_ASN1Template* sequenceTemplate = &(templateEntry[1]); |
346 const SEC_ASN1Template* sequenceEntry = NULL; | 346 const SEC_ASN1Template* sequenceEntry = NULL; |
347 unsigned long seqindex = 0; | 347 unsigned long seqindex = 0; |
348 | 348 |
349 #ifdef DEBUG | 349 #ifdef DEBUG |
350 /* for a sequence, we need to validate the template. */ | 350 /* for a sequence, we need to validate the template. */ |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 data in the DER that the template doesn't know about */ | 382 data in the DER that the template doesn't know about */ |
383 PORT_SetError(SEC_ERROR_BAD_DER); | 383 PORT_SetError(SEC_ERROR_BAD_DER); |
384 rv = SECFailure; | 384 rv = SECFailure; |
385 } | 385 } |
386 | 386 |
387 return rv; | 387 return rv; |
388 } | 388 } |
389 | 389 |
390 static SECStatus DecodeInline(void* dest, | 390 static SECStatus DecodeInline(void* dest, |
391 const SEC_ASN1Template* templateEntry, | 391 const SEC_ASN1Template* templateEntry, |
392 SECItem* src, PRArenaPool* arena, PRBool checkTag) | 392 SECItem* src, PLArenaPool* arena, PRBool checkTag) |
393 { | 393 { |
394 const SEC_ASN1Template* inlineTemplate = | 394 const SEC_ASN1Template* inlineTemplate = |
395 SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE); | 395 SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE); |
396 return DecodeItem((void*)((char*)dest + templateEntry->offset), | 396 return DecodeItem((void*)((char*)dest + templateEntry->offset), |
397 inlineTemplate, src, arena, checkTag); | 397 inlineTemplate, src, arena, checkTag); |
398 } | 398 } |
399 | 399 |
400 static SECStatus DecodePointer(void* dest, | 400 static SECStatus DecodePointer(void* dest, |
401 const SEC_ASN1Template* templateEntry, | 401 const SEC_ASN1Template* templateEntry, |
402 SECItem* src, PRArenaPool* arena, PRBool checkTag) | 402 SECItem* src, PLArenaPool* arena, PRBool checkTag) |
403 { | 403 { |
404 const SEC_ASN1Template* ptrTemplate = | 404 const SEC_ASN1Template* ptrTemplate = |
405 SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE); | 405 SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE); |
406 void* subdata = PORT_ArenaZAlloc(arena, ptrTemplate->size); | 406 void* subdata = PORT_ArenaZAlloc(arena, ptrTemplate->size); |
407 *(void**)((char*)dest + templateEntry->offset) = subdata; | 407 *(void**)((char*)dest + templateEntry->offset) = subdata; |
408 if (subdata) | 408 if (subdata) |
409 { | 409 { |
410 return DecodeItem(subdata, ptrTemplate, src, arena, checkTag); | 410 return DecodeItem(subdata, ptrTemplate, src, arena, checkTag); |
411 } | 411 } |
412 else | 412 else |
413 { | 413 { |
414 PORT_SetError(SEC_ERROR_NO_MEMORY); | 414 PORT_SetError(SEC_ERROR_NO_MEMORY); |
415 return SECFailure; | 415 return SECFailure; |
416 } | 416 } |
417 } | 417 } |
418 | 418 |
419 static SECStatus DecodeImplicit(void* dest, | 419 static SECStatus DecodeImplicit(void* dest, |
420 const SEC_ASN1Template* templateEntry, | 420 const SEC_ASN1Template* templateEntry, |
421 SECItem* src, PRArenaPool* arena) | 421 SECItem* src, PLArenaPool* arena) |
422 { | 422 { |
423 if (templateEntry->kind & SEC_ASN1_POINTER) | 423 if (templateEntry->kind & SEC_ASN1_POINTER) |
424 { | 424 { |
425 return DecodePointer((void*)((char*)dest ), | 425 return DecodePointer((void*)((char*)dest ), |
426 templateEntry, src, arena, PR_FALSE); | 426 templateEntry, src, arena, PR_FALSE); |
427 } | 427 } |
428 else | 428 else |
429 { | 429 { |
430 return DecodeInline((void*)((char*)dest ), | 430 return DecodeInline((void*)((char*)dest ), |
431 templateEntry, src, arena, PR_FALSE); | 431 templateEntry, src, arena, PR_FALSE); |
432 } | 432 } |
433 } | 433 } |
434 | 434 |
435 static SECStatus DecodeChoice(void* dest, | 435 static SECStatus DecodeChoice(void* dest, |
436 const SEC_ASN1Template* templateEntry, | 436 const SEC_ASN1Template* templateEntry, |
437 SECItem* src, PRArenaPool* arena) | 437 SECItem* src, PLArenaPool* arena) |
438 { | 438 { |
439 SECStatus rv = SECSuccess; | 439 SECStatus rv = SECSuccess; |
440 SECItem choice; | 440 SECItem choice; |
441 const SEC_ASN1Template* choiceTemplate = &(templateEntry[1]); | 441 const SEC_ASN1Template* choiceTemplate = &(templateEntry[1]); |
442 const SEC_ASN1Template* choiceEntry = NULL; | 442 const SEC_ASN1Template* choiceEntry = NULL; |
443 unsigned long choiceindex = 0; | 443 unsigned long choiceindex = 0; |
444 | 444 |
445 /* XXX for a choice component, we should validate the template to make | 445 /* XXX for a choice component, we should validate the template to make |
446 sure the tags are distinct, in debug builds. This hasn't been | 446 sure the tags are distinct, in debug builds. This hasn't been |
447 implemented yet */ | 447 implemented yet */ |
(...skipping 28 matching lines...) Expand all Loading... |
476 { | 476 { |
477 /* there is extra data that isn't listed in the template */ | 477 /* there is extra data that isn't listed in the template */ |
478 PORT_SetError(SEC_ERROR_BAD_DER); | 478 PORT_SetError(SEC_ERROR_BAD_DER); |
479 rv = SECFailure; | 479 rv = SECFailure; |
480 } | 480 } |
481 return rv; | 481 return rv; |
482 } | 482 } |
483 | 483 |
484 static SECStatus DecodeGroup(void* dest, | 484 static SECStatus DecodeGroup(void* dest, |
485 const SEC_ASN1Template* templateEntry, | 485 const SEC_ASN1Template* templateEntry, |
486 SECItem* src, PRArenaPool* arena) | 486 SECItem* src, PLArenaPool* arena) |
487 { | 487 { |
488 SECStatus rv = SECSuccess; | 488 SECStatus rv = SECSuccess; |
489 SECItem source; | 489 SECItem source; |
490 SECItem group; | 490 SECItem group; |
491 PRUint32 totalEntries = 0; | 491 PRUint32 totalEntries = 0; |
492 PRUint32 entryIndex = 0; | 492 PRUint32 entryIndex = 0; |
493 void** entries = NULL; | 493 void** entries = NULL; |
494 | 494 |
495 const SEC_ASN1Template* subTemplate = | 495 const SEC_ASN1Template* subTemplate = |
496 SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE); | 496 SEC_ASN1GetSubtemplate (templateEntry, dest, PR_FALSE); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 } while ( (SECSuccess == rv) && (group.len) ); | 564 } while ( (SECSuccess == rv) && (group.len) ); |
565 /* we should be at the end of the set by now */ | 565 /* we should be at the end of the set by now */ |
566 /* save the entries where requested */ | 566 /* save the entries where requested */ |
567 memcpy(((char*)dest + templateEntry->offset), &entries, sizeof(void**)); | 567 memcpy(((char*)dest + templateEntry->offset), &entries, sizeof(void**)); |
568 | 568 |
569 return rv; | 569 return rv; |
570 } | 570 } |
571 | 571 |
572 static SECStatus DecodeExplicit(void* dest, | 572 static SECStatus DecodeExplicit(void* dest, |
573 const SEC_ASN1Template* templateEntry, | 573 const SEC_ASN1Template* templateEntry, |
574 SECItem* src, PRArenaPool* arena) | 574 SECItem* src, PLArenaPool* arena) |
575 { | 575 { |
576 SECStatus rv = SECSuccess; | 576 SECStatus rv = SECSuccess; |
577 SECItem subItem; | 577 SECItem subItem; |
578 SECItem constructed = *src; | 578 SECItem constructed = *src; |
579 | 579 |
580 rv = GetItem(&constructed, &subItem, PR_FALSE); | 580 rv = GetItem(&constructed, &subItem, PR_FALSE); |
581 | 581 |
582 if (SECSuccess == rv) | 582 if (SECSuccess == rv) |
583 { | 583 { |
584 if (templateEntry->kind & SEC_ASN1_POINTER) | 584 if (templateEntry->kind & SEC_ASN1_POINTER) |
585 { | 585 { |
586 rv = DecodePointer(dest, templateEntry, &subItem, arena, PR_TRUE); | 586 rv = DecodePointer(dest, templateEntry, &subItem, arena, PR_TRUE); |
587 } | 587 } |
588 else | 588 else |
589 { | 589 { |
590 rv = DecodeInline(dest, templateEntry, &subItem, arena, PR_TRUE); | 590 rv = DecodeInline(dest, templateEntry, &subItem, arena, PR_TRUE); |
591 } | 591 } |
592 } | 592 } |
593 | 593 |
594 return rv; | 594 return rv; |
595 } | 595 } |
596 | 596 |
597 /* new decoder implementation. This is a recursive function */ | 597 /* new decoder implementation. This is a recursive function */ |
598 | 598 |
599 static SECStatus DecodeItem(void* dest, | 599 static SECStatus DecodeItem(void* dest, |
600 const SEC_ASN1Template* templateEntry, | 600 const SEC_ASN1Template* templateEntry, |
601 SECItem* src, PRArenaPool* arena, PRBool checkTag) | 601 SECItem* src, PLArenaPool* arena, PRBool checkTag) |
602 { | 602 { |
603 SECStatus rv = SECSuccess; | 603 SECStatus rv = SECSuccess; |
604 SECItem temp; | 604 SECItem temp; |
605 SECItem mark; | 605 SECItem mark; |
606 PRBool pop = PR_FALSE; | 606 PRBool pop = PR_FALSE; |
607 PRBool decode = PR_TRUE; | 607 PRBool decode = PR_TRUE; |
608 PRBool save = PR_FALSE; | 608 PRBool save = PR_FALSE; |
609 unsigned long kind; | 609 unsigned long kind; |
610 PRBool match = PR_TRUE; | 610 PRBool match = PR_TRUE; |
611 PRBool optional = PR_FALSE; | 611 PRBool optional = PR_FALSE; |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 if (PR_TRUE == pop) | 861 if (PR_TRUE == pop) |
862 { | 862 { |
863 /* we don't want to move ahead, so restore the position */ | 863 /* we don't want to move ahead, so restore the position */ |
864 *src = mark; | 864 *src = mark; |
865 } | 865 } |
866 return rv; | 866 return rv; |
867 } | 867 } |
868 | 868 |
869 /* the function below is the public one */ | 869 /* the function below is the public one */ |
870 | 870 |
871 SECStatus SEC_QuickDERDecodeItem(PRArenaPool* arena, void* dest, | 871 SECStatus SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest, |
872 const SEC_ASN1Template* templateEntry, | 872 const SEC_ASN1Template* templateEntry, |
873 const SECItem* src) | 873 const SECItem* src) |
874 { | 874 { |
875 SECStatus rv = SECSuccess; | 875 SECStatus rv = SECSuccess; |
876 SECItem newsrc; | 876 SECItem newsrc; |
877 | 877 |
878 if (!arena || !templateEntry || !src) | 878 if (!arena || !templateEntry || !src) |
879 { | 879 { |
880 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 880 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
881 rv = SECFailure; | 881 rv = SECFailure; |
882 } | 882 } |
883 | 883 |
884 if (SECSuccess == rv) | 884 if (SECSuccess == rv) |
885 { | 885 { |
886 newsrc = *src; | 886 newsrc = *src; |
887 rv = DecodeItem(dest, templateEntry, &newsrc, arena, PR_TRUE); | 887 rv = DecodeItem(dest, templateEntry, &newsrc, arena, PR_TRUE); |
888 if (SECSuccess == rv && newsrc.len) | 888 if (SECSuccess == rv && newsrc.len) |
889 { | 889 { |
890 rv = SECFailure; | 890 rv = SECFailure; |
891 PORT_SetError(SEC_ERROR_EXTRA_INPUT); | 891 PORT_SetError(SEC_ERROR_EXTRA_INPUT); |
892 } | 892 } |
893 } | 893 } |
894 | 894 |
895 return rv; | 895 return rv; |
896 } | 896 } |
897 | 897 |
OLD | NEW |