Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / libpkix / pkix / checker / pkix_ocspchecker.c
blob694db4ba8532bc029c1c953b1d4700cb10670043
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Sun Microsystems
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_ocspchecker.c
40 * OcspChecker Object Functions
44 #include "pkix_ocspchecker.h"
47 /* --Private-Functions-------------------------------------------- */
50 * FUNCTION: pkix_OcspChecker_Destroy
51 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
53 static PKIX_Error *
54 pkix_OcspChecker_Destroy(
55 PKIX_PL_Object *object,
56 void *plContext)
58 PKIX_OcspChecker *checker = NULL;
60 PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Destroy");
61 PKIX_NULLCHECK_ONE(object);
63 /* Check that this object is a ocsp checker */
64 PKIX_CHECK(pkix_CheckType
65 (object, PKIX_OCSPCHECKER_TYPE, plContext),
66 PKIX_OBJECTNOTOCSPCHECKER);
68 checker = (PKIX_OcspChecker *)object;
70 PKIX_DECREF(checker->response);
71 PKIX_DECREF(checker->validityTime);
72 PKIX_DECREF(checker->cert);
74 /* These are not yet ref-counted objects */
75 /* PKIX_DECREF(checker->passwordInfo); */
76 /* PKIX_DECREF(checker->responder); */
77 /* PKIX_DECREF(checker->nbioContext); */
79 cleanup:
81 PKIX_RETURN(OCSPCHECKER);
85 * FUNCTION: pkix_OcspChecker_RegisterSelf
86 * DESCRIPTION:
87 * Registers PKIX_OCSPCHECKER_TYPE and its related functions with
88 * systemClasses[]
89 * THREAD SAFETY:
90 * Not Thread Safe - for performance and complexity reasons
92 * Since this function is only called by PKIX_PL_Initialize, which should
93 * only be called once, it is acceptable that this function is not
94 * thread-safe.
96 PKIX_Error *
97 pkix_OcspChecker_RegisterSelf(void *plContext)
99 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
100 pkix_ClassTable_Entry entry;
102 PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_RegisterSelf");
104 entry.description = "OcspChecker";
105 entry.destructor = pkix_OcspChecker_Destroy;
106 entry.equalsFunction = NULL;
107 entry.hashcodeFunction = NULL;
108 entry.toStringFunction = NULL;
109 entry.comparator = NULL;
110 entry.duplicateFunction = NULL;
112 systemClasses[PKIX_OCSPCHECKER_TYPE] = entry;
114 PKIX_RETURN(OCSPCHECKER);
117 /* --Public-Functions--------------------------------------------- */
120 * FUNCTION: pkix_OcspChecker_Check (see comments in pkix_checker.h)
124 * The OCSPChecker is created in an idle state, and remains in this state until
125 * either (a) the default Responder has been set and enabled, and a Check
126 * request is received with no responder specified, or (b) a Check request is
127 * received with a specified responder. A request message is constructed and
128 * given to the HttpClient. If non-blocking I/O is used the client may return
129 * with WOULDBLOCK, in which case the OCSPChecker returns the WOULDBLOCK
130 * condition to its caller in turn. On a subsequent call the I/O is resumed.
131 * When a response is received it is decoded and the results provided to the
132 * caller.
135 static PKIX_Error *
136 pkix_OcspChecker_Check(
137 PKIX_PL_Object *checkerObject,
138 PKIX_PL_Cert *cert,
139 PKIX_ProcessingParams *procParams,
140 void **pNBIOContext,
141 PKIX_UInt32 *pResultCode,
142 void *plContext)
144 SECErrorCodes resultCode = 0;
145 PKIX_Boolean uriFound = PKIX_FALSE;
146 PKIX_Boolean passed = PKIX_FALSE;
147 PKIX_OcspChecker *checker = NULL;
148 PKIX_PL_OcspRequest *request = NULL;
149 void *nbioContext = NULL;
151 PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Check");
152 PKIX_NULLCHECK_FOUR(checkerObject, cert, pNBIOContext, pResultCode);
154 PKIX_CHECK(pkix_CheckType
155 (checkerObject, PKIX_OCSPCHECKER_TYPE, plContext),
156 PKIX_OBJECTNOTOCSPCHECKER);
158 checker = (PKIX_OcspChecker *)checkerObject;
160 nbioContext = *pNBIOContext;
161 *pNBIOContext = 0;
163 /* assert(checker->nbioContext == nbioContext) */
165 if (nbioContext == 0) {
166 /* We are initiating a check, not resuming previous I/O. */
168 PKIX_INCREF(cert);
169 checker->cert = cert;
171 /* create request */
172 PKIX_CHECK(pkix_pl_OcspRequest_Create
173 (cert,
174 NULL, /* PKIX_PL_Date *validity */
175 PKIX_FALSE, /* PKIX_Boolean addServiceLocator */
176 NULL, /* PKIX_PL_Cert *signerCert */
177 &uriFound,
178 &request,
179 plContext),
180 PKIX_OCSPREQUESTCREATEFAILED);
182 /* No uri to check is considered passing! */
183 if (uriFound == PKIX_FALSE) {
184 passed = PKIX_TRUE;
185 resultCode = 0;
186 goto cleanup;
191 /* Do we already have a response object? */
192 if ((checker->response) == NULL) {
193 /* send request and create a response object */
194 PKIX_CHECK(pkix_pl_OcspResponse_Create
195 (request,
196 checker->responder,
197 checker->verifyFcn,
198 &nbioContext,
199 &(checker->response),
200 plContext),
201 PKIX_OCSPRESPONSECREATEFAILED);
203 if (nbioContext != 0) {
204 *pNBIOContext = nbioContext;
205 goto cleanup;
208 PKIX_CHECK(pkix_pl_OcspResponse_Decode
209 ((checker->response), &passed, &resultCode, plContext),
210 PKIX_OCSPRESPONSEDECODEFAILED);
212 if (passed == PKIX_FALSE) {
213 goto cleanup;
216 PKIX_CHECK(pkix_pl_OcspResponse_GetStatus
217 ((checker->response), &passed, &resultCode, plContext),
218 PKIX_OCSPRESPONSEGETSTATUSRETURNEDANERROR);
220 if (passed == PKIX_FALSE) {
221 goto cleanup;
225 PKIX_CHECK(pkix_pl_OcspResponse_VerifySignature
226 ((checker->response),
227 cert,
228 procParams,
229 &passed,
230 &resultCode,
231 &nbioContext,
232 plContext),
233 PKIX_OCSPRESPONSEVERIFYSIGNATUREFAILED);
235 if (nbioContext != 0) {
236 *pNBIOContext = nbioContext;
237 goto cleanup;
240 if (passed == PKIX_FALSE) {
241 goto cleanup;
244 PKIX_CHECK(pkix_pl_OcspResponse_GetStatusForCert
245 ((checker->response), &passed, &resultCode, plContext),
246 PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
248 cleanup:
249 *pResultCode = (PKIX_UInt32)resultCode;
251 PKIX_DECREF(request);
252 PKIX_DECREF(checker->response);
254 PKIX_RETURN(OCSPCHECKER);
259 * FUNCTION: pkix_OcspChecker_Create
261 PKIX_Error *
262 pkix_OcspChecker_Create(
263 PKIX_PL_Date *validityTime,
264 void *passwordInfo,
265 void *responder,
266 PKIX_OcspChecker **pChecker,
267 void *plContext)
269 PKIX_OcspChecker *checkerObject = NULL;
270 PKIX_RevocationChecker *revChecker = NULL;
272 PKIX_ENTER(OCSPCHECKER, "pkix_OcspChecker_Create");
273 PKIX_NULLCHECK_ONE(pChecker);
275 PKIX_CHECK(PKIX_PL_Object_Alloc
276 (PKIX_OCSPCHECKER_TYPE,
277 sizeof (PKIX_OcspChecker),
278 (PKIX_PL_Object **)&checkerObject,
279 plContext),
280 PKIX_COULDNOTCREATECERTCHAINCHECKEROBJECT);
282 /* initialize fields */
283 checkerObject->response = NULL;
284 PKIX_INCREF(validityTime);
285 checkerObject->validityTime = validityTime;
286 checkerObject->clientIsDefault = PKIX_FALSE;
287 checkerObject->verifyFcn = NULL;
288 checkerObject->cert = NULL;
290 /* These void*'s will need INCREFs if they become PKIX_PL_Objects */
291 checkerObject->passwordInfo = passwordInfo;
292 checkerObject->responder = responder;
293 checkerObject->nbioContext = NULL;
295 *pChecker = checkerObject;
297 cleanup:
299 PKIX_RETURN(OCSPCHECKER);
304 * FUNCTION: PKIX_OcspChecker_SetPasswordInfo
305 * (see comments in pkix_checker.h)
307 PKIX_Error *
308 PKIX_OcspChecker_SetPasswordInfo(
309 PKIX_OcspChecker *checker,
310 void *passwordInfo,
311 void *plContext)
313 PKIX_ENTER(OCSPCHECKER, "PKIX_OcspChecker_SetPasswordInfo");
314 PKIX_NULLCHECK_ONE(checker);
316 checker->passwordInfo = passwordInfo;
318 PKIX_RETURN(OCSPCHECKER);
322 * FUNCTION: PKIX_OcspChecker_SetOCSPResponder
323 * (see comments in pkix_checker.h)
325 PKIX_Error *
326 PKIX_OcspChecker_SetOCSPResponder(
327 PKIX_OcspChecker *checker,
328 void *ocspResponder,
329 void *plContext)
331 PKIX_ENTER(OCSPCHECKER, "PKIX_OcspChecker_SetOCSPResponder");
332 PKIX_NULLCHECK_ONE(checker);
334 checker->responder = ocspResponder;
336 PKIX_RETURN(OCSPCHECKER);
340 * FUNCTION: PKIX_OcspChecker_SetVerifyFcn
341 * (see comments in pkix_checker.h)
343 PKIX_Error *
344 PKIX_OcspChecker_SetVerifyFcn(
345 PKIX_OcspChecker *checker,
346 PKIX_PL_OcspResponse_VerifyCallback verifyFcn,
347 void *plContext)
349 PKIX_ENTER(OCSPCHECKER, "PKIX_OcspChecker_SetVerifyFcn");
350 PKIX_NULLCHECK_ONE(checker);
352 checker->verifyFcn = verifyFcn;
354 PKIX_RETURN(OCSPCHECKER);
357 PKIX_Error *
358 PKIX_OcspChecker_Initialize(
359 PKIX_PL_Date *validityTime,
360 void *passwordInfo,
361 void *responder,
362 PKIX_RevocationChecker **pChecker,
363 void *plContext)
365 PKIX_OcspChecker *oChecker = NULL;
367 PKIX_ENTER(OCSPCHECKER, "PKIX_OcspChecker_Initialize");
368 PKIX_NULLCHECK_ONE(pChecker);
370 PKIX_CHECK(pkix_OcspChecker_Create
371 (validityTime, passwordInfo, responder, &oChecker, plContext),
372 PKIX_OCSPCHECKERCREATEFAILED);
374 PKIX_CHECK(PKIX_RevocationChecker_Create
375 (pkix_OcspChecker_Check,
376 (PKIX_PL_Object *)oChecker,
377 pChecker,
378 plContext),
379 PKIX_REVOCATIONCHECKERCREATEFAILED);
381 cleanup:
383 PKIX_DECREF(oChecker);
385 PKIX_RETURN(OCSPCHECKER);