/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #include #include #include #ifndef WIN32 #include #define CK_PTR * typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; typedef CK_RV (*CK_C_GetFunctionList) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList); #else #include #undef ERROR #endif namespace cryptoki { bool Init::functionList(const std::string& library) { CRYPTOKI_LOG("try to load: "<C_Initialize(0), //! @todo add optional argument CRYPTOKI_FN_LOG("C_Initialize")); } catch (...) { throw access_error(CRYPTOKI_FN_LOG("C_Initialize")+": Error in library"); } Init::operator bool() { CRYPTOKI_LOG("log "<<(_res==CKR_OK?"success":"failed")); return _res==CKR_OK; } std::string Init::error() { CRYPTOKI_LOG("log"); 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) { CRYPTOKI_LOG("log"); 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_fn->C_FindObjectsInit (_session, a, attrs.size()), CRYPTOKI_FN_LOG("C_FindObjectsInit"))) { CK_OBJECT_HANDLE obj; //! calls @c C_FindObjects for (CK_ULONG objs(0); check(_slot._init->_fn->C_FindObjects (_session, &obj, 1, &objs), CRYPTOKI_FN_LOG("C_FindObjects")) && objs; res.push_back(Object(*this, obj))); } //! calls @c C_FindObjectsFinal check(_slot._init->_fn->C_FindObjectsFinal(_session), CRYPTOKI_FN_LOG("C_FindObjectsFinal")); delete[] a; return res; } catch (...) { delete[] a; throw; } } //---------------------------------------------------------------------------- ObjectList Session::find(const Attribute& a) { CRYPTOKI_LOG("log"); AttributeList al; al.push_back(a); return find(al); } //---------------------------------------------------------------------------- ObjectList Session::find(const Attribute& a1, const Attribute& a2) { CRYPTOKI_LOG("log"); AttributeList al; al.push_back(a1); al.push_back(a2); return find(al); } //---------------------------------------------------------------------------- Object Session::create(const std::string& label, const openssl::X509& cert) { CRYPTOKI_LOG("log"); AttributeList attrs; attrs.push_back(Attribute(CKA_CLASS) .from(CKO_CERTIFICATE)); attrs.push_back(Attribute(CKA_TOKEN).from(TRUE)); attrs.push_back(Attribute(CKA_PRIVATE).from(FALSE)); attrs.push_back(Attribute(CKA_MODIFIABLE).from(TRUE)); attrs.push_back(Attribute(CKA_LABEL, label)); attrs.push_back(Attribute(CKA_CERTIFICATE_TYPE) .from(CKC_X_509)); attrs.push_back(Attribute(CKA_SUBJECT, cert.subjectDER())); attrs.push_back(Attribute(CKA_ID, cert.id())); attrs.push_back(Attribute(CKA_ISSUER, cert.issuerDER())); attrs.push_back(Attribute(CKA_SERIAL_NUMBER, cert.serial())); attrs.push_back(Attribute(CKA_VALUE, cert.valueDER())); CRYPTOKI_LOG("create: serial = "<(CKO_PRIVATE_KEY)); attrs.push_back(Attribute(CKA_TOKEN).from(TRUE)); attrs.push_back(Attribute(CKA_PRIVATE).from(TRUE)); attrs.push_back(Attribute(CKA_MODIFIABLE).from(TRUE)); attrs.push_back(Attribute(CKA_LABEL, label)); attrs.push_back(Attribute(CKA_KEY_TYPE).from(CKK_RSA)); attrs.push_back(Attribute(CKA_ID, cert.id())); attrs.push_back(Attribute(CKA_DERIVE).from(FALSE)); attrs.push_back(Attribute(CKA_SUBJECT, cert.subjectDER())); attrs.push_back(Attribute(CKA_SENSITIVE).from(TRUE)); attrs.push_back(Attribute(CKA_SECONDARY_AUTH).from(FALSE)); attrs.push_back(Attribute(CKA_DECRYPT) // Required by Doujak/Inverardi .from(usage&(X509v3_KU_DATA_ENCIPHERMENT |usage&X509v3_KU_KEY_ENCIPHERMENT) ?TRUE:FALSE)); // instead of CKA_UNWRAP attrs.push_back(Attribute(CKA_SIGN) .from(usage&(X509v3_KU_DIGITAL_SIGNATURE |X509v3_KU_NON_REPUDIATION) ?TRUE:FALSE)); attrs.push_back(Attribute(CKA_SIGN_RECOVER) // same as CKA_SIGN .from(usage&(X509v3_KU_DIGITAL_SIGNATURE |X509v3_KU_NON_REPUDIATION) ?TRUE:FALSE)); attrs.push_back(Attribute(CKA_EXTRACTABLE).from(FALSE)); attrs.push_back(Attribute(CKA_MODULUS, key.modulus())); attrs.push_back(Attribute(CKA_PUBLIC_EXPONENT, key.publicExponent())); attrs.push_back(Attribute(CKA_PRIVATE_EXPONENT, key.privateExponent())); attrs.push_back(Attribute(CKA_PRIME_1, key.prime1())); attrs.push_back(Attribute(CKA_PRIME_2, key.prime2())); attrs.push_back(Attribute(CKA_EXPONENT_1, key.exponent1())); attrs.push_back(Attribute(CKA_EXPONENT_2, key.exponent2())); attrs.push_back(Attribute(CKA_COEFFICIENT, key.coefficient())); return create(attrs); } //---------------------------------------------------------------------------- Object Session::create(const AttributeList& attrs) { CRYPTOKI_LOG("log"); CK_ATTRIBUTE* a(0); try { if (attrs.size()) { a = new CK_ATTRIBUTE[attrs.size()]; for (AttributeList::size_type i(0); i