From 2ea6f9b1963795dad74489b41bc7d37f897d7a21 Mon Sep 17 00:00:00 2001 From: Daniel Neus Date: Fri, 17 Jun 2016 11:37:18 +0200 Subject: add PKCS#11 support --- src/lib/prov/pkcs11/p11_object.cpp | 217 +++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 src/lib/prov/pkcs11/p11_object.cpp (limited to 'src/lib/prov/pkcs11/p11_object.cpp') 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 + +#include + +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(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& 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& 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 ObjectFinder::find(uint32_t max_count) const + { + std::vector 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 Object::get_attribute_value(AttributeType attribute) const + { + std::map> attribute_map = { { attribute, secure_vector() } }; + 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& value) const + { + std::map> 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; + } +} +} -- cgit v1.2.3