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