/* * FUNCTION: pkix_pl_AiaMgr_FindLDAPClient * DESCRIPTION: * * This function checks the collection of LDAPClient connections held by the * AIAMgr pointed to by "aiaMgr" for one matching the domain name given by * "domainName". The string may include a port number: e.g., "betty.nist.gov" * or "nss.red.iplanet.com:1389". If a match is found, that LDAPClient is * stored at "pClient". Otherwise, an LDAPClient is created and added to the * collection, and then stored at "pClient". * * PARAMETERS: * "aiaMgr" * The AIAMgr whose LDAPClient connected are to be managed. Must be * non-NULL. * "domainName" * Address of a string pointing to a server name. Must be non-NULL. * "pClient" * Address at which the returned LDAPClient is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an AIAMgr Error if the function fails in a non-fatal way * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error * pkix_pl_AiaMgr_FindLDAPClient( PKIX_PL_AIAMgr *aiaMgr, char *domainName, PKIX_PL_LdapClient **pClient, void *plContext) { PKIX_PL_String *domainString = NULL; PKIX_PL_LdapDefaultClient *client = NULL; PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient"); PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient); /* create PKIX_PL_String from domain name */ PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, domainName, 0, &domainString, plContext), PKIX_STRINGCREATEFAILED); /* Is this domainName already in cache? */ PKIX_CHECK(PKIX_PL_HashTable_Lookup (aiaConnectionCache, (PKIX_PL_Object *)domainString, (PKIX_PL_Object **)&client, plContext), PKIX_HASHTABLELOOKUPFAILED); if (client == NULL) { /* No, create a connection (and cache it) */ PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName (domainName, /* Do not use NBIO until we verify, that * it is working. For now use 1 min timeout. */ PR_SecondsToInterval( ((PKIX_PL_NssContext*)plContext)->timeoutSeconds), NULL, &client, plContext), PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED); PKIX_CHECK(PKIX_PL_HashTable_Add (aiaConnectionCache, (PKIX_PL_Object *)domainString, (PKIX_PL_Object *)client, plContext), PKIX_HASHTABLEADDFAILED); } *pClient = (PKIX_PL_LdapClient *)client; cleanup: PKIX_DECREF(domainString); PKIX_RETURN(AIAMGR); }
/* * FUNCTION: PKIX_PL_CRL_VerifySignature (see comments in pkix_pl_pki.h) */ PKIX_Error * PKIX_PL_CRL_VerifySignature( PKIX_PL_CRL *crl, PKIX_PL_PublicKey *pubKey, void *plContext) { PKIX_PL_CRL *cachedCrl = NULL; PKIX_Error *verifySig = NULL; PKIX_Error *cachedSig = NULL; PKIX_Boolean crlEqual = PKIX_FALSE; PKIX_Boolean crlInHash= PKIX_FALSE; CERTSignedCrl *nssSignedCrl = NULL; SECKEYPublicKey *nssPubKey = NULL; CERTSignedData *tbsCrl = NULL; void* wincx = NULL; SECStatus status; PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifySignature"); PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pubKey); /* Can call this function only with der been adopted. */ PORT_Assert(crl->adoptedDerCrl); verifySig = PKIX_PL_HashTable_Lookup (cachedCrlSigTable, (PKIX_PL_Object *) pubKey, (PKIX_PL_Object **) &cachedCrl, plContext); if (cachedCrl != NULL && verifySig == NULL) { /* Cached Signature Table lookup succeed */ PKIX_EQUALS(crl, cachedCrl, &crlEqual, plContext, PKIX_OBJECTEQUALSFAILED); if (crlEqual == PKIX_TRUE) { goto cleanup; } /* Different PubKey may hash to same value, skip add */ crlInHash = PKIX_TRUE; } nssSignedCrl = crl->nssSignedCrl; tbsCrl = &nssSignedCrl->signatureWrap; PKIX_CRL_DEBUG("\t\tCalling SECKEY_ExtractPublicKey\n"); nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI); if (!nssPubKey){ PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED); } PKIX_CHECK(pkix_pl_NssContext_GetWincx ((PKIX_PL_NssContext *)plContext, &wincx), PKIX_NSSCONTEXTGETWINCXFAILED); PKIX_CRL_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey\n"); status = CERT_VerifySignedDataWithPublicKey(tbsCrl, nssPubKey, wincx); if (status != SECSuccess) { PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY); } if (crlInHash == PKIX_FALSE) { cachedSig = PKIX_PL_HashTable_Add (cachedCrlSigTable, (PKIX_PL_Object *) pubKey, (PKIX_PL_Object *) crl, plContext); if (cachedSig != NULL) { PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n"); } } cleanup: if (nssPubKey){ PKIX_CRL_DEBUG("\t\tCalling SECKEY_DestroyPublicKey\n"); SECKEY_DestroyPublicKey(nssPubKey); nssPubKey = NULL; } PKIX_DECREF(cachedCrl); PKIX_DECREF(verifySig); PKIX_DECREF(cachedSig); PKIX_RETURN(CRL); }
/* * FUNCTION: pkix_pl_AiaMgr_FindLDAPClient * DESCRIPTION: * * This function checks the collection of LDAPClient connections held by the * AIAMgr pointed to by "aiaMgr" for one matching the domain name given by * "domainName". The string may include a port number: e.g., "betty.nist.gov" * or "nss.red.iplanet.com:1389". If a match is found, that LDAPClient is * stored at "pClient". Otherwise, an LDAPClient is created and added to the * collection, and then stored at "pClient". * * PARAMETERS: * "aiaMgr" * The AIAMgr whose LDAPClient connected are to be managed. Must be * non-NULL. * "domainName" * Address of a string pointing to a server name. Must be non-NULL. * An empty string (which means no <host> is given in the LDAP URL) is * not supported. * "pClient" * Address at which the returned LDAPClient is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns an AIAMgr Error if the function fails in a non-fatal way * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error * pkix_pl_AiaMgr_FindLDAPClient( PKIX_PL_AIAMgr *aiaMgr, char *domainName, PKIX_PL_LdapClient **pClient, void *plContext) { PKIX_PL_String *domainString = NULL; PKIX_PL_LdapDefaultClient *client = NULL; PKIX_ENTER(AIAMGR, "pkix_pl_AiaMgr_FindLDAPClient"); PKIX_NULLCHECK_THREE(aiaMgr, domainName, pClient); /* * An LDAP URL may not have a <host> part, for example, * ldap:///o=University%20of%20Michigan,c=US * PKIX_PL_LdapDefaultClient doesn't know how to discover the default * LDAP server, so we don't support this kind of LDAP URL. */ if (*domainName == '\0') { /* Simulate a PKIX_PL_LdapDefaultClient_CreateByName failure. */ PKIX_ERROR(PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED); } /* create PKIX_PL_String from domain name */ PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, domainName, 0, &domainString, plContext), PKIX_STRINGCREATEFAILED); /* Is this domainName already in cache? */ PKIX_CHECK(PKIX_PL_HashTable_Lookup (aiaConnectionCache, (PKIX_PL_Object *)domainString, (PKIX_PL_Object **)&client, plContext), PKIX_HASHTABLELOOKUPFAILED); if (client == NULL) { /* No, create a connection (and cache it) */ PKIX_CHECK(PKIX_PL_LdapDefaultClient_CreateByName (domainName, /* Do not use NBIO until we verify, that * it is working. For now use 1 min timeout. */ PR_SecondsToInterval( ((PKIX_PL_NssContext*)plContext)->timeoutSeconds), NULL, &client, plContext), PKIX_LDAPDEFAULTCLIENTCREATEBYNAMEFAILED); PKIX_CHECK(PKIX_PL_HashTable_Add (aiaConnectionCache, (PKIX_PL_Object *)domainString, (PKIX_PL_Object *)client, plContext), PKIX_HASHTABLEADDFAILED); } *pClient = (PKIX_PL_LdapClient *)client; cleanup: PKIX_DECREF(domainString); PKIX_RETURN(AIAMGR); }
/* * FUNCTION: pkix_HttpCertStore_FindSocketConnection * DESCRIPTION: * PRIntervalTime timeout, char *hostname, PRUint16 portnum, PRErrorCode *pStatus, PKIX_PL_Socket **pSocket, * This function checks for an existing socket, creating a new one if unable * to find an existing one, for the host pointed to by "hostname" and the port * pointed to by "portnum". If a new socket is created the PRIntervalTime in * "timeout" will be used for the timeout value and a creation status is * returned at "pStatus". The address of the socket is stored at "pSocket". * * PARAMETERS: * "timeout" * The PRIntervalTime of the timeout value. * "hostname" * The address of the string containing the hostname. Must be non-NULL. * "portnum" * The port number for the desired socket. * "pStatus" * The address at which the status is stored. Must be non-NULL. * "pSocket" * The address at which the socket is stored. Must be non-NULL. * "plContext" * Platform-specific context pointer. * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a HttpCertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ PKIX_Error * pkix_HttpCertStore_FindSocketConnection( PRIntervalTime timeout, char *hostname, PRUint16 portnum, PRErrorCode *pStatus, PKIX_PL_Socket **pSocket, void *plContext) { PKIX_PL_String *formatString = NULL; PKIX_PL_String *hostString = NULL; PKIX_PL_String *domainString = NULL; PKIX_PL_Socket *socket = NULL; PKIX_ENTER(CERTSTORE, "pkix_HttpCertStore_FindSocketConnection"); PKIX_NULLCHECK_THREE(hostname, pStatus, pSocket); *pStatus = 0; /* create PKIX_PL_String from hostname and port */ PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, "%s:%d", 0, &formatString, plContext), PKIX_STRINGCREATEFAILED); #if 0 hostname = "variation.red.iplanet.com"; portnum = 2001; #endif PKIX_CHECK(PKIX_PL_String_Create (PKIX_ESCASCII, hostname, 0, &hostString, plContext), PKIX_STRINGCREATEFAILED); PKIX_CHECK(PKIX_PL_Sprintf (&domainString, plContext, formatString, hostString, portnum), PKIX_STRINGCREATEFAILED); /* Is this domainName already in cache? */ PKIX_CHECK(PKIX_PL_HashTable_Lookup (httpSocketCache, (PKIX_PL_Object *)domainString, (PKIX_PL_Object **)&socket, plContext), PKIX_HASHTABLELOOKUPFAILED); if (socket == NULL) { /* No, create a connection (and cache it) */ PKIX_CHECK(pkix_pl_Socket_CreateByHostAndPort (PKIX_FALSE, /* create a client, not a server */ timeout, hostname, portnum, pStatus, &socket, plContext), PKIX_SOCKETCREATEBYHOSTANDPORTFAILED); PKIX_CHECK(PKIX_PL_HashTable_Add (httpSocketCache, (PKIX_PL_Object *)domainString, (PKIX_PL_Object *)socket, plContext), PKIX_HASHTABLEADDFAILED); } *pSocket = socket; socket = NULL; cleanup: PKIX_DECREF(formatString); PKIX_DECREF(hostString); PKIX_DECREF(domainString); PKIX_DECREF(socket); PKIX_RETURN(CERTSTORE); }