1/* 2 * Copyright (c) 2009-2010,2012-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/*! 26 @header SecOCSPCache 27 The functions provided in SecOCSPCache.h provide an interface to 28 an OCSP caching module. 29*/ 30 31#ifndef _SECURITY_SECOCSPCACHE_H_ 32#define _SECURITY_SECOCSPCACHE_H_ 33 34#include <securityd/SecOCSPRequest.h> 35#include <securityd/SecOCSPResponse.h> 36#include <CoreFoundation/CFURL.h> 37 38__BEGIN_DECLS 39 40 41void SecOCSPCacheAddResponse(SecOCSPResponseRef response, 42 CFURLRef localResponderURI); 43 44SecOCSPResponseRef SecOCSPCacheCopyMatching(SecOCSPRequestRef request, 45 CFURLRef localResponderURI /* may be NULL */); 46 47/* This should be called on a normal non emergency exit. */ 48void SecOCSPCacheGC(void); 49 50/* Call this periodically or perhaps when we are exiting due to low memory. */ 51void SecOCSPCacheFlush(void); 52 53__END_DECLS 54 55#endif /* _SECURITY_SECOCSPCACHE_H_ */ 56 57#if 0 58/* 59Experation policy assumptions: 60- We never check revocation status of anchors, whether they be system anchors, 61 passed in anchors or anchors hardcoded in a policy. 62- Revocation information is cached for positive reponses for a limited time. 63- Revocation information can be cached for negative reponses for an unlimited time. 64- Revocation information need never be kept around after the certificate has expired (unless we still check after the cert has expired like we were talking about for EERI). 65- Revocation information records that are used and still valid should be kept longer. 66- We can set an upper limit in number of records (or certificates) in the cache. 67- We can set an upper limit on total space consumed by the cache. 68Questions: 69- Remember bad server responses too? some ocsp responders required signed requests which we don't support, so we could consider caching the 6 (Not Authorized or something) response. 70 71Data needed per type of revocation record to implement this policy. 72 73Caching policy: 74- Deleting cache should not be user option. 75- Cache should surrvive backups. 76- Negative caching as long as possible. 77 78CRL certificate stati: 79unspecified, keyCompromise, cACompromise, 80affiliationChanged, superseded, cessationOfOperation, 81certificateHold, removeFromCRL, privilegeWithdrawn, 82aACompromise, the special value UNREVOKED, or the special 83value UNDETERMINED. This variable is initialized to the 84special value UNREVOKED. 85 86CRL Timestamp values: 87- thisUpdate 88- nextUpdate (optional but not really 5280 says CAs must provide it even though ASN.1 is optional) 89(no producedAt in CRLs, that's what thisUpdate is by definition it seems). 90 91 92OCSP Timestamp values: 93 thisUpdate = May 1, 2005 01:00:00 GMT 94 nextUpdate = May 3, 2005 01:00:00 GMT (optional abscence means update available any time) 95 productedAt = May 1, 2005 01:00:00 GMT 96 97PER CERTIFICATE RETURN in INFO 98 99Revocation object used: OCSP Response, mapping from 100reasons-> (CRL + most current delta CRL), Error Object (with status code). 101 -- good 102 -- revoked 103 -- unknown 104 105other exceptions (unsigned responses): 106 -- malformedRequest 107 -- internalError 108 -- tryLater 109 -- sigRequired 110 -- unauthorized (5019 The response "unauthorized" is returned in cases where the client 111 is not authorized to make this query to this server or the server 112 is not capable of responding authoritatively. (Expired certs might get this answer too)) 113 114 115CRL signer chain rules: 1161) Must use same anchor as cert itself. 117This implies that we can only cache the validity of a leaf or intermediate certificate for CRL checking based on the mapping: 118(certificate, path anchor, use_deltas) -> Revocation_status (unspecified, keyCompromise, cACompromise, 119affiliationChanged, superseded, cessationOfOperation,certificateHold, removeFromCRL, privilegeWithdrawn,aACompromise, UNREVOKED, UNDETERMINED). 120 121OCSP signer chain rules: 122(Wikipedia confirmed in rfc): The key that signs a response need not be the same key that signed the certificate. The certificate's issuer may delegate another authority to be the OCSP responder. In this case, the responder's certificate (the one that is used to sign the response) must be issued by the issuer of the certificate in question, and must include a certain extension that marks it as an OCSP signing authority (more precisely, an extended key usage extension with the OID {iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) keyPurpose(3) ocspSigning(9)}) 123 124rfc text of the wikipedia: Therefore, a certificate's issuer MUST either sign the OCSP 125 responses itself or it MUST explicitly designate this authority to 126 another entity. OCSP signing delegation SHALL be designated by the 127 inclusion of id-kp-OCSPSigning in an extendedKeyUsage certificate 128 extension included in the OCSP response signer's certificate. This 129 certificate MUST be issued directly by the CA that issued the 130 certificate in question. 131 132rfc: If ocsp signing cert has id-pkix-ocsp-nocheck extension we don't check it's revocation status. 133 134(certificate, direct issuer certificate) -> Revocation_status good (UNREVOKED) revoked revocationTime, CRLReason (unspecified, keyCompromise, cACompromise,affiliationChanged, superseded, cessationOfOperation,certificateHold, removeFromCRL, privilegeWithdrawn,aACompromise) unknown (UNDETERMINED). 135 136ocsp CertID ::= SEQUENCE { 137 hashAlgorithm AlgorithmIdentifier, 138 issuerNameHash OCTET STRING, -- Hash of Issuer's DN 139 issuerKeyHash OCTET STRING, -- Hash of Issuers public key 140 serialNumber CertificateSerialNumber } 141) 142 143In order to accomadate the responder using a different hashAlgorithm than we used in the request we need to recalc these from the cert itself. 144 145If all we have is a list of ocspresponses without knowing where they came from, we have to calculate the hashes of our issuerName and issuerKey for each hashAlgorithm we have cached ocsp responses for (optionally after limiting our candidates to those with matching serialNumbers first). 146 147SELECT from ocsp_cache hashAlgorithm WHERE serialNumber = <SERIAL> 148 149for hix = 0 hix < hashAlgorithms.count 150 ALG(hix).id = hashAlgorithms(hix) 151 152SELECT from ocsp_cache response WHERE serialNumber = <SERIAL> hashAlgorithm = ALG(hix).id issuerNameHash = ALG(hix).hash(issuer) issuerKeyHash = ALG(hix).hash(key) 153 154 155 156 157 158 159Notes for Matt: 160- ttl in amfi cache (to force recheck when ocsp response is invalid)? 161- Periodic check before launch to remove in band waiting for ocsp response? 162 163Notes on Nonces in ocsp request and responses. Only ask for nonce if we think server supports it (no way to know today). Fall back on time based validity checking if reponse has no nonce, even if we asked for one 164 165Note on CRL checking and experation and retries of OCSP checking. 166Clients MAY attempt to retrieve the CRL if no 167 OCSPResponse is received from the responder after a locally 168 configured timeout and number of retries.. 169 170 171 172CRL/OCSP cache design idea: 173 174revocation status table: 175 176rowid certhash issuer-rowid lastUsed thisUpdate producedAt nextUpdate revocationTime revocationStatus 177 178cacheAddOCSP(path, index_of_cert_resp_is_for, ocspResp) 179cacheAddCRLStatus(path, index_of_cert_in_path, nextUpdate, revocationTime, revocationStatus) 180(revocationTime, revocationStatus) = cacheLookupStatus(path, ix) 181 182Return a list of parent certificate hashes for the current leaf. If a result is returned, we have a candiate path leading up to an anchor, for which we already trust the signature in the chain and revocation information has been checked. 183 184CFArrayRef cacheSuggestParentsHashesFor(cert) 185 186for crl based status root must match root of path. For ocsp status issuer must match issuer of leaf in path 187 188presence in the cache means cert chain leading to an anchor is valid, and signed properly and trusted by the ocsp or crl policy, revocation status for cert is valid until the time indicated by nextUpdate. Cert chain itself may or may not be valid but that's checked by the policy engine. 189 190If a chain isn't properly signed or fails to satisfy the crl policy, it should not be in the cache. 191 192ocsp cache 193 194rowid ocspResponse (responder) lastUsed nextUpdate 195 196hashAlgorithm->(issuerNameHash,issuerKeyHash,serialNumber)->response 197 198 199crl cache () 200 201crlDistributionPoint (reasons) crl thisUpdate nextUpdate isDelta 202 203 204crlEntry cache table 205(certHash anchorHash) crlIssuer revocationStatus revocationTime expires lastUsed 206crlTable 207(crlIssuer anchorHash distributionPointURL?) crl sigVerified expires 208ocspEntry cache table 209(certHash parentHash ocspReponderID) hashAlg revocationStatus revocationTime expires lastUsed 210ocspTable 211((hashAlg, pubKeyHash, issuerHash, serialNum) anchorHash) ocspResponse sigVerified expires 212 213or 214cert cache table 215(certHash parentHash anchorHash) crlEntryID ocspID 216 217crlEntry cache table 218(crlEntryID anchorHash) crlIssuer revocationStatus revocationTime 219 220crlIssuerTable 221(crlIssuer anchorHash) crl sigVerified 222 223ocsp table 224(ocspID) ocspResponse 225 226 227but so does caching the raw response as a link to a blob table containing crls 228and ocsp-responses 229But also cache the revocationStatus for a (cert,parent) or (cert,anchor) via 230a link to a cached ocspResponse or revocationStatus and revocationTime entry from crl 231*/ 232 233#endif 234