get single attribute also with access operator

master
Marc Wäckerlin 15 years ago
parent 0c7be56e21
commit af0b86835d
  1. 250
      src/cryptoki.hxx

@ -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);
//! 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 attrs;
for (AttributeTypeList::const_iterator it(attributes.begin());
it!=attributes.end(); ++it) {
attrs = (CK_ATTRIBUTE){*it, 0, 0};
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:

Loading…
Cancel
Save