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

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


enum {
    dbInvalidCert = 0,
    dbNoSMimeProfile,
    dbOlderCert,
    dbBadCertificate,
    dbCertNotWrittenToDB
};

typedef struct dbRestoreInfoStr {
    NSSLOWCERTCertDBHandle *handle;
    PRBool verbose;
    PRFileDesc *out;
    int nCerts;
    int nOldCerts;
    int dbErrors[5];
    PRBool removeType[3];
    PRBool promptUser[3];
} dbRestoreInfo;

char *
IsEmailCert(CERTCertificate *cert)
{
    char *email, *tmp1, *tmp2;
    PRBool isCA;
    int len;

    if (!cert->subjectName) {
        return NULL;
    }

    tmp1 = PORT_Strstr(cert->subjectName, "E=");
    tmp2 = PORT_Strstr(cert->subjectName, "MAIL=");
    /* XXX Nelson has cert for KTrilli which does not have either
     * of above but is email cert (has cert->emailAddr).
     */

    if (!tmp1 && !tmp2 && !(cert->emailAddr && cert->emailAddr[0])) {
        return NULL;
    }

    /*  Server or CA cert, not personal email.  */
    isCA = CERT_IsCACert(cert, NULL);
    if (isCA)
        return NULL;

    /*  XXX CERT_IsCACert advertises checking the key usage ext.,
        but doesn't appear to. */

    /*  Check the key usage extension.  */
    if (cert->keyUsagePresent) {
        /*  Must at least be able to sign or encrypt (not neccesarily
         *  both if it is one of a dual cert).
         */

        if (!((cert->rawKeyUsage & KU_DIGITAL_SIGNATURE) ||
              (cert->rawKeyUsage & KU_KEY_ENCIPHERMENT)))
            return NULL;

        /*  CA cert, not personal email.  */
        if (cert->rawKeyUsage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN))
            return NULL;
    }

    if (cert->emailAddr && cert->emailAddr[0]) {
        email = PORT_Strdup(cert->emailAddr);
    } else {
        if (tmp1)
            tmp1 += 2; /* "E="  */
        else
            tmp1 = tmp2 + 5; /* "MAIL=" */
        len = strcspn(tmp1, ", ");
        email = (char *)PORT_Alloc(len + 1);
        PORT_Strncpy(email, tmp1, len);
        email[len] = '\0';
    }

    return email;
}

SECStatus
deleteit(CERTCertificate *cert, void *arg)
{
    return SEC_DeletePermCertificate(cert);
}

/*  Different than DeleteCertificate - has the added bonus of removing
 *  all certs with the same DN.
 */

SECStatus
deleteAllEntriesForCert(NSSLOWCERTCertDBHandle *handle, CERTCertificate *cert,
                        PRFileDesc *outfile)
{
#if 0
    certDBEntrySubject *subjectEntry;
    certDBEntryNickname *nicknameEntry;
    certDBEntrySMime *smimeEntry;
    int i;
#endif

    if (outfile) {
        PR_fprintf(outfile, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n");
        PR_fprintf(outfile, "Deleting redundant certificate:\n");
        dumpCertificate(cert, -1, outfile);
    }

    CERT_TraverseCertsForSubject(handle, cert->subjectList, deleteit, NULL);
#if 0
    CERT_LockDB(handle);
    subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
    /*  It had better be there, or created a bad db.  */
    PORT_Assert(subjectEntry);
    for (i=0; i<subjectEntry->ncerts; i++) {
        DeleteDBCertEntry(handle, &subjectEntry->certKeys[i]);
    }
    DeleteDBSubjectEntry(handle, &cert->derSubject);
    if (subjectEntry->emailAddr && subjectEntry->emailAddr[0]) {
        smimeEntry = ReadDBSMimeEntry(handle, subjectEntry->emailAddr);
        if (smimeEntry) {
            if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
                                      &smimeEntry->subjectName))
                /*  Only delete it if it's for this subject!  */
                DeleteDBSMimeEntry(handle, subjectEntry->emailAddr);
            SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
        }
    }
    if (subjectEntry->nickname) {
        nicknameEntry = ReadDBNicknameEntry(handle, subjectEntry->nickname);
        if (nicknameEntry) {
            if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
                                      &nicknameEntry->subjectName))
                /*  Only delete it if it's for this subject!  */
                DeleteDBNicknameEntry(handle, subjectEntry->nickname);
            SEC_DestroyDBEntry((certDBEntry*)nicknameEntry);
        }
    }
    SEC_DestroyDBEntry((certDBEntry*)subjectEntry);
    CERT_UnlockDB(handle);
#endif
    return SECSuccess;
}

void
getCertsToDelete(char *numlist, int len, int *certNums, int nCerts)
{
    int j, num;
    char *numstr, *numend, *end;

    numstr = numlist;
    end = numstr + len - 1;
    while (numstr != end) {
        numend = strpbrk(numstr, ", \n");
        *numend = '\0';
        if (PORT_Strlen(numstr) == 0)
            return;
        num = PORT_Atoi(numstr);
        if (numstr == numlist)
            certNums[0] = num;
        for (j = 1; j < nCerts + 1; j++) {
            if (num == certNums[j]) {
                certNums[j] = -1;
                break;
            }
        }
        if (numend == end)
            break;
        numstr = strpbrk(numend + 1, "0123456789");
    }
}

PRBool
userSaysDeleteCert(CERTCertificate **certs, int nCerts,
                   int errtype, dbRestoreInfo *info, int *certNums)
{
    char response[32];
    PRInt32 nb;
    int i;
    /*  User wants to remove cert without prompting.  */
    if (info->promptUser[errtype] == PR_FALSE)
        return (info->removeType[errtype]);
    switch (errtype) {
        case dbInvalidCert:
            PR_fprintf(PR_STDOUT, "******** Expired ********\n");
            PR_fprintf(PR_STDOUT, "Cert has expired.\n\n");
            dumpCertificate(certs[0], -1, PR_STDOUT);
            PR_fprintf(PR_STDOUT,
                       "Keep it? (y/n - this one, Y/N - all expired certs) [n] ");
            break;
        case dbNoSMimeProfile:
            PR_fprintf(PR_STDOUT, "******** No Profile ********\n");
            PR_fprintf(PR_STDOUT, "S/MIME cert has no profile.\n\n");
            dumpCertificate(certs[0], -1, PR_STDOUT);
            PR_fprintf(PR_STDOUT,
                       "Keep it? (y/n - this one, Y/N - all S/MIME w/o profile) [n] ");
            break;
        case dbOlderCert:
            PR_fprintf(PR_STDOUT, "******* Redundant nickname/email *******\n\n");
            PR_fprintf(PR_STDOUT, "These certs have the same nickname/email:\n");
            for (i = 0; i < nCerts; i++)
                dumpCertificate(certs[i], i, PR_STDOUT);
            PR_fprintf(PR_STDOUT,
                       "Enter the certs you would like to keep from those listed above.\n");
            PR_fprintf(PR_STDOUT,
                       "Use a comma-separated list of the cert numbers (ex. 0, 8, 12).\n");
            PR_fprintf(PR_STDOUT,
                       "The first cert in the list will be the primary cert\n");
            PR_fprintf(PR_STDOUT,
                       " accessed by the nickname/email handle.\n");
            PR_fprintf(PR_STDOUT,
                       "List cert numbers to keep here, or hit enter\n");
            PR_fprintf(PR_STDOUT,
                       " to always keep only the newest cert: ");
            break;
        default:
    }
    nb = PR_Read(PR_STDIN, response, sizeof(response));
    PR_fprintf(PR_STDOUT, "\n\n");
    if (errtype == dbOlderCert) {
        if (!isdigit((unsigned char)response[0])) {
            info->promptUser[errtype] = PR_FALSE;
            info->removeType[errtype] = PR_TRUE;
            return PR_TRUE;
        }
        getCertsToDelete(response, nb, certNums, nCerts);
        return PR_TRUE;
    }
    /*  User doesn't want to be prompted for this type anymore.  */
    if (response[0] == 'Y') {
        info->promptUser[errtype] = PR_FALSE;
        info->removeType[errtype] = PR_FALSE;
        return PR_FALSE;
    } else if (response[0] == 'N') {
        info->promptUser[errtype] = PR_FALSE;
        info->removeType[errtype] = PR_TRUE;
        return PR_TRUE;
    }
    return (response[0] != 'y') ? PR_TRUE : PR_FALSE;
}

SECStatus
addCertToDB(certDBEntryCert *certEntry, dbRestoreInfo *info,
            NSSLOWCERTCertDBHandle *oldhandle)
{
    SECStatus rv = SECSuccess;
    PRBool allowOverride;
    PRBool userCert;
    SECCertTimeValidity validity;
    CERTCertificate *oldCert = NULL;
    CERTCertificate *dbCert = NULL;
    CERTCertificate *newCert = NULL;
    CERTCertTrust *trust;
    certDBEntrySMime *smimeEntry = NULL;
    char *email = NULL;
    char *nickname = NULL;
    int nCertsForSubject = 1;

    oldCert = CERT_DecodeDERCertificate(&certEntry->derCert, PR_FALSE,
                                        certEntry->nickname);
    if (!oldCert) {
        info->dbErrors[dbBadCertificate]++;
        SEC_DestroyDBEntry((certDBEntry *)certEntry);
        return SECSuccess;
    }

    oldCert->dbEntry = certEntry;
    oldCert->trust = &certEntry->trust;
    oldCert->dbhandle = oldhandle;

    trust = oldCert->trust;

    info->nOldCerts++;

    if (info->verbose)
        PR_fprintf(info->out, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n");

    if (oldCert->nickname)
        nickname = PORT_Strdup(oldCert->nickname);

    /*  Always keep user certs.  Skip ahead.  */
    /*  XXX if someone sends themselves a signed message, it is possible
        for their cert to be imported as an "other" cert, not a user cert.
        this mucks with smime entries...  */

    userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
               (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
               (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
    if (userCert)
        goto createcert;

    /*  If user chooses so, ignore expired certificates.  */
    allowOverride = (PRBool)((oldCert->keyUsage == certUsageSSLServer) ||
                             (oldCert->keyUsage == certUsageSSLServerWithStepUp) ||
                             (oldCert->keyUsage == certUsageIPsec));
    validity = CERT_CheckCertValidTimes(oldCert, PR_Now(), allowOverride);
    /*  If cert expired and user wants to delete it, ignore it. */
    if ((validity != secCertTimeValid) &&
        userSaysDeleteCert(&oldCert, 1, dbInvalidCert, info, 0)) {
        info->dbErrors[dbInvalidCert]++;
        if (info->verbose) {
            PR_fprintf(info->out, "Deleting expired certificate:\n");
            dumpCertificate(oldCert, -1, info->out);
        }
        goto cleanup;
    }

    /*  New database will already have default certs, don't attempt
        to overwrite them.  */

    dbCert = CERT_FindCertByDERCert(info->handle, &oldCert->derCert);
    if (dbCert) {
        info->nCerts++;
        if (info->verbose) {
            PR_fprintf(info->out, "Added certificate to database:\n");
            dumpCertificate(oldCert, -1, info->out);
        }
        goto cleanup;
    }

    /*  Determine if cert is S/MIME and get its email if so.  */
    email = IsEmailCert(oldCert);

    /*
        XXX  Just create empty profiles?
    if (email) {
        SECItem *profile = CERT_FindSMimeProfile(oldCert);
        if (!profile &&
            userSaysDeleteCert(&oldCert, 1, dbNoSMimeProfile, info, 0)) {
            info->dbErrors[dbNoSMimeProfile]++;
            if (info->verbose) {
                PR_fprintf(info->out,
                           "Deleted cert missing S/MIME profile.\n");
                dumpCertificate(oldCert, -1, info->out);
            }
            goto cleanup;
        } else {
            SECITEM_FreeItem(profile);
        }
    }
    */


createcert:

    /*  Sometimes happens... */
    if (!nickname && userCert)
        nickname = PORT_Strdup(oldCert->subjectName);

    /*  Create a new certificate, copy of the old one.  */
    newCert = CERT_NewTempCertificate(info->handle, &oldCert->derCert,
                                      nickname, PR_FALSE, PR_TRUE);
    if (!newCert) {
        PR_fprintf(PR_STDERR, "Unable to create new certificate.\n");
        dumpCertificate(oldCert, -1, PR_STDERR);
        info->dbErrors[dbBadCertificate]++;
        goto cleanup;
    }

    /*  Add the cert to the new database.  */
    rv = CERT_AddTempCertToPerm(newCert, nickname, oldCert->trust);
    if (rv) {
        PR_fprintf(PR_STDERR, "Failed to write temp cert to perm database.\n");
        dumpCertificate(oldCert, -1, PR_STDERR);
        info->dbErrors[dbCertNotWrittenToDB]++;
        goto cleanup;
    }

    if (info->verbose) {
        PR_fprintf(info->out, "Added certificate to database:\n");
        dumpCertificate(oldCert, -1, info->out);
    }

    /*  If the cert is an S/MIME cert, and the first with it's subject,
     *  modify the subject entry to include the email address,
     *  CERT_AddTempCertToPerm does not do email addresses and S/MIME entries.
     */

    if (smimeEntry) { /*&& !userCert && nCertsForSubject == 1) { */
#if 0
        UpdateSubjectWithEmailAddr(newCert, email);
#endif
        SECItem emailProfile, profileTime;
        rv = CERT_FindFullSMimeProfile(oldCert, &emailProfile, &profileTime);
        /*  calls UpdateSubjectWithEmailAddr  */
        if (rv == SECSuccess)
            rv = CERT_SaveSMimeProfile(newCert, &emailProfile, &profileTime);
    }

    info->nCerts++;

cleanup:

    if (nickname)
        PORT_Free(nickname);
    if (email)
        PORT_Free(email);
    if (oldCert)
        CERT_DestroyCertificate(oldCert);
    if (dbCert)
        CERT_DestroyCertificate(dbCert);
    if (newCert)
        CERT_DestroyCertificate(newCert);
    if (smimeEntry)
        SEC_DestroyDBEntry((certDBEntry *)smimeEntry);
    return SECSuccess;
}

#if 0
SECStatus
copyDBEntry(SECItem *data, SECItem *key, certDBEntryType type, void *pdata)
{
    SECStatus rv;
    NSSLOWCERTCertDBHandle *newdb = (NSSLOWCERTCertDBHandle *)pdata;
    certDBEntryCommon common;
    SECItem dbkey;

    common.type = type;
    common.version = CERT_DB_FILE_VERSION;
    common.flags = data->data[2];
    common.arena = NULL;

    dbkey.len = key->len + SEC_DB_KEY_HEADER_LEN;
    dbkey.data = (unsigned char *)PORT_Alloc(dbkey.len*sizeof(unsigned char));
    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], key->data, key->len);
    dbkey.data[0] = type;

    rv = WriteDBEntry(newdb, &common, &dbkey, data);

    PORT_Free(dbkey.data);
    return rv;
}
#endif

int
certIsOlder(CERTCertificate **cert1, CERTCertificate **cert2)
{
    return !CERT_IsNewer(*cert1, *cert2);
}

int
findNewestSubjectForEmail(NSSLOWCERTCertDBHandle *handle, int subjectNum,
                          certDBArray *dbArray, dbRestoreInfo *info,
                          int *subjectWithSMime, int *smimeForSubject)
{
    int newestSubject;
    int subjectsForEmail[50];
    int i, j, ns, sNum;
    certDBEntryListNode *subjects = &dbArray->subjects;
    certDBEntryListNode *smime = &dbArray->smime;
    certDBEntrySubject *subjectEntry1, *subjectEntry2;
    certDBEntrySMime *smimeEntry;
    CERTCertificate **certs;
    CERTCertificate *cert;
    CERTCertTrust *trust;
    PRBool userCert;
    int *certNums;

    ns = 0;
    subjectEntry1 = (certDBEntrySubject *)&subjects.entries[subjectNum];
    subjectsForEmail[ns++] = subjectNum;

    *subjectWithSMime = -1;
    *smimeForSubject = -1;
    newestSubject = subjectNum;

    cert = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
    if (cert) {
        trust = cert->trust;
        userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
                   (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
                   (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
        CERT_DestroyCertificate(cert);
    }

    /*
     * XXX Should we make sure that subjectEntry1->emailAddr is not
     * a null pointer or an empty string before going into the next
     * two for loops, which pass it to PORT_Strcmp?
     */


    /*  Loop over the remaining subjects.  */
    for (i = subjectNum + 1; i < subjects.numEntries; i++) {
        subjectEntry2 = (certDBEntrySubject *)&subjects.entries[i];
        if (!subjectEntry2)
            continue;
        if (subjectEntry2->emailAddr && subjectEntry2->emailAddr[0] &&
            PORT_Strcmp(subjectEntry1->emailAddr,
                        subjectEntry2->emailAddr) == 0) {
            /*  Found a subject using the same email address.  */
            subjectsForEmail[ns++] = i;
        }
    }

    /*  Find the S/MIME entry for this email address.  */
    for (i = 0; i < smime.numEntries; i++) {
        smimeEntry = (certDBEntrySMime *)&smime.entries[i];
        if (smimeEntry->common.arena == NULL)
            continue;
        if (smimeEntry->emailAddr && smimeEntry->emailAddr[0] &&
            PORT_Strcmp(subjectEntry1->emailAddr, smimeEntry->emailAddr) == 0) {
            /*  Find which of the subjects uses this S/MIME entry.  */
            for (j = 0; j < ns && *subjectWithSMime < 0; j++) {
                sNum = subjectsForEmail[j];
                subjectEntry2 = (certDBEntrySubject *)&subjects.entries[sNum];
                if (SECITEM_ItemsAreEqual(&smimeEntry->subjectName,
                                          &subjectEntry2->derSubject)) {
                    /*  Found the subject corresponding to the S/MIME entry. */
                    *subjectWithSMime = sNum;
                    *smimeForSubject = i;
                }
            }
            SEC_DestroyDBEntry((certDBEntry *)smimeEntry);
            PORT_Memset(smimeEntry, 0, sizeof(certDBEntry));
            break;
        }
    }

    if (ns <= 1)
        return subjectNum;

    if (userCert)
        return *subjectWithSMime;

    /*  Now find which of the subjects has the newest cert.  */
    certs = (CERTCertificate **)PORT_Alloc(ns * sizeof(CERTCertificate *));
    certNums = (int *)PORT_Alloc((ns + 1) * sizeof(int));
    certNums[0] = 0;
    for (i = 0; i < ns; i++) {
        sNum = subjectsForEmail[i];
        subjectEntry1 = (certDBEntrySubject *)&subjects.entries[sNum];
        certs[i] = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
        certNums[i + 1] = i;
    }
    /*  Sort the array by validity.  */
    qsort(certs, ns, sizeof(CERTCertificate *),
          (int (*)(const void *, const void *))certIsOlder);
    newestSubject = -1;
    for (i = 0; i < ns; i++) {
        sNum = subjectsForEmail[i];
        subjectEntry1 = (certDBEntrySubject *)&subjects.entries[sNum];
        if (SECITEM_ItemsAreEqual(&subjectEntry1->derSubject,
                                  &certs[0]->derSubject))
            newestSubject = sNum;
        else
            SEC_DestroyDBEntry((certDBEntry *)subjectEntry1);
    }
    if (info && userSaysDeleteCert(certs, ns, dbOlderCert, info, certNums)) {
        for (i = 1; i < ns + 1; i++) {
            if (certNums[i] >= 0 && certNums[i] != certNums[0]) {
                deleteAllEntriesForCert(handle, certs[certNums[i]], info->out);
                info->dbErrors[dbOlderCert]++;
            }
        }
    }
    CERT_DestroyCertArray(certs, ns);
    return newestSubject;
}

NSSLOWCERTCertDBHandle *
DBCK_ReconstructDBFromCerts(NSSLOWCERTCertDBHandle *oldhandle, char *newdbname,
                            PRFileDesc *outfile, PRBool removeExpired,
                            PRBool requireProfile, PRBool singleEntry,
                            PRBool promptUser)
{
    SECStatus rv;
    dbRestoreInfo info;
    certDBEntryContentVersion *oldContentVersion;
    certDBArray dbArray;
    int i;

    PORT_Memset(&dbArray, 0, sizeof(dbArray));
    PORT_Memset(&info, 0, sizeof(info));
    info.verbose = (outfile) ? PR_TRUE : PR_FALSE;
    info.out = (outfile) ? outfile : PR_STDOUT;
    info.removeType[dbInvalidCert] = removeExpired;
    info.removeType[dbNoSMimeProfile] = requireProfile;
    info.removeType[dbOlderCert] = singleEntry;
    info.promptUser[dbInvalidCert] = promptUser;
    info.promptUser[dbNoSMimeProfile] = promptUser;
    info.promptUser[dbOlderCert] = promptUser;

    /*  Allocate a handle to fill with CERT_OpenCertDB below.  */
    info.handle = PORT_ZNew(NSSLOWCERTCertDBHandle);
    if (!info.handle) {
        fprintf(stderr, "unable to get database handle");
        return NULL;
    }

    /*  Create a certdb with the most recent set of roots.  */
    rv = CERT_OpenCertDBFilename(info.handle, newdbname, PR_FALSE);

    if (rv) {
        fprintf(stderr, "could not open certificate database");
        goto loser;
    }

    /*  Create certificate, subject, nickname, and email records.
     *  mcom_db seems to have a sequential access bug.  Though reads and writes
     *  should be allowed during traversal, they seem to screw up the sequence.
     *  So, stuff all the cert entries into an array, and loop over the array
     *  doing read/writes in the db.
     */

    fillDBEntryArray(oldhandle, certDBEntryTypeCert, &dbArray.certs);
    for (elem = PR_LIST_HEAD(&dbArray->certs.link);
         elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) {
        node = LISTNODE_CAST(elem);
        addCertToDB((certDBEntryCert *)&node->entry, &info, oldhandle);
        /* entries get destroyed in addCertToDB */
    }
#if 0
    rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeSMimeProfile,
                               copyDBEntry, info.handle);
#endif

/*  Fix up the pointers between (nickname|S/MIME) --> (subject).
 *  Create S/MIME entries for S/MIME certs.
 *  Have the S/MIME entry point to the last-expiring cert using
 *  an email address.
 */

#if 0
    CERT_RedoHandlesForSubjects(info.handle, singleEntry, &info);
#endif

    freeDBEntryList(&dbArray.certs.link);

/*  Copy over the version record.  */
/*  XXX Already exists - and _must_ be correct... */
/*
    versionEntry = ReadDBVersionEntry(oldhandle);
    rv = WriteDBVersionEntry(info.handle, versionEntry);
    */


/*  Copy over the content version record.  */
/*  XXX Can probably get useful info from old content version?
 *      Was this db created before/after this tool?  etc.
 */

#if 0
    oldContentVersion = ReadDBContentVersionEntry(oldhandle);
    CERT_SetDBContentVersion(oldContentVersion->contentVersion, info.handle);
#endif

#if 0
    /*  Copy over the CRL & KRL records.  */
    rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeRevocation,
                               copyDBEntry, info.handle);
    /*  XXX Only one KRL, just do db->get? */
    rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeKeyRevocation,
                               copyDBEntry, info.handle);
#endif

    PR_fprintf(info.out, "Database had %d certificates.\n", info.nOldCerts);

    PR_fprintf(info.out, "Reconstructed %d certificates.\n", info.nCerts);
    PR_fprintf(info.out, "(ax) Rejected %d expired certificates.\n",
               info.dbErrors[dbInvalidCert]);
    PR_fprintf(info.out, "(as) Rejected %d S/MIME certificates missing a profile.\n",
               info.dbErrors[dbNoSMimeProfile]);
    PR_fprintf(info.out, "(ar) Rejected %d certificates for which a newer certificate was found.\n",
               info.dbErrors[dbOlderCert]);
    PR_fprintf(info.out, " Rejected %d corrupt certificates.\n",
               info.dbErrors[dbBadCertificate]);
    PR_fprintf(info.out, " Rejected %d certificates which did not write to the DB.\n",
               info.dbErrors[dbCertNotWrittenToDB]);

    if (rv)
        goto loser;

    return info.handle;

loser:
    if (info.handle)
        PORT_Free(info.handle);
    return NULL;
}

Messung V0.5
C=93 H=80 G=86

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