2 * Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * ocspExtensions.cpp - OCSP Extension support.
28 #include "ocspExtensions.h"
29 #include "ocspdDebug.h"
30 #include "ocspdUtils.h"
31 #include <Security/oidscrl.h>
32 #include <Security/cssmapple.h>
34 #include "ocspdDebug.h"
35 #include <security_cdsa_utilities/cssmerrors.h>
37 #pragma mark ----- base class : OCSCExtension -----
40 * Public means to vend a subclass of this object while decoding.
42 OCSPExtension
*OCSPExtension::createFromNSS(
43 SecAsn1CoderRef coder
,
44 const NSS_CertExtension
&nssExt
)
46 const CSSM_OID
*extnId
= &nssExt
.extnId
;
47 if(ocspdCompareCssmData(extnId
, &CSSMOID_PKIX_OCSP_NONCE
)) {
48 return new OCSPNonce(coder
, nssExt
);
52 return new OCSPExtension(coder
, nssExt
, OET_Unknown
);
57 * Called in two circumstances:
59 * -- from subclass-specific constructor during decode
60 * -- from createFromNSS (during decode) when we don't recognize the extension ID
62 OCSPExtension::OCSPExtension(
63 SecAsn1CoderRef coder
,
64 const NSS_CertExtension
&nssExt
,
66 : mNssExt(const_cast<NSS_CertExtension
*>(&nssExt
)),
69 mUnrecognizedCritical(false)
71 if((nssExt
.critical
.Data
!= NULL
) && (*nssExt
.critical
.Data
!= 0)) {
77 if(mCritical
&& (tag
== OET_Unknown
)) {
78 mUnrecognizedCritical
= true;
83 * Constructor during encode, called from subclass-specific constructorÊ(which
84 * always has all of the subclass-specific arguments).
86 OCSPExtension::OCSPExtension(
87 SecAsn1CoderRef coder
, // passed to subclass constructor
88 const CSSM_OID
&extnId
, // subclass knows this
89 OCSPExtensionTag tag
, // subclass knows this
90 bool critical
) // passed to subclass constructor
91 : mNssExt(NULL
), // we'll cook this up
95 mUnrecognizedCritical(false) // this is a tautology
97 mNssExt
= (NSS_CertExtension
*)SecAsn1Malloc(coder
, sizeof(NSS_CertExtension
));
98 memset(mNssExt
, 0, sizeof(NSS_CertExtension
));
99 SecAsn1AllocCopyItem(coder
, &extnId
, &mNssExt
->extnId
);
100 /* alloc one byte for critical flag */
101 SecAsn1AllocItem(coder
, &mNssExt
->critical
, 1);
102 mNssExt
->critical
.Data
[0] = critical
? 0xff : 0;
105 OCSPExtension::~OCSPExtension()
107 /* nothing for now, need a virtual function for dynamic casts */
110 #pragma mark ---- Nonce -----
113 * Public constructor on encode
115 OCSPNonce::OCSPNonce(
116 SecAsn1CoderRef coder
,
118 const CSSM_DATA
&nonce
)
119 : OCSPExtension(coder
, CSSMOID_PKIX_OCSP_NONCE
, OET_Nonce
, critical
)
122 * They don't get much simpler than this: the nonce is the literal value
123 * of NSS_CertExtension.value.
125 SecAsn1AllocCopyItem(coder
, &nonce
, &mNonce
);
129 /* construct during decode, called only by OCSPExtension::createFromNSS() */
130 OCSPNonce::OCSPNonce(
131 SecAsn1CoderRef coder
,
132 const NSS_CertExtension
&nssExt
)
133 : OCSPExtension(coder
, nssExt
, OET_Nonce
)
135 /* only subclass-specific stuff is the nonce, no further processing needed */
136 SecAsn1AllocCopyItem(coder
, &nssExt
.value
, &mNonce
);
139 OCSPNonce::~OCSPNonce()
141 /* nothing for now, need a virtual function for dynamic casts */
144 #pragma mark ----- Extensions array -----
146 OCSPExtensions::OCSPExtensions(
147 NSS_CertExtension
**nssExts
)
148 : mCoder(NULL
), mNumExtensions(0), mExtensions(NULL
)
150 SecAsn1CoderCreate(&mCoder
);
151 mNumExtensions
= ocspdArraySize((const void **)nssExts
);
152 if(mNumExtensions
== 0) {
156 mExtensions
= (OCSPExtension
**)SecAsn1Malloc(mCoder
,
157 (mNumExtensions
* sizeof(OCSPExtension
*)));
158 for(unsigned dex
=0; dex
<mNumExtensions
; dex
++) {
161 OCSPExtension::createFromNSS(mCoder
, *nssExts
[dex
]);
162 if(mExtensions
[dex
] == NULL
) {
163 ocspdErrorLog("OCSPExtensions: extension failure (NULL) dex %u\n", dex
);
164 CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE
);
166 if(mExtensions
[dex
]->unrecognizedCritical()) {
167 ocspdErrorLog("OCSPExtensions: unrecognized critical extension\n");
168 CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE
);
172 ocspdErrorLog("OCSPExtensions: extension failure dex %u\n", dex
);
173 CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE
);
178 OCSPExtensions::~OCSPExtensions()
180 for(unsigned dex
=0; dex
<mNumExtensions
; dex
++) {
181 delete mExtensions
[dex
];
184 SecAsn1CoderRelease(mCoder
);
188 /* find parsed extension in mExtensions with specified OID */
189 OCSPExtension
*OCSPExtensions::findExtension(
192 for(unsigned dex
=0; dex
<mNumExtensions
; dex
++) {
193 const CSSM_OID
&extnId
= mExtensions
[dex
]->extnId();
194 if(ocspdCompareCssmData(&oid
, &extnId
)) {
195 return mExtensions
[dex
];