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 * ocspExtensions.h - OCSP extensions support 26 */ 27 28#ifndef _OCSP_EXTENSIONS_H_ 29#define _OCSP_EXTENSIONS_H_ 30 31#include <Security/SecAsn1Coder.h> 32#include <Security/x509defs.h> 33#include <Security/X509Templates.h> 34#include <security_utilities/utilities.h> 35 36/* 37 * We deal with a well bounded set of extensions, so we can enumerate them 38 * here for convenience. 39 */ 40typedef enum { 41 OET_Unknown, // no recognized 42 OET_Nonce, 43 OET_CrlReference, 44 OET_AcceptResponse, 45 OET_ArchiveCutoff, 46 OET_ServiceLocator 47} OCSPExtensionTag; 48 49class OCSPExtension 50{ 51 NOCOPY(OCSPExtension); 52 /* note NO public constructor implemented by this class */ 53public: 54 /* the public means to create an OCSPExtension subclass during decode */ 55 static OCSPExtension *createFromNSS( 56 SecAsn1CoderRef coder, 57 const NSS_CertExtension &nssExt); 58 59 virtual ~OCSPExtension(); 60 61 /* public accessors; suclass probably has others */ 62 bool critical() { return mCritical; } 63 bool unrecognizedCritical() { return mUnrecognizedCritical; } 64 CSSM_OID &extnId() { return mNssExt->extnId; } 65 OCSPExtensionTag tag() { return mTag; } 66 67 /* 68 * When encoding, this is ready to go - i.e., we're ready to be encoded - 69 * once subclass has called setDerValue(). That happens during subclass's 70 * constructor. 71 */ 72 NSS_CertExtension *nssExt() { return mNssExt; } 73 74protected: 75 /* 76 * Subclass must implement a version like this (without the tag argument), 77 * called from createFromNSS() during decode. 78 * 79 * This class's implementation just stashes away mNssExt, mCritical, and mCoder. 80 * This class's implementation is also used to construct the "I don't understand 81 * this extension" case (tag = OET_Unknown). 82 */ 83 OCSPExtension( 84 SecAsn1CoderRef coder, 85 const NSS_CertExtension &nssExt, 86 OCSPExtensionTag tag); 87 88 /* 89 * Constructor during encode, called from subclass-specific constructor�(which 90 * always has all of the subclass-specific arguments). 91 */ 92 OCSPExtension( 93 SecAsn1CoderRef coder, // passed to subclass constructor 94 const CSSM_OID &extnId, // subclass knows this 95 OCSPExtensionTag tag, // subclass knows this 96 bool critical); // passed to subclass constructor 97 98 /* 99 * Called by subclass after it DER encodes its NSS_CertExtension.value. The 100 * data is always in our coder's address space (so we don't copy it here). 101 */ 102 void setDerValue( 103 const CSSM_DATA &derValue) { mNssExt->value = (CSSM_DATA)derValue; } 104 105private: 106 /* 107 * This NSS_CertExtension is always in mCoder's address space. 108 * -- On decode, createFromNSS()'s caller provides a reference to it 109 * after high-level decode of a SecAsn1OCSPSignedRequest or a 110 * SecAsn1OCSPResponseData. 111 * -- On encode, *we* (this class) allocate with our mCoder. 112 */ 113 NSS_CertExtension *mNssExt; 114 SecAsn1CoderRef mCoder; 115 bool mCritical; // convenience - it's also in mNssExt 116 OCSPExtensionTag mTag; 117 118 /* set true when mCritical for extension we don't understand */ 119 bool mUnrecognizedCritical; 120}; 121 122class OCSPNonce : public OCSPExtension 123{ 124 NOCOPY(OCSPNonce); 125public: 126 /* construct during encode, called directly by app */ 127 OCSPNonce( 128 SecAsn1CoderRef coder, 129 bool critical, 130 const CSSM_DATA &nonce); 131 132 virtual ~OCSPNonce(); 133 134 CSSM_DATA &nonce() { return mNonce; } 135 136protected: 137 friend class OCSPExtension; 138 /* construct during decode, called only by OCSPExtension::createFromNSS() */ 139 OCSPNonce( 140 SecAsn1CoderRef coder, 141 const NSS_CertExtension &nssExt); 142 143private: 144 CSSM_DATA mNonce; 145}; 146 147 148/* 149 * A simple class representing an array of extensions, used during decoding. 150 */ 151class OCSPExtensions 152{ 153 NOCOPY(OCSPExtensions); 154public: 155 /* 156 * Create from array of NSS_CertExtensions, which is the form available 157 * immediately after decoding. We'll throw if we find any decoding error, 158 * or if we find a critical extension this module does not understand. 159 */ 160 OCSPExtensions( 161 NSS_CertExtension **nssExts); 162 ~OCSPExtensions(); 163 164 /* 165 * Find a decoded extension associated with specified extnId. Returns 166 * NULL if not found. 167 * Caller will typically cast (dynamic_cast would be appropriate) to 168 * a specific extension type. 169 */ 170 OCSPExtension *findExtension( 171 const CSSM_OID &oid); 172 173private: 174 SecAsn1CoderRef mCoder; 175 unsigned mNumExtensions; 176 OCSPExtension **mExtensions; 177}; 178 179#endif /* _OCSP_EXTENSIONS_H_ */ 180