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