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/. */
5
* pkix_pl_httpcertstore.c
7
* HTTPCertStore Function Definitions
11
/* We can't decode the length of a message without at least this many bytes */
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)
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)
25
const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = {
27
0, NULL, sizeof(CERTIssuerAndSN) },
29
offsetof(CERTIssuerAndSN,derIssuer) },
31
offsetof(CERTIssuerAndSN,issuer),
34
offsetof(CERTIssuerAndSN,serialNumber) },
38
const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
40
0, NULL, sizeof(SECAlgorithmID) },
42
offsetof(SECAlgorithmID,algorithm), },
43
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
44
offsetof(SECAlgorithmID,parameters), },
48
/* --Private-HttpCertStoreContext-Object Functions----------------------- */
51
* FUNCTION: pkix_pl_HttpCertStoreContext_Destroy
52
* (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
55
pkix_pl_HttpCertStoreContext_Destroy(
56
PKIX_PL_Object *object,
59
const SEC_HttpClientFcnV1 *hcv1 = NULL;
60
PKIX_PL_HttpCertStoreContext *context = NULL;
63
(HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStoreContext_Destroy");
64
PKIX_NULLCHECK_ONE(object);
66
PKIX_CHECK(pkix_CheckType
67
(object, PKIX_HTTPCERTSTORECONTEXT_TYPE, plContext),
68
PKIX_OBJECTNOTANHTTPCERTSTORECONTEXT);
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;
76
if (context->serverSession != NULL) {
77
(*hcv1->freeSessionFcn)(context->serverSession);
78
context->serverSession = NULL;
80
if (context->path != NULL) {
81
PORT_Free(context->path);
87
PKIX_RETURN(HTTPCERTSTORECONTEXT);
91
* FUNCTION: pkix_pl_HttpCertStoreContext_RegisterSelf
94
* Registers PKIX_PL_HTTPCERTSTORECONTEXT_TYPE and its related
95
* functions with systemClasses[]
98
* Not Thread Safe - for performance and complexity reasons
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
105
pkix_pl_HttpCertStoreContext_RegisterSelf(void *plContext)
107
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
108
pkix_ClassTable_Entry *entry = &systemClasses[PKIX_HTTPCERTSTORECONTEXT_TYPE];
110
PKIX_ENTER(HTTPCERTSTORECONTEXT,
111
"pkix_pl_HttpCertStoreContext_RegisterSelf");
113
entry->description = "HttpCertStoreContext";
114
entry->typeObjectSize = sizeof(PKIX_PL_HttpCertStoreContext);
115
entry->destructor = pkix_pl_HttpCertStoreContext_Destroy;
117
PKIX_RETURN(HTTPCERTSTORECONTEXT);
121
/* --Private-Http-CertStore-Database-Functions----------------------- */
123
typedef struct callbackContextStruct {
124
PKIX_List *pkixCertList;
131
* FUNCTION: certCallback
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.
139
* Note that it does not conform to the libpkix API standard of returning
140
* a PKIX_Error*. It returns a SECStatus.
144
* The address of the callbackContext provided as a void* argument to
145
* CERT_DecodeCertPackage. Must be non-NULL.
147
* The address of the null-terminated array of SECItems. Must be non-NULL.
149
* The number of SECItems found in the signedData. Must be non-NULL.
151
* Platform-specific context pointer.
153
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
155
* Returns SECSuccess if the function succeeds.
156
* Returns SECFailure if the function fails.
159
certCallback(void *arg, SECItem **secitemCerts, int numcerts)
161
callbackContext *cbContext;
162
PKIX_List *pkixCertList = NULL;
163
PKIX_Error *error = NULL;
164
void *plContext = NULL;
167
if ((arg == NULL) || (secitemCerts == NULL)) {
171
cbContext = (callbackContext *)arg;
172
plContext = cbContext->plContext;
173
pkixCertList = cbContext->pkixCertList;
175
for (; itemNum < numcerts; itemNum++ ) {
176
error = pkix_pl_Cert_CreateToList(secitemCerts[itemNum],
177
pkixCertList, plContext);
179
if (error->errClass == PKIX_FATAL_ERROR) {
180
cbContext->error = error;
183
/* reuse "error" since we could not destruct the old *
185
error = PKIX_PL_Object_DecRef((PKIX_PL_Object *)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;
202
typedef SECStatus (*pkix_DecodeCertsFunc)(char *certbuf, int certlen,
203
CERTImportCertificateFunc f, void *arg);
206
struct pkix_DecodeFuncStr {
207
pkix_DecodeCertsFunc func; /* function pointer to the
208
* CERT_DecodeCertPackage function */
209
PRLibrary *smimeLib; /* Pointer to the smime shared lib*/
213
static struct pkix_DecodeFuncStr pkix_decodeFunc;
214
static const PRCallOnceType pkix_pristine;
216
#define SMIME_LIB_NAME SHLIB_PREFIX"smime3."SHLIB_SUFFIX
219
* load the smime library and look up the SEC_ReadPKCS7Certs function.
220
* we do this so we don't have a circular depenency on the smime library,
221
* and also so we don't have to load the smime library in applications that
224
static PRStatus PR_CALLBACK pkix_getDecodeFunction(void)
226
pkix_decodeFunc.smimeLib =
227
PR_LoadLibrary(SHLIB_PREFIX"smime3."SHLIB_SUFFIX);
228
if (pkix_decodeFunc.smimeLib == NULL) {
232
pkix_decodeFunc.func = (pkix_DecodeCertsFunc) PR_FindFunctionSymbol(
233
pkix_decodeFunc.smimeLib, "CERT_DecodeCertPackage");
234
if (!pkix_decodeFunc.func) {
242
* clears our global state on shutdown.
245
pkix_pl_HttpCertStore_Shutdown(void *plContext)
247
if (pkix_decodeFunc.smimeLib) {
248
PR_UnloadLibrary(pkix_decodeFunc.smimeLib);
249
pkix_decodeFunc.smimeLib = NULL;
251
/* the function pointer just need to be cleared, not freed */
252
pkix_decodeFunc.func = NULL;
253
pkix_decodeFunc.once = pkix_pristine;
257
* This function is based on CERT_DecodeCertPackage from lib/pkcs7/certread.c
258
* read an old style ascii or binary certificate chain
261
pkix_pl_HttpCertStore_DecodeCertPackage
262
(const char *certbuf,
264
CERTImportCertificateFunc f,
273
(HTTPCERTSTORECONTEXT,
274
"pkix_pl_HttpCertStore_DecodeCertPackage");
275
PKIX_NULLCHECK_TWO(certbuf, f);
277
status = PR_CallOnce(&pkix_decodeFunc.once, pkix_getDecodeFunction);
279
if (status != PR_SUCCESS) {
280
PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
283
/* paranoia, shouldn't happen if status == PR_SUCCESS); */
284
if (!pkix_decodeFunc.func) {
285
PKIX_ERROR(PKIX_CANTLOADLIBSMIME);
288
rv = (*pkix_decodeFunc.func)((char*)certbuf, certlen, f, arg);
290
if (rv != SECSuccess) {
291
PKIX_ERROR (PKIX_SECREADPKCS7CERTSFAILED);
297
PKIX_RETURN(HTTPCERTSTORECONTEXT);
302
* FUNCTION: pkix_pl_HttpCertStore_ProcessCertResponse
305
* This function verifies that the response code pointed to by "responseCode"
306
* and the content type pointed to by "responseContentType" are as expected,
307
* and then decodes the data pointed to by "responseData", of length
308
* "responseDataLen", into a List of Certs, possibly empty, which is returned
313
* The value of the HTTP response code.
314
* "responseContentType"
315
* The address of the Content-type string. Must be non-NULL.
317
* The address of the message data. Must be non-NULL.
319
* The length of the message data.
321
* The address of the List that is created. Must be non-NULL.
323
* Platform-specific context pointer.
325
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
327
* Returns NULL if the function succeeds.
328
* Returns a HttpCertStore Error if the function fails in a non-fatal way.
329
* Returns a Fatal Error if the function fails in an unrecoverable way.
332
pkix_pl_HttpCertStore_ProcessCertResponse(
333
PRUint16 responseCode,
334
const char *responseContentType,
335
const char *responseData,
336
PRUint32 responseDataLen,
337
PKIX_List **pCertList,
340
callbackContext cbContext;
342
PKIX_ENTER(HTTPCERTSTORECONTEXT,
343
"pkix_pl_HttpCertStore_ProcessCertResponse");
345
cbContext.error = NULL;
346
cbContext.plContext = plContext;
347
cbContext.pkixCertList = NULL;
349
PKIX_NULLCHECK_ONE(pCertList);
351
if (responseCode != 200) {
352
PKIX_ERROR(PKIX_BADHTTPRESPONSE);
355
/* check that response type is application/pkcs7-mime */
356
if (responseContentType == NULL) {
357
PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
360
if (responseData == NULL) {
361
PKIX_ERROR(PKIX_NORESPONSEDATAINHTTPRESPONSE);
365
PKIX_List_Create(&cbContext.pkixCertList, plContext),
366
PKIX_LISTCREATEFAILED);
368
PKIX_CHECK_ONLY_FATAL(
369
pkix_pl_HttpCertStore_DecodeCertPackage(responseData,
374
PKIX_HTTPCERTSTOREDECODECERTPACKAGEFAILED);
375
if (cbContext.error) {
376
/* Aborting on a fatal error(See certCallback fn) */
377
pkixErrorResult = cbContext.error;
381
*pCertList = cbContext.pkixCertList;
382
cbContext.pkixCertList = NULL;
386
PKIX_DECREF(cbContext.pkixCertList);
388
PKIX_RETURN(HTTPCERTSTORECONTEXT);
392
* FUNCTION: pkix_pl_HttpCertStore_ProcessCrlResponse
395
* This function verifies that the response code pointed to by "responseCode"
396
* and the content type pointed to by "responseContentType" are as expected,
397
* and then decodes the data pointed to by "responseData", of length
398
* "responseDataLen", into a List of Crls, possibly empty, which is returned
403
* The value of the HTTP response code.
404
* "responseContentType"
405
* The address of the Content-type string. Must be non-NULL.
407
* The address of the message data. Must be non-NULL.
409
* The length of the message data.
411
* The address of the List that is created. Must be non-NULL.
413
* Platform-specific context pointer.
415
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
417
* Returns NULL if the function succeeds.
418
* Returns a HttpCertStore Error if the function fails in a non-fatal way.
419
* Returns a Fatal Error if the function fails in an unrecoverable way.
422
pkix_pl_HttpCertStore_ProcessCrlResponse(
423
PRUint16 responseCode,
424
const char *responseContentType,
425
const char *responseData,
426
PRUint32 responseDataLen,
427
PKIX_List **pCrlList,
430
SECItem encodedResponse;
431
PRInt16 compareVal = 0;
432
PKIX_List *crls = NULL;
433
SECItem *derCrlCopy = NULL;
434
CERTSignedCrl *nssCrl = NULL;
435
PKIX_PL_CRL *crl = NULL;
437
PKIX_ENTER(HTTPCERTSTORECONTEXT,
438
"pkix_pl_HttpCertStore_ProcessCrlResponse");
439
PKIX_NULLCHECK_ONE(pCrlList);
441
if (responseCode != 200) {
442
PKIX_ERROR(PKIX_BADHTTPRESPONSE);
445
/* check that response type is application/pkix-crl */
446
if (responseContentType == NULL) {
447
PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
450
compareVal = PORT_Strcasecmp(responseContentType,
451
"application/pkix-crl");
452
if (compareVal != 0) {
453
PKIX_ERROR(PKIX_CONTENTTYPENOTPKIXCRL);
455
encodedResponse.type = siBuffer;
456
encodedResponse.data = (void*)responseData;
457
encodedResponse.len = responseDataLen;
459
derCrlCopy = SECITEM_DupItem(&encodedResponse);
461
PKIX_ERROR(PKIX_ALLOCERROR);
463
/* crl will be based on derCrlCopy, but will not own the der. */
465
CERT_DecodeDERCrlWithFlags(NULL, derCrlCopy, SEC_CRL_TYPE,
466
CRL_DECODE_DONT_COPY_DER |
467
CRL_DECODE_SKIP_ENTRIES);
469
PKIX_ERROR(PKIX_FAILEDTODECODECRL);
471
/* pkix crls own the der. */
473
pkix_pl_CRL_CreateWithSignedCRL(nssCrl, derCrlCopy, NULL,
475
PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
476
/* Left control over memory pointed by derCrlCopy and
477
* nssCrl to pkix crl. */
480
PKIX_CHECK(PKIX_List_Create(&crls, plContext),
481
PKIX_LISTCREATEFAILED);
482
PKIX_CHECK(PKIX_List_AppendItem
483
(crls, (PKIX_PL_Object *) crl, plContext),
484
PKIX_LISTAPPENDITEMFAILED);
489
SECITEM_FreeItem(derCrlCopy, PR_TRUE);
492
SEC_DestroyCrl(nssCrl);
497
PKIX_RETURN(HTTPCERTSTORECONTEXT);
501
* FUNCTION: pkix_pl_HttpCertStore_CreateRequestSession
504
* This function takes elements from the HttpCertStoreContext pointed to by
505
* "context" (path, client, and serverSession) and creates a RequestSession.
506
* See the HTTPClient API described in ocspt.h for further details.
510
* The address of the HttpCertStoreContext. Must be non-NULL.
512
* Platform-specific context pointer.
514
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
516
* Returns NULL if the function succeeds.
517
* Returns a HttpCertStore Error if the function fails in a non-fatal way.
518
* Returns a Fatal Error if the function fails in an unrecoverable way.
521
pkix_pl_HttpCertStore_CreateRequestSession(
522
PKIX_PL_HttpCertStoreContext *context,
525
const SEC_HttpClientFcnV1 *hcv1 = NULL;
526
SECStatus rv = SECFailure;
529
(HTTPCERTSTORECONTEXT,
530
"pkix_pl_HttpCertStore_CreateRequestSession");
531
PKIX_NULLCHECK_TWO(context, context->serverSession);
533
if (context->client->version != 1) {
534
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
537
hcv1 = &(context->client->fcnTable.ftable1);
538
if (context->requestSession != NULL) {
539
(*hcv1->freeFcn)(context->requestSession);
540
context->requestSession = 0;
543
rv = (*hcv1->createFcn)(context->serverSession, "http",
544
context->path, "GET",
545
PR_SecondsToInterval(
546
((PKIX_PL_NssContext*)plContext)->timeoutSeconds),
547
&(context->requestSession));
549
if (rv != SECSuccess) {
550
PKIX_ERROR(PKIX_HTTPSERVERERROR);
554
PKIX_RETURN(HTTPCERTSTORECONTEXT);
559
* FUNCTION: pkix_pl_HttpCertStore_GetCert
560
* (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
563
pkix_pl_HttpCertStore_GetCert(
564
PKIX_CertStore *store,
565
PKIX_CertSelector *selector,
566
PKIX_VerifyNode *verifyNode,
568
PKIX_List **pCertList,
571
const SEC_HttpClientFcnV1 *hcv1 = NULL;
572
PKIX_PL_HttpCertStoreContext *context = NULL;
573
void *nbioContext = NULL;
574
SECStatus rv = SECFailure;
575
PRUint16 responseCode = 0;
576
const char *responseContentType = NULL;
577
const char *responseData = NULL;
578
PRUint32 responseDataLen = 0;
579
PKIX_List *certList = NULL;
581
PKIX_ENTER(HTTPCERTSTORECONTEXT, "pkix_pl_HttpCertStore_GetCert");
582
PKIX_NULLCHECK_THREE(store, selector, pCertList);
584
nbioContext = *pNBIOContext;
585
*pNBIOContext = NULL;
587
PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
588
(store, (PKIX_PL_Object **)&context, plContext),
589
PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
591
if (context->client->version != 1) {
592
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
595
hcv1 = &(context->client->fcnTable.ftable1);
597
PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
598
(context, plContext),
599
PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
602
((PKIX_PL_NssContext*)plContext)->maxResponseLength;
604
rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
605
(PRPollDesc **)&nbioContext,
607
(const char **)&responseContentType,
608
NULL, /* &responseHeaders */
609
(const char **)&responseData,
611
if (rv != SECSuccess) {
612
PKIX_ERROR(PKIX_HTTPSERVERERROR);
615
if (nbioContext != 0) {
616
*pNBIOContext = nbioContext;
620
PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
627
PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
629
*pCertList = certList;
632
PKIX_DECREF(context);
634
PKIX_RETURN(CERTSTORE);
638
* FUNCTION: pkix_pl_HttpCertStore_GetCertContinue
639
* (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
642
pkix_pl_HttpCertStore_GetCertContinue(
643
PKIX_CertStore *store,
644
PKIX_CertSelector *selector,
645
PKIX_VerifyNode *verifyNode,
647
PKIX_List **pCertList,
650
const SEC_HttpClientFcnV1 *hcv1 = NULL;
651
PKIX_PL_HttpCertStoreContext *context = NULL;
652
void *nbioContext = NULL;
653
SECStatus rv = SECFailure;
654
PRUint16 responseCode = 0;
655
const char *responseContentType = NULL;
656
const char *responseData = NULL;
657
PRUint32 responseDataLen = 0;
658
PKIX_List *certList = NULL;
660
PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCertContinue");
661
PKIX_NULLCHECK_THREE(store, selector, pCertList);
663
nbioContext = *pNBIOContext;
664
*pNBIOContext = NULL;
666
PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
667
(store, (PKIX_PL_Object **)&context, plContext),
668
PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
670
if (context->client->version != 1) {
671
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
674
hcv1 = &(context->client->fcnTable.ftable1);
675
PKIX_NULLCHECK_ONE(context->requestSession);
678
((PKIX_PL_NssContext*)plContext)->maxResponseLength;
680
rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
681
(PRPollDesc **)&nbioContext,
683
(const char **)&responseContentType,
684
NULL, /* &responseHeaders */
685
(const char **)&responseData,
688
if (rv != SECSuccess) {
689
PKIX_ERROR(PKIX_HTTPSERVERERROR);
692
if (nbioContext != 0) {
693
*pNBIOContext = nbioContext;
697
PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
704
PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);
706
*pCertList = certList;
709
PKIX_DECREF(context);
711
PKIX_RETURN(CERTSTORE);
715
* FUNCTION: pkix_pl_HttpCertStore_GetCRL
716
* (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
719
pkix_pl_HttpCertStore_GetCRL(
720
PKIX_CertStore *store,
721
PKIX_CRLSelector *selector,
723
PKIX_List **pCrlList,
727
const SEC_HttpClientFcnV1 *hcv1 = NULL;
728
PKIX_PL_HttpCertStoreContext *context = NULL;
729
void *nbioContext = NULL;
730
SECStatus rv = SECFailure;
731
PRUint16 responseCode = 0;
732
const char *responseContentType = NULL;
733
const char *responseData = NULL;
734
PRUint32 responseDataLen = 0;
735
PKIX_List *crlList = NULL;
737
PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRL");
738
PKIX_NULLCHECK_THREE(store, selector, pCrlList);
740
nbioContext = *pNBIOContext;
741
*pNBIOContext = NULL;
743
PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
744
(store, (PKIX_PL_Object **)&context, plContext),
745
PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
747
if (context->client->version != 1) {
748
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
751
hcv1 = &(context->client->fcnTable.ftable1);
752
PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
753
(context, plContext),
754
PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
757
((PKIX_PL_NssContext*)plContext)->maxResponseLength;
759
rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
760
(PRPollDesc **)&nbioContext,
762
(const char **)&responseContentType,
763
NULL, /* &responseHeaders */
764
(const char **)&responseData,
767
if (rv != SECSuccess) {
768
PKIX_ERROR(PKIX_HTTPSERVERERROR);
771
if (nbioContext != 0) {
772
*pNBIOContext = nbioContext;
776
PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
783
PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED);
788
PKIX_DECREF(context);
790
PKIX_RETURN(CERTSTORE);
794
* FUNCTION: pkix_pl_HttpCertStore_GetCRLContinue
795
* (see description of PKIX_CertStore_CRLCallback in pkix_certstore.h)
798
pkix_pl_HttpCertStore_GetCRLContinue(
799
PKIX_CertStore *store,
800
PKIX_CRLSelector *selector,
802
PKIX_List **pCrlList,
805
const SEC_HttpClientFcnV1 *hcv1 = NULL;
806
PKIX_PL_HttpCertStoreContext *context = NULL;
807
void *nbioContext = NULL;
808
SECStatus rv = SECFailure;
809
PRUint16 responseCode = 0;
810
const char *responseContentType = NULL;
811
const char *responseData = NULL;
812
PRUint32 responseDataLen = 0;
813
PKIX_List *crlList = NULL;
815
PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_GetCRLContinue");
816
PKIX_NULLCHECK_FOUR(store, selector, pNBIOContext, pCrlList);
818
nbioContext = *pNBIOContext;
819
*pNBIOContext = NULL;
821
PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
822
(store, (PKIX_PL_Object **)&context, plContext),
823
PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);
825
if (context->client->version != 1) {
826
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
828
hcv1 = &(context->client->fcnTable.ftable1);
830
PKIX_CHECK(pkix_pl_HttpCertStore_CreateRequestSession
831
(context, plContext),
832
PKIX_HTTPCERTSTORECREATEREQUESTSESSIONFAILED);
835
((PKIX_PL_NssContext*)plContext)->maxResponseLength;
837
rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
838
(PRPollDesc **)&nbioContext,
840
(const char **)&responseContentType,
841
NULL, /* &responseHeaders */
842
(const char **)&responseData,
845
if (rv != SECSuccess) {
846
PKIX_ERROR(PKIX_HTTPSERVERERROR);
849
if (nbioContext != 0) {
850
*pNBIOContext = nbioContext;
854
PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCrlResponse
861
PKIX_HTTPCERTSTOREPROCESSCRLRESPONSEFAILED);
866
PKIX_DECREF(context);
868
PKIX_RETURN(CERTSTORE);
871
/* --Public-HttpCertStore-Functions----------------------------------- */
874
* FUNCTION: pkix_pl_HttpCertStore_CreateWithAsciiName
877
* This function uses the HttpClient pointed to by "client" and the string
878
* (hostname:portnum/path, with portnum optional) pointed to by "locationAscii"
879
* to create an HttpCertStore connected to the desired location, storing the
880
* created CertStore at "pCertStore".
884
* The address of the HttpClient. Must be non-NULL.
886
* The address of the character string indicating the hostname, port, and
887
* path to be queried for Certs or Crls. Must be non-NULL.
889
* The address in which the object is stored. Must be non-NULL.
891
* Platform-specific context pointer.
893
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
895
* Returns NULL if the function succeeds.
896
* Returns a HttpCertStore Error if the function fails in a non-fatal way.
897
* Returns a Fatal Error if the function fails in an unrecoverable way.
900
pkix_pl_HttpCertStore_CreateWithAsciiName(
901
PKIX_PL_HttpClient *client,
903
PKIX_CertStore **pCertStore,
906
const SEC_HttpClientFcn *clientFcn = NULL;
907
const SEC_HttpClientFcnV1 *hcv1 = NULL;
908
PKIX_PL_HttpCertStoreContext *httpCertStore = NULL;
909
PKIX_CertStore *certStore = NULL;
910
char *hostname = NULL;
913
SECStatus rv = SECFailure;
915
PKIX_ENTER(CERTSTORE, "pkix_pl_HttpCertStore_CreateWithAsciiName");
916
PKIX_NULLCHECK_TWO(locationAscii, pCertStore);
918
if (client == NULL) {
919
clientFcn = SEC_GetRegisteredHttpClient();
920
if (clientFcn == NULL) {
921
PKIX_ERROR(PKIX_NOREGISTEREDHTTPCLIENT);
924
clientFcn = (const SEC_HttpClientFcn *)client;
927
if (clientFcn->version != 1) {
928
PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
931
/* create a PKIX_PL_HttpCertStore object */
932
PKIX_CHECK(PKIX_PL_Object_Alloc
933
(PKIX_HTTPCERTSTORECONTEXT_TYPE,
934
sizeof (PKIX_PL_HttpCertStoreContext),
935
(PKIX_PL_Object **)&httpCertStore,
937
PKIX_COULDNOTCREATEOBJECT);
939
/* Initialize fields */
940
httpCertStore->client = clientFcn; /* not a PKIX object! */
942
/* parse location -> hostname, port, path */
943
rv = CERT_ParseURL(locationAscii, &hostname, &port, &path);
944
if (rv == SECFailure || hostname == NULL || path == NULL) {
945
PKIX_ERROR(PKIX_URLPARSINGFAILED);
948
httpCertStore->path = path;
951
hcv1 = &(clientFcn->fcnTable.ftable1);
952
rv = (*hcv1->createSessionFcn)(hostname, port,
953
&(httpCertStore->serverSession));
954
if (rv != SECSuccess) {
955
PKIX_ERROR(PKIX_HTTPCLIENTCREATESESSIONFAILED);
958
httpCertStore->requestSession = NULL;
960
PKIX_CHECK(PKIX_CertStore_Create
961
(pkix_pl_HttpCertStore_GetCert,
962
pkix_pl_HttpCertStore_GetCRL,
963
pkix_pl_HttpCertStore_GetCertContinue,
964
pkix_pl_HttpCertStore_GetCRLContinue,
965
NULL, /* don't support trust */
966
NULL, /* can not store crls */
967
NULL, /* can not do revocation check */
968
(PKIX_PL_Object *)httpCertStore,
969
PKIX_TRUE, /* cache flag */
970
PKIX_FALSE, /* not local */
973
PKIX_CERTSTORECREATEFAILED);
975
*pCertStore = certStore;
979
PKIX_DECREF(httpCertStore);
987
PKIX_RETURN(CERTSTORE);
991
* FUNCTION: PKIX_PL_HttpCertStore_Create
992
* (see comments in pkix_samples_modules.h)
995
PKIX_PL_HttpCertStore_Create(
996
PKIX_PL_HttpClient *client,
997
PKIX_PL_GeneralName *location,
998
PKIX_CertStore **pCertStore,
1001
PKIX_PL_String *locationString = NULL;
1002
char *locationAscii = NULL;
1003
PKIX_UInt32 len = 0;
1005
PKIX_ENTER(CERTSTORE, "PKIX_PL_HttpCertStore_Create");
1006
PKIX_NULLCHECK_TWO(location, pCertStore);
1008
PKIX_TOSTRING(location, &locationString, plContext,
1009
PKIX_GENERALNAMETOSTRINGFAILED);
1011
PKIX_CHECK(PKIX_PL_String_GetEncoded
1014
(void **)&locationAscii,
1017
PKIX_STRINGGETENCODEDFAILED);
1019
PKIX_CHECK(pkix_pl_HttpCertStore_CreateWithAsciiName
1020
(client, locationAscii, pCertStore, plContext),
1021
PKIX_HTTPCERTSTORECREATEWITHASCIINAMEFAILED);
1025
PKIX_DECREF(locationString);
1027
PKIX_RETURN(CERTSTORE);
1031
* FUNCTION: pkix_HttpCertStore_FindSocketConnection
1034
PRIntervalTime timeout,
1037
PRErrorCode *pStatus,
1038
PKIX_PL_Socket **pSocket,
1040
* This function checks for an existing socket, creating a new one if unable
1041
* to find an existing one, for the host pointed to by "hostname" and the port
1042
* pointed to by "portnum". If a new socket is created the PRIntervalTime in
1043
* "timeout" will be used for the timeout value and a creation status is
1044
* returned at "pStatus". The address of the socket is stored at "pSocket".
1048
* The PRIntervalTime of the timeout value.
1050
* The address of the string containing the hostname. Must be non-NULL.
1052
* The port number for the desired socket.
1054
* The address at which the status is stored. Must be non-NULL.
1056
* The address at which the socket is stored. Must be non-NULL.
1058
* Platform-specific context pointer.
1060
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1062
* Returns NULL if the function succeeds.
1063
* Returns a HttpCertStore Error if the function fails in a non-fatal way.
1064
* Returns a Fatal Error if the function fails in an unrecoverable way.
1067
pkix_HttpCertStore_FindSocketConnection(
1068
PRIntervalTime timeout,
1071
PRErrorCode *pStatus,
1072
PKIX_PL_Socket **pSocket,
1075
PKIX_PL_String *formatString = NULL;
1076
PKIX_PL_String *hostString = NULL;
1077
PKIX_PL_String *domainString = NULL;
1078
PKIX_PL_Socket *socket = NULL;
1080
PKIX_ENTER(CERTSTORE, "pkix_HttpCertStore_FindSocketConnection");
1081
PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket);
1085
/* create PKIX_PL_String from hostname and port */
1086
PKIX_CHECK(PKIX_PL_String_Create
1087
(PKIX_ESCASCII, "%s:%d", 0, &formatString, plContext),
1088
PKIX_STRINGCREATEFAILED);
1091
hostname = "variation.red.iplanet.com";
1095
PKIX_CHECK(PKIX_PL_String_Create
1096
(PKIX_ESCASCII, hostname, 0, &hostString, plContext),
1097
PKIX_STRINGCREATEFAILED);
1099
PKIX_CHECK(PKIX_PL_Sprintf
1100
(&domainString, plContext, formatString, hostString, portnum),
1101
PKIX_STRINGCREATEFAILED);
1103
#ifdef PKIX_SOCKETCACHE
1104
/* Is this domainName already in cache? */
1105
PKIX_CHECK(PKIX_PL_HashTable_Lookup
1107
(PKIX_PL_Object *)domainString,
1108
(PKIX_PL_Object **)&socket,
1110
PKIX_HASHTABLELOOKUPFAILED);
1112
if (socket == NULL) {
1114
/* No, create a connection (and cache it) */
1115
PKIX_CHECK(pkix_pl_Socket_CreateByHostAndPort
1116
(PKIX_FALSE, /* create a client, not a server */
1123
PKIX_SOCKETCREATEBYHOSTANDPORTFAILED);
1125
#ifdef PKIX_SOCKETCACHE
1126
PKIX_CHECK(PKIX_PL_HashTable_Add
1128
(PKIX_PL_Object *)domainString,
1129
(PKIX_PL_Object *)socket,
1131
PKIX_HASHTABLEADDFAILED);
1140
PKIX_DECREF(formatString);
1141
PKIX_DECREF(hostString);
1142
PKIX_DECREF(domainString);
1143
PKIX_DECREF(socket);
1145
PKIX_RETURN(CERTSTORE);