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