pcertdb.c

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

C
2,743
字号
    }    entry->derCert.len = derCert->len;    PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len);        nnlen = ( nickname ? strlen(nickname) + 1 : 0 );        if ( nnlen ) {	entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen);	if ( !entry->nickname ) {	    goto loser;	}	PORT_Memcpy(entry->nickname, nickname, nnlen);	    } else {	entry->nickname = 0;    }    return(entry);loser:        /* allocation error, free arena and return */    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        PORT_SetError(SEC_ERROR_NO_MEMORY);    return(0);}/* * Decode a version 4 DBCert from the byte stream database format * and construct a current database entry struct */static certDBEntryCert *DecodeV4DBCertEntry(unsigned char *buf, int len){    certDBEntryCert *entry;    int certlen;    int nnlen;    PRArenaPool *arena;        /* make sure length is at least long enough for the header */    if ( len < DBCERT_V4_HEADER_LEN ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	return(0);    }    /* get other lengths */    certlen = buf[3] << 8 | buf[4];    nnlen = buf[5] << 8 | buf[6];        /* make sure DB entry is the right size */    if ( ( certlen + nnlen + DBCERT_V4_HEADER_LEN ) != len ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	return(0);    }    /* allocate arena */    arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );    if ( !arena ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return(0);    }	    /* allocate structure and members */    entry = (certDBEntryCert *)  PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));    if ( !entry ) {	goto loser;    }    entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen);    if ( !entry->derCert.data ) {	goto loser;    }    entry->derCert.len = certlen;        if ( nnlen ) {	entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen);	if ( !entry->nickname ) {	    goto loser;	}    } else {	entry->nickname = 0;    }    entry->common.arena = arena;    entry->common.version = CERT_DB_FILE_VERSION;    entry->common.type = certDBEntryTypeCert;    entry->common.flags = 0;    entry->trust.sslFlags = buf[0];    entry->trust.emailFlags = buf[1];    entry->trust.objectSigningFlags = buf[2];    PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen);    PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen);    return(entry);    loser:    PORT_FreeArena(arena, PR_FALSE);    PORT_SetError(SEC_ERROR_NO_MEMORY);    return(0);}/* * Encode a Certificate database entry into byte stream suitable for * the database */static SECStatusWriteDBCertEntry(CERTCertDBHandle *handle, certDBEntryCert *entry){    SECItem dbitem, dbkey;    PRArenaPool *tmparena = NULL;    SECItem tmpitem;    SECStatus rv;        tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	goto loser;    }        rv = EncodeDBCertEntry(entry, tmparena, &dbitem);    if ( rv != SECSuccess ) {	goto loser;    }    /* get the database key and format it */    rv = CERT_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem);    if ( rv == SECFailure ) {	goto loser;    }    rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey);    if ( rv == SECFailure ) {	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);}/* * delete a certificate entry */static SECStatusDeleteDBCertEntry(CERTCertDBHandle *handle, SECItem *certKey){    SECItem dbkey;    PRArenaPool *arena = NULL;    SECStatus rv;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	goto loser;    }    rv = EncodeDBCertKey(certKey, arena, &dbkey);    if ( rv != SECSuccess ) {	goto loser;    }        rv = DeleteDBEntry(handle, certDBEntryTypeCert, &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 certificate entry */static certDBEntryCert *ReadDBCertEntry(CERTCertDBHandle *handle, SECItem *certKey){    PRArenaPool *arena = NULL;    PRArenaPool *tmparena = NULL;    certDBEntryCert *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 = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = certDBEntryTypeCert;    rv = EncodeDBCertKey(certKey, tmparena, &dbkey);    if ( rv != SECSuccess ) {	goto loser;    }        rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);    if ( rv == SECFailure ) {	goto loser;    }    rv = DecodeDBCertEntry(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 database cert record */static SECStatusEncodeDBCrlEntry(certDBEntryRevocation *entry, PRArenaPool *arena, SECItem *dbitem){    unsigned int nnlen = 0;    unsigned char *buf;      if (entry->url) {  	nnlen = PORT_Strlen(entry->url) + 1;    }        /* allocate space for encoded database record, including space     * for low level header     */    dbitem->len = entry->derCrl.len + nnlen 		+ SEC_DB_ENTRY_HEADER_LEN + DB_CRL_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->derCrl.len >> 8 ) & 0xff;    buf[1] = entry->derCrl.len & 0xff;    buf[2] = ( nnlen >> 8 ) & 0xff;    buf[3] = nnlen & 0xff;        PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data,	      entry->derCrl.len);    if (nnlen != 0) {	PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len],	      entry->url, nnlen);    }    return(SECSuccess);loser:    return(SECFailure);}static SECStatusDecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry){    unsigned int nnlen;        /* is record long enough for header? */    if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }        /* 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) {	PORT_SetError(SEC_ERROR_BAD_DATABASE);	goto loser;    }        /* copy the dercert */    entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena,							 entry->derCrl.len);    if ( entry->derCrl.data == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN],	      entry->derCrl.len);    /* copy the url */    entry->url = NULL;    if (nnlen != 0) {	entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen);	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);    }        return(SECSuccess);loser:    return(SECFailure);}/* * Create a new certDBEntryRevocation from existing data */static certDBEntryRevocation *NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags){    certDBEntryRevocation *entry;    PRArenaPool *arena = NULL;    int nnlen;        arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE );    if ( !arena ) {	goto loser;    }	    entry = (certDBEntryRevocation*)			PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation));    if ( entry == NULL ) {	goto loser;    }        /* fill in the dbRevolcation */    entry->common.arena = arena;    entry->common.type = crlType;    entry->common.version = CERT_DB_FILE_VERSION;    entry->common.flags = flags;        entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len);    if ( !entry->derCrl.data ) {	goto loser;    }    if (url) {	nnlen = PORT_Strlen(url) + 1;	entry->url  = (char *)PORT_ArenaAlloc(arena, nnlen);	if ( !entry->url ) {	    goto loser;	}	PORT_Memcpy(entry->url, url, nnlen);    } else {	entry->url = NULL;    }	    entry->derCrl.len = derCrl->len;    PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len);    return(entry);loser:        /* allocation error, free arena and return */    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }        PORT_SetError(SEC_ERROR_NO_MEMORY);    return(0);}static SECStatusWriteDBCrlEntry(CERTCertDBHandle *handle, certDBEntryRevocation *entry ){    SECItem dbkey;    PRArenaPool *tmparena = NULL;    SECItem tmpitem,encodedEntry;    SECStatus rv;        tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( tmparena == NULL ) {	goto loser;    }    /* get the database key and format it */    rv = CERT_KeyFromDERCrl(tmparena, &entry->derCrl, &tmpitem);    if ( rv == SECFailure ) {	goto loser;    }    rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);    if ( rv == SECFailure ) {	goto loser;    }    rv = EncodeDBGenericKey(&tmpitem, tmparena, &dbkey, entry->common.type);    if ( rv == SECFailure ) {	goto loser;    }        /* now write it to the database */    rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry);    if ( rv != SECSuccess ) {	goto loser;    }        PORT_FreeArena(tmparena, PR_FALSE);    return(SECSuccess);loser:    if ( tmparena ) {	PORT_FreeArena(tmparena, PR_FALSE);    }    return(SECFailure);}/* * delete a crl entry */static SECStatusDeleteDBCrlEntry(CERTCertDBHandle *handle, SECItem *crlKey, 						certDBEntryType crlType){    SECItem dbkey;    PRArenaPool *arena = NULL;    SECStatus rv;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( arena == NULL ) {	goto loser;    }    rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType);    if ( rv != SECSuccess ) {	goto loser;    }        rv = DeleteDBEntry(handle, crlType, &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 certificate entry */static certDBEntryRevocation *ReadDBCrlEntry(CERTCertDBHandle *handle, SECItem *certKey,						certDBEntryType crlType){    PRArenaPool *arena = NULL;    PRArenaPool *tmparena = NULL;    certDBEntryRevocation *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 = (certDBEntryRevocation *)			PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation));    if ( entry == NULL ) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	goto loser;    }    entry->common.arena = arena;    entry->common.type = crlType;    rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType);    if ( rv != SECSuccess ) {	goto loser;    }        rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena);    if ( rv == SECFailure ) {	goto loser;    }    rv = DecodeDBCrlEntry(entry, &dbentry);    if ( rv != SECSuccess ) {	goto loser;    }        PORT_FreeArena(tmparena, PR_FALSE);    return(entry);    loser:

⌨️ 快捷键说明

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