/* 
 * 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;
}
Example #2
0
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;
}
Example #4
0
/* 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;
}