ocspResponse.h
1 /* 2 * Copyright (c) 2004,2011,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 24 /* 25 * ocspResponse.h - OCSP Response class 26 */ 27 28 #ifndef _OCSP_RESPONSE_H_ 29 #define _OCSP_RESPONSE_H_ 30 31 #include <security_ocspd/ocspExtensions.h> 32 #include <Security/ocspTemplates.h> 33 #include <Security/certextensions.h> 34 #include <Security/SecAsn1Coder.h> 35 #include <CoreFoundation/CoreFoundation.h> 36 37 /* used to indicate "I don't know the CRLReason" */ 38 #define CrlReason_NONE ((CE_CrlReason)-1) 39 40 /* 41 * CertIDs can be represented differently by two peers even though they refer to 42 * the same cert. Client can use SHA1 hash and server can use MD5, for example. 43 * So all of our code which creates a CertID based on known, existing subject and 44 * issuer certs uses one of these "smart" certIDs which can encode itself and also 45 * compare against any form of existing SecAsn1OCSPCertID. 46 */ 47 class OCSPClientCertID 48 { 49 NOCOPY(OCSPClientCertID); 50 public: 51 /* 52 * Basic constructor given issuer's public key and name, and subject's 53 * serial number. 54 */ 55 OCSPClientCertID( 56 const CSSM_DATA &issuerName, 57 const CSSM_DATA &issuerPubKey, 58 const CSSM_DATA &subjectSerial); 59 60 ~OCSPClientCertID(); 61 62 /* 63 * DER encode. 64 */ 65 const CSSM_DATA *encode(); 66 67 /* 68 * Does this object refer to the same cert as specified SecAsn1OCSPCertID? 69 * This is the main purpose of this class's existence; this function works 70 * even if specified SecAsn1OCSPCertID uses a different hash algorithm 71 * than we do, since we keep copies of our basic components. 72 * 73 * Returns true if compare successful. 74 */ 75 bool compareToExist( 76 const SecAsn1OCSPCertID &exist); 77 78 /* 79 * Convenience function, like compareToExist, with a raw encoded CertID. 80 */ 81 bool compareToExist( 82 const CSSM_DATA &exist); 83 84 private: 85 CSSM_DATA mIssuerName; 86 CSSM_DATA mIssuerPubKey; 87 CSSM_DATA mSubjectSerial; 88 CSSM_DATA mEncoded; 89 }; 90 91 /* 92 * Object representing one SecAsn1OCSPSingleResponse, i.e., the portion of 93 * an OCSP response associated with a single CertID. These are created and 94 * vended solely by an OCSPResponse object. The client which gets them from 95 * an OCSPResponse (via singleResponse()) must delete the object when finished 96 * with it. 97 */ 98 class OCSPSingleResponse 99 { 100 NOCOPY(OCSPSingleResponse); 101 public: 102 /* only OCSPResponse creates these */ 103 ~OCSPSingleResponse(); 104 friend class OCSPResponse; 105 protected: 106 107 OCSPSingleResponse( 108 SecAsn1OCSPSingleResponse *resp); 109 public: 110 SecAsn1OCSPCertStatusTag certStatus() { return mCertStatus; } 111 CFAbsoluteTime thisUpdate() { return mThisUpdate; } 112 CFAbsoluteTime nextUpdate() { return mNextUpdate; } 113 CFAbsoluteTime revokedTime() { return mRevokedTime; } 114 CE_CrlReason crlReason() { return mCrlReason; } 115 116 /* Extension accessors - all are optional */ 117 118 /* CRL Reference */ 119 const CSSM_DATA *crlUrl(); 120 const CSSM_DATA *crlNum(); 121 CFAbsoluteTime crlTime(); /* may be NULL_TIME */ 122 123 /* archive cutoff */ 124 CFAbsoluteTime archiveCutoff(); 125 126 /* service locator not implemented yet */ 127 private: 128 SecAsn1CoderRef mCoder; 129 SecAsn1OCSPCertStatusTag mCertStatus; 130 CFAbsoluteTime mThisUpdate; 131 CFAbsoluteTime mNextUpdate; /* may be NULL_TIME */ 132 CFAbsoluteTime mRevokedTime; /* != NULL_TIME for CS_Revoked */ 133 CE_CrlReason mCrlReason; 134 OCSPExtensions *mExtensions; 135 }; 136 137 /* 138 * OCSPResponse maintains its own temporal validity status based on the values of 139 * all of the enclosed SingleResponses' thisUpdate and (optional) nextUpdate 140 * fields, in addition to a default time-to-live (TTL) value passed to 141 * OCSPResponse's constructor. 142 * 143 * First, all of the thisUpdate fields are checked during OCSPResponse's constructor. 144 * if any of these are later than the current time, the entire response is considered 145 * invalid and the constructor throws a CssmError(CSSMERR_APPLETP_OCSP_BAD_RESPONSE). 146 * Subsequent to construction, all thisUpdate fields are ignored. 147 * 148 * The NextUpdate times are handled as follows. 149 * 150 * 1. An OCSPResponse's latestNextUpdate is defined as the latest of all of the 151 * nextUpdate fields in its SingleResponses. This is evaluated during construction. 152 * 153 * 2. An OCSPResponse's latestNextUpdate is NULL_TIME if none of its SingleResponses 154 * contain any nextUpdate (this field is in fact optional). 155 * 156 * 3. The caller of OCSPResponse's constructor passes in a default time-to-live 157 * (TTL) in seconds; call this defaultTTL. Call the time at which the 158 * constructor is called, PLUS defaultTTL, "defaultExpire". 159 * 160 * -- If the OCSPResponse's latestNextUpdate is NULL_TIME then expireTime() returns 161 * defaultExpire. 162 * 163 * -- Otherwise, expireTime() returns the lesser of (latestNextUpdate, 164 * defaultExpire). 165 * 166 * Note that this mechanism is used by both the TP's in-core cache and ocspd's 167 * on-disk cache; the two have different default TTLs values but the mechanism 168 * for calcuating expireTime() is identical. 169 */ 170 class OCSPResponse 171 { 172 NOCOPY(OCSPResponse) 173 public: 174 /* only constructor, from DER encoded data */ 175 OCSPResponse( 176 const CSSM_DATA &resp, 177 CFTimeInterval defaultTTL); // default time-to-live in seconds 178 179 ~OCSPResponse(); 180 181 /* 182 * Info obtained during decode (which is done immediately during constructor) 183 */ 184 SecAsn1OCSPResponseStatus responseStatus(); 185 const CSSM_DATA *nonce(); /* NULL means not present */ 186 CFAbsoluteTime producedAt(); /* should always work */ 187 CSSM_RETURN sigStatus(); 188 uint32 numSignerCerts(); 189 const CSSM_DATA *signerCert(uint32 dex); 190 191 /* 192 * Obtain a OCSPSingleResponse for a given CertID. 193 */ 194 OCSPSingleResponse *singleResponseFor(OCSPClientCertID &certID); 195 OCSPSingleResponse *singleResponseFor(const CSSM_DATA &matchCertID); 196 197 CFAbsoluteTime expireTime() { return mExpireTime; } 198 199 /* 200 * Access to decoded data. 201 */ 202 const SecAsn1OCSPResponseData &responseData() { return mResponseData; } 203 const SecAsn1OCSPBasicResponse &basicResponse() { return mBasicResponse; } 204 const SecAsn1OCSPResponderID &responderID() { return mResponderId; } 205 SecAsn1OCSPResponderIDTag responderIDTag() { return mResponderIdTag; } 206 207 const CSSM_DATA *encResponderName(); 208 209 private: 210 bool calculateValidity(CFTimeInterval defaultTTL); 211 212 SecAsn1CoderRef mCoder; 213 CFAbsoluteTime mLatestNextUpdate; 214 CFAbsoluteTime mExpireTime; 215 CSSM_DATA mEncResponderName; // encoded ResponderId.byName, 216 // if responder is in that format, 217 // lazily evaluated 218 /* 219 * Fields we decode - all in mCoder's memory space 220 */ 221 SecAsn1OCSPResponse mTopResp; 222 SecAsn1OCSPBasicResponse mBasicResponse; 223 SecAsn1OCSPResponseData mResponseData; 224 SecAsn1OCSPResponderID mResponderId; // we have to decode 225 SecAsn1OCSPResponderIDTag mResponderIdTag; // IDs previous field 226 OCSPExtensions *mExtensions; 227 }; 228 #endif /* _OCSP_RESPONSE_H_ */ 229