|
|
|
@ -107,7 +107,7 @@ namespace cryptoki { |
|
|
|
|
typedef std::vector<CK_ATTRIBUTE_TYPE> AttributeTypeList; |
|
|
|
|
|
|
|
|
|
struct Attribute { |
|
|
|
|
Attribute(CK_ATTRIBUTE_TYPE t): type(t) {} |
|
|
|
|
Attribute(CK_ATTRIBUTE_TYPE t = -1): type(t) {} |
|
|
|
|
Attribute(CK_ATTRIBUTE& attr): |
|
|
|
|
type(attr.type), value((char*)attr.pValue, attr.ulValueLen) { |
|
|
|
|
free(attr.pValue); |
|
|
|
@ -549,8 +549,7 @@ namespace cryptoki { |
|
|
|
|
~Init() { |
|
|
|
|
try { |
|
|
|
|
//! calls @c C_Finalize
|
|
|
|
|
return check(_slot._init->_fn->C_Finalize(0), |
|
|
|
|
CRYPTOKI_FN_LOG("C_Finalize")); |
|
|
|
|
check(_fn->C_Finalize(0), CRYPTOKI_FN_LOG("C_Finalize")); |
|
|
|
|
} catch (...) { |
|
|
|
|
if (!std::uncaught_exception()) throw; |
|
|
|
|
} |
|
|
|
@ -997,7 +996,6 @@ namespace cryptoki { |
|
|
|
|
res.resize(size); |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
@endcode */ |
|
|
|
|
|
|
|
|
|
/*! @todo Not implemented:
|
|
|
|
|
@code |
|
|
|
@ -1369,91 +1367,153 @@ namespace cryptoki { |
|
|
|
|
} |
|
|
|
|
@endcode */ |
|
|
|
|
|
|
|
|
|
AttributeMap attributes(AttributeTypeList attributes |
|
|
|
|
|
|
|
|
|
//! Get a Single Attribute
|
|
|
|
|
Attribute operator[](CK_ATTRIBUTE_TYPE a) { |
|
|
|
|
return attribute(a); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Get a Single Attribute
|
|
|
|
|
Attribute attribute(CK_ATTRIBUTE_TYPE a) { |
|
|
|
|
Attribute res; |
|
|
|
|
CK_ATTRIBUTE attr((CK_ATTRIBUTE){a, 0, 0}); |
|
|
|
|
//! calls @c C_GetAttributeValue
|
|
|
|
|
if (!check(_session->_slot._init->_fn->C_GetAttributeValue |
|
|
|
|
(_session->_session, _object, &attr, 1), |
|
|
|
|
CRYPTOKI_FN_LOG("C_GetAttributeValue")) |
|
|
|
|
|| !(long)attr.ulValueLen>0l) |
|
|
|
|
//! Without exception handling, size and type must be checked too.
|
|
|
|
|
return res; |
|
|
|
|
try { |
|
|
|
|
attr.pValue = malloc(attr.ulValueLen); |
|
|
|
|
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen); |
|
|
|
|
if (check(_session->_slot._init->_fn->C_GetAttributeValue |
|
|
|
|
(_session->_session, _object, &attr, 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 = Attribute(attr); |
|
|
|
|
else |
|
|
|
|
free(attr.pValue); |
|
|
|
|
} catch (...) { |
|
|
|
|
free(attr.pValue); |
|
|
|
|
throw; |
|
|
|
|
} |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! Get a List of Attributes.
|
|
|
|
|
/*! If @c attrs is empty, all available attributes are
|
|
|
|
|
returned. Attributes that cannot be accessed or that are not |
|
|
|
|
available in this Object won't be in the result map. There |
|
|
|
|
is no exception in this case. */ |
|
|
|
|
AttributeMap attributes(AttributeTypeList attrs |
|
|
|
|
= AttributeTypeList()) { |
|
|
|
|
AttributeMap res; |
|
|
|
|
//! Gets all attributes, if @c attributes is empty
|
|
|
|
|
if (attributes.empty()) { |
|
|
|
|
attributes.push_back(CKA_CLASS); |
|
|
|
|
attributes.push_back(CKA_TOKEN); |
|
|
|
|
attributes.push_back(CKA_PRIVATE); |
|
|
|
|
attributes.push_back(CKA_LABEL); |
|
|
|
|
attributes.push_back(CKA_APPLICATION); |
|
|
|
|
attributes.push_back(CKA_VALUE); |
|
|
|
|
attributes.push_back(CKA_OBJECT_ID); |
|
|
|
|
attributes.push_back(CKA_CERTIFICATE_TYPE); |
|
|
|
|
attributes.push_back(CKA_ISSUER); |
|
|
|
|
attributes.push_back(CKA_SERIAL_NUMBER); |
|
|
|
|
attributes.push_back(CKA_AC_ISSUER); |
|
|
|
|
attributes.push_back(CKA_OWNER); |
|
|
|
|
attributes.push_back(CKA_ATTR_TYPES); |
|
|
|
|
attributes.push_back(CKA_TRUSTED); |
|
|
|
|
attributes.push_back(CKA_KEY_TYPE); |
|
|
|
|
attributes.push_back(CKA_SUBJECT); |
|
|
|
|
attributes.push_back(CKA_ID); |
|
|
|
|
attributes.push_back(CKA_SENSITIVE); |
|
|
|
|
attributes.push_back(CKA_ENCRYPT); |
|
|
|
|
attributes.push_back(CKA_DECRYPT); |
|
|
|
|
attributes.push_back(CKA_WRAP); |
|
|
|
|
attributes.push_back(CKA_UNWRAP); |
|
|
|
|
attributes.push_back(CKA_SIGN); |
|
|
|
|
attributes.push_back(CKA_SIGN_RECOVER); |
|
|
|
|
attributes.push_back(CKA_VERIFY); |
|
|
|
|
attributes.push_back(CKA_VERIFY_RECOVER); |
|
|
|
|
attributes.push_back(CKA_DERIVE); |
|
|
|
|
attributes.push_back(CKA_START_DATE); |
|
|
|
|
attributes.push_back(CKA_END_DATE); |
|
|
|
|
attributes.push_back(CKA_MODULUS); |
|
|
|
|
attributes.push_back(CKA_MODULUS_BITS); |
|
|
|
|
attributes.push_back(CKA_PUBLIC_EXPONENT); |
|
|
|
|
attributes.push_back(CKA_PRIVATE_EXPONENT); |
|
|
|
|
attributes.push_back(CKA_PRIME_1); |
|
|
|
|
attributes.push_back(CKA_PRIME_2); |
|
|
|
|
attributes.push_back(CKA_EXPONENT_1); |
|
|
|
|
attributes.push_back(CKA_EXPONENT_2); |
|
|
|
|
attributes.push_back(CKA_COEFFICIENT); |
|
|
|
|
attributes.push_back(CKA_PRIME); |
|
|
|
|
attributes.push_back(CKA_SUBPRIME); |
|
|
|
|
attributes.push_back(CKA_BASE); |
|
|
|
|
attributes.push_back(CKA_PRIME_BITS); |
|
|
|
|
attributes.push_back(CKA_SUBPRIME_BITS); |
|
|
|
|
attributes.push_back(CKA_VALUE_BITS); |
|
|
|
|
attributes.push_back(CKA_VALUE_LEN); |
|
|
|
|
attributes.push_back(CKA_EXTRACTABLE); |
|
|
|
|
attributes.push_back(CKA_LOCAL); |
|
|
|
|
attributes.push_back(CKA_NEVER_EXTRACTABLE); |
|
|
|
|
attributes.push_back(CKA_ALWAYS_SENSITIVE); |
|
|
|
|
attributes.push_back(CKA_KEY_GEN_MECHANISM); |
|
|
|
|
attributes.push_back(CKA_MODIFIABLE); |
|
|
|
|
attributes.push_back(CKA_ECDSA_PARAMS); |
|
|
|
|
attributes.push_back(CKA_EC_PARAMS); |
|
|
|
|
attributes.push_back(CKA_EC_POINT); |
|
|
|
|
attributes.push_back(CKA_SECONDARY_AUTH); |
|
|
|
|
attributes.push_back(CKA_AUTH_PIN_FLAGS); |
|
|
|
|
attributes.push_back(CKA_HW_FEATURE_TYPE); |
|
|
|
|
attributes.push_back(CKA_RESET_ON_INIT); |
|
|
|
|
attributes.push_back(CKA_HAS_RESET); |
|
|
|
|
attributes.push_back(CKA_VENDOR_DEFINED); |
|
|
|
|
attributes.push_back(CKA_IBM_OPAQUE); |
|
|
|
|
} |
|
|
|
|
CK_ATTRIBUTE attrs; |
|
|
|
|
for (AttributeTypeList::const_iterator it(attributes.begin()); |
|
|
|
|
it!=attributes.end(); ++it) { |
|
|
|
|
attrs = (CK_ATTRIBUTE){*it, 0, 0}; |
|
|
|
|
//! Gets all attributes, if @c attrs is empty
|
|
|
|
|
if (attrs.empty()) { |
|
|
|
|
attrs.push_back(CKA_CLASS); |
|
|
|
|
attrs.push_back(CKA_TOKEN); |
|
|
|
|
attrs.push_back(CKA_PRIVATE); |
|
|
|
|
attrs.push_back(CKA_LABEL); |
|
|
|
|
attrs.push_back(CKA_APPLICATION); |
|
|
|
|
attrs.push_back(CKA_VALUE); |
|
|
|
|
attrs.push_back(CKA_OBJECT_ID); |
|
|
|
|
attrs.push_back(CKA_CERTIFICATE_TYPE); |
|
|
|
|
attrs.push_back(CKA_ISSUER); |
|
|
|
|
attrs.push_back(CKA_SERIAL_NUMBER); |
|
|
|
|
attrs.push_back(CKA_AC_ISSUER); |
|
|
|
|
attrs.push_back(CKA_OWNER); |
|
|
|
|
attrs.push_back(CKA_ATTR_TYPES); |
|
|
|
|
attrs.push_back(CKA_TRUSTED); |
|
|
|
|
attrs.push_back(CKA_KEY_TYPE); |
|
|
|
|
attrs.push_back(CKA_SUBJECT); |
|
|
|
|
attrs.push_back(CKA_ID); |
|
|
|
|
attrs.push_back(CKA_SENSITIVE); |
|
|
|
|
attrs.push_back(CKA_ENCRYPT); |
|
|
|
|
attrs.push_back(CKA_DECRYPT); |
|
|
|
|
attrs.push_back(CKA_WRAP); |
|
|
|
|
attrs.push_back(CKA_UNWRAP); |
|
|
|
|
attrs.push_back(CKA_SIGN); |
|
|
|
|
attrs.push_back(CKA_SIGN_RECOVER); |
|
|
|
|
attrs.push_back(CKA_VERIFY); |
|
|
|
|
attrs.push_back(CKA_VERIFY_RECOVER); |
|
|
|
|
attrs.push_back(CKA_DERIVE); |
|
|
|
|
attrs.push_back(CKA_START_DATE); |
|
|
|
|
attrs.push_back(CKA_END_DATE); |
|
|
|
|
attrs.push_back(CKA_MODULUS); |
|
|
|
|
attrs.push_back(CKA_MODULUS_BITS); |
|
|
|
|
attrs.push_back(CKA_PUBLIC_EXPONENT); |
|
|
|
|
attrs.push_back(CKA_PRIVATE_EXPONENT); |
|
|
|
|
attrs.push_back(CKA_PRIME_1); |
|
|
|
|
attrs.push_back(CKA_PRIME_2); |
|
|
|
|
attrs.push_back(CKA_EXPONENT_1); |
|
|
|
|
attrs.push_back(CKA_EXPONENT_2); |
|
|
|
|
attrs.push_back(CKA_COEFFICIENT); |
|
|
|
|
attrs.push_back(CKA_PRIME); |
|
|
|
|
attrs.push_back(CKA_SUBPRIME); |
|
|
|
|
attrs.push_back(CKA_BASE); |
|
|
|
|
attrs.push_back(CKA_PRIME_BITS); |
|
|
|
|
attrs.push_back(CKA_SUBPRIME_BITS); |
|
|
|
|
attrs.push_back(CKA_VALUE_BITS); |
|
|
|
|
attrs.push_back(CKA_VALUE_LEN); |
|
|
|
|
attrs.push_back(CKA_EXTRACTABLE); |
|
|
|
|
attrs.push_back(CKA_LOCAL); |
|
|
|
|
attrs.push_back(CKA_NEVER_EXTRACTABLE); |
|
|
|
|
attrs.push_back(CKA_ALWAYS_SENSITIVE); |
|
|
|
|
attrs.push_back(CKA_KEY_GEN_MECHANISM); |
|
|
|
|
attrs.push_back(CKA_MODIFIABLE); |
|
|
|
|
attrs.push_back(CKA_ECDSA_PARAMS); |
|
|
|
|
attrs.push_back(CKA_EC_PARAMS); |
|
|
|
|
attrs.push_back(CKA_EC_POINT); |
|
|
|
|
attrs.push_back(CKA_SECONDARY_AUTH); |
|
|
|
|
attrs.push_back(CKA_AUTH_PIN_FLAGS); |
|
|
|
|
attrs.push_back(CKA_HW_FEATURE_TYPE); |
|
|
|
|
attrs.push_back(CKA_RESET_ON_INIT); |
|
|
|
|
attrs.push_back(CKA_HAS_RESET); |
|
|
|
|
attrs.push_back(CKA_VENDOR_DEFINED); |
|
|
|
|
attrs.push_back(CKA_IBM_OPAQUE); |
|
|
|
|
} |
|
|
|
|
CK_ATTRIBUTE attr; |
|
|
|
|
for (AttributeTypeList::const_iterator it(attrs.begin()); |
|
|
|
|
it!=attrs.end(); ++it) { |
|
|
|
|
attr = (CK_ATTRIBUTE){*it, 0, 0}; |
|
|
|
|
try { |
|
|
|
|
//! calls @c C_GetAttributeValue
|
|
|
|
|
if (_session->_slot._init->_fn->C_GetAttributeValue |
|
|
|
|
(_session->_session, _object, &attrs, 1) |
|
|
|
|
(_session->_session, _object, &attr, 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); |
|
|
|
|
attrs.pValue = memset(attrs.pValue, 0, attrs.ulValueLen); |
|
|
|
|
if ((long)attr.ulValueLen>0l) { |
|
|
|
|
attr.pValue = malloc(attr.ulValueLen); |
|
|
|
|
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen); |
|
|
|
|
if (check(_session->_slot._init->_fn->C_GetAttributeValue |
|
|
|
|
(_session->_session, _object, &attrs, 1), |
|
|
|
|
(_session->_session, _object, &attr, 1), |
|
|
|
|
CRYPTOKI_FN_LOG("C_GetAttributeValue"))) |
|
|
|
|
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
|
|
|
|
Cryptoki. From the Specs: «In the special |
|
|
|
@ -1483,10 +1543,10 @@ namespace cryptoki { |
|
|
|
|
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(attr.type, Attribute(attr))); |
|
|
|
|
else |
|
|
|
|
free(attrs.pValue); |
|
|
|
|
} else if (*it==CKA_MODULUS && attrs.ulValueLen==0) { |
|
|
|
|
free(attr.pValue); |
|
|
|
|
} else if (*it==CKA_MODULUS && attr.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 |
|
|
|
@ -1498,41 +1558,15 @@ namespace cryptoki { |
|
|
|
|
CKA_MODULUS is 0 Bytes, the following |
|
|
|
|
attribute query is skipped as a work around |
|
|
|
|
to this bug. */ |
|
|
|
|
if (++it==attributes.end()) break; |
|
|
|
|
if (++it==attrs.end()) break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} catch (...) { |
|
|
|
|
free(attrs.pValue); |
|
|
|
|
free(attr.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)
|
|
|
|
|
// attrs[i] = (CK_ATTRIBUTE){*it, 0, 0};
|
|
|
|
|
// try {
|
|
|
|
|
// //! calls @c C_GetAttributeValue
|
|
|
|
|
// if (check(_session->_slot._init->_fn->C_GetAttributeValue
|
|
|
|
|
// (_session->_session, _object, attrs, attributes.size()),
|
|
|
|
|
// CRYPTOKI_FN_LOG("C_GetAttributeValue"))) {
|
|
|
|
|
// for (AttributeTypeList::size_type i(0); i<attributes.size(); ++i)
|
|
|
|
|
// if (attrs[i].ulValueLen>0)
|
|
|
|
|
// attrs[i].pValue = malloc(attrs[i].ulValueLen);
|
|
|
|
|
// check(_session->_slot._init->_fn->C_GetAttributeValue
|
|
|
|
|
// (_session->_session, _object, attrs, attributes.size()),
|
|
|
|
|
// CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
|
|
|
|
// }
|
|
|
|
|
// for (AttributeTypeList::size_type i(0); i<attributes.size(); ++i)
|
|
|
|
|
// if (attrs[i].ulValueLen>0)
|
|
|
|
|
// res.insert(std::make_pair(attrs[i].type, Attribute(attrs[i])));
|
|
|
|
|
// return res;
|
|
|
|
|
// } catch (...) {
|
|
|
|
|
// for (AttributeTypeList::size_type i(0); i<attributes.size(); ++i)
|
|
|
|
|
// free(attrs[i].pValue);
|
|
|
|
|
// delete[] attrs;
|
|
|
|
|
// throw;
|
|
|
|
|
// }
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*! @todo Not implemented:
|
|
|
|
|