pcertdb.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,743 行 · 第 1/5 页
C
2,743 行
/* copy the options date */ if ( optionsDate ) { rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate); if ( rv != SECSuccess ) { goto loser; } } else { PORT_Assert(smimeOptions == NULL); entry->optionsDate.data = NULL; entry->optionsDate.len = 0; } return(entry);loser: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } return(NULL);}/* * delete a SMIME entry */static SECStatusDeleteDBSMimeEntry(CERTCertDBHandle *handle, char *emailAddr){ PRArenaPool *arena = NULL; SECStatus rv; SECItem dbkey; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( arena == NULL ) { goto loser; } rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey); if ( rv != SECSuccess ) { goto loser; } rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &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 SMIME entry */static certDBEntrySMime *ReadDBSMimeEntry(CERTCertDBHandle *handle, char *emailAddr){ PRArenaPool *arena = NULL; PRArenaPool *tmparena = NULL; certDBEntrySMime *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 = (certDBEntrySMime *)PORT_ArenaAlloc(arena, sizeof(certDBEntrySMime)); if ( entry == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } entry->common.arena = arena; entry->common.type = certDBEntryTypeSMimeProfile; rv = EncodeDBSMimeKey(emailAddr, 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_SMIME_ENTRY_HEADER_LEN ) { PORT_SetError(SEC_ERROR_BAD_DATABASE); goto loser; } rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr); 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 SMIME entry into byte stream suitable for * the database */static SECStatusWriteDBSMimeEntry(CERTCertDBHandle *handle, certDBEntrySMime *entry){ SECItem dbitem, dbkey; PRArenaPool *tmparena = NULL; SECStatus rv; tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( tmparena == NULL ) { goto loser; } rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem); if ( rv != SECSuccess ) { goto loser; } rv = EncodeDBSMimeKey(entry->emailAddr, 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 subject record */static SECStatusEncodeDBSubjectEntry(certDBEntrySubject *entry, PRArenaPool *arena, SECItem *dbitem){ unsigned char *buf; int len; unsigned int ncerts; unsigned int i; unsigned char *tmpbuf; unsigned int nnlen = 0; unsigned int eaddrlen = 0; int keyidoff; SECItem *certKeys; SECItem *keyIDs; if ( entry->nickname ) { nnlen = PORT_Strlen(entry->nickname) + 1; } if ( entry->emailAddr ) { eaddrlen = PORT_Strlen(entry->emailAddr) + 1; } ncerts = entry->ncerts; /* compute the length of the entry */ keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen; len = keyidoff + 4 * ncerts; for ( i = 0; i < ncerts; i++ ) { len += entry->certKeys[i].len; len += entry->keyIDs[i].len; } /* allocate space for encoded database record, including space * for low level header */ dbitem->len = 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] = ( ncerts >> 8 ) & 0xff; buf[1] = ncerts & 0xff; buf[2] = ( nnlen >> 8 ) & 0xff; buf[3] = nnlen & 0xff; buf[4] = ( eaddrlen >> 8 ) & 0xff; buf[5] = eaddrlen & 0xff; PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen); PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], entry->emailAddr, eaddrlen); for ( i = 0; i < ncerts; i++ ) { certKeys = entry->certKeys; keyIDs = entry->keyIDs; buf[keyidoff+i*2] = ( certKeys[i].len >> 8 ) & 0xff; buf[keyidoff+1+i*2] = certKeys[i].len & 0xff; buf[keyidoff+ncerts*2+i*2] = ( keyIDs[i].len >> 8 ) & 0xff; buf[keyidoff+1+ncerts*2+i*2] = keyIDs[i].len & 0xff; } /* temp pointer used to stuff certkeys and keyids into the buffer */ tmpbuf = &buf[keyidoff+ncerts*4]; for ( i = 0; i < ncerts; i++ ) { certKeys = entry->certKeys; PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len); tmpbuf = tmpbuf + certKeys[i].len; } for ( i = 0; i < ncerts; i++ ) { keyIDs = entry->keyIDs; PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len); tmpbuf = tmpbuf + keyIDs[i].len; } PORT_Assert(tmpbuf == &buf[len]); return(SECSuccess);loser: return(SECFailure);}/* * Encode a database key for a subject record */static SECStatusEncodeDBSubjectKey(SECItem *derSubject, PRArenaPool *arena, SECItem *dbkey){ dbkey->len = derSubject->len + 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], derSubject->data, derSubject->len); dbkey->data[0] = certDBEntryTypeSubject; return(SECSuccess);loser: return(SECFailure);}static SECStatusDecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry, SECItem *derSubject){ unsigned int ncerts; PRArenaPool *arena; unsigned int len, itemlen; unsigned char *tmpbuf; unsigned int i; SECStatus rv; unsigned int keyidoff; unsigned int nnlen, eaddrlen; arena = entry->common.arena; rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject); if ( rv != SECSuccess ) { goto loser; } /* is record long enough for header? */ if ( dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN ) { PORT_SetError(SEC_ERROR_BAD_DATABASE); goto loser; } entry->ncerts = ncerts = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); eaddrlen = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] ); if ( dbentry->len < ( ncerts * 4 + DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen) ) { PORT_SetError(SEC_ERROR_BAD_DATABASE); goto loser; } entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem) * ncerts); entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem) * ncerts); if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } if ( nnlen > 1 ) { /* null terminator is stored */ entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); if ( entry->nickname == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } PORT_Memcpy(entry->nickname, &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN], nnlen); } else { entry->nickname = NULL; } if ( eaddrlen > 1 ) { /* null terminator is stored */ entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen); if ( entry->emailAddr == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } PORT_Memcpy(entry->emailAddr, &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], eaddrlen); } else { entry->emailAddr = NULL; } /* collect the lengths of the certKeys and keyIDs, and total the * overall length. */ keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen; len = keyidoff + 4 * ncerts; tmpbuf = &dbentry->data[0]; for ( i = 0; i < ncerts; i++ ) { itemlen = ( tmpbuf[keyidoff + 2*i] << 8 ) | tmpbuf[keyidoff + 1 + 2*i] ; len += itemlen; entry->certKeys[i].len = itemlen; itemlen = ( tmpbuf[keyidoff + 2*ncerts + 2*i] << 8 ) | tmpbuf[keyidoff + 1 + 2*ncerts + 2*i] ; len += itemlen; entry->keyIDs[i].len = itemlen; } /* is database entry correct length? */ if ( len != dbentry->len ){ PORT_SetError(SEC_ERROR_BAD_DATABASE); goto loser; } tmpbuf = &tmpbuf[keyidoff + 4*ncerts]; for ( i = 0; i < ncerts; i++ ) { entry->certKeys[i].data = (unsigned char *)PORT_ArenaAlloc(arena, entry->certKeys[i].len); if ( entry->certKeys[i].data == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } PORT_Memcpy(entry->certKeys[i].data, tmpbuf, entry->certKeys[i].len); tmpbuf = &tmpbuf[entry->certKeys[i].len]; } for ( i = 0; i < ncerts; i++ ) { entry->keyIDs[i].data = (unsigned char *)PORT_ArenaAlloc(arena, entry->keyIDs[i].len); if ( entry->keyIDs[i].data == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, entry->keyIDs[i].len); tmpbuf = &tmpbuf[entry->keyIDs[i].len]; } PORT_Assert(tmpbuf == &dbentry->data[dbentry->len]); return(SECSuccess);loser: return(SECFailure);}/* * create a new subject entry with a single cert */static certDBEntrySubject *NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey, SECItem *keyID, char *nickname, char *emailAddr, unsigned int flags){ PRArenaPool *arena = NULL; certDBEntrySubject *entry; SECStatus rv; unsigned int nnlen; unsigned int eaddrlen; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( arena == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena, sizeof(certDBEntrySubject)); if ( entry == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } /* init common fields */ entry->common.arena = arena; entry->common.type = certDBEntryTypeSubject; entry->common.version = CERT_DB_FILE_VERSION; entry->common.flags = flags; /* copy the subject */ rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject); if ( rv != SECSuccess ) { goto loser; } entry->ncerts = 1; /* copy nickname */ if ( nickname && ( *nickname != '\0' ) ) { nnlen = PORT_Strlen(nickname) + 1; entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); if ( entry->nickname == NULL ) { goto loser; } PORT_Memcpy(entry->nickname, nickname, nnlen); } else { entry->nickname = NULL; } /* copy email addr */ if ( emailAddr && ( *emailAddr != '\0' ) ) { emailAddr = CERT_FixupEmailAddr(emailAddr); if ( emailAddr == NULL ) { entry->emailAddr = NULL; goto loser; } eaddrlen = PORT_Strlen(emailAddr) + 1; entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen); if ( entry->emailAddr == NULL ) { PORT_Free(emailAddr); goto loser; } PORT_Memcpy(entry->emailAddr, emailAddr, eaddrlen); PORT_Free(emailAddr); } else { entry->emailAddr = NULL; } /* allocate space for certKeys and keyIDs */ entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) { goto loser; } /* copy the certKey and keyID */ rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey); if ( rv != SECSuccess ) { goto loser; } rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID); if ( rv != SECSuccess ) { goto loser; } return(entry);loser: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } return(NULL);}/* * delete a subject entry */static SECStatusDeleteDBSubjectEntry(CERTCertDBHandle *handle, SECItem *derSubject){ SECItem dbkey; PRArenaPool *arena = NULL; SECStatus rv; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( arena == NULL ) { goto loser; } rv = EncodeDBSubjectKey(derSubject, arena, &dbkey); if ( rv != SECSuccess ) { goto loser; } rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey); if ( rv == SECFailure ) { goto loser; } PORT_FreeArena(arena, PR_FALSE); return(SECSuccess);loser: if ( arena ) { PORT_FreeArena(arena, PR_FALSE); } return(SECFailure);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?