Bug 486304: cert8.db "corruption" when importing a large certificate (>64K)
Patch, part 2, r=rrelyea, git-svn-id: svn://10.0.0.236/trunk@256862 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
18113d7a39
commit
1feb852d58
@ -37,7 +37,7 @@
|
||||
/*
|
||||
* Permanent Certificate database handling code
|
||||
*
|
||||
* $Id: pcertdb.c,v 1.8 2009-04-08 04:35:29 nelson%bolyard.com Exp $
|
||||
* $Id: pcertdb.c,v 1.9 2009-04-09 02:00:33 nelson%bolyard.com Exp $
|
||||
*/
|
||||
#include "lowkeyti.h"
|
||||
#include "pcert.h"
|
||||
@ -1178,8 +1178,9 @@ loser:
|
||||
static SECStatus
|
||||
DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
|
||||
{
|
||||
unsigned int nnlen;
|
||||
|
||||
unsigned int urlLen;
|
||||
int lenDiff;
|
||||
|
||||
/* is record long enough for header? */
|
||||
if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
@ -1188,20 +1189,19 @@ DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
|
||||
|
||||
/* is database entry correct length? */
|
||||
entry->derCrl.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
|
||||
nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
|
||||
if ( ( entry->derCrl.len + nnlen + DB_CRL_ENTRY_HEADER_LEN )
|
||||
!= dbentry->len) {
|
||||
/* CRL entry is greater than 64 K. Hack to make this continue to work */
|
||||
if (dbentry->len >= (0xffff - DB_CRL_ENTRY_HEADER_LEN) - nnlen) {
|
||||
entry->derCrl.len =
|
||||
(dbentry->len - DB_CRL_ENTRY_HEADER_LEN) - nnlen;
|
||||
} else {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
goto loser;
|
||||
}
|
||||
urlLen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
|
||||
lenDiff = dbentry->len -
|
||||
(entry->derCrl.len + urlLen + DB_CRL_ENTRY_HEADER_LEN);
|
||||
if (lenDiff) {
|
||||
if (lenDiff < 0 || (lenDiff & 0xffff) != 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
goto loser;
|
||||
}
|
||||
/* CRL entry is greater than 64 K. Hack to make this continue to work */
|
||||
entry->derCrl.len += lenDiff;
|
||||
}
|
||||
|
||||
/* copy the dercert */
|
||||
/* copy the der CRL */
|
||||
entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,
|
||||
entry->derCrl.len);
|
||||
if ( entry->derCrl.data == NULL ) {
|
||||
@ -1213,15 +1213,15 @@ DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry)
|
||||
|
||||
/* copy the url */
|
||||
entry->url = NULL;
|
||||
if (nnlen != 0) {
|
||||
entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);
|
||||
if (urlLen != 0) {
|
||||
entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, urlLen);
|
||||
if ( entry->url == NULL ) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(entry->url,
|
||||
&dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],
|
||||
nnlen);
|
||||
urlLen);
|
||||
}
|
||||
|
||||
return(SECSuccess);
|
||||
@ -1503,6 +1503,8 @@ static SECStatus
|
||||
DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
|
||||
char *nickname)
|
||||
{
|
||||
int lenDiff;
|
||||
|
||||
/* is record long enough for header? */
|
||||
if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
@ -1511,12 +1513,17 @@ DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry,
|
||||
|
||||
/* is database entry correct length? */
|
||||
entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
|
||||
if (( entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN ) !=
|
||||
dbentry->len ){
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
goto loser;
|
||||
lenDiff = dbentry->len -
|
||||
(entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN);
|
||||
if (lenDiff) {
|
||||
if (lenDiff < 0 || (lenDiff & 0xffff) != 0 ) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
goto loser;
|
||||
}
|
||||
/* The entry size exceeded 64KB. Reconstruct the correct length. */
|
||||
entry->subjectName.len += lenDiff;
|
||||
}
|
||||
|
||||
|
||||
/* copy the certkey */
|
||||
entry->subjectName.data =
|
||||
(unsigned char *)PORT_ArenaAlloc(entry->common.arena,
|
||||
@ -1831,6 +1838,8 @@ loser:
|
||||
static SECStatus
|
||||
DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
|
||||
{
|
||||
int lenDiff;
|
||||
|
||||
/* is record long enough for header? */
|
||||
if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
@ -1838,15 +1847,22 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
|
||||
}
|
||||
|
||||
/* is database entry correct length? */
|
||||
entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] );
|
||||
entry->smimeOptions.len = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] );
|
||||
entry->optionsDate.len = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] );
|
||||
if (( entry->subjectName.len + entry->smimeOptions.len +
|
||||
entry->optionsDate.len + DB_SMIME_ENTRY_HEADER_LEN ) != dbentry->len){
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
goto loser;
|
||||
entry->subjectName.len = (( dbentry->data[0] << 8 ) | dbentry->data[1] );
|
||||
entry->smimeOptions.len = (( dbentry->data[2] << 8 ) | dbentry->data[3] );
|
||||
entry->optionsDate.len = (( dbentry->data[4] << 8 ) | dbentry->data[5] );
|
||||
lenDiff = dbentry->len - (entry->subjectName.len +
|
||||
entry->smimeOptions.len +
|
||||
entry->optionsDate.len +
|
||||
DB_SMIME_ENTRY_HEADER_LEN);
|
||||
if (lenDiff) {
|
||||
if (lenDiff < 0 || (lenDiff & 0xffff) != 0 ) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATABASE);
|
||||
goto loser;
|
||||
}
|
||||
/* The entry size exceeded 64KB. Reconstruct the correct length. */
|
||||
entry->subjectName.len += lenDiff;
|
||||
}
|
||||
|
||||
|
||||
/* copy the subject name */
|
||||
entry->subjectName.data =
|
||||
(unsigned char *)PORT_ArenaAlloc(entry->common.arena,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user