1/*
2 * Copyright (c) 2005-2009,2011,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/*
26 * DER_Cert.c - support for decoding X509 certificates
27 *
28 */
29
30#include <libDER/DER_Decode.h>
31#include <libDER/DER_CertCrl.h>
32#include <libDER/asn1Types.h>
33
34/*
35 * DERItemSpecs for X509 certificates.
36 */
37
38/* top level cert with three components */
39const DERItemSpec DERSignedCertCrlItemSpecs[] =
40{
41	{ DER_OFFSET(DERSignedCertCrl, tbs),
42			ASN1_CONSTR_SEQUENCE,
43			DER_DEC_NO_OPTS | DER_DEC_SAVE_DER},
44	{ DER_OFFSET(DERSignedCertCrl, sigAlg),
45			ASN1_CONSTR_SEQUENCE,
46			DER_DEC_NO_OPTS },
47	{ DER_OFFSET(DERSignedCertCrl, sig),
48			ASN1_BIT_STRING,
49			DER_DEC_NO_OPTS }
50};
51
52const DERSize DERNumSignedCertCrlItemSpecs =
53	sizeof(DERSignedCertCrlItemSpecs) / sizeof(DERItemSpec);
54
55/* TBS cert */
56const DERItemSpec DERTBSCertItemSpecs[] =
57{
58	{ DER_OFFSET(DERTBSCert, version),
59			ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0,
60			DER_DEC_OPTIONAL },						/* version - EXPLICIT */
61	{ DER_OFFSET(DERTBSCert, serialNum),
62			ASN1_INTEGER,
63			DER_DEC_NO_OPTS },
64	{ DER_OFFSET(DERTBSCert, tbsSigAlg),
65			ASN1_CONSTR_SEQUENCE,
66			DER_DEC_NO_OPTS },
67	{ DER_OFFSET(DERTBSCert, issuer),
68			ASN1_CONSTR_SEQUENCE,
69			DER_DEC_NO_OPTS },
70	{ DER_OFFSET(DERTBSCert, validity),
71			ASN1_CONSTR_SEQUENCE,
72			DER_DEC_NO_OPTS },
73	{ DER_OFFSET(DERTBSCert, subject),
74			ASN1_CONSTR_SEQUENCE,
75			DER_DEC_NO_OPTS },
76	{ DER_OFFSET(DERTBSCert, subjectPubKey),
77			ASN1_CONSTR_SEQUENCE,
78			DER_DEC_NO_OPTS },
79	/* libsecurity_asn1 has these two as CONSTRUCTED, but the ASN.1 spec
80	 * doesn't look that way to me. I don't have any certs that have these
81	 * fields.... */
82	{ DER_OFFSET(DERTBSCert, issuerID),
83			ASN1_CONTEXT_SPECIFIC | 1,
84			DER_DEC_OPTIONAL },
85	{ DER_OFFSET(DERTBSCert, subjectID),
86			ASN1_CONTEXT_SPECIFIC | 2,
87			DER_DEC_OPTIONAL },
88	{ DER_OFFSET(DERTBSCert, extensions),
89			ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3,
90			DER_DEC_OPTIONAL }
91};
92const DERSize DERNumTBSCertItemSpecs = sizeof(DERTBSCertItemSpecs) / sizeof(DERItemSpec);
93
94/* DERValidity */
95const DERItemSpec DERValidityItemSpecs[] =
96{
97	{ DER_OFFSET(DERValidity, notBefore),
98			0,					/* no tag - ANY */
99			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER },
100	{ DER_OFFSET(DERValidity, notAfter),
101			0,					/* no tag - ANY */
102			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }
103};
104const DERSize DERNumValidityItemSpecs =
105	sizeof(DERValidityItemSpecs) / sizeof(DERItemSpec);
106
107/* DERAttributeTypeAndValue */
108const DERItemSpec DERAttributeTypeAndValueItemSpecs[] = {
109	{ DER_OFFSET(DERAttributeTypeAndValue, type),
110			ASN1_OBJECT_ID,
111			DER_DEC_NO_OPTS },
112	{ DER_OFFSET(DERAttributeTypeAndValue, value),
113			0,					/* no tag - ANY */
114			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }
115};
116
117const DERSize DERNumAttributeTypeAndValueItemSpecs =
118	sizeof(DERAttributeTypeAndValueItemSpecs) / sizeof(DERItemSpec);
119
120/* DERExtension */
121const DERItemSpec DERExtensionItemSpecs[] =
122{
123	{ DER_OFFSET(DERExtension, extnID),
124			ASN1_OBJECT_ID,
125			DER_DEC_NO_OPTS },
126	{ DER_OFFSET(DERExtension, critical),
127			ASN1_BOOLEAN,
128			DER_DEC_OPTIONAL },
129	{ DER_OFFSET(DERExtension, extnValue),
130			ASN1_OCTET_STRING,
131            DER_DEC_NO_OPTS }
132};
133const DERSize DERNumExtensionItemSpecs =
134	sizeof(DERExtensionItemSpecs) / sizeof(DERItemSpec);
135
136/* DERBasicConstraints */
137const DERItemSpec DERBasicConstraintsItemSpecs[] =
138{
139	{ DER_OFFSET(DERBasicConstraints, cA),
140			ASN1_BOOLEAN,
141			DER_DEC_OPTIONAL },
142	{ DER_OFFSET(DERBasicConstraints, pathLenConstraint),
143			ASN1_INTEGER,
144			DER_DEC_OPTIONAL }
145};
146const DERSize DERNumBasicConstraintsItemSpecs =
147	sizeof(DERBasicConstraintsItemSpecs) / sizeof(DERItemSpec);
148
149/* DERPrivateKeyUsagePeriod. */
150const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[] =
151{
152	{ DER_OFFSET(DERPrivateKeyUsagePeriod, notBefore),
153			ASN1_CONTEXT_SPECIFIC | 0,
154			DER_DEC_OPTIONAL },
155	{ DER_OFFSET(DERPrivateKeyUsagePeriod, notAfter),
156			ASN1_CONTEXT_SPECIFIC | 1,
157			DER_DEC_OPTIONAL }
158};
159const DERSize DERNumPrivateKeyUsagePeriodItemSpecs =
160	sizeof(DERPrivateKeyUsagePeriodItemSpecs) / sizeof(DERItemSpec);
161
162/* DERDistributionPoint. */
163const DERItemSpec DERDistributionPointItemSpecs[] =
164{
165	{ DER_OFFSET(DERDistributionPoint, distributionPoint),
166			ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0,
167			DER_DEC_OPTIONAL },
168	{ DER_OFFSET(DERDistributionPoint, reasons),
169			ASN1_CONTEXT_SPECIFIC | 1,
170			DER_DEC_OPTIONAL },
171	{ DER_OFFSET(DERDistributionPoint, cRLIssuer),
172			ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2,
173			DER_DEC_OPTIONAL }
174};
175const DERSize DERNumDistributionPointItemSpecs =
176	sizeof(DERDistributionPointItemSpecs) / sizeof(DERItemSpec);
177
178/* DERPolicyInformation. */
179const DERItemSpec DERPolicyInformationItemSpecs[] =
180{
181	{ DER_OFFSET(DERPolicyInformation, policyIdentifier),
182			ASN1_OBJECT_ID,
183			DER_DEC_NO_OPTS },
184	{ DER_OFFSET(DERPolicyInformation, policyQualifiers),
185			ASN1_CONSTR_SEQUENCE,
186			DER_DEC_OPTIONAL }
187};
188const DERSize DERNumPolicyInformationItemSpecs =
189	sizeof(DERPolicyInformationItemSpecs) / sizeof(DERItemSpec);
190
191/* DERPolicyQualifierInfo. */
192const DERItemSpec DERPolicyQualifierInfoItemSpecs[] =
193{
194	{ DER_OFFSET(DERPolicyQualifierInfo, policyQualifierID),
195			ASN1_OBJECT_ID,
196			DER_DEC_NO_OPTS },
197	{ DER_OFFSET(DERPolicyQualifierInfo, qualifier),
198			0,					/* no tag - ANY */
199			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }
200};
201const DERSize DERNumPolicyQualifierInfoItemSpecs =
202	sizeof(DERPolicyQualifierInfoItemSpecs) / sizeof(DERItemSpec);
203
204/* DERUserNotice. */
205const DERItemSpec DERUserNoticeItemSpecs[] =
206{
207	{ DER_OFFSET(DERUserNotice, noticeRef),
208			ASN1_CONSTR_SEQUENCE,
209			DER_DEC_OPTIONAL },
210	{ DER_OFFSET(DERUserNotice, explicitText),
211			0,					/* no tag - ANY */
212			DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER }
213};
214const DERSize DERNumUserNoticeItemSpecs =
215	sizeof(DERUserNoticeItemSpecs) / sizeof(DERItemSpec);
216
217/* DERNoticeReference. */
218const DERItemSpec DERNoticeReferenceItemSpecs[] =
219{
220	{ DER_OFFSET(DERNoticeReference, organization),
221			0,					/* no tag - ANY */
222			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER },
223	{ DER_OFFSET(DERNoticeReference, noticeNumbers),
224			ASN1_CONSTR_SEQUENCE,
225			DER_DEC_NO_OPTS }
226};
227const DERSize DERNumNoticeReferenceItemSpecs =
228	sizeof(DERNoticeReferenceItemSpecs) / sizeof(DERItemSpec);
229
230/* DERPolicyMapping. */
231const DERItemSpec DERPolicyMappingItemSpecs[] =
232{
233	{ DER_OFFSET(DERPolicyMapping, issuerDomainPolicy),
234			ASN1_OBJECT_ID,
235			DER_DEC_NO_OPTS },
236	{ DER_OFFSET(DERPolicyMapping, subjectDomainPolicy),
237			ASN1_OBJECT_ID,
238			DER_DEC_NO_OPTS }
239};
240const DERSize DERNumPolicyMappingItemSpecs =
241	sizeof(DERPolicyMappingItemSpecs) / sizeof(DERItemSpec);
242
243/* DERAccessDescription. */
244const DERItemSpec DERAccessDescriptionItemSpecs[] =
245{
246	{ DER_OFFSET(DERAccessDescription, accessMethod),
247			ASN1_OBJECT_ID,
248			DER_DEC_NO_OPTS },
249	{ DER_OFFSET(DERAccessDescription, accessLocation),
250			0,					/* no tag - ANY */
251			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }
252};
253const DERSize DERNumAccessDescriptionItemSpecs =
254	sizeof(DERAccessDescriptionItemSpecs) / sizeof(DERItemSpec);
255
256/* DERAuthorityKeyIdentifier. */
257const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[] =
258{
259	{ DER_OFFSET(DERAuthorityKeyIdentifier, keyIdentifier),
260			ASN1_CONTEXT_SPECIFIC | 0,
261			DER_DEC_OPTIONAL },
262	{ DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertIssuer),
263			ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1,
264			DER_DEC_OPTIONAL },
265	{ DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertSerialNumber),
266			ASN1_CONTEXT_SPECIFIC | 2,
267			DER_DEC_OPTIONAL }
268};
269const DERSize DERNumAuthorityKeyIdentifierItemSpecs =
270	sizeof(DERAuthorityKeyIdentifierItemSpecs) / sizeof(DERItemSpec);
271
272/* DEROtherName. */
273const DERItemSpec DEROtherNameItemSpecs[] =
274{
275	{ DER_OFFSET(DEROtherName, typeIdentifier),
276			ASN1_OBJECT_ID,
277			DER_DEC_NO_OPTS },
278	{ DER_OFFSET(DEROtherName, value),
279			ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0,
280			DER_DEC_NO_OPTS },
281};
282const DERSize DERNumOtherNameItemSpecs =
283	sizeof(DEROtherNameItemSpecs) / sizeof(DERItemSpec);
284
285/* DERPolicyConstraints. */
286const DERItemSpec DERPolicyConstraintsItemSpecs[] =
287{
288	{ DER_OFFSET(DERPolicyConstraints, requireExplicitPolicy),
289			ASN1_CONTEXT_SPECIFIC | 0,
290			DER_DEC_OPTIONAL },
291	{ DER_OFFSET(DERPolicyConstraints, inhibitPolicyMapping),
292			ASN1_CONTEXT_SPECIFIC | 1,
293			DER_DEC_OPTIONAL }
294};
295const DERSize DERNumPolicyConstraintsItemSpecs =
296	sizeof(DERPolicyConstraintsItemSpecs) / sizeof(DERItemSpec);
297
298/* DERTBSCrl */
299const DERItemSpec DERTBSCrlItemSpecs[] =
300{
301	{ DER_OFFSET(DERTBSCrl, version),
302			ASN1_INTEGER,
303			DER_DEC_OPTIONAL },
304	{ DER_OFFSET(DERTBSCrl, tbsSigAlg),
305			ASN1_CONSTR_SEQUENCE,
306			DER_DEC_NO_OPTS },
307	{ DER_OFFSET(DERTBSCrl, issuer),
308			ASN1_CONSTR_SEQUENCE,
309			DER_DEC_NO_OPTS },
310	{ DER_OFFSET(DERTBSCrl, thisUpdate),
311			0,					/* no tag - ANY */
312			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER },
313	{ DER_OFFSET(DERTBSCrl, nextUpdate),
314			0,					/* no tag - ANY */
315			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER },
316	{ DER_OFFSET(DERTBSCrl, revokedCerts),
317			ASN1_CONSTR_SEQUENCE,
318			DER_DEC_OPTIONAL },
319	{ DER_OFFSET(DERTBSCrl, extensions),
320			ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0,
321			DER_DEC_OPTIONAL }
322};
323const DERSize DERNumTBSCrlItemSpecs = sizeof(DERTBSCrlItemSpecs) / sizeof(DERItemSpec);
324
325/* DERRevokedCert */
326const DERItemSpec DERRevokedCertItemSpecs[] =
327{
328	{ DER_OFFSET(DERRevokedCert, serialNum),
329			ASN1_INTEGER,
330			DER_DEC_NO_OPTS },
331	{ DER_OFFSET(DERRevokedCert, revocationDate),
332			0,					/* no tag - ANY */
333			DER_DEC_ASN_ANY | DER_DEC_SAVE_DER },
334	{ DER_OFFSET(DERRevokedCert, extensions),
335			ASN1_CONSTR_SEQUENCE,
336			DER_DEC_OPTIONAL }
337};
338
339const DERSize DERNumRevokedCertItemSpecs =
340	sizeof(DERRevokedCertItemSpecs) / sizeof(DERItemSpec);
341