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.cpp - ASN1 templates OCSP requests and responses. 24 */ 25 26#include "ocspTemplates.h" 27#include "keyTemplates.h" /* for kSecAsn1AlgorithmIDTemplate */ 28#include "SecAsn1Templates.h" 29#include <stddef.h> 30#include <assert.h> 31 32// MARK: ----- OCSP Request ----- 33 34const SecAsn1Template kSecAsn1OCSPCertIDTemplate[] = { 35 { SEC_ASN1_SEQUENCE, 36 0, NULL, sizeof(SecAsn1OCSPCertID) }, 37 { SEC_ASN1_INLINE, 38 offsetof(SecAsn1OCSPCertID, algId), 39 kSecAsn1AlgorithmIDTemplate }, 40 { SEC_ASN1_OCTET_STRING, offsetof(SecAsn1OCSPCertID, issuerNameHash) }, 41 { SEC_ASN1_OCTET_STRING, offsetof(SecAsn1OCSPCertID, issuerPubKeyHash) }, 42 /* serial number is SIGNED integer */ 43 { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 44 offsetof(SecAsn1OCSPCertID, serialNumber) }, 45 { 0 } 46}; 47 48const SecAsn1Template kSecAsn1OCSPRequestTemplate[] = { 49 { SEC_ASN1_SEQUENCE, 50 0, NULL, sizeof(SecAsn1OCSPRequest) }, 51 { SEC_ASN1_INLINE, 52 offsetof(SecAsn1OCSPRequest, reqCert), 53 kSecAsn1OCSPCertIDTemplate }, 54 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 55 SEC_ASN1_EXPLICIT | 0, 56 offsetof(SecAsn1OCSPRequest, extensions), 57 kSecAsn1SequenceOfCertExtensionTemplate }, 58 { 0 } 59}; 60 61const SecAsn1Template kSecAsn1OCSPSignatureTemplate[] = { 62 { SEC_ASN1_SEQUENCE, 63 0, NULL, sizeof(SecAsn1OCSPSignature) }, 64 { SEC_ASN1_INLINE, 65 offsetof(SecAsn1OCSPSignature, algId), 66 kSecAsn1AlgorithmIDTemplate }, 67 { SEC_ASN1_BIT_STRING, offsetof(SecAsn1OCSPSignature, sig) }, 68 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 69 SEC_ASN1_EXPLICIT | 0, 70 offsetof(SecAsn1OCSPSignature, certs), 71 kSecAsn1SequenceOfAnyTemplate }, 72 { 0 } 73}; 74 75const SecAsn1Template kSecAsn1OCSPTbsRequestTemplate[] = { 76 { SEC_ASN1_SEQUENCE, 77 0, NULL, sizeof(SecAsn1OCSPTbsRequest) }, 78 /* optional version, explicit tag 0, default 0 */ 79 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 80 SEC_ASN1_CONTEXT_SPECIFIC | 0, 81 offsetof(SecAsn1OCSPTbsRequest, version), 82 kSecAsn1PointerToIntegerTemplate }, 83 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 84 SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1, 85 offsetof(SecAsn1OCSPTbsRequest, requestorName), 86 kSecAsn1GeneralNameTemplate }, 87 { SEC_ASN1_SEQUENCE_OF, 88 offsetof(SecAsn1OCSPTbsRequest, requestList), 89 kSecAsn1OCSPRequestTemplate }, 90 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 91 SEC_ASN1_EXPLICIT | 2, 92 offsetof(SecAsn1OCSPTbsRequest, requestExtensions), 93 kSecAsn1SequenceOfCertExtensionTemplate }, 94 { 0 } 95}; 96 97const SecAsn1Template kSecAsn1OCSPSignedRequestTemplate[] = { 98 { SEC_ASN1_SEQUENCE, 99 0, NULL, sizeof(SecAsn1OCSPSignedRequest) }, 100 { SEC_ASN1_INLINE, 101 offsetof(SecAsn1OCSPSignedRequest, tbsRequest), 102 kSecAsn1OCSPTbsRequestTemplate }, 103 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 104 SEC_ASN1_POINTER | SEC_ASN1_EXPLICIT | 0, 105 offsetof(SecAsn1OCSPSignedRequest, signature), 106 kSecAsn1OCSPSignatureTemplate }, 107 { 0 } 108}; 109 110// MARK: ----- OCSP Response ----- 111 112const SecAsn1Template kSecAsn1OCSPRevokedInfoTemplate[] = { 113 { SEC_ASN1_SEQUENCE, 114 0, NULL, sizeof(SecAsn1OCSPRevokedInfo) }, 115 { SEC_ASN1_GENERALIZED_TIME, offsetof(SecAsn1OCSPRevokedInfo, revocationTime) }, 116 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 117 SEC_ASN1_CONTEXT_SPECIFIC | 0, 118 offsetof(SecAsn1OCSPRevokedInfo, revocationReason) , 119 kSecAsn1PointerToEnumeratedTemplate }, 120 { 0 } 121}; 122 123/* three context-specific templates, app picks one of these */ 124 125/* 126 * Encode/decode CertStatus separately using one of these †hree templates. 127 * The result goes into SecAsn1OCSPSingleResponse.certStatus on encode. 128 */ 129const SecAsn1Template kSecAsn1OCSPCertStatusGoodTemplate[] = { 130 { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 0, 131 offsetof(SecAsn1OCSPCertStatus, nullData), 132 kSecAsn1NullTemplate } 133}; 134 135const SecAsn1Template kSecAsn1OCSPCertStatusRevokedTemplate[] = { 136 { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, 137 offsetof(SecAsn1OCSPCertStatus, revokedInfo) , 138 kSecAsn1OCSPRevokedInfoTemplate } 139}; 140 141const SecAsn1Template kSecAsn1OCSPCertStatusUnknownTemplate[] = { 142 { SEC_ASN1_CONTEXT_SPECIFIC | 2, 143 offsetof(SecAsn1OCSPCertStatus, nullData), 144 kSecAsn1NullTemplate } 145}; 146 147const SecAsn1Template kSecAsn1OCSPSingleResponseTemplate[] = { 148 { SEC_ASN1_SEQUENCE, 149 0, NULL, sizeof(SecAsn1OCSPSingleResponse) }, 150 { SEC_ASN1_INLINE, 151 offsetof(SecAsn1OCSPSingleResponse, certID), 152 kSecAsn1OCSPCertIDTemplate }, 153 { SEC_ASN1_ANY, 154 offsetof(SecAsn1OCSPSingleResponse, certStatus), 155 kSecAsn1AnyTemplate }, 156 { SEC_ASN1_GENERALIZED_TIME, offsetof(SecAsn1OCSPSingleResponse, thisUpdate) }, 157 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 158 SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT | 0, 159 offsetof(SecAsn1OCSPSingleResponse, nextUpdate), 160 kSecAsn1PointerToGeneralizedTimeTemplate }, 161 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 162 SEC_ASN1_EXPLICIT | 1, 163 offsetof(SecAsn1OCSPSingleResponse, singleExtensions), 164 kSecAsn1SequenceOfCertExtensionTemplate }, 165 { 0 } 166}; 167 168/* 169 * support for ResponderID CHOICE 170 */ 171const SecAsn1Template kSecAsn1OCSPResponderIDAsNameTemplate[] = { 172 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 173 offsetof(SecAsn1OCSPResponderID, byName), 174 kSecAsn1AnyTemplate } 175}; 176 177const SecAsn1Template kSecAsn1OCSPResponderIDAsKeyTemplate[] = { 178 { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, 179 offsetof(SecAsn1OCSPResponderID, byKey), 180 kSecAsn1OctetStringTemplate } 181}; 182 183const SecAsn1Template kSecAsn1OCSPResponseDataTemplate[] = { 184 { SEC_ASN1_SEQUENCE, 185 0, NULL, sizeof(SecAsn1OCSPResponseData) }, 186 /* optional version, explicit tag 0, default 0 */ 187 { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 188 SEC_ASN1_CONTEXT_SPECIFIC | 0, 189 offsetof(SecAsn1OCSPResponseData, version), 190 kSecAsn1PointerToIntegerTemplate }, 191 { SEC_ASN1_ANY, 192 offsetof(SecAsn1OCSPResponseData, responderID), 193 kSecAsn1AnyTemplate }, 194 { SEC_ASN1_GENERALIZED_TIME, offsetof(SecAsn1OCSPResponseData, producedAt) }, 195 { SEC_ASN1_SEQUENCE_OF, 196 offsetof(SecAsn1OCSPResponseData, responses), 197 kSecAsn1OCSPSingleResponseTemplate }, 198 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 199 SEC_ASN1_EXPLICIT | 1, 200 offsetof(SecAsn1OCSPResponseData, responseExtensions), 201 kSecAsn1SequenceOfCertExtensionTemplate }, 202 { 0 } 203}; 204 205const SecAsn1Template kSecAsn1OCSPBasicResponseTemplate[] = { 206 { SEC_ASN1_SEQUENCE, 207 0, NULL, sizeof(SecAsn1OCSPBasicResponse) }, 208 { SEC_ASN1_ANY, offsetof(SecAsn1OCSPBasicResponse, tbsResponseData) }, 209 { SEC_ASN1_INLINE, 210 offsetof(SecAsn1OCSPBasicResponse, algId), 211 kSecAsn1AlgorithmIDTemplate }, 212 { SEC_ASN1_BIT_STRING, offsetof(SecAsn1OCSPBasicResponse, sig) }, 213 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 214 SEC_ASN1_EXPLICIT | 0, 215 offsetof(SecAsn1OCSPBasicResponse, certs), 216 kSecAsn1SequenceOfAnyTemplate }, 217 { 0 } 218}; 219 220const SecAsn1Template kSecAsn1OCSPResponseBytesTemplate[] = { 221 { SEC_ASN1_SEQUENCE, 222 0, NULL, sizeof(SecAsn1OCSPResponseBytes) }, 223 { SEC_ASN1_OBJECT_ID, offsetof(SecAsn1OCSPResponseBytes, responseType) }, 224 { SEC_ASN1_OCTET_STRING, offsetof(SecAsn1OCSPResponseBytes, response) }, 225 { 0 } 226}; 227 228const SecAsn1Template kSecAsn1OCSPPtrToResponseBytesTemplate[] = { 229 { SEC_ASN1_POINTER, 0, kSecAsn1OCSPResponseBytesTemplate } 230}; 231 232const SecAsn1Template kSecAsn1OCSPResponseTemplate[] = { 233 { SEC_ASN1_SEQUENCE, 234 0, NULL, sizeof(SecAsn1OCSPResponse) }, 235 { SEC_ASN1_ENUMERATED, offsetof(SecAsn1OCSPResponse, responseStatus) }, 236 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 237 SEC_ASN1_EXPLICIT | 0, 238 offsetof(SecAsn1OCSPResponse, responseBytes), 239 kSecAsn1OCSPPtrToResponseBytesTemplate }, 240 { 0 } 241}; 242 243// MARK: ---- OCSPD RPC ---- 244 245const SecAsn1Template kSecAsn1OCSPDRequestTemplate[] = { 246 { SEC_ASN1_SEQUENCE, 247 0, NULL, sizeof(SecAsn1OCSPDRequest) }, 248 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 249 SEC_ASN1_EXPLICIT | 0, 250 offsetof(SecAsn1OCSPDRequest, cacheWriteDisable), 251 kSecAsn1PointerToBooleanTemplate }, 252 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 253 SEC_ASN1_EXPLICIT | 1, 254 offsetof(SecAsn1OCSPDRequest, cacheReadDisable), 255 kSecAsn1PointerToBooleanTemplate }, 256 { SEC_ASN1_OCTET_STRING, offsetof(SecAsn1OCSPDRequest, certID) }, 257 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 258 SEC_ASN1_EXPLICIT | 2, 259 offsetof(SecAsn1OCSPDRequest, ocspReq), 260 kSecAsn1PointerToOctetStringTemplate }, 261 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 262 SEC_ASN1_EXPLICIT | 3, 263 offsetof(SecAsn1OCSPDRequest, localRespURI), 264 kSecAsn1PointerToIA5StringTemplate }, 265 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 266 SEC_ASN1_EXPLICIT | 4, 267 offsetof(SecAsn1OCSPDRequest, urls), 268 kSecAsn1SequenceOfIA5StringTemplate }, 269 { 0 } 270}; 271 272const SecAsn1Template kSecAsn1OCSPDRequestsTemplate[] = { 273 { SEC_ASN1_SEQUENCE, 274 0, NULL, sizeof(SecAsn1OCSPDRequests) }, 275 { SEC_ASN1_INTEGER, offsetof(SecAsn1OCSPDRequests, version) }, 276 { SEC_ASN1_SEQUENCE_OF, 277 offsetof(SecAsn1OCSPDRequests, requests), 278 kSecAsn1OCSPDRequestTemplate }, 279 { 0 } 280}; 281 282const SecAsn1Template kSecAsn1OCSPDReplyTemplate[] = { 283 { SEC_ASN1_SEQUENCE, 284 0, NULL, sizeof(SecAsn1OCSPDReply) }, 285 { SEC_ASN1_ANY, offsetof(SecAsn1OCSPDReply, certID) }, 286 { SEC_ASN1_ANY, offsetof(SecAsn1OCSPDReply, ocspResp) }, 287 { 0 } 288}; 289 290const SecAsn1Template kSecAsn1OCSPDRepliesTemplate[] = { 291 { SEC_ASN1_SEQUENCE, 292 0, NULL, sizeof(SecAsn1OCSPReplies) }, 293 { SEC_ASN1_INTEGER, offsetof(SecAsn1OCSPReplies, version) }, 294 { SEC_ASN1_SEQUENCE_OF, 295 offsetof(SecAsn1OCSPReplies, replies), 296 kSecAsn1OCSPDReplyTemplate }, 297 { 0 } 298}; 299