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