#ifndef CRYPTOKI_HXX #define CRYPTOKI_HXX /*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #include #include #include #include //! C++ Wrapper around Cryptoki API namespace cryptoki { #ifndef CRYPTOKI_FN_LOG #if __GNUC__ >= 2 #define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \ +std::string(__PRETTY_FUNCTION__)) #else #define CRYPTOKI_FN_LOG(X) X " failed in \ " __FILE__ ":" CRYPTOKI_QUOTE(__LINE__) #endif #define UNDEF_CRYPTOKI_FN_LOG #endif //============================================================================ class exception: public std::exception { public: exception(const std::string& reason) throw(): _what("cryptoki: "+reason) { } ~exception() throw() {} const char* what() const throw() { return _what.c_str(); } private: std::string _what; }; //---------------------------------------------------------------------------- class not_implemented: public exception { public: not_implemented(const std::string& reason) throw(): exception("feature is not implemented:\n"+reason) { } }; //---------------------------------------------------------------------------- class access_error: public exception { public: access_error(const std::string& reason) throw(): exception("smardcard access error:\n"+reason) { } }; class Slot; typedef std::vector SlotList; enum Mechanism { RSA_PKCS_KEY_PAIR_GEN = CKM_RSA_PKCS_KEY_PAIR_GEN, RSA_PKCS = CKM_RSA_PKCS, RSA_9796 = CKM_RSA_9796, RSA_X_509 = CKM_RSA_X_509, MD2_RSA_PKCS = CKM_MD2_RSA_PKCS, MD5_RSA_PKCS = CKM_MD5_RSA_PKCS, SHA1_RSA_PKCS = CKM_SHA1_RSA_PKCS, RIPEMD128_RSA_PKCS = CKM_RIPEMD128_RSA_PKCS, RIPEMD160_RSA_PKCS = CKM_RIPEMD160_RSA_PKCS, RSA_PKCS_OAEP = CKM_RSA_PKCS_OAEP, RSA_X9_31_KEY_PAIR_GEN = CKM_RSA_X9_31_KEY_PAIR_GEN, RSA_X9_31 = CKM_RSA_X9_31, SHA1_RSA_X9_31 = CKM_SHA1_RSA_X9_31, RSA_PKCS_PSS = CKM_RSA_PKCS_PSS, SHA1_RSA_PKCS_PSS = CKM_SHA1_RSA_PKCS_PSS, DSA_KEY_PAIR_GEN = CKM_DSA_KEY_PAIR_GEN, DSA = CKM_DSA, DSA_SHA1 = CKM_DSA_SHA1, DH_PKCS_KEY_PAIR_GEN = CKM_DH_PKCS_KEY_PAIR_GEN, DH_PKCS_DERIVE = CKM_DH_PKCS_DERIVE, X9_42_DH_KEY_PAIR_GEN = CKM_X9_42_DH_KEY_PAIR_GEN, X9_42_DH_DERIVE = CKM_X9_42_DH_DERIVE, X9_42_DH_HYBRID_DERIVE = CKM_X9_42_DH_HYBRID_DERIVE, X9_42_MQV_DERIVE = CKM_X9_42_MQV_DERIVE, SHA256_RSA_PKCS = CKM_SHA256_RSA_PKCS, RC2_KEY_GEN = CKM_RC2_KEY_GEN, RC2_ECB = CKM_RC2_ECB, RC2_CBC = CKM_RC2_CBC, RC2_MAC = CKM_RC2_MAC, RC2_MAC_GENERAL = CKM_RC2_MAC_GENERAL, RC2_CBC_PAD = CKM_RC2_CBC_PAD, RC4_KEY_GEN = CKM_RC4_KEY_GEN, RC4 = CKM_RC4, DES_KEY_GEN = CKM_DES_KEY_GEN, DES_ECB = CKM_DES_ECB, DES_CBC = CKM_DES_CBC, DES_MAC = CKM_DES_MAC, DES_MAC_GENERAL = CKM_DES_MAC_GENERAL, DES_CBC_PAD = CKM_DES_CBC_PAD, DES2_KEY_GEN = CKM_DES2_KEY_GEN, DES3_KEY_GEN = CKM_DES3_KEY_GEN, DES3_ECB = CKM_DES3_ECB, DES3_CBC = CKM_DES3_CBC, DES3_MAC = CKM_DES3_MAC, DES3_MAC_GENERAL = CKM_DES3_MAC_GENERAL, DES3_CBC_PAD = CKM_DES3_CBC_PAD, CDMF_KEY_GEN = CKM_CDMF_KEY_GEN, CDMF_ECB = CKM_CDMF_ECB, CDMF_CBC = CKM_CDMF_CBC, CDMF_MAC = CKM_CDMF_MAC, CDMF_MAC_GENERAL = CKM_CDMF_MAC_GENERAL, CDMF_CBC_PAD = CKM_CDMF_CBC_PAD, MD2 = CKM_MD2, MD2_HMAC = CKM_MD2_HMAC, MD2_HMAC_GENERAL = CKM_MD2_HMAC_GENERAL, MD5 = CKM_MD5, MD5_HMAC = CKM_MD5_HMAC, MD5_HMAC_GENERAL = CKM_MD5_HMAC_GENERAL, SHA_1 = CKM_SHA_1, SHA_1_HMAC = CKM_SHA_1_HMAC, SHA_1_HMAC_GENERAL = CKM_SHA_1_HMAC_GENERAL, RIPEMD128 = CKM_RIPEMD128, RIPEMD128_HMAC = CKM_RIPEMD128_HMAC, RIPEMD128_HMAC_GENERAL = CKM_RIPEMD128_HMAC_GENERAL, RIPEMD160 = CKM_RIPEMD160, RIPEMD160_HMAC = CKM_RIPEMD160_HMAC, RIPEMD160_HMAC_GENERAL = CKM_RIPEMD160_HMAC_GENERAL, SHA256 = CKM_SHA256, SHA256_HMAC = CKM_SHA256_HMAC, SHA256_HMAC_GENERAL = CKM_SHA256_HMAC_GENERAL, SHA384 = CKM_SHA384, SHA384_HMAC = CKM_SHA384_HMAC, SHA384_HMAC_GENERAL = CKM_SHA384_HMAC_GENERAL, SHA512 = CKM_SHA512, SHA512_HMAC = CKM_SHA512_HMAC, SHA512_HMAC_GENERAL = CKM_SHA512_HMAC_GENERAL, CAST_KEY_GEN = CKM_CAST_KEY_GEN, CAST_ECB = CKM_CAST_ECB, CAST_CBC = CKM_CAST_CBC, CAST_MAC = CKM_CAST_MAC, CAST_MAC_GENERAL = CKM_CAST_MAC_GENERAL, CAST_CBC_PAD = CKM_CAST_CBC_PAD, CAST3_KEY_GEN = CKM_CAST3_KEY_GEN, CAST3_ECB = CKM_CAST3_ECB, CAST3_CBC = CKM_CAST3_CBC, CAST3_MAC = CKM_CAST3_MAC, CAST3_MAC_GENERAL = CKM_CAST3_MAC_GENERAL, CAST3_CBC_PAD = CKM_CAST3_CBC_PAD, CAST5_KEY_GEN = CKM_CAST5_KEY_GEN, CAST128_KEY_GEN = CKM_CAST128_KEY_GEN, CAST5_ECB = CKM_CAST5_ECB, CAST128_ECB = CKM_CAST128_ECB, CAST5_CBC = CKM_CAST5_CBC, CAST128_CBC = CKM_CAST128_CBC, CAST5_MAC = CKM_CAST5_MAC, CAST128_MAC = CKM_CAST128_MAC, CAST5_MAC_GENERAL = CKM_CAST5_MAC_GENERAL, CAST128_MAC_GENERAL = CKM_CAST128_MAC_GENERAL, CAST5_CBC_PAD = CKM_CAST5_CBC_PAD, CAST128_CBC_PAD = CKM_CAST128_CBC_PAD, RC5_KEY_GEN = CKM_RC5_KEY_GEN, RC5_ECB = CKM_RC5_ECB, RC5_CBC = CKM_RC5_CBC, RC5_MAC = CKM_RC5_MAC, RC5_MAC_GENERAL = CKM_RC5_MAC_GENERAL, RC5_CBC_PAD = CKM_RC5_CBC_PAD, IDEA_KEY_GEN = CKM_IDEA_KEY_GEN, IDEA_ECB = CKM_IDEA_ECB, IDEA_CBC = CKM_IDEA_CBC, IDEA_MAC = CKM_IDEA_MAC, IDEA_MAC_GENERAL = CKM_IDEA_MAC_GENERAL, IDEA_CBC_PAD = CKM_IDEA_CBC_PAD, GENERIC_SECRET_KEY_GEN = CKM_GENERIC_SECRET_KEY_GEN, CONCATENATE_BASE_AND_KEY = CKM_CONCATENATE_BASE_AND_KEY, CONCATENATE_BASE_AND_DATA = CKM_CONCATENATE_BASE_AND_DATA, CONCATENATE_DATA_AND_BASE = CKM_CONCATENATE_DATA_AND_BASE, XOR_BASE_AND_DATA = CKM_XOR_BASE_AND_DATA, EXTRACT_KEY_FROM_KEY = CKM_EXTRACT_KEY_FROM_KEY, SSL3_PRE_MASTER_KEY_GEN = CKM_SSL3_PRE_MASTER_KEY_GEN, SSL3_MASTER_KEY_DERIVE = CKM_SSL3_MASTER_KEY_DERIVE, SSL3_KEY_AND_MAC_DERIVE = CKM_SSL3_KEY_AND_MAC_DERIVE, SSL3_MASTER_KEY_DERIVE_DH = CKM_SSL3_MASTER_KEY_DERIVE_DH, TLS_PRE_MASTER_KEY_GEN = CKM_TLS_PRE_MASTER_KEY_GEN, TLS_MASTER_KEY_DERIVE = CKM_TLS_MASTER_KEY_DERIVE, TLS_KEY_AND_MAC_DERIVE = CKM_TLS_KEY_AND_MAC_DERIVE, TLS_MASTER_KEY_DERIVE_DH = CKM_TLS_MASTER_KEY_DERIVE_DH, SSL3_MD5_MAC = CKM_SSL3_MD5_MAC, SSL3_SHA1_MAC = CKM_SSL3_SHA1_MAC, MD5_KEY_DERIVATION = CKM_MD5_KEY_DERIVATION, MD2_KEY_DERIVATION = CKM_MD2_KEY_DERIVATION, SHA1_KEY_DERIVATION = CKM_SHA1_KEY_DERIVATION, SHA256_KEY_DERIVATION = CKM_SHA256_KEY_DERIVATION, PBE_MD2_DES_CBC = CKM_PBE_MD2_DES_CBC, PBE_MD5_DES_CBC = CKM_PBE_MD5_DES_CBC, PBE_MD5_CAST_CBC = CKM_PBE_MD5_CAST_CBC, PBE_MD5_CAST3_CBC = CKM_PBE_MD5_CAST3_CBC, PBE_MD5_CAST5_CBC = CKM_PBE_MD5_CAST5_CBC, PBE_MD5_CAST128_CBC = CKM_PBE_MD5_CAST128_CBC, PBE_SHA1_CAST5_CBC = CKM_PBE_SHA1_CAST5_CBC, PBE_SHA1_CAST128_CBC = CKM_PBE_SHA1_CAST128_CBC, PBE_SHA1_RC4_128 = CKM_PBE_SHA1_RC4_128, PBE_SHA1_RC4_40 = CKM_PBE_SHA1_RC4_40, PBE_SHA1_DES3_EDE_CBC = CKM_PBE_SHA1_DES3_EDE_CBC, PBE_SHA1_DES2_EDE_CBC = CKM_PBE_SHA1_DES2_EDE_CBC, PBE_SHA1_RC2_128_CBC = CKM_PBE_SHA1_RC2_128_CBC, PBE_SHA1_RC2_40_CBC = CKM_PBE_SHA1_RC2_40_CBC, PKCS5_PBKD2 = CKM_PKCS5_PBKD2, PBA_SHA1_WITH_SHA1_HMAC = CKM_PBA_SHA1_WITH_SHA1_HMAC, KEY_WRAP_LYNKS = CKM_KEY_WRAP_LYNKS, KEY_WRAP_SET_OAEP = CKM_KEY_WRAP_SET_OAEP, SKIPJACK_KEY_GEN = CKM_SKIPJACK_KEY_GEN, SKIPJACK_ECB64 = CKM_SKIPJACK_ECB64, SKIPJACK_CBC64 = CKM_SKIPJACK_CBC64, SKIPJACK_OFB64 = CKM_SKIPJACK_OFB64, SKIPJACK_CFB64 = CKM_SKIPJACK_CFB64, SKIPJACK_CFB32 = CKM_SKIPJACK_CFB32, SKIPJACK_CFB16 = CKM_SKIPJACK_CFB16, SKIPJACK_CFB8 = CKM_SKIPJACK_CFB8, SKIPJACK_WRAP = CKM_SKIPJACK_WRAP, SKIPJACK_PRIVATE_WRAP = CKM_SKIPJACK_PRIVATE_WRAP, SKIPJACK_RELAYX = CKM_SKIPJACK_RELAYX, KEA_KEY_PAIR_GEN = CKM_KEA_KEY_PAIR_GEN, KEA_KEY_DERIVE = CKM_KEA_KEY_DERIVE, FORTEZZA_TIMESTAMP = CKM_FORTEZZA_TIMESTAMP, BATON_KEY_GEN = CKM_BATON_KEY_GEN, BATON_ECB128 = CKM_BATON_ECB128, BATON_ECB96 = CKM_BATON_ECB96, BATON_CBC128 = CKM_BATON_CBC128, BATON_COUNTER = CKM_BATON_COUNTER, BATON_SHUFFLE = CKM_BATON_SHUFFLE, BATON_WRAP = CKM_BATON_WRAP, ECDSA_KEY_PAIR_GEN = CKM_ECDSA_KEY_PAIR_GEN, EC_KEY_PAIR_GEN = CKM_EC_KEY_PAIR_GEN, ECDSA = CKM_ECDSA, ECDSA_SHA1 = CKM_ECDSA_SHA1, ECDH1_DERIVE = CKM_ECDH1_DERIVE, ECDH1_COFACTOR_DERIVE = CKM_ECDH1_COFACTOR_DERIVE, ECMQV_DERIVE = CKM_ECMQV_DERIVE, JUNIPER_KEY_GEN = CKM_JUNIPER_KEY_GEN, JUNIPER_ECB128 = CKM_JUNIPER_ECB128, JUNIPER_CBC128 = CKM_JUNIPER_CBC128, JUNIPER_COUNTER = CKM_JUNIPER_COUNTER, JUNIPER_SHUFFLE = CKM_JUNIPER_SHUFFLE, JUNIPER_WRAP = CKM_JUNIPER_WRAP, FASTHASH = CKM_FASTHASH, AES_KEY_GEN = CKM_AES_KEY_GEN, AES_ECB = CKM_AES_ECB, AES_CBC = CKM_AES_CBC, AES_MAC = CKM_AES_MAC, AES_MAC_GENERAL = CKM_AES_MAC_GENERAL, AES_CBC_PAD = CKM_AES_CBC_PAD, DSA_PARAMETER_GEN = CKM_DSA_PARAMETER_GEN, DH_PKCS_PARAMETER_GEN = CKM_DH_PKCS_PARAMETER_GEN, X9_42_DH_PARAMETER_GEN = CKM_X9_42_DH_PARAMETER_GEN, VENDOR_DEFINED = CKM_VENDOR_DEFINED }; typedef std::set MechanismList; template class FixString: public std::string { public: FixString() {} FixString(const char* const cStr) { *this = std::string(cStr, SIZE); size_type pos(find_last_not_of(" ")); if (pos!=npos) resize(pos+1); else resize(0); } FixString(const unsigned char* const cStr) { *this = std::string((const char*)cStr, SIZE); size_type pos(find_last_not_of(" ")); if (pos!=npos) resize(pos+1); else resize(0); } FixString& operator=(const std::string& other) { std::string::operator=(other); return *this; } FixString& operator=(const char* const cStr) { *this = std::string(cStr, SIZE); size_type pos(find_last_not_of(" ")); if (pos!=npos) resize(pos+1); else resize(0); return *this; } FixString& operator=(const unsigned char* const cStr) { *this = std::string((const char*)cStr, SIZE); size_type pos(find_last_not_of(" ")); if (pos!=npos) resize(pos+1); else resize(0); return *this; } FixString fix() { FixString cpy(*this); cpy.resize(SIZE, ' '); return cpy; } }; typedef CK_MECHANISM_INFO MechanismInfo; struct SlotInfo { FixString<64> slotDescription; FixString<32> manufacturerID; CK_FLAGS flags; CK_VERSION hardwareVersion; CK_VERSION firmwareVersion; }; struct TokenInfo { FixString<32> label; FixString<32> manufacturerID; FixString<16> model; FixString<16> serialNumber; CK_FLAGS flags; CK_ULONG maxSessionCount; CK_ULONG sessionCount; CK_ULONG maxRwSessionCount; CK_ULONG rwSessionCount; CK_ULONG maxPinLen; CK_ULONG minPinLen; CK_ULONG totalPublicMemory; CK_ULONG freePublicMemory; CK_ULONG totalPrivateMemory; CK_ULONG freePrivateMemory; CK_VERSION hardwareVersion; CK_VERSION firmwareVersion; FixString<16> utcTime; }; struct Info { CK_VERSION cryptokiVersion; FixString<32> manufacturerID; CK_FLAGS flags; FixString<32> libraryDescription; CK_VERSION libraryVersion; }; //! to be instanciated before first use class Init { private: friend class Slot; friend class Session; friend class Object; bool _exc; CK_RV _res; CK_FUNCTION_LIST* _fn; Init(const Init&); // forbidden Init& operator=(const Init&); // forbidden //! Initialize Funcion List for this Instance bool functionList(const std::string& library); bool check(CK_RV result, const std::string& context=""); /*! @return error text of last cryptoki call */ std::string error(CK_RV res); public: //! Initialize for a given library (default 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 exc wether exceptions should be thrown */ Init(const std::string& library="onepin-opensc-pkcs11.so", bool exc=true); /*! @name C Like Error Handling You are strongly recommended not to disable exception handling. If you disable it, you must check after every operation whether it was successful or not. These methods provide all you need for that. */ //@{ /*! @return @c true if last cryptoki on this object call was successful */ operator bool(); /*! @return error text of last cryptoki call */ std::string error(); //@} Info info() { Info inf; CK_INFO cInf; //! calls @c C_GetInfo if (!check(_fn->C_GetInfo(&cInf), CRYPTOKI_FN_LOG("C_GetInfo"))) return inf; inf.cryptokiVersion = cInf.cryptokiVersion; inf.manufacturerID = cInf.manufacturerID; inf.flags = cInf.flags; inf.libraryDescription = cInf.libraryDescription; inf.libraryVersion = cInf.libraryVersion; return inf; } //! Get a list of available slots /*! @param tokenPresent whether a token must be inserted into the reader @return list of matching slots */ SlotList slotList(bool tokenPresent=true); }; //! Slot and Token Management class Slot { private: friend class Init; friend class Session; friend class Object; Init* _init; CK_SLOT_ID _slot; CK_RV _res; Slot(Init& init, CK_SLOT_ID slot): _init(&init), _slot(slot), _res(CKR_OK) { } bool check(CK_RV result, const std::string& context="") { _res = result; if (_init->_exc && !*this) if (context.size()) throw access_error(context+": "+error()); else throw access_error(error()); return _res==CKR_OK; } public: /*! @name C Like Error Handling You are strongly recommended not to disable exception handling. If you disable it, you must check after every operation whether it was successful or not. These methods provide all you need for that. */ //@{ /*! @return @c true if last cryptoki on this object call was successful */ operator bool() { return _res==CKR_OK; } /*! @return error text of last cryptoki call */ std::string error() { return _init->error(_res); } //@} MechanismInfo mechanismInfo(Mechanism mechanism) { MechanismInfo info; //! calls @c C_GetMechanismInfo check(_init->_fn->C_GetMechanismInfo(_slot, mechanism, &info), CRYPTOKI_FN_LOG("C_GetMechanismInfo")); return info; } MechanismList mechanismlist() { MechanismList res; CK_ULONG count(0); //! calls @c C_GetMechanismList if (!check(_init->_fn->C_GetMechanismList(_slot, 0, &count), CRYPTOKI_FN_LOG("C_GetMechanismList")) || !count) return res; CK_MECHANISM_TYPE* mechanisms = 0; try { mechanisms = new CK_MECHANISM_TYPE[count]; if (!check(_init->_fn->C_GetMechanismList(_slot, mechanisms, &count), CRYPTOKI_FN_LOG("C_GetMechanismList"))) { delete[] mechanisms; return res; } for (CK_ULONG i(0); i_fn->C_GetSlotInfo(_slot, &cInfo), CRYPTOKI_FN_LOG("C_GetSlotInfo"))) return info; info.slotDescription = cInfo.slotDescription; info.manufacturerID = cInfo.manufacturerID; info.flags = cInfo.flags; info.hardwareVersion = cInfo.hardwareVersion; info.firmwareVersion = cInfo.firmwareVersion; return info; } TokenInfo tokenInfo() { TokenInfo info; //! calls @c C_GetTokenInfo CK_TOKEN_INFO cInfo; if (!check(_init->_fn->C_GetTokenInfo(_slot, &cInfo), CRYPTOKI_FN_LOG("C_GetTokenInfo"))) return info; info.label = cInfo.label; info.manufacturerID = cInfo.manufacturerID; info.model = cInfo.model; info.serialNumber = cInfo.serialNumber; info.flags = cInfo.flags; info.maxSessionCount = cInfo.ulMaxSessionCount; info.sessionCount = cInfo.ulSessionCount; info.maxRwSessionCount = cInfo.ulMaxRwSessionCount; info.rwSessionCount = cInfo.ulRwSessionCount; info.maxPinLen = cInfo.ulMaxPinLen; info.minPinLen = cInfo.ulMinPinLen; info.totalPublicMemory = cInfo.ulTotalPublicMemory; info.freePublicMemory = cInfo.ulFreePublicMemory; info.totalPrivateMemory = cInfo.ulTotalPrivateMemory; info.freePrivateMemory = cInfo.ulFreePrivateMemory; info.hardwareVersion = cInfo.hardwareVersion; info.firmwareVersion = cInfo.firmwareVersion; info.utcTime = cInfo.utcTime; return info; } std::string inittoken(std::string in) { std::string res; res.resize(in.size()); //! calls @c C_InitToken check(_init->_fn->C_InitToken (_slot, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->()), CRYPTOKI_FN_LOG("C_InitToken")); return res; } /*! @todo Not implemented: @code class SlotEventListener { public: virtual void slotEvent() = 0; } bool registerforslotevent(SlotEventListener&) { //! calls @c C_WaitForSlotEvent return check(_init->_fn->C_WaitForSlotEvent(CK_FLAGS, &_slot, CK_VOID_PTR), CRYPTOKI_FN_LOG("C_WaitForSlotEvent")); } @endcode */ }; //! Session Management //! Not implemented: CK_RV C_CloseAllSessions(CK_SLOT_ID); class Session { private: friend class Object; Slot& _slot; CK_SESSION_HANDLE _session; CK_RV _res; Session(); // forbidden Session(const Session&); // forbidden Session& operator=(const Session&); // forbidden bool check(CK_RV result, const std::string& context="") { _res = result; if (_slot._init->_exc && !*this) if (context.size()) throw access_error(context+": "+error()); else throw access_error(error()); return _res==CKR_OK; } public: //! Opens a new session. /*! @param slot slot to open a session on */ Session(Slot& slot): _slot(slot), _session(0), _res(CKR_OK) { //! calls @c C_OpenSession check(_slot._init->_fn->C_OpenSession(_slot._slot, 0, 0, 0, &_session), CRYPTOKI_FN_LOG("C_OpenSession")); //! @todo pass parameter } //! Closes actual session ~Session() { try { //! calls @c C_CloseSession check(_slot._init->_fn->C_CloseSession(_session), CRYPTOKI_FN_LOG("C_CloseSession")); } catch (...) { if (!std::uncaught_exception()) throw; } } /*! @name C Like Error Handling You are strongly recommended not to disable exception handling. If you disable it, you must check after every operation whether it was successful or not. These methods provide all you need for that. */ //@{ /*! @return @c true if last cryptoki on this object call was successful */ operator bool() { return _res==CKR_OK; } /*! @return error text of last cryptoki call */ std::string error() { return _slot._init->error(_res); } //@} /*! @name Low Level Cryptoki Functions Direct access to the low level cryptoki API. Better use the comfort methods. */ //@{ bool cancel() { //! calls @c C_CancelFunction return check(_slot._init->_fn->C_CancelFunction(_session), CRYPTOKI_FN_LOG("C_CancelFunction")); } std::string decrypt(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_Decrypt check(_slot._init->_fn->C_Decrypt (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_Decrypt")); res.resize(size); return res; } std::string decryptdigestupdate(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_DecryptDigestUpdate check(_slot._init->_fn->C_DecryptDigestUpdate (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_DecryptDigestUpdate")); res.resize(size); return res; } std::string decryptfinal(std::string in) { std::string res; // res.resize(in.size()); // CK_ULONG size(res.size()); //! @todo check if size is ok // //! calls @c C_DecryptFinal // check(_slot._init->_fn->C_DecryptFinal // (_session, // (unsigned char*)in.begin().operator->(), in.size(), // (unsigned char*)res.begin().operator->(), &size), // CRYPTOKI_FN_LOG("C_DecryptFinal")); // res.resize(size); //! @todo check docu return res; } std::string decryptupdate(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_DecryptUpdate check(_slot._init->_fn->C_DecryptUpdate (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_DecryptUpdate")); res.resize(size); return res; } std::string decryptverifyupdate(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_DecryptVerifyUpdate check(_slot._init->_fn->C_DecryptVerifyUpdate (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_DecryptVerifyUpdate")); res.resize(size); return res; } std::string digest(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_Digest check(_slot._init->_fn->C_Digest (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_Digest")); res.resize(size); return res; } std::string digestencryptupdate(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_DigestEncryptUpdate check(_slot._init->_fn->C_DigestEncryptUpdate (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_DigestEncryptUpdate")); res.resize(size); return res; } /*! @todo Not implemented: @code bool digestfinal() { //! calls @c C_DigestFinal return check(_slot._init->_fn->C_DigestFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_DigestFinal")); } @endcode */ /*! @todo Not implemented: @code bool digestinit() { //! calls @c C_DigestInit return check(_slot._init->_fn->C_DigestInit(_session, CK_MECHANISM_PTR), CRYPTOKI_FN_LOG("C_DigestInit")); } @endcode */ /*! @todo Not implemented: @code bool digestupdate() { //! calls @c C_DigestUpdate return check(_slot._init->_fn->C_DigestUpdate(_session, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_DigestUpdate")); } @endcode */ std::string encrypt(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_Encrypt check(_slot._init->_fn->C_Encrypt (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_Encrypt")); res.resize(size); return res; } /*! @todo Not implemented: @code bool encryptfinal() { //! calls @c C_EncryptFinal return check(_slot._init->_fn->C_EncryptFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_EncryptFinal")); } @endcode */ std::string encryptupdate(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_EncryptUpdate check(_slot._init->_fn->C_EncryptUpdate (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_EncryptUpdate")); 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: @code bool findobjectsfinal() { //! calls @c C_FindObjectsFinal return check(_slot._init->_fn->C_FindObjectsFinal(_session), CRYPTOKI_FN_LOG("C_FindObjectsFinal")); } @endcode */ /*! @todo Not implemented: @code bool findobjectsinit() { //! calls @c C_FindObjectsInit return check(_slot._init->_fn->C_FindObjectsInit(_session, CK_ATTRIBUTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_FindObjectsInit")); } @endcode */ /*! @todo Not implemented: @code bool generaterandom() { //! calls @c C_GenerateRandom return check(_slot._init->_fn->C_GenerateRandom(_session, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_GenerateRandom")); } @endcode */ /*! @todo Not implemented: @code bool getfunctionstatus() { //! calls @c C_GetFunctionStatus return check(_slot._init->_fn->C_GetFunctionStatus(_session), CRYPTOKI_FN_LOG("C_GetFunctionStatus")); } @endcode */ /*! @todo Not implemented: @code bool getoperationstate() { //! calls @c C_GetOperationState return check(_slot._init->_fn->C_GetOperationState(_session, CK_BYTE_PTR, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_GetOperationState")); } @endcode */ /*! @todo Not implemented: @code bool getsessioninfo() { //! calls @c C_GetSessionInfo return check(_slot._init->_fn->C_GetSessionInfo(_session, CK_SESSION_INFO_PTR), CRYPTOKI_FN_LOG("C_GetSessionInfo")); } @endcode */ /*! @todo Not implemented: @code bool initpin() { //! calls @c C_InitPIN return check(_slot._init->_fn->C_InitPIN(_session, CK_CHAR_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_InitPIN")); } @endcode */ /*! @todo Not implemented: @code bool login() { //! calls @c C_Login return check(_slot._init->_fn->C_Login(_session, CK_USER_TYPE, CK_CHAR_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_Login")); } @endcode */ /*! @todo Not implemented: @code bool logout() { //! calls @c C_Logout return check(_slot._init->_fn->C_Logout(_session), CRYPTOKI_FN_LOG("C_Logout")); } @endcode */ /*! @todo Not implemented: @code bool seedrandom() { //! calls @c C_SeedRandom return check(_slot._init->_fn->C_SeedRandom(_session, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_SeedRandom")); } @endcode */ /*! @todo Not implemented: @code bool setpin() { //! calls @c C_SetPIN return check(_slot._init->_fn->C_SetPIN(_session, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_SetPIN")); } @endcode */ std::string sign(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_Sign check(_slot._init->_fn->C_Sign (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_Sign")); res.resize(size); return res; } std::string signencryptupdate(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_SignEncryptUpdate check(_slot._init->_fn->C_SignEncryptUpdate (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_SignEncryptUpdate")); res.resize(size); return res; } /*! @todo Not implemented: @code bool signfinal() { //! calls @c C_SignFinal return check(_slot._init->_fn->C_SignFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_SignFinal")); } @endcode */ std::string signrecover(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_SignRecover check(_slot._init->_fn->C_SignRecover (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_SignRecover")); res.resize(size); return res; } /*! @todo Not implemented: @code bool signupdate() { //! calls @c C_SignUpdate return check(_slot._init->_fn->C_SignUpdate(_session, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_SignUpdate")); } @endcode */ /*! @todo Not implemented: @code bool verify() { //! calls @c C_Verify return check(_slot._init->_fn->C_Verify(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_Verify")); } @endcode */ /*! @todo Not implemented: @code bool verifyfinal() { //! calls @c C_VerifyFinal return check(_slot._init->_fn->C_VerifyFinal(_session, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_VerifyFinal")); } @endcode */ std::string verifyrecover(std::string in) { std::string res; res.resize(in.size()); CK_ULONG size(res.size()); //! @todo check if size is ok //! calls @c C_VerifyRecover check(_slot._init->_fn->C_VerifyRecover (_session, (unsigned char*)in.begin().operator->(), in.size(), (unsigned char*)res.begin().operator->(), &size), CRYPTOKI_FN_LOG("C_VerifyRecover")); res.resize(size); return res; } /*! @todo Not implemented: @code bool verifyupdate() { //! calls @c C_VerifyUpdate return check(_slot._init->_fn->C_VerifyUpdate(_session, CK_BYTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_VerifyUpdate")); } @endcode */ //@} }; class Object { private: friend class Session; Session& _session; CK_RV _res; bool check(CK_RV result, const std::string& context="") { _res = result; if (_session._slot._init->_exc && !*this) if (context.size()) throw access_error(context+": "+error()); else throw access_error(error()); return _res==CKR_OK; } Object(); //! forbidden Object(Session& session): _session(session), _res(CKR_OK) {} public: /*! @name C Like Error Handling You are strongly recommended not to disable exception handling. If you disable it, you must check after every operation whether it was successful or not. These methods provide all you need for that. */ //@{ /*! @return @c true if last cryptoki on this object call was successful */ operator bool() { return _res==CKR_OK; } /*! @return error text of last cryptoki call */ std::string error() { return _session._slot._init->error(_res); } //@} /*! @todo Not implemented: @code bool copyobject() { //! calls @c C_CopyObject return check(_session._slot._init->_fn->C_CopyObject(_session, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR), CRYPTOKI_FN_LOG("C_CopyObject")); } @endcode */ /*! @todo Not implemented: @code bool createobject() { //! calls @c C_CreateObject return check(_session._slot._init->_fn->C_CreateObject(_session, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR), CRYPTOKI_FN_LOG("C_CreateObject")); } @endcode */ /*! @todo Not implemented: @code bool decryptinit() { //! calls @c C_DecryptInit return check(_session._slot._init->_fn->C_DecryptInit(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_DecryptInit")); } @endcode */ /*! @todo Not implemented: @code bool derivekey() { //! calls @c C_DeriveKey return check(_session._slot._init->_fn->C_DeriveKey(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR), CRYPTOKI_FN_LOG("C_DeriveKey")); } @endcode */ /*! @todo Not implemented: @code bool destroyobject() { //! calls @c C_DestroyObject return check(_session._slot._init->_fn->C_DestroyObject(_session, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_DestroyObject")); } @endcode */ /*! @todo Not implemented: @code bool digestkey() { //! calls @c C_DigestKey return check(_session._slot._init->_fn->C_DigestKey(_session, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_DigestKey")); } @endcode */ /*! @todo Not implemented: @code bool encryptinit() { //! calls @c C_EncryptInit return check(_session._slot._init->_fn->C_EncryptInit(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_EncryptInit")); } @endcode */ /*! @todo Not implemented: @code bool findobjects() { //! calls @c C_FindObjects return check(_session._slot._init->_fn->C_FindObjects(_session, CK_OBJECT_HANDLE_PTR, CK_ULONG, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_FindObjects")); } @endcode */ /*! @todo Not implemented: @code bool generatekey() { //! calls @c C_GenerateKey return check(_session._slot._init->_fn->C_GenerateKey(_session, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR), CRYPTOKI_FN_LOG("C_GenerateKey")); } @endcode */ /*! @todo Not implemented: @code bool generatekeypair() { //! calls @c C_GenerateKeyPair return check(_session._slot._init->_fn->C_GenerateKeyPair(_session, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR), CRYPTOKI_FN_LOG("C_GenerateKeyPair")); } @endcode */ /*! @todo Not implemented: @code bool getattributevalue() { //! calls @c C_GetAttributeValue return check(_session._slot._init->_fn->C_GetAttributeValue(_session, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_GetAttributeValue")); } @endcode */ /*! @todo Not implemented: @code bool getobjectsize() { //! calls @c C_GetObjectSize return check(_session._slot._init->_fn->C_GetObjectSize(_session, CK_OBJECT_HANDLE, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_GetObjectSize")); } @endcode */ /*! @todo Not implemented: @code bool setattributevalue() { //! calls @c C_SetAttributeValue return check(_session._slot._init->_fn->C_SetAttributeValue(_session, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG), CRYPTOKI_FN_LOG("C_SetAttributeValue")); } @endcode */ /*! @todo Not implemented: @code bool setoperationstate() { //! calls @c C_SetOperationState return check(_session._slot._init->_fn->C_SetOperationState(_session, CK_BYTE_PTR, CK_ULONG, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_SetOperationState")); } @endcode */ /*! @todo Not implemented: @code bool signinit() { //! calls @c C_SignInit return check(_session._slot._init->_fn->C_SignInit(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_SignInit")); } @endcode */ /*! @todo Not implemented: @code bool signrecoverinit() { //! calls @c C_SignRecoverInit return check(_session._slot._init->_fn->C_SignRecoverInit(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_SignRecoverInit")); } @endcode */ /*! @todo Not implemented: @code bool unwrapkey() { //! calls @c C_UnwrapKey return check(_session._slot._init->_fn->C_UnwrapKey(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR), CRYPTOKI_FN_LOG("C_UnwrapKey")); } @endcode */ /*! @todo Not implemented: @code bool verifyinit() { //! calls @c C_VerifyInit return check(_session._slot._init->_fn->C_VerifyInit(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_VerifyInit")); } @endcode */ /*! @todo Not implemented: @code bool verifyrecoverinit() { //! calls @c C_VerifyRecoverInit return check(_session._slot._init->_fn->C_VerifyRecoverInit(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE), CRYPTOKI_FN_LOG("C_VerifyRecoverInit")); } @endcode */ /*! @todo Not implemented: @code bool wrapkey() { //! calls @c C_WrapKey return check(_session._slot._init->_fn->C_WrapKey(_session, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR), CRYPTOKI_FN_LOG("C_WrapKey")); } @endcode */ }; #endif #ifdef UNDEF_CRYPTOKI_FN_LOG // cleanup if it was set in here #undef CRYPTOKI_FN_LOG #undef CRYPTOKI_QUOTE #endif }