Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  pkix_pl_crl.c   Sprache: C

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * pkix_pl_crl.c
 *
 * CRL Function Definitions
 *
 */


#include "pkix_pl_crl.h"
#include "certxutl.h"

extern PKIX_PL_HashTable *cachedCrlSigTable;

/* --Private-CRL-Functions------------------------------------- */

/*
 * 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_CRL_GetCRLNumber (see comments in pkix_pl_pki.h)
 */

PKIX_Error *
PKIX_PL_CRL_GetCRLNumber(
        PKIX_PL_CRL *crl,
        PKIX_PL_BigInt **pCrlNumber,
        void *plContext)
{
        PKIX_PL_BigInt *crlNumber = NULL;
        SECItem nssCrlNumber;
        PLArenaPool *arena = NULL;
        SECStatus status;
        PKIX_UInt32 length = 0;
        char *bytes = NULL;

        PKIX_ENTER(CRL, "PKIX_PL_CRL_GetCRLNumber");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pCrlNumber);

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

        if (!crl->crlNumberAbsent && crl->crlNumber == NULL) {

            PKIX_OBJECT_LOCK(crl);

            if (!crl->crlNumberAbsent && crl->crlNumber == NULL) {

                nssCrlNumber.type = 0;
                nssCrlNumber.len = 0;
                nssCrlNumber.data = NULL;

                PKIX_CRL_DEBUG("\t\tCalling PORT_NewArena).\n");
                arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                if (arena == NULL) {
                        PKIX_ERROR(PKIX_OUTOFMEMORY);
                }

                PKIX_CRL_DEBUG("\t\tCalling CERT_FindCRLNumberExten\n");
                status = CERT_FindCRLNumberExten
                        (arena, &crl->nssSignedCrl->crl, &nssCrlNumber);

                if (status == SECSuccess) {
                        /* Get data in bytes then convert to bigint */
                        length = nssCrlNumber.len;
                        bytes = (char *)nssCrlNumber.data;

                        PKIX_CHECK(pkix_pl_BigInt_CreateWithBytes
                                    (bytes, length, &crlNumber, plContext),
                                    PKIX_BIGINTCREATEWITHBYTESFAILED);

                        /* arena release does the job 
                        PKIX_CRL_DEBUG("\t\tCalling SECITEM_FreeItem\n");
                        SECITEM_FreeItem(&nssCrlNumber, PKIX_FALSE);
                        */

                        crl->crlNumber = crlNumber;

                } else {

                        crl->crlNumberAbsent = PKIX_TRUE;
                }
            }

            PKIX_OBJECT_UNLOCK(crl);

        }

        PKIX_INCREF(crl->crlNumber);

        *pCrlNumber = crl->crlNumber;

cleanup:

        if (arena){
                PKIX_CRL_DEBUG("\t\tCalling PORT_FreeArena).\n");
                PORT_FreeArena(arena, PR_FALSE);
        }

        PKIX_RETURN(CRL);
}

/*
 * 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)
{
        PKIX_PL_OID *signatureAlgId = 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){
                    CERTCrl *nssCrl = &(crl->nssSignedCrl->crl);
                    SECAlgorithmID *algorithm = &nssCrl->signatureAlg;
                    SECItem *algBytes = &algorithm->algorithm;

                    if (!algBytes->data || !algBytes->len) {
                        PKIX_ERROR(PKIX_OIDBYTESLENGTH0);
                    }
                    PKIX_CHECK(PKIX_PL_OID_CreateBySECItem
                               (algBytes, &signatureAlgId, plContext),
                               PKIX_OIDCREATEFAILED);
                    
                    /* save a cached copy in case it is asked for again */
                    crl->signatureAlgId = signatureAlgId;
                    signatureAlgId = NULL;
                }
                PKIX_OBJECT_UNLOCK(crl);
        }
        PKIX_INCREF(crl->signatureAlgId);
        *pSignatureAlgId = crl->signatureAlgId;
cleanup:
        PKIX_DECREF(signatureAlgId);
        PKIX_RETURN(CRL);
}

/*
 * 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);
}

/*
 * FUNCTION: pkix_pl_CRL_Destroy
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
 */

static PKIX_Error *
pkix_pl_CRL_Destroy(
        PKIX_PL_Object *object,
        void *plContext)
{
        PKIX_PL_CRL *crl = NULL;

        PKIX_ENTER(CRL, "pkix_pl_CRL_Destroy");
        PKIX_NULLCHECK_ONE(object);

        PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
                    PKIX_OBJECTNOTCRL);

        crl = (PKIX_PL_CRL*)object;

        PKIX_CRL_DEBUG("\t\tCalling CERT_DestroyCrl\n");
        if (crl->nssSignedCrl) {
            CERT_DestroyCrl(crl->nssSignedCrl);
        }
        if (crl->adoptedDerCrl) {
            SECITEM_FreeItem(crl->adoptedDerCrl, PR_TRUE);
        }
        crl->nssSignedCrl = NULL;
        crl->adoptedDerCrl = NULL;
        crl->crlNumberAbsent = PKIX_FALSE;

        PKIX_DECREF(crl->issuer);
        PKIX_DECREF(crl->signatureAlgId);
        PKIX_DECREF(crl->crlNumber);
        PKIX_DECREF(crl->crlEntryList);
        PKIX_DECREF(crl->critExtOids);
        if (crl->derGenName) {
            SECITEM_FreeItem(crl->derGenName, PR_TRUE);
        }

cleanup:

        PKIX_RETURN(CRL);
}

/*
 * FUNCTION: pkix_pl_CRL_ToString_Helper
 * DESCRIPTION:
 *
 *  Helper function that creates a string representation of the CRL pointed
 *  to by "crl" and stores it at "pString".
 *
 * PARAMETERS
 *  "crl"
 *      Address of CRL 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 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_ToString_Helper(
        PKIX_PL_CRL *crl,
        PKIX_PL_String **pString,
        void *plContext)
{
        char *asciiFormat = NULL;
        PKIX_UInt32 crlVersion = 0;
        PKIX_PL_X500Name *crlIssuer = NULL;
        PKIX_PL_OID *nssSignatureAlgId = NULL;
        PKIX_PL_BigInt *crlNumber = NULL;
        PKIX_List *crlEntryList = NULL;
        PKIX_List *critExtOIDs = NULL;
        PKIX_PL_String *formatString = NULL;
        PKIX_PL_String *crlIssuerString = NULL;
        PKIX_PL_String *lastUpdateString = NULL;
        PKIX_PL_String *nextUpdateString = NULL;
        PKIX_PL_String *nssSignatureAlgIdString = NULL;
        PKIX_PL_String *crlNumberString = NULL;
        PKIX_PL_String *crlEntryListString = NULL;
        PKIX_PL_String *critExtOIDsString = NULL;
        PKIX_PL_String *crlString = NULL;

        PKIX_ENTER(CRL, "pkix_pl_CRL_ToString_Helper");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pString);

        asciiFormat =
                "[\n"
                "\tVersion: v%d\n"
                "\tIssuer: %s\n"
                "\tUpdate: [Last: %s\n"
                "\t Next: %s]\n"
                "\tSignatureAlgId: %s\n"
                "\tCRL Number : %s\n"
                "\n"
                "\tEntry List: %s\n"
                "\n"
                "\tCritExtOIDs: %s\n"
                "]\n";

        PKIX_CHECK(PKIX_PL_String_Create
                    (PKIX_ESCASCII,
                    asciiFormat,
                    0,
                    &formatString,
                    plContext),
                    PKIX_STRINGCREATEFAILED);

        /* Version */
        PKIX_CHECK(pkix_pl_CRL_GetVersion(crl, &crlVersion, plContext),
                    PKIX_CRLGETVERSIONFAILED);

        /* Issuer */
        PKIX_CHECK(PKIX_PL_CRL_GetIssuer(crl, &crlIssuer, plContext),
                    PKIX_CRLGETISSUERFAILED);

        PKIX_CHECK(PKIX_PL_Object_ToString
                    ((PKIX_PL_Object *)crlIssuer, &crlIssuerString, plContext),
                    PKIX_X500NAMETOSTRINGFAILED);

        /* This update - No Date object created, use nss data directly */
        PKIX_CHECK(pkix_pl_Date_ToString_Helper
                    (&(crl->nssSignedCrl->crl.lastUpdate),
                    &lastUpdateString,
                    plContext),
                    PKIX_DATETOSTRINGHELPERFAILED);

        /* Next update - No Date object created, use nss data directly */
        PKIX_CHECK(pkix_pl_Date_ToString_Helper
                    (&(crl->nssSignedCrl->crl.nextUpdate),
                    &nextUpdateString,
                    plContext),
                    PKIX_DATETOSTRINGHELPERFAILED);

        /* Signature Algorithm Id */
        PKIX_CHECK(pkix_pl_CRL_GetSignatureAlgId
                    (crl, &nssSignatureAlgId, plContext),
                    PKIX_CRLGETSIGNATUREALGIDFAILED);

        PKIX_CHECK(PKIX_PL_Object_ToString
                    ((PKIX_PL_Object *)nssSignatureAlgId,
                    &nssSignatureAlgIdString,
                    plContext),
                    PKIX_OIDTOSTRINGFAILED);

        /* CRL Number */
        PKIX_CHECK(PKIX_PL_CRL_GetCRLNumber
                    (crl, &crlNumber, plContext),
                    PKIX_CRLGETCRLNUMBERFAILED);

        PKIX_TOSTRING(crlNumber, &crlNumberString, plContext,
                    PKIX_BIGINTTOSTRINGFAILED);

        /* CRL Entries */
        PKIX_CHECK(pkix_pl_CRL_GetCRLEntries(crl, &crlEntryList, plContext),
                    PKIX_CRLGETCRLENTRIESFAILED);

        PKIX_TOSTRING(crlEntryList, &crlEntryListString, plContext,
                    PKIX_LISTTOSTRINGFAILED);

        /* CriticalExtensionOIDs */
        PKIX_CHECK(PKIX_PL_CRL_GetCriticalExtensionOIDs
                    (crl, &critExtOIDs, plContext),
                    PKIX_CRLGETCRITICALEXTENSIONOIDSFAILED);

        PKIX_TOSTRING(critExtOIDs, &critExtOIDsString, plContext,
                    PKIX_LISTTOSTRINGFAILED);

        PKIX_CHECK(PKIX_PL_Sprintf
                    (&crlString,
                    plContext,
                    formatString,
                    crlVersion + 1,
                    crlIssuerString,
                    lastUpdateString,
                    nextUpdateString,
                    nssSignatureAlgIdString,
                    crlNumberString,
                    crlEntryListString,
                    critExtOIDsString),
                    PKIX_SPRINTFFAILED);

        *pString = crlString;

cleanup:

        PKIX_DECREF(crlIssuer);
        PKIX_DECREF(nssSignatureAlgId);
        PKIX_DECREF(crlNumber);
        PKIX_DECREF(crlEntryList);
        PKIX_DECREF(critExtOIDs);
        PKIX_DECREF(crlIssuerString);
        PKIX_DECREF(lastUpdateString);
        PKIX_DECREF(nextUpdateString);
        PKIX_DECREF(nssSignatureAlgIdString);
        PKIX_DECREF(crlNumberString);
        PKIX_DECREF(crlEntryListString);
        PKIX_DECREF(critExtOIDsString);
        PKIX_DECREF(formatString);

        PKIX_RETURN(CRL);
}

/*
 * FUNCTION: pkix_pl_CRL_ToString
 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
 */

static PKIX_Error *
pkix_pl_CRL_ToString(
        PKIX_PL_Object *object,
        PKIX_PL_String **pString,
        void *plContext)
{
        PKIX_PL_String *crlString = NULL;
        PKIX_PL_CRL *crl = NULL;

        PKIX_ENTER(CRL, "pkix_pl_CRL_ToString");
        PKIX_NULLCHECK_TWO(object, pString);

        PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
                    PKIX_OBJECTNOTCRL);

        crl = (PKIX_PL_CRL *) object;

        PKIX_CHECK(pkix_pl_CRL_ToString_Helper(crl, &crlString, plContext),
                    PKIX_CRLTOSTRINGHELPERFAILED);

        *pString = crlString;

cleanup:

        PKIX_RETURN(CRL);
}

/*
 * FUNCTION: pkix_pl_CRL_Hashcode
 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
 */

static PKIX_Error *
pkix_pl_CRL_Hashcode(
        PKIX_PL_Object *object,
        PKIX_UInt32 *pHashcode,
        void *plContext)
{
        PKIX_PL_CRL *crl = NULL;
        PKIX_UInt32 certHash;
        SECItem *crlDer = NULL;
        
        PKIX_ENTER(CRL, "pkix_pl_CRL_Hashcode");
        PKIX_NULLCHECK_TWO(object, pHashcode);

        PKIX_CHECK(pkix_CheckType(object, PKIX_CRL_TYPE, plContext),
                    PKIX_OBJECTNOTCRL);

        crl = (PKIX_PL_CRL *)object;
        if (crl->adoptedDerCrl) {
            crlDer = crl->adoptedDerCrl;
        } else if (crl->nssSignedCrl && crl->nssSignedCrl->derCrl) { 
            crlDer = crl->nssSignedCrl->derCrl;
        }
        if (!crlDer || !crlDer->data) {
            PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER);
        }

        PKIX_CHECK(pkix_hash(crlDer->data, crlDer->len,
                             &certHash, plContext),
                   PKIX_ERRORINHASH);

        *pHashcode = certHash;

cleanup:

        PKIX_RETURN(CRL);
}

/*
 * 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;
        SECItem *crlDerOne = NULL, *crlDerTwo = 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;

        if (firstCrl->adoptedDerCrl) {
            crlDerOne = firstCrl->adoptedDerCrl;
        } else if (firstCrl->nssSignedCrl && firstCrl->nssSignedCrl->derCrl) {
            crlDerOne = firstCrl->nssSignedCrl->derCrl;
        }

        if (secondCrl->adoptedDerCrl) {
            crlDerTwo = secondCrl->adoptedDerCrl;
        } else if (secondCrl->nssSignedCrl && secondCrl->nssSignedCrl->derCrl) {
            crlDerTwo = secondCrl->nssSignedCrl->derCrl;
        }

        if (SECITEM_CompareItem(crlDerOne, crlDerTwo) == SECEqual) {
            *pResult = PKIX_TRUE;
        }

cleanup:

        PKIX_RETURN(CRL);
}

/*
 * FUNCTION: pkix_pl_CRL_RegisterSelf
 *
 * DESCRIPTION:
 *  Registers PKIX_CRL_TYPE and its related functions with systemClasses[]
 * THREAD SAFETY:
 *
 *  Not Thread Safe - for performance and complexity reasons
 *
 *  Since this function is only called by PKIX_PL_Initialize, which should
 *  only be called once, it is acceptable that this function is not
 *  thread-safe.
 */

PKIX_Error *
pkix_pl_CRL_RegisterSelf(void *plContext)
{
        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
        pkix_ClassTable_Entry *entry = &systemClasses[PKIX_CRL_TYPE];

        PKIX_ENTER(CRL, "pkix_pl_CRL_RegisterSelf");

        entry->description = "CRL";
        entry->typeObjectSize = sizeof(PKIX_PL_CRL);
        entry->destructor = pkix_pl_CRL_Destroy;
        entry->equalsFunction = pkix_pl_CRL_Equals;
        entry->hashcodeFunction = pkix_pl_CRL_Hashcode;
        entry->toStringFunction = pkix_pl_CRL_ToString;
        entry->duplicateFunction = pkix_duplicateImmutable;

        PKIX_RETURN(CRL);
}

/*
 * FUNCTION: PKIX_PL_CRL_VerifyUpdateTime (see comments in pkix_pl_pki.h)
 */

PKIX_Error *
PKIX_PL_CRL_VerifyUpdateTime(
        PKIX_PL_CRL *crl,
        PKIX_PL_Date *date,
        PKIX_Boolean *pResult,
        void *plContext)
{
        PRTime timeToCheck;
        PRTime nextUpdate;
        PRTime lastUpdate;
        SECStatus status;
        CERTCrl *nssCrl = NULL;
        SECItem *nextUpdateDer = NULL;
        PKIX_Boolean haveNextUpdate = PR_FALSE;

        PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifyUpdateTime");
        PKIX_NULLCHECK_FOUR(crl, crl->nssSignedCrl, date, pResult);

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

        nssCrl = &(crl->nssSignedCrl->crl);
        timeToCheck = date->nssTime;

        /* nextUpdate can be NULL. Checking before using it */
        nextUpdateDer = &nssCrl->nextUpdate;
        if (nextUpdateDer->data && nextUpdateDer->len) {
                haveNextUpdate = PR_TRUE;
                status = DER_DecodeTimeChoice(&nextUpdate, nextUpdateDer);
                if (status != SECSuccess) {
                        PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORNEXTUPDATEFAILED);
                }
        }

        status = DER_DecodeTimeChoice(&lastUpdate, &(nssCrl->lastUpdate));
        if (status != SECSuccess) {
                PKIX_ERROR(PKIX_DERDECODETIMECHOICEFORLASTUPDATEFAILED);
        }

        if (!haveNextUpdate || nextUpdate < timeToCheck) {
                *pResult = PKIX_FALSE;
                goto cleanup;
        }

        if (lastUpdate <= timeToCheck) {
                *pResult = PKIX_TRUE;
        } else {
                *pResult = PKIX_FALSE;
        }

cleanup:

        PKIX_RETURN(CRL);
}

/*
 * FUNCTION: pkix_pl_CRL_CreateWithSignedCRL
 * DESCRIPTION:
 *
 *  Creates a new CRL using the CERTSignedCrl pointed to by "nssSignedCrl"
 *  and stores it at "pCRL". If the decoding of the CERTSignedCrl fails,
 *  a PKIX_Error is returned.
 *
 * PARAMETERS:
 *  "nssSignedCrl"
 *      Address of CERTSignedCrl. Must be non-NULL.
 *  "adoptedDerCrl"
 *      SECItem ponter that if not NULL is indicating that memory used
 *      for der should be adopted by crl that is about to be created.
 *  "pCRL"
 *      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.
 */

PKIX_Error *
pkix_pl_CRL_CreateWithSignedCRL(
        CERTSignedCrl *nssSignedCrl,
        SECItem *adoptedDerCrl,
        SECItem *derGenName,
        PKIX_PL_CRL **pCrl,
        void *plContext)
{
        PKIX_PL_CRL *crl = NULL;

        PKIX_ENTER(CRL, "pkix_pl_CRL_CreateWithSignedCRL");
        PKIX_NULLCHECK_ONE(pCrl);

        /* create a PKIX_PL_CRL object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_CRL_TYPE,
                    sizeof (PKIX_PL_CRL),
                    (PKIX_PL_Object **)&crl,
                    plContext),
                    PKIX_COULDNOTCREATECRLOBJECT);

        /* populate the nssSignedCrl field */
        crl->nssSignedCrl = nssSignedCrl;
        crl->adoptedDerCrl = adoptedDerCrl;
        crl->issuer = NULL;
        crl->signatureAlgId = NULL;
        crl->crlNumber = NULL;
        crl->crlNumberAbsent = PKIX_FALSE;
        crl->crlEntryList = NULL;
        crl->critExtOids = NULL;
        if (derGenName) {
            crl->derGenName =
                SECITEM_DupItem(derGenName);
            if (!crl->derGenName) {
                PKIX_ERROR(PKIX_ALLOCERROR);
            }
        }

        *pCrl = crl;

cleanup:

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(crl);
        }

        PKIX_RETURN(CRL);
}

/* --Public-CRL-Functions------------------------------------- */

/*
 * FUNCTION: PKIX_PL_CRL_Create (see comments in pkix_pl_pki.h)
 */

PKIX_Error *
PKIX_PL_CRL_Create(
        PKIX_PL_ByteArray *byteArray,
        PKIX_PL_CRL **pCrl,
        void *plContext)
{
        CERTSignedCrl *nssSignedCrl = NULL;
        SECItem derItem, *derCrl = NULL;
        PKIX_PL_CRL *crl = NULL;

        PKIX_ENTER(CRL, "PKIX_PL_CRL_Create");
        PKIX_NULLCHECK_TWO(byteArray, pCrl);

        if (byteArray->length == 0){
            PKIX_ERROR(PKIX_ZEROLENGTHBYTEARRAYFORCRLENCODING);
        }
        derItem.type = siBuffer;
        derItem.data = byteArray->array;
        derItem.len = byteArray->length;
        derCrl = SECITEM_DupItem(&derItem);
        if (!derCrl) {
            PKIX_ERROR(PKIX_ALLOCERROR);
        }
        nssSignedCrl =
            CERT_DecodeDERCrlWithFlags(NULL, derCrl, SEC_CRL_TYPE,
                                       CRL_DECODE_DONT_COPY_DER |
                                       CRL_DECODE_SKIP_ENTRIES);
        if (!nssSignedCrl) {
            PKIX_ERROR(PKIX_CERTDECODEDERCRLFAILED);
        }
        PKIX_CHECK(
            pkix_pl_CRL_CreateWithSignedCRL(nssSignedCrl, derCrl, NULL,
                                            &crl, plContext),
            PKIX_CRLCREATEWITHSIGNEDCRLFAILED);
        nssSignedCrl = NULL;
        derCrl = NULL;
        *pCrl = crl;

cleanup:
        if (derCrl) {
            SECITEM_FreeItem(derCrl, PR_TRUE);
        }
        if (nssSignedCrl) {
            SEC_DestroyCrl(nssSignedCrl);
        } 

        PKIX_RETURN(CRL);
}

/*
 * 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);
}


/*
 * 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);
}

/*
 * FUNCTION: PKIX_PL_CRL_VerifySignature (see comments in pkix_pl_pki.h)
 */

PKIX_Error *
PKIX_PL_CRL_VerifySignature(
        PKIX_PL_CRL *crl,
        PKIX_PL_PublicKey *pubKey,
        void *plContext)
{
        PKIX_PL_CRL *cachedCrl = NULL;
        PKIX_Error *verifySig = NULL;
        PKIX_Error *cachedSig = NULL;
        PKIX_Boolean crlEqual = PKIX_FALSE;
        PKIX_Boolean crlInHash= PKIX_FALSE;
        CERTSignedCrl *nssSignedCrl = NULL;
        SECKEYPublicKey *nssPubKey = NULL;
        CERTSignedData *tbsCrl = NULL;
        void* wincx = NULL;
        SECStatus status;

        PKIX_ENTER(CRL, "PKIX_PL_CRL_VerifySignature");
        PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pubKey);

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

        verifySig = PKIX_PL_HashTable_Lookup
                (cachedCrlSigTable,
                (PKIX_PL_Object *) pubKey,
                (PKIX_PL_Object **) &cachedCrl,
                plContext);

        if (cachedCrl != NULL && verifySig == NULL) {
                /* Cached Signature Table lookup succeed */
                PKIX_EQUALS(crl, cachedCrl, &crlEqual, plContext,
                            PKIX_OBJECTEQUALSFAILED);
                if (crlEqual == PKIX_TRUE) {
                        goto cleanup;
                }
                /* Different PubKey may hash to same value, skip add */
                crlInHash = PKIX_TRUE;
        }

        nssSignedCrl = crl->nssSignedCrl;
        tbsCrl = &nssSignedCrl->signatureWrap;

        PKIX_CRL_DEBUG("\t\tCalling SECKEY_ExtractPublicKey\n");
        nssPubKey = SECKEY_ExtractPublicKey(pubKey->nssSPKI);
        if (!nssPubKey){
                PKIX_ERROR(PKIX_SECKEYEXTRACTPUBLICKEYFAILED);
        }

        PKIX_CHECK(pkix_pl_NssContext_GetWincx
                   ((PKIX_PL_NssContext *)plContext, &wincx),
                   PKIX_NSSCONTEXTGETWINCXFAILED);

        PKIX_CRL_DEBUG("\t\tCalling CERT_VerifySignedDataWithPublicKey\n");
        status = CERT_VerifySignedDataWithPublicKey(tbsCrl, nssPubKey, wincx);

        if (status != SECSuccess) {
                PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
                PKIX_ERROR(PKIX_SIGNATUREDIDNOTVERIFYWITHTHEPUBLICKEY);
        }

        if (crlInHash == PKIX_FALSE) {
                cachedSig = PKIX_PL_HashTable_Add
                        (cachedCrlSigTable,
                        (PKIX_PL_Object *) pubKey,
                        (PKIX_PL_Object *) crl,
                        plContext);

                if (cachedSig != NULL) {
                        PKIX_DEBUG("PKIX_PL_HashTable_Add skipped: entry existed\n");
                }
        }

cleanup:

        if (nssPubKey){
                PKIX_CRL_DEBUG("\t\tCalling SECKEY_DestroyPublicKey\n");
                SECKEY_DestroyPublicKey(nssPubKey);
                nssPubKey = NULL;
        }

        PKIX_DECREF(cachedCrl);
        PKIX_DECREF(verifySig);
        PKIX_DECREF(cachedSig);

        PKIX_RETURN(CRL);
}

PKIX_Error*
PKIX_PL_CRL_ReleaseDerCrl(PKIX_PL_CRL *crl,
                         SECItem **derCrl,
                         void *plContext)
{
    PKIX_ENTER(CRL, "PKIX_PL_CRL_ReleaseDerCrl");
    *derCrl = crl->adoptedDerCrl;
    crl->adoptedDerCrl = NULL;
        
    PKIX_RETURN(CRL);
}

PKIX_Error*
PKIX_PL_CRL_AdoptDerCrl(PKIX_PL_CRL *crl,
                         SECItem *derCrl,
                         void *plContext)
{
    PKIX_ENTER(CRL, "PKIX_PL_CRL_AquireDerCrl");
    if (crl->adoptedDerCrl) {
        PKIX_ERROR(PKIX_CANNOTAQUIRECRLDER);
    }
    crl->adoptedDerCrl = derCrl;
cleanup:        
    PKIX_RETURN(CRL);
}

Messung V0.5
C=96 H=92 G=93

¤ Dauer der Verarbeitung: 0.5 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge