2018-05-04 16:08:28 +02:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2015-10-21 05:03:22 +02:00
|
|
|
|
|
|
|
#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 void
|
|
|
|
nss_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_VERSION
|
|
|
|
nss_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_RV
|
|
|
|
nss_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 */
|
|
|
|
{
|
cherry-picked mozilla NSS upstream changes (to rev 82de44ead36f, which is on par with 3.18):
bug1095307, bug1073330(backout), bug1084986, bug1050069, bug942172, bug1054547, bug532081, bug1096348, bug1058870, bug1093940, bug1102985, bug1112461, bug1094492, bug112029, bug1119983, bug1120685, bug1120691, bug1113632, bug863076, bug1082973, bug1124539, bug1117617, bug1117621, bug1121273, bug753136, bug921684, bug1132818, bug1125375, bug647690, bug1055441, bug1134455, bug975010, bug950369, bug1128367, bug1129573, bug1136095, bug1117897, bug1113453, bug1061725, bug1073330, bug1111901, bug1083900, bug1136095, bug1138820, bug1096741, bug1134548, bug345725, bug950348, bug950344, bug1151037, bug991783, bug1153994
2018-07-11 16:42:30 +02:00
|
|
|
rv = NSSCKFWMutex_Lock(db->crustylock);
|
|
|
|
if( CKR_OK != rv ) {
|
2015-10-21 05:03:22 +02:00
|
|
|
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_RV
|
|
|
|
nss_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_ULONG
|
|
|
|
nss_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_type
|
|
|
|
nss_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 void
|
|
|
|
nss_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_RV
|
|
|
|
nss_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_RV
|
|
|
|
nss_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]);
|
|
|
|
|
|
|
|
p = nss_ZAlloc(arena, len);
|
|
|
|
if( (void *)NULL == p ) {
|
|
|
|
return CKR_HOST_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
nss_dbm_db_swap_copy(pTemplate[i].type, p, &pcData[offset], len);
|
|
|
|
pTemplate[i].ulValueLen = len;
|
|
|
|
pTemplate[i].pValue = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppTemplate = pTemplate;
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NSS_IMPLEMENT nss_dbm_dbt_t *
|
|
|
|
nss_dbm_db_create_object
|
|
|
|
(
|
|
|
|
NSSArena *arena,
|
|
|
|
nss_dbm_db_t *db,
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate,
|
|
|
|
CK_ULONG ulAttributeCount,
|
|
|
|
CK_RV *pError,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NSSArena *tmparena = (NSSArena *)NULL;
|
|
|
|
nss_dbm_dbt_t *rv = (nss_dbm_dbt_t *)NULL;
|
|
|
|
DBT object;
|
|
|
|
|
|
|
|
rv = nss_ZNEW(arena, nss_dbm_dbt_t);
|
|
|
|
if( (nss_dbm_dbt_t *)NULL == rv ) {
|
|
|
|
*pError = CKR_HOST_MEMORY;
|
|
|
|
return (nss_dbm_dbt_t *)NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv->my_db = db;
|
|
|
|
rv->dbt.size = sizeof(struct handle);
|
|
|
|
rv->dbt.data = nss_ZAlloc(arena, rv->dbt.size);
|
|
|
|
if( (void *)NULL == rv->dbt.data ) {
|
|
|
|
*pError = CKR_HOST_MEMORY;
|
|
|
|
return (nss_dbm_dbt_t *)NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = nss_dbm_db_new_handle(db, &rv->dbt, pError);
|
|
|
|
if( 0 != *pdbrv ) {
|
|
|
|
return (nss_dbm_dbt_t *)NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmparena = NSSArena_Create();
|
|
|
|
if( (NSSArena *)NULL == tmparena ) {
|
|
|
|
*pError = CKR_HOST_MEMORY;
|
|
|
|
return (nss_dbm_dbt_t *)NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pError = nss_dbm_db_wrap_object(tmparena, pTemplate, ulAttributeCount, &object);
|
|
|
|
if( CKR_OK != *pError ) {
|
|
|
|
return (nss_dbm_dbt_t *)NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Locked region */
|
|
|
|
{
|
|
|
|
*pError = NSSCKFWMutex_Lock(db->crustylock);
|
|
|
|
if( CKR_OK != *pError ) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = db->db->put(db->db, &rv->dbt, &object, 0);
|
|
|
|
if( 0 != *pdbrv ) {
|
|
|
|
*pError = CKR_DEVICE_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)db->db->sync(db->db, 0);
|
|
|
|
|
|
|
|
(void)NSSCKFWMutex_Unlock(db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
loser:
|
|
|
|
if( (NSSArena *)NULL != tmparena ) {
|
|
|
|
(void)NSSArena_Destroy(tmparena);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NSS_IMPLEMENT CK_RV
|
|
|
|
nss_dbm_db_find_objects
|
|
|
|
(
|
|
|
|
nss_dbm_find_t *find,
|
|
|
|
nss_dbm_db_t *db,
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate,
|
|
|
|
CK_ULONG ulAttributeCount,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CK_RV rv = CKR_OK;
|
|
|
|
|
|
|
|
if( (nss_dbm_db_t *)NULL != db ) {
|
|
|
|
DBT k, v;
|
|
|
|
|
|
|
|
rv = NSSCKFWMutex_Lock(db->crustylock);
|
|
|
|
if( CKR_OK != rv ) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = db->db->seq(db->db, &k, &v, R_FIRST);
|
|
|
|
while( 0 == *pdbrv ) {
|
|
|
|
CK_ULONG i, j;
|
|
|
|
NSSArena *tmparena = (NSSArena *)NULL;
|
|
|
|
CK_ULONG ulac;
|
|
|
|
CK_ATTRIBUTE_PTR pt;
|
|
|
|
|
|
|
|
if( (k.size < 4) || (0 != memcmp(k.data, PREFIX_OBJECT, 4)) ) {
|
|
|
|
goto nomatch;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmparena = NSSArena_Create();
|
|
|
|
|
|
|
|
rv = nss_dbm_db_unwrap_object(tmparena, &v, &pt, &ulac);
|
|
|
|
if( CKR_OK != rv ) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < ulAttributeCount; i++ ) {
|
|
|
|
for( j = 0; j < ulac; j++ ) {
|
|
|
|
if( pTemplate[i].type == pt[j].type ) {
|
|
|
|
if( pTemplate[i].ulValueLen != pt[j].ulValueLen ) {
|
|
|
|
goto nomatch;
|
|
|
|
}
|
|
|
|
if( 0 != memcmp(pTemplate[i].pValue, pt[j].pValue, pt[j].ulValueLen) ) {
|
|
|
|
goto nomatch;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( j == ulac ) {
|
|
|
|
goto nomatch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* entire template matches */
|
|
|
|
{
|
|
|
|
struct nss_dbm_dbt_node *node;
|
|
|
|
|
|
|
|
node = nss_ZNEW(find->arena, struct nss_dbm_dbt_node);
|
|
|
|
if( (struct nss_dbm_dbt_node *)NULL == node ) {
|
|
|
|
rv = CKR_HOST_MEMORY;
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
node->dbt = nss_ZNEW(find->arena, nss_dbm_dbt_t);
|
|
|
|
if( (nss_dbm_dbt_t *)NULL == node->dbt ) {
|
|
|
|
rv = CKR_HOST_MEMORY;
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
node->dbt->dbt.size = k.size;
|
|
|
|
node->dbt->dbt.data = nss_ZAlloc(find->arena, k.size);
|
|
|
|
if( (void *)NULL == node->dbt->dbt.data ) {
|
|
|
|
rv = CKR_HOST_MEMORY;
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)memcpy(node->dbt->dbt.data, k.data, k.size);
|
|
|
|
|
|
|
|
node->dbt->my_db = db;
|
|
|
|
|
|
|
|
node->next = find->found;
|
|
|
|
find->found = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
nomatch:
|
|
|
|
if( (NSSArena *)NULL != tmparena ) {
|
|
|
|
(void)NSSArena_Destroy(tmparena);
|
|
|
|
}
|
|
|
|
*pdbrv = db->db->seq(db->db, &k, &v, R_NEXT);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( *pdbrv < 0 ) {
|
|
|
|
rv = CKR_DEVICE_ERROR;
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = CKR_OK;
|
|
|
|
|
|
|
|
loser:
|
|
|
|
(void)NSSCKFWMutex_Unlock(db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSS_IMPLEMENT CK_BBOOL
|
|
|
|
nss_dbm_db_object_still_exists
|
|
|
|
(
|
|
|
|
nss_dbm_dbt_t *dbt
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CK_BBOOL rv;
|
|
|
|
CK_RV ckrv;
|
|
|
|
int dbrv;
|
|
|
|
DBT object;
|
|
|
|
|
|
|
|
ckrv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
|
|
|
|
if( CKR_OK != ckrv ) {
|
|
|
|
return CK_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 == dbrv ) {
|
|
|
|
rv = CK_TRUE;
|
|
|
|
} else {
|
|
|
|
rv = CK_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSS_IMPLEMENT CK_ULONG
|
|
|
|
nss_dbm_db_get_object_attribute_count
|
|
|
|
(
|
|
|
|
nss_dbm_dbt_t *dbt,
|
|
|
|
CK_RV *pError,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CK_ULONG rv = 0;
|
|
|
|
DBT object;
|
|
|
|
CK_ULONG *pulData;
|
|
|
|
|
|
|
|
/* Locked region */
|
|
|
|
{
|
|
|
|
*pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
|
|
|
|
if( CKR_OK != *pError ) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 == *pdbrv ) {
|
|
|
|
;
|
|
|
|
} else if( *pdbrv > 0 ) {
|
|
|
|
*pError = CKR_OBJECT_HANDLE_INVALID;
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
*pError = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
pulData = (CK_ULONG *)object.data;
|
|
|
|
rv = ntohl(pulData[0]);
|
|
|
|
|
|
|
|
done:
|
|
|
|
(void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSS_IMPLEMENT CK_RV
|
|
|
|
nss_dbm_db_get_object_attribute_types
|
|
|
|
(
|
|
|
|
nss_dbm_dbt_t *dbt,
|
|
|
|
CK_ATTRIBUTE_TYPE_PTR typeArray,
|
|
|
|
CK_ULONG ulCount,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CK_RV rv = CKR_OK;
|
|
|
|
DBT object;
|
|
|
|
CK_ULONG *pulData;
|
|
|
|
CK_ULONG n, i;
|
|
|
|
|
|
|
|
/* Locked region */
|
|
|
|
{
|
|
|
|
rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
|
|
|
|
if( CKR_OK != rv ) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 == *pdbrv ) {
|
|
|
|
;
|
|
|
|
} else if( *pdbrv > 0 ) {
|
|
|
|
rv = CKR_OBJECT_HANDLE_INVALID;
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
rv = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
pulData = (CK_ULONG *)object.data;
|
|
|
|
n = ntohl(pulData[0]);
|
|
|
|
|
|
|
|
if( ulCount < n ) {
|
|
|
|
rv = CKR_BUFFER_TOO_SMALL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < n; i++ ) {
|
|
|
|
typeArray[i] = ntohl(pulData[1 + i*3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
(void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSS_IMPLEMENT CK_ULONG
|
|
|
|
nss_dbm_db_get_object_attribute_size
|
|
|
|
(
|
|
|
|
nss_dbm_dbt_t *dbt,
|
|
|
|
CK_ATTRIBUTE_TYPE type,
|
|
|
|
CK_RV *pError,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CK_ULONG rv = 0;
|
|
|
|
DBT object;
|
|
|
|
CK_ULONG *pulData;
|
|
|
|
CK_ULONG n, i;
|
|
|
|
|
|
|
|
/* Locked region */
|
|
|
|
{
|
|
|
|
*pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
|
|
|
|
if( CKR_OK != *pError ) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 == *pdbrv ) {
|
|
|
|
;
|
|
|
|
} else if( *pdbrv > 0 ) {
|
|
|
|
*pError = CKR_OBJECT_HANDLE_INVALID;
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
*pError = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
pulData = (CK_ULONG *)object.data;
|
|
|
|
n = ntohl(pulData[0]);
|
|
|
|
|
|
|
|
for( i = 0; i < n; i++ ) {
|
|
|
|
if( type == ntohl(pulData[1 + i*3]) ) {
|
|
|
|
rv = ntohl(pulData[2 + i*3]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( i == n ) {
|
|
|
|
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
(void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSS_IMPLEMENT NSSItem *
|
|
|
|
nss_dbm_db_get_object_attribute
|
|
|
|
(
|
|
|
|
nss_dbm_dbt_t *dbt,
|
|
|
|
NSSArena *arena,
|
|
|
|
CK_ATTRIBUTE_TYPE type,
|
|
|
|
CK_RV *pError,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NSSItem *rv = (NSSItem *)NULL;
|
|
|
|
DBT object;
|
|
|
|
CK_ULONG i;
|
|
|
|
NSSArena *tmp = NSSArena_Create();
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate;
|
|
|
|
CK_ULONG ulAttributeCount;
|
|
|
|
|
|
|
|
/* Locked region */
|
|
|
|
{
|
|
|
|
*pError = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
|
|
|
|
if( CKR_OK != *pError ) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 == *pdbrv ) {
|
|
|
|
;
|
|
|
|
} else if( *pdbrv > 0 ) {
|
|
|
|
*pError = CKR_OBJECT_HANDLE_INVALID;
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
*pError = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pError = nss_dbm_db_unwrap_object(tmp, &object, &pTemplate, &ulAttributeCount);
|
|
|
|
if( CKR_OK != *pError ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < ulAttributeCount; i++ ) {
|
|
|
|
if( type == pTemplate[i].type ) {
|
|
|
|
rv = nss_ZNEW(arena, NSSItem);
|
|
|
|
if( (NSSItem *)NULL == rv ) {
|
|
|
|
*pError = CKR_HOST_MEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
rv->size = pTemplate[i].ulValueLen;
|
|
|
|
rv->data = nss_ZAlloc(arena, rv->size);
|
|
|
|
if( (void *)NULL == rv->data ) {
|
|
|
|
*pError = CKR_HOST_MEMORY;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
(void)memcpy(rv->data, pTemplate[i].pValue, rv->size);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( ulAttributeCount == i ) {
|
|
|
|
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
(void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
loser:
|
|
|
|
if( (NSSArena *)NULL != tmp ) {
|
|
|
|
NSSArena_Destroy(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NSS_IMPLEMENT CK_RV
|
|
|
|
nss_dbm_db_set_object_attribute
|
|
|
|
(
|
|
|
|
nss_dbm_dbt_t *dbt,
|
|
|
|
CK_ATTRIBUTE_TYPE type,
|
|
|
|
NSSItem *value,
|
|
|
|
CK_ULONG *pdbrv
|
|
|
|
)
|
|
|
|
{
|
|
|
|
CK_RV rv = CKR_OK;
|
|
|
|
DBT object;
|
|
|
|
CK_ULONG i;
|
|
|
|
NSSArena *tmp = NSSArena_Create();
|
|
|
|
CK_ATTRIBUTE_PTR pTemplate;
|
|
|
|
CK_ULONG ulAttributeCount;
|
|
|
|
|
|
|
|
/* Locked region */
|
|
|
|
{
|
|
|
|
rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock);
|
|
|
|
if( CKR_OK != rv ) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = dbt->my_db->db->get(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 == *pdbrv ) {
|
|
|
|
;
|
|
|
|
} else if( *pdbrv > 0 ) {
|
|
|
|
rv = CKR_OBJECT_HANDLE_INVALID;
|
|
|
|
goto done;
|
|
|
|
} else {
|
|
|
|
rv = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = nss_dbm_db_unwrap_object(tmp, &object, &pTemplate, &ulAttributeCount);
|
|
|
|
if( CKR_OK != rv ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < ulAttributeCount; i++ ) {
|
|
|
|
if( type == pTemplate[i].type ) {
|
|
|
|
/* Replacing an existing attribute */
|
|
|
|
pTemplate[i].ulValueLen = value->size;
|
|
|
|
pTemplate[i].pValue = value->data;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( i == ulAttributeCount ) {
|
|
|
|
/* Adding a new attribute */
|
|
|
|
CK_ATTRIBUTE_PTR npt = nss_ZNEWARRAY(tmp, CK_ATTRIBUTE, ulAttributeCount+1);
|
|
|
|
if( (CK_ATTRIBUTE_PTR)NULL == npt ) {
|
|
|
|
rv = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < ulAttributeCount; i++ ) {
|
|
|
|
npt[i] = pTemplate[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
npt[ulAttributeCount].type = type;
|
|
|
|
npt[ulAttributeCount].ulValueLen = value->size;
|
|
|
|
npt[ulAttributeCount].pValue = value->data;
|
|
|
|
|
|
|
|
pTemplate = npt;
|
|
|
|
ulAttributeCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = nss_dbm_db_wrap_object(tmp, pTemplate, ulAttributeCount, &object);
|
|
|
|
if( CKR_OK != rv ) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
*pdbrv = dbt->my_db->db->put(dbt->my_db->db, &dbt->dbt, &object, 0);
|
|
|
|
if( 0 != *pdbrv ) {
|
|
|
|
rv = CKR_DEVICE_ERROR;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)dbt->my_db->db->sync(dbt->my_db->db, 0);
|
|
|
|
|
|
|
|
done:
|
|
|
|
(void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock);
|
|
|
|
}
|
|
|
|
|
|
|
|
loser:
|
|
|
|
if( (NSSArena *)NULL != tmp ) {
|
|
|
|
NSSArena_Destroy(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|