pcertdb.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,743 行 · 第 1/5 页

C
2,743
字号
    if ( tmparena ) {	PORT_FreeArena(tmparena, PR_FALSE);    }    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(NULL);}/* * destroy a database entry */static voidDestroyDBEntry(certDBEntry *entry){    PRArenaPool *arena = entry->common.arena;    /* Zero out the entry struct, so that any further attempts to use it     * will cause an exception (e.g. null pointer reference). */    PORT_Memset(&entry->common, 0, sizeof entry->common);    PORT_FreeArena(arena, PR_FALSE);    return;}/* * Encode a database nickname record */static SECStatusEncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena,		      SECItem *dbitem){    unsigned char *buf;        /* allocate space for encoded database record, including space     * for low level header     */    dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN +	SEC_DB_ENTRY_HEADER_LEN;        dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);    if ( dbitem->data == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }        /* fill in database record */    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];        buf[0] = ( entry->subjectName.len >> 8 ) & 0xff;    buf[1] = entry->subjectName.len & 0xff;        PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data,	      entry->subjectName.len);    return(SECSuccess);loser:    return(SECFailure);}/* * Encode a database key for a nickname record */static SECStatusEncodeDBNicknameKey(char *nickname, PRArenaPool *arena,		    SECItem *dbkey){    unsigned int nnlen;        nnlen = PORT_Strlen(nickname) + 1; /* includes null */    /* now get the database key and format it */    dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN;    dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);    if ( dbkey->data == NULL ) {	goto loser;    }    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen);    dbkey->data[0] = certDBEntryTypeNickname;    return(SECSuccess);loser:    return(SECFailure);}static SECStatusDecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry){    /* is record long enough for header? */    if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }        /* 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;    }        /* copy the certkey */    entry->subjectName.data =	(unsigned char *)PORT_ArenaAlloc(entry->common.arena,					 entry->subjectName.len);    if ( entry->subjectName.data == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    PORT_Memcpy(entry->subjectName.data,	      &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN],	      entry->subjectName.len);        return(SECSuccess);loser:    return(SECFailure);}/* * create a new nickname entry */static certDBEntryNickname *NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags){    PRArenaPool *arena = NULL;    certDBEntryNickname *entry;    int nnlen;    SECStatus rv;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,						 sizeof(certDBEntryNickname));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    /* init common fields */    entry->common.arena = arena;    entry->common.type = certDBEntryTypeNickname;    entry->common.version = CERT_DB_FILE_VERSION;    entry->common.flags = flags;    /* copy the nickname */    nnlen = PORT_Strlen(nickname) + 1;        entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen);    if ( entry->nickname == NULL ) {	goto loser;    }        PORT_Memcpy(entry->nickname, nickname, nnlen);        rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);    if ( rv != SECSuccess ) {	goto loser;    }        return(entry);loser:    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(NULL);}/* * delete a nickname entry */static SECStatusDeleteDBNicknameEntry(CERTCertDBHandle *handle, char *nickname){    PRArenaPool *arena = NULL;    SECStatus rv;    SECItem dbkey;        if ( nickname == NULL ) {	return(SECSuccess);    }        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	goto loser;    }    rv = EncodeDBNicknameKey(nickname, arena, &dbkey);    if ( rv != SECSuccess ) {	goto loser;    }    rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey);    if ( rv == SECFailure ) {	goto loser;    }    PORT_FreeArena(arena, PR_FALSE);    return(SECSuccess);loser:    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(SECFailure);}/* * Read a nickname entry */static certDBEntryNickname *ReadDBNicknameEntry(CERTCertDBHandle *handle, char *nickname){    PRArenaPool *arena = NULL;    PRArenaPool *tmparena = NULL;    certDBEntryNickname *entry;    SECItem dbkey;    SECItem dbentry;    SECStatus rv;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }        entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena,						 sizeof(certDBEntryNickname));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeNickname;    rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey);    if ( rv != SECSuccess ) {	goto loser;    }        rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);    if ( rv == SECFailure ) {	goto loser;    }    /* is record long enough for header? */    if ( dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }    rv = DecodeDBNicknameEntry(entry, &dbentry);    if ( rv != SECSuccess ) {	goto loser;    }        PORT_FreeArena(tmparena, PR_FALSE);    return(entry);    loser:    if ( tmparena ) {	PORT_FreeArena(tmparena, PR_FALSE);    }    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(NULL);}/* * Encode a nickname entry into byte stream suitable for * the database */static SECStatusWriteDBNicknameEntry(CERTCertDBHandle *handle, certDBEntryNickname *entry){    SECItem dbitem, dbkey;    PRArenaPool *tmparena = NULL;    SECStatus rv;        tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	goto loser;    }        rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem);    if ( rv != SECSuccess ) {	goto loser;    }    rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey);    if ( rv != SECSuccess ) {	goto loser;    }    /* now write it to the database */    rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem);    if ( rv != SECSuccess ) {	goto loser;    }        PORT_FreeArena(tmparena, PR_FALSE);    return(SECSuccess);loser:    if ( tmparena ) {	PORT_FreeArena(tmparena, PR_FALSE);    }    return(SECFailure);    }/* * Encode a database smime record */static SECStatusEncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena,		   SECItem *dbitem){    unsigned char *buf;        /* allocate space for encoded database record, including space     * for low level header     */    dbitem->len = entry->subjectName.len + entry->smimeOptions.len +	entry->optionsDate.len +	DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN;        dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len);    if ( dbitem->data == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }        /* fill in database record */    buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN];        buf[0] = ( entry->subjectName.len >> 8 ) & 0xff;    buf[1] = entry->subjectName.len & 0xff;    buf[2] = ( entry->smimeOptions.len >> 8 ) & 0xff;    buf[3] = entry->smimeOptions.len & 0xff;    buf[4] = ( entry->optionsDate.len >> 8 ) & 0xff;    buf[5] = entry->optionsDate.len & 0xff;    /* if no smime options, then there should not be an options date either */    PORT_Assert( ! ( ( entry->smimeOptions.len == 0 ) &&		    ( entry->optionsDate.len != 0 ) ) );        PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data,	      entry->subjectName.len);    if ( entry->smimeOptions.len ) {	PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN+entry->subjectName.len],		    entry->smimeOptions.data,		    entry->smimeOptions.len);	PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len +			 entry->smimeOptions.len],		    entry->optionsDate.data,		    entry->optionsDate.len);    }    return(SECSuccess);loser:    return(SECFailure);}/* * Encode a database key for a SMIME record */static SECStatusEncodeDBSMimeKey(char *emailAddr, PRArenaPool *arena,		 SECItem *dbkey){    unsigned int addrlen;        addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */    /* now get the database key and format it */    dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN;    dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len);    if ( dbkey->data == NULL ) {	goto loser;    }    PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen);    dbkey->data[0] = certDBEntryTypeSMimeProfile;    return(SECSuccess);loser:    return(SECFailure);}/* * Decode a database SMIME record */static SECStatusDecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr){    /* is record long enough for header? */    if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }        /* 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;    }        /* copy the subject name */    entry->subjectName.data =	(unsigned char *)PORT_ArenaAlloc(entry->common.arena,					 entry->subjectName.len);    if ( entry->subjectName.data == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    PORT_Memcpy(entry->subjectName.data,	      &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN],	      entry->subjectName.len);    /* copy the smime options */    if ( entry->smimeOptions.len ) {	entry->smimeOptions.data =	    (unsigned char *)PORT_ArenaAlloc(entry->common.arena,					     entry->smimeOptions.len);	if ( entry->smimeOptions.data == NULL ) {	    PORT_SetError(SEC_ERROR_NO_MEMORY);	    goto loser;	}	PORT_Memcpy(entry->smimeOptions.data,		    &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +				   entry->subjectName.len],		    entry->smimeOptions.len);    }    if ( entry->optionsDate.len ) {	entry->optionsDate.data =	    (unsigned char *)PORT_ArenaAlloc(entry->common.arena,					     entry->optionsDate.len);	if ( entry->optionsDate.data == NULL ) {	    PORT_SetError(SEC_ERROR_NO_MEMORY);	    goto loser;	}	PORT_Memcpy(entry->optionsDate.data,		    &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +				   entry->subjectName.len +				   entry->smimeOptions.len],		    entry->optionsDate.len);    }    /* both options and options date must either exist or not exist */    if ( ( ( entry->optionsDate.len == 0 ) ||	  ( entry->smimeOptions.len == 0 ) ) &&	entry->smimeOptions.len != entry->optionsDate.len ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }    entry->emailAddr = (char *)PORT_Alloc(PORT_Strlen(emailAddr)+1);    if ( entry->emailAddr ) {	PORT_Strcpy(entry->emailAddr, emailAddr);    }        return(SECSuccess);loser:    return(SECFailure);}/* * create a new SMIME entry */static certDBEntrySMime *NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions,		SECItem *optionsDate, unsigned int flags){    PRArenaPool *arena = NULL;    certDBEntrySMime *entry;    int addrlen;    SECStatus rv;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,						sizeof(certDBEntrySMime));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    /* init common fields */    entry->common.arena = arena;    entry->common.type = certDBEntryTypeSMimeProfile;    entry->common.version = CERT_DB_FILE_VERSION;    entry->common.flags = flags;    /* copy the email addr */    addrlen = PORT_Strlen(emailAddr) + 1;        entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen);    if ( entry->emailAddr == NULL ) {	goto loser;    }        PORT_Memcpy(entry->emailAddr, emailAddr, addrlen);        /* copy the subject name */    rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName);    if ( rv != SECSuccess ) {	goto loser;    }    /* copy the smime options */    if ( smimeOptions ) {	rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions);	if ( rv != SECSuccess ) {	    goto loser;	}    } else {	PORT_Assert(optionsDate == NULL);	entry->smimeOptions.data = NULL;	entry->smimeOptions.len = 0;    }

⌨️ 快捷键说明

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