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