Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/nss/lib/crmf/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 18 kB image not shown  

Quelle  crmfreq.c   Sprache: C

 
/* -*- Mode: C; tab-width: 8 -*-*/
/* 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/. */


#include "crmf.h"
#include "crmfi.h"
#include "keyhi.h"
#include "secder.h"

/*
 * Macro that returns PR_TRUE if the pointer is not NULL.
 * If the pointer is NULL, then the macro will return PR_FALSE.
 */

#define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE

const unsigned char hexTrue = 0xff;
const unsigned char hexFalse = 0x00;

SECStatus
crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value)
{
    SECItem *dummy;

    dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
    PORT_Assert(dummy == dest);
    if (dummy == NULL) {
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
                             unsigned long value)
{
    SECItem *dummy;

    dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
    PORT_Assert(dummy == dest);
    if (dummy != dest) {
        return SECFailure;
    }
    return SECSuccess;
}

static SECStatus
crmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src)
{
    return SECITEM_CopyItem(poolp, dest, src);
}

PRBool
CRMF_DoesRequestHaveField(CRMFCertRequest *inCertReq,
                          CRMFCertTemplateField inField)
{

    PORT_Assert(inCertReq != NULL);
    if (inCertReq == NULL) {
        return PR_FALSE;
    }
    switch (inField) {
        case crmfVersion:
            return inCertReq->certTemplate.version.data != NULL;
        case crmfSerialNumber:
            return inCertReq->certTemplate.serialNumber.data != NULL;
        case crmfSigningAlg:
            return inCertReq->certTemplate.signingAlg != NULL;
        case crmfIssuer:
            return inCertReq->certTemplate.issuer != NULL;
        case crmfValidity:
            return inCertReq->certTemplate.validity != NULL;
        case crmfSubject:
            return inCertReq->certTemplate.subject != NULL;
        case crmfPublicKey:
            return inCertReq->certTemplate.publicKey != NULL;
        case crmfIssuerUID:
            return inCertReq->certTemplate.issuerUID.data != NULL;
        case crmfSubjectUID:
            return inCertReq->certTemplate.subjectUID.data != NULL;
        case crmfExtension:
            return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
    }
    return PR_FALSE;
}

CRMFCertRequest *
CRMF_CreateCertRequest(PRUint32 inRequestID)
{
    PLArenaPool *poolp;
    CRMFCertRequest *certReq;
    SECStatus rv;

    poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
    if (poolp == NULL) {
        goto loser;
    }

    certReq = PORT_ArenaZNew(poolp, CRMFCertRequest);
    if (certReq == NULL) {
        goto loser;
    }

    certReq->poolp = poolp;
    certReq->requestID = inRequestID;

    rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId),
                                      inRequestID);
    if (rv != SECSuccess) {
        goto loser;
    }

    return certReq;
loser:
    if (poolp) {
        PORT_FreeArena(poolp, PR_FALSE);
    }
    return NULL;
}

SECStatus
CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
{
    PORT_Assert(inCertReq != NULL);
    if (inCertReq != NULL) {
        if (inCertReq->certTemplate.extensions) {
            PORT_Free(inCertReq->certTemplate.extensions);
        }
        if (inCertReq->controls) {
            /* Right now we don't support EnveloppedData option,
             * so we won't go through and delete each occurrence of
             * an EnveloppedData in the control.
             */

            PORT_Free(inCertReq->controls);
        }
        if (inCertReq->poolp) {
            PORT_FreeArena(inCertReq->poolp, PR_TRUE);
        }
    }
    return SECSuccess;
}

static SECStatus
crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version)
{
    return (crmf_encode_integer(poolp, dest, version));
}

static SECStatus
crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial)
{
    return (crmf_encode_integer(poolp, dest, serial));
}

SECStatus
crmf_template_copy_secalg(PLArenaPool *poolp, SECAlgorithmID **dest,
                          SECAlgorithmID *src)
{
    SECStatus rv;
    void *mark = NULL;
    SECAlgorithmID *mySecAlg;

    if (!poolp) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    mark = PORT_ArenaMark(poolp);
    *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
    if (mySecAlg == NULL) {
        goto loser;
    }
    rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
    if (rv != SECSuccess) {
        goto loser;
    }
    if (mark) {
        PORT_ArenaUnmark(poolp, mark);
    }
    return SECSuccess;

loser:
    *dest = NULL;
    if (mark) {
        PORT_ArenaRelease(poolp, mark);
    }
    return SECFailure;
}

SECStatus
crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
                    CERTName *src)
{
    CERTName *newName;
    SECStatus rv;
    void *mark;

    mark = PORT_ArenaMark(poolp);
    *dest = newName = PORT_ArenaZNew(poolp, CERTName);
    if (newName == NULL) {
        goto loser;
    }

    rv = CERT_CopyName(poolp, newName, src);
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
loser:
    PORT_ArenaRelease(poolp, mark);
    *dest = NULL;
    return SECFailure;
}

static SECStatus
crmf_template_add_issuer(PLArenaPool *poolp, CERTName **dest,
                         CERTName *issuerName)
{
    return crmf_copy_cert_name(poolp, dest, issuerName);
}

static SECStatus
crmf_template_add_validity(PLArenaPool *poolp, CRMFOptionalValidity **dest,
                           CRMFValidityCreationInfo *info)
{
    SECStatus rv;
    void *mark;
    CRMFOptionalValidity *myValidity;

    /*First off, let's make sure at least one of the two fields is present*/
    if (!info || (!info->notBefore && !info->notAfter)) {
        return SECFailure;
    }
    mark = PORT_ArenaMark(poolp);
    *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
    if (myValidity == NULL) {
        goto loser;
    }

    if (info->notBefore) {
        rv = DER_EncodeTimeChoice(poolp, &myValidity->notBefore,
                                  *info->notBefore);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    if (info->notAfter) {
        rv = DER_EncodeTimeChoice(poolp, &myValidity->notAfter,
                                  *info->notAfter);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
loser:
    PORT_ArenaRelease(poolp, mark);
    *dest = NULL;
    return SECFailure;
}

static SECStatus
crmf_template_add_subject(PLArenaPool *poolp, CERTName **dest,
                          CERTName *subject)
{
    return crmf_copy_cert_name(poolp, dest, subject);
}

SECStatus
crmf_template_add_public_key(PLArenaPool *poolp,
                             CERTSubjectPublicKeyInfo **dest,
                             CERTSubjectPublicKeyInfo *pubKey)
{
    CERTSubjectPublicKeyInfo *spki;
    SECStatus rv;

    *dest = spki = (poolp == NULL) ? PORT_ZNew(CERTSubjectPublicKeyInfo) : PORT_ArenaZNew(poolp, CERTSubjectPublicKeyInfo);
    if (spki == NULL) {
        goto loser;
    }
    rv = SECKEY_CopySubjectPublicKeyInfo(poolp, spki, pubKey);
    if (rv != SECSuccess) {
        goto loser;
    }
    return SECSuccess;
loser:
    if (poolp == NULL && spki != NULL) {
        SECKEY_DestroySubjectPublicKeyInfo(spki);
    }
    *dest = NULL;
    return SECFailure;
}

static SECStatus
crmf_copy_bitstring(PLArenaPool *poolp, SECItem *dest, const SECItem *src)
{
    SECStatus rv;
    SECItem byteSrc;

    byteSrc = *src;
    byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len);
    rv = crmf_copy_secitem(poolp, dest, &byteSrc);
    dest->len = src->len;
    return rv;
}

static SECStatus
crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest,
                             const SECItem *issuerUID)
{
    return crmf_copy_bitstring(poolp, dest, issuerUID);
}

static SECStatus
crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest,
                              const SECItem *subjectUID)
{
    return crmf_copy_bitstring(poolp, dest, subjectUID);
}

static void
crmf_zeroize_new_extensions(CRMFCertExtension **extensions,
                            int numToZeroize)
{
    PORT_Memset((void *)extensions, 0, sizeof(CERTCertExtension *) * numToZeroize);
}

/*
 * The strategy for adding templates will differ from all the other
 * attributes in the template.  First, we want to allow the client
 * of this API to set extensions more than just once.  So we will
 * need the ability grow the array of extensions.  Since arenas don't
 * give us the realloc function, we'll use the generic PORT_* functions
 * to allocate the array of pointers *ONLY*.  Then we will allocate each
 * individual extension from the arena that comes along with the certReq
 * structure that owns this template.
 */

static SECStatus
crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate,
                             CRMFCertExtCreationInfo *extensions)
{
    void *mark;
    int newSize, oldSize, i;
    SECStatus rv;
    CRMFCertExtension **extArray;
    CRMFCertExtension *newExt, *currExt;

    mark = PORT_ArenaMark(poolp);
    if (inTemplate->extensions == NULL) {
        newSize = extensions->numExtensions;
        extArray = PORT_ZNewArray(CRMFCertExtension *, newSize + 1);
    } else {
        newSize = inTemplate->numExtensions + extensions->numExtensions;
        extArray = PORT_Realloc(inTemplate->extensions,
                                sizeof(CRMFCertExtension *) * (newSize + 1));
    }
    if (extArray == NULL) {
        goto loser;
    }
    oldSize = inTemplate->numExtensions;
    inTemplate->extensions = extArray;
    inTemplate->numExtensions = newSize;
    for (i = oldSize; i < newSize; i++) {
        newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
        if (newExt == NULL) {
            goto loser2;
        }
        currExt = extensions->extensions[i - oldSize];
        rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
        if (rv != SECSuccess) {
            goto loser2;
        }
        rv = crmf_copy_secitem(poolp, &(newExt->critical),
                               &(currExt->critical));
        if (rv != SECSuccess) {
            goto loser2;
        }
        rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
        if (rv != SECSuccess) {
            goto loser2;
        }
        extArray[i] = newExt;
    }
    extArray[newSize] = NULL;
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
loser2:
    crmf_zeroize_new_extensions(&(inTemplate->extensions[oldSize]),
                                extensions->numExtensions);
    inTemplate->numExtensions = oldSize;
loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

SECStatus
CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
                                 CRMFCertTemplateField inTemplateField,
                                 void *data)
{
    CRMFCertTemplate *certTemplate;
    PLArenaPool *poolp;
    SECStatus rv = SECFailure;
    void *mark;

    if (inCertReq == NULL) {
        return SECFailure;
    }

    certTemplate = &(inCertReq->certTemplate);

    poolp = inCertReq->poolp;
    mark = PORT_ArenaMark(poolp);
    switch (inTemplateField) {
        case crmfVersion:
            rv = crmf_template_add_version(poolp, &(certTemplate->version),
                                           *(long *)data);
            break;
        case crmfSerialNumber:
            rv = crmf_template_add_serialnumber(poolp,
                                                &(certTemplate->serialNumber),
                                                *(long *)data);
            break;
        case crmfSigningAlg:
            rv = crmf_template_copy_secalg(poolp, &(certTemplate->signingAlg),
                                           (SECAlgorithmID *)data);
            break;
        case crmfIssuer:
            rv = crmf_template_add_issuer(poolp, &(certTemplate->issuer),
                                          (CERTName *)data);
            break;
        case crmfValidity:
            rv = crmf_template_add_validity(poolp, &(certTemplate->validity),
                                            (CRMFValidityCreationInfo *)data);
            break;
        case crmfSubject:
            rv = crmf_template_add_subject(poolp, &(certTemplate->subject),
                                           (CERTName *)data);
            break;
        case crmfPublicKey:
            rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
                                              (CERTSubjectPublicKeyInfo *)data);
            break;
        case crmfIssuerUID:
            rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
                                              (SECItem *)data);
            break;
        case crmfSubjectUID:
            rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
                                               (SECItem *)data);
            break;
        case crmfExtension:
            rv = crmf_template_add_extensions(poolp, certTemplate,
                                              (CRMFCertExtCreationInfo *)data);
            break;
    }
    if (rv != SECSuccess) {
        PORT_ArenaRelease(poolp, mark);
    } else {
        PORT_ArenaUnmark(poolp, mark);
    }
    return rv;
}

SECStatus
CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg,
                              CRMFCertRequest *inCertReq)
{
    PORT_Assert(inCertReqMsg != NULL && inCertReq != NULL);
    if (inCertReqMsg == NULL || inCertReq == NULL) {
        return SECFailure;
    }
    inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
                                                   inCertReq);
    return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
}

CRMFCertReqMsg *
CRMF_CreateCertReqMsg(void)
{
    PLArenaPool *poolp;
    CRMFCertReqMsg *reqMsg;

    poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
    if (poolp == NULL) {
        goto loser;
    }
    reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
    if (reqMsg == NULL) {
        goto loser;
    }
    reqMsg->poolp = poolp;
    return reqMsg;

loser:
    if (poolp) {
        PORT_FreeArena(poolp, PR_FALSE);
    }
    return NULL;
}

SECStatus
CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
{
    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
    if (!inCertReqMsg->isDecoded) {
        if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
            PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
        }
        if (inCertReqMsg->certReq->controls != NULL) {
            PORT_Free(inCertReqMsg->certReq->controls);
        }
    }
    PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
    return SECSuccess;
}

CRMFCertExtension *
crmf_create_cert_extension(PLArenaPool *poolp,
                           SECOidTag id,
                           PRBool isCritical,
                           SECItem *data)
{
    CRMFCertExtension *newExt;
    SECOidData *oidData;
    SECStatus rv;

    newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) : PORT_ArenaZNew(poolp, CRMFCertExtension);
    if (newExt == NULL) {
        goto loser;
    }
    oidData = SECOID_FindOIDByTag(id);
    if (oidData == NULL ||
        oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
        goto loser;
    }

    rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (isCritical) {
        newExt->critical.data = (poolp == NULL) ? PORT_New(unsigned char)
                                                : PORT_ArenaNew(poolp, unsigned char);
        if (newExt->critical.data == NULL) {
            goto loser;
        }
        newExt->critical.data[0] = hexTrue;
        newExt->critical.len = 1;
    }
    return newExt;
loser:
    if (newExt != NULL && poolp == NULL) {
        CRMF_DestroyCertExtension(newExt);
    }
    return NULL;
}

CRMFCertExtension *
CRMF_CreateCertExtension(SECOidTag id,
                         PRBool isCritical,
                         SECItem *data)
{
    return crmf_create_cert_extension(NULL, id, isCritical, data);
}

static SECStatus
crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
{
    if (inExtension != NULL) {
        SECITEM_FreeItem(&(inExtension->id), PR_FALSE);
        SECITEM_FreeItem(&(inExtension->value), PR_FALSE);
        SECITEM_FreeItem(&(inExtension->critical), PR_FALSE);
        if (freeit) {
            PORT_Free(inExtension);
        }
    }
    return SECSuccess;
}

SECStatus
CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
{
    return crmf_destroy_cert_extension(inExtension, PR_TRUE);
}

SECStatus
CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs)
{
    PORT_Assert(inCertReqMsgs != NULL);
    if (inCertReqMsgs != NULL) {
        PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
    }
    return SECSuccess;
}

static PRBool
crmf_item_has_data(SECItem *item)
{
    if (item != NULL && item->data != NULL) {
        return PR_TRUE;
    }
    return PR_FALSE;
}

PRBool
CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
                               CRMFCertTemplateField inTemplateField)
{
    PRBool retVal;
    CRMFCertTemplate *certTemplate;

    PORT_Assert(inCertReq != NULL);
    if (inCertReq == NULL) {
        /* This is probably some kind of error, but this is
         * the safest return value for this function.
         */

        return PR_FALSE;
    }
    certTemplate = &inCertReq->certTemplate;
    switch (inTemplateField) {
        case crmfVersion:
            retVal = crmf_item_has_data(&certTemplate->version);
            break;
        case crmfSerialNumber:
            retVal = crmf_item_has_data(&certTemplate->serialNumber);
            break;
        case crmfSigningAlg:
            retVal = IS_NOT_NULL(certTemplate->signingAlg);
            break;
        case crmfIssuer:
            retVal = IS_NOT_NULL(certTemplate->issuer);
            break;
        case crmfValidity:
            retVal = IS_NOT_NULL(certTemplate->validity);
            break;
        case crmfSubject:
            retVal = IS_NOT_NULL(certTemplate->subject);
            break;
        case crmfPublicKey:
            retVal = IS_NOT_NULL(certTemplate->publicKey);
            break;
        case crmfIssuerUID:
            retVal = crmf_item_has_data(&certTemplate->issuerUID);
            break;
        case crmfSubjectUID:
            retVal = crmf_item_has_data(&certTemplate->subjectUID);
            break;
        case crmfExtension:
            retVal = IS_NOT_NULL(certTemplate->extensions);
            break;
        default:
            retVal = PR_FALSE;
    }
    return retVal;
}

Messung V0.5
C=99 H=79 G=89

¤ Dauer der Verarbeitung: 0.33 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.