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; | ||||
|  | ||||
|   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 â<><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()) { | ||||
|         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: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user