1/*
2 * Copyright (c) 2003-2006,2008,2010 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 * certExtensionTemplates.cpp - libnssasn1 structs and templates for cert and
24 *                              CRL extensions
25 *
26 */
27
28#include "certExtensionTemplates.h"
29#include "SecAsn1Templates.h"
30#include <stddef.h>
31
32/* Basic Constraints */
33const SecAsn1Template kSecAsn1BasicConstraintsTemplate[] = {
34    { SEC_ASN1_SEQUENCE,
35	  0, NULL, sizeof(NSS_BasicConstraints) },
36    { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL,
37	  offsetof(NSS_BasicConstraints,cA) },
38    { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL,
39	  offsetof(NSS_BasicConstraints, pathLenConstraint) },
40    { 0, }
41};
42
43/* Authority Key Identifier */
44
45/* signed integer - SEC_ASN1_SIGNED_INT state gets lost
46 * in SEC_ASN1_CONTEXT_SPECIFIC processing */
47const SecAsn1Template kSecAsn1SignedIntegerTemplate[] = {
48    { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 0, NULL, sizeof(SecAsn1Item) }
49};
50
51const SecAsn1Template kSecAsn1AuthorityKeyIdTemplate[] = {
52    { SEC_ASN1_SEQUENCE,
53	  0, NULL, sizeof(NSS_AuthorityKeyId) },
54    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
55	  SEC_ASN1_POINTER | 0,
56	  offsetof(NSS_AuthorityKeyId,keyIdentifier),
57	  kSecAsn1OctetStringTemplate },
58    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
59	                      SEC_ASN1_CONTEXT_SPECIFIC | 1,
60	  offsetof(NSS_AuthorityKeyId,genNames),
61	  kSecAsn1GeneralNamesTemplate },
62	/* serial number is SIGNED integer */
63    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2,
64	  offsetof(NSS_AuthorityKeyId,serialNumber),
65	  kSecAsn1SignedIntegerTemplate},
66	{ 0 }
67};
68
69/* Certificate policies */
70const SecAsn1Template kSecAsn1PolicyQualifierTemplate[] = {
71    { SEC_ASN1_SEQUENCE,
72	  0, NULL, sizeof(NSS_PolicyQualifierInfo) },
73    { SEC_ASN1_OBJECT_ID,
74	  offsetof(NSS_PolicyQualifierInfo,policyQualifierId) },
75	{ SEC_ASN1_ANY, offsetof(NSS_PolicyQualifierInfo, qualifier) },
76	{ 0 }
77};
78
79const SecAsn1Template kSecAsn1PolicyInformationTemplate[] = {
80    { SEC_ASN1_SEQUENCE,
81	  0, NULL, sizeof(NSS_PolicyInformation) },
82    { SEC_ASN1_OBJECT_ID,
83	  offsetof(NSS_PolicyInformation,certPolicyId) },
84	{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
85	  offsetof(NSS_PolicyInformation,policyQualifiers),
86	  kSecAsn1PolicyQualifierTemplate },
87	{ 0 }
88};
89
90const SecAsn1Template kSecAsn1CertPoliciesTemplate[] = {
91	{ SEC_ASN1_SEQUENCE_OF,
92	  offsetof(NSS_CertPolicies,policies),
93	  kSecAsn1PolicyInformationTemplate },
94	{ 0 }
95};
96
97/* CRL Distribution Points */
98
99/*
100 * NOTE WELL: RFC2459, and all the documentation I can find, claims that
101 * the tag for the DistributionPointName option (tag 0) of a
102 * DistributionPoint is IMPLICIT and context-specific. However this
103 * is IMPOSSIBLE - since the underlying type (DistributionPointName)
104 * also relies upon context-specific tags to resolve a CHOICE.
105 * The real world indicates that the tag for the DistributionPoint option
106 * is indeed EXPLICIT. Examination of many certs' cRLDistributionPoints
107 * extensions shows this, and the NSS reference code also specifies
108 * an EXPLICIT tag for this field.
109 */
110const SecAsn1Template kSecAsn1DistributionPointTemplate[] = {
111    { SEC_ASN1_SEQUENCE,
112	  0, NULL, sizeof(NSS_DistributionPoint) },
113	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
114	  SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0,
115	  offsetof(NSS_DistributionPoint,distPointName),
116	  kSecAsn1PointerToAnyTemplate },
117	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1,
118	  offsetof(NSS_DistributionPoint,reasons), kSecAsn1BitStringTemplate},
119	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
120						  SEC_ASN1_CONSTRUCTED | 2,
121	  offsetof(NSS_DistributionPoint, crlIssuer),
122	  kSecAsn1GeneralNamesTemplate
123	},
124	{ 0 }
125};
126
127const SecAsn1Template kSecAsn1CRLDistributionPointsTemplate[] = {
128	{ SEC_ASN1_SEQUENCE_OF,
129	  offsetof(NSS_CRLDistributionPoints,distPoints),
130	  kSecAsn1DistributionPointTemplate },
131	{ 0 }
132};
133
134
135/*
136 * These are the context-specific targets of the DistributionPointName
137 * option.
138 */
139const SecAsn1Template kSecAsn1DistPointFullNameTemplate[] = {
140    {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
141	offsetof (NSS_GeneralNames,names), kSecAsn1GeneralNamesTemplate}
142};
143
144const SecAsn1Template kSecAsn1DistPointRDNTemplate[] = {
145    {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
146	offsetof (NSS_RDN,atvs), kSecAsn1RDNTemplate}
147};
148
149/*
150 * Issuing distribution points
151 *
152 * Although the spec says that the DistributionPointName element
153 * is context-specific, it must be explicit because the underlying
154 * type - a DistributionPointName - also relies on a context-specific
155 * tags to resolve a CHOICE.
156 */
157
158/* kludge: ASN decoder doesn't handle
159 * SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER
160 * very well... */
161static const SecAsn1Template kSecAsn1OptBooleanTemplate[] = {
162    { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, 0, NULL, sizeof(SecAsn1Item) }
163};
164
165static const SecAsn1Template kSecAsn1OptBitStringTemplate[] = {
166    { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, 0, NULL, sizeof(SecAsn1Item) }
167};
168
169const SecAsn1Template kSecAsn1IssuingDistributionPointTemplate[] = {
170    { SEC_ASN1_SEQUENCE,
171	  0, NULL, sizeof(NSS_IssuingDistributionPoint) },
172	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
173	  SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0,
174	  offsetof(NSS_IssuingDistributionPoint,distPointName),
175	  kSecAsn1PointerToAnyTemplate },
176	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 1,
177	  offsetof(NSS_IssuingDistributionPoint,onlyUserCerts),
178	  kSecAsn1OptBooleanTemplate},
179	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 2,
180	  offsetof(NSS_IssuingDistributionPoint,onlyCACerts),
181	  kSecAsn1OptBooleanTemplate},
182	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 3,
183	  offsetof(NSS_IssuingDistributionPoint,onlySomeReasons),
184	  kSecAsn1OptBitStringTemplate},
185	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 4,
186	  offsetof(NSS_IssuingDistributionPoint,indirectCRL),
187	  kSecAsn1OptBooleanTemplate},
188	{ 0 }
189};
190
191
192/*
193 * Authority Information Access and Subject Information Access.
194 */
195const SecAsn1Template kSecAsn1AccessDescriptionTemplate[] = {
196    { SEC_ASN1_SEQUENCE,
197	  0, NULL, sizeof(NSS_AccessDescription) },
198    { SEC_ASN1_OBJECT_ID,
199	  offsetof(NSS_AccessDescription,accessMethod) },
200	/*
201	 * NSS encoder just can't handle direct inline of an NSS_GeneralName here.
202	 */
203    { SEC_ASN1_ANY,
204      offsetof(NSS_AccessDescription, encodedAccessLocation) },
205	{ 0 }
206};
207
208const SecAsn1Template kSecAsn1AuthorityInfoAccessTemplate[] = {
209    { SEC_ASN1_SEQUENCE_OF,
210	  offsetof(NSS_AuthorityInfoAccess,accessDescriptions),
211	  kSecAsn1AccessDescriptionTemplate,
212	  sizeof(NSS_AuthorityInfoAccess) }
213};
214
215/*
216 * Qualified Certificate Statements templates.
217 *
218 * This is the NSS_QC_Statement.info when NSS_QC_Statement.statementId
219 * is CSSMOID_OID_QCS_SYNTAX_V2.
220 */
221const SecAsn1Template kSecAsn1SemanticsInformationTemplate[] = {
222    { SEC_ASN1_SEQUENCE,
223		0, NULL, sizeof(NSS_SemanticsInformation) },
224	{ SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER,
225		offsetof(NSS_SemanticsInformation,semanticsIdentifier),
226		kSecAsn1ObjectIDTemplate },
227	{ SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER,
228		offsetof(NSS_SemanticsInformation, nameRegistrationAuthorities),
229		kSecAsn1GeneralNamesTemplate },
230	{ 0 }
231};
232
233const SecAsn1Template kSecAsn1QC_StatementTemplate[] = {
234    { SEC_ASN1_SEQUENCE,
235		0, NULL, sizeof(NSS_QC_Statement) },
236    { SEC_ASN1_OBJECT_ID,
237		offsetof(NSS_QC_Statement,statementId) },
238    { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
239		offsetof(NSS_QC_Statement, info) },
240	{ 0 }
241};
242
243const SecAsn1Template kSecAsn1QC_StatementsTemplate[] = {
244    { SEC_ASN1_SEQUENCE_OF,
245		offsetof(NSS_QC_Statements,qcStatements),
246		kSecAsn1QC_StatementTemplate,
247		sizeof(NSS_QC_Statements) }
248};
249
250/*
251 * NameConstraints templates
252 */
253const SecAsn1Template kSecAsn1GeneralSubtreeTemplate[] = {
254    { SEC_ASN1_SEQUENCE,
255	  0, NULL, sizeof(NSS_GeneralSubtree) },
256	{ SEC_ASN1_SEQUENCE,
257	  offsetof(NSS_GeneralSubtree,base),
258	  kSecAsn1GeneralNamesTemplate },
259	{ SEC_ASN1_INTEGER,
260	  offsetof(NSS_GeneralSubtree,minimum) },
261	{ SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL,
262	  offsetof(NSS_GeneralSubtree,maximum) },
263    { 0, }
264};
265
266const SecAsn1Template kSecAsn1GeneralSubtreesTemplate[] = {
267	{ SEC_ASN1_SEQUENCE_OF,
268	  offsetof(NSS_GeneralSubtrees,subtrees),
269	  kSecAsn1GeneralSubtreeTemplate },
270	{ 0 }
271};
272
273const SecAsn1Template kSecAsn1NameConstraintsTemplate[] = {
274    { SEC_ASN1_SEQUENCE,
275	  0, NULL, sizeof(NSS_NameConstraints) },
276	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
277	  SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0,
278	  offsetof(NSS_NameConstraints,permittedSubtrees),
279	  kSecAsn1GeneralSubtreesTemplate },
280	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
281	  SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 1,
282	  offsetof(NSS_NameConstraints,excludedSubtrees),
283	  kSecAsn1GeneralSubtreesTemplate },
284	{ 0 }
285};
286
287/*
288 * PolicyMappings templates
289 */
290const SecAsn1Template kSecAsn1PolicyMappingTemplate[] = {
291    { SEC_ASN1_SEQUENCE,
292		0, NULL, sizeof(NSS_PolicyMapping) },
293    { SEC_ASN1_OBJECT_ID,
294		offsetof(NSS_PolicyMapping,issuerDomainPolicy) },
295    { SEC_ASN1_OBJECT_ID,
296		offsetof(NSS_PolicyMapping,subjectDomainPolicy) },
297	{ 0 }
298};
299
300const SecAsn1Template kSecAsn1PolicyMappingsTemplate[] = {
301	{ SEC_ASN1_SEQUENCE_OF,
302	  offsetof(NSS_PolicyMappings,policyMappings),
303	  kSecAsn1PolicyMappingTemplate },
304	{ 0 }
305};
306
307/*
308 * PolicyConstraints templates
309 */
310const SecAsn1Template kSecAsn1PolicyConstraintsTemplate[] = {
311    { SEC_ASN1_SEQUENCE,
312	  0, NULL, sizeof(NSS_PolicyConstraints) },
313	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
314	  SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0,
315	  offsetof(NSS_PolicyConstraints,requireExplicitPolicy) },
316	{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
317	  SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 1,
318	  offsetof(NSS_PolicyConstraints,inhibitPolicyMapping) },
319	{ 0 }
320};
321
322
323