aboutsummaryrefslogtreecommitdiffstats
path: root/SoftHSMv2/src/lib/P11Attributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SoftHSMv2/src/lib/P11Attributes.cpp')
-rw-r--r--SoftHSMv2/src/lib/P11Attributes.cpp2514
1 files changed, 2514 insertions, 0 deletions
diff --git a/SoftHSMv2/src/lib/P11Attributes.cpp b/SoftHSMv2/src/lib/P11Attributes.cpp
new file mode 100644
index 0000000..28d0f9b
--- /dev/null
+++ b/SoftHSMv2/src/lib/P11Attributes.cpp
@@ -0,0 +1,2514 @@
+/*
+ * Copyright (c) 2011 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ P11Attributes.h
+
+ This file contains classes for controlling attributes
+ *****************************************************************************/
+
+#include "config.h"
+#include "P11Attributes.h"
+#include "ByteString.h"
+#include "CryptoFactory.h"
+#include "DESKey.h"
+#include "AESKey.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+// Constructor
+P11Attribute::P11Attribute(OSObject* inobject)
+{
+ osobject = inobject;
+ type = CKA_VENDOR_DEFINED;
+ size = (CK_ULONG)-1;
+ checks = 0;
+}
+
+// Destructor
+P11Attribute::~P11Attribute()
+{
+}
+
+CK_RV P11Attribute::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ ByteString value;
+ if (isPrivate)
+ {
+ if (!token->encrypt(ByteString((unsigned char*)pValue, ulValueLen),value))
+ return CKR_GENERAL_ERROR;
+ }
+ else
+ value = ByteString((unsigned char*)pValue, ulValueLen);
+ if (value.size() < ulValueLen)
+ return CKR_GENERAL_ERROR;
+ osobject->setAttribute(type, value);
+ return CKR_OK;
+}
+
+bool P11Attribute::isModifiable()
+{
+ // Get the CKA_MODIFIABLE attribute, when the attribute is
+ // not present return the default value which is CK_TRUE.
+ if (!osobject->attributeExists(CKA_MODIFIABLE)) return true;
+
+ return osobject->getBooleanValue(CKA_MODIFIABLE, true);
+}
+
+bool P11Attribute::isSensitive()
+{
+ // Get the CKA_SENSITIVE attribute, when the attribute is not present
+ // assume the object is not sensitive.
+ if (!osobject->attributeExists(CKA_SENSITIVE)) return false;
+
+ return osobject->getBooleanValue(CKA_SENSITIVE, false);
+}
+
+bool P11Attribute::isExtractable()
+{
+ // Get the CKA_EXTRACTABLE attribute, when the attribute is
+ // not present assume the object allows extraction.
+ if (!osobject->attributeExists(CKA_EXTRACTABLE)) return true;
+
+ return osobject->getBooleanValue(CKA_EXTRACTABLE, true);
+}
+
+bool P11Attribute::isTrusted()
+{
+ // Get the CKA_TRUSTED attribute, when the attribute is
+ // not present assume the object is not trusted.
+ if (!osobject->attributeExists(CKA_TRUSTED)) return false;
+
+ return osobject->getBooleanValue(CKA_TRUSTED, false);
+}
+
+// Initialize the attribute
+bool P11Attribute::init()
+{
+ if (osobject == NULL) return false;
+
+ // Create a default value if the attribute does not exist
+ if (osobject->attributeExists(type) == false)
+ {
+ return setDefault();
+ }
+
+ return true;
+}
+
+// Return the attribute type
+CK_ATTRIBUTE_TYPE P11Attribute::getType()
+{
+ return type;
+}
+
+// Return the attribute checks
+CK_ATTRIBUTE_TYPE P11Attribute::getChecks()
+{
+ return checks;
+}
+
+// Retrieve a template map
+static CK_RV retrieveAttributeMap(CK_ATTRIBUTE_PTR pTemplate, const std::map<CK_ATTRIBUTE_TYPE,OSAttribute>& map)
+{
+ size_t nullcnt = 0;
+
+ for (size_t i = 0; i < map.size(); ++i)
+ {
+ if (pTemplate[i].pValue == NULL_PTR)
+ ++nullcnt;
+ }
+
+ // Caller wants type & size
+ if (nullcnt == map.size())
+ {
+ std::map<CK_ATTRIBUTE_TYPE,OSAttribute>::const_iterator a = map.begin();
+ for (size_t i = 0; i < map.size(); ++i, ++a)
+ {
+ pTemplate[i].type = a->first;
+ const OSAttribute& attr = a->second;
+ if (attr.isBooleanAttribute())
+ {
+ pTemplate[i].ulValueLen = sizeof(CK_BBOOL);
+ }
+ else if (attr.isUnsignedLongAttribute())
+ {
+ pTemplate[i].ulValueLen = sizeof(CK_ULONG);
+ }
+ else if (attr.isByteStringAttribute())
+ {
+ pTemplate[i].ulValueLen = attr.getByteStringValue().size();
+ }
+ else
+ {
+ // Impossible
+ ERROR_MSG("Internal error: bad attribute in attribute map");
+
+ return CKR_GENERAL_ERROR;
+ }
+ }
+
+ return CKR_OK;
+ }
+
+ // Callers wants to get values
+ for (size_t i = 0; i < map.size(); ++i)
+ {
+ std::map<CK_ATTRIBUTE_TYPE,OSAttribute>::const_iterator a = map.find(pTemplate[i].type);
+ if (a == map.end())
+ {
+ pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ }
+ const OSAttribute& attr = a->second;
+ if (attr.isBooleanAttribute())
+ {
+ if (pTemplate[i].ulValueLen < sizeof(CK_BBOOL))
+ {
+ pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = sizeof(CK_BBOOL);
+ *(CK_BBOOL*)pTemplate[i].pValue = attr.getBooleanValue() ? CK_TRUE : CK_FALSE;
+ }
+ else if (attr.isUnsignedLongAttribute())
+ {
+ if (pTemplate[i].ulValueLen < sizeof(CK_ULONG))
+ {
+ pTemplate[i].ulValueLen= CK_UNAVAILABLE_INFORMATION;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = sizeof(CK_ULONG);
+ *(CK_ULONG_PTR)pTemplate[i].pValue= attr.getUnsignedLongValue();
+ }
+ else if (attr.isByteStringAttribute())
+ {
+ ByteString value = attr.getByteStringValue();
+ if (pTemplate[i].ulValueLen < value.size())
+ {
+ pTemplate[i].ulValueLen= CK_UNAVAILABLE_INFORMATION;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ pTemplate[i].ulValueLen = value.size();
+ memcpy(pTemplate[i].pValue, value.const_byte_str(), value.size());
+ }
+ else
+ {
+ // Impossible
+ ERROR_MSG("Internal error: bad attribute in attribute map");
+
+ return CKR_GENERAL_ERROR;
+ }
+ }
+
+ return CKR_OK;
+}
+
+// Retrieve the value if allowed
+CK_RV P11Attribute::retrieve(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG_PTR pulValueLen)
+{
+
+ if (osobject == NULL) {
+ ERROR_MSG("Internal error: osobject field contains NULL_PTR");
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (pulValueLen == NULL) {
+ ERROR_MSG("Internal error: pulValueLen contains NULL_PTR");
+ return CKR_GENERAL_ERROR;
+ }
+
+ // [PKCS#11 v2.40, C_GetAttributeValue]
+ // 1. If the specified attribute (i.e., the attribute specified by the
+ // type field) for the object cannot be revealed because the object
+ // is sensitive or unextractable, then the ulValueLen field in that
+ // triple is modified to hold the value CK_UNAVAILABLE_INFORMATION.
+ //
+ // [PKCS#11 v2.40, 4.2 Common attributes, table 10]
+ // 7 Cannot be revealed if object has its CKA_SENSITIVE attribute
+ // set to CK_TRUE or its CKA_EXTRACTABLE attribute set to CK_FALSE.
+ if ((checks & ck7) == ck7 && (isSensitive() || !isExtractable())) {
+ *pulValueLen = CK_UNAVAILABLE_INFORMATION;
+ return CKR_ATTRIBUTE_SENSITIVE;
+ }
+
+ // Retrieve the lower level attribute.
+ if (!osobject->attributeExists(type)) {
+ // Should be impossible.
+ ERROR_MSG("Internal error: attribute not present");
+ return CKR_GENERAL_ERROR;
+ }
+ OSAttribute attr = osobject->getAttribute(type);
+
+ // Get the actual attribute size.
+ CK_ULONG attrSize = size;
+ if (size == (CK_ULONG)-1)
+ {
+ // We don't have a fixed size attribute so we need to consult
+ // the lower level attribute for the exact size.
+
+ // Lower level attribute has to be variable sized.
+ if (attr.isByteStringAttribute())
+ {
+ if (isPrivate && attr.getByteStringValue().size() != 0)
+ {
+ ByteString value;
+ if (!token->decrypt(attr.getByteStringValue(),value))
+ {
+ ERROR_MSG("Internal error: failed to decrypt private attribute value");
+ return CKR_GENERAL_ERROR;
+ }
+ attrSize = value.size();
+ }
+ else
+ attrSize = attr.getByteStringValue().size();
+ }
+ else if (attr.isMechanismTypeSetAttribute())
+ {
+ attrSize = attr.getMechanismTypeSetValue().size() * sizeof(CK_MECHANISM_TYPE);
+ }
+ else if (attr.isAttributeMapAttribute())
+ {
+ attrSize = attr.getAttributeMapValue().size() * sizeof(CK_ATTRIBUTE);
+ }
+ else
+ {
+ // Should be impossible.
+ ERROR_MSG("Internal error: attribute has fixed size");
+ return CKR_GENERAL_ERROR;
+ }
+ }
+
+ // [PKCS#11 v2.40, C_GetAttributeValue]
+ // 3. Otherwise, if the pValue field has the value NULL_PTR, then the
+ // ulValueLen field is modified to hold the exact length of the
+ // specified attribute for the object.
+ if (pValue == NULL_PTR) {
+ // Return the size of the attribute.
+ *pulValueLen = attrSize;
+ return CKR_OK;
+ }
+
+ // [PKCS#11 v2.40, C_GetAttributeValue]
+ // 4. Otherwise, if the length specified in ulValueLen is large enough
+ // to hold the value of the specified attribute for the object, then
+ // that attribute is copied into the buffer located at pValue, and
+ // the ulValueLen field is modified to hold the exact length of the
+ // attribute.
+ if (*pulValueLen >= attrSize)
+ {
+ // Only copy when there is actually something to copy
+ CK_RV rv = CKR_OK;
+
+ if (attr.isUnsignedLongAttribute()) {
+ *(CK_ULONG_PTR)pValue = attr.getUnsignedLongValue();
+ }
+ else if (attr.isBooleanAttribute())
+ {
+ *(CK_BBOOL*)pValue = attr.getBooleanValue() ? CK_TRUE : CK_FALSE;
+ }
+ else if (attr.isByteStringAttribute())
+ {
+ if (isPrivate && attr.getByteStringValue().size() != 0)
+ {
+ ByteString value;
+ if (!token->decrypt(attr.getByteStringValue(),value))
+ {
+ ERROR_MSG("Internal error: failed to decrypt private attribute value");
+ return CKR_GENERAL_ERROR;
+ }
+ const unsigned char* attrPtr = value.const_byte_str();
+ memcpy(pValue,attrPtr,attrSize);
+ }
+ else if (attr.getByteStringValue().size() != 0)
+ {
+ const unsigned char* attrPtr = attr.getByteStringValue().const_byte_str();
+ memcpy(pValue,attrPtr,attrSize);
+ }
+ }
+ else if (attr.isMechanismTypeSetAttribute())
+ {
+ CK_MECHANISM_TYPE_PTR pTemplate = (CK_MECHANISM_TYPE_PTR) pValue;
+ size_t i = 0;
+
+ std::set<CK_MECHANISM_TYPE> set = attr.getMechanismTypeSetValue();
+ for (std::set<CK_MECHANISM_TYPE>::const_iterator it = set.begin(); it != set.end(); ++it)
+ pTemplate[++i] = *it;
+ }
+ else
+ {
+ // attr is already retrieved and verified to be an Attribute Map
+ rv = retrieveAttributeMap((CK_ATTRIBUTE_PTR)pValue, attr.getAttributeMapValue());
+ }
+ *pulValueLen = attrSize;
+ return rv;
+ }
+
+ // [PKCS#11 v2.40, C_GetAttributeValue]
+ // 5. Otherwise, the ulValueLen field is modified to hold the value CK_UNAVAILABLE_INFORMATION.
+ *pulValueLen = CK_UNAVAILABLE_INFORMATION;
+ return CKR_BUFFER_TOO_SMALL;
+}
+
+// Update the value if allowed
+CK_RV P11Attribute::update(Token* token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ if (osobject == NULL) {
+ ERROR_MSG("Internal error: osobject field contains NULL_PTR");
+ return CKR_GENERAL_ERROR;
+ }
+
+ // [PKCS#11 v2.40, 4.1.1 Creating objects]
+ // 2. If the supplied template specifies an invalid value for a valid attribute, then the
+ // attempt should fail with the error code CKR_ATTRIBUTE_VALUE_INVALID.
+ // The valid values for Cryptoki attributes are described in the Cryptoki specification.
+
+ // Check for null pointers in values.
+ if (pValue == NULL_PTR && ulValueLen != 0) {
+ ERROR_MSG("The attribute is a NULL_PTR but has a non-zero length")
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // For fixed sized attributes check that the size matches.
+ if (size != ((CK_ULONG)-1) && size != ulValueLen) {
+ ERROR_MSG("The attribute size is different from the expected size")
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // [PKCS#11 v2.40, 4.1.1 Creating objects] OBJECT_OP_CREATE | OBJECT_OP_SET | OBJECT_OP_COPY
+ // 3. If the supplied template specifies a value for a read-only attribute, then the attempt
+ // should fail with the error code CKR_ATTRIBUTE_READ_ONLY.
+ // Whether or not a given Cryptoki attribute is read-only is explicitly stated in the Cryptoki
+ // specification; however, a particular library and token may be even more restrictive than
+ // Cryptoki specifies. In other words, an attribute which Cryptoki says is not read-only may
+ // nonetheless be read-only under certain circumstances (i.e., in conjunction with some
+ // combinations of other attributes) for a particular library and token. Whether or not a
+ // given non-Cryptoki attribute is read-only is obviously outside the scope of Cryptoki.
+
+ // Attributes cannot be changed if CKA_MODIFIABLE is set to false
+ if (!isModifiable() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE) {
+ ERROR_MSG("An object is with CKA_MODIFIABLE set to false is not modifiable");
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ // Attributes cannot be modified if CKA_TRUSTED is true on a certificate object.
+ if (isTrusted() && op != OBJECT_OP_GENERATE && op != OBJECT_OP_CREATE) {
+ if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_CERTIFICATE)
+ {
+ ERROR_MSG("A trusted certificate cannot be modified");
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ // ck2 MUST not be specified when object is created with C_CreateObject.
+ if ((checks & ck2) == ck2)
+ {
+ if (OBJECT_OP_CREATE==op)
+ {
+ ERROR_MSG("Prohibited attribute was passed to object creation function");
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ // ck4 MUST not be specified when object is generated with C_GenerateKey or C_GenerateKeyPair.
+ if ((checks & ck4) == ck4)
+ {
+ if (OBJECT_OP_GENERATE==op)
+ {
+ ERROR_MSG("Prohibited attribute was passed to key generation function");
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ // ck6 MUST not be specified when object is unwrapped with C_UnwrapKey.
+ if ((checks & ck6) == ck6)
+ {
+ if (OBJECT_OP_UNWRAP==op)
+ {
+ ERROR_MSG("Prohibited attribute was passed to key unwrapping function");
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ // ck8 May be modified after object is created with a C_SetAttributeValue call
+ // or in the process of copying an object with a C_CopyObject call.
+ // However, it is possible that a particular token may not permit modification of
+ // the attribute during the course of a C_CopyObject call.
+ if ((checks & ck8) == ck8)
+ {
+ if (OBJECT_OP_SET==op || OBJECT_OP_COPY==op)
+ {
+ return updateAttr(token, isPrivate, pValue, ulValueLen, op);
+ }
+ }
+
+ // ck17 Can be changed in the process of copying the object using C_CopyObject.
+ if ((checks & ck17) == ck17)
+ {
+ if (OBJECT_OP_COPY==op)
+ {
+ return updateAttr(token, isPrivate, pValue, ulValueLen, op);
+ }
+ }
+
+ // For attributes that have not been explicitly excluded from modification
+ // during create/derive/generate/unwrap, we allow them to be modified.
+ if (OBJECT_OP_CREATE==op || OBJECT_OP_DERIVE==op || OBJECT_OP_GENERATE==op || OBJECT_OP_UNWRAP==op)
+ {
+ return updateAttr(token, isPrivate, pValue, ulValueLen, op);
+ }
+
+ return CKR_ATTRIBUTE_READ_ONLY;
+}
+
+/*****************************************
+ * CKA_CLASS
+ *****************************************/
+
+// Set default value
+bool P11AttrClass::setDefault()
+{
+ OSAttribute attrClass((unsigned long)CKO_VENDOR_DEFINED);
+ return osobject->setAttribute(type, attrClass);
+}
+
+// Update the value if allowed
+CK_RV P11AttrClass::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != *(CK_ULONG*)pValue)
+ {
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_KEY_TYPE
+ *****************************************/
+
+// Set default value
+bool P11AttrKeyType::setDefault()
+{
+ OSAttribute attr((unsigned long)CKK_VENDOR_DEFINED);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrKeyType::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ if (osobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != *(CK_ULONG*)pValue)
+ {
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_CERTIFICATE_TYPE
+ * footnote 1
+ * 1 MUST be specified when object is created with C_CreateObject.
+ *****************************************/
+
+// Set default value
+bool P11AttrCertificateType::setDefault()
+{
+ OSAttribute attr((unsigned long)CKC_VENDOR_DEFINED);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrCertificateType::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ if (osobject->getUnsignedLongValue(CKA_CERTIFICATE_TYPE, CKC_VENDOR_DEFINED) != *(CK_ULONG*)pValue)
+ {
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_TOKEN
+ *****************************************/
+
+// Set default value
+bool P11AttrToken::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrToken::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_PRIVATE
+ *****************************************/
+
+// Set default value
+bool P11AttrPrivate::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrPrivate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_MODIFIABLE
+ *****************************************/
+
+// Set default value
+bool P11AttrModifiable::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrModifiable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_LABEL
+ *****************************************/
+
+// Set default value
+bool P11AttrLabel::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_COPYABLE
+ *****************************************/
+
+// Set default value
+bool P11AttrCopyable::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrCopyable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ if (osobject->getBooleanValue(CKA_COPYABLE, true) == false)
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_DESTROYABLE
+ *****************************************/
+
+// Set default value
+bool P11AttrDestroyable::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrDestroyable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_APPLICATION
+ *****************************************/
+
+// Set default value
+bool P11AttrApplication::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_OBJECT_ID
+ *****************************************/
+
+// Set default value
+bool P11AttrObjectID::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_CHECK_VALUE
+ *****************************************/
+
+// Set default value
+bool P11AttrCheckValue::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrCheckValue::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ ByteString plaintext((unsigned char*)pValue, ulValueLen);
+ ByteString value;
+
+ // Encrypt
+
+ if (isPrivate)
+ {
+ if (!token->encrypt(plaintext, value))
+ return CKR_GENERAL_ERROR;
+ }
+ else
+ value = plaintext;
+
+ // Attribute specific checks
+
+ if (value.size() < ulValueLen)
+ return CKR_GENERAL_ERROR;
+
+ // Store data
+ if (ulValueLen == 0)
+ {
+ osobject->setAttribute(type, value);
+ }
+ else
+ {
+ ByteString checkValue;
+ ByteString keybits;
+ if (isPrivate)
+ {
+ if (!token->decrypt(osobject->getByteStringValue(CKA_VALUE), keybits))
+ return CKR_GENERAL_ERROR;
+ }
+ else
+ {
+ keybits = osobject->getByteStringValue(CKA_VALUE);
+ }
+
+ SymmetricKey key;
+ AESKey aes;
+ DESKey des;
+ switch (osobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED))
+ {
+ case CKK_GENERIC_SECRET:
+ case CKK_MD5_HMAC:
+ case CKK_SHA_1_HMAC:
+ case CKK_SHA224_HMAC:
+ case CKK_SHA256_HMAC:
+ case CKK_SHA384_HMAC:
+ case CKK_SHA512_HMAC:
+ key.setKeyBits(keybits);
+ key.setBitLen(keybits.size() * 8);
+ checkValue = key.getKeyCheckValue();
+ break;
+ case CKK_AES:
+ aes.setKeyBits(keybits);
+ aes.setBitLen(keybits.size() * 8);
+ checkValue = aes.getKeyCheckValue();
+ break;
+ case CKK_DES:
+ case CKK_DES2:
+ case CKK_DES3:
+ des.setKeyBits(keybits);
+ des.setBitLen(keybits.size() * 7);
+ checkValue = des.getKeyCheckValue();
+ break;
+ case CKK_GOST28147:
+ // TODO: Encryption support for CKK_GOST28147
+ // We do not calculate the KCV
+ checkValue = plaintext;
+ break;
+ default:
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (plaintext != checkValue)
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ osobject->setAttribute(type, value);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_PUBLIC_KEY_INFO
+ *****************************************/
+
+// Set default value
+bool P11AttrPublicKeyInfo::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_ID
+ *****************************************/
+
+// Set default value
+bool P11AttrID::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_VALUE
+ *****************************************/
+
+// Set default value
+bool P11AttrValue::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrValue::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ ByteString plaintext((unsigned char*)pValue, ulValueLen);
+ ByteString value;
+
+ // Encrypt
+
+ if (isPrivate)
+ {
+ if (!token->encrypt(plaintext, value))
+ return CKR_GENERAL_ERROR;
+ }
+ else
+ value = plaintext;
+
+ // Attribute specific checks
+
+ if (value.size() < ulValueLen)
+ return CKR_GENERAL_ERROR;
+
+ // Store data
+
+ osobject->setAttribute(type, value);
+
+ // Set the size during C_CreateObject and C_UnwrapKey.
+
+ if (op == OBJECT_OP_CREATE || op == OBJECT_OP_UNWRAP)
+ {
+ // Set the CKA_VALUE_LEN
+ if (osobject->attributeExists(CKA_VALUE_LEN))
+ {
+ OSAttribute bytes((unsigned long)plaintext.size());
+ osobject->setAttribute(CKA_VALUE_LEN, bytes);
+ }
+
+ // Set the CKA_VALUE_BITS
+ if (osobject->attributeExists(CKA_VALUE_BITS))
+ {
+ OSAttribute bits((unsigned long)plaintext.bits());
+ osobject->setAttribute(CKA_VALUE_BITS, bits);
+ }
+ }
+
+ // Calculate the CKA_CHECK_VALUE for certificates
+ if (osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_CERTIFICATE)
+ {
+ HashAlgorithm* hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA1);
+ if (hash == NULL) return CKR_GENERAL_ERROR;
+
+ ByteString digest;
+ if (hash->hashInit() == false ||
+ hash->hashUpdate(plaintext) == false ||
+ hash->hashFinal(digest) == false)
+ {
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ return CKR_GENERAL_ERROR;
+ }
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ // First three bytes of the SHA-1 hash
+ digest.resize(3);
+
+ if (isPrivate)
+ {
+ ByteString encrypted;
+ if (!token->encrypt(digest, encrypted))
+ return CKR_GENERAL_ERROR;
+ osobject->setAttribute(CKA_CHECK_VALUE, encrypted);
+ }
+ else
+ osobject->setAttribute(CKA_CHECK_VALUE, digest);
+ }
+
+ // Calculate the CKA_CHECK_VALUE for secret keys
+ if (op == OBJECT_OP_CREATE &&
+ osobject->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) == CKO_SECRET_KEY)
+ {
+ SymmetricKey key;
+ AESKey aes;
+ DESKey des;
+ ByteString checkValue;
+ switch (osobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED))
+ {
+ case CKK_GENERIC_SECRET:
+ case CKK_MD5_HMAC:
+ case CKK_SHA_1_HMAC:
+ case CKK_SHA224_HMAC:
+ case CKK_SHA256_HMAC:
+ case CKK_SHA384_HMAC:
+ case CKK_SHA512_HMAC:
+ key.setKeyBits(plaintext);
+ key.setBitLen(plaintext.size() * 8);
+ checkValue = key.getKeyCheckValue();
+ break;
+ case CKK_AES:
+ aes.setKeyBits(plaintext);
+ aes.setBitLen(plaintext.size() * 8);
+ checkValue = aes.getKeyCheckValue();
+ break;
+ case CKK_DES:
+ case CKK_DES2:
+ case CKK_DES3:
+ des.setKeyBits(plaintext);
+ des.setBitLen(plaintext.size() * 7);
+ checkValue = des.getKeyCheckValue();
+ break;
+ case CKK_GOST28147:
+ // TODO: Encryption support for CKK_GOST28147
+ // We do not calculate the KCV
+ break;
+ default:
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (isPrivate)
+ {
+ ByteString encrypted;
+ if (!token->encrypt(checkValue, encrypted))
+ return CKR_GENERAL_ERROR;
+ osobject->setAttribute(CKA_CHECK_VALUE, encrypted);
+ }
+ else
+ osobject->setAttribute(CKA_CHECK_VALUE, checkValue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_SUBJECT
+ *****************************************/
+
+// Set default value
+bool P11AttrSubject::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_ISSUER
+ *****************************************/
+
+// Set default value
+bool P11AttrIssuer::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_TRUSTED
+ *****************************************/
+
+// Set default value
+bool P11AttrTrusted::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrTrusted::updateAttr(Token *token, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ if (!token->isSOLoggedIn())
+ {
+ ERROR_MSG("CKA_TRUSTED can only be set to true by the SO");
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_CERTIFICATE_CATEGORY
+ *****************************************/
+
+// Set default value
+bool P11AttrCertificateCategory::setDefault()
+{
+ OSAttribute attr((unsigned long)0);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrCertificateCategory::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_START_DATE
+ *****************************************/
+
+// Set default value
+bool P11AttrStartDate::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrStartDate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_DATE) && ulValueLen !=0)
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+ osobject->setAttribute(type, ByteString((unsigned char*)pValue, ulValueLen));
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_END_DATE
+ *****************************************/
+
+// Set default value
+bool P11AttrEndDate::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrEndDate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_DATE) && ulValueLen !=0)
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+ osobject->setAttribute(type, ByteString((unsigned char*)pValue, ulValueLen));
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_SERIAL_NUMBER
+ *****************************************/
+
+// Set default value
+bool P11AttrSerialNumber::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_URL
+ *****************************************/
+
+// Set default value
+bool P11AttrURL::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_HASH_OF_SUBJECT_PUBLIC_KEY
+ *****************************************/
+
+// Set default value
+bool P11AttrHashOfSubjectPublicKey::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_HASH_OF_ISSUER_PUBLIC_KEY
+ *****************************************/
+
+// Set default value
+bool P11AttrHashOfIssuerPublicKey::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_JAVA_MIDP_SECURITY_DOMAIN
+ *****************************************/
+
+// Set default value
+bool P11AttrJavaMidpSecurityDomain::setDefault()
+{
+ OSAttribute attr((unsigned long)0);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrJavaMidpSecurityDomain::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_NAME_HASH_ALGORITHM
+ *****************************************/
+
+// Set default value
+bool P11AttrNameHashAlgorithm::setDefault()
+{
+ OSAttribute attr((unsigned long)CKM_SHA_1);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrNameHashAlgorithm::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_DERIVE
+ *****************************************/
+
+// Set default value
+bool P11AttrDerive::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrDerive::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_ENCRYPT
+ *****************************************/
+
+// Set default value
+bool P11AttrEncrypt::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrEncrypt::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_VERIFY
+ *****************************************/
+
+// Set default value
+bool P11AttrVerify::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrVerify::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_VERIFY_RECOVER
+ *****************************************/
+
+// Set default value
+bool P11AttrVerifyRecover::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrVerifyRecover::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_WRAP
+ *****************************************/
+
+// Set default value
+bool P11AttrWrap::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrWrap::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_DECRYPT
+ *****************************************/
+
+// Set default value
+bool P11AttrDecrypt::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrDecrypt::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_SIGN
+ *****************************************/
+
+// Set default value
+bool P11AttrSign::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrSign::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_SIGN_RECOVER
+ *****************************************/
+
+// Set default value
+bool P11AttrSignRecover::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrSignRecover::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_UNWRAP
+ *****************************************/
+
+// Set default value
+bool P11AttrUnwrap::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrUnwrap::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_LOCAL
+ *****************************************/
+
+// Set default value
+bool P11AttrLocal::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrLocal::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
+{
+ return CKR_ATTRIBUTE_READ_ONLY;
+}
+
+/*****************************************
+ * CKA_KEY_GEN_MECHANISM
+ *****************************************/
+
+// Set default value
+bool P11AttrKeyGenMechanism::setDefault()
+{
+ OSAttribute attr((unsigned long)CK_UNAVAILABLE_INFORMATION);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrKeyGenMechanism::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
+{
+ return CKR_ATTRIBUTE_READ_ONLY;
+}
+
+/*****************************************
+ * CKA_ALWAYS_SENSITIVE
+ *****************************************/
+
+// Set default value
+bool P11AttrAlwaysSensitive::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrAlwaysSensitive::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
+{
+ return CKR_ATTRIBUTE_READ_ONLY;
+}
+
+/*****************************************
+ * CKA_NEVER_EXTRACTABLE
+ *****************************************/
+
+// Set default value
+bool P11AttrNeverExtractable::setDefault()
+{
+ OSAttribute attr(true);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrNeverExtractable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR /*pValue*/, CK_ULONG /*ulValueLen*/, int /*op*/)
+{
+ return CKR_ATTRIBUTE_READ_ONLY;
+}
+
+/*****************************************
+ * CKA_SENSITIVE
+ *****************************************/
+
+// Set default value
+bool P11AttrSensitive::setDefault()
+{
+ // We default to false because we want to handle the secret keys in a correct way
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrSensitive::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (op == OBJECT_OP_SET || op == OBJECT_OP_COPY)
+ {
+ if (osobject->getBooleanValue(CKA_SENSITIVE, false))
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ osobject->setAttribute(CKA_ALWAYS_SENSITIVE, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+
+ // This is so that generated keys get the correct value
+ if (op == OBJECT_OP_GENERATE || op == OBJECT_OP_DERIVE)
+ {
+ osobject->setAttribute(CKA_ALWAYS_SENSITIVE, attrTrue);
+ }
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_EXTRACTABLE
+ *****************************************/
+
+// Set default value
+bool P11AttrExtractable::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrExtractable::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (op == OBJECT_OP_SET || op == OBJECT_OP_COPY)
+ {
+ if (osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false)
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ osobject->setAttribute(CKA_NEVER_EXTRACTABLE, attrFalse);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_WRAP_WITH_TRUSTED
+ *****************************************/
+
+// Set default value
+bool P11AttrWrapWithTrusted::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrWrapWithTrusted::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (op == OBJECT_OP_SET || op == OBJECT_OP_COPY)
+ {
+ if (osobject->getBooleanValue(CKA_WRAP_WITH_TRUSTED, false))
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+ }
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_ALWAYS_AUTHENTICATE
+ *****************************************/
+
+// Set default value
+bool P11AttrAlwaysAuthenticate::setDefault()
+{
+ OSAttribute attr(false);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrAlwaysAuthenticate::updateAttr(Token* /*token*/, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ OSAttribute attrTrue(true);
+ OSAttribute attrFalse(false);
+
+ // Attribute specific checks
+
+ if (ulValueLen !=sizeof(CK_BBOOL))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ if (*(CK_BBOOL*)pValue == CK_FALSE)
+ {
+ osobject->setAttribute(type, attrFalse);
+ }
+ else
+ {
+ if (!isPrivate)
+ {
+ return CKR_TEMPLATE_INCONSISTENT;
+ }
+
+ osobject->setAttribute(type, attrTrue);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_MODULUS
+ *****************************************/
+
+// Set default value
+bool P11AttrModulus::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrModulus::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ ByteString plaintext((unsigned char*)pValue, ulValueLen);
+ ByteString value;
+
+ // Encrypt
+
+ if (isPrivate)
+ {
+ if (!token->encrypt(plaintext, value))
+ return CKR_GENERAL_ERROR;
+ }
+ else
+ value = plaintext;
+
+ // Attribute specific checks
+
+ if (value.size() < ulValueLen)
+ return CKR_GENERAL_ERROR;
+
+ // Store data
+
+ osobject->setAttribute(type, value);
+
+ // Set the CKA_MODULUS_BITS during C_CreateObject
+
+ if (op == OBJECT_OP_CREATE && osobject->attributeExists(CKA_MODULUS_BITS))
+ {
+ OSAttribute bits((unsigned long)plaintext.bits());
+ osobject->setAttribute(CKA_MODULUS_BITS, bits);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_PUBLIC_EXPONENT
+ *****************************************/
+
+// Set default value
+bool P11AttrPublicExponent::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_PRIVATE_EXPONENT
+ *****************************************/
+
+// Set default value
+bool P11AttrPrivateExponent::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_PRIME_1
+ *****************************************/
+
+// Set default value
+bool P11AttrPrime1::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_PRIME_2
+ *****************************************/
+
+// Set default value
+bool P11AttrPrime2::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_EXPONENT_1
+ *****************************************/
+
+// Set default value
+bool P11AttrExponent1::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_EXPONENT_2
+ *****************************************/
+
+// Set default value
+bool P11AttrExponent2::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_COEFFICIENT
+ *****************************************/
+
+// Set default value
+bool P11AttrCoefficient::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_MODULUS_BITS
+ *****************************************/
+
+// Set default value
+bool P11AttrModulusBits::setDefault()
+{
+ OSAttribute attr((unsigned long)0);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrModulusBits::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ // Attribute specific checks
+
+ if (op != OBJECT_OP_GENERATE)
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ if (ulValueLen !=sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_PRIME
+ *****************************************/
+
+// Set default value
+bool P11AttrPrime::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrPrime::updateAttr(Token *token, bool isPrivate, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ ByteString plaintext((unsigned char*)pValue, ulValueLen);
+ ByteString value;
+
+ // Encrypt
+
+ if (isPrivate)
+ {
+ if (!token->encrypt(plaintext, value))
+ return CKR_GENERAL_ERROR;
+ }
+ else
+ value = plaintext;
+
+ // Attribute specific checks
+
+ if (value.size() < ulValueLen)
+ return CKR_GENERAL_ERROR;
+
+ // Store data
+
+ osobject->setAttribute(type, value);
+
+ // Set the CKA_PRIME_BITS during C_CreateObject
+
+ if (op == OBJECT_OP_CREATE && osobject->attributeExists(CKA_PRIME_BITS))
+ {
+ OSAttribute bits((unsigned long)plaintext.bits());
+ osobject->setAttribute(CKA_PRIME_BITS, bits);
+ }
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_SUBPRIME
+ *****************************************/
+
+// Set default value
+bool P11AttrSubPrime::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_BASE
+ *****************************************/
+
+// Set default value
+bool P11AttrBase::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_PRIME_BITS
+ *****************************************/
+
+// Set default value
+bool P11AttrPrimeBits::setDefault()
+{
+ OSAttribute attr((unsigned long)0);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrPrimeBits::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ // Attribute specific checks
+
+ if (op != OBJECT_OP_GENERATE)
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ if (ulValueLen != sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_VALUE_BITS
+ *****************************************/
+
+// Set default value
+bool P11AttrValueBits::setDefault()
+{
+ OSAttribute attr((unsigned long)0);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrValueBits::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ // Attribute specific checks
+
+ if (op != OBJECT_OP_GENERATE)
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ if (ulValueLen != sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_EC_PARAMS
+ *****************************************/
+
+// Set default value
+bool P11AttrEcParams::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_EC_POINT
+ *****************************************/
+
+// Set default value
+bool P11AttrEcPoint::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_GOSTR3410_PARAMS
+ *****************************************/
+
+// Set default value
+bool P11AttrGostR3410Params::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_GOSTR3411_PARAMS
+ *****************************************/
+
+// Set default value
+bool P11AttrGostR3411Params::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_GOST28147_PARAMS
+ *****************************************/
+
+// Set default value
+bool P11AttrGost28147Params::setDefault()
+{
+ OSAttribute attr(ByteString(""));
+ return osobject->setAttribute(type, attr);
+}
+
+/*****************************************
+ * CKA_VALUE_LEN
+ *****************************************/
+
+// Set default value
+bool P11AttrValueLen::setDefault()
+{
+ OSAttribute attr((unsigned long)0);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value if allowed
+CK_RV P11AttrValueLen::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int op)
+{
+ // Attribute specific checks
+
+ if (op != OBJECT_OP_GENERATE && op != OBJECT_OP_DERIVE)
+ {
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ if (ulValueLen != sizeof(CK_ULONG))
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Store data
+
+ osobject->setAttribute(type, *(CK_ULONG*)pValue);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_WRAP_TEMPLATE
+ *****************************************/
+
+// Set default value
+bool P11AttrWrapTemplate::setDefault()
+{
+ std::map<CK_ATTRIBUTE_TYPE,OSAttribute> empty;
+ OSAttribute attr(empty);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value
+CK_RV P11AttrWrapTemplate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+ if ((ulValueLen % sizeof(CK_ATTRIBUTE)) != 0)
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Fill the template vector with elements
+ CK_ATTRIBUTE_PTR attr = (CK_ATTRIBUTE_PTR) pValue;
+ std::map<CK_ATTRIBUTE_TYPE,OSAttribute> data;
+ for (size_t i = 0; i < ulValueLen / sizeof(CK_ATTRIBUTE); ++i, ++attr)
+ // Specialization for known attributes
+ switch (attr->type)
+ {
+ case CKA_TOKEN:
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ case CKA_COPYABLE:
+ case CKA_TRUSTED:
+ case CKA_ENCRYPT:
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ case CKA_UNWRAP:
+ case CKA_DERIVE:
+ case CKA_LOCAL:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_SENSITIVE:
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_EXTRACTABLE:
+ case CKA_WRAP_WITH_TRUSTED:
+ case CKA_SECONDARY_AUTH:
+ case CKA_ALWAYS_AUTHENTICATE:
+ {
+ // CK_BBOOL
+ if (attr->ulValueLen != sizeof(CK_BBOOL))
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ bool elem = (*(CK_BBOOL*)attr->pValue != CK_FALSE);
+ data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
+ }
+ break;
+
+ case CKA_CLASS:
+ case CKA_KEY_TYPE:
+ case CKA_CERTIFICATE_TYPE:
+ case CKA_CERTIFICATE_CATEGORY:
+ case CKA_JAVA_MIDP_SECURITY_DOMAIN:
+ case CKA_NAME_HASH_ALGORITHM:
+ case CKA_KEY_GEN_MECHANISM:
+ case CKA_MODULUS_BITS:
+ case CKA_PRIME_BITS:
+ case CKA_SUBPRIME_BITS:
+ case CKA_VALUE_BITS:
+ case CKA_VALUE_LEN:
+ case CKA_AUTH_PIN_FLAGS:
+ {
+ // CK_ULONG
+ if (attr->ulValueLen != sizeof(CK_ULONG))
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ unsigned long elem = *(CK_ULONG*)attr->pValue;
+ data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
+ }
+ break;
+
+ case CKA_WRAP_TEMPLATE:
+ case CKA_UNWRAP_TEMPLATE:
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ default:
+ {
+ // CK_BYTE
+ ByteString elem = ByteString((unsigned char*)attr->pValue, attr->ulValueLen);
+ data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
+ }
+ }
+
+ // Store data
+ osobject->setAttribute(type, data);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_UNWRAP_TEMPLATE
+ *****************************************/
+
+// Set default value
+bool P11AttrUnwrapTemplate::setDefault()
+{
+ std::map<CK_ATTRIBUTE_TYPE,OSAttribute> empty;
+ OSAttribute attr(empty);
+ return osobject->setAttribute(type, attr);
+}
+
+// Update the value
+CK_RV P11AttrUnwrapTemplate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ // Attribute specific checks
+ if ((ulValueLen % sizeof(CK_ATTRIBUTE)) != 0)
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ // Fill the template vector with elements
+ CK_ATTRIBUTE_PTR attr = (CK_ATTRIBUTE_PTR) pValue;
+ std::map<CK_ATTRIBUTE_TYPE,OSAttribute> data;
+ for (size_t i = 0; i < ulValueLen / sizeof(CK_ATTRIBUTE); ++i, ++attr)
+ // Specialization for known attributes
+ switch (attr->type)
+ {
+ case CKA_TOKEN:
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ case CKA_COPYABLE:
+ case CKA_TRUSTED:
+ case CKA_ENCRYPT:
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ case CKA_UNWRAP:
+ case CKA_DERIVE:
+ case CKA_LOCAL:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_SENSITIVE:
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_EXTRACTABLE:
+ case CKA_WRAP_WITH_TRUSTED:
+ case CKA_SECONDARY_AUTH:
+ case CKA_ALWAYS_AUTHENTICATE:
+ {
+ // CK_BBOOL
+ if (attr->ulValueLen != sizeof(CK_BBOOL))
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ bool elem = (*(CK_BBOOL*)attr->pValue != CK_FALSE);
+ data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
+ }
+ break;
+
+ case CKA_CLASS:
+ case CKA_KEY_TYPE:
+ case CKA_CERTIFICATE_TYPE:
+ case CKA_CERTIFICATE_CATEGORY:
+ case CKA_JAVA_MIDP_SECURITY_DOMAIN:
+ case CKA_NAME_HASH_ALGORITHM:
+ case CKA_KEY_GEN_MECHANISM:
+ case CKA_MODULUS_BITS:
+ case CKA_PRIME_BITS:
+ case CKA_SUBPRIME_BITS:
+ case CKA_VALUE_BITS:
+ case CKA_VALUE_LEN:
+ case CKA_AUTH_PIN_FLAGS:
+ {
+ // CK_ULONG
+ if (attr->ulValueLen != sizeof(CK_ULONG))
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ unsigned long elem = *(CK_ULONG*)attr->pValue;
+ data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
+ }
+ break;
+
+ case CKA_WRAP_TEMPLATE:
+ case CKA_UNWRAP_TEMPLATE:
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+
+ default:
+ {
+ // CK_BYTE
+ ByteString elem = ByteString((unsigned char*)attr->pValue, attr->ulValueLen);
+ data.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attr->type, elem));
+ }
+ }
+
+ // Store data
+ osobject->setAttribute(type, data);
+
+ return CKR_OK;
+}
+
+/*****************************************
+ * CKA_ALLOWED_MECHANISMS
+ *****************************************/
+
+// Set default value
+bool P11AttrAllowedMechanisms::setDefault()
+{
+ std::set<CK_MECHANISM_TYPE> emptyMap;
+ return osobject->setAttribute(type, OSAttribute(emptyMap));
+}
+
+// Update the value if allowed
+CK_RV P11AttrAllowedMechanisms::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_VOID_PTR pValue, CK_ULONG ulValueLen, int /*op*/)
+{
+ if (ulValueLen == 0 || (ulValueLen % sizeof(CK_MECHANISM_TYPE)) != 0)
+ {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ CK_MECHANISM_TYPE_PTR mechType = (CK_MECHANISM_TYPE_PTR) pValue;
+
+ // Fill the set with values
+ std::set<CK_MECHANISM_TYPE> data;
+ for (size_t i = 0; i < ulValueLen / sizeof(CK_MECHANISM_TYPE); ++i, ++mechType)
+ {
+ data.insert(*mechType);
+ }
+
+ // Store data
+ osobject->setAttribute(type, OSAttribute(data));
+ return CKR_OK;
+}