attributes read
This commit is contained in:
@@ -39,7 +39,8 @@ int main(int argc, char const*const*const argv) try {
|
|||||||
<<"label: \""<<info.label<<'"'<<std::endl
|
<<"label: \""<<info.label<<'"'<<std::endl
|
||||||
<<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl
|
<<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl
|
||||||
<<"model: \""<<info.model<<'"'<<std::endl
|
<<"model: \""<<info.model<<'"'<<std::endl
|
||||||
<<"serialNumber: \""<<info.serialNumber<<'"'<<std::endl
|
<<"serialNumber: \""<<cryptoki::readable(info.serialNumber)
|
||||||
|
<<'"'<<std::endl
|
||||||
<<"flags: \""<<info.flags<<'"'<<std::endl
|
<<"flags: \""<<info.flags<<'"'<<std::endl
|
||||||
<<"maxSessionCount: \""<<info.maxSessionCount<<'"'<<std::endl
|
<<"maxSessionCount: \""<<info.maxSessionCount<<'"'<<std::endl
|
||||||
<<"sessionCount: \""<<info.sessionCount<<'"'<<std::endl
|
<<"sessionCount: \""<<info.sessionCount<<'"'<<std::endl
|
||||||
@@ -56,7 +57,8 @@ int main(int argc, char const*const*const argv) try {
|
|||||||
<<'.'<<(int)info.hardwareVersion.minor<<'"'<<std::endl
|
<<'.'<<(int)info.hardwareVersion.minor<<'"'<<std::endl
|
||||||
<<"firmwareVersion: \""<<(int)info.firmwareVersion.major
|
<<"firmwareVersion: \""<<(int)info.firmwareVersion.major
|
||||||
<<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl
|
<<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl
|
||||||
<<"utcTime: \""<<info.utcTime<<'"'<<std::endl;
|
<<"utcTime: \""<<cryptoki::readable(info.utcTime)
|
||||||
|
<<'"'<<std::endl;
|
||||||
cryptoki::MechanismList mechs(it->mechanismlist());
|
cryptoki::MechanismList mechs(it->mechanismlist());
|
||||||
for (cryptoki::MechanismList::iterator it2(mechs.begin());
|
for (cryptoki::MechanismList::iterator it2(mechs.begin());
|
||||||
it2!=mechs.end(); ++it2) {
|
it2!=mechs.end(); ++it2) {
|
||||||
@@ -73,15 +75,15 @@ int main(int argc, char const*const*const argv) try {
|
|||||||
std::cout<<"Objects Found: "<<objs.size()<<std::endl;
|
std::cout<<"Objects Found: "<<objs.size()<<std::endl;
|
||||||
for (cryptoki::ObjectList::iterator it(objs.begin());
|
for (cryptoki::ObjectList::iterator it(objs.begin());
|
||||||
it!=objs.end(); ++it) {
|
it!=objs.end(); ++it) {
|
||||||
cryptoki::AttributeMap attrs(it->getattributevalue());
|
std::cout<<"-------------------- Object -----------------"<<std::endl;
|
||||||
|
cryptoki::AttributeMap attrs(it->attributes());
|
||||||
for (cryptoki::AttributeMap::iterator it(attrs.begin());
|
for (cryptoki::AttributeMap::iterator it(attrs.begin());
|
||||||
it!=attrs.end(); ++it) {
|
it!=attrs.end(); ++it) {
|
||||||
std::cout<<"-------------------- Object -----------------"<<std::endl
|
std::cout<<" - attribute: "<<it->second.name()<<"=\""
|
||||||
<<"id: \""<<it->second.type<<'"'<<std::endl
|
<<cryptoki::readable(it->second.value)<<'"'<<std::endl;
|
||||||
<<"name: \""<<it->second.name()<<'"'<<std::endl
|
|
||||||
<<"value: \""<<it->second.value<<'"'<<std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout<<"**** Success"<<std::endl;
|
||||||
} catch (std::exception& x) {
|
} catch (std::exception& x) {
|
||||||
std::cerr<<"**** FEHLER in "<<*argv<<": "<<x.what()<<std::endl;
|
std::cerr<<"**** FEHLER in "<<*argv<<": "<<x.what()<<std::endl;
|
||||||
}
|
}
|
||||||
|
131
src/cryptoki.hxx
131
src/cryptoki.hxx
@@ -17,6 +17,8 @@
|
|||||||
// for inline implementations only
|
// for inline implementations only
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstdlib> // malloc/free
|
#include <cstdlib> // malloc/free
|
||||||
|
#include <cstring> // memset
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include <iostream> // debug
|
#include <iostream> // debug
|
||||||
|
|
||||||
@@ -34,6 +36,31 @@ namespace cryptoki {
|
|||||||
#define UNDEF_CRYPTOKI_FN_LOG
|
#define UNDEF_CRYPTOKI_FN_LOG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::string hex(const std::string& data) {
|
||||||
|
std::stringstream res;
|
||||||
|
for (std::string::const_iterator it(data.begin()); it!=data.end(); ++it)
|
||||||
|
res<<std::hex<<std::setfill('0')<<std::setw(2)
|
||||||
|
<<(unsigned int)(unsigned char)*it;
|
||||||
|
return res.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string LETTER_CHARS
|
||||||
|
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
|
||||||
|
static const std::string NUMBER_CHARS
|
||||||
|
("0123456789");
|
||||||
|
static const std::string GRAFIC_CHARS
|
||||||
|
("!\"#%&'()*+,-./:;<=>?[\\]^_{|}~");
|
||||||
|
static const std::string BLANK_CHARS
|
||||||
|
(" ");
|
||||||
|
static const std::string VALID_CHARS
|
||||||
|
(LETTER_CHARS+NUMBER_CHARS+GRAFIC_CHARS+BLANK_CHARS);
|
||||||
|
|
||||||
|
std::string readable(const std::string& data) {
|
||||||
|
if (data.find_first_not_of(VALID_CHARS)<data.size())
|
||||||
|
return hex(data);
|
||||||
|
else
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
template <int NUM, typename TYPE> std::vector<TYPE> toVector(TYPE in[NUM]) {
|
template <int NUM, typename TYPE> std::vector<TYPE> toVector(TYPE in[NUM]) {
|
||||||
return std::vector<TYPE>(in, in+NUM);
|
return std::vector<TYPE>(in, in+NUM);
|
||||||
@@ -515,10 +542,29 @@ namespace cryptoki {
|
|||||||
/*! Please notem, that you must not instanciate more than one
|
/*! Please notem, that you must not instanciate more than one
|
||||||
Init per unique function list!
|
Init per unique function list!
|
||||||
|
|
||||||
@param fn function list to be used within this instance
|
@param library name of the shared library that supports pkcs#11
|
||||||
@param exc wether exceptions should be thrown */
|
@param exc wether exceptions should be thrown */
|
||||||
Init(const std::string& library="onepin-opensc-pkcs11.so", bool exc=true);
|
Init(const std::string& library="onepin-opensc-pkcs11.so", bool exc=true);
|
||||||
|
|
||||||
|
~Init() {
|
||||||
|
try {
|
||||||
|
//! calls @c C_Finalize
|
||||||
|
return check(_slot._init->_fn->C_Finalize(0),
|
||||||
|
CRYPTOKI_FN_LOG("C_Finalize"));
|
||||||
|
} catch (...) {
|
||||||
|
if (!std::uncaught_exception()) throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @todo Not implemented:
|
||||||
|
@code
|
||||||
|
bool finalize() {
|
||||||
|
//! calls @c C_Finalize
|
||||||
|
return check(_slot._init->_fn->C_Finalize(CK_VOID_PTR),
|
||||||
|
CRYPTOKI_FN_LOG("C_Finalize"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! @name C Like Error Handling
|
/*! @name C Like Error Handling
|
||||||
|
|
||||||
You are strongly recommended not to disable exception
|
You are strongly recommended not to disable exception
|
||||||
@@ -575,7 +621,7 @@ namespace cryptoki {
|
|||||||
bool check(CK_RV result, const std::string& context="") {
|
bool check(CK_RV result, const std::string& context="") {
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_init->_exc && !*this)
|
if (_init->_exc && !*this)
|
||||||
if (context.size())
|
if (!context.empty())
|
||||||
throw access_error(context+": "+error());
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
throw access_error(error());
|
throw access_error(error());
|
||||||
@@ -725,7 +771,7 @@ namespace cryptoki {
|
|||||||
bool check(CK_RV result, const std::string& context="") {
|
bool check(CK_RV result, const std::string& context="") {
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_slot._init->_exc && !*this)
|
if (_slot._init->_exc && !*this)
|
||||||
if (context.size())
|
if (!context.empty())
|
||||||
throw access_error(context+": "+error());
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
throw access_error(error());
|
throw access_error(error());
|
||||||
@@ -951,14 +997,6 @@ namespace cryptoki {
|
|||||||
res.resize(size);
|
res.resize(size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
|
||||||
@code
|
|
||||||
bool finalize() {
|
|
||||||
//! calls @c C_Finalize
|
|
||||||
return check(_slot._init->_fn->C_Finalize(CK_VOID_PTR),
|
|
||||||
CRYPTOKI_FN_LOG("C_Finalize"));
|
|
||||||
}
|
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@@ -1188,7 +1226,7 @@ namespace cryptoki {
|
|||||||
bool check(CK_RV result, const std::string& context="") {
|
bool check(CK_RV result, const std::string& context="") {
|
||||||
_res = result;
|
_res = result;
|
||||||
if (_session->_slot._init->_exc && !*this)
|
if (_session->_slot._init->_exc && !*this)
|
||||||
if (context.size())
|
if (!context.empty())
|
||||||
throw access_error(context+": "+error());
|
throw access_error(context+": "+error());
|
||||||
else
|
else
|
||||||
throw access_error(error());
|
throw access_error(error());
|
||||||
@@ -1331,11 +1369,11 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
@endcode */
|
@endcode */
|
||||||
|
|
||||||
AttributeMap getattributevalue(AttributeTypeList attributes
|
AttributeMap attributes(AttributeTypeList attributes
|
||||||
= AttributeTypeList()) {
|
= AttributeTypeList()) {
|
||||||
AttributeMap res;
|
AttributeMap res;
|
||||||
//! Gets all attributes, if @c attributes is empty
|
//! Gets all attributes, if @c attributes is empty
|
||||||
if (!attributes.size()) {
|
if (attributes.empty()) {
|
||||||
attributes.push_back(CKA_CLASS);
|
attributes.push_back(CKA_CLASS);
|
||||||
attributes.push_back(CKA_TOKEN);
|
attributes.push_back(CKA_TOKEN);
|
||||||
attributes.push_back(CKA_PRIVATE);
|
attributes.push_back(CKA_PRIVATE);
|
||||||
@@ -1404,28 +1442,71 @@ namespace cryptoki {
|
|||||||
attrs = (CK_ATTRIBUTE){*it, 0, 0};
|
attrs = (CK_ATTRIBUTE){*it, 0, 0};
|
||||||
try {
|
try {
|
||||||
//! calls @c C_GetAttributeValue
|
//! calls @c C_GetAttributeValue
|
||||||
if (check(_session->_slot._init->_fn->C_GetAttributeValue
|
|
||||||
(_session->_session, _object, &attrs, 1),
|
|
||||||
CRYPTOKI_FN_LOG("C_GetAttributeValue"))) {
|
|
||||||
if (attrs.ulValueLen>0) {
|
|
||||||
attrs.pValue = malloc(attrs.ulValueLen);
|
|
||||||
if (_session->_slot._init->_fn->C_GetAttributeValue
|
if (_session->_slot._init->_fn->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attrs, 1)
|
(_session->_session, _object, &attrs, 1)
|
||||||
== CKR_ATTRIBUTE_TYPE_INVALID)
|
== CKR_ATTRIBUTE_TYPE_INVALID
|
||||||
std::cerr<<"*** Inv. Attr:"<<Attribute(*it).name()<<std::endl;
|
|| _res == CKR_ATTRIBUTE_SENSITIVE) {
|
||||||
else {
|
continue; //! Ignores unsupported Attributes.
|
||||||
|
} else {
|
||||||
check(_res, CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
check(_res, CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
||||||
|
if ((long)attrs.ulValueLen>0l) {
|
||||||
|
attrs.pValue = malloc(attrs.ulValueLen);
|
||||||
|
attrs.pValue = memset(attrs.pValue, 0, attrs.ulValueLen);
|
||||||
|
if (check(_session->_slot._init->_fn->C_GetAttributeValue
|
||||||
|
(_session->_session, _object, &attrs, 1),
|
||||||
|
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
||||||
|
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
||||||
|
Cryptoki. From the Specs: «In the special
|
||||||
|
case of an attribute whose value is an
|
||||||
|
array of attributes, for example
|
||||||
|
CKA_WRAP_TEMPLATE, where it is passed in
|
||||||
|
with pValue not NULL, then if the pValue
|
||||||
|
of elements within the array is NULL_PTR
|
||||||
|
then the ulValueLen of elements within the
|
||||||
|
array will be set to the required
|
||||||
|
length. If the pValue of elements within
|
||||||
|
the array is not NULL_PTR, then the
|
||||||
|
ulValueLen element of attributes within
|
||||||
|
the array must reflect the space that the
|
||||||
|
corresponding pValue points to, and pValue
|
||||||
|
is filled in if there is sufficient
|
||||||
|
room. Therefore it is important to
|
||||||
|
initialize the contents of a buffer before
|
||||||
|
calling C_GetAttributeValue to get such an
|
||||||
|
array value. If any ulValueLen within the
|
||||||
|
array isn't large enough, it will be set
|
||||||
|
to â<><C3A2>1 and the function will return
|
||||||
|
CKR_BUFFER_TOO_SMALL, as it does if an
|
||||||
|
attribute in the pTemplate argument has
|
||||||
|
ulValueLen too small. Note that any
|
||||||
|
attribute whose value is an array of
|
||||||
|
attributes is identifiable by virtue of
|
||||||
|
the attribute type having the
|
||||||
|
CKF_ARRAY_ATTRIBUTE bit set.» */
|
||||||
res.insert(std::make_pair(attrs.type, Attribute(attrs)));
|
res.insert(std::make_pair(attrs.type, Attribute(attrs)));
|
||||||
|
else
|
||||||
|
free(attrs.pValue);
|
||||||
|
} else if (*it==CKA_MODULUS && attrs.ulValueLen==0) {
|
||||||
|
/*! @bug This is a bug in onepin-opensc-pkcs11.so: If
|
||||||
|
@c CKA_MODULUS has a size of 0 bytes, the
|
||||||
|
following query to @c CKA_MODULUS_BITS ends
|
||||||
|
in a segmentation fault.
|
||||||
|
|
||||||
|
@note @c CKA_MODULUS @b must immediately be
|
||||||
|
followed by @c CKA_MODULUS_BITS in the
|
||||||
|
attribute list, because if the size of @c
|
||||||
|
CKA_MODULUS is 0 Bytes, the following
|
||||||
|
attribute query is skipped as a work around
|
||||||
|
to this bug. */
|
||||||
|
if (++it==attributes.end()) break;
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
std::cerr<<"*** Wrong Attr: "<<Attribute(*it).name()<<std::endl;
|
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
free(attrs.pValue);
|
free(attrs.pValue);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
// CK_ATTRIBUTE* attrs(new CK_ATTRIBUTE[attributes.size()]);
|
// CK_ATTRIBUTE* attrs(new CK_ATTRIBUTE[attributes.size()]);
|
||||||
// AttributeTypeList::const_iterator it(attributes.begin());
|
// AttributeTypeList::const_iterator it(attributes.begin());
|
||||||
// for (AttributeTypeList::size_type i(0); it!=attributes.end(); ++it, ++i)
|
// for (AttributeTypeList::size_type i(0); it!=attributes.end(); ++it, ++i)
|
||||||
|
Reference in New Issue
Block a user