diff --git a/doc/examples/cryptoki-demo.cpp b/doc/examples/cryptoki-demo.cpp new file mode 100644 index 0000000..f9cbf29 --- /dev/null +++ b/doc/examples/cryptoki-demo.cpp @@ -0,0 +1,57 @@ +// g++ -I ../../src -I /usr/include/opencryptoki cryptoki-demo.cpp ../../src/cryptoki.cxx -ldl -ggdb3 +#include +#include + +int main(int argc, char const*const*const argv) try { + cryptoki::Init init(argc==2?argv[1]:"onepin-opensc-pkcs11.so"); + cryptoki::Info inf(init.info()); + std::cout<<"##################### INFO #####################"<slotInfo()); + std::cout<<"##################### S-CARD #####################"<tokenInfo()); + std::cout<<"--------------------------------------------------"< int main(int, char const*const*const argv) try { diff --git a/src/cryptoki.cxx b/src/cryptoki.cxx new file mode 100644 index 0000000..0b8f1c4 --- /dev/null +++ b/src/cryptoki.cxx @@ -0,0 +1,208 @@ +/*! @file + + @id $Id$ +*/ +// 1 2 3 4 5 6 7 8 +// 45678901234567890123456789012345678901234567890123456789012345678901234567890 + +#include + +#include +#include +#include + +#include +#define CRYPTOKI_LOG(X) std::clog<<"... "<= 2 + #define CRYPTOKI_FN_LOG(X) (std::string(X " failed in ") \ + +std::string(__PRETTY_FUNCTION__)) + #else + #define CRYPTOKI_FN_LOG(X) X " failed" + #endif + #endif + + bool Init::functionList(const std::string& library) { + void* lib(dlopen(library.c_str(), RTLD_NOW)); + if (!lib) throw exception("open of library failed: "+library); + CK_RV(*fn)(CK_FUNCTION_LIST**) + ((CK_RV(*)(CK_FUNCTION_LIST**))dlsym(lib, "C_GetFunctionList")); + if (!fn) + throw exception("required library symbol C_GetFunctionList not found in " + +library); + //! calls @c C_GetFunctionList + return check(fn(&_fn), CRYPTOKI_FN_LOG("C_GetFunctionList")); + } + + bool Init::check(CK_RV result, const std::string& context) { + _res = result; + if (_exc && !*this) + if (context.size()) + throw access_error(context+": "+error()); + else + throw access_error(error()); + return _res==CKR_OK; + } + + std::string Init::error(CK_RV res) { + switch (res) { + case CKR_OK: return "CKR_OK"; + case CKR_CANCEL: return "CKR_CANCEL"; + case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY"; + case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID"; + case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR"; + case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED"; + case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD"; + case CKR_NO_EVENT: return "CKR_NO_EVENT"; + case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS"; + case CKR_CANT_LOCK: return "CKR_CANT_LOCK"; + case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY"; + case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE"; + case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID"; + case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID"; + case CKR_DATA_INVALID: return "CKR_DATA_INVALID"; + case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE"; + case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR"; + case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY"; + case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED"; + case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID"; + case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE"; + case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED"; + case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL"; + case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED"; + case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID"; + case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE"; + case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT"; + case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED"; + case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED"; + case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED"; + case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE"; + case CKR_KEY_FUNCTION_NOT_PERMITTED: + return "CKR_KEY_FUNCTION_NOT_PERMITTED"; + case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE"; + case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE"; + case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID"; + case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID"; + case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID"; + case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE"; + case CKR_OPERATION_NOT_INITIALIZED: + return "CKR_OPERATION_NOT_INITIALIZED"; + case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT"; + case CKR_PIN_INVALID: return "CKR_PIN_INVALID"; + case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE"; + case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED"; + case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED"; + case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED"; + case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT"; + case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID"; + case CKR_SESSION_PARALLEL_NOT_SUPPORTED: + return "CKR_SESSION_PARALLEL_NOT_SUPPORTED"; + case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY"; + case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS"; + case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS"; + case CKR_SESSION_READ_WRITE_SO_EXISTS: + return "CKR_SESSION_READ_WRITE_SO_EXISTS"; + case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID"; + case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE"; + case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE"; + case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT"; + case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT"; + case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED"; + case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED"; + case CKR_UNWRAPPING_KEY_HANDLE_INVALID: + return "CKR_UNWRAPPING_KEY_HANDLE_INVALID"; + case CKR_UNWRAPPING_KEY_SIZE_RANGE: + return "CKR_UNWRAPPING_KEY_SIZE_RANGE"; + case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: + return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"; + case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN"; + case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN"; + case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED"; + case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID"; + case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: + return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN"; + case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES"; + case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID"; + case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE"; + case CKR_WRAPPING_KEY_HANDLE_INVALID: + return "CKR_WRAPPING_KEY_HANDLE_INVALID"; + case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE"; + case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: + return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"; + case CKR_RANDOM_SEED_NOT_SUPPORTED: + return "CKR_RANDOM_SEED_NOT_SUPPORTED"; + case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG"; + case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID"; + case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL"; + case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID"; + case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE"; + case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE"; + case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED"; + case CKR_CRYPTOKI_ALREADY_INITIALIZED: + return "CKR_CRYPTOKI_ALREADY_INITIALIZED"; + case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD"; + case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED"; + case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED"; + default: { + std::stringstream ss; + ss<<"unknown error code ("<C_Initialize(0), //! @todo add optional argument + CRYPTOKI_FN_LOG("C_Initialize")); + } + + Init::operator bool() { + return _res==CKR_OK; + } + + std::string Init::error() { + return error(_res); + } + + /*! @todo Not implemented: + @code + bool Init::getinfo() { + //! calls @c C_GetInfo + return check(_init._fn->C_GetInfo(CK_INFO_PTR), + CRYPTOKI_FN_LOG("C_GetInfo")); + } + @endcode */ + + SlotList Init::slotList(bool tokenPresent) { + SlotList res; + CK_ULONG count(0); + //! calls @c C_GetSlotList + check(_fn->C_GetSlotList(tokenPresent?TRUE:FALSE, 0, &count), + CRYPTOKI_FN_LOG("C_GetSlotList")); + if (!count || !*this) return res; + CK_SLOT_ID* slots = 0; + try { + do { + delete[] slots; + slots = new CK_SLOT_ID[count]; + _res = _fn->C_GetSlotList(tokenPresent?TRUE:FALSE, slots, &count); + } while (_res==CKR_BUFFER_TOO_SMALL); + check(_res, CRYPTOKI_FN_LOG("C_GetSlotList")); + if (!*this) return res; + for (CK_ULONG i(0); i +#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); + + /*! @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 Session; + friend class Init; + + 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: + + /*! @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; + } + + /*! @todo Not implemented: + @code + bool inittoken() { + //! calls @c C_InitToken + return check(_init->_fn->C_InitToken(_slot, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR), + CRYPTOKI_FN_LOG("C_InitToken")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool waitforslotevent() { + //! calls @c C_WaitForSlotEvent + return check(_init->_fn->C_WaitForSlotEvent(CK_FLAGS, _slot_PTR, CK_VOID_PTR), + CRYPTOKI_FN_LOG("C_WaitForSlotEvent")); + } + @endcode */ + }; + + //! Session Management + //! Not implemented: CK_RV C_CloseAllSessions(CK_SLOT_ID); + class Session { + private: + + 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) { + /*! @todo implement + //! calls @c C_OpenSession + return check(_slot._init->_fn->C_OpenSession(_slot._slot, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, + &_session), + CRYPTOKI_FN_LOG("C_OpenSession")); + */ + } + + //! 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; + } + } + + /*! @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); + } + + /*! @todo Not implemented: + @code + void cancel() { + //! calls @c C_CancelFunction + return check(_slot._init->_fn->C_CancelFunction(_session), + CRYPTOKI_FN_LOG("C_CancelFunction")); + } + @endcode */ + + + /*! @todo Not implemented: + @code + bool decrypt() { + //! calls @c C_Decrypt + return check(_slot._init->_fn->C_Decrypt(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_Decrypt")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool decryptdigestupdate() { + //! calls @c C_DecryptDigestUpdate + return check(_slot._init->_fn->C_DecryptDigestUpdate(_session, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_DecryptDigestUpdate")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool decryptfinal() { + //! calls @c C_DecryptFinal + return check(_slot._init->_fn->C_DecryptFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_DecryptFinal")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool decryptupdate() { + //! calls @c C_DecryptUpdate + return check(_slot._init->_fn->C_DecryptUpdate(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_DecryptUpdate")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool decryptverifyupdate() { + //! calls @c C_DecryptVerifyUpdate + return check(_slot._init->_fn->C_DecryptVerifyUpdate(_session, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_DecryptVerifyUpdate")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool digest() { + //! calls @c C_Digest + return check(_slot._init->_fn->C_Digest(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_Digest")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool digestencryptupdate() { + //! calls @c C_DigestEncryptUpdate + return check(_slot._init->_fn->C_DigestEncryptUpdate(_session, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_DigestEncryptUpdate")); + } + @endcode */ + + /*! @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 */ + + /*! @todo Not implemented: + @code + bool encrypt() { + //! calls @c C_Encrypt + return check(_slot._init->_fn->C_Encrypt(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_Encrypt")); + } + @endcode */ + + /*! @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 */ + + /*! @todo Not implemented: + @code + bool encryptupdate() { + //! calls @c C_EncryptUpdate + return check(_slot._init->_fn->C_EncryptUpdate(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_EncryptUpdate")); + } + @endcode */ + + /*! @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(_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(_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(_init->_fn->C_Logout(_session), + CRYPTOKI_FN_LOG("C_Logout")); + } + @endcode */ + + + /*! @todo Not implemented: + @code + bool seedrandom() { + //! calls @c C_SeedRandom + return check(_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(_init->_fn->C_SetPIN(_session, CK_CHAR_PTR, CK_ULONG, CK_CHAR_PTR, CK_ULONG), + CRYPTOKI_FN_LOG("C_SetPIN")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool sign() { + //! calls @c C_Sign + return check(_init->_fn->C_Sign(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_Sign")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool signencryptupdate() { + //! calls @c C_SignEncryptUpdate + return check(_init->_fn->C_SignEncryptUpdate(_session, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_SignEncryptUpdate")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool signfinal() { + //! calls @c C_SignFinal + return check(_init->_fn->C_SignFinal(_session, CK_BYTE_PTR, CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_SignFinal")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool signrecover() { + //! calls @c C_SignRecover + return check(_init->_fn->C_SignRecover(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_SignRecover")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool signupdate() { + //! calls @c C_SignUpdate + return check(_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(_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(_init->_fn->C_VerifyFinal(_session, CK_BYTE_PTR, CK_ULONG), + CRYPTOKI_FN_LOG("C_VerifyFinal")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool verifyrecover() { + //! calls @c C_VerifyRecover + return check(_init->_fn->C_VerifyRecover(_session, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR), + CRYPTOKI_FN_LOG("C_VerifyRecover")); + } + @endcode */ + + /*! @todo Not implemented: + @code + bool verifyupdate() { + //! calls @c C_VerifyUpdate + return check(_init->_fn->C_VerifyUpdate(_session, CK_BYTE_PTR, CK_ULONG), + CRYPTOKI_FN_LOG("C_VerifyUpdate")); + } + @endcode */ + + }; + +#ifdef NO_OBJECTS_YET //! @todo + class Object { + + private: + + CK_RV _res; + + bool check(CK_RV result, const std::string& context="") { + _res = result; + if (_exc && !*this) + if (context.size()) + throw access_error(context+": "+error()); + else + throw access_error(error()); + return _res==CKR_OK; + } + + public: + + Object(): _res(CKR_OK) {} + + /*! @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 error(_res); + } + + /*! @todo Not implemented: + @code + bool copyobject() { + //! calls @c C_CopyObject + return check(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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(_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 + +} +#endif diff --git a/src/makefile.am b/src/makefile.am index 555fd01..d6305ee 100644 --- a/src/makefile.am +++ b/src/makefile.am @@ -5,7 +5,7 @@ ## 1 2 3 4 5 6 7 8 ## 45678901234567890123456789012345678901234567890123456789012345678901234567890 -include_HEADERS=pcsc.hxx +include_HEADERS = pcsc.hxx cryptoki.hxx if BUILD_WIN else