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