Exemplo n.º 1
0
/*
 * FUNCTION: pkix_pl_Date_CreateFromPRTime
 * DESCRIPTION:
 *
 *  Creates a new Date from the PRTime whose value is "prtime", and stores the
 *  result at "pDate".
 *
 * PARAMETERS
 *  "prtime"
 *      The PRTime value to be embodied in the new Date object.
 *  "pDate"
 *      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 Date 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_Date_CreateFromPRTime(
        PRTime prtime,
        PKIX_PL_Date **pDate,
        void *plContext)
{
        PKIX_PL_Date *date = NULL;

        PKIX_ENTER(DATE, "PKIX_PL_Date_CreateFromPRTime");
        PKIX_NULLCHECK_ONE(pDate);

        /* create a PKIX_PL_Date object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_DATE_TYPE,
                    sizeof (PKIX_PL_Date),
                    (PKIX_PL_Object **)&date,
                    plContext),
                    PKIX_COULDNOTCREATEOBJECT);
        /* populate the nssTime field */
        date->nssTime = prtime;
        *pDate = date;
cleanup:
        PKIX_RETURN(DATE);
}
Exemplo n.º 2
0
/*
 * FUNCTION: pkix_pl_HashTable_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_HashTable_Destroy(
    PKIX_PL_Object *object,
    void *plContext)
{
    PKIX_PL_HashTable *ht = NULL;
    pkix_pl_HT_Elem *item = NULL;
    PKIX_UInt32 i;

    PKIX_ENTER(HASHTABLE, "pkix_pl_HashTable_Destroy");
    PKIX_NULLCHECK_ONE(object);

    PKIX_CHECK(pkix_CheckType(object, PKIX_HASHTABLE_TYPE, plContext),
               PKIX_OBJECTNOTHASHTABLE);

    ht = (PKIX_PL_HashTable*) object;

    /* DecRef every object in the primitive hash table */
    for (i = 0; i < ht->primHash->size; i++) {
        for (item = ht->primHash->buckets[i];
                item != NULL;
                item = item->next) {
            PKIX_DECREF(item->key);
            PKIX_DECREF(item->value);
        }
    }

    PKIX_CHECK(pkix_pl_PrimHashTable_Destroy(ht->primHash, plContext),
               PKIX_PRIMHASHTABLEDESTROYFAILED);

    PKIX_DECREF(ht->tableLock);

cleanup:

    PKIX_RETURN(HASHTABLE);
}
Exemplo n.º 3
0
/*
 * FUNCTION: pkix_pl_OcspCertID_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_OcspCertID_Destroy(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_PL_OcspCertID *certID = NULL;

        PKIX_ENTER(OCSPCERTID, "pkix_pl_OcspCertID_Destroy");

        PKIX_NULLCHECK_ONE(object);

        PKIX_CHECK(pkix_CheckType(object, PKIX_OCSPCERTID_TYPE, plContext),
                    PKIX_OBJECTNOTOCSPCERTID);

        certID = (PKIX_PL_OcspCertID *)object;

        if (certID->certID) {
                CERT_DestroyOCSPCertID(certID->certID);
        }

cleanup:

        PKIX_RETURN(OCSPCERTID);
}
/*
 * FUNCTION: pkix_pl_CertPolicyQualifier_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_CertPolicyQualifier_Destroy(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_PL_CertPolicyQualifier *certPQ = NULL;

        PKIX_ENTER(CERTPOLICYQUALIFIER, "pkix_pl_CertPolicyQualifier_Destroy");

        PKIX_NULLCHECK_ONE(object);

        PKIX_CHECK(pkix_CheckType
                (object, PKIX_CERTPOLICYQUALIFIER_TYPE, plContext),
                PKIX_OBJECTNOTCERTPOLICYQUALIFIER);

        certPQ = (PKIX_PL_CertPolicyQualifier*)object;

        PKIX_DECREF(certPQ->policyQualifierId);
        PKIX_DECREF(certPQ->qualifier);

cleanup:

        PKIX_RETURN(CERTPOLICYQUALIFIER);
}
Exemplo n.º 5
0
/*
 * FUNCTION: pkix_ValidateResult_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_ValidateResult_Destroy(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_ValidateResult *result = NULL;

        PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Destroy");
        PKIX_NULLCHECK_ONE(object);

        /* Check that this object is a validate result object */
        PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
                PKIX_OBJECTNOTVALIDATERESULT);

        result = (PKIX_ValidateResult *)object;

        PKIX_DECREF(result->anchor);
        PKIX_DECREF(result->pubKey);
        PKIX_DECREF(result->policyTree);

cleanup:

        PKIX_RETURN(VALIDATERESULT);
}
/*
 * FUNCTION: pkix_pl_CertBasicConstraints_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_CertBasicConstraints_Destroy(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_PL_CertBasicConstraints *certB = NULL;

        PKIX_ENTER(CERTBASICCONSTRAINTS,
                "pkix_pl_CertBasicConstraints_Destroy");
        PKIX_NULLCHECK_ONE(object);

        PKIX_CHECK(pkix_CheckType
                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
                    PKIX_OBJECTNOTCERTBASICCONSTRAINTS);

        certB = (PKIX_PL_CertBasicConstraints*)object;

        certB->isCA = PKIX_FALSE;
        certB->pathLen = 0;

cleanup:

        PKIX_RETURN(CERTBASICCONSTRAINTS);
}
Exemplo n.º 7
0
/*
 * FUNCTION: pkix_pl_CollectionCertStoreContext_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_CollectionCertStoreContext_Destroy(
    PKIX_PL_Object *object,
    void *plContext)
{
    PKIX_PL_CollectionCertStoreContext *colCertStoreContext = NULL;

    PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
               "pkix_pl_CollectionCertStoreContext_Destroy");
    PKIX_NULLCHECK_ONE(object);

    PKIX_CHECK(pkix_CheckType
               (object, PKIX_COLLECTIONCERTSTORECONTEXT_TYPE, plContext),
               PKIX_OBJECTNOTCOLLECTIONCERTSTORECONTEXT);

    colCertStoreContext = (PKIX_PL_CollectionCertStoreContext *)object;

    PKIX_DECREF(colCertStoreContext->storeDir);
    PKIX_DECREF(colCertStoreContext->crlList);
    PKIX_DECREF(colCertStoreContext->certList);

cleanup:
    PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
}
Exemplo n.º 8
0
/*
 * FUNCTION: pkix_RevocationChecker_Destroy
 *      (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_RevocationChecker_Destroy(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_RevocationChecker *checker = NULL;

        PKIX_ENTER(REVOCATIONCHECKER, "pkix_RevocationChecker_Destroy");
        PKIX_NULLCHECK_ONE(object);

        /* Check that this object is a revocation checker */
        PKIX_CHECK(pkix_CheckType
                    (object, PKIX_REVOCATIONCHECKER_TYPE, plContext),
                    PKIX_OBJECTNOTREVOCATIONCHECKER);

        checker = (PKIX_RevocationChecker *)object;

        PKIX_DECREF(checker->leafMethodList);
        PKIX_DECREF(checker->chainMethodList);
        
cleanup:

        PKIX_RETURN(REVOCATIONCHECKER);
}
/*
 * FUNCTION: pkix_DefaultCRLChecker_Check
 *
 * DESCRIPTION:
 *  Check if the Cert has been revoked based the CRLs data.  This function
 *  maintains the checker state to be current.
 *
 * PARAMETERS
 *  "checker"
 *      Address of CertChainChecker which has the state data.
 *      Must be non-NULL.
 *  "cert"
 *      Address of Certificate that is to be validated. Must be non-NULL.
 *  "unresolvedCriticalExtensions"
 *      A List OIDs. Not **yet** used in this checker function.
 *  "plContext"
 *      Platform-specific context pointer.
 *
 * THREAD SAFETY:
 *  Not Thread Safe
 *      (see Thread Safety Definitions in Programmer's Guide)
 *
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a CertChainChecker Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error
 */
static PKIX_Error *
pkix_DefaultCRLChecker_Check(
        PKIX_CertChainChecker *checker,
        PKIX_PL_Cert *cert,
        PKIX_List *unresolvedCriticalExtensions,
        void **pNBIOContext,
        void *plContext)
{
        pkix_DefaultCRLCheckerState *state = NULL;
        PKIX_PL_PublicKey *publicKey = NULL;
        PKIX_PL_PublicKey *newPublicKey = NULL;
        PKIX_Error *checkKeyUsageFail = NULL;
        PKIX_Boolean selfIssued = PKIX_FALSE;
        void *nbioContext = NULL;

        PKIX_ENTER(CERTCHAINCHECKER, "pkix_DefaultCRLChecker_Check");
        PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);

        nbioContext = *pNBIOContext;
        *pNBIOContext = NULL; /* prepare for Error exit */

        PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
                    (checker, (PKIX_PL_Object **)&state, plContext),
                    PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);

        PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey
                    (cert, &publicKey, plContext),
                    PKIX_CERTGETSUBJECTPUBLICKEYFAILED);

        /*
         * If we already have a selector, we were in the middle of checking
         * when a certStore returned with non-blocking I/O pendning.
         */
        if ((state->crlSelector) == NULL) {
                state->certsRemaining--;

                PKIX_NULLCHECK_ONE(state->prevPublicKey);

                if (state->prevCertCrlSign == PKIX_FALSE) {
                        PKIX_ERROR
                                (PKIX_KEYUSAGEKEYCRLSIGNBITNOTON);
                }

                /* Set up CRLSelector */
                PKIX_CHECK(pkix_DefaultCRLChecker_Check_SetSelector
                        (cert, state, plContext),
                        PKIX_DEFAULTCRLCHECKERCHECKSETSELECTORFAILED);

        }

        PKIX_CHECK(pkix_DefaultCRLChecker_Check_Helper
                    (checker,
                    cert,
                    state->prevPublicKey,
                    state,
                    unresolvedCriticalExtensions,
                    PKIX_FALSE,
                    &nbioContext,
                    plContext),
                    PKIX_DEFAULTCRLCHECKERCHECKHELPERFAILED);

        if (nbioContext != NULL) {
                *pNBIOContext = nbioContext;
                goto cleanup;
        }

        PKIX_DECREF(state->crlSelector);

        /*
         * Some NIST test case in 4.5.* use different publicKeys for
         * Cert and its CRL on the chain. Self-issued Certs are used
         * to speciy multiple keys for those cases. That is why we apply
         * the following algorithm:
         *
         * Check if Cert is self-issued. If so, the public key of the Cert
         * that issues this Cert (old key) can be used together with this
         * current key (new key) for key verification. If there are multiple
         * self-issued certs, keys of those Certs (old keys) can also be used
         * for key verification. Old key(s) is saved in a list (PrevPublickKey-
         * List) and cleared when a Cert is no longer self-issued.
         * PrevPublicKey keep key of the previous Cert.
         * PrevPublicKeyList keep key(s) of Cert before the previous one.
         */
        PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext),
                    PKIX_ISCERTSELFISSUEFAILED);

        if (selfIssued == PKIX_TRUE) {

                if (state->prevPublicKeyList == NULL) {

                        PKIX_CHECK(PKIX_List_Create
                            (&state->prevPublicKeyList, plContext),
                            PKIX_LISTCREATEFAILED);

                }

                PKIX_CHECK(PKIX_List_AppendItem
                            (state->prevPublicKeyList,
                            (PKIX_PL_Object *) state->prevPublicKey,
                            plContext),
                            PKIX_LISTAPPENDITEMFAILED);

        } else {
                /* Not self-issued Cert any more, clear old key(s) saved */
                PKIX_DECREF(state->prevPublicKeyList);
        }

        /* Make inheritance and save current Public Key */
        PKIX_CHECK(PKIX_PL_PublicKey_MakeInheritedDSAPublicKey
                    (publicKey, state->prevPublicKey, &newPublicKey, plContext),
                    PKIX_PUBLICKEYMAKEINHERITEDDSAPUBLICKEYFAILED);

        if (newPublicKey == NULL){
                PKIX_INCREF(publicKey);
                newPublicKey = publicKey;
        }

        PKIX_DECREF(state->prevPublicKey);
        PKIX_INCREF(newPublicKey);
        state->prevPublicKey = newPublicKey;

        /* Save current Cert's crlSign bit for CRL checking later */
        if (state->certsRemaining != 0) {
                checkKeyUsageFail = PKIX_PL_Cert_VerifyKeyUsage
                        (cert, PKIX_CRL_SIGN, plContext);

                state->prevCertCrlSign = (checkKeyUsageFail == NULL)?
                        PKIX_TRUE : PKIX_FALSE;

                PKIX_DECREF(checkKeyUsageFail);
        }

/*
        PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
                (checker, (PKIX_PL_Object *)state, plContext),
                PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
 */

cleanup:

        PKIX_DECREF(state);
        PKIX_DECREF(publicKey);
        PKIX_DECREF(newPublicKey);
        PKIX_DECREF(checkKeyUsageFail);

        PKIX_RETURN(CERTCHAINCHECKER);
}
Exemplo n.º 10
0
/*
 * FUNCTION: pkix_pl_OcspResponse_Create
 * DESCRIPTION:
 *
 *  This function transmits the OcspRequest pointed to by "request" and obtains
 *  an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient
 *  supports non-blocking I/O this function may store a non-NULL value at
 *  "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should
 *  make a subsequent call with the same value in "pNBIOContext" and
 *  "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may
 *  occur; the caller should persist until a return occurs with NULL stored at
 *  "pNBIOContext".
 *
 *  If a SEC_HttpClientFcn "responder" is supplied, it is used as the client
 *  to which the OCSP query is sent. If none is supplied, the default responder
 *  is used.
 *
 *  If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to
 *  verify the Cert received from the responder as the signer. If none is
 *  supplied, the default verification function is used.
 *
 *  The contents of "request" are ignored on calls subsequent to a WOULDBLOCK
 *  return, and the caller is permitted to supply NULL.
 *
 * PARAMETERS
 *  "request"
 *      Address of the OcspRequest for which a response is desired.
 *  "responder"
 *      Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP
 *      query.
 *  "verifyFcn"
 *      Address, if non-NULL, of the OcspResponse_VerifyCallback function to be
 *      used to verify the Cert of the OCSP responder.
 *  "pNBIOContext"
 *      Address at which platform-dependent information is stored for handling
 *      of non-blocking I/O. Must be non-NULL.
 *  "pOcspResponse"
 *      The address where the created OcspResponse 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 OcspResponse 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_OcspResponse_Create(
        PKIX_PL_OcspRequest *request,
        void *responder,
        PKIX_PL_VerifyCallback verifyFcn,
        void **pNBIOContext,
        PKIX_PL_OcspResponse **pResponse,
        void *plContext)
{
        void *nbioContext = NULL;
        PKIX_PL_OcspResponse *ocspResponse = NULL;
        const SEC_HttpClientFcn *httpClient = NULL;
        const SEC_HttpClientFcnV1 *hcv1 = NULL;
        SECStatus rv = SECFailure;
        char *location = NULL;
        char *hostname = NULL;
        char *path = NULL;
        char *responseContentType = NULL;
        PRUint16 port = 0;
        SEC_HTTP_SERVER_SESSION serverSession = NULL;
        SEC_HTTP_REQUEST_SESSION sessionRequest = NULL;
        SECItem *encodedRequest = NULL;
        PRUint16 responseCode = 0;
        char *responseData = NULL;
 
        PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create");
        PKIX_NULLCHECK_TWO(pNBIOContext, pResponse);

        nbioContext = *pNBIOContext;
        *pNBIOContext = NULL;

        if (nbioContext != NULL) {

                ocspResponse = *pResponse;
                PKIX_NULLCHECK_ONE(ocspResponse);

                httpClient = ocspResponse->httpClient;
                serverSession = ocspResponse->serverSession;
                sessionRequest = ocspResponse->sessionRequest;
                PKIX_NULLCHECK_THREE(httpClient, serverSession, sessionRequest);

        } else {
                PKIX_UInt32 timeout =
                    ((PKIX_PL_NssContext*)plContext)->timeoutSeconds;

                PKIX_NULLCHECK_ONE(request);

                PKIX_CHECK(pkix_pl_OcspRequest_GetEncoded
                        (request, &encodedRequest, plContext),
                        PKIX_OCSPREQUESTGETENCODEDFAILED);

                /* prepare initial message to HTTPClient */

                /* Is there a default responder and is it enabled? */
                if (responder) {
                    httpClient = (const SEC_HttpClientFcn *)responder;
                } else {
                    httpClient = SEC_GetRegisteredHttpClient();
                }

                if (httpClient && (httpClient->version == 1)) {

                        hcv1 = &(httpClient->fcnTable.ftable1);

                        PKIX_CHECK(pkix_pl_OcspRequest_GetLocation
                                (request, &location, plContext),
                                PKIX_OCSPREQUESTGETLOCATIONFAILED);

                        /* parse location -> hostname, port, path */    
                        rv = CERT_ParseURL(location, &hostname, &port, &path);
                        if (rv == SECFailure || hostname == NULL || path == NULL) {
                                PKIX_ERROR(PKIX_URLPARSINGFAILED);
                        }

                        rv = (*hcv1->createSessionFcn)(hostname, port,
                                                       &serverSession);
                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        rv = (*hcv1->createFcn)(serverSession, "http", path,
                                                "POST",
                                                PR_SecondsToInterval(timeout),
                                                &sessionRequest);
                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        rv = (*hcv1->setPostDataFcn)(sessionRequest,
                                                  (char *)encodedRequest->data,
                                                  encodedRequest->len,
                                                  "application/ocsp-request");
                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        /* create a PKIX_PL_OcspResponse object */
                        PKIX_CHECK(PKIX_PL_Object_Alloc
                                    (PKIX_OCSPRESPONSE_TYPE,
                                    sizeof (PKIX_PL_OcspResponse),
                                    (PKIX_PL_Object **)&ocspResponse,
                                    plContext),
                                    PKIX_COULDNOTCREATEOBJECT);

                        PKIX_INCREF(request);
                        ocspResponse->request = request;
                        ocspResponse->httpClient = httpClient;
                        ocspResponse->serverSession = serverSession;
                        ocspResponse->sessionRequest = sessionRequest;
                        ocspResponse->verifyFcn = verifyFcn;
                        ocspResponse->handle = CERT_GetDefaultCertDB();
                        ocspResponse->encodedResponse = NULL;
                        ocspResponse->arena = NULL;
                        ocspResponse->producedAt = 0;
                        ocspResponse->producedAtDate = NULL;
                        ocspResponse->pkixSignerCert = NULL;
                        ocspResponse->nssOCSPResponse = NULL;
                        ocspResponse->signerCert = NULL;
                }
        }

        /* begin or resume IO to HTTPClient */
        if (httpClient && (httpClient->version == 1)) {
                PRUint32 responseDataLen = 
                   ((PKIX_PL_NssContext*)plContext)->maxResponseLength;

                hcv1 = &(httpClient->fcnTable.ftable1);

                rv = (*hcv1->trySendAndReceiveFcn)(sessionRequest,
                        (PRPollDesc **)&nbioContext,
                        &responseCode,
                        &responseContentType,
                        NULL,   /* responseHeaders */
                        (const char **)&responseData,
                        &responseDataLen);

                if (rv != SECSuccess) {
                        PKIX_ERROR(PKIX_OCSPSERVERERROR);
                }
                /* responseContentType is a pointer to the null-terminated
                 * string returned by httpclient. Memory allocated for context
                 * type will be freed with freeing of the HttpClient struct. */
                if (PORT_Strcasecmp(responseContentType, 
                                   "application/ocsp-response")) {
                       PKIX_ERROR(PKIX_OCSPSERVERERROR);
                }
                if (nbioContext != NULL) {
                        *pNBIOContext = nbioContext;
                        goto cleanup;
                }
                if (responseCode != 200) {
                        PKIX_ERROR(PKIX_OCSPBADHTTPRESPONSE);
                }
                ocspResponse->arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                if (ocspResponse->arena == NULL) {
                        PKIX_ERROR(PKIX_OUTOFMEMORY);
                }
                ocspResponse->encodedResponse = SECITEM_AllocItem
                        (ocspResponse->arena, NULL, responseDataLen);
                if (ocspResponse->encodedResponse == NULL) {
                        PKIX_ERROR(PKIX_OUTOFMEMORY);
                }
                PORT_Memcpy(ocspResponse->encodedResponse->data,
                            responseData, responseDataLen);
        }
        *pResponse = ocspResponse;

cleanup:

        if (path != NULL) {
            PORT_Free(path);
        }

        if (hostname != NULL) {
            PORT_Free(hostname);
        }

        if (PKIX_ERROR_RECEIVED){
            if (ocspResponse) {
                PKIX_DECREF(ocspResponse);
            } else {
                if (serverSession) 
                    hcv1->freeSessionFcn(serverSession);
                if (sessionRequest)
                    hcv1->freeFcn(sessionRequest);
            }
        }

        PKIX_RETURN(OCSPRESPONSE);
}
/*
 * FUNCTION: pkix_TargetCertCheckerState_Create
 * DESCRIPTION:
 *
 *  Creates a new TargetCertCheckerState using the CertSelector pointed to
 *  by "certSelector" and the number of certs represented by "certsRemaining"
 *  and stores it at "pState".
 *
 * PARAMETERS:
 *  "certSelector"
 *      Address of CertSelector representing the criteria against which the
 *      final certificate in a chain is to be matched. Must be non-NULL.
 *  "certsRemaining"
 *      Number of certificates remaining in the chain.
 *  "pState"
 *      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 TargetCertCheckerState 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_TargetCertCheckerState_Create(
    PKIX_CertSelector *certSelector,
    PKIX_UInt32 certsRemaining,
    pkix_TargetCertCheckerState **pState,
    void *plContext)
{
        pkix_TargetCertCheckerState *state = NULL;
        PKIX_ComCertSelParams *certSelectorParams = NULL;
        PKIX_List *pathToNameList = NULL;
        PKIX_List *extKeyUsageList = NULL;
        PKIX_List *subjAltNameList = NULL;
        PKIX_PL_OID *extKeyUsageOID = NULL;
        PKIX_PL_OID *subjAltNameOID = NULL;
        PKIX_Boolean subjAltNameMatchAll = PKIX_TRUE;

        PKIX_ENTER(TARGETCERTCHECKERSTATE,
                    "pkix_TargetCertCheckerState_Create");
        PKIX_NULLCHECK_ONE(pState);

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_EXTENDEDKEYUSAGE_OID,
                    &extKeyUsageOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_CERTSUBJALTNAME_OID,
                    &subjAltNameOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_TARGETCERTCHECKERSTATE_TYPE,
                    sizeof (pkix_TargetCertCheckerState),
                    (PKIX_PL_Object **)&state,
                    plContext),
                    PKIX_COULDNOTCREATETARGETCERTCHECKERSTATEOBJECT);

        /* initialize fields */

        if (certSelector != NULL) {

                PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
                        (certSelector, &certSelectorParams, plContext),
                        PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMFAILED);

                if (certSelectorParams != NULL) {

                        PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
                            (certSelectorParams,
                            &pathToNameList,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);

                        PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
                            (certSelectorParams,
                            &extKeyUsageList,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);

                        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
                            (certSelectorParams,
                            &subjAltNameList,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);

                        PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
                            (certSelectorParams,
                            &subjAltNameMatchAll,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
                }
        }

        state->certsRemaining = certsRemaining;
        state->subjAltNameMatchAll = subjAltNameMatchAll;

        PKIX_INCREF(certSelector);
        state->certSelector = certSelector;

        state->pathToNameList = pathToNameList;
        pathToNameList = NULL;

        state->extKeyUsageList = extKeyUsageList;
        extKeyUsageList = NULL;

        state->subjAltNameList = subjAltNameList;
        subjAltNameList = NULL;

        state->extKeyUsageOID = extKeyUsageOID;
        extKeyUsageOID = NULL;

        state->subjAltNameOID = subjAltNameOID;
        subjAltNameOID = NULL;

        *pState = state;
        state = NULL;

cleanup:
        
        PKIX_DECREF(extKeyUsageOID);
        PKIX_DECREF(subjAltNameOID);
        PKIX_DECREF(pathToNameList);
        PKIX_DECREF(extKeyUsageList);
        PKIX_DECREF(subjAltNameList);
        PKIX_DECREF(state);

        PKIX_DECREF(certSelectorParams);

        PKIX_RETURN(TARGETCERTCHECKERSTATE);

}
Exemplo n.º 12
0
/*
 * FUNCTION: PKIX_Logger_AddLogger (see comments in pkix_util.h)
 */
PKIX_Error *
PKIX_AddLogger(
        PKIX_Logger *logger,
        void *plContext)
{
        PKIX_Logger *dupLogger = NULL;
        PKIX_Logger *addLogger = NULL;
        PKIX_List *savedPkixLoggersErrors = NULL;
        PKIX_List *savedPkixLoggersDebugTrace = NULL;
        PKIX_Boolean locked = PKIX_FALSE;
        PKIX_UInt32 i, length;

        PKIX_ENTER(LOGGER, "PKIX_Logger_AddLogger");
        PKIX_NULLCHECK_ONE(logger);

        PKIX_CHECK(PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext),
                PKIX_MONITORLOCKENTERFAILED);
        locked = PKIX_TRUE;

        savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
        pkixLoggersDebugTrace = NULL;
        savedPkixLoggersErrors = pkixLoggersErrors;
        pkixLoggersErrors = NULL;

        PKIX_DECREF(savedPkixLoggersErrors);
        PKIX_DECREF(savedPkixLoggersDebugTrace);

        if (pkixLoggers == NULL) {

            PKIX_CHECK(PKIX_List_Create(&pkixLoggers, plContext),
                    PKIX_LISTCREATEFAILED);
        }

        PKIX_CHECK(pkix_Logger_Duplicate
                    ((PKIX_PL_Object *)logger,
                    (PKIX_PL_Object **)&dupLogger,
                    plContext),
                    PKIX_LOGGERDUPLICATEFAILED);

        PKIX_CHECK(PKIX_List_AppendItem
                    (pkixLoggers,
                    (PKIX_PL_Object *) dupLogger,
                    plContext),
                    PKIX_LISTAPPENDITEMFAILED);

        PKIX_CHECK(PKIX_List_GetLength(pkixLoggers, &length, plContext),
                    PKIX_LISTGETLENGTHFAILED);

        /* Reconstruct pkixLoggersErrors and pkixLoggersDebugTrace */
        for (i = 0; i < length; i++) {

                PKIX_CHECK(PKIX_List_GetItem
                        (pkixLoggers,
                        i,
                        (PKIX_PL_Object **) &addLogger,
                        plContext),
                        PKIX_LISTGETITEMFAILED);


                /* Put in pkixLoggersErrors */

                if (savedPkixLoggersErrors == NULL) {

                        PKIX_CHECK(PKIX_List_Create
                                    (&savedPkixLoggersErrors,
                                    plContext),
                                    PKIX_LISTCREATEFAILED);
                }
        
                PKIX_CHECK(PKIX_List_AppendItem
                        (savedPkixLoggersErrors,
                        (PKIX_PL_Object *) addLogger,
                        plContext),
                        PKIX_LISTAPPENDITEMFAILED);
                            
                if (addLogger->maxLevel > PKIX_LOGGER_LEVEL_WARNING) {

                        /* Put in pkixLoggersDebugTrace */

                        if (savedPkixLoggersDebugTrace == NULL) {

                            PKIX_CHECK(PKIX_List_Create
                                    (&savedPkixLoggersDebugTrace,
                                    plContext),
                                    PKIX_LISTCREATEFAILED);
                        }

                        PKIX_CHECK(PKIX_List_AppendItem
                                (savedPkixLoggersDebugTrace,
                                (PKIX_PL_Object *) addLogger,
                                plContext),
                                PKIX_LISTAPPENDITEMFAILED);
                }

                PKIX_DECREF(addLogger);

        }

cleanup:

        PKIX_DECREF(dupLogger);
        PKIX_DECREF(addLogger);

        /* Restore logging capability */
        pkixLoggersErrors = savedPkixLoggersErrors;
        pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;

        if (locked) {
                PKIX_CHECK(PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext),
                        PKIX_MONITORLOCKEXITFAILED);
        }

       PKIX_RETURN(LOGGER);
}
Exemplo n.º 13
0
/*
 * FUNCTION: PKIX_Logger_GetLoggers (see comments in pkix_util.h)
 */
PKIX_Error *
PKIX_GetLoggers(
        PKIX_List **pLoggers,  /* list of PKIX_Logger */
        void *plContext)
{
        PKIX_List *list = NULL;
        PKIX_List *savedPkixLoggersDebugTrace = NULL;
        PKIX_List *savedPkixLoggersErrors = NULL;
        PKIX_Logger *logger = NULL;
        PKIX_Logger *dupLogger = NULL;
        PKIX_UInt32 i, length;
        PKIX_Boolean locked = PKIX_FALSE;

        PKIX_ENTER(LOGGER, "PKIX_Logger_GetLoggers");
        PKIX_NULLCHECK_ONE(pLoggers);

        PKIX_CHECK(PKIX_PL_MonitorLock_Enter(pkixLoggerLock, plContext),
                PKIX_MONITORLOCKENTERFAILED);
        locked = PKIX_TRUE;

        /*
         * Temporarily disable DEBUG/TRACE Logging to avoid possible
         * deadlock:
         * When the Logger List is being accessed, e.g. by PKIX_ENTER or
         * PKIX_DECREF, pkix_Logger_Check may check whether logging
         * is requested, creating a deadlock situation.
         */
        savedPkixLoggersDebugTrace = pkixLoggersDebugTrace;
        pkixLoggersDebugTrace = NULL;
        savedPkixLoggersErrors = pkixLoggersErrors;
        pkixLoggersErrors = NULL;

        if (pkixLoggers == NULL) {
                length = 0;
        } else {
                PKIX_CHECK(PKIX_List_GetLength
                    (pkixLoggers, &length, plContext),
                    PKIX_LISTGETLENGTHFAILED);
        }

        /* Create a list and copy the pkixLoggers item to the list */
        PKIX_CHECK(PKIX_List_Create(&list, plContext),
                    PKIX_LISTCREATEFAILED);

        for (i = 0; i < length; i++) {

            PKIX_CHECK(PKIX_List_GetItem
                        (pkixLoggers,
                        i,
                        (PKIX_PL_Object **) &logger,
                        plContext),
                        PKIX_LISTGETITEMFAILED);

            PKIX_CHECK(pkix_Logger_Duplicate
                        ((PKIX_PL_Object *)logger,
                        (PKIX_PL_Object **)&dupLogger,
                        plContext),
                        PKIX_LOGGERDUPLICATEFAILED);

            PKIX_CHECK(PKIX_List_AppendItem
                        (list,
                        (PKIX_PL_Object *) dupLogger,
                        plContext),
                        PKIX_LISTAPPENDITEMFAILED);

            PKIX_DECREF(logger);
            PKIX_DECREF(dupLogger);
        }

        /* Set the list to be immutable */
        PKIX_CHECK(PKIX_List_SetImmutable(list, plContext),
                        PKIX_LISTSETIMMUTABLEFAILED);

        *pLoggers = list;

cleanup:

        PKIX_DECREF(logger);

        /* Restore logging capability */
        pkixLoggersDebugTrace = savedPkixLoggersDebugTrace;
        pkixLoggersErrors = savedPkixLoggersErrors;

        if (locked) {
                PKIX_CHECK(PKIX_PL_MonitorLock_Exit(pkixLoggerLock, plContext),
                        PKIX_MONITORLOCKEXITFAILED);
        }

        PKIX_RETURN(LOGGER);
}
Exemplo n.º 14
0
/*
 * FUNCTION: pkix_pl_HttpCertStore_GetCertContinue
 *  (see description of PKIX_CertStore_CertCallback in pkix_certstore.h)
 */
PKIX_Error *
pkix_pl_HttpCertStore_GetCertContinue(
        PKIX_CertStore *store,
        PKIX_CertSelector *selector,
        void **pNBIOContext,
        PKIX_List **pCertList,
        void *plContext)
{
        const SEC_HttpClientFcnV1 *hcv1 = NULL;
        PKIX_PL_HttpCertStoreContext *context = NULL;
        void *nbioContext = NULL;
        SECStatus rv = SECFailure;
        PRUint16 responseCode = 0;
        const char *responseContentType = NULL;
        const char *responseData = NULL;
        PRUint32 responseDataLen = 0;
        PKIX_List *certList = NULL;

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

        nbioContext = *pNBIOContext;
        *pNBIOContext = NULL;

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

        if (context->client->version != 1) {
                PKIX_ERROR(PKIX_UNSUPPORTEDVERSIONOFHTTPCLIENT);
        }

        hcv1 = &(context->client->fcnTable.ftable1);
        PKIX_NULLCHECK_ONE(context->requestSession);

        responseDataLen = 
            ((PKIX_PL_NssContext*)plContext)->maxResponseLength;

        rv = (*hcv1->trySendAndReceiveFcn)(context->requestSession,
                        (PRPollDesc **)&nbioContext,
                        &responseCode,
                        (const char **)&responseContentType,
                        NULL, /* &responseHeaders */
                        (const char **)&responseData,
                        &responseDataLen);

        if (rv != SECSuccess) {
            PKIX_ERROR(PKIX_HTTPSERVERERROR);
        }
        
        if (nbioContext != 0) {
            *pNBIOContext = nbioContext;
            goto cleanup;
        }

        PKIX_CHECK(pkix_pl_HttpCertStore_ProcessCertResponse
                (responseCode,
                responseContentType,
                responseData,
                responseDataLen,
                &certList,
                plContext),
                PKIX_HTTPCERTSTOREPROCESSCERTRESPONSEFAILED);

        *pCertList = certList;

cleanup:
        PKIX_DECREF(context);
        
        PKIX_RETURN(CERTSTORE);
}
Exemplo n.º 15
0
/*
 * FUNCTION: pkix_pl_CollectionCertStoreContext_PopulateCRL
 * DESCRIPTION:
 *
 *  Create list of CRLs from *.crl files at directory specified in dirName,
 *  Not recursive to sub-dirctory. Also assume the directory contents are
 *  not changed dynamically.
 *
 * PARAMETERS
 *  "colCertStoreContext" - Address of CollectionCertStoreContext
 *              where the dirName is specified and where the return
 *              CRLs are stored as a list. Must be non-NULL.
 *  "plContext" - Platform-specific context pointer.
 *
 * THREAD SAFETY:
 *  Not Thread Safe - A lock at top level is required.
 *
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a CollectionCertStoreContext 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_CollectionCertStoreContext_PopulateCRL(
        PKIX_PL_CollectionCertStoreContext *colCertStoreContext,
        void *plContext)
{
        PKIX_List *crlList = NULL;
        PKIX_PL_CRL *crlItem = NULL;
        char *dirName = NULL;
        char *pathName = NULL;
        PKIX_UInt32 dirNameLen = 0;
        PRErrorCode prError = 0;
        PRDir *dir = NULL;
        PRDirEntry *dirEntry = NULL;

        PKIX_ENTER(COLLECTIONCERTSTORECONTEXT,
                    "pkix_pl_CollectionCertStoreContext_PopulateCRL");
        PKIX_NULLCHECK_ONE(colCertStoreContext);

        /* convert directory to ascii */

        PKIX_CHECK(PKIX_PL_String_GetEncoded
                    (colCertStoreContext->storeDir,
                    PKIX_ESCASCII,
                    (void **)&dirName,
                    &dirNameLen,
                    plContext),
                    PKIX_STRINGGETENCODEDFAILED);

        /* create CRL list, if no CRL file, should return an empty list */

        PKIX_CHECK(PKIX_List_Create(&crlList, plContext),
                    PKIX_LISTCREATEFAILED);

        /* open directory and read in .crl files */

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_OpenDir.\n");
        dir = PR_OpenDir(dirName);

        if (!dir) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG_ARG
                        ("\t\t Directory Name:%s\n", dirName);
                PKIX_ERROR(PKIX_CANNOTOPENCOLLECTIONCERTSTORECONTEXTDIRECTORY);
        }

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_ReadDir.\n");
        dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);

        if (!dirEntry) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Empty directory.\n");
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_GetError.\n");
                prError = PR_GetError();
        }

        PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG("\t\t Calling PR_SetError.\n");
        PR_SetError(0, 0);

        while (dirEntry != NULL && prError == 0) {
                if (PL_strrstr(dirEntry->name, ".crl") ==
                    dirEntry->name + PL_strlen(dirEntry->name) - 4) {

                        PKIX_CHECK_ONLY_FATAL
                                (PKIX_PL_Malloc
                                (dirNameLen + PL_strlen(dirEntry->name) + 2,
                                (void **)&pathName,
                                plContext),
                                PKIX_MALLOCFAILED);

                        if ((!PKIX_ERROR_RECEIVED) && (pathName != NULL)){

                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                    ("\t\t Calling PL_strcpy for dirName.\n");
                                PL_strcpy(pathName, dirName);
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                    ("\t\t Calling PL_strcat for dirName.\n");
                                PL_strcat(pathName, "/");
                                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                                        ("\t\t Calling PL_strcat for /.\n");
                                PL_strcat(pathName, dirEntry->name);

                        PKIX_CHECK_ONLY_FATAL
                                (pkix_pl_CollectionCertStoreContext_CreateCRL
                                (pathName, &crlItem, plContext),
                                PKIX_COLLECTIONCERTSTORECONTEXTCREATECRLFAILED);

                                if (!PKIX_ERROR_RECEIVED){
                                        PKIX_CHECK_ONLY_FATAL
                                                (PKIX_List_AppendItem
                                                (crlList,
                                                (PKIX_PL_Object *)crlItem,
                                                plContext),
                                                PKIX_LISTAPPENDITEMFAILED);
                                }
                        }

                        PKIX_DECREF(crlItem);
                        PKIX_FREE(pathName);
                }

                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_SetError.\n");
                PR_SetError(0, 0);

                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_ReadDir.\n");
                dirEntry = PR_ReadDir(dir, PR_SKIP_HIDDEN | PR_SKIP_BOTH);

                if (!dirEntry) {
                    PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_GetError.\n");
                    prError = PR_GetError();
                }
        }

        if ((prError != 0) && (prError != PR_NO_MORE_FILES_ERROR)) {
                PKIX_ERROR(PKIX_COLLECTIONCERTSTORECONTEXTGETSELECTCRLFAILED);
        }

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

        PKIX_INCREF(crlList);
        colCertStoreContext->crlList = crlList;

cleanup:
        if (dir) {
                PKIX_COLLECTIONCERTSTORECONTEXT_DEBUG
                        ("\t\t Calling PR_CloseDir.\n");
                PR_CloseDir(dir);
        }

        PKIX_FREE(pathName);
        PKIX_FREE(dirName);

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(crlList);
        }

        PKIX_DECREF(crlItem);
        PKIX_DECREF(crlList);

        PKIX_RETURN(COLLECTIONCERTSTORECONTEXT);
}
Exemplo n.º 16
0
/*
 * FUNCTION: PKIX_List_DeleteItem (see comments in pkix_util.h)
 */
PKIX_Error *
PKIX_List_DeleteItem(
        PKIX_List *list,
        PKIX_UInt32 index,
        void *plContext)
{
        PKIX_List *element = NULL;
        PKIX_List *prevElement = NULL;
        PKIX_List *nextElement = NULL;

        PKIX_ENTER(LIST, "PKIX_List_DeleteItem");
        PKIX_NULLCHECK_ONE(list);

        if (list->immutable){
                PKIX_ERROR(PKIX_OPERATIONNOTPERMITTEDONIMMUTABLELIST);
        }

        if (!list->isHeader){
                PKIX_ERROR(PKIX_INPUTLISTMUSTBEHEADER);
        }

        PKIX_CHECK(pkix_List_GetElement(list, index, &element, plContext),
                    PKIX_LISTGETELEMENTFAILED);

        /* DecRef old contents */
        PKIX_DECREF(element->item);

        nextElement = element->next;

        if (nextElement != NULL) {
                /* If the next element exists, splice it out. */

                /* Don't need to change ref counts for targets of next */
                element->item = nextElement->item;
                nextElement->item = NULL;

                /* Don't need to change ref counts for targets of next */
                element->next = nextElement->next;
                nextElement->next = NULL;

                PKIX_DECREF(nextElement);

        } else { /* The element is at the tail of the list */
                if (index != 0) {
                        PKIX_CHECK(pkix_List_GetElement
                                    (list, index-1, &prevElement, plContext),
                                    PKIX_LISTGETELEMENTFAILED);
                } else if (index == 0){ /* prevElement must be header */
                        prevElement = list;
                }
                prevElement->next = NULL;

                /* Delete the element */
                PKIX_DECREF(element);
        }

        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
                    ((PKIX_PL_Object *)list, plContext),
                    PKIX_OBJECTINVALIDATECACHEFAILED);

        list->length = list->length - 1;

cleanup:

        PKIX_RETURN(LIST);
}
Exemplo n.º 17
0
/*
 * FUNCTION: PKIX_PL_Object_DecRef (see comments in pkix_pl_system.h)
 */
PKIX_Error *
PKIX_PL_Object_DecRef(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_Int32 refCount = 0;
        PKIX_PL_Object *objectHeader = NULL;
        PKIX_PL_NssContext *context = NULL;
            
        PKIX_ENTER(OBJECT, "PKIX_PL_Object_DecRef");
        PKIX_NULLCHECK_ONE(object);

        if (plContext){
                /* 
                 * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't
                 * have a header therefore we cannot verify its type before
                 * casting.
                 */  
                context = (PKIX_PL_NssContext *) plContext;
                if (context->arena != NULL) {
                        goto cleanup;
                }
        }

        if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) {
                goto cleanup;
        }

        /* Shift pointer from user data to object header */
        PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
                    PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);

        refCount = PR_ATOMIC_DECREMENT(&objectHeader->references);

        if (refCount == 0) {
            PKIX_PL_DestructorCallback destructor = NULL;
            pkix_ClassTable_Entry *ctEntry = NULL;
            PKIX_UInt32 objType = objectHeader->type;
            
            /* first, special handling for system types */
            if (objType >= PKIX_NUMTYPES){
#ifdef PKIX_USER_OBJECT_TYPE
                PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
                PR_Lock(classTableLock);
                pkixErrorResult = pkix_pl_PrimHashTable_Lookup
                    (classTable,
                     (void *)&objType,
                     objType,
                     NULL,
                     (void **)&ctEntry,
                     plContext);
                PKIX_OBJECT_DEBUG
                    ("\tCalling PR_Unlock).\n");
                PR_Unlock(classTableLock);
                if (pkixErrorResult){
                    PKIX_ERROR_FATAL
                        (PKIX_ERRORINGETTINGDESTRUCTOR);
                }
                
                if (ctEntry != NULL){
                    destructor = ctEntry->destructor;
                }
#else
                PORT_Assert (0);
                pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
                pkixErrorClass = PKIX_FATAL_ERROR;
                goto cleanup;
#endif /* PKIX_USER_OBJECT_TYPE */
            } else {
                ctEntry = &systemClasses[objType];
                destructor = ctEntry->destructor;
            }
            
            if (destructor != NULL){
                /* Call destructor on user data if necessary */
                pkixErrorResult = destructor(object, plContext);
                if (pkixErrorResult) {
                    pkixErrorClass = PKIX_FATAL_ERROR;
                    PKIX_DoAddError(stdVarsPtr, pkixErrorResult, plContext);
                    pkixErrorResult = NULL;
                }
            }
            
            /* Atomically decrement object counter */
            PR_ATOMIC_DECREMENT(&ctEntry->objCounter);
            
            /* pkix_pl_Object_Destroy assumes the lock is held */
            /* It will call unlock and destroy the object */
            pkixErrorResult = pkix_pl_Object_Destroy(object, plContext);
            goto cleanup;
        }

        if (refCount < 0) {
            PKIX_ERROR_ALLOC_ERROR();
        }

cleanup:

        PKIX_RETURN(OBJECT);
}
Exemplo n.º 18
0
/*
 * FUNCTION: PKIX_PL_Object_Alloc (see comments in pkix_pl_system.h)
 */
PKIX_Error *
PKIX_PL_Object_Alloc(
        PKIX_TYPENUM objType,
        PKIX_UInt32 size,
        PKIX_PL_Object **pObject,
        void *plContext)
{
        PKIX_PL_Object *object = NULL;
        pkix_ClassTable_Entry *ctEntry = NULL;

        PKIX_ENTER(OBJECT, "PKIX_PL_Object_Alloc");
        PKIX_NULLCHECK_ONE(pObject);

        /*
         * We need to ensure that user-defined types have been registered.
         * All system types have already been registered by PKIX_PL_Initialize.
         */

        if (objType >= PKIX_NUMTYPES) { /* i.e. if this is a user-defined type */
#ifdef PKIX_USER_OBJECT_TYPE
                PKIX_Boolean typeRegistered;
                PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
                PR_Lock(classTableLock);
                pkixErrorResult = pkix_pl_PrimHashTable_Lookup
                        (classTable,
                        (void *)&objType,
                        objType,
                        NULL,
                        (void **)&ctEntry,
                        plContext);
                PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
                PR_Unlock(classTableLock);
                if (pkixErrorResult){
                        PKIX_ERROR_FATAL(PKIX_COULDNOTLOOKUPINHASHTABLE);
                }

                typeRegistered = (ctEntry != NULL);

                if (!typeRegistered) {
                        PKIX_ERROR_FATAL(PKIX_UNKNOWNTYPEARGUMENT);
                }
#else
                PORT_Assert (0);
                pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
                pkixErrorClass = PKIX_FATAL_ERROR;
                goto cleanup;
#endif /* PKIX_USER_OBJECT_TYPE */
        } else {
                ctEntry = &systemClasses[objType];
        }
        
        PORT_Assert(size == ctEntry->typeObjectSize);

        /* Allocate space for the object header and the requested size */
#ifdef PKIX_OBJECT_LEAK_TEST       
        PKIX_CHECK(PKIX_PL_Calloc
                    (1,
                    ((PKIX_UInt32)sizeof (PKIX_PL_Object))+size,
                    (void **)&object,
                    plContext),
                    PKIX_MALLOCFAILED);
#else
        PKIX_CHECK(PKIX_PL_Malloc
                    (((PKIX_UInt32)sizeof (PKIX_PL_Object))+size,
                    (void **)&object,
                    plContext),
                    PKIX_MALLOCFAILED);
#endif /* PKIX_OBJECT_LEAK_TEST */

        /* Initialize all object fields */
        object->magicHeader = PKIX_MAGIC_HEADER;
        object->type = objType;
        object->references = 1; /* Default to a single reference */
        object->stringRep = NULL;
        object->hashcode = 0;
        object->hashcodeCached = 0;

        /* Cannot use PKIX_PL_Mutex because it depends on Object */
        /* Using NSPR Locks instead */
        PKIX_OBJECT_DEBUG("\tCalling PR_NewLock).\n");
        object->lock = PR_NewLock();
        if (object->lock == NULL) {
                PKIX_ERROR_ALLOC_ERROR();
        }

        PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");


        /* Return a pointer to the user data. Need to offset by object size */
        *pObject = object + 1;
        object = NULL;

        /* Atomically increment object counter */
        PR_ATOMIC_INCREMENT(&ctEntry->objCounter);

cleanup:

        PKIX_FREE(object);

        PKIX_RETURN(OBJECT);
}
Exemplo n.º 19
0
/*
 * FUNCTION: PKIX_PL_Date_Create_UTCTime (see comments in pkix_pl_pki.h)
 */
PKIX_Error *
PKIX_PL_Date_Create_UTCTime(
        PKIX_PL_String *stringRep,
        PKIX_PL_Date **pDate,
        void *plContext)
{
        PKIX_PL_Date *date = NULL;
        char *asciiString = NULL;
        PKIX_UInt32 escAsciiLength;
        SECItem nssTime;
        SECStatus rv;
        PRTime time;

        PKIX_ENTER(DATE, "PKIX_PL_Date_Create_UTCTime");
        PKIX_NULLCHECK_ONE(pDate);

        if (stringRep == NULL){
                PKIX_DATE_DEBUG("\t\tCalling PR_Now).\n");
                time = PR_Now();
        } else {
                /* convert the input PKIX_PL_String to PKIX_ESCASCII */
                PKIX_CHECK(PKIX_PL_String_GetEncoded
                            (stringRep,
                            PKIX_ESCASCII,
                            (void **)&asciiString,
                            &escAsciiLength,
                            plContext),
                            PKIX_STRINGGETENCODEDFAILED);

                PKIX_DATE_DEBUG("\t\tCalling DER_AsciiToTime).\n");
                /* DER_AsciiToTime only supports UTCTime (2-digit years) */
                rv = DER_AsciiToTime(&time, asciiString);
                if (rv != SECSuccess){
                        PKIX_ERROR(PKIX_DERASCIITOTIMEFAILED);
                }
        }

        PKIX_DATE_DEBUG("\t\tCalling DER_TimeToUTCTime).\n");
        rv = DER_TimeToUTCTime(&nssTime, time);
        if (rv != SECSuccess){
                PKIX_ERROR(PKIX_DERTIMETOUTCTIMEFAILED);
        }

        /* create a PKIX_PL_Date object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_DATE_TYPE,
                    sizeof (PKIX_PL_Date),
                    (PKIX_PL_Object **)&date,
                    plContext),
                    PKIX_COULDNOTCREATEOBJECT);

        /* populate the nssTime field */
        date->nssTime = nssTime;

        *pDate = date;

cleanup:

        PKIX_FREE(asciiString);

        if (PKIX_ERROR_RECEIVED){
                PR_Free(nssTime.data);
        }

        PKIX_RETURN(DATE);
}
Exemplo n.º 20
0
/*
 * FUNCTION: pkix_pl_GeneralName_Hashcode
 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
 */
static PKIX_Error *
pkix_pl_GeneralName_Hashcode(
        PKIX_PL_Object *object,
        PKIX_UInt32 *pHashcode,
        void *plContext)
{
        PKIX_PL_GeneralName *name = NULL;
        PKIX_UInt32 firstHash, secondHash, nameHash;

        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Hashcode");
        PKIX_NULLCHECK_TWO(object, pHashcode);

        PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
                    PKIX_OBJECTNOTGENERALNAME);

        name = (PKIX_PL_GeneralName *)object;

        switch (name->type) {
        case certRFC822Name:
        case certDNSName:
        case certX400Address:
        case certEDIPartyName:
        case certURI:
        case certIPAddress:
                PKIX_NULLCHECK_ONE(name->other);
                PKIX_CHECK(pkix_hash
                            ((const unsigned char *)
                            name->other->data,
                            name->other->len,
                            &nameHash,
                            plContext),
                            PKIX_HASHFAILED);
                break;
        case certRegisterID:
                PKIX_CHECK(PKIX_PL_Object_Hashcode
                            ((PKIX_PL_Object *)name->oid,
                            &nameHash,
                            plContext),
                            PKIX_OIDHASHCODEFAILED);
                break;
        case certOtherName:
                PKIX_NULLCHECK_ONE(name->OthName);
                PKIX_CHECK(pkix_hash
                            ((const unsigned char *)
                            name->OthName->oid.data,
                            name->OthName->oid.len,
                            &firstHash,
                            plContext),
                            PKIX_HASHFAILED);

                PKIX_CHECK(pkix_hash
                            ((const unsigned char *)
                            name->OthName->name.data,
                            name->OthName->name.len,
                            &secondHash,
                            plContext),
                            PKIX_HASHFAILED);

                nameHash = firstHash + secondHash;
                break;
        case certDirectoryName:
                PKIX_CHECK(PKIX_PL_Object_Hashcode
                            ((PKIX_PL_Object *)
                            name->directoryName,
                            &nameHash,
                            plContext),
                            PKIX_X500NAMEHASHCODEFAILED);
                break;
        }

        *pHashcode = nameHash;

cleanup:

        PKIX_RETURN(GENERALNAME);

}
Exemplo n.º 21
0
/*
 * FUNCTION: pkix_pl_GeneralName_ToString_Helper
 * DESCRIPTION:
 *
 *  Helper function that creates a string representation of the GeneralName
 *  pointed to by "name" and stores it at "pString" Different mechanisms are
 *  used to create the string, depending on the type of the GeneralName.
 *
 * PARAMETERS
 *  "name"
 *      Address of GeneralName whose string representation is desired.
 *      Must be non-NULL.
 *  "pString"
 *      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 GeneralName 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_GeneralName_ToString_Helper(
        PKIX_PL_GeneralName *name,
        PKIX_PL_String **pString,
        void *plContext)
{
        PKIX_PL_X500Name *pkixDN = NULL;
        PKIX_PL_OID *pkixOID = NULL;
        char *x400AsciiName = NULL;
        char *ediPartyName = NULL;
        char *asciiName = NULL;

        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_ToString_Helper");
        PKIX_NULLCHECK_TWO(name, pString);

        switch (name->type) {
        case certRFC822Name:
        case certDNSName:
        case certURI:
                /*
                 * Note that we can't use PKIX_ESCASCII here because
                 * name->other->data is not guaranteed to be null-terminated.
                 */

                PKIX_NULLCHECK_ONE(name->other);

                PKIX_CHECK(PKIX_PL_String_Create(PKIX_UTF8,
                                                (name->other)->data,
                                                (name->other)->len,
                                                pString,
                                                plContext),
                            PKIX_STRINGCREATEFAILED);
                break;
        case certEDIPartyName:
                /* XXX print out the actual bytes */
                ediPartyName = "EDIPartyName: <DER-encoded value>";
                PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
                                                ediPartyName,
                                                0,
                                                pString,
                                                plContext),
                            PKIX_STRINGCREATEFAILED);
                break;
        case certX400Address:
                /* XXX print out the actual bytes */
                x400AsciiName = "X400Address: <DER-encoded value>";
                PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
                                                x400AsciiName,
                                                0,
                                                pString,
                                                plContext),
                            PKIX_STRINGCREATEFAILED);
                break;
        case certIPAddress:
                PKIX_CHECK(pkix_pl_ipAddrBytes2Ascii
                            (name->other, &asciiName, plContext),
                            PKIX_IPADDRBYTES2ASCIIFAILED);

                PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
                                                asciiName,
                                                0,
                                                pString,
                                                plContext),
                            PKIX_STRINGCREATEFAILED);
                break;
        case certOtherName:
                PKIX_NULLCHECK_ONE(name->OthName);

                /* we only print type-id - don't know how to print value */
                /* XXX print out the bytes of the value */
                PKIX_CHECK(pkix_pl_oidBytes2Ascii
                            (&name->OthName->oid, &asciiName, plContext),
                            PKIX_OIDBYTES2ASCIIFAILED);

                PKIX_CHECK(PKIX_PL_String_Create
                            (PKIX_ESCASCII,
                            asciiName,
                            0,
                            pString,
                            plContext),
                            PKIX_STRINGCREATEFAILED);
                break;
        case certRegisterID:
                pkixOID = name->oid;
                PKIX_CHECK(PKIX_PL_Object_ToString
                            ((PKIX_PL_Object *)pkixOID, pString, plContext),
                            PKIX_OIDTOSTRINGFAILED);
                break;
        case certDirectoryName:
                pkixDN = name->directoryName;
                PKIX_CHECK(PKIX_PL_Object_ToString
                            ((PKIX_PL_Object *)pkixDN, pString, plContext),
                            PKIX_X500NAMETOSTRINGFAILED);
                break;
        default:
                PKIX_ERROR
                        (PKIX_TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED);
        }

cleanup:

        PKIX_FREE(asciiName);

        PKIX_RETURN(GENERALNAME);
}
Exemplo n.º 22
0
/*
 * FUNCTION: pkix_List_MergeLists
 * DESCRIPTION:
 *
 *  Creates a new list consisting of the items from "firstList", followed by
 *  the items on "secondList", returns the new list at "pMergedList". If
 *  both input lists are NULL or empty, the result is an empty list. If an error
 *  occurs, the result is NULL.
 *
 * PARAMETERS:
 *  "firstList"
 *      Address of list to be merged from. May be NULL or empty.
 *  "secondList"
 *      Address of list to be merged from. May be NULL or empty.
 *  "pMergedList"
 *      Address where returned object is stored.
 *  "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 List Error if the functions fails in a non-fatal way
 *  Returns a Fatal Error if the function fails in an unrecoverable way
 */
PKIX_Error *
pkix_List_MergeLists(
        PKIX_List *firstList,
        PKIX_List *secondList,
        PKIX_List **pMergedList,
        void *plContext)
{
        PKIX_List *list = NULL;
        PKIX_PL_Object *item = NULL;
        PKIX_UInt32 numItems = 0;
        PKIX_UInt32 i;

        PKIX_ENTER(LIST, "pkix_List_MergeLists");
        PKIX_NULLCHECK_ONE(pMergedList);

        *pMergedList = NULL;

        PKIX_CHECK(PKIX_List_Create(&list, plContext),
                    PKIX_LISTCREATEFAILED);

        if (firstList != NULL) {

                PKIX_CHECK(PKIX_List_GetLength(firstList, &numItems, plContext),
                    PKIX_LISTGETLENGTHFAILED);
        }

        for (i = 0; i < numItems; i++) {

                PKIX_CHECK(PKIX_List_GetItem(firstList, i, &item, plContext),
                        PKIX_LISTGETITEMFAILED);

                PKIX_CHECK(PKIX_List_AppendItem(list, item, plContext),
                        PKIX_LISTAPPENDITEMFAILED);

                PKIX_DECREF(item);
        }

        numItems = 0;
        if (secondList != NULL) {

                PKIX_CHECK(PKIX_List_GetLength
                        (secondList,
                        &numItems,
                        plContext),
                        PKIX_LISTGETLENGTHFAILED);

        }

        for (i = 0; i < numItems; i++) {

                PKIX_CHECK(PKIX_List_GetItem
                        (secondList, i, &item, plContext),
                        PKIX_LISTGETITEMFAILED);

                PKIX_CHECK(PKIX_List_AppendItem
                        (list, item, plContext), PKIX_LISTAPPENDITEMFAILED);

                PKIX_DECREF(item);
        }

        *pMergedList = list;
        list = NULL;

cleanup:
        PKIX_DECREF(list);
        PKIX_DECREF(item);
 
        PKIX_RETURN(LIST);
}
/*
 * FUNCTION: pkix_pl_OcspResponse_Create
 * DESCRIPTION:
 *
 *  This function transmits the OcspRequest pointed to by "request" and obtains
 *  an OcspResponse, which it stores at "pOcspResponse". If the HTTPClient
 *  supports non-blocking I/O this function may store a non-NULL value at
 *  "pNBIOContext" (the WOULDBLOCK condition). In that case the caller should
 *  make a subsequent call with the same value in "pNBIOContext" and
 *  "pOcspResponse" to resume the operation. Additional WOULDBLOCK returns may
 *  occur; the caller should persist until a return occurs with NULL stored at
 *  "pNBIOContext".
 *
 *  If a SEC_HttpClientFcn "responder" is supplied, it is used as the client
 *  to which the OCSP query is sent. If none is supplied, the default responder
 *  is used.
 *
 *  If an OcspResponse_VerifyCallback "verifyFcn" is supplied, it is used to
 *  verify the Cert received from the responder as the signer. If none is
 *  supplied, the default verification function is used.
 *
 *  The contents of "request" are ignored on calls subsequent to a WOULDBLOCK
 *  return, and the caller is permitted to supply NULL.
 *
 * PARAMETERS
 *  "request"
 *      Address of the OcspRequest for which a response is desired.
 *  "responder"
 *      Address, if non-NULL, of the SEC_HttpClientFcn to be sent the OCSP
 *      query.
 *  "verifyFcn"
 *      Address, if non-NULL, of the OcspResponse_VerifyCallback function to be
 *      used to verify the Cert of the OCSP responder.
 *  "pNBIOContext"
 *      Address at which platform-dependent information is stored for handling
 *      of non-blocking I/O. Must be non-NULL.
 *  "pOcspResponse"
 *      The address where the created OcspResponse 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 OcspResponse 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_OcspResponse_Create(
        PKIX_PL_OcspRequest *request,
        void *responder,
        PKIX_PL_OcspResponse_VerifyCallback verifyFcn,
        void **pNBIOContext,
        PKIX_PL_OcspResponse **pResponse,
        void *plContext)
{
        void *nbioContext = NULL;
        PKIX_PL_OcspResponse *ocspResponse = NULL;
        const SEC_HttpClientFcn *httpClient = NULL;
        const SEC_HttpClientFcnV1 *hcv1 = NULL;
        SECStatus rv = SECFailure;
        char *location = NULL;
        char *hostname = NULL;
        char *path = NULL;
        PRUint16 port = 0;
        SEC_HTTP_SERVER_SESSION serverSession = NULL;
        SEC_HTTP_REQUEST_SESSION requestSession = NULL;
        SECItem *encodedRequest = NULL;
        PRUint16 responseCode = 0;
        char *responseData = NULL;
        PRUint32 responseDataLen = 0;

        PKIX_ENTER(OCSPRESPONSE, "pkix_pl_OcspResponse_Create");
        PKIX_NULLCHECK_TWO(pNBIOContext, pResponse);

        nbioContext = *pNBIOContext;
        *pNBIOContext = NULL;

        if (nbioContext != NULL) {

                ocspResponse = *pResponse;
                PKIX_NULLCHECK_ONE(ocspResponse);

                httpClient = ocspResponse->httpClient;
                serverSession = ocspResponse->serverSession;
                requestSession = ocspResponse->requestSession;
                PKIX_NULLCHECK_THREE(httpClient, serverSession, requestSession);

        } else {

                PKIX_NULLCHECK_ONE(request);

                PKIX_CHECK(pkix_pl_OcspRequest_GetEncoded
                        (request, &encodedRequest, plContext),
                        PKIX_OCSPREQUESTGETENCODEDFAILED);

                /* prepare initial message to HTTPClient */

                /* Is there a default responder and is it enabled? */
                if (!responder) {
                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE,
                                responder,
                                (void *)SEC_GetRegisteredHttpClient,
                                ());
                }

                httpClient = (const SEC_HttpClientFcn *)responder;

                if (httpClient && (httpClient->version == 1)) {

                        hcv1 = &(httpClient->fcnTable.ftable1);

                        PKIX_CHECK(pkix_pl_OcspRequest_GetLocation
                                (request, &location, plContext),
                                PKIX_OCSPREQUESTGETLOCATIONFAILED);

                        /* parse location -> hostname, port, path */    
                        PKIX_PL_NSSCALLRV(OCSPRESPONSE, rv, CERT_ParseURL,
                                (location, &hostname, &port, &path));

                        if ((hostname == NULL) || (path == NULL)) {
                                PKIX_ERROR(PKIX_URLPARSINGFAILED);
                        }

                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE,
                                rv,
                                hcv1->createSessionFcn,
                                (hostname, port, &serverSession));

                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE, rv, hcv1->createFcn,
                                (serverSession,
                                "http",
                                path,
                                "POST",
                                PR_TicksPerSecond() * 60,
                                &requestSession));

                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        PKIX_PL_NSSCALLRV
                                (OCSPRESPONSE, rv, hcv1->setPostDataFcn,
                                (requestSession,
                                (char *)encodedRequest->data,
                                encodedRequest->len,
                                "application/ocsp-request"));

                        if (rv != SECSuccess) {
                                PKIX_ERROR(PKIX_OCSPSERVERERROR);
                        }       

                        /* create a PKIX_PL_OcspResponse object */
                        PKIX_CHECK(PKIX_PL_Object_Alloc
                                    (PKIX_OCSPRESPONSE_TYPE,
                                    sizeof (PKIX_PL_OcspResponse),
                                    (PKIX_PL_Object **)&ocspResponse,
                                    plContext),
                                    PKIX_COULDNOTCREATEOBJECT);

                        PKIX_INCREF(request);
                        ocspResponse->request = request;
                        ocspResponse->httpClient = httpClient;
                        ocspResponse->serverSession = serverSession;
                        ocspResponse->requestSession = requestSession;
                        ocspResponse->verifyFcn = verifyFcn;
                        ocspResponse->handle = CERT_GetDefaultCertDB();
                        ocspResponse->encodedResponse = NULL;
                        ocspResponse->arena = NULL;
                        ocspResponse->producedAt = 0;
                        ocspResponse->producedAtDate = NULL;
                        ocspResponse->pkixSignerCert = NULL;
                        ocspResponse->nssOCSPResponse = NULL;
                        ocspResponse->signerCert = NULL;
                }
        }
/*
 * FUNCTION: PKIX_RevocationChecker_CreateAndAddMethod
 */
PKIX_Error *
PKIX_RevocationChecker_CreateAndAddMethod(
    PKIX_RevocationChecker *revChecker,
    PKIX_ProcessingParams *params,
    PKIX_RevocationMethodType methodType,
    PKIX_UInt32 flags,
    PKIX_UInt32 priority,
    PKIX_PL_VerifyCallback verificationFn,
    PKIX_Boolean isLeafMethod,
    void *plContext)
{
    PKIX_List **methodList = NULL;
    PKIX_List  *unsortedList = NULL;
    PKIX_List  *certStores = NULL;
    pkix_RevocationMethod *method = NULL;
    pkix_LocalRevocationCheckFn *localRevChecker = NULL;
    pkix_ExternalRevocationCheckFn *externRevChecker = NULL;
    PKIX_UInt32 miFlags;
    
    PKIX_ENTER(REVOCATIONCHECKER, "PKIX_RevocationChecker_CreateAndAddMethod");
    PKIX_NULLCHECK_ONE(revChecker);

    /* If the caller has said "Either one is sufficient, then don't let the 
     * absence of any one method's info lead to an overall failure.
     */
    miFlags = isLeafMethod ? revChecker->leafMethodListFlags 
	                   : revChecker->chainMethodListFlags;
    if (miFlags & PKIX_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE)
	flags &= ~PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;

    switch (methodType) {
    case PKIX_RevocationMethod_CRL:
        localRevChecker = pkix_CrlChecker_CheckLocal;
        externRevChecker = pkix_CrlChecker_CheckExternal;
        PKIX_CHECK(
            PKIX_ProcessingParams_GetCertStores(params, &certStores,
                                                plContext),
            PKIX_PROCESSINGPARAMSGETCERTSTORESFAILED);
        PKIX_CHECK(
            pkix_CrlChecker_Create(methodType, flags, priority,
                                   localRevChecker, externRevChecker,
                                   certStores, verificationFn,
                                   &method,
                                   plContext),
            PKIX_COULDNOTCREATECRLCHECKEROBJECT);
        break;
    case PKIX_RevocationMethod_OCSP:
        localRevChecker = pkix_OcspChecker_CheckLocal;
        externRevChecker = pkix_OcspChecker_CheckExternal;
        PKIX_CHECK(
            pkix_OcspChecker_Create(methodType, flags, priority,
                                    localRevChecker, externRevChecker,
                                    verificationFn,
                                    &method,
                                    plContext),
            PKIX_COULDNOTCREATEOCSPCHECKEROBJECT);
        break;
    default:
        PKIX_ERROR(PKIX_INVALIDREVOCATIONMETHOD);
    }

    if (isLeafMethod) {
        methodList = &revChecker->leafMethodList;
    } else {
        methodList = &revChecker->chainMethodList;
    }
    
    if (*methodList == NULL) {
        PKIX_CHECK(
            PKIX_List_Create(methodList, plContext),
            PKIX_LISTCREATEFAILED);
    }
    unsortedList = *methodList;
    PKIX_CHECK(
        PKIX_List_AppendItem(unsortedList, (PKIX_PL_Object*)method, plContext),
        PKIX_LISTAPPENDITEMFAILED);
    PKIX_CHECK(
        pkix_List_BubbleSort(unsortedList, 
                             pkix_RevocationChecker_SortComparator,
                             methodList, plContext),
        PKIX_LISTBUBBLESORTFAILED);

cleanup:
    PKIX_DECREF(method);
    PKIX_DECREF(unsortedList);
    PKIX_DECREF(certStores);
    
    PKIX_RETURN(REVOCATIONCHECKER);
}
Exemplo n.º 25
0
/*
 * FUNCTION: pkix_pl_HttpCertStore_ProcessCrlResponse
 * DESCRIPTION:
 *
 *  This function verifies that the response code pointed to by "responseCode"
 *  and the content type pointed to by "responseContentType" are as expected,
 *  and then decodes the data pointed to by "responseData", of length
 *  "responseDataLen", into a List of Crls, possibly empty, which is returned
 *  at "pCrlList".
 *
 * PARAMETERS:
 *  "responseCode"
 *      The value of the HTTP response code.
 *  "responseContentType"
 *      The address of the Content-type string. Must be non-NULL.
 *  "responseData"
 *      The address of the message data. Must be non-NULL.
 *  "responseDataLen"
 *      The length of the message data.
 *  "pCrlList"
 *      The address of the List that is created. 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_pl_HttpCertStore_ProcessCrlResponse(
        PRUint16 responseCode,
        const char *responseContentType,
        const char *responseData,
        PRUint32 responseDataLen,
        PKIX_List **pCrlList,
        void *plContext)
{
        PRArenaPool *arena = NULL;
        SECItem *encodedResponse = NULL;
        PRInt16 compareVal = 0;
        PKIX_List *crls = NULL;

        PKIX_ENTER
                (HTTPCERTSTORECONTEXT,
                "pkix_pl_HttpCertStore_ProcessCrlResponse");
        PKIX_NULLCHECK_ONE(pCrlList);

        if (responseCode != 200) {
                PKIX_ERROR(PKIX_BADHTTPRESPONSE);
        }

        /* check that response type is application/pkix-crl */
        if (responseContentType == NULL) {
                PKIX_ERROR(PKIX_NOCONTENTTYPEINHTTPRESPONSE);
        }

        compareVal = PORT_Strcasecmp(responseContentType,
                                     "application/pkix-crl");
        if (compareVal != 0) {
                PKIX_ERROR(PKIX_CONTENTTYPENOTPKIXCRL);
        }

        /* Make a SECItem of the response data */
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena == NULL) {
                PKIX_ERROR(PKIX_OUTOFMEMORY);
        }

        if (responseData == NULL) {
                PKIX_ERROR(PKIX_NORESPONSEDATAINHTTPRESPONSE);
        }

        encodedResponse = SECITEM_AllocItem(arena, NULL, responseDataLen);
        if (encodedResponse == NULL) {
                PKIX_ERROR(PKIX_OUTOFMEMORY);
        }

        PORT_Memcpy(encodedResponse->data, responseData, responseDataLen);

        PKIX_CHECK(PKIX_List_Create(&crls, plContext),
                PKIX_LISTCREATEFAILED);

        PKIX_CHECK(pkix_pl_CRL_CreateToList
                (encodedResponse, crls, plContext),
                PKIX_CRLCREATETOLISTFAILED);

        *pCrlList = crls;

cleanup:
        if (PKIX_ERROR_RECEIVED) {
                PKIX_DECREF(crls);
        }

        if (arena != NULL) {
                PKIX_PL_NSSCALL(CERTSTORE, PORT_FreeArena, (arena, PR_FALSE));
        }


        PKIX_RETURN(HTTPCERTSTORECONTEXT);
}