diff options
author | relyea%netscape.com <devnull@localhost> | 2002-07-16 16:44:22 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2002-07-16 16:44:22 +0000 |
commit | bac1a1747bbb43d573dea54c6b1927788b072e31 (patch) | |
tree | a4770a4dcba29d156edaf1c0428ea33506316082 | |
parent | 49421d3da424aaad545af9783eb543a9665051ff (diff) | |
download | nss-hg-bac1a1747bbb43d573dea54c6b1927788b072e31.tar.gz |
Automatically recover from database corruptions when importing new certs.
-rw-r--r-- | security/nss/lib/softoken/pcertdb.c | 52 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11u.c | 5 |
2 files changed, 31 insertions, 26 deletions
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c index edca8b75a..311be2fdd 100644 --- a/security/nss/lib/softoken/pcertdb.c +++ b/security/nss/lib/softoken/pcertdb.c @@ -2914,12 +2914,12 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, char *nickname) { SECItem *newCertKeys, *newKeyIDs; - unsigned int i; + unsigned int i, new_i; SECStatus rv; NSSLOWCERTCertificate *cmpcert; unsigned int nnlen; unsigned int ncerts; - + PRBool added = PR_FALSE; PORT_Assert(entry); ncerts = entry->ncerts; @@ -2949,60 +2949,68 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, return(SECFailure); } - for ( i = 0; i < ncerts; i++ ) { + for ( i = 0, new_i=0; i < ncerts; i++ ) { cmpcert = nsslowcert_FindCertByKey(cert->dbhandle, &entry->certKeys[i]); - PORT_Assert(cmpcert); + /* The entry has been corrupted, remove it from the list */ + if (!cmpcert) { + continue; + } + if ( nsslowcert_IsNewer(cert, cmpcert) ) { /* insert before cmpcert */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[i], + rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], &cert->certKey); if ( rv != SECSuccess ) { return(SECFailure); } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[i], + rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i], &cert->subjectKeyID); if ( rv != SECSuccess ) { return(SECFailure); } + new_i++; /* copy the rest of the entry */ - for ( ; i < ncerts; i++ ) { - newCertKeys[i+1] = entry->certKeys[i]; - newKeyIDs[i+1] = entry->keyIDs[i]; + for ( ; i < ncerts; i++ ,new_i++) { + newCertKeys[new_i] = entry->certKeys[i]; + newKeyIDs[new_i] = entry->keyIDs[i]; } /* update certKeys and keyIDs */ entry->certKeys = newCertKeys; entry->keyIDs = newKeyIDs; - /* increment count */ - entry->ncerts++; + /* set new count value */ + entry->ncerts = new_i; + added = PR_TRUE; break; } /* copy this cert entry */ - newCertKeys[i] = entry->certKeys[i]; - newKeyIDs[i] = entry->keyIDs[i]; + newCertKeys[new_i] = entry->certKeys[i]; + newKeyIDs[new_i] = entry->keyIDs[i]; + new_i++; /* only increment if we copied the entries */ } - if ( entry->ncerts == ncerts ) { + if ( !added ) { /* insert new one at end */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[ncerts], + rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], &cert->certKey); if ( rv != SECSuccess ) { return(SECFailure); } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[ncerts], + rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i], &cert->subjectKeyID); if ( rv != SECSuccess ) { return(SECFailure); } + new_i++; /* update certKeys and keyIDs */ entry->certKeys = newCertKeys; entry->keyIDs = newKeyIDs; /* increment count */ - entry->ncerts++; + entry->ncerts = new_i; } DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); rv = WriteDBSubjectEntry(cert->dbhandle, entry); @@ -3028,6 +3036,9 @@ nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle, for( i = 0; i < entry->ncerts; i++ ) { cert = nsslowcert_FindCertByKey(handle, &entry->certKeys[i]); + if (!cert) { + continue; + } rv = (* cb)(cert, cbarg); nsslowcert_DestroyCertificate(cert); if ( rv == SECFailure ) { @@ -3164,13 +3175,6 @@ nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle, certDBEntryNickname *nicknameEntry = NULL; nsslowcert_LockDB(dbhandle); - - PORT_Assert(cert->nickname == NULL); - - if ( cert->nickname != NULL ) { - rv = SECSuccess; - goto loser; - } entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject); if (entry == NULL) goto loser; diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index cf94eb307..4f7a5bf13 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -1468,9 +1468,10 @@ pk11_forceTokenAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, } /* if we are just setting it to the value we already have, - * allow it to happen. */ + * allow it to happen. Let label setting go through so + * we have the opportunity to repair any database corruption. */ attribute=pk11_FindAttribute(object,type); - if ((attribute->attrib.ulValueLen == len) && + if ((type != CKA_LABEL) && (attribute->attrib.ulValueLen == len) && PORT_Memcmp(attribute->attrib.pValue,value,len) == 0) { pk11_FreeAttribute(attribute); return CKR_OK; |