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