]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_keychain/libDER/Tests/DER_Ticket.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_keychain / libDER / Tests / DER_Ticket.c
1 /*
2 * Copyright (c) 2009,2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #include "DER_Ticket.h"
26
27 #include <libDER/asn1Types.h>
28 #include <libDER/DER_Decode.h>
29 #include <libDER/DER_Encode.h>
30 #include <libDER/DER_Keys.h>
31
32 /* Application Processor Ticket */
33 const DERItemSpec DERApTicketItemSpecs[] =
34 {
35 { DER_OFFSET(DERApTicket, signatureAlgorithm),
36 ASN1_CONSTR_SEQUENCE,
37 DER_DEC_NO_OPTS | DER_ENC_WRITE_DER },
38 { DER_OFFSET(DERApTicket, body),
39 ASN1_CONSTR_SET,
40 DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER },
41 { DER_OFFSET(DERApTicket, signature),
42 ASN1_OCTET_STRING,
43 DER_DEC_NO_OPTS },
44 { DER_OFFSET(DERApTicket, certificates),
45 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1,
46 DER_DEC_NO_OPTS | DER_ENC_WRITE_DER }
47 };
48 const DERSize DERNumApTicketItemSpecs =
49 sizeof(DERApTicketItemSpecs) / sizeof(DERItemSpec);
50
51 /* Baseband Ticket */
52 const DERItemSpec DERBbTicketItemSpecs[] =
53 {
54 { DER_OFFSET(DERBbTicket, signatureAlgorithm),
55 ASN1_CONSTR_SEQUENCE,
56 DER_DEC_NO_OPTS | DER_ENC_WRITE_DER },
57 { DER_OFFSET(DERBbTicket, body),
58 ASN1_CONSTR_SET,
59 DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER },
60 { DER_OFFSET(DERBbTicket, signature),
61 ASN1_OCTET_STRING,
62 DER_DEC_NO_OPTS },
63 { DER_OFFSET(DERBbTicket, gpuk),
64 ASN1_CONTEXT_SPECIFIC | 2,
65 DER_DEC_NO_OPTS }
66 };
67 const DERSize DERNumBbTicketItemSpecs =
68 sizeof(DERBbTicketItemSpecs) / sizeof(DERItemSpec);
69
70 #if 0
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
74 };
75 #endif
76
77 #ifdef FAST_SET_LOOKUP
78 /* Iterates over all the tags in the set to build an index returned in
79 derSet. */
80 DERReturn DERDecodeSetContentInit(
81 const DERItem *content, /* data to decode */
82 DERSet *derSet) /* IN/OUT, to use in DERDecodeSetTag */
83 {
84 DERReturn drtn;
85 DERSequence derSeq;
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;
93 }
94 if (drtn == DR_EndOfSequence) drtn = DR_Success;
95 }
96 derSet->end = content->data + content->length;
97
98 return drtn;
99 }
100
101 DERReturn DERDecodeSetTag(
102 DERSet *derSet, /* data to decode */
103 DERTag tag, /* tag in sequence/set we are looking for. */
104 DERItem *content) /* RETURNED */
105 {
106 DERReturn drtn;
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;
118
119 return drtn;
120 }
121 #endif /* FAST_SET_LOOKUP */
122
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 */
129 {
130 DERReturn drtn;
131 DERSequence derSeq;
132 DERTag topTag;
133 drtn = DERDecodeSeqInit(der, &topTag, &derSeq);
134 if (drtn == DR_Success) {
135 DERDecodedInfo info;
136 while ((drtn = DERDecodeSeqNext(&derSeq, &info)) == DR_Success) {
137 if (info.tag == tag) {
138 *content = info.content;
139 return DR_Success;
140 }
141 }
142 }
143
144 return drtn;
145 }
146
147 DERReturn DERDecodeApTicket(
148 const DERItem *contents,
149 DERApTicket *ticket, /* RETURNED */
150 DERSize *numUsedBytes) /* RETURNED */
151 {
152 DERReturn drtn;
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;
159
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. */
168
169 badTicket:
170 *numUsedBytes = decodedTicket.content.length +
171 decodedTicket.content.data - contents->data;
172
173 return drtn;
174 }
175
176 DERReturn DERDecodeBbTicket(
177 const DERItem *contents,
178 DERBbTicket *ticket, /* RETURNED */
179 DERSize *numUsedBytes) /* RETURNED */
180 {
181 DERReturn drtn;
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;
188
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. */
197
198 badTicket:
199 *numUsedBytes = decodedTicket.content.length +
200 decodedTicket.content.data - contents->data;
201
202 return drtn;
203 }