#include <libDER/asn1Types.h>
#include <libDER/DER_Decode.h>
#include <AssertMacros.h>
#include <Security/cssmtype.h>
#include <stdlib.h>
#include "tsaDERUtilities.h"
#ifndef DER_MULTIBYTE_TAGS
#error We expect DER_MULTIBYTE_TAGS
#endif
typedef struct {
DERItem status; DERItem statusString; DERItem failInfo; } DERPKIStatusInfo;
typedef struct {
DERItem statusString; } DERPKIStatusStringInner;
typedef struct
{
DERItem status;
DERItem timeStampToken;
} DERTimeStampResp;
const DERItemSpec DERTimeStampRespItemSpecs[] =
{
{ DER_OFFSET(DERTimeStampResp, status),
ASN1_CONSTR_SEQUENCE, DER_DEC_NO_OPTS },
{ DER_OFFSET(DERTimeStampResp, timeStampToken),
ASN1_CONSTR_SEQUENCE, DER_DEC_NO_OPTS | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER}
};
const DERSize DERNumTimeStampRespItemSpecs = sizeof(DERTimeStampRespItemSpecs) / sizeof(DERItemSpec);
int DERDecodeTimeStampResponse(
const CSSM_DATA *contents,
CSSM_DATA *derStatus,
CSSM_DATA *derTimeStampToken,
size_t *numUsedBytes)
{
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;
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 ? contents->Data : 0);
return drtn;
}