#include "DER_Ticket.h"
#include <libDER/asn1Types.h>
#include <libDER/DER_Decode.h>
#include <libDER/DER_Encode.h>
#include <libDER/DER_Keys.h>
const DERItemSpec DERApTicketItemSpecs[] =
{
{ DER_OFFSET(DERApTicket, signatureAlgorithm),
ASN1_CONSTR_SEQUENCE,
DER_DEC_NO_OPTS | DER_ENC_WRITE_DER },
{ DER_OFFSET(DERApTicket, body),
ASN1_CONSTR_SET,
DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER },
{ DER_OFFSET(DERApTicket, signature),
ASN1_OCTET_STRING,
DER_DEC_NO_OPTS },
{ DER_OFFSET(DERApTicket, certificates),
ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1,
DER_DEC_NO_OPTS | DER_ENC_WRITE_DER }
};
const DERSize DERNumApTicketItemSpecs =
sizeof(DERApTicketItemSpecs) / sizeof(DERItemSpec);
const DERItemSpec DERBbTicketItemSpecs[] =
{
{ DER_OFFSET(DERBbTicket, signatureAlgorithm),
ASN1_CONSTR_SEQUENCE,
DER_DEC_NO_OPTS | DER_ENC_WRITE_DER },
{ DER_OFFSET(DERBbTicket, body),
ASN1_CONSTR_SET,
DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER },
{ DER_OFFSET(DERBbTicket, signature),
ASN1_OCTET_STRING,
DER_DEC_NO_OPTS },
{ DER_OFFSET(DERBbTicket, gpuk),
ASN1_CONTEXT_SPECIFIC | 2,
DER_DEC_NO_OPTS }
};
const DERSize DERNumBbTicketItemSpecs =
sizeof(DERBbTicketItemSpecs) / sizeof(DERItemSpec);
#if 0
const DERByte rsaWithSha1Algorithm[] = {
0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05
};
#endif
#ifdef FAST_SET_LOOKUP
DERReturn DERDecodeSetContentInit(
const DERItem *content,
DERSet *derSet)
{
DERReturn drtn;
DERSequence derSeq;
memset(derSet->byTag, 0, derSet->capacity);
drtn = DERDecodeSeqContentInit(content, &derSeq);
if (drtn == DR_Success) {
DERDecodedInfo element;
while ((drtn = DERDecodeSeqNext(&derSeq, &element)) == DR_Success) {
if (element.tag >= derSet->capacity) return DR_UnexpectedTag;
derSet->byTag[element.tag] = element.content.data;
}
if (drtn == DR_EndOfSequence) drtn = DR_Success;
}
derSet->end = content->data + content->length;
return drtn;
}
DERReturn DERDecodeSetTag(
DERSet *derSet,
DERTag tag,
DERItem *content)
{
DERReturn drtn;
DERTag tagNumber = tag & ASN1_TAGNUM_MASK;
if (tagNumber > derSet->capacity)
return DR_UnexpectedTag;
DERByte *start = derSet->byTag[tagNumber];
if (!start) return DR_UnexpectedTag;
DERItem derItem = { .data = start, .length = derSet->end - start };
DERDecodedInfo element;
drtn = DERDecodeItem(&derItem, &element);
if (drtn) return drtn;
if (tag != element.tag) return DR_UnexpectedTag;
*content = element.content;
return drtn;
}
#endif
DERReturn DERSetDecodeItemWithTag(
const DERItem *der,
DERTag tag,
DERItem *content)
{
DERReturn drtn;
DERSequence derSeq;
DERTag topTag;
drtn = DERDecodeSeqInit(der, &topTag, &derSeq);
if (drtn == DR_Success) {
DERDecodedInfo info;
while ((drtn = DERDecodeSeqNext(&derSeq, &info)) == DR_Success) {
if (info.tag == tag) {
*content = info.content;
return DR_Success;
}
}
}
return drtn;
}
DERReturn DERDecodeApTicket(
const DERItem *contents,
DERApTicket *ticket,
DERSize *numUsedBytes)
{
DERReturn drtn;
DERDecodedInfo decodedTicket;
drtn = DERDecodeItem(contents, &decodedTicket);
if (drtn != DR_Success) goto badTicket;
drtn = DERParseSequenceContent(&decodedTicket.content,
DERNumApTicketItemSpecs, DERApTicketItemSpecs, ticket, 0);
if (drtn != DR_Success) goto badTicket;
DERAlgorithmId algorithm = {};
drtn = DERParseSequenceContent(&ticket->signatureAlgorithm,
DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs, &algorithm, 0);
if (drtn != DR_Success) goto badTicket;
badTicket:
*numUsedBytes = decodedTicket.content.length +
decodedTicket.content.data - contents->data;
return drtn;
}
DERReturn DERDecodeBbTicket(
const DERItem *contents,
DERBbTicket *ticket,
DERSize *numUsedBytes)
{
DERReturn drtn;
DERDecodedInfo decodedTicket;
drtn = DERDecodeItem(contents, &decodedTicket);
if (drtn != DR_Success) goto badTicket;
drtn = DERParseSequenceContent(&decodedTicket.content,
DERNumBbTicketItemSpecs, DERBbTicketItemSpecs, ticket, 0);
if (drtn != DR_Success) goto badTicket;
DERAlgorithmId algorithm = {};
drtn = DERParseSequenceContent(&ticket->signatureAlgorithm,
DERNumAlgorithmIdItemSpecs, DERAlgorithmIdItemSpecs, &algorithm, 0);
if (drtn != DR_Success) goto badTicket;
badTicket:
*numUsedBytes = decodedTicket.content.length +
decodedTicket.content.data - contents->data;
return drtn;
}