pcertdb.c

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

C
2,743
字号
/* * Read the subject entry */static certDBEntrySubject *ReadDBSubjectEntry(CERTCertDBHandle *handle, SECItem *derSubject){    PRArenaPool *arena = NULL;    PRArenaPool *tmparena = NULL;    certDBEntrySubject *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 = (certDBEntrySubject *)PORT_ArenaAlloc(arena,						sizeof(certDBEntrySubject));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeSubject;    rv = EncodeDBSubjectKey(derSubject, tmparena, &dbkey);    if ( rv != SECSuccess ) {	goto loser;    }        rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);    if ( rv == SECFailure ) {	goto loser;    }    rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject);    if ( rv == SECFailure ) {	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 subject name entry into byte stream suitable for * the database */static SECStatusWriteDBSubjectEntry(CERTCertDBHandle *handle, certDBEntrySubject *entry){    SECItem dbitem, dbkey;    PRArenaPool *tmparena = NULL;    SECStatus rv;        tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	goto loser;    }        rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem);    if ( rv != SECSuccess ) {	goto loser;    }        rv = EncodeDBSubjectKey(&entry->derSubject, 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);    }static SECStatusUpdateSubjectWithEmailAddr(CERTCertificate *cert, char *emailAddr){    CERTSubjectList *subjectList;    PRBool save = PR_FALSE, delold = PR_FALSE;    certDBEntrySubject *entry;    SECStatus rv;        emailAddr = CERT_FixupEmailAddr(emailAddr);    if ( emailAddr == NULL ) {	return(SECFailure);    }        subjectList = cert->subjectList;    PORT_Assert(subjectList != NULL);        if ( subjectList->emailAddr ) {	if ( PORT_Strcmp(subjectList->emailAddr, emailAddr) != 0 ) {	    save = PR_TRUE;	    delold = PR_TRUE;	}    } else {	save = PR_TRUE;    }    if ( delold ) {	/* delete the old smime entry, because this cert now has a new	 * smime entry pointing to it	 */	PORT_Assert(save);	PORT_Assert(subjectList->emailAddr != NULL);	DeleteDBSMimeEntry(cert->dbhandle, subjectList->emailAddr);    }    if ( save ) {	unsigned int len;		entry = subjectList->entry;	PORT_Assert(entry != NULL);	len = PORT_Strlen(emailAddr) + 1;	entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, len);	if ( entry->emailAddr == NULL ) {	    goto loser;	}	PORT_Memcpy(entry->emailAddr, emailAddr, len);		/* delete the subject entry */	DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);	/* write the new one */	rv = WriteDBSubjectEntry(cert->dbhandle, entry);	if ( rv != SECSuccess ) {	    goto loser;	}    }    PORT_Free(emailAddr);    return(SECSuccess);loser:    PORT_Free(emailAddr);    return(SECFailure);}/* * writes a nickname to an existing subject entry that does not currently * have one */static SECStatusAddNicknameToSubject(CERTCertificate *cert, char *nickname){    CERTSubjectList *subjectList;    certDBEntrySubject *entry;    SECStatus rv;        if ( nickname == NULL ) {	return(SECFailure);    }        subjectList = cert->subjectList;    PORT_Assert(subjectList != NULL);    if ( subjectList == NULL ) {	goto loser;    }        entry = subjectList->entry;    PORT_Assert(entry != NULL);    if ( entry == NULL ) {	goto loser;    }        PORT_Assert(entry->nickname == NULL);    if ( entry->nickname != NULL ) {	goto loser;    }        entry->nickname = (nickname) ? PORT_ArenaStrdup(entry->common.arena, nickname) : NULL;        if ( entry->nickname == NULL ) {	goto loser;    }	    /* delete the subject entry */    DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);    /* write the new one */    rv = WriteDBSubjectEntry(cert->dbhandle, entry);    if ( rv != SECSuccess ) {	goto loser;    }    return(SECSuccess);loser:    return(SECFailure);}/* * create a new version entry */static certDBEntryVersion *NewDBVersionEntry(unsigned int flags){    PRArenaPool *arena = NULL;    certDBEntryVersion *entry;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena,					       sizeof(certDBEntryVersion));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeVersion;    entry->common.version = CERT_DB_FILE_VERSION;    entry->common.flags = flags;    return(entry);loser:    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(NULL);}/* * Read the version entry */static certDBEntryVersion *ReadDBVersionEntry(CERTCertDBHandle *handle){    PRArenaPool *arena = NULL;    PRArenaPool *tmparena = NULL;    certDBEntryVersion *entry;    SECItem dbkey;    SECItem dbentry;        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 = (certDBEntryVersion *)PORT_ArenaAlloc(arena,						sizeof(certDBEntryVersion));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeVersion;    /* now get the database key and format it */    dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;    dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);    if ( dbkey.data == NULL ) {	goto loser;    }    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,	      SEC_DB_VERSION_KEY_LEN);    ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);    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 version entry into byte stream suitable for * the database */static SECStatusWriteDBVersionEntry(CERTCertDBHandle *handle, certDBEntryVersion *entry){    SECItem dbitem, dbkey;    PRArenaPool *tmparena = NULL;    SECStatus rv;        tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	goto loser;    }        /* allocate space for encoded database record, including space     * for low level header     */    dbitem.len = SEC_DB_ENTRY_HEADER_LEN;        dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);    if ( dbitem.data == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }        /* now get the database key and format it */    dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;    dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);    if ( dbkey.data == NULL ) {	goto loser;    }    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY,	      SEC_DB_VERSION_KEY_LEN);    /* 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);}/* * create a new version entry */static certDBEntryContentVersion *NewDBContentVersionEntry(unsigned int flags){    PRArenaPool *arena = NULL;    certDBEntryContentVersion *entry;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry = (certDBEntryContentVersion *)	PORT_ArenaAlloc(arena, sizeof(certDBEntryContentVersion));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeContentVersion;    entry->common.version = CERT_DB_FILE_VERSION;    entry->common.flags = flags;    entry->contentVersion = CERT_DB_CONTENT_VERSION;        return(entry);loser:    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        return(NULL);}/* * Read the version entry */static certDBEntryContentVersion *ReadDBContentVersionEntry(CERTCertDBHandle *handle){    PRArenaPool *arena = NULL;    PRArenaPool *tmparena = NULL;    certDBEntryContentVersion *entry;    SECItem dbkey;    SECItem dbentry;        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 = (certDBEntryContentVersion *)	PORT_ArenaAlloc(arena, sizeof(certDBEntryContentVersion));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeContentVersion;    /* now get the database key and format it */    dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;    dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);    if ( dbkey.data == NULL ) {	goto loser;    }    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY,		SEC_DB_CONTENT_VERSION_KEY_LEN);    dbentry.len = 0;    dbentry.data = NULL;        ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);    if ( dbentry.len != 1 ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }    entry->contentVersion = dbentry.data[0];        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 version entry into byte stream suitable for * the database */static SECStatusWriteDBContentVersionEntry(CERTCertDBHandle *handle,			   certDBEntryContentVersion *entry){    SECItem dbitem, dbkey;    PRArenaPool *tmparena = NULL;    SECStatus rv;        tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	goto loser;    }        /* allocate space for encoded database record, including space     * for low level header     */    dbitem.len = SEC_DB_ENTRY_HEADER_LEN + 1;        dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len);    if ( dbitem.data == NULL) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }        dbitem.data[SEC_DB_ENTRY_HEADER_LEN] = entry->contentVersion;        /* now get the database key and format it */    dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN;    dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len);    if ( dbkey.data == NULL ) {	goto loser;    }    PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY,		SEC_DB_CONTENT_VERSION_KEY_LEN);    /* 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);}/* * delete a content version entry */static SECStatusDeleteDBContentVersionEntry(CERTCertDBHandle *handle){    SECItem dbkey;    PRArenaPool *arena = NULL;    SECStatus rv;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	goto loser;    }    /* now get the database key and forma

⌨️ 快捷键说明

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