X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/OSX/libsecurity_asn1/lib/certExtensionTemplates.c diff --git a/OSX/libsecurity_asn1/lib/certExtensionTemplates.c b/OSX/libsecurity_asn1/lib/certExtensionTemplates.c new file mode 100644 index 00000000..02315128 --- /dev/null +++ b/OSX/libsecurity_asn1/lib/certExtensionTemplates.c @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2003-2006,2008,2010-2012 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * certExtensionTemplates.cpp - libnssasn1 structs and templates for cert and + * CRL extensions + * + */ + +#include "certExtensionTemplates.h" +#include "SecAsn1Templates.h" +#include + +/* Basic Constraints */ +const SecAsn1Template kSecAsn1BasicConstraintsTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_BasicConstraints) }, + { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, + offsetof(NSS_BasicConstraints,cA) }, + { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, + offsetof(NSS_BasicConstraints, pathLenConstraint) }, + { 0, } +}; + +/* Authority Key Identifier */ + +/* signed integer - SEC_ASN1_SIGNED_INT state gets lost + * in SEC_ASN1_CONTEXT_SPECIFIC processing */ +const SecAsn1Template kSecAsn1SignedIntegerTemplate[] = { + { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 0, NULL, sizeof(SecAsn1Item) } +}; + +const SecAsn1Template kSecAsn1AuthorityKeyIdTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_AuthorityKeyId) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_POINTER | 0, + offsetof(NSS_AuthorityKeyId,keyIdentifier), + kSecAsn1OctetStringTemplate }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | + SEC_ASN1_CONTEXT_SPECIFIC | 1, + offsetof(NSS_AuthorityKeyId,genNames), + kSecAsn1GeneralNamesTemplate }, + /* serial number is SIGNED integer */ + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2, + offsetof(NSS_AuthorityKeyId,serialNumber), + kSecAsn1SignedIntegerTemplate}, + { 0 } +}; + +/* Certificate policies */ +const SecAsn1Template kSecAsn1PolicyQualifierTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_PolicyQualifierInfo) }, + { SEC_ASN1_OBJECT_ID, + offsetof(NSS_PolicyQualifierInfo,policyQualifierId) }, + { SEC_ASN1_ANY, offsetof(NSS_PolicyQualifierInfo, qualifier) }, + { 0 } +}; + +const SecAsn1Template kSecAsn1PolicyInformationTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_PolicyInformation) }, + { SEC_ASN1_OBJECT_ID, + offsetof(NSS_PolicyInformation,certPolicyId) }, + { SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL, + offsetof(NSS_PolicyInformation,policyQualifiers), + kSecAsn1PolicyQualifierTemplate }, + { 0 } +}; + +const SecAsn1Template kSecAsn1CertPoliciesTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(NSS_CertPolicies,policies), + kSecAsn1PolicyInformationTemplate }, + { 0 } +}; + +/* CRL Distribution Points */ + +/* + * NOTE WELL: RFC2459, and all the documentation I can find, claims that + * the tag for the DistributionPointName option (tag 0) of a + * DistributionPoint is IMPLICIT and context-specific. However this + * is IMPOSSIBLE - since the underlying type (DistributionPointName) + * also relies upon context-specific tags to resolve a CHOICE. + * The real world indicates that the tag for the DistributionPoint option + * is indeed EXPLICIT. Examination of many certs' cRLDistributionPoints + * extensions shows this, and the NSS reference code also specifies + * an EXPLICIT tag for this field. + */ +const SecAsn1Template kSecAsn1DistributionPointTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_DistributionPoint) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, + offsetof(NSS_DistributionPoint,distPointName), + kSecAsn1PointerToAnyTemplate }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, + offsetof(NSS_DistributionPoint,reasons), kSecAsn1BitStringTemplate}, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | 2, + offsetof(NSS_DistributionPoint, crlIssuer), + kSecAsn1GeneralNamesTemplate + }, + { 0 } +}; + +const SecAsn1Template kSecAsn1CRLDistributionPointsTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(NSS_CRLDistributionPoints,distPoints), + kSecAsn1DistributionPointTemplate }, + { 0 } +}; + + +/* + * These are the context-specific targets of the DistributionPointName + * option. + */ +const SecAsn1Template kSecAsn1DistPointFullNameTemplate[] = { + {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, + offsetof (NSS_GeneralNames,names), kSecAsn1GeneralNamesTemplate} +}; + +const SecAsn1Template kSecAsn1DistPointRDNTemplate[] = { + {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, + offsetof (NSS_RDN,atvs), kSecAsn1RDNTemplate} +}; + +/* + * Issuing distribution points + * + * Although the spec says that the DistributionPointName element + * is context-specific, it must be explicit because the underlying + * type - a DistributionPointName - also relies on a context-specific + * tags to resolve a CHOICE. + */ + +/* kludge: ASN decoder doesn't handle + * SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER + * very well... */ +static const SecAsn1Template kSecAsn1OptBooleanTemplate[] = { + { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, 0, NULL, sizeof(SecAsn1Item) } +}; + +static const SecAsn1Template kSecAsn1OptBitStringTemplate[] = { + { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, 0, NULL, sizeof(SecAsn1Item) } +}; + +const SecAsn1Template kSecAsn1IssuingDistributionPointTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_IssuingDistributionPoint) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, + offsetof(NSS_IssuingDistributionPoint,distPointName), + kSecAsn1PointerToAnyTemplate }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 1, + offsetof(NSS_IssuingDistributionPoint,onlyUserCerts), + kSecAsn1OptBooleanTemplate}, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 2, + offsetof(NSS_IssuingDistributionPoint,onlyCACerts), + kSecAsn1OptBooleanTemplate}, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 3, + offsetof(NSS_IssuingDistributionPoint,onlySomeReasons), + kSecAsn1OptBitStringTemplate}, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_POINTER | 4, + offsetof(NSS_IssuingDistributionPoint,indirectCRL), + kSecAsn1OptBooleanTemplate}, + { 0 } +}; + + +/* + * Authority Information Access and Subject Information Access. + */ +const SecAsn1Template kSecAsn1AccessDescriptionTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_AccessDescription) }, + { SEC_ASN1_OBJECT_ID, + offsetof(NSS_AccessDescription,accessMethod) }, + /* + * NSS encoder just can't handle direct inline of an NSS_GeneralName here. + */ + { SEC_ASN1_ANY, + offsetof(NSS_AccessDescription, encodedAccessLocation) }, + { 0 } +}; + +const SecAsn1Template kSecAsn1AuthorityInfoAccessTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(NSS_AuthorityInfoAccess,accessDescriptions), + kSecAsn1AccessDescriptionTemplate, + sizeof(NSS_AuthorityInfoAccess) } +}; + +/* + * Qualified Certificate Statements templates. + * + * This is the NSS_QC_Statement.info when NSS_QC_Statement.statementId + * is CSSMOID_OID_QCS_SYNTAX_V2. + */ +const SecAsn1Template kSecAsn1SemanticsInformationTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_SemanticsInformation) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER, + offsetof(NSS_SemanticsInformation,semanticsIdentifier), + kSecAsn1ObjectIDTemplate }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER, + offsetof(NSS_SemanticsInformation, nameRegistrationAuthorities), + kSecAsn1GeneralNamesTemplate }, + { 0 } +}; + +const SecAsn1Template kSecAsn1QC_StatementTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_QC_Statement) }, + { SEC_ASN1_OBJECT_ID, + offsetof(NSS_QC_Statement,statementId) }, + { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL, + offsetof(NSS_QC_Statement, info) }, + { 0 } +}; + +const SecAsn1Template kSecAsn1QC_StatementsTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(NSS_QC_Statements,qcStatements), + kSecAsn1QC_StatementTemplate, + sizeof(NSS_QC_Statements) } +}; + +/* + * NameConstraints templates + */ +const SecAsn1Template kSecAsn1GeneralSubtreeTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_GeneralSubtree) }, + { SEC_ASN1_SEQUENCE, + offsetof(NSS_GeneralSubtree,base), + kSecAsn1GeneralNamesTemplate }, + { SEC_ASN1_INTEGER, + offsetof(NSS_GeneralSubtree,minimum) }, + { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, + offsetof(NSS_GeneralSubtree,maximum) }, + { 0, } +}; + +const SecAsn1Template kSecAsn1GeneralSubtreesTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(NSS_GeneralSubtrees,subtrees), + kSecAsn1GeneralSubtreeTemplate }, + { 0 } +}; + +const SecAsn1Template kSecAsn1NameConstraintsTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_NameConstraints) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, + offsetof(NSS_NameConstraints,permittedSubtrees), + kSecAsn1GeneralSubtreesTemplate }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 1, + offsetof(NSS_NameConstraints,excludedSubtrees), + kSecAsn1GeneralSubtreesTemplate }, + { 0 } +}; + +/* + * PolicyMappings templates + */ +const SecAsn1Template kSecAsn1PolicyMappingTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_PolicyMapping) }, + { SEC_ASN1_OBJECT_ID, + offsetof(NSS_PolicyMapping,issuerDomainPolicy) }, + { SEC_ASN1_OBJECT_ID, + offsetof(NSS_PolicyMapping,subjectDomainPolicy) }, + { 0 } +}; + +const SecAsn1Template kSecAsn1PolicyMappingsTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, + offsetof(NSS_PolicyMappings,policyMappings), + kSecAsn1PolicyMappingTemplate }, + { 0 } +}; + +/* + * PolicyConstraints templates + */ +const SecAsn1Template kSecAsn1PolicyConstraintsTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(NSS_PolicyConstraints) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, + offsetof(NSS_PolicyConstraints,requireExplicitPolicy) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 1, + offsetof(NSS_PolicyConstraints,inhibitPolicyMapping) }, + { 0 } +}; + +