Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Side by Side Diff: nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_httpcertstore.c
6 *
7 * HTTPCertStore Function Definitions
8 *
9 */
10
11 /* We can't decode the length of a message without at least this many bytes */
12
13 #include "pkix_pl_httpcertstore.h"
14 extern PKIX_PL_HashTable *httpSocketCache;
15 SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
16 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
17 SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
18 SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
19
20 SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate)
21 SEC_ASN1_CHOOSER_DECLARE(SECOID_AlgorithmIDTemplate)
22 /* SEC_ASN1_CHOOSER_DECLARE(SEC_SetOfAnyTemplate)
23 SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate)
24
25 const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = {
26 { SEC_ASN1_SEQUENCE,
27 0, NULL, sizeof(CERTIssuerAndSN) },
28 { SEC_ASN1_SAVE,
29 offsetof(CERTIssuerAndSN,derIssuer) },
30 { SEC_ASN1_INLINE,
31 offsetof(CERTIssuerAndSN,issuer),
32 CERT_NameTemplate },
33 { SEC_ASN1_INTEGER,
34 offsetof(CERTIssuerAndSN,serialNumber) },
35 { 0 }
36 };
37
38 const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
39 { SEC_ASN1_SEQUENCE,
40 0, NULL, sizeof(SECAlgorithmID) },
41 { SEC_ASN1_OBJECT_ID,
42 offsetof(SECAlgorithmID,algorithm) },
43 { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
44 offsetof(SECAlgorithmID,parameters) },
45 { 0 }
46 }; */
47
48 /* --Private-HttpCertStoreContext-Object Functions----------------------- */
49
50 /*
51 * FUNCTION: pkix_pl_HttpCertStoreContext_Destroy
52 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
53 */
54 static PKIX_Error *
55 pkix_pl_HttpCertStoreContext_Destroy(
56 PKIX_PL_Object *object,
57 void *plContext)
58 {
59 const SEC_HttpClientFcnV1 *hcv1 = NULL;
60 PKIX_PL_HttpCertStoreContext *context = NULL;
61
62 PKIX_ENTER
63 (HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStoreContext_Destroy");
64 PKIX_NULLCHECK_ONE(object);
65
66 PKIX_CHECK(pkix_CheckType
67 (object, PKIX_HTTPCERTSTORECONTEXT_TYPE, plContext),
68 PKIX_OBJECTNOTANHTTPCERTSTORECONTEXT);
69
70 context = (PKIX_PL_HttpCertStoreContext *)object;
71 hcv1 = (const SEC_HttpClientFcnV1 *)(context->client);
72 if (context->requestSession != NULL) {
73 (*hcv1->freeFcn)(context->requestSession);
74 context->requestSession = NULL;
75 }
76 if (context->serverSession != NULL) {
77 (*hcv1->freeSessionFcn)(context->serverSession);
78 context->serverSession = NULL;
79 }
80 if (context->path != NULL) {
81 PORT_Free(context->path);
82 context->path = NULL;
83 }
84
85 cleanup:
86
87 PKIX_RETURN(HTTPCERTSTORECONTEXT);
88 }
89
90 /*
91 * FUNCTION: pkix_pl_HttpCertStoreContext_RegisterSelf
92 *
93 * DESCRIPTION:
94 * Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
95 * functions with systemClasses[]
96 *
97 * THREAD SAFETY:
98 * Not Thread Safe - for performance and complexity reasons
99 *
100 * Since this function is only called by PKIX_PL_Initialize, which should
101 * only be called once, it is acceptable that this function is not
102 * thread-safe.
103 */
104 PKIX_Error *
105 pkix_pl_HttpCertStoreContext_RegisterSelf(void *plContext)
106 {
107 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
108 pkix_ClassTable_Entry *entry = &systemClasses[PKIX_HTTPCERTSTORECONTEXT_ TYPE];
109
110 PKIX_ENTER(HTTPCERTSTORECONTEXT,
111 "pkix_pl_HttpCertStoreContext_RegisterSelf");
112
113 entry->description = "HttpCertStoreContext";
114 entry->typeObjectSize = sizeof(PKIX_PL_HttpCertStoreContext);
115 entry->destructor = pkix_pl_HttpCertStoreContext_Destroy;
116
117 PKIX_RETURN(HTTPCERTSTORECONTEXT);
118 }
119
120
121 /* --Private-Http-CertStore-Database-Functions----------------------- */
122
123 typedef struct callbackContextStruct {
124 PKIX_List *pkixCertList;
125 PKIX_Error *error;
126 void *plContext;
127 } callbackContext;
128
129
130 /*
131 * FUNCTION: certCallback
132 * DESCRIPTION:
133 *
134 * This function processes the null-terminated array of SECItems produced by
135 * extracting the contents of a signedData message received in response to an
136 * HTTP cert query. Its address is supplied as a callback function to
137 * CERT_DecodeCertPackage; it is not expected to be called directly.
138 *
139 * Note that it does not conform to the libpkix API standard of returning
140 * a PKIX_Error*. It returns a SECStatus.
141 *
142 * PARAMETERS:
143 * "arg"
144 * The address of the callbackContext provided as a void* argument to
145 * CERT_DecodeCertPackage. Must be non-NULL.
146 * "secitemCerts"
147 * The address of the null-terminated array of SECItems. Must be non-NULL.
148 * "numcerts"
149 * The number of SECItems found in the signedData. Must be non-NULL.
150 * "plContext"
151 * Platform-specific context pointer.
152 * THREAD SAFETY:
153 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
154 * RETURNS:
155 * Returns SECSuccess if the function succeeds.
156 * Returns SECFailure if the function fails.
157 */
158 static SECStatus
159 certCallback(void *arg, SECItem **secitemCerts, int numcerts)
160 {
161 callbackContext *cbContext;
162 PKIX_List *pkixCertList = NULL;
163 PKIX_Error *error = NULL;
164 void *plContext = NULL;
165 int itemNum = 0;
166
167 if ((arg == NULL) || (secitemCerts == NULL)) {
168 return (SECFailure);
169 }
170
171 cbContext = (callbackContext *)arg;
172 plContext = cbContext->plContext;
173 pkixCertList = cbContext->pkixCertList;
174
175 for (; itemNum < numcerts; itemNum++ ) {
176 error = pkix_pl_Cert_CreateToList(secitemCerts[itemNum],
177 pkixCertList, plContext);
178 if (error != NULL) {
179 if (error->errClass == PKIX_FATAL_ERROR) {
180 cbContext->error = error;
181 return SECFailure;
182 }
183 /* reuse "error" since we could not destruct the old *
184 * value */
185 error = PKIX_PL_Object_DecRef((PKIX_PL_Object *)error,
186 plContext);
187 if (error) {
188 /* Treat decref failure as a fatal error.
189 * In this case will leak error, but can not do
190 * anything about it. */
191 error->errClass = PKIX_FATAL_ERROR;
192 cbContext->error = error;
193 return SECFailure;
194 }
195 }
196 }
197
198 return SECSuccess;
199 }
200
201
202 typedef SECStatus (*pkix_DecodeCertsFunc)(char *certbuf, int certlen,
203 CERTImportCertificateFunc f, void *arg );
204 #ifdef NSS_STATIC
205 extern SECStatus CERT_DecodeCertPackage(char* certbuf, int certlen,
206 CERTImportCertificateFunc f, void* arg);
207 #endif
208
209 struct pkix_DecodeFuncStr {
210 pkix_DecodeCertsFunc func; /* function pointer to the
211 * CERT_DecodeCertPackage function */
212 PRLibrary *smimeLib; /* Pointer to the smime shared lib*/
213 PRCallOnceType once;
214 };
215
216 static struct pkix_DecodeFuncStr pkix_decodeFunc;
217 static const PRCallOnceType pkix_pristine;
218
219 #define SMIME_LIB_NAME SHLIB_PREFIX"smime3."SHLIB_SUFFIX
220
221 /*
222 * load the smime library and look up the SEC_ReadPKCS7Certs function.
223 * we do this so we don't have a circular depenency on the smime library,
224 * and also so we don't have to load the smime library in applications that
225 * don't use it.
226 */
227 static PRStatus PR_CALLBACK pkix_getDecodeFunction(void)
228 {
229 #ifdef NSS_STATIC
230 pkix_decodeFunc.smimeLib = NULL;
231 pkix_decodeFunc.func = CERT_DecodeCertPackage;
232 return PR_SUCCESS;
233 #else
234 pkix_decodeFunc.smimeLib =
235 PR_LoadLibrary(SHLIB_PREFIX"smime3."SHLIB_SUFFIX);
236 if (pkix_decodeFunc.smimeLib == NULL) {
237 return PR_FAILURE;
238 }
239
240 pkix_decodeFunc.func = (pkix_DecodeCertsFunc) PR_FindFunctionSymbol(
241 pkix_decodeFunc.smimeLib, "CERT_DecodeCertPackage");
242 if (!pkix_decodeFunc.func) {
243 return PR_FAILURE;
244 }
245 return PR_SUCCESS;
246 #endif
247 }
248
249 /*
250 * clears our global state on shutdown.
251 */
252 void
253 pkix_pl_HttpCertStore_Shutdown(void *plContext)
254 {
255 if (pkix_decodeFunc.smimeLib) {
256 PR_UnloadLibrary(pkix_decodeFunc.smimeLib);
257 pkix_decodeFunc.smimeLib = NULL;
258 }
259 /* the function pointer just need to be cleared, not freed */
260 pkix_decodeFunc.func = NULL;
261 pkix_decodeFunc.once = pkix_pristine;
262 }
263
264 /*
265 * This function is based on CERT_DecodeCertPackage from lib/pkcs7/certread.c
266 * read an old style ascii or binary certificate chain
267 */
268 PKIX_Error *
269 pkix_pl_HttpCertStore_DecodeCertPackage
270 (const char *certbuf,
271 int certlen,
272 CERTImportCertificateFunc f,
273 void *arg,
274 void *plContext)
275 {
276
277 PRStatus status;
278 SECStatus rv;
279
280 PKIX_ENTER
281 (HTTPCERTSTORECONTEXT,
282 "pkix_pl_HttpCertStore_DecodeCertPackage");
283 PKIX_NULLCHECK_TWO(certbuf, f);
284
285 status = PR_CallOnce(&pkix_decodeFunc.once, pkix_getDecodeFunction);
286
287 if (status != PR_SUCCESS) {
288 PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
289 }
290
291 /* paranoia, shouldn't happen if status == PR_SUCCESS); */
292 if (!pkix_decodeFunc.func) {
293 PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
294 }
295
296 rv = (*pkix_decodeFunc.func)((char*)certbuf, certlen, f, arg);
297
298 if (rv != SECSuccess) {
299 PKIX_ERROR (PKIX_SECREADPKCS7CERTSFAILED);
300 }
301
302
303 cleanup:
304
305 PKIX_RETURN(HTTPCERTSTORECONTEXT);
306 }
307
308
309 /*
310 * FUNCTION: pkix_pl_HttpCertStore_ProcessCertResponse
311 * DESCRIPTION:
312 *
313 * This function verifies that the response code pointed to by "responseCode"
314 * and the content type pointed to by "responseContentType" are as expected,
315 * and then decodes the data pointed to by "responseData", of length
316 * "responseDataLen", into a List of Certs, possibly empty, which is returned
317 * at "pCertList".
318 *
319 * PARAMETERS:
320 * "responseCode"
321 * The value of the HTTP response code.
322 * "responseContentType"
323 * The address of the Content-type string. Must be non-NULL.
324 * "responseData"
325 * The address of the message data. Must be non-NULL.
326 * "responseDataLen"
327 * The length of the message data.
328 * "pCertList"
329 * The address of the List that is created. Must be non-NULL.
330 * "plContext"
331 * Platform-specific context pointer.
332 * THREAD SAFETY:
333 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
334 * RETURNS:
335 * Returns NULL if the function succeeds.
336 * Returns a HttpCertStore Error if the function fails in a non-fatal way.
337 * Returns a Fatal Error if the function fails in an unrecoverable way.
338 */
339 PKIX_Error *
340 pkix_pl_HttpCertStore_ProcessCertResponse(
341 PRUint16 responseCode,
342 const char *responseContentType,
343 const char *responseData,
344 PRUint32 responseDataLen,
345 PKIX_List **pCertList,
346 void *plContext)
347 {
348 callbackContext cbContext;
349
350 PKIX_ENTER(HTTPCERTSTORECONTEXT,
351 "pkix_pl_HttpCertStore_ProcessCertResponse");
352
353 cbContext.error = NULL;
354 cbContext.plContext = plContext;
355 cbContext.pkixCertList = NULL;
356
357 PKIX_NULLCHECK_ONE(pCertList);
358
359 if (responseCode != 200) {
360 PKIX_ERROR(PKIX_BADHTTPRESPONSE);
361 }
362
363 /* check that response type is application/pkcs7-mime */
364 if (responseContentType == NULL) {
365 PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
366 }
367
368 if (responseData == NULL) {
369 PKIX_ERROR(PKIX_NORESPONSEDATAINHTTPRESPONSE);
370 }
371
372 PKIX_CHECK(
373 PKIX_List_Create(&cbContext.pkixCertList, plContext),
374 PKIX_LISTCREATEFAILED);
375
376 PKIX_CHECK_ONLY_FATAL(
377 pkix_pl_HttpCertStore_DecodeCertPackage(responseData,
378 responseDataLen,
379 certCallback,
380 &cbContext,
381 plContext),
382 PKIX_HTTPCERTSTOREDECODECERTPACKAGEFAILED);
383 if (cbContext.error) {
384 /* Aborting on a fatal error(See certCallback fn) */
385 pkixErrorResult = cbContext.error;
386 goto cleanup;
387 }
388
389 *pCertList = cbContext.pkixCertList;
390 cbContext.pkixCertList = NULL;
391
392 cleanup:
393
394 PKIX_DECREF(cbContext.pkixCertList);
395
396 PKIX_RETURN(HTTPCERTSTORECONTEXT);
397 }
398
399 /*
400 * FUNCTION: pkix_pl_HttpCertStore_ProcessCrlResponse
401 * DESCRIPTION:
402 *
403 * This function verifies that the response code pointed to by "responseCode"
404 * and the content type pointed to by "responseContentType" are as expected,
405 * and then decodes the data pointed to by "responseData", of length
406 * "responseDataLen", into a List of Crls, possibly empty, which is returned
407 * at "pCrlList".
408 *
409 * PARAMETERS:
410 * "responseCode"
411 * The value of the HTTP response code.
412 * "responseContentType"
413 * The address of the Content-type string. Must be non-NULL.
414 * "responseData"
415 * The address of the message data. Must be non-NULL.
416 * "responseDataLen"
417 * The length of the message data.
418 * "pCrlList"
419 * The address of the List that is created. Must be non-NULL.
420 * "plContext"
421 * Platform-specific context pointer.
422 * THREAD SAFETY:
423 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
424 * RETURNS:
425 * Returns NULL if the function succeeds.
426 * Returns a HttpCertStore Error if the function fails in a non-fatal way.
427 * Returns a Fatal Error if the function fails in an unrecoverable way.
428 */
429 PKIX_Error *
430 pkix_pl_HttpCertStore_ProcessCrlResponse(
431 PRUint16 responseCode,
432 const char *responseContentType,
433 const char *responseData,
434 PRUint32 responseDataLen,
435 PKIX_List **pCrlList,
436 void *plContext)
437 {
438 SECItem encodedResponse;
439 PRInt16 compareVal = 0;
440 PKIX_List *crls = NULL;
441 SECItem *derCrlCopy = NULL;
442 CERTSignedCrl *nssCrl = NULL;
443 PKIX_PL_CRL *crl = NULL;
444
445 PKIX_ENTER(HTTPCERTSTORECONTEXT,
446 "pkix_pl_HttpCertStore_ProcessCrlResponse");
447 PKIX_NULLCHECK_ONE(pCrlList);
448
449 if (responseCode != 200) {
450 PKIX_ERROR(PKIX_BADHTTPRESPONSE);
451 }
452
453 /* check that response type is application/pkix-crl */
454 if (responseContentType == NULL) {
455 PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
456 }
457
458 compareVal = PORT_Strcasecmp(responseContentType,
459 "application/pkix-crl");
460 if (compareVal != 0) {
461 PKIX_ERROR(PKIX_CONTENTTYPENOTPKIXCRL);
462 }
463 encodedResponse.type = siBuffer;
464 encodedResponse.data = (void*)responseData;
465 encodedResponse.len = responseDataLen;
466
467 derCrlCopy = SECITEM_DupItem(&encodedResponse);
468 if (!derCrlCopy) {
469 PKIX_ERROR(PKIX_ALLOCERROR);
470 }
471 /* crl will be based on derCrlCopy, but will not own the der. */
472 nssCrl =
473 CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE,
474 CRL_DECODE_DONT_COPY_DER |
475 CRL_DECODE_SKIP_ENTRIES);
476 if (!nssCrl) {
477 PKIX_ERROR(PKIX_FAILEDTODECODECRL);
478 }
479 /* pkix crls own the der. */
480 PKIX_CHECK(
481 pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy, NULL,
482 &crl, plContext),
483 PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
484 /* Left control over memory pointed by derCrlCopy and
485 * nssCrl to pkix crl. */
486 derCrlCopy = NULL;
487 nssCrl = NULL;
488 PKIX_CHECK(PKIX_List_Create(&crls, plContext),
489 PKIX_LISTCREATEFAILED);
490 PKIX_CHECK(PKIX_List_AppendItem
491 (crls, (PKIX_PL_Object *) crl, plContext),
492 PKIX_LISTAPPENDITEMFAILED);
493 *pCrlList = crls;
494 crls = NULL;
495 cleanup:
496 if (derCrlCopy) {
497 SECITEM_FreeItem(derCrlCopy, PR_TRUE);
498 }
499 if (nssCrl) {
500 SEC_DestroyCrl(nssCrl);
501 }
502 PKIX_DECREF(crl);
503 PKIX_DECREF(crls);
504
505 PKIX_RETURN(HTTPCERTSTORECONTEXT);
506 }
507
508 /*
509 * FUNCTION: pkix_pl_HttpCertStore_CreateRequestSession
510 * DESCRIPTION:
511 *
512 * This function takes elements from the HttpCertStoreContext pointed to by
513 * "context" (path, client, and serverSession) and creates a RequestSession.
514 * See the HTTPClient API described in ocspt.h for further details.
515 *
516 * PARAMETERS:
517 * "context"
518 * The address of the HttpCertStoreContext. Must be non-NULL.
519 * "plContext"
520 * Platform-specific context pointer.
521 * THREAD SAFETY:
522 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
523 * RETURNS:
524 * Returns NULL if the function succeeds.
525 * Returns a HttpCertStore Error if the function fails in a non-fatal way.
526 * Returns a Fatal Error if the function fails in an unrecoverable way.
527 */
528 PKIX_Error *
529 pkix_pl_HttpCertStore_CreateRequestSession(
530 PKIX_PL_HttpCertStoreContext *context,
531 void *plContext)
532 {
533 const SEC_HttpClientFcnV1 *hcv1 = NULL;
534 SECStatus rv = SECFailure;
535
536 PKIX_ENTER
537 (HTTPCERTSTORECONTEXT,
538 "pkix_pl_HttpCertStore_CreateRequestSession");
539 PKIX_NULLCHECK_TWO(context, context->serverSession);
540
541 if (context->client->version != 1) {
542 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
543 }
544
545 hcv1 = &(context->client->fcnTable.ftable1);
546 if (context->requestSession != NULL) {
547 (*hcv1->freeFcn)(context->requestSession);
548 context->requestSession = 0;
549 }
550
551 rv = (*hcv1->createFcn)(context->serverSession, "http",
552 context->path, "GET",
553 PR_SecondsToInterval(
554 ((PKIX_PL_NssContext*)plContext)->timeoutSeconds),
555 &(context->requestSession));
556
557 if (rv != SECSuccess) {
558 PKIX_ERROR(PKIX_HTTPSERVERERROR);
559 }
560 cleanup:
561
562 PKIX_RETURN(HTTPCERTSTORECONTEXT);
563
564 }
565
566 /*
567 * FUNCTION: pkix_pl_HttpCertStore_GetCert
568 * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
569 */
570 PKIX_Error *
571 pkix_pl_HttpCertStore_GetCert(
572 PKIX_CertStore *store,
573 PKIX_CertSelector *selector,
574 PKIX_VerifyNode *verifyNode,
575 void **pNBIOContext,
576 PKIX_List **pCertList,
577 void *plContext)
578 {
579 const SEC_HttpClientFcnV1 *hcv1 = NULL;
580 PKIX_PL_HttpCertStoreContext *context = NULL;
581 void *nbioContext = NULL;
582 SECStatus rv = SECFailure;
583 PRUint16 responseCode = 0;
584 const char *responseContentType = NULL;
585 const char *responseData = NULL;
586 PRUint32 responseDataLen = 0;
587 PKIX_List *certList = NULL;
588
589 PKIX_ENTER(HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_GetCert");
590 PKIX_NULLCHECK_THREE(store, selector, pCertList);
591
592 nbioContext = *pNBIOContext;
593 *pNBIOContext = NULL;
594
595 PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
596 (store, (PKIX_PL_Object **)&context, plContext),
597 PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
598
599 if (context->client->version != 1) {
600 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
601 }
602
603 hcv1 = &(context->client->fcnTable.ftable1);
604
605 PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
606 (context, plContext),
607 PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
608
609 responseDataLen =
610 ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
611
612 rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
613 (PRPollDesc **)&nbioContext,
614 &responseCode,
615 (const char **)&responseContentType,
616 NULL, /* &responseHeaders */
617 (const char **)&responseData,
618 &responseDataLen);
619 if (rv != SECSuccess) {
620 PKIX_ERROR(PKIX_HTTPSERVERERROR);
621 }
622
623 if (nbioContext != 0) {
624 *pNBIOContext = nbioContext;
625 goto cleanup;
626 }
627
628 PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
629 (responseCode,
630 responseContentType,
631 responseData,
632 responseDataLen,
633 &certList,
634 plContext),
635 PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
636
637 *pCertList = certList;
638
639 cleanup:
640 PKIX_DECREF(context);
641
642 PKIX_RETURN(CERTSTORE);
643 }
644
645 /*
646 * FUNCTION: pkix_pl_HttpCertStore_GetCertContinue
647 * (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
648 */
649 PKIX_Error *
650 pkix_pl_HttpCertStore_GetCertContinue(
651 PKIX_CertStore *store,
652 PKIX_CertSelector *selector,
653 PKIX_VerifyNode *verifyNode,
654 void **pNBIOContext,
655 PKIX_List **pCertList,
656 void *plContext)
657 {
658 const SEC_HttpClientFcnV1 *hcv1 = NULL;
659 PKIX_PL_HttpCertStoreContext *context = NULL;
660 void *nbioContext = NULL;
661 SECStatus rv = SECFailure;
662 PRUint16 responseCode = 0;
663 const char *responseContentType = NULL;
664 const char *responseData = NULL;
665 PRUint32 responseDataLen = 0;
666 PKIX_List *certList = NULL;
667
668 PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCertContinue");
669 PKIX_NULLCHECK_THREE(store, selector, pCertList);
670
671 nbioContext = *pNBIOContext;
672 *pNBIOContext = NULL;
673
674 PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
675 (store, (PKIX_PL_Object **)&context, plContext),
676 PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
677
678 if (context->client->version != 1) {
679 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
680 }
681
682 hcv1 = &(context->client->fcnTable.ftable1);
683 PKIX_NULLCHECK_ONE(context->requestSession);
684
685 responseDataLen =
686 ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
687
688 rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
689 (PRPollDesc **)&nbioContext,
690 &responseCode,
691 (const char **)&responseContentType,
692 NULL, /* &responseHeaders */
693 (const char **)&responseData,
694 &responseDataLen);
695
696 if (rv != SECSuccess) {
697 PKIX_ERROR(PKIX_HTTPSERVERERROR);
698 }
699
700 if (nbioContext != 0) {
701 *pNBIOContext = nbioContext;
702 goto cleanup;
703 }
704
705 PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
706 (responseCode,
707 responseContentType,
708 responseData,
709 responseDataLen,
710 &certList,
711 plContext),
712 PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
713
714 *pCertList = certList;
715
716 cleanup:
717 PKIX_DECREF(context);
718
719 PKIX_RETURN(CERTSTORE);
720 }
721
722 /*
723 * FUNCTION: pkix_pl_HttpCertStore_GetCRL
724 * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
725 */
726 PKIX_Error *
727 pkix_pl_HttpCertStore_GetCRL(
728 PKIX_CertStore *store,
729 PKIX_CRLSelector *selector,
730 void **pNBIOContext,
731 PKIX_List **pCrlList,
732 void *plContext)
733 {
734
735 const SEC_HttpClientFcnV1 *hcv1 = NULL;
736 PKIX_PL_HttpCertStoreContext *context = NULL;
737 void *nbioContext = NULL;
738 SECStatus rv = SECFailure;
739 PRUint16 responseCode = 0;
740 const char *responseContentType = NULL;
741 const char *responseData = NULL;
742 PRUint32 responseDataLen = 0;
743 PKIX_List *crlList = NULL;
744
745 PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRL");
746 PKIX_NULLCHECK_THREE(store, selector, pCrlList);
747
748 nbioContext = *pNBIOContext;
749 *pNBIOContext = NULL;
750
751 PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
752 (store, (PKIX_PL_Object **)&context, plContext),
753 PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
754
755 if (context->client->version != 1) {
756 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
757 }
758
759 hcv1 = &(context->client->fcnTable.ftable1);
760 PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
761 (context, plContext),
762 PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
763
764 responseDataLen =
765 ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
766
767 rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
768 (PRPollDesc **)&nbioContext,
769 &responseCode,
770 (const char **)&responseContentType,
771 NULL, /* &responseHeaders */
772 (const char **)&responseData,
773 &responseDataLen);
774
775 if (rv != SECSuccess) {
776 PKIX_ERROR(PKIX_HTTPSERVERERROR);
777 }
778
779 if (nbioContext != 0) {
780 *pNBIOContext = nbioContext;
781 goto cleanup;
782 }
783
784 PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
785 (responseCode,
786 responseContentType,
787 responseData,
788 responseDataLen,
789 &crlList,
790 plContext),
791 PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED);
792
793 *pCrlList = crlList;
794
795 cleanup:
796 PKIX_DECREF(context);
797
798 PKIX_RETURN(CERTSTORE);
799 }
800
801 /*
802 * FUNCTION: pkix_pl_HttpCertStore_GetCRLContinue
803 * (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
804 */
805 PKIX_Error *
806 pkix_pl_HttpCertStore_GetCRLContinue(
807 PKIX_CertStore *store,
808 PKIX_CRLSelector *selector,
809 void **pNBIOContext,
810 PKIX_List **pCrlList,
811 void *plContext)
812 {
813 const SEC_HttpClientFcnV1 *hcv1 = NULL;
814 PKIX_PL_HttpCertStoreContext *context = NULL;
815 void *nbioContext = NULL;
816 SECStatus rv = SECFailure;
817 PRUint16 responseCode = 0;
818 const char *responseContentType = NULL;
819 const char *responseData = NULL;
820 PRUint32 responseDataLen = 0;
821 PKIX_List *crlList = NULL;
822
823 PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRLContinue");
824 PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);
825
826 nbioContext = *pNBIOContext;
827 *pNBIOContext = NULL;
828
829 PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
830 (store, (PKIX_PL_Object **)&context, plContext),
831 PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
832
833 if (context->client->version != 1) {
834 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
835 }
836 hcv1 = &(context->client->fcnTable.ftable1);
837
838 PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
839 (context, plContext),
840 PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
841
842 responseDataLen =
843 ((PKIX_PL_NssContext*)plContext)->maxResponseLength;
844
845 rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
846 (PRPollDesc **)&nbioContext,
847 &responseCode,
848 (const char **)&responseContentType,
849 NULL, /* &responseHeaders */
850 (const char **)&responseData,
851 &responseDataLen);
852
853 if (rv != SECSuccess) {
854 PKIX_ERROR(PKIX_HTTPSERVERERROR);
855 }
856
857 if (nbioContext != 0) {
858 *pNBIOContext = nbioContext;
859 goto cleanup;
860 }
861
862 PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
863 (responseCode,
864 responseContentType,
865 responseData,
866 responseDataLen,
867 &crlList,
868 plContext),
869 PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED);
870
871 *pCrlList = crlList;
872
873 cleanup:
874 PKIX_DECREF(context);
875
876 PKIX_RETURN(CERTSTORE);
877 }
878
879 /* --Public-HttpCertStore-Functions----------------------------------- */
880
881 /*
882 * FUNCTION: pkix_pl_HttpCertStore_CreateWithAsciiName
883 * DESCRIPTION:
884 *
885 * This function uses the HttpClient pointed to by "client" and the string
886 * (hostname:portnum/path, with portnum optional) pointed to by "locationAscii"
887 * to create an HttpCertStore connected to the desired location, storing the
888 * created CertStore at "pCertStore".
889 *
890 * PARAMETERS:
891 * "client"
892 * The address of the HttpClient. Must be non-NULL.
893 * "locationAscii"
894 * The address of the character string indicating the hostname, port, and
895 * path to be queried for Certs or Crls. Must be non-NULL.
896 * "pCertStore"
897 * The address in which the object is stored. Must be non-NULL.
898 * "plContext"
899 * Platform-specific context pointer.
900 * THREAD SAFETY:
901 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
902 * RETURNS:
903 * Returns NULL if the function succeeds.
904 * Returns a HttpCertStore Error if the function fails in a non-fatal way.
905 * Returns a Fatal Error if the function fails in an unrecoverable way.
906 */
907 PKIX_Error *
908 pkix_pl_HttpCertStore_CreateWithAsciiName(
909 PKIX_PL_HttpClient *client,
910 char *locationAscii,
911 PKIX_CertStore **pCertStore,
912 void *plContext)
913 {
914 const SEC_HttpClientFcn *clientFcn = NULL;
915 const SEC_HttpClientFcnV1 *hcv1 = NULL;
916 PKIX_PL_HttpCertStoreContext *httpCertStore = NULL;
917 PKIX_CertStore *certStore = NULL;
918 char *hostname = NULL;
919 char *path = NULL;
920 PRUint16 port = 0;
921 SECStatus rv = SECFailure;
922
923 PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_CreateWithAsciiName");
924 PKIX_NULLCHECK_TWO(locationAscii, pCertStore);
925
926 if (client == NULL) {
927 clientFcn = SEC_GetRegisteredHttpClient();
928 if (clientFcn == NULL) {
929 PKIX_ERROR(PKIX_NOREGISTEREDHTTPCLIENT);
930 }
931 } else {
932 clientFcn = (const SEC_HttpClientFcn *)client;
933 }
934
935 if (clientFcn->version != 1) {
936 PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
937 }
938
939 /* create a PKIX_PL_HttpCertStore object */
940 PKIX_CHECK(PKIX_PL_Object_Alloc
941 (PKIX_HTTPCERTSTORECONTEXT_TYPE,
942 sizeof (PKIX_PL_HttpCertStoreContext),
943 (PKIX_PL_Object **)&httpCertStore,
944 plContext),
945 PKIX_COULDNOTCREATEOBJECT);
946
947 /* Initialize fields */
948 httpCertStore->client = clientFcn; /* not a PKIX object! */
949
950 /* parse location -> hostname, port, path */
951 rv = CERT_ParseURL(locationAscii, &hostname, &port, &path);
952 if (rv == SECFailure || hostname == NULL || path == NULL) {
953 PKIX_ERROR(PKIX_URLPARSINGFAILED);
954 }
955
956 httpCertStore->path = path;
957 path = NULL;
958
959 hcv1 = &(clientFcn->fcnTable.ftable1);
960 rv = (*hcv1->createSessionFcn)(hostname, port,
961 &(httpCertStore->serverSession));
962 if (rv != SECSuccess) {
963 PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
964 }
965
966 httpCertStore->requestSession = NULL;
967
968 PKIX_CHECK(PKIX_CertStore_Create
969 (pkix_pl_HttpCertStore_GetCert,
970 pkix_pl_HttpCertStore_GetCRL,
971 pkix_pl_HttpCertStore_GetCertContinue,
972 pkix_pl_HttpCertStore_GetCRLContinue,
973 NULL, /* don't support trust */
974 NULL, /* can not store crls */
975 NULL, /* can not do revocation check */
976 (PKIX_PL_Object *)httpCertStore,
977 PKIX_TRUE, /* cache flag */
978 PKIX_FALSE, /* not local */
979 &certStore,
980 plContext),
981 PKIX_CERTSTORECREATEFAILED);
982
983 *pCertStore = certStore;
984 certStore = NULL;
985
986 cleanup:
987 PKIX_DECREF(httpCertStore);
988 if (hostname) {
989 PORT_Free(hostname);
990 }
991 if (path) {
992 PORT_Free(path);
993 }
994
995 PKIX_RETURN(CERTSTORE);
996 }
997
998 /*
999 * FUNCTION: PKIX_PL_HttpCertStore_Create
1000 * (see comments in pkix_samples_modules.h)
1001 */
1002 PKIX_Error *
1003 PKIX_PL_HttpCertStore_Create(
1004 PKIX_PL_HttpClient *client,
1005 PKIX_PL_GeneralName *location,
1006 PKIX_CertStore **pCertStore,
1007 void *plContext)
1008 {
1009 PKIX_PL_String *locationString = NULL;
1010 char *locationAscii = NULL;
1011 PKIX_UInt32 len = 0;
1012
1013 PKIX_ENTER(CERTSTORE, "PKIX_PL_HttpCertStore_Create");
1014 PKIX_NULLCHECK_TWO(location, pCertStore);
1015
1016 PKIX_TOSTRING(location, &locationString, plContext,
1017 PKIX_GENERALNAMETOSTRINGFAILED);
1018
1019 PKIX_CHECK(PKIX_PL_String_GetEncoded
1020 (locationString,
1021 PKIX_ESCASCII,
1022 (void **)&locationAscii,
1023 &len,
1024 plContext),
1025 PKIX_STRINGGETENCODEDFAILED);
1026
1027 PKIX_CHECK(pkix_pl_HttpCertStore_CreateWithAsciiName
1028 (client, locationAscii, pCertStore, plContext),
1029 PKIX_HTTPCERTSTORECREATEWITHASCIINAMEFAILED);
1030
1031 cleanup:
1032
1033 PKIX_DECREF(locationString);
1034
1035 PKIX_RETURN(CERTSTORE);
1036 }
1037
1038 /*
1039 * FUNCTION: pkix_HttpCertStore_FindSocketConnection
1040 * DESCRIPTION:
1041 *
1042 PRIntervalTime timeout,
1043 char *hostname,
1044 PRUint16 portnum,
1045 PRErrorCode *pStatus,
1046 PKIX_PL_Socket **pSocket,
1047
1048 * This function checks for an existing socket, creating a new one if unable
1049 * to find an existing one, for the host pointed to by "hostname" and the port
1050 * pointed to by "portnum". If a new socket is created the PRIntervalTime in
1051 * "timeout" will be used for the timeout value and a creation status is
1052 * returned at "pStatus". The address of the socket is stored at "pSocket".
1053 *
1054 * PARAMETERS:
1055 * "timeout"
1056 * The PRIntervalTime of the timeout value.
1057 * "hostname"
1058 * The address of the string containing the hostname. Must be non-NULL.
1059 * "portnum"
1060 * The port number for the desired socket.
1061 * "pStatus"
1062 * The address at which the status is stored. Must be non-NULL.
1063 * "pSocket"
1064 * The address at which the socket is stored. Must be non-NULL.
1065 * "plContext"
1066 * Platform-specific context pointer.
1067 * THREAD SAFETY:
1068 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1069 * RETURNS:
1070 * Returns NULL if the function succeeds.
1071 * Returns a HttpCertStore Error if the function fails in a non-fatal way.
1072 * Returns a Fatal Error if the function fails in an unrecoverable way.
1073 */
1074 PKIX_Error *
1075 pkix_HttpCertStore_FindSocketConnection(
1076 PRIntervalTime timeout,
1077 char *hostname,
1078 PRUint16 portnum,
1079 PRErrorCode *pStatus,
1080 PKIX_PL_Socket **pSocket,
1081 void *plContext)
1082 {
1083 PKIX_PL_String *formatString = NULL;
1084 PKIX_PL_String *hostString = NULL;
1085 PKIX_PL_String *domainString = NULL;
1086 PKIX_PL_Socket *socket = NULL;
1087
1088 PKIX_ENTER(CERTSTORE, "pkix_HttpCertStore_FindSocketConnection");
1089 PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket);
1090
1091 *pStatus = 0;
1092
1093 /* create PKIX_PL_String from hostname and port */
1094 PKIX_CHECK(PKIX_PL_String_Create
1095 (PKIX_ESCASCII, "%s:%d", 0, &formatString, plContext),
1096 PKIX_STRINGCREATEFAILED);
1097
1098 #if 0
1099 hostname = "variation.red.iplanet.com";
1100 portnum = 2001;
1101 #endif
1102
1103 PKIX_CHECK(PKIX_PL_String_Create
1104 (PKIX_ESCASCII, hostname, 0, &hostString, plContext),
1105 PKIX_STRINGCREATEFAILED);
1106
1107 PKIX_CHECK(PKIX_PL_Sprintf
1108 (&domainString, plContext, formatString, hostString, portnum),
1109 PKIX_STRINGCREATEFAILED);
1110
1111 #ifdef PKIX_SOCKETCACHE
1112 /* Is this domainName already in cache? */
1113 PKIX_CHECK(PKIX_PL_HashTable_Lookup
1114 (httpSocketCache,
1115 (PKIX_PL_Object *)domainString,
1116 (PKIX_PL_Object **)&socket,
1117 plContext),
1118 PKIX_HASHTABLELOOKUPFAILED);
1119 #endif
1120 if (socket == NULL) {
1121
1122 /* No, create a connection (and cache it) */
1123 PKIX_CHECK(pkix_pl_Socket_CreateByHostAndPort
1124 (PKIX_FALSE, /* create a client, not a server */
1125 timeout,
1126 hostname,
1127 portnum,
1128 pStatus,
1129 &socket,
1130 plContext),
1131 PKIX_SOCKETCREATEBYHOSTANDPORTFAILED);
1132
1133 #ifdef PKIX_SOCKETCACHE
1134 PKIX_CHECK(PKIX_PL_HashTable_Add
1135 (httpSocketCache,
1136 (PKIX_PL_Object *)domainString,
1137 (PKIX_PL_Object *)socket,
1138 plContext),
1139 PKIX_HASHTABLEADDFAILED);
1140 #endif
1141 }
1142
1143 *pSocket = socket;
1144 socket = NULL;
1145
1146 cleanup:
1147
1148 PKIX_DECREF(formatString);
1149 PKIX_DECREF(hostString);
1150 PKIX_DECREF(domainString);
1151 PKIX_DECREF(socket);
1152
1153 PKIX_RETURN(CERTSTORE);
1154 }
1155
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698