/*
 * 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);
}
Esempio n. 2
0
/*
 * 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);
}
Esempio n. 3
0
/*
 * 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);
}
Esempio n. 4
0
/*
 * 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);
}