1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 static const char CVS_ID
[] = "@(#) $RCSfile: db.c,v $ $Revision: 1.6 $ $Date: 2006/03/02 22:48:54 $";
43 #define PREFIX_METADATA "0000"
44 #define PREFIX_OBJECT "0001"
45 #define PREFIX_INDEX "0002"
47 static CK_VERSION nss_dbm_db_format_version
= { 1, 0 };
53 NSS_IMPLEMENT nss_dbm_db_t
*
57 NSSCKFWInstance
*fwInstance
,
64 CK_VERSION db_version
;
66 rv
= nss_ZNEW(arena
, nss_dbm_db_t
);
67 if( (nss_dbm_db_t
*)NULL
== rv
) {
68 *pError
= CKR_HOST_MEMORY
;
69 return (nss_dbm_db_t
*)NULL
;
72 rv
->db
= dbopen(filename
, flags
, 0600, DB_HASH
, (const void *)NULL
);
73 if( (DB
*)NULL
== rv
->db
) {
74 *pError
= CKR_TOKEN_NOT_PRESENT
;
75 return (nss_dbm_db_t
*)NULL
;
78 rv
->crustylock
= NSSCKFWInstance_CreateMutex(fwInstance
, arena
, pError
);
79 if( (NSSCKFWMutex
*)NULL
== rv
->crustylock
) {
80 return (nss_dbm_db_t
*)NULL
;
83 db_version
= nss_dbm_db_get_format_version(rv
);
84 if( db_version
.major
!= nss_dbm_db_format_version
.major
) {
86 *pError
= CKR_TOKEN_NOT_RECOGNIZED
;
87 return (nss_dbm_db_t
*)NULL
;
99 if( (NSSCKFWMutex
*)NULL
!= db
->crustylock
) {
100 (void)NSSCKFWMutex_Destroy(db
->crustylock
);
103 if( (DB
*)NULL
!= db
->db
) {
104 (void)db
->db
->close(db
->db
);
110 NSS_IMPLEMENT CK_VERSION
111 nss_dbm_db_get_format_version
121 rv
.major
= rv
.minor
= 0;
123 k
.data
= PREFIX_METADATA
"FormatVersion";
124 k
.size
= nssUTF8_Size((NSSUTF8
*)k
.data
, (PRStatus
*)NULL
);
125 (void)memset(&v
, 0, sizeof(v
));
129 if( CKR_OK
!= NSSCKFWMutex_Lock(db
->crustylock
) ) {
133 dbrv
= db
->db
->get(db
->db
, &k
, &v
, 0);
135 CK_ULONG major
= 0, minor
= 0;
136 (void)PR_sscanf(v
.data
, "%ld.%ld", &major
, &minor
);
139 } else if( dbrv
> 0 ) {
140 (void)PR_snprintf(buffer
, sizeof(buffer
), "%ld.%ld", nss_dbm_db_format_version
.major
,
141 nss_dbm_db_format_version
.minor
);
143 v
.size
= nssUTF8_Size((NSSUTF8
*)v
.data
, (PRStatus
*)NULL
);
144 dbrv
= db
->db
->put(db
->db
, &k
, &v
, 0);
145 (void)db
->db
->sync(db
->db
, 0);
146 rv
= nss_dbm_db_format_version
;
148 /* No error return.. */
152 (void)NSSCKFWMutex_Unlock(db
->crustylock
);
169 k
.data
= PREFIX_METADATA
"Label";
170 k
.size
= nssUTF8_Size((NSSUTF8
*)k
.data
, (PRStatus
*)NULL
);
172 v
.size
= nssUTF8_Size((NSSUTF8
*)v
.data
, (PRStatus
*)NULL
);
176 if( CKR_OK
!= NSSCKFWMutex_Lock(db
->crustylock
) ) {
180 dbrv
= db
->db
->put(db
->db
, &k
, &v
, 0);
182 rv
= CKR_DEVICE_ERROR
;
185 dbrv
= db
->db
->sync(db
->db
, 0);
187 rv
= CKR_DEVICE_ERROR
;
190 (void)NSSCKFWMutex_Unlock(db
->crustylock
);
196 NSS_IMPLEMENT NSSUTF8
*
204 NSSUTF8
*rv
= (NSSUTF8
*)NULL
;
208 k
.data
= PREFIX_METADATA
"Label";
209 k
.size
= nssUTF8_Size((NSSUTF8
*)k
.data
, (PRStatus
*)NULL
);
213 if( CKR_OK
!= NSSCKFWMutex_Lock(db
->crustylock
) ) {
217 dbrv
= db
->db
->get(db
->db
, &k
, &v
, 0);
219 rv
= nssUTF8_Duplicate((NSSUTF8
*)v
.data
, arena
);
220 if( (NSSUTF8
*)NULL
== rv
) {
221 *pError
= CKR_HOST_MEMORY
;
223 } else if( dbrv
> 0 ) {
224 /* Just return null */
227 *pError
= CKR_DEVICE_ERROR
;
232 (void)NSSCKFWMutex_Unlock(db
->crustylock
);
239 nss_dbm_db_delete_object
249 rv
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
254 dbrv
= dbt
->my_db
->db
->del(dbt
->my_db
->db
, &dbt
->dbt
, 0);
256 rv
= CKR_DEVICE_ERROR
;
260 dbrv
= dbt
->my_db
->db
->sync(dbt
->my_db
->db
, 0);
262 rv
= CKR_DEVICE_ERROR
;
267 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
274 nss_dbm_db_new_handle
277 DBT
*dbt
, /* pre-allocated */
283 CK_ULONG align
= 0, id
, myid
;
286 if( sizeof(struct handle
) != dbt
->size
) {
292 *pError
= NSSCKFWMutex_Lock(db
->crustylock
);
293 if( CKR_OK
!= *pError
) {
297 k
.data
= PREFIX_METADATA
"LastID";
298 k
.size
= nssUTF8_Size((NSSUTF8
*)k
.data
, (PRStatus
*)NULL
);
299 (void)memset(&v
, 0, sizeof(v
));
301 rv
= db
->db
->get(db
->db
, &k
, &v
, 0);
303 (void)memcpy(&align
, v
.data
, sizeof(CK_ULONG
));
305 } else if( rv
> 0 ) {
315 v
.size
= sizeof(CK_ULONG
);
317 rv
= db
->db
->put(db
->db
, &k
, &v
, 0);
322 rv
= db
->db
->sync(db
->db
, 0);
328 (void)NSSCKFWMutex_Unlock(db
->crustylock
);
335 hp
= (struct handle
*)dbt
->data
;
336 (void)memcpy(&hp
->prefix
[0], PREFIX_OBJECT
, 4);
343 * This attribute-type-dependent swapping should probably
344 * be in the Framework, because it'll be a concern of just
345 * about every Module. Of course any Framework implementation
346 * will have to be augmentable or overridable by a Module.
349 enum swap_type
{ type_byte
, type_short
, type_long
, type_opaque
};
351 static enum swap_type
354 CK_ATTRIBUTE_TYPE type
358 case CKA_CLASS
: return type_long
;
359 case CKA_TOKEN
: return type_byte
;
360 case CKA_PRIVATE
: return type_byte
;
361 case CKA_LABEL
: return type_opaque
;
362 case CKA_APPLICATION
: return type_opaque
;
363 case CKA_VALUE
: return type_opaque
;
364 case CKA_CERTIFICATE_TYPE
: return type_long
;
365 case CKA_ISSUER
: return type_opaque
;
366 case CKA_SERIAL_NUMBER
: return type_opaque
;
367 case CKA_KEY_TYPE
: return type_long
;
368 case CKA_SUBJECT
: return type_opaque
;
369 case CKA_ID
: return type_opaque
;
370 case CKA_SENSITIVE
: return type_byte
;
371 case CKA_ENCRYPT
: return type_byte
;
372 case CKA_DECRYPT
: return type_byte
;
373 case CKA_WRAP
: return type_byte
;
374 case CKA_UNWRAP
: return type_byte
;
375 case CKA_SIGN
: return type_byte
;
376 case CKA_SIGN_RECOVER
: return type_byte
;
377 case CKA_VERIFY
: return type_byte
;
378 case CKA_VERIFY_RECOVER
: return type_byte
;
379 case CKA_DERIVE
: return type_byte
;
380 case CKA_START_DATE
: return type_opaque
;
381 case CKA_END_DATE
: return type_opaque
;
382 case CKA_MODULUS
: return type_opaque
;
383 case CKA_MODULUS_BITS
: return type_long
;
384 case CKA_PUBLIC_EXPONENT
: return type_opaque
;
385 case CKA_PRIVATE_EXPONENT
: return type_opaque
;
386 case CKA_PRIME_1
: return type_opaque
;
387 case CKA_PRIME_2
: return type_opaque
;
388 case CKA_EXPONENT_1
: return type_opaque
;
389 case CKA_EXPONENT_2
: return type_opaque
;
390 case CKA_COEFFICIENT
: return type_opaque
;
391 case CKA_PRIME
: return type_opaque
;
392 case CKA_SUBPRIME
: return type_opaque
;
393 case CKA_BASE
: return type_opaque
;
394 case CKA_VALUE_BITS
: return type_long
;
395 case CKA_VALUE_LEN
: return type_long
;
396 case CKA_EXTRACTABLE
: return type_byte
;
397 case CKA_LOCAL
: return type_byte
;
398 case CKA_NEVER_EXTRACTABLE
: return type_byte
;
399 case CKA_ALWAYS_SENSITIVE
: return type_byte
;
400 case CKA_MODIFIABLE
: return type_byte
;
401 case CKA_NETSCAPE_URL
: return type_opaque
;
402 case CKA_NETSCAPE_EMAIL
: return type_opaque
;
403 case CKA_NETSCAPE_SMIME_INFO
: return type_opaque
;
404 case CKA_NETSCAPE_SMIME_TIMESTAMP
: return type_opaque
;
405 case CKA_NETSCAPE_PKCS8_SALT
: return type_opaque
;
406 case CKA_NETSCAPE_PASSWORD_CHECK
: return type_opaque
;
407 case CKA_NETSCAPE_EXPIRES
: return type_opaque
;
408 case CKA_TRUST_DIGITAL_SIGNATURE
: return type_long
;
409 case CKA_TRUST_NON_REPUDIATION
: return type_long
;
410 case CKA_TRUST_KEY_ENCIPHERMENT
: return type_long
;
411 case CKA_TRUST_DATA_ENCIPHERMENT
: return type_long
;
412 case CKA_TRUST_KEY_AGREEMENT
: return type_long
;
413 case CKA_TRUST_KEY_CERT_SIGN
: return type_long
;
414 case CKA_TRUST_CRL_SIGN
: return type_long
;
415 case CKA_TRUST_SERVER_AUTH
: return type_long
;
416 case CKA_TRUST_CLIENT_AUTH
: return type_long
;
417 case CKA_TRUST_CODE_SIGNING
: return type_long
;
418 case CKA_TRUST_EMAIL_PROTECTION
: return type_long
;
419 case CKA_TRUST_IPSEC_END_SYSTEM
: return type_long
;
420 case CKA_TRUST_IPSEC_TUNNEL
: return type_long
;
421 case CKA_TRUST_IPSEC_USER
: return type_long
;
422 case CKA_TRUST_TIME_STAMPING
: return type_long
;
423 case CKA_NETSCAPE_DB
: return type_opaque
;
424 case CKA_NETSCAPE_TRUST
: return type_opaque
;
425 default: return type_opaque
;
432 CK_ATTRIBUTE_TYPE type
,
438 switch( nss_dbm_db_swap_type(type
) ) {
441 (void)memcpy(dest
, src
, len
);
446 (void)memcpy(&s
, src
, sizeof(CK_USHORT
));
448 (void)memcpy(dest
, &d
, sizeof(CK_USHORT
));
454 (void)memcpy(&s
, src
, sizeof(CK_ULONG
));
456 (void)memcpy(dest
, &d
, sizeof(CK_ULONG
));
463 nss_dbm_db_wrap_object
466 CK_ATTRIBUTE_PTR pTemplate
,
467 CK_ULONG ulAttributeCount
,
471 CK_ULONG object_size
;
477 object_size
= (1 + ulAttributeCount
*3) * sizeof(CK_ULONG
);
478 offset
= object_size
;
479 for( i
= 0; i
< ulAttributeCount
; i
++ ) {
480 object_size
+= pTemplate
[i
].ulValueLen
;
483 object
->size
= object_size
;
484 object
->data
= nss_ZAlloc(arena
, object_size
);
485 if( (void *)NULL
== object
->data
) {
486 return CKR_HOST_MEMORY
;
489 pulData
= (CK_ULONG
*)object
->data
;
490 pcData
= (char *)object
->data
;
492 pulData
[0] = htonl(ulAttributeCount
);
493 for( i
= 0; i
< ulAttributeCount
; i
++ ) {
494 CK_ULONG len
= pTemplate
[i
].ulValueLen
;
495 pulData
[1 + i
*3] = htonl(pTemplate
[i
].type
);
496 pulData
[2 + i
*3] = htonl(len
);
497 pulData
[3 + i
*3] = htonl(offset
);
498 nss_dbm_db_swap_copy(pTemplate
[i
].type
, &pcData
[offset
], pTemplate
[i
].pValue
, len
);
506 nss_dbm_db_unwrap_object
510 CK_ATTRIBUTE_PTR
*ppTemplate
,
511 CK_ULONG
*pulAttributeCount
517 CK_ATTRIBUTE_PTR pTemplate
;
519 pulData
= (CK_ULONG
*)object
->data
;
520 pcData
= (char *)object
->data
;
522 n
= ntohl(pulData
[0]);
523 *pulAttributeCount
= n
;
524 pTemplate
= nss_ZNEWARRAY(arena
, CK_ATTRIBUTE
, n
);
525 if( (CK_ATTRIBUTE_PTR
)NULL
== pTemplate
) {
526 return CKR_HOST_MEMORY
;
529 for( i
= 0; i
< n
; i
++ ) {
534 pTemplate
[i
].type
= ntohl(pulData
[1 + i
*3]);
535 len
= ntohl(pulData
[2 + i
*3]);
536 offset
= ntohl(pulData
[3 + i
*3]);
538 p
= nss_ZAlloc(arena
, len
);
539 if( (void *)NULL
== p
) {
540 return CKR_HOST_MEMORY
;
543 nss_dbm_db_swap_copy(pTemplate
[i
].type
, p
, &pcData
[offset
], len
);
544 pTemplate
[i
].ulValueLen
= len
;
545 pTemplate
[i
].pValue
= p
;
548 *ppTemplate
= pTemplate
;
553 NSS_IMPLEMENT nss_dbm_dbt_t
*
554 nss_dbm_db_create_object
558 CK_ATTRIBUTE_PTR pTemplate
,
559 CK_ULONG ulAttributeCount
,
564 NSSArena
*tmparena
= (NSSArena
*)NULL
;
565 nss_dbm_dbt_t
*rv
= (nss_dbm_dbt_t
*)NULL
;
568 rv
= nss_ZNEW(arena
, nss_dbm_dbt_t
);
569 if( (nss_dbm_dbt_t
*)NULL
== rv
) {
570 *pError
= CKR_HOST_MEMORY
;
571 return (nss_dbm_dbt_t
*)NULL
;
575 rv
->dbt
.size
= sizeof(struct handle
);
576 rv
->dbt
.data
= nss_ZAlloc(arena
, rv
->dbt
.size
);
577 if( (void *)NULL
== rv
->dbt
.data
) {
578 *pError
= CKR_HOST_MEMORY
;
579 return (nss_dbm_dbt_t
*)NULL
;
582 *pdbrv
= nss_dbm_db_new_handle(db
, &rv
->dbt
, pError
);
584 return (nss_dbm_dbt_t
*)NULL
;
587 tmparena
= NSSArena_Create();
588 if( (NSSArena
*)NULL
== tmparena
) {
589 *pError
= CKR_HOST_MEMORY
;
590 return (nss_dbm_dbt_t
*)NULL
;
593 *pError
= nss_dbm_db_wrap_object(tmparena
, pTemplate
, ulAttributeCount
, &object
);
594 if( CKR_OK
!= *pError
) {
595 return (nss_dbm_dbt_t
*)NULL
;
600 *pError
= NSSCKFWMutex_Lock(db
->crustylock
);
601 if( CKR_OK
!= *pError
) {
605 *pdbrv
= db
->db
->put(db
->db
, &rv
->dbt
, &object
, 0);
607 *pError
= CKR_DEVICE_ERROR
;
610 (void)db
->db
->sync(db
->db
, 0);
612 (void)NSSCKFWMutex_Unlock(db
->crustylock
);
616 if( (NSSArena
*)NULL
!= tmparena
) {
617 (void)NSSArena_Destroy(tmparena
);
625 nss_dbm_db_find_objects
627 nss_dbm_find_t
*find
,
629 CK_ATTRIBUTE_PTR pTemplate
,
630 CK_ULONG ulAttributeCount
,
636 if( (nss_dbm_db_t
*)NULL
!= db
) {
639 rv
= NSSCKFWMutex_Lock(db
->crustylock
);
644 *pdbrv
= db
->db
->seq(db
->db
, &k
, &v
, R_FIRST
);
645 while( 0 == *pdbrv
) {
647 NSSArena
*tmparena
= (NSSArena
*)NULL
;
651 if( (k
.size
< 4) || (0 != memcmp(k
.data
, PREFIX_OBJECT
, 4)) ) {
655 tmparena
= NSSArena_Create();
657 rv
= nss_dbm_db_unwrap_object(tmparena
, &v
, &pt
, &ulac
);
662 for( i
= 0; i
< ulAttributeCount
; i
++ ) {
663 for( j
= 0; j
< ulac
; j
++ ) {
664 if( pTemplate
[i
].type
== pt
[j
].type
) {
665 if( pTemplate
[i
].ulValueLen
!= pt
[j
].ulValueLen
) {
668 if( 0 != memcmp(pTemplate
[i
].pValue
, pt
[j
].pValue
, pt
[j
].ulValueLen
) ) {
679 /* entire template matches */
681 struct nss_dbm_dbt_node
*node
;
683 node
= nss_ZNEW(find
->arena
, struct nss_dbm_dbt_node
);
684 if( (struct nss_dbm_dbt_node
*)NULL
== node
) {
685 rv
= CKR_HOST_MEMORY
;
689 node
->dbt
= nss_ZNEW(find
->arena
, nss_dbm_dbt_t
);
690 if( (nss_dbm_dbt_t
*)NULL
== node
->dbt
) {
691 rv
= CKR_HOST_MEMORY
;
695 node
->dbt
->dbt
.size
= k
.size
;
696 node
->dbt
->dbt
.data
= nss_ZAlloc(find
->arena
, k
.size
);
697 if( (void *)NULL
== node
->dbt
->dbt
.data
) {
698 rv
= CKR_HOST_MEMORY
;
702 (void)memcpy(node
->dbt
->dbt
.data
, k
.data
, k
.size
);
704 node
->dbt
->my_db
= db
;
706 node
->next
= find
->found
;
711 if( (NSSArena
*)NULL
!= tmparena
) {
712 (void)NSSArena_Destroy(tmparena
);
714 *pdbrv
= db
->db
->seq(db
->db
, &k
, &v
, R_NEXT
);
718 rv
= CKR_DEVICE_ERROR
;
725 (void)NSSCKFWMutex_Unlock(db
->crustylock
);
731 NSS_IMPLEMENT CK_BBOOL
732 nss_dbm_db_object_still_exists
742 ckrv
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
743 if( CKR_OK
!= ckrv
) {
747 dbrv
= dbt
->my_db
->db
->get(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
754 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
759 NSS_IMPLEMENT CK_ULONG
760 nss_dbm_db_get_object_attribute_count
773 *pError
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
774 if( CKR_OK
!= *pError
) {
778 *pdbrv
= dbt
->my_db
->db
->get(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
781 } else if( *pdbrv
> 0 ) {
782 *pError
= CKR_OBJECT_HANDLE_INVALID
;
785 *pError
= CKR_DEVICE_ERROR
;
789 pulData
= (CK_ULONG
*)object
.data
;
790 rv
= ntohl(pulData
[0]);
793 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
800 nss_dbm_db_get_object_attribute_types
803 CK_ATTRIBUTE_TYPE_PTR typeArray
,
815 rv
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
820 *pdbrv
= dbt
->my_db
->db
->get(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
823 } else if( *pdbrv
> 0 ) {
824 rv
= CKR_OBJECT_HANDLE_INVALID
;
827 rv
= CKR_DEVICE_ERROR
;
831 pulData
= (CK_ULONG
*)object
.data
;
832 n
= ntohl(pulData
[0]);
835 rv
= CKR_BUFFER_TOO_SMALL
;
839 for( i
= 0; i
< n
; i
++ ) {
840 typeArray
[i
] = ntohl(pulData
[1 + i
*3]);
844 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
850 NSS_IMPLEMENT CK_ULONG
851 nss_dbm_db_get_object_attribute_size
854 CK_ATTRIBUTE_TYPE type
,
866 *pError
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
867 if( CKR_OK
!= *pError
) {
871 *pdbrv
= dbt
->my_db
->db
->get(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
874 } else if( *pdbrv
> 0 ) {
875 *pError
= CKR_OBJECT_HANDLE_INVALID
;
878 *pError
= CKR_DEVICE_ERROR
;
882 pulData
= (CK_ULONG
*)object
.data
;
883 n
= ntohl(pulData
[0]);
885 for( i
= 0; i
< n
; i
++ ) {
886 if( type
== ntohl(pulData
[1 + i
*3]) ) {
887 rv
= ntohl(pulData
[2 + i
*3]);
892 *pError
= CKR_ATTRIBUTE_TYPE_INVALID
;
897 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
903 NSS_IMPLEMENT NSSItem
*
904 nss_dbm_db_get_object_attribute
908 CK_ATTRIBUTE_TYPE type
,
913 NSSItem
*rv
= (NSSItem
*)NULL
;
916 NSSArena
*tmp
= NSSArena_Create();
917 CK_ATTRIBUTE_PTR pTemplate
;
918 CK_ULONG ulAttributeCount
;
922 *pError
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
923 if( CKR_OK
!= *pError
) {
927 *pdbrv
= dbt
->my_db
->db
->get(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
930 } else if( *pdbrv
> 0 ) {
931 *pError
= CKR_OBJECT_HANDLE_INVALID
;
934 *pError
= CKR_DEVICE_ERROR
;
938 *pError
= nss_dbm_db_unwrap_object(tmp
, &object
, &pTemplate
, &ulAttributeCount
);
939 if( CKR_OK
!= *pError
) {
943 for( i
= 0; i
< ulAttributeCount
; i
++ ) {
944 if( type
== pTemplate
[i
].type
) {
945 rv
= nss_ZNEW(arena
, NSSItem
);
946 if( (NSSItem
*)NULL
== rv
) {
947 *pError
= CKR_HOST_MEMORY
;
950 rv
->size
= pTemplate
[i
].ulValueLen
;
951 rv
->data
= nss_ZAlloc(arena
, rv
->size
);
952 if( (void *)NULL
== rv
->data
) {
953 *pError
= CKR_HOST_MEMORY
;
956 (void)memcpy(rv
->data
, pTemplate
[i
].pValue
, rv
->size
);
960 if( ulAttributeCount
== i
) {
961 *pError
= CKR_ATTRIBUTE_TYPE_INVALID
;
966 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
970 if( (NSSArena
*)NULL
!= tmp
) {
971 NSSArena_Destroy(tmp
);
978 nss_dbm_db_set_object_attribute
981 CK_ATTRIBUTE_TYPE type
,
989 NSSArena
*tmp
= NSSArena_Create();
990 CK_ATTRIBUTE_PTR pTemplate
;
991 CK_ULONG ulAttributeCount
;
995 rv
= NSSCKFWMutex_Lock(dbt
->my_db
->crustylock
);
1000 *pdbrv
= dbt
->my_db
->db
->get(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
1003 } else if( *pdbrv
> 0 ) {
1004 rv
= CKR_OBJECT_HANDLE_INVALID
;
1007 rv
= CKR_DEVICE_ERROR
;
1011 rv
= nss_dbm_db_unwrap_object(tmp
, &object
, &pTemplate
, &ulAttributeCount
);
1012 if( CKR_OK
!= rv
) {
1016 for( i
= 0; i
< ulAttributeCount
; i
++ ) {
1017 if( type
== pTemplate
[i
].type
) {
1018 /* Replacing an existing attribute */
1019 pTemplate
[i
].ulValueLen
= value
->size
;
1020 pTemplate
[i
].pValue
= value
->data
;
1025 if( i
== ulAttributeCount
) {
1026 /* Adding a new attribute */
1027 CK_ATTRIBUTE_PTR npt
= nss_ZNEWARRAY(tmp
, CK_ATTRIBUTE
, ulAttributeCount
+1);
1028 if( (CK_ATTRIBUTE_PTR
)NULL
== npt
) {
1029 rv
= CKR_DEVICE_ERROR
;
1033 for( i
= 0; i
< ulAttributeCount
; i
++ ) {
1034 npt
[i
] = pTemplate
[i
];
1037 npt
[ulAttributeCount
].type
= type
;
1038 npt
[ulAttributeCount
].ulValueLen
= value
->size
;
1039 npt
[ulAttributeCount
].pValue
= value
->data
;
1045 rv
= nss_dbm_db_wrap_object(tmp
, pTemplate
, ulAttributeCount
, &object
);
1046 if( CKR_OK
!= rv
) {
1050 *pdbrv
= dbt
->my_db
->db
->put(dbt
->my_db
->db
, &dbt
->dbt
, &object
, 0);
1052 rv
= CKR_DEVICE_ERROR
;
1056 (void)dbt
->my_db
->db
->sync(dbt
->my_db
->db
, 0);
1059 (void)NSSCKFWMutex_Unlock(dbt
->my_db
->crustylock
);
1063 if( (NSSArena
*)NULL
!= tmp
) {
1064 NSSArena_Destroy(tmp
);