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