get single attribute also with access operator
This commit is contained in:
250
src/cryptoki.hxx
250
src/cryptoki.hxx
@@ -107,7 +107,7 @@ namespace cryptoki {
|
|||||||
typedef std::vector<CK_ATTRIBUTE_TYPE> AttributeTypeList;
|
typedef std::vector<CK_ATTRIBUTE_TYPE> AttributeTypeList;
|
||||||
|
|
||||||
struct Attribute {
|
struct Attribute {
|
||||||
Attribute(CK_ATTRIBUTE_TYPE t): type(t) {}
|
Attribute(CK_ATTRIBUTE_TYPE t = -1): type(t) {}
|
||||||
Attribute(CK_ATTRIBUTE& attr):
|
Attribute(CK_ATTRIBUTE& attr):
|
||||||
type(attr.type), value((char*)attr.pValue, attr.ulValueLen) {
|
type(attr.type), value((char*)attr.pValue, attr.ulValueLen) {
|
||||||
free(attr.pValue);
|
free(attr.pValue);
|
||||||
@@ -549,8 +549,7 @@ namespace cryptoki {
|
|||||||
~Init() {
|
~Init() {
|
||||||
try {
|
try {
|
||||||
//! calls @c C_Finalize
|
//! calls @c C_Finalize
|
||||||
return check(_slot._init->_fn->C_Finalize(0),
|
check(_fn->C_Finalize(0), CRYPTOKI_FN_LOG("C_Finalize"));
|
||||||
CRYPTOKI_FN_LOG("C_Finalize"));
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
if (!std::uncaught_exception()) throw;
|
if (!std::uncaught_exception()) throw;
|
||||||
}
|
}
|
||||||
@@ -997,7 +996,6 @@ namespace cryptoki {
|
|||||||
res.resize(size);
|
res.resize(size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@endcode */
|
|
||||||
|
|
||||||
/*! @todo Not implemented:
|
/*! @todo Not implemented:
|
||||||
@code
|
@code
|
||||||
@@ -1369,91 +1367,153 @@ namespace cryptoki {
|
|||||||
}
|
}
|
||||||
@endcode */
|
@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 â<><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 = 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()) {
|
= AttributeTypeList()) {
|
||||||
AttributeMap res;
|
AttributeMap res;
|
||||||
//! Gets all attributes, if @c attributes is empty
|
//! Gets all attributes, if @c attrs is empty
|
||||||
if (attributes.empty()) {
|
if (attrs.empty()) {
|
||||||
attributes.push_back(CKA_CLASS);
|
attrs.push_back(CKA_CLASS);
|
||||||
attributes.push_back(CKA_TOKEN);
|
attrs.push_back(CKA_TOKEN);
|
||||||
attributes.push_back(CKA_PRIVATE);
|
attrs.push_back(CKA_PRIVATE);
|
||||||
attributes.push_back(CKA_LABEL);
|
attrs.push_back(CKA_LABEL);
|
||||||
attributes.push_back(CKA_APPLICATION);
|
attrs.push_back(CKA_APPLICATION);
|
||||||
attributes.push_back(CKA_VALUE);
|
attrs.push_back(CKA_VALUE);
|
||||||
attributes.push_back(CKA_OBJECT_ID);
|
attrs.push_back(CKA_OBJECT_ID);
|
||||||
attributes.push_back(CKA_CERTIFICATE_TYPE);
|
attrs.push_back(CKA_CERTIFICATE_TYPE);
|
||||||
attributes.push_back(CKA_ISSUER);
|
attrs.push_back(CKA_ISSUER);
|
||||||
attributes.push_back(CKA_SERIAL_NUMBER);
|
attrs.push_back(CKA_SERIAL_NUMBER);
|
||||||
attributes.push_back(CKA_AC_ISSUER);
|
attrs.push_back(CKA_AC_ISSUER);
|
||||||
attributes.push_back(CKA_OWNER);
|
attrs.push_back(CKA_OWNER);
|
||||||
attributes.push_back(CKA_ATTR_TYPES);
|
attrs.push_back(CKA_ATTR_TYPES);
|
||||||
attributes.push_back(CKA_TRUSTED);
|
attrs.push_back(CKA_TRUSTED);
|
||||||
attributes.push_back(CKA_KEY_TYPE);
|
attrs.push_back(CKA_KEY_TYPE);
|
||||||
attributes.push_back(CKA_SUBJECT);
|
attrs.push_back(CKA_SUBJECT);
|
||||||
attributes.push_back(CKA_ID);
|
attrs.push_back(CKA_ID);
|
||||||
attributes.push_back(CKA_SENSITIVE);
|
attrs.push_back(CKA_SENSITIVE);
|
||||||
attributes.push_back(CKA_ENCRYPT);
|
attrs.push_back(CKA_ENCRYPT);
|
||||||
attributes.push_back(CKA_DECRYPT);
|
attrs.push_back(CKA_DECRYPT);
|
||||||
attributes.push_back(CKA_WRAP);
|
attrs.push_back(CKA_WRAP);
|
||||||
attributes.push_back(CKA_UNWRAP);
|
attrs.push_back(CKA_UNWRAP);
|
||||||
attributes.push_back(CKA_SIGN);
|
attrs.push_back(CKA_SIGN);
|
||||||
attributes.push_back(CKA_SIGN_RECOVER);
|
attrs.push_back(CKA_SIGN_RECOVER);
|
||||||
attributes.push_back(CKA_VERIFY);
|
attrs.push_back(CKA_VERIFY);
|
||||||
attributes.push_back(CKA_VERIFY_RECOVER);
|
attrs.push_back(CKA_VERIFY_RECOVER);
|
||||||
attributes.push_back(CKA_DERIVE);
|
attrs.push_back(CKA_DERIVE);
|
||||||
attributes.push_back(CKA_START_DATE);
|
attrs.push_back(CKA_START_DATE);
|
||||||
attributes.push_back(CKA_END_DATE);
|
attrs.push_back(CKA_END_DATE);
|
||||||
attributes.push_back(CKA_MODULUS);
|
attrs.push_back(CKA_MODULUS);
|
||||||
attributes.push_back(CKA_MODULUS_BITS);
|
attrs.push_back(CKA_MODULUS_BITS);
|
||||||
attributes.push_back(CKA_PUBLIC_EXPONENT);
|
attrs.push_back(CKA_PUBLIC_EXPONENT);
|
||||||
attributes.push_back(CKA_PRIVATE_EXPONENT);
|
attrs.push_back(CKA_PRIVATE_EXPONENT);
|
||||||
attributes.push_back(CKA_PRIME_1);
|
attrs.push_back(CKA_PRIME_1);
|
||||||
attributes.push_back(CKA_PRIME_2);
|
attrs.push_back(CKA_PRIME_2);
|
||||||
attributes.push_back(CKA_EXPONENT_1);
|
attrs.push_back(CKA_EXPONENT_1);
|
||||||
attributes.push_back(CKA_EXPONENT_2);
|
attrs.push_back(CKA_EXPONENT_2);
|
||||||
attributes.push_back(CKA_COEFFICIENT);
|
attrs.push_back(CKA_COEFFICIENT);
|
||||||
attributes.push_back(CKA_PRIME);
|
attrs.push_back(CKA_PRIME);
|
||||||
attributes.push_back(CKA_SUBPRIME);
|
attrs.push_back(CKA_SUBPRIME);
|
||||||
attributes.push_back(CKA_BASE);
|
attrs.push_back(CKA_BASE);
|
||||||
attributes.push_back(CKA_PRIME_BITS);
|
attrs.push_back(CKA_PRIME_BITS);
|
||||||
attributes.push_back(CKA_SUBPRIME_BITS);
|
attrs.push_back(CKA_SUBPRIME_BITS);
|
||||||
attributes.push_back(CKA_VALUE_BITS);
|
attrs.push_back(CKA_VALUE_BITS);
|
||||||
attributes.push_back(CKA_VALUE_LEN);
|
attrs.push_back(CKA_VALUE_LEN);
|
||||||
attributes.push_back(CKA_EXTRACTABLE);
|
attrs.push_back(CKA_EXTRACTABLE);
|
||||||
attributes.push_back(CKA_LOCAL);
|
attrs.push_back(CKA_LOCAL);
|
||||||
attributes.push_back(CKA_NEVER_EXTRACTABLE);
|
attrs.push_back(CKA_NEVER_EXTRACTABLE);
|
||||||
attributes.push_back(CKA_ALWAYS_SENSITIVE);
|
attrs.push_back(CKA_ALWAYS_SENSITIVE);
|
||||||
attributes.push_back(CKA_KEY_GEN_MECHANISM);
|
attrs.push_back(CKA_KEY_GEN_MECHANISM);
|
||||||
attributes.push_back(CKA_MODIFIABLE);
|
attrs.push_back(CKA_MODIFIABLE);
|
||||||
attributes.push_back(CKA_ECDSA_PARAMS);
|
attrs.push_back(CKA_ECDSA_PARAMS);
|
||||||
attributes.push_back(CKA_EC_PARAMS);
|
attrs.push_back(CKA_EC_PARAMS);
|
||||||
attributes.push_back(CKA_EC_POINT);
|
attrs.push_back(CKA_EC_POINT);
|
||||||
attributes.push_back(CKA_SECONDARY_AUTH);
|
attrs.push_back(CKA_SECONDARY_AUTH);
|
||||||
attributes.push_back(CKA_AUTH_PIN_FLAGS);
|
attrs.push_back(CKA_AUTH_PIN_FLAGS);
|
||||||
attributes.push_back(CKA_HW_FEATURE_TYPE);
|
attrs.push_back(CKA_HW_FEATURE_TYPE);
|
||||||
attributes.push_back(CKA_RESET_ON_INIT);
|
attrs.push_back(CKA_RESET_ON_INIT);
|
||||||
attributes.push_back(CKA_HAS_RESET);
|
attrs.push_back(CKA_HAS_RESET);
|
||||||
attributes.push_back(CKA_VENDOR_DEFINED);
|
attrs.push_back(CKA_VENDOR_DEFINED);
|
||||||
attributes.push_back(CKA_IBM_OPAQUE);
|
attrs.push_back(CKA_IBM_OPAQUE);
|
||||||
}
|
}
|
||||||
CK_ATTRIBUTE attrs;
|
CK_ATTRIBUTE attr;
|
||||||
for (AttributeTypeList::const_iterator it(attributes.begin());
|
for (AttributeTypeList::const_iterator it(attrs.begin());
|
||||||
it!=attributes.end(); ++it) {
|
it!=attrs.end(); ++it) {
|
||||||
attrs = (CK_ATTRIBUTE){*it, 0, 0};
|
attr = (CK_ATTRIBUTE){*it, 0, 0};
|
||||||
try {
|
try {
|
||||||
//! calls @c C_GetAttributeValue
|
//! calls @c C_GetAttributeValue
|
||||||
if (_session->_slot._init->_fn->C_GetAttributeValue
|
if (_session->_slot._init->_fn->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attrs, 1)
|
(_session->_session, _object, &attr, 1)
|
||||||
== CKR_ATTRIBUTE_TYPE_INVALID
|
== CKR_ATTRIBUTE_TYPE_INVALID
|
||||||
|| _res == CKR_ATTRIBUTE_SENSITIVE) {
|
|| _res == CKR_ATTRIBUTE_SENSITIVE) {
|
||||||
continue; //! Ignores unsupported Attributes.
|
continue; //! Ignores unsupported Attributes.
|
||||||
} else {
|
} else {
|
||||||
check(_res, CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
check(_res, CRYPTOKI_FN_LOG("C_GetAttributeValue"));
|
||||||
if ((long)attrs.ulValueLen>0l) {
|
if ((long)attr.ulValueLen>0l) {
|
||||||
attrs.pValue = malloc(attrs.ulValueLen);
|
attr.pValue = malloc(attr.ulValueLen);
|
||||||
attrs.pValue = memset(attrs.pValue, 0, attrs.ulValueLen);
|
attr.pValue = memset(attr.pValue, 0, attr.ulValueLen);
|
||||||
if (check(_session->_slot._init->_fn->C_GetAttributeValue
|
if (check(_session->_slot._init->_fn->C_GetAttributeValue
|
||||||
(_session->_session, _object, &attrs, 1),
|
(_session->_session, _object, &attr, 1),
|
||||||
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
CRYPTOKI_FN_LOG("C_GetAttributeValue")))
|
||||||
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
/*! @todo There's no @c CKA_WRAP_TEMPLATE in Open
|
||||||
Cryptoki. From the Specs: «In the special
|
Cryptoki. From the Specs: «In the special
|
||||||
@@ -1483,10 +1543,10 @@ namespace cryptoki {
|
|||||||
attributes is identifiable by virtue of
|
attributes is identifiable by virtue of
|
||||||
the attribute type having the
|
the attribute type having the
|
||||||
CKF_ARRAY_ATTRIBUTE bit set.» */
|
CKF_ARRAY_ATTRIBUTE bit set.» */
|
||||||
res.insert(std::make_pair(attrs.type, Attribute(attrs)));
|
res.insert(std::make_pair(attr.type, Attribute(attr)));
|
||||||
else
|
else
|
||||||
free(attrs.pValue);
|
free(attr.pValue);
|
||||||
} else if (*it==CKA_MODULUS && attrs.ulValueLen==0) {
|
} else if (*it==CKA_MODULUS && attr.ulValueLen==0) {
|
||||||
/*! @bug This is a bug in onepin-opensc-pkcs11.so: If
|
/*! @bug This is a bug in onepin-opensc-pkcs11.so: If
|
||||||
@c CKA_MODULUS has a size of 0 bytes, the
|
@c CKA_MODULUS has a size of 0 bytes, the
|
||||||
following query to @c CKA_MODULUS_BITS ends
|
following query to @c CKA_MODULUS_BITS ends
|
||||||
@@ -1498,41 +1558,15 @@ namespace cryptoki {
|
|||||||
CKA_MODULUS is 0 Bytes, the following
|
CKA_MODULUS is 0 Bytes, the following
|
||||||
attribute query is skipped as a work around
|
attribute query is skipped as a work around
|
||||||
to this bug. */
|
to this bug. */
|
||||||
if (++it==attributes.end()) break;
|
if (++it==attrs.end()) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
free(attrs.pValue);
|
free(attr.pValue);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
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:
|
/*! @todo Not implemented:
|
||||||
|
Reference in New Issue
Block a user