]> git.saurik.com Git - apple/security.git/blob - libsecurity_keychain/libDER/Tests/DER_Ticket.c
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_keychain / libDER / Tests / DER_Ticket.c
1 /*
2 * DER_Ticket.c
3 * libDER
4 *
5 * Created by Michael Brouwer on 10/13/09.
6 * Copyright 2009 Apple Inc. All rights reserved.
7 *
8 */
9
10 #include "DER_Ticket.h"
11
12 #include <libDER/asn1Types.h>
13 #include <libDER/DER_Decode.h>
14 #include <libDER/DER_Encode.h>
15 #include <libDER/DER_Keys.h>
16
17 /* Application Processor Ticket */
18 const DERItemSpec DERApTicketItemSpecs[] =
19 {
20 { DER_OFFSET(DERApTicket, signatureAlgorithm),
21 ASN1_CONSTR_SEQUENCE,
22 DER_DEC_NO_OPTS | DER_ENC_WRITE_DER },
23 { DER_OFFSET(DERApTicket, body),
24 ASN1_CONSTR_SET,
25 DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER },
26 { DER_OFFSET(DERApTicket, signature),
27 ASN1_OCTET_STRING,
28 DER_DEC_NO_OPTS },
29 { DER_OFFSET(DERApTicket, certificates),
30 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1,
31 DER_DEC_NO_OPTS | DER_ENC_WRITE_DER }
32 };
33 const DERSize DERNumApTicketItemSpecs =
34 sizeof(DERApTicketItemSpecs) / sizeof(DERItemSpec);
35
36 /* Baseband Ticket */
37 const DERItemSpec DERBbTicketItemSpecs[] =
38 {
39 { DER_OFFSET(DERBbTicket, signatureAlgorithm),
40 ASN1_CONSTR_SEQUENCE,
41 DER_DEC_NO_OPTS | DER_ENC_WRITE_DER },
42 { DER_OFFSET(DERBbTicket, body),
43 ASN1_CONSTR_SET,
44 DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER },
45 { DER_OFFSET(DERBbTicket, signature),
46 ASN1_OCTET_STRING,
47 DER_DEC_NO_OPTS },
48 { DER_OFFSET(DERBbTicket, gpuk),
49 ASN1_CONTEXT_SPECIFIC | 2,
50 DER_DEC_NO_OPTS }
51 };
52 const DERSize DERNumBbTicketItemSpecs =
53 sizeof(DERBbTicketItemSpecs) / sizeof(DERItemSpec);
54
55 #if 0
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
59 };
60 #endif
61
62 #ifdef FAST_SET_LOOKUP
63 /* Iterates over all the tags in the set to build an index returned in
64 derSet. */
65 DERReturn DERDecodeSetContentInit(
66 const DERItem *content, /* data to decode */
67 DERSet *derSet) /* IN/OUT, to use in DERDecodeSetTag */
68 {
69 DERReturn drtn;
70 DERSequence derSeq;
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;
78 }
79 if (drtn == DR_EndOfSequence) drtn = DR_Success;
80 }
81 derSet->end = content->data + content->length;
82
83 return drtn;
84 }
85
86 DERReturn DERDecodeSetTag(
87 DERSet *derSet, /* data to decode */
88 DERTag tag, /* tag in sequence/set we are looking for. */
89 DERItem *content) /* RETURNED */
90 {
91 DERReturn drtn;
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;
103
104 return drtn;
105 }
106 #endif /* FAST_SET_LOOKUP */
107
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 */
114 {
115 DERReturn drtn;
116 DERSequence derSeq;
117 DERTag topTag;
118 drtn = DERDecodeSeqInit(der, &topTag, &derSeq);
119 if (drtn == DR_Success) {
120 DERDecodedInfo info;
121 while ((drtn = DERDecodeSeqNext(&derSeq, &info)) == DR_Success) {
122 if (info.tag == tag) {
123 *content = info.content;
124 return DR_Success;
125 }
126 }
127 }
128
129 return drtn;
130 }
131
132 DERReturn DERDecodeApTicket(
133 const DERItem *contents,
134 DERApTicket *ticket, /* RETURNED */
135 DERSize *numUsedBytes) /* RETURNED */
136 {
137 DERReturn drtn;
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;
144
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. */
153
154 badTicket:
155 *numUsedBytes = decodedTicket.content.length +
156 decodedTicket.content.data - contents->data;
157
158 return drtn;
159 }
160
161 DERReturn DERDecodeBbTicket(
162 const DERItem *contents,
163 DERBbTicket *ticket, /* RETURNED */
164 DERSize *numUsedBytes) /* RETURNED */
165 {
166 DERReturn drtn;
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;
173
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. */
182
183 badTicket:
184 *numUsedBytes = decodedTicket.content.length +
185 decodedTicket.content.data - contents->data;
186
187 return drtn;
188 }