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


Quelle  certificate.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/. */


#ifndef NSSPKI_H
#include "nsspki.h"
#endif /* NSSPKI_H */

#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */

#ifndef PKIM_H
#include "pkim.h"
#endif /* PKIM_H */

#ifndef DEV_H
#include "dev.h"
#endif /* DEV_H */

#include "pkistore.h"

#include "pki3hack.h"
#include "pk11func.h"
#include "hasht.h"

#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */

extern const NSSError NSS_ERROR_NOT_FOUND;

/* Creates a certificate from a base object */
NSS_IMPLEMENT NSSCertificate *
nssCertificate_Create(
    nssPKIObject *object)
{
    PRStatus status;
    NSSCertificate *rvCert;
    nssArenaMark *mark;
    NSSArena *arena = object->arena;
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    PR_ASSERT(object->lockType == nssPKIMonitor);
    mark = nssArena_Mark(arena);
    rvCert = nss_ZNEW(arena, NSSCertificate);
    if (!rvCert) {
        return (NSSCertificate *)NULL;
    }
    rvCert->object = *object;
    /* XXX should choose instance based on some criteria */
    status = nssCryptokiCertificate_GetAttributes(object->instances[0],
                                                  NULL, /* XXX sessionOpt */
                                                  arena,
                                                  &rvCert->type,
                                                  &rvCert->id,
                                                  &rvCert->encoding,
                                                  &rvCert->issuer,
                                                  &rvCert->serial,
                                                  &rvCert->subject);
    if (status != PR_SUCCESS ||
        !rvCert->encoding.data ||
        !rvCert->encoding.size ||
        !rvCert->issuer.data ||
        !rvCert->issuer.size ||
        !rvCert->serial.data ||
        !rvCert->serial.size) {
        if (mark)
            nssArena_Release(arena, mark);
        return (NSSCertificate *)NULL;
    }
    if (mark)
        nssArena_Unmark(arena, mark);
    return rvCert;
}

NSS_IMPLEMENT NSSCertificate *
nssCertificate_AddRef(
    NSSCertificate *c)
{
    if (c) {
        nssPKIObject_AddRef(&c->object);
    }
    return c;
}

NSS_IMPLEMENT PRStatus
nssCertificate_Destroy(
    NSSCertificate *c)
{
    nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };

    if (c) {
        PRUint32 i;
        nssDecodedCert *dc = c->decoding;
        NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
        NSSCryptoContext *cc = c->object.cryptoContext;

        PR_ASSERT(c->object.refCount > 0);

        /* --- LOCK storage --- */
        if (cc) {
            nssCertificateStore_Lock(cc->certStore, &lockTrace);
        } else {
            nssTrustDomain_LockCertCache(td);
        }
        if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
            /* --- remove cert and UNLOCK storage --- */
            if (cc) {
                nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
                nssCertificateStore_Unlock(cc->certStore, &lockTrace,
                                           &unlockTrace);
            } else {
                nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
                nssTrustDomain_UnlockCertCache(td);
            }
            /* free cert data */
            for (i = 0; i < c->object.numInstances; i++) {
                nssCryptokiObject_Destroy(c->object.instances[i]);
            }
            nssPKIObject_DestroyLock(&c->object);
            nssArena_Destroy(c->object.arena);
            nssDecodedCert_Destroy(dc);
        } else {
            /* --- UNLOCK storage --- */
            if (cc) {
                nssCertificateStore_Unlock(cc->certStore,
                                           &lockTrace,
                                           &unlockTrace);
            } else {
                nssTrustDomain_UnlockCertCache(td);
            }
        }
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_Destroy(NSSCertificate *c)
{
    return nssCertificate_Destroy(c);
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetEncoding(NSSCertificate *c)
{
    if (c->encoding.size > 0 && c->encoding.data) {
        return &c->encoding;
    } else {
        return (NSSDER *)NULL;
    }
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetIssuer(NSSCertificate *c)
{
    if (c->issuer.size > 0 && c->issuer.data) {
        return &c->issuer;
    } else {
        return (NSSDER *)NULL;
    }
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetSerialNumber(NSSCertificate *c)
{
    if (c->serial.size > 0 && c->serial.data) {
        return &c->serial;
    } else {
        return (NSSDER *)NULL;
    }
}

NSS_IMPLEMENT NSSDER *
nssCertificate_GetSubject(NSSCertificate *c)
{
    if (c->subject.size > 0 && c->subject.data) {
        return &c->subject;
    } else {
        return (NSSDER *)NULL;
    }
}

/* Returns a copy, Caller must free using nss_ZFreeIf */
NSS_IMPLEMENT NSSUTF8 *
nssCertificate_GetNickname(
    NSSCertificate *c,
    NSSToken *tokenOpt)
{
    return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
}

NSS_IMPLEMENT NSSASCII7 *
nssCertificate_GetEmailAddress(NSSCertificate *c)
{
    return c->email;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_DeleteStoredObject(
    NSSCertificate *c,
    NSSCallback *uhh)
{
    return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
}

NSS_IMPLEMENT PRStatus
NSSCertificate_Validate(
    NSSCertificate *c,
    NSSTime *timeOpt, /* NULL for "now" */
    NSSUsage *usage,
    NSSPolicies *policiesOpt /* NULL for none */
)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FAILURE;
}

NSS_IMPLEMENT void ** /* void *[] */
NSSCertificate_ValidateCompletely(
    NSSCertificate *c,
    NSSTime *timeOpt, /* NULL for "now" */
    NSSUsage *usage,
    NSSPolicies *policiesOpt, /* NULL for none */
    void **rvOpt,             /* NULL for allocate */
    PRUint32 rvLimit,         /* zero for no limit */
    NSSArena *arenaOpt        /* NULL for heap */
)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_ValidateAndDiscoverUsagesAndPolicies(
    NSSCertificate *c,
    NSSTime **notBeforeOutOpt,
    NSSTime **notAfterOutOpt,
    void *allowedUsages,
    void *disallowedUsages,
    void *allowedPolicies,
    void *disallowedPolicies,
    /* more args.. work on this fgmr */
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FAILURE;
}

NSS_IMPLEMENT NSSDER *
NSSCertificate_Encode(
    NSSCertificate *c,
    NSSDER *rvOpt,
    NSSArena *arenaOpt)
{
    /* Item, DER, BER are all typedefs now... */
    return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
}

NSS_IMPLEMENT nssDecodedCert *
nssCertificate_GetDecoding(
    NSSCertificate *c)
{
    nssDecodedCert *deco = NULL;
    if (c->type == NSSCertificateType_PKIX) {
        (void)STAN_GetCERTCertificate(c);
    }
    nssPKIObject_Lock(&c->object);
    if (!c->decoding) {
        deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
        PORT_Assert(!c->decoding);
        c->decoding = deco;
    } else {
        deco = c->decoding;
    }
    nssPKIObject_Unlock(&c->object);
    return deco;
}

static NSSCertificate **
filter_subject_certs_for_id(
    NSSCertificate **subjectCerts,
    void *id)
{
    NSSCertificate **si;
    nssDecodedCert *dcp;
    int nextOpenSlot = 0;
    int i;
    nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
    nssCertIDMatch match;

    /* walk the subject certs */
    for (si = subjectCerts; *si; si++) {
        dcp = nssCertificate_GetDecoding(*si);
        if (!dcp) {
            NSSCertificate_Destroy(*si);
            continue;
        }
        match = dcp->matchIdentifier(dcp, id);
        switch (match) {
            case nssCertIDMatch_Yes:
                if (matchLevel == nssCertIDMatch_Unknown) {
                    /* we have non-definitive matches, forget them */
                    for (i = 0; i < nextOpenSlot; i++) {
                        NSSCertificate_Destroy(subjectCerts[i]);
                        subjectCerts[i] = NULL;
                    }
                    nextOpenSlot = 0;
                    /* only keep definitive matches from now on */
                    matchLevel = nssCertIDMatch_Yes;
                }
                /* keep the cert */
                subjectCerts[nextOpenSlot++] = *si;
                break;
            case nssCertIDMatch_Unknown:
                if (matchLevel == nssCertIDMatch_Unknown) {
                    /* only have non-definitive matches so far, keep it */
                    subjectCerts[nextOpenSlot++] = *si;
                    break;
                }
            /* else fall through, we have a definitive match already */
            case nssCertIDMatch_No:
            default:
                NSSCertificate_Destroy(*si);
                *si = NULL;
        }
    }
    subjectCerts[nextOpenSlot] = NULL;
    return subjectCerts;
}

static NSSCertificate **
filter_certs_for_valid_issuers(NSSCertificate **certs)
{
    NSSCertificate **cp;
    nssDecodedCert *dcp;
    int nextOpenSlot = 0;

    for (cp = certs; *cp; cp++) {
        dcp = nssCertificate_GetDecoding(*cp);
        if (dcp && dcp->isValidIssuer(dcp)) {
            certs[nextOpenSlot++] = *cp;
        } else {
            NSSCertificate_Destroy(*cp);
        }
    }
    certs[nextOpenSlot] = NULL;
    return certs;
}

static NSSCertificate *
find_cert_issuer(
    NSSCertificate *c,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSTrustDomain *td,
    NSSCryptoContext *cc)
{
    NSSArena *arena;
    NSSCertificate **certs = NULL;
    NSSCertificate **ccIssuers = NULL;
    NSSCertificate **tdIssuers = NULL;
    NSSCertificate *issuer = NULL;

    if (!cc)
        cc = c->object.cryptoContext;
    if (!td)
        td = NSSCertificate_GetTrustDomain(c);
    arena = nssArena_Create();
    if (!arena) {
        return (NSSCertificate *)NULL;
    }
    if (cc) {
        ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
                                                               &c->issuer,
                                                               NULL,
                                                               0,
                                                               arena);
    }
    if (td)
        tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
                                                             &c->issuer,
                                                             NULL,
                                                             0,
                                                             arena);
    certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
    if (certs) {
        nssDecodedCert *dc = NULL;
        void *issuerID = NULL;
        dc = nssCertificate_GetDecoding(c);
        if (dc) {
            issuerID = dc->getIssuerIdentifier(dc);
        }
        /* XXX review based on CERT_FindCertIssuer
         * this function is not using the authCertIssuer field as a fallback
         * if authority key id does not exist
         */

        if (issuerID) {
            certs = filter_subject_certs_for_id(certs, issuerID);
        }
        certs = filter_certs_for_valid_issuers(certs);
        issuer = nssCertificateArray_FindBestCertificate(certs,
                                                         timeOpt,
                                                         usage,
                                                         policiesOpt);
        nssCertificateArray_Destroy(certs);
    }
    nssArena_Destroy(arena);
    return issuer;
}

/* This function returns the built chain, as far as it gets,
** even if/when it fails to find an issuer, and returns PR_FAILURE
*/

NSS_IMPLEMENT NSSCertificate **
nssCertificate_BuildChain(
    NSSCertificate *c,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCertificate **rvOpt,
    PRUint32 rvLimit,
    NSSArena *arenaOpt,
    PRStatus *statusOpt,
    NSSTrustDomain *td,
    NSSCryptoContext *cc)
{
    NSSCertificate **rvChain = NULL;
    NSSUsage issuerUsage = *usage;
    nssPKIObjectCollection *collection = NULL;
    PRUint32 rvCount = 0;
    PRStatus st;
    PRStatus ret = PR_SUCCESS;

    if (!c || !cc ||
        (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
        goto loser;
    }
    /* bump the usage up to CA level */
    issuerUsage.nss3lookingForCA = PR_TRUE;
    collection = nssCertificateCollection_Create(td, NULL);
    if (!collection)
        goto loser;
    st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
    if (st != PR_SUCCESS)
        goto loser;
    for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
        CERTCertificate *cCert = STAN_GetCERTCertificate(c);
        if (cCert->isRoot) {
            /* not including the issuer of the self-signed cert, which is,
             * of course, itself
             */

            break;
        }
        c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
        if (!c) {
            ret = PR_FAILURE;
            break;
        }
        st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
        nssCertificate_Destroy(c); /* collection has it */
        if (st != PR_SUCCESS)
            goto loser;
    }
    rvChain = nssPKIObjectCollection_GetCertificates(collection,
                                                     rvOpt,
                                                     rvLimit,
                                                     arenaOpt);
    if (rvChain) {
        nssPKIObjectCollection_Destroy(collection);
        if (statusOpt)
            *statusOpt = ret;
        if (ret != PR_SUCCESS)
            nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
        return rvChain;
    }

loser:
    if (collection)
        nssPKIObjectCollection_Destroy(collection);
    if (statusOpt)
        *statusOpt = PR_FAILURE;
    nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
    return rvChain;
}

NSS_IMPLEMENT NSSCertificate **
NSSCertificate_BuildChain(
    NSSCertificate *c,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCertificate **rvOpt,
    PRUint32 rvLimit, /* zero for no limit */
    NSSArena *arenaOpt,
    PRStatus *statusOpt,
    NSSTrustDomain *td,
    NSSCryptoContext *cc)
{
    return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
                                     rvOpt, rvLimit, arenaOpt, statusOpt,
                                     td, cc);
}

NSS_IMPLEMENT NSSCryptoContext *
nssCertificate_GetCryptoContext(NSSCertificate *c)
{
    return c->object.cryptoContext;
}

NSS_IMPLEMENT NSSTrustDomain *
nssCertificate_GetTrustDomain(NSSCertificate *c)
{
    return c->object.trustDomain;
}

NSS_IMPLEMENT NSSTrustDomain *
NSSCertificate_GetTrustDomain(NSSCertificate *c)
{
    return nssCertificate_GetTrustDomain(c);
}

NSS_IMPLEMENT NSSToken *
NSSCertificate_GetToken(
    NSSCertificate *c,
    PRStatus *statusOpt)
{
    return (NSSToken *)NULL;
}

NSS_IMPLEMENT NSSSlot *
NSSCertificate_GetSlot(
    NSSCertificate *c,
    PRStatus *statusOpt)
{
    return (NSSSlot *)NULL;
}

NSS_IMPLEMENT NSSModule *
NSSCertificate_GetModule(
    NSSCertificate *c,
    PRStatus *statusOpt)
{
    return (NSSModule *)NULL;
}

NSS_IMPLEMENT NSSItem *
NSSCertificate_Encrypt(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT PRStatus
NSSCertificate_Verify(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSItem *signature,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FAILURE;
}

NSS_IMPLEMENT NSSItem *
NSSCertificate_VerifyRecover(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *signature,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSItem *
NSSCertificate_WrapSymmetricKey(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSSymmetricKey *keyToWrap,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSCryptoContext *
NSSCertificate_CreateCryptoContext(
    NSSCertificate *c,
    NSSAlgorithmAndParameters *apOpt,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSPublicKey *
NSSCertificate_GetPublicKey(
    NSSCertificate *c)
{
#if 0
    CK_ATTRIBUTE pubktemplate[] = {
    { CKA_CLASS,   NULL, 0 },
    { CKA_ID,      NULL, 0 },
    { CKA_SUBJECT, NULL, 0 }
    };
    PRStatus nssrv;
    CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
    NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
    if (c->id.size > 0) {
    /* CKA_ID */
    NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
    } else {
    /* failure, yes? */
    return (NSSPublicKey *)NULL;
    }
    if (c->subject.size > 0) {
    /* CKA_SUBJECT */
    NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
    } else {
    /* failure, yes? */
    return (NSSPublicKey *)NULL;
    }
    /* Try the cert's token first */
    if (c->token) {
    nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
    }
#endif
    /* Try all other key tokens */
    return (NSSPublicKey *)NULL;
}

NSS_IMPLEMENT NSSPrivateKey *
NSSCertificate_FindPrivateKey(
    NSSCertificate *c,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT PRBool
NSSCertificate_IsPrivateKeyAvailable(
    NSSCertificate *c,
    NSSCallback *uhh,
    PRStatus *statusOpt)
{
    PRBool isUser = PR_FALSE;
    nssCryptokiObject **ip;
    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
        return PR_FALSE;
    }
    for (ip = instances; *ip; ip++) {
        nssCryptokiObject *instance = *ip;
        if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
            isUser = PR_TRUE;
        }
    }
    nssCryptokiObjectArray_Destroy(instances);
    return isUser;
}

/* sort the subject cert list from newest to oldest */
PRIntn
nssCertificate_SubjectListSort(
    void *v1,
    void *v2)
{
    NSSCertificate *c1 = (NSSCertificate *)v1;
    NSSCertificate *c2 = (NSSCertificate *)v2;
    nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
    nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
    if (!dc1) {
        return dc2 ? 1 : 0;
    } else if (!dc2) {
        return -1;
    } else {
        return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
    }
}

NSS_IMPLEMENT PRBool
NSSUserCertificate_IsStillPresent(
    NSSUserCertificate *uc,
    PRStatus *statusOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return PR_FALSE;
}

NSS_IMPLEMENT NSSItem *
NSSUserCertificate_Decrypt(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSItem *
NSSUserCertificate_Sign(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSItem *
NSSUserCertificate_SignRecover(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *data,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSSymmetricKey *
NSSUserCertificate_UnwrapSymmetricKey(
    NSSUserCertificate *uc,
    NSSAlgorithmAndParameters *apOpt,
    NSSItem *wrappedKey,
    NSSTime *timeOpt,
    NSSUsage *usage,
    NSSPolicies *policiesOpt,
    NSSCallback *uhh,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT NSSSymmetricKey *
NSSUserCertificate_DeriveSymmetricKey(
    NSSUserCertificate *uc, /* provides private key */
    NSSCertificate *c,      /* provides public key */
    NSSAlgorithmAndParameters *apOpt,
    NSSOID *target,
    PRUint32 keySizeOpt, /* zero for best allowed */
    NSSOperations operations,
    NSSCallback *uhh)
{
    nss_SetError(NSS_ERROR_NOT_FOUND);
    return NULL;
}

NSS_IMPLEMENT nssSMIMEProfile *
nssSMIMEProfile_Create(
    NSSCertificate *cert,
    NSSItem *profileTime,
    NSSItem *profileData)
{
    NSSArena *arena;
    nssSMIMEProfile *rvProfile;
    nssPKIObject *object;
    NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
    NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
    arena = nssArena_Create();
    if (!arena) {
        return NULL;
    }
    object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
    if (!object) {
        goto loser;
    }
    rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
    if (!rvProfile) {
        goto loser;
    }
    rvProfile->object = *object;
    rvProfile->certificate = cert;
    rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
    rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
    if (profileTime) {
        rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
    }
    if (profileData) {
        rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
    }
    return rvProfile;
loser:
    if (object)
        nssPKIObject_Destroy(object);
    else if (arena)
        nssArena_Destroy(arena);
    return (nssSMIMEProfile *)NULL;
}

/* execute a callback function on all members of a cert list */
NSS_EXTERN PRStatus
nssCertificateList_DoCallback(
    nssList *certList,
    PRStatus (*callback)(NSSCertificate *c, void *arg),
    void *arg)
{
    nssListIterator *certs;
    NSSCertificate *cert;
    certs = nssList_CreateIterator(certList);
    if (!certs) {
        return PR_FAILURE;
    }
    for (cert = (NSSCertificate *)nssListIterator_Start(certs);
         cert != (NSSCertificate *)NULL;
         cert = (NSSCertificate *)nssListIterator_Next(certs)) {
        (void)(*callback)(cert, arg);
    }
    nssListIterator_Finish(certs);
    nssListIterator_Destroy(certs);
    return PR_SUCCESS;
}

static PRStatus
add_ref_callback(NSSCertificate *c, void *a)
{
    nssCertificate_AddRef(c);
    return PR_SUCCESS;
}

NSS_IMPLEMENT void
nssCertificateList_AddReferences(
    nssList *certList)
{
    (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
}

/*
 * Is this trust record safe to apply to all certs of the same issuer/SN
 * independent of the cert matching the hash. This is only true is the trust
 * is unknown or distrusted. In general this feature is only useful to
 * explicitly distrusting certs. It is not safe to use to trust certs, so
 * only allow unknown and untrusted trust types.
 */

PRBool
nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth,
                                nssTrustLevel clientAuth, nssTrustLevel codeSigning,
                                nssTrustLevel email, PRBool stepup)
{
    /* step up is a trust type, if it's on, we must have a hash for the cert */
    if (stepup) {
        return PR_FALSE;
    }
    if ((serverAuth != nssTrustLevel_Unknown) &&
        (serverAuth != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    if ((clientAuth != nssTrustLevel_Unknown) &&
        (clientAuth != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    if ((codeSigning != nssTrustLevel_Unknown) &&
        (codeSigning != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    if ((email != nssTrustLevel_Unknown) &&
        (email != nssTrustLevel_NotTrusted)) {
        return PR_FALSE;
    }
    /* record only has Unknown and Untrusted entries, ok to accept without a
     * hash */

    return PR_TRUE;
}

NSS_IMPLEMENT NSSTrust *
nssTrust_Create(
    nssPKIObject *object,
    NSSItem *certData)
{
    PRStatus status;
    PRUint32 i;
    PRUint32 lastTrustOrder, myTrustOrder;
    unsigned char sha1_hashcmp[SHA1_LENGTH];
    unsigned char sha1_hashin[SHA1_LENGTH];
    NSSItem sha1_hash;
    NSSTrust *rvt;
    nssCryptokiObject *instance;
    nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
    SECStatus rv; /* Should be stan flavor */
    PRBool stepUp;

    lastTrustOrder = 1 << 16; /* just make it big */
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    rvt = nss_ZNEW(object->arena, NSSTrust);
    if (!rvt) {
        return (NSSTrust *)NULL;
    }
    rvt->object = *object;

    /* should be stan flavor of Hashbuf */
    rv = PK11_HashBuf(SEC_OID_SHA1, sha1_hashcmp, certData->data, certData->size);
    if (rv != SECSuccess) {
        return (NSSTrust *)NULL;
    }
    sha1_hash.data = sha1_hashin;
    sha1_hash.size = sizeof(sha1_hashin);
    /* trust has to peek into the base object members */
    nssPKIObject_Lock(object);
    for (i = 0; i < object->numInstances; i++) {
        instance = object->instances[i];
        myTrustOrder = nssToken_GetTrustOrder(instance->token);
        status = nssCryptokiTrust_GetAttributes(instance, NULL,
                                                &sha1_hash,
                                                &serverAuth,
                                                &clientAuth,
                                                &codeSigning,
                                                &emailProtection,
                                                &stepUp);
        if (status != PR_SUCCESS) {
            nssPKIObject_Unlock(object);
            return (NSSTrust *)NULL;
        }
        /* if no hash is specified, then trust applies to all certs with
         * this issuer/SN. NOTE: This is only true for entries that
         * have distrust and unknown record */

        if (!(
                /* we continue if there is no hash, and the trust type is
                 * safe to accept without a hash ... or ... */

                ((sha1_hash.size == 0) &&
                 nssTrust_IsSafeToIgnoreCertHash(serverAuth, clientAuth,
                                                 codeSigning, emailProtection,
                                                 stepUp)) ||
                /* we have a hash of the correct size, and it matches */
                ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
                                                                 sha1_hashcmp,
                                                                 SHA1_LENGTH) == 0)))) {
            nssPKIObject_Unlock(object);
            return (NSSTrust *)NULL;
        }
        if (rvt->serverAuth == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->serverAuth = serverAuth;
        }
        if (rvt->clientAuth == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->clientAuth = clientAuth;
        }
        if (rvt->emailProtection == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->emailProtection = emailProtection;
        }
        if (rvt->codeSigning == nssTrustLevel_Unknown ||
            myTrustOrder < lastTrustOrder) {
            rvt->codeSigning = codeSigning;
        }
        rvt->stepUpApproved = stepUp;
        lastTrustOrder = myTrustOrder;
    }
    nssPKIObject_Unlock(object);
    return rvt;
}

NSS_IMPLEMENT NSSTrust *
nssTrust_AddRef(NSSTrust *trust)
{
    if (trust) {
        nssPKIObject_AddRef(&trust->object);
    }
    return trust;
}

NSS_IMPLEMENT PRStatus
nssTrust_Destroy(NSSTrust *trust)
{
    if (trust) {
        (void)nssPKIObject_Destroy(&trust->object);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT nssSMIMEProfile *
nssSMIMEProfile_AddRef(nssSMIMEProfile *profile)
{
    if (profile) {
        nssPKIObject_AddRef(&profile->object);
    }
    return profile;
}

NSS_IMPLEMENT PRStatus
nssSMIMEProfile_Destroy(nssSMIMEProfile *profile)
{
    if (profile) {
        (void)nssPKIObject_Destroy(&profile->object);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT NSSCRL *
nssCRL_Create(nssPKIObject *object)
{
    PRStatus status;
    NSSCRL *rvCRL;
    NSSArena *arena = object->arena;
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    rvCRL = nss_ZNEW(arena, NSSCRL);
    if (!rvCRL) {
        return (NSSCRL *)NULL;
    }
    rvCRL->object = *object;
    /* XXX should choose instance based on some criteria */
    status = nssCryptokiCRL_GetAttributes(object->instances[0],
                                          NULL, /* XXX sessionOpt */
                                          arena,
                                          &rvCRL->encoding,
                                          NULL, /* subject */
                                          NULL, /* class */
                                          &rvCRL->url,
                                          &rvCRL->isKRL);
    if (status != PR_SUCCESS) {
        if (!arena) {
            nssPKIObject_Destroy((nssPKIObject *)rvCRL);
        }
        return (NSSCRL *)NULL;
    }
    return rvCRL;
}

NSS_IMPLEMENT NSSCRL *
nssCRL_AddRef(NSSCRL *crl)
{
    if (crl) {
        nssPKIObject_AddRef(&crl->object);
    }
    return crl;
}

NSS_IMPLEMENT PRStatus
nssCRL_Destroy(NSSCRL *crl)
{
    if (crl) {
        (void)nssPKIObject_Destroy(&crl->object);
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT PRStatus
nssCRL_DeleteStoredObject(
    NSSCRL *crl,
    NSSCallback *uhh)
{
    return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
}

NSS_IMPLEMENT NSSDER *
nssCRL_GetEncoding(NSSCRL *crl)
{
    if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
        return &crl->encoding;
    } else {
        return (NSSDER *)NULL;
    }
}

Messung V0.5
C=95 H=89 G=91

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