comparison nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_pl_ocsprequest.c
6 *
7 */
8
9 #include "pkix_pl_ocsprequest.h"
10
11 /* --Private-OcspRequest-Functions------------------------------------- */
12
13 /*
14 * FUNCTION: pkix_pl_OcspRequest_Destroy
15 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
16 */
17 static PKIX_Error *
18 pkix_pl_OcspRequest_Destroy(
19 PKIX_PL_Object *object,
20 void *plContext)
21 {
22 PKIX_PL_OcspRequest *ocspReq = NULL;
23
24 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Destroy");
25 PKIX_NULLCHECK_ONE(object);
26
27 PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPREQUEST_TYPE, plContext),
28 PKIX_OBJECTNOTOCSPREQUEST);
29
30 ocspReq = (PKIX_PL_OcspRequest *)object;
31
32 if (ocspReq->decoded != NULL) {
33 CERT_DestroyOCSPRequest(ocspReq->decoded);
34 }
35
36 if (ocspReq->encoded != NULL) {
37 SECITEM_FreeItem(ocspReq->encoded, PR_TRUE);
38 }
39
40 if (ocspReq->location != NULL) {
41 PORT_Free(ocspReq->location);
42 }
43
44 PKIX_DECREF(ocspReq->cert);
45 PKIX_DECREF(ocspReq->validity);
46 PKIX_DECREF(ocspReq->signerCert);
47
48 cleanup:
49
50 PKIX_RETURN(OCSPREQUEST);
51 }
52
53 /*
54 * FUNCTION: pkix_pl_OcspRequest_Hashcode
55 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
56 */
57 static PKIX_Error *
58 pkix_pl_OcspRequest_Hashcode(
59 PKIX_PL_Object *object,
60 PKIX_UInt32 *pHashcode,
61 void *plContext)
62 {
63 PKIX_UInt32 certHash = 0;
64 PKIX_UInt32 dateHash = 0;
65 PKIX_UInt32 extensionHash = 0;
66 PKIX_UInt32 signerHash = 0;
67 PKIX_PL_OcspRequest *ocspRq = NULL;
68
69 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Hashcode");
70 PKIX_NULLCHECK_TWO(object, pHashcode);
71
72 PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPREQUEST_TYPE, plContext),
73 PKIX_OBJECTNOTOCSPREQUEST);
74
75 ocspRq = (PKIX_PL_OcspRequest *)object;
76
77 *pHashcode = 0;
78
79 PKIX_HASHCODE(ocspRq->cert, &certHash, plContext,
80 PKIX_CERTHASHCODEFAILED);
81
82 PKIX_HASHCODE(ocspRq->validity, &dateHash, plContext,
83 PKIX_DATEHASHCODEFAILED);
84
85 if (ocspRq->addServiceLocator == PKIX_TRUE) {
86 extensionHash = 0xff;
87 }
88
89 PKIX_HASHCODE(ocspRq->signerCert, &signerHash, plContext,
90 PKIX_CERTHASHCODEFAILED);
91
92 *pHashcode = (((((extensionHash << 8) || certHash) << 8) ||
93 dateHash) << 8) || signerHash;
94
95 cleanup:
96
97 PKIX_RETURN(OCSPREQUEST);
98
99 }
100
101 /*
102 * FUNCTION: pkix_pl_OcspRequest_Equals
103 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
104 */
105 static PKIX_Error *
106 pkix_pl_OcspRequest_Equals(
107 PKIX_PL_Object *firstObj,
108 PKIX_PL_Object *secondObj,
109 PKIX_Boolean *pResult,
110 void *plContext)
111 {
112 PKIX_Boolean match = PKIX_FALSE;
113 PKIX_UInt32 secondType = 0;
114 PKIX_PL_OcspRequest *firstReq = NULL;
115 PKIX_PL_OcspRequest *secondReq = NULL;
116
117 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Equals");
118 PKIX_NULLCHECK_THREE(firstObj, secondObj, pResult);
119
120 /* test that firstObj is a OcspRequest */
121 PKIX_CHECK(pkix_CheckType(firstObj, PKIX_OCSPREQUEST_TYPE, plContext),
122 PKIX_FIRSTOBJARGUMENTNOTOCSPREQUEST);
123
124 /*
125 * Since we know firstObj is a OcspRequest, if both references are
126 * identical, they must be equal
127 */
128 if (firstObj == secondObj){
129 match = PKIX_TRUE;
130 goto cleanup;
131 }
132
133 /*
134 * If secondObj isn't a OcspRequest, we don't throw an error.
135 * We simply return a Boolean result of FALSE
136 */
137 PKIX_CHECK(PKIX_PL_Object_GetType
138 (secondObj, &secondType, plContext),
139 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
140 if (secondType != PKIX_OCSPREQUEST_TYPE) {
141 goto cleanup;
142 }
143
144 firstReq = (PKIX_PL_OcspRequest *)firstObj;
145 secondReq = (PKIX_PL_OcspRequest *)secondObj;
146
147 if (firstReq->addServiceLocator != secondReq->addServiceLocator) {
148 goto cleanup;
149 }
150
151 PKIX_EQUALS(firstReq->cert, secondReq->cert, &match, plContext,
152 PKIX_CERTEQUALSFAILED);
153
154 if (match == PKIX_FALSE) {
155 goto cleanup;
156 }
157
158 PKIX_EQUALS(firstReq->validity, secondReq->validity, &match, plContext,
159 PKIX_DATEEQUALSFAILED);
160
161 if (match == PKIX_FALSE) {
162 goto cleanup;
163 }
164
165 PKIX_EQUALS
166 (firstReq->signerCert, secondReq->signerCert, &match, plContext,
167 PKIX_CERTEQUALSFAILED);
168
169 cleanup:
170
171 *pResult = match;
172
173 PKIX_RETURN(OCSPREQUEST);
174 }
175
176 /*
177 * FUNCTION: pkix_pl_OcspRequest_RegisterSelf
178 * DESCRIPTION:
179 * Registers PKIX_OCSPREQUEST_TYPE and its related functions with
180 * systemClasses[]
181 * PARAMETERS:
182 * "plContext"
183 * Platform-specific context pointer.
184 * THREAD SAFETY:
185 * Not Thread Safe - for performance and complexity reasons
186 *
187 * Since this function is only called by PKIX_PL_Initialize, which should
188 * only be called once, it is acceptable that this function is not
189 * thread-safe.
190 */
191 PKIX_Error *
192 pkix_pl_OcspRequest_RegisterSelf(void *plContext)
193 {
194 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
195 pkix_ClassTable_Entry entry;
196
197 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_RegisterSelf");
198
199 entry.description = "OcspRequest";
200 entry.objCounter = 0;
201 entry.typeObjectSize = sizeof(PKIX_PL_OcspRequest);
202 entry.destructor = pkix_pl_OcspRequest_Destroy;
203 entry.equalsFunction = pkix_pl_OcspRequest_Equals;
204 entry.hashcodeFunction = pkix_pl_OcspRequest_Hashcode;
205 entry.toStringFunction = NULL;
206 entry.comparator = NULL;
207 entry.duplicateFunction = pkix_duplicateImmutable;
208
209 systemClasses[PKIX_OCSPREQUEST_TYPE] = entry;
210
211 PKIX_RETURN(OCSPREQUEST);
212 }
213
214 /* --Public-Functions------------------------------------------------------- */
215
216 /*
217 * FUNCTION: pkix_pl_OcspRequest_Create
218 * DESCRIPTION:
219 *
220 * This function creates an OcspRequest to be used in validating the Cert
221 * pointed to by "cert" and storing the result at "pRequest". If a URI
222 * is found for an OCSP responder, PKIX_TRUE is stored at "pURIFound". If no
223 * URI is found, PKIX_FALSE is stored.
224 *
225 * If a Date is provided in "validity" it may be used in the search for the
226 * issuer of "cert" but has no effect on the request itself. If
227 * "addServiceLocator" is TRUE, the AddServiceLocator extension will be
228 * included in the Request. If "signerCert" is provided it will be used to sign
229 * the Request. (Note: this signed request feature is not currently supported.)
230 *
231 * PARAMETERS:
232 * "cert"
233 * Address of the Cert for which an OcspRequest is to be created. Must be
234 * non-NULL.
235 * "validity"
236 * Address of the Date for which the Cert's validity is to be determined.
237 * May be NULL.
238 * "signerCert"
239 * Address of the Cert to be used, if present, in signing the request.
240 * May be NULL.
241 * "pRequest"
242 * Address at which the result is stored. Must be non-NULL.
243 * "plContext"
244 * Platform-specific context pointer.
245 * THREAD SAFETY:
246 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
247 * RETURNS:
248 * Returns NULL if the function succeeds.
249 * Returns an OcspRequest Error if the function fails in a non-fatal way.
250 * Returns a Fatal Error if the function fails in an unrecoverable way.
251 */
252 PKIX_Error *
253 pkix_pl_OcspRequest_Create(
254 PKIX_PL_Cert *cert,
255 PKIX_PL_OcspCertID *cid,
256 PKIX_PL_Date *validity,
257 PKIX_PL_Cert *signerCert,
258 PKIX_UInt32 methodFlags,
259 PKIX_Boolean *pURIFound,
260 PKIX_PL_OcspRequest **pRequest,
261 void *plContext)
262 {
263 PKIX_PL_OcspRequest *ocspRequest = NULL;
264
265 CERTCertDBHandle *handle = NULL;
266 SECStatus rv = SECFailure;
267 SECItem *encoding = NULL;
268 CERTOCSPRequest *certRequest = NULL;
269 PRTime time = 0;
270 PRBool addServiceLocatorExtension = PR_FALSE;
271 CERTCertificate *nssCert = NULL;
272 CERTCertificate *nssSignerCert = NULL;
273 char *location = NULL;
274 PRErrorCode locError = 0;
275 PKIX_Boolean canUseDefaultSource = PKIX_FALSE;
276
277 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_Create");
278 PKIX_NULLCHECK_TWO(cert, pRequest);
279
280 /* create a PKIX_PL_OcspRequest object */
281 PKIX_CHECK(PKIX_PL_Object_Alloc
282 (PKIX_OCSPREQUEST_TYPE,
283 sizeof (PKIX_PL_OcspRequest),
284 (PKIX_PL_Object **)&ocspRequest,
285 plContext),
286 PKIX_COULDNOTCREATEOBJECT);
287
288 PKIX_INCREF(cert);
289 ocspRequest->cert = cert;
290
291 PKIX_INCREF(validity);
292 ocspRequest->validity = validity;
293
294 PKIX_INCREF(signerCert);
295 ocspRequest->signerCert = signerCert;
296
297 ocspRequest->decoded = NULL;
298 ocspRequest->encoded = NULL;
299
300 ocspRequest->location = NULL;
301
302 nssCert = cert->nssCert;
303
304 /*
305 * Does this Cert have an Authority Information Access extension with
306 * the URI of an OCSP responder?
307 */
308 handle = CERT_GetDefaultCertDB();
309
310 if (!(methodFlags & PKIX_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE)) {
311 canUseDefaultSource = PKIX_TRUE;
312 }
313 location = ocsp_GetResponderLocation(handle, nssCert,
314 canUseDefaultSource,
315 &addServiceLocatorExtension);
316 if (location == NULL) {
317 locError = PORT_GetError();
318 if (locError == SEC_ERROR_EXTENSION_NOT_FOUND ||
319 locError == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) {
320 PORT_SetError(0);
321 *pURIFound = PKIX_FALSE;
322 goto cleanup;
323 }
324 PKIX_ERROR(PKIX_ERRORFINDINGORPROCESSINGURI);
325 }
326
327 ocspRequest->location = location;
328 *pURIFound = PKIX_TRUE;
329
330 if (signerCert != NULL) {
331 nssSignerCert = signerCert->nssCert;
332 }
333
334 if (validity != NULL) {
335 PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
336 PKIX_DATEGETPRTIMEFAILED);
337 } else {
338 time = PR_Now();
339 }
340
341 certRequest = cert_CreateSingleCertOCSPRequest(
342 cid->certID, cert->nssCert, time,
343 addServiceLocatorExtension, nssSignerCert);
344
345 ocspRequest->decoded = certRequest;
346
347 if (certRequest == NULL) {
348 PKIX_ERROR(PKIX_UNABLETOCREATECERTOCSPREQUEST);
349 }
350
351 rv = CERT_AddOCSPAcceptableResponses(
352 certRequest, SEC_OID_PKIX_OCSP_BASIC_RESPONSE);
353
354 if (rv == SECFailure) {
355 PKIX_ERROR(PKIX_UNABLETOADDACCEPTABLERESPONSESTOREQUEST);
356 }
357
358 encoding = CERT_EncodeOCSPRequest(NULL, certRequest, NULL);
359
360 ocspRequest->encoded = encoding;
361
362 *pRequest = ocspRequest;
363 ocspRequest = NULL;
364
365 cleanup:
366 PKIX_DECREF(ocspRequest);
367
368 PKIX_RETURN(OCSPREQUEST);
369 }
370
371 /*
372 * FUNCTION: pkix_pl_OcspRequest_GetEncoded
373 * DESCRIPTION:
374 *
375 * This function obtains the encoded message from the OcspRequest pointed to
376 * by "request", storing the result at "pRequest".
377 *
378 * PARAMETERS
379 * "request"
380 * The address of the OcspRequest whose encoded message is to be
381 * retrieved. Must be non-NULL.
382 * "pRequest"
383 * The address at which is stored the address of the encoded message. Must
384 * be non-NULL.
385 * "plContext"
386 * Platform-specific context pointer.
387 * THREAD SAFETY:
388 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
389 * RETURNS:
390 * Returns NULL if the function succeeds.
391 * Returns a Fatal Error if the function fails in an unrecoverable way.
392 */
393 PKIX_Error *
394 pkix_pl_OcspRequest_GetEncoded(
395 PKIX_PL_OcspRequest *request,
396 SECItem **pRequest,
397 void *plContext)
398 {
399 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_GetEncoded");
400 PKIX_NULLCHECK_TWO(request, pRequest);
401
402 *pRequest = request->encoded;
403
404 PKIX_RETURN(OCSPREQUEST);
405 }
406
407 /*
408 * FUNCTION: pkix_pl_OcspRequest_GetLocation
409 * DESCRIPTION:
410 *
411 * This function obtains the location from the OcspRequest pointed to
412 * by "request", storing the result at "pLocation".
413 *
414 * PARAMETERS
415 * "request"
416 * The address of the OcspRequest whose encoded message is to be
417 * retrieved. Must be non-NULL.
418 * "pLocation"
419 * The address at which is stored the address of the location. Must
420 * be non-NULL.
421 * "plContext"
422 * Platform-specific context pointer.
423 * THREAD SAFETY:
424 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
425 * RETURNS:
426 * Returns NULL if the function succeeds.
427 * Returns a Fatal Error if the function fails in an unrecoverable way.
428 */
429 PKIX_Error *
430 pkix_pl_OcspRequest_GetLocation(
431 PKIX_PL_OcspRequest *request,
432 char **pLocation,
433 void *plContext)
434 {
435 PKIX_ENTER(OCSPREQUEST, "pkix_pl_OcspRequest_GetLocation");
436 PKIX_NULLCHECK_TWO(request, pLocation);
437
438 *pLocation = request->location;
439
440 PKIX_RETURN(OCSPREQUEST);
441 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)