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 + -
显示快捷键?