aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/prov/pkcs11/p11_object.cpp
diff options
context:
space:
mode:
authorDaniel Neus <[email protected]>2016-06-17 11:37:18 +0200
committerDaniel Neus <[email protected]>2016-06-17 16:19:40 +0200
commit2ea6f9b1963795dad74489b41bc7d37f897d7a21 (patch)
treec9120503521633ee4a25ac2021b392f33d82e8d7 /src/lib/prov/pkcs11/p11_object.cpp
parent601f8f6d6075ff2f944c11d357f2309da0c4deb1 (diff)
add PKCS#11 support
Diffstat (limited to 'src/lib/prov/pkcs11/p11_object.cpp')
-rw-r--r--src/lib/prov/pkcs11/p11_object.cpp217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/lib/prov/pkcs11/p11_object.cpp b/src/lib/prov/pkcs11/p11_object.cpp
new file mode 100644
index 000000000..ef7477284
--- /dev/null
+++ b/src/lib/prov/pkcs11/p11_object.cpp
@@ -0,0 +1,217 @@
+/*
+* PKCS#11 Object
+* (C) 2016 Daniel Neus, Sirrix AG
+* (C) 2016 Philipp Weber, Sirrix AG
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/p11_object.h>
+
+#include <map>
+
+namespace Botan {
+
+namespace PKCS11 {
+
+AttributeContainer::AttributeContainer(ObjectClass object_class)
+ {
+ add_class(object_class);
+ }
+
+void AttributeContainer::add_class(ObjectClass object_class)
+ {
+ m_numerics.push_back(static_cast< uint64_t >(object_class));
+ add_attribute(AttributeType::Class, reinterpret_cast< byte* >(&m_numerics.back()), sizeof(ObjectClass));
+ }
+
+void AttributeContainer::add_string(AttributeType attribute, const std::string& value)
+ {
+ m_strings.push_back(value);
+ add_attribute(attribute, reinterpret_cast< const byte* >(m_strings.back().data()), value.size());
+ }
+
+void AttributeContainer::add_binary(AttributeType attribute, const byte* value, size_t length)
+ {
+ m_vectors.push_back(secure_vector<byte>(value, value + length));
+ add_attribute(attribute, reinterpret_cast< const byte* >(m_vectors.back().data()), length);
+ }
+
+void AttributeContainer::add_bool(AttributeType attribute, bool value)
+ {
+ m_numerics.push_back(value ? True : False);
+ add_attribute(attribute, reinterpret_cast< byte* >(&m_numerics.back()), sizeof(Bbool));
+ }
+
+void AttributeContainer::add_attribute(AttributeType attribute, const byte* value, uint32_t size)
+ {
+ bool exists = false;
+ // check if the attribute has been added already
+ for(auto& existing_attribute : m_attributes)
+ {
+ if(existing_attribute.type == static_cast< CK_ATTRIBUTE_TYPE >(attribute))
+ {
+ // remove old entries
+ m_strings.erase(std::remove_if(m_strings.begin(), m_strings.end(), [ &existing_attribute ](const std::string& data)
+ {
+ return data.data() == existing_attribute.pValue;
+ }), m_strings.end());
+
+ m_numerics.erase(std::remove_if(m_numerics.begin(), m_numerics.end(), [ &existing_attribute ](const uint64_t& data)
+ {
+ return &data == existing_attribute.pValue;
+ }), m_numerics.end());
+
+ m_vectors.erase(std::remove_if(m_vectors.begin(),
+ m_vectors.end(), [ &existing_attribute ](const secure_vector<byte>& data)
+ {
+ return data.data() == existing_attribute.pValue;
+ }), m_vectors.end());
+
+ existing_attribute.pValue = const_cast< byte* >(value);
+ existing_attribute.ulValueLen = size;
+ exists = true;
+ break;
+ }
+ }
+
+ if(!exists)
+ {
+ m_attributes.push_back(Attribute{ static_cast< CK_ATTRIBUTE_TYPE >(attribute), const_cast< byte* >(value), size });
+ }
+ }
+
+// ====================================================================================================
+
+ObjectFinder::ObjectFinder(Session& session, const std::vector<Attribute>& search_template)
+ : m_session(session), m_search_terminated(false)
+ {
+ module()->C_FindObjectsInit(m_session.get().handle(), const_cast< Attribute* >(search_template.data()),
+ search_template.size());
+ }
+
+ObjectFinder::~ObjectFinder() BOTAN_NOEXCEPT
+ {
+ if(m_search_terminated == false)
+ {
+ module()->C_FindObjectsFinal(m_session.get().handle(), nullptr);
+ }
+ }
+
+std::vector<ObjectHandle> ObjectFinder::find(uint32_t max_count) const
+ {
+ std::vector<ObjectHandle> result(max_count);
+ Ulong objectCount = 0;
+ module()->C_FindObjects(m_session.get().handle(), result.data(), max_count, &objectCount);
+ if(objectCount < max_count)
+ {
+ result.resize(objectCount);
+ }
+ return result;
+ }
+
+void ObjectFinder::finish()
+ {
+ module()->C_FindObjectsFinal(m_session.get().handle());
+ m_search_terminated = true;
+ }
+
+// ====================================================================================================
+
+ObjectProperties::ObjectProperties(ObjectClass object_class)
+ : AttributeContainer(object_class), m_object_class(object_class)
+ {}
+
+// ====================================================================================================
+
+StorageObjectProperties::StorageObjectProperties(ObjectClass object_class)
+ : ObjectProperties(object_class)
+ {}
+
+// ====================================================================================================
+
+DataObjectProperties::DataObjectProperties()
+ : StorageObjectProperties(ObjectClass::Data)
+ {}
+
+// ====================================================================================================
+
+CertificateProperties::CertificateProperties(CertificateType cert_type)
+ : StorageObjectProperties(ObjectClass::Certificate), m_cert_type(cert_type)
+ {
+ add_numeric(AttributeType::CertificateType, static_cast< CK_CERTIFICATE_TYPE >(m_cert_type));
+ }
+
+// ====================================================================================================
+
+KeyProperties::KeyProperties(ObjectClass object_class, KeyType key_type)
+ : StorageObjectProperties(object_class), m_key_type(key_type)
+ {
+ add_numeric(AttributeType::KeyType, static_cast< CK_ULONG >(m_key_type));
+ }
+
+// ====================================================================================================
+
+PublicKeyProperties::PublicKeyProperties(KeyType key_type)
+ : KeyProperties(ObjectClass::PublicKey, key_type)
+ {}
+
+// ====================================================================================================
+
+PrivateKeyProperties::PrivateKeyProperties(KeyType key_type)
+ : KeyProperties(ObjectClass::PrivateKey, key_type)
+ {}
+
+// ====================================================================================================
+
+SecretKeyProperties::SecretKeyProperties(KeyType key_type)
+ : KeyProperties(ObjectClass::SecretKey, key_type)
+ {}
+
+// ====================================================================================================
+
+DomainParameterProperties::DomainParameterProperties(KeyType key_type)
+ : StorageObjectProperties(ObjectClass::DomainParameters), m_key_type(key_type)
+ {
+ add_numeric(AttributeType::KeyType, static_cast< CK_ULONG >(m_key_type));
+ }
+
+// ====================================================================================================
+
+Object::Object(Session& session, ObjectHandle handle)
+ : m_session(session), m_handle(handle)
+ {}
+
+Object::Object(Session& session, const ObjectProperties& obj_props)
+ : m_session(session), m_handle(0)
+ {
+ m_session.get().module()->C_CreateObject(m_session.get().handle(), obj_props.data(), obj_props.count(), &m_handle);
+ }
+
+secure_vector<byte> Object::get_attribute_value(AttributeType attribute) const
+ {
+ std::map<AttributeType, secure_vector<byte>> attribute_map = { { attribute, secure_vector<byte>() } };
+ module()->C_GetAttributeValue(m_session.get().handle(), m_handle, attribute_map);
+ return attribute_map.at(attribute);
+ }
+
+void Object::set_attribute_value(AttributeType attribute, const secure_vector<byte>& value) const
+ {
+ std::map<AttributeType, secure_vector<byte>> attribute_map = { { attribute, value } };
+ module()->C_SetAttributeValue(m_session.get().handle(), m_handle, attribute_map);
+ }
+
+void Object::destroy() const
+ {
+ module()->C_DestroyObject(m_session.get().handle(), m_handle);
+ }
+
+ObjectHandle Object::copy(const AttributeContainer& modified_attributes) const
+ {
+ ObjectHandle copied_handle;
+ module()->C_CopyObject(m_session.get().handle(), m_handle, modified_attributes.data(), modified_attributes.count(),
+ &copied_handle);
+ return copied_handle;
+ }
+}
+}