5 * Created by Michael Brouwer on 10/13/09.
6 * Copyright 2009 Apple Inc. All rights reserved.
10 #include "DER_Ticket.h"
12 #include <libDER/asn1Types.h>
13 #include <libDER/DER_Decode.h>
14 #include <libDER/DER_Encode.h>
15 #include <libDER/DER_Keys.h>
17 /* Application Processor Ticket */
18 const DERItemSpec DERApTicketItemSpecs
[] =
20 { DER_OFFSET(DERApTicket
, signatureAlgorithm
),
22 DER_DEC_NO_OPTS
| DER_ENC_WRITE_DER
},
23 { DER_OFFSET(DERApTicket
, body
),
25 DER_DEC_NO_OPTS
| DER_DEC_SAVE_DER
| DER_ENC_WRITE_DER
},
26 { DER_OFFSET(DERApTicket
, signature
),
29 { DER_OFFSET(DERApTicket
, certificates
),
30 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| 1,
31 DER_DEC_NO_OPTS
| DER_ENC_WRITE_DER
}
33 const DERSize DERNumApTicketItemSpecs
=
34 sizeof(DERApTicketItemSpecs
) / sizeof(DERItemSpec
);
37 const DERItemSpec DERBbTicketItemSpecs
[] =
39 { DER_OFFSET(DERBbTicket
, signatureAlgorithm
),
41 DER_DEC_NO_OPTS
| DER_ENC_WRITE_DER
},
42 { DER_OFFSET(DERBbTicket
, body
),
44 DER_DEC_NO_OPTS
| DER_DEC_SAVE_DER
| DER_ENC_WRITE_DER
},
45 { DER_OFFSET(DERBbTicket
, signature
),
48 { DER_OFFSET(DERBbTicket
, gpuk
),
49 ASN1_CONTEXT_SPECIFIC
| 2,
52 const DERSize DERNumBbTicketItemSpecs
=
53 sizeof(DERBbTicketItemSpecs
) / sizeof(DERItemSpec
);
56 /* We need to verify this value and use it here. */
57 const DERByte rsaWithSha1Algorithm
[] = {
58 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05
62 #ifdef FAST_SET_LOOKUP
63 /* Iterates over all the tags in the set to build an index returned in
65 DERReturn
DERDecodeSetContentInit(
66 const DERItem
*content
, /* data to decode */
67 DERSet
*derSet
) /* IN/OUT, to use in DERDecodeSetTag */
71 memset(derSet
->byTag
, 0, derSet
->capacity
);
72 drtn
= DERDecodeSeqContentInit(content
, &derSeq
);
73 if (drtn
== DR_Success
) {
74 DERDecodedInfo element
;
75 while ((drtn
= DERDecodeSeqNext(&derSeq
, &element
)) == DR_Success
) {
76 if (element
.tag
>= derSet
->capacity
) return DR_UnexpectedTag
;
77 derSet
->byTag
[element
.tag
] = element
.content
.data
;
79 if (drtn
== DR_EndOfSequence
) drtn
= DR_Success
;
81 derSet
->end
= content
->data
+ content
->length
;
86 DERReturn
DERDecodeSetTag(
87 DERSet
*derSet
, /* data to decode */
88 DERTag tag
, /* tag in sequence/set we are looking for. */
89 DERItem
*content
) /* RETURNED */
92 DERTag tagNumber
= tag
& ASN1_TAGNUM_MASK
;
93 if (tagNumber
> derSet
->capacity
)
94 return DR_UnexpectedTag
;
95 DERByte
*start
= derSet
->byTag
[tagNumber
];
96 if (!start
) return DR_UnexpectedTag
;
97 DERItem derItem
= { .data
= start
, .length
= derSet
->end
- start
};
98 DERDecodedInfo element
;
99 drtn
= DERDecodeItem(&derItem
, &element
);
100 if (drtn
) return drtn
;
101 if (tag
!= element
.tag
) return DR_UnexpectedTag
;
102 *content
= element
.content
;
106 #endif /* FAST_SET_LOOKUP */
108 /* Returns the item with tag from the sequence or set pointed to by der.
109 result DR_EndOfSequence if the tag was not found. */
110 DERReturn
DERSetDecodeItemWithTag(
111 const DERItem
*der
, /* data to decode */
112 DERTag tag
, /* tag in sequence/set we are looking for. */
113 DERItem
*content
) /* RETURNED */
118 drtn
= DERDecodeSeqInit(der
, &topTag
, &derSeq
);
119 if (drtn
== DR_Success
) {
121 while ((drtn
= DERDecodeSeqNext(&derSeq
, &info
)) == DR_Success
) {
122 if (info
.tag
== tag
) {
123 *content
= info
.content
;
132 DERReturn
DERDecodeApTicket(
133 const DERItem
*contents
,
134 DERApTicket
*ticket
, /* RETURNED */
135 DERSize
*numUsedBytes
) /* RETURNED */
138 DERDecodedInfo decodedTicket
;
139 drtn
= DERDecodeItem(contents
, &decodedTicket
);
140 if (drtn
!= DR_Success
) goto badTicket
;
141 drtn
= DERParseSequenceContent(&decodedTicket
.content
,
142 DERNumApTicketItemSpecs
, DERApTicketItemSpecs
, ticket
, 0);
143 if (drtn
!= DR_Success
) goto badTicket
;
145 /* Decode the algorithm sequence. */
146 DERAlgorithmId algorithm
= {};
147 drtn
= DERParseSequenceContent(&ticket
->signatureAlgorithm
,
148 DERNumAlgorithmIdItemSpecs
, DERAlgorithmIdItemSpecs
, &algorithm
, 0);
149 if (drtn
!= DR_Success
) goto badTicket
;
150 /* TODO Check algorithm oid and ensure there are no params.
151 Alternatively replace the code above with a simple memcmp with
152 an already ASN.1 encoded algorithm parms block. */
155 *numUsedBytes
= decodedTicket
.content
.length
+
156 decodedTicket
.content
.data
- contents
->data
;
161 DERReturn
DERDecodeBbTicket(
162 const DERItem
*contents
,
163 DERBbTicket
*ticket
, /* RETURNED */
164 DERSize
*numUsedBytes
) /* RETURNED */
167 DERDecodedInfo decodedTicket
;
168 drtn
= DERDecodeItem(contents
, &decodedTicket
);
169 if (drtn
!= DR_Success
) goto badTicket
;
170 drtn
= DERParseSequenceContent(&decodedTicket
.content
,
171 DERNumBbTicketItemSpecs
, DERBbTicketItemSpecs
, ticket
, 0);
172 if (drtn
!= DR_Success
) goto badTicket
;
174 /* Decode the algorithm sequence. */
175 DERAlgorithmId algorithm
= {};
176 drtn
= DERParseSequenceContent(&ticket
->signatureAlgorithm
,
177 DERNumAlgorithmIdItemSpecs
, DERAlgorithmIdItemSpecs
, &algorithm
, 0);
178 if (drtn
!= DR_Success
) goto badTicket
;
179 /* TODO Check algorithm oid and ensure there are no params.
180 Alternatively replace the code above with a simple memcmp with
181 an already ASN.1 encoded algorithm parms block. */
184 *numUsedBytes
= decodedTicket
.content
.length
+
185 decodedTicket
.content
.data
- contents
->data
;