⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbck.c

📁 支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509v3证书等安全协议或标准的开发库编译用到NSPR
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//*** dbck.c**** utility for fixing corrupt cert databases***/#include <stdio.h>#include <string.h>#include "secutil.h"#include "cdbhdl.h"#include "certdb.h"#include "cert.h"#include "nspr.h"#include "prtypes.h"#include "prtime.h"#include "prlong.h"static char *progName;/* placeholders for pointer error types */static void *WrongEntry;static void *NoNickname;static void *NoSMime;enum {    GOBOTH = 0,    GORIGHT,    GOLEFT};typedef struct{    PRBool verbose;    PRBool dograph;    PRFileDesc *out;    PRFileDesc *graphfile;    int dbErrors[10];} dbDebugInfo;/* * A list node for a cert db entry.  The index is a unique identifier * to use for creating generic maps of a db.  This struct handles * the cert, nickname, and smime db entry types, as all three have a * single handle to a subject entry. * This structure is pointed to by certDBEntryListNode->appData. */typedef struct {    PRArenaPool *arena;    int index;    certDBEntryListNode *pSubject;} certDBEntryMap;/* * Subject entry is special case, it has bidirectional handles.  One * subject entry can point to several certs (using the same DN), and * a nickname and/or smime entry. * This structure is pointed to by certDBEntryListNode->appData. */typedef struct{    PRArenaPool *arena;    int index;    int numCerts;    certDBEntryListNode **pCerts;    certDBEntryListNode *pNickname;    certDBEntryListNode *pSMime;} certDBSubjectEntryMap;/* * A map of a certdb. */typedef struct{    int numCerts;    int numSubjects;    int numNicknames;    int numSMime;    certDBEntryListNode certs;      /* pointer to head of cert list */    certDBEntryListNode subjects;   /* pointer to head of subject list */    certDBEntryListNode nicknames;  /* pointer to head of nickname list */    certDBEntryListNode smime;      /* pointer to head of smime list */} certDBArray;/* Cast list to the base element, a certDBEntryListNode. */#define LISTNODE_CAST(node) \    ((certDBEntryListNode *)(node))static void Usage(char *progName){#define FPS fprintf(stderr,     FPS "Type %s -H for more detailed descriptions\n", progName);    FPS "Usage:  %s -D [-d certdir] [-i dbname] [-m] [-v  [-f dumpfile]]\n", 	progName);    FPS "        %s -R -o newdbname [-d certdir] [-i dbname] [-aprsx] [-v [-f dumpfile]]\n", 	progName);    exit(-1);}static voidLongUsage(char *progName){    FPS "%-15s Display this help message.\n",	"-H");    FPS "%-15s Dump analysis.  No changes will be made to the database.\n",	"-D");    FPS "%-15s Cert database directory (default is ~/.netscape)\n",	"   -d certdir");    FPS "%-15s Input cert database name (default is cert7.db)\n",	"   -i dbname");    FPS "%-15s Mail a graph of the database to certdb@netscape.com.\n",	"   -m");    FPS "%-15s This will produce an index graph of your cert db and send\n",	"");    FPS "%-15s it to Netscape for analysis.  Personal info will be removed.\n",	"");    FPS "%-15s Verbose mode.  Dumps the entire contents of your cert7.db.\n",	"   -v");    FPS "%-15s File to dump verbose output into.\n",	"   -f dumpfile");    FPS "%-15s Repair the database.  The program will look for broken\n",	"-R");    FPS "%-15s dependencies between subject entries and certificates,\n",        "");    FPS "%-15s between nickname entries and subjects, and between SMIME\n",        "");    FPS "%-15s profiles and subjects.  Any duplicate entries will be\n",        "");    FPS "%-15s removed, any missing entries will be created.\n",        "");    FPS "%-15s File to store new database in (default is new_cert7.db)\n",	"   -o newdbname");    FPS "%-15s Cert database directory (default is ~/.netscape)\n",	"   -d certdir");    FPS "%-15s Input cert database name (default is cert7.db)\n",	"   -i dbname");    FPS "%-15s Prompt before removing any certificates.\n",        "   -p");    FPS "%-15s Keep all possible certificates.  Only remove certificates\n",	"   -a");    FPS "%-15s which prevent creation of a consistent database.  Thus any\n",	"");    FPS "%-15s expired or redundant entries will be kept.\n",	"");    FPS "%-15s Keep redundant nickname/email entries.  It is possible\n",	"   -r");    FPS "%-15s only one such entry will be usable.\n",	"");    FPS "%-15s Don't require an S/MIME profile in order to keep an S/MIME\n",	"   -s");    FPS "%-15s cert.  An empty profile will be created.\n",	"");    FPS "%-15s Keep expired certificates.\n",	"   -x");    FPS "%-15s Verbose mode - report all activity while recovering db.\n",	"   -v");    FPS "%-15s File to dump verbose output into.\n",	"   -f dumpfile");    FPS "\n");    exit(-1);#undef FPS}/******************************************************************* * *  Functions for dbck. * ******************************************************************/voidprintHexString(PRFileDesc *out, SECItem *hexval){    int i;    for (i = 0; i < hexval->len; i++) {	if (i != hexval->len - 1) {	    PR_fprintf(out, "%02x:", hexval->data[i]);	} else {	    PR_fprintf(out, "%02x", hexval->data[i]);	}    }    PR_fprintf(out, "\n");}typedef enum {/* 0*/ NoSubjectForCert = 0,/* 1*/ SubjectHasNoKeyForCert,/* 2*/ NoNicknameOrSMimeForSubject,/* 3*/ WrongNicknameForSubject,/* 4*/ NoNicknameEntry,/* 5*/ WrongSMimeForSubject,/* 6*/ NoSMimeEntry,/* 7*/ NoSubjectForNickname,/* 8*/ NoSubjectForSMime,/* 9*/ NicknameAndSMimeEntry} dbErrorType;static char *dbErrorString[] = {/* 0*/ "<CERT ENTRY>\nDid not find a subject entry for this certificate.",/* 1*/ "<SUBJECT ENTRY>\nSubject has certKey which is not in db.",/* 2*/ "<SUBJECT ENTRY>\nSubject does not have a nickname or email address.",/* 3*/ "<SUBJECT ENTRY>\nUsing this subject's nickname, found a nickname entry for a different subject.",/* 4*/ "<SUBJECT ENTRY>\nDid not find a nickname entry for this subject.",/* 5*/ "<SUBJECT ENTRY>\nUsing this subject's email, found an S/MIME entry for a different subject.",/* 6*/ "<SUBJECT ENTRY>\nDid not find an S/MIME entry for this subject.",/* 7*/ "<NICKNAME ENTRY>\nDid not find a subject entry for this nickname.",/* 8*/ "<S/MIME ENTRY>\nDid not find a subject entry for this S/MIME profile.",};SECStatusdumpCertificate(CERTCertificate *cert, int num, PRFileDesc *outfile){    int userCert = 0;    CERTCertTrust *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);    if (num >= 0) {	PR_fprintf(outfile, "Certificate: %3d\n", num);    } else {	PR_fprintf(outfile, "Certificate:\n");    }    PR_fprintf(outfile, "----------------\n");    if (userCert)	PR_fprintf(outfile, "(User Cert)\n");    PR_fprintf(outfile, "## SUBJECT:  %s\n", cert->subjectName);    PR_fprintf(outfile, "## ISSUER:  %s\n", cert->issuerName);    PR_fprintf(outfile, "## SERIAL NUMBER:  ");    printHexString(outfile, &cert->serialNumber);    {  /*  XXX should be separate function.  */	int64 timeBefore, timeAfter;	PRExplodedTime beforePrintable, afterPrintable;	char *beforestr, *afterstr;	DER_UTCTimeToTime(&timeBefore, &cert->validity.notBefore);	DER_UTCTimeToTime(&timeAfter, &cert->validity.notAfter);	PR_ExplodeTime(timeBefore, PR_GMTParameters, &beforePrintable);	PR_ExplodeTime(timeAfter, PR_GMTParameters, &afterPrintable);	beforestr = PORT_Alloc(100);	afterstr = PORT_Alloc(100);	PR_FormatTime(beforestr, 100, "%a %b %d %H:%M:%S %Y", &beforePrintable);	PR_FormatTime(afterstr, 100, "%a %b %d %H:%M:%S %Y", &afterPrintable);	PR_fprintf(outfile, "## VALIDITY:  %s to %s\n", beforestr, afterstr);    }    PR_fprintf(outfile, "\n");    return SECSuccess;}SECStatusdumpCertEntry(certDBEntryCert *entry, int num, PRFileDesc *outfile){    CERTCertificate *cert;    cert = CERT_DecodeDERCertificate(&entry->derCert, PR_FALSE, NULL);    if (!cert) {	fprintf(stderr, "Failed to decode certificate.\n");	return SECFailure;    }    cert->trust = &entry->trust;    dumpCertificate(cert, num, outfile);    CERT_DestroyCertificate(cert);    return SECSuccess;}SECStatusdumpSubjectEntry(certDBEntrySubject *entry, int num, PRFileDesc *outfile){    char *subjectName;    subjectName = CERT_DerNameToAscii(&entry->derSubject);    PR_fprintf(outfile, "Subject: %3d\n", num);    PR_fprintf(outfile, "------------\n");    PR_fprintf(outfile, "## %s\n", subjectName);    if (entry->nickname)	PR_fprintf(outfile, "## Subject nickname:  %s\n", entry->nickname);    if (entry->emailAddr)	PR_fprintf(outfile, "## Subject email address:  %s\n", 	           entry->emailAddr);    PR_fprintf(outfile, "## This subject has %d cert(s).\n", entry->ncerts);    PR_fprintf(outfile, "\n");    PORT_Free(subjectName);    return SECSuccess;}SECStatusdumpNicknameEntry(certDBEntryNickname *entry, int num, PRFileDesc *outfile){    PR_fprintf(outfile, "Nickname: %3d\n", num);    PR_fprintf(outfile, "-------------\n");    PR_fprintf(outfile, "##  \"%s\"\n\n", entry->nickname);    return SECSuccess;}SECStatusdumpSMimeEntry(certDBEntrySMime *entry, int num, PRFileDesc *outfile){    PR_fprintf(outfile, "S/MIME Profile: %3d\n", num);    PR_fprintf(outfile, "-------------------\n");    PR_fprintf(outfile, "##  \"%s\"\n", entry->emailAddr);    PR_fprintf(outfile, "##  OPTIONS:  ");    printHexString(outfile, &entry->smimeOptions);    PR_fprintf(outfile, "##  TIMESTAMP:  ");    printHexString(outfile, &entry->optionsDate);    PR_fprintf(outfile, "\n");    return SECSuccess;}SECStatusmapCertEntries(certDBArray *dbArray){    certDBEntryCert *certEntry;    certDBEntrySubject *subjectEntry;    certDBEntryListNode *certNode, *subjNode;    certDBSubjectEntryMap *smap;    certDBEntryMap *map;    PRArenaPool *tmparena;    SECItem derSubject;    SECItem certKey;    PRCList *cElem, *sElem;    int i;    /* Arena for decoded entries */    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (tmparena == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return SECFailure;    }    /* Iterate over cert entries and map them to subject entries.      * NOTE: mapSubjectEntries must be called first to alloc memory     * for array of subject->cert map.     */    for (cElem = PR_LIST_HEAD(&dbArray->certs.link);          cElem != &dbArray->certs.link; cElem = PR_NEXT_LINK(cElem)) {	certNode = LISTNODE_CAST(cElem);	certEntry = (certDBEntryCert *)&certNode->entry;	map = (certDBEntryMap *)certNode->appData;	CERT_NameFromDERCert(&certEntry->derCert, &derSubject);	CERT_KeyFromDERCert(tmparena, &certEntry->derCert, &certKey);	/*  Loop over found subjects for cert's DN.  */	for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);	     sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {	    subjNode = LISTNODE_CAST(sElem);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -