1/*
2 * Copyright (c) 2003-2006,2008-2012 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 * ocspTemplates.h -  ASN1 templates OCSP requests and responses.
24 */
25
26#ifndef	_OCSP_TEMPLATES_H_
27#define _OCSP_TEMPLATES_H_
28
29#include <Security/X509Templates.h> /* NSS_CertExtension */
30#include <Security/nameTemplates.h> /* NSS_GeneralName and support */
31
32#ifdef  __cplusplus
33extern "C" {
34#endif
35
36// MARK: ----- OCSP Request -----
37
38/*
39 * CertID          ::=     SEQUENCE {
40 *		hashAlgorithm		AlgorithmIdentifier,
41 *		issuerNameHash		OCTET STRING, -- Hash of Issuer's DN
42 *		issuerKeyHash		OCTET STRING, -- Hash of Issuers public key
43 *		serialNumber		CertificateSerialNumber }   -- i.e., INTEGER
44 */
45typedef struct {
46	SecAsn1AlgId		algId;
47	SecAsn1Item							issuerNameHash;
48	SecAsn1Item							issuerPubKeyHash;
49	SecAsn1Item							serialNumber;
50} SecAsn1OCSPCertID;
51
52extern const SecAsn1Template kSecAsn1OCSPCertIDTemplate[];
53
54/*
55 * Request         ::=     SEQUENCE {
56 *		reqCert                     CertID,
57 *		singleRequestExtensions     [0] EXPLICIT Extensions OPTIONAL }
58 */
59typedef struct {
60	SecAsn1OCSPCertID					reqCert;
61    NSS_CertExtension 					**extensions;		// optional
62} SecAsn1OCSPRequest;
63
64extern const SecAsn1Template kSecAsn1OCSPRequestTemplate[];
65
66/*
67 * Signature       ::=     SEQUENCE {
68 *		signatureAlgorithm      AlgorithmIdentifier,
69 *		signature               BIT STRING,
70 *		certs               [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL}
71 *
72 * Since we wish to avoid knowing anything about the details of the certs,
73 * we declare them here as ASN_ANY, get/set as raw data, and leave it to
74 * the CL to parse them.
75 */
76typedef struct {
77	SecAsn1AlgId		algId;
78	SecAsn1Item							sig;		// length in BITS
79	SecAsn1Item							**certs;	// OPTIONAL
80} SecAsn1OCSPSignature;
81
82extern const SecAsn1Template kSecAsn1OCSPSignatureTemplate[];
83
84/*
85 * TBSRequest      ::=     SEQUENCE {
86 *		version             [0]     EXPLICIT Version DEFAULT v1,
87 *		requestorName       [1]     EXPLICIT GeneralName OPTIONAL,
88 *		requestList                 SEQUENCE OF Request,
89 *		requestExtensions   [2]     EXPLICIT Extensions OPTIONAL }
90 */
91typedef struct {
92	SecAsn1Item							*version;				// OPTIONAL
93	NSS_GeneralName						*requestorName;			// OPTIONAL
94	SecAsn1OCSPRequest					**requestList;
95    NSS_CertExtension 					**requestExtensions;	// OPTIONAL
96} SecAsn1OCSPTbsRequest;
97
98extern const SecAsn1Template kSecAsn1OCSPTbsRequestTemplate[];
99
100/*
101 * OCSPRequest     ::=     SEQUENCE {
102 *		tbsRequest                  TBSRequest,
103 *		optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
104 */
105typedef struct {
106	SecAsn1OCSPTbsRequest				tbsRequest;
107	SecAsn1OCSPSignature				*signature;			// OPTIONAL
108} SecAsn1OCSPSignedRequest;
109
110extern const SecAsn1Template kSecAsn1OCSPSignedRequestTemplate[];
111
112// MARK: ----- OCSP Response -----
113
114/*
115 * CertStatus ::= CHOICE {
116 *		good        [0]     IMPLICIT NULL,
117 *		revoked     [1]     IMPLICIT RevokedInfo,
118 *		unknown     [2]     IMPLICIT UnknownInfo }
119 *
120 * RevokedInfo ::= SEQUENCE {
121 *		revocationTime              GeneralizedTime,
122 *		revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
123 *
124 * UnknownInfo ::= NULL -- this can be replaced with an enumeration
125 *
126 * See <Security/certextensions.h> for enum values of CE_CrlReason.
127 */
128typedef struct {
129	SecAsn1Item					revocationTime;
130	SecAsn1Item					*revocationReason;		// OPTIONAL, CE_CrlReason
131} SecAsn1OCSPRevokedInfo;
132
133typedef union {
134	SecAsn1OCSPRevokedInfo		*revokedInfo;
135	SecAsn1Item					*nullData;
136} SecAsn1OCSPCertStatus;
137
138typedef enum {
139	CS_Good = 0,
140	CS_Revoked = 1,
141	CS_Unknown = 2,
142	CS_NotParsed = 0xff		/* Not in protocol: means value not parsed or seen */
143} SecAsn1OCSPCertStatusTag;
144
145extern const SecAsn1Template kSecAsn1OCSPRevokedInfoTemplate[];
146
147/*
148 * Encode/decode CertStatus separately using one of these �hree templates.
149 * The result goes into SecAsn1OCSPSingleResponse.certStatus on encode.
150 */
151extern const SecAsn1Template kSecAsn1OCSPCertStatusGoodTemplate[];
152extern const SecAsn1Template kSecAsn1OCSPCertStatusRevokedTemplate[];
153extern const SecAsn1Template kSecAsn1OCSPCertStatusUnknownTemplate[];
154
155/*
156 * SingleResponse ::= SEQUENCE {
157 *		certID                       CertID,
158 *		certStatus                   CertStatus,
159 *		thisUpdate                   GeneralizedTime,
160 *		nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
161 *		singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
162 */
163typedef struct {
164	SecAsn1OCSPCertID			certID;
165	SecAsn1Item					certStatus;				// ASN_ANY here
166	SecAsn1Item					thisUpdate;				// GeneralizedTime
167	SecAsn1Item					*nextUpdate;			// GeneralizedTime, OPTIONAL
168    NSS_CertExtension 			**singleExtensions;		// OPTIONAL
169} SecAsn1OCSPSingleResponse;
170
171extern const SecAsn1Template kSecAsn1OCSPSingleResponseTemplate[];
172
173/*
174 * ResponderID ::= CHOICE {
175 *     byName               EXPLICIT [1] Name,
176 *     byKey                EXPLICIT [2] KeyHash }
177 *
178 * Since our ASN.1 encoder/decoder can't handle CHOICEs very well, we encode
179 * this separately using one of the following two templates. On encode the
180 * result if this step of the encode goes into SecAsn1OCSPResponseData.responderID,
181 * where it's treated as an ANY_ANY when encoding that struct. The reverse happens
182 * on decode.
183 */
184typedef union {
185	SecAsn1Item					byName;
186	SecAsn1Item					byKey;		// key hash in OCTET STRING
187} SecAsn1OCSPResponderID;
188
189typedef enum {
190	RIT_Name	= 1,
191	RIT_Key		= 2
192} SecAsn1OCSPResponderIDTag;
193
194extern const SecAsn1Template kSecAsn1OCSPResponderIDAsNameTemplate[];
195extern const SecAsn1Template kSecAsn1OCSPResponderIDAsKeyTemplate[];
196
197/*
198 * ResponseData ::= SEQUENCE {
199 *		version              [0] EXPLICIT Version DEFAULT v1,
200 *		responderID              ResponderID,
201 *		producedAt               GeneralizedTime,
202 *		responses                SEQUENCE OF SingleResponse,
203 *		responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
204 */
205typedef struct {
206	SecAsn1Item					*version;		// OPTIONAL
207	SecAsn1Item					responderID;	// ASN_ANY here, decode/encode separately
208	SecAsn1Item					producedAt;		// GeneralizedTime
209	SecAsn1OCSPSingleResponse   **responses;
210    NSS_CertExtension 			**responseExtensions;	// OPTIONAL
211} SecAsn1OCSPResponseData;
212
213extern const SecAsn1Template kSecAsn1OCSPResponseDataTemplate[];
214
215/*
216 * BasicOCSPResponse       ::= SEQUENCE {
217 *		tbsResponseData      ResponseData,
218 *		signatureAlgorithm   AlgorithmIdentifier,
219 *		signature            BIT STRING,
220 *		certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
221 *
222 * Since we ALWAYS encode the tbsResponseData in preparation for signing,
223 * we declare it as a raw ASN_ANY in the BasicOCSPResponse.
224 *
225 * Certs are likewise ASN_ANY since we use the CL to parse and create them.
226 */
227typedef struct {
228	SecAsn1Item						tbsResponseData;
229	SecAsn1AlgId	algId;
230	SecAsn1Item						sig;		// length in BITS
231	SecAsn1Item						**certs;	// optional
232} SecAsn1OCSPBasicResponse;
233
234extern const SecAsn1Template kSecAsn1OCSPBasicResponseTemplate[];
235
236/*
237 * ResponseBytes ::=       SEQUENCE {
238 *		responseType   OBJECT IDENTIFIER,
239 *		response       OCTET STRING }
240 *
241 * The contents of response are actually an encoded SecAsn1OCSPBasicResponse (at
242 * least until another response type is defined).
243 */
244typedef struct {
245	SecAsn1Oid					responseType;
246	SecAsn1Item					response;
247} SecAsn1OCSPResponseBytes;
248
249extern const SecAsn1Template kSecAsn1OCSPResponseBytesTemplate[];
250
251/*
252 * OCSPResponse ::= SEQUENCE {
253 *		responseStatus         OCSPResponseStatus,		-- an ENUM
254 *		responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
255 */
256typedef struct {
257	SecAsn1Item					responseStatus;		// see enum below
258	SecAsn1OCSPResponseBytes	*responseBytes;		// optional
259} SecAsn1OCSPResponse;
260
261extern const SecAsn1Template kSecAsn1OCSPResponseTemplate[];
262
263typedef enum {
264	RS_Success = 0,
265	RS_MalformedRequest = 1,
266	RS_InternalError = 2,
267	RS_TryLater = 3,
268	RS_Unused = 4,
269	RS_SigRequired = 5,
270	RS_Unauthorized = 6
271} SecAsn1OCSPResponseStatus;
272
273/*
274 * This is not part of the OCSP protocol; it's used in the communication between
275 * the Apple X.509 TP module and the ocspd server.
276 *
277 * OCSPDRequest ::= SEQUENCE {
278 *		cacheWriteDisable :: = EXPLICIT [0] BOOL OPTIONAL;	-- cache write disable
279 *															--  default FALSE
280 *		cacheWriteDisable :: = EXPLICIT [1] BOOL OPTIONAL;	-- cache read disable
281 *															--  default FALSE
282 *		certID		::= OCTET STRING;						-- for cache lookup
283 *		ocspReq		::= EXPLICIT [2] OCTET STRING OPTIONAL;	-- for net fetch
284 *		localResp	::= EXPLICIT [3] IA5String OPTIONAL;	-- for local responder
285 *		urls		::= EXPLICIT [4] SEQUENCE of IA5String OPTIONAL;
286 *															-- for normal net fetch
287 * };
288 */
289
290#define OCSPD_REQUEST_VERS	0
291
292typedef struct {
293	SecAsn1Item			*cacheWriteDisable;
294	SecAsn1Item			*cacheReadDisable;
295	SecAsn1Item			certID;				// DER encoded SecAsn1OCSPCertID
296	SecAsn1Item			*ocspReq;			// DER encoded SecAsn1OCSPSignedRequest
297	SecAsn1Item			*localRespURI;		// local responder URI
298	SecAsn1Item			**urls;				// normal URIs
299
300} SecAsn1OCSPDRequest;
301
302/*
303 * And this is a sequence of them, packaged up and sent to ocspd in one RPC.
304 */
305typedef struct {
306	SecAsn1Item			version;			// OCSPD_REQUEST_VERS
307	SecAsn1OCSPDRequest	**requests;
308} SecAsn1OCSPDRequests;
309
310extern const SecAsn1Template kSecAsn1OCSPDRequestTemplate[];
311extern const SecAsn1Template kSecAsn1OCSPDRequestsTemplate[];
312
313/*
314 * Unordered set of replies from ocsdp; they map back to individual
315 * SecAsn1OCSPDRequests by the encoded certID (which is obtained from the
316 * SecAsn1OCSPDRequest, NOT from the OCSP response).
317 */
318typedef struct {
319	SecAsn1Item			certID;			// DER encoded SecAsn1OCSPCertID
320	SecAsn1Item			ocspResp;		// DER encoded SecAsn1OCSPResponse
321} SecAsn1OCSPDReply;
322
323#define OCSPD_REPLY_VERS	0
324
325typedef struct {
326	SecAsn1Item			version;			// OCSPD_REPLY_VERS
327	SecAsn1OCSPDReply	**replies;
328} SecAsn1OCSPReplies;
329
330extern const SecAsn1Template kSecAsn1OCSPDReplyTemplate[];
331extern const SecAsn1Template kSecAsn1OCSPDRepliesTemplate[];
332
333#ifdef  __cplusplus
334}
335#endif
336
337#endif	/* _OCSP_TEMPLATES_H_ */
338