| OLD | NEW |
| (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 | |
| OLD | NEW |