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