1/* 2 * Copyright (c) 2003-2006,2008-2010 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