attributes read

master
Marc Wäckerlin 15 years ago
parent f3645efc8c
commit 0c7be56e21
  1. 16
      doc/examples/cryptoki-demo.cxx
  2. 133
      src/cryptoki.hxx

@ -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;
} }

@ -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 â<EFBFBD><EFBFBD>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)

Loading…
Cancel
Save