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
|
||||
<<"manufacturerID: \""<<info.manufacturerID<<'"'<<std::endl
|
||||
<<"model: \""<<info.model<<'"'<<std::endl
|
||||
<<"serialNumber: \""<<info.serialNumber<<'"'<<std::endl
|
||||
<<"serialNumber: \""<<cryptoki::readable(info.serialNumber)
|
||||
<<'"'<<std::endl
|
||||
<<"flags: \""<<info.flags<<'"'<<std::endl
|
||||
<<"maxSessionCount: \""<<info.maxSessionCount<<'"'<<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
|
||||
<<"firmwareVersion: \""<<(int)info.firmwareVersion.major
|
||||
<<'.'<<(int)info.firmwareVersion.minor<<'"'<<std::endl
|
||||
<<"utcTime: \""<<info.utcTime<<'"'<<std::endl;
|
||||
<<"utcTime: \""<<cryptoki::readable(info.utcTime)
|
||||
<<'"'<<std::endl;
|
||||
cryptoki::MechanismList mechs(it->mechanismlist());
|
||||
for (cryptoki::MechanismList::iterator it2(mechs.begin());
|
||||
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;
|
||||
for (cryptoki::ObjectList::iterator it(objs.begin());
|
||||
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());
|
||||
it!=attrs.end(); ++it) {
|
||||
std::cout<<"-------------------- Object -----------------"<<std::endl
|
||||
<<"id: \""<<it->second.type<<'"'<<std::endl
|
||||
<<"name: \""<<it->second.name()<<'"'<<std::endl
|
||||
<<"value: \""<<it->second.value<<'"'<<std::endl;
|
||||
std::cout<<" - attribute: "<<it->second.name()<<"=\""
|
||||
<<cryptoki::readable(it->second.value)<<'"'<<std::endl;
|
||||
}
|
||||
}
|
||||
std::cout<<"**** Success"<<std::endl;
|
||||
} catch (std::exception& x) {
|
||||
std::cerr<<"**** FEHLER in "<<*argv<<": "<<x.what()<<std::endl;
|
||||
}
|
||||
|
141
src/cryptoki.hxx
141
src/cryptoki.hxx
@@ -17,6 +17,8 @@
|
||||
// for inline implementations only
|
||||
#include <sstream>
|
||||
#include <cstdlib> // malloc/free
|
||||
#include <cstring> // memset
|
||||
#include <iomanip>
|
||||
|
||||
#include <iostream> // debug
|
||||
|
||||
@@ -33,8 +35,33 @@ namespace cryptoki {
|
||||
#endif
|
||||
#define UNDEF_CRYPTOKI_FN_LOG
|
||||
#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]) {
|
||||
return std::vector<TYPE>(in, in+NUM);
|
||||
}
|
||||
@@ -515,10 +542,29 @@ namespace cryptoki {
|
||||
/*! Please notem, that you must not instanciate more than one
|
||||
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 */
|
||||
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
|
||||
|
||||
You are strongly recommended not to disable exception
|
||||
@@ -575,7 +621,7 @@ namespace cryptoki {
|
||||
bool check(CK_RV result, const std::string& context="") {
|
||||
_res = result;
|
||||
if (_init->_exc && !*this)
|
||||
if (context.size())
|
||||
if (!context.empty())
|
||||
throw access_error(context+": "+error());
|
||||
else
|
||||
throw access_error(error());
|
||||
@@ -725,7 +771,7 @@ namespace cryptoki {
|
||||
bool check(CK_RV result, const std::string& context="") {
|
||||
_res = result;
|
||||
if (_slot._init->_exc && !*this)
|
||||
if (context.size())
|
||||
if (!context.empty())
|
||||
throw access_error(context+": "+error());
|
||||
else
|
||||
throw access_error(error());
|
||||
@@ -951,14 +997,6 @@ namespace cryptoki {
|
||||
res.resize(size);
|
||||
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 */
|
||||
|
||||
/*! @todo Not implemented:
|
||||
@@ -1188,7 +1226,7 @@ namespace cryptoki {
|
||||
bool check(CK_RV result, const std::string& context="") {
|
||||
_res = result;
|
||||
if (_session->_slot._init->_exc && !*this)
|
||||
if (context.size())
|
||||
if (!context.empty())
|
||||
throw access_error(context+": "+error());
|
||||
else
|
||||
throw access_error(error());
|
||||
@@ -1331,11 +1369,11 @@ namespace cryptoki {
|
||||
}
|
||||
@endcode */
|
||||
|
||||
AttributeMap getattributevalue(AttributeTypeList attributes
|
||||
=AttributeTypeList()) {
|
||||
AttributeMap attributes(AttributeTypeList attributes
|
||||
= AttributeTypeList()) {
|
||||
AttributeMap res;
|
||||
//! Gets all attributes, if @c attributes is empty
|
||||
if (!attributes.size()) {
|
||||
if (attributes.empty()) {
|
||||
attributes.push_back(CKA_CLASS);
|
||||
attributes.push_back(CKA_TOKEN);
|
||||
attributes.push_back(CKA_PRIVATE);
|
||||
@@ -1404,28 +1442,71 @@ namespace cryptoki {
|
||||
attrs = (CK_ATTRIBUTE){*it, 0, 0};
|
||||
try {
|
||||
//! 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) {
|
||||
if (_session->_slot._init->_fn->C_GetAttributeValue
|
||||
(_session->_session, _object, &attrs, 1)
|
||||
== CKR_ATTRIBUTE_TYPE_INVALID
|
||||
|| _res == CKR_ATTRIBUTE_SENSITIVE) {
|
||||
continue; //! Ignores unsupported Attributes.
|
||||
} else {
|
||||
check(_res, CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
||||
if ((long)attrs.ulValueLen>0l) {
|
||||
attrs.pValue = malloc(attrs.ulValueLen);
|
||||
if (_session->_slot._init->_fn->C_GetAttributeValue
|
||||
(_session->_session, _object, &attrs, 1)
|
||||
== CKR_ATTRIBUTE_TYPE_INVALID)
|
||||
std::cerr<<"*** Inv. Attr:"<<Attribute(*it).name()<<std::endl;
|
||||
else {
|
||||
check(_res, CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
||||
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)));
|
||||
}
|
||||
} else
|
||||
std::cerr<<"*** Wrong Attr: "<<Attribute(*it).name()<<std::endl;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} catch (...) {
|
||||
free(attrs.pValue);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
// CK_ATTRIBUTE* attrs(new CK_ATTRIBUTE[attributes.size()]);
|
||||
// AttributeTypeList::const_iterator it(attributes.begin());
|
||||
// for (AttributeTypeList::size_type i(0); it!=attributes.end(); ++it, ++i)
|
||||
|
Reference in New Issue
Block a user