Added a new Attribute to store TPM key handle
[aaf/sshsm.git] / SoftHSMv2 / src / lib / P11Attributes.cpp
1 /*
2  * Copyright (c) 2011 .SE (The Internet Infrastructure Foundation)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 /*****************************************************************************
28  P11Attributes.h
29
30  This file contains classes for controlling attributes
31  *****************************************************************************/
32
33 #include "config.h"
34 #include "P11Attributes.h"
35 #include "ByteString.h"
36 #include "CryptoFactory.h"
37 #include "DESKey.h"
38 #include "AESKey.h"
39 #include <stdio.h>
40 #include <stdlib.h>
41
42 // Constructor
43 P11Attribute::P11Attribute(OSObject* inobject)
44 {
45         osobject = inobject;
46         type = CKA_VENDOR_DEFINED;
47         size = (CK_ULONG)-1;
48         checks = 0;
49 }
50
51 // Destructor
52 P11Attribute::~P11Attribute()
53 {
54 }
55
56 CK_RV P11Attribute::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
57 {
58         ByteString value;
59         if (isPrivate)
60         {
61                 if (!token->encrypt(ByteString((unsigned char*)pValue, ulValueLen),value))
62                         return CKR_GENERAL_ERROR;
63         }
64         else
65                 value = ByteString((unsigned char*)pValue, ulValueLen);
66         if (value.size() < ulValueLen)
67                 return CKR_GENERAL_ERROR;
68         osobject->setAttribute(type, value);
69         return CKR_OK;
70 }
71
72 bool P11Attribute::isModifiable()
73 {
74         // Get the CKA_MODIFIABLE attribute, when the attribute is
75         // not present return the default value which is CK_TRUE.
76         if (!osobject->attributeExists(CKA_MODIFIABLE)) return true;
77
78         return osobject->getBooleanValue(CKA_MODIFIABLE, true);
79 }
80
81 bool P11Attribute::isSensitive()
82 {
83         // Get the CKA_SENSITIVE attribute, when the attribute is not present
84         // assume the object is not sensitive.
85         if (!osobject->attributeExists(CKA_SENSITIVE)) return false;
86
87         return osobject->getBooleanValue(CKA_SENSITIVE, false);
88 }
89
90 bool P11Attribute::isExtractable()
91 {
92         // Get the CKA_EXTRACTABLE attribute, when the attribute is
93         // not present assume the object allows extraction.
94         if (!osobject->attributeExists(CKA_EXTRACTABLE)) return true;
95
96         return osobject->getBooleanValue(CKA_EXTRACTABLE, true);
97 }
98
99 bool P11Attribute::isTrusted()
100 {
101         // Get the CKA_TRUSTED attribute, when the attribute is
102         // not present assume the object is not trusted.
103         if (!osobject->attributeExists(CKA_TRUSTED)) return false;
104
105         return osobject->getBooleanValue(CKA_TRUSTED, false);
106 }
107
108 // Initialize the attribute
109 bool P11Attribute::init()
110 {
111         if (osobject == NULL) return false;
112
113         // Create a default value if the attribute does not exist
114         if (osobject->attributeExists(type) == false)
115         {
116                 return setDefault();
117         }
118
119         return true;
120 }
121
122 // Return the attribute type
123 CK_ATTRIBUTE_TYPE P11Attribute::getType()
124 {
125         return type;
126 }
127
128 // Return the attribute checks
129 CK_ATTRIBUTE_TYPE P11Attribute::getChecks()
130 {
131         return checks;
132 }
133
134 // Retrieve a template map
135 static CK_RV retrieveAttributeMap(CK_ATTRIBUTE_PTR pTemplate, const std::map<CK_ATTRIBUTE_TYPE,OSAttribute>& map)
136 {
137         size_t nullcnt = 0;
138
139         for (size_t i = 0; i < map.size(); ++i)
140         {
141                 if (pTemplate[i].pValue == NULL_PTR)
142                         ++nullcnt;
143         }
144
145         // Caller wants type & size
146         if (nullcnt == map.size())
147         {
148                 std::map<CK_ATTRIBUTE_TYPE,OSAttribute>::const_iterator a = map.begin();
149                 for (size_t i = 0; i < map.size(); ++i, ++a)
150                 {
151                         pTemplate[i].type = a->first;
152                         const OSAttribute& attr = a->second;
153                         if (attr.isBooleanAttribute())
154                         {
155                                 pTemplate[i].ulValueLen = sizeof(CK_BBOOL);
156                         }
157                         else if (attr.isUnsignedLongAttribute())
158                         {
159                                 pTemplate[i].ulValueLen = sizeof(CK_ULONG);
160                         }
161                         else if (attr.isByteStringAttribute())
162                         {
163                                 pTemplate[i].ulValueLen = attr.getByteStringValue().size();
164                         }
165                         else
166                         {
167                                 // Impossible
168                                 ERROR_MSG("Internal error: bad attribute in attribute map");
169
170                                 return CKR_GENERAL_ERROR;
171                         }
172                 }
173
174                 return CKR_OK;
175         }
176
177         // Callers wants to get values
178         for (size_t i = 0; i < map.size(); ++i)
179         {
180                 std::map<CK_ATTRIBUTE_TYPE,OSAttribute>::const_iterator a = map.find(pTemplate[i].type);
181                 if (a == map.end())
182                 {
183                         pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
184                         return CKR_ATTRIBUTE_TYPE_INVALID;
185                 }
186                 const OSAttribute& attr = a->second;
187                 if (attr.isBooleanAttribute())
188                 {
189                         if (pTemplate[i].ulValueLen < sizeof(CK_BBOOL))
190                         {
191                                 pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
192                                 return CKR_BUFFER_TOO_SMALL;
193                         }
194                         pTemplate[i].ulValueLen = sizeof(CK_BBOOL);
195                         *(CK_BBOOL*)pTemplate[i].pValue = attr.getBooleanValue() ? CK_TRUE : CK_FALSE;
196                 }
197                 else if (attr.isUnsignedLongAttribute())
198                 {
199                         if (pTemplate[i].ulValueLen < sizeof(CK_ULONG))
200                         {
201                                 pTemplate[i].ulValueLen= CK_UNAVAILABLE_INFORMATION;
202                                 return CKR_BUFFER_TOO_SMALL;
203                         }
204                         pTemplate[i].ulValueLen = sizeof(CK_ULONG);
205                         *(CK_ULONG_PTR)pTemplate[i].pValue= attr.getUnsignedLongValue();
206                 }
207                 else if (attr.isByteStringAttribute())
208                 {
209                         ByteString value = attr.getByteStringValue();
210                         if (pTemplate[i].ulValueLen < value.size())
211                         {
212                                 pTemplate[i].ulValueLen= CK_UNAVAILABLE_INFORMATION;
213                                 return CKR_BUFFER_TOO_SMALL;
214                         }
215                         pTemplate[i].ulValueLen = value.size();
216                         memcpy(pTemplate[i].pValue, value.const_byte_str(), value.size());
217                 }
218                 else
219                 {
220                         // Impossible
221                         ERROR_MSG("Internal error: bad attribute in attribute map");
222
223                         return CKR_GENERAL_ERROR;
224                 }
225         }
226
227         return CKR_OK;
228 }
229
230 // Retrieve the value if allowed
231 CK_RV P11Attribute::retrieve(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG_PTR pulValueLen)
232 {
233
234         if (osobject == NULL) {
235                 ERROR_MSG("Internal error: osobject field contains NULL_PTR");
236                 return CKR_GENERAL_ERROR;
237         }
238
239         if (pulValueLen == NULL) {
240                 ERROR_MSG("Internal error: pulValueLen contains NULL_PTR");
241                 return CKR_GENERAL_ERROR;
242         }
243
244         // [PKCS#11 v2.40, C_GetAttributeValue]
245         // 1. If the specified attribute (i.e., the attribute specified by the
246         //    type field) for the object cannot be revealed because the object
247         //    is sensitive or unextractable, then the ulValueLen field in that
248         //    triple is modified to hold the value CK_UNAVAILABLE_INFORMATION.
249         //
250         // [PKCS#11 v2.40, 4.2 Common attributes, table 10]
251         //  7  Cannot be revealed if object has its CKA_SENSITIVE attribute
252         //     set to CK_TRUE or its CKA_EXTRACTABLE attribute set to CK_FALSE.
253         if ((checks & ck7) == ck7 && (isSensitive() || !isExtractable())) {
254                 *pulValueLen = CK_UNAVAILABLE_INFORMATION;
255                 return CKR_ATTRIBUTE_SENSITIVE;
256         }
257
258         // Retrieve the lower level attribute.
259         if (!osobject->attributeExists(type)) {
260                 // Should be impossible.
261                 ERROR_MSG("Internal error: attribute not present");
262                 return CKR_GENERAL_ERROR;
263         }
264         OSAttribute attr = osobject->getAttribute(type);
265
266         // Get the actual attribute size.
267         CK_ULONG attrSize = size;
268         if (size == (CK_ULONG)-1)
269         {
270                 // We don't have a fixed size attribute so we need to consult
271                 // the lower level attribute for the exact size.
272
273                 // Lower level attribute has to be variable sized.
274                 if (attr.isByteStringAttribute())
275                 {
276                         if (isPrivate && attr.getByteStringValue().size() != 0)
277                         {
278                                 ByteString value;
279                                 if (!token->decrypt(attr.getByteStringValue(),value))
280                                 {
281                                         ERROR_MSG("Internal error: failed to decrypt private attribute value");
282                                         return CKR_GENERAL_ERROR;
283                                 }
284                                 attrSize = value.size();
285                         }
286                         else
287                                 attrSize = attr.getByteStringValue().size();
288                 }
289                 else if (attr.isMechanismTypeSetAttribute())
290                 {
291                         attrSize = attr.getMechanismTypeSetValue().size() * sizeof(CK_MECHANISM_TYPE);
292                 }
293                 else if (attr.isAttributeMapAttribute())
294                 {
295                         attrSize = attr.getAttributeMapValue().size() * sizeof(CK_ATTRIBUTE);
296                 }
297                 else if (attr.isUnsignedLongAttribute())
298                 {
299                         attrSize = sizeof(unsigned long);
300                 }
301                 else
302                 {
303                         // Should be impossible.
304                         ERROR_MSG("Internal error: attribute has fixed size");
305                         return CKR_GENERAL_ERROR;
306                 }
307         }
308
309         // [PKCS#11 v2.40, C_GetAttributeValue]
310         // 3. Otherwise, if the pValue field has the value NULL_PTR, then the
311         //    ulValueLen field is modified to hold the exact length of the
312         //    specified attribute for the object.
313         if (pValue == NULL_PTR) {
314                 // Return the size of the attribute.
315                 *pulValueLen = attrSize;
316                 return CKR_OK;
317         }
318
319         // [PKCS#11 v2.40, C_GetAttributeValue]
320         // 4. Otherwise, if the length specified in ulValueLen is large enough
321         //    to hold the value of the specified attribute for the object, then
322         //    that attribute is copied into the buffer located at pValue, and
323         //    the ulValueLen field is modified to hold the exact length of the
324         //    attribute.
325         if (*pulValueLen >= attrSize)
326         {
327                 // Only copy when there is actually something to copy
328                 CK_RV rv = CKR_OK;
329
330                 if (attr.isUnsignedLongAttribute()) {
331                         *(CK_ULONG_PTR)pValue = attr.getUnsignedLongValue();
332                 }
333                 else if (attr.isBooleanAttribute())
334                 {
335                         *(CK_BBOOL*)pValue = attr.getBooleanValue() ? CK_TRUE : CK_FALSE;
336                 }
337                 else if (attr.isByteStringAttribute())
338                 {
339                         if (isPrivate && attr.getByteStringValue().size() != 0)
340                         {
341                                 ByteString value;
342                                 if (!token->decrypt(attr.getByteStringValue(),value))
343                                 {
344                                         ERROR_MSG("Internal error: failed to decrypt private attribute value");
345                                         return CKR_GENERAL_ERROR;
346                                 }
347                                 const unsigned char* attrPtr = value.const_byte_str();
348                                 memcpy(pValue,attrPtr,attrSize);
349                         }
350                         else if (attr.getByteStringValue().size() != 0)
351                         {
352                                 const unsigned char* attrPtr = attr.getByteStringValue().const_byte_str();
353                                 memcpy(pValue,attrPtr,attrSize);
354                         }
355                 }
356                 else if (attr.isMechanismTypeSetAttribute())
357                 {
358                         CK_MECHANISM_TYPE_PTR pTemplate = (CK_MECHANISM_TYPE_PTR) pValue;
359                         size_t i = 0;
360
361                         std::set<CK_MECHANISM_TYPE> set = attr.getMechanismTypeSetValue();
362                         for (std::set<CK_MECHANISM_TYPE>::const_iterator it = set.begin(); it != set.end(); ++it)
363                                 pTemplate[++i] = *it;
364                 }
365                 else
366                 {
367                         // attr is already retrieved and verified to be an Attribute Map
368                         rv = retrieveAttributeMap((CK_ATTRIBUTE_PTR)pValue, attr.getAttributeMapValue());
369                 }
370                 *pulValueLen = attrSize;
371                 return rv;
372         }
373
374         // [PKCS#11 v2.40, C_GetAttributeValue]
375         // 5. Otherwise, the ulValueLen field is modified to hold the value CK_UNAVAILABLE_INFORMATION.
376         *pulValueLen = CK_UNAVAILABLE_INFORMATION;
377         return CKR_BUFFER_TOO_SMALL;
378 }
379
380 // Update the value if allowed
381 CK_RV P11Attribute::update(Token* token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
382 {
383         if (osobject == NULL) {
384                 ERROR_MSG("Internal error: osobject field contains NULL_PTR");
385                 return CKR_GENERAL_ERROR;
386         }
387
388         // [PKCS#11 v2.40, 4.1.1 Creating objects]
389         //    2. If the supplied template specifies an invalid value for a valid attribute, then the
390         //    attempt should fail with the error code CKR_ATTRIBUTE_VALUE_INVALID.
391         //    The valid values for Cryptoki attributes are described in the Cryptoki specification.
392
393         // Check for null pointers in values.
394         if (pValue == NULL_PTR && ulValueLen != 0) {
395                 ERROR_MSG("The attribute is a NULL_PTR but has a non-zero length")
396                 return CKR_ATTRIBUTE_VALUE_INVALID;
397         }
398
399         // For fixed sized attributes check that the size matches.
400         if (size != ((CK_ULONG)-1) && size != ulValueLen) {
401                 ERROR_MSG("The attribute size is different from the expected size")
402                 return CKR_ATTRIBUTE_VALUE_INVALID;
403         }
404
405         // [PKCS#11 v2.40, 4.1.1 Creating objects] OBJECT_OP_CREATE | OBJECT_OP_SET | OBJECT_OP_COPY
406         //    3. If the supplied template specifies a value for a read-only attribute, then the attempt
407         //    should fail with the error code CKR_ATTRIBUTE_READ_ONLY.
408         //    Whether or not a given Cryptoki attribute is read-only is explicitly stated in the Cryptoki
409         //    specification; however, a particular library and token may be even more restrictive than
410         //    Cryptoki specifies. In other words, an attribute which Cryptoki says is not read-only may
411         //    nonetheless be read-only under certain circumstances (i.e., in conjunction with some
412         //    combinations of other attributes) for a particular library and token. Whether or not a
413         //    given non-Cryptoki attribute is read-only is obviously outside the scope of Cryptoki.
414
415         // Attributes cannot be changed if CKA_MODIFIABLE is set to false
416         if (!isModifiable() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE) {
417                 ERROR_MSG("An object is with CKA_MODIFIABLE set to false is not modifiable");
418                 return CKR_ATTRIBUTE_READ_ONLY;
419         }
420
421         // Attributes cannot be modified if CKA_TRUSTED is true on a certificate object.
422         if (isTrusted() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE) {
423                 if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_CERTIFICATE)
424                 {
425                         ERROR_MSG("A trusted certificate cannot be modified");
426                         return CKR_ATTRIBUTE_READ_ONLY;
427                 }
428         }
429
430         //  ck2  MUST not be specified when object is created with C_CreateObject.
431         if ((checks & ck2) == ck2)
432         {
433                 if (OBJECT_OP_CREATE==op)
434                 {
435                         ERROR_MSG("Prohibited attribute was passed to object creation function");
436                         return CKR_ATTRIBUTE_READ_ONLY;
437                 }
438         }
439
440         //  ck4  MUST not be specified when object is generated with C_GenerateKey or C_GenerateKeyPair.
441         if ((checks & ck4) == ck4)
442         {
443                 if (OBJECT_OP_GENERATE==op)
444                 {
445                         ERROR_MSG("Prohibited attribute was passed to key generation function");
446                         return CKR_ATTRIBUTE_READ_ONLY;
447                 }
448         }
449
450         //  ck6  MUST not be specified when object is unwrapped with C_UnwrapKey.
451         if ((checks & ck6) == ck6)
452         {
453                 if (OBJECT_OP_UNWRAP==op)
454                 {
455                         ERROR_MSG("Prohibited attribute was passed to key unwrapping function");
456                         return CKR_ATTRIBUTE_READ_ONLY;
457                 }
458         }
459
460         //  ck8  May be modified after object is created with a C_SetAttributeValue call
461         //       or in the process of copying an object with a C_CopyObject call.
462         //       However, it is possible that a particular token may not permit modification of
463         //       the attribute during the course of a C_CopyObject call.
464         if ((checks & ck8) == ck8)
465         {
466                 if (OBJECT_OP_SET==op || OBJECT_OP_COPY==op)
467                 {
468                         return updateAttr(token, isPrivate, pValue, ulValueLen, op);
469                 }
470         }
471
472         // ck17  Can be changed in the process of copying the object using C_CopyObject.
473         if ((checks & ck17) == ck17)
474         {
475                 if (OBJECT_OP_COPY==op)
476                 {
477                         return updateAttr(token, isPrivate, pValue, ulValueLen, op);
478                 }
479         }
480
481         // For attributes that have not been explicitly excluded from modification
482         // during create/derive/generate/unwrap, we allow them to be modified.
483         if (OBJECT_OP_CREATE==op || OBJECT_OP_DERIVE==op || OBJECT_OP_GENERATE==op || OBJECT_OP_UNWRAP==op)
484         {
485                 return updateAttr(token, isPrivate, pValue, ulValueLen, op);
486         }
487
488         return CKR_ATTRIBUTE_READ_ONLY;
489 }
490
491 /*****************************************
492  * CKA_CLASS
493  *****************************************/
494
495 // Set default value
496 bool P11AttrClass::setDefault()
497 {
498         OSAttribute attrClass((unsigned long)CKO_VENDOR_DEFINED);
499         return osobject->setAttribute(type, attrClass);
500 }
501
502 // Update the value if allowed
503 CK_RV P11AttrClass::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
504 {
505         // Attribute specific checks
506
507         if (ulValueLen !=sizeof(CK_ULONG))
508         {
509                 return CKR_ATTRIBUTE_VALUE_INVALID;
510         }
511
512         if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != *(CK_ULONG*)pValue)
513         {
514                 return CKR_TEMPLATE_INCONSISTENT;
515         }
516
517         return CKR_OK;
518 }
519
520 /*****************************************
521  * CKA_KEY_TYPE
522  *****************************************/
523
524 // Set default value
525 bool P11AttrKeyType::setDefault()
526 {
527         OSAttribute attr((unsigned long)CKK_VENDOR_DEFINED);
528         return osobject->setAttribute(type, attr);
529 }
530
531 // Update the value if allowed
532 CK_RV P11AttrKeyType::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
533 {
534         // Attribute specific checks
535
536         if (ulValueLen !=sizeof(CK_ULONG))
537         {
538                 return CKR_ATTRIBUTE_VALUE_INVALID;
539         }
540
541         if (osobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != *(CK_ULONG*)pValue)
542         {
543                 return CKR_TEMPLATE_INCONSISTENT;
544         }
545
546         return CKR_OK;
547 }
548
549 /*****************************************
550  * CKA_CERTIFICATE_TYPE
551  * footnote 1
552  *  1  MUST be specified when object is created with C_CreateObject.
553  *****************************************/
554
555 // Set default value
556 bool P11AttrCertificateType::setDefault()
557 {
558         OSAttribute attr((unsigned long)CKC_VENDOR_DEFINED);
559         return osobject->setAttribute(type, attr);
560 }
561
562 // Update the value if allowed
563 CK_RV P11AttrCertificateType::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
564 {
565         // Attribute specific checks
566
567         if (ulValueLen !=sizeof(CK_ULONG))
568         {
569                 return CKR_ATTRIBUTE_VALUE_INVALID;
570         }
571
572         if (osobject->getUnsignedLongValue(CKA_CERTIFICATE_TYPE, CKC_VENDOR_DEFINED) != *(CK_ULONG*)pValue)
573         {
574                 return CKR_TEMPLATE_INCONSISTENT;
575         }
576
577         return CKR_OK;
578 }
579
580 /*****************************************
581  * CKA_TOKEN
582  *****************************************/
583
584 // Set default value
585 bool P11AttrToken::setDefault()
586 {
587         OSAttribute attr(false);
588         return osobject->setAttribute(type, attr);
589 }
590
591 // Update the value if allowed
592 CK_RV P11AttrToken::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
593 {
594         OSAttribute attrTrue(true);
595         OSAttribute attrFalse(false);
596
597         // Attribute specific checks
598
599         if (ulValueLen !=sizeof(CK_BBOOL))
600         {
601                 return CKR_ATTRIBUTE_VALUE_INVALID;
602         }
603
604         // Store data
605
606         if (*(CK_BBOOL*)pValue == CK_FALSE)
607         {
608                 osobject->setAttribute(type, attrFalse);
609         }
610         else
611         {
612                 osobject->setAttribute(type, attrTrue);
613         }
614
615         return CKR_OK;
616 }
617
618 /*****************************************
619  * CKA_PRIVATE
620  *****************************************/
621
622 // Set default value
623 bool P11AttrPrivate::setDefault()
624 {
625         OSAttribute attr(true);
626         return osobject->setAttribute(type, attr);
627 }
628
629 // Update the value if allowed
630 CK_RV P11AttrPrivate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
631 {
632         OSAttribute attrTrue(true);
633         OSAttribute attrFalse(false);
634
635         // Attribute specific checks
636
637         if (ulValueLen !=sizeof(CK_BBOOL))
638         {
639                 return CKR_ATTRIBUTE_VALUE_INVALID;
640         }
641
642         // Store data
643
644         if (*(CK_BBOOL*)pValue == CK_FALSE)
645         {
646                 osobject->setAttribute(type, attrFalse);
647         }
648         else
649         {
650                 osobject->setAttribute(type, attrTrue);
651         }
652
653         return CKR_OK;
654 }
655
656 /*****************************************
657  * CKA_MODIFIABLE
658  *****************************************/
659
660 // Set default value
661 bool P11AttrModifiable::setDefault()
662 {
663         OSAttribute attr(true);
664         return osobject->setAttribute(type, attr);
665 }
666
667 // Update the value if allowed
668 CK_RV P11AttrModifiable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
669 {
670         OSAttribute attrTrue(true);
671         OSAttribute attrFalse(false);
672
673         // Attribute specific checks
674
675         if (ulValueLen !=sizeof(CK_BBOOL))
676         {
677                 return CKR_ATTRIBUTE_VALUE_INVALID;
678         }
679
680         // Store data
681
682         if (*(CK_BBOOL*)pValue == CK_FALSE)
683         {
684                 osobject->setAttribute(type, attrFalse);
685         }
686         else
687         {
688                 osobject->setAttribute(type, attrTrue);
689         }
690
691         return CKR_OK;
692 }
693
694 /*****************************************
695  * CKA_LABEL
696  *****************************************/
697
698 // Set default value
699 bool P11AttrLabel::setDefault()
700 {
701         OSAttribute attr(ByteString(""));
702         return osobject->setAttribute(type, attr);
703 }
704
705 /*****************************************
706  * CKA_COPYABLE
707  *****************************************/
708
709 // Set default value
710 bool P11AttrCopyable::setDefault()
711 {
712         OSAttribute attr(true);
713         return osobject->setAttribute(type, attr);
714 }
715
716 // Update the value if allowed
717 CK_RV P11AttrCopyable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
718 {
719         OSAttribute attrTrue(true);
720         OSAttribute attrFalse(false);
721
722         // Attribute specific checks
723
724         if (ulValueLen !=sizeof(CK_BBOOL))
725         {
726                 return CKR_ATTRIBUTE_VALUE_INVALID;
727         }
728
729         // Store data
730
731         if (*(CK_BBOOL*)pValue == CK_FALSE)
732         {
733                 osobject->setAttribute(type, attrFalse);
734         }
735         else
736         {
737                 if (osobject->getBooleanValue(CKA_COPYABLE, true) == false)
738                 {
739                         return CKR_ATTRIBUTE_READ_ONLY;
740                 }
741         }
742
743         return CKR_OK;
744 }
745
746 /*****************************************
747  * CKA_DESTROYABLE
748  *****************************************/
749
750 // Set default value
751 bool P11AttrDestroyable::setDefault()
752 {
753         OSAttribute attr(true);
754         return osobject->setAttribute(type, attr);
755 }
756
757 // Update the value if allowed
758 CK_RV P11AttrDestroyable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
759 {
760         OSAttribute attrTrue(true);
761         OSAttribute attrFalse(false);
762
763         // Attribute specific checks
764
765         if (ulValueLen !=sizeof(CK_BBOOL))
766         {
767                 return CKR_ATTRIBUTE_VALUE_INVALID;
768         }
769
770         // Store data
771
772         if (*(CK_BBOOL*)pValue == CK_FALSE)
773         {
774                 osobject->setAttribute(type, attrFalse);
775         }
776         else
777         {
778                 osobject->setAttribute(type, attrTrue);
779         }
780
781         return CKR_OK;
782 }
783
784 /*****************************************
785  * CKA_APPLICATION
786  *****************************************/
787
788 // Set default value
789 bool P11AttrApplication::setDefault()
790 {
791         OSAttribute attr(ByteString(""));
792         return osobject->setAttribute(type, attr);
793 }
794
795 /*****************************************
796  * CKA_OBJECT_ID
797  *****************************************/
798
799 // Set default value
800 bool P11AttrObjectID::setDefault()
801 {
802         OSAttribute attr(ByteString(""));
803         return osobject->setAttribute(type, attr);
804 }
805
806 /*****************************************
807  * CKA_CHECK_VALUE
808  *****************************************/
809
810 // Set default value
811 bool P11AttrCheckValue::setDefault()
812 {
813         OSAttribute attr(ByteString(""));
814         return osobject->setAttribute(type, attr);
815 }
816
817 // Update the value if allowed
818 CK_RV P11AttrCheckValue::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
819 {
820         ByteString plaintext((unsigned char*)pValue, ulValueLen);
821         ByteString value;
822
823         // Encrypt
824
825         if (isPrivate)
826         {
827                 if (!token->encrypt(plaintext, value))
828                         return CKR_GENERAL_ERROR;
829         }
830         else
831                 value = plaintext;
832
833         // Attribute specific checks
834
835         if (value.size() < ulValueLen)
836                 return CKR_GENERAL_ERROR;
837
838         // Store data
839         if (ulValueLen == 0)
840         {
841                 osobject->setAttribute(type, value);
842         }
843         else
844         {
845                 ByteString checkValue;
846                 ByteString keybits;
847                 if (isPrivate)
848                 {
849                         if (!token->decrypt(osobject->getByteStringValue(CKA_VALUE), keybits))
850                                 return CKR_GENERAL_ERROR;
851                 }
852                 else
853                 {
854                         keybits = osobject->getByteStringValue(CKA_VALUE);
855                 }
856
857                 SymmetricKey key;
858                 AESKey aes;
859                 DESKey des;
860                 switch (osobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED))
861                 {
862                         case CKK_GENERIC_SECRET:
863                         case CKK_MD5_HMAC:
864                         case CKK_SHA_1_HMAC:
865                         case CKK_SHA224_HMAC:
866                         case CKK_SHA256_HMAC:
867                         case CKK_SHA384_HMAC:
868                         case CKK_SHA512_HMAC:
869                                 key.setKeyBits(keybits);
870                                 key.setBitLen(keybits.size() * 8);
871                                 checkValue = key.getKeyCheckValue();
872                                 break;
873                         case CKK_AES:
874                                 aes.setKeyBits(keybits);
875                                 aes.setBitLen(keybits.size() * 8);
876                                 checkValue = aes.getKeyCheckValue();
877                                 break;
878                         case CKK_DES:
879                         case CKK_DES2:
880                         case CKK_DES3:
881                                 des.setKeyBits(keybits);
882                                 des.setBitLen(keybits.size() * 7);
883                                 checkValue = des.getKeyCheckValue();
884                                 break;
885                         case CKK_GOST28147:
886                                 // TODO: Encryption support for CKK_GOST28147
887                                 // We do not calculate the KCV
888                                 checkValue = plaintext;
889                                 break;
890                         default:
891                                 return CKR_GENERAL_ERROR;
892                 }
893
894                 if (plaintext != checkValue)
895                         return CKR_ATTRIBUTE_VALUE_INVALID;
896
897                 osobject->setAttribute(type, value);
898         }
899
900         return CKR_OK;
901 }
902
903 /*****************************************
904  * CKA_PUBLIC_KEY_INFO
905  *****************************************/
906
907 // Set default value
908 bool P11AttrPublicKeyInfo::setDefault()
909 {
910         OSAttribute attr(ByteString(""));
911         return osobject->setAttribute(type, attr);
912 }
913
914 /*****************************************
915  * CKA_ID
916  *****************************************/
917
918 // Set default value
919 bool P11AttrID::setDefault()
920 {
921         OSAttribute attr(ByteString(""));
922         return osobject->setAttribute(type, attr);
923 }
924
925 /*****************************************
926  * CKA_VALUE
927  *****************************************/
928
929 // Set default value
930 bool P11AttrValue::setDefault()
931 {
932         OSAttribute attr(ByteString(""));
933         return osobject->setAttribute(type, attr);
934 }
935
936 // Update the value if allowed
937 CK_RV P11AttrValue::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
938 {
939         ByteString plaintext((unsigned char*)pValue, ulValueLen);
940         ByteString value;
941
942         // Encrypt
943
944         if (isPrivate)
945         {
946                 if (!token->encrypt(plaintext, value))
947                         return CKR_GENERAL_ERROR;
948         }
949         else
950                 value = plaintext;
951
952         // Attribute specific checks
953
954         if (value.size() < ulValueLen)
955                 return CKR_GENERAL_ERROR;
956
957         // Store data
958
959         osobject->setAttribute(type, value);
960
961         // Set the size during C_CreateObject and C_UnwrapKey.
962
963         if (op == OBJECT_OP_CREATE || op == OBJECT_OP_UNWRAP)
964         {
965                 // Set the CKA_VALUE_LEN
966                 if (osobject->attributeExists(CKA_VALUE_LEN))
967                 {
968                         OSAttribute bytes((unsigned long)plaintext.size());
969                         osobject->setAttribute(CKA_VALUE_LEN, bytes);
970                 }
971
972                 // Set the CKA_VALUE_BITS
973                 if (osobject->attributeExists(CKA_VALUE_BITS))
974                 {
975                         OSAttribute bits((unsigned long)plaintext.bits());
976                         osobject->setAttribute(CKA_VALUE_BITS, bits);
977                 }
978         }
979
980         // Calculate the CKA_CHECK_VALUE for certificates
981         if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_CERTIFICATE)
982         {
983                 HashAlgorithm* hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA1);
984                 if (hash == NULL) return CKR_GENERAL_ERROR;
985
986                 ByteString digest;
987                 if (hash->hashInit() == false ||
988                     hash->hashUpdate(plaintext) == false ||
989                     hash->hashFinal(digest) == false)
990                 {
991                         CryptoFactory::i()->recycleHashAlgorithm(hash);
992                         return CKR_GENERAL_ERROR;
993                 }
994                 CryptoFactory::i()->recycleHashAlgorithm(hash);
995
996                 // First three bytes of the SHA-1 hash
997                 digest.resize(3);
998
999                 if (isPrivate)
1000                 {
1001                         ByteString encrypted;
1002                         if (!token->encrypt(digest, encrypted))
1003                                 return CKR_GENERAL_ERROR;
1004                         osobject->setAttribute(CKA_CHECK_VALUE, encrypted);
1005                 }
1006                 else
1007                         osobject->setAttribute(CKA_CHECK_VALUE, digest);
1008         }
1009
1010         // Calculate the CKA_CHECK_VALUE for secret keys
1011         if (op == OBJECT_OP_CREATE &&
1012             osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_SECRET_KEY)
1013         {
1014                 SymmetricKey key;
1015                 AESKey aes;
1016                 DESKey des;
1017                 ByteString checkValue;
1018                 switch (osobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED))
1019                 {
1020                         case CKK_GENERIC_SECRET:
1021                         case CKK_MD5_HMAC:
1022                         case CKK_SHA_1_HMAC:
1023                         case CKK_SHA224_HMAC:
1024                         case CKK_SHA256_HMAC:
1025                         case CKK_SHA384_HMAC:
1026                         case CKK_SHA512_HMAC:
1027                                 key.setKeyBits(plaintext);
1028                                 key.setBitLen(plaintext.size() * 8);
1029                                 checkValue = key.getKeyCheckValue();
1030                                 break;
1031                         case CKK_AES:
1032                                 aes.setKeyBits(plaintext);
1033                                 aes.setBitLen(plaintext.size() * 8);
1034                                 checkValue = aes.getKeyCheckValue();
1035                                 break;
1036                         case CKK_DES:
1037                         case CKK_DES2:
1038                         case CKK_DES3:
1039                                 des.setKeyBits(plaintext);
1040                                 des.setBitLen(plaintext.size() * 7);
1041                                 checkValue = des.getKeyCheckValue();
1042                                 break;
1043                         case CKK_GOST28147:
1044                                 // TODO: Encryption support for CKK_GOST28147
1045                                 // We do not calculate the KCV
1046                                 break;
1047                         default:
1048                                 return CKR_GENERAL_ERROR;
1049                 }
1050
1051                 if (isPrivate)
1052                 {
1053                         ByteString encrypted;
1054                         if (!token->encrypt(checkValue, encrypted))
1055                                 return CKR_GENERAL_ERROR;
1056                         osobject->setAttribute(CKA_CHECK_VALUE, encrypted);
1057                 }
1058                 else
1059                         osobject->setAttribute(CKA_CHECK_VALUE, checkValue);
1060         }
1061
1062         return CKR_OK;
1063 }
1064
1065 /*****************************************
1066  * CKA_SUBJECT
1067  *****************************************/
1068
1069 // Set default value
1070 bool P11AttrSubject::setDefault()
1071 {
1072         OSAttribute attr(ByteString(""));
1073         return osobject->setAttribute(type, attr);
1074 }
1075
1076 /*****************************************
1077  * CKA_ISSUER
1078  *****************************************/
1079
1080 // Set default value
1081 bool P11AttrIssuer::setDefault()
1082 {
1083         OSAttribute attr(ByteString(""));
1084         return osobject->setAttribute(type, attr);
1085 }
1086
1087 /*****************************************
1088  * CKA_TRUSTED
1089  *****************************************/
1090
1091 // Set default value
1092 bool P11AttrTrusted::setDefault()
1093 {
1094         OSAttribute attr(false);
1095         return osobject->setAttribute(type, attr);
1096 }
1097
1098 // Update the value if allowed
1099 CK_RV P11AttrTrusted::updateAttr(Token *token, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1100 {
1101         OSAttribute attrTrue(true);
1102         OSAttribute attrFalse(false);
1103
1104         // Attribute specific checks
1105
1106         if (ulValueLen !=sizeof(CK_BBOOL))
1107         {
1108                 return CKR_ATTRIBUTE_VALUE_INVALID;
1109         }
1110
1111         // Store data
1112
1113         if (*(CK_BBOOL*)pValue == CK_FALSE)
1114         {
1115                 osobject->setAttribute(type, attrFalse);
1116         }
1117         else
1118         {
1119                 if (!token->isSOLoggedIn())
1120                 {
1121                         ERROR_MSG("CKA_TRUSTED can only be set to true by the SO");
1122                         return CKR_ATTRIBUTE_READ_ONLY;
1123                 }
1124                 osobject->setAttribute(type, attrTrue);
1125         }
1126
1127         return CKR_OK;
1128 }
1129
1130 /*****************************************
1131  * CKA_CERTIFICATE_CATEGORY
1132  *****************************************/
1133
1134 // Set default value
1135 bool P11AttrCertificateCategory::setDefault()
1136 {
1137         OSAttribute attr((unsigned long)0);
1138         return osobject->setAttribute(type, attr);
1139 }
1140
1141 // Update the value if allowed
1142 CK_RV P11AttrCertificateCategory::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1143 {
1144         // Attribute specific checks
1145
1146         if (ulValueLen !=sizeof(CK_ULONG))
1147         {
1148                 return CKR_ATTRIBUTE_VALUE_INVALID;
1149         }
1150
1151         // Store data
1152         osobject->setAttribute(type, *(CK_ULONG*)pValue);
1153
1154         return CKR_OK;
1155 }
1156
1157 /*****************************************
1158  * CKA_START_DATE
1159  *****************************************/
1160
1161 // Set default value
1162 bool P11AttrStartDate::setDefault()
1163 {
1164         OSAttribute attr(ByteString(""));
1165         return osobject->setAttribute(type, attr);
1166 }
1167
1168 // Update the value if allowed
1169 CK_RV P11AttrStartDate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1170 {
1171         // Attribute specific checks
1172
1173         if (ulValueLen !=sizeof(CK_DATE) && ulValueLen !=0)
1174         {
1175                 return CKR_ATTRIBUTE_VALUE_INVALID;
1176         }
1177
1178         // Store data
1179         osobject->setAttribute(type, ByteString((unsigned char*)pValue, ulValueLen));
1180
1181         return CKR_OK;
1182 }
1183
1184 /*****************************************
1185  * CKA_END_DATE
1186  *****************************************/
1187
1188 // Set default value
1189 bool P11AttrEndDate::setDefault()
1190 {
1191         OSAttribute attr(ByteString(""));
1192         return osobject->setAttribute(type, attr);
1193 }
1194
1195 // Update the value if allowed
1196 CK_RV P11AttrEndDate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1197 {
1198         // Attribute specific checks
1199
1200         if (ulValueLen !=sizeof(CK_DATE) && ulValueLen !=0)
1201         {
1202                 return CKR_ATTRIBUTE_VALUE_INVALID;
1203         }
1204
1205         // Store data
1206         osobject->setAttribute(type, ByteString((unsigned char*)pValue, ulValueLen));
1207
1208         return CKR_OK;
1209 }
1210
1211 /*****************************************
1212  * CKA_SERIAL_NUMBER
1213  *****************************************/
1214
1215 // Set default value
1216 bool P11AttrSerialNumber::setDefault()
1217 {
1218         OSAttribute attr(ByteString(""));
1219         return osobject->setAttribute(type, attr);
1220 }
1221
1222 /*****************************************
1223  * CKA_URL
1224  *****************************************/
1225
1226 // Set default value
1227 bool P11AttrURL::setDefault()
1228 {
1229         OSAttribute attr(ByteString(""));
1230         return osobject->setAttribute(type, attr);
1231 }
1232
1233 /*****************************************
1234  * CKA_HASH_OF_SUBJECT_PUBLIC_KEY
1235  *****************************************/
1236
1237 // Set default value
1238 bool P11AttrHashOfSubjectPublicKey::setDefault()
1239 {
1240         OSAttribute attr(ByteString(""));
1241         return osobject->setAttribute(type, attr);
1242 }
1243
1244 /*****************************************
1245  * CKA_HASH_OF_ISSUER_PUBLIC_KEY
1246  *****************************************/
1247
1248 // Set default value
1249 bool P11AttrHashOfIssuerPublicKey::setDefault()
1250 {
1251         OSAttribute attr(ByteString(""));
1252         return osobject->setAttribute(type, attr);
1253 }
1254
1255 /*****************************************
1256  * CKA_JAVA_MIDP_SECURITY_DOMAIN
1257  *****************************************/
1258
1259 // Set default value
1260 bool P11AttrJavaMidpSecurityDomain::setDefault()
1261 {
1262         OSAttribute attr((unsigned long)0);
1263         return osobject->setAttribute(type, attr);
1264 }
1265
1266 // Update the value if allowed
1267 CK_RV P11AttrJavaMidpSecurityDomain::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1268 {
1269         // Attribute specific checks
1270
1271         if (ulValueLen !=sizeof(CK_ULONG))
1272         {
1273                 return CKR_ATTRIBUTE_VALUE_INVALID;
1274         }
1275
1276         // Store data
1277         osobject->setAttribute(type, *(CK_ULONG*)pValue);
1278
1279         return CKR_OK;
1280 }
1281
1282 /*****************************************
1283  * CKA_NAME_HASH_ALGORITHM
1284  *****************************************/
1285
1286 // Set default value
1287 bool P11AttrNameHashAlgorithm::setDefault()
1288 {
1289         OSAttribute attr((unsigned long)CKM_SHA_1);
1290         return osobject->setAttribute(type, attr);
1291 }
1292
1293 // Update the value if allowed
1294 CK_RV P11AttrNameHashAlgorithm::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1295 {
1296         // Attribute specific checks
1297
1298         if (ulValueLen !=sizeof(CK_ULONG))
1299         {
1300                 return CKR_ATTRIBUTE_VALUE_INVALID;
1301         }
1302
1303         // Store data
1304         osobject->setAttribute(type, *(CK_ULONG*)pValue);
1305
1306         return CKR_OK;
1307 }
1308
1309 /*****************************************
1310  * CKA_DERIVE
1311  *****************************************/
1312
1313 // Set default value
1314 bool P11AttrDerive::setDefault()
1315 {
1316         OSAttribute attr(false);
1317         return osobject->setAttribute(type, attr);
1318 }
1319
1320 // Update the value if allowed
1321 CK_RV P11AttrDerive::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1322 {
1323         OSAttribute attrTrue(true);
1324         OSAttribute attrFalse(false);
1325
1326         // Attribute specific checks
1327
1328         if (ulValueLen !=sizeof(CK_BBOOL))
1329         {
1330                 return CKR_ATTRIBUTE_VALUE_INVALID;
1331         }
1332
1333         // Store data
1334
1335         if (*(CK_BBOOL*)pValue == CK_FALSE)
1336         {
1337                 osobject->setAttribute(type, attrFalse);
1338         }
1339         else
1340         {
1341                 osobject->setAttribute(type, attrTrue);
1342         }
1343
1344         return CKR_OK;
1345 }
1346
1347 /*****************************************
1348  * CKA_ENCRYPT
1349  *****************************************/
1350
1351 // Set default value
1352 bool P11AttrEncrypt::setDefault()
1353 {
1354         OSAttribute attr(true);
1355         return osobject->setAttribute(type, attr);
1356 }
1357
1358 // Update the value if allowed
1359 CK_RV P11AttrEncrypt::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1360 {
1361         OSAttribute attrTrue(true);
1362         OSAttribute attrFalse(false);
1363
1364         // Attribute specific checks
1365
1366         if (ulValueLen !=sizeof(CK_BBOOL))
1367         {
1368                 return CKR_ATTRIBUTE_VALUE_INVALID;
1369         }
1370
1371         // Store data
1372
1373         if (*(CK_BBOOL*)pValue == CK_FALSE)
1374         {
1375                 osobject->setAttribute(type, attrFalse);
1376         }
1377         else
1378         {
1379                 osobject->setAttribute(type, attrTrue);
1380         }
1381
1382         return CKR_OK;
1383 }
1384
1385 /*****************************************
1386  * CKA_VERIFY
1387  *****************************************/
1388
1389 // Set default value
1390 bool P11AttrVerify::setDefault()
1391 {
1392         OSAttribute attr(true);
1393         return osobject->setAttribute(type, attr);
1394 }
1395
1396 // Update the value if allowed
1397 CK_RV P11AttrVerify::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1398 {
1399         OSAttribute attrTrue(true);
1400         OSAttribute attrFalse(false);
1401
1402         // Attribute specific checks
1403
1404         if (ulValueLen !=sizeof(CK_BBOOL))
1405         {
1406                 return CKR_ATTRIBUTE_VALUE_INVALID;
1407         }
1408
1409         // Store data
1410
1411         if (*(CK_BBOOL*)pValue == CK_FALSE)
1412         {
1413                 osobject->setAttribute(type, attrFalse);
1414         }
1415         else
1416         {
1417                 osobject->setAttribute(type, attrTrue);
1418         }
1419
1420         return CKR_OK;
1421 }
1422
1423 /*****************************************
1424  * CKA_VERIFY_RECOVER
1425  *****************************************/
1426
1427 // Set default value
1428 bool P11AttrVerifyRecover::setDefault()
1429 {
1430         OSAttribute attr(true);
1431         return osobject->setAttribute(type, attr);
1432 }
1433
1434 // Update the value if allowed
1435 CK_RV P11AttrVerifyRecover::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1436 {
1437         OSAttribute attrTrue(true);
1438         OSAttribute attrFalse(false);
1439
1440         // Attribute specific checks
1441
1442         if (ulValueLen !=sizeof(CK_BBOOL))
1443         {
1444                 return CKR_ATTRIBUTE_VALUE_INVALID;
1445         }
1446
1447         // Store data
1448
1449         if (*(CK_BBOOL*)pValue == CK_FALSE)
1450         {
1451                 osobject->setAttribute(type, attrFalse);
1452         }
1453         else
1454         {
1455                 osobject->setAttribute(type, attrTrue);
1456         }
1457
1458         return CKR_OK;
1459 }
1460
1461 /*****************************************
1462  * CKA_WRAP
1463  *****************************************/
1464
1465 // Set default value
1466 bool P11AttrWrap::setDefault()
1467 {
1468         OSAttribute attr(true);
1469         return osobject->setAttribute(type, attr);
1470 }
1471
1472 // Update the value if allowed
1473 CK_RV P11AttrWrap::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1474 {
1475         OSAttribute attrTrue(true);
1476         OSAttribute attrFalse(false);
1477
1478         // Attribute specific checks
1479
1480         if (ulValueLen !=sizeof(CK_BBOOL))
1481         {
1482                 return CKR_ATTRIBUTE_VALUE_INVALID;
1483         }
1484
1485         // Store data
1486
1487         if (*(CK_BBOOL*)pValue == CK_FALSE)
1488         {
1489                 osobject->setAttribute(type, attrFalse);
1490         }
1491         else
1492         {
1493                 osobject->setAttribute(type, attrTrue);
1494         }
1495
1496         return CKR_OK;
1497 }
1498
1499 /*****************************************
1500  * CKA_DECRYPT
1501  *****************************************/
1502
1503 // Set default value
1504 bool P11AttrDecrypt::setDefault()
1505 {
1506         OSAttribute attr(true);
1507         return osobject->setAttribute(type, attr);
1508 }
1509
1510 // Update the value if allowed
1511 CK_RV P11AttrDecrypt::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1512 {
1513         OSAttribute attrTrue(true);
1514         OSAttribute attrFalse(false);
1515
1516         // Attribute specific checks
1517
1518         if (ulValueLen !=sizeof(CK_BBOOL))
1519         {
1520                 return CKR_ATTRIBUTE_VALUE_INVALID;
1521         }
1522
1523         // Store data
1524
1525         if (*(CK_BBOOL*)pValue == CK_FALSE)
1526         {
1527                 osobject->setAttribute(type, attrFalse);
1528         }
1529         else
1530         {
1531                 osobject->setAttribute(type, attrTrue);
1532         }
1533
1534         return CKR_OK;
1535 }
1536
1537 /*****************************************
1538  * CKA_SIGN
1539  *****************************************/
1540
1541 // Set default value
1542 bool P11AttrSign::setDefault()
1543 {
1544         OSAttribute attr(true);
1545         return osobject->setAttribute(type, attr);
1546 }
1547
1548 // Update the value if allowed
1549 CK_RV P11AttrSign::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1550 {
1551         OSAttribute attrTrue(true);
1552         OSAttribute attrFalse(false);
1553
1554         // Attribute specific checks
1555
1556         if (ulValueLen !=sizeof(CK_BBOOL))
1557         {
1558                 return CKR_ATTRIBUTE_VALUE_INVALID;
1559         }
1560
1561         // Store data
1562
1563         if (*(CK_BBOOL*)pValue == CK_FALSE)
1564         {
1565                 osobject->setAttribute(type, attrFalse);
1566         }
1567         else
1568         {
1569                 osobject->setAttribute(type, attrTrue);
1570         }
1571
1572         return CKR_OK;
1573 }
1574
1575 /*****************************************
1576  * CKA_SIGN_RECOVER
1577  *****************************************/
1578
1579 // Set default value
1580 bool P11AttrSignRecover::setDefault()
1581 {
1582         OSAttribute attr(true);
1583         return osobject->setAttribute(type, attr);
1584 }
1585
1586 // Update the value if allowed
1587 CK_RV P11AttrSignRecover::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1588 {
1589         OSAttribute attrTrue(true);
1590         OSAttribute attrFalse(false);
1591
1592         // Attribute specific checks
1593
1594         if (ulValueLen !=sizeof(CK_BBOOL))
1595         {
1596                 return CKR_ATTRIBUTE_VALUE_INVALID;
1597         }
1598
1599         // Store data
1600
1601         if (*(CK_BBOOL*)pValue == CK_FALSE)
1602         {
1603                 osobject->setAttribute(type, attrFalse);
1604         }
1605         else
1606         {
1607                 osobject->setAttribute(type, attrTrue);
1608         }
1609
1610         return CKR_OK;
1611 }
1612
1613 /*****************************************
1614  * CKA_UNWRAP
1615  *****************************************/
1616
1617 // Set default value
1618 bool P11AttrUnwrap::setDefault()
1619 {
1620         OSAttribute attr(true);
1621         return osobject->setAttribute(type, attr);
1622 }
1623
1624 // Update the value if allowed
1625 CK_RV P11AttrUnwrap::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1626 {
1627         OSAttribute attrTrue(true);
1628         OSAttribute attrFalse(false);
1629
1630         // Attribute specific checks
1631
1632         if (ulValueLen !=sizeof(CK_BBOOL))
1633         {
1634                 return CKR_ATTRIBUTE_VALUE_INVALID;
1635         }
1636
1637         // Store data
1638
1639         if (*(CK_BBOOL*)pValue == CK_FALSE)
1640         {
1641                 osobject->setAttribute(type, attrFalse);
1642         }
1643         else
1644         {
1645                 osobject->setAttribute(type, attrTrue);
1646         }
1647
1648         return CKR_OK;
1649 }
1650
1651 /*****************************************
1652  * CKA_LOCAL
1653  *****************************************/
1654
1655 // Set default value
1656 bool P11AttrLocal::setDefault()
1657 {
1658         OSAttribute attr(false);
1659         return osobject->setAttribute(type, attr);
1660 }
1661
1662 // Update the value if allowed
1663 CK_RV P11AttrLocal::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
1664 {
1665         return CKR_ATTRIBUTE_READ_ONLY;
1666 }
1667
1668 /*****************************************
1669  * CKA_KEY_GEN_MECHANISM
1670  *****************************************/
1671
1672 // Set default value
1673 bool P11AttrKeyGenMechanism::setDefault()
1674 {
1675         OSAttribute attr((unsigned long)CK_UNAVAILABLE_INFORMATION);
1676         return osobject->setAttribute(type, attr);
1677 }
1678
1679 // Update the value if allowed
1680 CK_RV P11AttrKeyGenMechanism::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
1681 {
1682         return CKR_ATTRIBUTE_READ_ONLY;
1683 }
1684
1685 /*****************************************
1686  * CKA_ALWAYS_SENSITIVE
1687  *****************************************/
1688
1689 // Set default value
1690 bool P11AttrAlwaysSensitive::setDefault()
1691 {
1692         OSAttribute attr(false);
1693         return osobject->setAttribute(type, attr);
1694 }
1695
1696 // Update the value if allowed
1697 CK_RV P11AttrAlwaysSensitive::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
1698 {
1699         return CKR_ATTRIBUTE_READ_ONLY;
1700 }
1701
1702 /*****************************************
1703  * CKA_NEVER_EXTRACTABLE
1704  *****************************************/
1705
1706 // Set default value
1707 bool P11AttrNeverExtractable::setDefault()
1708 {
1709         OSAttribute attr(true);
1710         return osobject->setAttribute(type, attr);
1711 }
1712
1713 // Update the value if allowed
1714 CK_RV P11AttrNeverExtractable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
1715 {
1716         return CKR_ATTRIBUTE_READ_ONLY;
1717 }
1718
1719 /*****************************************
1720  * CKA_SENSITIVE
1721  *****************************************/
1722
1723 // Set default value
1724 bool P11AttrSensitive::setDefault()
1725 {
1726         // We default to false because we want to handle the secret keys in a correct way
1727         OSAttribute attr(false);
1728         return osobject->setAttribute(type, attr);
1729 }
1730
1731 // Update the value if allowed
1732 CK_RV P11AttrSensitive::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
1733 {
1734         OSAttribute attrTrue(true);
1735         OSAttribute attrFalse(false);
1736
1737         // Attribute specific checks
1738
1739         if (op == OBJECT_OP_SET || op == OBJECT_OP_COPY)
1740         {
1741                 if (osobject->getBooleanValue(CKA_SENSITIVE, false))
1742                 {
1743                         return CKR_ATTRIBUTE_READ_ONLY;
1744                 }
1745         }
1746
1747         if (ulValueLen !=sizeof(CK_BBOOL))
1748         {
1749                 return CKR_ATTRIBUTE_VALUE_INVALID;
1750         }
1751
1752         // Store data
1753
1754         if (*(CK_BBOOL*)pValue == CK_FALSE)
1755         {
1756                 osobject->setAttribute(type, attrFalse);
1757                 osobject->setAttribute(CKA_ALWAYS_SENSITIVE, attrFalse);
1758         }
1759         else
1760         {
1761                 osobject->setAttribute(type, attrTrue);
1762
1763                 // This is so that generated keys get the correct value
1764                 if (op == OBJECT_OP_GENERATE || op == OBJECT_OP_DERIVE)
1765                 {
1766                         osobject->setAttribute(CKA_ALWAYS_SENSITIVE, attrTrue);
1767                 }
1768         }
1769
1770         return CKR_OK;
1771 }
1772
1773 /*****************************************
1774  * CKA_EXTRACTABLE
1775  *****************************************/
1776
1777 // Set default value
1778 bool P11AttrExtractable::setDefault()
1779 {
1780         OSAttribute attr(false);
1781         return osobject->setAttribute(type, attr);
1782 }
1783
1784 // Update the value if allowed
1785 CK_RV P11AttrExtractable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
1786 {
1787         OSAttribute attrTrue(true);
1788         OSAttribute attrFalse(false);
1789
1790         // Attribute specific checks
1791
1792         if (op == OBJECT_OP_SET || op == OBJECT_OP_COPY)
1793         {
1794                 if (osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false)
1795                 {
1796                         return CKR_ATTRIBUTE_READ_ONLY;
1797                 }
1798         }
1799
1800         if (ulValueLen !=sizeof(CK_BBOOL))
1801         {
1802                 return CKR_ATTRIBUTE_VALUE_INVALID;
1803         }
1804
1805         // Store data
1806
1807         if (*(CK_BBOOL*)pValue == CK_FALSE)
1808         {
1809                 osobject->setAttribute(type, attrFalse);
1810         }
1811         else
1812         {
1813                 osobject->setAttribute(type, attrTrue);
1814                 osobject->setAttribute(CKA_NEVER_EXTRACTABLE, attrFalse);
1815         }
1816
1817         return CKR_OK;
1818 }
1819
1820 /*****************************************
1821  * CKA_WRAP_WITH_TRUSTED
1822  *****************************************/
1823
1824 // Set default value
1825 bool P11AttrWrapWithTrusted::setDefault()
1826 {
1827         OSAttribute attr(false);
1828         return osobject->setAttribute(type, attr);
1829 }
1830
1831 // Update the value if allowed
1832 CK_RV P11AttrWrapWithTrusted::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
1833 {
1834         OSAttribute attrTrue(true);
1835         OSAttribute attrFalse(false);
1836
1837         // Attribute specific checks
1838
1839         if (op == OBJECT_OP_SET || op == OBJECT_OP_COPY)
1840         {
1841                 if (osobject->getBooleanValue(CKA_WRAP_WITH_TRUSTED, false))
1842                 {
1843                         return CKR_ATTRIBUTE_READ_ONLY;
1844                 }
1845         }
1846
1847         if (ulValueLen !=sizeof(CK_BBOOL))
1848         {
1849                 return CKR_ATTRIBUTE_VALUE_INVALID;
1850         }
1851
1852         // Store data
1853
1854         if (*(CK_BBOOL*)pValue == CK_FALSE)
1855         {
1856                 osobject->setAttribute(type, attrFalse);
1857         }
1858         else
1859         {
1860                 osobject->setAttribute(type, attrTrue);
1861         }
1862
1863         return CKR_OK;
1864 }
1865
1866 /*****************************************
1867  * CKA_ALWAYS_AUTHENTICATE
1868  *****************************************/
1869
1870 // Set default value
1871 bool P11AttrAlwaysAuthenticate::setDefault()
1872 {
1873         OSAttribute attr(false);
1874         return osobject->setAttribute(type, attr);
1875 }
1876
1877 // Update the value if allowed
1878 CK_RV P11AttrAlwaysAuthenticate::updateAttr(Token* /*token*/, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
1879 {
1880         OSAttribute attrTrue(true);
1881         OSAttribute attrFalse(false);
1882
1883         // Attribute specific checks
1884
1885         if (ulValueLen !=sizeof(CK_BBOOL))
1886         {
1887                 return CKR_ATTRIBUTE_VALUE_INVALID;
1888         }
1889
1890         // Store data
1891
1892         if (*(CK_BBOOL*)pValue == CK_FALSE)
1893         {
1894                 osobject->setAttribute(type, attrFalse);
1895         }
1896         else
1897         {
1898                 if (!isPrivate)
1899                 {
1900                         return CKR_TEMPLATE_INCONSISTENT;
1901                 }
1902
1903                 osobject->setAttribute(type, attrTrue);
1904         }
1905
1906         return CKR_OK;
1907 }
1908
1909 /*****************************************
1910  * CKA_MODULUS
1911  *****************************************/
1912
1913 // Set default value
1914 bool P11AttrModulus::setDefault()
1915 {
1916         OSAttribute attr(ByteString(""));
1917         return osobject->setAttribute(type, attr);
1918 }
1919
1920 // Update the value if allowed
1921 CK_RV P11AttrModulus::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
1922 {
1923         ByteString plaintext((unsigned char*)pValue, ulValueLen);
1924         ByteString value;
1925
1926         // Encrypt
1927
1928         if (isPrivate)
1929         {
1930                 if (!token->encrypt(plaintext, value))
1931                         return CKR_GENERAL_ERROR;
1932         }
1933         else
1934                 value = plaintext;
1935
1936         // Attribute specific checks
1937
1938         if (value.size() < ulValueLen)
1939                 return CKR_GENERAL_ERROR;
1940
1941         // Store data
1942
1943         osobject->setAttribute(type, value);
1944
1945         // Set the CKA_MODULUS_BITS during C_CreateObject
1946
1947         if (op == OBJECT_OP_CREATE && osobject->attributeExists(CKA_MODULUS_BITS))
1948         {
1949                 OSAttribute bits((unsigned long)plaintext.bits());
1950                 osobject->setAttribute(CKA_MODULUS_BITS, bits);
1951         }
1952
1953         return CKR_OK;
1954 }
1955
1956 /*****************************************
1957  * CKA_PUBLIC_EXPONENT
1958  *****************************************/
1959
1960 // Set default value
1961 bool P11AttrPublicExponent::setDefault()
1962 {
1963         OSAttribute attr(ByteString(""));
1964         return osobject->setAttribute(type, attr);
1965 }
1966
1967 /*****************************************
1968  * CKA_PRIVATE_EXPONENT
1969  *****************************************/
1970
1971 // Set default value
1972 bool P11AttrPrivateExponent::setDefault()
1973 {
1974         OSAttribute attr(ByteString(""));
1975         return osobject->setAttribute(type, attr);
1976 }
1977
1978 /*****************************************
1979  * CKA_PRIME_1
1980  *****************************************/
1981
1982 // Set default value
1983 bool P11AttrPrime1::setDefault()
1984 {
1985         OSAttribute attr(ByteString(""));
1986         return osobject->setAttribute(type, attr);
1987 }
1988
1989 /*****************************************
1990  * CKA_PRIME_2
1991  *****************************************/
1992
1993 // Set default value
1994 bool P11AttrPrime2::setDefault()
1995 {
1996         OSAttribute attr(ByteString(""));
1997         return osobject->setAttribute(type, attr);
1998 }
1999
2000 /*****************************************
2001  * CKA_EXPONENT_1
2002  *****************************************/
2003
2004 // Set default value
2005 bool P11AttrExponent1::setDefault()
2006 {
2007         OSAttribute attr(ByteString(""));
2008         return osobject->setAttribute(type, attr);
2009 }
2010
2011 /*****************************************
2012  * CKA_EXPONENT_2
2013  *****************************************/
2014
2015 // Set default value
2016 bool P11AttrExponent2::setDefault()
2017 {
2018         OSAttribute attr(ByteString(""));
2019         return osobject->setAttribute(type, attr);
2020 }
2021
2022 /*****************************************
2023  * CKA_COEFFICIENT
2024  *****************************************/
2025
2026 // Set default value
2027 bool P11AttrCoefficient::setDefault()
2028 {
2029         OSAttribute attr(ByteString(""));
2030         return osobject->setAttribute(type, attr);
2031 }
2032
2033 /*****************************************
2034  * CKA_MODULUS_BITS
2035  *****************************************/
2036
2037 // Set default value
2038 bool P11AttrModulusBits::setDefault()
2039 {
2040         OSAttribute attr((unsigned long)0);
2041         return osobject->setAttribute(type, attr);
2042 }
2043
2044 // Update the value if allowed
2045 CK_RV P11AttrModulusBits::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
2046 {
2047         // Attribute specific checks
2048
2049         if (op != OBJECT_OP_GENERATE)
2050         {
2051                 return CKR_ATTRIBUTE_READ_ONLY;
2052         }
2053
2054         if (ulValueLen !=sizeof(CK_ULONG))
2055         {
2056                 return CKR_ATTRIBUTE_VALUE_INVALID;
2057         }
2058
2059         // Store data
2060
2061         osobject->setAttribute(type, *(CK_ULONG*)pValue);
2062
2063         return CKR_OK;
2064 }
2065
2066 /*****************************************
2067  * CKA_PRIME
2068  *****************************************/
2069
2070 // Set default value
2071 bool P11AttrPrime::setDefault()
2072 {
2073         OSAttribute attr(ByteString(""));
2074         return osobject->setAttribute(type, attr);
2075 }
2076
2077 // Update the value if allowed
2078 CK_RV P11AttrPrime::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
2079 {
2080         ByteString plaintext((unsigned char*)pValue, ulValueLen);
2081         ByteString value;
2082
2083         // Encrypt
2084
2085         if (isPrivate)
2086         {
2087                 if (!token->encrypt(plaintext, value))
2088                         return CKR_GENERAL_ERROR;
2089         }
2090         else
2091                 value = plaintext;
2092
2093         // Attribute specific checks
2094
2095         if (value.size() < ulValueLen)
2096                 return CKR_GENERAL_ERROR;
2097
2098         // Store data
2099
2100         osobject->setAttribute(type, value);
2101
2102         // Set the CKA_PRIME_BITS during C_CreateObject
2103
2104         if (op == OBJECT_OP_CREATE && osobject->attributeExists(CKA_PRIME_BITS))
2105         {
2106                 OSAttribute bits((unsigned long)plaintext.bits());
2107                 osobject->setAttribute(CKA_PRIME_BITS, bits);
2108         }
2109
2110         return CKR_OK;
2111 }
2112
2113 /*****************************************
2114  * CKA_SUBPRIME
2115  *****************************************/
2116
2117 // Set default value
2118 bool P11AttrSubPrime::setDefault()
2119 {
2120         OSAttribute attr(ByteString(""));
2121         return osobject->setAttribute(type, attr);
2122 }
2123
2124 /*****************************************
2125  * CKA_BASE
2126  *****************************************/
2127
2128 // Set default value
2129 bool P11AttrBase::setDefault()
2130 {
2131         OSAttribute attr(ByteString(""));
2132         return osobject->setAttribute(type, attr);
2133 }
2134
2135 /*****************************************
2136  * CKA_PRIME_BITS
2137  *****************************************/
2138
2139 // Set default value
2140 bool P11AttrPrimeBits::setDefault()
2141 {
2142         OSAttribute attr((unsigned long)0);
2143         return osobject->setAttribute(type, attr);
2144 }
2145
2146 // Update the value if allowed
2147 CK_RV P11AttrPrimeBits::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
2148 {
2149         // Attribute specific checks
2150
2151         if (op != OBJECT_OP_GENERATE)
2152         {
2153                 return CKR_ATTRIBUTE_READ_ONLY;
2154         }
2155
2156         if (ulValueLen != sizeof(CK_ULONG))
2157         {
2158                 return CKR_ATTRIBUTE_VALUE_INVALID;
2159         }
2160
2161         // Store data
2162
2163         osobject->setAttribute(type, *(CK_ULONG*)pValue);
2164
2165         return CKR_OK;
2166 }
2167
2168 /*****************************************
2169  * CKA_VALUE_BITS
2170  *****************************************/
2171
2172 // Set default value
2173 bool P11AttrValueBits::setDefault()
2174 {
2175         OSAttribute attr((unsigned long)0);
2176         return osobject->setAttribute(type, attr);
2177 }
2178
2179 // Update the value if allowed
2180 CK_RV P11AttrValueBits::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
2181 {
2182         // Attribute specific checks
2183
2184         if (op != OBJECT_OP_GENERATE)
2185         {
2186                 return CKR_ATTRIBUTE_READ_ONLY;
2187         }
2188
2189         if (ulValueLen != sizeof(CK_ULONG))
2190         {
2191                 return CKR_ATTRIBUTE_VALUE_INVALID;
2192         }
2193
2194         // Store data
2195
2196         osobject->setAttribute(type, *(CK_ULONG*)pValue);
2197
2198         return CKR_OK;
2199 }
2200
2201 /*****************************************
2202  * CKA_EC_PARAMS
2203  *****************************************/
2204
2205 // Set default value
2206 bool P11AttrEcParams::setDefault()
2207 {
2208         OSAttribute attr(ByteString(""));
2209         return osobject->setAttribute(type, attr);
2210 }
2211
2212 /*****************************************
2213  * CKA_EC_POINT
2214  *****************************************/
2215
2216 // Set default value
2217 bool P11AttrEcPoint::setDefault()
2218 {
2219         OSAttribute attr(ByteString(""));
2220         return osobject->setAttribute(type, attr);
2221 }
2222
2223 /*****************************************
2224  * CKA_GOSTR3410_PARAMS
2225  *****************************************/
2226
2227 // Set default value
2228 bool P11AttrGostR3410Params::setDefault()
2229 {
2230         OSAttribute attr(ByteString(""));
2231         return osobject->setAttribute(type, attr);
2232 }
2233
2234 /*****************************************
2235  * CKA_GOSTR3411_PARAMS
2236  *****************************************/
2237
2238 // Set default value
2239 bool P11AttrGostR3411Params::setDefault()
2240 {
2241         OSAttribute attr(ByteString(""));
2242         return osobject->setAttribute(type, attr);
2243 }
2244
2245 /*****************************************
2246  * CKA_GOST28147_PARAMS
2247  *****************************************/
2248
2249 // Set default value
2250 bool P11AttrGost28147Params::setDefault()
2251 {
2252         OSAttribute attr(ByteString(""));
2253         return osobject->setAttribute(type, attr);
2254 }
2255
2256 /*****************************************
2257  * CKA_VALUE_LEN
2258  *****************************************/
2259
2260 // Set default value
2261 bool P11AttrValueLen::setDefault()
2262 {
2263         OSAttribute attr((unsigned long)0);
2264         return osobject->setAttribute(type, attr);
2265 }
2266
2267 // Update the value if allowed
2268 CK_RV P11AttrValueLen::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
2269 {
2270         // Attribute specific checks
2271
2272         if (op != OBJECT_OP_GENERATE && op != OBJECT_OP_DERIVE)
2273         {
2274                 return CKR_ATTRIBUTE_READ_ONLY;
2275         }
2276
2277         if (ulValueLen != sizeof(CK_ULONG))
2278         {
2279                 return CKR_ATTRIBUTE_VALUE_INVALID;
2280         }
2281
2282         // Store data
2283
2284         osobject->setAttribute(type, *(CK_ULONG*)pValue);
2285
2286         return CKR_OK;
2287 }
2288
2289 /*****************************************
2290  * CKA_WRAP_TEMPLATE
2291  *****************************************/
2292
2293 // Set default value
2294 bool P11AttrWrapTemplate::setDefault()
2295 {
2296         std::map<CK_ATTRIBUTE_TYPE,OSAttribute> empty;
2297         OSAttribute attr(empty);
2298         return osobject->setAttribute(type, attr);
2299 }
2300
2301 // Update the value
2302 CK_RV P11AttrWrapTemplate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
2303 {
2304         // Attribute specific checks
2305         if ((ulValueLen % sizeof(CK_ATTRIBUTE)) != 0)
2306         {
2307                 return CKR_ATTRIBUTE_VALUE_INVALID;
2308         }
2309
2310         // Fill the template vector with elements
2311         CK_ATTRIBUTE_PTR attr = (CK_ATTRIBUTE_PTR) pValue;
2312         std::map<CK_ATTRIBUTE_TYPE,OSAttribute> data;
2313         for (size_t i = 0; i < ulValueLen / sizeof(CK_ATTRIBUTE); ++i, ++attr)
2314         // Specialization for known attributes
2315         switch (attr->type)
2316         {
2317         case CKA_TOKEN:
2318         case CKA_PRIVATE:
2319         case CKA_MODIFIABLE:
2320         case CKA_COPYABLE:
2321         case CKA_TRUSTED:
2322         case CKA_ENCRYPT:
2323         case CKA_DECRYPT:
2324         case CKA_SIGN:
2325         case CKA_SIGN_RECOVER:
2326         case CKA_VERIFY:
2327         case CKA_VERIFY_RECOVER:
2328         case CKA_WRAP:
2329         case CKA_UNWRAP:
2330         case CKA_DERIVE:
2331         case CKA_LOCAL:
2332         case CKA_ALWAYS_SENSITIVE:
2333         case CKA_SENSITIVE:
2334         case CKA_NEVER_EXTRACTABLE:
2335         case CKA_EXTRACTABLE:
2336         case CKA_WRAP_WITH_TRUSTED:
2337         case CKA_SECONDARY_AUTH:
2338         case CKA_ALWAYS_AUTHENTICATE:
2339                 {
2340                         // CK_BBOOL
2341                         if (attr->ulValueLen != sizeof(CK_BBOOL))
2342                                 return CKR_ATTRIBUTE_VALUE_INVALID;
2343                         bool elem = (*(CK_BBOOL*)attr->pValue != CK_FALSE);
2344                         data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
2345                 }
2346                 break;
2347
2348         case CKA_CLASS:
2349         case CKA_KEY_TYPE:
2350         case CKA_CERTIFICATE_TYPE:
2351         case CKA_CERTIFICATE_CATEGORY:
2352         case CKA_JAVA_MIDP_SECURITY_DOMAIN:
2353         case CKA_NAME_HASH_ALGORITHM:
2354         case CKA_KEY_GEN_MECHANISM:
2355         case CKA_MODULUS_BITS:
2356         case CKA_PRIME_BITS:
2357         case CKA_SUBPRIME_BITS:
2358         case CKA_VALUE_BITS:
2359         case CKA_VALUE_LEN:
2360         case CKA_AUTH_PIN_FLAGS:
2361                 {
2362                         // CK_ULONG
2363                         if (attr->ulValueLen != sizeof(CK_ULONG))
2364                                 return CKR_ATTRIBUTE_VALUE_INVALID;
2365                         unsigned long elem = *(CK_ULONG*)attr->pValue;
2366                         data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
2367                 }
2368                 break;
2369
2370         case CKA_WRAP_TEMPLATE:
2371         case CKA_UNWRAP_TEMPLATE:
2372                 return CKR_ATTRIBUTE_VALUE_INVALID;
2373
2374         default:
2375                 {
2376                         // CK_BYTE
2377                         ByteString elem = ByteString((unsigned char*)attr->pValue, attr->ulValueLen);
2378                         data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
2379                 }
2380         }
2381
2382         // Store data
2383         osobject->setAttribute(type, data);
2384
2385         return CKR_OK;
2386 }
2387
2388 /*****************************************
2389  * CKA_UNWRAP_TEMPLATE
2390  *****************************************/
2391
2392 // Set default value
2393 bool P11AttrUnwrapTemplate::setDefault()
2394 {
2395         std::map<CK_ATTRIBUTE_TYPE,OSAttribute> empty;
2396         OSAttribute attr(empty);
2397         return osobject->setAttribute(type, attr);
2398 }
2399
2400 // Update the value
2401 CK_RV P11AttrUnwrapTemplate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
2402 {
2403         // Attribute specific checks
2404         if ((ulValueLen % sizeof(CK_ATTRIBUTE)) != 0)
2405         {
2406                 return CKR_ATTRIBUTE_VALUE_INVALID;
2407         }
2408
2409         // Fill the template vector with elements
2410         CK_ATTRIBUTE_PTR attr = (CK_ATTRIBUTE_PTR) pValue;
2411         std::map<CK_ATTRIBUTE_TYPE,OSAttribute> data;
2412         for (size_t i = 0; i < ulValueLen / sizeof(CK_ATTRIBUTE); ++i, ++attr)
2413         // Specialization for known attributes
2414         switch (attr->type)
2415         {
2416         case CKA_TOKEN:
2417         case CKA_PRIVATE:
2418         case CKA_MODIFIABLE:
2419         case CKA_COPYABLE:
2420         case CKA_TRUSTED:
2421         case CKA_ENCRYPT:
2422         case CKA_DECRYPT:
2423         case CKA_SIGN:
2424         case CKA_SIGN_RECOVER:
2425         case CKA_VERIFY:
2426         case CKA_VERIFY_RECOVER:
2427         case CKA_WRAP:
2428         case CKA_UNWRAP:
2429         case CKA_DERIVE:
2430         case CKA_LOCAL:
2431         case CKA_ALWAYS_SENSITIVE:
2432         case CKA_SENSITIVE:
2433         case CKA_NEVER_EXTRACTABLE:
2434         case CKA_EXTRACTABLE:
2435         case CKA_WRAP_WITH_TRUSTED:
2436         case CKA_SECONDARY_AUTH:
2437         case CKA_ALWAYS_AUTHENTICATE:
2438                 {
2439                         // CK_BBOOL
2440                         if (attr->ulValueLen != sizeof(CK_BBOOL))
2441                                 return CKR_ATTRIBUTE_VALUE_INVALID;
2442                         bool elem = (*(CK_BBOOL*)attr->pValue != CK_FALSE);
2443                         data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
2444                 }
2445                 break;
2446
2447         case CKA_CLASS:
2448         case CKA_KEY_TYPE:
2449         case CKA_CERTIFICATE_TYPE:
2450         case CKA_CERTIFICATE_CATEGORY:
2451         case CKA_JAVA_MIDP_SECURITY_DOMAIN:
2452         case CKA_NAME_HASH_ALGORITHM:
2453         case CKA_KEY_GEN_MECHANISM:
2454         case CKA_MODULUS_BITS:
2455         case CKA_PRIME_BITS:
2456         case CKA_SUBPRIME_BITS:
2457         case CKA_VALUE_BITS:
2458         case CKA_VALUE_LEN:
2459         case CKA_AUTH_PIN_FLAGS:
2460                 {
2461                         // CK_ULONG
2462                         if (attr->ulValueLen != sizeof(CK_ULONG))
2463                                 return CKR_ATTRIBUTE_VALUE_INVALID;
2464                         unsigned long elem = *(CK_ULONG*)attr->pValue;
2465                         data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
2466                 }
2467                 break;
2468
2469         case CKA_WRAP_TEMPLATE:
2470         case CKA_UNWRAP_TEMPLATE:
2471                 return CKR_ATTRIBUTE_VALUE_INVALID;
2472
2473         default:
2474                 {
2475                         // CK_BYTE
2476                         ByteString elem = ByteString((unsigned char*)attr->pValue, attr->ulValueLen);
2477                         data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
2478                 }
2479         }
2480
2481         // Store data
2482         osobject->setAttribute(type, data);
2483
2484         return CKR_OK;
2485 }
2486
2487 /*****************************************
2488  * CKA_ALLOWED_MECHANISMS
2489  *****************************************/
2490
2491 // Set default value
2492 bool P11AttrAllowedMechanisms::setDefault()
2493 {
2494         std::set<CK_MECHANISM_TYPE> emptyMap;
2495         return osobject->setAttribute(type, OSAttribute(emptyMap));
2496 }
2497
2498 // Update the value if allowed
2499 CK_RV P11AttrAllowedMechanisms::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
2500 {
2501         if (ulValueLen == 0 || (ulValueLen % sizeof(CK_MECHANISM_TYPE)) != 0)
2502         {
2503                 return CKR_ATTRIBUTE_VALUE_INVALID;
2504         }
2505
2506         CK_MECHANISM_TYPE_PTR mechType = (CK_MECHANISM_TYPE_PTR) pValue;
2507
2508         // Fill the set with values
2509         std::set<CK_MECHANISM_TYPE> data;
2510         for (size_t i = 0; i < ulValueLen / sizeof(CK_MECHANISM_TYPE); ++i, ++mechType)
2511         {
2512                 data.insert(*mechType);
2513         }
2514
2515         // Store data
2516         osobject->setAttribute(type, OSAttribute(data));
2517         return CKR_OK;
2518 }
2519
2520
2521 // Set default value
2522 bool P11AttrPrivateHandle::setDefault()
2523 {
2524         OSAttribute attr((CK_ULONG)0);
2525         return osobject->setAttribute(type, attr);
2526 }
2527
2528 // Update the value if allowed
2529 CK_RV P11AttrPrivateHandle::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
2530 {
2531         // Attribute specific checks
2532         if (op != OBJECT_OP_CREATE)
2533         {
2534                 return CKR_ATTRIBUTE_READ_ONLY;
2535         }
2536
2537         if (ulValueLen !=sizeof(CK_ULONG))
2538         {
2539                 return CKR_ATTRIBUTE_VALUE_INVALID;
2540         }
2541
2542         // Store data
2543         osobject->setAttribute(type, *((CK_ULONG*)pValue));
2544
2545         return CKR_OK;
2546 }
2547
2548