1/* 2 * Copyright (c) 2000-2009,2012 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 size_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