/ OSX / libsecurity_ocspd / common / ocspResponse.h
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