/* * Copyright (c) 2012-2014 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@ * * tsaTemplates.c - ASN1 templates Time Stamping Authority requests and responses */ #include /* for kSecAsn1AlgorithmIDTemplate */ #include #include #include #include "tsaTemplates.h" #include "cmslocal.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-const-variable" // *** from CMSEncoder.cpp typedef struct { CSSM_OID contentType; CSSM_DATA content; } SimpleContentInfo; // SecCmsContentInfoTemplate static const SecAsn1Template cmsSimpleContentInfoTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SimpleContentInfo) }, { SEC_ASN1_OBJECT_ID, offsetof(SimpleContentInfo, contentType) }, { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(SimpleContentInfo, content), kSecAsn1AnyTemplate }, { 0, } }; #pragma mark ----- tsa ----- /* Accuracy ::= SEQUENCE { seconds INTEGER OPTIONAL, millis [0] INTEGER (1..999) OPTIONAL, micros [1] INTEGER (1..999) OPTIONAL } */ const SecAsn1Template kSecAsn1SignedIntegerTemplate[] = { { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 0, NULL, sizeof(SecAsn1Item) } }; const SecAsn1Template kSecAsn1UnsignedIntegerTemplate[] = { { SEC_ASN1_INTEGER, 0, NULL, sizeof(SecAsn1Item) } }; const SecAsn1Template kSecAsn1TSAAccuracyTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSAAccuracy) }, { SEC_ASN1_INTEGER, offsetof(SecAsn1TSAAccuracy, seconds) }, { SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSAAccuracy, millis), kSecAsn1UnsignedIntegerTemplate }, { SEC_ASN1_CONTEXT_SPECIFIC | 1 | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSAAccuracy, micros), kSecAsn1UnsignedIntegerTemplate }, { 0 } }; /* MessageImprint ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, hashedMessage OCTET STRING } */ const SecAsn1Template kSecAsn1TSAMessageImprintTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSAMessageImprint) }, { SEC_ASN1_INLINE, offsetof(SecAsn1TSAMessageImprint,hashAlgorithm), kSecAsn1AlgorithmIDTemplate }, { SEC_ASN1_OCTET_STRING, offsetof(SecAsn1TSAMessageImprint,hashedMessage) }, { 0 } }; /* TimeStampReq ::= SEQUENCE { version INTEGER { v1(1) }, messageImprint MessageImprint, --a hash algorithm OID and the hash value of the data to be --time-stamped reqPolicy TSAPolicyId OPTIONAL, nonce INTEGER OPTIONAL, certReq BOOLEAN DEFAULT FALSE, extensions [0] IMPLICIT Extensions OPTIONAL } MessageImprint ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, hashedMessage OCTET STRING } TSAPolicyId ::= OBJECT IDENTIFIER */ const SecAsn1Template kSecAsn1TSATimeStampReqTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSATimeStampReq) }, { SEC_ASN1_INTEGER, offsetof(SecAsn1TSATimeStampReq, version) }, { SEC_ASN1_INLINE, offsetof(SecAsn1TSATimeStampReq,messageImprint), kSecAsn1TSAMessageImprintTemplate }, { SEC_ASN1_OBJECT_ID | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATimeStampReq,reqPolicy) }, { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATimeStampReq, nonce) }, { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATimeStampReq, certReq) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(SecAsn1TSATimeStampReq, extensions), kSecAsn1SequenceOfCertExtensionTemplate }, { 0 } }; /* PKIFreeText ::= SEQUENCE { SIZE (1..MAX) OF UTF8String -- text encoded as UTF-8 String (note: each UTF8String SHOULD -- include an RFC 1766 language tag to indicate the language -- of the contained text) } See e.g. kSecAsn1SequenceOfUTF8StringTemplate */ const SecAsn1Template kSecAsn1TSAPKIStatusInfoTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSAPKIStatusInfo) }, { SEC_ASN1_INTEGER, offsetof(SecAsn1TSAPKIStatusInfo, status) }, { SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSAPKIStatusInfo, statusString) }, { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSAPKIStatusInfo,failInfo) }, { 0 } }; const SecAsn1Template kSecAsn1TSAPKIStatusInfoTemplateRFC3161[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSAPKIStatusInfo) }, { SEC_ASN1_INTEGER, offsetof(SecAsn1TSAPKIStatusInfo, status) }, { SEC_ASN1_UTF8_STRING | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSAPKIStatusInfo, statusString) }, { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSAPKIStatusInfo,failInfo) }, { 0 } }; const SecAsn1Template kSecAsn1TSATimeStampRespTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TimeStampResp) }, { SEC_ASN1_INLINE, offsetof(SecAsn1TimeStampResp,status), kSecAsn1TSAPKIStatusInfoTemplate }, { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TimeStampResp,timeStampToken), SecCmsContentInfoTemplate }, { 0 } }; // Decode the status but not the TimeStampToken const SecAsn1Template kSecAsn1TSATimeStampRespTemplateDER[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TimeStampRespDER) }, { SEC_ASN1_INLINE, offsetof(SecAsn1TimeStampRespDER,status), kSecAsn1TSAPKIStatusInfoTemplate }, { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL ,//| SEC_ASN1_SAVE, offsetof(SecAsn1TimeStampRespDER, timeStampTokenDER), kSecAsn1AnyTemplate }, { 0 } }; /* RFC 3161 Time-Stamp Protocol (TSP) August 2001 TimeStampToken ::= ContentInfo -- contentType is id-signedData as defined in [CMS] -- content is SignedData as defined in([CMS]) -- eContentType within SignedData is id-ct-TSTInfo -- eContent within SignedData is TSTInfo TSTInfo ::= SEQUENCE { version INTEGER { v1(1) }, policy TSAPolicyId, messageImprint MessageImprint, -- MUST have the same value as the similar field in -- TimeStampReq serialNumber INTEGER, -- Time-Stamping users MUST be ready to accommodate integers -- up to 160 bits. genTime GeneralizedTime, accuracy Accuracy OPTIONAL, ordering BOOLEAN DEFAULT FALSE, nonce INTEGER OPTIONAL, -- MUST be present if the similar field was present -- in TimeStampReq. In that case it MUST have the same value. tsa [0] GeneralName OPTIONAL, extensions [1] IMPLICIT Extensions OPTIONAL } Accuracy ::= SEQUENCE { seconds INTEGER OPTIONAL, millis [0] INTEGER (1..999) OPTIONAL, micros [1] INTEGER (1..999) OPTIONAL } */ const SecAsn1Template kSecAsn1TSATSTInfoTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSATSTInfo) }, { SEC_ASN1_INTEGER, offsetof(SecAsn1TSATSTInfo, version) }, { SEC_ASN1_OBJECT_ID, offsetof(SecAsn1TSATSTInfo,reqPolicy) }, { SEC_ASN1_INLINE, offsetof(SecAsn1TSATSTInfo,messageImprint), kSecAsn1TSAMessageImprintTemplate }, { SEC_ASN1_INTEGER, offsetof(SecAsn1TSATSTInfo, serialNumber) }, { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, offsetof(SecAsn1TSATSTInfo,genTime) }, { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATSTInfo,accuracy), kSecAsn1TSAAccuracyTemplate }, { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATSTInfo, ordering) }, { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATSTInfo, nonce) }, { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATSTInfo, tsa), kSecAsn1GenNameOtherNameTemplate}, { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1 | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TSATSTInfo, extensions), kSecAsn1CertExtensionTemplate }, { 0 } }; #pragma clang diagnostic pop