security/nss/lib/ckfw/dbm/db.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "ckdbm.h"
     7 #define PREFIX_METADATA "0000"
     8 #define PREFIX_OBJECT   "0001"
     9 #define PREFIX_INDEX    "0002"
    11 static CK_VERSION nss_dbm_db_format_version = { 1, 0 };
    12 struct handle {
    13   char prefix[4];
    14   CK_ULONG id;
    15 };
    17 NSS_IMPLEMENT nss_dbm_db_t *
    18 nss_dbm_db_open
    19 (
    20   NSSArena *arena,
    21   NSSCKFWInstance *fwInstance,
    22   char *filename,
    23   int flags,
    24   CK_RV *pError
    25 )
    26 {
    27   nss_dbm_db_t *rv;
    28   CK_VERSION db_version;
    30   rv = nss_ZNEW(arena, nss_dbm_db_t);
    31   if( (nss_dbm_db_t *)NULL == rv ) {
    32     *pError = CKR_HOST_MEMORY;
    33     return (nss_dbm_db_t *)NULL;
    34   }
    36   rv->db = dbopen(filename, flags, 0600, DB_HASH, (const void *)NULL);
    37   if( (DB *)NULL == rv->db ) {
    38     *pError = CKR_TOKEN_NOT_PRESENT;
    39     return (nss_dbm_db_t *)NULL;
    40   }
    42   rv->crustylock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError);
    43   if( (NSSCKFWMutex *)NULL == rv->crustylock ) {
    44     return (nss_dbm_db_t *)NULL;
    45   }
    47   db_version = nss_dbm_db_get_format_version(rv);
    48   if( db_version.major != nss_dbm_db_format_version.major ) {
    49     nss_dbm_db_close(rv);
    50     *pError = CKR_TOKEN_NOT_RECOGNIZED;
    51     return (nss_dbm_db_t *)NULL;
    52   }
    54   return rv;
    55 }
    57 NSS_IMPLEMENT void
    58 nss_dbm_db_close
    59 (
    60   nss_dbm_db_t *db
    61 )
    62 {
    63   if( (NSSCKFWMutex *)NULL != db->crustylock ) {
    64     (void)NSSCKFWMutex_Destroy(db->crustylock);
    65   }
    67   if( (DB *)NULL != db->db ) {
    68     (void)db->db->close(db->db);
    69   }
    71   nss_ZFreeIf(db);
    72 }
    74 NSS_IMPLEMENT CK_VERSION
    75 nss_dbm_db_get_format_version
    76 (
    77   nss_dbm_db_t *db
    78 )
    79 {
    80   CK_VERSION rv;
    81   DBT k, v;
    82   int dbrv;
    83   char buffer[64];
    85   rv.major = rv.minor = 0;
    87   k.data = PREFIX_METADATA "FormatVersion";
    88   k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
    89   (void)memset(&v, 0, sizeof(v));
    91   /* Locked region */ 
    92   {
    93     if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
    94       return rv;
    95     }
    97     dbrv = db->db->get(db->db, &k, &v, 0);
    98     if( dbrv == 0 ) {
    99       CK_ULONG major = 0, minor = 0;
   100       (void)PR_sscanf(v.data, "%ld.%ld", &major, &minor);
   101       rv.major = major;
   102       rv.minor = minor;
   103     } else if( dbrv > 0 ) {
   104       (void)PR_snprintf(buffer, sizeof(buffer), "%ld.%ld", nss_dbm_db_format_version.major,
   105                         nss_dbm_db_format_version.minor);
   106       v.data = buffer;
   107       v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL);
   108       dbrv = db->db->put(db->db, &k, &v, 0);
   109       (void)db->db->sync(db->db, 0);
   110       rv = nss_dbm_db_format_version;
   111     } else {
   112       /* No error return.. */
   113       ;
   114     }
   116     (void)NSSCKFWMutex_Unlock(db->crustylock);
   117   }
   119   return rv;
   120 }
   122 NSS_IMPLEMENT CK_RV
   123 nss_dbm_db_set_label
   124 (
   125   nss_dbm_db_t *db,
   126   NSSUTF8 *label
   127 )
   128 {
   129   CK_RV rv;
   130   DBT k, v;
   131   int dbrv;
   133   k.data = PREFIX_METADATA "Label";
   134   k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
   135   v.data = label;
   136   v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL);
   138   /* Locked region */ 
   139   {
   140     if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
   141       return rv;
   142     }
   144     dbrv = db->db->put(db->db, &k, &v, 0);
   145     if( 0 != dbrv ) {
   146       rv = CKR_DEVICE_ERROR;
   147     }
   149     dbrv = db->db->sync(db->db, 0);
   150     if( 0 != dbrv ) {
   151       rv = CKR_DEVICE_ERROR;
   152     }
   154     (void)NSSCKFWMutex_Unlock(db->crustylock);
   155   }
   157   return rv;
   158 }
   160 NSS_IMPLEMENT NSSUTF8 *
   161 nss_dbm_db_get_label
   162 (
   163   nss_dbm_db_t *db,
   164   NSSArena *arena,
   165   CK_RV *pError
   166 )
   167 {
   168   NSSUTF8 *rv = (NSSUTF8 *)NULL;
   169   DBT k, v;
   170   int dbrv;
   172   k.data = PREFIX_METADATA "Label";
   173   k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
   175   /* Locked region */ 
   176   {
   177     if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) {
   178       return rv;
   179     }
   181     dbrv = db->db->get(db->db, &k, &v, 0);
   182     if( 0 == dbrv ) {
   183       rv = nssUTF8_Duplicate((NSSUTF8 *)v.data, arena);
   184       if( (NSSUTF8 *)NULL == rv ) {
   185         *pError = CKR_HOST_MEMORY;
   186       }
   187     } else if( dbrv > 0 ) {
   188       /* Just return null */
   189       ;
   190     } else {
   191       *pError = CKR_DEVICE_ERROR;
   192       ;
   193     }
   196     (void)NSSCKFWMutex_Unlock(db->crustylock);
   197   }
   199   return rv;
   200 }
   202 NSS_IMPLEMENT CK_RV
   203 nss_dbm_db_delete_object
   204 (
   205   nss_dbm_dbt_t *dbt
   206 )
   207 {
   208   CK_RV rv;
   209   int dbrv;
   211   /* Locked region */
   212   {
   213     rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   214     if( CKR_OK != rv ) {
   215       return rv;
   216     }
   218     dbrv = dbt->my_db->db->del(dbt->my_db->db, &dbt->dbt, 0);
   219     if( 0 != dbrv ) {
   220       rv = CKR_DEVICE_ERROR;
   221       goto done;
   222     }
   224     dbrv = dbt->my_db->db->sync(dbt->my_db->db, 0);
   225     if( 0 != dbrv ) {
   226       rv = CKR_DEVICE_ERROR;
   227       goto done;
   228     }
   230   done:
   231     (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
   232   }
   234   return rv;
   235 }
   237 static CK_ULONG
   238 nss_dbm_db_new_handle
   239 (
   240   nss_dbm_db_t *db,
   241   DBT *dbt, /* pre-allocated */
   242   CK_RV *pError
   243 )
   244 {
   245   CK_ULONG rv;
   246   DBT k, v;
   247   CK_ULONG align = 0, id, myid;
   248   struct handle *hp;
   250   if( sizeof(struct handle) != dbt->size ) {
   251     return EINVAL;
   252   }
   254   /* Locked region */
   255   {
   256     *pError = NSSCKFWMutex_Lock(db->crustylock);
   257     if( CKR_OK != *pError ) {
   258       return EINVAL;
   259     }
   261     k.data = PREFIX_METADATA "LastID";
   262     k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL);
   263     (void)memset(&v, 0, sizeof(v));
   265     rv = db->db->get(db->db, &k, &v, 0);
   266     if( 0 == rv ) {
   267       (void)memcpy(&align, v.data, sizeof(CK_ULONG));
   268       id = ntohl(align);
   269     } else if( rv > 0 ) {
   270       id = 0;
   271     } else {
   272       goto done;
   273     }
   275     myid = id;
   276     id++;
   277     align = htonl(id);
   278     v.data = &align;
   279     v.size = sizeof(CK_ULONG);
   281     rv = db->db->put(db->db, &k, &v, 0);
   282     if( 0 != rv ) {
   283       goto done;
   284     }
   286     rv = db->db->sync(db->db, 0);
   287     if( 0 != rv ) {
   288       goto done;
   289     }
   291   done:
   292     (void)NSSCKFWMutex_Unlock(db->crustylock);
   293   }
   295   if( 0 != rv ) {
   296     return rv;
   297   }
   299   hp = (struct handle *)dbt->data;
   300   (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4);
   301   hp->id = myid;
   303   return 0;
   304 }
   306 /*
   307  * This attribute-type-dependent swapping should probably
   308  * be in the Framework, because it'll be a concern of just
   309  * about every Module.  Of course any Framework implementation
   310  * will have to be augmentable or overridable by a Module.
   311  */
   313 enum swap_type { type_byte, type_short, type_long, type_opaque };
   315 static enum swap_type
   316 nss_dbm_db_swap_type
   317 (
   318   CK_ATTRIBUTE_TYPE type
   319 )
   320 {
   321   switch( type ) {
   322   case CKA_CLASS: return type_long;
   323   case CKA_TOKEN: return type_byte;
   324   case CKA_PRIVATE: return type_byte;
   325   case CKA_LABEL: return type_opaque;
   326   case CKA_APPLICATION: return type_opaque;
   327   case CKA_VALUE: return type_opaque;
   328   case CKA_CERTIFICATE_TYPE: return type_long;
   329   case CKA_ISSUER: return type_opaque;
   330   case CKA_SERIAL_NUMBER: return type_opaque;
   331   case CKA_KEY_TYPE: return type_long;
   332   case CKA_SUBJECT: return type_opaque;
   333   case CKA_ID: return type_opaque;
   334   case CKA_SENSITIVE: return type_byte;
   335   case CKA_ENCRYPT: return type_byte;
   336   case CKA_DECRYPT: return type_byte;
   337   case CKA_WRAP: return type_byte;
   338   case CKA_UNWRAP: return type_byte;
   339   case CKA_SIGN: return type_byte;
   340   case CKA_SIGN_RECOVER: return type_byte;
   341   case CKA_VERIFY: return type_byte;
   342   case CKA_VERIFY_RECOVER: return type_byte;
   343   case CKA_DERIVE: return type_byte;
   344   case CKA_START_DATE: return type_opaque;
   345   case CKA_END_DATE: return type_opaque;
   346   case CKA_MODULUS: return type_opaque;
   347   case CKA_MODULUS_BITS: return type_long;
   348   case CKA_PUBLIC_EXPONENT: return type_opaque;
   349   case CKA_PRIVATE_EXPONENT: return type_opaque;
   350   case CKA_PRIME_1: return type_opaque;
   351   case CKA_PRIME_2: return type_opaque;
   352   case CKA_EXPONENT_1: return type_opaque;
   353   case CKA_EXPONENT_2: return type_opaque;
   354   case CKA_COEFFICIENT: return type_opaque;
   355   case CKA_PRIME: return type_opaque;
   356   case CKA_SUBPRIME: return type_opaque;
   357   case CKA_BASE: return type_opaque;
   358   case CKA_VALUE_BITS: return type_long;
   359   case CKA_VALUE_LEN: return type_long;
   360   case CKA_EXTRACTABLE: return type_byte;
   361   case CKA_LOCAL: return type_byte;
   362   case CKA_NEVER_EXTRACTABLE: return type_byte;
   363   case CKA_ALWAYS_SENSITIVE: return type_byte;
   364   case CKA_MODIFIABLE: return type_byte;
   365   case CKA_NETSCAPE_URL: return type_opaque;
   366   case CKA_NETSCAPE_EMAIL: return type_opaque;
   367   case CKA_NETSCAPE_SMIME_INFO: return type_opaque;
   368   case CKA_NETSCAPE_SMIME_TIMESTAMP: return type_opaque;
   369   case CKA_NETSCAPE_PKCS8_SALT: return type_opaque;
   370   case CKA_NETSCAPE_PASSWORD_CHECK: return type_opaque;
   371   case CKA_NETSCAPE_EXPIRES: return type_opaque;
   372   case CKA_TRUST_DIGITAL_SIGNATURE: return type_long;
   373   case CKA_TRUST_NON_REPUDIATION: return type_long;
   374   case CKA_TRUST_KEY_ENCIPHERMENT: return type_long;
   375   case CKA_TRUST_DATA_ENCIPHERMENT: return type_long;
   376   case CKA_TRUST_KEY_AGREEMENT: return type_long;
   377   case CKA_TRUST_KEY_CERT_SIGN: return type_long;
   378   case CKA_TRUST_CRL_SIGN: return type_long;
   379   case CKA_TRUST_SERVER_AUTH: return type_long;
   380   case CKA_TRUST_CLIENT_AUTH: return type_long;
   381   case CKA_TRUST_CODE_SIGNING: return type_long;
   382   case CKA_TRUST_EMAIL_PROTECTION: return type_long;
   383   case CKA_TRUST_IPSEC_END_SYSTEM: return type_long;
   384   case CKA_TRUST_IPSEC_TUNNEL: return type_long;
   385   case CKA_TRUST_IPSEC_USER: return type_long;
   386   case CKA_TRUST_TIME_STAMPING: return type_long;
   387   case CKA_NETSCAPE_DB: return type_opaque;
   388   case CKA_NETSCAPE_TRUST: return type_opaque;
   389   default: return type_opaque;
   390   }
   391 }
   393 static void
   394 nss_dbm_db_swap_copy
   395 (
   396   CK_ATTRIBUTE_TYPE type,
   397   void *dest,
   398   void *src,
   399   CK_ULONG len
   400 )
   401 {
   402   switch( nss_dbm_db_swap_type(type) ) {
   403   case type_byte:
   404   case type_opaque:
   405     (void)memcpy(dest, src, len);
   406     break;
   407   case type_short:
   408     {
   409       CK_USHORT s, d;
   410       (void)memcpy(&s, src, sizeof(CK_USHORT));
   411       d = htons(s);
   412       (void)memcpy(dest, &d, sizeof(CK_USHORT));
   413       break;
   414     }
   415   case type_long:
   416     {
   417       CK_ULONG s, d;
   418       (void)memcpy(&s, src, sizeof(CK_ULONG));
   419       d = htonl(s);
   420       (void)memcpy(dest, &d, sizeof(CK_ULONG));
   421       break;
   422     }
   423   }
   424 }
   426 static CK_RV
   427 nss_dbm_db_wrap_object
   428 (
   429   NSSArena *arena,
   430   CK_ATTRIBUTE_PTR pTemplate,
   431   CK_ULONG ulAttributeCount,
   432   DBT *object
   433 )
   434 {
   435   CK_ULONG object_size;
   436   CK_ULONG i;
   437   CK_ULONG *pulData;
   438   char *pcData;
   439   CK_ULONG offset;
   441   object_size = (1 + ulAttributeCount*3) * sizeof(CK_ULONG);
   442   offset = object_size;
   443   for( i = 0; i < ulAttributeCount; i++ ) {
   444     object_size += pTemplate[i].ulValueLen;
   445   }
   447   object->size = object_size;
   448   object->data = nss_ZAlloc(arena, object_size);
   449   if( (void *)NULL == object->data ) {
   450     return CKR_HOST_MEMORY;
   451   }
   453   pulData = (CK_ULONG *)object->data;
   454   pcData = (char *)object->data;
   456   pulData[0] = htonl(ulAttributeCount);
   457   for( i = 0; i < ulAttributeCount; i++ ) {
   458     CK_ULONG len = pTemplate[i].ulValueLen;
   459     pulData[1 + i*3] = htonl(pTemplate[i].type);
   460     pulData[2 + i*3] = htonl(len);
   461     pulData[3 + i*3] = htonl(offset);
   462     nss_dbm_db_swap_copy(pTemplate[i].type, &pcData[offset], pTemplate[i].pValue, len);
   463     offset += len;
   464   }
   466   return CKR_OK;
   467 }
   469 static CK_RV
   470 nss_dbm_db_unwrap_object
   471 (
   472   NSSArena *arena,
   473   DBT *object,
   474   CK_ATTRIBUTE_PTR *ppTemplate,
   475   CK_ULONG *pulAttributeCount
   476 )
   477 {
   478   CK_ULONG *pulData;
   479   char *pcData;
   480   CK_ULONG n, i;
   481   CK_ATTRIBUTE_PTR pTemplate;
   483   pulData = (CK_ULONG *)object->data;
   484   pcData = (char *)object->data;
   486   n = ntohl(pulData[0]);
   487   *pulAttributeCount = n;
   488   pTemplate = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, n);
   489   if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
   490     return CKR_HOST_MEMORY;
   491   }
   493   for( i = 0; i < n; i++ ) {
   494     CK_ULONG len;
   495     CK_ULONG offset;
   496     void *p;
   498     pTemplate[i].type = ntohl(pulData[1 + i*3]);
   499     len = ntohl(pulData[2 + i*3]);
   500     offset = ntohl(pulData[3 +  i*3]);
   502     p = nss_ZAlloc(arena, len);
   503     if( (void *)NULL == p ) {
   504       return CKR_HOST_MEMORY;
   505     }
   507     nss_dbm_db_swap_copy(pTemplate[i].type, p, &pcData[offset], len);
   508     pTemplate[i].ulValueLen = len;
   509     pTemplate[i].pValue = p;
   510   }
   512   *ppTemplate = pTemplate;
   513   return CKR_OK;
   514 }
   517 NSS_IMPLEMENT nss_dbm_dbt_t *
   518 nss_dbm_db_create_object
   519 (
   520   NSSArena *arena,
   521   nss_dbm_db_t *db,
   522   CK_ATTRIBUTE_PTR pTemplate,
   523   CK_ULONG ulAttributeCount,
   524   CK_RV *pError,
   525   CK_ULONG *pdbrv
   526 )
   527 {
   528   NSSArena *tmparena = (NSSArena *)NULL;
   529   nss_dbm_dbt_t *rv = (nss_dbm_dbt_t *)NULL;
   530   DBT object;
   532   rv = nss_ZNEW(arena, nss_dbm_dbt_t);
   533   if( (nss_dbm_dbt_t *)NULL == rv ) {
   534     *pError = CKR_HOST_MEMORY;
   535     return (nss_dbm_dbt_t *)NULL;
   536   }
   538   rv->my_db = db;
   539   rv->dbt.size = sizeof(struct handle);
   540   rv->dbt.data = nss_ZAlloc(arena, rv->dbt.size);
   541   if( (void *)NULL == rv->dbt.data ) {
   542     *pError = CKR_HOST_MEMORY;
   543     return (nss_dbm_dbt_t *)NULL;
   544   }
   546   *pdbrv = nss_dbm_db_new_handle(db, &rv->dbt, pError);
   547   if( 0 != *pdbrv ) {
   548     return (nss_dbm_dbt_t *)NULL;
   549   }
   551   tmparena = NSSArena_Create();
   552   if( (NSSArena *)NULL == tmparena ) {
   553     *pError = CKR_HOST_MEMORY;
   554     return (nss_dbm_dbt_t *)NULL;
   555   }
   557   *pError = nss_dbm_db_wrap_object(tmparena, pTemplate, ulAttributeCount, &object);
   558   if( CKR_OK != *pError ) {
   559     return (nss_dbm_dbt_t *)NULL;
   560   }
   562   /* Locked region */
   563   {
   564     *pError = NSSCKFWMutex_Lock(db->crustylock);
   565     if( CKR_OK != *pError ) {
   566       goto loser;
   567     }
   569     *pdbrv = db->db->put(db->db, &rv->dbt, &object, 0);
   570     if( 0 != *pdbrv ) {
   571       *pError = CKR_DEVICE_ERROR;
   572     }
   574     (void)db->db->sync(db->db, 0);
   576     (void)NSSCKFWMutex_Unlock(db->crustylock);
   577   }
   579  loser:  
   580   if( (NSSArena *)NULL != tmparena ) {
   581     (void)NSSArena_Destroy(tmparena);
   582   }
   584   return rv;
   585 }
   588 NSS_IMPLEMENT CK_RV
   589 nss_dbm_db_find_objects
   590 (
   591   nss_dbm_find_t *find,
   592   nss_dbm_db_t *db,
   593   CK_ATTRIBUTE_PTR pTemplate,
   594   CK_ULONG ulAttributeCount,
   595   CK_ULONG *pdbrv
   596 )
   597 {
   598   CK_RV rv = CKR_OK;
   600   if( (nss_dbm_db_t *)NULL != db ) {
   601     DBT k, v;
   603     rv = NSSCKFWMutex_Lock(db->crustylock);
   604     if( CKR_OK != rv ) {
   605       return rv;
   606     }
   608     *pdbrv = db->db->seq(db->db, &k, &v, R_FIRST);
   609     while( 0 == *pdbrv ) {
   610       CK_ULONG i, j;
   611       NSSArena *tmparena = (NSSArena *)NULL;
   612       CK_ULONG ulac;
   613       CK_ATTRIBUTE_PTR pt;
   615       if( (k.size < 4) || (0 != memcmp(k.data, PREFIX_OBJECT, 4)) ) {
   616         goto nomatch;
   617       }
   619       tmparena = NSSArena_Create();
   621       rv = nss_dbm_db_unwrap_object(tmparena, &v, &pt, &ulac);
   622       if( CKR_OK != rv ) {
   623         goto loser;
   624       }
   626       for( i = 0; i < ulAttributeCount; i++ ) {
   627         for( j = 0; j < ulac; j++ ) {
   628           if( pTemplate[i].type == pt[j].type ) {
   629             if( pTemplate[i].ulValueLen != pt[j].ulValueLen ) {
   630               goto nomatch;
   631             }
   632             if( 0 != memcmp(pTemplate[i].pValue, pt[j].pValue, pt[j].ulValueLen) ) {
   633               goto nomatch;
   634             }
   635             break;
   636           }
   637         }
   638         if( j == ulac ) {
   639           goto nomatch;
   640         }
   641       }
   643       /* entire template matches */
   644       {
   645         struct nss_dbm_dbt_node *node;
   647         node = nss_ZNEW(find->arena, struct nss_dbm_dbt_node);
   648         if( (struct nss_dbm_dbt_node *)NULL == node ) {
   649           rv = CKR_HOST_MEMORY;
   650           goto loser;
   651         }
   653         node->dbt = nss_ZNEW(find->arena, nss_dbm_dbt_t);
   654         if( (nss_dbm_dbt_t *)NULL == node->dbt ) {
   655           rv = CKR_HOST_MEMORY;
   656           goto loser;
   657         }
   659         node->dbt->dbt.size = k.size;
   660         node->dbt->dbt.data = nss_ZAlloc(find->arena, k.size);
   661         if( (void *)NULL == node->dbt->dbt.data ) {
   662           rv = CKR_HOST_MEMORY;
   663           goto loser;
   664         }
   666         (void)memcpy(node->dbt->dbt.data, k.data, k.size);
   668         node->dbt->my_db = db;
   670         node->next = find->found;
   671         find->found = node;
   672       }
   674     nomatch:
   675       if( (NSSArena *)NULL != tmparena ) {
   676         (void)NSSArena_Destroy(tmparena);
   677       }
   678       *pdbrv = db->db->seq(db->db, &k, &v, R_NEXT);
   679     }
   681     if( *pdbrv < 0 ) {
   682       rv = CKR_DEVICE_ERROR;
   683       goto loser;
   684     }
   686     rv = CKR_OK;
   688   loser:
   689     (void)NSSCKFWMutex_Unlock(db->crustylock);
   690   }
   692   return rv;
   693 }
   695 NSS_IMPLEMENT CK_BBOOL
   696 nss_dbm_db_object_still_exists
   697 (
   698   nss_dbm_dbt_t *dbt
   699 )
   700 {
   701   CK_BBOOL rv;
   702   CK_RV ckrv;
   703   int dbrv;
   704   DBT object;
   706   ckrv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   707   if( CKR_OK != ckrv ) {
   708     return CK_FALSE;
   709   }
   711   dbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
   712   if( 0 == dbrv ) {
   713     rv = CK_TRUE;
   714   } else {
   715     rv = CK_FALSE;
   716   }
   718   (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
   720   return rv;
   721 }
   723 NSS_IMPLEMENT CK_ULONG
   724 nss_dbm_db_get_object_attribute_count
   725 (
   726   nss_dbm_dbt_t *dbt,
   727   CK_RV *pError,
   728   CK_ULONG *pdbrv
   729 )
   730 {
   731   CK_ULONG rv = 0;
   732   DBT object;
   733   CK_ULONG *pulData;
   735   /* Locked region */
   736   {
   737     *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   738     if( CKR_OK != *pError ) {
   739       return rv;
   740     }
   742     *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
   743     if( 0 == *pdbrv ) {
   744       ;
   745     } else if( *pdbrv > 0 ) {
   746       *pError = CKR_OBJECT_HANDLE_INVALID;
   747       goto done;
   748     } else {
   749       *pError = CKR_DEVICE_ERROR;
   750       goto done;
   751     }
   753     pulData = (CK_ULONG *)object.data;
   754     rv = ntohl(pulData[0]);
   756   done:
   757     (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
   758   }
   760   return rv;
   761 }
   763 NSS_IMPLEMENT CK_RV
   764 nss_dbm_db_get_object_attribute_types
   765 (
   766   nss_dbm_dbt_t *dbt,
   767   CK_ATTRIBUTE_TYPE_PTR typeArray,
   768   CK_ULONG ulCount,
   769   CK_ULONG *pdbrv
   770 )
   771 {
   772   CK_RV rv = CKR_OK;
   773   DBT object;
   774   CK_ULONG *pulData;
   775   CK_ULONG n, i;
   777   /* Locked region */
   778   {
   779     rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   780     if( CKR_OK != rv ) {
   781       return rv;
   782     }
   784     *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
   785     if( 0 == *pdbrv ) {
   786       ;
   787     } else if( *pdbrv > 0 ) {
   788       rv = CKR_OBJECT_HANDLE_INVALID;
   789       goto done;
   790     } else {
   791       rv = CKR_DEVICE_ERROR;
   792       goto done;
   793     }
   795     pulData = (CK_ULONG *)object.data;
   796     n = ntohl(pulData[0]);
   798     if( ulCount < n ) {
   799       rv = CKR_BUFFER_TOO_SMALL;
   800       goto done;
   801     }
   803     for( i = 0; i < n; i++ ) {
   804       typeArray[i] = ntohl(pulData[1 + i*3]);
   805     }
   807   done:
   808     (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
   809   }
   811   return rv;
   812 }
   814 NSS_IMPLEMENT CK_ULONG
   815 nss_dbm_db_get_object_attribute_size
   816 (
   817   nss_dbm_dbt_t *dbt,
   818   CK_ATTRIBUTE_TYPE type,
   819   CK_RV *pError,
   820   CK_ULONG *pdbrv
   821 )
   822 {
   823   CK_ULONG rv = 0;
   824   DBT object;
   825   CK_ULONG *pulData;
   826   CK_ULONG n, i;
   828   /* Locked region */
   829   {
   830     *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   831     if( CKR_OK != *pError ) {
   832       return rv;
   833     }
   835     *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
   836     if( 0 == *pdbrv ) {
   837       ;
   838     } else if( *pdbrv > 0 ) {
   839       *pError = CKR_OBJECT_HANDLE_INVALID;
   840       goto done;
   841     } else {
   842       *pError = CKR_DEVICE_ERROR;
   843       goto done;
   844     }
   846     pulData = (CK_ULONG *)object.data;
   847     n = ntohl(pulData[0]);
   849     for( i = 0; i < n; i++ ) {
   850       if( type == ntohl(pulData[1 + i*3]) ) {
   851         rv = ntohl(pulData[2 + i*3]);
   852       }
   853     }
   855     if( i == n ) {
   856       *pError = CKR_ATTRIBUTE_TYPE_INVALID;
   857       goto done;
   858     }
   860   done:
   861     (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
   862   }
   864   return rv;
   865 }
   867 NSS_IMPLEMENT NSSItem *
   868 nss_dbm_db_get_object_attribute
   869 (
   870   nss_dbm_dbt_t *dbt,
   871   NSSArena *arena,
   872   CK_ATTRIBUTE_TYPE type,
   873   CK_RV *pError,
   874   CK_ULONG *pdbrv
   875 )
   876 {
   877   NSSItem *rv = (NSSItem *)NULL;
   878   DBT object;
   879   CK_ULONG i;
   880   NSSArena *tmp = NSSArena_Create();
   881   CK_ATTRIBUTE_PTR pTemplate;
   882   CK_ULONG ulAttributeCount;
   884   /* Locked region */
   885   {
   886     *pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   887     if( CKR_OK != *pError ) {
   888       goto loser;
   889     }
   891     *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
   892     if( 0 == *pdbrv ) {
   893       ;
   894     } else if( *pdbrv > 0 ) {
   895       *pError = CKR_OBJECT_HANDLE_INVALID;
   896       goto done;
   897     } else {
   898       *pError = CKR_DEVICE_ERROR;
   899       goto done;
   900     }
   902     *pError = nss_dbm_db_unwrap_object(tmp, &object, &pTemplate, &ulAttributeCount);
   903     if( CKR_OK != *pError ) {
   904       goto done;
   905     }
   907     for( i = 0; i < ulAttributeCount; i++ ) {
   908       if( type == pTemplate[i].type ) {
   909         rv = nss_ZNEW(arena, NSSItem);
   910         if( (NSSItem *)NULL == rv ) {
   911           *pError = CKR_HOST_MEMORY;
   912           goto done;
   913         }
   914         rv->size = pTemplate[i].ulValueLen;
   915         rv->data = nss_ZAlloc(arena, rv->size);
   916         if( (void *)NULL == rv->data ) {
   917           *pError = CKR_HOST_MEMORY;
   918           goto done;
   919         }
   920         (void)memcpy(rv->data, pTemplate[i].pValue, rv->size);
   921         break;
   922       }
   923     }
   924     if( ulAttributeCount == i ) {
   925       *pError = CKR_ATTRIBUTE_TYPE_INVALID;
   926       goto done;
   927     }
   929   done:
   930     (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
   931   }
   933  loser:
   934   if( (NSSArena *)NULL != tmp ) {
   935     NSSArena_Destroy(tmp);
   936   }
   938   return rv;
   939 }
   941 NSS_IMPLEMENT CK_RV
   942 nss_dbm_db_set_object_attribute
   943 (
   944   nss_dbm_dbt_t *dbt,
   945   CK_ATTRIBUTE_TYPE type,
   946   NSSItem *value,
   947   CK_ULONG *pdbrv
   948 )
   949 {
   950   CK_RV rv = CKR_OK;
   951   DBT object;
   952   CK_ULONG i;
   953   NSSArena *tmp = NSSArena_Create();
   954   CK_ATTRIBUTE_PTR pTemplate;
   955   CK_ULONG ulAttributeCount;
   957   /* Locked region */
   958   {
   959     rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
   960     if( CKR_OK != rv ) {
   961       goto loser;
   962     }
   964     *pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
   965     if( 0 == *pdbrv ) {
   966       ;
   967     } else if( *pdbrv > 0 ) {
   968       rv = CKR_OBJECT_HANDLE_INVALID;
   969       goto done;
   970     } else {
   971       rv = CKR_DEVICE_ERROR;
   972       goto done;
   973     }
   975     rv = nss_dbm_db_unwrap_object(tmp, &object, &pTemplate, &ulAttributeCount);
   976     if( CKR_OK != rv ) {
   977       goto done;
   978     }
   980     for( i = 0; i < ulAttributeCount; i++ ) {
   981       if( type == pTemplate[i].type ) {
   982         /* Replacing an existing attribute */
   983         pTemplate[i].ulValueLen = value->size;
   984         pTemplate[i].pValue = value->data;
   985         break;
   986       }
   987     }
   989     if( i == ulAttributeCount ) {
   990       /* Adding a new attribute */
   991       CK_ATTRIBUTE_PTR npt = nss_ZNEWARRAY(tmp, CK_ATTRIBUTE, ulAttributeCount+1);
   992       if( (CK_ATTRIBUTE_PTR)NULL == npt ) {
   993         rv = CKR_DEVICE_ERROR;
   994         goto done;
   995       }
   997       for( i = 0; i < ulAttributeCount; i++ ) {
   998         npt[i] = pTemplate[i];
   999       }
  1001       npt[ulAttributeCount].type = type;
  1002       npt[ulAttributeCount].ulValueLen = value->size;
  1003       npt[ulAttributeCount].pValue = value->data;
  1005       pTemplate = npt;
  1006       ulAttributeCount++;
  1009     rv = nss_dbm_db_wrap_object(tmp, pTemplate, ulAttributeCount, &object);
  1010     if( CKR_OK != rv ) {
  1011       goto done;
  1014     *pdbrv = dbt->my_db->db->put(dbt->my_db->db, &dbt->dbt, &object, 0);
  1015     if( 0 != *pdbrv ) {
  1016       rv = CKR_DEVICE_ERROR;
  1017       goto done;
  1020     (void)dbt->my_db->db->sync(dbt->my_db->db, 0);
  1022   done:
  1023     (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
  1026  loser:
  1027   if( (NSSArena *)NULL != tmp ) {
  1028     NSSArena_Destroy(tmp);
  1031   return rv;

mercurial