/* * To decode a set or sequence, call DERDecodeSeqInit once, then * call DERDecodeSeqNext to get each enclosed item. * DERDecodeSeqNext returns DR_EndOfSequence when no more * items are available. */ DERReturn DERDecodeSeqInit( const DERItem *der, /* data to decode */ DERTag *tag, /* RETURNED tag of sequence/set. This will be * either ASN1_CONSTR_SEQUENCE or ASN1_CONSTR_SET. */ DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ { DERDecodedInfo decoded; DERReturn drtn; drtn = DERDecodeItem(der, &decoded); if(drtn) { return drtn; } *tag = decoded.tag; switch(decoded.tag) { case ASN1_CONSTR_SEQUENCE: case ASN1_CONSTR_SET: break; default: return DR_UnexpectedTag; } derSeq->nextItem = decoded.content.data; derSeq->end = decoded.content.data + decoded.content.length; return DR_Success; }
int DERImg4Decode(const DERItem *a1, DERItem *a2) { int rv; DERDecodedInfo var_38; if (a1 == NULL || a2 == NULL) { return DR_ParamErr; } rv = DERDecodeItem(a1, &var_38); if (rv) { return rv; } if (var_38.tag != ASN1_CONSTR_SEQUENCE) { return DR_UnexpectedTag; } if (a1->data + a1->length != var_38.content.data + var_38.content.length) { return DR_BufOverflow; } rv = DERParseSequenceContent(&var_38.content, 4, DERImg4ItemSpecs, a2, 0); if (rv) { return rv; } if (DERImg4DecodeTagCompare(a2, 'IMG4')) { return DR_UnexpectedTag; } return 0; }
int DERDecodeTimeStampResponse( const CSSM_DATA *contents, CSSM_DATA *derStatus, CSSM_DATA *derTimeStampToken, size_t *numUsedBytes) /* RETURNED */ { DERReturn drtn = DR_ParamErr; DERDecodedInfo decodedPackage; if (contents) { DERItem derContents = {.data = contents->Data, .length = contents->Length }; DERTimeStampResp derResponse = {{0,},{0,}}; DERReturn rx; require_noerr(DERDecodeItem(&derContents, &decodedPackage), badResponse); rx = DERParseSequenceContent(&decodedPackage.content, DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, &derResponse, 0); if (rx != DR_Success) goto badResponse; /* require_noerr(DERParseSequenceContent(&decodedPackage.content, DERNumTimeStampRespItemSpecs, DERTimeStampRespItemSpecs, &derResponse, 0), badResponse); */ if (derStatus && derResponse.status.data) { derStatus->Data = malloc(derResponse.status.length); derStatus->Length = derResponse.status.length; memcpy(derStatus->Data, derResponse.status.data, derStatus->Length); } if (derTimeStampToken && derResponse.timeStampToken.data) { derTimeStampToken->Data = malloc(derResponse.timeStampToken.length); derTimeStampToken->Length = derResponse.timeStampToken.length; memcpy(derTimeStampToken->Data, derResponse.timeStampToken.data, derTimeStampToken->Length); } } drtn = DR_Success; badResponse: if (numUsedBytes) *numUsedBytes = decodedPackage.content.length + decodedPackage.content.data - contents->Data; return drtn; }
/* decode one item and print it */ void decodePrintItem( const char *label, ItemType itemType, int verbose, DERItem *derItem) { DERDecodedInfo decoded; DERReturn drtn; drtn = DERDecodeItem(derItem, &decoded); if(drtn) { DERPerror("DERDecodeItem()", drtn); return; } printItem(label, IT_Leaf, 0, decoded.tag, &decoded.content); }
/* * High level set of parse, starting with top-level tag and content. * Top level tag must be ASN1_CONSTR_SET - if it's not, and that's * OK, use DERParseSetOrSequenceOfContent(). */ DERReturn DERParseSetOf( const DERItem *der, DERShort numItems, /* size of itemSpecs[] */ const DERItemSpec *itemSpecs, void *dest, /* DERDecodedInfo(s) here RETURNED */ DERSize *numDestItems) /* output */ { DERReturn drtn; DERDecodedInfo topDecode; drtn = DERDecodeItem(der, &topDecode); if(drtn) { return drtn; } if(topDecode.tag != ASN1_CONSTR_SET) { return DR_UnexpectedTag; } return DERParseSetOrSequenceOfContent(&topDecode.content, numItems, itemSpecs, dest, numDestItems); }
/* * High level sequence parse, starting with top-level tag and content. * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's * OK, use DERParseSequenceContent(). */ DERReturn DERParseSequence( const DERItem *der, DERShort numItems, /* size of itemSpecs[] */ const DERItemSpec *itemSpecs, void *dest, /* DERDecodedInfo(s) here RETURNED */ DERSize sizeToZero) /* optional */ { DERReturn drtn; DERDecodedInfo topDecode; drtn = DERDecodeItem(der, &topDecode); if(drtn) { return drtn; } if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { return DR_UnexpectedTag; } return DERParseSequenceContent(&topDecode.content, numItems, itemSpecs, dest, sizeToZero); }
DERReturn DERDecodeSeqNext( DERSequence *derSeq, DERDecodedInfo *decoded) /* RETURNED */ { DERReturn drtn; DERItem item; if(derSeq->nextItem >= derSeq->end) { /* normal termination, contents all used up */ return DR_EndOfSequence; } /* decode next item */ item.data = derSeq->nextItem; item.length = derSeq->end - derSeq->nextItem; drtn = DERDecodeItem(&item, decoded); if(drtn) { return drtn; } /* skip over the item we just decoded */ derSeq->nextItem = decoded->content.data + decoded->content.length; return DR_Success; }