1/*
2 * Copyright (c) 2000-2009,2011 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 * CertExtensions.h -- X.509 Cert Extensions as C structs
24 */
25
26#ifndef	_CERT_EXTENSIONS_H_
27#define _CERT_EXTENSIONS_H_
28
29#include <stdbool.h>
30#include <libDER/libDER.h>
31//#include <Security/x509defs.h>
32
33/***
34 *** Structs for declaring extension-specific data.
35 ***/
36
37/*
38 * GeneralName, used in AuthorityKeyID, SubjectAltName, and
39 * IssuerAltName.
40 *
41 * For now, we just provide explicit support for the types which are
42 * represented as IA5Strings, OIDs, and octet strings. Constructed types
43 * such as EDIPartyName and x400Address are not explicitly handled
44 * right now and must be encoded and decoded by the caller. (See exception
45 * for Name and OtherName, below). In those cases the SecCEGeneralName.name.Data field
46 * represents the BER contents octets; SecCEGeneralName.name.Length is the
47 * length of the contents; the tag of the field is not needed - the BER
48 * encoding uses context-specific implicit tagging. The berEncoded field
49 * is set to true in these case. Simple types have berEncoded = false.
50 *
51 * In the case of a GeneralName in the form of a Name, we parse the Name
52 * into a CSSM_X509_NAME and place a pointer to the CSSM_X509_NAME in the
53 * SecCEGeneralName.name.Data field. SecCEGeneralName.name.Length is set to
54 * sizeof(CSSM_X509_NAME). In this case berEncoded is false.
55 *
56 * In the case of a GeneralName in the form of a OtherName, we parse the fields
57 * into a SecCEOtherName and place a pointer to the SecCEOtherName in the
58 * SecCEGeneralName.name.Data field. SecCEGeneralName.name.Length is set to
59 * sizeof(SecCEOtherName). In this case berEncoded is false.
60 *
61 *      GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
62 *
63 *      GeneralName ::= CHOICE {
64 *           otherName                       [0]     OtherName
65 *           rfc822Name                      [1]     IA5String,
66 *           dNSName                         [2]     IA5String,
67 *           x400Address                     [3]     ORAddress,
68 *           directoryName                   [4]     Name,
69 *           ediPartyName                    [5]     EDIPartyName,
70 *           uniformResourceIdentifier       [6]     IA5String,
71 *           iPAddress                       [7]     OCTET STRING,
72 *           registeredID                    [8]     OBJECT IDENTIFIER}
73 *
74 *      OtherName ::= SEQUENCE {
75 *           type-id    OBJECT IDENTIFIER,
76 *           value      [0] EXPLICIT ANY DEFINED BY type-id }
77 *
78 *      EDIPartyName ::= SEQUENCE {
79 *           nameAssigner            [0]     DirectoryString OPTIONAL,
80 *           partyName               [1]     DirectoryString }
81 */
82typedef enum {
83	GNT_OtherName = 0,
84	GNT_RFC822Name,
85	GNT_DNSName,
86	GNT_X400Address,
87	GNT_DirectoryName,
88	GNT_EdiPartyName,
89	GNT_URI,
90	GNT_IPAddress,
91	GNT_RegisteredID
92} SecCEGeneralNameType;
93
94typedef struct {
95	DERItem                 typeId;
96	DERItem                 value;		// unparsed, BER-encoded
97} SecCEOtherName;
98
99typedef struct {
100	SecCEGeneralNameType		nameType;	// GNT_RFC822Name, etc.
101	bool                    berEncoded;
102	DERItem                 name;
103} SecCEGeneralName;
104
105typedef struct {
106	uint32_t					numNames;
107	SecCEGeneralName			*generalName;
108} SecCEGeneralNames;
109
110/*
111 * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
112 *
113 *   AuthorityKeyIdentifier ::= SEQUENCE {
114 *     keyIdentifier             [0] KeyIdentifier           OPTIONAL,
115 *     authorityCertIssuer       [1] GeneralNames            OPTIONAL,
116 *     authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
117 *
118 *   KeyIdentifier ::= OCTET STRING
119 *
120 * CSSM OID = CSSMOID_AuthorityKeyIdentifier
121 */
122typedef struct {
123	bool                keyIdentifierPresent;
124	DERItem             keyIdentifier;
125	bool                generalNamesPresent;
126	SecCEGeneralNames		*generalNames;
127	bool                serialNumberPresent;
128	DERItem             serialNumber;
129} SecCEAuthorityKeyID;
130
131/*
132 * id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
133 *   SubjectKeyIdentifier ::= KeyIdentifier
134 *
135 * CSSM OID = CSSMOID_SubjectKeyIdentifier
136 */
137typedef DERItem SecCESubjectKeyID;
138
139/*
140 * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
141 *
142 *     KeyUsage ::= BIT STRING {
143 *          digitalSignature        (0),
144 *          nonRepudiation          (1),
145 *          keyEncipherment         (2),
146 *          dataEncipherment        (3),
147 *          keyAgreement            (4),
148 *          keyCertSign             (5),
149 *          cRLSign                 (6),
150 *          encipherOnly            (7),
151 *          decipherOnly            (8) }
152 *
153 * CSSM OID = CSSMOID_KeyUsage
154 *
155 */
156typedef uint16_t SecCEKeyUsage;
157
158#define SecCEKU_DigitalSignature	0x8000
159#define SecCEKU_NonRepudiation	0x4000
160#define SecCEKU_KeyEncipherment	0x2000
161#define SecCEKU_DataEncipherment	0x1000
162#define SecCEKU_KeyAgreement		0x0800
163#define SecCEKU_KeyCertSign	 	0x0400
164#define SecCEKU_CRLSign			0x0200
165#define SecCEKU_EncipherOnly	 	0x0100
166#define SecCEKU_DecipherOnly	 	0x0080
167
168/*
169 *  id-ce-cRLReason OBJECT IDENTIFIER ::= { id-ce 21 }
170 *
171 *   -- reasonCode ::= { CRLReason }
172 *
173 *   CRLReason ::= ENUMERATED {
174 *  	unspecified             (0),
175 *      keyCompromise           (1),
176 *     	cACompromise            (2),
177 *    	affiliationChanged      (3),
178 *   	superseded              (4),
179 *  	cessationOfOperation    (5),
180 * 		certificateHold         (6),
181 *		removeFromCRL           (8) }
182 *
183 * CSSM OID = CSSMOID_CrlReason
184 *
185 */
186typedef uint32_t SecCECrlReason;
187
188#define SecCECR_Unspecified			0
189#define SecCECR_KeyCompromise			1
190#define SecCECR_CACompromise			2
191#define SecCECR_AffiliationChanged	3
192#define SecCECR_Superseded			4
193#define SecCECR_CessationOfOperation	5
194#define SecCECR_CertificateHold		6
195#define SecCECR_RemoveFromCRL	 		8
196
197/*
198 * id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
199 *
200 *      SubjectAltName ::= GeneralNames
201 *
202 * CSSM OID = CSSMOID_SubjectAltName
203 *
204 * GeneralNames defined above.
205 */
206
207/*
208 *  id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
209 *
210 *   ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId*
211 *
212 *  KeyPurposeId ::= OBJECT IDENTIFIER
213 *
214 * CSSM OID = CSSMOID_ExtendedKeyUsage
215 */
216typedef struct {
217	uint32_t		numPurposes;
218	DERItem         *purposes;		// in Intel pre-encoded format
219} SecCEExtendedKeyUsage;
220
221/*
222 * id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
223 *
224 * BasicConstraints ::= SEQUENCE {
225 *       cA                      BOOLEAN DEFAULT FALSE,
226 *       pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
227 *
228 * CSSM OID = CSSMOID_BasicConstraints
229 */
230typedef struct {
231	bool                present;
232	bool                critical;
233	bool                isCA;
234	bool                pathLenConstraintPresent;
235	uint32_t			pathLenConstraint;
236} SecCEBasicConstraints;
237
238typedef struct {
239	bool                present;
240	bool                critical;
241	bool                requireExplicitPolicyPresent;
242	uint32_t			requireExplicitPolicy;
243	bool                inhibitPolicyMappingPresent;
244	uint32_t			inhibitPolicyMapping;
245} SecCEPolicyConstraints;
246
247/*
248 * id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
249 *
250 *   certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
251 *
252 *   PolicyInformation ::= SEQUENCE {
253 *        policyIdentifier   CertPolicyId,
254 *        policyQualifiers   SEQUENCE SIZE (1..MAX) OF
255 *                                PolicyQualifierInfo OPTIONAL }
256 *
257 *   CertPolicyId ::= OBJECT IDENTIFIER
258 *
259 *   PolicyQualifierInfo ::= SEQUENCE {
260 *        policyQualifierId  PolicyQualifierId,
261 *        qualifier          ANY DEFINED BY policyQualifierId }
262 *
263 *   -- policyQualifierIds for Internet policy qualifiers
264 *
265 *   id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
266 *   id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
267 *   id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
268 *
269 *   PolicyQualifierId ::=
270 *        OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
271 *
272 *   Qualifier ::= CHOICE {
273 *        cPSuri           CPSuri,
274 *        userNotice       UserNotice }
275 *
276 *   CPSuri ::= IA5String
277 *
278 *   UserNotice ::= SEQUENCE {
279 *        noticeRef        NoticeReference OPTIONAL,
280 *        explicitText     DisplayText OPTIONAL}
281 *
282 *   NoticeReference ::= SEQUENCE {
283 *        organization     DisplayText,
284 *        noticeNumbers    SEQUENCE OF INTEGER }
285 *
286 *   DisplayText ::= CHOICE {
287 *        visibleString    VisibleString  (SIZE (1..200)),
288 *        bmpString        BMPString      (SIZE (1..200)),
289 *        utf8String       UTF8String     (SIZE (1..200)) }
290 *
291 *  CSSM OID = CSSMOID_CertificatePolicies
292 *
293 * We only support down to the level of Qualifier, and then only the CPSuri
294 * choice. UserNotice is transmitted to and from this library as a raw
295 * CSSM_DATA containing the BER-encoded UserNotice sequence.
296 */
297#if 0
298typedef struct {
299	DERItem     policyQualifierId;			// CSSMOID_QT_CPS, CSSMOID_QT_UNOTICE
300	DERItem     qualifier;					// CSSMOID_QT_CPS: IA5String contents
301											// CSSMOID_QT_UNOTICE : Sequence contents
302} SecCEPolicyQualifierInfo;
303#endif
304
305typedef struct {
306    DERItem policyIdentifier;
307    DERItem policyQualifiers;
308} SecCEPolicyInformation;
309
310typedef struct {
311	bool                    present;
312	bool                    critical;
313	uint32_t                numPolicies;			// size of *policies;
314	SecCEPolicyInformation  *policies;
315} SecCECertificatePolicies;
316
317typedef struct {
318    DERItem issuerDomainPolicy;
319    DERItem subjectDomainPolicy;
320} SecCEPolicyMapping;
321
322/*
323   PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
324        issuerDomainPolicy      CertPolicyId,
325        subjectDomainPolicy     CertPolicyId }
326*/
327typedef struct {
328	bool                present;
329	bool                critical;
330	uint32_t            numMappings;			// size of *mappings;
331	SecCEPolicyMapping  *mappings;
332} SecCEPolicyMappings;
333
334#if 0
335typedef struct {
336	bool                    present;
337	bool                    critical;
338	uint32_t                skipCerts;
339} SecCEInhibitAnyPolicy;
340
341/*
342 * netscape-cert-type, a bit string.
343 *
344 * CSSM OID = CSSMOID_NetscapeCertType
345 *
346 * Bit fields defined in oidsattr.h: SecCENCT_SSL_Client, etc.
347 */
348typedef uint16_t SecCENetscapeCertType;
349
350/*
351 * CRLDistributionPoints.
352 *
353 *   id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 }
354 *
355 *   cRLDistributionPoints ::= {
356 *        CRLDistPointsSyntax }
357 *
358 *   CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
359 *
360 *   NOTE: RFC 2459 claims that the tag for the optional DistributionPointName
361 *   is IMPLICIT as shown here, but in practice it is EXPLICIT. It has to be -
362 *   because the underlying type also uses an implicit tag for distinguish
363 *   between CHOICEs.
364 *
365 *   DistributionPoint ::= SEQUENCE {
366 *        distributionPoint       [0]     DistributionPointName OPTIONAL,
367 *        reasons                 [1]     ReasonFlags OPTIONAL,
368 *        cRLIssuer               [2]     GeneralNames OPTIONAL }
369 *
370 *   DistributionPointName ::= CHOICE {
371 *        fullName                [0]     GeneralNames,
372 *        nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
373 *
374 *   ReasonFlags ::= BIT STRING {
375 *        unused                  (0),
376 *        keyCompromise           (1),
377 *        cACompromise            (2),
378 *        affiliationChanged      (3),
379 *        superseded              (4),
380 *        cessationOfOperation    (5),
381 *        certificateHold         (6) }
382 *
383 * CSSM OID = CSSMOID_CrlDistributionPoints
384 */
385
386/*
387 * Note that this looks similar to SecCECrlReason, but that's an enum and this
388 * is an OR-able bit string.
389 */
390typedef uint8_t SecCECrlDistReasonFlags;
391
392#define SecCECD_Unspecified			0x80
393#define SecCECD_KeyCompromise			0x40
394#define SecCECD_CACompromise			0x20
395#define SecCECD_AffiliationChanged	0x10
396#define SecCECD_Superseded			0x08
397#define SecCECD_CessationOfOperation	0x04
398#define SecCECD_CertificateHold		0x02
399
400typedef enum {
401	SecCECDNT_FullName,
402	SecCECDNT_NameRelativeToCrlIssuer
403} SecCECrlDistributionPointNameType;
404
405typedef struct {
406	SecCECrlDistributionPointNameType		nameType;
407	union {
408		SecCEGeneralNames					*fullName;
409		CSSM_X509_RDN_PTR				rdn;
410	} dpn;
411} SecCEDistributionPointName;
412
413/*
414 * The top-level CRLDistributionPoint.
415 * All fields are optional; NULL pointers indicate absence.
416 */
417typedef struct {
418	SecCEDistributionPointName			*distPointName;
419	bool                                reasonsPresent;
420	SecCECrlDistReasonFlags				reasons;
421	SecCEGeneralNames						*crlIssuer;
422} SecCECRLDistributionPoint;
423
424typedef struct {
425	uint32_t							numDistPoints;
426	SecCECRLDistributionPoint				*distPoints;
427} SecCECRLDistPointsSyntax;
428
429/*
430 * Authority Information Access and Subject Information Access.
431 *
432 * CSSM OID = CSSMOID_AuthorityInfoAccess
433 * CSSM OID = CSSMOID_SubjectInfoAccess
434 *
435 * SubjAuthInfoAccessSyntax  ::=
436 *		SEQUENCE SIZE (1..MAX) OF AccessDescription
437 *
438 * AccessDescription  ::=  SEQUENCE {
439 *		accessMethod          OBJECT IDENTIFIER,
440 *		accessLocation        GeneralName  }
441 */
442typedef struct {
443	DERItem                 accessMethod;
444	SecCEGeneralName			accessLocation;
445} SecCEAccessDescription;
446
447typedef struct {
448	uint32_t				numAccessDescriptions;
449	SecCEAccessDescription	*accessDescriptions;
450} SecCEAuthorityInfoAccess;
451
452/*** CRL extensions ***/
453
454/*
455 * cRLNumber, an integer.
456 *
457 * CSSM OID = CSSMOID_CrlNumber
458 */
459typedef uint32_t SecCECrlNumber;
460
461/*
462 * deltaCRLIndicator, an integer.
463 *
464 * CSSM OID = CSSMOID_DeltaCrlIndicator
465 */
466typedef uint32_t SecCEDeltaCrl;
467
468/*
469 * IssuingDistributionPoint
470 *
471 * id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
472 *
473 * issuingDistributionPoint ::= SEQUENCE {
474 *      distributionPoint       [0] DistributionPointName OPTIONAL,
475 *		onlyContainsUserCerts   [1] BOOLEAN DEFAULT FALSE,
476 *      onlyContainsCACerts     [2] BOOLEAN DEFAULT FALSE,
477 *      onlySomeReasons         [3] ReasonFlags OPTIONAL,
478 *      indirectCRL             [4] BOOLEAN DEFAULT FALSE }
479 *
480 * CSSM OID = CSSMOID_IssuingDistributionPoint
481 */
482typedef struct {
483	SecCEDistributionPointName	*distPointName;		// optional
484	bool                        onlyUserCertsPresent;
485	bool                        onlyUserCerts;
486	bool                        onlyCACertsPresent;
487	bool                        onlyCACerts;
488	bool                        onlySomeReasonsPresent;
489	SecCECrlDistReasonFlags		onlySomeReasons;
490	bool                        indirectCrlPresent;
491	bool                        indirectCrl;
492} SecCEIssuingDistributionPoint;
493
494/*
495 * An enumerated list identifying one of the above per-extension
496 * structs.
497 */
498typedef enum {
499	DT_AuthorityKeyID,			// SecCEAuthorityKeyID
500	DT_SubjectKeyID,			// SecCESubjectKeyID
501	DT_KeyUsage,				// SecCEKeyUsage
502	DT_SubjectAltName,			// implies SecCEGeneralName
503	DT_IssuerAltName,			// implies SecCEGeneralName
504	DT_ExtendedKeyUsage,		// SecCEExtendedKeyUsage
505	DT_BasicConstraints,		// SecCEBasicConstraints
506	DT_CertPolicies,			// SecCECertPolicies
507	DT_NetscapeCertType,		// SecCENetscapeCertType
508	DT_CrlNumber,				// SecCECrlNumber
509	DT_DeltaCrl,				// SecCEDeltaCrl
510	DT_CrlReason,				// SecCECrlReason
511	DT_CrlDistributionPoints,	// SecCECRLDistPointsSyntax
512	DT_IssuingDistributionPoint,// SecCEIssuingDistributionPoint
513	DT_AuthorityInfoAccess,		// SecCEAuthorityInfoAccess
514	DT_Other					// unknown, raw data as a CSSM_DATA
515} SecCEDataType;
516
517/*
518 * One unified representation of all the cert adn CRL extensions we know about.
519 */
520typedef union {
521	SecCEAuthorityKeyID				authorityKeyID;
522	SecCESubjectKeyID				subjectKeyID;
523	SecCEKeyUsage					keyUsage;
524	SecCEGeneralNames				subjectAltName;
525	SecCEGeneralNames				issuerAltName;
526	SecCEExtendedKeyUsage			extendedKeyUsage;
527	SecCEBasicConstraints			basicConstraints;
528	SecCECertPolicies				certPolicies;
529	SecCENetscapeCertType			netscapeCertType;
530	SecCECrlNumber					crlNumber;
531	SecCEDeltaCrl					deltaCrl;
532	SecCECrlReason					crlReason;
533	SecCECRLDistPointsSyntax		crlDistPoints;
534	SecCEIssuingDistributionPoint	issuingDistPoint;
535	SecCEAuthorityInfoAccess		authorityInfoAccess;
536	DERItem							rawData;			// unknown, not decoded
537} SecCEData;
538
539typedef struct {
540	SecCEDataType				type;
541	SecCEData					extension;
542	bool						critical;
543} SecCEDataAndType;
544#endif /* 0 */
545
546#endif	/* _CERT_EXTENSIONS_H_ */
547