/*
 * FUNCTION: pkix_pl_Date_Comparator
 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_Date_Comparator(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Int32 *pResult,
        void *plContext)
{
        PRTime firstTime;
        PRTime secondTime;
        SECComparison cmpResult;

        PKIX_ENTER(DATE, "pkix_pl_Date_Comparator");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        PKIX_CHECK(pkix_CheckTypes
                    (firstObject, secondObject, PKIX_DATE_TYPE, plContext),
                    PKIX_ARGUMENTSNOTDATES);

        firstTime = ((PKIX_PL_Date *)firstObject)->nssTime;
        secondTime = ((PKIX_PL_Date *)secondObject)->nssTime;

        if (firstTime == secondTime)
            cmpResult = SECEqual;
        else if (firstTime < secondTime)
            cmpResult = SECLessThan;
        else
            cmpResult = SECGreaterThan;

        *pResult = cmpResult;

cleanup:

        PKIX_RETURN(DATE);
}
/*
 * FUNCTION: pkix_pl_Date_Equals
 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_Date_Equals(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Boolean *pResult,
        void *plContext)
{
        PKIX_ENTER(DATE, "pkix_pl_Date_Equals");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        /* test that firstObject is a Date */
        PKIX_CHECK(pkix_CheckType(firstObject, PKIX_DATE_TYPE, plContext),
                PKIX_FIRSTOBJECTNOTDATE);

        /*
         * Since we know firstObject is a Date, if both references are
         * identical, they must be equal
         */
        if (firstObject == secondObject){
                *pResult = PKIX_TRUE;
                goto cleanup;
        }

        *pResult = PKIX_FALSE;
        pkixErrorResult =
            pkix_pl_Date_Comparator(firstObject, secondObject,
                                    pResult, plContext);
        if (pkixErrorResult) {
            PKIX_DECREF(pkixErrorResult);
        }
            
cleanup:

        PKIX_RETURN(DATE);
}
Beispiel #3
0
/*
 * FUNCTION: pkix_pl_CRL_GetVersion
 * DESCRIPTION:
 *
 *  Retrieves the version of the CRL pointed to by "crl" and stores it at
 *  "pVersion". The version number will either be 0 or 1 (corresponding to
 *  v1 or v2, respectively).
 *
 *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 *
 * PARAMETERS:
 *  "crl"
 *      Address of CRL whose version is to be stored. Must be non-NULL.
 *  "pVersion"
 *      Address where a version will be 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 CRL 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_CRL_GetVersion(
        PKIX_PL_CRL *crl,
        PKIX_UInt32 *pVersion,
        void *plContext)
{
        PKIX_UInt32 myVersion;

        PKIX_ENTER(CRL, "pkix_pl_CRL_GetVersion");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pVersion);
      
        PKIX_NULLCHECK_ONE(crl->nssSignedCrl->crl.version.data);

        myVersion = *(crl->nssSignedCrl->crl.version.data);

        if (myVersion > 1) {
                PKIX_ERROR(PKIX_VERSIONVALUEMUSTBEV1ORV2);
        }

        *pVersion = myVersion;

cleanup:

        PKIX_RETURN(CRL);
}
/*
 * FUNCTION: pkix_pl_CertPolicyMap_Create
 * DESCRIPTION:
 *
 *  Creates a new CertPolicyMap Object pairing the OID given by
 *  "issuerDomainPolicy" with the OID given by "subjectDomainPolicy", and
 *  stores the result at "pCertPolicyMap".
 *
 * PARAMETERS
 *  "issuerDomainPolicy"
 *      Address of the OID of the IssuerDomainPolicy. Must be non-NULL.
 *  "subjectDomainPolicy"
 *      Address of the OID of the SubjectDomainPolicy. Must be non-NULL.
 *  "pCertPolicyMap"
 *      Address where CertPolicyMap pointer will be 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 CertPolicyMap 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_pl_CertPolicyMap_Create(
        PKIX_PL_OID *issuerDomainPolicy,
        PKIX_PL_OID *subjectDomainPolicy,
        PKIX_PL_CertPolicyMap **pCertPolicyMap,
        void *plContext)
{
        PKIX_PL_CertPolicyMap *policyMap = NULL;

        PKIX_ENTER(CERTPOLICYMAP, "pkix_pl_CertPolicyMap_Create");

        PKIX_NULLCHECK_THREE
                (issuerDomainPolicy, subjectDomainPolicy, pCertPolicyMap);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                (PKIX_CERTPOLICYMAP_TYPE,
                sizeof (PKIX_PL_CertPolicyMap),
                (PKIX_PL_Object **)&policyMap,
                plContext),
                PKIX_COULDNOTCREATECERTPOLICYMAPOBJECT);

        PKIX_INCREF(issuerDomainPolicy);
        policyMap->issuerDomainPolicy = issuerDomainPolicy;

        PKIX_INCREF(subjectDomainPolicy);
        policyMap->subjectDomainPolicy = subjectDomainPolicy;

        *pCertPolicyMap = policyMap;

cleanup:

        PKIX_RETURN(CERTPOLICYMAP);
}
 /*
 * FUNCTION: pkix_pl_OID_Comparator
 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_OID_Comparator(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Int32 *pRes,
        void *plContext)
{
        PKIX_PL_OID *firstOID = NULL;
        PKIX_PL_OID *secondOID = NULL;

        PKIX_ENTER(OID, "pkix_pl_OID_Comparator");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pRes);

        PKIX_CHECK(pkix_CheckTypes
                    (firstObject, secondObject, PKIX_OID_TYPE, plContext),
                    PKIX_ARGUMENTSNOTOIDS);

        firstOID = (PKIX_PL_OID*)firstObject;
        secondOID = (PKIX_PL_OID*)secondObject;

        *pRes = (PKIX_Int32)SECITEM_CompareItem(&firstOID->derOid,
                                                &secondOID->derOid);
cleanup:
        PKIX_RETURN(OID);
}
/*
 * FUNCTION: pkix_pl_Date_Comparator
 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_Date_Comparator(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Int32 *pResult,
        void *plContext)
{
        SECItem *firstTime = NULL;
        SECItem *secondTime = NULL;
        SECComparison cmpResult;

        PKIX_ENTER(DATE, "pkix_pl_Date_Comparator");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        PKIX_CHECK(pkix_CheckTypes
                    (firstObject, secondObject, PKIX_DATE_TYPE, plContext),
                    PKIX_ARGUMENTSNOTDATES);

        firstTime = &((PKIX_PL_Date *)firstObject)->nssTime;
        secondTime = &((PKIX_PL_Date *)secondObject)->nssTime;

        PKIX_DATE_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
        cmpResult = SECITEM_CompareItem(firstTime, secondTime);

        *pResult = cmpResult;

cleanup:

        PKIX_RETURN(DATE);
}
/*
 * FUNCTION: pkix_pl_HashTableLookup
 * DESCRIPTION:
 *
 *  Looks up object using the key pointed to by "key" and hashCode value
 *  equal to "hashCode" from the PrimHashtable pointed to by "ht", using the
 *  function pointed to by "keyComp" to compare keys, and stores the object's
 *  value at "pResult". Assumes "key" is a PKIX_UInt32 or a PKIX_PL_Object.
 *  This function sets "pResult" to NULL if the key is not in the hashtable.
 *
 * PARAMETERS:
 *  "ht"
 *      Address of PrimHashtable to lookup object from. Must be non-NULL.
 *  "key"
 *      Address of key for lookup. Typically a PKIX_UInt32 or PKIX_PL_Object.
 *      Must be non-NULL.
 *  "keyComp"
 *      Address of function used to determine if two keys are equal.
 *      If NULL, pkix_pl_KeyComparator_Default is used.
 *  "hashCode"
 *      Hashcode value of the key.
 *  "pResult"
 *      Address where value will be stored. Must be non-NULL.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Conditionally Thread Safe
 *      (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_pl_PrimHashTable_Lookup(
        pkix_pl_PrimHashTable *ht,
        void *key,
        PKIX_UInt32 hashCode,
        PKIX_PL_EqualsCallback keyComp,
        void **pResult,
        void *plContext)
{
        pkix_pl_HT_Elem *element = NULL;
        PKIX_Boolean compResult = PKIX_FALSE;

        PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Lookup");
        PKIX_NULLCHECK_THREE(ht, key, pResult);

        *pResult = NULL;

        for (element = (ht->buckets)[hashCode%ht->size];
            (element != NULL) && (*pResult == NULL);
            element = element->next) {

                if (element->hashCode != hashCode){
                        /* no possibility of a match */
                        continue;
                }

                if (keyComp == NULL){
                        PKIX_CHECK(pkix_pl_KeyComparator_Default
                                ((PKIX_UInt32 *)key,
                                (PKIX_UInt32 *)(element->key),
                                &compResult,
                                plContext),
                                PKIX_COULDNOTTESTWHETHERKEYSEQUAL);
                } else {
                       pkixErrorResult =
                           keyComp((PKIX_PL_Object *)key,
                                   (PKIX_PL_Object *)(element->key),
                                   &compResult,
                                   plContext);
                       if (pkixErrorResult) {
                           pkixErrorClass = PKIX_FATAL_ERROR;
                           pkixErrorCode = PKIX_COULDNOTTESTWHETHERKEYSEQUAL;
                           goto cleanup;
                       }
                }

                if ((element->hashCode == hashCode) &&
                    (compResult == PKIX_TRUE)){
                        *pResult = element->value;
                        goto cleanup;
                }
        }

        /* if we've reached here, specified key doesn't exist in hashtable */
        *pResult = NULL;

cleanup:

        PKIX_RETURN(HASHTABLE);
}
/*
 * FUNCTION: pkix_pl_PrimHashTable_RemoveFIFO
 * DESCRIPTION:
 *
 *  Remove the first entry in the bucket the "hashCode" is designated in
 *  the hashtable "ht". Since new entry is added at end of the link list
 *  the first one is the oldest (FI) therefore removed first (FO).
 *
 * PARAMETERS:
 *  "ht"
 *      Address of PrimHashtable to get entries count. Must be non-NULL.
 *  "hashCode"
 *      Hashcode value of the key.
 *  "pKey"
 *      Address of key of the entry deleted. Must be non-NULL.
 *  "pValue"
 *      Address of Value of the entry deleted. Must be non-NULL.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Not Thread Safe - assumes exclusive access to "ht"
 *  (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a HashTable 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_pl_PrimHashTable_RemoveFIFO(
        pkix_pl_PrimHashTable *ht,
        PKIX_UInt32 hashCode,
        void **pKey,
        void **pValue,
        void *plContext)
{
        pkix_pl_HT_Elem *element = NULL;

        PKIX_ENTER(HASHTABLE, "pkix_pl_PrimHashTable_Remove");
        PKIX_NULLCHECK_THREE(ht, pKey, pValue);

        element = (ht->buckets)[hashCode%ht->size];

        if (element != NULL) {

                *pKey = element->key;
                *pValue = element->value;
                ht->buckets[hashCode%ht->size] = element->next;
                element->key = NULL;
                element->value = NULL;
                element->next = NULL;
                PKIX_FREE(element);
        }

        PKIX_RETURN(HASHTABLE);
}
/*
 * FUNCTION: pkix_pl_LdapCertStore_GetCertContinue
 *  (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
 */
PKIX_Error *
pkix_pl_LdapCertStore_GetCertContinue(
        PKIX_CertStore *store,
        PKIX_CertSelector *selector,
        PKIX_VerifyNode *verifyNode,
        void **pNBIOContext,
        PKIX_List **pCertList,
        void *plContext)
{
        PKIX_Boolean cacheFlag = PKIX_FALSE;
        PKIX_PL_LdapCertStoreContext *lcs = NULL;
        void *pollDesc = NULL;
        PKIX_List *responses = NULL;
        PKIX_List *unfilteredCerts = NULL;
        PKIX_List *filteredCerts = NULL;

        PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_GetCertContinue");
        PKIX_NULLCHECK_THREE(store, selector, pCertList);

        PKIX_CHECK(PKIX_CertStore_GetCertStoreContext
                (store, (PKIX_PL_Object **)&lcs, plContext),
                PKIX_CERTSTOREGETCERTSTORECONTEXTFAILED);

        PKIX_CHECK(PKIX_PL_LdapClient_ResumeRequest
                ((PKIX_PL_LdapClient *)lcs, &pollDesc, &responses, plContext),
                PKIX_LDAPCLIENTRESUMEREQUESTFAILED);

        if (pollDesc != NULL) {
                /* client is waiting for non-blocking I/O to complete */
                *pNBIOContext = (void *)pollDesc;
                *pCertList = NULL;
                goto cleanup;
        }
        /* LdapClient has given us a response! */

        if (responses) {
                PKIX_CHECK(PKIX_CertStore_GetCertStoreCacheFlag
                        (store, &cacheFlag, plContext),
                        PKIX_CERTSTOREGETCERTSTORECACHEFLAGFAILED);

                PKIX_CHECK(pkix_pl_LdapCertStore_BuildCertList
                        (responses, &unfilteredCerts, plContext),
                        PKIX_LDAPCERTSTOREBUILDCERTLISTFAILED);

                PKIX_CHECK(pkix_CertSelector_Select
                        (selector, unfilteredCerts, &filteredCerts, plContext),
                        PKIX_CERTSELECTORSELECTFAILED);
        }

        *pNBIOContext = NULL;
        *pCertList = filteredCerts;

cleanup:

        PKIX_DECREF(responses);
        PKIX_DECREF(unfilteredCerts);
        PKIX_DECREF(lcs);

        PKIX_RETURN(CERTSTORE);
}
/*
 * FUNCTION: PKIX_PL_OcspCertID_GetFreshCacheStatus
 * DESCRIPTION:
 *
 *  This function may return cached OCSP results for the provided
 *  certificate, but only if stored information is still considered to be
 *  fresh.
 *
 * PARAMETERS
 *  "cid"
 *      A certificate ID as used by OCSP
 *  "validity"
 *      Optional date parameter to request validity for a specifc time.
 *  "hasFreshStatus"
 *      Output parameter, if the function successed to find fresh cached
 *      information, this will be set to true. Must be non-NULL.
 *  "statusIsGood"
 *      The good/bad result stored in the cache. Must be non-NULL.
 *  "missingResponseError"
 *      If OCSP status is "bad", this variable may indicate the exact
 *      reason why the previous OCSP request had failed.
 *  "plContext"
 *      Platform-specific context pointer.
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns an OcspCertID 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_PL_OcspCertID_GetFreshCacheStatus(
        PKIX_PL_OcspCertID *cid, 
        PKIX_PL_Date *validity,
        PKIX_Boolean *hasFreshStatus,
        PKIX_Boolean *statusIsGood,
        SECErrorCodes *missingResponseError,
        void *plContext)
{
        PRTime time = 0;
        SECStatus rv;
        SECStatus rvOcsp;
        OCSPFreshness freshness;

        PKIX_ENTER(DATE, "PKIX_PL_OcspCertID_GetFreshCacheStatus");
        PKIX_NULLCHECK_THREE(cid, hasFreshStatus, statusIsGood);

        if (validity != NULL) {
                PKIX_CHECK(pkix_pl_Date_GetPRTime(validity, &time, plContext),
                        PKIX_DATEGETPRTIMEFAILED);
        } else {
                time = PR_Now();
        }

        rv = ocsp_GetCachedOCSPResponseStatus(
                cid->certID, time, PR_TRUE, /*ignoreGlobalOcspFailureSetting*/
                &rvOcsp, missingResponseError, &freshness);

        *hasFreshStatus = (rv == SECSuccess && freshness == ocspFresh);
        if (*hasFreshStatus) {
                *statusIsGood = (rvOcsp == SECSuccess);
        }
cleanup:
        PKIX_RETURN(OCSPCERTID);
}
/*
 * FUNCTION: pkix_pl_CertPolicyQualifier_Create
 * DESCRIPTION:
 *
 *  Creates a CertPolicyQualifier object with the OID given by "oid"
 *  and the ByteArray given by "qualifier", and stores it at "pObject".
 *
 * PARAMETERS
 *  "oid"
 *      Address of OID of the desired policyQualifierId; must be non-NULL
 *  "qualifier"
 *      Address of ByteArray with the desired value of the qualifier;
 *      must be non-NULL
 *  "pObject"
 *      Address where object pointer will be 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 Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_pl_CertPolicyQualifier_Create(
        PKIX_PL_OID *oid,
        PKIX_PL_ByteArray *qualifier,
        PKIX_PL_CertPolicyQualifier **pObject,
        void *plContext)
{
        PKIX_PL_CertPolicyQualifier *qual = NULL;

        PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_Create");

        PKIX_NULLCHECK_THREE(oid, qualifier, pObject);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                (PKIX_CERTPOLICYQUALIFIER_TYPE,
                sizeof (PKIX_PL_CertPolicyQualifier),
                (PKIX_PL_Object **)&qual,
                plContext),
                PKIX_COULDNOTCREATECERTPOLICYQUALIFIEROBJECT);

        PKIX_INCREF(oid);
        qual->policyQualifierId = oid;

        PKIX_INCREF(qualifier);
        qual->qualifier = qualifier;

        *pObject = qual;
        qual = NULL;

cleanup:
        PKIX_DECREF(qual);

        PKIX_RETURN(CERTPOLICYQUALIFIER);
}
/*
 * FUNCTION: pkix_pl_CRL_Equals
 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_CRL_Equals(
    PKIX_PL_Object *firstObject,
    PKIX_PL_Object *secondObject,
    PKIX_Boolean *pResult,
    void *plContext)
{
    PKIX_PL_CRL *firstCrl = NULL;
    PKIX_PL_CRL *secondCrl = NULL;
    PKIX_UInt32 secondType;

    PKIX_ENTER(CRL, "pkix_pl_CRL_Equals");
    PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

    /* test that firstObject is a CRL */
    PKIX_CHECK(pkix_CheckType(firstObject, PKIX_CRL_TYPE, plContext),
               PKIX_FIRSTOBJECTNOTCRL);

    firstCrl = (PKIX_PL_CRL *)firstObject;
    secondCrl = (PKIX_PL_CRL *)secondObject;

    /*
     * Since we know firstObject is a CRL, if both references are
     * identical, they must be equal
     */
    if (firstCrl == secondCrl) {
        *pResult = PKIX_TRUE;
        goto cleanup;
    }

    /*
     * If secondCrl isn't a CRL, we don't throw an error.
     * We simply return a Boolean result of FALSE
     */
    *pResult = PKIX_FALSE;
    PKIX_CHECK(PKIX_PL_Object_GetType
               ((PKIX_PL_Object *)secondCrl, &secondType, plContext),
               PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
    if (secondType != PKIX_CRL_TYPE) goto cleanup;

    /* Compare DER Bytes */
    PKIX_NULLCHECK_TWO
    (firstCrl->nssSignedCrl,
     firstCrl->nssSignedCrl->derCrl);

    PKIX_NULLCHECK_TWO
    (secondCrl->nssSignedCrl,
     secondCrl->nssSignedCrl->derCrl);

    PKIX_CRL_DEBUG("\t\tCalling SECITEM_CompareItem on derCrl\n");
    if (SECITEM_CompareItem(firstCrl->nssSignedCrl->derCrl,
                            secondCrl->nssSignedCrl->derCrl) == SECEqual) {
        *pResult = PKIX_TRUE;
    }

cleanup:

    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.
 *  "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_GetSignatureAlgId
 *
 * DESCRIPTION:
 *  Retrieves a pointer to the OID that represents the signature algorithm of
 *  the CRL pointed to by "crl" and stores it at "pSignatureAlgId".
 *
 *  AlgorithmIdentifier  ::=  SEQUENCE  {
 *      algorithm               OBJECT IDENTIFIER,
 *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
 *
 * PARAMETERS:
 *  "crl"
 *      Address of CRL whose signature algorithm OID is to be stored.
 *      Must be non-NULL.
 *  "pSignatureAlgId"
 *      Address where object pointer will be 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 CRL 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_CRL_GetSignatureAlgId(
    PKIX_PL_CRL *crl,
    PKIX_PL_OID **pSignatureAlgId,
    void *plContext)
{
    CERTCrl *nssCrl = NULL;
    PKIX_PL_OID *signatureAlgId = NULL;
    SECAlgorithmID algorithm;
    SECItem algBytes;
    char *asciiOID = NULL;

    PKIX_ENTER(CRL, "pkix_pl_CRL_GetSignatureAlgId");
    PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pSignatureAlgId);

    /* if we don't have a cached copy from before, we create one */
    if (crl->signatureAlgId == NULL) {

        PKIX_OBJECT_LOCK(crl);

        if (crl->signatureAlgId == NULL) {

            nssCrl = &(crl->nssSignedCrl->crl);
            algorithm = nssCrl->signatureAlg;
            algBytes = algorithm.algorithm;

            PKIX_NULLCHECK_ONE(algBytes.data);
            if (algBytes.len == 0) {
                PKIX_ERROR_FATAL(PKIX_OIDBYTESLENGTH0);
            }

            PKIX_CHECK(pkix_pl_oidBytes2Ascii
                       (&algBytes, &asciiOID, plContext),
                       PKIX_OIDBYTES2ASCIIFAILED);

            PKIX_CHECK(PKIX_PL_OID_Create
                       (asciiOID, &signatureAlgId, plContext),
                       PKIX_OIDCREATEFAILED);

            /* save a cached copy in case it is asked for again */
            crl->signatureAlgId = signatureAlgId;
        }

        PKIX_OBJECT_UNLOCK(crl);

    }

    PKIX_INCREF(crl->signatureAlgId);
    *pSignatureAlgId = crl->signatureAlgId;

cleanup:

    PKIX_FREE(asciiOID);

    PKIX_RETURN(CRL);
}
/*
 * FUNCTION: PKIX_PL_HashTable_Lookup (see comments in pkix_pl_system.h)
 */
PKIX_Error *
PKIX_PL_HashTable_Lookup(
    PKIX_PL_HashTable *ht,
    PKIX_PL_Object *key,
    PKIX_PL_Object **pResult,
    void *plContext)
{
    PKIX_PL_Mutex *lockedMutex = NULL;
    PKIX_UInt32 hashCode;
    PKIX_PL_EqualsCallback keyComp;
    PKIX_PL_Object *result = NULL;

    PKIX_ENTER(HASHTABLE, "PKIX_PL_HashTable_Lookup");

#if !defined(PKIX_OBJECT_LEAK_TEST)
    PKIX_NULLCHECK_THREE(ht, key, pResult);
#else
    PKIX_NULLCHECK_TWO(key, pResult);

    if (ht == NULL) {
        PKIX_RETURN(HASHTABLE);
    }
#endif

    PKIX_CHECK(PKIX_PL_Object_Hashcode(key, &hashCode, plContext),
               PKIX_OBJECTHASHCODEFAILED);

    PKIX_CHECK(pkix_pl_Object_RetrieveEqualsCallback
               (key, &keyComp, plContext),
               PKIX_OBJECTRETRIEVEEQUALSCALLBACKFAILED);

    PKIX_MUTEX_LOCK(ht->tableLock);

    /* Lookup in primitive hashtable */
    PKIX_CHECK(pkix_pl_PrimHashTable_Lookup
               (ht->primHash,
                (void *)key,
                hashCode,
                keyComp,
                (void **)&result,
                plContext),
               PKIX_PRIMHASHTABLELOOKUPFAILED);

    PKIX_INCREF(result);
    PKIX_MUTEX_UNLOCK(ht->tableLock);

    *pResult = result;

cleanup:

    PKIX_MUTEX_UNLOCK(ht->tableLock);

    PKIX_RETURN(HASHTABLE);
}
/*
 * FUNCTION: pkix_SingleVerifyNode_Equals
 * DESCRIPTION:
 *
 *  Compares for equality the components of the VerifyNode pointed to by
 *  "firstPN", other than its parents and children, with those of the
 *  VerifyNode pointed to by "secondPN" and stores the result at "pResult"
 *  (PKIX_TRUE if equal; PKIX_FALSE if not).
 *
 * PARAMETERS:
 *  "firstPN"
 *      Address of first of the VerifyNodes to be compared; must be non-NULL
 *  "secondPN"
 *      Address of second of the VerifyNodes to be compared; must be non-NULL
 *  "pResult"
 *      Address where Boolean will be stored; must be non-NULL
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Conditionally Thread Safe
 *  (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if function succeeds
 *  Returns a VerifyNode Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error if the function fails in a fatal way
 */
static PKIX_Error *
pkix_SingleVerifyNode_Equals(
        PKIX_VerifyNode *firstVN,
        PKIX_VerifyNode *secondVN,
        PKIX_Boolean *pResult,
        void *plContext)
{
        PKIX_Boolean compResult = PKIX_FALSE;

        PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Equals");
        PKIX_NULLCHECK_THREE(firstVN, secondVN, pResult);

        /* If both references are identical, they must be equal */
        if (firstVN == secondVN) {
                compResult = PKIX_TRUE;
                goto cleanup;
        }

        /*
         * It seems we have to do the comparisons. Do
         * the easiest ones first.
         */
        if ((firstVN->depth) != (secondVN->depth)) {
                goto cleanup;
        }

        /* These fields must be non-NULL */
        PKIX_NULLCHECK_TWO(firstVN->verifyCert, secondVN->verifyCert);

        PKIX_EQUALS
                (firstVN->verifyCert,
                secondVN->verifyCert,
                &compResult,
                plContext,
                PKIX_OBJECTEQUALSFAILED);

        if (compResult == PKIX_FALSE) {
                goto cleanup;
        }

        PKIX_EQUALS
                (firstVN->error,
                secondVN->error,
                &compResult,
                plContext,
                PKIX_OBJECTEQUALSFAILED);

cleanup:

        *pResult = compResult;

        PKIX_RETURN(VERIFYNODE);
}
/*
 * FUNCTION: pkix_pl_Date_Equals
 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_Date_Equals(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Boolean *pResult,
        void *plContext)
{

        /* note: pkix_pl_Date can only represent UTCTime,not GeneralizedTime */

        SECItem *firstTime = NULL;
        SECItem *secondTime = NULL;
        PKIX_UInt32 secondType;
        SECComparison cmpResult;

        PKIX_ENTER(DATE, "pkix_pl_Date_Equals");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        /* test that firstObject is a Date */
        PKIX_CHECK(pkix_CheckType(firstObject, PKIX_DATE_TYPE, plContext),
                PKIX_FIRSTOBJECTNOTDATE);

        /*
         * Since we know firstObject is a Date, if both references are
         * identical, they must be equal
         */
        if (firstObject == secondObject){
                *pResult = PKIX_TRUE;
                goto cleanup;
        }

        /*
         * If secondObject isn't a Date, we don't throw an error.
         * We simply return a Boolean result of FALSE
         */
        *pResult = PKIX_FALSE;
        PKIX_CHECK(PKIX_PL_Object_GetType
                    (secondObject, &secondType, plContext),
                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
        if (secondType != PKIX_DATE_TYPE) goto cleanup;

        firstTime = &((PKIX_PL_Date *)firstObject)->nssTime;
        secondTime = &((PKIX_PL_Date *)secondObject)->nssTime;

        PKIX_DATE_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
        cmpResult = SECITEM_CompareItem(firstTime, secondTime);

        *pResult = (cmpResult == SECEqual);

cleanup:

        PKIX_RETURN(DATE);
}
Beispiel #18
0
/*
 * FUNCTION: PKIX_PL_CRL_GetIssuer (see comments in pkix_pl_pki.h)
 */
PKIX_Error *
PKIX_PL_CRL_GetIssuer(
        PKIX_PL_CRL *crl,
        PKIX_PL_X500Name **pCRLIssuer,
        void *plContext)
{
        PKIX_PL_String *crlString = NULL;
        PKIX_PL_X500Name *issuer = NULL;
        SECItem  *derIssuerName = NULL;
        CERTName *issuerName = NULL;

        PKIX_ENTER(CRL, "PKIX_PL_CRL_GetIssuer");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCRLIssuer);

        /* Can call this function only with der been adopted. */
        PORT_Assert(crl->adoptedDerCrl);

        /* if we don't have a cached copy from before, we create one */
        if (crl->issuer == NULL){

                PKIX_OBJECT_LOCK(crl);

                if (crl->issuer == NULL) {

                        issuerName = &crl->nssSignedCrl->crl.name;
                        derIssuerName = &crl->nssSignedCrl->crl.derName;

                        PKIX_CHECK(
                            PKIX_PL_X500Name_CreateFromCERTName(derIssuerName,
                                                                issuerName,
                                                                &issuer,
                                                                plContext),
                            PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
                        
                        /* save a cached copy in case it is asked for again */
                        crl->issuer = issuer;
                }

                PKIX_OBJECT_UNLOCK(crl);

        }

        PKIX_INCREF(crl->issuer);

        *pCRLIssuer = crl->issuer;

cleanup:

        PKIX_DECREF(crlString);

        PKIX_RETURN(CRL);
}
Beispiel #19
0
/*
 * FUNCTION: pkix_PolicyNode_Create
 * DESCRIPTION:
 *
 *  Creates a new PolicyNode using the OID pointed to by "validPolicy", the List
 *  of CertPolicyQualifiers pointed to by "qualifierSet", the criticality
 *  indicated by the Boolean value of "criticality", and the List of OIDs
 *  pointed to by "expectedPolicySet", and stores the result at "pObject". The
 *  criticality should be derived from whether the certificate policy extension
 *  was marked as critical in the certificate that led to creation of this
 *  PolicyNode. The "qualifierSet" and "expectedPolicySet" Lists are made
 *  immutable. The PolicyNode pointers to parent and to children are initialized
 *  to NULL, and the depth is set to zero; those values should be set by using
 *  the pkix_PolicyNode_AddToParent function.
 *
 * PARAMETERS
 *  "validPolicy"
 *      Address of OID of the valid policy for the path. Must be non-NULL
 *  "qualifierSet"
 *      Address of List of CertPolicyQualifiers associated with the validpolicy.
 *      May be NULL
 *  "criticality"
 *      Boolean indicator of whether the criticality should be set in this
 *      PolicyNode
 *  "expectedPolicySet"
 *      Address of List of OIDs that would satisfy this policy in the next
 *      certificate. Must be non-NULL
 *  "pObject"
 *      Address where the PolicyNode pointer will be 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 PolicyNode 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_PolicyNode_Create(
    PKIX_PL_OID *validPolicy,
    PKIX_List *qualifierSet,
    PKIX_Boolean criticality,
    PKIX_List *expectedPolicySet,
    PKIX_PolicyNode **pObject,
    void *plContext)
{
    PKIX_PolicyNode *node = NULL;

    PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Create");

    PKIX_NULLCHECK_THREE(validPolicy, expectedPolicySet, pObject);

    PKIX_CHECK(PKIX_PL_Object_Alloc
               (PKIX_CERTPOLICYNODE_TYPE,
                sizeof (PKIX_PolicyNode),
                (PKIX_PL_Object **)&node,
                plContext),
               PKIX_COULDNOTCREATEPOLICYNODEOBJECT);

    PKIX_INCREF(validPolicy);
    node->validPolicy = validPolicy;

    PKIX_INCREF(qualifierSet);
    node->qualifierSet = qualifierSet;
    if (qualifierSet) {
        PKIX_CHECK(PKIX_List_SetImmutable(qualifierSet, plContext),
                   PKIX_LISTSETIMMUTABLEFAILED);
    }

    node->criticality = criticality;

    PKIX_INCREF(expectedPolicySet);
    node->expectedPolicySet = expectedPolicySet;
    PKIX_CHECK(PKIX_List_SetImmutable(expectedPolicySet, plContext),
               PKIX_LISTSETIMMUTABLEFAILED);

    node->parent = NULL;
    node->children = NULL;
    node->depth = 0;

    *pObject = node;
    node = NULL;

cleanup:

    PKIX_DECREF(node);

    PKIX_RETURN(CERTPOLICYNODE);
}
/*
 * FUNCTION: pkix_ValidateParams_Equals
 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_ValidateParams_Equals(
        PKIX_PL_Object *first,
        PKIX_PL_Object *second,
        PKIX_Boolean *pResult,
        void *plContext)
{
        PKIX_UInt32 secondType;
        PKIX_Boolean cmpResult;
        PKIX_ValidateParams *firstValParams = NULL;
        PKIX_ValidateParams *secondValParams = NULL;

        PKIX_ENTER(VALIDATEPARAMS, "pkix_ValidateParams_Equals");
        PKIX_NULLCHECK_THREE(first, second, pResult);

        PKIX_CHECK(pkix_CheckType(first, PKIX_VALIDATEPARAMS_TYPE, plContext),
                    PKIX_FIRSTOBJECTNOTVALIDATEPARAMS);

        PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);

        *pResult = PKIX_FALSE;

        if (secondType != PKIX_VALIDATEPARAMS_TYPE) goto cleanup;

        firstValParams = (PKIX_ValidateParams *)first;
        secondValParams = (PKIX_ValidateParams *)second;

        PKIX_CHECK(PKIX_PL_Object_Equals
                    ((PKIX_PL_Object *)firstValParams->procParams,
                    (PKIX_PL_Object *)secondValParams->procParams,
                    &cmpResult,
                    plContext),
                    PKIX_OBJECTEQUALSFAILED);

        if (!cmpResult) goto cleanup;

        PKIX_CHECK(PKIX_PL_Object_Equals
                    ((PKIX_PL_Object *)firstValParams->chain,
                    (PKIX_PL_Object *)secondValParams->chain,
                    &cmpResult,
                    plContext),
                    PKIX_OBJECTEQUALSFAILED);

        if (!cmpResult) goto cleanup;

        *pResult = cmpResult;

cleanup:

        PKIX_RETURN(VALIDATEPARAMS);
}
/*
 * FUNCTION: PKIX_TrustAnchor_CreateWithNameKeyPair
 *      (see comments in pkix_params.h)
 */
PKIX_Error *
PKIX_TrustAnchor_CreateWithNameKeyPair(
        PKIX_PL_X500Name *name,
        PKIX_PL_PublicKey *pubKey,
        PKIX_PL_CertNameConstraints *nameConstraints,
        PKIX_TrustAnchor **pAnchor,
        void *plContext)
{
        PKIX_TrustAnchor *anchor = NULL;

        PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithNameKeyPair");

#ifndef BUILD_LIBPKIX_TESTS
        /* Nss creates trust anchors by using PKIX_TrustAnchor_CreateWithCert
         * function as the complete trusted cert structure, and not only cert
         * public key, is required for chain building and validation processes. 
         * Restricting this function for been used only in libpkix unit
         * tests. */
        PKIX_ERROR(PKIX_FUNCTIONMUSTNOTBEUSED);
#endif

        PKIX_NULLCHECK_THREE(name, pubKey, pAnchor);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_TRUSTANCHOR_TYPE,
                    sizeof (PKIX_TrustAnchor),
                    (PKIX_PL_Object **)&anchor,
                    plContext),
                    PKIX_COULDNOTCREATETRUSTANCHOROBJECT);

        /* initialize fields */
        anchor->trustedCert = NULL;

        PKIX_INCREF(name);
        anchor->caName = name;

        PKIX_INCREF(pubKey);
        anchor->caPubKey = pubKey;

        PKIX_INCREF(nameConstraints);
        anchor->nameConstraints = nameConstraints;

        *pAnchor = anchor;
        anchor = NULL;
cleanup:

        PKIX_DECREF(anchor);

        PKIX_RETURN(TRUSTANCHOR);
}
/*
 * FUNCTION: pkix_pl_CollectionCertStore_CheckTrust
 * DESCRIPTION:
 * This function checks the trust status of this "cert" that was retrieved
 * from the CertStore "store" and returns its trust status at "pTrusted".
 *
 * PARAMETERS:
 * "store"
 *      Address of the CertStore. Must be non-NULL.
 * "cert"
 *      Address of the Cert. Must be non-NULL.
 * "pTrusted"
 *      Address of PKIX_Boolean where the "cert" trust status is returned.
 *      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 CertStore 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_CollectionCertStore_CheckTrust(
        PKIX_CertStore *store,
        PKIX_PL_Cert *cert,
        PKIX_Boolean *pTrusted,
        void *plContext)
{
        PKIX_ENTER(CERTSTORE, "pkix_pl_CollectionCertStore_CheckTrust");
        PKIX_NULLCHECK_THREE(store, cert, pTrusted);

        *pTrusted = PKIX_TRUE;

        PKIX_RETURN(CERTSTORE);
}
/*
 * FUNCTION: pkix_pl_ByteArray_Comparator
 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
 *
 *  NOTE:
 *  It is not clear that this definition of comparing byte arrays makes
 *  sense. It does allow you to tell whether two blocks of memory are
 *  identical, so we only use it for the Equals function (i.e. we don't
 *  register it as a Compare function for ByteArray).
 */
static PKIX_Error *
pkix_pl_ByteArray_Comparator(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Int32 *pResult,
        void *plContext)
{
        PKIX_PL_ByteArray *firstByteArray = NULL;
        PKIX_PL_ByteArray *secondByteArray = NULL;
        unsigned char *firstData = NULL;
        unsigned char *secondData = NULL;
        PKIX_UInt32 i;

        PKIX_ENTER(BYTEARRAY, "pkix_pl_ByteArray_Comparator");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        PKIX_CHECK(pkix_CheckTypes
                (firstObject, secondObject, PKIX_BYTEARRAY_TYPE, plContext),
                PKIX_ARGUMENTSNOTBYTEARRAYS);

        /* It's safe to cast */
        firstByteArray = (PKIX_PL_ByteArray *)firstObject;
        secondByteArray = (PKIX_PL_ByteArray *)secondObject;

        *pResult = 0;
        firstData = (unsigned char *)firstByteArray->array;
        secondData = (unsigned char *)secondByteArray->array;

        if (firstByteArray->length < secondByteArray->length) {
                *pResult = -1;
        } else if (firstByteArray->length > secondByteArray->length) {
                *pResult = 1;
        } else if (firstByteArray->length == secondByteArray->length) {
                /* Check if both array contents are identical */
                for (i = 0;
                    (i < firstByteArray->length) && (*pResult == 0);
                    i++) {
                        if (firstData[i] < secondData[i]) {
                                *pResult = -1;
                        } else if (firstData[i] > secondData[i]) {
                                *pResult = 1;
                        }
                }
        }

cleanup:

        PKIX_RETURN(BYTEARRAY);
}
Beispiel #24
0
/*
 * FUNCTION: PKIX_CertStore_Create (see comments in pkix_certstore.h)
 */
PKIX_Error *
PKIX_CertStore_Create(
        PKIX_CertStore_CertCallback certCallback,
        PKIX_CertStore_CRLCallback crlCallback,
        PKIX_CertStore_CertContinueFunction certContinue,
        PKIX_CertStore_CrlContinueFunction crlContinue,
        PKIX_CertStore_CheckTrustCallback trustCallback,
        PKIX_CertStore_ImportCrlCallback importCrlCallback,
        PKIX_CertStore_CheckRevokationByCrlCallback checkRevByCrlCallback,
        PKIX_PL_Object *certStoreContext,
        PKIX_Boolean cacheFlag,
        PKIX_Boolean localFlag,
        PKIX_CertStore **pStore,
        void *plContext)
{
        PKIX_CertStore *certStore = NULL;

        PKIX_ENTER(CERTSTORE, "PKIX_CertStore_Create");
        PKIX_NULLCHECK_THREE(certCallback, crlCallback, pStore);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_CERTSTORE_TYPE,
                    sizeof (PKIX_CertStore),
                    (PKIX_PL_Object **)&certStore,
                    plContext),
                    PKIX_COULDNOTCREATECERTSTOREOBJECT);

        certStore->certCallback = certCallback;
        certStore->crlCallback = crlCallback;
        certStore->certContinue = certContinue;
        certStore->crlContinue = crlContinue;
        certStore->trustCallback = trustCallback;
        certStore->importCrlCallback = importCrlCallback;
        certStore->checkRevByCrlCallback = checkRevByCrlCallback;
        certStore->cacheFlag = cacheFlag;
        certStore->localFlag = localFlag;

        PKIX_INCREF(certStoreContext);
        certStore->certStoreContext = certStoreContext;

        *pStore = certStore;
        certStore = NULL;

cleanup:

        PKIX_DECREF(certStore);

        PKIX_RETURN(CERTSTORE);
}
Beispiel #25
0
/*
 * FUNCTION: pkix_pl_Object_Equals_Default
 * DESCRIPTION:
 *
 *  Default Object_Equals callback: Compares the address of the Object pointed
 *  to by "firstObject" with the address of the Object pointed to by
 *  "secondObject" and stores the Boolean result at "pResult".
 *
 * PARAMETERS:
 *  "firstObject"
 *      Address of first Object to compare. Must be non-NULL.
 *  "secondObject"
 *      Address of second Object to compare. Must be non-NULL.
 *  "pResult"
 *      Address where Boolean result will be 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 Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_Object_Equals_Default(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Boolean *pResult,
        void *plContext)
{
        PKIX_ENTER(OBJECT, "pkix_pl_Object_Equals_Default");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        /* Just compare pointer values */
        *pResult = (firstObject == secondObject)?PKIX_TRUE:PKIX_FALSE;

        PKIX_RETURN(OBJECT);
}
Beispiel #26
0
/*
 * FUNCTION: pkix_pl_ipAddrBytes2Ascii
 * DESCRIPTION:
 *
 *  Converts the DER encoding of an IPAddress pointed to by "secItem" to an
 *  ASCII representation and stores the result at "pAscii". The ASCII
 *  representation is guaranteed to end with a NUL character. The input
 *  SECItem must contain non-NULL data and must have a positive length.
 *
 *  The return value "pAscii" is not reference-counted and will need to
 *  be freed with PKIX_PL_Free.
 *  XXX this function assumes that IPv4 addresses are being used
 *  XXX what about IPv6? can NSS tell the difference
 *
 * PARAMETERS
 *  "secItem"
 *      Address of SECItem which contains bytes and length of DER encoding.
 *      Must be non-NULL.
 *  "pAscii"
 *      Address where object pointer will be 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 Object 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_pl_ipAddrBytes2Ascii(
        SECItem *secItem,
        char **pAscii,
        void *plContext)
{
        char *data = NULL;
        PKIX_UInt32 *tokens = NULL;
        PKIX_UInt32 numTokens = 0;
        PKIX_UInt32 i = 0;
        char *asciiString = NULL;

        PKIX_ENTER(OBJECT, "pkix_pl_ipAddrBytes2Ascii");
        PKIX_NULLCHECK_THREE(secItem, pAscii, secItem->data);

        if (secItem->len == 0) {
                PKIX_ERROR_FATAL(PKIX_IPADDRBYTES2ASCIIDATALENGTHZERO);
        }

        data = (char *)(secItem->data);
        numTokens = secItem->len;

        /* allocate space for array of integers */
        PKIX_CHECK(PKIX_PL_Malloc
                    (numTokens * sizeof (PKIX_UInt32),
                    (void **)&tokens,
                    plContext),
                    PKIX_MALLOCFAILED);

        /* populate array of integers */
        for (i = 0; i < numTokens; i++){
                tokens[i] = data[i];
        }

        /* convert array of integers to ASCII */
        PKIX_CHECK(pkix_pl_helperBytes2Ascii
                    (tokens, numTokens, &asciiString, plContext),
                    PKIX_HELPERBYTES2ASCIIFAILED);

        *pAscii = asciiString;

cleanup:

        PKIX_FREE(tokens);

        PKIX_RETURN(OBJECT);
}
/*
 * FUNCTION: pkix_pl_GeneralName_GetNssGeneralName
 * DESCRIPTION:
 *
 *  Retrieves the NSS representation of the PKIX_PL_GeneralName pointed by
 *  "genName" and stores it at "pNssGenName". The NSS data type CERTGeneralName
 *  is stored in this object when the object was created.
 *
 * PARAMETERS:
 *  "genName"
 *      Address of PKIX_PL_GeneralName. Must be non-NULL.
 *  "pNssGenName"
 *      Address where CERTGeneralName will be 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 GeneralName 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_pl_GeneralName_GetNssGeneralName(
        PKIX_PL_GeneralName *genName,
        CERTGeneralName **pNssGenName,
        void *plContext)
{
        CERTGeneralName *nssGenName = NULL;

        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_GetNssGeneralName");
        PKIX_NULLCHECK_THREE(genName, pNssGenName, genName->nssGeneralNameList);

        nssGenName = genName->nssGeneralNameList->name;

        *pNssGenName = nssGenName;

        PKIX_RETURN(GENERALNAME);
}
/*
 * FUNCTION: pkix_pl_CollectionCertStoreContext_Equals
 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_CollectionCertStoreContext_Equals(
        PKIX_PL_Object *firstObject,
        PKIX_PL_Object *secondObject,
        PKIX_Int32 *pResult,
        void *plContext)
{
        PKIX_PL_CollectionCertStoreContext *firstCCSContext = NULL;
        PKIX_PL_CollectionCertStoreContext *secondCCSContext = NULL;
        PKIX_Boolean cmpResult = 0;

        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
                    "pkix_pl_CollectionCertStoreContext_Equals");
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);

        PKIX_CHECK(pkix_CheckTypes
                    (firstObject,
                    secondObject,
                    PKIX_COLLECTIONCERTSTORECONTEXT_TYPE,
                    plContext),
                    PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);

        firstCCSContext = (PKIX_PL_CollectionCertStoreContext *)firstObject;
        secondCCSContext = (PKIX_PL_CollectionCertStoreContext *)secondObject;

        if (firstCCSContext->storeDir == secondCCSContext->storeDir) {

                cmpResult = PKIX_TRUE;

        } else {

                PKIX_CHECK(PKIX_PL_Object_Equals
                    ((PKIX_PL_Object *) firstCCSContext->storeDir,
                    (PKIX_PL_Object *) secondCCSContext->storeDir,
                    &cmpResult,
                    plContext),
                    PKIX_STRINGEQUALSFAILED);
        }

        *pResult = cmpResult;

        /* should not check equal on crlList and certList, data are dynamic */

cleanup:
        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
}
Beispiel #29
0
/*
 * FUNCTION: PKIX_PL_CRL_GetCriticalExtensionOIDs
 * (see comments in pkix_pl_pki.h)
 */
PKIX_Error *
PKIX_PL_CRL_GetCriticalExtensionOIDs(
        PKIX_PL_CRL *crl,
        PKIX_List **pExtensions,   /* list of PKIX_PL_OID */
        void *plContext)
{
        PKIX_List *oidsList = NULL;
        CERTCertExtension **extensions = NULL;
        CERTCrl *nssSignedCrl = NULL;

        PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCriticalExtensionOIDs");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pExtensions);

        /* Can call this function only with der been adopted. */
        PORT_Assert(crl->adoptedDerCrl);

        /* if we don't have a cached copy from before, we create one */
        if (crl->critExtOids == NULL) {

                PKIX_OBJECT_LOCK(crl);

                nssSignedCrl = &(crl->nssSignedCrl->crl);
                extensions = nssSignedCrl->extensions;

                if (crl->critExtOids == NULL) {

                        PKIX_CHECK(pkix_pl_OID_GetCriticalExtensionOIDs
                                    (extensions, &oidsList, plContext),
                                    PKIX_GETCRITICALEXTENSIONOIDSFAILED);

                        crl->critExtOids = oidsList;
                }

                PKIX_OBJECT_UNLOCK(crl);

        }

        /* We should return a copy of the List since this list changes */
        PKIX_DUPLICATE(crl->critExtOids, pExtensions, plContext,
                PKIX_OBJECTDUPLICATELISTFAILED);

cleanup:

        PKIX_RETURN(CRL);
}
Beispiel #30
0
/*
 * FUNCTION: pkix_pl_CRL_GetCRLEntries
 * DESCRIPTION:
 *
 *  Retrieves a pointer to the List of CRLEntries found in the CRL pointed to
 *  by "crl" and stores it at "pCRLEntries". If there are no CRLEntries,
 *  this functions stores NULL at "pCRLEntries".
 *
 * PARAMETERS:
 *  "crl"
 *      Address of CRL whose CRL Entries are to be retrieved. Must be non-NULL.
 *  "pCRLEntries"
 *      Address where object pointer will be 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 CRL 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_CRL_GetCRLEntries(
        PKIX_PL_CRL *crl,
        PKIX_List **pCrlEntries,
        void *plContext)
{
        PKIX_List *entryList = NULL;
        CERTCrl *nssCrl = NULL;

        PKIX_ENTER(CRL, "pkix_pl_CRL_GetCRLEntries");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlEntries);

        /* if we don't have a cached copy from before, we create one */
        if (crl->crlEntryList == NULL) {

                PKIX_OBJECT_LOCK(crl);

                if (crl->crlEntryList == NULL){

                        nssCrl = &(crl->nssSignedCrl->crl);

                        PKIX_CHECK(pkix_pl_CRLEntry_Create
                                    (nssCrl->entries, &entryList, plContext),
                                    PKIX_CRLENTRYCREATEFAILED);

                        PKIX_CHECK(PKIX_List_SetImmutable
                                    (entryList, plContext),
                                    PKIX_LISTSETIMMUTABLEFAILED);

                        crl->crlEntryList = entryList;
                }

                PKIX_OBJECT_UNLOCK(crl);

        }

        PKIX_INCREF(crl->crlEntryList);

        *pCrlEntries = crl->crlEntryList;

cleanup:

        PKIX_RETURN(CRL);
}