2 * Copyright (c) 2009,2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include "DER_Ticket.h"
27 #include <libDER/asn1Types.h>
28 #include <libDER/DER_Decode.h>
29 #include <libDER/DER_Encode.h>
30 #include <libDER/DER_Keys.h>
32 /* Application Processor Ticket */
33 const DERItemSpec DERApTicketItemSpecs
[] =
35 { DER_OFFSET(DERApTicket
, signatureAlgorithm
),
37 DER_DEC_NO_OPTS
| DER_ENC_WRITE_DER
},
38 { DER_OFFSET(DERApTicket
, body
),
40 DER_DEC_NO_OPTS
| DER_DEC_SAVE_DER
| DER_ENC_WRITE_DER
},
41 { DER_OFFSET(DERApTicket
, signature
),
44 { DER_OFFSET(DERApTicket
, certificates
),
45 ASN1_CONTEXT_SPECIFIC
| ASN1_CONSTRUCTED
| 1,
46 DER_DEC_NO_OPTS
| DER_ENC_WRITE_DER
}
48 const DERSize DERNumApTicketItemSpecs
=
49 sizeof(DERApTicketItemSpecs
) / sizeof(DERItemSpec
);
52 const DERItemSpec DERBbTicketItemSpecs
[] =
54 { DER_OFFSET(DERBbTicket
, signatureAlgorithm
),
56 DER_DEC_NO_OPTS
| DER_ENC_WRITE_DER
},
57 { DER_OFFSET(DERBbTicket
, body
),
59 DER_DEC_NO_OPTS
| DER_DEC_SAVE_DER
| DER_ENC_WRITE_DER
},
60 { DER_OFFSET(DERBbTicket
, signature
),
63 { DER_OFFSET(DERBbTicket
, gpuk
),
64 ASN1_CONTEXT_SPECIFIC
| 2,
67 const DERSize DERNumBbTicketItemSpecs
=
68 sizeof(DERBbTicketItemSpecs
) / sizeof(DERItemSpec
);
71 /* We need to verify this value and use it here. */
72 const DERByte rsaWithSha1Algorithm
[] = {
73 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05
77 #ifdef FAST_SET_LOOKUP
78 /* Iterates over all the tags in the set to build an index returned in
80 DERReturn
DERDecodeSetContentInit(
81 const DERItem
*content
, /* data to decode */
82 DERSet
*derSet
) /* IN/OUT, to use in DERDecodeSetTag */
86 memset(derSet
->byTag
, 0, derSet
->capacity
);
87 drtn
= DERDecodeSeqContentInit(content
, &derSeq
);
88 if (drtn
== DR_Success
) {
89 DERDecodedInfo element
;
90 while ((drtn
= DERDecodeSeqNext(&derSeq
, &element
)) == DR_Success
) {
91 if (element
.tag
>= derSet
->capacity
) return DR_UnexpectedTag
;
92 derSet
->byTag
[element
.tag
] = element
.content
.data
;
94 if (drtn
== DR_EndOfSequence
) drtn
= DR_Success
;
96 derSet
->end
= content
->data
+ content
->length
;
101 DERReturn
DERDecodeSetTag(
102 DERSet
*derSet
, /* data to decode */
103 DERTag tag
, /* tag in sequence/set we are looking for. */
104 DERItem
*content
) /* RETURNED */
107 DERTag tagNumber
= tag
& ASN1_TAGNUM_MASK
;
108 if (tagNumber
> derSet
->capacity
)
109 return DR_UnexpectedTag
;
110 DERByte
*start
= derSet
->byTag
[tagNumber
];
111 if (!start
) return DR_UnexpectedTag
;
112 DERItem derItem
= { .data
= start
, .length
= derSet
->end
- start
};
113 DERDecodedInfo element
;
114 drtn
= DERDecodeItem(&derItem
, &element
);
115 if (drtn
) return drtn
;
116 if (tag
!= element
.tag
) return DR_UnexpectedTag
;
117 *content
= element
.content
;
121 #endif /* FAST_SET_LOOKUP */
123 /* Returns the item with tag from the sequence or set pointed to by der.
124 result DR_EndOfSequence if the tag was not found. */
125 DERReturn
DERSetDecodeItemWithTag(
126 const DERItem
*der
, /* data to decode */
127 DERTag tag
, /* tag in sequence/set we are looking for. */
128 DERItem
*content
) /* RETURNED */
133 drtn
= DERDecodeSeqInit(der
, &topTag
, &derSeq
);
134 if (drtn
== DR_Success
) {
136 while ((drtn
= DERDecodeSeqNext(&derSeq
, &info
)) == DR_Success
) {
137 if (info
.tag
== tag
) {
138 *content
= info
.content
;
147 DERReturn
DERDecodeApTicket(
148 const DERItem
*contents
,
149 DERApTicket
*ticket
, /* RETURNED */
150 DERSize
*numUsedBytes
) /* RETURNED */
153 DERDecodedInfo decodedTicket
;
154 drtn
= DERDecodeItem(contents
, &decodedTicket
);
155 if (drtn
!= DR_Success
) goto badTicket
;
156 drtn
= DERParseSequenceContent(&decodedTicket
.content
,
157 DERNumApTicketItemSpecs
, DERApTicketItemSpecs
, ticket
, 0);
158 if (drtn
!= DR_Success
) goto badTicket
;
160 /* Decode the algorithm sequence. */
161 DERAlgorithmId algorithm
= {};
162 drtn
= DERParseSequenceContent(&ticket
->signatureAlgorithm
,
163 DERNumAlgorithmIdItemSpecs
, DERAlgorithmIdItemSpecs
, &algorithm
, 0);
164 if (drtn
!= DR_Success
) goto badTicket
;
165 /* TODO Check algorithm oid and ensure there are no params.
166 Alternatively replace the code above with a simple memcmp with
167 an already ASN.1 encoded algorithm parms block. */
170 *numUsedBytes
= decodedTicket
.content
.length
+
171 decodedTicket
.content
.data
- contents
->data
;
176 DERReturn
DERDecodeBbTicket(
177 const DERItem
*contents
,
178 DERBbTicket
*ticket
, /* RETURNED */
179 DERSize
*numUsedBytes
) /* RETURNED */
182 DERDecodedInfo decodedTicket
;
183 drtn
= DERDecodeItem(contents
, &decodedTicket
);
184 if (drtn
!= DR_Success
) goto badTicket
;
185 drtn
= DERParseSequenceContent(&decodedTicket
.content
,
186 DERNumBbTicketItemSpecs
, DERBbTicketItemSpecs
, ticket
, 0);
187 if (drtn
!= DR_Success
) goto badTicket
;
189 /* Decode the algorithm sequence. */
190 DERAlgorithmId algorithm
= {};
191 drtn
= DERParseSequenceContent(&ticket
->signatureAlgorithm
,
192 DERNumAlgorithmIdItemSpecs
, DERAlgorithmIdItemSpecs
, &algorithm
, 0);
193 if (drtn
!= DR_Success
) goto badTicket
;
194 /* TODO Check algorithm oid and ensure there are no params.
195 Alternatively replace the code above with a simple memcmp with
196 an already ASN.1 encoded algorithm parms block. */
199 *numUsedBytes
= decodedTicket
.content
.length
+
200 decodedTicket
.content
.data
- contents
->data
;