1/* 2 * Copyright (c) 2012 Apple Computer, 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 * tsaTemplates.c - ASN1 templates Time Stamping Authority requests and responses 24 */ 25 26#include <security_asn1/keyTemplates.h> /* for kSecAsn1AlgorithmIDTemplate */ 27#include <security_asn1/SecAsn1Templates.h> 28#include <stddef.h> 29#include <assert.h> 30 31#include "tsaTemplates.h" 32#include "cmslocal.h" 33 34// *** from CMSEncoder.cpp 35 36typedef struct { 37 CSSM_OID contentType; 38 CSSM_DATA content; 39} SimpleContentInfo; 40 41// SecCmsContentInfoTemplate 42static const SecAsn1Template cmsSimpleContentInfoTemplate[] = { 43 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SimpleContentInfo) }, 44 { SEC_ASN1_OBJECT_ID, offsetof(SimpleContentInfo, contentType) }, 45 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 46 offsetof(SimpleContentInfo, content), 47 kSecAsn1AnyTemplate }, 48 { 0, } 49}; 50 51#pragma mark ----- tsa ----- 52 53/* 54Accuracy ::= SEQUENCE { 55 seconds INTEGER OPTIONAL, 56 millis [0] INTEGER (1..999) OPTIONAL, 57 micros [1] INTEGER (1..999) OPTIONAL } 58*/ 59 60const SecAsn1Template kSecAsn1SignedIntegerTemplate[] = { 61 { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 0, NULL, sizeof(SecAsn1Item) } 62}; 63 64const SecAsn1Template kSecAsn1UnsignedIntegerTemplate[] = { 65 { SEC_ASN1_INTEGER, 0, NULL, sizeof(SecAsn1Item) } 66}; 67 68const SecAsn1Template kSecAsn1TSAAccuracyTemplate[] = { 69 { SEC_ASN1_SEQUENCE, 70 0, NULL, sizeof(SecAsn1TSAAccuracy) }, 71 { SEC_ASN1_INTEGER, 72 offsetof(SecAsn1TSAAccuracy, seconds) }, 73 { SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_OPTIONAL, 74 offsetof(SecAsn1TSAAccuracy, millis), kSecAsn1UnsignedIntegerTemplate }, 75 { SEC_ASN1_CONTEXT_SPECIFIC | 1 | SEC_ASN1_OPTIONAL, 76 offsetof(SecAsn1TSAAccuracy, micros), kSecAsn1UnsignedIntegerTemplate }, 77 { 0 } 78}; 79 80/* 81MessageImprint ::= SEQUENCE { 82 hashAlgorithm AlgorithmIdentifier, 83 hashedMessage OCTET STRING } 84*/ 85 86const SecAsn1Template kSecAsn1TSAMessageImprintTemplate[] = { 87 { SEC_ASN1_SEQUENCE, 88 0, NULL, sizeof(SecAsn1TSAMessageImprint) }, 89 { SEC_ASN1_INLINE, offsetof(SecAsn1TSAMessageImprint,hashAlgorithm), 90 kSecAsn1AlgorithmIDTemplate }, 91 { SEC_ASN1_OCTET_STRING, 92 offsetof(SecAsn1TSAMessageImprint,hashedMessage) }, 93 { 0 } 94}; 95 96/* 97 TimeStampReq ::= SEQUENCE { 98 version INTEGER { v1(1) }, 99 messageImprint MessageImprint, 100 --a hash algorithm OID and the hash value of the data to be 101 --time-stamped 102 reqPolicy TSAPolicyId OPTIONAL, 103 nonce INTEGER OPTIONAL, 104 certReq BOOLEAN DEFAULT FALSE, 105 extensions [0] IMPLICIT Extensions OPTIONAL } 106 107 MessageImprint ::= SEQUENCE { 108 hashAlgorithm AlgorithmIdentifier, 109 hashedMessage OCTET STRING } 110 111 TSAPolicyId ::= OBJECT IDENTIFIER 112*/ 113 114const SecAsn1Template kSecAsn1TSATimeStampReqTemplate[] = { 115 { SEC_ASN1_SEQUENCE, 116 0, NULL, sizeof(SecAsn1TSATimeStampReq) }, 117 { SEC_ASN1_INTEGER, 118 offsetof(SecAsn1TSATimeStampReq, version) }, 119 { SEC_ASN1_INLINE, offsetof(SecAsn1TSATimeStampReq,messageImprint), 120 kSecAsn1TSAMessageImprintTemplate }, 121 { SEC_ASN1_OBJECT_ID | SEC_ASN1_OPTIONAL, 122 offsetof(SecAsn1TSATimeStampReq,reqPolicy) }, 123 { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, 124 offsetof(SecAsn1TSATimeStampReq, nonce) }, 125 { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, 126 offsetof(SecAsn1TSATimeStampReq, certReq) }, 127 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 128 offsetof(SecAsn1TSATimeStampReq, extensions), 129 kSecAsn1SequenceOfCertExtensionTemplate }, 130 { 0 } 131}; 132 133/* 134 PKIFreeText ::= SEQUENCE { 135 SIZE (1..MAX) OF UTF8String 136 -- text encoded as UTF-8 String (note: each UTF8String SHOULD 137 -- include an RFC 1766 language tag to indicate the language -- of the contained text) 138 } 139 140 See e.g. kSecAsn1SequenceOfUTF8StringTemplate 141*/ 142 143const SecAsn1Template kSecAsn1TSAPKIStatusInfoTemplate[] = { 144 { SEC_ASN1_SEQUENCE, 145 0, NULL, sizeof(SecAsn1TSAPKIStatusInfo) }, 146 { SEC_ASN1_INTEGER, 147 offsetof(SecAsn1TSAPKIStatusInfo, status) }, 148 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE | SEC_ASN1_OPTIONAL, 149 offsetof(SecAsn1TSAPKIStatusInfo, statusString) }, 150 { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, 151 offsetof(SecAsn1TSAPKIStatusInfo,failInfo) }, 152 { 0 } 153}; 154 155const SecAsn1Template kSecAsn1TSAPKIStatusInfoTemplateRFC3161[] = { 156 { SEC_ASN1_SEQUENCE, 157 0, NULL, sizeof(SecAsn1TSAPKIStatusInfo) }, 158 { SEC_ASN1_INTEGER, 159 offsetof(SecAsn1TSAPKIStatusInfo, status) }, 160 { SEC_ASN1_UTF8_STRING | SEC_ASN1_OPTIONAL, 161 offsetof(SecAsn1TSAPKIStatusInfo, statusString) }, 162 { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, 163 offsetof(SecAsn1TSAPKIStatusInfo,failInfo) }, 164 { 0 } 165}; 166 167const SecAsn1Template kSecAsn1TSATimeStampRespTemplate[] = { 168 { SEC_ASN1_SEQUENCE, 169 0, NULL, sizeof(SecAsn1TimeStampResp) }, 170 { SEC_ASN1_INLINE, offsetof(SecAsn1TimeStampResp,status), 171 kSecAsn1TSAPKIStatusInfoTemplate }, 172 { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, offsetof(SecAsn1TimeStampResp,timeStampToken), 173 SecCmsContentInfoTemplate }, 174 { 0 } 175}; 176 177// Decode the status but not the TimeStampToken 178const SecAsn1Template kSecAsn1TSATimeStampRespTemplateDER[] = { 179 { SEC_ASN1_SEQUENCE, 180 0, NULL, sizeof(SecAsn1TimeStampRespDER) }, 181 { SEC_ASN1_INLINE, offsetof(SecAsn1TimeStampRespDER,status), 182 kSecAsn1TSAPKIStatusInfoTemplate }, 183 { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL ,//| SEC_ASN1_SAVE, 184 offsetof(SecAsn1TimeStampRespDER, timeStampTokenDER), kSecAsn1AnyTemplate }, 185 { 0 } 186}; 187 188/* 189 RFC 3161 Time-Stamp Protocol (TSP) August 2001 190 191 TimeStampToken ::= ContentInfo 192 193 -- contentType is id-signedData as defined in [CMS] 194 -- content is SignedData as defined in([CMS]) 195 -- eContentType within SignedData is id-ct-TSTInfo 196 -- eContent within SignedData is TSTInfo 197 198 TSTInfo ::= SEQUENCE { 199 version INTEGER { v1(1) }, 200 policy TSAPolicyId, 201 messageImprint MessageImprint, 202 -- MUST have the same value as the similar field in 203 -- TimeStampReq 204 serialNumber INTEGER, 205 -- Time-Stamping users MUST be ready to accommodate integers 206 -- up to 160 bits. 207 genTime GeneralizedTime, 208 accuracy Accuracy OPTIONAL, 209 ordering BOOLEAN DEFAULT FALSE, 210 nonce INTEGER OPTIONAL, 211 -- MUST be present if the similar field was present 212 -- in TimeStampReq. In that case it MUST have the same value. 213 tsa [0] GeneralName OPTIONAL, 214 extensions [1] IMPLICIT Extensions OPTIONAL } 215 216 Accuracy ::= SEQUENCE { 217 seconds INTEGER OPTIONAL, 218 millis [0] INTEGER (1..999) OPTIONAL, 219 micros [1] INTEGER (1..999) OPTIONAL } 220*/ 221 222const SecAsn1Template kSecAsn1TSATSTInfoTemplate[] = { 223 { SEC_ASN1_SEQUENCE, 224 0, NULL, sizeof(SecAsn1TSATSTInfo) }, 225 { SEC_ASN1_INTEGER, 226 offsetof(SecAsn1TSATSTInfo, version) }, 227 { SEC_ASN1_OBJECT_ID, 228 offsetof(SecAsn1TSATSTInfo,reqPolicy) }, 229 { SEC_ASN1_INLINE, offsetof(SecAsn1TSATSTInfo,messageImprint), 230 kSecAsn1TSAMessageImprintTemplate }, 231 { SEC_ASN1_INTEGER, 232 offsetof(SecAsn1TSATSTInfo, serialNumber) }, 233 { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 234 offsetof(SecAsn1TSATSTInfo,genTime) }, 235 { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, 236 offsetof(SecAsn1TSATSTInfo,accuracy), 237 kSecAsn1TSAAccuracyTemplate }, 238 { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, 239 offsetof(SecAsn1TSATSTInfo, ordering) }, 240 { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, 241 offsetof(SecAsn1TSATSTInfo, nonce) }, 242 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_OPTIONAL, 243 offsetof(SecAsn1TSATSTInfo, tsa), 244 kSecAsn1GenNameOtherNameTemplate}, 245 246 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1 | SEC_ASN1_OPTIONAL, 247 offsetof(SecAsn1TSATSTInfo, extensions), 248 kSecAsn1CertExtensionTemplate }, 249 { 0 } 250}; 251 252 253