db.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,066 行 · 第 1/2 页
C
1,066 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#ifdef DEBUGstatic const char CVS_ID[] = "@(#) $RCSfile: db.c,v $ $Revision: 1.4 $ $Date: 2000/05/17 18:28:13 $ $Name: NSS_3_1_1_RTM $";#endif /* DEBUG */#include "ckdbm.h"#define PREFIX_METADATA "0000"#define PREFIX_OBJECT "0001"#define PREFIX_INDEX "0002"static CK_VERSION nss_dbm_db_format_version = { 1, 0 };struct handle { char prefix[4]; CK_ULONG id;};NSS_IMPLEMENT nss_dbm_db_t *nss_dbm_db_open( NSSArena *arena, NSSCKFWInstance *fwInstance, char *filename, int flags, CK_RV *pError){ nss_dbm_db_t *rv; CK_VERSION db_version; rv = nss_ZNEW(arena, nss_dbm_db_t); if( (nss_dbm_db_t *)NULL == rv ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_db_t *)NULL; } rv->db = dbopen(filename, flags, 0600, DB_HASH, (const void *)NULL); if( (DB *)NULL == rv->db ) { *pError = CKR_TOKEN_NOT_PRESENT; return (nss_dbm_db_t *)NULL; } rv->crustylock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError); if( (NSSCKFWMutex *)NULL == rv->crustylock ) { return (nss_dbm_db_t *)NULL; } db_version = nss_dbm_db_get_format_version(rv); if( db_version.major != nss_dbm_db_format_version.major ) { nss_dbm_db_close(rv); *pError = CKR_TOKEN_NOT_RECOGNIZED; return (nss_dbm_db_t *)NULL; } return rv;}NSS_IMPLEMENT voidnss_dbm_db_close( nss_dbm_db_t *db){ if( (NSSCKFWMutex *)NULL != db->crustylock ) { (void)NSSCKFWMutex_Destroy(db->crustylock); } if( (DB *)NULL != db->db ) { (void)db->db->close(db->db); } nss_ZFreeIf(db);}NSS_IMPLEMENT CK_VERSIONnss_dbm_db_get_format_version( nss_dbm_db_t *db){ CK_VERSION rv; DBT k, v; int dbrv; char buffer[64]; rv.major = rv.minor = 0; k.data = PREFIX_METADATA "FormatVersion"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); (void)memset(&v, 0, sizeof(v)); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->get(db->db, &k, &v, 0); if( dbrv == 0 ) { CK_ULONG major = 0, minor = 0; (void)PR_sscanf(v.data, "%ld.%ld", &major, &minor); rv.major = major; rv.minor = minor; } else if( dbrv > 0 ) { (void)PR_snprintf(buffer, sizeof(buffer), "%ld.%ld", nss_dbm_db_format_version.major, nss_dbm_db_format_version.minor); v.data = buffer; v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL); dbrv = db->db->put(db->db, &k, &v, 0); (void)db->db->sync(db->db, 0); rv = nss_dbm_db_format_version; } else { /* No error return.. */ ; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv;}NSS_IMPLEMENT CK_RVnss_dbm_db_set_label( nss_dbm_db_t *db, NSSUTF8 *label){ CK_RV rv; DBT k, v; int dbrv; k.data = PREFIX_METADATA "Label"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); v.data = label; v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->put(db->db, &k, &v, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; } dbrv = db->db->sync(db->db, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv;}NSS_IMPLEMENT NSSUTF8 *nss_dbm_db_get_label( nss_dbm_db_t *db, NSSArena *arena, CK_RV *pError){ NSSUTF8 *rv = (NSSUTF8 *)NULL; DBT k, v; int dbrv; k.data = PREFIX_METADATA "Label"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->get(db->db, &k, &v, 0); if( 0 == dbrv ) { rv = nssUTF8_Duplicate((NSSUTF8 *)v.data, arena); if( (NSSUTF8 *)NULL == rv ) { *pError = CKR_HOST_MEMORY; } } else if( dbrv > 0 ) { /* Just return null */ ; } else { *pError = CKR_DEVICE_ERROR; ; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv;}NSS_IMPLEMENT CK_RVnss_dbm_db_delete_object( nss_dbm_dbt_t *dbt){ CK_RV rv; int dbrv; /* Locked region */ { rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock); if( CKR_OK != rv ) { return rv; } dbrv = dbt->my_db->db->del(dbt->my_db->db, &dbt->dbt, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; goto done; } dbrv = dbt->my_db->db->sync(dbt->my_db->db, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; goto done; } done: (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock); } return rv;}static CK_ULONGnss_dbm_db_new_handle( nss_dbm_db_t *db, DBT *dbt, /* pre-allocated */ CK_RV *pError){ CK_ULONG rv; DBT k, v; CK_ULONG align = 0, id, myid; struct handle *hp; if( sizeof(struct handle) != dbt->size ) { return EINVAL; } /* Locked region */ { *pError = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != *pError ) { return EINVAL; } k.data = PREFIX_METADATA "LastID"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); (void)memset(&v, 0, sizeof(v)); rv = db->db->get(db->db, &k, &v, 0); if( 0 == rv ) { (void)memcpy(&align, v.data, sizeof(CK_ULONG)); id = ntohl(align); } else if( rv > 0 ) { id = 0; } else { goto done; } myid = id; id++; align = htonl(id); v.data = &align; v.size = sizeof(CK_ULONG); rv = db->db->put(db->db, &k, &v, 0); if( 0 != rv ) { goto done; } rv = db->db->sync(db->db, 0); if( 0 != rv ) { goto done; } done: (void)NSSCKFWMutex_Unlock(db->crustylock); } if( 0 != rv ) { return rv; } hp = (struct handle *)dbt->data; (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4); hp->id = myid; return 0;}/* * This attribute-type-dependent swapping should probably * be in the Framework, because it'll be a concern of just * about every Module. Of course any Framework implementation * will have to be augmentable or overridable by a Module. */enum swap_type { type_byte, type_short, type_long, type_opaque };static enum swap_typenss_dbm_db_swap_type( CK_ATTRIBUTE_TYPE type){ switch( type ) { case CKA_CLASS: return type_long; case CKA_TOKEN: return type_byte; case CKA_PRIVATE: return type_byte; case CKA_LABEL: return type_opaque; case CKA_APPLICATION: return type_opaque; case CKA_VALUE: return type_opaque; case CKA_CERTIFICATE_TYPE: return type_long; case CKA_ISSUER: return type_opaque; case CKA_SERIAL_NUMBER: return type_opaque; case CKA_KEY_TYPE: return type_long; case CKA_SUBJECT: return type_opaque; case CKA_ID: return type_opaque; case CKA_SENSITIVE: return type_byte; case CKA_ENCRYPT: return type_byte; case CKA_DECRYPT: return type_byte; case CKA_WRAP: return type_byte; case CKA_UNWRAP: return type_byte; case CKA_SIGN: return type_byte; case CKA_SIGN_RECOVER: return type_byte; case CKA_VERIFY: return type_byte; case CKA_VERIFY_RECOVER: return type_byte; case CKA_DERIVE: return type_byte; case CKA_START_DATE: return type_opaque; case CKA_END_DATE: return type_opaque; case CKA_MODULUS: return type_opaque; case CKA_MODULUS_BITS: return type_long; case CKA_PUBLIC_EXPONENT: return type_opaque; case CKA_PRIVATE_EXPONENT: return type_opaque; case CKA_PRIME_1: return type_opaque; case CKA_PRIME_2: return type_opaque; case CKA_EXPONENT_1: return type_opaque; case CKA_EXPONENT_2: return type_opaque; case CKA_COEFFICIENT: return type_opaque; case CKA_PRIME: return type_opaque; case CKA_SUBPRIME: return type_opaque; case CKA_BASE: return type_opaque; case CKA_VALUE_BITS: return type_long; case CKA_VALUE_LEN: return type_long; case CKA_EXTRACTABLE: return type_byte; case CKA_LOCAL: return type_byte; case CKA_NEVER_EXTRACTABLE: return type_byte; case CKA_ALWAYS_SENSITIVE: return type_byte; case CKA_MODIFIABLE: return type_byte; case CKA_NETSCAPE_URL: return type_opaque; case CKA_NETSCAPE_EMAIL: return type_opaque; case CKA_NETSCAPE_SMIME_INFO: return type_opaque; case CKA_NETSCAPE_SMIME_TIMESTAMP: return type_opaque; case CKA_NETSCAPE_PKCS8_SALT: return type_opaque; case CKA_NETSCAPE_PASSWORD_CHECK: return type_opaque; case CKA_NETSCAPE_EXPIRES: return type_opaque; case CKA_TRUST_DIGITAL_SIGNATURE: return type_long; case CKA_TRUST_NON_REPUDIATION: return type_long; case CKA_TRUST_KEY_ENCIPHERMENT: return type_long; case CKA_TRUST_DATA_ENCIPHERMENT: return type_long; case CKA_TRUST_KEY_AGREEMENT: return type_long; case CKA_TRUST_KEY_CERT_SIGN: return type_long; case CKA_TRUST_CRL_SIGN: return type_long; case CKA_TRUST_SERVER_AUTH: return type_long; case CKA_TRUST_CLIENT_AUTH: return type_long; case CKA_TRUST_CODE_SIGNING: return type_long; case CKA_TRUST_EMAIL_PROTECTION: return type_long; case CKA_TRUST_IPSEC_END_SYSTEM: return type_long; case CKA_TRUST_IPSEC_TUNNEL: return type_long; case CKA_TRUST_IPSEC_USER: return type_long; case CKA_TRUST_TIME_STAMPING: return type_long; case CKA_NETSCAPE_DB: return type_opaque; case CKA_NETSCAPE_TRUST: return type_opaque; default: return type_opaque; }}static voidnss_dbm_db_swap_copy( CK_ATTRIBUTE_TYPE type, void *dest, void *src, CK_ULONG len){ switch( nss_dbm_db_swap_type(type) ) { case type_byte: case type_opaque: (void)memcpy(dest, src, len); break; case type_short: { CK_USHORT s, d; (void)memcpy(&s, src, sizeof(CK_USHORT)); d = htons(s); (void)memcpy(dest, &d, sizeof(CK_USHORT)); break; } case type_long: { CK_ULONG s, d; (void)memcpy(&s, src, sizeof(CK_ULONG)); d = htonl(s); (void)memcpy(dest, &d, sizeof(CK_ULONG)); break; } }}static CK_RVnss_dbm_db_wrap_object( NSSArena *arena, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, DBT *object){ CK_ULONG object_size; CK_ULONG i; CK_ULONG *pulData; char *pcData; CK_ULONG offset; object_size = (1 + ulAttributeCount*3) * sizeof(CK_ULONG); offset = object_size; for( i = 0; i < ulAttributeCount; i++ ) { object_size += pTemplate[i].ulValueLen; } object->size = object_size; object->data = nss_ZAlloc(arena, object_size); if( (void *)NULL == object->data ) { return CKR_HOST_MEMORY; } pulData = (CK_ULONG *)object->data; pcData = (char *)object->data; pulData[0] = htonl(ulAttributeCount); for( i = 0; i < ulAttributeCount; i++ ) { CK_ULONG len = pTemplate[i].ulValueLen; pulData[1 + i*3] = htonl(pTemplate[i].type); pulData[2 + i*3] = htonl(len); pulData[3 + i*3] = htonl(offset); nss_dbm_db_swap_copy(pTemplate[i].type, &pcData[offset], pTemplate[i].pValue, len); offset += len; } return CKR_OK;}static CK_RVnss_dbm_db_unwrap_object( NSSArena *arena, DBT *object, CK_ATTRIBUTE_PTR *ppTemplate, CK_ULONG *pulAttributeCount){ CK_ULONG *pulData; char *pcData; CK_ULONG n, i; CK_ATTRIBUTE_PTR pTemplate; pulData = (CK_ULONG *)object->data; pcData = (char *)object->data; n = ntohl(pulData[0]); *pulAttributeCount = n; pTemplate = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, n); if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { return CKR_HOST_MEMORY; } for( i = 0; i < n; i++ ) { CK_ULONG len; CK_ULONG offset; void *p; pTemplate[i].type = ntohl(pulData[1 + i*3]); len = ntohl(pulData[2 + i*3]); offset = ntohl(pulData[3 + i*3]);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?