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


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

#include "secitem.h"
#include "pkcs11.h"
#include "lgdb.h"
#include "lowkeyi.h"
#include "pcert.h"
#include "blapi.h"

#include "keydbi.h"

/*
 * This code maps PKCS #11 Finds to legacy database searches. This code
 * was orginally in pkcs11.c in previous versions of NSS.
 */


struct SDBFindStr {
    CK_OBJECT_HANDLE *handles;
    int size;
    int index;
    int array_size;
};

/*
 * free a search structure
 */

void
lg_FreeSearch(SDBFind *search)
{
    if (search->handles) {
        PORT_Free(search->handles);
    }
    PORT_Free(search);
}

void
lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle)
{
    if (search->handles == NULL) {
        return;
    }
    if (search->size >= search->array_size) {
        search->array_size += LG_SEARCH_BLOCK_SIZE;
        search->handles = (CK_OBJECT_HANDLE *)PORT_Realloc(search->handles,
                                                           sizeof(CK_OBJECT_HANDLE) * search->array_size);
        if (search->handles == NULL) {
            return;
        }
    }
    search->handles[search->size] = handle;
    search->size++;
}

/*
 * find any certs that may match the template and load them.
 */

#define LG_CERT 0x00000001
#define LG_TRUST 0x00000002
#define LG_CRL 0x00000004
#define LG_SMIME 0x00000008
#define LG_PRIVATE 0x00000010
#define LG_PUBLIC 0x00000020
#define LG_KEY 0x00000040

/*
 * structure to collect key handles.
 */

typedef struct lgEntryDataStr {
    SDB *sdb;
    SDBFind *searchHandles;
    const CK_ATTRIBUTE *template;
    CK_ULONG templ_count;
} lgEntryData;

static SECStatus
lg_crl_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg)
{
    lgEntryData *crlData;
    CK_OBJECT_HANDLE class_handle;
    SDB *sdb;

    crlData = (lgEntryData *)arg;
    sdb = crlData->sdb;

    class_handle = (type == certDBEntryTypeRevocation) ? LG_TOKEN_TYPE_CRL : LG_TOKEN_KRL_HANDLE;
    if (lg_tokenMatch(sdb, key, class_handle,
                      crlData->template, crlData->templ_count)) {
        lg_addHandle(crlData->searchHandles,
                     lg_mkHandle(sdb, key, class_handle));
    }
    return (SECSuccess);
}

static void
lg_searchCrls(SDB *sdb, SECItem *derSubject, PRBool isKrl,
              unsigned long classFlags, SDBFind *search,
              const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
{
    NSSLOWCERTCertDBHandle *certHandle = NULL;

    certHandle = lg_getCertDB(sdb);
    if (certHandle == NULL) {
        return;
    }
    if (derSubject->data != NULL) {
        certDBEntryRevocation *crl =
            nsslowcert_FindCrlByKey(certHandle, derSubject, isKrl);

        if (crl != NULL) {
            lg_addHandle(search, lg_mkHandle(sdb, derSubject,
                                             isKrl ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL));
            nsslowcert_DestroyDBEntry((certDBEntry *)crl);
        }
    } else {
        lgEntryData crlData;

        /* traverse */
        crlData.sdb = sdb;
        crlData.searchHandles = search;
        crlData.template = pTemplate;
        crlData.templ_count = ulCount;
        nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeRevocation,
                                     lg_crl_collect, (void *)&crlData);
        nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeKeyRevocation,
                                     lg_crl_collect, (void *)&crlData);
    }
}

/*
 * structure to collect key handles.
 */

typedef struct lgKeyDataStr {
    SDB *sdb;
    NSSLOWKEYDBHandle *keyHandle;
    SDBFind *searchHandles;
    SECItem *id;
    const CK_ATTRIBUTE *template;
    CK_ULONG templ_count;
    unsigned long classFlags;
    PRBool strict;
} lgKeyData;

static PRBool
isSecretKey(NSSLOWKEYPrivateKey *privKey)
{
    if (privKey->keyType == NSSLOWKEYRSAKey &&
        privKey->u.rsa.publicExponent.len == 1 &&
        privKey->u.rsa.publicExponent.data[0] == 0)
        return PR_TRUE;

    return PR_FALSE;
}

static SECStatus
lg_key_collect(DBT *key, DBT *data, void *arg)
{
    lgKeyData *keyData;
    NSSLOWKEYPrivateKey *privKey = NULL;
    SECItem tmpDBKey;
    SDB *sdb;
    unsigned long classFlags;

    keyData = (lgKeyData *)arg;
    sdb = keyData->sdb;
    classFlags = keyData->classFlags;

    tmpDBKey.data = key->data;
    tmpDBKey.len = key->size;
    tmpDBKey.type = siBuffer;

    PORT_Assert(keyData->keyHandle);
    if (!keyData->strict && keyData->id && keyData->id->data) {
        SECItem result;
        PRBool haveMatch = PR_FALSE;
        unsigned char hashKey[SHA1_LENGTH];
        result.data = hashKey;
        result.len = sizeof(hashKey);

        if (keyData->id->len == 0) {
            /* Make sure this isn't a LG_KEY */
            privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle,
                                                   &tmpDBKey, keyData->sdb /*->password*/);
            if (privKey) {
                /* turn off the unneeded class flags */
                classFlags &= isSecretKey(privKey) ? ~(LG_PRIVATE | LG_PUBLIC) : ~LG_KEY;
                haveMatch = (PRBool)((classFlags & (LG_KEY | LG_PRIVATE | LG_PUBLIC)) != 0);
                lg_nsslowkey_DestroyPrivateKey(privKey);
            }
        } else {
            SHA1_HashBuf(hashKey, key->data, key->size); /* match id */
            haveMatch = SECITEM_ItemsAreEqual(keyData->id, &result);
            if (!haveMatch && ((unsigned char *)key->data)[0] == 0) {
                /* This is a fix for backwards compatibility.  The key
                 * database indexes private keys by the public key, and
                 * versions of NSS prior to 3.4 stored the public key as
                 * a signed integer.  The public key is now treated as an
                 * unsigned integer, with no leading zero.  In order to
                 * correctly compute the hash of an old key, it is necessary
                 * to fallback and detect the leading zero.
                 */

                SHA1_HashBuf(hashKey,
                             (unsigned char *)key->data + 1, key->size - 1);
                haveMatch = SECITEM_ItemsAreEqual(keyData->id, &result);
            }
        }
        if (haveMatch) {
            if (classFlags & LG_PRIVATE) {
                lg_addHandle(keyData->searchHandles,
                             lg_mkHandle(sdb, &tmpDBKey, LG_TOKEN_TYPE_PRIV));
            }
            if (classFlags & LG_PUBLIC) {
                lg_addHandle(keyData->searchHandles,
                             lg_mkHandle(sdb, &tmpDBKey, LG_TOKEN_TYPE_PUB));
            }
            if (classFlags & LG_KEY) {
                lg_addHandle(keyData->searchHandles,
                             lg_mkHandle(sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY));
            }
        }
        return SECSuccess;
    }

    privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle, &tmpDBKey,
                                           keyData->sdb /*->password*/);
    if (privKey == NULL) {
        goto loser;
    }

    if (isSecretKey(privKey)) {
        if ((classFlags & LG_KEY) &&
            lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY,
                          keyData->template, keyData->templ_count)) {
            lg_addHandle(keyData->searchHandles,
                         lg_mkHandle(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY));
        }
    } else {
        if ((classFlags & LG_PRIVATE) &&
            lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PRIV,
                          keyData->template, keyData->templ_count)) {
            lg_addHandle(keyData->searchHandles,
                         lg_mkHandle(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PRIV));
        }
        if ((classFlags & LG_PUBLIC) &&
            lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PUB,
                          keyData->template, keyData->templ_count)) {
            lg_addHandle(keyData->searchHandles,
                         lg_mkHandle(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PUB));
        }
    }

loser:
    if (privKey) {
        lg_nsslowkey_DestroyPrivateKey(privKey);
    }
    return (SECSuccess);
}

static void
lg_searchKeys(SDB *sdb, SECItem *key_id,
              unsigned long classFlags, SDBFind *search, PRBool mustStrict,
              const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
{
    NSSLOWKEYDBHandle *keyHandle = NULL;
    NSSLOWKEYPrivateKey *privKey;
    lgKeyData keyData;
    PRBool found = PR_FALSE;

    keyHandle = lg_getKeyDB(sdb);
    if (keyHandle == NULL) {
        return;
    }

    if (key_id->data) {
        privKey = nsslowkey_FindKeyByPublicKey(keyHandle, key_id, sdb);
        if (privKey) {
            if ((classFlags & LG_KEY) && isSecretKey(privKey)) {
                lg_addHandle(search,
                             lg_mkHandle(sdb, key_id, LG_TOKEN_TYPE_KEY));
                found = PR_TRUE;
            }
            if ((classFlags & LG_PRIVATE) && !isSecretKey(privKey)) {
                lg_addHandle(search,
                             lg_mkHandle(sdb, key_id, LG_TOKEN_TYPE_PRIV));
                found = PR_TRUE;
            }
            if ((classFlags & LG_PUBLIC) && !isSecretKey(privKey)) {
                lg_addHandle(search,
                             lg_mkHandle(sdb, key_id, LG_TOKEN_TYPE_PUB));
                found = PR_TRUE;
            }
            lg_nsslowkey_DestroyPrivateKey(privKey);
        }
        /* don't do the traversal if we have an up to date db */
        if (keyHandle->version != 3) {
            goto loser;
        }
        /* don't do the traversal if it can't possibly be the correct id */
        /* all soft token id's are SHA1_HASH_LEN's */
        if (key_id->len != SHA1_LENGTH) {
            goto loser;
        }
        if (found) {
            /* if we already found some keys, don't do the traversal */
            goto loser;
        }
    }
    keyData.sdb = sdb;
    keyData.keyHandle = keyHandle;
    keyData.searchHandles = search;
    keyData.id = key_id;
    keyData.template = pTemplate;
    keyData.templ_count = ulCount;
    keyData.classFlags = classFlags;
    keyData.strict = mustStrict ? mustStrict : LG_STRICT;

    nsslowkey_TraverseKeys(keyHandle, lg_key_collect, &keyData);

loser:
    return;
}

/*
 * structure to collect certs into
 */

typedef struct lgCertDataStr {
    SDB *sdb;
    int cert_count;
    int max_cert_count;
    NSSLOWCERTCertificate **certs;
    const CK_ATTRIBUTE *template;
    CK_ULONG templ_count;
    unsigned long classFlags;
    PRBool strict;
} lgCertData;

/*
 * collect all the certs from the traverse call.
 */

static SECStatus
lg_cert_collect(NSSLOWCERTCertificate *cert, void *arg)
{
    lgCertData *cd = (lgCertData *)arg;

    if (cert == NULL) {
        return SECSuccess;
    }

    if (cd->certs == NULL) {
        return SECFailure;
    }

    if (cd->strict) {
        if ((cd->classFlags & LG_CERT) &&
            !lg_tokenMatch(cd->sdb, &cert->certKey, LG_TOKEN_TYPE_CERT, cd->template, cd->templ_count)) {
            return SECSuccess;
        }
        if ((cd->classFlags & LG_TRUST) &&
            !lg_tokenMatch(cd->sdb, &cert->certKey, LG_TOKEN_TYPE_TRUST, cd->template, cd->templ_count)) {
            return SECSuccess;
        }
    }

    /* allocate more space if we need it. This should only happen in
     * the general traversal case */

    if (cd->cert_count >= cd->max_cert_count) {
        int size;
        cd->max_cert_count += LG_SEARCH_BLOCK_SIZE;
        size = cd->max_cert_count * sizeof(NSSLOWCERTCertificate *);
        cd->certs = (NSSLOWCERTCertificate **)PORT_Realloc(cd->certs, size);
        if (cd->certs == NULL) {
            return SECFailure;
        }
    }

    cd->certs[cd->cert_count++] = nsslowcert_DupCertificate(cert);
    return SECSuccess;
}

/* provide impedence matching ... */
static SECStatus
lg_cert_collect2(NSSLOWCERTCertificate *cert, SECItem *dymmy, void *arg)
{
    return lg_cert_collect(cert, arg);
}

static void
lg_searchSingleCert(lgCertData *certData, NSSLOWCERTCertificate *cert)
{
    if (cert == NULL) {
        return;
    }
    if (certData->strict &&
        !lg_tokenMatch(certData->sdb, &cert->certKey, LG_TOKEN_TYPE_CERT,
                       certData->template, certData->templ_count)) {
        nsslowcert_DestroyCertificate(cert);
        return;
    }
    certData->certs = (NSSLOWCERTCertificate **)
        PORT_Alloc(sizeof(NSSLOWCERTCertificate *));
    if (certData->certs == NULL) {
        nsslowcert_DestroyCertificate(cert);
        return;
    }
    certData->certs[0] = cert;
    certData->cert_count = 1;
}

static void
lg_CertSetupData(lgCertData *certData, int count)
{
    certData->max_cert_count = count;

    if (certData->max_cert_count <= 0) {
        return;
    }
    certData->certs = (NSSLOWCERTCertificate **)
        PORT_Alloc(count * sizeof(NSSLOWCERTCertificate *));
    return;
}

static void
lg_searchCertsAndTrust(SDB *sdb, SECItem *derCert, SECItem *name,
                       SECItem *derSubject, NSSLOWCERTIssuerAndSN *issuerSN,
                       SECItem *email,
                       unsigned long classFlags, SDBFind *handles,
                       const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
{
    NSSLOWCERTCertDBHandle *certHandle = NULL;
    lgCertData certData;
    int i;

    certHandle = lg_getCertDB(sdb);
    if (certHandle == NULL)
        return;

    certData.sdb = sdb;
    certData.max_cert_count = 0;
    certData.certs = NULL;
    certData.cert_count = 0;
    certData.template = pTemplate;
    certData.templ_count = ulCount;
    certData.classFlags = classFlags;
    certData.strict = LG_STRICT;

    /*
     * Find the Cert.
     */

    if (derCert->data != NULL) {
        NSSLOWCERTCertificate *cert =
            nsslowcert_FindCertByDERCert(certHandle, derCert);
        lg_searchSingleCert(&certData, cert);
    } else if (name->data != NULL) {
        char *tmp_name = (char *)PORT_Alloc(name->len + 1);
        int count;

        if (tmp_name == NULL) {
            return;
        }
        PORT_Memcpy(tmp_name, name->data, name->len);
        tmp_name[name->len] = 0;

        count = nsslowcert_NumPermCertsForNickname(certHandle, tmp_name);
        lg_CertSetupData(&certData, count);
        nsslowcert_TraversePermCertsForNickname(certHandle, tmp_name,
                                                lg_cert_collect, &certData);
        PORT_Free(tmp_name);
    } else if (derSubject->data != NULL) {
        int count;

        count = nsslowcert_NumPermCertsForSubject(certHandle, derSubject);
        lg_CertSetupData(&certData, count);
        nsslowcert_TraversePermCertsForSubject(certHandle, derSubject,
                                               lg_cert_collect, &certData);
    } else if ((issuerSN->derIssuer.data != NULL) &&
               (issuerSN->serialNumber.data != NULL)) {
        if (classFlags & LG_CERT) {
            NSSLOWCERTCertificate *cert =
                nsslowcert_FindCertByIssuerAndSN(certHandle, issuerSN);

            lg_searchSingleCert(&certData, cert);
        }
        if (classFlags & LG_TRUST) {
            NSSLOWCERTTrust *trust =
                nsslowcert_FindTrustByIssuerAndSN(certHandle, issuerSN);

            if (trust) {
                lg_addHandle(handles,
                             lg_mkHandle(sdb, &trust->dbKey, LG_TOKEN_TYPE_TRUST));
                nsslowcert_DestroyTrust(trust);
            }
        }
    } else if (email->data != NULL) {
        char *tmp_name = (char *)PORT_Alloc(email->len + 1);
        certDBEntrySMime *entry = NULL;

        if (tmp_name == NULL) {
            return;
        }
        PORT_Memcpy(tmp_name, email->data, email->len);
        tmp_name[email->len] = 0;

        entry = nsslowcert_ReadDBSMimeEntry(certHandle, tmp_name);
        if (entry) {
            int count;
            SECItem *subjectName = &entry->subjectName;

            count = nsslowcert_NumPermCertsForSubject(certHandle, subjectName);
            lg_CertSetupData(&certData, count);
            nsslowcert_TraversePermCertsForSubject(certHandle, subjectName,
                                                   lg_cert_collect, &certData);

            nsslowcert_DestroyDBEntry((certDBEntry *)entry);
        }
        PORT_Free(tmp_name);
    } else {
        /* we aren't filtering the certs, we are working on all, so turn
         * on the strict filters. */

        certData.strict = PR_TRUE;
        lg_CertSetupData(&certData, LG_SEARCH_BLOCK_SIZE);
        nsslowcert_TraversePermCerts(certHandle, lg_cert_collect2, &certData);
    }

    /*
     * build the handles
     */

    for (i = 0; i < certData.cert_count; i++) {
        NSSLOWCERTCertificate *cert = certData.certs[i];

        /* if we filtered it would have been on the stuff above */
        if (classFlags & LG_CERT) {
            lg_addHandle(handles,
                         lg_mkHandle(sdb, &cert->certKey, LG_TOKEN_TYPE_CERT));
        }
        if ((classFlags & LG_TRUST) && nsslowcert_hasTrust(cert->trust)) {
            lg_addHandle(handles,
                         lg_mkHandle(sdb, &cert->certKey, LG_TOKEN_TYPE_TRUST));
        }
        nsslowcert_DestroyCertificate(cert);
    }

    if (certData.certs)
        PORT_Free(certData.certs);
    return;
}

static SECStatus
lg_smime_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg)
{
    lgEntryData *smimeData;
    SDB *sdb;

    smimeData = (lgEntryData *)arg;
    sdb = smimeData->sdb;

    if (lg_tokenMatch(sdb, key, LG_TOKEN_TYPE_SMIME,
                      smimeData->template, smimeData->templ_count)) {
        lg_addHandle(smimeData->searchHandles,
                     lg_mkHandle(sdb, key, LG_TOKEN_TYPE_SMIME));
    }
    return (SECSuccess);
}

static void
lg_searchSMime(SDB *sdb, SECItem *email, SDBFind *handles,
               const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
{
    NSSLOWCERTCertDBHandle *certHandle = NULL;
    certDBEntrySMime *entry;

    certHandle = lg_getCertDB(sdb);
    if (certHandle == NULL)
        return;

    if (email->data != NULL) {
        char *tmp_name = (char *)PORT_Alloc(email->len + 1);

        if (tmp_name == NULL) {
            return;
        }
        PORT_Memcpy(tmp_name, email->data, email->len);
        tmp_name[email->len] = 0;

        entry = nsslowcert_ReadDBSMimeEntry(certHandle, tmp_name);
        if (entry) {
            SECItem emailKey;

            emailKey.data = (unsigned char *)tmp_name;
            emailKey.len = PORT_Strlen(tmp_name) + 1;
            emailKey.type = 0;
            lg_addHandle(handles,
                         lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME));
            nsslowcert_DestroyDBEntry((certDBEntry *)entry);
        }
        PORT_Free(tmp_name);
    } else {
        /* traverse */
        lgEntryData smimeData;

        /* traverse */
        smimeData.sdb = sdb;
        smimeData.searchHandles = handles;
        smimeData.template = pTemplate;
        smimeData.templ_count = ulCount;
        nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeSMimeProfile,
                                     lg_smime_collect, (void *)&smimeData);
    }
    return;
}

static CK_RV
lg_searchTokenList(SDB *sdb, SDBFind *search,
                   const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
{
    int i;
    PRBool isKrl = PR_FALSE;
    SECItem derCert = { siBuffer, NULL, 0 };
    SECItem derSubject = { siBuffer, NULL, 0 };
    SECItem name = { siBuffer, NULL, 0 };
    SECItem email = { siBuffer, NULL, 0 };
    SECItem key_id = { siBuffer, NULL, 0 };
    SECItem cert_sha1_hash = { siBuffer, NULL, 0 };
    SECItem cert_md5_hash = { siBuffer, NULL, 0 };
    NSSLOWCERTIssuerAndSN issuerSN = {
        { siBuffer, NULL, 0 },
        { siBuffer, NULL, 0 }
    };
    SECItem *copy = NULL;
    CK_CERTIFICATE_TYPE certType;
    CK_OBJECT_CLASS objectClass;
    CK_RV crv;
    unsigned long classFlags;

    if (lg_getCertDB(sdb) == NULL) {
        classFlags = LG_PRIVATE | LG_KEY;
    } else {
        classFlags = LG_CERT | LG_TRUST | LG_PUBLIC | LG_SMIME | LG_CRL;
    }

    /*
     * look for things to search on token objects for. If the right options
     * are specified, we can use them as direct indeces into the database
     * (rather than using linear searches. We can also use the attributes to
     * limit the kinds of objects we are searching for. Later we can use this
     * array to filter the remaining objects more finely.
     */

    for (i = 0; classFlags && i < (int)ulCount; i++) {

        switch (pTemplate[i].type) {
            case CKA_SUBJECT:
                copy = &derSubject;
                classFlags &= (LG_CERT | LG_PRIVATE | LG_PUBLIC | LG_SMIME | LG_CRL);
                break;
            case CKA_ISSUER:
                copy = &issuerSN.derIssuer;
                classFlags &= (LG_CERT | LG_TRUST);
                break;
            case CKA_SERIAL_NUMBER:
                copy = &issuerSN.serialNumber;
                classFlags &= (LG_CERT | LG_TRUST);
                break;
            case CKA_VALUE:
                copy = &derCert;
                classFlags &= (LG_CERT | LG_CRL | LG_SMIME);
                break;
            case CKA_LABEL:
                copy = &name;
                break;
            case CKA_NSS_EMAIL:
                copy = &email;
                classFlags &= LG_SMIME | LG_CERT;
                break;
            case CKA_NSS_SMIME_TIMESTAMP:
                classFlags &= LG_SMIME;
                break;
            case CKA_CLASS:
                crv = lg_GetULongAttribute(CKA_CLASS, &pTemplate[i], 1, &objectClass);
                if (crv != CKR_OK) {
                    classFlags = 0;
                    break;
                }
                switch (objectClass) {
                    case CKO_CERTIFICATE:
                        classFlags &= LG_CERT;
                        break;
                    case CKO_NSS_TRUST:
                        classFlags &= LG_TRUST;
                        break;
                    case CKO_NSS_CRL:
                        classFlags &= LG_CRL;
                        break;
                    case CKO_NSS_SMIME:
                        classFlags &= LG_SMIME;
                        break;
                    case CKO_PRIVATE_KEY:
                        classFlags &= LG_PRIVATE;
                        break;
                    case CKO_PUBLIC_KEY:
                        classFlags &= LG_PUBLIC;
                        break;
                    case CKO_SECRET_KEY:
                        classFlags &= LG_KEY;
                        break;
                    default:
                        classFlags = 0;
                        break;
                }
                break;
            case CKA_PRIVATE:
                if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
                    classFlags = 0;
                    break;
                }
                if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
                    classFlags &= (LG_PRIVATE | LG_KEY);
                } else {
                    classFlags &= ~(LG_PRIVATE | LG_KEY);
                }
                break;
            case CKA_SENSITIVE:
                if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
                    classFlags = 0;
                    break;
                }
                if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
                    classFlags &= (LG_PRIVATE | LG_KEY);
                } else {
                    classFlags = 0;
                }
                break;
            case CKA_TOKEN:
                if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
                    classFlags = 0;
                    break;
                }
                if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) {
                    classFlags = 0;
                }
                break;
            case CKA_CERT_SHA1_HASH:
                classFlags &= LG_TRUST;
                copy = &cert_sha1_hash;
                break;
            case CKA_CERT_MD5_HASH:
                classFlags &= LG_TRUST;
                copy = &cert_md5_hash;
                break;
            case CKA_CERTIFICATE_TYPE:
                crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE, &pTemplate[i],
                                           1, &certType);
                if (crv != CKR_OK) {
                    classFlags = 0;
                    break;
                }
                classFlags &= LG_CERT;
                if (certType != CKC_X_509) {
                    classFlags = 0;
                }
                break;
            case CKA_ID:
                copy = &key_id;
                classFlags &= (LG_CERT | LG_PRIVATE | LG_KEY | LG_PUBLIC);
                break;
            case CKA_NSS_KRL:
                if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
                    classFlags = 0;
                    break;
                }
                classFlags &= LG_CRL;
                isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE);
                break;
            case CKA_MODIFIABLE:
                break;
            case CKA_KEY_TYPE:
            case CKA_DERIVE:
                classFlags &= LG_PUBLIC | LG_PRIVATE | LG_KEY;
                break;
            case CKA_VERIFY_RECOVER:
                classFlags &= LG_PUBLIC;
                break;
            case CKA_SIGN_RECOVER:
                classFlags &= LG_PRIVATE;
                break;
            case CKA_ENCRYPT:
            case CKA_VERIFY:
            case CKA_WRAP:
                classFlags &= LG_PUBLIC | LG_KEY;
                break;
            case CKA_DECRYPT:
            case CKA_SIGN:
            case CKA_UNWRAP:
            case CKA_ALWAYS_SENSITIVE:
            case CKA_EXTRACTABLE:
            case CKA_NEVER_EXTRACTABLE:
                classFlags &= LG_PRIVATE | LG_KEY;
                break;
            /* can't be a certificate if it doesn't match one of the above
             * attributes */

            default:
                classFlags = 0;
                break;
        }
        if (copy) {
            copy->data = (unsigned char *)pTemplate[i].pValue;
            copy->len = pTemplate[i].ulValueLen;
        }
        copy = NULL;
    }

    /* certs */
    if (classFlags & (LG_CERT | LG_TRUST)) {
        lg_searchCertsAndTrust(sdb, &derCert, &name, &derSubject,
                               &issuerSN, &email, classFlags, search,
                               pTemplate, ulCount);
    }

    /* keys */
    if (classFlags & (LG_PRIVATE | LG_PUBLIC | LG_KEY)) {
        PRBool mustStrict = (name.len != 0);
        lg_searchKeys(sdb, &key_id, classFlags, search,
                      mustStrict, pTemplate, ulCount);
    }

    /* crl's */
    if (classFlags & LG_CRL) {
        lg_searchCrls(sdb, &derSubject, isKrl, classFlags, search,
                      pTemplate, ulCount);
    }
    /* Add S/MIME entry stuff */
    if (classFlags & LG_SMIME) {
        lg_searchSMime(sdb, &email, search, pTemplate, ulCount);
    }
    return CKR_OK;
}

/* lg_FindObjectsInit initializes a search for token and session objects
 * that match a template. */

CK_RV
lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate,
                   CK_ULONG ulCount, SDBFind **retSearch)
{
    SDBFind *search;
    CK_RV crv = CKR_OK;

    *retSearch = NULL;

    search = (SDBFind *)PORT_Alloc(sizeof(SDBFind));
    if (search == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }
    search->handles = (CK_OBJECT_HANDLE *)
        PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * LG_SEARCH_BLOCK_SIZE);
    if (search->handles == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }
    search->index = 0;
    search->size = 0;
    search->array_size = LG_SEARCH_BLOCK_SIZE;
    /* FIXME - do we still need to get Login state? */

    crv = lg_searchTokenList(sdb, search, pTemplate, ulCount);
    if (crv != CKR_OK) {
        goto loser;
    }

    *retSearch = search;
    return CKR_OK;

loser:
    if (search) {
        lg_FreeSearch(search);
    }
    return crv;
}

/* lg_FindObjects continues a search for token and session objects
 * that match a template, obtaining additional object handles. */

CK_RV
lg_FindObjects(SDB *sdb, SDBFind *search,
               CK_OBJECT_HANDLE *phObject, CK_ULONG ulMaxObjectCount,
               CK_ULONG *pulObjectCount)
{
    int transfer;
    int left;

    *pulObjectCount = 0;
    left = search->size - search->index;
    transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount;
    if (transfer > 0) {
        PORT_Memcpy(phObject, &search->handles[search->index],
                    transfer * sizeof(CK_OBJECT_HANDLE));
    } else {
        *phObject = CK_INVALID_HANDLE;
    }

    search->index += transfer;
    *pulObjectCount = transfer;
    return CKR_OK;
}

/* lg_FindObjectsFinal finishes a search for token and session objects. */
CK_RV
lg_FindObjectsFinal(SDB *lgdb, SDBFind *search)
{

    if (search != NULL) {
        lg_FreeSearch(search);
    }
    return CKR_OK;
}

Messung V0.5
C=97 H=95 G=95

¤ Dauer der Verarbeitung: 0.12 Sekunden  ¤

*© 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