diff options
author | Kyungwook Tak <k.tak@samsung.com> | 2016-04-12 19:19:09 +0900 |
---|---|---|
committer | Kyungwook Tak <k.tak@samsung.com> | 2016-04-18 15:36:25 +0900 |
commit | ebd0c830669ce3c374f262a4a1b0e8063f2e443f (patch) | |
tree | 5beec35f8bb1a63845052f3bc17e21945f7e19be | |
parent | 5e4916bf2e05adb0c078aa9eacf24d7686dbee7c (diff) | |
download | key-manager-ebd0c830669ce3c374f262a4a1b0e8063f2e443f.tar.gz key-manager-ebd0c830669ce3c374f262a4a1b0e8063f2e443f.tar.bz2 key-manager-ebd0c830669ce3c374f262a4a1b0e8063f2e443f.zip |
Coding style applied according to style checkersubmit/tizen/20160418.104308accepted/tizen/wearable/20160418.235737accepted/tizen/tv/20160418.235750accepted/tizen/mobile/20160418.235742accepted/tizen/ivi/20160418.235747accepted/tizen/common/20160418.142113
Checker/Guide in http://10.113.136.204/confluence/pages/viewpage.action?pageId=44567756
Change-Id: Ie1c934dcc898b72a68b7a56d43eea4a3298b509c
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
231 files changed, 22580 insertions, 20823 deletions
diff --git a/doc/key-manager-client_doc.h b/doc/key-manager-client_doc.h index 25d2084d..25720cc1 100644 --- a/doc/key-manager-client_doc.h +++ b/doc/key-manager-client_doc.h @@ -16,7 +16,7 @@ #ifndef __TIZEN_CORE_KEY_MANAGER_CLIENT_DOC_H__ #define __TIZEN_CORE_KEY_MANAGER_CLIENT_DOC_H__ /** - * @ingroup CAPI_KEY_MANAGER_MODULE + * @ingroup CAPI_KEY_MANAGER_MODULE * @defgroup CAPI_KEY_MANAGER_CLIENT_MODULE Key Manager Client * @brief It provides APIs accessing on the secure repository and additional secure cryptographic operations. * diff --git a/doc/key-manager_doc.h b/doc/key-manager_doc.h index 3c2e3d7c..d34293f6 100644 --- a/doc/key-manager_doc.h +++ b/doc/key-manager_doc.h @@ -18,7 +18,7 @@ /** * @ingroup CAPI_SECURITY_FRAMEWORK * @defgroup CAPI_KEY_MANAGER_MODULE Key Manager - * @brief The key manager provides a secure repository protected by Tizen platform for keys, certificates, and sensitive data of users and/or their APPs. + * @brief The key manager provides a secure repository protected by Tizen platform for keys, certificates, and sensitive data of users and/or their APPs. * Additionally, the key manager provides secure cryptographic operations for non-exportable keys without revealing key values to clients. * * @section CAPI_KEY_MANAGER_MODULE_OVERVIEW Overview diff --git a/src/include/ckm/ckm-certificate.h b/src/include/ckm/ckm-certificate.h index e864b4b5..5496f0a8 100644 --- a/src/include/ckm/ckm-certificate.h +++ b/src/include/ckm/ckm-certificate.h @@ -27,8 +27,8 @@ #include <ckm/ckm-type.h> extern "C" { -struct x509_st; -typedef struct x509_st X509; + struct x509_st; + typedef struct x509_st X509; } // Central Key Manager namespace @@ -39,16 +39,16 @@ typedef std::shared_ptr<Certificate> CertificateShPtr; class KEY_MANAGER_API Certificate { public: - virtual bool empty() const = 0; + virtual bool empty() const = 0; - // This function will return openssl struct X509*. - // You should not free the memory. - // Memory will be freed in ~Certificate. - virtual X509 *getX509() const = 0; - virtual RawBuffer getDER() const = 0; - virtual ~Certificate() {} + // This function will return openssl struct X509*. + // You should not free the memory. + // Memory will be freed in ~Certificate. + virtual X509 *getX509() const = 0; + virtual RawBuffer getDER() const = 0; + virtual ~Certificate() {} - static CertificateShPtr create(const RawBuffer &rawBuffer, DataFormat format); + static CertificateShPtr create(const RawBuffer &rawBuffer, DataFormat format); }; typedef std::vector<CertificateShPtr> CertificateShPtrVector; diff --git a/src/include/ckm/ckm-control.h b/src/include/ckm/ckm-control.h index af0a3806..dd36f9d1 100644 --- a/src/include/ckm/ckm-control.h +++ b/src/include/ckm/ckm-control.h @@ -36,40 +36,41 @@ typedef std::shared_ptr<Control> ControlShPtr; // used by login manager to unlock user data with global password class KEY_MANAGER_API Control { public: - // decrypt user key with password - virtual int unlockUserKey(uid_t user, const Password &password) = 0; + // decrypt user key with password + virtual int unlockUserKey(uid_t user, const Password &password) = 0; - // remove user key from memory - virtual int lockUserKey(uid_t user) = 0; + // remove user key from memory + virtual int lockUserKey(uid_t user) = 0; - // remove user data from Store and erase key used for encryption - virtual int removeUserData(uid_t user) = 0; + // remove user data from Store and erase key used for encryption + virtual int removeUserData(uid_t user) = 0; - // change password for user - virtual int changeUserPassword(uid_t user, const Password &oldPassword, const Password &newPassword) = 0; + // change password for user + virtual int changeUserPassword(uid_t user, const Password &oldPassword, + const Password &newPassword) = 0; - // This is work around for security-server api - resetPassword that may be called without passing oldPassword. - // This api should not be supported on tizen 3.0 - // User must be already logged in and his DKEK is already loaded into memory in plain text form. - // The service will use DKEK in plain text and encrypt it in encrypted form (using new password). - virtual int resetUserPassword(uid_t user, const Password &newPassword) = 0; + // This is work around for security-server api - resetPassword that may be called without passing oldPassword. + // This api should not be supported on tizen 3.0 + // User must be already logged in and his DKEK is already loaded into memory in plain text form. + // The service will use DKEK in plain text and encrypt it in encrypted form (using new password). + virtual int resetUserPassword(uid_t user, const Password &newPassword) = 0; - // Required for tizen 2.3. - // It will remove all application data owned by application identified - // by smackLabel. This function will remove application data from unlocked - // database only. This function may be used during application uninstallation. - virtual int removeApplicationData(const std::string &smackLabel) = 0; + // Required for tizen 2.3. + // It will remove all application data owned by application identified + // by smackLabel. This function will remove application data from unlocked + // database only. This function may be used during application uninstallation. + virtual int removeApplicationData(const std::string &smackLabel) = 0; - virtual int updateCCMode() = 0; + virtual int updateCCMode() = 0; - virtual int setPermission(uid_t user, - const Alias &alias, - const Label &accessor, - PermissionMask permissionMask) = 0; + virtual int setPermission(uid_t user, + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask) = 0; - virtual ~Control() {} + virtual ~Control() {} - static ControlShPtr create(); + static ControlShPtr create(); }; } // namespace CKM diff --git a/src/include/ckm/ckm-key.h b/src/include/ckm/ckm-key.h index 9095d498..6b586c6d 100644 --- a/src/include/ckm/ckm-key.h +++ b/src/include/ckm/ckm-key.h @@ -30,18 +30,18 @@ typedef std::shared_ptr<Key> KeyShPtr; class KEY_MANAGER_API Key { public: - virtual bool empty() const = 0; - virtual KeyType getType() const = 0; - virtual int getSize() const = 0; - virtual RawBuffer getDER() const = 0; - virtual ~Key() {} - - static KeyShPtr create( - const RawBuffer &rawBuffer, - const Password &password = Password()); - - static KeyShPtr createAES( - const RawBuffer &rawBuffer); + virtual bool empty() const = 0; + virtual KeyType getType() const = 0; + virtual int getSize() const = 0; + virtual RawBuffer getDER() const = 0; + virtual ~Key() {} + + static KeyShPtr create( + const RawBuffer &rawBuffer, + const Password &password = Password()); + + static KeyShPtr createAES( + const RawBuffer &rawBuffer); }; } // namespace CKM diff --git a/src/include/ckm/ckm-manager-async.h b/src/include/ckm/ckm-manager-async.h index 774bb32b..da2d4459 100644 --- a/src/include/ckm/ckm-manager-async.h +++ b/src/include/ckm/ckm-manager-async.h @@ -34,182 +34,184 @@ namespace CKM { // Asynchronous interface to Central Key Manager. This implementation uses // internal thread for connection. Key Manager is not thread safe. -class KEY_MANAGER_API ManagerAsync -{ +class KEY_MANAGER_API ManagerAsync { public: - class Impl; - - ManagerAsync(); - - ManagerAsync(const ManagerAsync&) = delete; - ManagerAsync& operator=(const ManagerAsync&) = delete; - - // Observer will observer custom operation. - struct Observer { - virtual void ReceivedError(int error) = 0; - - virtual void ReceivedSaveKey() {} - virtual void ReceivedSaveCertificate() {} - virtual void ReceivedSaveData() {} - virtual void ReceivedSavePKCS12() {} - - virtual void ReceivedRemovedAlias() {} - - virtual void ReceivedKey(Key &&) {} - virtual void ReceivedCertificate(Certificate &&) {} - virtual void ReceivedData(RawBuffer &&) {} - virtual void ReceivedPKCS12(PKCS12ShPtr &&) {} - - virtual void ReceivedKeyAliasVector(AliasVector &&) {} - virtual void ReceivedCertificateAliasVector(AliasVector &&) {} - virtual void ReceivedDataAliasVector(AliasVector &&) {} - - virtual void ReceivedCreateKeyAES() {} - virtual void ReceivedCreateKeyPair() {} - - virtual void ReceivedGetCertificateChain(CertificateShPtrVector &&) {} - - virtual void ReceivedCreateSignature(RawBuffer &&) {} - virtual void ReceivedVerifySignature() {} - - virtual void ReceivedOCSPCheck(int) {} - - virtual void ReceivedSetPermission() {} - - virtual void ReceivedEncrypted(RawBuffer &&) {} - virtual void ReceivedDecrypted(RawBuffer &&) {} - - virtual ~Observer() {} - }; - - typedef std::shared_ptr<Observer> ObserverPtr; - - virtual ~ManagerAsync(); - - void saveKey( - const ObserverPtr& observer, - const Alias& alias, - const KeyShPtr& key, - const Policy& policy); - void saveCertificate( - const ObserverPtr& observer, - const Alias& alias, - const CertificateShPtr& cert, - const Policy& policy); - void saveData( - const ObserverPtr& observer, - const Alias& alias, - const RawBuffer& data, - const Policy& policy); - void savePKCS12( - const ObserverPtr& observer, - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy); - - void removeAlias(const ObserverPtr& observer, const Alias& alias); - - void getKey(const ObserverPtr& observer, const Alias& alias, const Password& password); - void getCertificate(const ObserverPtr& observer, const Alias& alias, const Password& password); - void getData(const ObserverPtr& observer, const Alias& alias, const Password& password); - - void getPKCS12( - const ObserverPtr& observer, - const Alias &alias, - const Password& passwordKey = Password(), - const Password& passwordCert = Password()); - - // send request for list of all keys/certificates/data that application/user may use - void getKeyAliasVector(const ObserverPtr& observer); - void getCertificateAliasVector(const ObserverPtr& observer); - void getDataAliasVector(const ObserverPtr& observer); - - void createKeyPairRSA( - const ObserverPtr& observer, - int size, - const Alias& privateKeyAlias, - const Alias& publicKeyAlias, - const Policy& policyPrivateKey = Policy(), - const Policy& policyPublicKey = Policy()); - void createKeyPairDSA( - const ObserverPtr& observer, - int size, - const Alias& privateKeyAlias, - const Alias& publicKeyAlias, - const Policy& policyPrivateKey = Policy(), - const Policy& policyPublicKey = Policy()); - void createKeyPairECDSA( - const ObserverPtr& observer, - const ElipticCurve type, - const Alias& privateKeyAlias, - const Alias& publicKeyAlias, - const Policy& policyPrivateKey = Policy(), - const Policy& policyPublicKey = Policy()); - void createKeyAES( - const ObserverPtr& observer, - int sizeBits, - const Alias &keyAlias, - const Policy &policyKey = Policy()); - - void getCertificateChain( - const ObserverPtr& observer, - const CertificateShPtr& certificate, - const CertificateShPtrVector& untrustedCertificates, - const CertificateShPtrVector& trustedCertificates, - bool useSystemTrustedCertificates); - void getCertificateChain( - const ObserverPtr& observer, - const CertificateShPtr& certificate, - const AliasVector& untrustedCertificates, - const AliasVector& trustedCertificates, - bool useSystemTrustedCertificates); - - void createSignature( - const ObserverPtr& observer, - const Alias& privateKeyAlias, - const Password& password, // password for private_key - const RawBuffer& message, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding); - void verifySignature( - const ObserverPtr& observer, - const Alias& publicKeyOrCertAlias, - const Password& password, // password for public_key (optional) - const RawBuffer& message, - const RawBuffer& signature, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding); - - // This function will check all certificates in chain except Root CA. - // This function will delegate task to service. You may use this even - // if application does not have permission to use network. - void ocspCheck( - const ObserverPtr& observer, - const CertificateShPtrVector& certificateChainVector); - - void setPermission( - const ObserverPtr& observer, - const Alias& alias, - const Label& accessor, - PermissionMask permissionMask); - - void encrypt( - const ObserverPtr& observer, - const CryptoAlgorithm& algo, - const Alias& keyAlias, - const Password& password, - const RawBuffer& plain); - - void decrypt( - const ObserverPtr& observer, - const CryptoAlgorithm& algo, - const Alias& keyAlias, - const Password& password, - const RawBuffer& encrypted); + class Impl; + + ManagerAsync(); + + ManagerAsync(const ManagerAsync &) = delete; + ManagerAsync &operator=(const ManagerAsync &) = delete; + + // Observer will observer custom operation. + struct Observer { + virtual void ReceivedError(int error) = 0; + + virtual void ReceivedSaveKey() {} + virtual void ReceivedSaveCertificate() {} + virtual void ReceivedSaveData() {} + virtual void ReceivedSavePKCS12() {} + + virtual void ReceivedRemovedAlias() {} + + virtual void ReceivedKey(Key &&) {} + virtual void ReceivedCertificate(Certificate &&) {} + virtual void ReceivedData(RawBuffer &&) {} + virtual void ReceivedPKCS12(PKCS12ShPtr &&) {} + + virtual void ReceivedKeyAliasVector(AliasVector &&) {} + virtual void ReceivedCertificateAliasVector(AliasVector &&) {} + virtual void ReceivedDataAliasVector(AliasVector &&) {} + + virtual void ReceivedCreateKeyAES() {} + virtual void ReceivedCreateKeyPair() {} + + virtual void ReceivedGetCertificateChain(CertificateShPtrVector &&) {} + + virtual void ReceivedCreateSignature(RawBuffer &&) {} + virtual void ReceivedVerifySignature() {} + + virtual void ReceivedOCSPCheck(int) {} + + virtual void ReceivedSetPermission() {} + + virtual void ReceivedEncrypted(RawBuffer &&) {} + virtual void ReceivedDecrypted(RawBuffer &&) {} + + virtual ~Observer() {} + }; + + typedef std::shared_ptr<Observer> ObserverPtr; + + virtual ~ManagerAsync(); + + void saveKey( + const ObserverPtr &observer, + const Alias &alias, + const KeyShPtr &key, + const Policy &policy); + void saveCertificate( + const ObserverPtr &observer, + const Alias &alias, + const CertificateShPtr &cert, + const Policy &policy); + void saveData( + const ObserverPtr &observer, + const Alias &alias, + const RawBuffer &data, + const Policy &policy); + void savePKCS12( + const ObserverPtr &observer, + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy); + + void removeAlias(const ObserverPtr &observer, const Alias &alias); + + void getKey(const ObserverPtr &observer, const Alias &alias, + const Password &password); + void getCertificate(const ObserverPtr &observer, const Alias &alias, + const Password &password); + void getData(const ObserverPtr &observer, const Alias &alias, + const Password &password); + + void getPKCS12( + const ObserverPtr &observer, + const Alias &alias, + const Password &passwordKey = Password(), + const Password &passwordCert = Password()); + + // send request for list of all keys/certificates/data that application/user may use + void getKeyAliasVector(const ObserverPtr &observer); + void getCertificateAliasVector(const ObserverPtr &observer); + void getDataAliasVector(const ObserverPtr &observer); + + void createKeyPairRSA( + const ObserverPtr &observer, + int size, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + void createKeyPairDSA( + const ObserverPtr &observer, + int size, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + void createKeyPairECDSA( + const ObserverPtr &observer, + const ElipticCurve type, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + void createKeyAES( + const ObserverPtr &observer, + int sizeBits, + const Alias &keyAlias, + const Policy &policyKey = Policy()); + + void getCertificateChain( + const ObserverPtr &observer, + const CertificateShPtr &certificate, + const CertificateShPtrVector &untrustedCertificates, + const CertificateShPtrVector &trustedCertificates, + bool useSystemTrustedCertificates); + void getCertificateChain( + const ObserverPtr &observer, + const CertificateShPtr &certificate, + const AliasVector &untrustedCertificates, + const AliasVector &trustedCertificates, + bool useSystemTrustedCertificates); + + void createSignature( + const ObserverPtr &observer, + const Alias &privateKeyAlias, + const Password &password, // password for private_key + const RawBuffer &message, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding); + void verifySignature( + const ObserverPtr &observer, + const Alias &publicKeyOrCertAlias, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding); + + // This function will check all certificates in chain except Root CA. + // This function will delegate task to service. You may use this even + // if application does not have permission to use network. + void ocspCheck( + const ObserverPtr &observer, + const CertificateShPtrVector &certificateChainVector); + + void setPermission( + const ObserverPtr &observer, + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask); + + void encrypt( + const ObserverPtr &observer, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &plain); + + void decrypt( + const ObserverPtr &observer, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &encrypted); private: - std::unique_ptr<Impl> m_impl; + std::unique_ptr<Impl> m_impl; }; } // namespace CKM diff --git a/src/include/ckm/ckm-manager.h b/src/include/ckm/ckm-manager.h index e5c2043f..c300fff4 100644 --- a/src/include/ckm/ckm-manager.h +++ b/src/include/ckm/ckm-manager.h @@ -38,127 +38,130 @@ typedef std::shared_ptr<Manager> ManagerShPtr; class KEY_MANAGER_API Manager { public: - class Impl; - - Manager(); - Manager(const Manager &) = delete; - Manager& operator=(const Manager&) = delete; - - virtual ~Manager(); - - int saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy); - int saveCertificate(const Alias &alias, const CertificateShPtr &cert, const Policy &policy); - int savePKCS12( - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy); - - /* - * Data must be extractable. If you set extractable bit to false function will - * return ERROR_INPUT_PARAM. - */ - int saveData(const Alias &alias, const RawBuffer &data, const Policy &policy); - - int removeAlias(const Alias &alias); - - int getKey(const Alias &alias, const Password &password, KeyShPtr &key); - int getCertificate( - const Alias &alias, - const Password &password, - CertificateShPtr &certificate); - int getData(const Alias &alias, const Password &password, RawBuffer &data); - int getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs); - int getPKCS12( - const Alias &alias, - const Password &keyPass, - const Password &certPass, - PKCS12ShPtr &pkcs); - - // send request for list of all keys/certificates/data that application/user may use - int getKeyAliasVector(AliasVector &aliasVector); - int getCertificateAliasVector(AliasVector &aliasVector); - int getDataAliasVector(AliasVector &aliasVector); - - int createKeyPairRSA( - const int size, // size in bits [1024, 2048, 4096] - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey = Policy(), - const Policy &policyPublicKey = Policy()); - - int createKeyPairDSA( - const int size, // size in bits [1024, 2048, 3072, 4096] - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey = Policy(), - const Policy &policyPublicKey = Policy()); - - int createKeyPairECDSA( - const ElipticCurve type, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey = Policy(), - const Policy &policyPublicKey = Policy()); - - int createKeyAES( - const int size, // size in bits [128, 192, 256] - const Alias &keyAlias, - const Policy &policyKey = Policy()); - - int getCertificateChain( - const CertificateShPtr &certificate, - const CertificateShPtrVector &untrustedCertificates, - const CertificateShPtrVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector); - - int getCertificateChain( - const CertificateShPtr &certificate, - const AliasVector &untrustedCertificates, - const AliasVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector); - - int createSignature( - const Alias &privateKeyAlias, - const Password &password, // password for private_key - const RawBuffer &message, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding, - RawBuffer &signature); - - int verifySignature( - const Alias &publicKeyOrCertAlias, - const Password &password, // password for public_key (optional) - const RawBuffer &message, - const RawBuffer &signature, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding); - - // This function will check all certificates in chain except Root CA. - // This function will delegate task to service. You may use this even - // if application does not have permission to use network. - int ocspCheck(const CertificateShPtrVector &certificateChainVector, int &ocspStatus); - - int setPermission(const Alias &alias, const Label &accessor, PermissionMask permissionMask); - - int encrypt(const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& plain, - RawBuffer& encrypted); - - int decrypt(const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& encrypted, - RawBuffer& decrypted); - - static ManagerShPtr create(); + class Impl; + + Manager(); + Manager(const Manager &) = delete; + Manager &operator=(const Manager &) = delete; + + virtual ~Manager(); + + int saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy); + int saveCertificate(const Alias &alias, const CertificateShPtr &cert, + const Policy &policy); + int savePKCS12( + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy); + + /* + * Data must be extractable. If you set extractable bit to false function will + * return ERROR_INPUT_PARAM. + */ + int saveData(const Alias &alias, const RawBuffer &data, const Policy &policy); + + int removeAlias(const Alias &alias); + + int getKey(const Alias &alias, const Password &password, KeyShPtr &key); + int getCertificate( + const Alias &alias, + const Password &password, + CertificateShPtr &certificate); + int getData(const Alias &alias, const Password &password, RawBuffer &data); + int getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs); + int getPKCS12( + const Alias &alias, + const Password &keyPass, + const Password &certPass, + PKCS12ShPtr &pkcs); + + // send request for list of all keys/certificates/data that application/user may use + int getKeyAliasVector(AliasVector &aliasVector); + int getCertificateAliasVector(AliasVector &aliasVector); + int getDataAliasVector(AliasVector &aliasVector); + + int createKeyPairRSA( + const int size, // size in bits [1024, 2048, 4096] + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + + int createKeyPairDSA( + const int size, // size in bits [1024, 2048, 3072, 4096] + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + + int createKeyPairECDSA( + const ElipticCurve type, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + + int createKeyAES( + const int size, // size in bits [128, 192, 256] + const Alias &keyAlias, + const Policy &policyKey = Policy()); + + int getCertificateChain( + const CertificateShPtr &certificate, + const CertificateShPtrVector &untrustedCertificates, + const CertificateShPtrVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector); + + int getCertificateChain( + const CertificateShPtr &certificate, + const AliasVector &untrustedCertificates, + const AliasVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector); + + int createSignature( + const Alias &privateKeyAlias, + const Password &password, // password for private_key + const RawBuffer &message, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding, + RawBuffer &signature); + + int verifySignature( + const Alias &publicKeyOrCertAlias, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding); + + // This function will check all certificates in chain except Root CA. + // This function will delegate task to service. You may use this even + // if application does not have permission to use network. + int ocspCheck(const CertificateShPtrVector &certificateChainVector, + int &ocspStatus); + + int setPermission(const Alias &alias, const Label &accessor, + PermissionMask permissionMask); + + int encrypt(const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &plain, + RawBuffer &encrypted); + + int decrypt(const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &encrypted, + RawBuffer &decrypted); + + static ManagerShPtr create(); private: - std::unique_ptr<Impl> m_impl; + std::unique_ptr<Impl> m_impl; }; } // namespace CKM diff --git a/src/include/ckm/ckm-password.h b/src/include/ckm/ckm-password.h index efd891ab..cfeaeb1e 100644 --- a/src/include/ckm/ckm-password.h +++ b/src/include/ckm/ckm-password.h @@ -27,7 +27,8 @@ namespace CKM { -typedef std::basic_string<char, std::char_traits<char>, std_erase_on_dealloc<char>> Password; +typedef std::basic_string<char, std::char_traits<char>, std_erase_on_dealloc<char>> + Password; } // namespace CKM diff --git a/src/include/ckm/ckm-pkcs12.h b/src/include/ckm/ckm-pkcs12.h index f00e5f69..d90d6f46 100644 --- a/src/include/ckm/ckm-pkcs12.h +++ b/src/include/ckm/ckm-pkcs12.h @@ -36,17 +36,18 @@ typedef std::shared_ptr<PKCS12> PKCS12ShPtr; class KEY_MANAGER_API PKCS12 { public: - virtual KeyShPtr getKey() const = 0; + virtual KeyShPtr getKey() const = 0; - virtual CertificateShPtr getCertificate() const = 0; + virtual CertificateShPtr getCertificate() const = 0; - virtual CertificateShPtrVector getCaCertificateShPtrVector() const = 0; + virtual CertificateShPtrVector getCaCertificateShPtrVector() const = 0; - virtual bool empty() const = 0; + virtual bool empty() const = 0; - virtual ~PKCS12() {} + virtual ~PKCS12() {} - static PKCS12ShPtr create(const RawBuffer &rawData, const Password &password = Password()); + static PKCS12ShPtr create(const RawBuffer &rawData, + const Password &password = Password()); }; } // namespace CKM diff --git a/src/include/ckm/ckm-raw-buffer.h b/src/include/ckm/ckm-raw-buffer.h index 6ac4ab61..8ae908f0 100644 --- a/src/include/ckm/ckm-raw-buffer.h +++ b/src/include/ckm/ckm-raw-buffer.h @@ -30,65 +30,67 @@ namespace CKM { template <typename T> struct std_erase_on_dealloc { - // MJK: if re-factoring, remember not to inherit from the std::allocator ! - // MJK: to be replaced with much shorter version once std::allocator_traits - // becomes supported in STL containers (i.e. list, vector and string) - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - std_erase_on_dealloc() = default; - - template <typename U> - std_erase_on_dealloc(const std_erase_on_dealloc<U>&) {} - - T* allocate(std::size_t n) - { - return static_cast<T*>(::operator new(n*sizeof(T))); - } - - void deallocate(T* ptr, std::size_t n) - { - // clear the memory before deleting - memset(ptr, 0 , n * sizeof(T)); - ::operator delete(ptr); - } - - template<typename _Tp1> - struct rebind { - typedef std_erase_on_dealloc<_Tp1> other; - }; - - void construct(pointer p, const T& val) - { - new (p) T(val); - } - - void destroy(pointer p) - { - p->~T(); - } - - size_type max_size() const - { - return size_type(-1); - } + // MJK: if re-factoring, remember not to inherit from the std::allocator ! + // MJK: to be replaced with much shorter version once std::allocator_traits + // becomes supported in STL containers (i.e. list, vector and string) + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T *pointer; + typedef const T *const_pointer; + typedef T &reference; + typedef const T &const_reference; + typedef T value_type; + + std_erase_on_dealloc() = default; + + template <typename U> + std_erase_on_dealloc(const std_erase_on_dealloc<U> &) {} + + T *allocate(std::size_t n) + { + return static_cast<T *>(::operator new(n * sizeof(T))); + } + + void deallocate(T *ptr, std::size_t n) + { + // clear the memory before deleting + memset(ptr, 0 , n * sizeof(T)); + ::operator delete(ptr); + } + + template<typename _Tp1> + struct rebind { + typedef std_erase_on_dealloc<_Tp1> other; + }; + + void construct(pointer p, const T &val) + { + new(p) T(val); + } + + void destroy(pointer p) + { + p->~T(); + } + + size_type max_size() const + { + return size_type(-1); + } }; template <typename T, typename U> -inline bool operator == (const std_erase_on_dealloc<T>&, const std_erase_on_dealloc<U>&) +inline bool operator==(const std_erase_on_dealloc<T> &, + const std_erase_on_dealloc<U> &) { - return true; + return true; } template <typename T, typename U> -inline bool operator != (const std_erase_on_dealloc<T>& a, const std_erase_on_dealloc<U>& b) +inline bool operator!=(const std_erase_on_dealloc<T> &a, + const std_erase_on_dealloc<U> &b) { - return !(a == b); + return !(a == b); } @@ -104,7 +106,7 @@ inline bool operator != (const std_erase_on_dealloc<T>& a, const std_erase_on_de */ template <typename T> struct SafeBuffer { - typedef std::vector<T, std_erase_on_dealloc<T>> Type; + typedef std::vector<T, std_erase_on_dealloc<T>> Type; }; // used to pass password and raw key data diff --git a/src/include/ckm/ckm-type.h b/src/include/ckm/ckm-type.h index 7b91d99e..e534384c 100644 --- a/src/include/ckm/ckm-type.h +++ b/src/include/ckm/ckm-type.h @@ -43,188 +43,201 @@ typedef std::string Label; typedef std::vector<Alias> AliasVector; enum class KeyType : int { - KEY_NONE = 0, - KEY_RSA_PUBLIC, - KEY_RSA_PRIVATE, - KEY_ECDSA_PUBLIC, - KEY_ECDSA_PRIVATE, - KEY_DSA_PUBLIC, - KEY_DSA_PRIVATE, - KEY_AES + KEY_NONE = 0, + KEY_RSA_PUBLIC, + KEY_RSA_PRIVATE, + KEY_ECDSA_PUBLIC, + KEY_ECDSA_PRIVATE, + KEY_DSA_PUBLIC, + KEY_DSA_PRIVATE, + KEY_AES }; enum class DataFormat : int { - FORM_DER_BASE64 = 0, - FORM_DER, - FORM_PEM + FORM_DER_BASE64 = 0, + FORM_DER, + FORM_PEM }; enum class ElipticCurve : int { - prime192v1 = 0, - prime256v1, - secp384r1 + prime192v1 = 0, + prime256v1, + secp384r1 }; enum class CertificateFieldId : int { - ISSUER = 0, - SUBJECT + ISSUER = 0, + SUBJECT }; struct Policy { - Policy(const Password &pass = Password(), bool extract = true) - : password(pass) - , extractable(extract) - {} - virtual ~Policy() {} - Password password; // byte array used to encrypt data inside CKM - bool extractable; // if true key may be extracted from storage + Policy(const Password &pass = Password(), bool extract = true) : + password(pass), extractable(extract) {} + virtual ~Policy() {} + Password password; // byte array used to encrypt data inside CKM + bool extractable; // if true key may be extracted from storage }; enum class HashAlgorithm : int { - NONE = 0, - SHA1, - SHA256, - SHA384, - SHA512 + NONE = 0, + SHA1, + SHA256, + SHA384, + SHA512 }; enum class RSAPaddingAlgorithm : int { - NONE = 0, - PKCS1, - X931 + NONE = 0, + PKCS1, + X931 }; enum class DBCMAlgType : int { - NONE = 0, - AES_GCM_256, - COUNT + NONE = 0, + AES_GCM_256, + COUNT }; typedef int PermissionMask; -enum Permission: int { - NONE = 0x00, - READ = 0x01, - REMOVE = 0x02 - // keep in sync with ckmc_permission_e ! +enum Permission : int { + NONE = 0x00, + READ = 0x01, + REMOVE = 0x02 + // keep in sync with ckmc_permission_e ! }; // algorithm parameters enum class ParamName : int { - ALGO_TYPE = 1, // If there's no such param, the service will try to deduce the algorithm - // type from the key. - - // encryption & decryption - ED_IV = 101, - ED_CTR_LEN, - ED_AAD, - ED_TAG_LEN, - ED_LABEL, - - // key generation - GEN_KEY_LEN = 201, - GEN_EC, // elliptic curve (ElipticCurve) - - // sign & verify - SV_HASH_ALGO = 301, // hash algorithm (HashAlgorithm) - SV_RSA_PADDING, // RSA padding (RSAPaddingAlgorithm) - - // special values marking valid values range - FIRST = ALGO_TYPE, - LAST = SV_RSA_PADDING + ALGO_TYPE = 1, // If there's no such param, the service will try to deduce the algorithm + // type from the key. + + // encryption & decryption + ED_IV = 101, + ED_CTR_LEN, + ED_AAD, + ED_TAG_LEN, + ED_LABEL, + + // key generation + GEN_KEY_LEN = 201, + GEN_EC, // elliptic curve (ElipticCurve) + + // sign & verify + SV_HASH_ALGO = 301, // hash algorithm (HashAlgorithm) + SV_RSA_PADDING, // RSA padding (RSAPaddingAlgorithm) + + // special values marking valid values range + FIRST = ALGO_TYPE, + LAST = SV_RSA_PADDING }; // algorithm types (ALGO_TYPE param) enum class AlgoType : int { - AES_CTR = 1, - AES_CBC, - AES_GCM, - AES_CFB, - RSA_OAEP, - RSA_SV, - DSA_SV, - ECDSA_SV, - RSA_GEN, - DSA_GEN, - ECDSA_GEN, - AES_GEN, + AES_CTR = 1, + AES_CBC, + AES_GCM, + AES_CFB, + RSA_OAEP, + RSA_SV, + DSA_SV, + ECDSA_SV, + RSA_GEN, + DSA_GEN, + ECDSA_GEN, + AES_GEN, }; // cryptographic algorithm description class KEY_MANAGER_API CryptoAlgorithm { public: - template <typename T> - bool getParam(ParamName name, T& value) const; + template <typename T> + bool getParam(ParamName name, T &value) const; - // returns false if param 'name' is invalid - template <typename T> - bool setParam(ParamName name, const T& value); + // returns false if param 'name' is invalid + template <typename T> + bool setParam(ParamName name, const T &value); protected: - class BaseParam { - public: - virtual bool getBuffer(RawBuffer&) const { return false; } - virtual bool getInt(uint64_t&) const { return false; } - virtual ~BaseParam() {} - - protected: - BaseParam() {} - }; - typedef std::shared_ptr<BaseParam> BaseParamPtr; - - class BufferParam : public BaseParam { - public: - bool getBuffer(RawBuffer& buffer) const; - static BaseParamPtr create(const RawBuffer& buffer); - private: - explicit BufferParam(const RawBuffer& value) : m_buffer(value) {} - - RawBuffer m_buffer; - }; - - class IntParam : public BaseParam { - public: - static BaseParamPtr create(uint64_t value); - bool getInt(uint64_t& value) const; - private: - explicit IntParam(uint64_t value) : m_int(value) {} - - uint64_t m_int; - }; - - std::map<ParamName, BaseParamPtr> m_params; + class BaseParam { + public: + virtual bool getBuffer(RawBuffer &) const + { + return false; + } + + virtual bool getInt(uint64_t &) const + { + return false; + } + + virtual ~BaseParam() {} + + protected: + BaseParam() {} + }; + + typedef std::shared_ptr<BaseParam> BaseParamPtr; + + class BufferParam : public BaseParam { + public: + bool getBuffer(RawBuffer &buffer) const; + static BaseParamPtr create(const RawBuffer &buffer); + + private: + explicit BufferParam(const RawBuffer &value) : m_buffer(value) {} + + RawBuffer m_buffer; + }; + + class IntParam : public BaseParam { + public: + static BaseParamPtr create(uint64_t value); + bool getInt(uint64_t &value) const; + + private: + explicit IntParam(uint64_t value) : m_int(value) {} + + uint64_t m_int; + }; + + std::map<ParamName, BaseParamPtr> m_params; }; template <typename T> -bool CryptoAlgorithm::getParam(ParamName name, T& value) const +bool CryptoAlgorithm::getParam(ParamName name, T &value) const { - auto param = m_params.find(name); - if (param == m_params.end()) - return false; - - assert(param->second); - - uint64_t valueTmp; - if (param->second->getInt(valueTmp)) { - value = static_cast<T>(valueTmp); - return true; - } - return false; + auto param = m_params.find(name); + + if (param == m_params.end()) + return false; + + assert(param->second); + + uint64_t valueTmp; + + if (param->second->getInt(valueTmp)) { + value = static_cast<T>(valueTmp); + return true; + } + + return false; } template <> -bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) const; +bool CryptoAlgorithm::getParam(ParamName name, RawBuffer &value) const; template <typename T> -bool CryptoAlgorithm::setParam(ParamName name, const T& value) +bool CryptoAlgorithm::setParam(ParamName name, const T &value) { - if (name < ParamName::FIRST || name > ParamName::LAST) - return false; - m_params[name] = IntParam::create(static_cast<uint64_t>(value)); - return true; + if (name < ParamName::FIRST || name > ParamName::LAST) + return false; + + m_params[name] = IntParam::create(static_cast<uint64_t>(value)); + return true; } template <> -bool CryptoAlgorithm::setParam(ParamName name, const RawBuffer& value); +bool CryptoAlgorithm::setParam(ParamName name, const RawBuffer &value); } // namespace CKM diff --git a/src/include/ckmc/ckmc-control.h b/src/include/ckmc/ckmc-control.h index 6666950a..dc7670fb 100644 --- a/src/include/ckmc/ckmc-control.h +++ b/src/include/ckmc/ckmc-control.h @@ -141,7 +141,8 @@ int ckmc_remove_user_data(uid_t user); * @see ckmc_remove_user_data() * @see ckmc_reset_user_password() */ -int ckmc_change_user_password(uid_t user, const char *old_password, const char *new_password); +int ckmc_change_user_password(uid_t user, const char *old_password, + const char *new_password); /** * @brief Changes a password for a user without old password. @@ -202,10 +203,10 @@ int ckmc_reset_user_password(uid_t user, const char *new_password); * @see ckmc_set_permission() */ int ckmc_allow_access_by_adm(uid_t user, - const char *owner, - const char *alias, - const char *accessor, - ckmc_access_right_e granted); + const char *owner, + const char *alias, + const char *accessor, + ckmc_access_right_e granted); /** * @brief Allows another application to access client's application data @@ -237,7 +238,8 @@ int ckmc_allow_access_by_adm(uid_t user, * * @see ckmc_set_permission() */ -int ckmc_set_permission_by_adm(uid_t user, const char *alias, const char *accessor, int mask); +int ckmc_set_permission_by_adm(uid_t user, const char *alias, + const char *accessor, int mask); /** @@ -271,7 +273,8 @@ int ckmc_set_permission_by_adm(uid_t user, const char *alias, const char *access * @see ckmc_set_permission() * @see ckmc_set_permission_by_adm() */ -int ckmc_deny_access_by_adm(uid_t user, const char *owner, const char *alias, const char *accessor); +int ckmc_deny_access_by_adm(uid_t user, const char *owner, const char *alias, + const char *accessor); /** * @} diff --git a/src/include/ckmc/ckmc-error.h b/src/include/ckmc/ckmc-error.h index 52cbb226..082c887e 100644 --- a/src/include/ckmc/ckmc-error.h +++ b/src/include/ckmc/ckmc-error.h @@ -36,30 +36,30 @@ extern "C" { * @since_tizen 2.3 */ typedef enum { - CKMC_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ - CKMC_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ - CKMC_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - CKMC_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ - CKMC_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Device needed to run API is not supported*/ + CKMC_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + CKMC_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid function parameter */ + CKMC_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + CKMC_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + CKMC_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Device needed to run API is not supported*/ - CKMC_ERROR_SOCKET = TIZEN_ERROR_KEY_MANAGER | 0x01, /**< Socket error between client and Central Key Manager */ - CKMC_ERROR_BAD_REQUEST = TIZEN_ERROR_KEY_MANAGER | 0x02, /**< Invalid request from client */ - CKMC_ERROR_BAD_RESPONSE = TIZEN_ERROR_KEY_MANAGER | 0x03, /**< Invalid response from Central Key Manager */ - CKMC_ERROR_SEND_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x04, /**< Transmitting request failed */ - CKMC_ERROR_RECV_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x05, /**< Receiving response failed */ - CKMC_ERROR_AUTHENTICATION_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x06, /**< Optional password which used when saving is incorrect */ - CKMC_ERROR_BUFFER_TOO_SMALL = TIZEN_ERROR_KEY_MANAGER | 0x07, /**< The output buffer size which is passed as parameter is too small */ - CKMC_ERROR_SERVER_ERROR = TIZEN_ERROR_KEY_MANAGER | 0x08, /**< Central Key Manager has been failed for some reason */ - CKMC_ERROR_DB_LOCKED = TIZEN_ERROR_KEY_MANAGER | 0x09, /**< The database was not unlocked - user did not login */ - CKMC_ERROR_DB_ERROR = TIZEN_ERROR_KEY_MANAGER | 0x0A, /**< An internal error inside the database */ - CKMC_ERROR_DB_ALIAS_EXISTS = TIZEN_ERROR_KEY_MANAGER | 0x0B, /**< Provided alias already exists in the database */ - CKMC_ERROR_DB_ALIAS_UNKNOWN = TIZEN_ERROR_KEY_MANAGER | 0x0C, /**< No data for given alias */ - CKMC_ERROR_VERIFICATION_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x0D, /**< CA certificate(s) were unknown and chain could not be created */ - CKMC_ERROR_INVALID_FORMAT = TIZEN_ERROR_KEY_MANAGER | 0x0E, /**< A provided file or binary has not a valid format */ - CKMC_ERROR_FILE_ACCESS_DENIED = TIZEN_ERROR_KEY_MANAGER | 0x0F, /**< A provided file doesn't exist or cannot be accessed in the file system */ - CKMC_ERROR_NOT_EXPORTABLE = TIZEN_ERROR_KEY_MANAGER | 0x10, /**< The data is saved as unexportable so it cannot be leaked */ - CKMC_ERROR_FILE_SYSTEM = TIZEN_ERROR_KEY_MANAGER | 0x11, /**< Save key/certificate/pkcs12 failed because of file system error */ - CKMC_ERROR_UNKNOWN = TIZEN_ERROR_KEY_MANAGER | 0xFF, /**< The error with unknown reason */ + CKMC_ERROR_SOCKET = TIZEN_ERROR_KEY_MANAGER | 0x01, /**< Socket error between client and Central Key Manager */ + CKMC_ERROR_BAD_REQUEST = TIZEN_ERROR_KEY_MANAGER | 0x02, /**< Invalid request from client */ + CKMC_ERROR_BAD_RESPONSE = TIZEN_ERROR_KEY_MANAGER | 0x03, /**< Invalid response from Central Key Manager */ + CKMC_ERROR_SEND_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x04, /**< Transmitting request failed */ + CKMC_ERROR_RECV_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x05, /**< Receiving response failed */ + CKMC_ERROR_AUTHENTICATION_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x06, /**< Optional password which used when saving is incorrect */ + CKMC_ERROR_BUFFER_TOO_SMALL = TIZEN_ERROR_KEY_MANAGER | 0x07, /**< The output buffer size which is passed as parameter is too small */ + CKMC_ERROR_SERVER_ERROR = TIZEN_ERROR_KEY_MANAGER | 0x08, /**< Central Key Manager has been failed for some reason */ + CKMC_ERROR_DB_LOCKED = TIZEN_ERROR_KEY_MANAGER | 0x09, /**< The database was not unlocked - user did not login */ + CKMC_ERROR_DB_ERROR = TIZEN_ERROR_KEY_MANAGER | 0x0A, /**< An internal error inside the database */ + CKMC_ERROR_DB_ALIAS_EXISTS = TIZEN_ERROR_KEY_MANAGER | 0x0B, /**< Provided alias already exists in the database */ + CKMC_ERROR_DB_ALIAS_UNKNOWN = TIZEN_ERROR_KEY_MANAGER | 0x0C, /**< No data for given alias */ + CKMC_ERROR_VERIFICATION_FAILED = TIZEN_ERROR_KEY_MANAGER | 0x0D, /**< CA certificate(s) were unknown and chain could not be created */ + CKMC_ERROR_INVALID_FORMAT = TIZEN_ERROR_KEY_MANAGER | 0x0E, /**< A provided file or binary has not a valid format */ + CKMC_ERROR_FILE_ACCESS_DENIED = TIZEN_ERROR_KEY_MANAGER | 0x0F, /**< A provided file doesn't exist or cannot be accessed in the file system */ + CKMC_ERROR_NOT_EXPORTABLE = TIZEN_ERROR_KEY_MANAGER | 0x10, /**< The data is saved as unexportable so it cannot be leaked */ + CKMC_ERROR_FILE_SYSTEM = TIZEN_ERROR_KEY_MANAGER | 0x11, /**< Save key/certificate/pkcs12 failed because of file system error */ + CKMC_ERROR_UNKNOWN = TIZEN_ERROR_KEY_MANAGER | 0xFF, /**< The error with unknown reason */ } key_manager_error_e; /** diff --git a/src/include/ckmc/ckmc-manager.h b/src/include/ckmc/ckmc-manager.h index bc02ecd9..f0cdc5d5 100644 --- a/src/include/ckmc/ckmc-manager.h +++ b/src/include/ckmc/ckmc-manager.h @@ -81,7 +81,8 @@ extern "C" { * @see #ckmc_key_s * @see #ckmc_policy_s */ -int ckmc_save_key(const char *alias, const ckmc_key_s key, const ckmc_policy_s policy); +int ckmc_save_key(const char *alias, const ckmc_key_s key, + const ckmc_policy_s policy); /** * @deprecated Deprecated since 2.4. [Use ckmc_remove_alias() instead] @@ -185,7 +186,7 @@ int ckmc_get_key(const char *alias, const char *password, ckmc_key_s **ppkey); * @see ckmc_remove_alias() * @see ckmc_get_key() */ -int ckmc_get_key_alias_list(ckmc_alias_list_s** ppalias_list); +int ckmc_get_key_alias_list(ckmc_alias_list_s **ppalias_list); @@ -223,7 +224,8 @@ int ckmc_get_key_alias_list(ckmc_alias_list_s** ppalias_list); * @see #ckmc_cert_s * @see #ckmc_policy_s */ -int ckmc_save_cert(const char *alias, const ckmc_cert_s cert, const ckmc_policy_s policy); +int ckmc_save_cert(const char *alias, const ckmc_cert_s cert, + const ckmc_policy_s policy); /** * @deprecated Deprecated since 2.4. [Use ckmc_remove_alias() instead] @@ -294,7 +296,8 @@ int ckmc_remove_cert(const char *alias); * @see ckmc_remove_alias() * @see ckmc_get_cert_alias_list() */ -int ckmc_get_cert(const char *alias, const char *password, ckmc_cert_s **ppcert); +int ckmc_get_cert(const char *alias, const char *password, + ckmc_cert_s **ppcert); /** * @brief Gets all alias of certificates which the client can access. @@ -328,7 +331,7 @@ int ckmc_get_cert(const char *alias, const char *password, ckmc_cert_s **ppcert) * @see ckmc_remove_alias() * @see ckmc_get_cert() */ -int ckmc_get_cert_alias_list(ckmc_alias_list_s** ppalias_list); +int ckmc_get_cert_alias_list(ckmc_alias_list_s **ppalias_list); @@ -367,9 +370,9 @@ int ckmc_get_cert_alias_list(ckmc_alias_list_s** ppalias_list); * @see #ckmc_policy_s */ int ckmc_save_pkcs12(const char *alias, - const ckmc_pkcs12_s *pkcs, - const ckmc_policy_s key_policy, - const ckmc_policy_s cert_policy); + const ckmc_pkcs12_s *pkcs, + const ckmc_policy_s key_policy, + const ckmc_policy_s cert_policy); /** * @brief Gets a pkcs12 from key manager. @@ -406,7 +409,8 @@ int ckmc_save_pkcs12(const char *alias, * @see ckmc_save_pkcs12() * @see ckmc_remove_alias() */ -int ckmc_get_pkcs12(const char *alias, const char *key_password, const char *cert_password, ckmc_pkcs12_s **pkcs12); +int ckmc_get_pkcs12(const char *alias, const char *key_password, + const char *cert_password, ckmc_pkcs12_s **pkcs12); /** * @brief Stores a data inside key manager based on the provided policy. @@ -438,7 +442,8 @@ int ckmc_get_pkcs12(const char *alias, const char *key_password, const char *cer * @see #ckmc_raw_buffer_s * @see #ckmc_policy_s */ -int ckmc_save_data(const char *alias, ckmc_raw_buffer_s data, const ckmc_policy_s policy); +int ckmc_save_data(const char *alias, ckmc_raw_buffer_s data, + const ckmc_policy_s policy); /** * @deprecated Deprecated since 2.4. [Use ckmc_remove_alias() instead] @@ -507,7 +512,8 @@ int ckmc_remove_data(const char *alias); * @see ckmc_remove_alias() * @see ckmc_get_data_alias_list() */ -int ckmc_get_data(const char *alias, const char *password, ckmc_raw_buffer_s **ppdata); +int ckmc_get_data(const char *alias, const char *password, + ckmc_raw_buffer_s **ppdata); /** * @brief Gets all alias of data which the client can access. @@ -541,7 +547,7 @@ int ckmc_get_data(const char *alias, const char *password, ckmc_raw_buffer_s **p * @see ckmc_remove_alias() * @see ckmc_get_data() */ -int ckmc_get_data_alias_list(ckmc_alias_list_s** ppalias_list); +int ckmc_get_data_alias_list(ckmc_alias_list_s **ppalias_list); @@ -583,10 +589,10 @@ int ckmc_get_data_alias_list(ckmc_alias_list_s** ppalias_list); * @see ckmc_verify_signature() */ int ckmc_create_key_pair_rsa(const size_t size, - const char *private_key_alias, - const char *public_key_alias, - const ckmc_policy_s policy_private_key, - const ckmc_policy_s policy_public_key); + const char *private_key_alias, + const char *public_key_alias, + const ckmc_policy_s policy_private_key, + const ckmc_policy_s policy_public_key); /** * @brief Creates DSA private/public key pair and stores them inside key manager based on each @@ -625,10 +631,10 @@ int ckmc_create_key_pair_rsa(const size_t size, * @see ckmc_verify_signature() */ int ckmc_create_key_pair_dsa(const size_t size, - const char *private_key_alias, - const char *public_key_alias, - const ckmc_policy_s policy_private_key, - const ckmc_policy_s policy_public_key); + const char *private_key_alias, + const char *public_key_alias, + const ckmc_policy_s policy_private_key, + const ckmc_policy_s policy_public_key); /** * @brief Creates ECDSA private/public key pair and stores them inside key manager based on each @@ -667,10 +673,10 @@ int ckmc_create_key_pair_dsa(const size_t size, * @see #ckmc_ec_type_e */ int ckmc_create_key_pair_ecdsa(const ckmc_ec_type_e type, - const char *private_key_alias, - const char *public_key_alias, - const ckmc_policy_s policy_private_key, - const ckmc_policy_s policy_public_key); + const char *private_key_alias, + const char *public_key_alias, + const ckmc_policy_s policy_private_key, + const ckmc_policy_s policy_public_key); /** * @brief Creates AES key and stores it inside key manager based on the policy. @@ -704,8 +710,8 @@ int ckmc_create_key_pair_ecdsa(const ckmc_ec_type_e type, * @see #ckmc_policy_s */ int ckmc_create_key_aes(size_t size, - const char *key_alias, - ckmc_policy_s key_policy); + const char *key_alias, + ckmc_policy_s key_policy); /** * @brief Creates a signature on a given message using a private key and returns the signature. @@ -751,11 +757,11 @@ int ckmc_create_key_aes(size_t size, * @see #ckmc_rsa_padding_algo_e */ int ckmc_create_signature(const char *private_key_alias, - const char *password, - const ckmc_raw_buffer_s message, - const ckmc_hash_algo_e hash, - const ckmc_rsa_padding_algo_e padding, - ckmc_raw_buffer_s **ppsignature); + const char *password, + const ckmc_raw_buffer_s message, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding, + ckmc_raw_buffer_s **ppsignature); /** * @brief Verifies a given signature on a given message using a public key and returns the signature @@ -799,11 +805,11 @@ int ckmc_create_signature(const char *private_key_alias, * @see #ckmc_rsa_padding_algo_e */ int ckmc_verify_signature(const char *public_key_alias, - const char *password, - const ckmc_raw_buffer_s message, - const ckmc_raw_buffer_s signature, - const ckmc_hash_algo_e hash, - const ckmc_rsa_padding_algo_e padding); + const char *password, + const ckmc_raw_buffer_s message, + const ckmc_raw_buffer_s signature, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding); /** * @brief Verifies a certificate chain and returns that chain. @@ -842,8 +848,8 @@ int ckmc_verify_signature(const char *public_key_alias, * @see ckmc_cert_list_all_free() */ int ckmc_get_cert_chain(const ckmc_cert_s *cert, - const ckmc_cert_list_s *untrustedcerts, - ckmc_cert_list_s **ppcert_chain_list); + const ckmc_cert_list_s *untrustedcerts, + ckmc_cert_list_s **ppcert_chain_list); /** * @deprecated Deprecated since 2.4. [Use ckmc_get_cert_chain() instead] @@ -888,8 +894,8 @@ int ckmc_get_cert_chain(const ckmc_cert_s *cert, * @see ckmc_cert_list_all_free() */ int ckmc_get_cert_chain_with_alias(const ckmc_cert_s *cert, - const ckmc_alias_list_s *untrustedcerts, - ckmc_cert_list_s **ppcert_chain_list); + const ckmc_alias_list_s *untrustedcerts, + ckmc_cert_list_s **ppcert_chain_list); /** * @brief Verifies a certificate chain and returns that chain using user entered trusted and @@ -931,10 +937,10 @@ int ckmc_get_cert_chain_with_alias(const ckmc_cert_s *cert, * @see ckmc_cert_list_all_free() */ int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s *cert, - const ckmc_cert_list_s *untrustedcerts, - const ckmc_cert_list_s *trustedcerts, - const bool use_trustedsystemcerts, - ckmc_cert_list_s **ppcert_chain_list); + const ckmc_cert_list_s *untrustedcerts, + const ckmc_cert_list_s *trustedcerts, + const bool use_trustedsystemcerts, + ckmc_cert_list_s **ppcert_chain_list); /** * @brief Perform OCSP which checks certificate is whether revoked or not. @@ -964,7 +970,8 @@ int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s *cert, * @see ckmc_get_cert_chain()) * @see ckmc_cert_list_all_free() */ -int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e *ocsp_status); +int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, + ckmc_ocsp_status_e *ocsp_status); /** * @deprecated Deprecated since 2.4. [Use ckmc_set_permission() instead] @@ -994,7 +1001,8 @@ int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e * * @see ckmc_deny_access() */ -int ckmc_allow_access(const char *alias, const char *accessor, ckmc_access_right_e granted); +int ckmc_allow_access(const char *alias, const char *accessor, + ckmc_access_right_e granted); /** * @brief Allows another application to access client's application data. @@ -1023,7 +1031,8 @@ int ckmc_allow_access(const char *alias, const char *accessor, ckmc_access_right * * @pre User is already logged in and the user key is already loaded into memory in plain text form. */ -int ckmc_set_permission(const char *alias, const char *accessor, int permissions); +int ckmc_set_permission(const char *alias, const char *accessor, + int permissions); /** * @deprecated Deprecated since 2.4. [Use ckmc_set_permission() instead] @@ -1141,10 +1150,10 @@ int ckmc_remove_alias(const char *alias); * @see #ckmc_algo_type_e */ int ckmc_encrypt_data(ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s decrypted, - ckmc_raw_buffer_s **ppencrypted); + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s decrypted, + ckmc_raw_buffer_s **ppencrypted); /** * @brief Decrypts data using selected key and algorithm. @@ -1193,10 +1202,10 @@ int ckmc_encrypt_data(ckmc_param_list_h params, * @see #ckmc_algo_type_e */ int ckmc_decrypt_data(ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s encrypted, - ckmc_raw_buffer_s **ppdecrypted); + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s encrypted, + ckmc_raw_buffer_s **ppdecrypted); #ifdef __cplusplus } diff --git a/src/include/ckmc/ckmc-type.h b/src/include/ckmc/ckmc-type.h index de1fcf19..4b2ef4df 100644 --- a/src/include/ckmc/ckmc-type.h +++ b/src/include/ckmc/ckmc-type.h @@ -58,7 +58,7 @@ extern "C" { * @see #ckmc_owner_id_separator * @see key-manager_doc.h */ -KEY_MANAGER_CAPI extern char const * const ckmc_label_name_separator; +KEY_MANAGER_CAPI extern char const *const ckmc_label_name_separator; /** * @brief Separator between alias and owner id. @@ -67,7 +67,7 @@ KEY_MANAGER_CAPI extern char const * const ckmc_label_name_separator; * In this case, separator " " (space bar) is used to separate id and alias. * @see key-manager_doc.h */ -KEY_MANAGER_CAPI extern char const * const ckmc_owner_id_separator; +KEY_MANAGER_CAPI extern char const *const ckmc_owner_id_separator; /** * @brief The owner of system database. @@ -78,21 +78,21 @@ KEY_MANAGER_CAPI extern char const * const ckmc_owner_id_separator; * and stored in system database. * Note: Client must have permission to access proper row. */ -KEY_MANAGER_CAPI extern char const * const ckmc_owner_id_system; +KEY_MANAGER_CAPI extern char const *const ckmc_owner_id_system; /** * @brief Enumeration for key types of key manager. * @since_tizen 2.3 */ typedef enum __ckmc_key_type { - CKMC_KEY_NONE = 0, /**< Key type not specified */ - CKMC_KEY_RSA_PUBLIC, /**< RSA public key */ - CKMC_KEY_RSA_PRIVATE, /**< RSA private key */ - CKMC_KEY_ECDSA_PUBLIC, /**< ECDSA public key */ - CKMC_KEY_ECDSA_PRIVATE, /**< ECDSA private key */ - CKMC_KEY_DSA_PUBLIC, /**< DSA public key */ - CKMC_KEY_DSA_PRIVATE, /**< DSA private key */ - CKMC_KEY_AES, /**< AES key */ + CKMC_KEY_NONE = 0, /**< Key type not specified */ + CKMC_KEY_RSA_PUBLIC, /**< RSA public key */ + CKMC_KEY_RSA_PRIVATE, /**< RSA private key */ + CKMC_KEY_ECDSA_PUBLIC, /**< ECDSA public key */ + CKMC_KEY_ECDSA_PRIVATE, /**< ECDSA private key */ + CKMC_KEY_DSA_PUBLIC, /**< DSA public key */ + CKMC_KEY_DSA_PRIVATE, /**< DSA private key */ + CKMC_KEY_AES, /**< AES key */ } ckmc_key_type_e; /** @@ -100,9 +100,9 @@ typedef enum __ckmc_key_type { * @since_tizen 2.3 */ typedef enum __ckmc_data_format { - CKMC_FORM_DER_BASE64 = 0, /**< DER format base64 encoded data */ - CKMC_FORM_DER, /**< DER encoded data */ - CKMC_FORM_PEM /**< PEM encoded data. It consists of the DER format base64 encoded + CKMC_FORM_DER_BASE64 = 0, /**< DER format base64 encoded data */ + CKMC_FORM_DER, /**< DER encoded data */ + CKMC_FORM_PEM /**< PEM encoded data. It consists of the DER format base64 encoded with additional header and footer lines. */ } ckmc_data_format_e; @@ -111,10 +111,10 @@ typedef enum __ckmc_data_format { * @since_tizen 2.3 */ typedef enum __ckmc_ec_type { - CKMC_EC_PRIME192V1 = 0, /**< Elliptic curve domain "secp192r1" listed in "SEC 2" recommended + CKMC_EC_PRIME192V1 = 0, /**< Elliptic curve domain "secp192r1" listed in "SEC 2" recommended elliptic curve domain */ - CKMC_EC_PRIME256V1, /**< "SEC 2" recommended elliptic curve domain - secp256r1 */ - CKMC_EC_SECP384R1 /**< NIST curve P-384(covers "secp384r1", the elliptic curve domain + CKMC_EC_PRIME256V1, /**< "SEC 2" recommended elliptic curve domain - secp256r1 */ + CKMC_EC_SECP384R1 /**< NIST curve P-384(covers "secp384r1", the elliptic curve domain listed in See SEC 2 */ } ckmc_ec_type_e; @@ -123,11 +123,11 @@ typedef enum __ckmc_ec_type { * @since_tizen 2.3 */ typedef enum __ckmc_hash_algo { - CKMC_HASH_NONE = 0, /**< No Hash Algorithm */ - CKMC_HASH_SHA1, /**< Hash Algorithm SHA1 */ - CKMC_HASH_SHA256, /**< Hash Algorithm SHA256 */ - CKMC_HASH_SHA384, /**< Hash Algorithm SHA384 */ - CKMC_HASH_SHA512 /**< Hash Algorithm SHA512 */ + CKMC_HASH_NONE = 0, /**< No Hash Algorithm */ + CKMC_HASH_SHA1, /**< Hash Algorithm SHA1 */ + CKMC_HASH_SHA256, /**< Hash Algorithm SHA256 */ + CKMC_HASH_SHA384, /**< Hash Algorithm SHA384 */ + CKMC_HASH_SHA512 /**< Hash Algorithm SHA512 */ } ckmc_hash_algo_e; /** @@ -135,9 +135,9 @@ typedef enum __ckmc_hash_algo { * @since_tizen 2.3 */ typedef enum __ckmc_rsa_padding_algo { - CKMC_NONE_PADDING = 0, /**< No Padding */ - CKMC_PKCS1_PADDING, /**< PKCS#1 Padding */ - CKMC_X931_PADDING /**< X9.31 padding */ + CKMC_NONE_PADDING = 0, /**< No Padding */ + CKMC_PKCS1_PADDING, /**< PKCS#1 Padding */ + CKMC_X931_PADDING /**< X9.31 padding */ } ckmc_rsa_padding_algo_e; /** @@ -146,8 +146,8 @@ typedef enum __ckmc_rsa_padding_algo { * @since_tizen 2.3 */ typedef enum __ckmc_access_right { - CKMC_AR_READ = 0, /**< Access right for read*/ - CKMC_AR_READ_REMOVE /**< Access right for read and remove*/ + CKMC_AR_READ = 0, /**< Access right for read*/ + CKMC_AR_READ_REMOVE /**< Access right for read and remove*/ } ckmc_access_right_e; /** @@ -155,9 +155,9 @@ typedef enum __ckmc_access_right { * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ typedef enum __ckmc_permission { - CKMC_PERMISSION_NONE = 0x00, /**< Clear permissions */ - CKMC_PERMISSION_READ = 0x01, /**< Eead allowed */ - CKMC_PERMISSION_REMOVE = 0x02 /**< Remove allowed */ + CKMC_PERMISSION_NONE = 0x00, /**< Clear permissions */ + CKMC_PERMISSION_READ = 0x01, /**< Eead allowed */ + CKMC_PERMISSION_REMOVE = 0x02 /**< Remove allowed */ } ckmc_permission_e; /** @@ -165,8 +165,8 @@ typedef enum __ckmc_permission { * @since_tizen 2.3 */ typedef struct __ckmc_raw_buff { - unsigned char* data; /**< Byte array containing binary data */ - size_t size; /**< The size of the binary data */ + unsigned char *data; /**< Byte array containing binary data */ + size_t size; /**< The size of the binary data */ } ckmc_raw_buffer_s; /** @@ -174,10 +174,10 @@ typedef struct __ckmc_raw_buff { * @since_tizen 2.3 */ typedef struct __ckmc_policy { - char* password; /**< Byte array used to encrypt data inside CKM. If it is not null, the data + char *password; /**< Byte array used to encrypt data inside CKM. If it is not null, the data (or key, or certificate) is stored encrypted with this password inside key manager */ - bool extractable; /**< If true key may be extracted from storage */ + bool extractable; /**< If true key may be extracted from storage */ } ckmc_policy_s; /** @@ -185,10 +185,11 @@ typedef struct __ckmc_policy { * @since_tizen 2.3 */ typedef struct __ckmc_key { - unsigned char* raw_key; /**< Byte array of key. raw_key may be encrypted with password */ - size_t key_size; /**< The byte size of raw_key */ - ckmc_key_type_e key_type; /**< The raw_key's type */ - char* password; /**< Byte array used to decrypt data raw_key inside key manager. */ + unsigned char + *raw_key; /**< Byte array of key. raw_key may be encrypted with password */ + size_t key_size; /**< The byte size of raw_key */ + ckmc_key_type_e key_type; /**< The raw_key's type */ + char *password; /**< Byte array used to decrypt data raw_key inside key manager. */ } ckmc_key_s; /** @@ -196,9 +197,9 @@ typedef struct __ckmc_key { * @since_tizen 2.3 */ typedef struct __ckmc_cert { - unsigned char* raw_cert; /**< Byte array of certificate */ - size_t cert_size; /**< Byte size of raw_cert */ - ckmc_data_format_e data_format; /**< Raw_cert's encoding format */ + unsigned char *raw_cert; /**< Byte array of certificate */ + size_t cert_size; /**< Byte size of raw_cert */ + ckmc_data_format_e data_format; /**< Raw_cert's encoding format */ } ckmc_cert_s; /** @@ -206,8 +207,9 @@ typedef struct __ckmc_cert { * @since_tizen 2.3 */ typedef struct __ckmc_alias_list { - char *alias; /**< The name of key, certificate or data stored in key manager */ - struct __ckmc_alias_list *next; /**< The pointer pointing to the next ckmc_alias_list_s */ + char *alias; /**< The name of key, certificate or data stored in key manager */ + struct __ckmc_alias_list + *next; /**< The pointer pointing to the next ckmc_alias_list_s */ } ckmc_alias_list_s; /** @@ -215,8 +217,9 @@ typedef struct __ckmc_alias_list { * @since_tizen 2.3 */ typedef struct __ckmc_cert_list { - ckmc_cert_s *cert; /**< The pointer of ckmc_cert_s */ - struct __ckmc_cert_list *next; /**< The pointer pointing to the next ckmc_cert_list_s */ + ckmc_cert_s *cert; /**< The pointer of ckmc_cert_s */ + struct __ckmc_cert_list + *next; /**< The pointer pointing to the next ckmc_cert_list_s */ } ckmc_cert_list_s; /** @@ -224,15 +227,15 @@ typedef struct __ckmc_cert_list { * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ typedef enum __ckmc_ocsp_status { - CKMC_OCSP_STATUS_GOOD = 0, /**< OCSP status is good */ - CKMC_OCSP_STATUS_REVOKED, /**< The certificate is revoked */ - CKMC_OCSP_STATUS_UNKNOWN, /**< Unknown error */ - CKMC_OCSP_ERROR_UNSUPPORTED, /**< The certificate does not provide OCSP extension */ - CKMC_OCSP_ERROR_INVALID_URL, /**< The invalid URL in certificate OCSP extension */ - CKMC_OCSP_ERROR_INVALID_RESPONSE, /**< The invalid response from OCSP server */ - CKMC_OCSP_ERROR_REMOTE, /**< OCSP remote server error */ - CKMC_OCSP_ERROR_NET, /**< Network connection error */ - CKMC_OCSP_ERROR_INTERNAL /**< OpenSSL API error */ + CKMC_OCSP_STATUS_GOOD = 0, /**< OCSP status is good */ + CKMC_OCSP_STATUS_REVOKED, /**< The certificate is revoked */ + CKMC_OCSP_STATUS_UNKNOWN, /**< Unknown error */ + CKMC_OCSP_ERROR_UNSUPPORTED, /**< The certificate does not provide OCSP extension */ + CKMC_OCSP_ERROR_INVALID_URL, /**< The invalid URL in certificate OCSP extension */ + CKMC_OCSP_ERROR_INVALID_RESPONSE, /**< The invalid response from OCSP server */ + CKMC_OCSP_ERROR_REMOTE, /**< OCSP remote server error */ + CKMC_OCSP_ERROR_NET, /**< Network connection error */ + CKMC_OCSP_ERROR_INTERNAL /**< OpenSSL API error */ } ckmc_ocsp_status_e; /** @@ -240,9 +243,9 @@ typedef enum __ckmc_ocsp_status { * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ typedef struct __ckmc_pkcs12 { - ckmc_key_s *priv_key; /**< The private key, may be null */ - ckmc_cert_s *cert; /**< The certificate, may be null */ - ckmc_cert_list_s *ca_chain; /**< The chain certificate list, may be null */ + ckmc_key_s *priv_key; /**< The private key, may be null */ + ckmc_cert_s *cert; /**< The certificate, may be null */ + ckmc_cert_list_s *ca_chain; /**< The chain certificate list, may be null */ } ckmc_pkcs12_s; /** @@ -252,13 +255,13 @@ typedef struct __ckmc_pkcs12 { * @see #ckmc_algo_type_e */ typedef enum __ckmc_param_name { - CKMC_PARAM_ALGO_TYPE = 1, + CKMC_PARAM_ALGO_TYPE = 1, - CKMC_PARAM_ED_IV = 101, /**< 16B buffer (up to 2^64-1 bytes long in case of AES GCM) */ - CKMC_PARAM_ED_CTR_LEN, /**< integer - ctr length in bits*/ - CKMC_PARAM_ED_AAD, /**< buffer */ - CKMC_PARAM_ED_TAG_LEN, /**< integer - tag length in bits */ - CKMC_PARAM_ED_LABEL /**< buffer */ + CKMC_PARAM_ED_IV = 101, /**< 16B buffer (up to 2^64-1 bytes long in case of AES GCM) */ + CKMC_PARAM_ED_CTR_LEN, /**< integer - ctr length in bits*/ + CKMC_PARAM_ED_AAD, /**< buffer */ + CKMC_PARAM_ED_TAG_LEN, /**< integer - tag length in bits */ + CKMC_PARAM_ED_LABEL /**< buffer */ } ckmc_param_name_e; /** @@ -287,19 +290,19 @@ typedef struct __ckmc_param_list *ckmc_param_list_h; * @see #ckmc_param_name_e */ typedef enum __ckmc_algo_type { - CKMC_ALGO_AES_CTR = 1, /**< AES-CTR algorithm + CKMC_ALGO_AES_CTR = 1, /**< AES-CTR algorithm Supported parameters: - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_AES_CTR(mandatory), - CKMC_PARAM_ED_IV = 16-byte initialization vector(mandatory) - CKMC_PARAM_ED_CTR_LEN = length of counter block in bits (optional, only 128b is supported at the moment) */ - CKMC_ALGO_AES_CBC, /**< AES-CBC algorithm + CKMC_ALGO_AES_CBC, /**< AES-CBC algorithm Supported parameters: - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_AES_CBC(mandatory), - CKMC_PARAM_ED_IV = 16-byte initialization vector(mandatory) */ - CKMC_ALGO_AES_GCM, /**< AES-GCM algorithm + CKMC_ALGO_AES_GCM, /**< AES-GCM algorithm Supported parameters: - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_AES_GCM(mandatory), - CKMC_PARAM_ED_IV = initialization vector(mandatory) @@ -308,12 +311,12 @@ typedef enum __ckmc_algo_type { length 128 is used) - CKMC_PARAM_ED_AAD = additional authentication data(optional) */ - CKMC_ALGO_AES_CFB, /**< AES-CFB algorithm + CKMC_ALGO_AES_CFB, /**< AES-CFB algorithm Supported parameters: - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_AES_CFB(mandatory), - CKMC_PARAM_ED_IV = 16-byte initialization vector(mandatory) */ - CKMC_ALGO_RSA_OAEP /**< RSA-OAEP algorithm + CKMC_ALGO_RSA_OAEP /**< RSA-OAEP algorithm Supported parameters: - CKMC_PARAM_ALGO_TYPE = CKMC_ALGO_RSA_OAEP(required), - CKMC_PARAM_ED_LABEL = label to be associated with the message @@ -347,9 +350,9 @@ typedef enum __ckmc_algo_type { * @see #ckmc_key_s */ int ckmc_key_new(unsigned char *raw_key, - size_t key_size, - ckmc_key_type_e key_type, - char *password, ckmc_key_s **ppkey); + size_t key_size, + ckmc_key_type_e key_type, + char *password, ckmc_key_s **ppkey); /** * @brief Destroys the @a ckmc_key_s handle and releases all its resources. @@ -383,7 +386,8 @@ void ckmc_key_free(ckmc_key_s *key); * @see ckmc_buffer_free() * @see #ckmc_raw_buffer_s */ -int ckmc_buffer_new(unsigned char *data, size_t size, ckmc_raw_buffer_s **ppbuffer); +int ckmc_buffer_new(unsigned char *data, size_t size, + ckmc_raw_buffer_s **ppbuffer); /** * @brief Destroys the @a ckmc_raw_buffer_s handle and releases all its resources. @@ -420,9 +424,9 @@ void ckmc_buffer_free(ckmc_raw_buffer_s *buffer); * @see #ckmc_cert_s */ int ckmc_cert_new(unsigned char *raw_cert, - size_t cert_size, - ckmc_data_format_e data_format, - ckmc_cert_s **ppcert); + size_t cert_size, + ckmc_data_format_e data_format, + ckmc_cert_s **ppcert); /** * @brief Destroys the @a ckmc_cert handle and releases all its resources. @@ -493,9 +497,9 @@ int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert); * @see #ckmc_pkcs12_s */ int ckmc_pkcs12_new(ckmc_key_s *private_key, - ckmc_cert_s *cert, - ckmc_cert_list_s *ca_cert_list, - ckmc_pkcs12_s **pkcs12_bundle); + ckmc_cert_s *cert, + ckmc_cert_list_s *ca_cert_list, + ckmc_pkcs12_s **pkcs12_bundle); /** * @deprecated Deprecated since 2.4. [Use ckmc_pkcs12_load() instead] @@ -536,9 +540,9 @@ int ckmc_pkcs12_new(ckmc_key_s *private_key, * @see #ckmc_cert_list_s */ int ckmc_load_from_pkcs12_file(const char *file_path, - const char *passphrase, - ckmc_key_s **private_key, ckmc_cert_s **cert, - ckmc_cert_list_s **ca_cert_list); + const char *passphrase, + ckmc_key_s **private_key, ckmc_cert_s **cert, + ckmc_cert_list_s **ca_cert_list); /** * @brief Creates a new @a ckmc_pkcs12_s handle from a given PKCS#12 file and returns it. @@ -567,8 +571,8 @@ int ckmc_load_from_pkcs12_file(const char *file_path, * @see #ckmc_pkcs12_s */ int ckmc_pkcs12_load(const char *file_path, - const char *passphrase, - ckmc_pkcs12_s **pkcs12_bundle); + const char *passphrase, + ckmc_pkcs12_s **pkcs12_bundle); /** * @brief Destroys the @a ckmc_pkcs12_s handle and releases all its resources. @@ -631,8 +635,8 @@ int ckmc_alias_list_new(char *alias, ckmc_alias_list_s **ppalias_list); * @see #ckmc_alias_list_s */ int ckmc_alias_list_add(ckmc_alias_list_s *previous, - char *alias, - ckmc_alias_list_s **pplast); + char *alias, + ckmc_alias_list_s **pplast); /** * @brief Destroys the @a ckmc_alias_list_s handle and releases resources of @a ckmc_alias_list_s @@ -710,7 +714,8 @@ int ckmc_cert_list_new(ckmc_cert_s *cert, ckmc_cert_list_s **ppalias_list); * @see ckmc_cert_list_all_free() * @see #ckmc_cert_list_s */ -int ckmc_cert_list_add(ckmc_cert_list_s *previous, ckmc_cert_s *cert, ckmc_cert_list_s **pplast); +int ckmc_cert_list_add(ckmc_cert_list_s *previous, ckmc_cert_s *cert, + ckmc_cert_list_s **pplast); /** * @brief Destroys the @a ckmc_cert_list_s handle and releases resources of @a ckmc_cert_list_s @@ -799,8 +804,8 @@ int ckmc_param_list_new(ckmc_param_list_h *pparams); * @see #ckmc_algo_type_e */ int ckmc_param_list_set_integer(ckmc_param_list_h params, - ckmc_param_name_e name, - uint64_t value); + ckmc_param_name_e name, + uint64_t value); /** * @brief Sets buffer parameter to the list. @@ -835,8 +840,8 @@ int ckmc_param_list_set_integer(ckmc_param_list_h params, * @see #ckmc_algo_type_e */ int ckmc_param_list_set_buffer(ckmc_param_list_h params, - ckmc_param_name_e name, - const ckmc_raw_buffer_s *buffer); + ckmc_param_name_e name, + const ckmc_raw_buffer_s *buffer); /** * @brief Gets integer parameter from the list. @@ -869,8 +874,8 @@ int ckmc_param_list_set_buffer(ckmc_param_list_h params, */ int ckmc_param_list_get_integer(ckmc_param_list_h params, - ckmc_param_name_e name, - uint64_t *pvalue); + ckmc_param_name_e name, + uint64_t *pvalue); /** * @brief Gets buffer parameter from the list. @@ -904,8 +909,8 @@ int ckmc_param_list_get_integer(ckmc_param_list_h params, * @see #ckmc_algo_type_e */ int ckmc_param_list_get_buffer(ckmc_param_list_h params, - ckmc_param_name_e name, - ckmc_raw_buffer_s **ppbuffer); + ckmc_param_name_e name, + ckmc_raw_buffer_s **ppbuffer); /** * @brief Frees previously allocated list of algorithm params. diff --git a/src/manager/client-async/async-request.cpp b/src/manager/client-async/async-request.cpp index 554028dd..ba885d82 100644 --- a/src/manager/client-async/async-request.cpp +++ b/src/manager/client-async/async-request.cpp @@ -24,15 +24,15 @@ namespace CKM { -AsyncRequest::AsyncRequest(const ManagerAsync::ObserverPtr& o, - std::string&& i, - RawBuffer&& b, - int id) : - observer(o), - interface(std::move(i)), - buffer(std::move(b)), - written(0), - id(id) +AsyncRequest::AsyncRequest(const ManagerAsync::ObserverPtr &o, + std::string &&i, + RawBuffer &&b, + int id) : + observer(o), + interface(std::move(i)), + buffer(std::move(b)), + written(0), + id(id) { } diff --git a/src/manager/client-async/async-request.h b/src/manager/client-async/async-request.h index 18199fe3..68f1336e 100644 --- a/src/manager/client-async/async-request.h +++ b/src/manager/client-async/async-request.h @@ -31,19 +31,19 @@ namespace CKM { struct AsyncRequest { - typedef std::map<int, AsyncRequest> Map; - typedef std::queue<AsyncRequest, std::list<AsyncRequest> > Queue; + typedef std::map<int, AsyncRequest> Map; + typedef std::queue<AsyncRequest, std::list<AsyncRequest>> Queue; - AsyncRequest(const ManagerAsync::ObserverPtr& observer, - std::string&& interface, - RawBuffer&& buffer, - int id); + AsyncRequest(const ManagerAsync::ObserverPtr &observer, + std::string &&interface, + RawBuffer &&buffer, + int id); - ManagerAsync::ObserverPtr observer; - std::string interface; - RawBuffer buffer; - size_t written; - int id; + ManagerAsync::ObserverPtr observer; + std::string interface; + RawBuffer buffer; + size_t written; + int id; }; } /* namespace CKM */ diff --git a/src/manager/client-async/client-manager-async-impl.cpp b/src/manager/client-async/client-manager-async-impl.cpp index 5024eaeb..5b9fbf36 100644 --- a/src/manager/client-async/client-manager-async-impl.cpp +++ b/src/manager/client-async/client-manager-async-impl.cpp @@ -30,381 +30,385 @@ namespace CKM { int ManagerAsync::Impl::m_counter = 0; -ManagerAsync::Impl::Impl() -{ -} +ManagerAsync::Impl::Impl() {} -ManagerAsync::Impl::~Impl() -{ -} +ManagerAsync::Impl::~Impl() {} -void ManagerAsync::Impl::saveKey(const ObserverPtr& observer, - const Alias& alias, - const KeyShPtr& key, - const Policy& policy) +void ManagerAsync::Impl::saveKey(const ObserverPtr &observer, + const Alias &alias, + const KeyShPtr &key, + const Policy &policy) { - observerCheck(observer); - if (alias.empty() || !key) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - Try { - saveBinaryData(observer, alias, DataType(key->getType()), key->getDER(), policy); - } Catch(DataType::Exception::Base) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - } + observerCheck(observer); + + if (alias.empty() || !key) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try { + saveBinaryData(observer, alias, DataType(key->getType()), key->getDER(), + policy); + } catch (const DataType::Exception::Base &) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + } } -void ManagerAsync::Impl::saveCertificate(const ObserverPtr& observer, - const Alias& alias, - const CertificateShPtr& cert, - const Policy& policy) +void ManagerAsync::Impl::saveCertificate(const ObserverPtr &observer, + const Alias &alias, + const CertificateShPtr &cert, + const Policy &policy) { - observerCheck(observer); - if (alias.empty() || !cert) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - saveBinaryData(observer, alias, DataType::CERTIFICATE, cert->getDER(), policy); + observerCheck(observer); + + if (alias.empty() || !cert) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + saveBinaryData(observer, alias, DataType::CERTIFICATE, cert->getDER(), policy); } -void ManagerAsync::Impl::saveData(const ObserverPtr& observer, - const Alias& alias, - const RawBuffer& data, - const Policy& policy) +void ManagerAsync::Impl::saveData(const ObserverPtr &observer, + const Alias &alias, + const RawBuffer &data, + const Policy &policy) { - observerCheck(observer); - if (alias.empty() || data.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - saveBinaryData(observer, alias, DataType::BINARY_DATA, data, policy); + observerCheck(observer); + + if (alias.empty() || data.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + saveBinaryData(observer, alias, DataType::BINARY_DATA, data, policy); } -void ManagerAsync::Impl::saveBinaryData(const ManagerAsync::ObserverPtr& observer, - const Alias& alias, - DataType dataType, - const RawBuffer& rawData, - const Policy& policy) +void ManagerAsync::Impl::saveBinaryData(const ManagerAsync::ObserverPtr + &observer, + const Alias &alias, + DataType dataType, + const RawBuffer &rawData, + const Policy &policy) { - try_catch_async([&] { - AliasSupport helper(alias); - sendToStorage(observer, - static_cast<int>(LogicCommand::SAVE), - m_counter, - static_cast<int>(dataType), - helper.getName(), - helper.getLabel(), - rawData, - PolicySerializable(policy)); - }, [&observer](int error){ observer->ReceivedError(error); } ); + try_catch_async([&]() { + AliasSupport helper(alias); + + sendToStorage(observer, static_cast<int>(LogicCommand::SAVE), m_counter, + static_cast<int>(dataType), helper.getName(), helper.getLabel(), rawData, + PolicySerializable(policy)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::savePKCS12(const ManagerAsync::ObserverPtr& observer, - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy) +void ManagerAsync::Impl::savePKCS12(const ManagerAsync::ObserverPtr &observer, + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy) { - try_catch_async([&] { - AliasSupport helper(alias); - sendToStorage(observer, - static_cast<int>(LogicCommand::SAVE_PKCS12), - m_counter, - helper.getName(), - helper.getLabel(), - PKCS12Serializable(*pkcs.get()), - PolicySerializable(keyPolicy), - PolicySerializable(certPolicy)); - }, [&observer](int error){ observer->ReceivedError(error); } ); + try_catch_async([&]() { + AliasSupport helper(alias); + sendToStorage(observer, static_cast<int>(LogicCommand::SAVE_PKCS12), + m_counter, helper.getName(), helper.getLabel(), PKCS12Serializable(*pkcs.get()), + PolicySerializable(keyPolicy), PolicySerializable(certPolicy)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::removeAlias(const ManagerAsync::ObserverPtr& observer, - const Alias& alias) +void ManagerAsync::Impl::removeAlias(const ManagerAsync::ObserverPtr &observer, + const Alias &alias) { - observerCheck(observer); - if (alias.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - AliasSupport helper(alias); - sendToStorage(observer, - static_cast<int>(LogicCommand::REMOVE), - m_counter, - helper.getName(), - helper.getLabel()); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (alias.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport helper(alias); + sendToStorage(observer, static_cast<int>(LogicCommand::REMOVE), m_counter, + helper.getName(), helper.getLabel()); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::getBinaryData(const ManagerAsync::ObserverPtr& observer, - const Alias &alias, - DataType sendDataType, - const Password &password) +void ManagerAsync::Impl::getBinaryData(const ManagerAsync::ObserverPtr + &observer, + const Alias &alias, + DataType sendDataType, + const Password &password) { - observerCheck(observer); - if (alias.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - AliasSupport helper(alias); - sendToStorage(observer, - static_cast<int>(LogicCommand::GET), - m_counter, - static_cast<int>(sendDataType), - helper.getName(), - helper.getLabel(), - password); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (alias.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport helper(alias); + + sendToStorage(observer, static_cast<int>(LogicCommand::GET), m_counter, + static_cast<int>(sendDataType), helper.getName(), helper.getLabel(), password); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::getPKCS12(const ManagerAsync::ObserverPtr& observer, - const Alias &alias, - const Password &passwordKey, - const Password &passwordCert) +void ManagerAsync::Impl::getPKCS12(const ManagerAsync::ObserverPtr &observer, + const Alias &alias, + const Password &passwordKey, + const Password &passwordCert) { - observerCheck(observer); - if (alias.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - AliasSupport helper(alias); - sendToStorage(observer, - static_cast<int>(LogicCommand::GET_PKCS12), - m_counter, - helper.getName(), - helper.getLabel(), - passwordKey, - passwordCert); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (alias.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport helper(alias); + + sendToStorage(observer, static_cast<int>(LogicCommand::GET_PKCS12), m_counter, + helper.getName(), helper.getLabel(), passwordKey, passwordCert); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::createSignature(const ObserverPtr& observer, - const Alias& privateKeyAlias, - const Password& password, - const RawBuffer& message, - const CryptoAlgorithm &cAlg) +void ManagerAsync::Impl::createSignature(const ObserverPtr &observer, + const Alias &privateKeyAlias, + const Password &password, + const RawBuffer &message, + const CryptoAlgorithm &cAlg) { - observerCheck(observer); - if (privateKeyAlias.empty() || message.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - AliasSupport helper(privateKeyAlias); - sendToStorage(observer, - static_cast<int>(LogicCommand::CREATE_SIGNATURE), - m_counter, - helper.getName(), - helper.getLabel(), - password, - message, - CryptoAlgorithmSerializable(cAlg)); - }, [&observer](int error) {observer->ReceivedError(error);} ); + observerCheck(observer); + + if (privateKeyAlias.empty() || message.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport helper(privateKeyAlias); + sendToStorage(observer, static_cast<int>(LogicCommand::CREATE_SIGNATURE), + m_counter, helper.getName(), helper.getLabel(), password, message, + CryptoAlgorithmSerializable(cAlg)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::verifySignature(const ObserverPtr& observer, - const Alias& publicKeyOrCertAlias, - const Password& password, - const RawBuffer& message, - const RawBuffer& signature, - const CryptoAlgorithm &cAlg) +void ManagerAsync::Impl::verifySignature(const ObserverPtr &observer, + const Alias &publicKeyOrCertAlias, + const Password &password, + const RawBuffer &message, + const RawBuffer &signature, + const CryptoAlgorithm &cAlg) { - observerCheck(observer); - if (publicKeyOrCertAlias.empty() || message.empty() || signature.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - AliasSupport helper(publicKeyOrCertAlias); - sendToStorage(observer, - static_cast<int>(LogicCommand::VERIFY_SIGNATURE), - m_counter, - helper.getName(), - helper.getLabel(), - password, - message, - signature, - CryptoAlgorithmSerializable(cAlg)); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (publicKeyOrCertAlias.empty() || message.empty() || signature.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport helper(publicKeyOrCertAlias); + + sendToStorage(observer, static_cast<int>(LogicCommand::VERIFY_SIGNATURE), + m_counter, helper.getName(), helper.getLabel(), password, + message, signature, CryptoAlgorithmSerializable(cAlg)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::ocspCheck(const ObserverPtr& observer, - const CertificateShPtrVector& certificateChainVector) +void ManagerAsync::Impl::ocspCheck(const ObserverPtr &observer, + const CertificateShPtrVector &certificateChainVector) { - observerCheck(observer); - if (certificateChainVector.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - RawBufferVector rawCertChain; - for (auto &e: certificateChainVector) { - if (!e || e->empty()) - return observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - rawCertChain.push_back(e->getDER()); - } - - m_counter++; - auto send = MessageBuffer::Serialize(m_counter, rawCertChain); - - thread()->sendMessage(AsyncRequest(observer, - SERVICE_SOCKET_OCSP, - send.Pop(), - m_counter)); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (certificateChainVector.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + RawBufferVector rawCertChain; + + for (auto &e : certificateChainVector) { + if (!e || e->empty()) + return observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + + rawCertChain.push_back(e->getDER()); + } + + m_counter++; + auto send = MessageBuffer::Serialize(m_counter, rawCertChain); + + thread()->sendMessage(AsyncRequest(observer, SERVICE_SOCKET_OCSP, send.Pop(), + m_counter)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::setPermission(const ObserverPtr& observer, - const Alias& alias, - const Label& accessor, - PermissionMask permissionMask) +void ManagerAsync::Impl::setPermission(const ObserverPtr &observer, + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask) { - observerCheck(observer); - if (alias.empty() || accessor.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - AliasSupport helper(alias); - sendToStorage(observer, - static_cast<int>(LogicCommand::SET_PERMISSION), - m_counter, - helper.getName(), - helper.getLabel(), - accessor, - permissionMask); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (alias.empty() || accessor.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport helper(alias); + + sendToStorage(observer, static_cast<int>(LogicCommand::SET_PERMISSION), + m_counter, helper.getName(), helper.getLabel(), accessor, permissionMask); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::getBinaryDataAliasVector(const ManagerAsync::ObserverPtr& observer, - DataType dataType) +void ManagerAsync::Impl::getBinaryDataAliasVector(const + ManagerAsync::ObserverPtr &observer, + DataType dataType) { - observerCheck(observer); - try_catch_async([&] { - sendToStorage(observer, - static_cast<int>(LogicCommand::GET_LIST), - m_counter, - static_cast<int>(dataType)); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + try_catch_async([&]() { + sendToStorage(observer, static_cast<int>(LogicCommand::GET_LIST), m_counter, + static_cast<int>(dataType)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::createKeyPair(const ManagerAsync::ObserverPtr& observer, - const KeyType key_type, - const int additional_param, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) +void ManagerAsync::Impl::createKeyPair(const ManagerAsync::ObserverPtr + &observer, + const KeyType key_type, + const int additional_param, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - observerCheck(observer); - if (privateKeyAlias.empty() || publicKeyAlias.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - // input type check - CryptoAlgorithm keyGenAlgorithm; - switch (key_type) { - case KeyType::KEY_RSA_PUBLIC: - case KeyType::KEY_RSA_PRIVATE: - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); - break; - - case KeyType::KEY_DSA_PUBLIC: - case KeyType::KEY_DSA_PRIVATE: - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); - break; - - case KeyType::KEY_ECDSA_PUBLIC: - case KeyType::KEY_ECDSA_PRIVATE: - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param); - break; - - default: - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - - try_catch_async([&] { - AliasSupport prvHelper(privateKeyAlias); - AliasSupport pubHelper(publicKeyAlias); - sendToStorage(observer, - static_cast<int>(LogicCommand::CREATE_KEY_PAIR), - m_counter, - CryptoAlgorithmSerializable(keyGenAlgorithm), - PolicySerializable(policyPrivateKey), - PolicySerializable(policyPublicKey), - prvHelper.getName(), - prvHelper.getLabel(), - pubHelper.getName(), - pubHelper.getLabel()); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (privateKeyAlias.empty() || publicKeyAlias.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + // input type check + CryptoAlgorithm keyGenAlgorithm; + + switch (key_type) { + case KeyType::KEY_RSA_PUBLIC: + case KeyType::KEY_RSA_PRIVATE: + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); + break; + + case KeyType::KEY_DSA_PUBLIC: + case KeyType::KEY_DSA_PRIVATE: + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); + break; + + case KeyType::KEY_ECDSA_PUBLIC: + case KeyType::KEY_ECDSA_PRIVATE: + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param); + break; + + default: + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport prvHelper(privateKeyAlias); + AliasSupport pubHelper(publicKeyAlias); + + sendToStorage(observer, static_cast<int>(LogicCommand::CREATE_KEY_PAIR), + m_counter, CryptoAlgorithmSerializable(keyGenAlgorithm), + PolicySerializable(policyPrivateKey), PolicySerializable(policyPublicKey), + prvHelper.getName(), prvHelper.getLabel(), pubHelper.getName(), + pubHelper.getLabel()); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::createKeyAES(const ManagerAsync::ObserverPtr& observer, - const size_t size, - const Alias &keyAlias, - const Policy &policyKey) +void ManagerAsync::Impl::createKeyAES(const ManagerAsync::ObserverPtr &observer, + const size_t size, + const Alias &keyAlias, + const Policy &policyKey) { - observerCheck(observer); - if (keyAlias.empty()) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - - try_catch_async([&] { - AliasSupport aliasHelper(keyAlias); - sendToStorage(observer, - static_cast<int>(LogicCommand::CREATE_KEY_AES), - m_counter, - static_cast<int>(size), - PolicySerializable(policyKey), - aliasHelper.getName(), - aliasHelper.getLabel()); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (keyAlias.empty()) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + AliasSupport aliasHelper(keyAlias); + + sendToStorage(observer, static_cast<int>(LogicCommand::CREATE_KEY_AES), + m_counter, static_cast<int>(size), PolicySerializable(policyKey), + aliasHelper.getName(), aliasHelper.getLabel()); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } -void ManagerAsync::Impl::observerCheck(const ManagerAsync::ObserverPtr& observer) +void ManagerAsync::Impl::observerCheck(const ManagerAsync::ObserverPtr + &observer) { - if (!observer) - throw std::invalid_argument("Empty observer"); + if (!observer) + throw std::invalid_argument("Empty observer"); } void ManagerAsync::Impl::crypt( - const ObserverPtr& observer, - const CryptoAlgorithm& algo, - const Alias& keyAlias, - const Password& password, - const RawBuffer& input, - bool encryption) + const ObserverPtr &observer, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &input, + bool encryption) { - observerCheck(observer); - if (input.empty() || keyAlias.empty()) - return observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - - try_catch_async([&] { - AliasSupport helper(keyAlias); - CryptoAlgorithmSerializable cas(algo); - m_counter++; - - auto send = MessageBuffer::Serialize( - static_cast<int>(encryption?EncryptionCommand::ENCRYPT:EncryptionCommand::DECRYPT), - m_counter, - cas, - helper.getName(), - helper.getLabel(), - password, - input); - thread()->sendMessage(AsyncRequest(observer, - SERVICE_SOCKET_ENCRYPTION, - send.Pop(), - m_counter)); - }, [&observer](int error){ observer->ReceivedError(error); } ); + observerCheck(observer); + + if (input.empty() || keyAlias.empty()) + return observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + + try_catch_async([&]() { + AliasSupport helper(keyAlias); + CryptoAlgorithmSerializable cas(algo); + m_counter++; + + auto send = MessageBuffer::Serialize(static_cast<int>(encryption ? + EncryptionCommand::ENCRYPT : EncryptionCommand::DECRYPT), m_counter, cas, + helper.getName(), helper.getLabel(), password, input); + + thread()->sendMessage(AsyncRequest(observer, SERVICE_SOCKET_ENCRYPTION, + send.Pop(), m_counter)); + }, [&observer](int error) { + observer->ReceivedError(error); + }); } } // namespace CKM diff --git a/src/manager/client-async/client-manager-async-impl.h b/src/manager/client-async/client-manager-async-impl.h index 6975c7c5..c0cfaab5 100644 --- a/src/manager/client-async/client-manager-async-impl.h +++ b/src/manager/client-async/client-manager-async-impl.h @@ -29,165 +29,166 @@ namespace CKM { -class ManagerAsync::Impl -{ +class ManagerAsync::Impl { public: - Impl(); - - NONCOPYABLE(Impl); - - virtual ~Impl(); - - void saveKey( - const ObserverPtr& observer, - const Alias& alias, - const KeyShPtr& key, - const Policy& policy); - void saveCertificate( - const ObserverPtr& observer, - const Alias& alias, - const CertificateShPtr& cert, - const Policy& policy); - void saveData( - const ObserverPtr& observer, - const Alias& alias, - const RawBuffer& data, - const Policy& policy); - void savePKCS12( - const ObserverPtr& observer, - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy); - - void createSignature( - const ObserverPtr& observer, - const Alias& privateKeyAlias, - const Password& password, - const RawBuffer& message, - const CryptoAlgorithm& cAlgorithm); - void verifySignature( - const ObserverPtr& observer, - const Alias& publicKeyOrCertAlias, - const Password& password, - const RawBuffer& message, - const RawBuffer& signature, - const CryptoAlgorithm& cAlgorithm); - - void ocspCheck( - const ObserverPtr& observer, - const CertificateShPtrVector& certificateChainVector); - - void setPermission( - const ObserverPtr& observer, - const Alias& alias, - const Label& accessor, - PermissionMask permissionMask); - - // generic methods - void saveBinaryData( - const ManagerAsync::ObserverPtr& observer, - const Alias& alias, - DataType dataType, - const RawBuffer& rawData, - const Policy& policy); - - void removeAlias( - const ManagerAsync::ObserverPtr& observer, - const Alias &alias); - - void getBinaryData( - const ManagerAsync::ObserverPtr& observer, - const Alias &alias, - DataType sendDataType, - const Password &password); - - void getPKCS12( - const ManagerAsync::ObserverPtr& observer, - const Alias &alias, - const Password &keyPassword, - const Password &certPassword); - - void getBinaryDataAliasVector( - const ManagerAsync::ObserverPtr& observer, - DataType dataType); - - void createKeyPair( - const ManagerAsync::ObserverPtr& observer, - const KeyType key_type, - const int additional_param, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey); - - void createKeyAES( - const ManagerAsync::ObserverPtr& observer, - const size_t size, - const Alias &keyAlias, - const Policy &policyKey); - - template <typename T> - void getCertChain( - const ManagerAsync::ObserverPtr& observer, - LogicCommand command, - const CertificateShPtr &certificate, - const T &untrusted, - const T &trusted, - bool useSystemTrustedCertificates) - { - observerCheck(observer); - if (!certificate) { - observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); - return; - } - try_catch_async([&] { - sendToStorage(observer, - static_cast<int>(command), - m_counter, - certificate->getDER(), - untrusted, - trusted, - useSystemTrustedCertificates); - }, [&observer](int error){ observer->ReceivedError(error);}); - } - - void crypt( - const ObserverPtr& observer, - const CryptoAlgorithm& algo, - const Alias& keyAlias, - const Password& password, - const RawBuffer& input, - bool encryption); + Impl(); + + NONCOPYABLE(Impl); + + virtual ~Impl(); + + void saveKey( + const ObserverPtr &observer, + const Alias &alias, + const KeyShPtr &key, + const Policy &policy); + void saveCertificate( + const ObserverPtr &observer, + const Alias &alias, + const CertificateShPtr &cert, + const Policy &policy); + void saveData( + const ObserverPtr &observer, + const Alias &alias, + const RawBuffer &data, + const Policy &policy); + void savePKCS12( + const ObserverPtr &observer, + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy); + + void createSignature( + const ObserverPtr &observer, + const Alias &privateKeyAlias, + const Password &password, + const RawBuffer &message, + const CryptoAlgorithm &cAlgorithm); + void verifySignature( + const ObserverPtr &observer, + const Alias &publicKeyOrCertAlias, + const Password &password, + const RawBuffer &message, + const RawBuffer &signature, + const CryptoAlgorithm &cAlgorithm); + + void ocspCheck( + const ObserverPtr &observer, + const CertificateShPtrVector &certificateChainVector); + + void setPermission( + const ObserverPtr &observer, + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask); + + // generic methods + void saveBinaryData( + const ManagerAsync::ObserverPtr &observer, + const Alias &alias, + DataType dataType, + const RawBuffer &rawData, + const Policy &policy); + + void removeAlias( + const ManagerAsync::ObserverPtr &observer, + const Alias &alias); + + void getBinaryData( + const ManagerAsync::ObserverPtr &observer, + const Alias &alias, + DataType sendDataType, + const Password &password); + + void getPKCS12( + const ManagerAsync::ObserverPtr &observer, + const Alias &alias, + const Password &keyPassword, + const Password &certPassword); + + void getBinaryDataAliasVector( + const ManagerAsync::ObserverPtr &observer, + DataType dataType); + + void createKeyPair( + const ManagerAsync::ObserverPtr &observer, + const KeyType key_type, + const int additional_param, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey); + + void createKeyAES( + const ManagerAsync::ObserverPtr &observer, + const size_t size, + const Alias &keyAlias, + const Policy &policyKey); + + template <typename T> + void getCertChain( + const ManagerAsync::ObserverPtr &observer, + LogicCommand command, + const CertificateShPtr &certificate, + const T &untrusted, + const T &trusted, + bool useSystemTrustedCertificates) + { + observerCheck(observer); + + if (!certificate) { + observer->ReceivedError(CKM_API_ERROR_INPUT_PARAM); + return; + } + + try_catch_async([&]() { + sendToStorage(observer, static_cast<int>(command), m_counter, + certificate->getDER(), untrusted, trusted, useSystemTrustedCertificates); + }, [&observer](int error) { + observer->ReceivedError(error); + }); + } + + void crypt( + const ObserverPtr &observer, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &input, + bool encryption); private: - template <typename... Args> - void sendToStorage(const ManagerAsync::ObserverPtr& observer, const Args&... args) - { - m_counter++; // yes, it changes m_counter argument passed in args + template <typename... Args> + void sendToStorage(const ManagerAsync::ObserverPtr &observer, + const Args &... args) + { + m_counter++; // yes, it changes m_counter argument passed in args - auto send = MessageBuffer::Serialize(args...); - thread()->sendMessage(AsyncRequest(observer, - SERVICE_SOCKET_CKM_STORAGE, - send.Pop(), - m_counter)); - } + auto send = MessageBuffer::Serialize(args...); + thread()->sendMessage(AsyncRequest(observer, + SERVICE_SOCKET_CKM_STORAGE, + send.Pop(), + m_counter)); + } - void observerCheck(const ManagerAsync::ObserverPtr& observer); + void observerCheck(const ManagerAsync::ObserverPtr &observer); - typedef std::unique_ptr<ConnectionThread> ConnectionThreadPtr; + typedef std::unique_ptr<ConnectionThread> ConnectionThreadPtr; - ConnectionThreadPtr& thread() { - if (!m_thread || m_thread->finished()) { - m_thread.reset(new ConnectionThread()); - m_thread->run(); - } - return m_thread; - } + ConnectionThreadPtr &thread() + { + if (!m_thread || m_thread->finished()) { + m_thread.reset(new ConnectionThread()); + m_thread->run(); + } - ConnectionThreadPtr m_thread; + return m_thread; + } - static int m_counter; + ConnectionThreadPtr m_thread; + + static int m_counter; }; } // namespace CKM diff --git a/src/manager/client-async/client-manager-async.cpp b/src/manager/client-async/client-manager-async.cpp index 935e9d30..7ef0696a 100644 --- a/src/manager/client-async/client-manager-async.cpp +++ b/src/manager/client-async/client-manager-async.cpp @@ -25,263 +25,268 @@ namespace CKM { namespace { -RawBufferVector toRawBufferVector(const CertificateShPtrVector& certificates) +RawBufferVector toRawBufferVector(const CertificateShPtrVector &certificates) { - RawBufferVector rawBufferVector; - for (auto &e: certificates) - rawBufferVector.push_back(e->getDER()); + RawBufferVector rawBufferVector; - return rawBufferVector; + for (auto &e : certificates) + rawBufferVector.push_back(e->getDER()); + + return rawBufferVector; } -LabelNameVector toLabelNameVector(const AliasVector& aliases) +LabelNameVector toLabelNameVector(const AliasVector &aliases) { - LabelNameVector labelNames; - for (auto &e: aliases) { - AliasSupport helper(e); - labelNames.push_back(std::make_pair(helper.getLabel(), helper.getName())); - } - return labelNames; + LabelNameVector labelNames; + + for (auto &e : aliases) { + AliasSupport helper(e); + labelNames.push_back(std::make_pair(helper.getLabel(), helper.getName())); + } + + return labelNames; } } // namespace anonymous ManagerAsync::ManagerAsync() { - m_impl.reset(new Impl()); + m_impl.reset(new Impl()); } ManagerAsync::~ManagerAsync() { - m_impl.reset(); + m_impl.reset(); } -void ManagerAsync::saveKey(const ObserverPtr& observer, - const Alias& alias, - const KeyShPtr& key, - const Policy& policy) +void ManagerAsync::saveKey(const ObserverPtr &observer, + const Alias &alias, + const KeyShPtr &key, + const Policy &policy) { - m_impl->saveKey(observer, alias, key, policy); + m_impl->saveKey(observer, alias, key, policy); } -void ManagerAsync::saveCertificate(const ObserverPtr& observer, - const Alias& alias, - const CertificateShPtr& cert, - const Policy& policy) +void ManagerAsync::saveCertificate(const ObserverPtr &observer, + const Alias &alias, + const CertificateShPtr &cert, + const Policy &policy) { - m_impl->saveCertificate(observer, alias, cert, policy); + m_impl->saveCertificate(observer, alias, cert, policy); } -void ManagerAsync::saveData(const ObserverPtr& observer, - const Alias& alias, - const RawBuffer& data, - const Policy& policy) +void ManagerAsync::saveData(const ObserverPtr &observer, + const Alias &alias, + const RawBuffer &data, + const Policy &policy) { - m_impl->saveData(observer, alias, data, policy); + m_impl->saveData(observer, alias, data, policy); } -void ManagerAsync::savePKCS12(const ObserverPtr& observer, - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy) +void ManagerAsync::savePKCS12(const ObserverPtr &observer, + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy) { - m_impl->savePKCS12(observer, alias, pkcs, keyPolicy, certPolicy); + m_impl->savePKCS12(observer, alias, pkcs, keyPolicy, certPolicy); } -void ManagerAsync::removeAlias(const ObserverPtr& observer, const Alias& alias) +void ManagerAsync::removeAlias(const ObserverPtr &observer, const Alias &alias) { - m_impl->removeAlias(observer, alias); + m_impl->removeAlias(observer, alias); } -void ManagerAsync::getKey(const ObserverPtr& observer, const Alias& alias, const Password& password) +void ManagerAsync::getKey(const ObserverPtr &observer, const Alias &alias, + const Password &password) { - m_impl->getBinaryData(observer, alias, DataType::DB_KEY_FIRST, password); + m_impl->getBinaryData(observer, alias, DataType::DB_KEY_FIRST, password); } -void ManagerAsync::getCertificate(const ObserverPtr& observer, - const Alias& alias, - const Password& password) +void ManagerAsync::getCertificate(const ObserverPtr &observer, + const Alias &alias, + const Password &password) { - m_impl->getBinaryData(observer, alias, DataType::CERTIFICATE, password); + m_impl->getBinaryData(observer, alias, DataType::CERTIFICATE, password); } -void ManagerAsync::getData(const ObserverPtr& observer, - const Alias& alias, - const Password& password) +void ManagerAsync::getData(const ObserverPtr &observer, + const Alias &alias, + const Password &password) { - m_impl->getBinaryData(observer, alias, DataType::BINARY_DATA, password); + m_impl->getBinaryData(observer, alias, DataType::BINARY_DATA, password); } -void ManagerAsync::getPKCS12(const ObserverPtr& observer, - const Alias &alias, - const Password &keyPassword, - const Password &certPassword) +void ManagerAsync::getPKCS12(const ObserverPtr &observer, + const Alias &alias, + const Password &keyPassword, + const Password &certPassword) { - m_impl->getPKCS12(observer, alias, keyPassword, certPassword); + m_impl->getPKCS12(observer, alias, keyPassword, certPassword); } -void ManagerAsync::getKeyAliasVector(const ObserverPtr& observer) +void ManagerAsync::getKeyAliasVector(const ObserverPtr &observer) { - m_impl->getBinaryDataAliasVector(observer, DataType::DB_KEY_FIRST); + m_impl->getBinaryDataAliasVector(observer, DataType::DB_KEY_FIRST); } -void ManagerAsync::getCertificateAliasVector(const ObserverPtr& observer) +void ManagerAsync::getCertificateAliasVector(const ObserverPtr &observer) { - m_impl->getBinaryDataAliasVector(observer, DataType::CERTIFICATE); + m_impl->getBinaryDataAliasVector(observer, DataType::CERTIFICATE); } -void ManagerAsync::getDataAliasVector(const ObserverPtr& observer) +void ManagerAsync::getDataAliasVector(const ObserverPtr &observer) { - m_impl->getBinaryDataAliasVector(observer, DataType::BINARY_DATA); + m_impl->getBinaryDataAliasVector(observer, DataType::BINARY_DATA); } -void ManagerAsync::createKeyPairRSA(const ObserverPtr& observer, - int size, - const Alias& privateKeyAlias, - const Alias& publicKeyAlias, - const Policy& policyPrivateKey, - const Policy& policyPublicKey) +void ManagerAsync::createKeyPairRSA(const ObserverPtr &observer, + int size, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - m_impl->createKeyPair(observer, - KeyType::KEY_RSA_PUBLIC, - size, - privateKeyAlias, - publicKeyAlias, - policyPrivateKey, - policyPublicKey); + m_impl->createKeyPair(observer, + KeyType::KEY_RSA_PUBLIC, + size, + privateKeyAlias, + publicKeyAlias, + policyPrivateKey, + policyPublicKey); } -void ManagerAsync::createKeyPairDSA(const ObserverPtr& observer, - int size, - const Alias& privateKeyAlias, - const Alias& publicKeyAlias, - const Policy& policyPrivateKey, - const Policy& policyPublicKey) +void ManagerAsync::createKeyPairDSA(const ObserverPtr &observer, + int size, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - m_impl->createKeyPair(observer, - KeyType::KEY_DSA_PUBLIC, - size, - privateKeyAlias, - publicKeyAlias, - policyPrivateKey, - policyPublicKey); + m_impl->createKeyPair(observer, + KeyType::KEY_DSA_PUBLIC, + size, + privateKeyAlias, + publicKeyAlias, + policyPrivateKey, + policyPublicKey); } -void ManagerAsync::createKeyPairECDSA(const ObserverPtr& observer, - const ElipticCurve type, - const Alias& privateKeyAlias, - const Alias& publicKeyAlias, - const Policy& policyPrivateKey, - const Policy& policyPublicKey) +void ManagerAsync::createKeyPairECDSA(const ObserverPtr &observer, + const ElipticCurve type, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - m_impl->createKeyPair(observer, - KeyType::KEY_ECDSA_PUBLIC, - static_cast<int>(type), - privateKeyAlias, - publicKeyAlias, - policyPrivateKey, - policyPublicKey); + m_impl->createKeyPair(observer, + KeyType::KEY_ECDSA_PUBLIC, + static_cast<int>(type), + privateKeyAlias, + publicKeyAlias, + policyPrivateKey, + policyPublicKey); } -void ManagerAsync::createKeyAES(const ObserverPtr& observer, - int size, - const Alias &keyAlias, - const Policy &policyKey) +void ManagerAsync::createKeyAES(const ObserverPtr &observer, + int size, + const Alias &keyAlias, + const Policy &policyKey) { - m_impl->createKeyAES(observer, - size, - keyAlias, - policyKey); + m_impl->createKeyAES(observer, + size, + keyAlias, + policyKey); } -void ManagerAsync::getCertificateChain(const ObserverPtr& observer, - const CertificateShPtr& certificate, - const CertificateShPtrVector& untrustedCertificates, - const CertificateShPtrVector& trustedCertificates, - bool useSystemTrustedCertificates) +void ManagerAsync::getCertificateChain(const ObserverPtr &observer, + const CertificateShPtr &certificate, + const CertificateShPtrVector &untrustedCertificates, + const CertificateShPtrVector &trustedCertificates, + bool useSystemTrustedCertificates) { - m_impl->getCertChain(observer, - LogicCommand::GET_CHAIN_CERT, - certificate, - toRawBufferVector(untrustedCertificates), - toRawBufferVector(trustedCertificates), - useSystemTrustedCertificates); + m_impl->getCertChain(observer, + LogicCommand::GET_CHAIN_CERT, + certificate, + toRawBufferVector(untrustedCertificates), + toRawBufferVector(trustedCertificates), + useSystemTrustedCertificates); } -void ManagerAsync::getCertificateChain(const ObserverPtr& observer, - const CertificateShPtr& certificate, - const AliasVector& untrustedCertificates, - const AliasVector& trustedCertificates, - bool useSystemTrustedCertificates) +void ManagerAsync::getCertificateChain(const ObserverPtr &observer, + const CertificateShPtr &certificate, + const AliasVector &untrustedCertificates, + const AliasVector &trustedCertificates, + bool useSystemTrustedCertificates) { - m_impl->getCertChain(observer, - LogicCommand::GET_CHAIN_ALIAS, - certificate, - toLabelNameVector(untrustedCertificates), - toLabelNameVector(trustedCertificates), - useSystemTrustedCertificates); + m_impl->getCertChain(observer, + LogicCommand::GET_CHAIN_ALIAS, + certificate, + toLabelNameVector(untrustedCertificates), + toLabelNameVector(trustedCertificates), + useSystemTrustedCertificates); } -void ManagerAsync::createSignature(const ObserverPtr& observer, - const Alias& privateKeyAlias, - const Password& password, - const RawBuffer& message, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding) +void ManagerAsync::createSignature(const ObserverPtr &observer, + const Alias &privateKeyAlias, + const Password &password, + const RawBuffer &message, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding) { - CryptoAlgorithm cAlg; - cAlg.setParam(ParamName::SV_HASH_ALGO, hash); - cAlg.setParam(ParamName::SV_RSA_PADDING, padding); - m_impl->createSignature(observer, privateKeyAlias, password, message, cAlg); + CryptoAlgorithm cAlg; + cAlg.setParam(ParamName::SV_HASH_ALGO, hash); + cAlg.setParam(ParamName::SV_RSA_PADDING, padding); + m_impl->createSignature(observer, privateKeyAlias, password, message, cAlg); } -void ManagerAsync::verifySignature(const ObserverPtr& observer, - const Alias& publicKeyOrCertAlias, - const Password& password, - const RawBuffer& message, - const RawBuffer& signature, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding) +void ManagerAsync::verifySignature(const ObserverPtr &observer, + const Alias &publicKeyOrCertAlias, + const Password &password, + const RawBuffer &message, + const RawBuffer &signature, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding) { - CryptoAlgorithm cAlg; - cAlg.setParam(ParamName::SV_HASH_ALGO, hash); - cAlg.setParam(ParamName::SV_RSA_PADDING, padding); - m_impl->verifySignature(observer, publicKeyOrCertAlias, password, message, signature, cAlg); + CryptoAlgorithm cAlg; + cAlg.setParam(ParamName::SV_HASH_ALGO, hash); + cAlg.setParam(ParamName::SV_RSA_PADDING, padding); + m_impl->verifySignature(observer, publicKeyOrCertAlias, password, message, + signature, cAlg); } -void ManagerAsync::ocspCheck(const ObserverPtr& observer, - const CertificateShPtrVector& certificateChainVector) +void ManagerAsync::ocspCheck(const ObserverPtr &observer, + const CertificateShPtrVector &certificateChainVector) { - m_impl->ocspCheck(observer, certificateChainVector); + m_impl->ocspCheck(observer, certificateChainVector); } -void ManagerAsync::setPermission(const ObserverPtr& observer, - const Alias& alias, - const Label& accessor, - PermissionMask permissionMask) +void ManagerAsync::setPermission(const ObserverPtr &observer, + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask) { - m_impl->setPermission(observer, alias, accessor, permissionMask); + m_impl->setPermission(observer, alias, accessor, permissionMask); } void ManagerAsync::encrypt( - const ObserverPtr& observer, - const CryptoAlgorithm& algo, - const Alias& keyAlias, - const Password& password, - const RawBuffer& plain) + const ObserverPtr &observer, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &plain) { - m_impl->crypt(observer, algo, keyAlias, password, plain, true); + m_impl->crypt(observer, algo, keyAlias, password, plain, true); } void ManagerAsync::decrypt( - const ObserverPtr& observer, - const CryptoAlgorithm& algo, - const Alias& keyAlias, - const Password& password, - const RawBuffer& encrypted) + const ObserverPtr &observer, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &encrypted) { - m_impl->crypt(observer, algo, keyAlias, password, encrypted, false); + m_impl->crypt(observer, algo, keyAlias, password, encrypted, false); } } // namespace CKM diff --git a/src/manager/client-async/connection-thread.cpp b/src/manager/client-async/connection-thread.cpp index d816530b..555056bc 100644 --- a/src/manager/client-async/connection-thread.cpp +++ b/src/manager/client-async/connection-thread.cpp @@ -32,132 +32,138 @@ namespace CKM { ConnectionThread::Pipe::Pipe() { - if (-1 == pipe(m_pipe)) - ThrowMsg(PipeError, "Pipe creation failed " << GetErrnoString(errno)); + if (-1 == pipe(m_pipe)) + ThrowMsg(PipeError, "Pipe creation failed " << GetErrnoString(errno)); } ConnectionThread::Pipe::~Pipe() { - close(m_pipe[0]); - close(m_pipe[1]); + close(m_pipe[0]); + close(m_pipe[1]); } void ConnectionThread::Pipe::notify() { - if (-1 == TEMP_FAILURE_RETRY(write(m_pipe[1], "j", 1))) - ThrowMsg(PipeError, "Writing pipe failed " << GetErrnoString(errno)); + if (-1 == TEMP_FAILURE_RETRY(write(m_pipe[1], "j", 1))) + ThrowMsg(PipeError, "Writing pipe failed " << GetErrnoString(errno)); } ConnectionThread::ConnectionThread() : - m_join(false), - m_finished(false) + m_join(false), + m_finished(false) { } ConnectionThread::~ConnectionThread() { - m_join = true; - m_pipe.notify(); - m_thread.join(); + m_join = true; + m_pipe.notify(); + m_thread.join(); } void ConnectionThread::run() { - m_thread = std::thread(&ConnectionThread::threadLoop, this); + m_thread = std::thread(&ConnectionThread::threadLoop, this); } -void ConnectionThread::sendMessage(AsyncRequest&& req) +void ConnectionThread::sendMessage(AsyncRequest &&req) { - std::unique_lock<std::mutex> lock(m_mutex); - m_waitingReqs.push(std::move(req)); - lock.unlock(); + std::unique_lock<std::mutex> lock(m_mutex); + m_waitingReqs.push(std::move(req)); + lock.unlock(); - // notify via pipe - m_pipe.notify(); + // notify via pipe + m_pipe.notify(); } void ConnectionThread::threadLoop() { - try { - m_descriptors.add(m_pipe.output(), - POLLIN, - [this](int fd, short revents){ newRequest(fd, revents); }); - - while (!m_join) { - // wait for pipe/socket notification - m_descriptors.wait(); - } - } catch (CKM::Exception &e) { - LogError("CKM::Exception::Exception " << e.DumpToString()); - } catch (std::exception &e) { - LogError("STD exception " << e.what()); - } catch (...) { - LogError("Unknown exception occured"); - } - - // cleanup services - for (auto& it: m_services) - it.second.serviceError(CKM_API_ERROR_UNKNOWN); - m_services.clear(); - - // close all descriptors (including pipe) - m_descriptors.purge(); - - // remove waiting requests and notify about error - std::unique_lock<std::mutex> lock(m_mutex); - while (!m_waitingReqs.empty()) { - m_waitingReqs.front().observer->ReceivedError(CKM_API_ERROR_UNKNOWN); - m_waitingReqs.pop(); - } - lock.unlock(); - - m_finished = true; + try { + m_descriptors.add(m_pipe.output(), + POLLIN, + [this](int fd, short revents) { + newRequest(fd, revents); + }); + + while (!m_join) { + // wait for pipe/socket notification + m_descriptors.wait(); + } + } catch (CKM::Exception &e) { + LogError("CKM::Exception::Exception " << e.DumpToString()); + } catch (std::exception &e) { + LogError("STD exception " << e.what()); + } catch (...) { + LogError("Unknown exception occured"); + } + + // cleanup services + for (auto &it : m_services) + it.second.serviceError(CKM_API_ERROR_UNKNOWN); + + m_services.clear(); + + // close all descriptors (including pipe) + m_descriptors.purge(); + + // remove waiting requests and notify about error + std::unique_lock<std::mutex> lock(m_mutex); + + while (!m_waitingReqs.empty()) { + m_waitingReqs.front().observer->ReceivedError(CKM_API_ERROR_UNKNOWN); + m_waitingReqs.pop(); + } + + lock.unlock(); + + m_finished = true; } void ConnectionThread::readPipe(int pipe, short revents) { - char buffer[1]; + char buffer[1]; - if ((revents & POLLIN) == 0) - ThrowMsg(PipeError, "Unexpected event: " << revents << "!=" << POLLIN); + if ((revents & POLLIN) == 0) + ThrowMsg(PipeError, "Unexpected event: " << revents << "!=" << POLLIN); - if (1 != TEMP_FAILURE_RETRY(read(pipe, buffer, 1))) { - int err = errno; - ThrowMsg(PipeError, "Failed to read pipe: " << GetErrnoString(err)); - } + if (1 != TEMP_FAILURE_RETRY(read(pipe, buffer, 1))) { + int err = errno; + ThrowMsg(PipeError, "Failed to read pipe: " << GetErrnoString(err)); + } } -Service& ConnectionThread::getService(const std::string& interface) +Service &ConnectionThread::getService(const std::string &interface) { - auto it = m_services.find(interface); - if (it != m_services.end()) - return it->second; + auto it = m_services.find(interface); - // create new service, insert it and return - return m_services.insert( - std::make_pair(interface, Service(m_descriptors, interface))).first->second; + if (it != m_services.end()) + return it->second; + + // create new service, insert it and return + return m_services.insert( + std::make_pair(interface, Service(m_descriptors, interface))).first->second; } void ConnectionThread::newRequest(int pipe, short revents) { - readPipe(pipe, revents); + readPipe(pipe, revents); - std::unique_lock<std::mutex> lock(m_mutex); + std::unique_lock<std::mutex> lock(m_mutex); - // nothing to do? - if (m_waitingReqs.empty()) { - LogWarning("Empty request queue. Are we exiting?"); - return; - } + // nothing to do? + if (m_waitingReqs.empty()) { + LogWarning("Empty request queue. Are we exiting?"); + return; + } - // zero-copy remove - AsyncRequest req = std::move(m_waitingReqs.front()); - m_waitingReqs.pop(); + // zero-copy remove + AsyncRequest req = std::move(m_waitingReqs.front()); + m_waitingReqs.pop(); - lock.unlock(); + lock.unlock(); - Service& srv = getService(req.interface); - srv.addRequest(std::move(req)); + Service &srv = getService(req.interface); + srv.addRequest(std::move(req)); } } /* namespace CKM */ diff --git a/src/manager/client-async/connection-thread.h b/src/manager/client-async/connection-thread.h index 690828bb..ebae27cb 100644 --- a/src/manager/client-async/connection-thread.h +++ b/src/manager/client-async/connection-thread.h @@ -33,59 +33,64 @@ namespace CKM { -class ConnectionThread -{ +class ConnectionThread { public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, PipeError) + DECLARE_EXCEPTION_TYPE(CKM::Exception, PipeError) - ConnectionThread(); - virtual ~ConnectionThread(); + ConnectionThread(); + virtual ~ConnectionThread(); - NONCOPYABLE(ConnectionThread); + NONCOPYABLE(ConnectionThread); - void run(); + void run(); - void sendMessage(AsyncRequest&& request); + void sendMessage(AsyncRequest &&request); - bool finished() const { return m_finished; } + bool finished() const + { + return m_finished; + } private: - void threadLoop(); + void threadLoop(); - void newRequest(int pipe, short revents); + void newRequest(int pipe, short revents); - // reads notification pipe - void readPipe(int pipe, short revents); + // reads notification pipe + void readPipe(int pipe, short revents); - Service& getService(const std::string& interface); + Service &getService(const std::string &interface); - // Helper class that creates a pipe before thread is started - class Pipe { - public: - Pipe(); - ~Pipe(); + // Helper class that creates a pipe before thread is started + class Pipe { + public: + Pipe(); + ~Pipe(); - NONCOPYABLE(Pipe); + NONCOPYABLE(Pipe); - void notify(); - int output() const { return m_pipe[0]; } + void notify(); + int output() const + { + return m_pipe[0]; + } - private: - int m_pipe[2]; - }; - // shared vars - Pipe m_pipe; - AsyncRequest::Queue m_waitingReqs; - std::mutex m_mutex; - bool m_join; - bool m_finished; + private: + int m_pipe[2]; + }; + // shared vars + Pipe m_pipe; + AsyncRequest::Queue m_waitingReqs; + std::mutex m_mutex; + bool m_join; + bool m_finished; - // parent thread vars - std::thread m_thread; + // parent thread vars + std::thread m_thread; - // child thread vars - std::map<std::string, Service> m_services; - DescriptorSet m_descriptors; + // child thread vars + std::map<std::string, Service> m_services; + DescriptorSet m_descriptors; }; } /* namespace CKM */ diff --git a/src/manager/client-async/descriptor-set.cpp b/src/manager/client-async/descriptor-set.cpp index 8767ceed..83442b2f 100644 --- a/src/manager/client-async/descriptor-set.cpp +++ b/src/manager/client-async/descriptor-set.cpp @@ -33,100 +33,113 @@ DescriptorSet::DescriptorSet() : m_dirty(true), m_fds(NULL) DescriptorSet::~DescriptorSet() { - purge(); + purge(); } void DescriptorSet::purge() { - for (auto it:m_descriptors) - close(it.first); - m_descriptors.clear(); + for (auto it : m_descriptors) + close(it.first); + + m_descriptors.clear(); } -void DescriptorSet::add(int fd, short events, Callback&& callback) +void DescriptorSet::add(int fd, short events, Callback &&callback) { - // map operator[] requires empty DescriptorData constructor - auto it = m_descriptors.find(fd); - if (it == m_descriptors.end()) { - m_descriptors.insert(std::make_pair(fd, DescriptorData(events, std::move(callback)))); - } else { - it->second.events = events; - it->second.callback = std::move(callback); - } - m_dirty = true; + // map operator[] requires empty DescriptorData constructor + auto it = m_descriptors.find(fd); + + if (it == m_descriptors.end()) { + m_descriptors.insert(std::make_pair(fd, DescriptorData(events, + std::move(callback)))); + } else { + it->second.events = events; + it->second.callback = std::move(callback); + } + + m_dirty = true; } void DescriptorSet::remove(int fd, bool close_fd) { - if (0 != m_descriptors.erase(fd)) { - if (close_fd) - close(fd); - m_dirty = true; - } + if (0 != m_descriptors.erase(fd)) { + if (close_fd) + close(fd); + + m_dirty = true; + } } void DescriptorSet::wait(int timeout_ms) { - if (!rebuildPollfd()) - return; - - // wait - int ret = TEMP_FAILURE_RETRY(poll(m_fds, m_descriptors.size(), timeout_ms)); - if (ret == 0) { - ThrowMsg(Timeout, "Poll timeout"); - } else if (ret < 0) { - int err = errno; - ThrowMsg(InternalError, "Poll failed " << GetErrnoString(err)); - } - - notify(ret); + if (!rebuildPollfd()) + return; + + // wait + int ret = TEMP_FAILURE_RETRY(poll(m_fds, m_descriptors.size(), timeout_ms)); + + if (ret == 0) { + ThrowMsg(Timeout, "Poll timeout"); + } else if (ret < 0) { + int err = errno; + ThrowMsg(InternalError, "Poll failed " << GetErrnoString(err)); + } + + notify(ret); } bool DescriptorSet::rebuildPollfd() { - if (m_dirty) { - delete[] m_fds; - m_fds = NULL; - if (m_descriptors.empty()) { - LogWarning("Nothing to wait for"); - return false; - } - - m_fds = new pollfd[m_descriptors.size()]; - size_t idx = 0; - for (const auto& it : m_descriptors) { - m_fds[idx].fd = it.first; - m_fds[idx].events = it.second.events; - idx++; - } - m_dirty = false; - } - return true; + if (m_dirty) { + delete[] m_fds; + m_fds = NULL; + + if (m_descriptors.empty()) { + LogWarning("Nothing to wait for"); + return false; + } + + m_fds = new pollfd[m_descriptors.size()]; + size_t idx = 0; + + for (const auto &it : m_descriptors) { + m_fds[idx].fd = it.first; + m_fds[idx].events = it.second.events; + idx++; + } + + m_dirty = false; + } + + return true; } void DescriptorSet::notify(int descCount) { - size_t size = m_descriptors.size(); - for (size_t idx = 0;idx < size;++idx) { - const pollfd& pfd = m_fds[idx]; - if (pfd.revents == 0) - continue; - - /* - * Descriptors can be added/removed inside observer callback but: - * 1. m_fds is not affected. It will be regenerated in next wait() - * 2. No m_descriptors iterator will be invalidated - * 3. m_descriptors size is stored in local variable - */ - m_descriptors.at(pfd.fd).callback(pfd.fd, pfd.revents); - descCount--; - - // no more descriptors to check - if (descCount == 0) - break; - } - if (descCount != 0) - ThrowMsg(InternalError, "Number of notified descriptors do not match"); + size_t size = m_descriptors.size(); + + for (size_t idx = 0; idx < size; ++idx) { + const pollfd &pfd = m_fds[idx]; + + if (pfd.revents == 0) + continue; + + /* + * Descriptors can be added/removed inside observer callback but: + * 1. m_fds is not affected. It will be regenerated in next wait() + * 2. No m_descriptors iterator will be invalidated + * 3. m_descriptors size is stored in local variable + */ + m_descriptors.at(pfd.fd).callback(pfd.fd, pfd.revents); + descCount--; + + // no more descriptors to check + if (descCount == 0) + break; + } + + if (descCount != 0) + ThrowMsg(InternalError, "Number of notified descriptors do not match"); } } /* namespace CKM */ diff --git a/src/manager/client-async/descriptor-set.h b/src/manager/client-async/descriptor-set.h index 0f8e2c10..931d10d8 100644 --- a/src/manager/client-async/descriptor-set.h +++ b/src/manager/client-async/descriptor-set.h @@ -31,15 +31,15 @@ namespace CKM { class IDescriptorSet { public: - // int is for descriptor, short is for revents, - typedef std::function<void(int, short)> Callback; + // int is for descriptor, short is for revents, + typedef std::function<void(int, short)> Callback; - virtual void add(int fd, short events, Callback&& callback) = 0; - virtual void remove(int fd, bool close_fd = true) = 0; + virtual void add(int fd, short events, Callback &&callback) = 0; + virtual void remove(int fd, bool close_fd = true) = 0; protected: - // I don't want anyone to manage object lifetime via interface. - IDescriptorSet() {} - ~IDescriptorSet() {} + // I don't want anyone to manage object lifetime via interface. + IDescriptorSet() {} + ~IDescriptorSet() {} }; /** @@ -47,63 +47,63 @@ protected: */ class DescriptorSet : public IDescriptorSet { public: - DescriptorSet(); - virtual ~DescriptorSet(); - - NONCOPYABLE(DescriptorSet); - - /* - * Add descriptor fd to watched set. Watches for events. Takes ownership of fd (closes it). Will - * synchronously call supported callback when an event occurs on descriptor. If descriptor - * already exists in the set events and callback will be overwritten. - * - * @param fd descriptor to be watched - * @param events events to watch for - * @param callback callback to be called when an event on descriptor occurs - */ - virtual void add(int fd, short events, Callback&& callback); - /* - * Removes give descriptor from watched set and closes it. - * - * @param fd descriptor to be removed and closed - */ - virtual void remove(int fd, bool close_fd = true); - - /* - * Wait for descriptor events using poll(). - * Synchronously calls provided descriptor callbacks. - * - * @param timeout_ms timeout in ms. egative value means no timeout. - * - * @throws Timeout exception in case of timeout - * @throws InternalError in case of other error - */ - void wait(int timeout_ms = 60000); - /* - * Removes and closes all descriptors - */ - void purge(); - - DECLARE_EXCEPTION_TYPE(CKM::Exception, InternalError); - DECLARE_EXCEPTION_TYPE(CKM::Exception, Timeout); + DescriptorSet(); + virtual ~DescriptorSet(); + + NONCOPYABLE(DescriptorSet); + + /* + * Add descriptor fd to watched set. Watches for events. Takes ownership of fd (closes it). Will + * synchronously call supported callback when an event occurs on descriptor. If descriptor + * already exists in the set events and callback will be overwritten. + * + * @param fd descriptor to be watched + * @param events events to watch for + * @param callback callback to be called when an event on descriptor occurs + */ + virtual void add(int fd, short events, Callback &&callback); + /* + * Removes give descriptor from watched set and closes it. + * + * @param fd descriptor to be removed and closed + */ + virtual void remove(int fd, bool close_fd = true); + + /* + * Wait for descriptor events using poll(). + * Synchronously calls provided descriptor callbacks. + * + * @param timeout_ms timeout in ms. egative value means no timeout. + * + * @throws Timeout exception in case of timeout + * @throws InternalError in case of other error + */ + void wait(int timeout_ms = 60000); + /* + * Removes and closes all descriptors + */ + void purge(); + + DECLARE_EXCEPTION_TYPE(CKM::Exception, InternalError); + DECLARE_EXCEPTION_TYPE(CKM::Exception, Timeout); protected: - // returns false if there are no descriptors to wait for - bool rebuildPollfd(); - void notify(int descCount); + // returns false if there are no descriptors to wait for + bool rebuildPollfd(); + void notify(int descCount); - struct DescriptorData { - DescriptorData(short e, Callback&& c) : events(e), callback(std::move(c)) {} + struct DescriptorData { + DescriptorData(short e, Callback &&c) : events(e), callback(std::move(c)) {} - short events; - Callback callback; - }; + short events; + Callback callback; + }; - std::map<int, DescriptorData> m_descriptors; + std::map<int, DescriptorData> m_descriptors; - // true if pollfd needs update - bool m_dirty; - pollfd* m_fds; + // true if pollfd needs update + bool m_dirty; + pollfd *m_fds; }; } /* namespace CKM */ diff --git a/src/manager/client-async/encryption-receiver.cpp b/src/manager/client-async/encryption-receiver.cpp index a406c0aa..89d1e134 100644 --- a/src/manager/client-async/encryption-receiver.cpp +++ b/src/manager/client-async/encryption-receiver.cpp @@ -25,48 +25,54 @@ namespace CKM { -EncryptionReceiver::EncryptionReceiver(MessageBuffer& buffer, AsyncRequest::Map& requests) : - m_buffer(buffer), - m_requests(requests) +EncryptionReceiver::EncryptionReceiver(MessageBuffer &buffer, + AsyncRequest::Map &requests) : + m_buffer(buffer), + m_requests(requests) { } void EncryptionReceiver::processResponse() { - int command = 0; - int id = 0; - int retCode; - RawBuffer output; - m_buffer.Deserialize(command, id, retCode, output); + int command = 0; + int id = 0; + int retCode; + RawBuffer output; + m_buffer.Deserialize(command, id, retCode, output); - auto it = m_requests.find(id); - if (it == m_requests.end()) { - LogError("Request with id " << id << " not found!"); - ThrowMsg(BadResponse, "Request with id " << id << " not found!"); - } + auto it = m_requests.find(id); - // let it throw - AsyncRequest req = std::move(m_requests.at(id)); - m_requests.erase(id); + if (it == m_requests.end()) { + LogError("Request with id " << id << " not found!"); + ThrowMsg(BadResponse, "Request with id " << id << " not found!"); + } - switch (static_cast<EncryptionCommand>(command)) { - case EncryptionCommand::ENCRYPT: - if (retCode == CKM_API_SUCCESS) - req.observer->ReceivedEncrypted(std::move(output)); - else - req.observer->ReceivedError(retCode); - break; - case EncryptionCommand::DECRYPT: - if (retCode == CKM_API_SUCCESS) - req.observer->ReceivedDecrypted(std::move(output)); - else - req.observer->ReceivedError(retCode); - break; - default: - LogError("Unknown command id: " << command); - ThrowMsg(BadResponse, "Unknown command id: " << command); - break; - } + // let it throw + AsyncRequest req = std::move(m_requests.at(id)); + m_requests.erase(id); + + switch (static_cast<EncryptionCommand>(command)) { + case EncryptionCommand::ENCRYPT: + if (retCode == CKM_API_SUCCESS) + req.observer->ReceivedEncrypted(std::move(output)); + else + req.observer->ReceivedError(retCode); + + break; + + case EncryptionCommand::DECRYPT: + if (retCode == CKM_API_SUCCESS) + req.observer->ReceivedDecrypted(std::move(output)); + else + req.observer->ReceivedError(retCode); + + break; + + default: + LogError("Unknown command id: " << command); + ThrowMsg(BadResponse, "Unknown command id: " << command); + break; + } } } /* namespace CKM */ diff --git a/src/manager/client-async/encryption-receiver.h b/src/manager/client-async/encryption-receiver.h index 9995a31a..7ea096fd 100644 --- a/src/manager/client-async/encryption-receiver.h +++ b/src/manager/client-async/encryption-receiver.h @@ -28,19 +28,18 @@ namespace CKM { -class EncryptionReceiver : public IReceiver -{ +class EncryptionReceiver : public IReceiver { public: - EncryptionReceiver(MessageBuffer& buffer, AsyncRequest::Map& reqMap); - virtual ~EncryptionReceiver() {} + EncryptionReceiver(MessageBuffer &buffer, AsyncRequest::Map &reqMap); + virtual ~EncryptionReceiver() {} - NONCOPYABLE(EncryptionReceiver); + NONCOPYABLE(EncryptionReceiver); - void processResponse(); + void processResponse(); private: - MessageBuffer& m_buffer; - AsyncRequest::Map& m_requests; + MessageBuffer &m_buffer; + AsyncRequest::Map &m_requests; }; } /* namespace CKM */ diff --git a/src/manager/client-async/ocsp-receiver.cpp b/src/manager/client-async/ocsp-receiver.cpp index 3b4af1a3..33dbe92d 100644 --- a/src/manager/client-async/ocsp-receiver.cpp +++ b/src/manager/client-async/ocsp-receiver.cpp @@ -24,31 +24,32 @@ namespace CKM { -OcspReceiver::OcspReceiver(MessageBuffer& buffer, AsyncRequest::Map& requests) : - m_buffer(buffer), - m_requests(requests) +OcspReceiver::OcspReceiver(MessageBuffer &buffer, AsyncRequest::Map &requests) : + m_buffer(buffer), + m_requests(requests) { } void OcspReceiver::processResponse() { - int id = 0, retCode = 0, ocspStatus = 0; - m_buffer.Deserialize(id, retCode, ocspStatus); - - auto it = m_requests.find(id); - if (it == m_requests.end()) { - LogError("Request with id " << id << " not found!"); - ThrowMsg(BadResponse, "Request with id " << id << " not found!"); - } - - // let it throw - AsyncRequest req = std::move(m_requests.at(id)); - m_requests.erase(id); - - if (retCode == CKM_API_SUCCESS) - req.observer->ReceivedOCSPCheck(ocspStatus); - else - req.observer->ReceivedError(retCode); + int id = 0, retCode = 0, ocspStatus = 0; + m_buffer.Deserialize(id, retCode, ocspStatus); + + auto it = m_requests.find(id); + + if (it == m_requests.end()) { + LogError("Request with id " << id << " not found!"); + ThrowMsg(BadResponse, "Request with id " << id << " not found!"); + } + + // let it throw + AsyncRequest req = std::move(m_requests.at(id)); + m_requests.erase(id); + + if (retCode == CKM_API_SUCCESS) + req.observer->ReceivedOCSPCheck(ocspStatus); + else + req.observer->ReceivedError(retCode); } } /* namespace CKM */ diff --git a/src/manager/client-async/ocsp-receiver.h b/src/manager/client-async/ocsp-receiver.h index 93d2dec4..95523487 100644 --- a/src/manager/client-async/ocsp-receiver.h +++ b/src/manager/client-async/ocsp-receiver.h @@ -28,19 +28,18 @@ namespace CKM { -class OcspReceiver : public IReceiver -{ +class OcspReceiver : public IReceiver { public: - OcspReceiver(MessageBuffer& buffer, AsyncRequest::Map& reqMap); - virtual ~OcspReceiver() {} + OcspReceiver(MessageBuffer &buffer, AsyncRequest::Map &reqMap); + virtual ~OcspReceiver() {} - NONCOPYABLE(OcspReceiver); + NONCOPYABLE(OcspReceiver); - void processResponse(); + void processResponse(); private: - MessageBuffer& m_buffer; - AsyncRequest::Map& m_requests; + MessageBuffer &m_buffer; + AsyncRequest::Map &m_requests; }; } /* namespace CKM */ diff --git a/src/manager/client-async/receiver.h b/src/manager/client-async/receiver.h index cac16088..81c24125 100644 --- a/src/manager/client-async/receiver.h +++ b/src/manager/client-async/receiver.h @@ -25,10 +25,10 @@ namespace CKM { class IReceiver { public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, BadResponse); + DECLARE_EXCEPTION_TYPE(CKM::Exception, BadResponse); - virtual void processResponse() = 0; - virtual ~IReceiver() {}; + virtual void processResponse() = 0; + virtual ~IReceiver() {}; }; } diff --git a/src/manager/client-async/service.cpp b/src/manager/client-async/service.cpp index 40ab9ac3..cd7cd198 100644 --- a/src/manager/client-async/service.cpp +++ b/src/manager/client-async/service.cpp @@ -37,179 +37,188 @@ namespace { const size_t RECV_BUFFER_SIZE = 2048; } -Service::Service(IDescriptorSet& descriptors, const std::string& interface) : - m_interface(interface), - m_descriptors(descriptors) +Service::Service(IDescriptorSet &descriptors, const std::string &interface) : + m_interface(interface), + m_descriptors(descriptors) { } -void Service::addRequest(AsyncRequest&& req) +void Service::addRequest(AsyncRequest &&req) { - if (!m_socket) { - m_socket.reset(new SockRAII()); - int ret; - if (CKM_API_SUCCESS != (ret = m_socket->connect(m_interface.c_str()))) { - LogError("Socket connection failed: " << ret); - m_socket.reset(); - req.observer->ReceivedError(ret); - return; - } - } - - if (m_sendQueue.empty()) - watch(POLLOUT); - - m_sendQueue.push(std::move(req)); + if (!m_socket) { + m_socket.reset(new SockRAII()); + int ret; + + if (CKM_API_SUCCESS != (ret = m_socket->connect(m_interface.c_str()))) { + LogError("Socket connection failed: " << ret); + m_socket.reset(); + req.observer->ReceivedError(ret); + return; + } + } + + if (m_sendQueue.empty()) + watch(POLLOUT); + + m_sendQueue.push(std::move(req)); } void Service::serviceError(int error) { - if (m_socket) { - // stop listening on socket - m_descriptors.remove(m_socket->get(), false); - // close the socket - m_socket.reset(); - } - - // notify observers waiting for response - for (const auto& it: m_responseMap) - it.second.observer->ReceivedError(error); - - m_responseMap.clear(); - - // notify observers waiting for send - while (!m_sendQueue.empty()) { - m_sendQueue.front().observer->ReceivedError(error); - m_sendQueue.pop(); - } - - // clear response buffer - m_responseBuffer.reset(); + if (m_socket) { + // stop listening on socket + m_descriptors.remove(m_socket->get(), false); + // close the socket + m_socket.reset(); + } + + // notify observers waiting for response + for (const auto &it : m_responseMap) + it.second.observer->ReceivedError(error); + + m_responseMap.clear(); + + // notify observers waiting for send + while (!m_sendQueue.empty()) { + m_sendQueue.front().observer->ReceivedError(error); + m_sendQueue.pop(); + } + + // clear response buffer + m_responseBuffer.reset(); } void Service::socketReady(int sock, short revents) { - if (sock != m_socket->get()) { - LogError("Unexpected socket: " << sock << "!=" << m_socket->get()); - serviceError(CKM_API_ERROR_SOCKET); - return; - } - - try { - if (revents & POLLOUT) - sendData(); - else if (revents & POLLIN) - receiveData(); - else { - LogError("Unexpected event: " << revents << "!=" << POLLOUT); - serviceError(CKM_API_ERROR_SOCKET); - } - } catch (const IReceiver::BadResponse&) { - serviceError(CKM_API_ERROR_BAD_RESPONSE); - } catch (std::exception &e) { - LogError("STD exception " << e.what()); - serviceError(CKM_API_ERROR_UNKNOWN); - } catch (...) { - LogError("Unknown exception occurred"); - serviceError(CKM_API_ERROR_UNKNOWN); - } + if (sock != m_socket->get()) { + LogError("Unexpected socket: " << sock << "!=" << m_socket->get()); + serviceError(CKM_API_ERROR_SOCKET); + return; + } + + try { + if (revents & POLLOUT) { + sendData(); + } else if (revents & POLLIN) { + receiveData(); + } else { + LogError("Unexpected event: " << revents << "!=" << POLLOUT); + serviceError(CKM_API_ERROR_SOCKET); + } + } catch (const IReceiver::BadResponse &) { + serviceError(CKM_API_ERROR_BAD_RESPONSE); + } catch (std::exception &e) { + LogError("STD exception " << e.what()); + serviceError(CKM_API_ERROR_UNKNOWN); + } catch (...) { + LogError("Unknown exception occurred"); + serviceError(CKM_API_ERROR_UNKNOWN); + } } void Service::sendData() { - // nothing to send? -> stop watching POLLOUT - if (m_sendQueue.empty()) { - watch(POLLIN); - return; - } - - while (!m_sendQueue.empty()) { - AsyncRequest& req = m_sendQueue.front(); - - ssize_t temp = TEMP_FAILURE_RETRY(::send(m_socket->get(), - &req.buffer[req.written], - req.buffer.size() - req.written, - MSG_NOSIGNAL)); - if (-1 == temp) { - int err = errno; - // can't write? -> go to sleep - if (EAGAIN == err || EWOULDBLOCK == err) - return; - - LogError("Error in send: " << GetErrnoString(err)); - serviceError(CKM_API_ERROR_SEND_FAILED); - return; - } - - req.written += temp; - - // finished? -> move request to response map - if (req.written == req.buffer.size()) { - AsyncRequest finished = std::move(m_sendQueue.front()); - m_sendQueue.pop(); - - // update poll flags if necessary - if (m_sendQueue.empty() || m_responseMap.empty()) - watch((m_sendQueue.empty()? 0 : POLLOUT) | POLLIN); - - m_responseMap.insert(std::make_pair(finished.id, finished)); - } - } + // nothing to send? -> stop watching POLLOUT + if (m_sendQueue.empty()) { + watch(POLLIN); + return; + } + + while (!m_sendQueue.empty()) { + AsyncRequest &req = m_sendQueue.front(); + + ssize_t temp = TEMP_FAILURE_RETRY(::send(m_socket->get(), + &req.buffer[req.written], + req.buffer.size() - req.written, + MSG_NOSIGNAL)); + + if (-1 == temp) { + int err = errno; + + // can't write? -> go to sleep + if (EAGAIN == err || EWOULDBLOCK == err) + return; + + LogError("Error in send: " << GetErrnoString(err)); + serviceError(CKM_API_ERROR_SEND_FAILED); + return; + } + + req.written += temp; + + // finished? -> move request to response map + if (req.written == req.buffer.size()) { + AsyncRequest finished = std::move(m_sendQueue.front()); + m_sendQueue.pop(); + + // update poll flags if necessary + if (m_sendQueue.empty() || m_responseMap.empty()) + watch((m_sendQueue.empty() ? 0 : POLLOUT) | POLLIN); + + m_responseMap.insert(std::make_pair(finished.id, finished)); + } + } } void Service::receiveData() { - char buffer[RECV_BUFFER_SIZE]; - - ssize_t temp = TEMP_FAILURE_RETRY(::recv(m_socket->get(), buffer, RECV_BUFFER_SIZE, 0)); - if (-1 == temp) { - int err = errno; - LogError("Error in recv: " << GetErrnoString(err)); - serviceError(CKM_API_ERROR_RECV_FAILED); - return; - } - - if (0 == temp) { - LogError("Recv return 0/Connection closed by server(?)"); - serviceError(CKM_API_ERROR_RECV_FAILED); - return; - } - - if (!m_responseBuffer) - m_responseBuffer.reset(new MessageBuffer()); - - RawBuffer raw(buffer, buffer+temp); - m_responseBuffer->Push(raw); - - // parse while you can - while (m_responseBuffer->Ready()) { - std::unique_ptr<IReceiver> receiver; - if (m_interface == SERVICE_SOCKET_CKM_STORAGE) - receiver.reset(new StorageReceiver(*m_responseBuffer, m_responseMap)); - else if (m_interface == SERVICE_SOCKET_OCSP) - receiver.reset(new OcspReceiver(*m_responseBuffer, m_responseMap)); - else if (m_interface == SERVICE_SOCKET_ENCRYPTION) - receiver.reset(new EncryptionReceiver(*m_responseBuffer, m_responseMap)); - else { - LogError("Unknown service " << m_interface); - serviceError(CKM_API_ERROR_RECV_FAILED); - return; - } - receiver->processResponse(); - - if (m_responseMap.empty()) - watch(m_sendQueue.empty()?0:POLLOUT); - } + char buffer[RECV_BUFFER_SIZE]; + + ssize_t temp = TEMP_FAILURE_RETRY(::recv(m_socket->get(), buffer, + RECV_BUFFER_SIZE, 0)); + + if (-1 == temp) { + int err = errno; + LogError("Error in recv: " << GetErrnoString(err)); + serviceError(CKM_API_ERROR_RECV_FAILED); + return; + } + + if (0 == temp) { + LogError("Recv return 0/Connection closed by server(?)"); + serviceError(CKM_API_ERROR_RECV_FAILED); + return; + } + + if (!m_responseBuffer) + m_responseBuffer.reset(new MessageBuffer()); + + RawBuffer raw(buffer, buffer + temp); + m_responseBuffer->Push(raw); + + // parse while you can + while (m_responseBuffer->Ready()) { + std::unique_ptr<IReceiver> receiver; + + if (m_interface == SERVICE_SOCKET_CKM_STORAGE) { + receiver.reset(new StorageReceiver(*m_responseBuffer, m_responseMap)); + } else if (m_interface == SERVICE_SOCKET_OCSP) { + receiver.reset(new OcspReceiver(*m_responseBuffer, m_responseMap)); + } else if (m_interface == SERVICE_SOCKET_ENCRYPTION) { + receiver.reset(new EncryptionReceiver(*m_responseBuffer, m_responseMap)); + } else { + LogError("Unknown service " << m_interface); + serviceError(CKM_API_ERROR_RECV_FAILED); + return; + } + + receiver->processResponse(); + + if (m_responseMap.empty()) + watch(m_sendQueue.empty() ? 0 : POLLOUT); + } } void Service::watch(short events) { - if (0 == events) - m_descriptors.remove(m_socket->get(), false); - else - m_descriptors.add(m_socket->get(), - events, - [this](int sock, short revents){ socketReady(sock, revents); }); + if (0 == events) + m_descriptors.remove(m_socket->get(), false); + else + m_descriptors.add(m_socket->get(), + events, + [this](int sock, short revents) { + socketReady(sock, revents); + }); } } // namespace CKM diff --git a/src/manager/client-async/service.h b/src/manager/client-async/service.h index 0de979f8..1640f570 100644 --- a/src/manager/client-async/service.h +++ b/src/manager/client-async/service.h @@ -32,29 +32,29 @@ namespace CKM { class Service { public: - Service(IDescriptorSet& descriptors, const std::string& interface); + Service(IDescriptorSet &descriptors, const std::string &interface); - Service(Service&&) = default; - Service& operator=(Service&&) = default; + Service(Service &&) = default; + Service &operator=(Service &&) = default; - void addRequest(AsyncRequest&& req); + void addRequest(AsyncRequest &&req); - void serviceError(int error); + void serviceError(int error); private: - void socketReady(int sock, short revents); + void socketReady(int sock, short revents); - void sendData(); - void receiveData(); + void sendData(); + void receiveData(); - void watch(short events); + void watch(short events); - std::string m_interface; - std::unique_ptr<SockRAII> m_socket; - IDescriptorSet& m_descriptors; - AsyncRequest::Queue m_sendQueue; - AsyncRequest::Map m_responseMap; - std::unique_ptr<MessageBuffer> m_responseBuffer; + std::string m_interface; + std::unique_ptr<SockRAII> m_socket; + IDescriptorSet &m_descriptors; + AsyncRequest::Queue m_sendQueue; + AsyncRequest::Map m_responseMap; + std::unique_ptr<MessageBuffer> m_responseBuffer; }; } // namespace CKM diff --git a/src/manager/client-async/storage-receiver.cpp b/src/manager/client-async/storage-receiver.cpp index b8b59a19..ad259173 100644 --- a/src/manager/client-async/storage-receiver.cpp +++ b/src/manager/client-async/storage-receiver.cpp @@ -28,257 +28,276 @@ namespace CKM { -StorageReceiver::StorageReceiver(MessageBuffer& buffer, AsyncRequest::Map& requests) : - m_buffer(buffer), - m_requests(requests), - m_observer(NULL) +StorageReceiver::StorageReceiver(MessageBuffer &buffer, + AsyncRequest::Map &requests) : + m_buffer(buffer), + m_requests(requests), + m_observer(NULL) { } void StorageReceiver::processResponse() { - int command = 0, id = 0; - m_buffer.Deserialize(command, id); - - auto it = m_requests.find(id); - if (it == m_requests.end()) { - LogError("Request with id " << id << " not found!"); - ThrowMsg(BadResponse, "Request with id " << id << " not found!"); - } - - // let it throw - AsyncRequest req = std::move(m_requests.at(id)); - m_requests.erase(id); - - m_observer = req.observer; - - switch (static_cast<LogicCommand>(command)) { - case LogicCommand::GET: - parseGetCommand(); - break; - case LogicCommand::GET_PKCS12: - parseGetPKCS12Command(); - break; - case LogicCommand::GET_LIST: - parseGetListCommand(); - break; - case LogicCommand::SAVE: - parseSaveCommand(); - break; - case LogicCommand::SAVE_PKCS12: - parseSavePKCS12Command(); - break; - case LogicCommand::REMOVE: - parseRemoveCommand(); - break; - case LogicCommand::CREATE_KEY_AES: - parseRetCode(&ManagerAsync::Observer::ReceivedCreateKeyAES); - break; - case LogicCommand::CREATE_KEY_PAIR: - parseRetCode(&ManagerAsync::Observer::ReceivedCreateKeyPair); - break; - case LogicCommand::GET_CHAIN_CERT: - case LogicCommand::GET_CHAIN_ALIAS: - parseGetChainCertCommand(); - break; - case LogicCommand::CREATE_SIGNATURE: - parseCreateSignatureCommand(); - break; - case LogicCommand::VERIFY_SIGNATURE: - parseRetCode(&ManagerAsync::Observer::ReceivedVerifySignature); - break; - case LogicCommand::SET_PERMISSION: - parseRetCode(&ManagerAsync::Observer::ReceivedSetPermission); - break; - - default: - LogError("Unknown command id: " << command); - ThrowMsg(BadResponse, "Unknown command id: " << command); - break; - } + int command = 0, id = 0; + m_buffer.Deserialize(command, id); + + auto it = m_requests.find(id); + + if (it == m_requests.end()) { + LogError("Request with id " << id << " not found!"); + ThrowMsg(BadResponse, "Request with id " << id << " not found!"); + } + + // let it throw + AsyncRequest req = std::move(m_requests.at(id)); + m_requests.erase(id); + + m_observer = req.observer; + + switch (static_cast<LogicCommand>(command)) { + case LogicCommand::GET: + parseGetCommand(); + break; + + case LogicCommand::GET_PKCS12: + parseGetPKCS12Command(); + break; + + case LogicCommand::GET_LIST: + parseGetListCommand(); + break; + + case LogicCommand::SAVE: + parseSaveCommand(); + break; + + case LogicCommand::SAVE_PKCS12: + parseSavePKCS12Command(); + break; + + case LogicCommand::REMOVE: + parseRemoveCommand(); + break; + + case LogicCommand::CREATE_KEY_AES: + parseRetCode(&ManagerAsync::Observer::ReceivedCreateKeyAES); + break; + + case LogicCommand::CREATE_KEY_PAIR: + parseRetCode(&ManagerAsync::Observer::ReceivedCreateKeyPair); + break; + + case LogicCommand::GET_CHAIN_CERT: + case LogicCommand::GET_CHAIN_ALIAS: + parseGetChainCertCommand(); + break; + + case LogicCommand::CREATE_SIGNATURE: + parseCreateSignatureCommand(); + break; + + case LogicCommand::VERIFY_SIGNATURE: + parseRetCode(&ManagerAsync::Observer::ReceivedVerifySignature); + break; + + case LogicCommand::SET_PERMISSION: + parseRetCode(&ManagerAsync::Observer::ReceivedSetPermission); + break; + + default: + LogError("Unknown command id: " << command); + ThrowMsg(BadResponse, "Unknown command id: " << command); + break; + } } void StorageReceiver::parseGetCommand() { - RawBuffer rawData; - int dataType = 0, retCode = 0; - m_buffer.Deserialize(retCode, dataType, rawData); - - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } - - DataType type(dataType); - if (type.isKey()) - m_observer->ReceivedKey(KeyImpl(rawData)); - else if (type.isCertificate()) - m_observer->ReceivedCertificate(CertificateImpl(rawData, DataFormat::FORM_DER)); - else if (type.isBinaryData()) - m_observer->ReceivedData(std::move(rawData)); - else - m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); + RawBuffer rawData; + int dataType = 0, retCode = 0; + m_buffer.Deserialize(retCode, dataType, rawData); + + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } + + DataType type(dataType); + + if (type.isKey()) + m_observer->ReceivedKey(KeyImpl(rawData)); + else if (type.isCertificate()) + m_observer->ReceivedCertificate(CertificateImpl(rawData, DataFormat::FORM_DER)); + else if (type.isBinaryData()) + m_observer->ReceivedData(std::move(rawData)); + else + m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); } void StorageReceiver::parseGetPKCS12Command() { - int retCode = 0; - PKCS12Serializable gotPkcs; - m_buffer.Deserialize(retCode, gotPkcs); + int retCode = 0; + PKCS12Serializable gotPkcs; + m_buffer.Deserialize(retCode, gotPkcs); - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } - m_observer->ReceivedPKCS12(std::make_shared<PKCS12Impl>(std::move(gotPkcs))); + m_observer->ReceivedPKCS12(std::make_shared<PKCS12Impl>(std::move(gotPkcs))); } void StorageReceiver::parseGetListCommand() { - int dataType = 0, retCode = 0; - LabelNameVector labelNameVector; - m_buffer.Deserialize(retCode, dataType, labelNameVector); - - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } - - AliasVector aliasVector; - for (const auto &it : labelNameVector) - aliasVector.push_back(AliasSupport::merge(it.first, it.second)); - - DataType type(dataType); - - if (type.isKey()) - m_observer->ReceivedKeyAliasVector(std::move(aliasVector)); - else if (type.isCertificate()) - m_observer->ReceivedCertificateAliasVector(std::move(aliasVector)); - else if (type.isBinaryData()) - m_observer->ReceivedDataAliasVector(std::move(aliasVector)); - else - m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); + int dataType = 0, retCode = 0; + LabelNameVector labelNameVector; + m_buffer.Deserialize(retCode, dataType, labelNameVector); + + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } + + AliasVector aliasVector; + + for (const auto &it : labelNameVector) + aliasVector.push_back(AliasSupport::merge(it.first, it.second)); + + DataType type(dataType); + + if (type.isKey()) + m_observer->ReceivedKeyAliasVector(std::move(aliasVector)); + else if (type.isCertificate()) + m_observer->ReceivedCertificateAliasVector(std::move(aliasVector)); + else if (type.isBinaryData()) + m_observer->ReceivedDataAliasVector(std::move(aliasVector)); + else + m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); } void StorageReceiver::parseSaveCommand() { - int dataType = 0, retCode = 0; - m_buffer.Deserialize(retCode, dataType); - - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } - - DataType type(dataType); - if (type.isKey()) - m_observer->ReceivedSaveKey(); - else if (type.isCertificate()) - m_observer->ReceivedSaveCertificate(); - else if (type.isBinaryData()) - m_observer->ReceivedSaveData(); - else - m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); + int dataType = 0, retCode = 0; + m_buffer.Deserialize(retCode, dataType); + + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } + + DataType type(dataType); + + if (type.isKey()) + m_observer->ReceivedSaveKey(); + else if (type.isCertificate()) + m_observer->ReceivedSaveCertificate(); + else if (type.isBinaryData()) + m_observer->ReceivedSaveData(); + else + m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); } void StorageReceiver::parseSavePKCS12Command() { - int retCode = 0; - m_buffer.Deserialize(retCode); + int retCode = 0; + m_buffer.Deserialize(retCode); - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } - m_observer->ReceivedSavePKCS12(); + m_observer->ReceivedSavePKCS12(); } void StorageReceiver::parseRemoveCommand() { - int retCode = 0; - m_buffer.Deserialize(retCode); + int retCode = 0; + m_buffer.Deserialize(retCode); - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } - m_observer->ReceivedRemovedAlias(); + m_observer->ReceivedRemovedAlias(); } void StorageReceiver::parseGetChainCertCommand() { - CertificateShPtrVector certificateChainVector; - RawBufferVector rawBufferVector; - int retCode = 0; - m_buffer.Deserialize(retCode, rawBufferVector); - - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } - - for (auto &e: rawBufferVector) { - CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER)); - if (cert->empty()) { - m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); - return; - } - certificateChainVector.push_back(cert); - } - m_observer->ReceivedGetCertificateChain(std::move(certificateChainVector)); + CertificateShPtrVector certificateChainVector; + RawBufferVector rawBufferVector; + int retCode = 0; + m_buffer.Deserialize(retCode, rawBufferVector); + + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } + + for (auto &e : rawBufferVector) { + CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER)); + + if (cert->empty()) { + m_observer->ReceivedError(CKM_API_ERROR_BAD_RESPONSE); + return; + } + + certificateChainVector.push_back(cert); + } + + m_observer->ReceivedGetCertificateChain(std::move(certificateChainVector)); } void StorageReceiver::parseCreateSignatureCommand() { - int retCode = 0; - RawBuffer signature; - m_buffer.Deserialize(retCode, signature); + int retCode = 0; + RawBuffer signature; + m_buffer.Deserialize(retCode, signature); - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } - m_observer->ReceivedCreateSignature(std::move(signature)); + m_observer->ReceivedCreateSignature(std::move(signature)); } void StorageReceiver::parseSetPermission() { - int retCode = 0; - m_buffer.Deserialize(retCode); + int retCode = 0; + m_buffer.Deserialize(retCode); - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } - m_observer->ReceivedSetPermission(); + m_observer->ReceivedSetPermission(); } void StorageReceiver::parseRetCode(ObserverCb callback) { - int retCode = 0; - m_buffer.Deserialize(retCode); + int retCode = 0; + m_buffer.Deserialize(retCode); - // check error code - if (retCode != CKM_API_SUCCESS) { - m_observer->ReceivedError(retCode); - return; - } + // check error code + if (retCode != CKM_API_SUCCESS) { + m_observer->ReceivedError(retCode); + return; + } - (m_observer.get()->*callback)(); + (m_observer.get()->*callback)(); } } /* namespace CKM */ diff --git a/src/manager/client-async/storage-receiver.h b/src/manager/client-async/storage-receiver.h index 98847b69..5cfa7c72 100644 --- a/src/manager/client-async/storage-receiver.h +++ b/src/manager/client-async/storage-receiver.h @@ -29,34 +29,33 @@ namespace CKM { -class StorageReceiver : public IReceiver -{ +class StorageReceiver : public IReceiver { public: - StorageReceiver(MessageBuffer& buffer, AsyncRequest::Map& reqMap); - virtual ~StorageReceiver() {} + StorageReceiver(MessageBuffer &buffer, AsyncRequest::Map &reqMap); + virtual ~StorageReceiver() {} - NONCOPYABLE(StorageReceiver); + NONCOPYABLE(StorageReceiver); - void processResponse(); + void processResponse(); private: - void parseGetCommand(); - void parseGetPKCS12Command(); - void parseGetListCommand(); - void parseSaveCommand(); - void parseSavePKCS12Command(); - void parseRemoveCommand(); - void parseGetChainCertCommand(); - void parseCreateSignatureCommand(); - void parseSetPermission(); - - typedef void (ManagerAsync::Observer::*ObserverCb)(); - - void parseRetCode(ObserverCb callback); - - MessageBuffer& m_buffer; - AsyncRequest::Map& m_requests; - ManagerAsync::ObserverPtr m_observer; + void parseGetCommand(); + void parseGetPKCS12Command(); + void parseGetListCommand(); + void parseSaveCommand(); + void parseSavePKCS12Command(); + void parseRemoveCommand(); + void parseGetChainCertCommand(); + void parseCreateSignatureCommand(); + void parseSetPermission(); + + typedef void (ManagerAsync::Observer::*ObserverCb)(); + + void parseRetCode(ObserverCb callback); + + MessageBuffer &m_buffer; + AsyncRequest::Map &m_requests; + ManagerAsync::ObserverPtr m_observer; }; } /* namespace CKM */ diff --git a/src/manager/client-capi/ckmc-control.cpp b/src/manager/client-capi/ckmc-control.cpp index ebc5c929..bd7a7d1f 100644 --- a/src/manager/client-capi/ckmc-control.cpp +++ b/src/manager/client-capi/ckmc-control.cpp @@ -29,89 +29,98 @@ CKM::Password _toPasswordStr(const char *str) { - if (str == NULL) - return CKM::Password(); - return CKM::Password(str); + if (str == NULL) + return CKM::Password(); + + return CKM::Password(str); } KEY_MANAGER_CAPI int ckmc_unlock_user_key(uid_t user, const char *password) { - auto control = CKM::Control::create(); - int ret = control->unlockUserKey(user, _toPasswordStr(password)); - return to_ckmc_error(ret); + auto control = CKM::Control::create(); + int ret = control->unlockUserKey(user, _toPasswordStr(password)); + return to_ckmc_error(ret); } KEY_MANAGER_CAPI int ckmc_lock_user_key(uid_t user) { - auto control = CKM::Control::create(); - int ret = control->lockUserKey(user); - return to_ckmc_error(ret); + auto control = CKM::Control::create(); + int ret = control->lockUserKey(user); + return to_ckmc_error(ret); } KEY_MANAGER_CAPI int ckmc_remove_user_data(uid_t user) { - auto control = CKM::Control::create(); - int ret = control->removeUserData(user); - return to_ckmc_error(ret); + auto control = CKM::Control::create(); + int ret = control->removeUserData(user); + return to_ckmc_error(ret); } KEY_MANAGER_CAPI -int ckmc_change_user_password(uid_t user, const char *oldPassword, const char *newPassword) +int ckmc_change_user_password(uid_t user, const char *oldPassword, + const char *newPassword) { - auto control = CKM::Control::create(); - int ret = control->changeUserPassword(user, - _toPasswordStr(oldPassword), - _toPasswordStr(newPassword)); - return to_ckmc_error(ret); + auto control = CKM::Control::create(); + int ret = control->changeUserPassword(user, + _toPasswordStr(oldPassword), + _toPasswordStr(newPassword)); + return to_ckmc_error(ret); } KEY_MANAGER_CAPI int ckmc_reset_user_password(uid_t user, const char *newPassword) { - auto control = CKM::Control::create(); - int ret = control->resetUserPassword(user, _toPasswordStr(newPassword)); - return to_ckmc_error(ret); + auto control = CKM::Control::create(); + int ret = control->resetUserPassword(user, _toPasswordStr(newPassword)); + return to_ckmc_error(ret); } KEY_MANAGER_CAPI -int ckmc_allow_access_by_adm(uid_t user, const char* owner, const char *alias, const char *accessor, ckmc_access_right_e granted) +int ckmc_allow_access_by_adm(uid_t user, const char *owner, const char *alias, + const char *accessor, ckmc_access_right_e granted) { - if (!owner || !alias) - return CKMC_ERROR_INVALID_PARAMETER; + if (!owner || !alias) + return CKMC_ERROR_INVALID_PARAMETER; + + int ec, permissionMask; + ec = access_to_permission_mask(granted, permissionMask); - int ec, permissionMask; - ec = access_to_permission_mask(granted, permissionMask); - if (ec != CKMC_ERROR_NONE) - return ec; + if (ec != CKMC_ERROR_NONE) + return ec; - // if label given twice, service will return an error - return ckmc_set_permission_by_adm(user, CKM::AliasSupport::merge(CKM::Label(owner), CKM::Name(alias)).c_str(), accessor, permissionMask); + // if label given twice, service will return an error + return ckmc_set_permission_by_adm(user, + CKM::AliasSupport::merge(CKM::Label(owner), CKM::Name(alias)).c_str(), accessor, + permissionMask); } KEY_MANAGER_CAPI -int ckmc_set_permission_by_adm(uid_t user, const char *alias, const char *accessor, int permissions) +int ckmc_set_permission_by_adm(uid_t user, const char *alias, + const char *accessor, int permissions) { - if (!alias || !accessor) - return CKMC_ERROR_INVALID_PARAMETER; + if (!alias || !accessor) + return CKMC_ERROR_INVALID_PARAMETER; - auto control = CKM::Control::create(); - return to_ckmc_error(control->setPermission(user, alias, accessor, permissions)); + auto control = CKM::Control::create(); + return to_ckmc_error(control->setPermission(user, alias, accessor, + permissions)); } KEY_MANAGER_CAPI -int ckmc_deny_access_by_adm(uid_t user, const char* owner, const char *alias, const char *accessor) +int ckmc_deny_access_by_adm(uid_t user, const char *owner, const char *alias, + const char *accessor) { - if (!owner || !alias) - return CKMC_ERROR_INVALID_PARAMETER; - - // if label given twice, service will return an error - auto control = CKM::Control::create(); - return to_ckmc_error(control->setPermission( - user, - CKM::AliasSupport::merge(CKM::Label(owner), CKM::Name(alias)).c_str(), - accessor, - CKM::Permission::NONE)); + if (!owner || !alias) + return CKMC_ERROR_INVALID_PARAMETER; + + // if label given twice, service will return an error + auto control = CKM::Control::create(); + return to_ckmc_error(control->setPermission( + user, + CKM::AliasSupport::merge(CKM::Label(owner), CKM::Name(alias)).c_str(), + accessor, + CKM::Permission::NONE)); } diff --git a/src/manager/client-capi/ckmc-manager.cpp b/src/manager/client-capi/ckmc-manager.cpp index b0601650..7f337a1e 100644 --- a/src/manager/client-capi/ckmc-manager.cpp +++ b/src/manager/client-capi/ckmc-manager.cpp @@ -37,784 +37,882 @@ const CKM::AliasVector EMPTY_ALIAS_VECTOR; inline CKM::Password _tostring(const char *str) { - return (str == nullptr) ? CKM::Password() : CKM::Password(str); + return (str == nullptr) ? CKM::Password() : CKM::Password(str); } inline CKM::Policy _toCkmPolicy(const ckmc_policy_s &policy) { - return CKM::Policy(_tostring(policy.password), policy.extractable); + return CKM::Policy(_tostring(policy.password), policy.extractable); } inline CKM::KeyShPtr _toCkmKey(const ckmc_key_s *key) { - return (key == nullptr) ? - CKM::KeyShPtr() : - CKM::Key::create( - CKM::RawBuffer(key->raw_key, key->raw_key + key->key_size), - _tostring(key->password)); + return (key == nullptr) ? + CKM::KeyShPtr() : + CKM::Key::create( + CKM::RawBuffer(key->raw_key, key->raw_key + key->key_size), + _tostring(key->password)); } inline CKM::CertificateShPtr _toCkmCertificate(const ckmc_cert_s *cert) { - return (cert == nullptr) ? - CKM::CertificateShPtr() : - CKM::Certificate::create( - CKM::RawBuffer(cert->raw_cert, cert->raw_cert + cert->cert_size), - static_cast<CKM::DataFormat>(static_cast<int>(cert->data_format))); + return (cert == nullptr) ? + CKM::CertificateShPtr() : + CKM::Certificate::create( + CKM::RawBuffer(cert->raw_cert, cert->raw_cert + cert->cert_size), + static_cast<CKM::DataFormat>(static_cast<int>(cert->data_format))); } -CKM::CertificateShPtrVector _toCkmCertificateVector(const ckmc_cert_list_s *list) +CKM::CertificateShPtrVector _toCkmCertificateVector(const ckmc_cert_list_s + *list) { - CKM::CertificateShPtrVector certs; - auto current = list; - while (current != nullptr) { - if (current->cert != nullptr) - certs.emplace_back(_toCkmCertificate(current->cert)); - current = current->next; - } - return certs; + CKM::CertificateShPtrVector certs; + auto current = list; + + while (current != nullptr) { + if (current->cert != nullptr) + certs.emplace_back(_toCkmCertificate(current->cert)); + + current = current->next; + } + + return certs; } CKM::AliasVector _toCkmAliasVector(const ckmc_alias_list_s *list) { - CKM::AliasVector aliases; - auto current = list; - while (current != nullptr) { - if (current->alias != nullptr) - aliases.emplace_back(CKM::Alias(current->alias)); - current = current->next; - } - return aliases; + CKM::AliasVector aliases; + auto current = list; + + while (current != nullptr) { + if (current->alias != nullptr) + aliases.emplace_back(CKM::Alias(current->alias)); + + current = current->next; + } + + return aliases; } -ckmc_cert_list_s *_toNewCkmCertList(const CKM::CertificateShPtrVector &certVector) +ckmc_cert_list_s *_toNewCkmCertList(const CKM::CertificateShPtrVector + &certVector) { - ckmc_cert_list_s *start = nullptr; - ckmc_cert_list_s *plist = nullptr; + ckmc_cert_list_s *start = nullptr; + ckmc_cert_list_s *plist = nullptr; + + for (const auto &e : certVector) { + auto rawBuffer = e->getDER(); + ckmc_cert_s *pcert = nullptr; + int ret = ckmc_cert_new(rawBuffer.data(), rawBuffer.size(), CKMC_FORM_DER, + &pcert); - for (const auto &e : certVector) { - auto rawBuffer = e->getDER(); - ckmc_cert_s *pcert = nullptr; - int ret = ckmc_cert_new(rawBuffer.data(), rawBuffer.size(), CKMC_FORM_DER, &pcert); - if (ret != CKMC_ERROR_NONE || pcert == nullptr) { - ckmc_cert_list_all_free(start); - return nullptr; - } + if (ret != CKMC_ERROR_NONE || pcert == nullptr) { + ckmc_cert_list_all_free(start); + return nullptr; + } - ret = ckmc_cert_list_add(plist, pcert, &plist); - if (ret != CKMC_ERROR_NONE) { - ckmc_cert_list_all_free(start); - return nullptr; - } + ret = ckmc_cert_list_add(plist, pcert, &plist); - if (start == nullptr) - start = plist; - } + if (ret != CKMC_ERROR_NONE) { + ckmc_cert_list_all_free(start); + return nullptr; + } - return start; + if (start == nullptr) + start = plist; + } + + return start; } -typedef int (CKM::Manager::*cryptoFn)(const CKM::CryptoAlgorithm&, - const CKM::Alias&, - const CKM::Password&, - const CKM::RawBuffer&, - CKM::RawBuffer&); +typedef int (CKM::Manager::*cryptoFn)(const CKM::CryptoAlgorithm &, + const CKM::Alias &, + const CKM::Password &, + const CKM::RawBuffer &, + CKM::RawBuffer &); int _cryptoOperation(cryptoFn operation, - ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s in, - ckmc_raw_buffer_s **ppout) + ckmc_param_list_h params, + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s in, + ckmc_raw_buffer_s **ppout) { - if (!params || !key_alias || !ppout) - return CKMC_ERROR_INVALID_PARAMETER; + if (!params || !key_alias || !ppout) + return CKMC_ERROR_INVALID_PARAMETER; - // params - const CKM::CryptoAlgorithm* ca = reinterpret_cast<const CKM::CryptoAlgorithm*>(params); + // params + const CKM::CryptoAlgorithm *ca = reinterpret_cast<const CKM::CryptoAlgorithm *> + (params); - // password - CKM::Password pass; - if (password) - pass = password; + // password + CKM::Password pass; - // buffers - CKM::RawBuffer inBuffer(in.data, in.data + in.size); - CKM::RawBuffer outBuffer; + if (password) + pass = password; - auto mgr = CKM::Manager::create(); - int ret = ((*mgr).*operation)(*ca, key_alias, pass, inBuffer, outBuffer); - if (ret != CKM_API_SUCCESS) - return to_ckmc_error(ret); + // buffers + CKM::RawBuffer inBuffer(in.data, in.data + in.size); + CKM::RawBuffer outBuffer; - return ckmc_buffer_new(outBuffer.data(), outBuffer.size(), ppout); -} + auto mgr = CKM::Manager::create(); + int ret = ((*mgr).*operation)(*ca, key_alias, pass, inBuffer, outBuffer); -int try_catch_enclosure(const std::function<int()> &func) -{ - try { - return func(); - } catch (const std::bad_alloc &e) { - LogError("memory allocation exception: " << e.what()); - return CKMC_ERROR_OUT_OF_MEMORY; - } catch (const std::exception &e) { - LogError("std exception occured: " << e.what()); - return CKMC_ERROR_UNKNOWN; - } catch (...) { - LogError("Unknown exception occured."); - return CKMC_ERROR_UNKNOWN; - } + if (ret != CKM_API_SUCCESS) + return to_ckmc_error(ret); + + return ckmc_buffer_new(outBuffer.data(), outBuffer.size(), ppout); } } KEY_MANAGER_CAPI -int ckmc_save_key(const char *alias, const ckmc_key_s key, const ckmc_policy_s policy) +int ckmc_save_key(const char *alias, const ckmc_key_s key, + const ckmc_policy_s policy) { - return try_catch_enclosure([&]()->int { - auto mgr = CKM::Manager::create(); + EXCEPTION_GUARD_START_CAPI + + auto mgr = CKM::Manager::create(); + + if (alias == nullptr || key.raw_key == nullptr || key.key_size == 0) + return CKMC_ERROR_INVALID_PARAMETER; - if (alias == nullptr || key.raw_key == nullptr || key.key_size == 0) - return CKMC_ERROR_INVALID_PARAMETER; + CKM::RawBuffer buffer(key.raw_key, key.raw_key + key.key_size); + CKM::KeyShPtr ckmKey; - CKM::RawBuffer buffer(key.raw_key, key.raw_key + key.key_size); - CKM::KeyShPtr ckmKey; + if (key.key_type == CKMC_KEY_AES) { + if (key.password) + return CKMC_ERROR_INVALID_PARAMETER; - if (key.key_type == CKMC_KEY_AES) { - if (key.password) - return CKMC_ERROR_INVALID_PARAMETER; - ckmKey = CKM::Key::createAES(buffer); - } else { - ckmKey = CKM::Key::create(buffer, _tostring(key.password)); - } + ckmKey = CKM::Key::createAES(buffer); + } else { + ckmKey = CKM::Key::create(buffer, _tostring(key.password)); + } - if (!ckmKey) - return CKMC_ERROR_INVALID_FORMAT; + if (!ckmKey) + return CKMC_ERROR_INVALID_FORMAT; - return to_ckmc_error(mgr->saveKey(CKM::Alias(alias), ckmKey, _toCkmPolicy(policy))); - }); + return to_ckmc_error(mgr->saveKey(CKM::Alias(alias), ckmKey, + _toCkmPolicy(policy))); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_remove_key(const char *alias) { - return ckmc_remove_alias(alias); + return ckmc_remove_alias(alias); } KEY_MANAGER_CAPI int ckmc_get_key(const char *alias, const char *password, ckmc_key_s **key) { - return try_catch_enclosure([&]()->int { + EXCEPTION_GUARD_START_CAPI + + if (alias == nullptr || key == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - if (alias == nullptr || key == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + int ret; + CKM::KeyShPtr ckmKey; + auto mgr = CKM::Manager::create(); - int ret; - CKM::KeyShPtr ckmKey; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->getKey(alias, _tostring(password), ckmKey)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); + if ((ret = mgr->getKey(alias, _tostring(password), ckmKey)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); - auto buffer = ckmKey->getDER(); - return ckmc_key_new( - buffer.data(), - buffer.size(), - static_cast<ckmc_key_type_e>(static_cast<int>(ckmKey->getType())), - nullptr, - key); - }); + auto buffer = ckmKey->getDER(); + return ckmc_key_new( + buffer.data(), + buffer.size(), + static_cast<ckmc_key_type_e>(static_cast<int>(ckmKey->getType())), + nullptr, + key); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_key_alias_list(ckmc_alias_list_s** alias_list) +int ckmc_get_key_alias_list(ckmc_alias_list_s **alias_list) { - return try_catch_enclosure([&]()->int { - int ret; + EXCEPTION_GUARD_START_CAPI + + int ret; - if (alias_list == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + if (alias_list == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - CKM::AliasVector aliasVector; - auto mgr = CKM::Manager::create(); + CKM::AliasVector aliasVector; + auto mgr = CKM::Manager::create(); - if ((ret = mgr->getKeyAliasVector(aliasVector)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); + if ((ret = mgr->getKeyAliasVector(aliasVector)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); - ckmc_alias_list_s *start = nullptr; - ckmc_alias_list_s *plist = nullptr; + ckmc_alias_list_s *start = nullptr; + ckmc_alias_list_s *plist = nullptr; - for (const auto &it : aliasVector) { - char *alias = strndup(it.c_str(), it.size()); + for (const auto &it : aliasVector) { + char *alias = strndup(it.c_str(), it.size()); - ret = ckmc_alias_list_add(plist, alias, &plist); + ret = ckmc_alias_list_add(plist, alias, &plist); - if (ret != CKMC_ERROR_NONE) { - free(alias); - ckmc_alias_list_all_free(start); - return ret; - } + if (ret != CKMC_ERROR_NONE) { + free(alias); + ckmc_alias_list_all_free(start); + return ret; + } - if (start == nullptr) - start = plist; - } + if (start == nullptr) + start = plist; + } - if (plist == nullptr) // if the alias_list size is zero - return CKMC_ERROR_DB_ALIAS_UNKNOWN; + if (plist == nullptr) // if the alias_list size is zero + return CKMC_ERROR_DB_ALIAS_UNKNOWN; - *alias_list = start; + *alias_list = start; - return CKMC_ERROR_NONE; - }); + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_save_cert(const char *alias, const ckmc_cert_s cert, const ckmc_policy_s policy) +int ckmc_save_cert(const char *alias, const ckmc_cert_s cert, + const ckmc_policy_s policy) { - return try_catch_enclosure([&]()->int { - if (alias == nullptr || cert.raw_cert == nullptr || cert.cert_size == 0) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (alias == nullptr || cert.raw_cert == nullptr || cert.cert_size == 0) + return CKMC_ERROR_INVALID_PARAMETER; + + auto ckmCert = _toCkmCertificate(&cert); - auto ckmCert = _toCkmCertificate(&cert); - if (!ckmCert) - return CKMC_ERROR_INVALID_FORMAT; + if (!ckmCert) + return CKMC_ERROR_INVALID_FORMAT; - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->saveCertificate(CKM::Alias(alias), ckmCert, _toCkmPolicy(policy))); - }); + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->saveCertificate(CKM::Alias(alias), ckmCert, + _toCkmPolicy(policy))); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_remove_cert(const char *alias) { - return ckmc_remove_alias(alias); + return ckmc_remove_alias(alias); } KEY_MANAGER_CAPI int ckmc_get_cert(const char *alias, const char *password, ckmc_cert_s **cert) { - return try_catch_enclosure([&]()->int { - CKM::CertificateShPtr ckmCert; - int ret; + EXCEPTION_GUARD_START_CAPI + + CKM::CertificateShPtr ckmCert; + int ret; + + if (alias == nullptr || cert == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - if (alias == nullptr || cert == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + auto mgr = CKM::Manager::create(); - auto mgr = CKM::Manager::create(); - if ((ret = mgr->getCertificate(alias, _tostring(password), ckmCert)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); + if ((ret = mgr->getCertificate(alias, _tostring(password), + ckmCert)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); - auto buffer = ckmCert->getDER(); - return ckmc_cert_new(buffer.data(), buffer.size(), CKMC_FORM_DER, cert); - }); + auto buffer = ckmCert->getDER(); + return ckmc_cert_new(buffer.data(), buffer.size(), CKMC_FORM_DER, cert); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_cert_alias_list(ckmc_alias_list_s** alias_list) +int ckmc_get_cert_alias_list(ckmc_alias_list_s **alias_list) { - return try_catch_enclosure([&]()->int { - if (alias_list == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (alias_list == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + CKM::AliasVector aliasVector; + int ret; + auto mgr = CKM::Manager::create(); - CKM::AliasVector aliasVector; - int ret; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->getCertificateAliasVector(aliasVector)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); + if ((ret = mgr->getCertificateAliasVector(aliasVector)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); - ckmc_alias_list_s *start = nullptr; - ckmc_alias_list_s *plist = nullptr; + ckmc_alias_list_s *start = nullptr; + ckmc_alias_list_s *plist = nullptr; - for (const auto &it : aliasVector) { - char *alias = strndup(it.c_str(), it.size()); + for (const auto &it : aliasVector) { + char *alias = strndup(it.c_str(), it.size()); - ret = ckmc_alias_list_add(plist, alias, &plist); + ret = ckmc_alias_list_add(plist, alias, &plist); - if (ret != CKMC_ERROR_NONE) { - free(alias); - ckmc_alias_list_all_free(start); - return ret; - } + if (ret != CKMC_ERROR_NONE) { + free(alias); + ckmc_alias_list_all_free(start); + return ret; + } - if (start == nullptr) - start = plist; - } + if (start == nullptr) + start = plist; + } - if (plist == nullptr) // if the alias_list size is zero - return CKMC_ERROR_DB_ALIAS_UNKNOWN; + if (plist == nullptr) // if the alias_list size is zero + return CKMC_ERROR_DB_ALIAS_UNKNOWN; - *alias_list = start; + *alias_list = start; - return CKMC_ERROR_NONE; - }); + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_save_pkcs12(const char *alias, const ckmc_pkcs12_s *ppkcs, const ckmc_policy_s key_policy, const ckmc_policy_s cert_policy) +int ckmc_save_pkcs12(const char *alias, const ckmc_pkcs12_s *ppkcs, + const ckmc_policy_s key_policy, const ckmc_policy_s cert_policy) { - return try_catch_enclosure([&]()->int { - if (alias == nullptr || ppkcs == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (alias == nullptr || ppkcs == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - CKM::PKCS12ShPtr pkcs12(new CKM::PKCS12Impl( - _toCkmKey(ppkcs->priv_key), - _toCkmCertificate(ppkcs->cert), - _toCkmCertificateVector(ppkcs->ca_chain))); + CKM::PKCS12ShPtr pkcs12(new CKM::PKCS12Impl( + _toCkmKey(ppkcs->priv_key), + _toCkmCertificate(ppkcs->cert), + _toCkmCertificateVector(ppkcs->ca_chain))); - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->savePKCS12( - CKM::Alias(alias), - pkcs12, - _toCkmPolicy(key_policy), - _toCkmPolicy(cert_policy))); - }); + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->savePKCS12( + CKM::Alias(alias), + pkcs12, + _toCkmPolicy(key_policy), + _toCkmPolicy(cert_policy))); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_pkcs12(const char *alias, const char *key_password, const char *cert_password, ckmc_pkcs12_s **pkcs12) -{ - return try_catch_enclosure([&]()->int { - if (!alias || !pkcs12) - return CKMC_ERROR_INVALID_PARAMETER; - - int ret; - CKM::PKCS12ShPtr pkcs; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->getPKCS12(alias, _tostring(key_password), _tostring(cert_password), pkcs)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); - - if (!pkcs) - return CKMC_ERROR_BAD_RESPONSE; - - ckmc_key_s *private_key = nullptr; - auto pkcsKey = pkcs->getKey(); - if (pkcsKey) { - auto buffer = pkcsKey->getDER(); - ckmc_key_type_e keyType = static_cast<ckmc_key_type_e>(pkcsKey->getType()); - ret = ckmc_key_new(buffer.data(), buffer.size(), keyType, nullptr, &private_key); - if (ret != CKMC_ERROR_NONE) - return ret; - } - - ckmc_cert_s *cert = nullptr; - auto pkcsCert = pkcs->getCertificate(); - if (pkcsCert) { - CKM::RawBuffer buffer = pkcsCert->getDER(); - ret = ckmc_cert_new(buffer.data(), buffer.size(), CKMC_FORM_DER, &cert); - if (ret != CKMC_ERROR_NONE) { - ckmc_key_free(private_key); - return ret; - } - } - - auto ca_cert_list = _toNewCkmCertList(pkcs->getCaCertificateShPtrVector()); - - ret = ckmc_pkcs12_new(private_key, cert, ca_cert_list, pkcs12); - if (ret != CKMC_ERROR_NONE) { - ckmc_key_free(private_key); - ckmc_cert_free(cert); - ckmc_cert_list_free(ca_cert_list); - } - - return ret; - }); +int ckmc_get_pkcs12(const char *alias, const char *key_password, + const char *cert_password, ckmc_pkcs12_s **pkcs12) +{ + EXCEPTION_GUARD_START_CAPI + + if (!alias || !pkcs12) + return CKMC_ERROR_INVALID_PARAMETER; + + int ret; + CKM::PKCS12ShPtr pkcs; + auto mgr = CKM::Manager::create(); + + if ((ret = mgr->getPKCS12(alias, _tostring(key_password), + _tostring(cert_password), pkcs)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); + + if (!pkcs) + return CKMC_ERROR_BAD_RESPONSE; + + ckmc_key_s *private_key = nullptr; + auto pkcsKey = pkcs->getKey(); + + if (pkcsKey) { + auto buffer = pkcsKey->getDER(); + ckmc_key_type_e keyType = static_cast<ckmc_key_type_e>(pkcsKey->getType()); + ret = ckmc_key_new(buffer.data(), buffer.size(), keyType, nullptr, + &private_key); + + if (ret != CKMC_ERROR_NONE) + return ret; + } + + ckmc_cert_s *cert = nullptr; + auto pkcsCert = pkcs->getCertificate(); + + if (pkcsCert) { + CKM::RawBuffer buffer = pkcsCert->getDER(); + ret = ckmc_cert_new(buffer.data(), buffer.size(), CKMC_FORM_DER, &cert); + + if (ret != CKMC_ERROR_NONE) { + ckmc_key_free(private_key); + return ret; + } + } + + auto ca_cert_list = _toNewCkmCertList(pkcs->getCaCertificateShPtrVector()); + + ret = ckmc_pkcs12_new(private_key, cert, ca_cert_list, pkcs12); + + if (ret != CKMC_ERROR_NONE) { + ckmc_key_free(private_key); + ckmc_cert_free(cert); + ckmc_cert_list_free(ca_cert_list); + } + + return ret; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_save_data(const char *alias, ckmc_raw_buffer_s data, const ckmc_policy_s policy) +int ckmc_save_data(const char *alias, ckmc_raw_buffer_s data, + const ckmc_policy_s policy) { - return try_catch_enclosure([&]()->int { - if (alias == nullptr || data.data == nullptr || data.size == 0) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->saveData( - CKM::Alias(alias), - CKM::RawBuffer(data.data, data.data + data.size), - _toCkmPolicy(policy))); - }); + if (alias == nullptr || data.data == nullptr || data.size == 0) + return CKMC_ERROR_INVALID_PARAMETER; + + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->saveData( + CKM::Alias(alias), + CKM::RawBuffer(data.data, data.data + data.size), + _toCkmPolicy(policy))); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_remove_data(const char *alias) { - return ckmc_remove_alias(alias); + return ckmc_remove_alias(alias); } KEY_MANAGER_CAPI -int ckmc_get_data(const char *alias, const char *password, ckmc_raw_buffer_s **data) +int ckmc_get_data(const char *alias, const char *password, + ckmc_raw_buffer_s **data) { - return try_catch_enclosure([&]()->int { - if (alias == nullptr || data == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (alias == nullptr || data == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - int ret; - CKM::RawBuffer ckmBuff; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->getData(alias, _tostring(password), ckmBuff)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); + int ret; + CKM::RawBuffer ckmBuff; + auto mgr = CKM::Manager::create(); - return ckmc_buffer_new(ckmBuff.data(), ckmBuff.size(), data); - }); + if ((ret = mgr->getData(alias, _tostring(password), + ckmBuff)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); + + return ckmc_buffer_new(ckmBuff.data(), ckmBuff.size(), data); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_data_alias_list(ckmc_alias_list_s** alias_list) +int ckmc_get_data_alias_list(ckmc_alias_list_s **alias_list) { - return try_catch_enclosure([&]()->int { - if (alias_list == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (alias_list == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - int ret; - CKM::AliasVector aliasVector; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->getDataAliasVector(aliasVector)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); + int ret; + CKM::AliasVector aliasVector; + auto mgr = CKM::Manager::create(); - ckmc_alias_list_s *start = nullptr; - ckmc_alias_list_s *plist = nullptr; + if ((ret = mgr->getDataAliasVector(aliasVector)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); - for (const auto &it : aliasVector) { - char *alias = strndup(it.c_str(), it.size()); + ckmc_alias_list_s *start = nullptr; + ckmc_alias_list_s *plist = nullptr; - ret = ckmc_alias_list_add(plist, alias, &plist); + for (const auto &it : aliasVector) { + char *alias = strndup(it.c_str(), it.size()); - if (ret != CKMC_ERROR_NONE) { - free(alias); - ckmc_alias_list_all_free(start); - return ret; - } + ret = ckmc_alias_list_add(plist, alias, &plist); - if (start == nullptr) - start = plist; - } + if (ret != CKMC_ERROR_NONE) { + free(alias); + ckmc_alias_list_all_free(start); + return ret; + } - if (plist == nullptr) // if the alias_list size is zero - return CKMC_ERROR_DB_ALIAS_UNKNOWN; + if (start == nullptr) + start = plist; + } - *alias_list = start; + if (plist == nullptr) // if the alias_list size is zero + return CKMC_ERROR_DB_ALIAS_UNKNOWN; - return CKMC_ERROR_NONE; - }); + *alias_list = start; + + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_create_key_pair_rsa(const size_t size, - const char *private_key_alias, - const char *public_key_alias, - const ckmc_policy_s policy_private_key, - const ckmc_policy_s policy_public_key) + const char *private_key_alias, + const char *public_key_alias, + const ckmc_policy_s policy_private_key, + const ckmc_policy_s policy_public_key) { - return try_catch_enclosure([&]()->int { - auto mgr = CKM::Manager::create(); + EXCEPTION_GUARD_START_CAPI + + auto mgr = CKM::Manager::create(); + + if (private_key_alias == nullptr || public_key_alias == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - if (private_key_alias == nullptr || public_key_alias == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + return to_ckmc_error(mgr->createKeyPairRSA( + static_cast<int>(size), + CKM::Alias(private_key_alias), + CKM::Alias(public_key_alias), + _toCkmPolicy(policy_private_key), + _toCkmPolicy(policy_public_key))); - return to_ckmc_error(mgr->createKeyPairRSA( - static_cast<int>(size), - CKM::Alias(private_key_alias), - CKM::Alias(public_key_alias), - _toCkmPolicy(policy_private_key), - _toCkmPolicy(policy_public_key))); - }); + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_create_key_pair_dsa(const size_t size, - const char *private_key_alias, - const char *public_key_alias, - const ckmc_policy_s policy_private_key, - const ckmc_policy_s policy_public_key) + const char *private_key_alias, + const char *public_key_alias, + const ckmc_policy_s policy_private_key, + const ckmc_policy_s policy_public_key) { - return try_catch_enclosure([&]()->int { - if (private_key_alias == nullptr || public_key_alias == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->createKeyPairDSA( - static_cast<int>(size), - CKM::Alias(private_key_alias), - CKM::Alias(public_key_alias), - _toCkmPolicy(policy_private_key), - _toCkmPolicy(policy_public_key))); - }); + if (private_key_alias == nullptr || public_key_alias == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->createKeyPairDSA( + static_cast<int>(size), + CKM::Alias(private_key_alias), + CKM::Alias(public_key_alias), + _toCkmPolicy(policy_private_key), + _toCkmPolicy(policy_public_key))); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_create_key_pair_ecdsa(const ckmc_ec_type_e type, - const char *private_key_alias, - const char *public_key_alias, - const ckmc_policy_s policy_private_key, - const ckmc_policy_s policy_public_key) + const char *private_key_alias, + const char *public_key_alias, + const ckmc_policy_s policy_private_key, + const ckmc_policy_s policy_public_key) { - return try_catch_enclosure([&]()->int { - if (private_key_alias == nullptr || public_key_alias == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (private_key_alias == nullptr || public_key_alias == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->createKeyPairECDSA( - static_cast<CKM::ElipticCurve>(static_cast<int>(type)), - CKM::Alias(private_key_alias), - CKM::Alias(public_key_alias), - _toCkmPolicy(policy_private_key), - _toCkmPolicy(policy_public_key))); - }); + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->createKeyPairECDSA( + static_cast<CKM::ElipticCurve>(static_cast<int>(type)), + CKM::Alias(private_key_alias), + CKM::Alias(public_key_alias), + _toCkmPolicy(policy_private_key), + _toCkmPolicy(policy_public_key))); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_create_key_aes(size_t size, - const char *key_alias, - ckmc_policy_s key_policy) + const char *key_alias, + ckmc_policy_s key_policy) { - return try_catch_enclosure([&]()->int { - if (key_alias == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (key_alias == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->createKeyAES(size, CKM::Alias(key_alias), + _toCkmPolicy(key_policy))); - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->createKeyAES(size, CKM::Alias(key_alias), _toCkmPolicy(key_policy))); - }); + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_create_signature(const char *private_key_alias, - const char *password, - const ckmc_raw_buffer_s message, - const ckmc_hash_algo_e hash, - const ckmc_rsa_padding_algo_e padding, - ckmc_raw_buffer_s **signature) -{ - return try_catch_enclosure([&]()->int { - if (private_key_alias == nullptr || signature == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; - - int ret; - CKM::RawBuffer ckmSignature; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->createSignature( - CKM::Alias(private_key_alias), - _tostring(password), - CKM::RawBuffer(message.data, message.data + message.size), - static_cast<CKM::HashAlgorithm>(static_cast<int>(hash)), - static_cast<CKM::RSAPaddingAlgorithm>(static_cast<int>(padding)), - ckmSignature)) != CKM_API_SUCCESS) - return to_ckmc_error(ret); - - return ckmc_buffer_new(ckmSignature.data(), ckmSignature.size(), signature); - }); + const char *password, + const ckmc_raw_buffer_s message, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding, + ckmc_raw_buffer_s **signature) +{ + EXCEPTION_GUARD_START_CAPI + + if (private_key_alias == nullptr || signature == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + int ret; + CKM::RawBuffer ckmSignature; + auto mgr = CKM::Manager::create(); + + if ((ret = mgr->createSignature( + CKM::Alias(private_key_alias), + _tostring(password), + CKM::RawBuffer(message.data, message.data + message.size), + static_cast<CKM::HashAlgorithm>(static_cast<int>(hash)), + static_cast<CKM::RSAPaddingAlgorithm>(static_cast<int>(padding)), + ckmSignature)) != CKM_API_SUCCESS) + return to_ckmc_error(ret); + + return ckmc_buffer_new(ckmSignature.data(), ckmSignature.size(), signature); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_verify_signature(const char *public_key_alias, - const char *password, - const ckmc_raw_buffer_s message, - const ckmc_raw_buffer_s signature, - const ckmc_hash_algo_e hash, - const ckmc_rsa_padding_algo_e padding) -{ - return try_catch_enclosure([&]()->int { - if (public_key_alias == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; - - int ret; - auto mgr = CKM::Manager::create(); - if ((ret = mgr->verifySignature( - CKM::Alias(public_key_alias), - _tostring(password), - CKM::RawBuffer(message.data, message.data + message.size), - CKM::RawBuffer(signature.data, signature.data + signature.size), - static_cast<CKM::HashAlgorithm>(static_cast<int>(hash)), - static_cast<CKM::RSAPaddingAlgorithm>(static_cast<int>(padding)))) != CKM_API_SUCCESS) - return to_ckmc_error(ret); - - return CKMC_ERROR_NONE; - }); + const char *password, + const ckmc_raw_buffer_s message, + const ckmc_raw_buffer_s signature, + const ckmc_hash_algo_e hash, + const ckmc_rsa_padding_algo_e padding) +{ + EXCEPTION_GUARD_START_CAPI + + if (public_key_alias == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + int ret; + auto mgr = CKM::Manager::create(); + + if ((ret = mgr->verifySignature( + CKM::Alias(public_key_alias), + _tostring(password), + CKM::RawBuffer(message.data, message.data + message.size), + CKM::RawBuffer(signature.data, signature.data + signature.size), + static_cast<CKM::HashAlgorithm>(static_cast<int>(hash)), + static_cast<CKM::RSAPaddingAlgorithm>(static_cast<int>(padding)))) != + CKM_API_SUCCESS) + return to_ckmc_error(ret); + + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_cert_chain(const ckmc_cert_s *cert, const ckmc_cert_list_s *untrustedcerts, ckmc_cert_list_s **cert_chain_list) +int ckmc_get_cert_chain(const ckmc_cert_s *cert, + const ckmc_cert_list_s *untrustedcerts, ckmc_cert_list_s **cert_chain_list) { - return try_catch_enclosure([&]()->int { - if (cert == nullptr || cert->raw_cert == nullptr || cert->cert_size == 0 || cert_chain_list == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (cert == nullptr || cert->raw_cert == nullptr || cert->cert_size == 0 || + cert_chain_list == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + auto ckmCert = _toCkmCertificate(cert); + + if (!ckmCert) + return CKMC_ERROR_INVALID_FORMAT; - auto ckmCert = _toCkmCertificate(cert); - if (!ckmCert) - return CKMC_ERROR_INVALID_FORMAT; + CKM::CertificateShPtrVector ckmCertChain; + auto mgr = CKM::Manager::create(); + int ret = mgr->getCertificateChain( + ckmCert, + _toCkmCertificateVector(untrustedcerts), + EMPTY_CERT_VECTOR, + true, + ckmCertChain); - CKM::CertificateShPtrVector ckmCertChain; - auto mgr = CKM::Manager::create(); - int ret = mgr->getCertificateChain( - ckmCert, - _toCkmCertificateVector(untrustedcerts), - EMPTY_CERT_VECTOR, - true, - ckmCertChain); - if (ret != CKM_API_SUCCESS) - return to_ckmc_error(ret); + if (ret != CKM_API_SUCCESS) + return to_ckmc_error(ret); - *cert_chain_list = _toNewCkmCertList(ckmCertChain); + *cert_chain_list = _toNewCkmCertList(ckmCertChain); - return CKMC_ERROR_NONE; - }); + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_cert_chain_with_alias(const ckmc_cert_s *cert, const ckmc_alias_list_s *untrustedcerts, ckmc_cert_list_s **cert_chain_list) +int ckmc_get_cert_chain_with_alias(const ckmc_cert_s *cert, + const ckmc_alias_list_s *untrustedcerts, ckmc_cert_list_s **cert_chain_list) { - return try_catch_enclosure([&]()->int { - if (cert == nullptr || cert->raw_cert == nullptr || cert->cert_size == 0 || cert_chain_list == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (cert == nullptr || cert->raw_cert == nullptr || cert->cert_size == 0 || + cert_chain_list == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + auto ckmCert = _toCkmCertificate(cert); + + if (!ckmCert) + return CKMC_ERROR_INVALID_FORMAT; - auto ckmCert = _toCkmCertificate(cert); - if (!ckmCert) - return CKMC_ERROR_INVALID_FORMAT; + CKM::CertificateShPtrVector ckmCertChain; + auto mgr = CKM::Manager::create(); + int ret = mgr->getCertificateChain(ckmCert, _toCkmAliasVector(untrustedcerts), + EMPTY_ALIAS_VECTOR, true, ckmCertChain); - CKM::CertificateShPtrVector ckmCertChain; - auto mgr = CKM::Manager::create(); - int ret = mgr->getCertificateChain(ckmCert, _toCkmAliasVector(untrustedcerts),EMPTY_ALIAS_VECTOR, true, ckmCertChain); - if (ret != CKM_API_SUCCESS) - return to_ckmc_error(ret); + if (ret != CKM_API_SUCCESS) + return to_ckmc_error(ret); - *cert_chain_list = _toNewCkmCertList(ckmCertChain); + *cert_chain_list = _toNewCkmCertList(ckmCertChain); - return CKMC_ERROR_NONE; - }); + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s* cert, - const ckmc_cert_list_s* untrustedcerts, - const ckmc_cert_list_s* trustedcerts, - const bool sys_certs, - ckmc_cert_list_s** ppcert_chain_list) +int ckmc_get_cert_chain_with_trustedcert(const ckmc_cert_s *cert, + const ckmc_cert_list_s *untrustedcerts, + const ckmc_cert_list_s *trustedcerts, + const bool sys_certs, + ckmc_cert_list_s **ppcert_chain_list) { - return try_catch_enclosure([&]()->int { - if (cert == nullptr || cert->raw_cert == nullptr || cert->cert_size == 0 || ppcert_chain_list == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (cert == nullptr || cert->raw_cert == nullptr || cert->cert_size == 0 || + ppcert_chain_list == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; + + auto ckmCert = _toCkmCertificate(cert); - auto ckmCert = _toCkmCertificate(cert); - if (!ckmCert) - return CKMC_ERROR_INVALID_PARAMETER; + if (!ckmCert) + return CKMC_ERROR_INVALID_PARAMETER; - CKM::CertificateShPtrVector ckmCertChain; - auto mgr = CKM::Manager::create(); - int ret = mgr->getCertificateChain( - ckmCert, - _toCkmCertificateVector(untrustedcerts), - _toCkmCertificateVector(trustedcerts), - sys_certs, - ckmCertChain); - if (ret != CKM_API_SUCCESS) - return to_ckmc_error(ret); + CKM::CertificateShPtrVector ckmCertChain; + auto mgr = CKM::Manager::create(); + int ret = mgr->getCertificateChain( + ckmCert, + _toCkmCertificateVector(untrustedcerts), + _toCkmCertificateVector(trustedcerts), + sys_certs, + ckmCertChain); - *ppcert_chain_list = _toNewCkmCertList(ckmCertChain); + if (ret != CKM_API_SUCCESS) + return to_ckmc_error(ret); - return CKMC_ERROR_NONE; - }); + *ppcert_chain_list = _toNewCkmCertList(ckmCertChain); + + return CKMC_ERROR_NONE; + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, ckmc_ocsp_status_e *ocsp_status) +int ckmc_ocsp_check(const ckmc_cert_list_s *pcert_chain_list, + ckmc_ocsp_status_e *ocsp_status) { - return try_catch_enclosure([&]()->int { - if (pcert_chain_list == nullptr - || pcert_chain_list->cert == nullptr - || pcert_chain_list->cert->raw_cert == nullptr - || pcert_chain_list->cert->cert_size == 0 - || ocsp_status == nullptr) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (pcert_chain_list == nullptr + || pcert_chain_list->cert == nullptr + || pcert_chain_list->cert->raw_cert == nullptr + || pcert_chain_list->cert->cert_size == 0 + || ocsp_status == nullptr) + return CKMC_ERROR_INVALID_PARAMETER; - int tmpOcspStatus = -1; - auto mgr = CKM::Manager::create(); - int ret = mgr->ocspCheck(_toCkmCertificateVector(pcert_chain_list), tmpOcspStatus); + int tmpOcspStatus = -1; + auto mgr = CKM::Manager::create(); + int ret = mgr->ocspCheck(_toCkmCertificateVector(pcert_chain_list), + tmpOcspStatus); - *ocsp_status = to_ckmc_ocsp_status(tmpOcspStatus); + *ocsp_status = to_ckmc_ocsp_status(tmpOcspStatus); - return to_ckmc_error(ret); - }); + return to_ckmc_error(ret); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_allow_access(const char *alias, const char *accessor, ckmc_access_right_e granted) +int ckmc_allow_access(const char *alias, const char *accessor, + ckmc_access_right_e granted) { - return try_catch_enclosure([&]()->int { - int permissionMask; - int ret = access_to_permission_mask(granted, permissionMask); - if (ret != CKMC_ERROR_NONE) - return ret; + EXCEPTION_GUARD_START_CAPI + + int permissionMask; + int ret = access_to_permission_mask(granted, permissionMask); + + if (ret != CKMC_ERROR_NONE) + return ret; - return ckmc_set_permission(alias, accessor, permissionMask); - }); + return ckmc_set_permission(alias, accessor, permissionMask); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI -int ckmc_set_permission(const char *alias, const char *accessor, int permissions) +int ckmc_set_permission(const char *alias, const char *accessor, + int permissions) { - return try_catch_enclosure([&]()->int { - if (!alias || !accessor) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (!alias || !accessor) + return CKMC_ERROR_INVALID_PARAMETER; + + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->setPermission(alias, accessor, permissions)); - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->setPermission(alias, accessor, permissions)); - }); + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_deny_access(const char *alias, const char *accessor) { - return try_catch_enclosure([&]()->int { - if (!alias || !accessor) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->setPermission(alias, accessor, CKM::Permission::NONE)); - }); + if (!alias || !accessor) + return CKMC_ERROR_INVALID_PARAMETER; + + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->setPermission(alias, accessor, + CKM::Permission::NONE)); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_remove_alias(const char *alias) { - return try_catch_enclosure([&]()->int { - if (!alias) - return CKMC_ERROR_INVALID_PARAMETER; + EXCEPTION_GUARD_START_CAPI + + if (!alias) + return CKMC_ERROR_INVALID_PARAMETER; - auto mgr = CKM::Manager::create(); - return to_ckmc_error(mgr->removeAlias(alias)); - }); + auto mgr = CKM::Manager::create(); + return to_ckmc_error(mgr->removeAlias(alias)); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_encrypt_data(ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s decrypted, - ckmc_raw_buffer_s **ppencrypted) + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s decrypted, + ckmc_raw_buffer_s **ppencrypted) { - return try_catch_enclosure([&]()->int { - return _cryptoOperation(&CKM::Manager::encrypt, - params, - key_alias, - password, - decrypted, - ppencrypted); - }); + EXCEPTION_GUARD_START_CAPI + + return _cryptoOperation(&CKM::Manager::encrypt, + params, + key_alias, + password, + decrypted, + ppencrypted); + + EXCEPTION_GUARD_END } KEY_MANAGER_CAPI int ckmc_decrypt_data(ckmc_param_list_h params, - const char *key_alias, - const char *password, - const ckmc_raw_buffer_s encrypted, - ckmc_raw_buffer_s **ppdecrypted) -{ - return try_catch_enclosure([&]()->int { - return _cryptoOperation(&CKM::Manager::decrypt, - params, - key_alias, - password, - encrypted, - ppdecrypted); - }); + const char *key_alias, + const char *password, + const ckmc_raw_buffer_s encrypted, + ckmc_raw_buffer_s **ppdecrypted) +{ + EXCEPTION_GUARD_START_CAPI + + return _cryptoOperation(&CKM::Manager::decrypt, + params, + key_alias, + password, + encrypted, + ppdecrypted); + + EXCEPTION_GUARD_END } diff --git a/src/manager/client-capi/ckmc-type-converter.cpp b/src/manager/client-capi/ckmc-type-converter.cpp index 94a43858..63a16608 100644 --- a/src/manager/client-capi/ckmc-type-converter.cpp +++ b/src/manager/client-capi/ckmc-type-converter.cpp @@ -25,62 +25,126 @@ int to_ckmc_error(int ckm_error) { - switch (ckm_error) { - case CKM_API_SUCCESS: return CKMC_ERROR_NONE; - case CKM_API_ERROR_SOCKET: return CKMC_ERROR_SOCKET; - case CKM_API_ERROR_BAD_REQUEST: return CKMC_ERROR_BAD_REQUEST; - case CKM_API_ERROR_BAD_RESPONSE: return CKMC_ERROR_BAD_RESPONSE; - case CKM_API_ERROR_SEND_FAILED: return CKMC_ERROR_SEND_FAILED; - case CKM_API_ERROR_RECV_FAILED: return CKMC_ERROR_RECV_FAILED; - case CKM_API_ERROR_AUTHENTICATION_FAILED: return CKMC_ERROR_AUTHENTICATION_FAILED; - case CKM_API_ERROR_INPUT_PARAM: return CKMC_ERROR_INVALID_PARAMETER; - case CKM_API_ERROR_BUFFER_TOO_SMALL: return CKMC_ERROR_BUFFER_TOO_SMALL; - case CKM_API_ERROR_OUT_OF_MEMORY: return CKMC_ERROR_OUT_OF_MEMORY; - case CKM_API_ERROR_ACCESS_DENIED: return CKMC_ERROR_PERMISSION_DENIED; - case CKM_API_ERROR_SERVER_ERROR: return CKMC_ERROR_SERVER_ERROR; - case CKM_API_ERROR_DB_LOCKED: return CKMC_ERROR_DB_LOCKED; - case CKM_API_ERROR_DB_ERROR: return CKMC_ERROR_DB_ERROR; - case CKM_API_ERROR_DB_ALIAS_EXISTS: return CKMC_ERROR_DB_ALIAS_EXISTS; - case CKM_API_ERROR_DB_ALIAS_UNKNOWN: return CKMC_ERROR_DB_ALIAS_UNKNOWN; - case CKM_API_ERROR_VERIFICATION_FAILED: return CKMC_ERROR_VERIFICATION_FAILED; - case CKM_API_ERROR_INVALID_FORMAT: return CKMC_ERROR_INVALID_FORMAT; - case CKM_API_ERROR_FILE_ACCESS_DENIED: return CKMC_ERROR_FILE_ACCESS_DENIED; - case CKM_API_ERROR_NOT_EXPORTABLE: return CKMC_ERROR_NOT_EXPORTABLE; - case CKM_API_ERROR_FILE_SYSTEM: return CKMC_ERROR_FILE_SYSTEM; - case CKM_API_ERROR_NOT_SUPPORTED: return CKMC_ERROR_NOT_SUPPORTED; - case CKM_API_ERROR_UNKNOWN: return CKMC_ERROR_UNKNOWN; - } - return CKMC_ERROR_UNKNOWN; + switch (ckm_error) { + case CKM_API_SUCCESS: + return CKMC_ERROR_NONE; + + case CKM_API_ERROR_SOCKET: + return CKMC_ERROR_SOCKET; + + case CKM_API_ERROR_BAD_REQUEST: + return CKMC_ERROR_BAD_REQUEST; + + case CKM_API_ERROR_BAD_RESPONSE: + return CKMC_ERROR_BAD_RESPONSE; + + case CKM_API_ERROR_SEND_FAILED: + return CKMC_ERROR_SEND_FAILED; + + case CKM_API_ERROR_RECV_FAILED: + return CKMC_ERROR_RECV_FAILED; + + case CKM_API_ERROR_AUTHENTICATION_FAILED: + return CKMC_ERROR_AUTHENTICATION_FAILED; + + case CKM_API_ERROR_INPUT_PARAM: + return CKMC_ERROR_INVALID_PARAMETER; + + case CKM_API_ERROR_BUFFER_TOO_SMALL: + return CKMC_ERROR_BUFFER_TOO_SMALL; + + case CKM_API_ERROR_OUT_OF_MEMORY: + return CKMC_ERROR_OUT_OF_MEMORY; + + case CKM_API_ERROR_ACCESS_DENIED: + return CKMC_ERROR_PERMISSION_DENIED; + + case CKM_API_ERROR_SERVER_ERROR: + return CKMC_ERROR_SERVER_ERROR; + + case CKM_API_ERROR_DB_LOCKED: + return CKMC_ERROR_DB_LOCKED; + + case CKM_API_ERROR_DB_ERROR: + return CKMC_ERROR_DB_ERROR; + + case CKM_API_ERROR_DB_ALIAS_EXISTS: + return CKMC_ERROR_DB_ALIAS_EXISTS; + + case CKM_API_ERROR_DB_ALIAS_UNKNOWN: + return CKMC_ERROR_DB_ALIAS_UNKNOWN; + + case CKM_API_ERROR_VERIFICATION_FAILED: + return CKMC_ERROR_VERIFICATION_FAILED; + + case CKM_API_ERROR_INVALID_FORMAT: + return CKMC_ERROR_INVALID_FORMAT; + + case CKM_API_ERROR_FILE_ACCESS_DENIED: + return CKMC_ERROR_FILE_ACCESS_DENIED; + + case CKM_API_ERROR_NOT_EXPORTABLE: + return CKMC_ERROR_NOT_EXPORTABLE; + + case CKM_API_ERROR_FILE_SYSTEM: + return CKMC_ERROR_FILE_SYSTEM; + + case CKM_API_ERROR_NOT_SUPPORTED: + return CKMC_ERROR_NOT_SUPPORTED; + + case CKM_API_ERROR_UNKNOWN: + return CKMC_ERROR_UNKNOWN; + } + + return CKMC_ERROR_UNKNOWN; } ckmc_ocsp_status_e to_ckmc_ocsp_status(int ckm_ocsp_status) { - switch (ckm_ocsp_status) { - case CKM_API_OCSP_STATUS_GOOD: return CKMC_OCSP_STATUS_GOOD; - case CKM_API_OCSP_STATUS_UNSUPPORTED: return CKMC_OCSP_ERROR_UNSUPPORTED; - case CKM_API_OCSP_STATUS_REVOKED: return CKMC_OCSP_STATUS_REVOKED; - case CKM_API_OCSP_STATUS_NET_ERROR: return CKMC_OCSP_ERROR_NET; - case CKM_API_OCSP_STATUS_INVALID_URL: return CKMC_OCSP_ERROR_INVALID_URL; - case CKM_API_OCSP_STATUS_INVALID_RESPONSE: return CKMC_OCSP_ERROR_INVALID_RESPONSE; - case CKM_API_OCSP_STATUS_REMOTE_ERROR: return CKMC_OCSP_ERROR_REMOTE; - case CKM_API_OCSP_STATUS_INTERNAL_ERROR: return CKMC_OCSP_ERROR_INTERNAL; - default: return CKMC_OCSP_STATUS_UNKNOWN; - } + switch (ckm_ocsp_status) { + case CKM_API_OCSP_STATUS_GOOD: + return CKMC_OCSP_STATUS_GOOD; + + case CKM_API_OCSP_STATUS_UNSUPPORTED: + return CKMC_OCSP_ERROR_UNSUPPORTED; + + case CKM_API_OCSP_STATUS_REVOKED: + return CKMC_OCSP_STATUS_REVOKED; + + case CKM_API_OCSP_STATUS_NET_ERROR: + return CKMC_OCSP_ERROR_NET; + + case CKM_API_OCSP_STATUS_INVALID_URL: + return CKMC_OCSP_ERROR_INVALID_URL; + + case CKM_API_OCSP_STATUS_INVALID_RESPONSE: + return CKMC_OCSP_ERROR_INVALID_RESPONSE; + + case CKM_API_OCSP_STATUS_REMOTE_ERROR: + return CKMC_OCSP_ERROR_REMOTE; + + case CKM_API_OCSP_STATUS_INTERNAL_ERROR: + return CKMC_OCSP_ERROR_INTERNAL; + + default: + return CKMC_OCSP_STATUS_UNKNOWN; + } } -int access_to_permission_mask(ckmc_access_right_e ar, int & permissionMask) +int access_to_permission_mask(ckmc_access_right_e ar, int &permissionMask) { - switch (ar) { - case CKMC_AR_READ: - permissionMask = CKMC_PERMISSION_READ; - break; - - case CKMC_AR_READ_REMOVE: - permissionMask = CKMC_PERMISSION_READ | CKMC_PERMISSION_REMOVE; - break; - - default: - return CKMC_ERROR_INVALID_PARAMETER; - } - return CKMC_ERROR_NONE; + switch (ar) { + case CKMC_AR_READ: + permissionMask = CKMC_PERMISSION_READ; + break; + + case CKMC_AR_READ_REMOVE: + permissionMask = CKMC_PERMISSION_READ | CKMC_PERMISSION_REMOVE; + break; + + default: + return CKMC_ERROR_INVALID_PARAMETER; + } + + return CKMC_ERROR_NONE; } diff --git a/src/manager/client-capi/ckmc-type-converter.h b/src/manager/client-capi/ckmc-type-converter.h index 0a49d0ec..bbbf9ae9 100644 --- a/src/manager/client-capi/ckmc-type-converter.h +++ b/src/manager/client-capi/ckmc-type-converter.h @@ -33,7 +33,7 @@ extern "C" { int to_ckmc_error(int ckm_error); ckmc_ocsp_status_e to_ckmc_ocsp_status(int ckm_ocsp_status); -int access_to_permission_mask(ckmc_access_right_e ar, int & permissionMask); +int access_to_permission_mask(ckmc_access_right_e ar, int &permissionMask); #ifdef __cplusplus } diff --git a/src/manager/client-capi/ckmc-type.cpp b/src/manager/client-capi/ckmc-type.cpp index 4db37f86..75fde1c0 100644 --- a/src/manager/client-capi/ckmc-type.cpp +++ b/src/manager/client-capi/ckmc-type.cpp @@ -39,643 +39,714 @@ namespace { const size_t DEFAULT_IV_LEN = 16; -const size_t DEFAULT_IV_LEN_BITS = 8*DEFAULT_IV_LEN; +const size_t DEFAULT_IV_LEN_BITS = 8 * DEFAULT_IV_LEN; const size_t DEFAULT_KEY_LEN_BITS = 4096; int _ckmc_load_cert_from_x509(X509 *xCert, ckmc_cert_s **cert) { - if (xCert == NULL) - return CKMC_ERROR_INVALID_FORMAT; + if (xCert == NULL) + return CKMC_ERROR_INVALID_FORMAT; - BIO *bcert = BIO_new(BIO_s_mem()); + BIO *bcert = BIO_new(BIO_s_mem()); - i2d_X509_bio(bcert, xCert); + i2d_X509_bio(bcert, xCert); - CKM::RawBuffer output(8196); - int size = BIO_read(bcert, output.data(), output.size()); - BIO_free_all(bcert); - if (size <= 0) - return CKMC_ERROR_INVALID_FORMAT; + CKM::RawBuffer output(8196); + int size = BIO_read(bcert, output.data(), output.size()); + BIO_free_all(bcert); - output.resize(size); + if (size <= 0) + return CKMC_ERROR_INVALID_FORMAT; - return ckmc_cert_new(output.data(), output.size(), CKMC_FORM_DER, cert); + output.resize(size); + + return ckmc_cert_new(output.data(), output.size(), CKMC_FORM_DER, cert); } } // namespace anonymous -const char * const ckmc_label_name_separator = CKM::LABEL_NAME_SEPARATOR; -const char * const ckmc_owner_id_separator = CKM::LABEL_NAME_SEPARATOR; -const char * const ckmc_owner_id_system = CKM::OWNER_ID_SYSTEM; +const char *const ckmc_label_name_separator = CKM::LABEL_NAME_SEPARATOR; +const char *const ckmc_owner_id_separator = CKM::LABEL_NAME_SEPARATOR; +const char *const ckmc_owner_id_system = CKM::OWNER_ID_SYSTEM; KEY_MANAGER_CAPI -int ckmc_key_new(unsigned char *raw_key, size_t key_size, ckmc_key_type_e key_type, char *password, ckmc_key_s **ppkey) +int ckmc_key_new(unsigned char *raw_key, size_t key_size, + ckmc_key_type_e key_type, char *password, ckmc_key_s **ppkey) { - ckmc_key_s *pkey; - - if (raw_key == NULL || key_size == 0 || ppkey == NULL) - return CKMC_ERROR_INVALID_PARAMETER; - - pkey = static_cast<ckmc_key_s*>(malloc(sizeof(ckmc_key_s))); - if (pkey == NULL) - return CKMC_ERROR_OUT_OF_MEMORY; - - pkey->raw_key = reinterpret_cast<unsigned char*>(malloc(key_size)); - if (pkey->raw_key == NULL) { - free(pkey); - return CKMC_ERROR_OUT_OF_MEMORY; - } - memcpy(pkey->raw_key, raw_key, key_size); - - pkey->key_size = key_size; - pkey->key_type = key_type; - - if (password != NULL) { - pkey->password = reinterpret_cast<char*>(malloc(strlen(password) +1)); - if (pkey->password == NULL) { - free(pkey->raw_key); - free(pkey); - return CKMC_ERROR_OUT_OF_MEMORY; - } - memset(pkey->password, 0, strlen(password) +1); - strncpy(pkey->password, password, strlen(password)); - } else { - pkey->password = NULL; - } - - *ppkey = pkey; - - return CKMC_ERROR_NONE; + ckmc_key_s *pkey; + + if (raw_key == NULL || key_size == 0 || ppkey == NULL) + return CKMC_ERROR_INVALID_PARAMETER; + + pkey = static_cast<ckmc_key_s *>(malloc(sizeof(ckmc_key_s))); + + if (pkey == NULL) + return CKMC_ERROR_OUT_OF_MEMORY; + + pkey->raw_key = reinterpret_cast<unsigned char *>(malloc(key_size)); + + if (pkey->raw_key == NULL) { + free(pkey); + return CKMC_ERROR_OUT_OF_MEMORY; + } + + memcpy(pkey->raw_key, raw_key, key_size); + + pkey->key_size = key_size; + pkey->key_type = key_type; + + if (password != NULL) { + pkey->password = reinterpret_cast<char *>(malloc(strlen(password) + 1)); + + if (pkey->password == NULL) { + free(pkey->raw_key); + free(pkey); + return CKMC_ERROR_OUT_OF_MEMORY; + } + + memset(pkey->password, 0, strlen(password) + 1); + strncpy(pkey->password, password, strlen(password)); + } else { + pkey->password = NULL; + } + + *ppkey = pkey; + + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI void ckmc_key_free(ckmc_key_s *key) { - if (key == NULL) - return; + if (key == NULL) + return; - if (key->password != NULL) - free(key->password); - if (key->raw_key != NULL) { - memset(key->raw_key, 0, key->key_size); - free(key->raw_key); - } + if (key->password != NULL) + free(key->password); - free(key); + if (key->raw_key != NULL) { + memset(key->raw_key, 0, key->key_size); + free(key->raw_key); + } + + free(key); } KEY_MANAGER_CAPI -int ckmc_buffer_new(unsigned char *data, size_t size, ckmc_raw_buffer_s **ppbuffer) +int ckmc_buffer_new(unsigned char *data, size_t size, + ckmc_raw_buffer_s **ppbuffer) { - ckmc_raw_buffer_s *pbuff; + ckmc_raw_buffer_s *pbuff; + + if (data == NULL || size == 0 || ppbuffer == NULL) + return CKMC_ERROR_INVALID_PARAMETER; - if (data == NULL || size == 0 || ppbuffer == NULL) - return CKMC_ERROR_INVALID_PARAMETER; + pbuff = static_cast<ckmc_raw_buffer_s *>(malloc(sizeof(ckmc_raw_buffer_s))); - pbuff = static_cast<ckmc_raw_buffer_s*>(malloc(sizeof(ckmc_raw_buffer_s))); - if (pbuff == NULL) - return CKMC_ERROR_OUT_OF_MEMORY; + if (pbuff == NULL) + return CKMC_ERROR_OUT_OF_MEMORY; - pbuff->data = reinterpret_cast<unsigned char*>(malloc(size)); - if (pbuff->data == NULL) { - free(pbuff); - return CKMC_ERROR_OUT_OF_MEMORY; - } - memcpy(pbuff->data, data, size); + pbuff->data = reinterpret_cast<unsigned char *>(malloc(size)); - pbuff->size = size; - *ppbuffer = pbuff; + if (pbuff->data == NULL) { + free(pbuff); + return CKMC_ERROR_OUT_OF_MEMORY; + } - return CKMC_ERROR_NONE; + memcpy(pbuff->data, data, size); + + pbuff->size = size; + *ppbuffer = pbuff; + + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI void ckmc_buffer_free(ckmc_raw_buffer_s *buffer) { - if (buffer == NULL) - return; - - if (buffer->data != NULL) { - memset(buffer->data, 0, buffer->size); - free(buffer->data); - } - free(buffer); + if (buffer == NULL) + return; + + if (buffer->data != NULL) { + memset(buffer->data, 0, buffer->size); + free(buffer->data); + } + + free(buffer); } KEY_MANAGER_CAPI -int ckmc_cert_new(unsigned char *raw_cert, size_t cert_size, ckmc_data_format_e data_format, ckmc_cert_s **ppcert) +int ckmc_cert_new(unsigned char *raw_cert, size_t cert_size, + ckmc_data_format_e data_format, ckmc_cert_s **ppcert) { - ckmc_cert_s *pcert; + ckmc_cert_s *pcert; + + if (raw_cert == NULL || cert_size == 0 || ppcert == NULL) + return CKMC_ERROR_INVALID_PARAMETER; - if (raw_cert == NULL || cert_size == 0 || ppcert == NULL) - return CKMC_ERROR_INVALID_PARAMETER; + pcert = static_cast<ckmc_cert_s *>(malloc(sizeof(ckmc_cert_s))); - pcert = static_cast<ckmc_cert_s*>(malloc(sizeof(ckmc_cert_s))); - if (pcert == NULL) - return CKMC_ERROR_OUT_OF_MEMORY; + if (pcert == NULL) + return CKMC_ERROR_OUT_OF_MEMORY; - pcert->raw_cert = reinterpret_cast<unsigned char*>(malloc(cert_size)); - if (pcert->raw_cert == NULL) { - free(pcert); - return CKMC_ERROR_OUT_OF_MEMORY; - } - memcpy(pcert->raw_cert, raw_cert, cert_size); + pcert->raw_cert = reinterpret_cast<unsigned char *>(malloc(cert_size)); - pcert->cert_size = cert_size; - pcert->data_format = data_format; + if (pcert->raw_cert == NULL) { + free(pcert); + return CKMC_ERROR_OUT_OF_MEMORY; + } - *ppcert = pcert; - return CKMC_ERROR_NONE; + memcpy(pcert->raw_cert, raw_cert, cert_size); + + pcert->cert_size = cert_size; + pcert->data_format = data_format; + + *ppcert = pcert; + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert) { - CKM::initOpenSslOnce(); - - FILE *fp = fopen(file_path, "r"); - if (fp == NULL) - return CKMC_ERROR_FILE_ACCESS_DENIED; - X509 *pcert = NULL; - if (!(pcert = d2i_X509_fp(fp, NULL))) { - fseek(fp, 0, SEEK_SET); - pcert = PEM_read_X509(fp, NULL, NULL, NULL); - } - fclose(fp); - if (pcert == NULL) - return CKMC_ERROR_INVALID_FORMAT; - - int ret = _ckmc_load_cert_from_x509(pcert, cert); - if (ret != CKMC_ERROR_NONE) - X509_free(pcert); - - return ret; + CKM::initOpenSslOnce(); + + FILE *fp = fopen(file_path, "r"); + + if (fp == NULL) + return CKMC_ERROR_FILE_ACCESS_DENIED; + + X509 *pcert = NULL; + + if (!(pcert = d2i_X509_fp(fp, NULL))) { + fseek(fp, 0, SEEK_SET); + pcert = PEM_read_X509(fp, NULL, NULL, NULL); + } + + fclose(fp); + + if (pcert == NULL) + return CKMC_ERROR_INVALID_FORMAT; + + int ret = _ckmc_load_cert_from_x509(pcert, cert); + + if (ret != CKMC_ERROR_NONE) + X509_free(pcert); + + return ret; } KEY_MANAGER_CAPI void ckmc_cert_free(ckmc_cert_s *cert) { - if (cert == NULL) - return; - - if (cert->raw_cert != NULL) { - memset(cert->raw_cert, 0, cert->cert_size); - free(cert->raw_cert); - } - free(cert); + if (cert == NULL) + return; + + if (cert->raw_cert != NULL) { + memset(cert->raw_cert, 0, cert->cert_size); + free(cert->raw_cert); + } + + free(cert); } KEY_MANAGER_CAPI int ckmc_pkcs12_new(ckmc_key_s *private_key, ckmc_cert_s *cert, - ckmc_cert_list_s *ca_cert_list, ckmc_pkcs12_s **pkcs12_bundle) + ckmc_cert_list_s *ca_cert_list, ckmc_pkcs12_s **pkcs12_bundle) { - ckmc_pkcs12_s *pkcs12; + ckmc_pkcs12_s *pkcs12; - if (!pkcs12_bundle || - (private_key == NULL && cert == NULL && (ca_cert_list == NULL || ca_cert_list->cert == NULL))) - return CKMC_ERROR_INVALID_PARAMETER; + if (!pkcs12_bundle || + (private_key == NULL && cert == NULL && (ca_cert_list == NULL || + ca_cert_list->cert == NULL))) + return CKMC_ERROR_INVALID_PARAMETER; - pkcs12 = static_cast<ckmc_pkcs12_s*>(malloc(sizeof(ckmc_pkcs12_s))); - if (pkcs12 == NULL) - return CKMC_ERROR_OUT_OF_MEMORY; + pkcs12 = static_cast<ckmc_pkcs12_s *>(malloc(sizeof(ckmc_pkcs12_s))); - // ownership is transferred into pkcs12 - mentioned in the docs - pkcs12->priv_key = private_key; - pkcs12->cert = cert; - pkcs12->ca_chain = ca_cert_list; + if (pkcs12 == NULL) + return CKMC_ERROR_OUT_OF_MEMORY; - *pkcs12_bundle = pkcs12; - return CKMC_ERROR_NONE; + // ownership is transferred into pkcs12 - mentioned in the docs + pkcs12->priv_key = private_key; + pkcs12->cert = cert; + pkcs12->ca_chain = ca_cert_list; + + *pkcs12_bundle = pkcs12; + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI -int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ckmc_key_s **private_key, ckmc_cert_s **ckmcert, ckmc_cert_list_s **ca_cert_list) +int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, + ckmc_key_s **private_key, ckmc_cert_s **ckmcert, + ckmc_cert_list_s **ca_cert_list) { - class Pkcs12Converter { - private: - FILE* fp_in; - PKCS12* p12; - EVP_PKEY* pkey; - X509* x509Cert; - STACK_OF(X509)* ca; - - int ret; - - public: - ckmc_key_s *retPrivateKey; - ckmc_cert_s *retCkmCert; - ckmc_cert_list_s *retCaCertList; - - Pkcs12Converter() - { - fp_in = NULL; - p12 = NULL; - pkey = NULL; - x509Cert = NULL; - ca = NULL; - ret = CKMC_ERROR_NONE; - retPrivateKey = NULL; - retCkmCert = NULL; - retCaCertList = NULL; - }; - ~Pkcs12Converter() - { - if (fp_in != NULL) - fclose(fp_in); - if (p12 != NULL) - PKCS12_free(p12); - if (x509Cert != NULL) - X509_free(x509Cert); - if (pkey != NULL) - EVP_PKEY_free(pkey); - if (ca != NULL) - sk_X509_pop_free(ca, X509_free); - - if (ret != CKMC_ERROR_NONE) { - if (retPrivateKey != NULL) { - ckmc_key_free(retPrivateKey); - retPrivateKey = NULL; - } - if (retCkmCert != NULL) { - ckmc_cert_free(retCkmCert); - retCkmCert = NULL; - } - if (retCaCertList != NULL) { - ckmc_cert_list_all_free(retCaCertList); - retCaCertList = NULL; - } - } - }; - - int parsePkcs12(const char *filePath, const char *pass) - { - fp_in = NULL; - if (!(fp_in = fopen(filePath, "rb"))) - return CKMC_ERROR_FILE_ACCESS_DENIED; - - if (!(p12 = d2i_PKCS12_fp(fp_in, NULL))) - return CKMC_ERROR_INVALID_FORMAT; - - /* parse PKCS#12 certificate */ - if ((ret = PKCS12_parse(p12, pass, &pkey, &x509Cert, &ca)) != 1) - return CKMC_ERROR_INVALID_FORMAT; - - return CKMC_ERROR_NONE; - } - - int toCkmCert() - { - if ((ret = _ckmc_load_cert_from_x509(x509Cert, &retCkmCert)) != CKMC_ERROR_NONE) - return ret; - - return CKMC_ERROR_NONE; - } - - int toCkmKey() - { - BIO *bkey = BIO_new(BIO_s_mem()); - - i2d_PrivateKey_bio(bkey, pkey); - - CKM::RawBuffer output(8196); - int size = BIO_read(bkey, output.data(), output.size()); - BIO_free_all(bkey); - if (size <= 0) - return CKMC_ERROR_INVALID_FORMAT; - - output.resize(size); - - int type = EVP_PKEY_type(pkey->type); - ckmc_key_type_e key_type = CKMC_KEY_NONE; - switch (type) { - case EVP_PKEY_RSA : - key_type = CKMC_KEY_RSA_PRIVATE; - break; - case EVP_PKEY_DSA : - key_type = CKMC_KEY_DSA_PRIVATE; - break; - case EVP_PKEY_EC : - key_type = CKMC_KEY_ECDSA_PRIVATE; - break; - } - if (key_type == CKMC_KEY_NONE) - return CKMC_ERROR_INVALID_FORMAT; - - char *nullPassword = NULL; - - return ckmc_key_new(output.data(), size, key_type, nullPassword, &retPrivateKey); - } - - int toCaCkmCertList() - { - int tmpRet; - X509* popedCert = NULL; - ckmc_cert_s *popedCkmCert = NULL; - ckmc_cert_list_s *tmpCertList = NULL; - while ((popedCert = sk_X509_pop(ca)) != NULL) { - if ((tmpRet =_ckmc_load_cert_from_x509(popedCert, &popedCkmCert)) != CKMC_ERROR_NONE) - return CKMC_ERROR_OUT_OF_MEMORY; - - if (tmpCertList == NULL) { // first - tmpRet = ckmc_cert_list_new(popedCkmCert, &tmpCertList); - retCaCertList = tmpCertList; - } else { - tmpRet = ckmc_cert_list_add(tmpCertList, popedCkmCert, &tmpCertList); - } - if (tmpRet != CKMC_ERROR_NONE) { - ckmc_cert_list_all_free(retCaCertList); - retCaCertList = NULL; - return tmpRet; - } - } - return CKMC_ERROR_NONE; - } - }; - - CKM::initOpenSslOnce(); - - int ret = CKMC_ERROR_NONE; - - Pkcs12Converter converter; - if ((ret = converter.parsePkcs12(file_path, passphrase)) != CKMC_ERROR_NONE) - return ret; - - if ((ret = converter.toCkmCert()) != CKMC_ERROR_NONE) - return ret; - - if ((ret = converter.toCkmKey()) != CKMC_ERROR_NONE) - return ret; - - if ((ret = converter.toCaCkmCertList()) != CKMC_ERROR_NONE) - return ret; - - *private_key = converter.retPrivateKey; - *ckmcert = converter.retCkmCert; - *ca_cert_list = converter.retCaCertList; - - return CKMC_ERROR_NONE; + class Pkcs12Converter { + private: + FILE *fp_in; + PKCS12 *p12; + EVP_PKEY *pkey; + X509 *x509Cert; + STACK_OF(X509) *ca; + + int ret; + + public: + ckmc_key_s *retPrivateKey; + ckmc_cert_s *retCkmCert; + ckmc_cert_list_s *retCaCertList; + + Pkcs12Converter() + { + fp_in = NULL; + p12 = NULL; + pkey = NULL; + x509Cert = NULL; + ca = NULL; + ret = CKMC_ERROR_NONE; + retPrivateKey = NULL; + retCkmCert = NULL; + retCaCertList = NULL; + } + + ~Pkcs12Converter() + { + if (fp_in != NULL) + fclose(fp_in); + + if (p12 != NULL) + PKCS12_free(p12); + + if (x509Cert != NULL) + X509_free(x509Cert); + + if (pkey != NULL) + EVP_PKEY_free(pkey); + + if (ca != NULL) + sk_X509_pop_free(ca, X509_free); + + if (ret != CKMC_ERROR_NONE) { + if (retPrivateKey != NULL) { + ckmc_key_free(retPrivateKey); + retPrivateKey = NULL; + } + + if (retCkmCert != NULL) { + ckmc_cert_free(retCkmCert); + retCkmCert = NULL; + } + + if (retCaCertList != NULL) { + ckmc_cert_list_all_free(retCaCertList); + retCaCertList = NULL; + } + } + } + + int parsePkcs12(const char *filePath, const char *pass) + { + fp_in = NULL; + + if (!(fp_in = fopen(filePath, "rb"))) + return CKMC_ERROR_FILE_ACCESS_DENIED; + + if (!(p12 = d2i_PKCS12_fp(fp_in, NULL))) + return CKMC_ERROR_INVALID_FORMAT; + + /* parse PKCS#12 certificate */ + if ((ret = PKCS12_parse(p12, pass, &pkey, &x509Cert, &ca)) != 1) + return CKMC_ERROR_INVALID_FORMAT; + + return CKMC_ERROR_NONE; + } + + int toCkmCert() + { + if ((ret = _ckmc_load_cert_from_x509(x509Cert, &retCkmCert)) != CKMC_ERROR_NONE) + return ret; + + return CKMC_ERROR_NONE; + } + + int toCkmKey() + { + BIO *bkey = BIO_new(BIO_s_mem()); + + i2d_PrivateKey_bio(bkey, pkey); + + CKM::RawBuffer output(8196); + int size = BIO_read(bkey, output.data(), output.size()); + BIO_free_all(bkey); + + if (size <= 0) + return CKMC_ERROR_INVALID_FORMAT; + + output.resize(size); + + int type = EVP_PKEY_type(pkey->type); + ckmc_key_type_e key_type = CKMC_KEY_NONE; + + switch (type) { + case EVP_PKEY_RSA : + key_type = CKMC_KEY_RSA_PRIVATE; + break; + + case EVP_PKEY_DSA : + key_type = CKMC_KEY_DSA_PRIVATE; + break; + + case EVP_PKEY_EC : + key_type = CKMC_KEY_ECDSA_PRIVATE; + break; + } + + if (key_type == CKMC_KEY_NONE) + return CKMC_ERROR_INVALID_FORMAT; + + char *nullPassword = NULL; + + return ckmc_key_new(output.data(), size, key_type, nullPassword, + &retPrivateKey); + } + + int toCaCkmCertList() + { + int tmpRet; + X509 *popedCert = NULL; + ckmc_cert_s *popedCkmCert = NULL; + ckmc_cert_list_s *tmpCertList = NULL; + + while ((popedCert = sk_X509_pop(ca)) != NULL) { + if ((tmpRet = _ckmc_load_cert_from_x509(popedCert, + &popedCkmCert)) != CKMC_ERROR_NONE) + return CKMC_ERROR_OUT_OF_MEMORY; + + if (tmpCertList == NULL) { // first + tmpRet = ckmc_cert_list_new(popedCkmCert, &tmpCertList); + retCaCertList = tmpCertList; + } else { + tmpRet = ckmc_cert_list_add(tmpCertList, popedCkmCert, &tmpCertList); + } + + if (tmpRet != CKMC_ERROR_NONE) { + ckmc_cert_list_all_free(retCaCertList); + retCaCertList = NULL; + return tmpRet; + } + } + + return CKMC_ERROR_NONE; + } + }; + + CKM::initOpenSslOnce(); + + int ret = CKMC_ERROR_NONE; + + Pkcs12Converter converter; + + if ((ret = converter.parsePkcs12(file_path, passphrase)) != CKMC_ERROR_NONE) + return ret; + + if ((ret = converter.toCkmCert()) != CKMC_ERROR_NONE) + return ret; + + if ((ret = converter.toCkmKey()) != CKMC_ERROR_NONE) + return ret; + + if ((ret = converter.toCaCkmCertList()) != CKMC_ERROR_NONE) + return ret; + + *private_key = converter.retPrivateKey; + *ckmcert = converter.retCkmCert; + *ca_cert_list = converter.retCaCertList; + + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI -int ckmc_pkcs12_load(const char *file_path, const char *passphrase, ckmc_pkcs12_s **pkcs12_bundle) +int ckmc_pkcs12_load(const char *file_path, const char *passphrase, + ckmc_pkcs12_s **pkcs12_bundle) { - int ec; - ckmc_key_s *private_key = 0; - ckmc_cert_s *cert = 0; - ckmc_cert_list_s *ca_cert_list = 0; - - if (!file_path || !pkcs12_bundle) - return CKMC_ERROR_INVALID_PARAMETER; - - ec = ckmc_load_from_pkcs12_file(file_path, passphrase, &private_key, &cert, &ca_cert_list); - if (ec != CKMC_ERROR_NONE) - return ec; - - ec = ckmc_pkcs12_new(private_key, cert, ca_cert_list, pkcs12_bundle); - if (ec != CKMC_ERROR_NONE) { - ckmc_key_free(private_key); - ckmc_cert_free(cert); - ckmc_cert_list_free(ca_cert_list); - return ec; - } - - return CKMC_ERROR_NONE; + int ec; + ckmc_key_s *private_key = 0; + ckmc_cert_s *cert = 0; + ckmc_cert_list_s *ca_cert_list = 0; + + if (!file_path || !pkcs12_bundle) + return CKMC_ERROR_INVALID_PARAMETER; + + ec = ckmc_load_from_pkcs12_file(file_path, passphrase, &private_key, &cert, + &ca_cert_list); + + if (ec != CKMC_ERROR_NONE) + return ec; + + ec = ckmc_pkcs12_new(private_key, cert, ca_cert_list, pkcs12_bundle); + + if (ec != CKMC_ERROR_NONE) { + ckmc_key_free(private_key); + ckmc_cert_free(cert); + ckmc_cert_list_free(ca_cert_list); + return ec; + } + + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI void ckmc_pkcs12_free(ckmc_pkcs12_s *pkcs12) { - if (pkcs12 == NULL) - return; + if (pkcs12 == NULL) + return; - ckmc_key_free(pkcs12->priv_key); - ckmc_cert_free(pkcs12->cert); - ckmc_cert_list_free(pkcs12->ca_chain); - free(pkcs12); + ckmc_key_free(pkcs12->priv_key); + ckmc_cert_free(pkcs12->cert); + ckmc_cert_list_free(pkcs12->ca_chain); + free(pkcs12); } KEY_MANAGER_CAPI int ckmc_alias_list_new(char *alias, ckmc_alias_list_s **ppalias_list) { - ckmc_alias_list_s *previous = NULL; - return ckmc_alias_list_add(previous, alias, ppalias_list); + ckmc_alias_list_s *previous = NULL; + return ckmc_alias_list_add(previous, alias, ppalias_list); } KEY_MANAGER_CAPI -int ckmc_alias_list_add(ckmc_alias_list_s *previous, char *alias, ckmc_alias_list_s **pplast) +int ckmc_alias_list_add(ckmc_alias_list_s *previous, char *alias, + ckmc_alias_list_s **pplast) { - ckmc_alias_list_s *plist; + ckmc_alias_list_s *plist; + + if (alias == NULL || pplast == NULL) + return CKMC_ERROR_INVALID_PARAMETER; - if (alias == NULL || pplast == NULL) - return CKMC_ERROR_INVALID_PARAMETER; + plist = static_cast<ckmc_alias_list_s *>(malloc(sizeof(ckmc_alias_list_s))); - plist = static_cast<ckmc_alias_list_s*>(malloc(sizeof(ckmc_alias_list_s))); - if (plist == NULL) - return CKMC_ERROR_OUT_OF_MEMORY; + if (plist == NULL) + return CKMC_ERROR_OUT_OF_MEMORY; - plist->alias = alias; - plist->next = NULL; + plist->alias = alias; + plist->next = NULL; - if (previous != NULL) - previous->next = plist; + if (previous != NULL) + previous->next = plist; - *pplast = plist; + *pplast = plist; - return CKMC_ERROR_NONE; + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI void ckmc_alias_list_free(ckmc_alias_list_s *first) { - ckmc_alias_list_s *next = first; - while (next) { - ckmc_alias_list_s *current = next; - next = current->next; - free(current); - } + ckmc_alias_list_s *next = first; + + while (next) { + ckmc_alias_list_s *current = next; + next = current->next; + free(current); + } } KEY_MANAGER_CAPI void ckmc_alias_list_all_free(ckmc_alias_list_s *first) { - ckmc_alias_list_s *next = first; - while (next) { - ckmc_alias_list_s *current = next; - next = current->next; - free(current->alias); - free(current); - } + ckmc_alias_list_s *next = first; + + while (next) { + ckmc_alias_list_s *current = next; + next = current->next; + free(current->alias); + free(current); + } } KEY_MANAGER_CAPI int ckmc_cert_list_new(ckmc_cert_s *cert, ckmc_cert_list_s **ppalias_list) { - ckmc_cert_list_s *previous = NULL; - return ckmc_cert_list_add(previous, cert, ppalias_list); + ckmc_cert_list_s *previous = NULL; + return ckmc_cert_list_add(previous, cert, ppalias_list); } KEY_MANAGER_CAPI -int ckmc_cert_list_add(ckmc_cert_list_s *previous, ckmc_cert_s *cert, ckmc_cert_list_s **pplast) +int ckmc_cert_list_add(ckmc_cert_list_s *previous, ckmc_cert_s *cert, + ckmc_cert_list_s **pplast) { - ckmc_cert_list_s *plist; + ckmc_cert_list_s *plist; - if (cert == NULL || pplast == NULL) - return CKMC_ERROR_INVALID_PARAMETER; + if (cert == NULL || pplast == NULL) + return CKMC_ERROR_INVALID_PARAMETER; - plist = static_cast<ckmc_cert_list_s*>(malloc(sizeof(ckmc_cert_list_s))); - if (plist == NULL) - return CKMC_ERROR_OUT_OF_MEMORY; + plist = static_cast<ckmc_cert_list_s *>(malloc(sizeof(ckmc_cert_list_s))); - plist->cert = cert; - plist->next = NULL; + if (plist == NULL) + return CKMC_ERROR_OUT_OF_MEMORY; - if (previous != NULL) - previous->next = plist; + plist->cert = cert; + plist->next = NULL; - *pplast = plist; + if (previous != NULL) + previous->next = plist; - return CKMC_ERROR_NONE; + *pplast = plist; + + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI void ckmc_cert_list_free(ckmc_cert_list_s *first) { - ckmc_cert_list_s *next = first; - while (next) { - ckmc_cert_list_s *current = next; - next = current->next; - free(current); - } + ckmc_cert_list_s *next = first; + + while (next) { + ckmc_cert_list_s *current = next; + next = current->next; + free(current); + } } KEY_MANAGER_CAPI void ckmc_cert_list_all_free(ckmc_cert_list_s *first) { - ckmc_cert_list_s *next = first; - while (next) { - ckmc_cert_list_s *current = next; - next = current->next; - ckmc_cert_free(current->cert); - free(current); - } + ckmc_cert_list_s *next = first; + + while (next) { + ckmc_cert_list_s *current = next; + next = current->next; + ckmc_cert_free(current->cert); + free(current); + } } KEY_MANAGER_CAPI int ckmc_param_list_new(ckmc_param_list_h *pparams) { - if (!pparams) - return CKMC_ERROR_INVALID_PARAMETER; + if (!pparams) + return CKMC_ERROR_INVALID_PARAMETER; - *pparams = reinterpret_cast<ckmc_param_list_h>(new(std::nothrow)(CKM::CryptoAlgorithm)); - if (!*pparams) - return CKMC_ERROR_OUT_OF_MEMORY; - return CKMC_ERROR_NONE; + *pparams = reinterpret_cast<ckmc_param_list_h>(new(std::nothrow)( + CKM::CryptoAlgorithm)); + + if (!*pparams) + return CKMC_ERROR_OUT_OF_MEMORY; + + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI int ckmc_param_list_set_integer(ckmc_param_list_h params, - ckmc_param_name_e name, - uint64_t value) + ckmc_param_name_e name, + uint64_t value) { - if (!params) - return CKMC_ERROR_INVALID_PARAMETER; + if (!params) + return CKMC_ERROR_INVALID_PARAMETER; - CKM::CryptoAlgorithm* algo = reinterpret_cast<CKM::CryptoAlgorithm*>(params); - bool ret = algo->setParam(static_cast<CKM::ParamName>(name), value); - return (ret ? CKMC_ERROR_NONE : CKMC_ERROR_INVALID_PARAMETER); + CKM::CryptoAlgorithm *algo = reinterpret_cast<CKM::CryptoAlgorithm *>(params); + bool ret = algo->setParam(static_cast<CKM::ParamName>(name), value); + return (ret ? CKMC_ERROR_NONE : CKMC_ERROR_INVALID_PARAMETER); } KEY_MANAGER_CAPI int ckmc_param_list_set_buffer(ckmc_param_list_h params, - ckmc_param_name_e name, - const ckmc_raw_buffer_s *buffer) + ckmc_param_name_e name, + const ckmc_raw_buffer_s *buffer) { - if (!params || !buffer || !buffer->data || buffer->size == 0) - return CKMC_ERROR_INVALID_PARAMETER; + if (!params || !buffer || !buffer->data || buffer->size == 0) + return CKMC_ERROR_INVALID_PARAMETER; - CKM::CryptoAlgorithm* algo = reinterpret_cast<CKM::CryptoAlgorithm*>(params); - CKM::RawBuffer b(buffer->data, buffer->data + buffer->size); - bool ret = algo->setParam(static_cast<CKM::ParamName>(name), b); - return (ret ? CKMC_ERROR_NONE : CKMC_ERROR_INVALID_PARAMETER); + CKM::CryptoAlgorithm *algo = reinterpret_cast<CKM::CryptoAlgorithm *>(params); + CKM::RawBuffer b(buffer->data, buffer->data + buffer->size); + bool ret = algo->setParam(static_cast<CKM::ParamName>(name), b); + return (ret ? CKMC_ERROR_NONE : CKMC_ERROR_INVALID_PARAMETER); } KEY_MANAGER_CAPI int ckmc_param_list_get_integer(ckmc_param_list_h params, - ckmc_param_name_e name, - uint64_t *pvalue) + ckmc_param_name_e name, + uint64_t *pvalue) { - if (!params || !pvalue) - return CKMC_ERROR_INVALID_PARAMETER; + if (!params || !pvalue) + return CKMC_ERROR_INVALID_PARAMETER; + + const CKM::CryptoAlgorithm *algo = + reinterpret_cast<const CKM::CryptoAlgorithm *>(params); - const CKM::CryptoAlgorithm* algo = reinterpret_cast<const CKM::CryptoAlgorithm*>(params); - if (!algo->getParam(static_cast<CKM::ParamName>(name), *pvalue)) - return CKMC_ERROR_INVALID_PARAMETER; + if (!algo->getParam(static_cast<CKM::ParamName>(name), *pvalue)) + return CKMC_ERROR_INVALID_PARAMETER; - return CKMC_ERROR_NONE; + return CKMC_ERROR_NONE; } KEY_MANAGER_CAPI int ckmc_param_list_get_buffer(ckmc_param_list_h params, - ckmc_param_name_e name, - ckmc_raw_buffer_s **ppbuffer) + ckmc_param_name_e name, + ckmc_raw_buffer_s **ppbuffer) { - if (!params || !ppbuffer || *ppbuffer) - return CKMC_ERROR_INVALID_PARAMETER; + if (!params || !ppbuffer || *ppbuffer) + return CKMC_ERROR_INVALID_PARAMETER; - const CKM::CryptoAlgorithm* algo = reinterpret_cast<const CKM::CryptoAlgorithm*>(params); - CKM::RawBuffer value; - if (!algo->getParam(static_cast<CKM::ParamName>(name), value)) - return CKMC_ERROR_INVALID_PARAMETER; + const CKM::CryptoAlgorithm *algo = + reinterpret_cast<const CKM::CryptoAlgorithm *>(params); + CKM::RawBuffer value; - return ckmc_buffer_new(value.data(), value.size(), ppbuffer); + if (!algo->getParam(static_cast<CKM::ParamName>(name), value)) + return CKMC_ERROR_INVALID_PARAMETER; + + return ckmc_buffer_new(value.data(), value.size(), ppbuffer); } KEY_MANAGER_CAPI void ckmc_param_list_free(ckmc_param_list_h params) { - CKM::CryptoAlgorithm* algo = reinterpret_cast<CKM::CryptoAlgorithm*>(params); - delete algo; + CKM::CryptoAlgorithm *algo = reinterpret_cast<CKM::CryptoAlgorithm *>(params); + delete algo; } KEY_MANAGER_CAPI int ckmc_generate_new_params(ckmc_algo_type_e type, ckmc_param_list_h *pparams) { - if (!pparams) - return CKMC_ERROR_INVALID_PARAMETER; - - ckmc_param_list_h params = NULL; - int ret = ckmc_param_list_new(¶ms); - if (ret != CKMC_ERROR_NONE) - return ret; - - switch (type) { - case CKMC_ALGO_AES_CTR: - ret = ckmc_param_list_set_integer(params, CKMC_PARAM_ED_CTR_LEN, DEFAULT_IV_LEN_BITS); - break; - case CKMC_ALGO_AES_CBC: - case CKMC_ALGO_AES_GCM: - case CKMC_ALGO_AES_CFB: - case CKMC_ALGO_RSA_OAEP: - // no iv by default - break; - default: - ret = CKMC_ERROR_INVALID_PARAMETER; - break; - } - - if (ret != CKMC_ERROR_NONE) { - ckmc_param_list_free(params); - return ret; - } - - ret = ckmc_param_list_set_integer(params, CKMC_PARAM_ALGO_TYPE, type); - if (ret != CKMC_ERROR_NONE) { - ckmc_param_list_free(params); - return ret; - } - - *pparams = params; - - return CKMC_ERROR_NONE; + if (!pparams) + return CKMC_ERROR_INVALID_PARAMETER; + + ckmc_param_list_h params = NULL; + int ret = ckmc_param_list_new(¶ms); + + if (ret != CKMC_ERROR_NONE) + return ret; + + switch (type) { + case CKMC_ALGO_AES_CTR: + ret = ckmc_param_list_set_integer(params, CKMC_PARAM_ED_CTR_LEN, + DEFAULT_IV_LEN_BITS); + break; + + case CKMC_ALGO_AES_CBC: + case CKMC_ALGO_AES_GCM: + case CKMC_ALGO_AES_CFB: + case CKMC_ALGO_RSA_OAEP: + // no iv by default + break; + + default: + ret = CKMC_ERROR_INVALID_PARAMETER; + break; + } + + if (ret != CKMC_ERROR_NONE) { + ckmc_param_list_free(params); + return ret; + } + + ret = ckmc_param_list_set_integer(params, CKMC_PARAM_ALGO_TYPE, type); + + if (ret != CKMC_ERROR_NONE) { + ckmc_param_list_free(params); + return ret; + } + + *pparams = params; + + return CKMC_ERROR_NONE; } diff --git a/src/manager/client/client-common.cpp b/src/manager/client/client-common.cpp index 02bbbcfb..c50a71aa 100644 --- a/src/manager/client/client-common.cpp +++ b/src/manager/client/client-common.cpp @@ -52,298 +52,327 @@ SockRAII::SockRAII() : m_sock(-1) {} SockRAII::~SockRAII() { - disconnect(); + disconnect(); } -int SockRAII::connect(const char * interface) +int SockRAII::connect(const char *interface) { - if (!interface) { - LogError("No valid interface address given."); - return CKM_API_ERROR_INPUT_PARAM; - } + if (!interface) { + LogError("No valid interface address given."); + return CKM_API_ERROR_INPUT_PARAM; + } - int localSock = socket(AF_UNIX, SOCK_STREAM, 0); + int localSock = socket(AF_UNIX, SOCK_STREAM, 0); - if (localSock < 0) { - LogError("Error creating socket: " << CKM::GetErrnoString(errno)); - return CKM_API_ERROR_SOCKET; - } + if (localSock < 0) { + LogError("Error creating socket: " << CKM::GetErrnoString(errno)); + return CKM_API_ERROR_SOCKET; + } - int retCode = connectWrapper(localSock, interface); + int retCode = connectWrapper(localSock, interface); - if (retCode != CKM_API_SUCCESS) { - close(localSock); - return retCode; - } + if (retCode != CKM_API_SUCCESS) { + close(localSock); + return retCode; + } - disconnect(); + disconnect(); - m_sock = localSock; + m_sock = localSock; - return CKM_API_SUCCESS; + return CKM_API_SUCCESS; } int SockRAII::connectWrapper(int sock, const char *interface) { - int flags; - - // we need to be sure that socket is in blocking mode - if ((flags = fcntl(sock, F_GETFL, 0)) < 0 || fcntl(sock, F_SETFL, flags & ~O_NONBLOCK) < 0) { - LogError("Error in fcntl: " << CKM::GetErrnoString(errno)); - return CKM_API_ERROR_SOCKET; - } - - sockaddr_un clientAddr; - memset(&clientAddr, 0, sizeof(clientAddr)); - clientAddr.sun_family = AF_UNIX; - - if (strlen(interface) >= sizeof(clientAddr.sun_path)) { - LogError("Error: interface name " << interface << "is too long." - " Max len is:" << sizeof(clientAddr.sun_path)); - return CKM_API_ERROR_INPUT_PARAM; - } - - strncpy(clientAddr.sun_path, interface, sizeof(clientAddr.sun_path) - 1); - LogDebug("ClientAddr.sun_path = " << interface); - - int retval = TEMP_FAILURE_RETRY(::connect(sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr))); - - // we don't need to support EINPROGRESS because the socket is in blocking mode - if (-1 == retval) { - if (errno == EACCES) { - LogError("Access denied to interface: " << interface); - return CKM_API_ERROR_ACCESS_DENIED; - } - LogError("Error connecting socket: " << CKM::GetErrnoString(errno)); - return CKM_API_ERROR_SOCKET; - } - - // make the socket non-blocking - if ((flags = fcntl(sock, F_GETFL, 0)) < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) { - LogError("Error in fcntl: " << CKM::GetErrnoString(errno)); - return CKM_API_ERROR_SOCKET; - } - - return CKM_API_SUCCESS; + int flags; + + // we need to be sure that socket is in blocking mode + if ((flags = fcntl(sock, F_GETFL, 0)) < 0 || + fcntl(sock, F_SETFL, flags & ~O_NONBLOCK) < 0) { + LogError("Error in fcntl: " << CKM::GetErrnoString(errno)); + return CKM_API_ERROR_SOCKET; + } + + sockaddr_un clientAddr; + memset(&clientAddr, 0, sizeof(clientAddr)); + clientAddr.sun_family = AF_UNIX; + + if (strlen(interface) >= sizeof(clientAddr.sun_path)) { + LogError("Error: interface name " << interface << "is too long." + " Max len is:" << sizeof(clientAddr.sun_path)); + return CKM_API_ERROR_INPUT_PARAM; + } + + strncpy(clientAddr.sun_path, interface, sizeof(clientAddr.sun_path) - 1); + LogDebug("ClientAddr.sun_path = " << interface); + + int retval = TEMP_FAILURE_RETRY(::connect(sock, (struct sockaddr *)&clientAddr, + SUN_LEN(&clientAddr))); + + // we don't need to support EINPROGRESS because the socket is in blocking mode + if (-1 == retval) { + if (errno == EACCES) { + LogError("Access denied to interface: " << interface); + return CKM_API_ERROR_ACCESS_DENIED; + } + + LogError("Error connecting socket: " << CKM::GetErrnoString(errno)); + return CKM_API_ERROR_SOCKET; + } + + // make the socket non-blocking + if ((flags = fcntl(sock, F_GETFL, 0)) < 0 || + fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) { + LogError("Error in fcntl: " << CKM::GetErrnoString(errno)); + return CKM_API_ERROR_SOCKET; + } + + return CKM_API_SUCCESS; } bool SockRAII::isConnected() const { - return (m_sock > -1); + return (m_sock > -1); } void SockRAII::disconnect() { - if (isConnected()) - close(m_sock); - m_sock = -1; + if (isConnected()) + close(m_sock); + + m_sock = -1; } int SockRAII::waitForSocket(int event, int timeout) { - int retval; - pollfd desc[1]; - desc[0].fd = m_sock; - desc[0].events = event; - - while ((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) { - timeout >>= 1; - errno = 0; - } - - if (0 == retval) - LogDebug("Poll timeout"); - else if (-1 == retval) - LogError("Error in poll: " << CKM::GetErrnoString(errno)); - - return retval; + int retval; + pollfd desc[1]; + desc[0].fd = m_sock; + desc[0].events = event; + + while ((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) { + timeout >>= 1; + errno = 0; + } + + if (0 == retval) + LogDebug("Poll timeout"); + else if (-1 == retval) + LogError("Error in poll: " << CKM::GetErrnoString(errno)); + + return retval; } int SockRAII::get() const { - return m_sock; + return m_sock; } AliasSupport::AliasSupport(const Alias &alias) { - std::size_t separator_pos = alias.rfind(CKM::LABEL_NAME_SEPARATOR); - if (separator_pos == Alias::npos) { - m_label.clear(); - m_name = alias; - } else { - m_label = alias.substr(0, separator_pos); - m_name = alias.substr(separator_pos + strlen(CKM::LABEL_NAME_SEPARATOR)); - } + std::size_t separator_pos = alias.rfind(CKM::LABEL_NAME_SEPARATOR); + + if (separator_pos == Alias::npos) { + m_label.clear(); + m_name = alias; + } else { + m_label = alias.substr(0, separator_pos); + m_name = alias.substr(separator_pos + strlen(CKM::LABEL_NAME_SEPARATOR)); + } } Alias AliasSupport::merge(const Label &label, const Name &name) { - if (label.empty()) - return name; + if (label.empty()) + return name; - std::stringstream output; - output << label << std::string(CKM::LABEL_NAME_SEPARATOR) << name; - return output.str(); + std::stringstream output; + output << label << std::string(CKM::LABEL_NAME_SEPARATOR) << name; + return output.str(); } -const Name & AliasSupport::getName() const +const Name &AliasSupport::getName() const { - return m_name; + return m_name; } -const Label & AliasSupport::getLabel() const +const Label &AliasSupport::getLabel() const { - return m_label; + return m_label; } bool AliasSupport::isLabelEmpty() const { - return m_label.empty(); + return m_label.empty(); } ServiceConnection::ServiceConnection(const char *service_interface) { - if (service_interface) - m_serviceInterface = std::string(service_interface); + if (service_interface) + m_serviceInterface = std::string(service_interface); } int ServiceConnection::processRequest( - const CKM::RawBuffer &send_buf, - CKM::MessageBuffer &recv_buf) + const CKM::RawBuffer &send_buf, + CKM::MessageBuffer &recv_buf) { - int ec; - if (CKM_API_SUCCESS != (ec = send(send_buf))) - return ec; + int ec; + + if (CKM_API_SUCCESS != (ec = send(send_buf))) + return ec; - return receive(recv_buf); + return receive(recv_buf); } int ServiceConnection::prepareConnection() { - if (m_socket.isConnected()) - return CKM_API_SUCCESS; + if (m_socket.isConnected()) + return CKM_API_SUCCESS; - return m_socket.connect(m_serviceInterface.c_str()); + return m_socket.connect(m_serviceInterface.c_str()); } int ServiceConnection::send(const CKM::RawBuffer &send_buf) { - int retCode = prepareConnection(); - - if (retCode != CKM_API_SUCCESS) { - LogError("Failed to prepare connection: " << retCode); - return retCode; - } - - ssize_t done = 0; - while ((send_buf.size() - done) > 0) { - if (0 >= m_socket.waitForSocket(POLLOUT, POLL_TIMEOUT)) { - LogError("Error in WaitForSocket."); - retCode = CKM_API_ERROR_SOCKET; - break; - } - - ssize_t temp = TEMP_FAILURE_RETRY(::send(m_socket.get(), - &send_buf[done], - send_buf.size() - done, - MSG_NOSIGNAL)); - if (-1 == temp) { - LogError("Error in write: " << CKM::GetErrnoString(errno)); - retCode = CKM_API_ERROR_SOCKET; - break; - } - - done += temp; - } - - if (retCode != CKM_API_SUCCESS) - m_socket.disconnect(); - - return retCode; + int retCode = prepareConnection(); + + if (retCode != CKM_API_SUCCESS) { + LogError("Failed to prepare connection: " << retCode); + return retCode; + } + + ssize_t done = 0; + + while ((send_buf.size() - done) > 0) { + if (0 >= m_socket.waitForSocket(POLLOUT, POLL_TIMEOUT)) { + LogError("Error in WaitForSocket."); + retCode = CKM_API_ERROR_SOCKET; + break; + } + + ssize_t temp = TEMP_FAILURE_RETRY(::send(m_socket.get(), + &send_buf[done], + send_buf.size() - done, + MSG_NOSIGNAL)); + + if (-1 == temp) { + LogError("Error in write: " << CKM::GetErrnoString(errno)); + retCode = CKM_API_ERROR_SOCKET; + break; + } + + done += temp; + } + + if (retCode != CKM_API_SUCCESS) + m_socket.disconnect(); + + return retCode; } int ServiceConnection::receive(CKM::MessageBuffer &recv_buf) { - if (!m_socket.isConnected()) { - LogError("Not connected!"); - return CKM_API_ERROR_SOCKET; - } - - int ec = CKM_API_SUCCESS; - const size_t c_recv_buf_len = 2048; - char buffer[c_recv_buf_len]; - do { - if (0 >= m_socket.waitForSocket(POLLIN, POLL_TIMEOUT)) { - LogError("Error in WaitForSocket."); - ec = CKM_API_ERROR_SOCKET; - break; - } - - ssize_t temp = TEMP_FAILURE_RETRY(::recv(m_socket.get(), - buffer, - sizeof(buffer), - 0)); - if (-1 == temp) { - LogError("Error in read: " << CKM::GetErrnoString(errno)); - ec = CKM_API_ERROR_SOCKET; - break; - } - - if (0 == temp) { - LogError("Read return 0/Connection closed by server(?)"); - ec = CKM_API_ERROR_SOCKET; - break; - } - - CKM::RawBuffer raw(buffer, buffer+temp); - recv_buf.Push(raw); - } while (!recv_buf.Ready()); - - if (ec != CKM_API_SUCCESS) - m_socket.disconnect(); - - return ec; + if (!m_socket.isConnected()) { + LogError("Not connected!"); + return CKM_API_ERROR_SOCKET; + } + + int ec = CKM_API_SUCCESS; + const size_t c_recv_buf_len = 2048; + char buffer[c_recv_buf_len]; + + do { + if (0 >= m_socket.waitForSocket(POLLIN, POLL_TIMEOUT)) { + LogError("Error in WaitForSocket."); + ec = CKM_API_ERROR_SOCKET; + break; + } + + ssize_t temp = TEMP_FAILURE_RETRY(::recv(m_socket.get(), + buffer, + sizeof(buffer), + 0)); + + if (-1 == temp) { + LogError("Error in read: " << CKM::GetErrnoString(errno)); + ec = CKM_API_ERROR_SOCKET; + break; + } + + if (0 == temp) { + LogError("Read return 0/Connection closed by server(?)"); + ec = CKM_API_ERROR_SOCKET; + break; + } + + CKM::RawBuffer raw(buffer, buffer + temp); + recv_buf.Push(raw); + } while (!recv_buf.Ready()); + + if (ec != CKM_API_SUCCESS) + m_socket.disconnect(); + + return ec; } ServiceConnection::~ServiceConnection() { } -int try_catch(const std::function<int()>& func) +int try_catch(const std::function<int()> &func) +{ + int retval = CKM_API_ERROR_UNKNOWN; + + try { + return func(); + } catch (const MessageBuffer::Exception::Base &e) { + LogError("CKM::MessageBuffer::Exception " << e.DumpToString()); + } catch (const DataType::Exception::Base &e) { + LogError("CKM::DBDataType::Exception " << e.DumpToString()); + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + } catch (...) { + LogError("Unknown exception occured"); + } + + return retval; +} + +int try_catch_enclosure(const std::function<int()> &func) { - int retval = CKM_API_ERROR_UNKNOWN; - try { - return func(); - } catch (const MessageBuffer::Exception::Base &e) { - LogError("CKM::MessageBuffer::Exception " << e.DumpToString()); - } catch (const DataType::Exception::Base &e) { - LogError("CKM::DBDataType::Exception " << e.DumpToString()); - } catch (const std::exception &e) { - LogError("STD exception " << e.what()); - } catch (...) { - LogError("Unknown exception occured"); - } - return retval; + try { + return func(); + } catch (const std::bad_alloc &e) { + LogError("memory allocation exception: " << e.what()); + return CKMC_ERROR_OUT_OF_MEMORY; + } catch (const std::exception &e) { + LogError("std exception occured: " << e.what()); + return CKMC_ERROR_UNKNOWN; + } catch (...) { + LogError("Unknown exception occured."); + return CKMC_ERROR_UNKNOWN; + } } -void try_catch_async(const std::function<void()>& func, - const std::function<void(int)>& error) +void try_catch_async(const std::function<void()> &func, + const std::function<void(int)> &error) { - try { - func(); - } catch (const MessageBuffer::Exception::Base& e) { - LogError("CKM::MessageBuffer::Exception " << e.DumpToString()); - error(CKM_API_ERROR_BAD_REQUEST); - } catch (const DataType::Exception::Base &e) { - LogError("CKM::DBDataType conversion failed:" << e.DumpToString()); - error(CKM_API_ERROR_UNKNOWN); - } catch (const std::exception& e) { - LogError("STD exception " << e.what()); - error(CKM_API_ERROR_UNKNOWN); - } catch (...) { - LogError("Unknown exception occured"); - error(CKM_API_ERROR_UNKNOWN); - } + try { + func(); + } catch (const MessageBuffer::Exception::Base &e) { + LogError("CKM::MessageBuffer::Exception " << e.DumpToString()); + error(CKM_API_ERROR_BAD_REQUEST); + } catch (const DataType::Exception::Base &e) { + LogError("CKM::DBDataType conversion failed:" << e.DumpToString()); + error(CKM_API_ERROR_UNKNOWN); + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + error(CKM_API_ERROR_UNKNOWN); + } catch (...) { + LogError("Unknown exception occured"); + error(CKM_API_ERROR_UNKNOWN); + } } } // namespace CKM @@ -351,7 +380,7 @@ void try_catch_async(const std::function<void()>& func, static void init_lib(void) __attribute__((constructor)); static void init_lib(void) { - CKM::SetupClientLogSystem(); + CKM::SetupClientLogSystem(); } static void fini_lib(void) __attribute__((destructor)); diff --git a/src/manager/client/client-common.h b/src/manager/client/client-common.h index ac391dda..9dc071c7 100644 --- a/src/manager/client/client-common.h +++ b/src/manager/client/client-common.h @@ -33,77 +33,87 @@ #include <noncopyable.h> #include <ckm/ckm-type.h> +#include <ckmc/ckmc-error.h> #include <message-buffer.h> #include <protocols.h> +#define EXCEPTION_GUARD_START_CPPAPI return CKM::try_catch([&]()->int { +#define EXCEPTION_GUARD_START_CAPI return CKM::try_catch_enclosure([&]()->int { +#define EXCEPTION_GUARD_END }); + extern "C" { - struct msghdr; + struct msghdr; } namespace CKM { class AliasSupport { - public: - AliasSupport(const Alias &alias); +public: + AliasSupport(const Alias &alias); - const Label & getLabel() const; - const Name & getName() const; - bool isLabelEmpty() const; + const Label &getLabel() const; + const Name &getName() const; + bool isLabelEmpty() const; - static Alias merge(const Label &label, const Name &alias); + static Alias merge(const Label &label, const Name &alias); - private: - Name m_name; - Label m_label; +private: + Name m_name; + Label m_label; }; class SockRAII { - public: - SockRAII(); +public: + SockRAII(); - NONCOPYABLE(SockRAII); + NONCOPYABLE(SockRAII); - virtual ~SockRAII(); + virtual ~SockRAII(); - int connect(const char * interface); - void disconnect(); - bool isConnected() const; - int get() const; - int waitForSocket(int event, int timeout); + int connect(const char *interface); + void disconnect(); + bool isConnected() const; + int get() const; + int waitForSocket(int event, int timeout); - protected: - int connectWrapper(int socket, const char *interface); - int m_sock; +protected: + int connectWrapper(int socket, const char *interface); + int m_sock; }; class ServiceConnection { - public: - ServiceConnection(const char * service_interface); +public: + ServiceConnection(const char *service_interface); - // roundtrip: send and receive - int processRequest(const CKM::RawBuffer &send_buf, - CKM::MessageBuffer &recv_buf); + // roundtrip: send and receive + int processRequest(const CKM::RawBuffer &send_buf, + CKM::MessageBuffer &recv_buf); - // blocking - int send(const CKM::RawBuffer &send_buf); - int receive(CKM::MessageBuffer &recv_buf); + // blocking + int send(const CKM::RawBuffer &send_buf); + int receive(CKM::MessageBuffer &recv_buf); - virtual ~ServiceConnection(); + virtual ~ServiceConnection(); - protected: - int prepareConnection(); +protected: + int prepareConnection(); - SockRAII m_socket; - std::string m_serviceInterface; + SockRAII m_socket; + std::string m_serviceInterface; }; /* * Decorator function that performs frequently repeated exception handling in * SS client API functions. Accepts lambda expression as an argument. */ -int try_catch(const std::function<int()>& func); - -void try_catch_async(const std::function<void()>& func, const std::function<void(int)>& error); +// for c++ api layer +int try_catch(const std::function<int()> &func); +// for c api layer +int try_catch_enclosure(const std::function<int()> &func); + +// for c++ async api layer +void try_catch_async(const std::function<void()> &func, + const std::function<void(int)> &error); } // namespace CKM diff --git a/src/manager/client/client-control.cpp b/src/manager/client/client-control.cpp index 62db1487..9a90cad7 100644 --- a/src/manager/client/client-control.cpp +++ b/src/manager/client/client-control.cpp @@ -32,196 +32,226 @@ namespace CKM { class ControlImpl : public Control { public: - ControlImpl() : m_controlConnection(SERVICE_SOCKET_CKM_CONTROL) {} - ControlImpl(const ControlImpl &) = delete; - ControlImpl(ControlImpl &&) = delete; - ControlImpl& operator=(const ControlImpl &) = delete; - ControlImpl& operator=(ControlImpl &&) = delete; - - virtual int unlockUserKey(uid_t user, const Password &password) - { - return try_catch([&] { - if ((int)user < 0) - return CKM_API_ERROR_INPUT_PARAM; - - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::UNLOCK_USER_KEY), - user, - password); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int lockUserKey(uid_t user) - { - return try_catch([&] { - if ((int)user < 0) - return CKM_API_ERROR_INPUT_PARAM; - - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::LOCK_USER_KEY), user); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int removeUserData(uid_t user) - { - return try_catch([&] { - if ((int)user < 0) - return CKM_API_ERROR_INPUT_PARAM; - - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::REMOVE_USER_DATA), user); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int changeUserPassword(uid_t user, const Password &oldPassword, const Password &newPassword) - { - return try_catch([&] { - if ((int)user < 0) - return CKM_API_ERROR_INPUT_PARAM; - - MessageBuffer recv; - auto send = MessageBuffer::Serialize( - static_cast<int>(ControlCommand::CHANGE_USER_PASSWORD), - user, - oldPassword, - newPassword); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int resetUserPassword(uid_t user, const Password &newPassword) - { - return try_catch([&] { - if ((int)user < 0) - return CKM_API_ERROR_INPUT_PARAM; - - MessageBuffer recv; - auto send = MessageBuffer::Serialize( - static_cast<int>(ControlCommand::RESET_USER_PASSWORD), - user, - newPassword); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int removeApplicationData(const Label &smackLabel) - { - return try_catch([&] { - if (smackLabel.empty()) - return CKM_API_ERROR_INPUT_PARAM; - - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::REMOVE_APP_DATA), smackLabel); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int updateCCMode() - { - return try_catch([&] { - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::UPDATE_CC_MODE)); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - recv.Deserialize(retCode); - - return retCode; - }); - } - - virtual int setPermission(uid_t user, - const Alias &alias, - const Label &accessor, - PermissionMask permissionMask) - { - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(ControlCommand::SET_PERMISSION), - static_cast<int>(user), - helper.getName(), - helper.getLabel(), - accessor, - permissionMask); - - int retCode = m_controlConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - int command; - int counter; - recv.Deserialize(command, counter, retCode); - - return retCode; - }); - } - - virtual ~ControlImpl() - { - } + ControlImpl() : m_controlConnection(SERVICE_SOCKET_CKM_CONTROL) {} + ControlImpl(const ControlImpl &) = delete; + ControlImpl(ControlImpl &&) = delete; + ControlImpl &operator=(const ControlImpl &) = delete; + ControlImpl &operator=(ControlImpl &&) = delete; + + virtual int unlockUserKey(uid_t user, const Password &password) + { + EXCEPTION_GUARD_START_CPPAPI + + if ((int)user < 0) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int> + (ControlCommand::UNLOCK_USER_KEY), + user, + password); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int lockUserKey(uid_t user) + { + EXCEPTION_GUARD_START_CPPAPI + + if ((int)user < 0) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int> + (ControlCommand::LOCK_USER_KEY), user); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int removeUserData(uid_t user) + { + EXCEPTION_GUARD_START_CPPAPI + + if ((int)user < 0) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int> + (ControlCommand::REMOVE_USER_DATA), user); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int changeUserPassword(uid_t user, const Password &oldPassword, + const Password &newPassword) + { + EXCEPTION_GUARD_START_CPPAPI + + if ((int)user < 0) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + auto send = MessageBuffer::Serialize( + static_cast<int>(ControlCommand::CHANGE_USER_PASSWORD), + user, + oldPassword, + newPassword); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int resetUserPassword(uid_t user, const Password &newPassword) + { + EXCEPTION_GUARD_START_CPPAPI + + if ((int)user < 0) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + auto send = MessageBuffer::Serialize( + static_cast<int>(ControlCommand::RESET_USER_PASSWORD), + user, + newPassword); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int removeApplicationData(const Label &smackLabel) + { + EXCEPTION_GUARD_START_CPPAPI + + if (smackLabel.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int> + (ControlCommand::REMOVE_APP_DATA), smackLabel); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int updateCCMode() + { + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int> + (ControlCommand::UPDATE_CC_MODE)); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + recv.Deserialize(retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual int setPermission(uid_t user, + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask) + { + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int> + (ControlCommand::SET_PERMISSION), + static_cast<int>(user), + helper.getName(), + helper.getLabel(), + accessor, + permissionMask); + + int retCode = m_controlConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + int command; + int counter; + recv.Deserialize(command, counter, retCode); + + return retCode; + + EXCEPTION_GUARD_END + } + + virtual ~ControlImpl() {} private: - CKM::ServiceConnection m_controlConnection; + CKM::ServiceConnection m_controlConnection; }; ControlShPtr Control::create() { - try { - return std::make_shared<ControlImpl>(); - } catch (const std::bad_alloc &) { - LogDebug("Bad alloc was caught during ControlImpl creation."); - } catch (...) { - LogError("Critical error: Unknown exception was caught druing ControlImpl creation!"); - } - return ControlShPtr(); + try { + return std::make_shared<ControlImpl>(); + } catch (const std::bad_alloc &) { + LogDebug("Bad alloc was caught during ControlImpl creation."); + } catch (...) { + LogError("Critical error: Unknown exception was caught druing ControlImpl creation!"); + } + + return ControlShPtr(); } } // namespace CKM diff --git a/src/manager/client/client-manager-impl.cpp b/src/manager/client/client-manager-impl.cpp index 17b79b7a..78c10768 100644 --- a/src/manager/client/client-manager-impl.cpp +++ b/src/manager/client/client-manager-impl.cpp @@ -37,779 +37,856 @@ namespace CKM { namespace { template <class T> int getCertChain( - ServiceConnection & serviceConnection, - LogicCommand command, - int counter, - const CertificateShPtr &certificate, - const T &untrustedVector, - const T &trustedVector, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector) -{ - return try_catch([&] { - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(command), - counter, - certificate->getDER(), - untrustedVector, - trustedVector, - useTrustedSystemCertificates); - - int retCode = serviceConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - int retCommand; - int retCounter; - RawBufferVector rawBufferVector; - recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector); - - if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) - return CKM_API_ERROR_UNKNOWN; - - if (retCode != CKM_API_SUCCESS) - return retCode; - - for (auto &e: rawBufferVector) { - CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER)); - if (cert->empty()) - return CKM_API_ERROR_BAD_RESPONSE; - certificateChainVector.push_back(cert); - } - - return retCode; - }); + ServiceConnection &serviceConnection, + LogicCommand command, + int counter, + const CertificateShPtr &certificate, + const T &untrustedVector, + const T &trustedVector, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector) +{ + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int>(command), + counter, + certificate->getDER(), + untrustedVector, + trustedVector, + useTrustedSystemCertificates); + + int retCode = serviceConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + int retCommand; + int retCounter; + RawBufferVector rawBufferVector; + recv.Deserialize(retCommand, retCounter, retCode, rawBufferVector); + + if ((counter != retCounter) || (static_cast<int>(command) != retCommand)) + return CKM_API_ERROR_UNKNOWN; + + if (retCode != CKM_API_SUCCESS) + return retCode; + + for (auto &e : rawBufferVector) { + CertificateShPtr cert(new CertificateImpl(e, DataFormat::FORM_DER)); + + if (cert->empty()) + return CKM_API_ERROR_BAD_RESPONSE; + + certificateChainVector.push_back(cert); + } + + return retCode; + + EXCEPTION_GUARD_END } } // namespace anonymous Manager::Impl::Impl() - : m_counter(0), - m_storageConnection(SERVICE_SOCKET_CKM_STORAGE), - m_ocspConnection(SERVICE_SOCKET_OCSP), - m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION) + : m_counter(0), + m_storageConnection(SERVICE_SOCKET_CKM_STORAGE), + m_ocspConnection(SERVICE_SOCKET_OCSP), + m_encryptionConnection(SERVICE_SOCKET_ENCRYPTION) { - initOpenSslOnce(); + initOpenSslOnce(); } int Manager::Impl::saveBinaryData( - const Alias &alias, - DataType dataType, - const RawBuffer &rawData, - const Policy &policy) + const Alias &alias, + DataType dataType, + const RawBuffer &rawData, + const Policy &policy) { - int my_counter = ++m_counter; + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + if (alias.empty() || rawData.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE), + my_counter, + static_cast<int>(dataType), + helper.getName(), + helper.getLabel(), + rawData, + PolicySerializable(policy)); - return try_catch([&] { - if (alias.empty() || rawData.empty()) - return CKM_API_ERROR_INPUT_PARAM; + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE), - my_counter, - static_cast<int>(dataType), - helper.getName(), - helper.getLabel(), - rawData, - PolicySerializable(policy)); + if (CKM_API_SUCCESS != retCode) + return retCode; - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int command; + int counter; + int opType; + recv.Deserialize(command, counter, retCode, opType); - int command; - int counter; - int opType; - recv.Deserialize(command, counter, retCode, opType); + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; + return retCode; - return retCode; - }); + EXCEPTION_GUARD_END } -int Manager::Impl::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) +int Manager::Impl::saveKey(const Alias &alias, const KeyShPtr &key, + const Policy &policy) { - if (key.get() == NULL) - return CKM_API_ERROR_INPUT_PARAM; - Try { - return saveBinaryData(alias, DataType(key->getType()), key->getDER(), policy); - } Catch(DataType::Exception::Base) { - LogError("Error in key conversion. Could not convert KeyType::NONE to DBDataType!"); - } - return CKM_API_ERROR_INPUT_PARAM; + if (key.get() == NULL) + return CKM_API_ERROR_INPUT_PARAM; + + try { + return saveBinaryData(alias, DataType(key->getType()), key->getDER(), policy); + } catch (const DataType::Exception::Base &) { + LogError("Error in key conversion. Could not convert KeyType::NONE to DBDataType!"); + } + + return CKM_API_ERROR_INPUT_PARAM; } int Manager::Impl::saveCertificate( - const Alias &alias, - const CertificateShPtr &cert, - const Policy &policy) + const Alias &alias, + const CertificateShPtr &cert, + const Policy &policy) { - if (cert.get() == NULL) - return CKM_API_ERROR_INPUT_PARAM; - return saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy); + if (cert.get() == NULL) + return CKM_API_ERROR_INPUT_PARAM; + + return saveBinaryData(alias, DataType::CERTIFICATE, cert->getDER(), policy); } -int Manager::Impl::saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy) +int Manager::Impl::saveData(const Alias &alias, const RawBuffer &rawData, + const Policy &policy) { - if (!policy.extractable) - return CKM_API_ERROR_INPUT_PARAM; - return saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy); + if (!policy.extractable) + return CKM_API_ERROR_INPUT_PARAM; + + return saveBinaryData(alias, DataType::BINARY_DATA, rawData, policy); } int Manager::Impl::savePKCS12( - const Alias & alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy) + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy) { - if (alias.empty() || pkcs.get() == NULL) - return CKM_API_ERROR_INPUT_PARAM; + if (alias.empty() || pkcs.get() == NULL) + return CKM_API_ERROR_INPUT_PARAM; + + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::SAVE_PKCS12), + my_counter, + helper.getName(), + helper.getLabel(), + PKCS12Serializable(*pkcs.get()), + PolicySerializable(keyPolicy), + PolicySerializable(certPolicy)); - int my_counter = ++m_counter; + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12), - my_counter, - helper.getName(), - helper.getLabel(), - PKCS12Serializable(*pkcs.get()), - PolicySerializable(keyPolicy), - PolicySerializable(certPolicy)); + if (CKM_API_SUCCESS != retCode) + return retCode; - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int command; + int counter; + recv.Deserialize(command, counter, retCode); - int command; - int counter; - recv.Deserialize(command, counter, retCode); + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; + return retCode; - return retCode; - }); + EXCEPTION_GUARD_END } int Manager::Impl::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs) { - return getPKCS12(alias, Password(), Password(), pkcs); + return getPKCS12(alias, Password(), Password(), pkcs); } -int Manager::Impl::getPKCS12(const Alias &alias, const Password &keyPass, const Password &certPass, PKCS12ShPtr &pkcs) +int Manager::Impl::getPKCS12(const Alias &alias, const Password &keyPass, + const Password &certPass, PKCS12ShPtr &pkcs) { - if (alias.empty()) - return CKM_API_ERROR_INPUT_PARAM; + if (alias.empty()) + return CKM_API_ERROR_INPUT_PARAM; - int my_counter = ++m_counter; + int my_counter = ++m_counter; - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12), - my_counter, - helper.getName(), - helper.getLabel(), - keyPass, - certPass); + EXCEPTION_GUARD_START_CPPAPI - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12), + my_counter, + helper.getName(), + helper.getLabel(), + keyPass, + certPass); - int command; - int counter; - PKCS12Serializable gotPkcs; - recv.Deserialize(command, counter, retCode, gotPkcs); + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; + if (CKM_API_SUCCESS != retCode) + return retCode; - pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs)); + int command; + int counter; + PKCS12Serializable gotPkcs; + recv.Deserialize(command, counter, retCode, gotPkcs); - return retCode; - }); + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; + + pkcs = std::make_shared<PKCS12Impl>(std::move(gotPkcs)); + + return retCode; + + EXCEPTION_GUARD_END } int Manager::Impl::removeAlias(const Alias &alias) { - if (alias.empty()) - return CKM_API_ERROR_INPUT_PARAM; + if (alias.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + int my_counter = ++m_counter; - int my_counter = ++m_counter; + EXCEPTION_GUARD_START_CPPAPI - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE), - my_counter, - helper.getName(), - helper.getLabel()); + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE), + my_counter, + helper.getName(), + helper.getLabel()); - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - int command; - int counter; - recv.Deserialize(command, counter, retCode); + if (CKM_API_SUCCESS != retCode) + return retCode; - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; + int command; + int counter; + recv.Deserialize(command, counter, retCode); - return retCode; - }); + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; + + return retCode; + + EXCEPTION_GUARD_END } int Manager::Impl::getBinaryData( - const Alias &alias, - DataType sendDataType, - const Password &password, - DataType &recvDataType, - RawBuffer &rawData) + const Alias &alias, + DataType sendDataType, + const Password &password, + DataType &recvDataType, + RawBuffer &rawData) { - if (alias.empty()) - return CKM_API_ERROR_INPUT_PARAM; + if (alias.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + int my_counter = ++m_counter; - int my_counter = ++m_counter; + EXCEPTION_GUARD_START_CPPAPI - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET), - my_counter, - static_cast<int>(sendDataType), - helper.getName(), - helper.getLabel(), - password); + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET), + my_counter, + static_cast<int>(sendDataType), + helper.getName(), + helper.getLabel(), + password); - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - int command; - int counter; - int tmpDataType; - recv.Deserialize(command, counter, retCode, tmpDataType, rawData); - recvDataType = DataType(tmpDataType); + if (CKM_API_SUCCESS != retCode) + return retCode; - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; + int command; + int counter; + int tmpDataType; + recv.Deserialize(command, counter, retCode, tmpDataType, rawData); + recvDataType = DataType(tmpDataType); - return retCode; - }); + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; + + return retCode; + + EXCEPTION_GUARD_END } -int Manager::Impl::getKey(const Alias &alias, const Password &password, KeyShPtr &key) +int Manager::Impl::getKey(const Alias &alias, const Password &password, + KeyShPtr &key) { - DataType recvDataType; - RawBuffer rawData; + DataType recvDataType; + RawBuffer rawData; - int retCode = getBinaryData( - alias, - DataType::KEY_RSA_PUBLIC, - password, - recvDataType, - rawData); + int retCode = getBinaryData( + alias, + DataType::KEY_RSA_PUBLIC, + password, + recvDataType, + rawData); - if (retCode != CKM_API_SUCCESS) - return retCode; + if (retCode != CKM_API_SUCCESS) + return retCode; - KeyShPtr keyParsed; - if (DataType::KEY_AES == recvDataType) - keyParsed = KeyShPtr(new KeyAESImpl(rawData)); - else - keyParsed = KeyShPtr(new KeyImpl(rawData)); + KeyShPtr keyParsed; - if (keyParsed->empty()) { - LogDebug("Key empty - failed to parse!"); - return CKM_API_ERROR_BAD_RESPONSE; - } + if (DataType::KEY_AES == recvDataType) + keyParsed = KeyShPtr(new KeyAESImpl(rawData)); + else + keyParsed = KeyShPtr(new KeyImpl(rawData)); - key = keyParsed; + if (keyParsed->empty()) { + LogDebug("Key empty - failed to parse!"); + return CKM_API_ERROR_BAD_RESPONSE; + } - return CKM_API_SUCCESS; + key = keyParsed; + + return CKM_API_SUCCESS; } -int Manager::Impl::getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert) +int Manager::Impl::getCertificate(const Alias &alias, const Password &password, + CertificateShPtr &cert) { - DataType recvDataType; - RawBuffer rawData; + DataType recvDataType; + RawBuffer rawData; - int retCode = getBinaryData( - alias, - DataType::CERTIFICATE, - password, - recvDataType, - rawData); + int retCode = getBinaryData( + alias, + DataType::CERTIFICATE, + password, + recvDataType, + rawData); - if (retCode != CKM_API_SUCCESS) - return retCode; + if (retCode != CKM_API_SUCCESS) + return retCode; - if (recvDataType != DataType::CERTIFICATE) - return CKM_API_ERROR_BAD_RESPONSE; + if (recvDataType != DataType::CERTIFICATE) + return CKM_API_ERROR_BAD_RESPONSE; - CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER)); + CertificateShPtr certParsed(new CertificateImpl(rawData, DataFormat::FORM_DER)); - if (certParsed->empty()) - return CKM_API_ERROR_BAD_RESPONSE; + if (certParsed->empty()) + return CKM_API_ERROR_BAD_RESPONSE; - cert = certParsed; + cert = certParsed; - return CKM_API_SUCCESS; + return CKM_API_SUCCESS; } -int Manager::Impl::getData(const Alias &alias, const Password &password, RawBuffer &rawData) +int Manager::Impl::getData(const Alias &alias, const Password &password, + RawBuffer &rawData) { - DataType recvDataType = DataType::BINARY_DATA; + DataType recvDataType = DataType::BINARY_DATA; - int retCode = getBinaryData( - alias, - DataType::BINARY_DATA, - password, - recvDataType, - rawData); + int retCode = getBinaryData( + alias, + DataType::BINARY_DATA, + password, + recvDataType, + rawData); - if (retCode != CKM_API_SUCCESS) - return retCode; + if (retCode != CKM_API_SUCCESS) + return retCode; - if (recvDataType != DataType::BINARY_DATA) - return CKM_API_ERROR_BAD_RESPONSE; + if (recvDataType != DataType::BINARY_DATA) + return CKM_API_ERROR_BAD_RESPONSE; - return CKM_API_SUCCESS; + return CKM_API_SUCCESS; } -int Manager::Impl::getBinaryDataAliasVector(DataType dataType, AliasVector &aliasVector) +int Manager::Impl::getBinaryDataAliasVector(DataType dataType, + AliasVector &aliasVector) { - int my_counter = ++m_counter; + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST), + my_counter, + static_cast<int>(dataType)); + + int retCode = m_storageConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; - return try_catch([&] { - MessageBuffer recv; - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST), - my_counter, - static_cast<int>(dataType)); + int command; + int counter; + int tmpDataType; + LabelNameVector labelNameVector; + recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector); - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + if ((command != static_cast<int>(LogicCommand::GET_LIST)) || + (counter != my_counter)) + return CKM_API_ERROR_UNKNOWN; - int command; - int counter; - int tmpDataType; - LabelNameVector labelNameVector; - recv.Deserialize(command, counter, retCode, tmpDataType, labelNameVector); - if ((command != static_cast<int>(LogicCommand::GET_LIST)) || (counter != my_counter)) - return CKM_API_ERROR_UNKNOWN; + for (const auto &it : labelNameVector) + aliasVector.push_back(AliasSupport::merge(it.first, it.second)); - for (const auto &it : labelNameVector) - aliasVector.push_back(AliasSupport::merge(it.first, it.second)); + return retCode; - return retCode; - }); + EXCEPTION_GUARD_END } int Manager::Impl::getKeyAliasVector(AliasVector &aliasVector) { - // in fact datatype has no meaning here - if not certificate or binary data - // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST - return getBinaryDataAliasVector(DataType::DB_KEY_LAST, aliasVector); + // in fact datatype has no meaning here - if not certificate or binary data + // then manager decides to list all between DB_KEY_FIRST and DB_KEY_LAST + return getBinaryDataAliasVector(DataType::DB_KEY_LAST, aliasVector); } int Manager::Impl::getCertificateAliasVector(AliasVector &aliasVector) { - return getBinaryDataAliasVector(DataType::CERTIFICATE, aliasVector); + return getBinaryDataAliasVector(DataType::CERTIFICATE, aliasVector); } int Manager::Impl::getDataAliasVector(AliasVector &aliasVector) { - return getBinaryDataAliasVector(DataType::BINARY_DATA, aliasVector); + return getBinaryDataAliasVector(DataType::BINARY_DATA, aliasVector); } int Manager::Impl::createKeyPairRSA( - const int size, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) + const int size, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey); + return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, + publicKeyAlias, policyPrivateKey, policyPublicKey); } int Manager::Impl::createKeyPairDSA( - const int size, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) + const int size, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey); + return this->createKeyPair(CKM::KeyType::KEY_DSA_PUBLIC, size, privateKeyAlias, + publicKeyAlias, policyPrivateKey, policyPublicKey); } int Manager::Impl::createKeyPairECDSA( - ElipticCurve type, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) + ElipticCurve type, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey); + return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, + static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, + policyPublicKey); } int Manager::Impl::createKeyAES( - const int size, - const Alias &keyAlias, - const Policy &policyKey) + const int size, + const Alias &keyAlias, + const Policy &policyKey) { - // proceed with sending request - int my_counter = ++m_counter; + // proceed with sending request + int my_counter = ++m_counter; - return try_catch([&] { - MessageBuffer recv; - AliasSupport aliasHelper(keyAlias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES), - my_counter, - static_cast<int>(size), - PolicySerializable(policyKey), - aliasHelper.getName(), - aliasHelper.getLabel()); + EXCEPTION_GUARD_START_CPPAPI - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + MessageBuffer recv; + AliasSupport aliasHelper(keyAlias); + auto send = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::CREATE_KEY_AES), + my_counter, + static_cast<int>(size), + PolicySerializable(policyKey), + aliasHelper.getName(), + aliasHelper.getLabel()); - int command; - int counter; - recv.Deserialize(command, counter, retCode); - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - return retCode; - }); + if (CKM_API_SUCCESS != retCode) + return retCode; + + int command; + int counter; + recv.Deserialize(command, counter, retCode); + + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; + + return retCode; + + EXCEPTION_GUARD_END } int Manager::Impl::createKeyPair( - const KeyType key_type, - const int additional_param, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) -{ - // input type check - CryptoAlgorithm keyGenAlgorithm; - switch (key_type) { - case KeyType::KEY_RSA_PUBLIC: - case KeyType::KEY_RSA_PRIVATE: - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); - break; - - case KeyType::KEY_DSA_PUBLIC: - case KeyType::KEY_DSA_PRIVATE: - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); - break; - - case KeyType::KEY_ECDSA_PUBLIC: - case KeyType::KEY_ECDSA_PRIVATE: - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param); - break; - - default: - return CKM_API_ERROR_INPUT_PARAM; - } - - // proceed with sending request - int my_counter = ++m_counter; - - return try_catch([&] { - MessageBuffer recv; - AliasSupport privateHelper(privateKeyAlias); - AliasSupport publicHelper(publicKeyAlias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR), - my_counter, - CryptoAlgorithmSerializable(keyGenAlgorithm), - PolicySerializable(policyPrivateKey), - PolicySerializable(policyPublicKey), - privateHelper.getName(), - privateHelper.getLabel(), - publicHelper.getName(), - publicHelper.getLabel()); - - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - int command; - int counter; - recv.Deserialize(command, counter, retCode); - if (counter != my_counter) - return CKM_API_ERROR_UNKNOWN; - - return retCode; - }); + const KeyType key_type, + const int additional_param, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) +{ + // input type check + CryptoAlgorithm keyGenAlgorithm; + + switch (key_type) { + case KeyType::KEY_RSA_PUBLIC: + case KeyType::KEY_RSA_PRIVATE: + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); + break; + + case KeyType::KEY_DSA_PUBLIC: + case KeyType::KEY_DSA_PRIVATE: + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::DSA_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, additional_param); + break; + + case KeyType::KEY_ECDSA_PUBLIC: + case KeyType::KEY_ECDSA_PRIVATE: + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::ECDSA_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_EC, additional_param); + break; + + default: + return CKM_API_ERROR_INPUT_PARAM; + } + + // proceed with sending request + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + AliasSupport privateHelper(privateKeyAlias); + AliasSupport publicHelper(publicKeyAlias); + auto send = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::CREATE_KEY_PAIR), + my_counter, + CryptoAlgorithmSerializable(keyGenAlgorithm), + PolicySerializable(policyPrivateKey), + PolicySerializable(policyPublicKey), + privateHelper.getName(), + privateHelper.getLabel(), + publicHelper.getName(), + publicHelper.getLabel()); + + int retCode = m_storageConnection.processRequest(send.Pop(), recv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + int command; + int counter; + recv.Deserialize(command, counter, retCode); + + if (counter != my_counter) + return CKM_API_ERROR_UNKNOWN; + + return retCode; + + EXCEPTION_GUARD_END } int Manager::Impl::getCertificateChain( - const CertificateShPtr &certificate, - const CertificateShPtrVector &untrustedCertificates, - const CertificateShPtrVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector) + const CertificateShPtr &certificate, + const CertificateShPtrVector &untrustedCertificates, + const CertificateShPtrVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector) { - RawBufferVector untrustedVector; - RawBufferVector trustedVector; + RawBufferVector untrustedVector; + RawBufferVector trustedVector; - if (!certificate || certificate->empty()) - return CKM_API_ERROR_INPUT_PARAM; + if (!certificate || certificate->empty()) + return CKM_API_ERROR_INPUT_PARAM; - for (auto &e: untrustedCertificates) - untrustedVector.push_back(e->getDER()); + for (auto &e : untrustedCertificates) + untrustedVector.push_back(e->getDER()); - for (auto &e: trustedCertificates) - trustedVector.push_back(e->getDER()); + for (auto &e : trustedCertificates) + trustedVector.push_back(e->getDER()); - return getCertChain( - m_storageConnection, - LogicCommand::GET_CHAIN_CERT, - ++m_counter, - certificate, - untrustedVector, - trustedVector, - useTrustedSystemCertificates, - certificateChainVector); + return getCertChain( + m_storageConnection, + LogicCommand::GET_CHAIN_CERT, + ++m_counter, + certificate, + untrustedVector, + trustedVector, + useTrustedSystemCertificates, + certificateChainVector); } int Manager::Impl::getCertificateChain( - const CertificateShPtr &certificate, - const AliasVector &untrustedCertificates, - const AliasVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector) -{ - LabelNameVector untrustedVector; - LabelNameVector trustedVector; - - if (!certificate || certificate->empty()) - return CKM_API_ERROR_INPUT_PARAM; - - for (auto &e: untrustedCertificates) { - AliasSupport helper(e); - untrustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName())); - } - for (auto &e: trustedCertificates) { - AliasSupport helper(e); - trustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName())); - } - - return getCertChain( - m_storageConnection, - LogicCommand::GET_CHAIN_ALIAS, - ++m_counter, - certificate, - untrustedVector, - trustedVector, - useTrustedSystemCertificates, - certificateChainVector); + const CertificateShPtr &certificate, + const AliasVector &untrustedCertificates, + const AliasVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector) +{ + LabelNameVector untrustedVector; + LabelNameVector trustedVector; + + if (!certificate || certificate->empty()) + return CKM_API_ERROR_INPUT_PARAM; + + for (auto &e : untrustedCertificates) { + AliasSupport helper(e); + untrustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName())); + } + + for (auto &e : trustedCertificates) { + AliasSupport helper(e); + trustedVector.push_back(std::make_pair(helper.getLabel(), helper.getName())); + } + + return getCertChain( + m_storageConnection, + LogicCommand::GET_CHAIN_ALIAS, + ++m_counter, + certificate, + untrustedVector, + trustedVector, + useTrustedSystemCertificates, + certificateChainVector); } int Manager::Impl::createSignature( - const Alias &privateKeyAlias, - const Password &password, // password for private_key - const RawBuffer &message, - const CryptoAlgorithm &cAlgorithm, - RawBuffer &signature) + const Alias &privateKeyAlias, + const Password &password, // password for private_key + const RawBuffer &message, + const CryptoAlgorithm &cAlgorithm, + RawBuffer &signature) { - int my_counter = ++m_counter; + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + AliasSupport helper(privateKeyAlias); + auto send = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::CREATE_SIGNATURE), + my_counter, + helper.getName(), + helper.getLabel(), + password, + message, + CryptoAlgorithmSerializable(cAlgorithm)); + + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(privateKeyAlias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE), - my_counter, - helper.getName(), - helper.getLabel(), - password, - message, - CryptoAlgorithmSerializable(cAlgorithm)); + if (CKM_API_SUCCESS != retCode) + return retCode; - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int command; + int counter; + recv.Deserialize(command, counter, retCode, signature); - int command; - int counter; - recv.Deserialize(command, counter, retCode, signature); + if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE)) + || (counter != my_counter)) + return CKM_API_ERROR_UNKNOWN; - if ((command != static_cast<int>(LogicCommand::CREATE_SIGNATURE)) - || (counter != my_counter)) - return CKM_API_ERROR_UNKNOWN; + return retCode; - return retCode; - }); + EXCEPTION_GUARD_END } int Manager::Impl::verifySignature( - const Alias &publicKeyOrCertAlias, - const Password &password, // password for public_key (optional) - const RawBuffer &message, - const RawBuffer &signature, - const CryptoAlgorithm &cAlg) + const Alias &publicKeyOrCertAlias, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const CryptoAlgorithm &cAlg) { - int my_counter = ++m_counter; + int my_counter = ++m_counter; - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(publicKeyOrCertAlias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE), - my_counter, - helper.getName(), - helper.getLabel(), - password, - message, - signature, - CryptoAlgorithmSerializable(cAlg)); + EXCEPTION_GUARD_START_CPPAPI - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + MessageBuffer recv; + AliasSupport helper(publicKeyOrCertAlias); + auto send = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::VERIFY_SIGNATURE), + my_counter, + helper.getName(), + helper.getLabel(), + password, + message, + signature, + CryptoAlgorithmSerializable(cAlg)); - int command; - int counter; - recv.Deserialize(command, counter, retCode); + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE)) - || (counter != my_counter)) - return CKM_API_ERROR_UNKNOWN; + if (CKM_API_SUCCESS != retCode) + return retCode; - return retCode; - }); + int command; + int counter; + recv.Deserialize(command, counter, retCode); + + if ((command != static_cast<int>(LogicCommand::VERIFY_SIGNATURE)) + || (counter != my_counter)) + return CKM_API_ERROR_UNKNOWN; + + return retCode; + + EXCEPTION_GUARD_END } -int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain, int &ocspStatus) +int Manager::Impl::ocspCheck(const CertificateShPtrVector &certChain, + int &ocspStatus) { - return try_catch([&] { - int my_counter = ++m_counter; - MessageBuffer recv; + EXCEPTION_GUARD_START_CPPAPI + + int my_counter = ++m_counter; + MessageBuffer recv; + + RawBufferVector rawCertChain; + + for (auto &e : certChain) { + if (!e || e->empty()) { + LogError("Empty certificate"); + return CKM_API_ERROR_INPUT_PARAM; + } + + rawCertChain.push_back(e->getDER()); + } - RawBufferVector rawCertChain; - for (auto &e: certChain) { - if (!e || e->empty()) { - LogError("Empty certificate"); - return CKM_API_ERROR_INPUT_PARAM; - } - rawCertChain.push_back(e->getDER()); - } + auto send = MessageBuffer::Serialize(my_counter, rawCertChain); - auto send = MessageBuffer::Serialize(my_counter, rawCertChain); + int retCode = m_ocspConnection.processRequest(send.Pop(), recv); - int retCode = m_ocspConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + if (CKM_API_SUCCESS != retCode) + return retCode; - int counter; - recv.Deserialize(counter, retCode, ocspStatus); + int counter; + recv.Deserialize(counter, retCode, ocspStatus); - if (my_counter != counter) - return CKM_API_ERROR_UNKNOWN; + if (my_counter != counter) + return CKM_API_ERROR_UNKNOWN; - return retCode; - }); + return retCode; + + EXCEPTION_GUARD_END } int Manager::Impl::setPermission(const Alias &alias, - const Label &accessor, - PermissionMask permissionMask) + const Label &accessor, + PermissionMask permissionMask) { - int my_counter = ++m_counter; + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + AliasSupport helper(alias); + auto send = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::SET_PERMISSION), + my_counter, + helper.getName(), + helper.getLabel(), + accessor, + permissionMask); + + int retCode = m_storageConnection.processRequest(send.Pop(), recv); - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(alias); - auto send = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SET_PERMISSION), - my_counter, - helper.getName(), - helper.getLabel(), - accessor, - permissionMask); + if (CKM_API_SUCCESS != retCode) + return retCode; - int retCode = m_storageConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int command; + int counter; + recv.Deserialize(command, counter, retCode); - int command; - int counter; - recv.Deserialize(command, counter, retCode); + if (my_counter != counter) + return CKM_API_ERROR_UNKNOWN; - if (my_counter != counter) - return CKM_API_ERROR_UNKNOWN; + return retCode; - return retCode; - }); + EXCEPTION_GUARD_END } int Manager::Impl::crypt(EncryptionCommand command, - const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& input, - RawBuffer& output) + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &input, + RawBuffer &output) { - int my_counter = ++m_counter; + int my_counter = ++m_counter; + + EXCEPTION_GUARD_START_CPPAPI + + MessageBuffer recv; + AliasSupport helper(keyAlias); + CryptoAlgorithmSerializable cas(algo); + auto send = MessageBuffer::Serialize(static_cast<int>(command), + my_counter, + cas, + helper.getName(), + helper.getLabel(), + password, + input); + + int retCode = m_encryptionConnection.processRequest(send.Pop(), recv); - return try_catch([&] { - MessageBuffer recv; - AliasSupport helper(keyAlias); - CryptoAlgorithmSerializable cas(algo); - auto send = MessageBuffer::Serialize(static_cast<int>(command), - my_counter, - cas, - helper.getName(), - helper.getLabel(), - password, - input); + if (CKM_API_SUCCESS != retCode) + return retCode; - int retCode = m_encryptionConnection.processRequest(send.Pop(), recv); - if (CKM_API_SUCCESS != retCode) - return retCode; + int retCommand; + int counter; + recv.Deserialize(retCommand, counter, retCode, output); - int retCommand; - int counter; - recv.Deserialize(retCommand, counter, retCode, output); + if (my_counter != counter || retCommand != static_cast<int>(command)) + return CKM_API_ERROR_UNKNOWN; - if (my_counter != counter || retCommand != static_cast<int>(command)) - return CKM_API_ERROR_UNKNOWN; + return retCode; - return retCode; - }); + EXCEPTION_GUARD_END } int Manager::Impl::encrypt(const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& plain, - RawBuffer& encrypted) + const Alias &keyAlias, + const Password &password, + const RawBuffer &plain, + RawBuffer &encrypted) { - return crypt(EncryptionCommand::ENCRYPT, algo, keyAlias, password, plain, encrypted); + return crypt(EncryptionCommand::ENCRYPT, algo, keyAlias, password, plain, + encrypted); } int Manager::Impl::decrypt(const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& encrypted, - RawBuffer& decrypted) + const Alias &keyAlias, + const Password &password, + const RawBuffer &encrypted, + RawBuffer &decrypted) { - return crypt(EncryptionCommand::DECRYPT, algo, keyAlias, password, encrypted, decrypted); + return crypt(EncryptionCommand::DECRYPT, algo, keyAlias, password, encrypted, + decrypted); } } // namespace CKM diff --git a/src/manager/client/client-manager-impl.h b/src/manager/client/client-manager-impl.h index 98010f9e..ca8a6173 100644 --- a/src/manager/client/client-manager-impl.h +++ b/src/manager/client/client-manager-impl.h @@ -30,138 +30,144 @@ namespace CKM { class Manager::Impl { public: - Impl(); - virtual ~Impl() {} - - int saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy); - int getKey(const Alias &alias, const Password &password, KeyShPtr &key); - int getKeyAliasVector(AliasVector &aliasVector); - - int saveCertificate(const Alias &alias, const CertificateShPtr &cert, const Policy &policy); - int getCertificate(const Alias &alias, const Password &password, CertificateShPtr &cert); - int getCertificateAliasVector(AliasVector &aliasVector); - - int saveData(const Alias &alias, const RawBuffer &rawData, const Policy &policy); - int getData(const Alias &alias, const Password &password, RawBuffer &cert); - int getDataAliasVector(AliasVector &aliasVector); - - int savePKCS12( - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy); - int getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs); - int getPKCS12(const Alias &alias, const Password &keyPass, const Password &certPass, PKCS12ShPtr &pkcs); - - int removeAlias(const Alias &alias); - - int createKeyPairRSA( - const int size, // size in bits [1024, 2048, 4096] - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey = Policy(), - const Policy &policyPublicKey = Policy()); - - int createKeyPairDSA( - const int size, // size in bits [1024, 2048, 3072, 4096] - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey = Policy(), - const Policy &policyPublicKey = Policy()); - - int createKeyPairECDSA( - ElipticCurve type, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey = Policy(), - const Policy &policyPublicKey = Policy()); - - int createKeyAES( - const int size, // size in bits [128, 192, 256] - const Alias &keyAlias, - const Policy &policyKey = Policy()); - - int getCertificateChain( - const CertificateShPtr &certificate, - const CertificateShPtrVector &untrustedCertificates, - const CertificateShPtrVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector); - - int getCertificateChain( - const CertificateShPtr &certificate, - const AliasVector &untrustedCertificates, - const AliasVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector); - - int createSignature( - const Alias &privateKeyAlias, - const Password &password, // password for private_key - const RawBuffer &message, - const CryptoAlgorithm &cAlgorithm, - RawBuffer &signature); - - int verifySignature( - const Alias &publicKeyOrCertAlias, - const Password &password, // password for public_key (optional) - const RawBuffer &message, - const RawBuffer &signature, - const CryptoAlgorithm &cAlgorithm); - - int ocspCheck(const CertificateShPtrVector &certificateChain, int &ocspCheck); - - int setPermission(const Alias &alias, const Label &accessor, PermissionMask permissionMask); - - int encrypt(const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& plain, - RawBuffer& encrypted); - - int decrypt(const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& encrypted, - RawBuffer& decrypted); + Impl(); + virtual ~Impl() {} + + int saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy); + int getKey(const Alias &alias, const Password &password, KeyShPtr &key); + int getKeyAliasVector(AliasVector &aliasVector); + + int saveCertificate(const Alias &alias, const CertificateShPtr &cert, + const Policy &policy); + int getCertificate(const Alias &alias, const Password &password, + CertificateShPtr &cert); + int getCertificateAliasVector(AliasVector &aliasVector); + + int saveData(const Alias &alias, const RawBuffer &rawData, + const Policy &policy); + int getData(const Alias &alias, const Password &password, RawBuffer &cert); + int getDataAliasVector(AliasVector &aliasVector); + + int savePKCS12( + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy); + int getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs); + int getPKCS12(const Alias &alias, const Password &keyPass, + const Password &certPass, PKCS12ShPtr &pkcs); + + int removeAlias(const Alias &alias); + + int createKeyPairRSA( + const int size, // size in bits [1024, 2048, 4096] + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + + int createKeyPairDSA( + const int size, // size in bits [1024, 2048, 3072, 4096] + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + + int createKeyPairECDSA( + ElipticCurve type, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey = Policy(), + const Policy &policyPublicKey = Policy()); + + int createKeyAES( + const int size, // size in bits [128, 192, 256] + const Alias &keyAlias, + const Policy &policyKey = Policy()); + + int getCertificateChain( + const CertificateShPtr &certificate, + const CertificateShPtrVector &untrustedCertificates, + const CertificateShPtrVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector); + + int getCertificateChain( + const CertificateShPtr &certificate, + const AliasVector &untrustedCertificates, + const AliasVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector); + + int createSignature( + const Alias &privateKeyAlias, + const Password &password, // password for private_key + const RawBuffer &message, + const CryptoAlgorithm &cAlgorithm, + RawBuffer &signature); + + int verifySignature( + const Alias &publicKeyOrCertAlias, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const CryptoAlgorithm &cAlgorithm); + + int ocspCheck(const CertificateShPtrVector &certificateChain, int &ocspCheck); + + int setPermission(const Alias &alias, const Label &accessor, + PermissionMask permissionMask); + + int encrypt(const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &plain, + RawBuffer &encrypted); + + int decrypt(const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &encrypted, + RawBuffer &decrypted); protected: - int saveBinaryData( - const Alias &alias, - DataType dataType, - const RawBuffer &rawData, - const Policy &policy); - - int getBinaryData( - const Alias &alias, - DataType sendDataType, - const Password &password, - DataType &recvDataType, - RawBuffer &rawData); - - int getBinaryDataAliasVector( - DataType sendDataType, - AliasVector &aliasVector); - - int createKeyPair( - const KeyType key_type, - const int additional_param, // key size for [RSA|DSA], elliptic curve type for ECDSA - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey); - - int crypt(EncryptionCommand command, - const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& input, - RawBuffer& output); - - int m_counter; - CKM::ServiceConnection m_storageConnection; - CKM::ServiceConnection m_ocspConnection; - CKM::ServiceConnection m_encryptionConnection; + int saveBinaryData( + const Alias &alias, + DataType dataType, + const RawBuffer &rawData, + const Policy &policy); + + int getBinaryData( + const Alias &alias, + DataType sendDataType, + const Password &password, + DataType &recvDataType, + RawBuffer &rawData); + + int getBinaryDataAliasVector( + DataType sendDataType, + AliasVector &aliasVector); + + int createKeyPair( + const KeyType key_type, + const int + additional_param, // key size for [RSA|DSA], elliptic curve type for ECDSA + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey); + + int crypt(EncryptionCommand command, + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &input, + RawBuffer &output); + + int m_counter; + CKM::ServiceConnection m_storageConnection; + CKM::ServiceConnection m_ocspConnection; + CKM::ServiceConnection m_encryptionConnection; }; } // namespace CKM diff --git a/src/manager/client/client-manager.cpp b/src/manager/client/client-manager.cpp index 1e7c8eff..c7f13190 100644 --- a/src/manager/client/client-manager.cpp +++ b/src/manager/client/client-manager.cpp @@ -27,234 +27,242 @@ namespace CKM { Manager::Manager() - : m_impl(new Impl()) + : m_impl(new Impl()) {} Manager::~Manager() {} -int Manager::saveKey(const Alias &alias, const KeyShPtr &key, const Policy &policy) +int Manager::saveKey(const Alias &alias, const KeyShPtr &key, + const Policy &policy) { - return m_impl->saveKey(alias, key, policy); + return m_impl->saveKey(alias, key, policy); } -int Manager::saveCertificate(const Alias &alias, const CertificateShPtr &cert, const Policy &policy) +int Manager::saveCertificate(const Alias &alias, const CertificateShPtr &cert, + const Policy &policy) { - return m_impl->saveCertificate(alias, cert, policy); + return m_impl->saveCertificate(alias, cert, policy); } int Manager::savePKCS12( - const Alias &alias, - const PKCS12ShPtr &pkcs, - const Policy &keyPolicy, - const Policy &certPolicy) + const Alias &alias, + const PKCS12ShPtr &pkcs, + const Policy &keyPolicy, + const Policy &certPolicy) { - return m_impl->savePKCS12(alias, pkcs, keyPolicy, certPolicy); + return m_impl->savePKCS12(alias, pkcs, keyPolicy, certPolicy); } -int Manager::saveData(const Alias &alias, const RawBuffer &data, const Policy &policy) +int Manager::saveData(const Alias &alias, const RawBuffer &data, + const Policy &policy) { - return m_impl->saveData(alias, data, policy); + return m_impl->saveData(alias, data, policy); } int Manager::removeAlias(const Alias &alias) { - return m_impl->removeAlias(alias); + return m_impl->removeAlias(alias); } int Manager::getKey(const Alias &alias, const Password &password, KeyShPtr &key) { - return m_impl->getKey(alias, password, key); + return m_impl->getKey(alias, password, key); } int Manager::getCertificate( - const Alias &alias, - const Password &password, - CertificateShPtr &certificate) + const Alias &alias, + const Password &password, + CertificateShPtr &certificate) { - return m_impl->getCertificate(alias, password, certificate); + return m_impl->getCertificate(alias, password, certificate); } -int Manager::getData(const Alias &alias, const Password &password, RawBuffer &data) +int Manager::getData(const Alias &alias, const Password &password, + RawBuffer &data) { - return m_impl->getData(alias, password, data); + return m_impl->getData(alias, password, data); } int Manager::getPKCS12(const Alias &alias, PKCS12ShPtr &pkcs) { - return m_impl->getPKCS12(alias, pkcs); + return m_impl->getPKCS12(alias, pkcs); } int Manager::getPKCS12( - const Alias &alias, - const Password &keyPass, - const Password &certPass, - PKCS12ShPtr &pkcs) + const Alias &alias, + const Password &keyPass, + const Password &certPass, + PKCS12ShPtr &pkcs) { - return m_impl->getPKCS12(alias, keyPass, certPass, pkcs); + return m_impl->getPKCS12(alias, keyPass, certPass, pkcs); } int Manager::getKeyAliasVector(AliasVector &aliasVector) { - return m_impl->getKeyAliasVector(aliasVector); + return m_impl->getKeyAliasVector(aliasVector); } int Manager::getCertificateAliasVector(AliasVector &aliasVector) { - return m_impl->getCertificateAliasVector(aliasVector); + return m_impl->getCertificateAliasVector(aliasVector); } int Manager::getDataAliasVector(AliasVector &aliasVector) { - return m_impl->getDataAliasVector(aliasVector); + return m_impl->getDataAliasVector(aliasVector); } int Manager::createKeyPairRSA( - const int size, // size in bits [1024, 2048, 4096] - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) + const int size, // size in bits [1024, 2048, 4096] + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - return m_impl->createKeyPairRSA(size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey); + return m_impl->createKeyPairRSA(size, privateKeyAlias, publicKeyAlias, + policyPrivateKey, policyPublicKey); } int Manager::createKeyPairDSA( - const int size, // size in bits [1024, 2048, 3072, 4096] - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) + const int size, // size in bits [1024, 2048, 3072, 4096] + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - return m_impl->createKeyPairDSA(size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey); + return m_impl->createKeyPairDSA(size, privateKeyAlias, publicKeyAlias, + policyPrivateKey, policyPublicKey); } int Manager::createKeyPairECDSA( - const ElipticCurve type, - const Alias &privateKeyAlias, - const Alias &publicKeyAlias, - const Policy &policyPrivateKey, - const Policy &policyPublicKey) + const ElipticCurve type, + const Alias &privateKeyAlias, + const Alias &publicKeyAlias, + const Policy &policyPrivateKey, + const Policy &policyPublicKey) { - return m_impl->createKeyPairECDSA(type, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey); + return m_impl->createKeyPairECDSA(type, privateKeyAlias, publicKeyAlias, + policyPrivateKey, policyPublicKey); } int Manager::createKeyAES( - const int size, - const Alias &keyAlias, - const Policy &policyKey) + const int size, + const Alias &keyAlias, + const Policy &policyKey) { - return m_impl->createKeyAES(size, keyAlias, policyKey); + return m_impl->createKeyAES(size, keyAlias, policyKey); } int Manager::getCertificateChain( - const CertificateShPtr &certificate, - const CertificateShPtrVector &untrustedCertificates, - const CertificateShPtrVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector) + const CertificateShPtr &certificate, + const CertificateShPtrVector &untrustedCertificates, + const CertificateShPtrVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector) { - return m_impl->getCertificateChain( - certificate, - untrustedCertificates, - trustedCertificates, - useTrustedSystemCertificates, - certificateChainVector); + return m_impl->getCertificateChain( + certificate, + untrustedCertificates, + trustedCertificates, + useTrustedSystemCertificates, + certificateChainVector); } int Manager::getCertificateChain( - const CertificateShPtr &certificate, - const AliasVector &untrustedCertificates, - const AliasVector &trustedCertificates, - bool useTrustedSystemCertificates, - CertificateShPtrVector &certificateChainVector) + const CertificateShPtr &certificate, + const AliasVector &untrustedCertificates, + const AliasVector &trustedCertificates, + bool useTrustedSystemCertificates, + CertificateShPtrVector &certificateChainVector) { - return m_impl->getCertificateChain( - certificate, - untrustedCertificates, - trustedCertificates, - useTrustedSystemCertificates, - certificateChainVector); + return m_impl->getCertificateChain( + certificate, + untrustedCertificates, + trustedCertificates, + useTrustedSystemCertificates, + certificateChainVector); } int Manager::createSignature( - const Alias &privateKeyAlias, - const Password &password, - const RawBuffer &message, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding, - RawBuffer &signature) + const Alias &privateKeyAlias, + const Password &password, + const RawBuffer &message, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding, + RawBuffer &signature) { - CryptoAlgorithm cAlg; - cAlg.setParam(ParamName::SV_HASH_ALGO, hash); - cAlg.setParam(ParamName::SV_RSA_PADDING, padding); - return m_impl->createSignature( - privateKeyAlias, - password, - message, - cAlg, - signature); + CryptoAlgorithm cAlg; + cAlg.setParam(ParamName::SV_HASH_ALGO, hash); + cAlg.setParam(ParamName::SV_RSA_PADDING, padding); + return m_impl->createSignature( + privateKeyAlias, + password, + message, + cAlg, + signature); } int Manager::verifySignature( - const Alias &publicKeyOrCertAlias, - const Password &password, // password for public_key (optional) - const RawBuffer &message, - const RawBuffer &signature, - const HashAlgorithm hash, - const RSAPaddingAlgorithm padding) + const Alias &publicKeyOrCertAlias, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const HashAlgorithm hash, + const RSAPaddingAlgorithm padding) { - CryptoAlgorithm cAlg; - cAlg.setParam(ParamName::SV_HASH_ALGO, hash); - cAlg.setParam(ParamName::SV_RSA_PADDING, padding); - return m_impl->verifySignature( - publicKeyOrCertAlias, - password, - message, - signature, - cAlg); + CryptoAlgorithm cAlg; + cAlg.setParam(ParamName::SV_HASH_ALGO, hash); + cAlg.setParam(ParamName::SV_RSA_PADDING, padding); + return m_impl->verifySignature( + publicKeyOrCertAlias, + password, + message, + signature, + cAlg); } -int Manager::ocspCheck(const CertificateShPtrVector &certificateChainVector, int &ocspStatus) +int Manager::ocspCheck(const CertificateShPtrVector &certificateChainVector, + int &ocspStatus) { - return m_impl->ocspCheck(certificateChainVector, ocspStatus); + return m_impl->ocspCheck(certificateChainVector, ocspStatus); } int Manager::setPermission( - const Alias &alias, - const Label &accessor, - PermissionMask permissionMask) + const Alias &alias, + const Label &accessor, + PermissionMask permissionMask) { - return m_impl->setPermission(alias, accessor, permissionMask); + return m_impl->setPermission(alias, accessor, permissionMask); } int Manager::encrypt( - const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& plain, - RawBuffer& encrypted) + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &plain, + RawBuffer &encrypted) { - return m_impl->encrypt(algo, keyAlias, password, plain, encrypted); + return m_impl->encrypt(algo, keyAlias, password, plain, encrypted); } int Manager::decrypt( - const CryptoAlgorithm &algo, - const Alias &keyAlias, - const Password &password, - const RawBuffer& encrypted, - RawBuffer& decrypted) + const CryptoAlgorithm &algo, + const Alias &keyAlias, + const Password &password, + const RawBuffer &encrypted, + RawBuffer &decrypted) { - return m_impl->decrypt(algo, keyAlias, password, encrypted, decrypted); + return m_impl->decrypt(algo, keyAlias, password, encrypted, decrypted); } ManagerShPtr Manager::create() { - try { - return std::make_shared<Manager>(); - } catch (...) { - LogError("Exception occured in Manager::create"); - throw; - } + try { + return std::make_shared<Manager>(); + } catch (...) { + LogError("Exception occured in Manager::create"); + throw; + } } } // namespace CKM diff --git a/src/manager/common/algo-param.cpp b/src/manager/common/algo-param.cpp index 9f8f4a65..52102618 100644 --- a/src/manager/common/algo-param.cpp +++ b/src/manager/common/algo-param.cpp @@ -24,46 +24,49 @@ namespace CKM { -bool CryptoAlgorithm::BufferParam::getBuffer(RawBuffer& buffer) const +bool CryptoAlgorithm::BufferParam::getBuffer(RawBuffer &buffer) const { - buffer = m_buffer; - return true; + buffer = m_buffer; + return true; } -CryptoAlgorithm::BaseParamPtr CryptoAlgorithm::BufferParam::create(const RawBuffer& buffer) +CryptoAlgorithm::BaseParamPtr CryptoAlgorithm::BufferParam::create( + const RawBuffer &buffer) { - return BaseParamPtr(new CryptoAlgorithm::BufferParam(buffer)); + return BaseParamPtr(new CryptoAlgorithm::BufferParam(buffer)); } -bool CryptoAlgorithm::IntParam::getInt(uint64_t& value) const +bool CryptoAlgorithm::IntParam::getInt(uint64_t &value) const { - value = m_int; - return true; + value = m_int; + return true; } CryptoAlgorithm::BaseParamPtr CryptoAlgorithm::IntParam::create(uint64_t value) { - return BaseParamPtr(new CryptoAlgorithm::IntParam(value)); + return BaseParamPtr(new CryptoAlgorithm::IntParam(value)); } template <> -bool CryptoAlgorithm::getParam(ParamName name, RawBuffer& value) const +bool CryptoAlgorithm::getParam(ParamName name, RawBuffer &value) const { - auto param = m_params.find(name); - if (param == m_params.end()) - return false; + auto param = m_params.find(name); - assert(param->second); - return param->second->getBuffer(value); + if (param == m_params.end()) + return false; + + assert(param->second); + return param->second->getBuffer(value); } template <> -bool CryptoAlgorithm::setParam(ParamName name, const RawBuffer& value) +bool CryptoAlgorithm::setParam(ParamName name, const RawBuffer &value) { - if (name < ParamName::FIRST || name > ParamName::LAST) - return false; - m_params[name] = BufferParam::create(value); - return true; + if (name < ParamName::FIRST || name > ParamName::LAST) + return false; + + m_params[name] = BufferParam::create(value); + return true; } } // namespace CKM diff --git a/src/manager/common/base64.cpp b/src/manager/common/base64.cpp index 47ad1e9d..1e37998d 100644 --- a/src/manager/common/base64.cpp +++ b/src/manager/common/base64.cpp @@ -28,184 +28,193 @@ namespace CKM { Base64Encoder::Base64Encoder() : - m_b64(0), - m_bmem(0), - m_finalized(false) + m_b64(0), + m_bmem(0), + m_finalized(false) { } void Base64Encoder::append(const RawBuffer &data) { - if (m_finalized) { - LogWarning("Already finalized."); - ThrowMsg(Exception::AlreadyFinalized, "Already finalized"); - } + if (m_finalized) { + LogWarning("Already finalized."); + ThrowMsg(Exception::AlreadyFinalized, "Already finalized"); + } - if (!m_b64) - reset(); + if (!m_b64) + reset(); - BIO_write(m_b64, data.data(), data.size()); + BIO_write(m_b64, data.data(), data.size()); } void Base64Encoder::finalize() { - if (m_finalized) { - LogWarning("Already finalized."); - ThrowMsg(Exception::AlreadyFinalized, "Already finalized."); - } - m_finalized = true; - (void)BIO_flush(m_b64); + if (m_finalized) { + LogWarning("Already finalized."); + ThrowMsg(Exception::AlreadyFinalized, "Already finalized."); + } + + m_finalized = true; + (void)BIO_flush(m_b64); } RawBuffer Base64Encoder::get() { - if (!m_finalized) { - LogWarning("Not finalized"); - ThrowMsg(Exception::NotFinalized, "Not finalized"); - } - BUF_MEM *bptr = nullptr; - BIO_get_mem_ptr(m_b64, &bptr); - if (!bptr) { - LogError("Bio internal error"); - ThrowMsg(Exception::InternalError, "Bio internal error"); - } - - if (bptr->length > 0) - return RawBuffer(bptr->data, bptr->data + bptr->length); - - return RawBuffer(); + if (!m_finalized) { + LogWarning("Not finalized"); + ThrowMsg(Exception::NotFinalized, "Not finalized"); + } + + BUF_MEM *bptr = nullptr; + BIO_get_mem_ptr(m_b64, &bptr); + + if (!bptr) { + LogError("Bio internal error"); + ThrowMsg(Exception::InternalError, "Bio internal error"); + } + + if (bptr->length > 0) + return RawBuffer(bptr->data, bptr->data + bptr->length); + + return RawBuffer(); } void Base64Encoder::reset() { - m_finalized = false; - BIO_free_all(m_b64); - m_b64 = BIO_new(BIO_f_base64()); - m_bmem = BIO_new(BIO_s_mem()); - if (!m_b64 || !m_bmem) { - LogError("Error during allocation memory in BIO"); - ThrowMsg(Exception::InternalError, - "Error during allocation memory in BIO"); - } - BIO_set_flags(m_b64, BIO_FLAGS_BASE64_NO_NL); - m_b64 = BIO_push(m_b64, m_bmem); + m_finalized = false; + BIO_free_all(m_b64); + m_b64 = BIO_new(BIO_f_base64()); + m_bmem = BIO_new(BIO_s_mem()); + + if (!m_b64 || !m_bmem) { + LogError("Error during allocation memory in BIO"); + ThrowMsg(Exception::InternalError, + "Error during allocation memory in BIO"); + } + + BIO_set_flags(m_b64, BIO_FLAGS_BASE64_NO_NL); + m_b64 = BIO_push(m_b64, m_bmem); } Base64Encoder::~Base64Encoder() { - BIO_free_all(m_b64); + BIO_free_all(m_b64); } Base64Decoder::Base64Decoder() : - m_finalized(false) + m_finalized(false) { } void Base64Decoder::append(const RawBuffer &data) { - if (m_finalized) { - LogWarning("Already finalized."); - ThrowMsg(Exception::AlreadyFinalized, "Already finalized."); - } - std::copy(data.begin(), data.end(), std::back_inserter(m_input)); + if (m_finalized) { + LogWarning("Already finalized."); + ThrowMsg(Exception::AlreadyFinalized, "Already finalized."); + } + + std::copy(data.begin(), data.end(), std::back_inserter(m_input)); } static bool whiteCharacter(char a) { - return a == '\n'; + return a == '\n'; } bool Base64Decoder::finalize() { - if (m_finalized) { - LogWarning("Already finalized."); - ThrowMsg(Exception::AlreadyFinalized, "Already finalized."); - } - - m_finalized = true; - - m_input.erase(std::remove_if(m_input.begin(), - m_input.end(), - whiteCharacter), - m_input.end()); - - for (size_t i = 0; i < m_input.size(); ++i) { - if (isalnum(m_input[i]) - || m_input[i] == '+' - || m_input[i] == '/' - || m_input[i] == '=') - continue; - - LogError("Base64 input contains illegal chars: " << m_input[i]); - return false; - } - - BIO *b64, *bmem; - size_t len = m_input.size(); - - RawBuffer buffer(len); - - if (!buffer.data()) { - LogError("Error in malloc."); - ThrowMsg(Exception::InternalError, "Error in malloc."); - } - - memset(buffer.data(), 0, buffer.size()); - b64 = BIO_new(BIO_f_base64()); - if (!b64) { - LogError("Couldn't create BIO object."); - ThrowMsg(Exception::InternalError, "Couldn't create BIO object."); - } - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - RawBuffer tmp(m_input); - m_input.clear(); - - bmem = BIO_new_mem_buf(tmp.data(), len); - - if (!bmem) { - BIO_free(b64); - LogError("Internal error in BIO"); - ThrowMsg(Exception::InternalError, "Internal error in BIO"); - } - - bmem = BIO_push(b64, bmem); - - if (!bmem) { - BIO_free(b64); - LogError("Internal error in BIO"); - ThrowMsg(Exception::InternalError, "Internal error in BIO"); - } - - int readlen = BIO_read(bmem, buffer.data(), buffer.size()); - m_output.clear(); - - bool status = true; - - if (readlen > 0) { - buffer.resize(readlen); - m_output = std::move(buffer); - } else { - status = false; - } - - BIO_free_all(bmem); - return status; + if (m_finalized) { + LogWarning("Already finalized."); + ThrowMsg(Exception::AlreadyFinalized, "Already finalized."); + } + + m_finalized = true; + + m_input.erase(std::remove_if(m_input.begin(), + m_input.end(), + whiteCharacter), + m_input.end()); + + for (size_t i = 0; i < m_input.size(); ++i) { + if (isalnum(m_input[i]) + || m_input[i] == '+' + || m_input[i] == '/' + || m_input[i] == '=') + continue; + + LogError("Base64 input contains illegal chars: " << m_input[i]); + return false; + } + + BIO *b64, *bmem; + size_t len = m_input.size(); + + RawBuffer buffer(len); + + if (!buffer.data()) { + LogError("Error in malloc."); + ThrowMsg(Exception::InternalError, "Error in malloc."); + } + + memset(buffer.data(), 0, buffer.size()); + b64 = BIO_new(BIO_f_base64()); + + if (!b64) { + LogError("Couldn't create BIO object."); + ThrowMsg(Exception::InternalError, "Couldn't create BIO object."); + } + + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + RawBuffer tmp(m_input); + m_input.clear(); + + bmem = BIO_new_mem_buf(tmp.data(), len); + + if (!bmem) { + BIO_free(b64); + LogError("Internal error in BIO"); + ThrowMsg(Exception::InternalError, "Internal error in BIO"); + } + + bmem = BIO_push(b64, bmem); + + if (!bmem) { + BIO_free(b64); + LogError("Internal error in BIO"); + ThrowMsg(Exception::InternalError, "Internal error in BIO"); + } + + int readlen = BIO_read(bmem, buffer.data(), buffer.size()); + m_output.clear(); + + bool status = true; + + if (readlen > 0) { + buffer.resize(readlen); + m_output = std::move(buffer); + } else { + status = false; + } + + BIO_free_all(bmem); + return status; } RawBuffer Base64Decoder::get() const { - if (!m_finalized) { - LogWarning("Not finalized."); - ThrowMsg(Exception::NotFinalized, "Not finalized"); - } - return m_output; + if (!m_finalized) { + LogWarning("Not finalized."); + ThrowMsg(Exception::NotFinalized, "Not finalized"); + } + + return m_output; } void Base64Decoder::reset() { - m_finalized = false; - m_input.clear(); - m_output.clear(); + m_finalized = false; + m_input.clear(); + m_output.clear(); } } // namespace CKM diff --git a/src/manager/common/base64.h b/src/manager/common/base64.h index 8a69c626..228285ec 100644 --- a/src/manager/common/base64.h +++ b/src/manager/common/base64.h @@ -29,58 +29,56 @@ typedef bio_st BIO; namespace CKM { class COMMON_API Base64Encoder { - public: - NONCOPYABLE(Base64Encoder) +public: + NONCOPYABLE(Base64Encoder) - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, InternalError) - DECLARE_EXCEPTION_TYPE(Base, NotFinalized) - DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized) - }; - Base64Encoder(); - void append(const RawBuffer &data); - void finalize(); - RawBuffer get(); - void reset(); - ~Base64Encoder(); + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InternalError) + DECLARE_EXCEPTION_TYPE(Base, NotFinalized) + DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized) + }; + Base64Encoder(); + void append(const RawBuffer &data); + void finalize(); + RawBuffer get(); + void reset(); + ~Base64Encoder(); - private: - BIO *m_b64; - BIO *m_bmem; - bool m_finalized; +private: + BIO *m_b64; + BIO *m_bmem; + bool m_finalized; }; class COMMON_API Base64Decoder { - public: - NONCOPYABLE(Base64Decoder) +public: + NONCOPYABLE(Base64Decoder) - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, InternalError) - DECLARE_EXCEPTION_TYPE(Base, NotFinalized) - DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized) - }; - Base64Decoder(); - void append(const RawBuffer &data); + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InternalError) + DECLARE_EXCEPTION_TYPE(Base, NotFinalized) + DECLARE_EXCEPTION_TYPE(Base, AlreadyFinalized) + }; + Base64Decoder(); + void append(const RawBuffer &data); - /* - * Function will return false when BIO_read fails - * (for example: when string was not in base64 format). - */ - bool finalize(); - RawBuffer get() const; - void reset(); - ~Base64Decoder() - { - } + /* + * Function will return false when BIO_read fails + * (for example: when string was not in base64 format). + */ + bool finalize(); + RawBuffer get() const; + void reset(); + ~Base64Decoder() {} - private: - RawBuffer m_input; - RawBuffer m_output; - bool m_finalized; +private: + RawBuffer m_input; + RawBuffer m_output; + bool m_finalized; }; } // namespace CKM diff --git a/src/manager/common/certificate-impl.cpp b/src/manager/common/certificate-impl.cpp index bce2daa4..ea652ba5 100644 --- a/src/manager/common/certificate-impl.cpp +++ b/src/manager/common/certificate-impl.cpp @@ -31,133 +31,140 @@ namespace CKM { CertificateImpl::CertificateImpl(const RawBuffer &der, DataFormat format) - : m_x509(nullptr) + : m_x509(nullptr) { - LogDebug("Certificate to parse. Size: " << der.size()); - - if (DataFormat::FORM_DER_BASE64 == format) { - Base64Decoder base64; - base64.reset(); - base64.append(der); - base64.finalize(); - auto tmp = base64.get(); - auto ptr = reinterpret_cast<const unsigned char *>(tmp.data()); - auto size = static_cast<int>(tmp.size()); - m_x509 = d2i_X509(nullptr, &ptr, size); - } else if (DataFormat::FORM_DER == format) { - auto ptr = reinterpret_cast<const unsigned char *>(der.data()); - auto size = static_cast<int>(der.size()); - m_x509 = d2i_X509(nullptr, &ptr, size); - } else if (DataFormat::FORM_PEM == format) { - auto buff = BIO_new(BIO_s_mem()); - BIO_write(buff, der.data(), der.size()); - m_x509 = PEM_read_bio_X509(buff, nullptr, nullptr, nullptr); - BIO_free_all(buff); - } else { - // TODO - LogError("Unknown certificate format"); - } - - if (!m_x509) { - // TODO - LogError("Certificate could not be parsed."); -// ThrowMsg(Exception::OpensslInternalError, -// "Internal Openssl error in d2i_X509 function."); - } + LogDebug("Certificate to parse. Size: " << der.size()); + + if (DataFormat::FORM_DER_BASE64 == format) { + Base64Decoder base64; + base64.reset(); + base64.append(der); + base64.finalize(); + auto tmp = base64.get(); + auto ptr = reinterpret_cast<const unsigned char *>(tmp.data()); + auto size = static_cast<int>(tmp.size()); + m_x509 = d2i_X509(nullptr, &ptr, size); + } else if (DataFormat::FORM_DER == format) { + auto ptr = reinterpret_cast<const unsigned char *>(der.data()); + auto size = static_cast<int>(der.size()); + m_x509 = d2i_X509(nullptr, &ptr, size); + } else if (DataFormat::FORM_PEM == format) { + auto buff = BIO_new(BIO_s_mem()); + BIO_write(buff, der.data(), der.size()); + m_x509 = PEM_read_bio_X509(buff, nullptr, nullptr, nullptr); + BIO_free_all(buff); + } else { + // TODO + LogError("Unknown certificate format"); + } + + if (!m_x509) { + // TODO + LogError("Certificate could not be parsed."); + // ThrowMsg(Exception::OpensslInternalError, + // "Internal Openssl error in d2i_X509 function."); + } } CertificateImpl::CertificateImpl(X509 *x509, bool duplicate) { - if (duplicate) - m_x509 = X509_dup(x509); - else - m_x509 = x509; + if (duplicate) + m_x509 = X509_dup(x509); + else + m_x509 = x509; } CertificateImpl::CertificateImpl(CertificateImpl &&second) { - m_x509 = second.m_x509; - second.m_x509 = nullptr; - LogDebug("Certificate moved: " << (void*)m_x509); + m_x509 = second.m_x509; + second.m_x509 = nullptr; + LogDebug("Certificate moved: " << (void *)m_x509); } -CertificateImpl& CertificateImpl::operator=(CertificateImpl &&second) +CertificateImpl &CertificateImpl::operator=(CertificateImpl &&second) { - if (this == &second) - return *this; - if (m_x509) - X509_free(m_x509); - m_x509 = second.m_x509; - second.m_x509 = nullptr; - LogDebug("Certificate moved: " << (void*)m_x509); - return *this; + if (this == &second) + return *this; + + if (m_x509) + X509_free(m_x509); + + m_x509 = second.m_x509; + second.m_x509 = nullptr; + LogDebug("Certificate moved: " << (void *)m_x509); + return *this; } -X509* CertificateImpl::getX509() const +X509 *CertificateImpl::getX509() const { - return m_x509; + return m_x509; } RawBuffer CertificateImpl::getDER(void) const { - unsigned char *rawDer = nullptr; - int size = i2d_X509(m_x509, &rawDer); - if (!rawDer || size <= 0) { - LogError("i2d_X509 failed"); - return RawBuffer(); - } - - RawBuffer output( - reinterpret_cast<char*>(rawDer), - reinterpret_cast<char*>(rawDer) + size); - OPENSSL_free(rawDer); - return output; + unsigned char *rawDer = nullptr; + int size = i2d_X509(m_x509, &rawDer); + + if (!rawDer || size <= 0) { + LogError("i2d_X509 failed"); + return RawBuffer(); + } + + RawBuffer output( + reinterpret_cast<char *>(rawDer), + reinterpret_cast<char *>(rawDer) + size); + OPENSSL_free(rawDer); + return output; } bool CertificateImpl::empty() const { - return m_x509 == nullptr; + return m_x509 == nullptr; } KeyImpl::EvpShPtr CertificateImpl::getEvpShPtr() const { - return KeyImpl::EvpShPtr(X509_get_pubkey(m_x509), EVP_PKEY_free); + return KeyImpl::EvpShPtr(X509_get_pubkey(m_x509), EVP_PKEY_free); } std::string CertificateImpl::getOCSPURL() const { - if (!m_x509) - return std::string(); + if (!m_x509) + return std::string(); - STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509); + STACK_OF(OPENSSL_STRING) *aia = X509_get1_ocsp(m_x509); - if (nullptr == aia) - return std::string(); + if (nullptr == aia) + return std::string(); - std::string result(sk_OPENSSL_STRING_value(aia, 0)); - X509_email_free(aia); // TODO is it correct? - return result; + std::string result(sk_OPENSSL_STRING_value(aia, 0)); + X509_email_free(aia); // TODO is it correct? + return result; } CertificateImpl::~CertificateImpl() { - if (m_x509) - X509_free(m_x509); + if (m_x509) + X509_free(m_x509); } -CertificateShPtr Certificate::create(const RawBuffer &rawBuffer, DataFormat format) +CertificateShPtr Certificate::create(const RawBuffer &rawBuffer, + DataFormat format) { - try { - CertificateShPtr output = std::make_shared<CertificateImpl>(rawBuffer, format); - if (output->empty()) - output.reset(); - return output; - } catch (const std::bad_alloc &) { - LogDebug("Bad alloc was caught during CertificateImpl creation"); - } catch (...) { - LogError("Critical error: Unknown exception was caught during CertificateImpl creation!"); - } - return CertificateShPtr(); + try { + CertificateShPtr output = std::make_shared<CertificateImpl>(rawBuffer, format); + + if (output->empty()) + output.reset(); + + return output; + } catch (const std::bad_alloc &) { + LogDebug("Bad alloc was caught during CertificateImpl creation"); + } catch (...) { + LogError("Critical error: Unknown exception was caught during CertificateImpl creation!"); + } + + return CertificateShPtr(); } } // namespace CKM diff --git a/src/manager/common/certificate-impl.h b/src/manager/common/certificate-impl.h index b30d97f3..f9d544a7 100644 --- a/src/manager/common/certificate-impl.h +++ b/src/manager/common/certificate-impl.h @@ -33,27 +33,27 @@ namespace CKM { class COMMON_API CertificateImpl : public Certificate { public: - CertificateImpl() : m_x509(nullptr) {} - explicit CertificateImpl(X509* x509, bool duplicate = true); - CertificateImpl(const RawBuffer &data, DataFormat format); + CertificateImpl() : m_x509(nullptr) {} + explicit CertificateImpl(X509 *x509, bool duplicate = true); + CertificateImpl(const RawBuffer &data, DataFormat format); - CertificateImpl(const CertificateImpl &) = delete; - CertificateImpl &operator=(const CertificateImpl &) = delete; + CertificateImpl(const CertificateImpl &) = delete; + CertificateImpl &operator=(const CertificateImpl &) = delete; - CertificateImpl(CertificateImpl &&); - CertificateImpl& operator=(CertificateImpl &&); + CertificateImpl(CertificateImpl &&); + CertificateImpl &operator=(CertificateImpl &&); - virtual RawBuffer getDER() const; - virtual bool empty() const; - virtual X509* getX509() const; + virtual RawBuffer getDER() const; + virtual bool empty() const; + virtual X509 *getX509() const; - KeyImpl::EvpShPtr getEvpShPtr() const; - std::string getOCSPURL() const; + KeyImpl::EvpShPtr getEvpShPtr() const; + std::string getOCSPURL() const; - virtual ~CertificateImpl(); + virtual ~CertificateImpl(); protected: - X509* m_x509; + X509 *m_x509; }; typedef std::vector<CertificateImpl> CertificateImplVector; diff --git a/src/manager/common/connection-info.h b/src/manager/common/connection-info.h index c0ea3ad3..044c6cbe 100644 --- a/src/manager/common/connection-info.h +++ b/src/manager/common/connection-info.h @@ -31,14 +31,14 @@ #include <message-buffer.h> namespace CKM { - struct ConnectionInfo { - InterfaceID interfaceID; - MessageBuffer buffer; - Credentials credentials; - bool checkInProgress; - }; +struct ConnectionInfo { + InterfaceID interfaceID; + MessageBuffer buffer; + Credentials credentials; + bool checkInProgress; +}; - typedef std::map<int, ConnectionInfo> ConnectionInfoMap; +typedef std::map<int, ConnectionInfo> ConnectionInfoMap; } //namespace CKM #endif //_CONNECTION_INFO_H_ diff --git a/src/manager/common/crypto-init.cpp b/src/manager/common/crypto-init.cpp index 37fea8a0..99822997 100644 --- a/src/manager/common/crypto-init.cpp +++ b/src/manager/common/crypto-init.cpp @@ -39,46 +39,46 @@ namespace CKM { namespace { -const char* DEV_HW_RANDOM_FILE = "/dev/hwrng"; -const char* DEV_URANDOM_FILE = "/dev/urandom"; +const char *DEV_HW_RANDOM_FILE = "/dev/hwrng"; +const char *DEV_URANDOM_FILE = "/dev/urandom"; const size_t RANDOM_BUFFER_LEN = 32; -std::mutex* g_mutexes = NULL; +std::mutex *g_mutexes = NULL; -void lockingCallback(int mode, int type, const char*, int) +void lockingCallback(int mode, int type, const char *, int) { - if (!g_mutexes) { - LogError("Openssl mutexes do not exist"); - return; - } - - if (mode & CRYPTO_LOCK) - g_mutexes[type].lock(); - else if (mode & CRYPTO_UNLOCK) - g_mutexes[type].unlock(); + if (!g_mutexes) { + LogError("Openssl mutexes do not exist"); + return; + } + + if (mode & CRYPTO_LOCK) + g_mutexes[type].lock(); + else if (mode & CRYPTO_UNLOCK) + g_mutexes[type].unlock(); } unsigned long threadIdCallback() { - std::hash<std::thread::id> hasher; - return hasher(std::this_thread::get_id()); + std::hash<std::thread::id> hasher; + return hasher(std::this_thread::get_id()); } void opensslInstallLocks() { - g_mutexes = new std::mutex[CRYPTO_num_locks()]; + g_mutexes = new std::mutex[CRYPTO_num_locks()]; - CRYPTO_set_id_callback(threadIdCallback); - CRYPTO_set_locking_callback(lockingCallback); + CRYPTO_set_id_callback(threadIdCallback); + CRYPTO_set_locking_callback(lockingCallback); } void opensslUninstallLocks() { - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); - delete[] g_mutexes; - g_mutexes = NULL; + delete[] g_mutexes; + g_mutexes = NULL; } } // namespace anonymous @@ -86,64 +86,65 @@ void opensslUninstallLocks() void initOpenSsl() { - // Loads all error strings (crypto and ssl) - SSL_load_error_strings(); - - /* - * Initialize libcrypto (add all algorithms, digests & ciphers) - * It also does the stuff from SSL_library_init() except for ssl_load_ciphers() - */ - OpenSSL_add_all_algorithms(); // Can be optimized by using EVP_add_cipher instead - - /* - * Initialize libssl (OCSP uses it) - * SSL_library_init() == OpenSSL_add_ssl_algorithms() - * It always returns 1 - */ - SSL_library_init(); - - // load default configuration (/etc/ssl/openssl.cnf) - OPENSSL_config(NULL); - - // enable FIPS mode by default - if (0 == FIPS_mode_set(1)) - LogWarning("Failed to set FIPS mode. Key-manager will be operated in non FIPS mode."); - - /* - * Initialize entropy - * entropy sources - /dev/random,/dev/urandom(Default) - */ - int ret = 0; - - std::ifstream ifile(DEV_HW_RANDOM_FILE); - if (ifile.is_open()) - ret = RAND_load_file(DEV_HW_RANDOM_FILE, RANDOM_BUFFER_LEN); - - if (ret != RANDOM_BUFFER_LEN) { - LogWarning("Error in HW_RAND file load"); - ret = RAND_load_file(DEV_URANDOM_FILE, RANDOM_BUFFER_LEN); - - if (ret != RANDOM_BUFFER_LEN) - LogError("Error in U_RAND_file_load"); - } - - // Install locks for multithreading support - opensslInstallLocks(); + // Loads all error strings (crypto and ssl) + SSL_load_error_strings(); + + /* + * Initialize libcrypto (add all algorithms, digests & ciphers) + * It also does the stuff from SSL_library_init() except for ssl_load_ciphers() + */ + OpenSSL_add_all_algorithms(); // Can be optimized by using EVP_add_cipher instead + + /* + * Initialize libssl (OCSP uses it) + * SSL_library_init() == OpenSSL_add_ssl_algorithms() + * It always returns 1 + */ + SSL_library_init(); + + // load default configuration (/etc/ssl/openssl.cnf) + OPENSSL_config(NULL); + + // enable FIPS mode by default + if (0 == FIPS_mode_set(1)) + LogWarning("Failed to set FIPS mode. Key-manager will be operated in non FIPS mode."); + + /* + * Initialize entropy + * entropy sources - /dev/random,/dev/urandom(Default) + */ + int ret = 0; + + std::ifstream ifile(DEV_HW_RANDOM_FILE); + + if (ifile.is_open()) + ret = RAND_load_file(DEV_HW_RANDOM_FILE, RANDOM_BUFFER_LEN); + + if (ret != RANDOM_BUFFER_LEN) { + LogWarning("Error in HW_RAND file load"); + ret = RAND_load_file(DEV_URANDOM_FILE, RANDOM_BUFFER_LEN); + + if (ret != RANDOM_BUFFER_LEN) + LogError("Error in U_RAND_file_load"); + } + + // Install locks for multithreading support + opensslInstallLocks(); } void deinitOpenSsl() { - opensslUninstallLocks(); - CONF_modules_unload(1); - EVP_cleanup(); - ERR_free_strings(); - deinitOpenSslThread(); + opensslUninstallLocks(); + CONF_modules_unload(1); + EVP_cleanup(); + ERR_free_strings(); + deinitOpenSslThread(); } void deinitOpenSslThread() { - CRYPTO_cleanup_all_ex_data(); - ERR_remove_thread_state(NULL); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); } namespace { @@ -160,33 +161,34 @@ void initEmpty() {} void initOpenSslAndDetach() { - // DCLP - std::lock_guard<std::mutex> lock(cryptoInitMutex); - /* - * We don't care about memory ordering here. Current thread will order it correctly and for - * other threads only store matters. Also only one thread can be here at once because of lock. - */ - if (initFn.load(std::memory_order_relaxed) != &initEmpty) { - initOpenSsl(); - - /* - * Synchronizes with load. Everything that happened before this store in this thread is - * visible to everything that happens after load in another thread. We switch to an empty - * function here. - */ - initFn.store(&initEmpty, std::memory_order_release); - } + // DCLP + std::lock_guard<std::mutex> lock(cryptoInitMutex); + + /* + * We don't care about memory ordering here. Current thread will order it correctly and for + * other threads only store matters. Also only one thread can be here at once because of lock. + */ + if (initFn.load(std::memory_order_relaxed) != &initEmpty) { + initOpenSsl(); + + /* + * Synchronizes with load. Everything that happened before this store in this thread is + * visible to everything that happens after load in another thread. We switch to an empty + * function here. + */ + initFn.store(&initEmpty, std::memory_order_release); + } } } // namespace anonymous void initOpenSslOnce() { - /* - * Synchronizes with store. Everything that happened before store in another thread will be - * visible in this thread after load. - */ - initFn.load(std::memory_order_acquire)(); + /* + * Synchronizes with store. Everything that happened before store in another thread will be + * visible in this thread after load. + */ + initFn.load(std::memory_order_acquire)(); } } /* namespace CKM */ diff --git a/src/manager/common/data-type.cpp b/src/manager/common/data-type.cpp index 35701bc7..ba1a6b2a 100644 --- a/src/manager/common/data-type.cpp +++ b/src/manager/common/data-type.cpp @@ -24,159 +24,216 @@ namespace CKM { DataType::DataType() : - m_dataType(BINARY_DATA) + m_dataType(BINARY_DATA) { } DataType::DataType(Type data) - : m_dataType(data) + : m_dataType(data) { - if (!isInRange(data)) - ThrowMsg(Exception::OutOfRange, - "Invalid conversion from DataType=" << static_cast<int>(data) << " to DBDataType"); + if (!isInRange(data)) + ThrowMsg(Exception::OutOfRange, + "Invalid conversion from DataType=" << static_cast<int>(data) << + " to DBDataType"); } -DataType::DataType(KeyType key) { - switch (key) { - case KeyType::KEY_RSA_PUBLIC: m_dataType = DataType::KEY_RSA_PUBLIC; break; - case KeyType::KEY_RSA_PRIVATE: m_dataType = DataType::KEY_RSA_PRIVATE; break; - case KeyType::KEY_DSA_PUBLIC: m_dataType = DataType::KEY_DSA_PUBLIC; break; - case KeyType::KEY_DSA_PRIVATE: m_dataType = DataType::KEY_DSA_PRIVATE; break; - case KeyType::KEY_ECDSA_PUBLIC: m_dataType = DataType::KEY_ECDSA_PUBLIC; break; - case KeyType::KEY_ECDSA_PRIVATE: m_dataType = DataType::KEY_ECDSA_PRIVATE; break; - case KeyType::KEY_AES: m_dataType = DataType::KEY_AES; break; - default: - ThrowMsg(Exception::OutOfRange, - "Invalid conversion from KeyType=" << static_cast<int>(key) << " to DBDataType"); - } +DataType::DataType(KeyType key) +{ + switch (key) { + case KeyType::KEY_RSA_PUBLIC: + m_dataType = DataType::KEY_RSA_PUBLIC; + break; + + case KeyType::KEY_RSA_PRIVATE: + m_dataType = DataType::KEY_RSA_PRIVATE; + break; + + case KeyType::KEY_DSA_PUBLIC: + m_dataType = DataType::KEY_DSA_PUBLIC; + break; + + case KeyType::KEY_DSA_PRIVATE: + m_dataType = DataType::KEY_DSA_PRIVATE; + break; + + case KeyType::KEY_ECDSA_PUBLIC: + m_dataType = DataType::KEY_ECDSA_PUBLIC; + break; + + case KeyType::KEY_ECDSA_PRIVATE: + m_dataType = DataType::KEY_ECDSA_PRIVATE; + break; + + case KeyType::KEY_AES: + m_dataType = DataType::KEY_AES; + break; + + default: + ThrowMsg(Exception::OutOfRange, + "Invalid conversion from KeyType=" << static_cast<int>(key) << + " to DBDataType"); + } } DataType::DataType(AlgoType algorithmType) { - switch (algorithmType) { - case AlgoType::AES_CTR: - case AlgoType::AES_CBC: - case AlgoType::AES_GCM: - case AlgoType::AES_CFB: - case AlgoType::AES_GEN: m_dataType = DataType::KEY_AES; break; - case AlgoType::RSA_SV: - case AlgoType::RSA_OAEP: - case AlgoType::RSA_GEN: m_dataType = DataType::KEY_RSA_PUBLIC; break; - case AlgoType::DSA_SV: - case AlgoType::DSA_GEN: m_dataType = DataType::KEY_DSA_PUBLIC; break; - case AlgoType::ECDSA_SV: - case AlgoType::ECDSA_GEN: m_dataType = DataType::KEY_ECDSA_PUBLIC; break; - default: - ThrowMsg(Exception::OutOfRange, - "Invalid conversion from AlgoType=" << static_cast<int>(algorithmType) << - " to DBDataType"); - } + switch (algorithmType) { + case AlgoType::AES_CTR: + case AlgoType::AES_CBC: + case AlgoType::AES_GCM: + case AlgoType::AES_CFB: + case AlgoType::AES_GEN: + m_dataType = DataType::KEY_AES; + break; + + case AlgoType::RSA_SV: + case AlgoType::RSA_OAEP: + case AlgoType::RSA_GEN: + m_dataType = DataType::KEY_RSA_PUBLIC; + break; + + case AlgoType::DSA_SV: + case AlgoType::DSA_GEN: + m_dataType = DataType::KEY_DSA_PUBLIC; + break; + + case AlgoType::ECDSA_SV: + case AlgoType::ECDSA_GEN: + m_dataType = DataType::KEY_ECDSA_PUBLIC; + break; + + default: + ThrowMsg(Exception::OutOfRange, + "Invalid conversion from AlgoType=" << static_cast<int>(algorithmType) << + " to DBDataType"); + } } DataType::DataType(int data) : - m_dataType(static_cast<Type>(data)) + m_dataType(static_cast<Type>(data)) { - if (!isInRange(data)) - ThrowMsg(Exception::OutOfRange, "Invalid conversion from int=" << data << " to DBDataType"); + if (!isInRange(data)) + ThrowMsg(Exception::OutOfRange, + "Invalid conversion from int=" << data << " to DBDataType"); } DataType::operator int () const { - return static_cast<int>(m_dataType); + return static_cast<int>(m_dataType); } -DataType::operator KeyType () const +DataType::operator KeyType() const { - switch (m_dataType) { - case DataType::KEY_RSA_PUBLIC: return KeyType::KEY_RSA_PUBLIC; - case DataType::KEY_RSA_PRIVATE: return KeyType::KEY_RSA_PRIVATE; - case DataType::KEY_DSA_PUBLIC: return KeyType::KEY_DSA_PUBLIC; - case DataType::KEY_DSA_PRIVATE: return KeyType::KEY_DSA_PRIVATE; - case DataType::KEY_ECDSA_PRIVATE: return KeyType::KEY_ECDSA_PRIVATE; - case DataType::KEY_ECDSA_PUBLIC: return KeyType::KEY_ECDSA_PUBLIC; - case DataType::KEY_AES: return KeyType::KEY_AES; - default: - ThrowMsg(Exception::OutOfRange, - "Invalid conversion from DBDataType=" << static_cast<int>(m_dataType) << - " to KeyType"); - } + switch (m_dataType) { + case DataType::KEY_RSA_PUBLIC: + return KeyType::KEY_RSA_PUBLIC; + + case DataType::KEY_RSA_PRIVATE: + return KeyType::KEY_RSA_PRIVATE; + + case DataType::KEY_DSA_PUBLIC: + return KeyType::KEY_DSA_PUBLIC; + + case DataType::KEY_DSA_PRIVATE: + return KeyType::KEY_DSA_PRIVATE; + + case DataType::KEY_ECDSA_PRIVATE: + return KeyType::KEY_ECDSA_PRIVATE; + + case DataType::KEY_ECDSA_PUBLIC: + return KeyType::KEY_ECDSA_PUBLIC; + + case DataType::KEY_AES: + return KeyType::KEY_AES; + + default: + ThrowMsg(Exception::OutOfRange, + "Invalid conversion from DBDataType=" << static_cast<int>(m_dataType) << + " to KeyType"); + } } bool DataType::operator==(const DataType &second) const { - return m_dataType == second.m_dataType; + return m_dataType == second.m_dataType; } bool DataType::isKey() const { - if (DB_KEY_FIRST <= m_dataType && DB_KEY_LAST >= m_dataType) - return true; - return false; + if (DB_KEY_FIRST <= m_dataType && DB_KEY_LAST >= m_dataType) + return true; + + return false; } bool DataType::isSKey() const { - return (KEY_AES == m_dataType); + return (KEY_AES == m_dataType); } bool DataType::isChainCert() const { - if (DB_CHAIN_FIRST <= m_dataType && DB_CHAIN_LAST >= m_dataType) - return true; - return false; + if (DB_CHAIN_FIRST <= m_dataType && DB_CHAIN_LAST >= m_dataType) + return true; + + return false; } bool DataType::isKeyPrivate() const { - switch (m_dataType) { - case KEY_RSA_PRIVATE: - case KEY_DSA_PRIVATE: - case KEY_ECDSA_PRIVATE: - return true; - default: - return false; - } + switch (m_dataType) { + case KEY_RSA_PRIVATE: + case KEY_DSA_PRIVATE: + case KEY_ECDSA_PRIVATE: + return true; + + default: + return false; + } } bool DataType::isKeyPublic() const { - switch (m_dataType) { - case KEY_RSA_PUBLIC: - case KEY_DSA_PUBLIC: - case KEY_ECDSA_PUBLIC: - return true; - default: - return false; - } + switch (m_dataType) { + case KEY_RSA_PUBLIC: + case KEY_DSA_PUBLIC: + case KEY_ECDSA_PUBLIC: + return true; + + default: + return false; + } } bool DataType::isCertificate() const { - return m_dataType == CERTIFICATE; + return m_dataType == CERTIFICATE; } bool DataType::isBinaryData() const { - return m_dataType == BINARY_DATA; + return m_dataType == BINARY_DATA; } bool DataType::isInRange(int data) { - if (data < static_cast<int>(DB_FIRST)) - return false; - if (data > static_cast<int>(DB_LAST)) - return false; - return true; + if (data < static_cast<int>(DB_FIRST)) + return false; + + if (data > static_cast<int>(DB_LAST)) + return false; + + return true; } DataType DataType::getChainDatatype(unsigned int index) { - DataType result(static_cast<int>(index) + DB_CHAIN_FIRST); + DataType result(static_cast<int>(index) + DB_CHAIN_FIRST); - if ( !result.isChainCert() ) - ThrowMsg(Exception::OutOfRange, "Certificate number is out of range"); + if (!result.isChainCert()) + ThrowMsg(Exception::OutOfRange, "Certificate number is out of range"); - return result; + return result; } } // namespace CKM diff --git a/src/manager/common/data-type.h b/src/manager/common/data-type.h index 4cb7814e..a3225342 100644 --- a/src/manager/common/data-type.h +++ b/src/manager/common/data-type.h @@ -29,77 +29,77 @@ namespace CKM { class COMMON_API DataType { public: - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, OutOfRange) - }; + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfRange) + }; - enum Type { - KEY_RSA_PUBLIC, - KEY_RSA_PRIVATE, - KEY_ECDSA_PUBLIC, - KEY_ECDSA_PRIVATE, - KEY_DSA_PUBLIC, - KEY_DSA_PRIVATE, - KEY_AES, - CERTIFICATE, - BINARY_DATA, + enum Type { + KEY_RSA_PUBLIC, + KEY_RSA_PRIVATE, + KEY_ECDSA_PUBLIC, + KEY_ECDSA_PRIVATE, + KEY_DSA_PUBLIC, + KEY_DSA_PRIVATE, + KEY_AES, + CERTIFICATE, + BINARY_DATA, - CHAIN_CERT_0, - CHAIN_CERT_1, - CHAIN_CERT_2, - CHAIN_CERT_3, - CHAIN_CERT_4, - CHAIN_CERT_5, - CHAIN_CERT_6, - CHAIN_CERT_7, - CHAIN_CERT_8, - CHAIN_CERT_9, - CHAIN_CERT_10, - CHAIN_CERT_11, - CHAIN_CERT_12, - CHAIN_CERT_13, - CHAIN_CERT_14, - CHAIN_CERT_15, + CHAIN_CERT_0, + CHAIN_CERT_1, + CHAIN_CERT_2, + CHAIN_CERT_3, + CHAIN_CERT_4, + CHAIN_CERT_5, + CHAIN_CERT_6, + CHAIN_CERT_7, + CHAIN_CERT_8, + CHAIN_CERT_9, + CHAIN_CERT_10, + CHAIN_CERT_11, + CHAIN_CERT_12, + CHAIN_CERT_13, + CHAIN_CERT_14, + CHAIN_CERT_15, - // Special types to support database, - DB_KEY_FIRST = KEY_RSA_PUBLIC, - DB_KEY_LAST = KEY_AES, - DB_CHAIN_FIRST = CHAIN_CERT_0, - DB_CHAIN_LAST = CHAIN_CERT_15, - DB_FIRST = KEY_RSA_PUBLIC, - DB_LAST = CHAIN_CERT_15, - }; + // Special types to support database, + DB_KEY_FIRST = KEY_RSA_PUBLIC, + DB_KEY_LAST = KEY_AES, + DB_CHAIN_FIRST = CHAIN_CERT_0, + DB_CHAIN_LAST = CHAIN_CERT_15, + DB_FIRST = KEY_RSA_PUBLIC, + DB_LAST = CHAIN_CERT_15, + }; - DataType(); - DataType(Type data); - explicit DataType(int data); - explicit DataType(KeyType key); - explicit DataType(AlgoType algorithmType); - DataType(const DataType &) = default; - DataType& operator=(const DataType &) = default; + DataType(); + DataType(Type data); + explicit DataType(int data); + explicit DataType(KeyType key); + explicit DataType(AlgoType algorithmType); + DataType(const DataType &) = default; + DataType &operator=(const DataType &) = default; - operator int () const; - operator KeyType () const; - bool operator==(const DataType &second) const; + operator int () const; + operator KeyType() const; + bool operator==(const DataType &second) const; - bool isKey() const; - bool isSKey() const; - bool isChainCert() const; - bool isKeyPrivate() const; - bool isKeyPublic() const; - bool isCertificate() const; - bool isBinaryData() const; + bool isKey() const; + bool isSKey() const; + bool isChainCert() const; + bool isKeyPrivate() const; + bool isKeyPublic() const; + bool isCertificate() const; + bool isBinaryData() const; - static bool isInRange(int data); - static DataType getChainDatatype(unsigned int index); + static bool isInRange(int data); + static DataType getChainDatatype(unsigned int index); - // it's not virtual for a reason! - ~DataType() {} + // it's not virtual for a reason! + ~DataType() {} private: - Type m_dataType; + Type m_dataType; }; } // namespace CKM diff --git a/src/manager/common/exception.cpp b/src/manager/common/exception.cpp index d3b8c9b5..8a9edf5c 100644 --- a/src/manager/common/exception.cpp +++ b/src/manager/common/exception.cpp @@ -26,23 +26,25 @@ namespace CKM { namespace Exc { PrintError::PrintError( - const std::string &path, - const std::string &function, - int line, - int error, - const std::string &message) + const std::string &path, + const std::string &function, + int line, + int error, + const std::string &message) { - LogErrorPosition(message << " (Error: " << error << ")", path.c_str(), line, function.c_str()); + LogErrorPosition(message << " (Error: " << error << ")", path.c_str(), line, + function.c_str()); } PrintDebug::PrintDebug( - const std::string &path, - const std::string &function, - int line, - int error, - const std::string &message) + const std::string &path, + const std::string &function, + int line, + int error, + const std::string &message) { - LogDebugPosition(message << " (Error: " << error << ")", path.c_str(), line, function.c_str()); + LogDebugPosition(message << " (Error: " << error << ")", path.c_str(), line, + function.c_str()); } } // namespace Exc diff --git a/src/manager/common/exception.h b/src/manager/common/exception.h index 4b950f22..380675f2 100644 --- a/src/manager/common/exception.h +++ b/src/manager/common/exception.h @@ -35,107 +35,110 @@ namespace Exc { class COMMON_API Exception : public std::exception { public: - Exception(const char *path, const char *function, int line, const std::string &message = std::string()) - : m_path(path) - , m_function(function) - , m_line(line) - , m_message(message) - {} - - virtual ~Exception() noexcept {} - - virtual const char *what(void) const noexcept - { - return m_message.c_str(); - } - - virtual std::string message(void) const - { - std::ostringstream msg; - msg << "[" << m_path << ":" << m_line << " " << m_function << "()] " << m_message; - return msg.str(); - } - - virtual int error(void) const = 0; + Exception(const char *path, const char *function, int line, + const std::string &message = std::string()) : + m_path(path), + m_function(function), + m_line(line), + m_message(message) {} + + virtual ~Exception() noexcept {} + + virtual const char *what(void) const noexcept + { + return m_message.c_str(); + } + + virtual std::string message(void) const + { + std::ostringstream msg; + msg << "[" << m_path << ":" << m_line << " " << m_function << "()] " << + m_message; + return msg.str(); + } + + virtual int error(void) const = 0; protected: - std::string m_path; - std::string m_function; - int m_line; - std::string m_message; + std::string m_path; + std::string m_function; + int m_line; + std::string m_message; }; class DefaultExceptionLogger { public: - template <typename... Args> - DefaultExceptionLogger(const Args&...) {} + template <typename... Args> + DefaultExceptionLogger(const Args &...) {} }; -template< - int Error = 0, - typename Stringify = StringifyAvoid, - typename Before = DefaultExceptionLogger, - typename After = DefaultExceptionLogger> +template < + int Error = 0, + typename Stringify = StringifyAvoid, + typename Before = DefaultExceptionLogger, + typename After = DefaultExceptionLogger > class COMMON_API DefineException : public Exception { public: - template<typename... Args> - DefineException(const char *path, const char *function, int line, const Args&... args) - : Exception(path, function, line, Stringify::Merge(args...)) - { - Before(m_path, m_function, m_line, DefineException<Error, Stringify, Before, After>::error(), m_message); - } - ~DefineException() noexcept - { - After(m_path, m_function, m_line, DefineException<Error, Stringify, Before, After>::error(), m_message); - } - virtual int error(void) const - { - return Error; - } + template<typename... Args> + DefineException(const char *path, const char *function, int line, + const Args &... args) + : Exception(path, function, line, Stringify::Merge(args...)) + { + Before(m_path, m_function, m_line, + DefineException<Error, Stringify, Before, After>::error(), m_message); + } + + ~DefineException() noexcept + { + After(m_path, m_function, m_line, + DefineException<Error, Stringify, Before, After>::error(), m_message); + } + + virtual int error(void) const + { + return Error; + } }; class COMMON_API PrintError { public: - PrintError( - const std::string &path, - const std::string &function, - int line, int error, - const std::string &message = std::string()); + PrintError(const std::string &path, const std::string &function, int line, + int error, const std::string &message = std::string()); }; class COMMON_API PrintDebug { public: - PrintDebug( - const std::string &path, - const std::string &function, - int line, int error, - const std::string &message = std::string()); + PrintDebug( + const std::string &path, + const std::string &function, + int line, int error, + const std::string &message = std::string()); }; -typedef DefineException<CKM_API_ERROR_SERVER_ERROR, - Stringify, PrintError> InternalError; -typedef DefineException<CKM_API_ERROR_INPUT_PARAM, - StringifyDebug, PrintDebug> InputParam; -typedef DefineException<CKM_API_ERROR_DB_LOCKED, - Stringify, PrintError> DatabaseLocked; -typedef DefineException<CKM_API_ERROR_FILE_SYSTEM, - Stringify, PrintError> FileSystemFailed; -typedef DefineException<CKM_API_ERROR_AUTHENTICATION_FAILED, - StringifyDebug, PrintDebug> AuthenticationFailed; -typedef DefineException<CKM_API_ERROR_DB_ERROR, - StringifyError, PrintError> DatabaseFailed; +using InternalError = + DefineException<CKM_API_ERROR_SERVER_ERROR, Stringify, PrintError>; +using DatabaseLocked = + DefineException<CKM_API_ERROR_DB_LOCKED, Stringify, PrintError>; +using DatabaseFailed = + DefineException<CKM_API_ERROR_DB_ERROR, StringifyError, PrintError>; +using FileSystemFailed = + DefineException<CKM_API_ERROR_FILE_SYSTEM, Stringify, PrintError>; +using InputParam = + DefineException<CKM_API_ERROR_INPUT_PARAM, StringifyDebug, PrintDebug>; +using AuthenticationFailed = + DefineException<CKM_API_ERROR_AUTHENTICATION_FAILED, StringifyDebug, PrintDebug>; struct TransactionFailed : public DatabaseFailed { - template<typename... Args> - TransactionFailed(const char *path, const char *function, int line, const Args&... args) - : DatabaseFailed(path, function, line, args...) - {} + template<typename... Args> + TransactionFailed(const char *path, const char *function, int line, + const Args &... args) + : DatabaseFailed(path, function, line, args...) {} }; } // namespace Exc } // namespace CKM #define ThrowErr(name, ...) \ - throw name(__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); + throw name(__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); diff --git a/src/manager/common/key-aes-impl.cpp b/src/manager/common/key-aes-impl.cpp index b931f8f4..54c8d613 100644 --- a/src/manager/common/key-aes-impl.cpp +++ b/src/manager/common/key-aes-impl.cpp @@ -26,53 +26,56 @@ namespace CKM { KeyAESImpl::KeyAESImpl(const RawBuffer &buf) : m_key(buf) { - // buf stores bytes -> compare the bit sizes - switch (buf.size() * 8) { - case 128: - case 192: - case 256: - break; + // buf stores bytes -> compare the bit sizes + switch (buf.size() * 8) { + case 128: + case 192: + case 256: + break; - default: - throw std::invalid_argument("invalid AES key size"); - } + default: + throw std::invalid_argument("invalid AES key size"); + } } bool KeyAESImpl::empty() const { - return (getSize() == 0); + return (getSize() == 0); } KeyType KeyAESImpl::getType() const { - return KeyType::KEY_AES; + return KeyType::KEY_AES; } RawBuffer KeyAESImpl::getDER() const { - return m_key; + return m_key; } int KeyAESImpl::getSize() const { - return m_key.size(); + return m_key.size(); } KeyShPtr Key::createAES(const RawBuffer &raw) { - try { - KeyShPtr output = std::make_shared<KeyAESImpl>(raw); - if (output->empty()) - output.reset(); - return output; - } catch (const std::bad_alloc &) { - LogDebug("Bad alloc during KeyAESImpl creation"); - } catch (const std::invalid_argument &e) { - LogDebug(e.what()); - } catch (...) { - LogError("Critical error: Unknown exception was caught during KeyAESImpl creation"); - } - return KeyShPtr(); + try { + KeyShPtr output = std::make_shared<KeyAESImpl>(raw); + + if (output->empty()) + output.reset(); + + return output; + } catch (const std::bad_alloc &) { + LogDebug("Bad alloc during KeyAESImpl creation"); + } catch (const std::invalid_argument &e) { + LogDebug(e.what()); + } catch (...) { + LogError("Critical error: Unknown exception was caught during KeyAESImpl creation"); + } + + return KeyShPtr(); } } // namespace CKM diff --git a/src/manager/common/key-aes-impl.h b/src/manager/common/key-aes-impl.h index 946a9842..4a8d2210 100644 --- a/src/manager/common/key-aes-impl.h +++ b/src/manager/common/key-aes-impl.h @@ -28,15 +28,15 @@ namespace CKM { class COMMON_API KeyAESImpl : public Key { public: - explicit KeyAESImpl(const RawBuffer& buffer); + explicit KeyAESImpl(const RawBuffer &buffer); - virtual KeyType getType() const; - virtual RawBuffer getDER() const; - virtual int getSize() const; - virtual bool empty() const; + virtual KeyType getType() const; + virtual RawBuffer getDER() const; + virtual int getSize() const; + virtual bool empty() const; protected: - CKM::RawBuffer m_key; + CKM::RawBuffer m_key; }; } // namespace CKM diff --git a/src/manager/common/key-impl.cpp b/src/manager/common/key-impl.cpp index ab5308de..680f7e11 100644 --- a/src/manager/common/key-impl.cpp +++ b/src/manager/common/key-impl.cpp @@ -38,45 +38,45 @@ namespace CKM { namespace { -typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr; +typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr; int passcb(char *buff, int size, int /*rwflag*/, void *userdata) { - auto ptr = static_cast<Password *>(userdata); + auto ptr = static_cast<Password *>(userdata); - if (ptr == nullptr || ptr->empty() || static_cast<int>(ptr->size()) > size) - return 0; + if (ptr == nullptr || ptr->empty() || static_cast<int>(ptr->size()) > size) + return 0; - memcpy(buff, ptr->c_str(), ptr->size()); + memcpy(buff, ptr->c_str(), ptr->size()); - return ptr->size(); + return ptr->size(); } -typedef int(*I2D_CONV)(BIO*, EVP_PKEY*); +typedef int(*I2D_CONV)(BIO *, EVP_PKEY *); -CKM::RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) +CKM::RawBuffer i2d(I2D_CONV fun, EVP_PKEY *pkey) { - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - if (pkey == nullptr || !bio) - return RawBuffer(); + if (pkey == nullptr || !bio) + return RawBuffer(); - if (fun(bio.get(), pkey) != 1) { - LogError("Error in conversion EVP_PKEY to der"); - return RawBuffer(); - } + if (fun(bio.get(), pkey) != 1) { + LogError("Error in conversion EVP_PKEY to der"); + return RawBuffer(); + } - CKM::RawBuffer output(8196); + CKM::RawBuffer output(8196); - int size = BIO_read(bio.get(), output.data(), output.size()); + int size = BIO_read(bio.get(), output.data(), output.size()); - if (size <= 0) { - LogError("Error in BIO_read: " << size); - return RawBuffer(); - } + if (size <= 0) { + LogError("Error in BIO_read: " << size); + return RawBuffer(); + } - output.resize(size); - return output; + output.resize(size); + return output; } } // anonymous namespace @@ -86,168 +86,175 @@ KeyImpl::KeyImpl() : m_pkey(nullptr, EVP_PKEY_free), m_type(KeyType::KEY_NONE) } KeyImpl::KeyImpl(const RawBuffer &buf, const Password &password) : - m_pkey(nullptr, EVP_PKEY_free), - m_type(KeyType::KEY_NONE) + m_pkey(nullptr, EVP_PKEY_free), + m_type(KeyType::KEY_NONE) { - bool isPrivate = false; - EVP_PKEY *pkey = nullptr; - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - - LogDebug("Start to parse key:"); - - if (buf[0] != '-') { - BIO_write(bio.get(), buf.data(), buf.size()); - pkey = d2i_PUBKEY_bio(bio.get(), nullptr); - isPrivate = false; - LogDebug("Trying d2i_PUBKEY_bio Status: " << (void*)pkey); - } - - if (!pkey && buf[0] != '-') { - /* cast to void of return val to ignore unused-value warning */ - static_cast<void>(BIO_reset(bio.get())); - BIO_write(bio.get(), buf.data(), buf.size()); - pkey = d2i_PrivateKey_bio(bio.get(), nullptr); - isPrivate = true; - LogDebug("Trying d2i_PrivateKey_bio Status: " << (void*)pkey); - } - - if (!pkey && buf[0] == '-') { - /* cast to void of return val to ignore unused-value warning */ - static_cast<void>(BIO_reset(bio.get())); - BIO_write(bio.get(), buf.data(), buf.size()); - pkey = PEM_read_bio_PUBKEY(bio.get(), nullptr, passcb, const_cast<Password*>(&password)); - isPrivate = false; - LogDebug("PEM_read_bio_PUBKEY Status: " << (void*)pkey); - } - - if (!pkey && buf[0] == '-') { - /* cast to void of return val to ignore unused-value warning */ - static_cast<void>(BIO_reset(bio.get())); - BIO_write(bio.get(), buf.data(), buf.size()); - pkey = PEM_read_bio_PrivateKey(bio.get(), nullptr, passcb, const_cast<Password*>(&password)); - isPrivate = true; - LogDebug("PEM_read_bio_PrivateKey Status: " << (void*)pkey); - } - - if (!pkey) { - LogError("Failed to parse key"); - return; - } - - m_pkey.reset(pkey, EVP_PKEY_free); - - switch (EVP_PKEY_type(pkey->type)) { - case EVP_PKEY_RSA: - m_type = isPrivate ? KeyType::KEY_RSA_PRIVATE : KeyType::KEY_RSA_PUBLIC; - break; - - case EVP_PKEY_DSA: - m_type = isPrivate ? KeyType::KEY_DSA_PRIVATE : KeyType::KEY_DSA_PUBLIC; - break; - - case EVP_PKEY_EC: - m_type = isPrivate ? KeyType::KEY_ECDSA_PRIVATE : KeyType::KEY_ECDSA_PUBLIC; - break; - } - - LogDebug("KeyType is: " << static_cast<int>(m_type) << " isPrivate: " << isPrivate); + bool isPrivate = false; + EVP_PKEY *pkey = nullptr; + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + + LogDebug("Start to parse key:"); + + if (buf[0] != '-') { + BIO_write(bio.get(), buf.data(), buf.size()); + pkey = d2i_PUBKEY_bio(bio.get(), nullptr); + isPrivate = false; + LogDebug("Trying d2i_PUBKEY_bio Status: " << (void *)pkey); + } + + if (!pkey && buf[0] != '-') { + /* cast to void of return val to ignore unused-value warning */ + static_cast<void>(BIO_reset(bio.get())); + BIO_write(bio.get(), buf.data(), buf.size()); + pkey = d2i_PrivateKey_bio(bio.get(), nullptr); + isPrivate = true; + LogDebug("Trying d2i_PrivateKey_bio Status: " << (void *)pkey); + } + + if (!pkey && buf[0] == '-') { + /* cast to void of return val to ignore unused-value warning */ + static_cast<void>(BIO_reset(bio.get())); + BIO_write(bio.get(), buf.data(), buf.size()); + pkey = PEM_read_bio_PUBKEY(bio.get(), nullptr, passcb, + const_cast<Password *>(&password)); + isPrivate = false; + LogDebug("PEM_read_bio_PUBKEY Status: " << (void *)pkey); + } + + if (!pkey && buf[0] == '-') { + /* cast to void of return val to ignore unused-value warning */ + static_cast<void>(BIO_reset(bio.get())); + BIO_write(bio.get(), buf.data(), buf.size()); + pkey = PEM_read_bio_PrivateKey(bio.get(), nullptr, passcb, + const_cast<Password *>(&password)); + isPrivate = true; + LogDebug("PEM_read_bio_PrivateKey Status: " << (void *)pkey); + } + + if (!pkey) { + LogError("Failed to parse key"); + return; + } + + m_pkey.reset(pkey, EVP_PKEY_free); + + switch (EVP_PKEY_type(pkey->type)) { + case EVP_PKEY_RSA: + m_type = isPrivate ? KeyType::KEY_RSA_PRIVATE : KeyType::KEY_RSA_PUBLIC; + break; + + case EVP_PKEY_DSA: + m_type = isPrivate ? KeyType::KEY_DSA_PRIVATE : KeyType::KEY_DSA_PUBLIC; + break; + + case EVP_PKEY_EC: + m_type = isPrivate ? KeyType::KEY_ECDSA_PRIVATE : KeyType::KEY_ECDSA_PUBLIC; + break; + } + + LogDebug("KeyType is: " << static_cast<int>(m_type) << " isPrivate: " << + isPrivate); } KeyImpl::KeyImpl(EvpShPtr pkey, KeyType type) : m_pkey(pkey), m_type(type) { - int expected_type = EVP_PKEY_NONE; - - switch (type) { - case KeyType::KEY_RSA_PRIVATE: - case KeyType::KEY_RSA_PUBLIC: - expected_type = EVP_PKEY_RSA; - break; - - case KeyType::KEY_DSA_PRIVATE: - case KeyType::KEY_DSA_PUBLIC: - expected_type = EVP_PKEY_DSA; - break; - - case KeyType::KEY_AES: - LogError("Error, AES keys are not supported yet."); - break; - - case KeyType::KEY_ECDSA_PRIVATE: - case KeyType::KEY_ECDSA_PUBLIC: - expected_type = EVP_PKEY_EC; - break; - - default: - LogError("Unknown key type provided."); - break; - } - - // verify if actual key type matches the expected tpe - int given_key_type = EVP_PKEY_type(pkey->type); - if (given_key_type == EVP_PKEY_NONE || expected_type != given_key_type) { - m_pkey.reset(); - m_type = KeyType::KEY_NONE; - } + int expected_type = EVP_PKEY_NONE; + + switch (type) { + case KeyType::KEY_RSA_PRIVATE: + case KeyType::KEY_RSA_PUBLIC: + expected_type = EVP_PKEY_RSA; + break; + + case KeyType::KEY_DSA_PRIVATE: + case KeyType::KEY_DSA_PUBLIC: + expected_type = EVP_PKEY_DSA; + break; + + case KeyType::KEY_AES: + LogError("Error, AES keys are not supported yet."); + break; + + case KeyType::KEY_ECDSA_PRIVATE: + case KeyType::KEY_ECDSA_PUBLIC: + expected_type = EVP_PKEY_EC; + break; + + default: + LogError("Unknown key type provided."); + break; + } + + // verify if actual key type matches the expected tpe + int given_key_type = EVP_PKEY_type(pkey->type); + + if (given_key_type == EVP_PKEY_NONE || expected_type != given_key_type) { + m_pkey.reset(); + m_type = KeyType::KEY_NONE; + } } bool KeyImpl::empty() const { - return !m_pkey; + return !m_pkey; } KeyImpl::EvpShPtr KeyImpl::getEvpShPtr() const { - return m_pkey; + return m_pkey; } KeyType KeyImpl::getType() const { - return m_type; + return m_type; } RawBuffer KeyImpl::getDERPRV() const { - return i2d(i2d_PrivateKey_bio, m_pkey.get()); + return i2d(i2d_PrivateKey_bio, m_pkey.get()); } RawBuffer KeyImpl::getDERPUB() const { - return i2d(i2d_PUBKEY_bio, m_pkey.get()); + return i2d(i2d_PUBKEY_bio, m_pkey.get()); } RawBuffer KeyImpl::getDER() const { - switch (m_type) { - case KeyType::KEY_RSA_PRIVATE: - case KeyType::KEY_DSA_PRIVATE: - case KeyType::KEY_ECDSA_PRIVATE: - return getDERPRV(); - - case KeyType::KEY_RSA_PUBLIC: - case KeyType::KEY_DSA_PUBLIC: - case KeyType::KEY_ECDSA_PUBLIC: - return getDERPUB(); - - default: - break; - } - - return RawBuffer(); + switch (m_type) { + case KeyType::KEY_RSA_PRIVATE: + case KeyType::KEY_DSA_PRIVATE: + case KeyType::KEY_ECDSA_PRIVATE: + return getDERPRV(); + + case KeyType::KEY_RSA_PUBLIC: + case KeyType::KEY_DSA_PUBLIC: + case KeyType::KEY_ECDSA_PUBLIC: + return getDERPUB(); + + default: + break; + } + + return RawBuffer(); } KeyShPtr Key::create(const RawBuffer &raw, const Password &password) { - try { - KeyShPtr output = std::make_shared<KeyImpl>(raw, password); - if (output->empty()) - output.reset(); - return output; - } catch (const std::bad_alloc &) { - LogDebug("Bad alloc was catch during KeyImpl creation"); - } catch (...) { - LogError("Critical error: Unknown exception was caught during KeyImpl creation"); - } - return KeyShPtr(); + try { + KeyShPtr output = std::make_shared<KeyImpl>(raw, password); + + if (output->empty()) + output.reset(); + + return output; + } catch (const std::bad_alloc &) { + LogDebug("Bad alloc was catch during KeyImpl creation"); + } catch (...) { + LogError("Critical error: Unknown exception was caught during KeyImpl creation"); + } + + return KeyShPtr(); } } // namespace CKM diff --git a/src/manager/common/key-impl.h b/src/manager/common/key-impl.h index c09b4a5e..b31c9045 100644 --- a/src/manager/common/key-impl.h +++ b/src/manager/common/key-impl.h @@ -31,38 +31,38 @@ namespace CKM { class COMMON_API KeyImpl : public Key { public: - typedef std::shared_ptr<EVP_PKEY> EvpShPtr; + using EvpShPtr = std::shared_ptr<EVP_PKEY>; - KeyImpl(); - KeyImpl(const KeyImpl &second) = delete; - KeyImpl &operator=(const KeyImpl &second) = delete; - KeyImpl(const RawBuffer& buffer, const Password &password = Password()); - KeyImpl(EvpShPtr pkey, KeyType type); + KeyImpl(); + KeyImpl(const KeyImpl &second) = delete; + KeyImpl &operator=(const KeyImpl &second) = delete; + KeyImpl(const RawBuffer &buffer, const Password &password = Password()); + KeyImpl(EvpShPtr pkey, KeyType type); - virtual KeyType getType() const; - virtual RawBuffer getDER() const; - virtual RawBuffer getDERPUB() const; - virtual RawBuffer getDERPRV() const; - virtual EvpShPtr getEvpShPtr() const; - /* //TODO - virtual ElipticCurve getCurve() const - { - return ElipticCurve::prime192v1; - } - */ + virtual KeyType getType() const; + virtual RawBuffer getDER() const; + virtual RawBuffer getDERPUB() const; + virtual RawBuffer getDERPRV() const; + virtual EvpShPtr getEvpShPtr() const; + /* //TODO + virtual ElipticCurve getCurve() const + { + return ElipticCurve::prime192v1; + } + */ - virtual int getSize() const - { - // TODO - return 0; - } + virtual int getSize() const + { + // TODO + return 0; + } - virtual bool empty() const; - virtual ~KeyImpl() {} + virtual bool empty() const; + virtual ~KeyImpl() {} protected: - EvpShPtr m_pkey; - KeyType m_type; + EvpShPtr m_pkey; + KeyType m_type; }; } // namespace CKM diff --git a/src/manager/common/log-setup.cpp b/src/manager/common/log-setup.cpp index 70207c0b..5939907b 100644 --- a/src/manager/common/log-setup.cpp +++ b/src/manager/common/log-setup.cpp @@ -40,38 +40,46 @@ bool logSystemReady = false; */ class EnvFileParser { public: - EnvFileParser(); - virtual ~EnvFileParser() {} + EnvFileParser(); + virtual ~EnvFileParser() {} - std::string getProvider() const { return m_provider; } - std::string getLevel() const { return m_level; } + std::string getProvider() const + { + return m_provider; + } + + std::string getLevel() const + { + return m_level; + } private: - std::string m_provider; - std::string m_level; + std::string m_provider; + std::string m_level; }; EnvFileParser::EnvFileParser() { #ifdef SYSTEMD_ENV_FILE - std::ifstream is(SYSTEMD_ENV_FILE); - LogDebug("Reading env file: " SYSTEMD_ENV_FILE); - - while (is.good()) { - std::string line; - - std::getline(is, line); - - if (0 == line.compare(0, PROVIDER_MATCH.size(), PROVIDER_MATCH)) { - m_provider = line.substr(PROVIDER_MATCH.size()); - LogDebug("Log provider: " << m_provider); - } else if (0 == line.compare(0, LEVEL_MATCH.size(), LEVEL_MATCH)) { - m_level = line.substr(LEVEL_MATCH.size()); - LogDebug("Log level: " << m_level); - } - } + std::ifstream is(SYSTEMD_ENV_FILE); + LogDebug("Reading env file: " SYSTEMD_ENV_FILE); + + while (is.good()) { + std::string line; + + std::getline(is, line); + + if (0 == line.compare(0, PROVIDER_MATCH.size(), PROVIDER_MATCH)) { + m_provider = line.substr(PROVIDER_MATCH.size()); + LogDebug("Log provider: " << m_provider); + } else if (0 == line.compare(0, LEVEL_MATCH.size(), LEVEL_MATCH)) { + m_level = line.substr(LEVEL_MATCH.size()); + LogDebug("Log level: " << m_level); + } + } + #else - LogWarning("Log configuration file is undefined"); + LogWarning("Log configuration file is undefined"); #endif } @@ -79,33 +87,36 @@ EnvFileParser::EnvFileParser() void SetupClientLogSystem() { - /* - * This function is called from library constructors. This will prevent from executing the code - * more than once from single binary (because both client libraries use their constructors to - * initialize log system). To make it work the code has to be in a common library linked by both - * clients. - */ - if (logSystemReady) - return; - - CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_CLIENT"); - - CKM::EnvFileParser parser; - const std::string provider = parser.getProvider(); - if (!provider.empty()) { - try { - CKM::Singleton<CKM::Log::LogSystem>::Instance().SelectProvider(provider); - // reset tag after changing log provider - CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_CLIENT"); - } catch(const std::out_of_range&) { - LogError("Unsupported log provider: " << provider); - } - } - const std::string level = parser.getLevel(); - if (!level.empty()) - CKM::Singleton<CKM::Log::LogSystem>::Instance().SetLogLevel(level.c_str()); - - logSystemReady = true; + /* + * This function is called from library constructors. This will prevent from executing the code + * more than once from single binary (because both client libraries use their constructors to + * initialize log system). To make it work the code has to be in a common library linked by both + * clients. + */ + if (logSystemReady) + return; + + CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_CLIENT"); + + CKM::EnvFileParser parser; + const std::string provider = parser.getProvider(); + + if (!provider.empty()) { + try { + CKM::Singleton<CKM::Log::LogSystem>::Instance().SelectProvider(provider); + // reset tag after changing log provider + CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_CLIENT"); + } catch (const std::out_of_range &) { + LogError("Unsupported log provider: " << provider); + } + } + + const std::string level = parser.getLevel(); + + if (!level.empty()) + CKM::Singleton<CKM::Log::LogSystem>::Instance().SetLogLevel(level.c_str()); + + logSystemReady = true; } } /* namespace CKM */ diff --git a/src/manager/common/message-buffer.cpp b/src/manager/common/message-buffer.cpp index 166da553..97e2d472 100644 --- a/src/manager/common/message-buffer.cpp +++ b/src/manager/common/message-buffer.cpp @@ -31,44 +31,49 @@ namespace CKM { void MessageBuffer::Push(const RawBuffer &data) { - m_buffer.AppendCopy(&data[0], data.size()); + m_buffer.AppendCopy(&data[0], data.size()); } RawBuffer MessageBuffer::Pop() { - size_t size = m_buffer.Size(); - RawBuffer buffer; - buffer.resize(size + sizeof(size_t)); - memcpy(&buffer[0], &size, sizeof(size_t)); - m_buffer.FlattenConsume(&buffer[sizeof(size_t)], size); - return buffer; + size_t size = m_buffer.Size(); + RawBuffer buffer; + buffer.resize(size + sizeof(size_t)); + memcpy(&buffer[0], &size, sizeof(size_t)); + m_buffer.FlattenConsume(&buffer[sizeof(size_t)], size); + return buffer; } bool MessageBuffer::Ready() { - CountBytesLeft(); - if (m_bytesLeft == 0) - return false; - if (m_bytesLeft > m_buffer.Size()) - return false; - return true; + CountBytesLeft(); + + if (m_bytesLeft == 0) + return false; + + if (m_bytesLeft > m_buffer.Size()) + return false; + + return true; } void MessageBuffer::Read(size_t num, void *bytes) { - CountBytesLeft(); - if (num > m_bytesLeft) { - LogDebug("Protocol broken. OutOfData. Asked for: " << num << " Ready: " << m_bytesLeft << " Buffer.size(): " << m_buffer.Size()); - Throw(Exception::OutOfData); - } + CountBytesLeft(); + + if (num > m_bytesLeft) { + LogDebug("Protocol broken. OutOfData. Asked for: " << num << " Ready: " << + m_bytesLeft << " Buffer.size(): " << m_buffer.Size()); + Throw(Exception::OutOfData); + } - m_buffer.FlattenConsume(bytes, num); - m_bytesLeft -= num; + m_buffer.FlattenConsume(bytes, num); + m_bytesLeft -= num; } void MessageBuffer::Write(size_t num, const void *bytes) { - m_buffer.AppendCopy(bytes, num); + m_buffer.AppendCopy(bytes, num); } } // namespace CKM diff --git a/src/manager/common/message-buffer.h b/src/manager/common/message-buffer.h index f519fc36..e32ed85e 100644 --- a/src/manager/common/message-buffer.h +++ b/src/manager/common/message-buffer.h @@ -36,60 +36,57 @@ namespace CKM { class COMMON_API MessageBuffer : public CKM::IStream { public: - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, OutOfData) - }; + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; - MessageBuffer() : - m_bytesLeft(0) - { - } + MessageBuffer() : m_bytesLeft(0) {} - MessageBuffer(MessageBuffer&&) = default; - MessageBuffer& operator=(MessageBuffer&&) = default; + MessageBuffer(MessageBuffer &&) = default; + MessageBuffer &operator=(MessageBuffer &&) = default; - void Push(const RawBuffer &data); + void Push(const RawBuffer &data); - RawBuffer Pop(); + RawBuffer Pop(); - bool Ready(); + bool Ready(); - virtual void Read(size_t num, void *bytes); + virtual void Read(size_t num, void *bytes); - virtual void Write(size_t num, const void *bytes); + virtual void Write(size_t num, const void *bytes); - // generic serialization - template <typename... Args> - static MessageBuffer Serialize(const Args&... args) - { - MessageBuffer buffer; - Serializer<Args...>::Serialize(buffer, args...); - return buffer; - } + // generic serialization + template <typename... Args> + static MessageBuffer Serialize(const Args &... args) + { + MessageBuffer buffer; + Serializer<Args...>::Serialize(buffer, args...); + return buffer; + } - // generic deserialization - template <typename... Args> - void Deserialize(Args&... args) - { - Deserializer<Args...>::Deserialize(*this, args...); - } + // generic deserialization + template <typename... Args> + void Deserialize(Args &... args) + { + Deserializer<Args...>::Deserialize(*this, args...); + } protected: - inline void CountBytesLeft() - { - if (m_bytesLeft > 0) - return; // we already counted m_bytesLeft nothing to do + inline void CountBytesLeft() + { + if (m_bytesLeft > 0) + return; // we already counted m_bytesLeft nothing to do - if (m_buffer.Size() < sizeof(size_t)) - return; // we cannot count m_bytesLeft because buffer is too small + if (m_buffer.Size() < sizeof(size_t)) + return; // we cannot count m_bytesLeft because buffer is too small - m_buffer.FlattenConsume(&m_bytesLeft, sizeof(size_t)); - } + m_buffer.FlattenConsume(&m_bytesLeft, sizeof(size_t)); + } - size_t m_bytesLeft; - CKM::BinaryQueue m_buffer; + size_t m_bytesLeft; + CKM::BinaryQueue m_buffer; }; } // namespace CKM diff --git a/src/manager/common/noncopyable.h b/src/manager/common/noncopyable.h index 32f443a0..c1581e62 100644 --- a/src/manager/common/noncopyable.h +++ b/src/manager/common/noncopyable.h @@ -22,5 +22,5 @@ #pragma once #define NONCOPYABLE(type) \ - type(const type&) = delete; \ - type& operator=(const type&) = delete; + type(const type&) = delete; \ + type& operator=(const type&) = delete; diff --git a/src/manager/common/openssl_utils.h b/src/manager/common/openssl_utils.h index 83d2525e..a552b22a 100644 --- a/src/manager/common/openssl_utils.h +++ b/src/manager/common/openssl_utils.h @@ -25,19 +25,22 @@ #include <memory> -namespace CKM -{ +namespace CKM { -typedef std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX*)> X509_STORE_CTX_PTR; -typedef std::unique_ptr<STACK_OF(X509), void(*)(STACK_OF(X509)*)> X509_STACK_PTR; +typedef std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)> +X509_STORE_CTX_PTR; +typedef std::unique_ptr<STACK_OF(X509), void(*)(STACK_OF(X509) *)> +X509_STACK_PTR; inline X509_STACK_PTR create_x509_stack() { - return X509_STACK_PTR(sk_X509_new_null(), [](STACK_OF(X509)* stack) { sk_X509_free(stack); }); + return X509_STACK_PTR(sk_X509_new_null(), [](STACK_OF(X509) * stack) { + sk_X509_free(stack); + }); } inline X509_STORE_CTX_PTR create_x509_store_ctx() { - return X509_STORE_CTX_PTR(X509_STORE_CTX_new(), X509_STORE_CTX_free); + return X509_STORE_CTX_PTR(X509_STORE_CTX_new(), X509_STORE_CTX_free); } } // namespace CKM diff --git a/src/manager/common/pkcs12-impl.cpp b/src/manager/common/pkcs12-impl.cpp index a73c0559..c53a3773 100644 --- a/src/manager/common/pkcs12-impl.cpp +++ b/src/manager/common/pkcs12-impl.cpp @@ -34,132 +34,136 @@ namespace CKM { namespace { -typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr; +typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr; } // anonymous namespace -PKCS12Impl::PKCS12Impl(const KeyShPtr &key, const CertificateShPtr &cert, const CertificateShPtrVector &caChain) - : m_pkey(key), - m_cert(cert), - m_ca(caChain) +PKCS12Impl::PKCS12Impl(const KeyShPtr &key, const CertificateShPtr &cert, + const CertificateShPtrVector &caChain) + : m_pkey(key), + m_cert(cert), + m_ca(caChain) { } PKCS12Impl::PKCS12Impl(const RawBuffer &buffer, const Password &password) { - EVP_PKEY *pkey = NULL; - X509 *cert = NULL; - STACK_OF(X509) *ca = NULL; - ::PKCS12 *pkcs12 = NULL; - - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - LogDebug("Start to parse PKCS12"); - - int result = BIO_write(bio.get(), buffer.data(), buffer.size()); - if (result != static_cast<int>(buffer.size())) { - LogError("BIO_write failed. result = " << result << " Expected: " << buffer.size()); - return; - } - - pkcs12 = d2i_PKCS12_bio(bio.get(), NULL); - - if (pkcs12 == NULL) { - LogDebug("d2i_PKCS12_bio failed."); - return; - } - - // needed if parsing is done before manager initialization - initOpenSslOnce(); - - if (!PKCS12_verify_mac(pkcs12, password.c_str(), password.size())) { - LogDebug("Pkcs12 verify failed. Wrong password"); - return; - } - - if (!PKCS12_parse(pkcs12, password.c_str(), &pkey, &cert, &ca)) { - LogError("PKCS12_parse failed"); - return; - } - - if (pkey) { - KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); - switch (EVP_PKEY_type(pkey->type)) { - case EVP_PKEY_RSA: - m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_RSA_PRIVATE); - break; - - case EVP_PKEY_DSA: - m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_DSA_PRIVATE); - break; - - case EVP_PKEY_EC: - m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_ECDSA_PRIVATE); - break; - - default: - LogError("Unsupported private key type."); - EVP_PKEY_free(pkey); - break; - } - } - - if (cert) - m_cert = std::make_shared<CertificateImpl>(cert, false); - - if (ca) { - while (sk_X509_num(ca) > 0) { - X509 *top = sk_X509_pop(ca); - m_ca.push_back(std::make_shared<CertificateImpl>(top, false)); - } - - sk_X509_pop_free(ca, X509_free); - } + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + ::PKCS12 *pkcs12 = NULL; + + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + LogDebug("Start to parse PKCS12"); + + int result = BIO_write(bio.get(), buffer.data(), buffer.size()); + + if (result != static_cast<int>(buffer.size())) { + LogError("BIO_write failed. result = " << result << " Expected: " << + buffer.size()); + return; + } + + pkcs12 = d2i_PKCS12_bio(bio.get(), NULL); + + if (pkcs12 == NULL) { + LogDebug("d2i_PKCS12_bio failed."); + return; + } + + // needed if parsing is done before manager initialization + initOpenSslOnce(); + + if (!PKCS12_verify_mac(pkcs12, password.c_str(), password.size())) { + LogDebug("Pkcs12 verify failed. Wrong password"); + return; + } + + if (!PKCS12_parse(pkcs12, password.c_str(), &pkey, &cert, &ca)) { + LogError("PKCS12_parse failed"); + return; + } + + if (pkey) { + KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); + + switch (EVP_PKEY_type(pkey->type)) { + case EVP_PKEY_RSA: + m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_RSA_PRIVATE); + break; + + case EVP_PKEY_DSA: + m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_DSA_PRIVATE); + break; + + case EVP_PKEY_EC: + m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_ECDSA_PRIVATE); + break; + + default: + LogError("Unsupported private key type."); + EVP_PKEY_free(pkey); + break; + } + } + + if (cert) + m_cert = std::make_shared<CertificateImpl>(cert, false); + + if (ca) { + while (sk_X509_num(ca) > 0) { + X509 *top = sk_X509_pop(ca); + m_ca.push_back(std::make_shared<CertificateImpl>(top, false)); + } + + sk_X509_pop_free(ca, X509_free); + } } PKCS12Impl::PKCS12Impl(PKCS12Impl &&other) : - m_pkey(std::move(other.m_pkey)), - m_cert(std::move(other.m_cert)), - m_ca(std::move(other.m_ca)) + m_pkey(std::move(other.m_pkey)), + m_cert(std::move(other.m_cert)), + m_ca(std::move(other.m_ca)) { } PKCS12Impl &PKCS12Impl::operator=(PKCS12Impl &&other) { - if (this == &other) - return *this; + if (this == &other) + return *this; - m_pkey = std::move(other.m_pkey); - m_cert = std::move(other.m_cert); - m_ca = std::move(other.m_ca); + m_pkey = std::move(other.m_pkey); + m_cert = std::move(other.m_cert); + m_ca = std::move(other.m_ca); - return *this; + return *this; } PKCS12Impl::PKCS12Impl(const PKCS12 &other) : - m_pkey(other.getKey()), - m_cert(other.getCertificate()), - m_ca(other.getCaCertificateShPtrVector()) + m_pkey(other.getKey()), + m_cert(other.getCertificate()), + m_ca(other.getCaCertificateShPtrVector()) { } KeyShPtr PKCS12Impl::getKey() const { - return m_pkey; + return m_pkey; } CertificateShPtr PKCS12Impl::getCertificate() const { - return m_cert; + return m_cert; } CertificateShPtrVector PKCS12Impl::getCaCertificateShPtrVector() const { - return m_ca; + return m_ca; } bool PKCS12Impl::empty() const { - return m_pkey.get() == NULL && m_cert.get() == NULL && m_ca.empty(); + return m_pkey.get() == NULL && m_cert.get() == NULL && m_ca.empty(); } PKCS12Impl::~PKCS12Impl() @@ -168,17 +172,20 @@ PKCS12Impl::~PKCS12Impl() PKCS12ShPtr PKCS12::create(const RawBuffer &rawBuffer, const Password &password) { - try { - auto output = std::make_shared<PKCS12Impl>(rawBuffer, password); - if (output->empty()) - output.reset(); - return output; - } catch (const std::bad_alloc &e) { - LogDebug("Bad alloc was caught during PKCS12 creation"); - } catch (...) { - LogError("Critical error: Unknown exception was caught during PCKS12Impl creation!"); - } - return PKCS12ShPtr(); + try { + auto output = std::make_shared<PKCS12Impl>(rawBuffer, password); + + if (output->empty()) + output.reset(); + + return output; + } catch (const std::bad_alloc &e) { + LogDebug("Bad alloc was caught during PKCS12 creation"); + } catch (...) { + LogError("Critical error: Unknown exception was caught during PCKS12Impl creation!"); + } + + return PKCS12ShPtr(); } } // namespace CKM diff --git a/src/manager/common/pkcs12-impl.h b/src/manager/common/pkcs12-impl.h index 8078d8b8..ff9f0bb7 100644 --- a/src/manager/common/pkcs12-impl.h +++ b/src/manager/common/pkcs12-impl.h @@ -29,28 +29,30 @@ namespace CKM { class COMMON_API PKCS12Impl : public PKCS12 { public: - PKCS12Impl() {} - explicit PKCS12Impl(const PKCS12 &); - PKCS12Impl(const RawBuffer &, const Password &); - PKCS12Impl(const KeyShPtr &, const CertificateShPtr &, const CertificateShPtrVector &); + PKCS12Impl() {} + explicit PKCS12Impl(const PKCS12 &); + PKCS12Impl(const RawBuffer &, const Password &); + PKCS12Impl(const KeyShPtr &, const CertificateShPtr &, + const CertificateShPtrVector &); - PKCS12Impl(PKCS12Impl &&); - PKCS12Impl& operator=(PKCS12Impl &&); + PKCS12Impl(PKCS12Impl &&); + PKCS12Impl &operator=(PKCS12Impl &&); - PKCS12Impl(const PKCS12Impl &) = delete; - PKCS12Impl& operator=(const PKCS12Impl &) = delete; + PKCS12Impl(const PKCS12Impl &) = delete; + PKCS12Impl &operator=(const PKCS12Impl &) = delete; - virtual KeyShPtr getKey() const; - virtual CertificateShPtr getCertificate() const; - virtual CertificateShPtrVector getCaCertificateShPtrVector() const; - virtual bool empty() const; + virtual KeyShPtr getKey() const; + virtual CertificateShPtr getCertificate() const; + virtual CertificateShPtrVector getCaCertificateShPtrVector() const; + virtual bool empty() const; + + virtual ~PKCS12Impl(); - virtual ~PKCS12Impl(); protected: - KeyShPtr m_pkey; - CertificateShPtr m_cert; - CertificateShPtrVector m_ca; + KeyShPtr m_pkey; + CertificateShPtr m_cert; + CertificateShPtrVector m_ca; }; } // namespace CKM diff --git a/src/manager/common/protocols.cpp b/src/manager/common/protocols.cpp index 8e725794..27dbb5fa 100644 --- a/src/manager/common/protocols.cpp +++ b/src/manager/common/protocols.cpp @@ -29,118 +29,139 @@ namespace CKM { -char const * const SERVICE_SOCKET_ECHO = "/tmp/.central-key-manager-echo.sock"; -char const * const SERVICE_SOCKET_CKM_CONTROL = "/tmp/.central-key-manager-api-control.sock"; -char const * const SERVICE_SOCKET_CKM_STORAGE = "/tmp/.central-key-manager-api-storage.sock"; -char const * const SERVICE_SOCKET_OCSP = "/tmp/.central-key-manager-api-ocsp.sock"; -char const * const SERVICE_SOCKET_ENCRYPTION = "/tmp/.central-key-manager-api-encryption.sock"; -char const * const LABEL_NAME_SEPARATOR = " "; -char const * const OWNER_ID_SYSTEM = "/System"; +char const *const SERVICE_SOCKET_ECHO = "/tmp/.central-key-manager-echo.sock"; +char const *const SERVICE_SOCKET_CKM_CONTROL = + "/tmp/.central-key-manager-api-control.sock"; +char const *const SERVICE_SOCKET_CKM_STORAGE = + "/tmp/.central-key-manager-api-storage.sock"; +char const *const SERVICE_SOCKET_OCSP = + "/tmp/.central-key-manager-api-ocsp.sock"; +char const *const SERVICE_SOCKET_ENCRYPTION = + "/tmp/.central-key-manager-api-encryption.sock"; +char const *const LABEL_NAME_SEPARATOR = " "; +char const *const OWNER_ID_SYSTEM = "/System"; PKCS12Serializable::PKCS12Serializable() { } PKCS12Serializable::PKCS12Serializable(const PKCS12 &pkcs) - : PKCS12Impl(pkcs) + : PKCS12Impl(pkcs) { } PKCS12Serializable::PKCS12Serializable(PKCS12Serializable &&other) - : PKCS12Impl(std::move(other)) + : PKCS12Impl(std::move(other)) { } PKCS12Serializable &PKCS12Serializable::operator=(PKCS12Serializable &&other) { - if (this == &other) - return *this; + if (this == &other) + return *this; - m_pkey = std::move(other.m_pkey); - m_cert = std::move(other.m_cert); - m_ca = std::move(other.m_ca); + m_pkey = std::move(other.m_pkey); + m_cert = std::move(other.m_cert); + m_ca = std::move(other.m_ca); - return *this; + return *this; } PKCS12Serializable::PKCS12Serializable(IStream &stream) { - bool keyPresent = false; - Deserialization::Deserialize(stream, keyPresent); - if (keyPresent) { - int keyType; - RawBuffer keyData; - Deserialization::Deserialize(stream, keyType); - Deserialization::Deserialize(stream, keyData); - m_pkey = CKM::Key::create(keyData); - if (m_pkey) - LogDebug("private key from pkcs deserialized success. key size: " << keyData.size() << " and DER size: " << m_pkey->getDER().size()); - else - LogError("private key from pkcs deserialized fail"); - } - - bool certPresent = false; - Deserialization::Deserialize(stream, certPresent); - if (certPresent) { - RawBuffer certData; - Deserialization::Deserialize(stream, certData); - m_cert = CKM::Certificate::create(certData, DataFormat::FORM_DER); - if (m_cert) - LogDebug("certificate from pkcs deserialized success. cert size: " << certData.size() << " and DER size: " << m_cert->getDER().size()); - else - LogError("certificate from pkcs deserialized fail"); - } - - size_t numCA = 0; - Deserialization::Deserialize(stream, numCA); - for (size_t i = 0; i < numCA; i++) { - RawBuffer CAcertData; - Deserialization::Deserialize(stream, CAcertData); - m_ca.emplace_back(CKM::Certificate::create(CAcertData, DataFormat::FORM_DER)); - if (m_pkey) - LogDebug("ca certificate from pkcs deserialized success. cert size: " << CAcertData.size() << " and DER size: " << CKM::Certificate::create(CAcertData, DataFormat::FORM_DER)->getDER().size()); - else - LogError("ca certificate from pkcs deserialized fail"); - } + bool keyPresent = false; + Deserialization::Deserialize(stream, keyPresent); + + if (keyPresent) { + int keyType; + RawBuffer keyData; + Deserialization::Deserialize(stream, keyType); + Deserialization::Deserialize(stream, keyData); + m_pkey = CKM::Key::create(keyData); + + if (m_pkey) + LogDebug("private key from pkcs deserialized success. key size: " << + keyData.size() << " and DER size: " << m_pkey->getDER().size()); + else + LogError("private key from pkcs deserialized fail"); + } + + bool certPresent = false; + Deserialization::Deserialize(stream, certPresent); + + if (certPresent) { + RawBuffer certData; + Deserialization::Deserialize(stream, certData); + m_cert = CKM::Certificate::create(certData, DataFormat::FORM_DER); + + if (m_cert) + LogDebug("certificate from pkcs deserialized success. cert size: " << + certData.size() << " and DER size: " << m_cert->getDER().size()); + else + LogError("certificate from pkcs deserialized fail"); + } + + size_t numCA = 0; + Deserialization::Deserialize(stream, numCA); + + for (size_t i = 0; i < numCA; i++) { + RawBuffer CAcertData; + Deserialization::Deserialize(stream, CAcertData); + m_ca.emplace_back(CKM::Certificate::create(CAcertData, DataFormat::FORM_DER)); + + if (m_pkey) + LogDebug("ca certificate from pkcs deserialized success. cert size: " << + CAcertData.size() << " and DER size: " << CKM::Certificate::create(CAcertData, + DataFormat::FORM_DER)->getDER().size()); + else + LogError("ca certificate from pkcs deserialized fail"); + } } -PKCS12Serializable::PKCS12Serializable(KeyShPtr &&privKey, CertificateShPtr &&cert, CertificateShPtrVector &&chainCerts) +PKCS12Serializable::PKCS12Serializable(KeyShPtr &&privKey, + CertificateShPtr &&cert, CertificateShPtrVector &&chainCerts) { - m_pkey = std::move(privKey); - m_cert = std::move(cert); - m_ca = std::move(chainCerts); + m_pkey = std::move(privKey); + m_cert = std::move(cert); + m_ca = std::move(chainCerts); } void PKCS12Serializable::Serialize(IStream &stream) const { - auto keyPtr = getKey(); - bool isKeyPresent = !!keyPtr; - - // logics if PKCS is correct or not is on the service side. - // sending number of keys and certificates to allow proper parsing on the service side. - // (what if no key or cert present? attempt to deserialize a not present key/cert would - // throw an error and close the connection). - Serialization::Serialize(stream, isKeyPresent); - if (isKeyPresent) { - Serialization::Serialize(stream, DataType(keyPtr->getType())); - Serialization::Serialize(stream, keyPtr->getDER()); - LogDebug("private key from pkcs serialized success. key DER size: " << keyPtr->getDER().size()); - } - - auto certPtr = getCertificate(); - bool isCertPresent = !!certPtr; - Serialization::Serialize(stream, isCertPresent); - if (isCertPresent) { - Serialization::Serialize(stream, certPtr->getDER()); - LogDebug("certificate from pkcs serialized success. cert DER size: " << certPtr->getDER().size()); - } - - auto caCertPtrVec = getCaCertificateShPtrVector(); - Serialization::Serialize(stream, caCertPtrVec.size()); - for (auto &caCertPtr : getCaCertificateShPtrVector()) { - Serialization::Serialize(stream, caCertPtr->getDER()); - LogDebug("ca certificate from pkcs serialized success. cert DER size: " << caCertPtr->getDER().size()); - } + auto keyPtr = getKey(); + bool isKeyPresent = !!keyPtr; + + // logics if PKCS is correct or not is on the service side. + // sending number of keys and certificates to allow proper parsing on the service side. + // (what if no key or cert present? attempt to deserialize a not present key/cert would + // throw an error and close the connection). + Serialization::Serialize(stream, isKeyPresent); + + if (isKeyPresent) { + Serialization::Serialize(stream, DataType(keyPtr->getType())); + Serialization::Serialize(stream, keyPtr->getDER()); + LogDebug("private key from pkcs serialized success. key DER size: " << + keyPtr->getDER().size()); + } + + auto certPtr = getCertificate(); + bool isCertPresent = !!certPtr; + Serialization::Serialize(stream, isCertPresent); + + if (isCertPresent) { + Serialization::Serialize(stream, certPtr->getDER()); + LogDebug("certificate from pkcs serialized success. cert DER size: " << + certPtr->getDER().size()); + } + + auto caCertPtrVec = getCaCertificateShPtrVector(); + Serialization::Serialize(stream, caCertPtrVec.size()); + + for (auto &caCertPtr : getCaCertificateShPtrVector()) { + Serialization::Serialize(stream, caCertPtr->getDER()); + LogDebug("ca certificate from pkcs serialized success. cert DER size: " << + caCertPtr->getDER().size()); + } }; @@ -148,62 +169,68 @@ CryptoAlgorithmSerializable::CryptoAlgorithmSerializable() { } -CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(const CryptoAlgorithm &algo) : - CryptoAlgorithm(algo) +CryptoAlgorithmSerializable::CryptoAlgorithmSerializable( + const CryptoAlgorithm &algo) : + CryptoAlgorithm(algo) { } CryptoAlgorithmSerializable::CryptoAlgorithmSerializable(IStream &stream) { - size_t plen = 0; - Deserializer<size_t>::Deserialize(stream, plen); - while (plen) { - ParamName name; - uint64_t integer; - RawBuffer buffer; - int tmpName; - Deserializer<int>::Deserialize(stream, tmpName); - name = static_cast<ParamName>(tmpName); - switch (name) { - case ParamName::ED_IV: - case ParamName::ED_AAD: - case ParamName::ED_LABEL: - Deserializer<RawBuffer>::Deserialize(stream, buffer); - setParam(name, buffer); - break; - - case ParamName::ALGO_TYPE: - case ParamName::ED_CTR_LEN: - case ParamName::ED_TAG_LEN: - case ParamName::GEN_KEY_LEN: - case ParamName::GEN_EC: - case ParamName::SV_HASH_ALGO: - case ParamName::SV_RSA_PADDING: - Deserializer<uint64_t>::Deserialize(stream, integer); - setParam(name, integer); - break; - - default: - ThrowMsg(UnsupportedParam, "Unsupported param name"); - } - plen--; - } + size_t plen = 0; + Deserializer<size_t>::Deserialize(stream, plen); + + while (plen) { + ParamName name; + uint64_t integer; + RawBuffer buffer; + int tmpName; + Deserializer<int>::Deserialize(stream, tmpName); + name = static_cast<ParamName>(tmpName); + + switch (name) { + case ParamName::ED_IV: + case ParamName::ED_AAD: + case ParamName::ED_LABEL: + Deserializer<RawBuffer>::Deserialize(stream, buffer); + setParam(name, buffer); + break; + + case ParamName::ALGO_TYPE: + case ParamName::ED_CTR_LEN: + case ParamName::ED_TAG_LEN: + case ParamName::GEN_KEY_LEN: + case ParamName::GEN_EC: + case ParamName::SV_HASH_ALGO: + case ParamName::SV_RSA_PADDING: + Deserializer<uint64_t>::Deserialize(stream, integer); + setParam(name, integer); + break; + + default: + ThrowMsg(UnsupportedParam, "Unsupported param name"); + } + + plen--; + } } void CryptoAlgorithmSerializable::Serialize(IStream &stream) const { - Serializer<size_t>::Serialize(stream, m_params.size()); - for (const auto& it : m_params) { - Serializer<int>::Serialize(stream, static_cast<int>(it.first)); - uint64_t integer; - RawBuffer buffer; - if (it.second->getInt(integer)) - Serializer<uint64_t>::Serialize(stream, integer); - else if (it.second->getBuffer(buffer)) - Serializer<RawBuffer>::Serialize(stream, buffer); - else - ThrowMsg(UnsupportedParam, "Unsupported param type"); - } + Serializer<size_t>::Serialize(stream, m_params.size()); + + for (const auto &it : m_params) { + Serializer<int>::Serialize(stream, static_cast<int>(it.first)); + uint64_t integer; + RawBuffer buffer; + + if (it.second->getInt(integer)) + Serializer<uint64_t>::Serialize(stream, integer); + else if (it.second->getBuffer(buffer)) + Serializer<RawBuffer>::Serialize(stream, buffer); + else + ThrowMsg(UnsupportedParam, "Unsupported param type"); + } } } // namespace CKM diff --git a/src/manager/common/protocols.h b/src/manager/common/protocols.h index de108f36..3294ef2e 100644 --- a/src/manager/common/protocols.h +++ b/src/manager/common/protocols.h @@ -35,98 +35,97 @@ namespace CKM { -COMMON_API extern char const * const SERVICE_SOCKET_ECHO; -COMMON_API extern char const * const SERVICE_SOCKET_CKM_CONTROL; -COMMON_API extern char const * const SERVICE_SOCKET_CKM_STORAGE; -COMMON_API extern char const * const SERVICE_SOCKET_OCSP; -COMMON_API extern char const * const SERVICE_SOCKET_ENCRYPTION; +COMMON_API extern char const *const SERVICE_SOCKET_ECHO; +COMMON_API extern char const *const SERVICE_SOCKET_CKM_CONTROL; +COMMON_API extern char const *const SERVICE_SOCKET_CKM_STORAGE; +COMMON_API extern char const *const SERVICE_SOCKET_OCSP; +COMMON_API extern char const *const SERVICE_SOCKET_ENCRYPTION; enum class ControlCommand : int { - UNLOCK_USER_KEY, - LOCK_USER_KEY, - REMOVE_USER_DATA, - CHANGE_USER_PASSWORD, - RESET_USER_PASSWORD, - REMOVE_APP_DATA, - UPDATE_CC_MODE, - SET_PERMISSION + UNLOCK_USER_KEY, + LOCK_USER_KEY, + REMOVE_USER_DATA, + CHANGE_USER_PASSWORD, + RESET_USER_PASSWORD, + REMOVE_APP_DATA, + UPDATE_CC_MODE, + SET_PERMISSION }; enum class LogicCommand : int { - GET, - GET_LIST, - SAVE, - REMOVE, - CREATE_KEY_AES, - CREATE_KEY_PAIR, - GET_CHAIN_CERT, - GET_CHAIN_ALIAS, - CREATE_SIGNATURE, - VERIFY_SIGNATURE, - SET_PERMISSION, - SAVE_PKCS12, - GET_PKCS12 + GET, + GET_LIST, + SAVE, + REMOVE, + CREATE_KEY_AES, + CREATE_KEY_PAIR, + GET_CHAIN_CERT, + GET_CHAIN_ALIAS, + CREATE_SIGNATURE, + VERIFY_SIGNATURE, + SET_PERMISSION, + SAVE_PKCS12, + GET_PKCS12 }; enum class EncryptionCommand : int { - ENCRYPT, - DECRYPT + ENCRYPT, + DECRYPT }; // (client side) Alias = (service side) Label::Name -COMMON_API extern char const * const LABEL_NAME_SEPARATOR; -COMMON_API extern char const * const OWNER_ID_SYSTEM; +COMMON_API extern char const *const LABEL_NAME_SEPARATOR; +COMMON_API extern char const *const OWNER_ID_SYSTEM; typedef std::string Name; -typedef std::vector<std::pair<Label, Name> > LabelNameVector; +typedef std::vector<std::pair<Label, Name>> LabelNameVector; class IStream; struct COMMON_API PolicySerializable : public Policy, ISerializable { - PolicySerializable() {}; - explicit PolicySerializable(const Policy &policy) : Policy(policy) - { - } - - explicit PolicySerializable(IStream &stream) - { - Deserialization::Deserialize(stream, password); - Deserialization::Deserialize(stream, extractable); - } - - void Serialize(IStream &stream) const - { - Serialization::Serialize(stream, password); - Serialization::Serialize(stream, extractable); - } + PolicySerializable() {} + explicit PolicySerializable(const Policy &policy) : Policy(policy) {} + + explicit PolicySerializable(IStream &stream) + { + Deserialization::Deserialize(stream, password); + Deserialization::Deserialize(stream, extractable); + } + + void Serialize(IStream &stream) const + { + Serialization::Serialize(stream, password); + Serialization::Serialize(stream, extractable); + } }; struct COMMON_API PKCS12Serializable : public PKCS12Impl, ISerializable { - PKCS12Serializable(); + PKCS12Serializable(); - PKCS12Serializable(const PKCS12Serializable &) = delete; - PKCS12Serializable &operator=(const PKCS12Serializable &) = delete; + PKCS12Serializable(const PKCS12Serializable &) = delete; + PKCS12Serializable &operator=(const PKCS12Serializable &) = delete; - PKCS12Serializable(PKCS12Serializable &&); - PKCS12Serializable &operator=(PKCS12Serializable &&); + PKCS12Serializable(PKCS12Serializable &&); + PKCS12Serializable &operator=(PKCS12Serializable &&); - explicit PKCS12Serializable(const PKCS12 &); - explicit PKCS12Serializable(IStream &); - PKCS12Serializable(KeyShPtr &&privKey, - CertificateShPtr &&cert, - CertificateShPtrVector &&chainCerts); - void Serialize(IStream &) const; + explicit PKCS12Serializable(const PKCS12 &); + explicit PKCS12Serializable(IStream &); + PKCS12Serializable(KeyShPtr &&privKey, + CertificateShPtr &&cert, + CertificateShPtrVector &&chainCerts); + void Serialize(IStream &) const; }; -struct COMMON_API CryptoAlgorithmSerializable : public CryptoAlgorithm, ISerializable { - DECLARE_EXCEPTION_TYPE(Exception, Base); - DECLARE_EXCEPTION_TYPE(Exception, UnsupportedParam); +struct COMMON_API CryptoAlgorithmSerializable : public CryptoAlgorithm, + ISerializable { + DECLARE_EXCEPTION_TYPE(Exception, Base); + DECLARE_EXCEPTION_TYPE(Exception, UnsupportedParam); - CryptoAlgorithmSerializable(); - explicit CryptoAlgorithmSerializable(const CryptoAlgorithm &); - explicit CryptoAlgorithmSerializable(IStream &); + CryptoAlgorithmSerializable(); + explicit CryptoAlgorithmSerializable(const CryptoAlgorithm &); + explicit CryptoAlgorithmSerializable(IStream &); - void Serialize(IStream &) const; + void Serialize(IStream &) const; }; } // namespace CKM diff --git a/src/manager/common/stringify.h b/src/manager/common/stringify.h index 60265c8b..64edfa6d 100644 --- a/src/manager/common/stringify.h +++ b/src/manager/common/stringify.h @@ -31,48 +31,48 @@ class StringifyBasic; template <> class StringifyBasic<false> { - StringifyBasic() = delete; + StringifyBasic() = delete; + public: - static std::string Merge() - { - return std::string(); - } + static std::string Merge() + { + return std::string(); + } - template <typename... Args> - static std::string Merge(const Args&...) - { - return std::string(); - } + template <typename... Args> + static std::string Merge(const Args &...) + { + return std::string(); + } }; template <> class StringifyBasic<true> { - StringifyBasic() = delete; + StringifyBasic() = delete; - static void Concatenate(std::ostringstream&) - { - } + static void Concatenate(std::ostringstream &) {} - template <typename t, typename... Args> - static void Concatenate(std::ostringstream& stream, const t& arg1, const Args&... args) - { - stream << arg1; - Concatenate(stream, args...); - } + template <typename t, typename... Args> + static void Concatenate(std::ostringstream &stream, const t &arg1, + const Args &... args) + { + stream << arg1; + Concatenate(stream, args...); + } public: - static std::string Merge() - { - return std::string(); - } + static std::string Merge() + { + return std::string(); + } - template <typename T, typename... Args> - static std::string Merge(const T& arg1, const Args&... args) - { - std::ostringstream stream; - Concatenate(stream, arg1, args...); - return stream.str(); - } + template <typename T, typename... Args> + static std::string Merge(const T &arg1, const Args &... args) + { + std::ostringstream stream; + Concatenate(stream, arg1, args...); + return stream.str(); + } }; #ifdef DEBUG @@ -81,12 +81,11 @@ public: #define DEBUG_STATUS false #endif -typedef StringifyBasic<true> Stringify; -typedef StringifyBasic<false> StringifyAvoid; -typedef StringifyBasic<true> StringifyError; -typedef StringifyBasic<DEBUG_STATUS> StringifyDebug; +using Stringify = StringifyBasic<true>; +using StringifyAvoid = StringifyBasic<false>; +using StringifyError = StringifyBasic<true>; +using StringifyDebug = StringifyBasic<DEBUG_STATUS>; #undef DEBUG_STATUS } // namespace CKM - diff --git a/src/manager/crypto/generic-backend/algo-validation.h b/src/manager/crypto/generic-backend/algo-validation.h index b51f23de..b4621df0 100644 --- a/src/manager/crypto/generic-backend/algo-validation.h +++ b/src/manager/crypto/generic-backend/algo-validation.h @@ -34,14 +34,15 @@ namespace Crypto { template<typename T> T unpack( - const CryptoAlgorithm &alg, - ParamName paramName) + const CryptoAlgorithm &alg, + ParamName paramName) { - T result; - if (!alg.getParam(paramName, result)) - ThrowErr(Exc::Crypto::InputParam, "Wrong input param"); + T result; - return result; + if (!alg.getParam(paramName, result)) + ThrowErr(Exc::Crypto::InputParam, "Wrong input param"); + + return result; } @@ -50,51 +51,63 @@ T unpack( // Always validates as true. Useful for checking parameter existence only template <typename T> struct DefaultValidator { - static bool Check(const T&) { return true; } - static void Why(std::ostringstream& os) { os << "is ok"; } + static bool Check(const T &) + { + return true; + } + static void Why(std::ostringstream &os) + { + os << "is ok"; + } }; // Validates as true if parameter value is equal to one of Args template <typename T> struct Type { - template <T ...Args> - struct Equals; - - template <T First> - struct Equals<First> { - public: - static bool Check(const T& value) - { - return First == value; - } - - static void Why(std::ostringstream& os) - { - os << "doesn't match " << static_cast<int>(First); - } - }; - - template <T First, T ...Args> - struct Equals<First, Args...> : public Equals<First>, public Equals<Args...> { - public: - static bool Check(const T& value) - { - return Equals<First>::Check(value) || Equals<Args...>::Check(value); - } - - static void Why(std::ostringstream& os) - { - Equals<First>::Why(os); - os << ", "; - Equals<Args...>::Why(os); - } - }; + template <T ...Args> + struct Equals; + + template <T First> + struct Equals<First> { + public: + static bool Check(const T &value) + { + return First == value; + } + + static void Why(std::ostringstream &os) + { + os << "doesn't match " << static_cast<int>(First); + } + }; + + template <T First, T ...Args> + struct Equals<First, Args...> : public Equals<First>, public Equals<Args...> { + public: + static bool Check(const T &value) + { + return Equals<First>::Check(value) || Equals<Args...>::Check(value); + } + + static void Why(std::ostringstream &os) + { + Equals<First>::Why(os); + os << ", "; + Equals<Args...>::Why(os); + } + }; }; template <typename T> struct Unsupported { - static bool Check(const T&) { return false; } - static void Why(std::ostringstream& os) { os << "is not supported"; } + static bool Check(const T &) + { + return false; + } + static void Why(std::ostringstream &os) + { + os << "is not supported"; + } }; @@ -103,38 +116,58 @@ struct Unsupported { // simply returns parameter value template <typename T> struct DefaultGetter { - static T Get(const T& value) { return value; } - static void What(std::ostringstream& os) { os << "value"; } - static void Print(std::ostringstream& os, const T& value) { os << static_cast<int>(value); } + static T Get(const T &value) + { + return value; + } + static void What(std::ostringstream &os) + { + os << "value"; + } + static void Print(std::ostringstream &os, const T &value) + { + os << static_cast<int>(value); + } }; template <> -void DefaultGetter<RawBuffer>::Print(std::ostringstream& os, const RawBuffer& buffer) { - os << "[" << buffer.size() << "B buffer]"; +void DefaultGetter<RawBuffer>::Print(std::ostringstream &os, + const RawBuffer &buffer) +{ + os << "[" << buffer.size() << "B buffer]"; } // returns buffer param size struct BufferSizeGetter { - static size_t Get(const RawBuffer& buffer) { return buffer.size(); } - static void What(std::ostringstream& os) { os << "buffer size"; } - static void Print(std::ostringstream& os, const RawBuffer& buffer) { os << buffer.size(); } + static size_t Get(const RawBuffer &buffer) + { + return buffer.size(); + } + static void What(std::ostringstream &os) + { + os << "buffer size"; + } + static void Print(std::ostringstream &os, const RawBuffer &buffer) + { + os << buffer.size(); + } }; ////////// ErrorHandlers ////////////// struct ThrowingHandler { - static void Handle(std::string message) - { - ThrowErr(Exc::Crypto::InputParam, message); - } + static void Handle(std::string message) + { + ThrowErr(Exc::Crypto::InputParam, message); + } }; // base class for parameter check struct ParamCheckBase { - virtual ~ParamCheckBase() {} - virtual void Check(const CryptoAlgorithm& ca) const = 0; + virtual ~ParamCheckBase() {} + virtual void Check(const CryptoAlgorithm &ca) const = 0; }; typedef std::unique_ptr<const ParamCheckBase> ParamCheckBasePtr; @@ -148,42 +181,43 @@ struct VBuilder; template <> struct VBuilder<> { - static ValidatorVector Build() - { - return ValidatorVector(); - } + static ValidatorVector Build() + { + return ValidatorVector(); + } }; template <typename First> struct VBuilder<First> { - static ValidatorVector Build() - { - ValidatorVector validators; - Add(validators); - return validators; - } + static ValidatorVector Build() + { + ValidatorVector validators; + Add(validators); + return validators; + } protected: - static void Add(ValidatorVector& validators) - { - validators.emplace_back(new First); - } + static void Add(ValidatorVector &validators) + { + validators.emplace_back(new First); + } }; template <typename First, typename ...Args> -struct VBuilder<First, Args...> : public VBuilder<First>, public VBuilder<Args...> { - static ValidatorVector Build() - { - ValidatorVector validators; - Add(validators); - return validators; - } +struct VBuilder<First, Args...> : public VBuilder<First>, + public VBuilder<Args...> { + static ValidatorVector Build() + { + ValidatorVector validators; + Add(validators); + return validators; + } protected: - static void Add(ValidatorVector& validators) - { - VBuilder<First>::Add(validators); - VBuilder<Args...>::Add(validators); - } + static void Add(ValidatorVector &validators) + { + VBuilder<First>::Add(validators); + VBuilder<Args...>::Add(validators); + } }; /* @@ -198,36 +232,38 @@ protected: */ template <ParamName Name, - typename Type, - bool Mandatory, - typename Validator = DefaultValidator<Type>, - typename Getter = DefaultGetter<Type>, - typename ErrorHandler = ThrowingHandler> + typename Type, + bool Mandatory, + typename Validator = DefaultValidator<Type>, + typename Getter = DefaultGetter<Type>, + typename ErrorHandler = ThrowingHandler> struct ParamCheck : public ParamCheckBase { - void Check(const CryptoAlgorithm& ca) const - { - Type value; - std::ostringstream os; - - // check existence - if (!ca.getParam(Name, value)) { - if (Mandatory) { - os << "Mandatory parameter " << static_cast<int>(Name) << " doesn't exist"; - ErrorHandler::Handle(os.str()); - } - return; - } - // validate - if (!Validator::Check(Getter::Get(value))) { - os << "The "; - Getter::What(os); - os << " of param '" << static_cast<int>(Name) << "'="; - Getter::Print(os, value); - os << " "; - Validator::Why(os); - ErrorHandler::Handle(os.str()); - } - } + void Check(const CryptoAlgorithm &ca) const + { + Type value; + std::ostringstream os; + + // check existence + if (!ca.getParam(Name, value)) { + if (Mandatory) { + os << "Mandatory parameter " << static_cast<int>(Name) << " doesn't exist"; + ErrorHandler::Handle(os.str()); + } + + return; + } + + // validate + if (!Validator::Check(Getter::Get(value))) { + os << "The "; + Getter::What(os); + os << " of param '" << static_cast<int>(Name) << "'="; + Getter::Print(os, value); + os << " "; + Validator::Why(os); + ErrorHandler::Handle(os.str()); + } + } }; } // namespace Crypto diff --git a/src/manager/crypto/generic-backend/gobj.h b/src/manager/crypto/generic-backend/gobj.h index fc779fb8..9da3b887 100644 --- a/src/manager/crypto/generic-backend/gobj.h +++ b/src/manager/crypto/generic-backend/gobj.h @@ -32,37 +32,38 @@ namespace Crypto { class GObj { protected: - GObj() {} + GObj() {} public: - virtual RawBuffer getBinary() const - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } + virtual RawBuffer getBinary() const + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } - virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } + virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } - virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } + virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } - virtual RawBuffer sign(const CryptoAlgorithm &, const RawBuffer &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } + virtual RawBuffer sign(const CryptoAlgorithm &, const RawBuffer &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } - virtual int verify(const CryptoAlgorithm &, const RawBuffer &, const RawBuffer &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } + virtual int verify(const CryptoAlgorithm &, const RawBuffer &, + const RawBuffer &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } - virtual ~GObj() - { - } + virtual ~GObj() + { + } }; typedef std::unique_ptr<GObj> GObjUPtr; diff --git a/src/manager/crypto/generic-backend/gstore.h b/src/manager/crypto/generic-backend/gstore.h index 5ada1665..d66d9eae 100644 --- a/src/manager/crypto/generic-backend/gstore.h +++ b/src/manager/crypto/generic-backend/gstore.h @@ -33,58 +33,61 @@ namespace Crypto { // Data is very generic and does not say anything about content. struct Data { - Data() {}; - Data(const DataType& t, RawBuffer d) : type(t), data(std::move(d)) {} - DataType type; - RawBuffer data; // buffer will be better? + Data() {}; + Data(const DataType &t, RawBuffer d) : type(t), data(std::move(d)) {} + DataType type; + RawBuffer data; // buffer will be better? }; // Too generic. The name does not say anything aobut content. struct DataEncryption { - DataEncryption() {}; - DataEncryption(RawBuffer encKey, RawBuffer ivector) - : encryptedKey(std::move(encKey)) - , iv(std::move(ivector)) - {} - RawBuffer encryptedKey; - RawBuffer iv; + DataEncryption() {} + DataEncryption(RawBuffer encKey, RawBuffer ivector) + : encryptedKey(std::move(encKey)) + , iv(std::move(ivector)) + { + } + RawBuffer encryptedKey; + RawBuffer iv; }; class GStore { public: - virtual GObjUPtr getObject(const Token &, const Password &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } - virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, const Password &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } - virtual Token generateSKey(const CryptoAlgorithm &, const Password &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } - virtual Token import(const Data &, const Password &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } - virtual Token importEncrypted(const Data &, const Password &, const DataEncryption &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } - virtual void destroy(const Token &) - { - ThrowErr(Exc::Crypto::OperationNotSupported); - } - virtual ~GStore() {} + virtual GObjUPtr getObject(const Token &, const Password &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } + virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, + const Password &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } + virtual Token generateSKey(const CryptoAlgorithm &, const Password &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } + virtual Token import(const Data &, const Password &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } + virtual Token importEncrypted(const Data &, const Password &, + const DataEncryption &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } + virtual void destroy(const Token &) + { + ThrowErr(Exc::Crypto::OperationNotSupported); + } + virtual ~GStore() {} protected: - explicit GStore(CryptoBackend backendId) : - m_backendId(backendId) - { - } + explicit GStore(CryptoBackend backendId) : + m_backendId(backendId) + { + } - CryptoBackend m_backendId; + CryptoBackend m_backendId; }; } // namespace Crypto diff --git a/src/manager/crypto/platform/decider.cpp b/src/manager/crypto/platform/decider.cpp index 6c6dc963..c986f4ea 100644 --- a/src/manager/crypto/platform/decider.cpp +++ b/src/manager/crypto/platform/decider.cpp @@ -32,62 +32,65 @@ namespace CKM { namespace Crypto { namespace { -CryptoBackend chooseCryptoBackend(DataType dataType, bool exportable, bool encrypted) +CryptoBackend chooseCryptoBackend(DataType dataType, bool exportable, + bool encrypted) { -// Only software backend supports device encyption key - if (encrypted) - return CryptoBackend::OpenSSL; + // Only software backend supports device encyption key + if (encrypted) + return CryptoBackend::OpenSSL; -// The list of items that MUST be support by OpenSSL - if (dataType.isCertificate()) - return CryptoBackend::OpenSSL; + // The list of items that MUST be support by OpenSSL + if (dataType.isCertificate()) + return CryptoBackend::OpenSSL; - if (dataType.isBinaryData()) - return CryptoBackend::OpenSSL; + if (dataType.isBinaryData()) + return CryptoBackend::OpenSSL; - if (exportable) - return CryptoBackend::OpenSSL; + if (exportable) + return CryptoBackend::OpenSSL; -// This is the place where we can use trust zone backend -// Examples: -// -// if (dataType.isKeyPrivate()) -// return CryptoBackend::TrustZone; + // This is the place where we can use trust zone backend + // Examples: + // + // if (dataType.isKeyPrivate()) + // return CryptoBackend::TrustZone; -// This item does not met Trust Zone requirements. Let's use software backend - return CryptoBackend::OpenSSL; + // This item does not met Trust Zone requirements. Let's use software backend + return CryptoBackend::OpenSSL; } } // namespace Decider::Decider() - : m_swStore(new SW::Store(CryptoBackend::OpenSSL)) - , m_tzStore(new TZ::Store(CryptoBackend::TrustZone)) + : m_swStore(new SW::Store(CryptoBackend::OpenSSL)) + , m_tzStore(new TZ::Store(CryptoBackend::TrustZone)) { } -GStore& Decider::getStore(const Token &token) const +GStore &Decider::getStore(const Token &token) const { - return getStore(token.backendId); + return getStore(token.backendId); }; -GStore& Decider::getStore(CryptoBackend cryptoBackend) const +GStore &Decider::getStore(CryptoBackend cryptoBackend) const { - GStore *gStore = NULL; - if (cryptoBackend == CryptoBackend::OpenSSL) - gStore = m_swStore.get(); - if (cryptoBackend == CryptoBackend::TrustZone) - gStore = m_tzStore.get(); + GStore *gStore = NULL; - if (gStore) - return *gStore; + if (cryptoBackend == CryptoBackend::OpenSSL) + gStore = m_swStore.get(); - ThrowErr(Exc::Crypto::InternalError, - "Backend not available. BackendId: ", (int)cryptoBackend); + if (cryptoBackend == CryptoBackend::TrustZone) + gStore = m_tzStore.get(); + + if (gStore) + return *gStore; + + ThrowErr(Exc::Crypto::InternalError, + "Backend not available. BackendId: ", (int)cryptoBackend); } -GStore& Decider::getStore(DataType data, bool exportable, bool encrypted) const +GStore &Decider::getStore(DataType data, bool exportable, bool encrypted) const { - return getStore(chooseCryptoBackend(data, exportable, encrypted)); + return getStore(chooseCryptoBackend(data, exportable, encrypted)); } } // namespace Crypto diff --git a/src/manager/crypto/platform/decider.h b/src/manager/crypto/platform/decider.h index 5e48791e..184f698a 100644 --- a/src/manager/crypto/platform/decider.h +++ b/src/manager/crypto/platform/decider.h @@ -34,17 +34,17 @@ namespace Crypto { class Decider { public: - Decider(); - GStore& getStore(const Token &token) const; - GStore& getStore(DataType data, bool exportable, bool encrypted = false) const; + Decider(); + GStore &getStore(const Token &token) const; + GStore &getStore(DataType data, bool exportable, bool encrypted = false) const; - virtual ~Decider() {} + virtual ~Decider() {} protected: - GStore& getStore(CryptoBackend id) const; + GStore &getStore(CryptoBackend id) const; - std::unique_ptr<GStore> m_swStore; - std::unique_ptr<GStore> m_tzStore; + std::unique_ptr<GStore> m_swStore; + std::unique_ptr<GStore> m_tzStore; }; } // Crypto diff --git a/src/manager/crypto/sw-backend/crypto.h b/src/manager/crypto/sw-backend/crypto.h index ab3b17e4..99251972 100644 --- a/src/manager/crypto/sw-backend/crypto.h +++ b/src/manager/crypto/sw-backend/crypto.h @@ -36,93 +36,102 @@ namespace Cipher { template<class T> struct Base { - Base() - : m_ctx(EVP_CIPHER_CTX_new()) - { - static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside conatainer."); - } - Base(const Base&) = delete; - Base(Base &&) = delete; - Base<T>& operator=(const Base&) = delete; - Base<T>& operator=(Base &&) = delete; - - // Low level api. - // Allows various cipher specific parameters to be determined and set. - int Control(int type, int arg, void *ptr) - { - return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr); - } - - virtual void AppendAAD(const T&) = 0; - virtual T Append(const T&) = 0; - virtual T Finalize() = 0; - virtual ~Base() - { - EVP_CIPHER_CTX_free(m_ctx); - } + Base() : m_ctx(EVP_CIPHER_CTX_new()) + { + static_assert(sizeof(typename T::value_type) == 1, + "Unsupported type inside conatainer."); + } + Base(const Base &) = delete; + Base(Base &&) = delete; + Base<T> &operator=(const Base &) = delete; + Base<T> &operator=(Base &&) = delete; + + // Low level api. + // Allows various cipher specific parameters to be determined and set. + int Control(int type, int arg, void *ptr) + { + return EVP_CIPHER_CTX_ctrl(m_ctx, type, arg, ptr); + } + + virtual void AppendAAD(const T &) = 0; + virtual T Append(const T &) = 0; + virtual T Finalize() = 0; + virtual ~Base() + { + EVP_CIPHER_CTX_free(m_ctx); + } protected: - EVP_CIPHER_CTX *m_ctx; + EVP_CIPHER_CTX *m_ctx; }; template<class T> class EvpCipherWrapper : public Base<T> { public: - using Base<T>::m_ctx; - - EvpCipherWrapper(const EVP_CIPHER *type, const T &key, const T &iv, bool encryption) - { - if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type)) - ThrowErr(Exc::Crypto::InternalError, "Wrong key size! Expected: ", EVP_CIPHER_key_length(type), " Get: ", key.size()); - - if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type)) - ThrowErr(Exc::Crypto::InternalError, "Wrong iv size! Expected: ", EVP_CIPHER_iv_length(type), " Get: ", iv.size()); - - if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), encryption ? 1 : 0)) - ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherInit"); - - EVP_CIPHER_CTX_set_padding(m_ctx, 1); - } - - void AppendAAD(const T& data) - { - static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container."); - int bytesLen; - if (1 != EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size())) - ThrowErr(Exc::Crypto::InternalError, "AppendAAD(): Failed in EVP_CipherUpdate"); - } - - T Append(const T& data) - { - static_assert(sizeof(typename T::value_type) == 1, "Unsupported type inside container."); - int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx)); - T output(bytesLen); - if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), data.size())) - ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate"); - - output.resize(bytesLen); - return output; - } - - T Finalize() - { - int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx); - T output(bytesLen); - if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)) - ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherFinal"); - - output.resize(bytesLen); - return output; - } + using Base<T>::m_ctx; + + EvpCipherWrapper(const EVP_CIPHER *type, const T &key, const T &iv, + bool encryption) + { + if (static_cast<int>(key.size()) != EVP_CIPHER_key_length(type)) + ThrowErr(Exc::Crypto::InternalError, "Wrong key size! Expected: ", + EVP_CIPHER_key_length(type), " Get: ", key.size()); + + if (static_cast<int>(iv.size()) < EVP_CIPHER_iv_length(type)) + ThrowErr(Exc::Crypto::InternalError, "Wrong iv size! Expected: ", + EVP_CIPHER_iv_length(type), " Get: ", iv.size()); + + if (1 != EVP_CipherInit_ex(m_ctx, type, NULL, key.data(), iv.data(), + encryption ? 1 : 0)) + ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherInit"); + + EVP_CIPHER_CTX_set_padding(m_ctx, 1); + } + + void AppendAAD(const T &data) + { + static_assert(sizeof(typename T::value_type) == 1, + "Unsupported type inside container."); + int bytesLen; + + if (1 != EVP_CipherUpdate(m_ctx, NULL, &bytesLen, data.data(), data.size())) + ThrowErr(Exc::Crypto::InternalError, "AppendAAD(): Failed in EVP_CipherUpdate"); + } + + T Append(const T &data) + { + static_assert(sizeof(typename T::value_type) == 1, + "Unsupported type inside container."); + int bytesLen = static_cast<int>(data.size() + EVP_CIPHER_CTX_block_size(m_ctx)); + T output(bytesLen); + + if (1 != EVP_CipherUpdate(m_ctx, output.data(), &bytesLen, data.data(), + data.size())) + ThrowErr(Exc::Crypto::InternalError, "Append(): Failed in EVP_CipherUpdate"); + + output.resize(bytesLen); + return output; + } + + T Finalize() + { + int bytesLen = EVP_CIPHER_CTX_block_size(m_ctx); + T output(bytesLen); + + if (1 != EVP_CipherFinal_ex(m_ctx, output.data(), &bytesLen)) + ThrowErr(Exc::Crypto::InternalError, "Failed in EVP_CipherFinal"); + + output.resize(bytesLen); + return output; + } }; #define DEFINE_CIPHER(__classname, __type, __evpcipher, __encryption) \ -class __classname : public EvpCipherWrapper<__type> { \ -public: \ - __classname(const __type &key, const __type &iv) \ - : EvpCipherWrapper(__evpcipher, key, iv, __encryption) \ - {} \ -} + class __classname : public EvpCipherWrapper<__type> { \ + public: \ + __classname(const __type &key, const __type &iv) : \ + EvpCipherWrapper(__evpcipher, key, iv, __encryption) {} \ + } DEFINE_CIPHER(AesCbcEncryption128, RawBuffer, EVP_aes_128_cbc(), true); DEFINE_CIPHER(AesCbcDecryption128, RawBuffer, EVP_aes_128_cbc(), false); diff --git a/src/manager/crypto/sw-backend/internals.cpp b/src/manager/crypto/sw-backend/internals.cpp index cabb094a..b6f725c2 100644 --- a/src/manager/crypto/sw-backend/internals.cpp +++ b/src/manager/crypto/sw-backend/internals.cpp @@ -52,953 +52,1041 @@ namespace SW { namespace Internals { namespace { -typedef std::unique_ptr<EVP_MD_CTX, std::function<void(EVP_MD_CTX*)>> EvpMdCtxUPtr; -typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX*)>> EvpPkeyCtxUPtr; -typedef std::unique_ptr<EVP_PKEY, std::function<void(EVP_PKEY*)>> EvpPkeyUPtr; +typedef std::unique_ptr<EVP_MD_CTX, std::function<void(EVP_MD_CTX *)>> + EvpMdCtxUPtr; +typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX *)>> + EvpPkeyCtxUPtr; +typedef std::unique_ptr<EVP_PKEY, std::function<void(EVP_PKEY *)>> EvpPkeyUPtr; -typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr; -typedef int(*I2D_CONV)(BIO*, EVP_PKEY*); +typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr; +typedef int(*I2D_CONV)(BIO *, EVP_PKEY *); -const size_t DEFAULT_AES_GCM_TAG_LEN = 128; // tag length in bits according to W3C Crypto API +const size_t DEFAULT_AES_GCM_TAG_LEN = + 128; // tag length in bits according to W3C Crypto API const size_t DEFAULT_AES_IV_LEN = 16; // default iv size in bytes for AES -RawBuffer i2d(I2D_CONV fun, EVP_PKEY* pkey) +RawBuffer i2d(I2D_CONV fun, EVP_PKEY *pkey) { - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - if (NULL == pkey) - ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!"); + if (NULL == pkey) + ThrowErr(Exc::Crypto::InternalError, "attempt to parse an empty key!"); - if (NULL == bio.get()) - ThrowErr(Exc::Crypto::InternalError, "Error in memory allocation! Function: BIO_new."); + if (NULL == bio.get()) + ThrowErr(Exc::Crypto::InternalError, + "Error in memory allocation! Function: BIO_new."); - if (1 != fun(bio.get(), pkey)) - ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER"); + if (1 != fun(bio.get(), pkey)) + ThrowErr(Exc::Crypto::InternalError, "Error in conversion EVP_PKEY to DER"); - RawBuffer output(8196); + RawBuffer output(8196); - int size = BIO_read(bio.get(), output.data(), output.size()); + int size = BIO_read(bio.get(), output.data(), output.size()); - if (size <= 0) - ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size); + if (size <= 0) + ThrowErr(Exc::Crypto::InternalError, "Error in BIO_read: ", size); - output.resize(size); - return output; + output.resize(size); + return output; } // encryption / decryption typedef ParamCheck<ParamName::ALGO_TYPE, - AlgoType, - true, - Type<AlgoType>::Equals<AlgoType::AES_CTR, - AlgoType::AES_CBC, - AlgoType::AES_GCM, - AlgoType::AES_CFB>> IsSymEncryption; + AlgoType, + true, + Type<AlgoType>::Equals<AlgoType::AES_CTR, + AlgoType::AES_CBC, + AlgoType::AES_GCM, + AlgoType::AES_CFB>> IsSymEncryption; typedef ParamCheck<ParamName::ALGO_TYPE, - AlgoType, - true, - Type<AlgoType>::Equals<AlgoType::RSA_OAEP>> IsAsymEncryption; + AlgoType, + true, + Type<AlgoType>::Equals<AlgoType::RSA_OAEP>> IsAsymEncryption; typedef ParamCheck<ParamName::ED_IV, - RawBuffer, - true, - Type<size_t>::Equals<DEFAULT_AES_IV_LEN>, - BufferSizeGetter> IvSizeCheck; + RawBuffer, + true, + Type<size_t>::Equals<DEFAULT_AES_IV_LEN>, + BufferSizeGetter> IvSizeCheck; typedef ParamCheck<ParamName::ED_CTR_LEN, - int, - false, - Type<int>::Equals<128>> CtrLenCheck; + int, + false, + Type<int>::Equals<128>> CtrLenCheck; typedef ParamCheck<ParamName::ED_IV, - RawBuffer, - true, - DefaultValidator<RawBuffer>> GcmIvCheck; + RawBuffer, + true, + DefaultValidator<RawBuffer>> GcmIvCheck; typedef ParamCheck<ParamName::ED_TAG_LEN, - int, - false, - Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck; + int, + false, + Type<int>::Equals<32, 64, 96, 104, 112, 120, 128>> GcmTagCheck; typedef ParamCheck<ParamName::ED_LABEL, - RawBuffer, - false, - Unsupported<RawBuffer>> RsaLabelCheck; + RawBuffer, + false, + Unsupported<RawBuffer>> RsaLabelCheck; // sign / verify typedef ParamCheck<ParamName::ALGO_TYPE, - AlgoType, - false, - Type<AlgoType>::Equals<AlgoType::RSA_SV, - AlgoType::DSA_SV, - AlgoType::ECDSA_SV>> IsSignVerify; + AlgoType, + false, + Type<AlgoType>::Equals<AlgoType::RSA_SV, + AlgoType::DSA_SV, + AlgoType::ECDSA_SV>> IsSignVerify; typedef ParamCheck<ParamName::SV_HASH_ALGO, - HashAlgorithm, - false, - Type<HashAlgorithm>::Equals<HashAlgorithm::NONE, - HashAlgorithm::SHA1, - HashAlgorithm::SHA256, - HashAlgorithm::SHA384, - HashAlgorithm::SHA512>> HashAlgoCheck; + HashAlgorithm, + false, + Type<HashAlgorithm>::Equals<HashAlgorithm::NONE, + HashAlgorithm::SHA1, + HashAlgorithm::SHA256, + HashAlgorithm::SHA384, + HashAlgorithm::SHA512>> HashAlgoCheck; typedef ParamCheck<ParamName::SV_RSA_PADDING, - RSAPaddingAlgorithm, - false, - Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE, - RSAPaddingAlgorithm::PKCS1, - RSAPaddingAlgorithm::X931>> RsaPaddingCheck; + RSAPaddingAlgorithm, + false, + Type<RSAPaddingAlgorithm>::Equals<RSAPaddingAlgorithm::NONE, + RSAPaddingAlgorithm::PKCS1, + RSAPaddingAlgorithm::X931>> RsaPaddingCheck; // key generation typedef ParamCheck<ParamName::ALGO_TYPE, - AlgoType, - true, - Type<AlgoType>::Equals<AlgoType::RSA_GEN, - AlgoType::DSA_GEN, - AlgoType::ECDSA_GEN>> IsAsymGeneration; + AlgoType, + true, + Type<AlgoType>::Equals<AlgoType::RSA_GEN, + AlgoType::DSA_GEN, + AlgoType::ECDSA_GEN>> IsAsymGeneration; typedef ParamCheck<ParamName::ALGO_TYPE, - AlgoType, - true, - Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration; + AlgoType, + true, + Type<AlgoType>::Equals<AlgoType::AES_GEN>> IsSymGeneration; typedef ParamCheck<ParamName::GEN_KEY_LEN, - int, - true, - Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck; + int, + true, + Type<int>::Equals<1024, 2048, 4096>> RsaKeyLenCheck; typedef ParamCheck<ParamName::GEN_KEY_LEN, - int, - true, - Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck; + int, + true, + Type<int>::Equals<1024, 2048, 3072, 4096>> DsaKeyLenCheck; typedef ParamCheck<ParamName::GEN_KEY_LEN, - int, - true, - Type<int>::Equals<128, 192, 256>> AesKeyLenCheck; + int, + true, + Type<int>::Equals<128, 192, 256>> AesKeyLenCheck; typedef ParamCheck<ParamName::GEN_EC, - ElipticCurve, - true, - Type<ElipticCurve>::Equals<ElipticCurve::prime192v1, - ElipticCurve::prime256v1, - ElipticCurve::secp384r1>> EcdsaEcCheck; + ElipticCurve, + true, + Type<ElipticCurve>::Equals<ElipticCurve::prime192v1, + ElipticCurve::prime256v1, + ElipticCurve::secp384r1>> EcdsaEcCheck; typedef std::map<AlgoType, ValidatorVector> ValidatorMap; ValidatorMap initValidators() { - ValidatorMap validators; - validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build()); - validators.emplace(AlgoType::RSA_SV, VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build()); - validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build()); - validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build()); - validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build()); - validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build()); - validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build()); - validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build()); - validators.emplace(AlgoType::AES_CTR, VBuilder<IvSizeCheck, CtrLenCheck>::Build()); - validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build()); - validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build()); - validators.emplace(AlgoType::AES_GCM, VBuilder<GcmIvCheck, GcmTagCheck>::Build()); - validators.emplace(AlgoType::RSA_OAEP, VBuilder<RsaLabelCheck>::Build()); - return validators; + ValidatorMap validators; + validators.emplace(AlgoType::RSA_SV, + VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build()); + validators.emplace(AlgoType::RSA_SV, + VBuilder<HashAlgoCheck, RsaPaddingCheck>::Build()); + validators.emplace(AlgoType::DSA_SV, VBuilder<HashAlgoCheck>::Build()); + validators.emplace(AlgoType::ECDSA_SV, VBuilder<HashAlgoCheck>::Build()); + validators.emplace(AlgoType::RSA_GEN, VBuilder<RsaKeyLenCheck>::Build()); + validators.emplace(AlgoType::DSA_GEN, VBuilder<DsaKeyLenCheck>::Build()); + validators.emplace(AlgoType::ECDSA_GEN, VBuilder<EcdsaEcCheck>::Build()); + validators.emplace(AlgoType::AES_GEN, VBuilder<AesKeyLenCheck>::Build()); + validators.emplace(AlgoType::AES_CTR, + VBuilder<IvSizeCheck, CtrLenCheck>::Build()); + validators.emplace(AlgoType::AES_CBC, VBuilder<IvSizeCheck>::Build()); + validators.emplace(AlgoType::AES_CFB, VBuilder<IvSizeCheck>::Build()); + validators.emplace(AlgoType::AES_GCM, + VBuilder<GcmIvCheck, GcmTagCheck>::Build()); + validators.emplace(AlgoType::RSA_OAEP, VBuilder<RsaLabelCheck>::Build()); + return validators; }; ValidatorMap g_validators = initValidators(); template <typename TypeCheck> -void validateParams(const CryptoAlgorithm& ca) -{ - // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation) - TypeCheck tc; - tc.Check(ca); - - AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE); - try { - for (const auto& validator : g_validators.at(at)) - validator->Check(ca); - } catch (const std::out_of_range&) { - ThrowErr(Exc::Crypto::InputParam, "Unsupported algorithm ", static_cast<int>(at)); - } +void validateParams(const CryptoAlgorithm &ca) +{ + // check algorithm type (Encryption/Decryption, Sign/Verify, Key generation) + TypeCheck tc; + tc.Check(ca); + + AlgoType at = unpack<AlgoType>(ca, ParamName::ALGO_TYPE); + + try { + for (const auto &validator : g_validators.at(at)) + validator->Check(ca); + } catch (const std::out_of_range &) { + ThrowErr(Exc::Crypto::InputParam, "Unsupported algorithm ", + static_cast<int>(at)); + } } typedef std::unique_ptr<Cipher::EvpCipherWrapper<RawBuffer>> EvpCipherPtr; -typedef std::function<void(EvpCipherPtr&, const RawBuffer& key, const RawBuffer& iv)> InitCipherFn; +typedef std::function<void(EvpCipherPtr &, const RawBuffer &key, const RawBuffer &iv)> +InitCipherFn; // aes mode, key length in bits, encryption -typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> CipherTree; +typedef std::map<AlgoType, std::map<size_t, std::map<bool, InitCipherFn>>> +CipherTree; template <typename T> -void initCipher(EvpCipherPtr& ptr, const RawBuffer& key, const RawBuffer& iv) +void initCipher(EvpCipherPtr &ptr, const RawBuffer &key, const RawBuffer &iv) { - ptr.reset(new T(key, iv)); + ptr.reset(new T(key, iv)); } CipherTree initializeCipherTree() { - CipherTree tree; - tree[AlgoType::AES_CBC][128][true] = initCipher<Cipher::AesCbcEncryption128>; - tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>; - tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>; + CipherTree tree; + tree[AlgoType::AES_CBC][128][true] = initCipher<Cipher::AesCbcEncryption128>; + tree[AlgoType::AES_CBC][192][true] = initCipher<Cipher::AesCbcEncryption192>; + tree[AlgoType::AES_CBC][256][true] = initCipher<Cipher::AesCbcEncryption256>; - tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>; - tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>; - tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>; + tree[AlgoType::AES_CBC][128][false] = initCipher<Cipher::AesCbcDecryption128>; + tree[AlgoType::AES_CBC][192][false] = initCipher<Cipher::AesCbcDecryption192>; + tree[AlgoType::AES_CBC][256][false] = initCipher<Cipher::AesCbcDecryption256>; - tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>; - tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>; - tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>; + tree[AlgoType::AES_GCM][128][true] = initCipher<Cipher::AesGcmEncryption128>; + tree[AlgoType::AES_GCM][192][true] = initCipher<Cipher::AesGcmEncryption192>; + tree[AlgoType::AES_GCM][256][true] = initCipher<Cipher::AesGcmEncryption256>; - tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>; - tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>; - tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>; + tree[AlgoType::AES_GCM][128][false] = initCipher<Cipher::AesGcmDecryption128>; + tree[AlgoType::AES_GCM][192][false] = initCipher<Cipher::AesGcmDecryption192>; + tree[AlgoType::AES_GCM][256][false] = initCipher<Cipher::AesGcmDecryption256>; - tree[AlgoType::AES_CTR][128][true] = initCipher<Cipher::AesCtrEncryption128>; - tree[AlgoType::AES_CTR][192][true] = initCipher<Cipher::AesCtrEncryption192>; - tree[AlgoType::AES_CTR][256][true] = initCipher<Cipher::AesCtrEncryption256>; + tree[AlgoType::AES_CTR][128][true] = initCipher<Cipher::AesCtrEncryption128>; + tree[AlgoType::AES_CTR][192][true] = initCipher<Cipher::AesCtrEncryption192>; + tree[AlgoType::AES_CTR][256][true] = initCipher<Cipher::AesCtrEncryption256>; - tree[AlgoType::AES_CTR][128][false] = initCipher<Cipher::AesCtrDecryption128>; - tree[AlgoType::AES_CTR][192][false] = initCipher<Cipher::AesCtrDecryption192>; - tree[AlgoType::AES_CTR][256][false] = initCipher<Cipher::AesCtrDecryption256>; + tree[AlgoType::AES_CTR][128][false] = initCipher<Cipher::AesCtrDecryption128>; + tree[AlgoType::AES_CTR][192][false] = initCipher<Cipher::AesCtrDecryption192>; + tree[AlgoType::AES_CTR][256][false] = initCipher<Cipher::AesCtrDecryption256>; - tree[AlgoType::AES_CFB][128][true] = initCipher<Cipher::AesCfbEncryption128>; - tree[AlgoType::AES_CFB][192][true] = initCipher<Cipher::AesCfbEncryption192>; - tree[AlgoType::AES_CFB][256][true] = initCipher<Cipher::AesCfbEncryption256>; + tree[AlgoType::AES_CFB][128][true] = initCipher<Cipher::AesCfbEncryption128>; + tree[AlgoType::AES_CFB][192][true] = initCipher<Cipher::AesCfbEncryption192>; + tree[AlgoType::AES_CFB][256][true] = initCipher<Cipher::AesCfbEncryption256>; - tree[AlgoType::AES_CFB][128][false] = initCipher<Cipher::AesCfbDecryption128>; - tree[AlgoType::AES_CFB][192][false] = initCipher<Cipher::AesCfbDecryption192>; - tree[AlgoType::AES_CFB][256][false] = initCipher<Cipher::AesCfbDecryption256>; + tree[AlgoType::AES_CFB][128][false] = initCipher<Cipher::AesCfbDecryption128>; + tree[AlgoType::AES_CFB][192][false] = initCipher<Cipher::AesCfbDecryption192>; + tree[AlgoType::AES_CFB][256][false] = initCipher<Cipher::AesCfbDecryption256>; - return tree; + return tree; } CipherTree g_cipherTree = initializeCipherTree(); // key length in bytes -InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, bool encryption = true) -{ - try { - return g_cipherTree.at(type).at(key_len*8).at(encryption); - } catch (const std::out_of_range&) { - ThrowErr(Exc::Crypto::InternalError, - "Unsupported cipher: ", - static_cast<int>(type), ", ", - key_len, ", ", - encryption); - } +InitCipherFn selectCipher(AlgoType type, size_t key_len = 32, + bool encryption = true) +{ + try { + return g_cipherTree.at(type).at(key_len * 8).at(encryption); + } catch (const std::out_of_range &) { + ThrowErr(Exc::Crypto::InternalError, + "Unsupported cipher: ", + static_cast<int>(type), ", ", + key_len, ", ", + encryption); + } } -RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char*, unsigned char*, RSA*, int), - const std::string &logPrefix, - const EvpShPtr &pkey, - const CryptoAlgorithm &alg, - const RawBuffer &data) -{ - validateParams<IsAsymEncryption>(alg); - - RSA* rsa = EVP_PKEY_get1_RSA(pkey.get()); - if (!rsa) - ThrowErr(Exc::Crypto::InputParam, logPrefix, "invalid key"); - - /* - * RSA_padding_add_PKCS1_OAEP supports custom label but RSA_public_encrypt calls it with NULL - * value so for now label is not supported. Alternative is to rewrite the openssl implementation - * to support it: openssl-fips/crypto/rsa/rsa_eay.c - */ - RawBuffer output; - output.resize(RSA_size(rsa)); - int ret = cryptoFn(data.size(), - data.data(), - output.data(), - rsa, - RSA_PKCS1_OAEP_PADDING); - RSA_free(rsa); - if (ret < 0) - ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed"); - - output.resize(ret); - return output; +RawBuffer asymmetricHelper(int (*cryptoFn)(int, const unsigned char *, + unsigned char *, RSA *, int), + const std::string &logPrefix, + const EvpShPtr &pkey, + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + validateParams<IsAsymEncryption>(alg); + + RSA *rsa = EVP_PKEY_get1_RSA(pkey.get()); + + if (!rsa) + ThrowErr(Exc::Crypto::InputParam, logPrefix, "invalid key"); + + /* + * RSA_padding_add_PKCS1_OAEP supports custom label but RSA_public_encrypt calls it with NULL + * value so for now label is not supported. Alternative is to rewrite the openssl implementation + * to support it: openssl-fips/crypto/rsa/rsa_eay.c + */ + RawBuffer output; + output.resize(RSA_size(rsa)); + int ret = cryptoFn(data.size(), + data.data(), + output.data(), + rsa, + RSA_PKCS1_OAEP_PADDING); + RSA_free(rsa); + + if (ret < 0) + ThrowErr(Exc::Crypto::InternalError, logPrefix, "failed"); + + output.resize(ret); + return output; } } // anonymous namespace const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo) { - const EVP_MD *md_algo = NULL; - switch (hashAlgo) { - case HashAlgorithm::NONE: - md_algo = NULL; - break; - case HashAlgorithm::SHA1: - md_algo = EVP_sha1(); - break; - case HashAlgorithm::SHA256: - md_algo = EVP_sha256(); - break; - case HashAlgorithm::SHA384: - md_algo = EVP_sha384(); - break; - case HashAlgorithm::SHA512: - md_algo = EVP_sha512(); - break; - default: - ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value"); - } - return md_algo; + const EVP_MD *md_algo = NULL; + + switch (hashAlgo) { + case HashAlgorithm::NONE: + md_algo = NULL; + break; + + case HashAlgorithm::SHA1: + md_algo = EVP_sha1(); + break; + + case HashAlgorithm::SHA256: + md_algo = EVP_sha256(); + break; + + case HashAlgorithm::SHA384: + md_algo = EVP_sha384(); + break; + + case HashAlgorithm::SHA512: + md_algo = EVP_sha512(); + break; + + default: + ThrowErr(Exc::Crypto::InternalError, "Error in hashAlgorithm value"); + } + + return md_algo; } int getRsaPadding(const RSAPaddingAlgorithm padAlgo) { - int rsa_padding = -1; - switch (padAlgo) { - case RSAPaddingAlgorithm::NONE: - rsa_padding = RSA_NO_PADDING; - break; - case RSAPaddingAlgorithm::PKCS1: - rsa_padding = RSA_PKCS1_PADDING; - break; - case RSAPaddingAlgorithm::X931: - rsa_padding = RSA_X931_PADDING; - break; - default: - ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value"); - } - return rsa_padding; + int rsa_padding = -1; + + switch (padAlgo) { + case RSAPaddingAlgorithm::NONE: + rsa_padding = RSA_NO_PADDING; + break; + + case RSAPaddingAlgorithm::PKCS1: + rsa_padding = RSA_PKCS1_PADDING; + break; + + case RSAPaddingAlgorithm::X931: + rsa_padding = RSA_X931_PADDING; + break; + + default: + ThrowErr(Exc::Crypto::InternalError, "Error in RSAPaddingAlgorithm value"); + } + + return rsa_padding; } DataPair createKeyPairRSA(const int size) { - EvpPkeyUPtr pkey; + EvpPkeyUPtr pkey; + + // check the parameters of functions + if (size != 1024 && size != 2048 && size != 4096) + ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size"); - // check the parameters of functions - if (size != 1024 && size != 2048 && size != 4096) - ThrowErr(Exc::Crypto::InputParam, "Error in RSA input size"); + EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free); - EvpPkeyCtxUPtr ctx(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL), EVP_PKEY_CTX_free); - if (!ctx) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function !!"); + if (!ctx) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_new_id function !!"); - if (EVP_PKEY_keygen_init(ctx.get()) <= 0) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function !!"); + if (EVP_PKEY_keygen_init(ctx.get()) <= 0) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_keygen_init function !!"); - if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!"); + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), size) <= 0) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_rsa_keygen_bits function !!"); - EVP_PKEY *pkeyTmp = NULL; - if (!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); - pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); + EVP_PKEY *pkeyTmp = NULL; - return std::make_pair<Data, Data>( - {DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())}, - {DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())}); + if (!EVP_PKEY_keygen(ctx.get(), &pkeyTmp)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + + pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); + + return std::make_pair<Data, Data>( + {DataType(KeyType::KEY_RSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())}, + {DataType(KeyType::KEY_RSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())}); } DataPair createKeyPairDSA(const int size) { - EvpPkeyUPtr pkey; - EvpPkeyUPtr pparam; + EvpPkeyUPtr pkey; + EvpPkeyUPtr pparam; + + // check the parameters of functions + if (size != 1024 && size != 2048 && size != 3072 && size != 4096) + ThrowErr(Exc::Crypto::InputParam, "Error in DSA input size"); + + /* Create the context for generating the parameters */ + EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free); - // check the parameters of functions - if (size != 1024 && size != 2048 && size != 3072 && size != 4096) - ThrowErr(Exc::Crypto::InputParam, "Error in DSA input size"); + if (!pctx) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function"); - /* Create the context for generating the parameters */ - EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL), EVP_PKEY_CTX_free); - if (!pctx) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function"); + if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_paramgen_init function"); - if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function"); + if (EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function"); - if (EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx.get(), size)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(", size, ") function"); + /* Generate parameters */ + EVP_PKEY *pparamTmp = NULL; - /* Generate parameters */ - EVP_PKEY *pparamTmp = NULL; - if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function"); + if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function"); - pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free); + pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free); - // Start to generate key - EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free); - if (!kctx) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); + // Start to generate key + EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free); - if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function"); + if (!kctx) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - /* Generate the key */ - EVP_PKEY *pkeyTmp = NULL; - if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function"); - pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); + /* Generate the key */ + EVP_PKEY *pkeyTmp = NULL; - return std::make_pair<Data, Data>( - {DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())}, - {DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())}); + if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + + pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); + + return std::make_pair<Data, Data>( + {DataType(KeyType::KEY_DSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())}, + {DataType(KeyType::KEY_DSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())}); } DataPair createKeyPairECDSA(ElipticCurve type) { - int ecCurve = NOT_DEFINED; - EvpPkeyUPtr pkey; - EvpPkeyUPtr pparam; - - switch (type) { - case ElipticCurve::prime192v1: - ecCurve = NID_X9_62_prime192v1; - break; - case ElipticCurve::prime256v1: - ecCurve = NID_X9_62_prime256v1; - break; - case ElipticCurve::secp384r1: - ecCurve = NID_secp384r1; - break; - default: - ThrowErr(Exc::Crypto::InputParam, "Error in EC type"); - } - - /* Create the context for generating the parameters */ - EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free); - if (!pctx) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function"); - - if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen_init function"); - - if (EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function"); - - /* Generate parameters */ - EVP_PKEY *pparamTmp = NULL; - if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function"); - - pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free); - - // Start to generate key - EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free); - if (!kctx) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - - if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function"); - - /* Generate the key */ - EVP_PKEY *pkeyTmp = NULL; - if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); - - pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); - - return std::make_pair<Data, Data>( - {DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())}, - {DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())}); + int ecCurve = NOT_DEFINED; + EvpPkeyUPtr pkey; + EvpPkeyUPtr pparam; + + switch (type) { + case ElipticCurve::prime192v1: + ecCurve = NID_X9_62_prime192v1; + break; + + case ElipticCurve::prime256v1: + ecCurve = NID_X9_62_prime256v1; + break; + + case ElipticCurve::secp384r1: + ecCurve = NID_secp384r1; + break; + + default: + ThrowErr(Exc::Crypto::InputParam, "Error in EC type"); + } + + /* Create the context for generating the parameters */ + EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free); + + if (!pctx) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new_id function"); + + if (EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx.get())) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_paramgen_init function"); + + if (EVP_SUCCESS != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx.get(), ecCurve)) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_ec_paramgen_curve_nid function"); + + /* Generate parameters */ + EVP_PKEY *pparamTmp = NULL; + + if (EVP_SUCCESS != EVP_PKEY_paramgen(pctx.get(), &pparamTmp)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_paramgen function"); + + pparam = EvpPkeyUPtr(pparamTmp, EVP_PKEY_free); + + // Start to generate key + EvpPkeyCtxUPtr kctx(EVP_PKEY_CTX_new(pparam.get(), NULL), EVP_PKEY_CTX_free); + + if (!kctx) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); + + if (EVP_SUCCESS != EVP_PKEY_keygen_init(kctx.get())) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen_init function"); + + /* Generate the key */ + EVP_PKEY *pkeyTmp = NULL; + + if (!EVP_PKEY_keygen(kctx.get(), &pkeyTmp)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function !!"); + + pkey = EvpPkeyUPtr(pkeyTmp, EVP_PKEY_free); + + return std::make_pair<Data, Data>( + {DataType(KeyType::KEY_ECDSA_PRIVATE), i2d(i2d_PrivateKey_bio, pkey.get())}, + {DataType(KeyType::KEY_ECDSA_PUBLIC), i2d(i2d_PUBKEY_bio, pkey.get())}); } Data createKeyAES(const int sizeBits) { - // check the parameters of functions - if (sizeBits != 128 && sizeBits != 192 && sizeBits != 256) { - LogError("Error in AES input size"); - ThrowMsg(Exc::Crypto::InputParam, "Error in AES input size"); - } + // check the parameters of functions + if (sizeBits != 128 && sizeBits != 192 && sizeBits != 256) { + LogError("Error in AES input size"); + ThrowMsg(Exc::Crypto::InputParam, "Error in AES input size"); + } - uint8_t key[32]; - int sizeBytes = sizeBits/8; - if (!RAND_bytes(key, sizeBytes)) { - LogError("Error in AES key generation"); - ThrowMsg(Exc::Crypto::InternalError, "Error in AES key generation"); - } + uint8_t key[32]; + int sizeBytes = sizeBits / 8; - return { DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key+sizeBytes)}; + if (!RAND_bytes(key, sizeBytes)) { + LogError("Error in AES key generation"); + ThrowMsg(Exc::Crypto::InternalError, "Error in AES key generation"); + } + + return { DataType(KeyType::KEY_AES), CKM::RawBuffer(key, key + sizeBytes)}; } DataPair generateAKey(const CryptoAlgorithm &algorithm) { - validateParams<IsAsymGeneration>(algorithm); - - AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE); - if (keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN) { - int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN); - if (keyType == AlgoType::RSA_GEN) - return createKeyPairRSA(keyLength); - else - return createKeyPairDSA(keyLength); - } else { // AlgoType::ECDSA_GEN - ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC); - return createKeyPairECDSA(ecType); - } + validateParams<IsAsymGeneration>(algorithm); + + AlgoType keyType = unpack<AlgoType>(algorithm, ParamName::ALGO_TYPE); + + if (keyType == AlgoType::RSA_GEN || keyType == AlgoType::DSA_GEN) { + int keyLength = unpack<int>(algorithm, ParamName::GEN_KEY_LEN); + + if (keyType == AlgoType::RSA_GEN) + return createKeyPairRSA(keyLength); + else + return createKeyPairDSA(keyLength); + } else { // AlgoType::ECDSA_GEN + ElipticCurve ecType = unpack<ElipticCurve>(algorithm, ParamName::GEN_EC); + return createKeyPairECDSA(ecType); + } } Data generateSKey(const CryptoAlgorithm &algorithm) { - validateParams<IsSymGeneration>(algorithm); + validateParams<IsSymGeneration>(algorithm); - int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN); - return createKeyAES(keySizeBits); + int keySizeBits = unpack<int>(algorithm, ParamName::GEN_KEY_LEN); + return createKeyAES(keySizeBits); } RawBuffer encryptDataAes( - AlgoType type, - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv) -{ - EvpCipherPtr enc; - selectCipher(type, key.size())(enc, key, iv); - RawBuffer result = enc->Append(data); - RawBuffer tmp = enc->Finalize(); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); - return result; + AlgoType type, + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv) +{ + EvpCipherPtr enc; + selectCipher(type, key.size())(enc, key, iv); + RawBuffer result = enc->Append(data); + RawBuffer tmp = enc->Finalize(); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); + return result; } std::pair<RawBuffer, RawBuffer> encryptDataAesGcm( - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv, - int tagSize, - const RawBuffer &aad) -{ - RawBuffer tag(tagSize); - EvpCipherPtr enc; - selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv); - - if (!aad.empty()) - enc->AppendAAD(aad); - - RawBuffer result = enc->Append(data); - RawBuffer tmp = enc->Finalize(); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); - if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) - ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Get tag failed."); - - return std::make_pair(result, tag); + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv, + int tagSize, + const RawBuffer &aad) +{ + RawBuffer tag(tagSize); + EvpCipherPtr enc; + selectCipher(AlgoType::AES_GCM, key.size())(enc, key, iv); + + if (!aad.empty()) + enc->AppendAAD(aad); + + RawBuffer result = enc->Append(data); + RawBuffer tmp = enc->Finalize(); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); + + if (0 == enc->Control(EVP_CTRL_GCM_GET_TAG, tagSize, tag.data())) + ThrowErr(Exc::Crypto::InternalError, + "Error in AES control function. Get tag failed."); + + return std::make_pair(result, tag); } RawBuffer encryptDataAesGcmPacked( - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv, - int tagSize, - const RawBuffer &aad) -{ - auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad); - std::copy(pair.second.begin(), pair.second.end(), std::back_inserter(pair.first)); - return pair.first; + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv, + int tagSize, + const RawBuffer &aad) +{ + auto pair = encryptDataAesGcm(key, data, iv, tagSize, aad); + std::copy(pair.second.begin(), pair.second.end(), + std::back_inserter(pair.first)); + return pair.first; } RawBuffer decryptDataAes( - AlgoType type, - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv) -{ - EvpCipherPtr dec; - selectCipher(type, key.size(), false)(dec, key, iv); - RawBuffer result = dec->Append(data); - RawBuffer tmp = dec->Finalize(); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); - return result; + AlgoType type, + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv) +{ + EvpCipherPtr dec; + selectCipher(type, key.size(), false)(dec, key, iv); + RawBuffer result = dec->Append(data); + RawBuffer tmp = dec->Finalize(); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); + return result; } RawBuffer decryptDataAesGcm( - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv, - const RawBuffer &tag, - const RawBuffer &aad) -{ - EvpCipherPtr dec; - selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv); - void *ptr = (void*)tag.data(); - if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) - ThrowErr(Exc::Crypto::InternalError, "Error in AES control function. Set tag failed."); - - if (!aad.empty()) - dec->AppendAAD(aad); - - RawBuffer result = dec->Append(data); - RawBuffer tmp = dec->Finalize(); - std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); - return result; + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv, + const RawBuffer &tag, + const RawBuffer &aad) +{ + EvpCipherPtr dec; + selectCipher(AlgoType::AES_GCM, key.size(), false)(dec, key, iv); + void *ptr = (void *)tag.data(); + + if (0 == dec->Control(EVP_CTRL_GCM_SET_TAG, tag.size(), ptr)) + ThrowErr(Exc::Crypto::InternalError, + "Error in AES control function. Set tag failed."); + + if (!aad.empty()) + dec->AppendAAD(aad); + + RawBuffer result = dec->Append(data); + RawBuffer tmp = dec->Finalize(); + std::copy(tmp.begin(), tmp.end(), std::back_inserter(result)); + return result; } RawBuffer decryptDataAesGcmPacked( - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv, - int tagSize, - const RawBuffer &aad) -{ - if (tagSize > static_cast<int>(data.size())) - ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag"); - - auto tagPos = data.data() + data.size() - tagSize; - return decryptDataAesGcm( - key, - RawBuffer(data.data(), tagPos), - iv, - RawBuffer(tagPos, data.data() + data.size()), - aad); + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv, + int tagSize, + const RawBuffer &aad) +{ + if (tagSize > static_cast<int>(data.size())) + ThrowErr(Exc::Crypto::InputParam, "Wrong size of tag"); + + auto tagPos = data.data() + data.size() - tagSize; + return decryptDataAesGcm( + key, + RawBuffer(data.data(), tagPos), + iv, + RawBuffer(tagPos, data.data() + data.size()), + aad); } RawBuffer symmetricEncrypt(const RawBuffer &key, - const CryptoAlgorithm &alg, - const RawBuffer &data) -{ - validateParams<IsSymEncryption>(alg); - AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE); - - switch (keyType) { - case AlgoType::AES_CBC: - case AlgoType::AES_CTR: - case AlgoType::AES_CFB: - return encryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV)); - case AlgoType::AES_GCM: - { - int tagLenBits = DEFAULT_AES_GCM_TAG_LEN; - alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); - RawBuffer aad; - alg.getParam(ParamName::ED_AAD, aad); - return encryptDataAesGcmPacked(key, - data, - unpack<RawBuffer>(alg, ParamName::ED_IV), - tagLenBits/8, - aad); - } - default: - break; - } - ThrowErr(Exc::Crypto::OperationNotSupported, "symmetric enc: algorithm not recognized"); + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + validateParams<IsSymEncryption>(alg); + AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE); + + switch (keyType) { + case AlgoType::AES_CBC: + case AlgoType::AES_CTR: + case AlgoType::AES_CFB: + return encryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, + ParamName::ED_IV)); + + case AlgoType::AES_GCM: { + int tagLenBits = DEFAULT_AES_GCM_TAG_LEN; + alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); + RawBuffer aad; + alg.getParam(ParamName::ED_AAD, aad); + return encryptDataAesGcmPacked(key, + data, + unpack<RawBuffer>(alg, ParamName::ED_IV), + tagLenBits / 8, + aad); + } + + default: + break; + } + + ThrowErr(Exc::Crypto::OperationNotSupported, + "symmetric enc: algorithm not recognized"); } RawBuffer symmetricDecrypt(const RawBuffer &key, - const CryptoAlgorithm &alg, - const RawBuffer &data) -{ - validateParams<IsSymEncryption>(alg); - AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE); - - switch (keyType) { - case AlgoType::AES_CBC: - case AlgoType::AES_CTR: - case AlgoType::AES_CFB: - return decryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, ParamName::ED_IV)); - case AlgoType::AES_GCM: - { - int tagLenBits = DEFAULT_AES_GCM_TAG_LEN; - alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); - RawBuffer aad; - alg.getParam(ParamName::ED_AAD, aad); - return decryptDataAesGcmPacked(key, - data, - unpack<RawBuffer>(alg, ParamName::ED_IV), - tagLenBits/8, - aad); - } - default: - break; - } - ThrowErr(Exc::Crypto::InputParam, "symmetric dec: algorithm not recognized"); + const CryptoAlgorithm &alg, + const RawBuffer &data) +{ + validateParams<IsSymEncryption>(alg); + AlgoType keyType = unpack<AlgoType>(alg, ParamName::ALGO_TYPE); + + switch (keyType) { + case AlgoType::AES_CBC: + case AlgoType::AES_CTR: + case AlgoType::AES_CFB: + return decryptDataAes(keyType, key, data, unpack<RawBuffer>(alg, + ParamName::ED_IV)); + + case AlgoType::AES_GCM: { + int tagLenBits = DEFAULT_AES_GCM_TAG_LEN; + alg.getParam(ParamName::ED_TAG_LEN, tagLenBits); + RawBuffer aad; + alg.getParam(ParamName::ED_AAD, aad); + return decryptDataAesGcmPacked(key, + data, + unpack<RawBuffer>(alg, ParamName::ED_IV), + tagLenBits / 8, + aad); + } + + default: + break; + } + + ThrowErr(Exc::Crypto::InputParam, "symmetric dec: algorithm not recognized"); } RawBuffer asymmetricEncrypt(const EvpShPtr &pkey, - const CryptoAlgorithm &alg, - const RawBuffer &data) + const CryptoAlgorithm &alg, + const RawBuffer &data) { - return asymmetricHelper(RSA_public_encrypt, "Asymmetric encryption: ", pkey, alg, data); + return asymmetricHelper(RSA_public_encrypt, "Asymmetric encryption: ", pkey, + alg, data); } RawBuffer asymmetricDecrypt(const EvpShPtr &pkey, - const CryptoAlgorithm &alg, - const RawBuffer &data) + const CryptoAlgorithm &alg, + const RawBuffer &data) { - return asymmetricHelper(RSA_private_decrypt, "Asymmetric decryption: ", pkey, alg, data); + return asymmetricHelper(RSA_private_decrypt, "Asymmetric decryption: ", pkey, + alg, data); } RawBuffer sign(EVP_PKEY *pkey, - const CryptoAlgorithm &alg, - const RawBuffer &message) -{ - validateParams<IsSignVerify>(alg); - - HashAlgorithm hashTmp = HashAlgorithm::NONE; - alg.getParam(ParamName::SV_HASH_ALGO, hashTmp); - const EVP_MD *md_algo = getMdAlgo(hashTmp); - - RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE; - alg.getParam(ParamName::SV_RSA_PADDING, rsaPad); - int rsa_padding = getRsaPadding(rsaPad); - -// -// if ((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) && -// (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) && -// (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE)) -// { -// LogError("Error in private key type"); -// ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type"); -// } -// -// if (privateKey.getType()==KeyType::KEY_RSA_PRIVATE) { -// rsa_padding = getRsaPadding(padAlgo); -// } - - if (NULL == pkey) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function"); - - if (md_algo == NULL) - return signMessage(pkey, message, rsa_padding); - - return digestSignMessage(pkey, message, md_algo, rsa_padding); + const CryptoAlgorithm &alg, + const RawBuffer &message) +{ + validateParams<IsSignVerify>(alg); + + HashAlgorithm hashTmp = HashAlgorithm::NONE; + alg.getParam(ParamName::SV_HASH_ALGO, hashTmp); + const EVP_MD *md_algo = getMdAlgo(hashTmp); + + RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE; + alg.getParam(ParamName::SV_RSA_PADDING, rsaPad); + int rsa_padding = getRsaPadding(rsaPad); + + // + // if ((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) && + // (privateKey.getType() != KeyType::KEY_DSA_PRIVATE) && + // (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE)) + // { + // LogError("Error in private key type"); + // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type"); + // } + // + // if (privateKey.getType()==KeyType::KEY_RSA_PRIVATE) { + // rsa_padding = getRsaPadding(padAlgo); + // } + + if (NULL == pkey) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_keygen function"); + + if (md_algo == NULL) + return signMessage(pkey, message, rsa_padding); + + return digestSignMessage(pkey, message, md_algo, rsa_padding); } RawBuffer signMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const int rsa_padding) -{ - EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free); - - if (!pctx.get()) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - - if (EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function"); - - /* Set padding algorithm */ - if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) - ThrowErr(Exc::Crypto::InternalError, - "Error in EVP_PKEY_CTX_set_rsa_padding function"); - - /* Finalize the Sign operation */ - /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the - * signature. Length is returned in slen */ - size_t slen; - if (EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), message.size())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function"); - - /* Allocate memory for the signature based on size in slen */ - RawBuffer sig(slen); - - if (EVP_SUCCESS == EVP_PKEY_sign(pctx.get(), - sig.data(), - &slen, - message.data(), - message.size())) { - // Set value to return RawData - sig.resize(slen); - return sig; - } - - ThrowErr(Exc::Crypto::InputParam, "Error in EVP_PKEY_sign function. Input param error."); + const RawBuffer &message, + const int rsa_padding) +{ + EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(privKey, NULL), EVP_PKEY_CTX_free); + + if (!pctx.get()) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); + + if (EVP_PKEY_sign_init(pctx.get()) != EVP_SUCCESS) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign_init function"); + + /* Set padding algorithm */ + if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) + if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_rsa_padding function"); + + /* Finalize the Sign operation */ + /* First call EVP_PKEY_sign with a NULL sig parameter to obtain the length of the + * signature. Length is returned in slen */ + size_t slen; + + if (EVP_SUCCESS != EVP_PKEY_sign(pctx.get(), NULL, &slen, message.data(), + message.size())) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_sign function"); + + /* Allocate memory for the signature based on size in slen */ + RawBuffer sig(slen); + + if (EVP_SUCCESS == EVP_PKEY_sign(pctx.get(), + sig.data(), + &slen, + message.data(), + message.size())) { + // Set value to return RawData + sig.resize(slen); + return sig; + } + + ThrowErr(Exc::Crypto::InputParam, + "Error in EVP_PKEY_sign function. Input param error."); } RawBuffer digestSignMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const EVP_MD *md_algo, - const int rsa_padding) + const RawBuffer &message, + const EVP_MD *md_algo, + const int rsa_padding) { - EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy); + EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy); + + EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY_CTX *pctx = NULL; + // Create the Message Digest Context + if (!mdctx.get()) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function"); - // Create the Message Digest Context - if (!mdctx.get()) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function"); + if (EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, + privKey)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function"); - if (EVP_SUCCESS != EVP_DigestSignInit(mdctx.get(), &pctx, md_algo, NULL, privKey)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignInit function"); + /* Set padding algorithm */ + if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) + if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_rsa_padding function"); - /* Set padding algorithm */ - if (EVP_PKEY_type(privKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); + /* Call update with the message */ + if (EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), + message.size())) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function"); - /* Call update with the message */ - if (EVP_SUCCESS != EVP_DigestSignUpdate(mdctx.get(), message.data(), message.size())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignUpdate function"); + /* Finalize the DigestSign operation */ + /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the + * signature. Length is returned in slen */ + size_t slen; - /* Finalize the DigestSign operation */ - /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the - * signature. Length is returned in slen */ - size_t slen; - if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function"); + if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), NULL, &slen)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function"); - /* Allocate memory for the signature based on size in slen */ - RawBuffer sig(slen); + /* Allocate memory for the signature based on size in slen */ + RawBuffer sig(slen); - /* Obtain the signature */ - if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function"); + /* Obtain the signature */ + if (EVP_SUCCESS != EVP_DigestSignFinal(mdctx.get(), sig.data(), &slen)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestSignFinal function"); - // Set value to return RawData - sig.resize(slen); - return sig; + // Set value to return RawData + sig.resize(slen); + return sig; } int verify(EVP_PKEY *pkey, - const CryptoAlgorithm &alg, - const RawBuffer &message, - const RawBuffer &signature) -{ - validateParams<IsSignVerify>(alg); - - int rsa_padding = NOT_DEFINED; - const EVP_MD *md_algo = NULL; - - HashAlgorithm hashTmp = HashAlgorithm::NONE; - alg.getParam(ParamName::SV_HASH_ALGO, hashTmp); - md_algo = getMdAlgo(hashTmp); - - RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE; - alg.getParam(ParamName::SV_RSA_PADDING, rsaPad); - rsa_padding = getRsaPadding(rsaPad); - -// -// if ((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) && -// (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) && -// (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC)) -// { -// LogError("Error in private key type"); -// ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type"); -// } -// -// if (publicKey.getType()==KeyType::KEY_RSA_PUBLIC) { -// rsa_padding = getRsaPadding(padAlgo); -// } - -// auto shrPKey = publicKey.getEvpShPtr(); - if (NULL == pkey) - ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function"); - - if (md_algo == NULL) - return verifyMessage(pkey, message, signature, rsa_padding); - - return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding); + const CryptoAlgorithm &alg, + const RawBuffer &message, + const RawBuffer &signature) +{ + validateParams<IsSignVerify>(alg); + + int rsa_padding = NOT_DEFINED; + const EVP_MD *md_algo = NULL; + + HashAlgorithm hashTmp = HashAlgorithm::NONE; + alg.getParam(ParamName::SV_HASH_ALGO, hashTmp); + md_algo = getMdAlgo(hashTmp); + + RSAPaddingAlgorithm rsaPad = RSAPaddingAlgorithm::NONE; + alg.getParam(ParamName::SV_RSA_PADDING, rsaPad); + rsa_padding = getRsaPadding(rsaPad); + + // + // if ((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) && + // (publicKey.getType() != KeyType::KEY_DSA_PUBLIC) && + // (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC)) + // { + // LogError("Error in private key type"); + // ThrowErr(CryptoService::Exception::Crypto_internal, "Error in private key type"); + // } + // + // if (publicKey.getType()==KeyType::KEY_RSA_PUBLIC) { + // rsa_padding = getRsaPadding(padAlgo); + // } + + // auto shrPKey = publicKey.getEvpShPtr(); + if (NULL == pkey) + ThrowErr(Exc::Crypto::InternalError, "Error in getEvpShPtr function"); + + if (md_algo == NULL) + return verifyMessage(pkey, message, signature, rsa_padding); + + return digestVerifyMessage(pkey, message, signature, md_algo, rsa_padding); } int verifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const int rsa_padding) + const RawBuffer &message, + const RawBuffer &signature, + const int rsa_padding) { - EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free); + EvpPkeyCtxUPtr pctx(EVP_PKEY_CTX_new(pubKey, NULL), EVP_PKEY_CTX_free); - if (!pctx.get()) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); + if (!pctx.get()) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_new function"); - if (EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function"); + if (EVP_PKEY_verify_init(pctx.get()) != EVP_SUCCESS) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_verify_init function"); - /* Set padding algorithm */ - if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); + /* Set padding algorithm */ + if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) + if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx.get(), rsa_padding)) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_rsa_padding function"); - if (EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), signature.size(), message.data(), message.size())) - return CKM_API_SUCCESS; + if (EVP_SUCCESS == EVP_PKEY_verify(pctx.get(), signature.data(), + signature.size(), message.data(), message.size())) + return CKM_API_SUCCESS; - LogError("EVP_PKEY_verify Failed"); - return CKM_API_ERROR_VERIFICATION_FAILED; + LogError("EVP_PKEY_verify Failed"); + return CKM_API_ERROR_VERIFICATION_FAILED; } int digestVerifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const EVP_MD *md_algo, - const int rsa_padding) + const RawBuffer &message, + const RawBuffer &signature, + const EVP_MD *md_algo, + const int rsa_padding) { - EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy); - EVP_PKEY_CTX *pctx = NULL; + EvpMdCtxUPtr mdctx(EVP_MD_CTX_create(), EVP_MD_CTX_destroy); + EVP_PKEY_CTX *pctx = NULL; - /* Create the Message Digest Context */ - if (!mdctx.get()) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function"); + /* Create the Message Digest Context */ + if (!mdctx.get()) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_MD_CTX_create function"); - if (EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, pubKey)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function"); + if (EVP_SUCCESS != EVP_DigestVerifyInit(mdctx.get(), &pctx, md_algo, NULL, + pubKey)) + ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyInit function"); - if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) - if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_PKEY_CTX_set_rsa_padding function"); + if (EVP_PKEY_type(pubKey->type) == EVP_PKEY_RSA) + if (EVP_SUCCESS != EVP_PKEY_CTX_set_rsa_padding(pctx, rsa_padding)) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_PKEY_CTX_set_rsa_padding function"); - if (EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), message.size())) - ThrowErr(Exc::Crypto::InternalError, "Error in EVP_DigestVerifyUpdate function"); + if (EVP_SUCCESS != EVP_DigestVerifyUpdate(mdctx.get(), message.data(), + message.size())) + ThrowErr(Exc::Crypto::InternalError, + "Error in EVP_DigestVerifyUpdate function"); - if (EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), const_cast<unsigned char*>(signature.data()), signature.size())) - return CKM_API_SUCCESS; + if (EVP_SUCCESS == EVP_DigestVerifyFinal(mdctx.get(), + const_cast<unsigned char *>(signature.data()), signature.size())) + return CKM_API_SUCCESS; - LogError("EVP_PKEY_verify Failed"); - return CKM_API_ERROR_VERIFICATION_FAILED; + LogError("EVP_PKEY_verify Failed"); + return CKM_API_ERROR_VERIFICATION_FAILED; } bool verifyBinaryData(DataType dataType, const RawBuffer &buffer) { - if (dataType.isSKey()) { - switch (buffer.size()) { - case 128: - case 192: - case 256: - LogDebug("AES key verified."); - return true; - default: - LogError("AES key have wrong size."); - return false; - } - } - - if (dataType.isKeyPublic()) { - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - - BIO_write(bio.get(), buffer.data(), buffer.size()); - EVP_PKEY *pkey = d2i_PUBKEY_bio(bio.get(), NULL); - if (pkey) { - EVP_PKEY_free(pkey); - LogDebug("Verified with d2i_PUBKEY_bio."); - return true; - } - LogError("Key was not verified. Unsupported format."); - return false; - } - - if (dataType.isKeyPrivate()) { - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - - BIO_write(bio.get(), buffer.data(), buffer.size()); - EVP_PKEY *pkey = d2i_PrivateKey_bio(bio.get(), NULL); - if (pkey) { - EVP_PKEY_free(pkey); - LogDebug("Key verified with d2i_PrivateKey_bio." << (void*)pkey); - return true; - } - LogError("Key was not verified. Unsupported format."); - return false; - } - - if (dataType.isCertificate() || dataType.isChainCert()) { - const unsigned char *ptr = reinterpret_cast<const unsigned char*>(buffer.data()); - int size = static_cast<int>(buffer.size()); - X509 *x509 = d2i_X509(NULL, &ptr, size); - if (x509) { - LogDebug("Cerificate verified with d2i_X509"); - X509_free(x509); - return true; - } - LogError("Certificate was not verified. Unsupported format."); - return false; - } - - LogDebug("Importing binary data..."); - return true; + if (dataType.isSKey()) { + switch (buffer.size()) { + case 128: + case 192: + case 256: + LogDebug("AES key verified."); + return true; + + default: + LogError("AES key have wrong size."); + return false; + } + } + + if (dataType.isKeyPublic()) { + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + + BIO_write(bio.get(), buffer.data(), buffer.size()); + EVP_PKEY *pkey = d2i_PUBKEY_bio(bio.get(), NULL); + + if (pkey) { + EVP_PKEY_free(pkey); + LogDebug("Verified with d2i_PUBKEY_bio."); + return true; + } + + LogError("Key was not verified. Unsupported format."); + return false; + } + + if (dataType.isKeyPrivate()) { + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + + BIO_write(bio.get(), buffer.data(), buffer.size()); + EVP_PKEY *pkey = d2i_PrivateKey_bio(bio.get(), NULL); + + if (pkey) { + EVP_PKEY_free(pkey); + LogDebug("Key verified with d2i_PrivateKey_bio." << (void *)pkey); + return true; + } + + LogError("Key was not verified. Unsupported format."); + return false; + } + + if (dataType.isCertificate() || dataType.isChainCert()) { + const unsigned char *ptr = reinterpret_cast<const unsigned char *> + (buffer.data()); + int size = static_cast<int>(buffer.size()); + X509 *x509 = d2i_X509(NULL, &ptr, size); + + if (x509) { + LogDebug("Cerificate verified with d2i_X509"); + X509_free(x509); + return true; + } + + LogError("Certificate was not verified. Unsupported format."); + return false; + } + + LogDebug("Importing binary data..."); + return true; } } // namespace Internals diff --git a/src/manager/crypto/sw-backend/internals.h b/src/manager/crypto/sw-backend/internals.h index 275500ec..56a1e00b 100644 --- a/src/manager/crypto/sw-backend/internals.h +++ b/src/manager/crypto/sw-backend/internals.h @@ -39,8 +39,8 @@ namespace Internals { // TODO replace it with DataContainer struct Data { - DataType type; - RawBuffer buffer; + DataType type; + RawBuffer buffer; }; typedef std::pair<Data, Data> DataPair; @@ -54,77 +54,77 @@ DataPair generateAKey(const CryptoAlgorithm &algorithm); Data generateSKey(const CryptoAlgorithm &algorithm); RawBuffer symmetricEncrypt( - const RawBuffer &key, - const CryptoAlgorithm &alg, - const RawBuffer &data); + const RawBuffer &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); RawBuffer symmetricDecrypt( - const RawBuffer &key, - const CryptoAlgorithm &alg, - const RawBuffer &cipher); + const RawBuffer &key, + const CryptoAlgorithm &alg, + const RawBuffer &cipher); RawBuffer asymmetricEncrypt( - const EvpShPtr &key, - const CryptoAlgorithm &alg, - const RawBuffer &data); + const EvpShPtr &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); RawBuffer asymmetricDecrypt( - const EvpShPtr &key, - const CryptoAlgorithm &alg, - const RawBuffer &data); + const EvpShPtr &key, + const CryptoAlgorithm &alg, + const RawBuffer &data); std::pair<RawBuffer, RawBuffer> encryptDataAesGcm( - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv, - int tagSize, - const RawBuffer &aad = RawBuffer()); + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv, + int tagSize, + const RawBuffer &aad = RawBuffer()); RawBuffer decryptDataAesGcm( - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv, - const RawBuffer &tag, - const RawBuffer &aad = RawBuffer()); + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv, + const RawBuffer &tag, + const RawBuffer &aad = RawBuffer()); RawBuffer encryptDataAes(AlgoType type, - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv); + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv); RawBuffer decryptDataAes(AlgoType type, - const RawBuffer &key, - const RawBuffer &data, - const RawBuffer &iv); + const RawBuffer &key, + const RawBuffer &data, + const RawBuffer &iv); RawBuffer sign(EVP_PKEY *pkey, - const CryptoAlgorithm &alg, - const RawBuffer &message); + const CryptoAlgorithm &alg, + const RawBuffer &message); int verify(EVP_PKEY *pkey, - const CryptoAlgorithm &alg, - const RawBuffer &message, - const RawBuffer &signature); + const CryptoAlgorithm &alg, + const RawBuffer &message, + const RawBuffer &signature); const EVP_MD *getMdAlgo(const HashAlgorithm hashAlgo); int getRsaPadding(const RSAPaddingAlgorithm padAlgo); RawBuffer signMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const int rsa_padding); + const RawBuffer &message, + const int rsa_padding); RawBuffer digestSignMessage(EVP_PKEY *privKey, - const RawBuffer &message, - const EVP_MD *md_algo, - const int rsa_padding); + const RawBuffer &message, + const EVP_MD *md_algo, + const int rsa_padding); int verifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const int rsa_padding); + const RawBuffer &message, + const RawBuffer &signature, + const int rsa_padding); int digestVerifyMessage(EVP_PKEY *pubKey, - const RawBuffer &message, - const RawBuffer &signature, - const EVP_MD *md_algo, - const int rsa_padding); + const RawBuffer &message, + const RawBuffer &signature, + const EVP_MD *md_algo, + const int rsa_padding); bool verifyBinaryData(DataType dataType, const RawBuffer &buffer); diff --git a/src/manager/crypto/sw-backend/obj.cpp b/src/manager/crypto/sw-backend/obj.cpp index 7364fa8d..8b5e21a7 100644 --- a/src/manager/crypto/sw-backend/obj.cpp +++ b/src/manager/crypto/sw-backend/obj.cpp @@ -41,124 +41,138 @@ namespace { AlgoType key2algo(DataType type) { - switch (static_cast<int>(type)) { - case DataType::Type::KEY_RSA_PRIVATE: - case DataType::Type::KEY_RSA_PUBLIC: - return AlgoType::RSA_SV; - case DataType::Type::KEY_DSA_PRIVATE: - case DataType::Type::KEY_DSA_PUBLIC: - return AlgoType::DSA_SV; - case DataType::Type::KEY_ECDSA_PRIVATE: - case DataType::Type::KEY_ECDSA_PUBLIC: - return AlgoType::ECDSA_SV; - default: - ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", type); - } + switch (static_cast<int>(type)) { + case DataType::Type::KEY_RSA_PRIVATE: + case DataType::Type::KEY_RSA_PUBLIC: + return AlgoType::RSA_SV; + + case DataType::Type::KEY_DSA_PRIVATE: + case DataType::Type::KEY_DSA_PUBLIC: + return AlgoType::DSA_SV; + + case DataType::Type::KEY_ECDSA_PRIVATE: + case DataType::Type::KEY_ECDSA_PUBLIC: + return AlgoType::ECDSA_SV; + + default: + ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", type); + } } } // namespace anonymous -typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr; +typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr; RawBuffer SKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data) { - return Internals::symmetricEncrypt(getBinary(), alg, data); + return Internals::symmetricEncrypt(getBinary(), alg, data); } RawBuffer SKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &cipher) { - return Internals::symmetricDecrypt(getBinary(), alg, cipher); + return Internals::symmetricDecrypt(getBinary(), alg, cipher); } RawBuffer AKey::sign( - const CryptoAlgorithm &alg, - const RawBuffer &message) + const CryptoAlgorithm &alg, + const RawBuffer &message) { - CryptoAlgorithm algWithType(alg); - algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type)); - return Internals::sign(getEvpShPtr().get(), algWithType, message); + CryptoAlgorithm algWithType(alg); + algWithType.setParam(ParamName::ALGO_TYPE, key2algo(m_type)); + return Internals::sign(getEvpShPtr().get(), algWithType, message); } -int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign) +int AKey::verify(const CryptoAlgorithm &alg, const RawBuffer &message, + const RawBuffer &sign) { - CryptoAlgorithm algWithType(alg); - EVP_PKEY* evp = getEvpShPtr().get(); - AlgoType type; - - // setup algorithm type basing on evp key type if it doesn't exist - if (!algWithType.getParam(ParamName::ALGO_TYPE, type)) { - int subType = EVP_PKEY_type(evp->type); - switch (subType) { - case EVP_PKEY_RSA: - type = AlgoType::RSA_SV; break; - case EVP_PKEY_DSA: - type = AlgoType::DSA_SV; break; - case EVP_PKEY_EC: - type = AlgoType::ECDSA_SV; break; - default: - ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType); - } - algWithType.setParam(ParamName::ALGO_TYPE, type); - } - return Internals::verify(evp, algWithType, message, sign); + CryptoAlgorithm algWithType(alg); + EVP_PKEY *evp = getEvpShPtr().get(); + AlgoType type; + + // setup algorithm type basing on evp key type if it doesn't exist + if (!algWithType.getParam(ParamName::ALGO_TYPE, type)) { + int subType = EVP_PKEY_type(evp->type); + + switch (subType) { + case EVP_PKEY_RSA: + type = AlgoType::RSA_SV; + break; + + case EVP_PKEY_DSA: + type = AlgoType::DSA_SV; + break; + + case EVP_PKEY_EC: + type = AlgoType::ECDSA_SV; + break; + + default: + ThrowErr(Exc::Crypto::InputParam, "Invalid key type: ", subType); + } + + algWithType.setParam(ParamName::ALGO_TYPE, type); + } + + return Internals::verify(evp, algWithType, message, sign); } RawBuffer AKey::encrypt(const CryptoAlgorithm &alg, const RawBuffer &data) { - return Internals::asymmetricEncrypt(getEvpShPtr(), alg, data); + return Internals::asymmetricEncrypt(getEvpShPtr(), alg, data); } RawBuffer AKey::decrypt(const CryptoAlgorithm &alg, const RawBuffer &data) { - return Internals::asymmetricDecrypt(getEvpShPtr(), alg, data); + return Internals::asymmetricDecrypt(getEvpShPtr(), alg, data); } EvpShPtr AKey::getEvpShPtr() { - if (m_evp) - return m_evp; + if (m_evp) + return m_evp; - EVP_PKEY *pkey = NULL; - BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); + EVP_PKEY *pkey = NULL; + BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all); - LogDebug("Start to parse key:"); + LogDebug("Start to parse key:"); - if (!pkey) { - (void)BIO_reset(bio.get()); - BIO_write(bio.get(), m_raw.data(), m_raw.size()); - pkey = d2i_PrivateKey_bio(bio.get(), NULL); - LogDebug("Trying d2i_PrivateKey_bio Status: " << (void*)pkey); - } + if (!pkey) { + (void)BIO_reset(bio.get()); + BIO_write(bio.get(), m_raw.data(), m_raw.size()); + pkey = d2i_PrivateKey_bio(bio.get(), NULL); + LogDebug("Trying d2i_PrivateKey_bio Status: " << (void *)pkey); + } - if (!pkey) { - (void)BIO_reset(bio.get()); - BIO_write(bio.get(), m_raw.data(), m_raw.size()); - pkey = d2i_PUBKEY_bio(bio.get(), NULL); - LogDebug("Trying d2i_PUBKEY_bio Status: " << (void*)pkey); - } + if (!pkey) { + (void)BIO_reset(bio.get()); + BIO_write(bio.get(), m_raw.data(), m_raw.size()); + pkey = d2i_PUBKEY_bio(bio.get(), NULL); + LogDebug("Trying d2i_PUBKEY_bio Status: " << (void *)pkey); + } - if (!pkey) - ThrowErr(Exc::Crypto::InternalError, "Failed to parse key"); + if (!pkey) + ThrowErr(Exc::Crypto::InternalError, "Failed to parse key"); - m_evp.reset(pkey, EVP_PKEY_free); - return m_evp; + m_evp.reset(pkey, EVP_PKEY_free); + return m_evp; } EvpShPtr Cert::getEvpShPtr() { - if (m_evp) - return m_evp; + if (m_evp) + return m_evp; - int size = static_cast<int>(m_raw.size()); - const unsigned char *ptr = reinterpret_cast<const unsigned char *>(m_raw.data()); + int size = static_cast<int>(m_raw.size()); + const unsigned char *ptr = reinterpret_cast<const unsigned char *> + (m_raw.data()); - X509 *x509 = d2i_X509(NULL, &ptr, size); + X509 *x509 = d2i_X509(NULL, &ptr, size); - if (!x509) - ThrowErr(Exc::Crypto::InternalError, "Failed to parse certificate."); + if (!x509) + ThrowErr(Exc::Crypto::InternalError, "Failed to parse certificate."); - m_evp.reset(X509_get_pubkey(x509), EVP_PKEY_free); - X509_free(x509); - return m_evp; + m_evp.reset(X509_get_pubkey(x509), EVP_PKEY_free); + X509_free(x509); + return m_evp; } } // namespace SW diff --git a/src/manager/crypto/sw-backend/obj.h b/src/manager/crypto/sw-backend/obj.h index 082664a2..0a00734f 100644 --- a/src/manager/crypto/sw-backend/obj.h +++ b/src/manager/crypto/sw-backend/obj.h @@ -30,59 +30,61 @@ namespace CKM { namespace Crypto { namespace SW { -typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX*)>> ContextUPtr; +typedef std::unique_ptr<EVP_PKEY_CTX, std::function<void(EVP_PKEY_CTX *)>> + ContextUPtr; typedef std::shared_ptr<EVP_PKEY> EvpShPtr; class BData : public GObj { public: - BData(RawBuffer buffer, DataType keyType) - : m_raw(std::move(buffer)) - , m_type(keyType) - { - } + BData(RawBuffer buffer, DataType keyType) : + m_raw(std::move(buffer)), m_type(keyType) {} + + virtual RawBuffer getBinary() const + { + return m_raw; + } - virtual RawBuffer getBinary() const { return m_raw; } protected: - RawBuffer m_raw; - DataType m_type; + RawBuffer m_raw; + DataType m_type; }; class SKey : public BData { public: - SKey(RawBuffer buffer, DataType keyType) : BData(std::move(buffer), keyType) - { - } + SKey(RawBuffer buffer, DataType keyType) : + BData(std::move(buffer), keyType) {} - virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &); - virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &); + virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &); + virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &); }; class AKey : public BData { public: - AKey(RawBuffer buffer, DataType dataType) : BData(std::move(buffer), dataType) - { - } - virtual RawBuffer sign(const CryptoAlgorithm &alg, const RawBuffer &message); - virtual int verify(const CryptoAlgorithm &alg, const RawBuffer &message, const RawBuffer &sign); - virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &); - virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &); - virtual ~AKey() {} + AKey(RawBuffer buffer, DataType dataType) : + BData(std::move(buffer), dataType) {} + + virtual RawBuffer sign(const CryptoAlgorithm &alg, const RawBuffer &message); + virtual int verify(const CryptoAlgorithm &alg, const RawBuffer &message, + const RawBuffer &sign); + virtual RawBuffer encrypt(const CryptoAlgorithm &, const RawBuffer &); + virtual RawBuffer decrypt(const CryptoAlgorithm &, const RawBuffer &); + virtual ~AKey() {} protected: - virtual EvpShPtr getEvpShPtr(); + virtual EvpShPtr getEvpShPtr(); - EvpShPtr m_evp; + EvpShPtr m_evp; }; class Cert : public AKey { public: - Cert(RawBuffer buffer, DataType dataType) - : AKey(std::move(buffer), dataType) - { - } - virtual ~Cert() {} + Cert(RawBuffer buffer, DataType dataType) : + AKey(std::move(buffer), dataType) {} + + virtual ~Cert() {} + protected: - virtual EvpShPtr getEvpShPtr(); + virtual EvpShPtr getEvpShPtr(); }; } // namespace SW diff --git a/src/manager/crypto/sw-backend/store.cpp b/src/manager/crypto/sw-backend/store.cpp index b3143ebd..ca44df90 100644 --- a/src/manager/crypto/sw-backend/store.cpp +++ b/src/manager/crypto/sw-backend/store.cpp @@ -44,193 +44,210 @@ const int STORE_AES_GCM_TAG_SIZE = 16; // length of AES GCM tag // internal SW encryption scheme flags enum EncryptionScheme { - NONE = 0, - PASSWORD = 1 << 0 + NONE = 0, + PASSWORD = 1 << 0 }; template <typename T, typename ...Args> -std::unique_ptr<T> make_unique(Args&& ...args) +std::unique_ptr<T> make_unique(Args &&...args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } RawBuffer generateRandIV() { - RawBuffer civ(EVP_MAX_IV_LENGTH); + RawBuffer civ(EVP_MAX_IV_LENGTH); - if (1 != RAND_bytes(civ.data(), civ.size())) - ThrowErr(Exc::Crypto::InternalError, "RAND_bytes failed to generate IV."); - return civ; + if (1 != RAND_bytes(civ.data(), civ.size())) + ThrowErr(Exc::Crypto::InternalError, "RAND_bytes failed to generate IV."); + + return civ; } -RawBuffer passwordToKey(const Password &password, const RawBuffer &salt, size_t keySize) +RawBuffer passwordToKey(const Password &password, const RawBuffer &salt, + size_t keySize) { - RawBuffer result(keySize); - - if (1 != PKCS5_PBKDF2_HMAC_SHA1( - password.c_str(), - password.size(), - salt.data(), - salt.size(), - ITERATIONS, - result.size(), - result.data())) - ThrowErr(Exc::InternalError, "PCKS5_PKKDF2_HMAC_SHA1 failed."); - - return result; + RawBuffer result(keySize); + + if (1 != PKCS5_PBKDF2_HMAC_SHA1( + password.c_str(), + password.size(), + salt.data(), + salt.size(), + ITERATIONS, + result.size(), + result.data())) + ThrowErr(Exc::InternalError, "PCKS5_PKKDF2_HMAC_SHA1 failed."); + + return result; } -RawBuffer unpack(const RawBuffer& packed, const Password& pass) +RawBuffer unpack(const RawBuffer &packed, const Password &pass) { - MessageBuffer buffer; - buffer.Push(packed); - int encryptionScheme = 0; - RawBuffer data; - buffer.Deserialize(encryptionScheme, data); - - if (encryptionScheme == 0) - return data; - - MessageBuffer internalBuffer; - internalBuffer.Push(data); - RawBuffer encrypted; - RawBuffer iv; - RawBuffer tag; - - // serialization exceptions will be catched as CKM::Exception and will cause - // CKM_API_ERROR_SERVER_ERROR - internalBuffer.Deserialize(encrypted, iv, tag); - - /* - * AES GCM will check data integrity and handle cases where: - * - wrong password is used - * - password is empty when it shouldn't be - * - password is not empty when it should be - */ - RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH); - - RawBuffer ret; - try { - ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag); - } catch( const Exc::Crypto::InternalError& e) { - ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed"); - } - return ret; + MessageBuffer buffer; + buffer.Push(packed); + int encryptionScheme = 0; + RawBuffer data; + buffer.Deserialize(encryptionScheme, data); + + if (encryptionScheme == 0) + return data; + + MessageBuffer internalBuffer; + internalBuffer.Push(data); + RawBuffer encrypted; + RawBuffer iv; + RawBuffer tag; + + // serialization exceptions will be catched as CKM::Exception and will cause + // CKM_API_ERROR_SERVER_ERROR + internalBuffer.Deserialize(encrypted, iv, tag); + + /* + * AES GCM will check data integrity and handle cases where: + * - wrong password is used + * - password is empty when it shouldn't be + * - password is not empty when it should be + */ + RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH); + + RawBuffer ret; + + try { + ret = Crypto::SW::Internals::decryptDataAesGcm(key, encrypted, iv, tag); + } catch (const Exc::Crypto::InternalError &e) { + ThrowErr(Exc::AuthenticationFailed, "Decryption with custom password failed"); + } + + return ret; } -RawBuffer pack(const RawBuffer& data, const Password& pass) +RawBuffer pack(const RawBuffer &data, const Password &pass) { - int scheme = EncryptionScheme::NONE; - RawBuffer packed = data; - if (!pass.empty()) { - RawBuffer iv = generateRandIV(); - RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH); - - std::pair<RawBuffer, RawBuffer> ret; - try { - ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv, STORE_AES_GCM_TAG_SIZE); - } catch( const Exc::Crypto::InternalError& e) { - ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed"); - } - scheme |= EncryptionScheme::PASSWORD; - - // serialization exceptions will be catched as CKM::Exception and will cause - // CKM_API_ERROR_SERVER_ERROR - packed = MessageBuffer::Serialize(ret.first, iv, ret.second).Pop(); - } - // encryption scheme + internal buffer - return MessageBuffer::Serialize(scheme, packed).Pop(); + int scheme = EncryptionScheme::NONE; + RawBuffer packed = data; + + if (!pass.empty()) { + RawBuffer iv = generateRandIV(); + RawBuffer key = passwordToKey(pass, iv, KEY_LENGTH); + + std::pair<RawBuffer, RawBuffer> ret; + + try { + ret = Crypto::SW::Internals::encryptDataAesGcm(key, data, iv, + STORE_AES_GCM_TAG_SIZE); + } catch (const Exc::Crypto::InternalError &e) { + ThrowErr(Exc::AuthenticationFailed, "Encryption with custom password failed"); + } + + scheme |= EncryptionScheme::PASSWORD; + + // serialization exceptions will be catched as CKM::Exception and will cause + // CKM_API_ERROR_SERVER_ERROR + packed = MessageBuffer::Serialize(ret.first, iv, ret.second).Pop(); + } + + // encryption scheme + internal buffer + return MessageBuffer::Serialize(scheme, packed).Pop(); } } // namespace anonymous -namespace -{ -const char * const DEVICE_KEY_XSD = RO_DATA_DIR "/sw_key.xsd"; -const char * const DEVICE_KEY_SW_FILE = RW_DATA_DIR "/device_key.xml"; +namespace { +const char *const DEVICE_KEY_XSD = RO_DATA_DIR "/sw_key.xsd"; +const char *const DEVICE_KEY_SW_FILE = RW_DATA_DIR "/device_key.xml"; } Store::Store(CryptoBackend backendId) - : GStore(backendId) + : GStore(backendId) { - // get the device key if present - InitialValues::SWKeyFile keyFile(DEVICE_KEY_SW_FILE); - int rc = keyFile.Validate(DEVICE_KEY_XSD); - if (rc == XML::Parser::PARSE_SUCCESS) { - rc = keyFile.Parse(); - if (rc == XML::Parser::PARSE_SUCCESS) - m_deviceKey = keyFile.getPrivKey(); - else - // do nothing, bypass encrypted elements - LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", parsing code: " << rc); - } else { - LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", validation code: " << rc); - } + // get the device key if present + InitialValues::SWKeyFile keyFile(DEVICE_KEY_SW_FILE); + int rc = keyFile.Validate(DEVICE_KEY_XSD); + + if (rc == XML::Parser::PARSE_SUCCESS) { + rc = keyFile.Parse(); + + if (rc == XML::Parser::PARSE_SUCCESS) + m_deviceKey = keyFile.getPrivKey(); + else + // do nothing, bypass encrypted elements + LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << ", parsing code: " + << rc); + } else { + LogWarning("invalid SW key file: " << DEVICE_KEY_SW_FILE << + ", validation code: " << rc); + } } GObjUPtr Store::getObject(const Token &token, const Password &pass) { - if (token.backendId != m_backendId) - ThrowErr(Exc::Crypto::WrongBackend, "Decider choose wrong backend!"); + if (token.backendId != m_backendId) + ThrowErr(Exc::Crypto::WrongBackend, "Decider choose wrong backend!"); - RawBuffer data = unpack(token.data, pass); + RawBuffer data = unpack(token.data, pass); - if (token.dataType.isKeyPrivate() || token.dataType.isKeyPublic()) - return make_unique<AKey>(data, token.dataType); + if (token.dataType.isKeyPrivate() || token.dataType.isKeyPublic()) + return make_unique<AKey>(data, token.dataType); - if (token.dataType == DataType(DataType::KEY_AES)) - return make_unique<SKey>(data, token.dataType); + if (token.dataType == DataType(DataType::KEY_AES)) + return make_unique<SKey>(data, token.dataType); - if (token.dataType.isCertificate() || token.dataType.isChainCert()) - return make_unique<Cert>(data, token.dataType); + if (token.dataType.isCertificate() || token.dataType.isChainCert()) + return make_unique<Cert>(data, token.dataType); - if (token.dataType.isBinaryData()) - return make_unique<BData>(data, token.dataType); + if (token.dataType.isBinaryData()) + return make_unique<BData>(data, token.dataType); - ThrowErr(Exc::Crypto::DataTypeNotSupported, - "This type of data is not supported by openssl backend: ", (int)token.dataType); + ThrowErr(Exc::Crypto::DataTypeNotSupported, + "This type of data is not supported by openssl backend: ", (int)token.dataType); } TokenPair Store::generateAKey(const CryptoAlgorithm &algorithm, - const Password &prvPass, - const Password &pubPass) + const Password &prvPass, + const Password &pubPass) { - Internals::DataPair ret = Internals::generateAKey(algorithm); - return std::make_pair<Token, Token>( - Token(m_backendId, ret.first.type, pack(ret.first.buffer, prvPass)), - Token(m_backendId, ret.second.type, pack(ret.second.buffer, pubPass))); + Internals::DataPair ret = Internals::generateAKey(algorithm); + return std::make_pair<Token, Token>( + Token(m_backendId, ret.first.type, pack(ret.first.buffer, prvPass)), + Token(m_backendId, ret.second.type, pack(ret.second.buffer, pubPass))); } -Token Store::generateSKey(const CryptoAlgorithm &algorithm, const Password &pass) +Token Store::generateSKey(const CryptoAlgorithm &algorithm, + const Password &pass) { - Internals::Data ret = Internals::generateSKey(algorithm); - return Token(m_backendId, ret.type, pack(ret.buffer, pass)); + Internals::Data ret = Internals::generateSKey(algorithm); + return Token(m_backendId, ret.type, pack(ret.buffer, pass)); } Token Store::import(const Data &data, const Password &pass) { - return Token(m_backendId, data.type, pack(data.data, pass)); + return Token(m_backendId, data.type, pack(data.data, pass)); } -Token Store::importEncrypted(const Data &data, const Password &pass, const DataEncryption &enc) +Token Store::importEncrypted(const Data &data, const Password &pass, + const DataEncryption &enc) { - if (!m_deviceKey) - ThrowErr(Exc::Crypto::InternalError, "No device key present"); - - // decrypt the AES key using device key - CryptoAlgorithm algorithmRSAOAEP; - algorithmRSAOAEP.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP); - Crypto::SW::SKey aesKey(m_deviceKey->decrypt(algorithmRSAOAEP, enc.encryptedKey), DataType::KEY_AES); - - // decrypt the buffer using AES key - CryptoAlgorithm algorithmAESCBC; - algorithmAESCBC.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC); - algorithmAESCBC.setParam(ParamName::ED_IV, enc.iv); - RawBuffer rawData = aesKey.decrypt(algorithmAESCBC, data.data); - if (!Internals::verifyBinaryData(data.type, rawData)) - ThrowErr(Exc::Crypto::InputParam, "Verification failed. Data could not be imported!"); - - return Token(m_backendId, data.type, pack(rawData, pass)); + if (!m_deviceKey) + ThrowErr(Exc::Crypto::InternalError, "No device key present"); + + // decrypt the AES key using device key + CryptoAlgorithm algorithmRSAOAEP; + algorithmRSAOAEP.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP); + Crypto::SW::SKey aesKey(m_deviceKey->decrypt(algorithmRSAOAEP, + enc.encryptedKey), DataType::KEY_AES); + + // decrypt the buffer using AES key + CryptoAlgorithm algorithmAESCBC; + algorithmAESCBC.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC); + algorithmAESCBC.setParam(ParamName::ED_IV, enc.iv); + RawBuffer rawData = aesKey.decrypt(algorithmAESCBC, data.data); + + if (!Internals::verifyBinaryData(data.type, rawData)) + ThrowErr(Exc::Crypto::InputParam, + "Verification failed. Data could not be imported!"); + + return Token(m_backendId, data.type, pack(rawData, pass)); } } // namespace SW diff --git a/src/manager/crypto/sw-backend/store.h b/src/manager/crypto/sw-backend/store.h index a29f30c0..6132b92b 100644 --- a/src/manager/crypto/sw-backend/store.h +++ b/src/manager/crypto/sw-backend/store.h @@ -29,17 +29,19 @@ namespace SW { class Store : public GStore { public: - explicit Store(CryptoBackend backendId); + explicit Store(CryptoBackend backendId); - virtual GObjUPtr getObject(const Token &, const Password &); - virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, const Password &); - virtual Token generateSKey(const CryptoAlgorithm &, const Password &); - virtual Token import(const Data &data, const Password &); - virtual Token importEncrypted(const Data &, const Password &, const DataEncryption &); - virtual void destroy(const Token &) {} + virtual GObjUPtr getObject(const Token &, const Password &); + virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, + const Password &); + virtual Token generateSKey(const CryptoAlgorithm &, const Password &); + virtual Token import(const Data &data, const Password &); + virtual Token importEncrypted(const Data &, const Password &, + const DataEncryption &); + virtual void destroy(const Token &) {} private: - Crypto::GObjShPtr m_deviceKey; + Crypto::GObjShPtr m_deviceKey; }; } // namespace SW diff --git a/src/manager/crypto/tz-backend/obj.h b/src/manager/crypto/tz-backend/obj.h index d8ca54a3..424563c5 100644 --- a/src/manager/crypto/tz-backend/obj.h +++ b/src/manager/crypto/tz-backend/obj.h @@ -28,16 +28,16 @@ namespace TZ { class SKey : public GObj { public: - SKey() {} - virtual ~SKey() {} + SKey() {} + virtual ~SKey() {} protected: }; class AKey : public GObj { public: - AKey() {} - virtual ~AKey() {} + AKey() {} + virtual ~AKey() {} protected: }; diff --git a/src/manager/crypto/tz-backend/store.cpp b/src/manager/crypto/tz-backend/store.cpp index 8fd12f1f..e878b45f 100644 --- a/src/manager/crypto/tz-backend/store.cpp +++ b/src/manager/crypto/tz-backend/store.cpp @@ -27,28 +27,34 @@ namespace Crypto { namespace TZ { Store::Store(CryptoBackend backendId) : - GStore(backendId) + GStore(backendId) { } GObjUPtr Store::getObject(const Token &, const Password &) { - ThrowErr(Exc::Crypto::OperationNotSupported, "Trust zone backend is not implemented!"); + ThrowErr(Exc::Crypto::OperationNotSupported, + "Trust zone backend is not implemented!"); } -TokenPair Store::generateAKey(const CryptoAlgorithm &, const Password &, const Password &) +TokenPair Store::generateAKey(const CryptoAlgorithm &, const Password &, + const Password &) { - ThrowErr(Exc::Crypto::OperationNotSupported, "Trust zone backend is not implemented!"); + ThrowErr(Exc::Crypto::OperationNotSupported, + "Trust zone backend is not implemented!"); } Token Store::import(const Data &, const Password &) { - ThrowErr(Exc::Crypto::OperationNotSupported, "Trust zone backend is not implemented!"); + ThrowErr(Exc::Crypto::OperationNotSupported, + "Trust zone backend is not implemented!"); } -Token Store::importEncrypted(const Data &, const Password &, const DataEncryption &) +Token Store::importEncrypted(const Data &, const Password &, + const DataEncryption &) { - ThrowErr(Exc::Crypto::OperationNotSupported, "Trust zone backend is not implemented!"); + ThrowErr(Exc::Crypto::OperationNotSupported, + "Trust zone backend is not implemented!"); } } // namespace TZ diff --git a/src/manager/crypto/tz-backend/store.h b/src/manager/crypto/tz-backend/store.h index 2182ab5a..bb616072 100644 --- a/src/manager/crypto/tz-backend/store.h +++ b/src/manager/crypto/tz-backend/store.h @@ -29,13 +29,15 @@ namespace TZ { class Store : public GStore { public: - explicit Store(CryptoBackend backendId); + explicit Store(CryptoBackend backendId); - virtual GObjUPtr getObject(const Token &, const Password &); - virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, const Password &); - virtual Token import(const Data &data, const Password &); - virtual Token importEncrypted(const Data &, const Password &, const DataEncryption &); - virtual void destroy(const Token &){} + virtual GObjUPtr getObject(const Token &, const Password &); + virtual TokenPair generateAKey(const CryptoAlgorithm &, const Password &, + const Password &); + virtual Token import(const Data &data, const Password &); + virtual Token importEncrypted(const Data &, const Password &, + const DataEncryption &); + virtual void destroy(const Token &) {} }; } // namespace TZ diff --git a/src/manager/dpl/core/include/dpl/assert.h b/src/manager/dpl/core/include/dpl/assert.h index ad0205da..ee865d19 100644 --- a/src/manager/dpl/core/include/dpl/assert.h +++ b/src/manager/dpl/core/include/dpl/assert.h @@ -30,24 +30,24 @@ namespace CKM { // Do not call directly // Always use Assert macro CENT_KEY_NORETURN void AssertProc(const char *condition, - const char *file, - int line, - const char *function); + const char *file, + int line, + const char *function); } // namespace CKM #define Assert(Condition) do { if (!(Condition)) { CKM::AssertProc(#Condition, \ - __FILE__, \ - __LINE__, \ - __FUNCTION__); \ - } } while (0) + __FILE__, \ + __LINE__, \ + __FUNCTION__); \ + } } while (0) #define AssertMsg(Condition, Msg) \ - do { \ - if (!(Condition)) { \ - CKM::AssertProc( \ - (std::string(std::string(#Condition)+" ") + Msg).c_str(), \ - __FILE__, __LINE__, __FUNCTION__); \ - } \ - } while (0) + do { \ + if (!(Condition)) { \ + CKM::AssertProc( \ + (std::string(std::string(#Condition)+" ") + Msg).c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ + } while (0) #endif // CENT_KEY_ASSERT_H diff --git a/src/manager/dpl/core/include/dpl/binary_queue.h b/src/manager/dpl/core/include/dpl/binary_queue.h index e8f1a33f..54c1c673 100644 --- a/src/manager/dpl/core/include/dpl/binary_queue.h +++ b/src/manager/dpl/core/include/dpl/binary_queue.h @@ -42,266 +42,266 @@ typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr; * @todo Add optimized implementation for FlattenConsume */ class COMMON_API BinaryQueue { -// : public AbstractInputOutput + // : public AbstractInputOutput public: - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, OutOfData) - }; - - typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize, - void *userParam); - static void BufferDeleterFree(const void *buffer, - size_t bufferSize, - void *userParam); - - class BucketVisitor { - public: - /** - * Destructor - */ - virtual ~BucketVisitor(); - - /** - * Visit bucket - * - * @return none - * @param[in] buffer Constant pointer to bucket data buffer - * @param[in] bufferSize Number of bytes in bucket - */ - virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0; - }; + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; + + typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize, + void *userParam); + static void BufferDeleterFree(const void *buffer, + size_t bufferSize, + void *userParam); + + class BucketVisitor { + public: + /** + * Destructor + */ + virtual ~BucketVisitor(); + + /** + * Visit bucket + * + * @return none + * @param[in] buffer Constant pointer to bucket data buffer + * @param[in] bufferSize Number of bytes in bucket + */ + virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0; + }; private: - struct Bucket { - NONCOPYABLE(Bucket); - - const void *buffer; - const void *ptr; - size_t size; - size_t left; - - BufferDeleter deleter; - void *param; - - Bucket(const void *buffer, - size_t bufferSize, - BufferDeleter deleter, - void *userParam); - virtual ~Bucket(); - }; - - typedef std::list<Bucket *> BucketList; - BucketList m_buckets; - size_t m_size; - - static void DeleteBucket(Bucket *bucket); - - class BucketVisitorCall { - private: - BucketVisitor *m_visitor; - - public: - BucketVisitorCall(BucketVisitor *visitor); - virtual ~BucketVisitorCall(); - - void operator()(Bucket *bucket) const; - }; - - public: - /** - * Construct empty binary queue - */ - BinaryQueue(); - - /** - * Construct binary queue via bare copy of other binary queue - * - * @param[in] other Other binary queue to copy from - * @warning One cannot assume that bucket structure is preserved during copy - */ - BinaryQueue(const BinaryQueue &other); - - /** - * Construct binary queue by moving data from other binary queue - * - * @param[in] other Other binary queue to move from - */ - BinaryQueue(BinaryQueue&&) = default; - - /** - * Destructor - */ - virtual ~BinaryQueue(); - - /** - * Construct binary queue via bare copy of other binary queue - * - * @param[in] other Other binary queue to copy from - * @warning One cannot assume that bucket structure is preserved during copy - */ - const BinaryQueue &operator=(const BinaryQueue &other); - - /** - * Assign data from other binary queue using move semantics - * - * @param[in] other Other binary queue to move from - */ - BinaryQueue &operator=(BinaryQueue&&) = default; - - /** - * Append copy of @a bufferSize bytes from memory pointed by @a buffer - * to the end of binary queue. Uses default deleter based on free. - * - * @return none - * @param[in] buffer Pointer to buffer to copy data from - * @param[in] bufferSize Number of bytes to copy - * @exception std::bad_alloc Cannot allocate memory to hold additional data - * @see BinaryQueue::BufferDeleterFree - */ - void AppendCopy(const void *buffer, size_t bufferSize); - - /** - * Append @a bufferSize bytes from memory pointed by @a buffer - * to the end of binary queue. Uses custom provided deleter. - * Responsibility for deleting provided buffer is transfered to BinaryQueue. - * - * @return none - * @param[in] buffer Pointer to data buffer - * @param[in] bufferSize Number of bytes available in buffer - * @param[in] deleter Pointer to deleter procedure used to free provided - * buffer - * @param[in] userParam User parameter passed to deleter routine - * @exception std::bad_alloc Cannot allocate memory to hold additional data - */ - void AppendUnmanaged( - const void *buffer, - size_t bufferSize, - BufferDeleter deleter = - &BinaryQueue::BufferDeleterFree, - void *userParam = NULL); - - /** - * Append copy of other binary queue to the end of this binary queue - * - * @return none - * @param[in] other Constant reference to other binary queue to copy data - * from - * @exception std::bad_alloc Cannot allocate memory to hold additional data - * @warning One cannot assume that bucket structure is preserved during copy - */ - void AppendCopyFrom(const BinaryQueue &other); - - /** - * Move bytes from other binary queue to the end of this binary queue. - * This also removes all bytes from other binary queue. - * This method is designed to be as fast as possible (only pointer swaps) - * and is suggested over making copies of binary queues. - * Bucket structure is preserved after operation. - * - * @return none - * @param[in] other Reference to other binary queue to move data from - * @exception std::bad_alloc Cannot allocate memory to hold additional data - */ - void AppendMoveFrom(BinaryQueue &other); - - /** - * Append copy of binary queue to the end of other binary queue - * - * @return none - * @param[in] other Constant reference to other binary queue to copy data to - * @exception std::bad_alloc Cannot allocate memory to hold additional data - * @warning One cannot assume that bucket structure is preserved during copy - */ - void AppendCopyTo(BinaryQueue &other) const; - - /** - * Move bytes from binary queue to the end of other binary queue. - * This also removes all bytes from binary queue. - * This method is designed to be as fast as possible (only pointer swaps) - * and is suggested over making copies of binary queues. - * Bucket structure is preserved after operation. - * - * @return none - * @param[in] other Reference to other binary queue to move data to - * @exception std::bad_alloc Cannot allocate memory to hold additional data - */ - void AppendMoveTo(BinaryQueue &other); - - /** - * Retrieve total size of all data contained in binary queue - * - * @return Number of bytes in binary queue - */ - size_t Size() const; - - /** - * Remove all data from binary queue - * - * @return none - */ - void Clear(); - - /** - * Check if binary queue is empty - * - * @return true if binary queue is empty, false otherwise - */ - bool Empty() const; - - /** - * Remove @a size bytes from beginning of binary queue - * - * @return none - * @param[in] size Number of bytes to remove - * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger - * than available bytes in binary queue - */ - void Consume(size_t size); - - /** - * Retrieve @a bufferSize bytes from beginning of binary queue and copy them - * to user supplied buffer - * - * @return none - * @param[in] buffer Pointer to user buffer to receive bytes - * @param[in] bufferSize Size of user buffer pointed by @a buffer - * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten - * is larger than available bytes in binary queue - */ - void Flatten(void *buffer, size_t bufferSize) const; - - /** - * Retrieve @a bufferSize bytes from beginning of binary queue, copy them - * to user supplied buffer, and remove from binary queue - * - * @return none - * @param[in] buffer Pointer to user buffer to receive bytes - * @param[in] bufferSize Size of user buffer pointed by @a buffer - * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten - * is larger than available bytes in binary queue - */ - void FlattenConsume(void *buffer, size_t bufferSize); - - /** - * Visit each buffer with data using visitor object - * - * @return none - * @param[in] visitor Pointer to bucket visitor - * @see BinaryQueue::BucketVisitor - */ - void VisitBuckets(BucketVisitor *visitor) const; - - /** - * IAbstractInput interface - */ - virtual BinaryQueueAutoPtr Read(size_t size); - - /** - * IAbstractOutput interface - */ - virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); + struct Bucket { + NONCOPYABLE(Bucket); + + const void *buffer; + const void *ptr; + size_t size; + size_t left; + + BufferDeleter deleter; + void *param; + + Bucket(const void *buffer, + size_t bufferSize, + BufferDeleter deleter, + void *userParam); + virtual ~Bucket(); + }; + + typedef std::list<Bucket *> BucketList; + BucketList m_buckets; + size_t m_size; + + static void DeleteBucket(Bucket *bucket); + + class BucketVisitorCall { + private: + BucketVisitor *m_visitor; + + public: + BucketVisitorCall(BucketVisitor *visitor); + virtual ~BucketVisitorCall(); + + void operator()(Bucket *bucket) const; + }; + +public: + /** + * Construct empty binary queue + */ + BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + BinaryQueue(const BinaryQueue &other); + + /** + * Construct binary queue by moving data from other binary queue + * + * @param[in] other Other binary queue to move from + */ + BinaryQueue(BinaryQueue &&) = default; + + /** + * Destructor + */ + virtual ~BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + const BinaryQueue &operator=(const BinaryQueue &other); + + /** + * Assign data from other binary queue using move semantics + * + * @param[in] other Other binary queue to move from + */ + BinaryQueue &operator=(BinaryQueue &&) = default; + + /** + * Append copy of @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses default deleter based on free. + * + * @return none + * @param[in] buffer Pointer to buffer to copy data from + * @param[in] bufferSize Number of bytes to copy + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @see BinaryQueue::BufferDeleterFree + */ + void AppendCopy(const void *buffer, size_t bufferSize); + + /** + * Append @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses custom provided deleter. + * Responsibility for deleting provided buffer is transfered to BinaryQueue. + * + * @return none + * @param[in] buffer Pointer to data buffer + * @param[in] bufferSize Number of bytes available in buffer + * @param[in] deleter Pointer to deleter procedure used to free provided + * buffer + * @param[in] userParam User parameter passed to deleter routine + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendUnmanaged( + const void *buffer, + size_t bufferSize, + BufferDeleter deleter = + &BinaryQueue::BufferDeleterFree, + void *userParam = NULL); + + /** + * Append copy of other binary queue to the end of this binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data + * from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyFrom(const BinaryQueue &other); + + /** + * Move bytes from other binary queue to the end of this binary queue. + * This also removes all bytes from other binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveFrom(BinaryQueue &other); + + /** + * Append copy of binary queue to the end of other binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyTo(BinaryQueue &other) const; + + /** + * Move bytes from binary queue to the end of other binary queue. + * This also removes all bytes from binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveTo(BinaryQueue &other); + + /** + * Retrieve total size of all data contained in binary queue + * + * @return Number of bytes in binary queue + */ + size_t Size() const; + + /** + * Remove all data from binary queue + * + * @return none + */ + void Clear(); + + /** + * Check if binary queue is empty + * + * @return true if binary queue is empty, false otherwise + */ + bool Empty() const; + + /** + * Remove @a size bytes from beginning of binary queue + * + * @return none + * @param[in] size Number of bytes to remove + * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger + * than available bytes in binary queue + */ + void Consume(size_t size); + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue and copy them + * to user supplied buffer + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void Flatten(void *buffer, size_t bufferSize) const; + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue, copy them + * to user supplied buffer, and remove from binary queue + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void FlattenConsume(void *buffer, size_t bufferSize); + + /** + * Visit each buffer with data using visitor object + * + * @return none + * @param[in] visitor Pointer to bucket visitor + * @see BinaryQueue::BucketVisitor + */ + void VisitBuckets(BucketVisitor *visitor) const; + + /** + * IAbstractInput interface + */ + virtual BinaryQueueAutoPtr Read(size_t size); + + /** + * IAbstractOutput interface + */ + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); }; } // namespace CKM diff --git a/src/manager/dpl/core/include/dpl/colors.h b/src/manager/dpl/core/include/dpl/colors.h index 5750425d..a03b3449 100644 --- a/src/manager/dpl/core/include/dpl/colors.h +++ b/src/manager/dpl/core/include/dpl/colors.h @@ -27,25 +27,25 @@ namespace CKM { namespace Colors { namespace Text { -extern const char* BOLD_GREEN_BEGIN; -extern const char* BOLD_GREEN_END; -extern const char* PURPLE_BEGIN; -extern const char* PURPLE_END; -extern const char* RED_BEGIN; -extern const char* RED_END; -extern const char* GREEN_BEGIN; -extern const char* GREEN_END; -extern const char* CYAN_BEGIN; -extern const char* CYAN_END; -extern const char* BOLD_RED_BEGIN; -extern const char* BOLD_RED_END; -extern const char* BOLD_YELLOW_BEGIN; -extern const char* BOLD_YELLOW_END; -extern const char* BOLD_GOLD_BEGIN; -extern const char* BOLD_GOLD_END; -extern const char* BOLD_WHITE_BEGIN; -extern const char* BOLD_WHITE_END; -extern const char* COLOR_END; +extern const char *BOLD_GREEN_BEGIN; +extern const char *BOLD_GREEN_END; +extern const char *PURPLE_BEGIN; +extern const char *PURPLE_END; +extern const char *RED_BEGIN; +extern const char *RED_END; +extern const char *GREEN_BEGIN; +extern const char *GREEN_END; +extern const char *CYAN_BEGIN; +extern const char *CYAN_END; +extern const char *BOLD_RED_BEGIN; +extern const char *BOLD_RED_END; +extern const char *BOLD_YELLOW_BEGIN; +extern const char *BOLD_YELLOW_END; +extern const char *BOLD_GOLD_BEGIN; +extern const char *BOLD_GOLD_END; +extern const char *BOLD_WHITE_BEGIN; +extern const char *BOLD_WHITE_END; +extern const char *COLOR_END; } //namespace Text } //namespace Colors } //namespace CKM diff --git a/src/manager/dpl/core/include/dpl/exception.h b/src/manager/dpl/core/include/dpl/exception.h index 7bc7ad30..538076b6 100644 --- a/src/manager/dpl/core/include/dpl/exception.h +++ b/src/manager/dpl/core/include/dpl/exception.h @@ -33,330 +33,304 @@ namespace CKM { COMMON_API void LogUnhandledException(const std::string &str); COMMON_API void LogUnhandledException(const std::string &str, - const char *filename, - int line, - const char *function); + const char *filename, + int line, + const char *function); } namespace CKM { -class COMMON_API Exception -{ - private: - static unsigned int m_exceptionCount; - static Exception* m_lastException; - static void (*m_terminateHandler)(); - - static void AddRef(Exception* exception) - { - if (!m_exceptionCount) - m_terminateHandler = std::set_terminate(&TerminateHandler); - - ++m_exceptionCount; - m_lastException = exception; - } - - static void UnRef(Exception* e) - { - if (m_lastException == e) - m_lastException = NULL; - - --m_exceptionCount; - - if (!m_exceptionCount) { - std::set_terminate(m_terminateHandler); - m_terminateHandler = NULL; - } - } - - static void TerminateHandler() - { - if (m_lastException != NULL) { - DisplayKnownException(*m_lastException); - abort(); - } else { - DisplayUnknownException(); - abort(); - } - } - - Exception *m_reason; - std::string m_path; - std::string m_function; - int m_line; - - protected: - std::string m_message; - std::string m_className; - - public: - static std::string KnownExceptionToString(const Exception &e) - { - std::ostringstream message; - message << - "\033[1;5;31m\n=== Unhandled CKM exception occurred ===\033[m\n\n"; - message << "\033[1;33mException trace:\033[m\n\n"; - message << e.DumpToString(); - message << "\033[1;31m\n=== Will now abort ===\033[m\n"; - - return message.str(); - } - - static std::string UnknownExceptionToString() - { - std::ostringstream message; - message << - "\033[1;5;31m\n=== Unhandled non-CKM exception occurred ===\033[m\n\n"; - message << "\033[1;31m\n=== Will now abort ===\033[m\n"; - - return message.str(); - } - - static void DisplayKnownException(const Exception& e) - { - LogUnhandledException(KnownExceptionToString(e).c_str()); - } - - static void DisplayUnknownException() - { - LogUnhandledException(UnknownExceptionToString().c_str()); - } - - Exception(const Exception &other) - { - // Deep copy - if (other.m_reason != NULL) - m_reason = new Exception(*other.m_reason); - else - m_reason = NULL; - - m_message = other.m_message; - m_path = other.m_path; - m_function = other.m_function; - m_line = other.m_line; - - m_className = other.m_className; - - AddRef(this); - } - - const Exception &operator =(const Exception &other) - { - if (this == &other) - return *this; - - // Deep copy - if (other.m_reason != NULL) - m_reason = new Exception(*other.m_reason); - else - m_reason = NULL; - - m_message = other.m_message; - m_path = other.m_path; - m_function = other.m_function; - m_line = other.m_line; - - m_className = other.m_className; - - AddRef(this); - - return *this; - } - - Exception(const char *path, - const char *function, - int line, - const std::string &message) : - m_reason(NULL), - m_path(path), - m_function(function), - m_line(line), - m_message(message) - { - AddRef(this); - } - - Exception(const char *path, - const char *function, - int line, - const Exception &reason, - const std::string &message) : - m_reason(new Exception(reason)), - m_path(path), - m_function(function), - m_line(line), - m_message(message) - { - AddRef(this); - } - - virtual ~Exception() throw() - { - if (m_reason != NULL) { - delete m_reason; - m_reason = NULL; - } - - UnRef(this); - } - - void Dump() const - { - // Show reason first - if (m_reason != NULL) - m_reason->Dump(); - - // Afterward, dump exception - const char *file = strchr(m_path.c_str(), '/'); - - if (file == NULL) - file = m_path.c_str(); - else - ++file; - - printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", - file, m_line, - m_function.c_str(), - m_className.c_str(), - m_message.empty() ? "<EMPTY>" : m_message.c_str()); - } - - std::string DumpToString() const - { - std::string ret; - if (m_reason != NULL) - ret = m_reason->DumpToString(); - - const char *file = strchr(m_path.c_str(), '/'); - - if (file == NULL) - file = m_path.c_str(); - else - ++file; - - char buf[1024]; - snprintf(buf, - sizeof(buf), - "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", - file, - m_line, - m_function.c_str(), - m_className.c_str(), - m_message.empty() ? "<EMPTY>" : m_message.c_str()); - - buf[sizeof(buf) - 1] = '\n'; - ret += buf; - - return ret; - } - - Exception *GetReason() const - { - return m_reason; - } - - std::string GetPath() const - { - return m_path; - } - - std::string GetFunction() const - { - return m_function; - } - - int GetLine() const - { - return m_line; - } - - std::string GetMessage() const - { - return m_message; - } - - std::string GetClassName() const - { - return m_className; - } +class COMMON_API Exception { +private: + static unsigned int m_exceptionCount; + static Exception *m_lastException; + static void (*m_terminateHandler)(); + + static void AddRef(Exception *exception) + { + if (!m_exceptionCount) + m_terminateHandler = std::set_terminate(&TerminateHandler); + + ++m_exceptionCount; + m_lastException = exception; + } + + static void UnRef(Exception *e) + { + if (m_lastException == e) + m_lastException = NULL; + + --m_exceptionCount; + + if (!m_exceptionCount) { + std::set_terminate(m_terminateHandler); + m_terminateHandler = NULL; + } + } + + static void TerminateHandler() + { + if (m_lastException != NULL) { + DisplayKnownException(*m_lastException); + abort(); + } else { + DisplayUnknownException(); + abort(); + } + } + + Exception *m_reason; + std::string m_path; + std::string m_function; + int m_line; + +protected: + std::string m_message; + std::string m_className; + +public: + static std::string KnownExceptionToString(const Exception &e) + { + std::ostringstream message; + message << + "\033[1;5;31m\n=== Unhandled CKM exception occurred ===\033[m\n\n"; + message << "\033[1;33mException trace:\033[m\n\n"; + message << e.DumpToString(); + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static std::string UnknownExceptionToString() + { + std::ostringstream message; + message << + "\033[1;5;31m\n=== Unhandled non-CKM exception occurred ===\033[m\n\n"; + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static void DisplayKnownException(const Exception &e) + { + LogUnhandledException(KnownExceptionToString(e).c_str()); + } + + static void DisplayUnknownException() + { + LogUnhandledException(UnknownExceptionToString().c_str()); + } + + Exception(const Exception &other) + { + // Deep copy + if (other.m_reason != NULL) + m_reason = new Exception(*other.m_reason); + else + m_reason = NULL; + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + } + + const Exception &operator=(const Exception &other) + { + if (this == &other) + return *this; + + // Deep copy + if (other.m_reason != NULL) + m_reason = new Exception(*other.m_reason); + else + m_reason = NULL; + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + + return *this; + } + + Exception(const char *path, + const char *function, + int line, + const std::string &message) : + m_reason(NULL), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + Exception(const char *path, + const char *function, + int line, + const Exception &reason, + const std::string &message) : + m_reason(new Exception(reason)), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + virtual ~Exception() throw() + { + if (m_reason != NULL) { + delete m_reason; + m_reason = NULL; + } + + UnRef(this); + } + + void Dump() const + { + // Show reason first + if (m_reason != NULL) + m_reason->Dump(); + + // Afterward, dump exception + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) + file = m_path.c_str(); + else + ++file; + + printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "<EMPTY>" : m_message.c_str()); + } + + std::string DumpToString() const + { + std::string ret; + + if (m_reason != NULL) + ret = m_reason->DumpToString(); + + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) + file = m_path.c_str(); + else + ++file; + + char buf[1024]; + snprintf(buf, + sizeof(buf), + "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, + m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "<EMPTY>" : m_message.c_str()); + + buf[sizeof(buf) - 1] = '\n'; + ret += buf; + + return ret; + } + + Exception *GetReason() const + { + return m_reason; + } + + std::string GetPath() const + { + return m_path; + } + + std::string GetFunction() const + { + return m_function; + } + + int GetLine() const + { + return m_line; + } + + std::string GetMessage() const + { + return m_message; + } + + std::string GetClassName() const + { + return m_className; + } }; } // namespace CKM -#define Try try - #define Throw(ClassName) \ - throw ClassName(__FILE__, __FUNCTION__, __LINE__) + throw ClassName(__FILE__, __FUNCTION__, __LINE__) #define ThrowMsg(ClassName, Message) \ - do { \ - std::ostringstream dplLoggingStream; \ - dplLoggingStream << Message; \ - throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \ - } while (0) - -#define ReThrow(ClassName) \ - throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception) - -#define ReThrowMsg(ClassName, Message) \ - throw ClassName(__FILE__, \ - __FUNCTION__, \ - __LINE__, \ - _rethrown_exception, \ - Message) - -#define Catch(ClassName) \ - catch (const ClassName &_rethrown_exception) - -#define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \ - class Class : \ - public BaseClass \ - { \ - public: \ - Class(const char *path, \ - const char *function, \ - int line, \ - const std::string & message = std::string()) : \ - BaseClass(path, function, line, message) \ - { \ - BaseClass::m_className = #Class; \ - } \ - \ - Class(const char *path, \ - const char *function, \ - int line, \ - const CKM::Exception & reason, \ - const std::string & message = std::string()) : \ - BaseClass(path, function, line, reason, message) \ - { \ - BaseClass::m_className = #Class; \ - } \ - }; - -#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try - -#define UNHANDLED_EXCEPTION_HANDLER_END \ - catch (const CKM::Exception &exception) \ - { \ - std::ostringstream msg; \ - msg << CKM::Exception::KnownExceptionToString(exception); \ - CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } \ - catch (std::exception& e) \ - { \ - std::ostringstream msg; \ - msg << e.what(); \ - msg << "\n"; \ - msg << CKM::Exception::UnknownExceptionToString(); \ - CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } \ - catch (...) \ - { \ - std::ostringstream msg; \ - msg << CKM::Exception::UnknownExceptionToString(); \ - CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ - abort(); \ - } + do { \ + std::ostringstream dplLoggingStream; \ + dplLoggingStream << Message; \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \ + } while (false) + +#define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \ + class Class : public BaseClass { \ + public: \ + Class(const char *path, \ + const char *function, \ + int line, \ + const std::string & message = std::string()) : \ + BaseClass(path, function, line, message) { \ + BaseClass::m_className = #Class; \ + } \ + \ + Class(const char *path, \ + const char *function, \ + int line, \ + const CKM::Exception & reason, \ + const std::string & message = std::string()) : \ + BaseClass(path, function, line, reason, message) { \ + BaseClass::m_className = #Class; \ + } \ + }; + +#define UNHANDLED_EXCEPTION_HANDLER_END \ + catch (const CKM::Exception &exception) { \ + std::ostringstream msg; \ + msg << CKM::Exception::KnownExceptionToString(exception); \ + CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } catch (std::exception& e) { \ + std::ostringstream msg; \ + msg << e.what(); \ + msg << "\n"; \ + msg << CKM::Exception::UnknownExceptionToString(); \ + CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } catch (...) { \ + std::ostringstream msg; \ + msg << CKM::Exception::UnknownExceptionToString(); \ + CKM::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } namespace CKM { namespace CommonException { @@ -368,8 +342,8 @@ namespace CommonException { * important messages. */ DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from - // underlying libraries or - // kernel +// underlying libraries or +// kernel } } diff --git a/src/manager/dpl/core/include/dpl/fstream_accessors.h b/src/manager/dpl/core/include/dpl/fstream_accessors.h index e5850354..6dea52eb 100644 --- a/src/manager/dpl/core/include/dpl/fstream_accessors.h +++ b/src/manager/dpl/core/include/dpl/fstream_accessors.h @@ -36,12 +36,12 @@ namespace CKM { template<typename T> class FstreamAccessors : T::__filebuf_type { - typedef FstreamAccessors<T> MyType; + typedef FstreamAccessors<T> MyType; public: - static int GetFd(T &strm) - { - return static_cast<MyType *>(strm.rdbuf())->_M_file.fd(); - } + static int GetFd(T &strm) + { + return static_cast<MyType *>(strm.rdbuf())->_M_file.fd(); + } }; } // namespace CKM diff --git a/src/manager/dpl/core/include/dpl/scoped_ptr.h b/src/manager/dpl/core/include/dpl/scoped_ptr.h index d39b0324..0c0a1910 100644 --- a/src/manager/dpl/core/include/dpl/scoped_ptr.h +++ b/src/manager/dpl/core/include/dpl/scoped_ptr.h @@ -26,11 +26,11 @@ #include <memory> namespace CKM { -struct free_deleter{ - void operator()(char *p) - { - free(p); - } +struct free_deleter { + void operator()(char *p) + { + free(p); + } }; typedef std::unique_ptr<char, free_deleter> CharUniquePtr; diff --git a/src/manager/dpl/core/include/dpl/serialization.h b/src/manager/dpl/core/include/dpl/serialization.h index 9f616808..5d4ed2bc 100644 --- a/src/manager/dpl/core/include/dpl/serialization.h +++ b/src/manager/dpl/core/include/dpl/serialization.h @@ -33,415 +33,424 @@ namespace CKM { // Abstract data stream buffer class IStream { - public: - virtual void Read(size_t num, void * bytes) = 0; - virtual void Write(size_t num, const void * bytes) = 0; - virtual ~IStream(){} +public: + virtual void Read(size_t num, void *bytes) = 0; + virtual void Write(size_t num, const void *bytes) = 0; + virtual ~IStream() {} }; // Serializable interface class ISerializable { - public: - /* ISerializable(){}; - * ISerializable(IStream&){}; */ - virtual void Serialize(IStream &) const = 0; - virtual ~ISerializable(){} +public: + /* ISerializable(){}; + * ISerializable(IStream&){}; */ + virtual void Serialize(IStream &) const = 0; + virtual ~ISerializable() {} }; struct Serialization { - // serialization - // normal functions - - // ISerializable objects - static void Serialize(IStream& stream, const ISerializable& object) - { - object.Serialize(stream); - } - - static void Serialize(IStream& stream, const ISerializable* const object) - { - object->Serialize(stream); - } - - // char - static void Serialize(IStream& stream, const char value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const char* const value) - { - stream.Write(sizeof(*value), value); - } - - // unsigned char - static void Serialize(IStream& stream, const unsigned char value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const unsigned char* const value) - { - stream.Write(sizeof(*value), value); - } - - // unsigned int32 - static void Serialize(IStream& stream, const uint32_t value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const uint32_t* const value) - { - stream.Write(sizeof(*value), value); - } - - // int32 - static void Serialize(IStream& stream, const int32_t value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const int32_t* const value) - { - stream.Write(sizeof(*value), value); - } - - // unsigned int64 - static void Serialize(IStream& stream, const uint64_t value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const uint64_t* const value) - { - stream.Write(sizeof(*value), value); - } - - // int64 - static void Serialize(IStream& stream, const int64_t value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const int64_t* const value) - { - stream.Write(sizeof(*value), value); - } - - // bool - static void Serialize(IStream& stream, const bool value) - { - stream.Write(sizeof(value), &value); - } - static void Serialize(IStream& stream, const bool* const value) - { - stream.Write(sizeof(*value), value); - } - - // std::string - template <typename T, typename R, typename A> - static void Serialize(IStream& stream, const std::basic_string<T, R, A>& str) - { - int length = str.size(); - stream.Write(sizeof(length), &length); - stream.Write(length*sizeof(T), str.data()); - } - - template<typename T, typename R, typename A> - static void Serialize(IStream& stream, const std::basic_string<T, R, A>* const str) - { - int length = str->size(); - stream.Write(sizeof(length), &length); - stream.Write(length*sizeof(T), str->data()); - } - - // STL templates - - // std::list - template <typename T> - static void Serialize(IStream& stream, const std::list<T>& list) - { - int length = list.size(); - stream.Write(sizeof(length), &length); - for (typename std::list<T>::const_iterator list_iter = list.begin(); - list_iter != list.end(); list_iter++) - Serialize(stream, *list_iter); - } - template <typename T> - static void Serialize(IStream& stream, const std::list<T>* const list) - { - Serialize(stream, *list); - } - - // RawBuffer - template <typename A> - static void Serialize(IStream& stream, const std::vector<unsigned char, A>& vec) - { - int length = vec.size(); - stream.Write(sizeof(length), &length); - stream.Write(length, vec.data()); - } - - template <typename A> - static void Serialize(IStream& stream, const std::vector<unsigned char, A>* const vec) - { - Serialize(stream, *vec); - } - - // std::vector - template <typename T, typename A> - static void Serialize(IStream& stream, const std::vector<T, A>& vec) - { - int length = vec.size(); - stream.Write(sizeof(length), &length); - for (const auto &i : vec) - Serialize(stream, i); - } - template <typename T, typename A> - static void Serialize(IStream& stream, const std::vector<T, A>* const vec) - { - Serialize(stream, *vec); - } - - // std::pair - template <typename A, typename B> - static void Serialize(IStream& stream, const std::pair<A, B>& p) - { - Serialize(stream, p.first); - Serialize(stream, p.second); - } - template <typename A, typename B> - static void Serialize(IStream& stream, const std::pair<A, B>* const p) - { - Serialize(stream, *p); - } - - // std::map - template <typename K, typename T> - static void Serialize(IStream& stream, const std::map<K, T>& map) - { - int length = map.size(); - stream.Write(sizeof(length), &length); - typename std::map<K, T>::const_iterator it; - for (it = map.begin(); it != map.end(); ++it) { - Serialize(stream, (*it).first); - Serialize(stream, (*it).second); - } - } - template <typename K, typename T> - static void Serialize(IStream& stream, const std::map<K, T>* const map) - { - Serialize(stream, *map); - } - - // std::unique_ptr - template <typename T> - static void Serialize(IStream& stream, const std::unique_ptr<T>& p) - { - Serialize(stream, *p); - } + // serialization + // normal functions + + // ISerializable objects + static void Serialize(IStream &stream, const ISerializable &object) + { + object.Serialize(stream); + } + + static void Serialize(IStream &stream, const ISerializable *const object) + { + object->Serialize(stream); + } + + // char + static void Serialize(IStream &stream, const char value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const char *const value) + { + stream.Write(sizeof(*value), value); + } + + // unsigned char + static void Serialize(IStream &stream, const unsigned char value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const unsigned char *const value) + { + stream.Write(sizeof(*value), value); + } + + // unsigned int32 + static void Serialize(IStream &stream, const uint32_t value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const uint32_t *const value) + { + stream.Write(sizeof(*value), value); + } + + // int32 + static void Serialize(IStream &stream, const int32_t value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const int32_t *const value) + { + stream.Write(sizeof(*value), value); + } + + // unsigned int64 + static void Serialize(IStream &stream, const uint64_t value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const uint64_t *const value) + { + stream.Write(sizeof(*value), value); + } + + // int64 + static void Serialize(IStream &stream, const int64_t value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const int64_t *const value) + { + stream.Write(sizeof(*value), value); + } + + // bool + static void Serialize(IStream &stream, const bool value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const bool *const value) + { + stream.Write(sizeof(*value), value); + } + + // std::string + template <typename T, typename R, typename A> + static void Serialize(IStream &stream, const std::basic_string<T, R, A> &str) + { + int length = str.size(); + stream.Write(sizeof(length), &length); + stream.Write(length * sizeof(T), str.data()); + } + + template<typename T, typename R, typename A> + static void Serialize(IStream &stream, + const std::basic_string<T, R, A> *const str) + { + int length = str->size(); + stream.Write(sizeof(length), &length); + stream.Write(length * sizeof(T), str->data()); + } + + // STL templates + + // std::list + template <typename T> + static void Serialize(IStream &stream, const std::list<T> &list) + { + int length = list.size(); + stream.Write(sizeof(length), &length); + + for (typename std::list<T>::const_iterator list_iter = list.begin(); + list_iter != list.end(); list_iter++) + Serialize(stream, *list_iter); + } + template <typename T> + static void Serialize(IStream &stream, const std::list<T> *const list) + { + Serialize(stream, *list); + } + + // RawBuffer + template <typename A> + static void Serialize(IStream &stream, + const std::vector<unsigned char, A> &vec) + { + int length = vec.size(); + stream.Write(sizeof(length), &length); + stream.Write(length, vec.data()); + } + + template <typename A> + static void Serialize(IStream &stream, + const std::vector<unsigned char, A> *const vec) + { + Serialize(stream, *vec); + } + + // std::vector + template <typename T, typename A> + static void Serialize(IStream &stream, const std::vector<T, A> &vec) + { + int length = vec.size(); + stream.Write(sizeof(length), &length); + + for (const auto &i : vec) + Serialize(stream, i); + } + template <typename T, typename A> + static void Serialize(IStream &stream, const std::vector<T, A> *const vec) + { + Serialize(stream, *vec); + } + + // std::pair + template <typename A, typename B> + static void Serialize(IStream &stream, const std::pair<A, B> &p) + { + Serialize(stream, p.first); + Serialize(stream, p.second); + } + template <typename A, typename B> + static void Serialize(IStream &stream, const std::pair<A, B> *const p) + { + Serialize(stream, *p); + } + + // std::map + template <typename K, typename T> + static void Serialize(IStream &stream, const std::map<K, T> &map) + { + int length = map.size(); + stream.Write(sizeof(length), &length); + typename std::map<K, T>::const_iterator it; + + for (it = map.begin(); it != map.end(); ++it) { + Serialize(stream, (*it).first); + Serialize(stream, (*it).second); + } + } + template <typename K, typename T> + static void Serialize(IStream &stream, const std::map<K, T> *const map) + { + Serialize(stream, *map); + } + + // std::unique_ptr + template <typename T> + static void Serialize(IStream &stream, const std::unique_ptr<T> &p) + { + Serialize(stream, *p); + } }; // struct Serialization struct Deserialization { - // deserialization - // normal functions - - // ISerializable objects - // T instead of ISerializable is needed to call proper constructor - template <typename T> - static void Deserialize(IStream& stream, T& object) - { - object = T(stream); - } - template <typename T> - static void Deserialize(IStream& stream, T*& object) - { - object = new T(stream); - } - - // char - static void Deserialize(IStream& stream, char& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, char*& value) - { - value = new char; - stream.Read(sizeof(*value), value); - } - - // unsigned char - static void Deserialize(IStream& stream, unsigned char& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, unsigned char*& value) - { - value = new unsigned char; - stream.Read(sizeof(*value), value); - } - - // unsigned int32 - static void Deserialize(IStream& stream, uint32_t& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, uint32_t*& value) - { - value = new uint32_t; - stream.Read(sizeof(*value), value); - } - - // int32 - static void Deserialize(IStream& stream, int32_t& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, int32_t*& value) - { - value = new int32_t; - stream.Read(sizeof(*value), value); - } - - // unsigned int64 - static void Deserialize(IStream& stream, uint64_t& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, uint64_t*& value) - { - value = new uint64_t; - stream.Read(sizeof(*value), value); - } - - // int64 - static void Deserialize(IStream& stream, int64_t& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, int64_t*& value) - { - value = new int64_t; - stream.Read(sizeof(*value), value); - } - - // bool - static void Deserialize(IStream& stream, bool& value) - { - stream.Read(sizeof(value), &value); - } - static void Deserialize(IStream& stream, bool*& value) - { - value = new bool; - stream.Read(sizeof(*value), value); - } - - template <typename T, typename R, typename A> - static void Deserialize(IStream& stream, std::basic_string<T, R, A>& str) - { - int length; - stream.Read(sizeof(length), &length); - std::vector<T> buf(length); - stream.Read(length*sizeof(T), buf.data()); - str = std::basic_string<T, R, A>(buf.data(), buf.data() + length); - } - - template <typename T, typename R, typename A> - static void Deserialize(IStream& stream, std::basic_string<T, R, A>*& str) - { - int length; - stream.Read(sizeof(length), &length); - std::vector<T> buf(length); - stream.Read(length*sizeof(T), buf.data()); - str = new std::basic_string<T, R, A>(buf.data(), buf.data() + length); - } - - // STL templates - - // std::list - template <typename T> - static void Deserialize(IStream& stream, std::list<T>& list) - { - int length; - stream.Read(sizeof(length), &length); - for (int i = 0; i < length; ++i) { - T obj; - Deserialize(stream, obj); - list.push_back(std::move(obj)); - } - } - template <typename T> - static void Deserialize(IStream& stream, std::list<T>*& list) - { - list = new std::list<T>; - Deserialize(stream, *list); - } - - // RawBuffer - template <typename A> - static void Deserialize(IStream& stream, std::vector<unsigned char, A>& vec) - { - int length; - stream.Read(sizeof(length), &length); - vec.resize(length); - stream.Read(length, vec.data()); - } - - template <typename A> - static void Deserialize(IStream& stream, std::vector<unsigned char, A>*& vec) - { - vec = new std::vector<unsigned char, A>; - Deserialize(stream, *vec); - } - - // std::vector - template <typename T, typename A> - static void Deserialize(IStream& stream, std::vector<T, A>& vec) - { - int length; - stream.Read(sizeof(length), &length); - for (int i = 0; i < length; ++i) { - T obj; - Deserialize(stream, obj); - vec.push_back(std::move(obj)); - } - } - template <typename T, typename A> - static void Deserialize(IStream& stream, std::vector<T, A>*& vec) - { - vec = new std::vector<T, A>; - Deserialize(stream, *vec); - } - - // std::pair - template <typename A, typename B> - static void Deserialize(IStream& stream, std::pair<A, B>& p) - { - Deserialize(stream, p.first); - Deserialize(stream, p.second); - } - template <typename A, typename B> - static void Deserialize(IStream& stream, std::pair<A, B>*& p) - { - p = new std::pair<A, B>; - Deserialize(stream, *p); - } - - // std::map - template <typename K, typename T> - static void Deserialize(IStream& stream, std::map<K, T>& map) - { - int length; - stream.Read(sizeof(length), &length); - for (int i = 0; i < length; ++i) { - K key; - T obj; - Deserialize(stream, key); - Deserialize(stream, obj); - map[key] = std::move(obj); - } - } - template <typename K, typename T> - static void Deserialize(IStream& stream, std::map<K, T>*& map) - { - map = new std::map<K, T>; - Deserialize(stream, *map); - } + // deserialization + // normal functions + + // ISerializable objects + // T instead of ISerializable is needed to call proper constructor + template <typename T> + static void Deserialize(IStream &stream, T &object) + { + object = T(stream); + } + template <typename T> + static void Deserialize(IStream &stream, T *&object) + { + object = new T(stream); + } + + // char + static void Deserialize(IStream &stream, char &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, char *&value) + { + value = new char; + stream.Read(sizeof(*value), value); + } + + // unsigned char + static void Deserialize(IStream &stream, unsigned char &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, unsigned char *&value) + { + value = new unsigned char; + stream.Read(sizeof(*value), value); + } + + // unsigned int32 + static void Deserialize(IStream &stream, uint32_t &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, uint32_t *&value) + { + value = new uint32_t; + stream.Read(sizeof(*value), value); + } + + // int32 + static void Deserialize(IStream &stream, int32_t &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, int32_t *&value) + { + value = new int32_t; + stream.Read(sizeof(*value), value); + } + + // unsigned int64 + static void Deserialize(IStream &stream, uint64_t &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, uint64_t *&value) + { + value = new uint64_t; + stream.Read(sizeof(*value), value); + } + + // int64 + static void Deserialize(IStream &stream, int64_t &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, int64_t *&value) + { + value = new int64_t; + stream.Read(sizeof(*value), value); + } + + // bool + static void Deserialize(IStream &stream, bool &value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, bool *&value) + { + value = new bool; + stream.Read(sizeof(*value), value); + } + + template <typename T, typename R, typename A> + static void Deserialize(IStream &stream, std::basic_string<T, R, A> &str) + { + int length; + stream.Read(sizeof(length), &length); + std::vector<T> buf(length); + stream.Read(length * sizeof(T), buf.data()); + str = std::basic_string<T, R, A>(buf.data(), buf.data() + length); + } + + template <typename T, typename R, typename A> + static void Deserialize(IStream &stream, std::basic_string<T, R, A> *&str) + { + int length; + stream.Read(sizeof(length), &length); + std::vector<T> buf(length); + stream.Read(length * sizeof(T), buf.data()); + str = new std::basic_string<T, R, A>(buf.data(), buf.data() + length); + } + + // STL templates + + // std::list + template <typename T> + static void Deserialize(IStream &stream, std::list<T> &list) + { + int length; + stream.Read(sizeof(length), &length); + + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + list.push_back(std::move(obj)); + } + } + template <typename T> + static void Deserialize(IStream &stream, std::list<T> *&list) + { + list = new std::list<T>; + Deserialize(stream, *list); + } + + // RawBuffer + template <typename A> + static void Deserialize(IStream &stream, std::vector<unsigned char, A> &vec) + { + int length; + stream.Read(sizeof(length), &length); + vec.resize(length); + stream.Read(length, vec.data()); + } + + template <typename A> + static void Deserialize(IStream &stream, std::vector<unsigned char, A> *&vec) + { + vec = new std::vector<unsigned char, A>; + Deserialize(stream, *vec); + } + + // std::vector + template <typename T, typename A> + static void Deserialize(IStream &stream, std::vector<T, A> &vec) + { + int length; + stream.Read(sizeof(length), &length); + + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + vec.push_back(std::move(obj)); + } + } + template <typename T, typename A> + static void Deserialize(IStream &stream, std::vector<T, A> *&vec) + { + vec = new std::vector<T, A>; + Deserialize(stream, *vec); + } + + // std::pair + template <typename A, typename B> + static void Deserialize(IStream &stream, std::pair<A, B> &p) + { + Deserialize(stream, p.first); + Deserialize(stream, p.second); + } + template <typename A, typename B> + static void Deserialize(IStream &stream, std::pair<A, B> *&p) + { + p = new std::pair<A, B>; + Deserialize(stream, *p); + } + + // std::map + template <typename K, typename T> + static void Deserialize(IStream &stream, std::map<K, T> &map) + { + int length; + stream.Read(sizeof(length), &length); + + for (int i = 0; i < length; ++i) { + K key; + T obj; + Deserialize(stream, key); + Deserialize(stream, obj); + map[key] = std::move(obj); + } + } + template <typename K, typename T> + static void Deserialize(IStream &stream, std::map<K, T> *&map) + { + map = new std::map<K, T>; + Deserialize(stream, *map); + } }; // struct Deserialization // generic serialization @@ -450,20 +459,20 @@ struct Serializer; template <typename First, typename... Args> struct Serializer<First, Args...> : public Serializer<Args...> { - static void Serialize(IStream& stream, const First& f, const Args&... args) - { - Serialization::Serialize(stream, f); - Serializer<Args...>::Serialize(stream, args...); - } + static void Serialize(IStream &stream, const First &f, const Args &... args) + { + Serialization::Serialize(stream, f); + Serializer<Args...>::Serialize(stream, args...); + } }; // end of recursion template <> struct Serializer<> { - static void Serialize(IStream&) - { - return; - } + static void Serialize(IStream &) + { + return; + } }; // generic deserialization @@ -472,20 +481,20 @@ struct Deserializer; template <typename First, typename... Args> struct Deserializer<First, Args...> : public Deserializer<Args...> { - static void Deserialize(IStream& stream, First& f, Args&... args) - { - Deserialization::Deserialize(stream, f); - Deserializer<Args...>::Deserialize(stream, args...); - } + static void Deserialize(IStream &stream, First &f, Args &... args) + { + Deserialization::Deserialize(stream, f); + Deserializer<Args...>::Deserialize(stream, args...); + } }; // end of recursion template <> struct Deserializer<> { - static void Deserialize(IStream&) - { - return; - } + static void Deserialize(IStream &) + { + return; + } }; } // namespace CKM diff --git a/src/manager/dpl/core/include/dpl/singleton.h b/src/manager/dpl/core/include/dpl/singleton.h index 93831aa8..55861c41 100644 --- a/src/manager/dpl/core/include/dpl/singleton.h +++ b/src/manager/dpl/core/include/dpl/singleton.h @@ -27,26 +27,23 @@ namespace CKM { template<typename Class> class COMMON_API Singleton : - private Class -{ - // - // Note: - // - // To remove posibility of instantiating directly Class, - // make Class' default constructor protected - // + private Class { + // + // Note: + // + // To remove posibility of instantiating directly Class, + // make Class' default constructor protected + // - private: - Singleton() - {} +private: + Singleton() {} - static Singleton &InternalInstance(); + static Singleton &InternalInstance(); - public: - virtual ~Singleton() - {} +public: + virtual ~Singleton() {} - static Class &Instance(); + static Class &Instance(); }; } // namespace CKM diff --git a/src/manager/dpl/core/include/dpl/singleton_impl.h b/src/manager/dpl/core/include/dpl/singleton_impl.h index cce89591..afa066a4 100644 --- a/src/manager/dpl/core/include/dpl/singleton_impl.h +++ b/src/manager/dpl/core/include/dpl/singleton_impl.h @@ -32,22 +32,22 @@ namespace CKM { template<typename Class> -Singleton<Class>& Singleton<Class>::InternalInstance() +Singleton<Class> &Singleton<Class>::InternalInstance() { - static Singleton<Class> instance; - return instance; + static Singleton<Class> instance; + return instance; } template<typename Class> Class &Singleton<Class>::Instance() { - Singleton<Class>& instance = Singleton<Class>::InternalInstance(); - return instance; + Singleton<Class> &instance = Singleton<Class>::InternalInstance(); + return instance; } } // namespace CKM #define IMPLEMENT_SINGLETON(Type) \ - template CKM::Singleton<Type>&CKM::Singleton<Type>::InternalInstance(); \ - template Type & CKM::Singleton<Type>::Instance(); \ + template CKM::Singleton<Type>&CKM::Singleton<Type>::InternalInstance(); \ + template Type & CKM::Singleton<Type>::Instance(); \ #endif // CENT_KEY_SINGLETON_IMPL_H diff --git a/src/manager/dpl/core/include/dpl/singleton_safe_impl.h b/src/manager/dpl/core/include/dpl/singleton_safe_impl.h index 9b66c0d9..508151e1 100644 --- a/src/manager/dpl/core/include/dpl/singleton_safe_impl.h +++ b/src/manager/dpl/core/include/dpl/singleton_safe_impl.h @@ -22,24 +22,22 @@ #ifndef CENT_KEY_SINGLETON_SAFE_IMPL_H #define CENT_KEY_SINGLETON_SAFE_IMPL_H -#define IMPLEMENT_SAFE_SINGLETON(Class) \ - namespace CKM { \ - template<> \ - Singleton<Class>&Singleton<Class>::InternalInstance() \ - { \ - static Singleton<Class> instance; \ - return instance; \ - } \ - \ - template<> \ - Class & Singleton<Class>::Instance() \ - { \ - Singleton<Class>& instance = Singleton<Class>::InternalInstance(); \ - return instance; \ - } \ - \ - template Singleton<Class>&Singleton<Class>::InternalInstance(); \ - template Class & Singleton<Class>::Instance(); \ - } // namespace CKM +#define IMPLEMENT_SAFE_SINGLETON(Class) \ + namespace CKM { \ + template<> \ + Singleton<Class>&Singleton<Class>::InternalInstance() { \ + static Singleton<Class> instance; \ + return instance; \ + } \ + \ + template<> \ + Class &Singleton<Class>::Instance() { \ + Singleton<Class>& instance = Singleton<Class>::InternalInstance(); \ + return instance; \ + } \ + \ + template Singleton<Class>&Singleton<Class>::InternalInstance(); \ + template Class & Singleton<Class>::Instance(); \ + } // namespace CKM #endif // CENT_KEY_SINGLETON_SAFE_IMPL_H diff --git a/src/manager/dpl/core/src/assert.cpp b/src/manager/dpl/core/src/assert.cpp index 96591783..9fb4fa67 100644 --- a/src/manager/dpl/core/src/assert.cpp +++ b/src/manager/dpl/core/src/assert.cpp @@ -27,25 +27,28 @@ namespace CKM { void AssertProc(const char *condition, - const char *file, - int line, - const char *function) + const char *file, + int line, + const char *function) { - try { - LogError( - "################################################################################" << std::endl << - "### CKM assertion failed! ###" << std::endl << - "################################################################################" << std::endl << - "### Condition: " << condition << std::endl << - "### File: " << file << std::endl << - "### Line: " << line << std::endl << - "### Function: " << function << - "################################################################################"); - } catch (...) { - // Just ignore possible double errors - } + try { + LogError( + "################################################################################" + << std::endl << + "### CKM assertion failed! ###" + << std::endl << + "################################################################################" + << std::endl << + "### Condition: " << condition << std::endl << + "### File: " << file << std::endl << + "### Line: " << line << std::endl << + "### Function: " << function << + "################################################################################"); + } catch (...) { + // Just ignore possible double errors + } - // Fail with c-library abort - abort(); + // Fail with c-library abort + abort(); } } // namespace CKM diff --git a/src/manager/dpl/core/src/binary_queue.cpp b/src/manager/dpl/core/src/binary_queue.cpp index 8d3a232f..c469478e 100644 --- a/src/manager/dpl/core/src/binary_queue.cpp +++ b/src/manager/dpl/core/src/binary_queue.cpp @@ -29,233 +29,234 @@ namespace CKM { BinaryQueue::BinaryQueue() : - m_size(0) + m_size(0) {} BinaryQueue::BinaryQueue(const BinaryQueue &other) : - m_size(0) + m_size(0) { - AppendCopyFrom(other); + AppendCopyFrom(other); } BinaryQueue::~BinaryQueue() { - // Remove all remainig buckets - Clear(); + // Remove all remainig buckets + Clear(); } const BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other) { - if (this != &other) { - Clear(); - AppendCopyFrom(other); - } + if (this != &other) { + Clear(); + AppendCopyFrom(other); + } - return *this; + return *this; } void BinaryQueue::AppendCopyFrom(const BinaryQueue &other) { - // To speed things up, always copy as one bucket - void *bufferCopy = malloc(other.m_size); - - if (bufferCopy == NULL) - throw std::bad_alloc(); - - try { - other.Flatten(bufferCopy, other.m_size); - AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL); - } catch (const std::bad_alloc &) { - // Free allocated memory - free(bufferCopy); - throw; - } + // To speed things up, always copy as one bucket + void *bufferCopy = malloc(other.m_size); + + if (bufferCopy == NULL) + throw std::bad_alloc(); + + try { + other.Flatten(bufferCopy, other.m_size); + AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL); + } catch (const std::bad_alloc &) { + // Free allocated memory + free(bufferCopy); + throw; + } } void BinaryQueue::AppendMoveFrom(BinaryQueue &other) { - // Copy all buckets - std::copy(other.m_buckets.begin(), - other.m_buckets.end(), std::back_inserter(m_buckets)); - m_size += other.m_size; - - // Clear other, but do not free memory - other.m_buckets.clear(); - other.m_size = 0; + // Copy all buckets + std::copy(other.m_buckets.begin(), + other.m_buckets.end(), std::back_inserter(m_buckets)); + m_size += other.m_size; + + // Clear other, but do not free memory + other.m_buckets.clear(); + other.m_size = 0; } void BinaryQueue::AppendCopyTo(BinaryQueue &other) const { - other.AppendCopyFrom(*this); + other.AppendCopyFrom(*this); } void BinaryQueue::AppendMoveTo(BinaryQueue &other) { - other.AppendMoveFrom(*this); + other.AppendMoveFrom(*this); } void BinaryQueue::Clear() { - std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket); - m_buckets.clear(); - m_size = 0; + std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket); + m_buckets.clear(); + m_size = 0; } -void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize) +void BinaryQueue::AppendCopy(const void *buffer, size_t bufferSize) { - // Create data copy with malloc/free - void *bufferCopy = malloc(bufferSize); - - // Check if allocation succeded - if (bufferCopy == NULL) - throw std::bad_alloc(); - - // Copy user data - memcpy(bufferCopy, buffer, bufferSize); - - try { - // Try to append new bucket - AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL); - } catch (const std::bad_alloc &) { - // Free allocated memory - free(bufferCopy); - throw; - } + // Create data copy with malloc/free + void *bufferCopy = malloc(bufferSize); + + // Check if allocation succeded + if (bufferCopy == NULL) + throw std::bad_alloc(); + + // Copy user data + memcpy(bufferCopy, buffer, bufferSize); + + try { + // Try to append new bucket + AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL); + } catch (const std::bad_alloc &) { + // Free allocated memory + free(bufferCopy); + throw; + } } -void BinaryQueue::AppendUnmanaged(const void* buffer, - size_t bufferSize, - BufferDeleter deleter, - void* userParam) +void BinaryQueue::AppendUnmanaged(const void *buffer, + size_t bufferSize, + BufferDeleter deleter, + void *userParam) { - // Do not attach empty buckets - if (bufferSize == 0) { - deleter(buffer, bufferSize, userParam); - return; - } - - // Just add new bucket with selected deleter - Bucket *bucket = new Bucket(buffer, bufferSize, deleter, userParam); - try { - m_buckets.push_back(bucket); - } catch (const std::bad_alloc &) { - delete bucket; - throw; - } - - // Increase total queue size - m_size += bufferSize; + // Do not attach empty buckets + if (bufferSize == 0) { + deleter(buffer, bufferSize, userParam); + return; + } + + // Just add new bucket with selected deleter + Bucket *bucket = new Bucket(buffer, bufferSize, deleter, userParam); + + try { + m_buckets.push_back(bucket); + } catch (const std::bad_alloc &) { + delete bucket; + throw; + } + + // Increase total queue size + m_size += bufferSize; } size_t BinaryQueue::Size() const { - return m_size; + return m_size; } bool BinaryQueue::Empty() const { - return m_size == 0; + return m_size == 0; } void BinaryQueue::Consume(size_t size) { - // Check parameters - if (size > m_size) - Throw(Exception::OutOfData); - - size_t bytesLeft = size; - - // Consume data and/or remove buckets - while (bytesLeft > 0) { - // Get consume size - size_t count = std::min(bytesLeft, m_buckets.front()->left); - - m_buckets.front()->ptr = - static_cast<const char *>(m_buckets.front()->ptr) + count; - m_buckets.front()->left -= count; - bytesLeft -= count; - m_size -= count; - - if (m_buckets.front()->left == 0) { - DeleteBucket(m_buckets.front()); - m_buckets.pop_front(); - } - } + // Check parameters + if (size > m_size) + Throw(Exception::OutOfData); + + size_t bytesLeft = size; + + // Consume data and/or remove buckets + while (bytesLeft > 0) { + // Get consume size + size_t count = std::min(bytesLeft, m_buckets.front()->left); + + m_buckets.front()->ptr = + static_cast<const char *>(m_buckets.front()->ptr) + count; + m_buckets.front()->left -= count; + bytesLeft -= count; + m_size -= count; + + if (m_buckets.front()->left == 0) { + DeleteBucket(m_buckets.front()); + m_buckets.pop_front(); + } + } } void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const { - // Check parameters - if (bufferSize == 0) - return; + // Check parameters + if (bufferSize == 0) + return; - if (bufferSize > m_size) - Throw(Exception::OutOfData); + if (bufferSize > m_size) + Throw(Exception::OutOfData); - size_t bytesLeft = bufferSize; - void *ptr = buffer; - BucketList::const_iterator bucketIterator = m_buckets.begin(); - Assert(m_buckets.end() != bucketIterator); + size_t bytesLeft = bufferSize; + void *ptr = buffer; + BucketList::const_iterator bucketIterator = m_buckets.begin(); + Assert(m_buckets.end() != bucketIterator); - // Flatten data - while (bytesLeft > 0) { - // Get consume size - size_t count = std::min(bytesLeft, (*bucketIterator)->left); + // Flatten data + while (bytesLeft > 0) { + // Get consume size + size_t count = std::min(bytesLeft, (*bucketIterator)->left); - // Copy data to user pointer - memcpy(ptr, (*bucketIterator)->ptr, count); + // Copy data to user pointer + memcpy(ptr, (*bucketIterator)->ptr, count); - // Update flattened bytes count - bytesLeft -= count; - ptr = static_cast<char *>(ptr) + count; + // Update flattened bytes count + bytesLeft -= count; + ptr = static_cast<char *>(ptr) + count; - // Take next bucket - ++bucketIterator; - } + // Take next bucket + ++bucketIterator; + } } void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize) { - // FIXME: Optimize - Flatten(buffer, bufferSize); - Consume(bufferSize); + // FIXME: Optimize + Flatten(buffer, bufferSize); + Consume(bufferSize); } void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket) { - delete bucket; + delete bucket; } -void BinaryQueue::BufferDeleterFree(const void* data, - size_t dataSize, - void* userParam) +void BinaryQueue::BufferDeleterFree(const void *data, + size_t dataSize, + void *userParam) { - (void)dataSize; - (void)userParam; + (void)dataSize; + (void)userParam; - // Default free deleter - free(const_cast<void *>(data)); + // Default free deleter + free(const_cast<void *>(data)); } -BinaryQueue::Bucket::Bucket(const void* data, - size_t dataSize, - BufferDeleter dataDeleter, - void* userParam) : - buffer(data), - ptr(data), - size(dataSize), - left(dataSize), - deleter(dataDeleter), - param(userParam) +BinaryQueue::Bucket::Bucket(const void *data, + size_t dataSize, + BufferDeleter dataDeleter, + void *userParam) : + buffer(data), + ptr(data), + size(dataSize), + left(dataSize), + deleter(dataDeleter), + param(userParam) { - Assert(data != NULL); - Assert(deleter != NULL); + Assert(data != NULL); + Assert(deleter != NULL); } BinaryQueue::Bucket::~Bucket() { - // Invoke deleter on bucket data - deleter(buffer, size, param); + // Invoke deleter on bucket data + deleter(buffer, size, param); } BinaryQueue::BucketVisitor::~BucketVisitor() @@ -263,7 +264,7 @@ BinaryQueue::BucketVisitor::~BucketVisitor() } BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) : - m_visitor(visitor) + m_visitor(visitor) { } @@ -273,42 +274,42 @@ BinaryQueue::BucketVisitorCall::~BucketVisitorCall() void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const { - m_visitor->OnVisitBucket(bucket->ptr, bucket->left); + m_visitor->OnVisitBucket(bucket->ptr, bucket->left); } void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const { - Assert(visitor != NULL); + Assert(visitor != NULL); - // Visit all buckets - std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor)); + // Visit all buckets + std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor)); } BinaryQueueAutoPtr BinaryQueue::Read(size_t size) { - // Simulate input stream - size_t available = std::min(size, m_size); + // Simulate input stream + size_t available = std::min(size, m_size); - std::unique_ptr<void, std::function<void(void*)>> - bufferCopy(malloc(available), free); + std::unique_ptr<void, std::function<void(void *)>> + bufferCopy(malloc(available), free); - if (!bufferCopy.get()) - throw std::bad_alloc(); + if (!bufferCopy.get()) + throw std::bad_alloc(); - BinaryQueueAutoPtr result(new BinaryQueue()); + BinaryQueueAutoPtr result(new BinaryQueue()); - Flatten(bufferCopy.get(), available); - result->AppendUnmanaged( - bufferCopy.release(), available, &BufferDeleterFree, NULL); - Consume(available); + Flatten(bufferCopy.get(), available); + result->AppendUnmanaged( + bufferCopy.release(), available, &BufferDeleterFree, NULL); + Consume(available); - return result; + return result; } size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize) { - // Simulate output stream - AppendCopyFrom(buffer); - return bufferSize; + // Simulate output stream + AppendCopyFrom(buffer); + return bufferSize; } } // namespace CKM diff --git a/src/manager/dpl/core/src/colors.cpp b/src/manager/dpl/core/src/colors.cpp index 7b329b08..a8639e63 100644 --- a/src/manager/dpl/core/src/colors.cpp +++ b/src/manager/dpl/core/src/colors.cpp @@ -26,25 +26,25 @@ namespace CKM { namespace Colors { namespace Text { -const char* BOLD_GREEN_BEGIN = "\033[1;32m"; -const char* BOLD_GREEN_END = "\033[m"; -const char* RED_BEGIN = "\033[0;31m"; -const char* RED_END = "\033[m"; -const char* PURPLE_BEGIN = "\033[0;35m"; -const char* PURPLE_END = "\033[m"; -const char* GREEN_BEGIN = "\033[0;32m"; -const char* GREEN_END = "\033[m"; -const char* CYAN_BEGIN = "\033[0;36m"; -const char* CYAN_END = "\033[m"; -const char* BOLD_RED_BEGIN = "\033[1;31m"; -const char* BOLD_RED_END = "\033[m"; -const char* BOLD_YELLOW_BEGIN = "\033[1;33m"; -const char* BOLD_YELLOW_END = "\033[m"; -const char* BOLD_GOLD_BEGIN = "\033[0;33m"; -const char* BOLD_GOLD_END = "\033[m"; -const char* BOLD_WHITE_BEGIN = "\033[1;37m"; -const char* BOLD_WHITE_END = "\033[m"; -const char* COLOR_END = "\033[m"; +const char *BOLD_GREEN_BEGIN = "\033[1;32m"; +const char *BOLD_GREEN_END = "\033[m"; +const char *RED_BEGIN = "\033[0;31m"; +const char *RED_END = "\033[m"; +const char *PURPLE_BEGIN = "\033[0;35m"; +const char *PURPLE_END = "\033[m"; +const char *GREEN_BEGIN = "\033[0;32m"; +const char *GREEN_END = "\033[m"; +const char *CYAN_BEGIN = "\033[0;36m"; +const char *CYAN_END = "\033[m"; +const char *BOLD_RED_BEGIN = "\033[1;31m"; +const char *BOLD_RED_END = "\033[m"; +const char *BOLD_YELLOW_BEGIN = "\033[1;33m"; +const char *BOLD_YELLOW_END = "\033[m"; +const char *BOLD_GOLD_BEGIN = "\033[0;33m"; +const char *BOLD_GOLD_END = "\033[m"; +const char *BOLD_WHITE_BEGIN = "\033[1;37m"; +const char *BOLD_WHITE_END = "\033[m"; +const char *COLOR_END = "\033[m"; } //namespace Text } //namespace Colors } //namespace CKM diff --git a/src/manager/dpl/core/src/errno_string.cpp b/src/manager/dpl/core/src/errno_string.cpp index 1327edf1..0be6839f 100644 --- a/src/manager/dpl/core/src/errno_string.cpp +++ b/src/manager/dpl/core/src/errno_string.cpp @@ -34,17 +34,21 @@ const size_t MAX_BUF = 256; std::string GetErrnoString(int error) { - std::vector<char> buffer(MAX_BUF, '\0'); + std::vector<char> buffer(MAX_BUF, '\0'); #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE - if (0 == strerror_r(error, buffer.data(), buffer.size())) - return std::string(buffer.begin(), buffer.end()); + + if (0 == strerror_r(error, buffer.data(), buffer.size())) + return std::string(buffer.begin(), buffer.end()); + #else - char *result = strerror_r(error, buffer.data(), buffer.size()); - if (result) - return std::string(result); + char *result = strerror_r(error, buffer.data(), buffer.size()); + + if (result) + return std::string(result); + #endif - return std::string(); + return std::string(); } } // namespace CKM diff --git a/src/manager/dpl/core/src/exception.cpp b/src/manager/dpl/core/src/exception.cpp index c01bdbbe..71d038ea 100644 --- a/src/manager/dpl/core/src/exception.cpp +++ b/src/manager/dpl/core/src/exception.cpp @@ -25,28 +25,31 @@ #include <dpl/log/log.h> namespace CKM { -Exception* Exception::m_lastException = NULL; +Exception *Exception::m_lastException = NULL; unsigned int Exception::m_exceptionCount = 0; void (*Exception::m_terminateHandler)() = NULL; void LogUnhandledException(const std::string &str) { - LogError(str); + LogError(str); } void LogUnhandledException(const std::string &str, - const char *filename, - int line, - const char *function) + const char *filename, + int line, + const char *function) { - LogError( - "################################################################################" << std::endl << - "### CKM Unhandled Exception Occured! ###" << std::endl << - "################################################################################" << std::endl << - "### Condition: " << str << std::endl << - "### File: " << filename << std::endl << - "### Line: " << line << std::endl << - "### Function: " << function << - "################################################################################"); + LogError( + "################################################################################" + << std::endl << + "### CKM Unhandled Exception Occured! ###" + << std::endl << + "################################################################################" + << std::endl << + "### Condition: " << str << std::endl << + "### File: " << filename << std::endl << + "### Line: " << line << std::endl << + "### Function: " << function << + "################################################################################"); } } // namespace CKM diff --git a/src/manager/dpl/db/include/dpl/db/naive_synchronization_object.h b/src/manager/dpl/db/include/dpl/db/naive_synchronization_object.h index 2980b4a4..12ae6e5f 100644 --- a/src/manager/dpl/db/include/dpl/db/naive_synchronization_object.h +++ b/src/manager/dpl/db/include/dpl/db/naive_synchronization_object.h @@ -32,12 +32,11 @@ namespace DB { * to the same database across different threads and processes */ class NaiveSynchronizationObject : - public SqlConnection::SynchronizationObject -{ - public: - // [SqlConnection::SynchronizationObject] - virtual void Synchronize(); - virtual void NotifyAll(); + public SqlConnection::SynchronizationObject { +public: + // [SqlConnection::SynchronizationObject] + virtual void Synchronize(); + virtual void NotifyAll(); }; } // namespace DB } // namespace CKM diff --git a/src/manager/dpl/db/include/dpl/db/sql_connection.h b/src/manager/dpl/db/include/dpl/db/sql_connection.h index 6a05fdf4..466ffa05 100644 --- a/src/manager/dpl/db/include/dpl/db/sql_connection.h +++ b/src/manager/dpl/db/include/dpl/db/sql_connection.h @@ -39,523 +39,529 @@ namespace DB { * SQL connection class */ class SqlConnection { - public: - /** - * SQL Exception classes - */ - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, SyntaxError) - DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken) - DECLARE_EXCEPTION_TYPE(Base, InternalError) - DECLARE_EXCEPTION_TYPE(Base, InvalidColumn) - DECLARE_EXCEPTION_TYPE(Base, InvalidArguments) - }; - - /** - * Output of SQL command - */ - class Output { - public: - typedef std::vector<std::string> Row; - typedef std::vector<Row> Rows; - - static int Callback(void*, int, char**, char**); - const Row& GetNames() const { return m_names; } - const Rows& GetValues() const { return m_values; } - private: - void SetResults(int columns, char** values, char** names); - - Row m_names; - Rows m_values; - }; - - typedef int ColumnIndex; - typedef int ArgumentIndex; - - /* - * SQL processed data command - */ - class DataCommand { - private: - SqlConnection *m_masterConnection; - sqlcipher3_stmt *m_stmt; - - void CheckBindResult(int result); - void CheckColumnIndex(SqlConnection::ColumnIndex column); - - DataCommand(SqlConnection *connection, const char *buffer); - - friend class SqlConnection; - - public: - NONCOPYABLE(DataCommand); - - virtual ~DataCommand(); - - /** - * Bind null to the prepared statement argument - * - * @param position Index of argument to bind value to - */ - void BindNull(ArgumentIndex position); - - /** - * Bind int to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInteger(ArgumentIndex position, int value); - - /** - * Bind int8_t to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt8(ArgumentIndex position, int8_t value); - - /** - * Bind int16 to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt16(ArgumentIndex position, int16_t value); - - /** - * Bind int32 to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt32(ArgumentIndex position, int32_t value); - - /** - * Bind int64 to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt64(ArgumentIndex position, int64_t value); - - /** - * Bind float to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindFloat(ArgumentIndex position, float value); - - /** - * Bind double to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindDouble(ArgumentIndex position, double value); - - /** - * Bind string to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindString(ArgumentIndex position, const char *value); - - /** - * Bind string to the prepared statement argument - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindBlob(ArgumentIndex position, const RawBuffer &value); - - /** - * Bind optional int to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInteger(ArgumentIndex position, const boost::optional<int> &value); - - /** - * Bind optional int8 to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt8(ArgumentIndex position, const boost::optional<int8_t> &value); - - /** - * Bind optional int16 to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt16(ArgumentIndex position, const boost::optional<int16_t> &value); - - /** - * Bind optional int32 to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt32(ArgumentIndex position, const boost::optional<int32_t> &value); - - /** - * Bind optional int64 to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindInt64(ArgumentIndex position, const boost::optional<int64_t> &value); - - /** - * Bind optional float to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindFloat(ArgumentIndex position, const boost::optional<float> &value); - - /** - * Bind optional double to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindDouble(ArgumentIndex position, const boost::optional<double> &value); - - /** - * Bind optional string to the prepared statement argument. - * If optional is not set null will be bound - * - * @param position Index of argument to bind value to - * @param value Value to bind - */ - void BindBlob(ArgumentIndex position, const boost::optional<RawBuffer> &value); - - /** - * Execute the prepared statement and/or move - * to the next row of the result - * - * @return True when there was a row returned - */ - bool Step(); - - /** - * Reset prepared statement's arguments - * All parameters will become null - */ - void Reset(); - - /** - * Checks whether column value is null - * - * @throw Exception::InvalidColumn - */ - bool IsColumnNull(ColumnIndex column); - - /** - * Get integer value from column in current row. - * - * @throw Exception::InvalidColumn - */ - int GetColumnInteger(ColumnIndex column); - - /** - * Get int8 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - int8_t GetColumnInt8(ColumnIndex column); - - /** - * Get int16 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - int16_t GetColumnInt16(ColumnIndex column); - /** - * Get int32 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - int32_t GetColumnInt32(ColumnIndex column); - - /** - * Get int64 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - int64_t GetColumnInt64(ColumnIndex column); - - /** - * Get float value from column in current row. - * - * @throw Exception::InvalidColumn - */ - float GetColumnFloat(ColumnIndex column); - - /** - * Get double value from column in current row. - * - * @throw Exception::InvalidColumn - */ - double GetColumnDouble(ColumnIndex column); - - /** - * Get string value from column in current row. - * - * @throw Exception::InvalidColumn - */ - std::string GetColumnString(ColumnIndex column); - - /** - * Get string value from column in current row. - * - * @throw Exception::InvalidColumn - */ - RawBuffer GetColumnBlob(ColumnIndex column); - - /** - * Get optional integer value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<int> GetColumnOptionalInteger(ColumnIndex column); - - /** - * Get optional int8 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<int8_t> GetColumnOptionalInt8(ColumnIndex column); - - /** - * Get optional int16value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<int16_t> GetColumnOptionalInt16(ColumnIndex column); - - /** - * Get optional int32 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<int32_t> GetColumnOptionalInt32(ColumnIndex column); - - /** - * Get optional int64 value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<int64_t> GetColumnOptionalInt64(ColumnIndex column); - - /** - * Get optional float value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<float> GetColumnOptionalFloat(ColumnIndex column); - - /** - * Get optional double value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<double> GetColumnOptionalDouble(ColumnIndex column); - - /** - * Get string value from column in current row. - * - * @throw Exception::InvalidColumn - */ - boost::optional<RawBuffer> GetColumnOptionalBlob(ColumnIndex column); - }; - - // Move on copy constructor. No copy semantics - typedef std::unique_ptr<DataCommand> DataCommandUniquePtr; - - // Open flags - class Flag { - public: - enum Option { - RO = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READONLY, - RW = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READWRITE, - CRW = RW | SQLCIPHER_OPEN_CREATE - }; - }; - - // RowID - typedef sqlcipher3_int64 RowID; - - /** - * Synchronization object used to synchronize SQL connection - * to the same database across different threads and processes - */ - class SynchronizationObject { - public: - virtual ~SynchronizationObject() {} - - /** - * Synchronizes SQL connection for multiple clients. - */ - virtual void Synchronize() = 0; - - /** - * Notify all waiting clients that the connection is no longer locked. - */ - virtual void NotifyAll() = 0; - }; - - protected: - sqlcipher3 *m_connection; - - // Options - - // Stored data procedures - int m_dataCommandsCount; - - // Synchronization object - std::unique_ptr<SynchronizationObject> m_synchronizationObject; - - bool m_isKeySet; - - virtual void Connect(const std::string &address, - Flag::Option = Flag::RO); - virtual void Disconnect(); - - void TurnOnForeignKeys(); - - static SynchronizationObject *AllocDefaultSynchronizationObject(); - - public: - /** - * Open SQL connection - * - * Synchronization is archieved by using provided asynchronization object. - * If synchronizationObject is set to NULL, so synchronization is performed. - * Ownership of the synchronization object is transfered to sql connection - * object. - * - * @param address Database file name - * @param flags Open flags - * @param synchronizationObject A synchronization object to use. - */ - explicit SqlConnection(const std::string &address = std::string(), - Flag::Option options = Flag::RO, - SynchronizationObject *synchronizationObject = - AllocDefaultSynchronizationObject()); - - /** - * Destructor - */ - virtual ~SqlConnection(); - - /** - * Added extension for encryption functionality: - * - * SetKey gives sqlcipher key, which will be used to encrypt the database - * This function will only fail because of invalid arguments. To check if - * database can be opened with provided key, it is necessary to perform - * some operation on the database (i.e. read from it) and confirm if it - * succeeds. - * Password must have length >= 1. - * - * @param rawPass password given in raw binary format - */ - void SetKey(const RawBuffer &rawPass); - - /** - * ResetKey is used for changing key used for database encryption. - * If key was already set by using SetKey, this function will only change it. - * If no key was yet set, this function first will set key with rawPassOld and - * then change it to rawPassNew. - * Same rules for failing apply as for SetKey. - * Both password must have length >=1. - * - * @param rawPassOld current password for encryption in raw binary format - * @param rawPassNew new password for encryption in raw binary format - * - */ - void ResetKey(const RawBuffer &rawPassOld, - const RawBuffer &rawPassNew); - - /** - * Execute SQL command without result - * - * @param format - * @param ... - */ - //To prevent sql injection do not use this method for direct sql execution - void ExecCommand(const char *format, ...); - - /** - * Execute SQL command without result - * - * @param output The output of SQL command will be stored in this object - * if it's no NULL. - * @param format - * @param ... - */ - //To prevent sql injection do not use this method for direct sql execution - void ExecCommand(Output* output, const char *format, ...); - - /** - * Execute BEGIN; command to start new transaction - * - */ - void BeginTransaction(); - - /** - * Execute ROLLBACK; command to discard changes made - * - */ - void RollbackTransaction(); - - /** - * Execute COMMIT; command to commit changes in database - * - */ - void CommitTransaction(); - - /** - * Prepare stored procedure - * - * @param format SQL statement - * @return Data command representing stored procedure - */ - DataCommandUniquePtr PrepareDataCommand(const char *format, ...); - - /** - * Check whether given table exists - * - * @param tableName Name of the table to check - * @return True if given table name exists - */ - bool CheckTableExist(const char *tableName); - - /** - * Get last insert operation new row id - * - * @return Row ID - */ - RowID GetLastInsertRowID() const; - - private: - void ExecCommandHelper(Output* out, const char *format, va_list args); +public: + /** + * SQL Exception classes + */ + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, SyntaxError) + DECLARE_EXCEPTION_TYPE(Base, ConnectionBroken) + DECLARE_EXCEPTION_TYPE(Base, InternalError) + DECLARE_EXCEPTION_TYPE(Base, InvalidColumn) + DECLARE_EXCEPTION_TYPE(Base, InvalidArguments) + }; + + /** + * Output of SQL command + */ + class Output { + public: + typedef std::vector<std::string> Row; + typedef std::vector<Row> Rows; + + static int Callback(void *, int, char **, char **); + const Row &GetNames() const + { + return m_names; + } + const Rows &GetValues() const + { + return m_values; + } + private: + void SetResults(int columns, char **values, char **names); + + Row m_names; + Rows m_values; + }; + + typedef int ColumnIndex; + typedef int ArgumentIndex; + + /* + * SQL processed data command + */ + class DataCommand { + private: + SqlConnection *m_masterConnection; + sqlcipher3_stmt *m_stmt; + + void CheckBindResult(int result); + void CheckColumnIndex(SqlConnection::ColumnIndex column); + + DataCommand(SqlConnection *connection, const char *buffer); + + friend class SqlConnection; + + public: + NONCOPYABLE(DataCommand); + + virtual ~DataCommand(); + + /** + * Bind null to the prepared statement argument + * + * @param position Index of argument to bind value to + */ + void BindNull(ArgumentIndex position); + + /** + * Bind int to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInteger(ArgumentIndex position, int value); + + /** + * Bind int8_t to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt8(ArgumentIndex position, int8_t value); + + /** + * Bind int16 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt16(ArgumentIndex position, int16_t value); + + /** + * Bind int32 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt32(ArgumentIndex position, int32_t value); + + /** + * Bind int64 to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt64(ArgumentIndex position, int64_t value); + + /** + * Bind float to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindFloat(ArgumentIndex position, float value); + + /** + * Bind double to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindDouble(ArgumentIndex position, double value); + + /** + * Bind string to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindString(ArgumentIndex position, const char *value); + + /** + * Bind string to the prepared statement argument + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindBlob(ArgumentIndex position, const RawBuffer &value); + + /** + * Bind optional int to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInteger(ArgumentIndex position, const boost::optional<int> &value); + + /** + * Bind optional int8 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt8(ArgumentIndex position, const boost::optional<int8_t> &value); + + /** + * Bind optional int16 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt16(ArgumentIndex position, const boost::optional<int16_t> &value); + + /** + * Bind optional int32 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt32(ArgumentIndex position, const boost::optional<int32_t> &value); + + /** + * Bind optional int64 to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindInt64(ArgumentIndex position, const boost::optional<int64_t> &value); + + /** + * Bind optional float to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindFloat(ArgumentIndex position, const boost::optional<float> &value); + + /** + * Bind optional double to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindDouble(ArgumentIndex position, const boost::optional<double> &value); + + /** + * Bind optional string to the prepared statement argument. + * If optional is not set null will be bound + * + * @param position Index of argument to bind value to + * @param value Value to bind + */ + void BindBlob(ArgumentIndex position, const boost::optional<RawBuffer> &value); + + /** + * Execute the prepared statement and/or move + * to the next row of the result + * + * @return True when there was a row returned + */ + bool Step(); + + /** + * Reset prepared statement's arguments + * All parameters will become null + */ + void Reset(); + + /** + * Checks whether column value is null + * + * @throw Exception::InvalidColumn + */ + bool IsColumnNull(ColumnIndex column); + + /** + * Get integer value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int GetColumnInteger(ColumnIndex column); + + /** + * Get int8 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int8_t GetColumnInt8(ColumnIndex column); + + /** + * Get int16 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int16_t GetColumnInt16(ColumnIndex column); + /** + * Get int32 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int32_t GetColumnInt32(ColumnIndex column); + + /** + * Get int64 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + int64_t GetColumnInt64(ColumnIndex column); + + /** + * Get float value from column in current row. + * + * @throw Exception::InvalidColumn + */ + float GetColumnFloat(ColumnIndex column); + + /** + * Get double value from column in current row. + * + * @throw Exception::InvalidColumn + */ + double GetColumnDouble(ColumnIndex column); + + /** + * Get string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + std::string GetColumnString(ColumnIndex column); + + /** + * Get string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + RawBuffer GetColumnBlob(ColumnIndex column); + + /** + * Get optional integer value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<int> GetColumnOptionalInteger(ColumnIndex column); + + /** + * Get optional int8 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<int8_t> GetColumnOptionalInt8(ColumnIndex column); + + /** + * Get optional int16value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<int16_t> GetColumnOptionalInt16(ColumnIndex column); + + /** + * Get optional int32 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<int32_t> GetColumnOptionalInt32(ColumnIndex column); + + /** + * Get optional int64 value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<int64_t> GetColumnOptionalInt64(ColumnIndex column); + + /** + * Get optional float value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<float> GetColumnOptionalFloat(ColumnIndex column); + + /** + * Get optional double value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<double> GetColumnOptionalDouble(ColumnIndex column); + + /** + * Get string value from column in current row. + * + * @throw Exception::InvalidColumn + */ + boost::optional<RawBuffer> GetColumnOptionalBlob(ColumnIndex column); + }; + + // Move on copy constructor. No copy semantics + typedef std::unique_ptr<DataCommand> DataCommandUniquePtr; + + // Open flags + class Flag { + public: + enum Option { + RO = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READONLY, + RW = SQLCIPHER_OPEN_NOMUTEX | SQLCIPHER_OPEN_READWRITE, + CRW = RW | SQLCIPHER_OPEN_CREATE + }; + }; + + // RowID + typedef sqlcipher3_int64 RowID; + + /** + * Synchronization object used to synchronize SQL connection + * to the same database across different threads and processes + */ + class SynchronizationObject { + public: + virtual ~SynchronizationObject() {} + + /** + * Synchronizes SQL connection for multiple clients. + */ + virtual void Synchronize() = 0; + + /** + * Notify all waiting clients that the connection is no longer locked. + */ + virtual void NotifyAll() = 0; + }; + +protected: + sqlcipher3 *m_connection; + + // Options + + // Stored data procedures + int m_dataCommandsCount; + + // Synchronization object + std::unique_ptr<SynchronizationObject> m_synchronizationObject; + + bool m_isKeySet; + + virtual void Connect(const std::string &address, + Flag::Option = Flag::RO); + virtual void Disconnect(); + + void TurnOnForeignKeys(); + + static SynchronizationObject *AllocDefaultSynchronizationObject(); + +public: + /** + * Open SQL connection + * + * Synchronization is archieved by using provided asynchronization object. + * If synchronizationObject is set to NULL, so synchronization is performed. + * Ownership of the synchronization object is transfered to sql connection + * object. + * + * @param address Database file name + * @param flags Open flags + * @param synchronizationObject A synchronization object to use. + */ + explicit SqlConnection(const std::string &address = std::string(), + Flag::Option options = Flag::RO, + SynchronizationObject *synchronizationObject = + AllocDefaultSynchronizationObject()); + + /** + * Destructor + */ + virtual ~SqlConnection(); + + /** + * Added extension for encryption functionality: + * + * SetKey gives sqlcipher key, which will be used to encrypt the database + * This function will only fail because of invalid arguments. To check if + * database can be opened with provided key, it is necessary to perform + * some operation on the database (i.e. read from it) and confirm if it + * succeeds. + * Password must have length >= 1. + * + * @param rawPass password given in raw binary format + */ + void SetKey(const RawBuffer &rawPass); + + /** + * ResetKey is used for changing key used for database encryption. + * If key was already set by using SetKey, this function will only change it. + * If no key was yet set, this function first will set key with rawPassOld and + * then change it to rawPassNew. + * Same rules for failing apply as for SetKey. + * Both password must have length >=1. + * + * @param rawPassOld current password for encryption in raw binary format + * @param rawPassNew new password for encryption in raw binary format + * + */ + void ResetKey(const RawBuffer &rawPassOld, + const RawBuffer &rawPassNew); + + /** + * Execute SQL command without result + * + * @param format + * @param ... + */ + //To prevent sql injection do not use this method for direct sql execution + void ExecCommand(const char *format, ...); + + /** + * Execute SQL command without result + * + * @param output The output of SQL command will be stored in this object + * if it's no NULL. + * @param format + * @param ... + */ + //To prevent sql injection do not use this method for direct sql execution + void ExecCommand(Output *output, const char *format, ...); + + /** + * Execute BEGIN; command to start new transaction + * + */ + void BeginTransaction(); + + /** + * Execute ROLLBACK; command to discard changes made + * + */ + void RollbackTransaction(); + + /** + * Execute COMMIT; command to commit changes in database + * + */ + void CommitTransaction(); + + /** + * Prepare stored procedure + * + * @param format SQL statement + * @return Data command representing stored procedure + */ + DataCommandUniquePtr PrepareDataCommand(const char *format, ...); + + /** + * Check whether given table exists + * + * @param tableName Name of the table to check + * @return True if given table name exists + */ + bool CheckTableExist(const char *tableName); + + /** + * Get last insert operation new row id + * + * @return Row ID + */ + RowID GetLastInsertRowID() const; + +private: + void ExecCommandHelper(Output *out, const char *format, va_list args); }; } // namespace DB } // namespace CKM diff --git a/src/manager/dpl/db/src/naive_synchronization_object.cpp b/src/manager/dpl/db/src/naive_synchronization_object.cpp index ece4f26d..26436052 100644 --- a/src/manager/dpl/db/src/naive_synchronization_object.cpp +++ b/src/manager/dpl/db/src/naive_synchronization_object.cpp @@ -26,7 +26,7 @@ #include <time.h> namespace { - unsigned int seed = time(NULL); +unsigned int seed = time(NULL); } //Taken from Thread class, so we don't have to pull whole definition @@ -34,37 +34,37 @@ namespace { namespace Thread { static const size_t NANOSECONDS_PER_SECOND = - static_cast<uint64_t>(1000 * 1000 * 1000); + static_cast<uint64_t>(1000 * 1000 * 1000); static const size_t NANOSECONDS_PER_MILISECOND = - static_cast<uint64_t>(1000 * 1000); + static_cast<uint64_t>(1000 * 1000); void NanoSleep(uint64_t nanoseconds) { - timespec requestedTime = { - static_cast<time_t>( - nanoseconds / NANOSECONDS_PER_SECOND), + timespec requestedTime = { + static_cast<time_t>( + nanoseconds / NANOSECONDS_PER_SECOND), - static_cast<long>( - nanoseconds % NANOSECONDS_PER_SECOND) - }; + static_cast<long>( + nanoseconds % NANOSECONDS_PER_SECOND) + }; - timespec remainingTime; + timespec remainingTime; - for (;;) { - if (nanosleep(&requestedTime, &remainingTime) == 0) - break; + for (;;) { + if (nanosleep(&requestedTime, &remainingTime) == 0) + break; - int error = errno; - Assert(error == EINTR); + int error = errno; + Assert(error == EINTR); - requestedTime = remainingTime; - } + requestedTime = remainingTime; + } } void MiliSleep(uint64_t miliseconds) { - NanoSleep(miliseconds * NANOSECONDS_PER_MILISECOND); + NanoSleep(miliseconds * NANOSECONDS_PER_MILISECOND); } } @@ -72,13 +72,13 @@ namespace CKM { namespace DB { void NaiveSynchronizationObject::Synchronize() { - // Sleep for about 10ms - 30ms - Thread::MiliSleep(10 + rand_r(&seed) % 20); + // Sleep for about 10ms - 30ms + Thread::MiliSleep(10 + rand_r(&seed) % 20); } void NaiveSynchronizationObject::NotifyAll() { - // No need to inform about anything + // No need to inform about anything } } // namespace DB } // namespace CKM diff --git a/src/manager/dpl/db/src/sql_connection.cpp b/src/manager/dpl/db/src/sql_connection.cpp index 02a12c62..bbfe9a94 100644 --- a/src/manager/dpl/db/src/sql_connection.cpp +++ b/src/manager/dpl/db/src/sql_connection.cpp @@ -38,8 +38,11 @@ namespace { const int MAX_RETRY = 10; struct ScopedVaList { - ~ScopedVaList() { va_end(args); } - va_list args; + ~ScopedVaList() + { + va_end(args); + } + va_list args; }; #define scoped_va_start(name, param) ScopedVaList name; va_start(name.args, param); @@ -48,615 +51,623 @@ struct ScopedVaList { namespace CKM { namespace DB { namespace { // anonymous -class ScopedNotifyAll -{ - private: - SqlConnection::SynchronizationObject *m_synchronizationObject; - - public: - NONCOPYABLE(ScopedNotifyAll) - - explicit ScopedNotifyAll( - SqlConnection::SynchronizationObject *synchronizationObject) : - m_synchronizationObject(synchronizationObject) - { - } - - ~ScopedNotifyAll() - { - if (!m_synchronizationObject) - return; - - LogPedantic("Notifying after successful synchronize"); - m_synchronizationObject->NotifyAll(); - } +class ScopedNotifyAll { +private: + SqlConnection::SynchronizationObject *m_synchronizationObject; + +public: + NONCOPYABLE(ScopedNotifyAll) + + explicit ScopedNotifyAll( + SqlConnection::SynchronizationObject *synchronizationObject) : + m_synchronizationObject(synchronizationObject) + { + } + + ~ScopedNotifyAll() + { + if (!m_synchronizationObject) + return; + + LogPedantic("Notifying after successful synchronize"); + m_synchronizationObject->NotifyAll(); + } }; } // namespace anonymous SqlConnection::DataCommand::DataCommand(SqlConnection *connection, - const char *buffer) : - m_masterConnection(connection), - m_stmt(NULL) + const char *buffer) : + m_masterConnection(connection), + m_stmt(NULL) { - Assert(connection != NULL); + Assert(connection != NULL); - // Notify all after potentially synchronized database connection access - ScopedNotifyAll notifyAll(connection->m_synchronizationObject.get()); + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll(connection->m_synchronizationObject.get()); - for (int i = 0; i < MAX_RETRY; i++) { - int ret = sqlcipher3_prepare_v2(connection->m_connection, - buffer, strlen(buffer), - &m_stmt, NULL); + for (int i = 0; i < MAX_RETRY; i++) { + int ret = sqlcipher3_prepare_v2(connection->m_connection, + buffer, strlen(buffer), + &m_stmt, NULL); - if (ret == SQLCIPHER_OK) { - LogPedantic("Prepared data command: " << buffer); + if (ret == SQLCIPHER_OK) { + LogPedantic("Prepared data command: " << buffer); - // Increment stored data command count - ++m_masterConnection->m_dataCommandsCount; - return; - } else if (ret == SQLCIPHER_BUSY) { - LogPedantic("Collision occurred while preparing SQL command"); + // Increment stored data command count + ++m_masterConnection->m_dataCommandsCount; + return; + } else if (ret == SQLCIPHER_BUSY) { + LogPedantic("Collision occurred while preparing SQL command"); - // Synchronize if synchronization object is available - if (connection->m_synchronizationObject) { - LogPedantic("Performing synchronization"); - connection->m_synchronizationObject->Synchronize(); - continue; - } + // Synchronize if synchronization object is available + if (connection->m_synchronizationObject) { + LogPedantic("Performing synchronization"); + connection->m_synchronizationObject->Synchronize(); + continue; + } - // No synchronization object defined. Fail. - } + // No synchronization object defined. Fail. + } - // Fatal error - const char *error = sqlcipher3_errmsg(m_masterConnection->m_connection); + // Fatal error + const char *error = sqlcipher3_errmsg(m_masterConnection->m_connection); - LogError("SQL prepare data command failed"); - LogError(" Statement: " << buffer); - LogError(" Error: " << error); + LogError("SQL prepare data command failed"); + LogError(" Statement: " << buffer); + LogError(" Error: " << error); - ThrowMsg(Exception::SyntaxError, error); - } + ThrowMsg(Exception::SyntaxError, error); + } - LogError("sqlite in the state of possible infinite loop"); - ThrowMsg(Exception::InternalError, "sqlite permanently busy"); + LogError("sqlite in the state of possible infinite loop"); + ThrowMsg(Exception::InternalError, "sqlite permanently busy"); } SqlConnection::DataCommand::~DataCommand() { - LogPedantic("SQL data command finalizing"); + LogPedantic("SQL data command finalizing"); - if (sqlcipher3_finalize(m_stmt) != SQLCIPHER_OK) - LogError("Failed to finalize data command"); + if (sqlcipher3_finalize(m_stmt) != SQLCIPHER_OK) + LogError("Failed to finalize data command"); - // Decrement stored data command count - --m_masterConnection->m_dataCommandsCount; + // Decrement stored data command count + --m_masterConnection->m_dataCommandsCount; } void SqlConnection::DataCommand::CheckBindResult(int result) { - if (result != SQLCIPHER_OK) { - const char *error = sqlcipher3_errmsg( - m_masterConnection->m_connection); + if (result != SQLCIPHER_OK) { + const char *error = sqlcipher3_errmsg( + m_masterConnection->m_connection); - LogError("Failed to bind SQL statement parameter"); - LogError(" Error: " << error); + LogError("Failed to bind SQL statement parameter"); + LogError(" Error: " << error); - ThrowMsg(Exception::SyntaxError, error); - } + ThrowMsg(Exception::SyntaxError, error); + } } void SqlConnection::DataCommand::BindNull( - SqlConnection::ArgumentIndex position) + SqlConnection::ArgumentIndex position) { - CheckBindResult(sqlcipher3_bind_null(m_stmt, position)); - LogPedantic("SQL data command bind null: [" - << position << "]"); + CheckBindResult(sqlcipher3_bind_null(m_stmt, position)); + LogPedantic("SQL data command bind null: [" + << position << "]"); } void SqlConnection::DataCommand::BindInteger( - SqlConnection::ArgumentIndex position, - int value) + SqlConnection::ArgumentIndex position, + int value) { - CheckBindResult(sqlcipher3_bind_int(m_stmt, position, value)); - LogPedantic("SQL data command bind integer: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_int(m_stmt, position, value)); + LogPedantic("SQL data command bind integer: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindInt8( - SqlConnection::ArgumentIndex position, - int8_t value) + SqlConnection::ArgumentIndex position, + int8_t value) { - CheckBindResult(sqlcipher3_bind_int(m_stmt, position, - static_cast<int>(value))); - LogPedantic("SQL data command bind int8: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_int(m_stmt, position, + static_cast<int>(value))); + LogPedantic("SQL data command bind int8: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindInt16( - SqlConnection::ArgumentIndex position, - int16_t value) + SqlConnection::ArgumentIndex position, + int16_t value) { - CheckBindResult(sqlcipher3_bind_int(m_stmt, position, - static_cast<int>(value))); - LogPedantic("SQL data command bind int16: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_int(m_stmt, position, + static_cast<int>(value))); + LogPedantic("SQL data command bind int16: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindInt32( - SqlConnection::ArgumentIndex position, - int32_t value) + SqlConnection::ArgumentIndex position, + int32_t value) { - CheckBindResult(sqlcipher3_bind_int(m_stmt, position, - static_cast<int>(value))); - LogPedantic("SQL data command bind int32: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_int(m_stmt, position, + static_cast<int>(value))); + LogPedantic("SQL data command bind int32: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindInt64( - SqlConnection::ArgumentIndex position, - int64_t value) + SqlConnection::ArgumentIndex position, + int64_t value) { - CheckBindResult(sqlcipher3_bind_int64(m_stmt, position, - static_cast<sqlcipher3_int64>(value))); - LogPedantic("SQL data command bind int64: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_int64(m_stmt, position, + static_cast<sqlcipher3_int64>(value))); + LogPedantic("SQL data command bind int64: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindFloat( - SqlConnection::ArgumentIndex position, - float value) + SqlConnection::ArgumentIndex position, + float value) { - CheckBindResult(sqlcipher3_bind_double(m_stmt, position, - static_cast<double>(value))); - LogPedantic("SQL data command bind float: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_double(m_stmt, position, + static_cast<double>(value))); + LogPedantic("SQL data command bind float: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindDouble( - SqlConnection::ArgumentIndex position, - double value) + SqlConnection::ArgumentIndex position, + double value) { - CheckBindResult(sqlcipher3_bind_double(m_stmt, position, value)); - LogPedantic("SQL data command bind double: [" - << position << "] -> " << value); + CheckBindResult(sqlcipher3_bind_double(m_stmt, position, value)); + LogPedantic("SQL data command bind double: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindString( - SqlConnection::ArgumentIndex position, - const char *value) + SqlConnection::ArgumentIndex position, + const char *value) { - if (!value) { - BindNull(position); - return; - } + if (!value) { + BindNull(position); + return; + } - // Assume that text may disappear - CheckBindResult(sqlcipher3_bind_text(m_stmt, position, - value, strlen(value), - SQLCIPHER_TRANSIENT)); + // Assume that text may disappear + CheckBindResult(sqlcipher3_bind_text(m_stmt, position, + value, strlen(value), + SQLCIPHER_TRANSIENT)); - LogPedantic("SQL data command bind string: [" - << position << "] -> " << value); + LogPedantic("SQL data command bind string: [" + << position << "] -> " << value); } void SqlConnection::DataCommand::BindBlob( - SqlConnection::ArgumentIndex position, - const RawBuffer &raw) + SqlConnection::ArgumentIndex position, + const RawBuffer &raw) { - if (raw.size() == 0) { - BindNull(position); - return; - } + if (raw.size() == 0) { + BindNull(position); + return; + } - // Assume that blob may dissappear - CheckBindResult(sqlcipher3_bind_blob(m_stmt, position, - raw.data(), raw.size(), - SQLCIPHER_TRANSIENT)); - LogPedantic("SQL data command bind blob of size: [" - << position << "] -> " << raw.size()); + // Assume that blob may dissappear + CheckBindResult(sqlcipher3_bind_blob(m_stmt, position, + raw.data(), raw.size(), + SQLCIPHER_TRANSIENT)); + LogPedantic("SQL data command bind blob of size: [" + << position << "] -> " << raw.size()); } void SqlConnection::DataCommand::BindInteger( - SqlConnection::ArgumentIndex position, - const boost::optional<int> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<int> &value) { - if (!value) - BindNull(position); - else - BindInteger(position, *value); + if (!value) + BindNull(position); + else + BindInteger(position, *value); } void SqlConnection::DataCommand::BindInt8( - SqlConnection::ArgumentIndex position, - const boost::optional<int8_t> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<int8_t> &value) { - if (!value) - BindNull(position); - else - BindInt8(position, *value); + if (!value) + BindNull(position); + else + BindInt8(position, *value); } void SqlConnection::DataCommand::BindInt16( - SqlConnection::ArgumentIndex position, - const boost::optional<int16_t> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<int16_t> &value) { - if (!value) - BindNull(position); - else - BindInt16(position, *value); + if (!value) + BindNull(position); + else + BindInt16(position, *value); } void SqlConnection::DataCommand::BindInt32( - SqlConnection::ArgumentIndex position, - const boost::optional<int32_t> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<int32_t> &value) { - if (!value) - BindNull(position); - else - BindInt32(position, *value); + if (!value) + BindNull(position); + else + BindInt32(position, *value); } void SqlConnection::DataCommand::BindInt64( - SqlConnection::ArgumentIndex position, - const boost::optional<int64_t> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<int64_t> &value) { - if (!value) - BindNull(position); - else - BindInt64(position, *value); + if (!value) + BindNull(position); + else + BindInt64(position, *value); } void SqlConnection::DataCommand::BindFloat( - SqlConnection::ArgumentIndex position, - const boost::optional<float> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<float> &value) { - if (!value) - BindNull(position); - else - BindFloat(position, *value); + if (!value) + BindNull(position); + else + BindFloat(position, *value); } void SqlConnection::DataCommand::BindDouble( - SqlConnection::ArgumentIndex position, - const boost::optional<double> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<double> &value) { - if (!value) - BindNull(position); - else - BindDouble(position, *value); + if (!value) + BindNull(position); + else + BindDouble(position, *value); } void SqlConnection::DataCommand::BindBlob( - SqlConnection::ArgumentIndex position, - const boost::optional<RawBuffer> &value) + SqlConnection::ArgumentIndex position, + const boost::optional<RawBuffer> &value) { - if (!!value) - BindBlob(position, *value); - else - BindNull(position); + if (!!value) + BindBlob(position, *value); + else + BindNull(position); } bool SqlConnection::DataCommand::Step() { - // Notify all after potentially synchronized database connection access - ScopedNotifyAll notifyAll( - m_masterConnection->m_synchronizationObject.get()); + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll( + m_masterConnection->m_synchronizationObject.get()); - for (int i = 0; i < MAX_RETRY; i++) { - int ret = sqlcipher3_step(m_stmt); + for (int i = 0; i < MAX_RETRY; i++) { + int ret = sqlcipher3_step(m_stmt); - if (ret == SQLCIPHER_ROW) { - LogPedantic("SQL data command step ROW"); - return true; - } else if (ret == SQLCIPHER_DONE) { - LogPedantic("SQL data command step DONE"); - return false; - } else if (ret == SQLCIPHER_BUSY) { - LogPedantic("Collision occurred while executing SQL command"); + if (ret == SQLCIPHER_ROW) { + LogPedantic("SQL data command step ROW"); + return true; + } else if (ret == SQLCIPHER_DONE) { + LogPedantic("SQL data command step DONE"); + return false; + } else if (ret == SQLCIPHER_BUSY) { + LogPedantic("Collision occurred while executing SQL command"); - // Synchronize if synchronization object is available - if (m_masterConnection->m_synchronizationObject) { - LogPedantic("Performing synchronization"); + // Synchronize if synchronization object is available + if (m_masterConnection->m_synchronizationObject) { + LogPedantic("Performing synchronization"); - m_masterConnection-> - m_synchronizationObject->Synchronize(); + m_masterConnection-> + m_synchronizationObject->Synchronize(); - continue; - } - // No synchronization object defined. Fail. - } + continue; + } - // Fatal error - const char *error = sqlcipher3_errmsg(m_masterConnection->m_connection); + // No synchronization object defined. Fail. + } - LogError("SQL step data command failed"); - LogError(" Error: " << error); + // Fatal error + const char *error = sqlcipher3_errmsg(m_masterConnection->m_connection); - ThrowMsg(Exception::InternalError, error); - } + LogError("SQL step data command failed"); + LogError(" Error: " << error); - LogError("sqlite in the state of possible infinite loop"); - ThrowMsg(Exception::InternalError, "sqlite permanently busy"); + ThrowMsg(Exception::InternalError, error); + } + + LogError("sqlite in the state of possible infinite loop"); + ThrowMsg(Exception::InternalError, "sqlite permanently busy"); } void SqlConnection::DataCommand::Reset() { - /* - * According to: - * http://www.sqllite.org/c3ref/stmt.html - * - * if last sqlcipher3_step command on this stmt returned an error, - * then sqlcipher3_reset will return that error, althought it is not an error. - * So sqlcipher3_reset allways succedes. - */ - sqlcipher3_reset(m_stmt); + /* + * According to: + * http://www.sqllite.org/c3ref/stmt.html + * + * if last sqlcipher3_step command on this stmt returned an error, + * then sqlcipher3_reset will return that error, althought it is not an error. + * So sqlcipher3_reset allways succedes. + */ + sqlcipher3_reset(m_stmt); - LogPedantic("SQL data command reset"); + LogPedantic("SQL data command reset"); } void SqlConnection::DataCommand::CheckColumnIndex( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - if (column < 0 || column >= sqlcipher3_column_count(m_stmt)) - ThrowMsg(Exception::InvalidColumn, "Column index is out of bounds"); + if (column < 0 || column >= sqlcipher3_column_count(m_stmt)) + ThrowMsg(Exception::InvalidColumn, "Column index is out of bounds"); } bool SqlConnection::DataCommand::IsColumnNull( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column type: [" << column << "]"); - CheckColumnIndex(column); - return sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL; + LogPedantic("SQL data command get column type: [" << column << "]"); + CheckColumnIndex(column); + return sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL; } int SqlConnection::DataCommand::GetColumnInteger( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column integer: [" << column << "]"); - CheckColumnIndex(column); - int value = sqlcipher3_column_int(m_stmt, column); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column integer: [" << column << "]"); + CheckColumnIndex(column); + int value = sqlcipher3_column_int(m_stmt, column); + LogPedantic(" Value: " << value); + return value; } int8_t SqlConnection::DataCommand::GetColumnInt8( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column int8: [" << column << "]"); - CheckColumnIndex(column); - int8_t value = static_cast<int8_t>(sqlcipher3_column_int(m_stmt, column)); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column int8: [" << column << "]"); + CheckColumnIndex(column); + int8_t value = static_cast<int8_t>(sqlcipher3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; } int16_t SqlConnection::DataCommand::GetColumnInt16( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column int16: [" << column << "]"); - CheckColumnIndex(column); - int16_t value = static_cast<int16_t>(sqlcipher3_column_int(m_stmt, column)); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column int16: [" << column << "]"); + CheckColumnIndex(column); + int16_t value = static_cast<int16_t>(sqlcipher3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; } int32_t SqlConnection::DataCommand::GetColumnInt32( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column int32: [" << column << "]"); - CheckColumnIndex(column); - int32_t value = static_cast<int32_t>(sqlcipher3_column_int(m_stmt, column)); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column int32: [" << column << "]"); + CheckColumnIndex(column); + int32_t value = static_cast<int32_t>(sqlcipher3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; } int64_t SqlConnection::DataCommand::GetColumnInt64( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column int64: [" << column << "]"); - CheckColumnIndex(column); - int64_t value = static_cast<int64_t>(sqlcipher3_column_int64(m_stmt, column)); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column int64: [" << column << "]"); + CheckColumnIndex(column); + int64_t value = static_cast<int64_t>(sqlcipher3_column_int64(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; } float SqlConnection::DataCommand::GetColumnFloat( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column float: [" << column << "]"); - CheckColumnIndex(column); - float value = static_cast<float>(sqlcipher3_column_double(m_stmt, column)); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column float: [" << column << "]"); + CheckColumnIndex(column); + float value = static_cast<float>(sqlcipher3_column_double(m_stmt, column)); + LogPedantic(" Value: " << value); + return value; } double SqlConnection::DataCommand::GetColumnDouble( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column double: [" << column << "]"); - CheckColumnIndex(column); - double value = sqlcipher3_column_double(m_stmt, column); - LogPedantic(" Value: " << value); - return value; + LogPedantic("SQL data command get column double: [" << column << "]"); + CheckColumnIndex(column); + double value = sqlcipher3_column_double(m_stmt, column); + LogPedantic(" Value: " << value); + return value; } std::string SqlConnection::DataCommand::GetColumnString( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column string: [" << column << "]"); - CheckColumnIndex(column); + LogPedantic("SQL data command get column string: [" << column << "]"); + CheckColumnIndex(column); - const char *value = reinterpret_cast<const char *>( - sqlcipher3_column_text(m_stmt, column)); + const char *value = reinterpret_cast<const char *>( + sqlcipher3_column_text(m_stmt, column)); - LogPedantic("Value: " << (value ? value : "NULL")); + LogPedantic("Value: " << (value ? value : "NULL")); - if (value == NULL) - return std::string(); + if (value == NULL) + return std::string(); - return std::string(value); + return std::string(value); } RawBuffer SqlConnection::DataCommand::GetColumnBlob( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column blog: [" << column << "]"); - CheckColumnIndex(column); + LogPedantic("SQL data command get column blog: [" << column << "]"); + CheckColumnIndex(column); - const unsigned char *value = reinterpret_cast<const unsigned char*>( - sqlcipher3_column_blob(m_stmt, column)); + const unsigned char *value = reinterpret_cast<const unsigned char *>( + sqlcipher3_column_blob(m_stmt, column)); - if (value == NULL) - return RawBuffer(); + if (value == NULL) + return RawBuffer(); - int length = sqlcipher3_column_bytes(m_stmt, column); - LogPedantic("Got blob of length: " << length); + int length = sqlcipher3_column_bytes(m_stmt, column); + LogPedantic("Got blob of length: " << length); - return RawBuffer(value, value + length); + return RawBuffer(value, value + length); } boost::optional<int> SqlConnection::DataCommand::GetColumnOptionalInteger( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional integer: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<int>(); + LogPedantic("SQL data command get column optional integer: [" + << column << "]"); + CheckColumnIndex(column); + + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<int>(); - int value = sqlcipher3_column_int(m_stmt, column); - LogPedantic(" Value: " << value); - return boost::optional<int>(value); + int value = sqlcipher3_column_int(m_stmt, column); + LogPedantic(" Value: " << value); + return boost::optional<int>(value); } boost::optional<int8_t> SqlConnection::DataCommand::GetColumnOptionalInt8( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional int8: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<int8_t>(); + LogPedantic("SQL data command get column optional int8: [" + << column << "]"); + CheckColumnIndex(column); - int8_t value = static_cast<int8_t>(sqlcipher3_column_int(m_stmt, column)); - LogPedantic(" Value: " << value); - return boost::optional<int8_t>(value); + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<int8_t>(); + + int8_t value = static_cast<int8_t>(sqlcipher3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return boost::optional<int8_t>(value); } boost::optional<int16_t> SqlConnection::DataCommand::GetColumnOptionalInt16( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional int16: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<int16_t>(); + LogPedantic("SQL data command get column optional int16: [" + << column << "]"); + CheckColumnIndex(column); + + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<int16_t>(); - int16_t value = static_cast<int16_t>(sqlcipher3_column_int(m_stmt, column)); - LogPedantic(" Value: " << value); - return boost::optional<int16_t>(value); + int16_t value = static_cast<int16_t>(sqlcipher3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return boost::optional<int16_t>(value); } boost::optional<int32_t> SqlConnection::DataCommand::GetColumnOptionalInt32( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional int32: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<int32_t>(); + LogPedantic("SQL data command get column optional int32: [" + << column << "]"); + CheckColumnIndex(column); - int32_t value = static_cast<int32_t>(sqlcipher3_column_int(m_stmt, column)); - LogPedantic(" Value: " << value); - return boost::optional<int32_t>(value); + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<int32_t>(); + + int32_t value = static_cast<int32_t>(sqlcipher3_column_int(m_stmt, column)); + LogPedantic(" Value: " << value); + return boost::optional<int32_t>(value); } boost::optional<int64_t> SqlConnection::DataCommand::GetColumnOptionalInt64( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional int64: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<int64_t>(); + LogPedantic("SQL data command get column optional int64: [" + << column << "]"); + CheckColumnIndex(column); + + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<int64_t>(); - int64_t value = static_cast<int64_t>(sqlcipher3_column_int64(m_stmt, column)); - LogPedantic(" Value: " << value); - return boost::optional<int64_t>(value); + int64_t value = static_cast<int64_t>(sqlcipher3_column_int64(m_stmt, column)); + LogPedantic(" Value: " << value); + return boost::optional<int64_t>(value); } boost::optional<float> SqlConnection::DataCommand::GetColumnOptionalFloat( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional float: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<float>(); + LogPedantic("SQL data command get column optional float: [" + << column << "]"); + CheckColumnIndex(column); + + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<float>(); - float value = static_cast<float>(sqlcipher3_column_double(m_stmt, column)); - LogPedantic(" Value: " << value); - return boost::optional<float>(value); + float value = static_cast<float>(sqlcipher3_column_double(m_stmt, column)); + LogPedantic(" Value: " << value); + return boost::optional<float>(value); } boost::optional<double> SqlConnection::DataCommand::GetColumnOptionalDouble( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column optional double: [" - << column << "]"); - CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<double>(); + LogPedantic("SQL data command get column optional double: [" + << column << "]"); + CheckColumnIndex(column); - double value = sqlcipher3_column_double(m_stmt, column); - LogPedantic(" Value: " << value); - return boost::optional<double>(value); + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<double>(); + + double value = sqlcipher3_column_double(m_stmt, column); + LogPedantic(" Value: " << value); + return boost::optional<double>(value); } boost::optional<RawBuffer> SqlConnection::DataCommand::GetColumnOptionalBlob( - SqlConnection::ColumnIndex column) + SqlConnection::ColumnIndex column) { - LogPedantic("SQL data command get column blog: [" << column << "]"); - CheckColumnIndex(column); + LogPedantic("SQL data command get column blog: [" << column << "]"); + CheckColumnIndex(column); - if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) - return boost::optional<RawBuffer>(); + if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL) + return boost::optional<RawBuffer>(); - const unsigned char *value = reinterpret_cast<const unsigned char*>( - sqlcipher3_column_blob(m_stmt, column)); + const unsigned char *value = reinterpret_cast<const unsigned char *>( + sqlcipher3_column_blob(m_stmt, column)); - int length = sqlcipher3_column_bytes(m_stmt, column); - LogPedantic("Got blob of length: " << length); + int length = sqlcipher3_column_bytes(m_stmt, column); + LogPedantic("Got blob of length: " << length); - RawBuffer temp(value, value + length); - return boost::optional<RawBuffer>(temp); + RawBuffer temp(value, value + length); + return boost::optional<RawBuffer>(temp); } void SqlConnection::Connect(const std::string &address, - Flag::Option flag) + Flag::Option flag) { - if (m_connection != NULL) { - LogPedantic("Already connected."); - return; - } - LogPedantic("Connecting to DB: " << address << "..."); + if (m_connection != NULL) { + LogPedantic("Already connected."); + return; + } + + LogPedantic("Connecting to DB: " << address << "..."); - // Connect to database - int result; - result = sqlcipher3_open_v2( - address.c_str(), - &m_connection, - flag, - NULL); + // Connect to database + int result; + result = sqlcipher3_open_v2( + address.c_str(), + &m_connection, + flag, + NULL); - if (result == SQLCIPHER_OK) { - LogPedantic("Connected to DB"); - } else { - LogError("Failed to connect to DB!"); - ThrowMsg(Exception::ConnectionBroken, address); - } + if (result == SQLCIPHER_OK) { + LogPedantic("Connected to DB"); + } else { + LogError("Failed to connect to DB!"); + ThrowMsg(Exception::ConnectionBroken, address); + } - // Enable foreign keys - TurnOnForeignKeys(); + // Enable foreign keys + TurnOnForeignKeys(); } const std::string SQLCIPHER_RAW_PREFIX = "x'"; @@ -665,324 +676,337 @@ const std::size_t SQLCIPHER_RAW_DATA_SIZE = 32; RawBuffer rawToHexString(const RawBuffer &raw) { - RawBuffer output; - for (auto &e: raw) { - char result[3]; - snprintf(result, sizeof(result), "%02X", (e & 0xff)); - output.push_back(static_cast<unsigned char>(result[0])); - output.push_back(static_cast<unsigned char>(result[1])); - } - return output; + RawBuffer output; + + for (auto &e : raw) { + char result[3]; + snprintf(result, sizeof(result), "%02X", (e & 0xff)); + output.push_back(static_cast<unsigned char>(result[0])); + output.push_back(static_cast<unsigned char>(result[1])); + } + + return output; } RawBuffer createHexPass(const RawBuffer &rawPass) { - // We are required to pass 64byte long hex password made out of 32byte raw - // binary data - RawBuffer output; - std::copy(SQLCIPHER_RAW_PREFIX.begin(), SQLCIPHER_RAW_PREFIX.end(), - std::back_inserter(output)); - - RawBuffer password = rawToHexString(rawPass); - - std::copy(password.begin(), password.end(), - std::back_inserter(output)); - - std::copy(SQLCIPHER_RAW_SUFIX.begin(), SQLCIPHER_RAW_SUFIX.end(), - std::back_inserter(output)); - - return output; -} - -void SqlConnection::SetKey(const RawBuffer &rawPass){ - if (m_connection == NULL) { - LogPedantic("Cannot set key. No connection to DB!"); - return; - } - if (rawPass.size() != SQLCIPHER_RAW_DATA_SIZE) - ThrowMsg(Exception::InvalidArguments, - "Binary data for raw password should be 32 bytes long."); - RawBuffer pass = createHexPass(rawPass); - int result = sqlcipher3_key(m_connection, pass.data(), pass.size()); - if (result == SQLCIPHER_OK) { - LogPedantic("Set key on DB"); - } else { - //sqlcipher3_key fails only when m_connection == NULL || key == NULL || - // key length == 0 - LogError("Failed to set key on DB"); - ThrowMsg(Exception::InvalidArguments, result); - } - - m_isKeySet = true; + // We are required to pass 64byte long hex password made out of 32byte raw + // binary data + RawBuffer output; + std::copy(SQLCIPHER_RAW_PREFIX.begin(), SQLCIPHER_RAW_PREFIX.end(), + std::back_inserter(output)); + + RawBuffer password = rawToHexString(rawPass); + + std::copy(password.begin(), password.end(), + std::back_inserter(output)); + + std::copy(SQLCIPHER_RAW_SUFIX.begin(), SQLCIPHER_RAW_SUFIX.end(), + std::back_inserter(output)); + + return output; +} + +void SqlConnection::SetKey(const RawBuffer &rawPass) +{ + if (m_connection == NULL) { + LogPedantic("Cannot set key. No connection to DB!"); + return; + } + + if (rawPass.size() != SQLCIPHER_RAW_DATA_SIZE) + ThrowMsg(Exception::InvalidArguments, + "Binary data for raw password should be 32 bytes long."); + + RawBuffer pass = createHexPass(rawPass); + int result = sqlcipher3_key(m_connection, pass.data(), pass.size()); + + if (result == SQLCIPHER_OK) { + LogPedantic("Set key on DB"); + } else { + //sqlcipher3_key fails only when m_connection == NULL || key == NULL || + // key length == 0 + LogError("Failed to set key on DB"); + ThrowMsg(Exception::InvalidArguments, result); + } + + m_isKeySet = true; }; void SqlConnection::ResetKey(const RawBuffer &rawPassOld, - const RawBuffer &rawPassNew) { - if (m_connection == NULL) { - LogPedantic("Cannot reset key. No connection to DB!"); - return; - } - AssertMsg(rawPassOld.size() == SQLCIPHER_RAW_DATA_SIZE && - rawPassNew.size() == SQLCIPHER_RAW_DATA_SIZE, - "Binary data for raw password should be 32 bytes long."); - // sqlcipher3_rekey requires for key to be already set - if (!m_isKeySet) - SetKey(rawPassOld); - - RawBuffer pass = createHexPass(rawPassNew); - int result = sqlcipher3_rekey(m_connection, pass.data(), pass.size()); - if (result == SQLCIPHER_OK) { - LogPedantic("Reset key on DB"); - } else { - //sqlcipher3_rekey fails only when m_connection == NULL || key == NULL || - // key length == 0 - LogError("Failed to reset key on DB"); - ThrowMsg(Exception::InvalidArguments, result); - } + const RawBuffer &rawPassNew) +{ + if (m_connection == NULL) { + LogPedantic("Cannot reset key. No connection to DB!"); + return; + } + + AssertMsg(rawPassOld.size() == SQLCIPHER_RAW_DATA_SIZE && + rawPassNew.size() == SQLCIPHER_RAW_DATA_SIZE, + "Binary data for raw password should be 32 bytes long."); + + // sqlcipher3_rekey requires for key to be already set + if (!m_isKeySet) + SetKey(rawPassOld); + + RawBuffer pass = createHexPass(rawPassNew); + int result = sqlcipher3_rekey(m_connection, pass.data(), pass.size()); + + if (result == SQLCIPHER_OK) { + LogPedantic("Reset key on DB"); + } else { + //sqlcipher3_rekey fails only when m_connection == NULL || key == NULL || + // key length == 0 + LogError("Failed to reset key on DB"); + ThrowMsg(Exception::InvalidArguments, result); + } } void SqlConnection::Disconnect() { - if (m_connection == NULL) { - LogPedantic("Already disconnected."); - return; - } + if (m_connection == NULL) { + LogPedantic("Already disconnected."); + return; + } - LogPedantic("Disconnecting from DB..."); + LogPedantic("Disconnecting from DB..."); - // All stored data commands must be deleted before disconnect - AssertMsg(m_dataCommandsCount == 0, - "All stored procedures must be deleted" - " before disconnecting SqlConnection"); + // All stored data commands must be deleted before disconnect + AssertMsg(m_dataCommandsCount == 0, + "All stored procedures must be deleted" + " before disconnecting SqlConnection"); - int result; + int result; - result = sqlcipher3_close(m_connection); + result = sqlcipher3_close(m_connection); - if (result != SQLCIPHER_OK) { - const char *error = sqlcipher3_errmsg(m_connection); - LogError("SQL close failed"); - LogError(" Error: " << error); - Throw(Exception::InternalError); - } + if (result != SQLCIPHER_OK) { + const char *error = sqlcipher3_errmsg(m_connection); + LogError("SQL close failed"); + LogError(" Error: " << error); + Throw(Exception::InternalError); + } - m_connection = NULL; + m_connection = NULL; - LogPedantic("Disconnected from DB"); + LogPedantic("Disconnected from DB"); } bool SqlConnection::CheckTableExist(const char *tableName) { - if (m_connection == NULL) { - LogPedantic("Cannot execute command. Not connected to DB!"); - return false; - } + if (m_connection == NULL) { + LogPedantic("Cannot execute command. Not connected to DB!"); + return false; + } - DataCommandUniquePtr command = - PrepareDataCommand("select tbl_name from sqlcipher_master where name=?;"); + DataCommandUniquePtr command = + PrepareDataCommand("select tbl_name from sqlcipher_master where name=?;"); - command->BindString(1, tableName); + command->BindString(1, tableName); - if (!command->Step()) { - LogPedantic("No matching records in table"); - return false; - } + if (!command->Step()) { + LogPedantic("No matching records in table"); + return false; + } - return command->GetColumnString(0) == tableName; + return command->GetColumnString(0) == tableName; } SqlConnection::SqlConnection(const std::string &address, - Flag::Option option, - SynchronizationObject *synchronizationObject) : - m_connection(NULL), - m_dataCommandsCount(0), - m_synchronizationObject(synchronizationObject), - m_isKeySet(false) + Flag::Option option, + SynchronizationObject *synchronizationObject) : + m_connection(NULL), + m_dataCommandsCount(0), + m_synchronizationObject(synchronizationObject), + m_isKeySet(false) { - LogPedantic("Opening database connection to: " << address); + LogPedantic("Opening database connection to: " << address); - // Connect to DB - SqlConnection::Connect(address, option); + // Connect to DB + SqlConnection::Connect(address, option); - if (!m_synchronizationObject) - LogPedantic("No synchronization object defined"); + if (!m_synchronizationObject) + LogPedantic("No synchronization object defined"); } SqlConnection::~SqlConnection() { - LogPedantic("Closing database connection"); + LogPedantic("Closing database connection"); - // Disconnect from DB - Try - { - SqlConnection::Disconnect(); - } - Catch(Exception::Base) - { - LogError("Failed to disconnect from database"); - } + // Disconnect from DB + try { + SqlConnection::Disconnect(); + } catch (const Exception::Base &) { + LogError("Failed to disconnect from database"); + } } -int SqlConnection::Output::Callback(void* param, int columns, char** values, char** names) +int SqlConnection::Output::Callback(void *param, int columns, char **values, + char **names) { - if (param) - static_cast<Output*>(param)->SetResults(columns, values, names); - return 0; + if (param) + static_cast<Output *>(param)->SetResults(columns, values, names); + + return 0; } -void SqlConnection::Output::SetResults(int columns, char** values, char** names) +void SqlConnection::Output::SetResults(int columns, char **values, char **names) { - if (m_names.empty()) { - for (int i=0; i < columns; i++) - m_names.push_back(names[i] ? names[i] : "NULL"); - } - Row row; - for (int i=0; i < columns; i++) - row.push_back(values[i] ? values[i] : "NULL"); - m_values.push_back(std::move(row)); + if (m_names.empty()) { + for (int i = 0; i < columns; i++) + m_names.push_back(names[i] ? names[i] : "NULL"); + } + + Row row; + + for (int i = 0; i < columns; i++) + row.push_back(values[i] ? values[i] : "NULL"); + + m_values.push_back(std::move(row)); } -void SqlConnection::ExecCommandHelper(Output* out, const char* format, va_list args) +void SqlConnection::ExecCommandHelper(Output *out, const char *format, + va_list args) { - if (m_connection == NULL) { - LogError("Cannot execute command. Not connected to DB!"); - return; - } + if (m_connection == NULL) { + LogError("Cannot execute command. Not connected to DB!"); + return; + } - if (format == NULL) { - LogError("Null query!"); - ThrowMsg(Exception::SyntaxError, "Null statement"); - } + if (format == NULL) { + LogError("Null query!"); + ThrowMsg(Exception::SyntaxError, "Null statement"); + } - char *query; + char *query; - if (vasprintf(&query, format, args) == -1) { - LogError("Failed to allocate statement string"); - return; - } + if (vasprintf(&query, format, args) == -1) { + LogError("Failed to allocate statement string"); + return; + } - CharUniquePtr queryPtr(query); + CharUniquePtr queryPtr(query); - LogPedantic("Executing SQL command: " << queryPtr.get()); + LogPedantic("Executing SQL command: " << queryPtr.get()); - // Notify all after potentially synchronized database connection access - ScopedNotifyAll notifyAll(m_synchronizationObject.get()); + // Notify all after potentially synchronized database connection access + ScopedNotifyAll notifyAll(m_synchronizationObject.get()); - for (int i = 0; i < MAX_RETRY; i++) { - char *errorBuffer; - int ret = sqlcipher3_exec(m_connection, - queryPtr.get(), - out ? &Output::Callback : NULL, - out, - &errorBuffer); + for (int i = 0; i < MAX_RETRY; i++) { + char *errorBuffer; + int ret = sqlcipher3_exec(m_connection, + queryPtr.get(), + out ? &Output::Callback : NULL, + out, + &errorBuffer); - std::string errorMsg; + std::string errorMsg; - // Take allocated error buffer - if (errorBuffer != NULL) { - errorMsg = errorBuffer; - sqlcipher3_free(errorBuffer); - } + // Take allocated error buffer + if (errorBuffer != NULL) { + errorMsg = errorBuffer; + sqlcipher3_free(errorBuffer); + } - if (ret == SQLCIPHER_OK) - return; + if (ret == SQLCIPHER_OK) + return; - if (ret == SQLCIPHER_BUSY) { - LogPedantic("Collision occurred while executing SQL command"); + if (ret == SQLCIPHER_BUSY) { + LogPedantic("Collision occurred while executing SQL command"); - // Synchronize if synchronization object is available - if (m_synchronizationObject) { - LogPedantic("Performing synchronization"); - m_synchronizationObject->Synchronize(); - continue; - } + // Synchronize if synchronization object is available + if (m_synchronizationObject) { + LogPedantic("Performing synchronization"); + m_synchronizationObject->Synchronize(); + continue; + } - // No synchronization object defined. Fail. - } + // No synchronization object defined. Fail. + } - // Fatal error - LogError("Failed to execute SQL command. Error: " << errorMsg); - ThrowMsg(Exception::SyntaxError, errorMsg); - } + // Fatal error + LogError("Failed to execute SQL command. Error: " << errorMsg); + ThrowMsg(Exception::SyntaxError, errorMsg); + } - LogError("sqlite in the state of possible infinite loop"); - ThrowMsg(Exception::InternalError, "sqlite permanently busy"); + LogError("sqlite in the state of possible infinite loop"); + ThrowMsg(Exception::InternalError, "sqlite permanently busy"); } -void SqlConnection::ExecCommand(Output* out, const char *format, ...) +void SqlConnection::ExecCommand(Output *out, const char *format, ...) { - scoped_va_start(svl, format); + scoped_va_start(svl, format); - ExecCommandHelper(out, format, svl.args); + ExecCommandHelper(out, format, svl.args); } void SqlConnection::ExecCommand(const char *format, ...) { - scoped_va_start(svl, format); + scoped_va_start(svl, format); - ExecCommandHelper(NULL, format, svl.args); + ExecCommandHelper(NULL, format, svl.args); } SqlConnection::DataCommandUniquePtr SqlConnection::PrepareDataCommand( - const char *format, - ...) + const char *format, + ...) { - if (m_connection == NULL) { - LogError("Cannot execute data command. Not connected to DB!"); - return DataCommandUniquePtr(); - } + if (m_connection == NULL) { + LogError("Cannot execute data command. Not connected to DB!"); + return DataCommandUniquePtr(); + } - char *rawBuffer; + char *rawBuffer; - va_list args; - va_start(args, format); + va_list args; + va_start(args, format); - if (vasprintf(&rawBuffer, format, args) == -1) - rawBuffer = NULL; + if (vasprintf(&rawBuffer, format, args) == -1) + rawBuffer = NULL; - va_end(args); + va_end(args); - CharUniquePtr buffer(rawBuffer); + CharUniquePtr buffer(rawBuffer); - if (!buffer) { - LogError("Failed to allocate statement string"); - return DataCommandUniquePtr(); - } + if (!buffer) { + LogError("Failed to allocate statement string"); + return DataCommandUniquePtr(); + } - LogPedantic("Executing SQL data command: " << buffer.get()); + LogPedantic("Executing SQL data command: " << buffer.get()); - return DataCommandUniquePtr(new DataCommand(this, buffer.get())); + return DataCommandUniquePtr(new DataCommand(this, buffer.get())); } SqlConnection::RowID SqlConnection::GetLastInsertRowID() const { - return static_cast<RowID>(sqlcipher3_last_insert_rowid(m_connection)); + return static_cast<RowID>(sqlcipher3_last_insert_rowid(m_connection)); } void SqlConnection::TurnOnForeignKeys() { - ExecCommand("PRAGMA foreign_keys = ON;"); + ExecCommand("PRAGMA foreign_keys = ON;"); } void SqlConnection::BeginTransaction() { - ExecCommand("BEGIN;"); + ExecCommand("BEGIN;"); } void SqlConnection::RollbackTransaction() { - ExecCommand("ROLLBACK;"); + ExecCommand("ROLLBACK;"); } void SqlConnection::CommitTransaction() { - ExecCommand("COMMIT;"); + ExecCommand("COMMIT;"); } SqlConnection::SynchronizationObject * SqlConnection::AllocDefaultSynchronizationObject() { - return new NaiveSynchronizationObject(); + return new NaiveSynchronizationObject(); } } // namespace DB } // namespace CKM diff --git a/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h b/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h index dd40fb33..7ba1c875 100644 --- a/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h +++ b/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h @@ -25,28 +25,28 @@ namespace CKM { namespace Log { class AbstractLogProvider { - public: - enum class LogLevel { - None, - Error, - Warning, - Info, - Debug, - Pedantic - }; +public: + enum class LogLevel { + None, + Error, + Warning, + Info, + Debug, + Pedantic + }; - virtual ~AbstractLogProvider() {} + virtual ~AbstractLogProvider() {} - virtual void SetTag(const char *tag); + virtual void SetTag(const char *tag); - virtual void Log(LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const = 0; + virtual void Log(LogLevel level, + const char *message, + const char *fileName, + int line, + const char *function) const = 0; - protected: - static const char *LocateSourceFileName(const char *filename); +protected: + static const char *LocateSourceFileName(const char *filename); }; } } // namespace CKM diff --git a/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h b/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h index 77ad4ae9..75685eff 100644 --- a/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h +++ b/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h @@ -28,21 +28,21 @@ namespace CKM { namespace Log { class DLOGLogProvider : public AbstractLogProvider { - public: - DLOGLogProvider(); - virtual ~DLOGLogProvider(); +public: + DLOGLogProvider(); + virtual ~DLOGLogProvider(); - virtual void Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const; + virtual void Log(AbstractLogProvider::LogLevel level, + const char *message, + const char *fileName, + int line, + const char *function) const; - // Set global Tag according to DLOG - void SetTag(const char *tag); + // Set global Tag according to DLOG + void SetTag(const char *tag); - private: - std::unique_ptr<char[]> m_tag; +private: + std::unique_ptr<char[]> m_tag; }; } // namespace Log diff --git a/src/manager/dpl/log/include/dpl/log/journal_log_provider.h b/src/manager/dpl/log/include/dpl/log/journal_log_provider.h index 3d9455c4..9600233c 100644 --- a/src/manager/dpl/log/include/dpl/log/journal_log_provider.h +++ b/src/manager/dpl/log/include/dpl/log/journal_log_provider.h @@ -28,14 +28,14 @@ namespace Log { class JournalLogProvider: public AbstractLogProvider { public: - JournalLogProvider(); - virtual ~JournalLogProvider(); + JournalLogProvider(); + virtual ~JournalLogProvider(); - virtual void Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const; + virtual void Log(AbstractLogProvider::LogLevel level, + const char *message, + const char *fileName, + int line, + const char *function) const; }; } /* namespace Log */ diff --git a/src/manager/dpl/log/include/dpl/log/log.h b/src/manager/dpl/log/include/dpl/log/log.h index aac1e7fe..c169b9e0 100644 --- a/src/manager/dpl/log/include/dpl/log/log.h +++ b/src/manager/dpl/log/include/dpl/log/log.h @@ -39,76 +39,79 @@ namespace Log { * CKM log system */ class COMMON_API LogSystem { - public: - NONCOPYABLE(LogSystem) - - LogSystem(); - virtual ~LogSystem(); - - AbstractLogProvider::LogLevel GetLogLevel() const { return m_level; } - - void Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *filename, - int line, - const char *function); - - /** - * Set default's DLOG provider Tag - */ - void SetTag(const char *tag); - - /** - * Add abstract provider to providers list - * - * @notice Ownership is transfered to LogSystem and deleted upon exit - */ - void AddProvider(AbstractLogProvider *provider); - - /** - * Remove abstract provider from providers list - */ - void RemoveProvider(AbstractLogProvider *provider); - - /** - * Selects given provider by name (overwrites environment setting) - * - * Throws std::out_of_range exception if not found. - */ - void SelectProvider(const std::string& name); - - /** - * Sets log level (overwrites environment settings) - */ - void SetLogLevel(const char* level); - - private: - void RemoveProviders(); - - typedef std::list<AbstractLogProvider *> AbstractLogProviderPtrList; - AbstractLogProviderPtrList m_providers; - AbstractLogProvider::LogLevel m_level; - - typedef AbstractLogProvider*(*ProviderFn)(); - /* - * It cannot be global as it is used in library constructor and we can't be sure which - * constructor is called first: library's or new_provider's. - */ - std::unordered_map<std::string, ProviderFn> m_providerCtor; +public: + NONCOPYABLE(LogSystem) + + LogSystem(); + virtual ~LogSystem(); + + AbstractLogProvider::LogLevel GetLogLevel() const + { + return m_level; + } + + void Log(AbstractLogProvider::LogLevel level, + const char *message, + const char *filename, + int line, + const char *function); + + /** + * Set default's DLOG provider Tag + */ + void SetTag(const char *tag); + + /** + * Add abstract provider to providers list + * + * @notice Ownership is transfered to LogSystem and deleted upon exit + */ + void AddProvider(AbstractLogProvider *provider); + + /** + * Remove abstract provider from providers list + */ + void RemoveProvider(AbstractLogProvider *provider); + + /** + * Selects given provider by name (overwrites environment setting) + * + * Throws std::out_of_range exception if not found. + */ + void SelectProvider(const std::string &name); + + /** + * Sets log level (overwrites environment settings) + */ + void SetLogLevel(const char *level); + +private: + void RemoveProviders(); + + using AbstractLogProviderPtrList = std::list<AbstractLogProvider *>; + AbstractLogProviderPtrList m_providers; + AbstractLogProvider::LogLevel m_level; + + using ProviderFn = AbstractLogProvider *(*)(); + /* + * It cannot be global as it is used in library constructor and we can't be sure which + * constructor is called first: library's or new_provider's. + */ + std::unordered_map<std::string, ProviderFn> m_providerCtor; }; /* * Replacement low overhead null logging class */ class NullStream { - public: - NullStream() {} - - template <typename T> - NullStream& operator<<(const T&) - { - return *this; - } +public: + NullStream() {} + + template <typename T> + NullStream &operator<<(const T &) + { + return *this; + } }; /** @@ -125,70 +128,70 @@ typedef Singleton<LogSystem> LogSystemSingleton; /* avoid warnings about unused variables */ #define DPL_MACRO_DUMMY_LOGGING(message, level) \ - do { \ - CKM::Log::NullStream ns; \ - ns << message; \ - } while (0) - -#define DPL_MACRO_FOR_LOGGING(message, level) \ -do { \ - if (level > CKM::Log::AbstractLogProvider::LogLevel::None && \ - CKM::Log::LogSystemSingleton::Instance().GetLogLevel() >= level) { \ - std::ostringstream platformLog; \ - platformLog << message; \ - CKM::Log::LogSystemSingleton::Instance().Log(level, \ - platformLog.str().c_str(), \ - __FILE__, \ - __LINE__, \ - __FUNCTION__); \ - } \ -} while (0) - -#define DPL_MACRO_FOR_LOGGING_POSITION(message, level, file, line, function) \ -do { \ - if (level > CKM::Log::AbstractLogProvider::LogLevel::None && \ - CKM::Log::LogSystemSingleton::Instance().GetLogLevel() >= level) { \ - std::ostringstream platformLog; \ - platformLog << message; \ - CKM::Log::LogSystemSingleton::Instance().Log(level, \ - platformLog.str().c_str(), \ - file, \ - line, \ - function); \ - } \ -} while (0) + do { \ + CKM::Log::NullStream ns; \ + ns << message; \ + } while (false) + +#define DPL_MACRO_FOR_LOGGING(message, level) \ + do { \ + if (level > CKM::Log::AbstractLogProvider::LogLevel::None && \ + CKM::Log::LogSystemSingleton::Instance().GetLogLevel() >= level) { \ + std::ostringstream platformLog; \ + platformLog << message; \ + CKM::Log::LogSystemSingleton::Instance().Log(level, \ + platformLog.str().c_str(), \ + __FILE__, \ + __LINE__, \ + __FUNCTION__); \ + } \ + } while (false) + +#define DPL_MACRO_FOR_LOGGING_POSITION(message, level, file, line, function) \ + do { \ + if (level > CKM::Log::AbstractLogProvider::LogLevel::None && \ + CKM::Log::LogSystemSingleton::Instance().GetLogLevel() >= level) { \ + std::ostringstream platformLog; \ + platformLog << message; \ + CKM::Log::LogSystemSingleton::Instance().Log(level, \ + platformLog.str().c_str(), \ + file, \ + line, \ + function); \ + } \ + } while (false) /* Errors must be always logged. */ -#define LogError(message) \ - DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Error) -#define LogErrorPosition(message, file, line, function) \ - DPL_MACRO_FOR_LOGGING_POSITION(message, CKM::Log::AbstractLogProvider::LogLevel::Error, file, line, function) +#define LogError(message) \ + DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Error) +#define LogErrorPosition(message, file, line, function) \ + DPL_MACRO_FOR_LOGGING_POSITION(message, CKM::Log::AbstractLogProvider::LogLevel::Error, file, line, function) #ifdef BUILD_TYPE_DEBUG - #define LogDebug(message) \ - DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Debug) - #define LogInfo(message) \ - DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Info) - #define LogWarning(message) \ - DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Warning) - #define LogPedantic(message) \ - DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Pedantic) - #define LogDebugPosition(message, file, line, function) \ - DPL_MACRO_FOR_LOGGING_POSITION(message, CKM::Log::AbstractLogProvider::LogLevel::Debug, file, line, function) +#define LogDebug(message) \ + DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Debug) +#define LogInfo(message) \ + DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Info) +#define LogWarning(message) \ + DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Warning) +#define LogPedantic(message) \ + DPL_MACRO_FOR_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Pedantic) +#define LogDebugPosition(message, file, line, function) \ + DPL_MACRO_FOR_LOGGING_POSITION(message, CKM::Log::AbstractLogProvider::LogLevel::Debug, file, line, function) #else - #define LogDebug(message) \ - DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Debug) - #define LogInfo(message) \ - DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Info) - #define LogWarning(message) \ - DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Warning) - #define LogPedantic(message) \ - DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Pedantic) - #define LogDebugPosition(message, file, line, function) \ - do { \ - (void) file; (void) line; (void) function; \ - DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Debug); \ - } while (0) +#define LogDebug(message) \ + DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Debug) +#define LogInfo(message) \ + DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Info) +#define LogWarning(message) \ + DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Warning) +#define LogPedantic(message) \ + DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Pedantic) +#define LogDebugPosition(message, file, line, function) \ + do { \ + (void) file; (void) line; (void) function; \ + DPL_MACRO_DUMMY_LOGGING(message, CKM::Log::AbstractLogProvider::LogLevel::Debug); \ + } while (false) #endif // BUILD_TYPE_DEBUG #endif // CENT_KEY_LOG_H diff --git a/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h b/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h index bb5b197f..d70bfa91 100644 --- a/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h +++ b/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h @@ -27,15 +27,15 @@ namespace CKM { namespace Log { class OldStyleLogProvider : public AbstractLogProvider { - public: - OldStyleLogProvider(); - virtual ~OldStyleLogProvider() {} +public: + OldStyleLogProvider(); + virtual ~OldStyleLogProvider() {} - virtual void Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const; + virtual void Log(AbstractLogProvider::LogLevel level, + const char *message, + const char *fileName, + int line, + const char *function) const; }; } } // namespace CKM diff --git a/src/manager/dpl/log/src/abstract_log_provider.cpp b/src/manager/dpl/log/src/abstract_log_provider.cpp index 094eeab4..7c3a0003 100644 --- a/src/manager/dpl/log/src/abstract_log_provider.cpp +++ b/src/manager/dpl/log/src/abstract_log_provider.cpp @@ -31,8 +31,8 @@ void AbstractLogProvider::SetTag(const char *tag CKM_UNUSED) {} const char *AbstractLogProvider::LocateSourceFileName(const char *filename) { - const char *ptr = strrchr(filename, '/'); - return ptr != NULL ? ptr + 1 : filename; + const char *ptr = strrchr(filename, '/'); + return ptr != NULL ? ptr + 1 : filename; } } } diff --git a/src/manager/dpl/log/src/dlog_log_provider.cpp b/src/manager/dpl/log/src/dlog_log_provider.cpp index 1536965d..ef8ac9f9 100644 --- a/src/manager/dpl/log/src/dlog_log_provider.cpp +++ b/src/manager/dpl/log/src/dlog_log_provider.cpp @@ -31,36 +31,36 @@ namespace CKM { namespace Log { namespace { -typedef void (*dlogMacro)(const char*, const char*); +typedef void (*dlogMacro)(const char *, const char *); // I can't map LOG_ values because SLOG uses token concatenation -void error(const char* tag, const char* msg) +void error(const char *tag, const char *msg) { - SLOG(LOG_ERROR, tag, "%s", msg); + SLOG(LOG_ERROR, tag, "%s", msg); } -void warning(const char* tag, const char* msg) +void warning(const char *tag, const char *msg) { - SLOG(LOG_WARN, tag, "%s", msg); + SLOG(LOG_WARN, tag, "%s", msg); } -void info(const char* tag, const char* msg) +void info(const char *tag, const char *msg) { - SLOG(LOG_INFO, tag, "%s", msg); + SLOG(LOG_INFO, tag, "%s", msg); } -void debug(const char* tag, const char* msg) +void debug(const char *tag, const char *msg) { - SLOG(LOG_DEBUG, tag, "%s", msg); + SLOG(LOG_DEBUG, tag, "%s", msg); } -void pedantic(const char* tag, const char* msg) +void pedantic(const char *tag, const char *msg) { - SLOG(LOG_VERBOSE, tag, "%s", msg); + SLOG(LOG_VERBOSE, tag, "%s", msg); } std::map<AbstractLogProvider::LogLevel, dlogMacro> dlogMacros = { - // [](const char* tag, const char* msg) { SLOG(LOG_ERROR, tag, "%s", msg); } won't compile - { AbstractLogProvider::LogLevel::Error, error }, - { AbstractLogProvider::LogLevel::Warning, warning }, - { AbstractLogProvider::LogLevel::Info, info }, - { AbstractLogProvider::LogLevel::Debug, debug}, - { AbstractLogProvider::LogLevel::Pedantic, pedantic} + // [](const char* tag, const char* msg) { SLOG(LOG_ERROR, tag, "%s", msg); } won't compile + { AbstractLogProvider::LogLevel::Error, error }, + { AbstractLogProvider::LogLevel::Warning, warning }, + { AbstractLogProvider::LogLevel::Info, info }, + { AbstractLogProvider::LogLevel::Debug, debug}, + { AbstractLogProvider::LogLevel::Pedantic, pedantic} }; } // namespace anonymous @@ -76,28 +76,31 @@ DLOGLogProvider::~DLOGLogProvider() void DLOGLogProvider::SetTag(const char *tag) { - size_t size = strlen(tag)+1; - char *buff = new (std::nothrow) char[size]; - if (buff) - memcpy(buff, tag, size); - m_tag.reset(buff); + size_t size = strlen(tag) + 1; + char *buff = new(std::nothrow) char[size]; + + if (buff) + memcpy(buff, tag, size); + + m_tag.reset(buff); } void DLOGLogProvider::Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const + const char *message, + const char *fileName, + int line, + const char *function) const { - std::ostringstream val; - val << std::string("[") << LocateSourceFileName(fileName) << std::string(":") << line << - std::string("] ") << function << std::string("(): ") << message; + std::ostringstream val; + val << std::string("[") << LocateSourceFileName(fileName) << std::string(":") << + line << + std::string("] ") << function << std::string("(): ") << message; - try { - dlogMacros.at(level)(m_tag.get(), val.str().c_str()); - } catch (const std::out_of_range&) { - SLOG(LOG_ERROR, m_tag.get(), "Unsupported log level: %d", level); - } + try { + dlogMacros.at(level)(m_tag.get(), val.str().c_str()); + } catch (const std::out_of_range &) { + SLOG(LOG_ERROR, m_tag.get(), "Unsupported log level: %d", level); + } } } // nemespace Log diff --git a/src/manager/dpl/log/src/journal_log_provider.cpp b/src/manager/dpl/log/src/journal_log_provider.cpp index 2453cdc2..cfe84836 100644 --- a/src/manager/dpl/log/src/journal_log_provider.cpp +++ b/src/manager/dpl/log/src/journal_log_provider.cpp @@ -29,11 +29,11 @@ namespace Log { namespace { std::map<AbstractLogProvider::LogLevel, int> journalLevel = { - { AbstractLogProvider::LogLevel::Error, LOG_ERR }, - { AbstractLogProvider::LogLevel::Warning, LOG_WARNING }, - { AbstractLogProvider::LogLevel::Info, LOG_INFO }, - { AbstractLogProvider::LogLevel::Debug, LOG_DEBUG}, - { AbstractLogProvider::LogLevel::Pedantic, LOG_DEBUG} + { AbstractLogProvider::LogLevel::Error, LOG_ERR }, + { AbstractLogProvider::LogLevel::Warning, LOG_WARNING }, + { AbstractLogProvider::LogLevel::Info, LOG_INFO }, + { AbstractLogProvider::LogLevel::Debug, LOG_DEBUG}, + { AbstractLogProvider::LogLevel::Pedantic, LOG_DEBUG} }; } // namespace anonymous @@ -47,29 +47,30 @@ JournalLogProvider::~JournalLogProvider() } void JournalLogProvider::Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const + const char *message, + const char *fileName, + int line, + const char *function) const { - try { - sd_journal_send("PRIORITY=%d", journalLevel.at(level), - "CODE_FILE=%s", fileName, - "CODE_FUNC=%s", function, - "CODE_LINE=%d", line, - // add file, line & function info to log message - "MESSAGE=[%s:%d] %s(): %s", fileName, line, function, message, - NULL); - } catch (const std::out_of_range&) { - sd_journal_send( - "PRIORITY=%d", LOG_ERR, - "CODE_FILE=%s", fileName, - "CODE_FUNC=%s", function, - "CODE_LINE=%d", line, - // add file, line & function info to log message - "MESSAGE=[%s:%d] %s(): Unsupported log level %d", fileName, line, function, level, - NULL); - } + try { + sd_journal_send("PRIORITY=%d", journalLevel.at(level), + "CODE_FILE=%s", fileName, + "CODE_FUNC=%s", function, + "CODE_LINE=%d", line, + // add file, line & function info to log message + "MESSAGE=[%s:%d] %s(): %s", fileName, line, function, message, + NULL); + } catch (const std::out_of_range &) { + sd_journal_send( + "PRIORITY=%d", LOG_ERR, + "CODE_FILE=%s", fileName, + "CODE_FUNC=%s", function, + "CODE_LINE=%d", line, + // add file, line & function info to log message + "MESSAGE=[%s:%d] %s(): Unsupported log level %d", fileName, line, function, + level, + NULL); + } } } /* namespace Log */ diff --git a/src/manager/dpl/log/src/log.cpp b/src/manager/dpl/log/src/log.cpp index 9d246754..37baa3a0 100644 --- a/src/manager/dpl/log/src/log.cpp +++ b/src/manager/dpl/log/src/log.cpp @@ -45,100 +45,105 @@ namespace { // anonymous * CKM_LOG_LEVEL=3 * CKM_LOG_PROVIDER=JOURNALD */ -const char * const CKM_LOG_LEVEL = "CKM_LOG_LEVEL"; -const char * const CKM_LOG_PROVIDER = "CKM_LOG_PROVIDER"; +const char *const CKM_LOG_LEVEL = "CKM_LOG_LEVEL"; +const char *const CKM_LOG_PROVIDER = "CKM_LOG_PROVIDER"; -const char * const CONSOLE = "CONSOLE"; -const char * const DLOG = "DLOG"; -const char * const JOURNALD = "JOURNALD"; +const char *const CONSOLE = "CONSOLE"; +const char *const DLOG = "DLOG"; +const char *const JOURNALD = "JOURNALD"; } // namespace anonymous LogSystem::LogSystem() : - m_providerCtor({ + m_providerCtor( +{ #ifdef BUILD_TYPE_DEBUG - { CONSOLE, []{ return static_cast<AbstractLogProvider*>(new OldStyleLogProvider()); } }, + { CONSOLE, []{ return static_cast<AbstractLogProvider *>(new OldStyleLogProvider()); } }, #endif // BUILD_TYPE_DEBUG - { DLOG, []{ return static_cast<AbstractLogProvider*>(new DLOGLogProvider()); } }, - { JOURNALD, []{ return static_cast<AbstractLogProvider*>(new JournalLogProvider()); } } - }) + { DLOG, []{ return static_cast<AbstractLogProvider *>(new DLOGLogProvider()); } }, + { JOURNALD, []{ return static_cast<AbstractLogProvider *>(new JournalLogProvider()); } } +}) { - SetLogLevel(getenv(CKM_LOG_LEVEL)); - - AbstractLogProvider* prv = NULL; - try { - prv = m_providerCtor.at(getenv(CKM_LOG_PROVIDER))(); - } catch(const std::exception&) { - prv = m_providerCtor[DLOG](); - } - AddProvider(prv); + SetLogLevel(getenv(CKM_LOG_LEVEL)); + + AbstractLogProvider *prv = NULL; + + try { + prv = m_providerCtor.at(getenv(CKM_LOG_PROVIDER))(); + } catch (const std::exception &) { + prv = m_providerCtor[DLOG](); + } + + AddProvider(prv); } LogSystem::~LogSystem() { - RemoveProviders(); + RemoveProviders(); } -void LogSystem::SetTag(const char* tag) +void LogSystem::SetTag(const char *tag) { - for (auto it : m_providers) - it->SetTag(tag); + for (auto it : m_providers) + it->SetTag(tag); } void LogSystem::AddProvider(AbstractLogProvider *provider) { - m_providers.push_back(provider); + m_providers.push_back(provider); } void LogSystem::RemoveProvider(AbstractLogProvider *provider) { - m_providers.remove(provider); + m_providers.remove(provider); } -void LogSystem::SelectProvider(const std::string& name) +void LogSystem::SelectProvider(const std::string &name) { - // let it throw - ProviderFn& prv = m_providerCtor.at(name); + // let it throw + ProviderFn &prv = m_providerCtor.at(name); - RemoveProviders(); - AddProvider(prv()); + RemoveProviders(); + AddProvider(prv()); } -void LogSystem::SetLogLevel(const char* level) +void LogSystem::SetLogLevel(const char *level) { - try { - m_level = static_cast<AbstractLogProvider::LogLevel>(std::stoi(level)); - } catch(const std::exception&) { - m_level = AbstractLogProvider::LogLevel::Debug; - } + try { + m_level = static_cast<AbstractLogProvider::LogLevel>(std::stoi(level)); + } catch (const std::exception &) { + m_level = AbstractLogProvider::LogLevel::Debug; + } - if (m_level < AbstractLogProvider::LogLevel::None) - m_level = AbstractLogProvider::LogLevel::None; - else if (m_level > AbstractLogProvider::LogLevel::Pedantic) - m_level = AbstractLogProvider::LogLevel::Pedantic; + if (m_level < AbstractLogProvider::LogLevel::None) + m_level = AbstractLogProvider::LogLevel::None; + else if (m_level > AbstractLogProvider::LogLevel::Pedantic) + m_level = AbstractLogProvider::LogLevel::Pedantic; #ifndef BUILD_TYPE_DEBUG - if (m_level > AbstractLogProvider::LogLevel::Error) - m_level = AbstractLogProvider::LogLevel::Error; + + if (m_level > AbstractLogProvider::LogLevel::Error) + m_level = AbstractLogProvider::LogLevel::Error; + #endif // BUILD_TYPE_DEBUG } void LogSystem::Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *filename, - int line, - const char *function) + const char *message, + const char *filename, + int line, + const char *function) { - for (const auto& it : m_providers ) - it->Log(level, message, filename, line, function); + for (const auto &it : m_providers) + it->Log(level, message, filename, line, function); } void LogSystem::RemoveProviders() { - // Delete all providers - for (auto it : m_providers) - delete it; + // Delete all providers + for (auto it : m_providers) + delete it; - m_providers.clear(); + m_providers.clear(); } } // namespace Log diff --git a/src/manager/dpl/log/src/old_style_log_provider.cpp b/src/manager/dpl/log/src/old_style_log_provider.cpp index c62dac4a..dabf0b5e 100644 --- a/src/manager/dpl/log/src/old_style_log_provider.cpp +++ b/src/manager/dpl/log/src/old_style_log_provider.cpp @@ -49,34 +49,34 @@ const char *PEDANTIC_END = PURPLE_END; std::string GetFormattedTime() { - timeval tv; - tm localNowTime; + timeval tv; + tm localNowTime; - gettimeofday(&tv, NULL); - localtime_r(&tv.tv_sec, &localNowTime); + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &localNowTime); - char format[64]; - snprintf(format, - sizeof(format), - "%02i:%02i:%02i.%03i", - localNowTime.tm_hour, - localNowTime.tm_min, - localNowTime.tm_sec, - static_cast<int>(tv.tv_usec / 1000)); - return format; + char format[64]; + snprintf(format, + sizeof(format), + "%02i:%02i:%02i.%03i", + localNowTime.tm_hour, + localNowTime.tm_min, + localNowTime.tm_sec, + static_cast<int>(tv.tv_usec / 1000)); + return format; } struct ColorMark { - const char* const begin; - const char* const end; + const char *const begin; + const char *const end; }; std::map<AbstractLogProvider::LogLevel, ColorMark> consoleLevel = { - { AbstractLogProvider::LogLevel::Error, {ERROR_BEGIN, ERROR_END} }, - { AbstractLogProvider::LogLevel::Warning, {WARNING_BEGIN, WARNING_END} }, - { AbstractLogProvider::LogLevel::Info, {INFO_BEGIN, INFO_END} }, - { AbstractLogProvider::LogLevel::Debug, {DEBUG_BEGIN, DEBUG_END} }, - { AbstractLogProvider::LogLevel::Pedantic, {PEDANTIC_BEGIN, PEDANTIC_END} } + { AbstractLogProvider::LogLevel::Error, {ERROR_BEGIN, ERROR_END} }, + { AbstractLogProvider::LogLevel::Warning, {WARNING_BEGIN, WARNING_END} }, + { AbstractLogProvider::LogLevel::Info, {INFO_BEGIN, INFO_END} }, + { AbstractLogProvider::LogLevel::Debug, {DEBUG_BEGIN, DEBUG_END} }, + { AbstractLogProvider::LogLevel::Pedantic, {PEDANTIC_BEGIN, PEDANTIC_END} } }; } // namespace anonymous @@ -86,23 +86,26 @@ OldStyleLogProvider::OldStyleLogProvider() } void OldStyleLogProvider::Log(AbstractLogProvider::LogLevel level, - const char *message, - const char *fileName, - int line, - const char *function) const + const char *message, + const char *fileName, + int line, + const char *function) const { - try { - const struct ColorMark& mark = consoleLevel.at(level); + try { + const struct ColorMark &mark = consoleLevel.at(level); - std::ostringstream val; - val << mark.begin << std::string("[") << GetFormattedTime() << std::string("] [") << - static_cast<unsigned long>(pthread_self()) << "/" << static_cast<int>(getpid()) << - std::string("] [") << LocateSourceFileName(fileName) << std::string(":") << line << - std::string("] ") << function << std::string("(): ") << message << mark.end; - fprintf(stdout, "%s\n", val.str().c_str()); - } catch (const std::out_of_range&) { - fprintf(stdout, "Unsupported log level: %d\n", level); - } + std::ostringstream val; + val << mark.begin << std::string("[") << GetFormattedTime() << + std::string("] [") << + static_cast<unsigned long>(pthread_self()) << "/" << static_cast<int> + (getpid()) << + std::string("] [") << LocateSourceFileName(fileName) << std::string(":") << line + << + std::string("] ") << function << std::string("(): ") << message << mark.end; + fprintf(stdout, "%s\n", val.str().c_str()); + } catch (const std::out_of_range &) { + fprintf(stdout, "Unsupported log level: %d\n", level); + } } } diff --git a/src/manager/initial-values/BufferHandler.cpp b/src/manager/initial-values/BufferHandler.cpp index 38a7be35..cca06b20 100644 --- a/src/manager/initial-values/BufferHandler.cpp +++ b/src/manager/initial-values/BufferHandler.cpp @@ -28,7 +28,7 @@ #include <base64.h> namespace { -const char * const XML_ATTR_IV = "IV"; +const char *const XML_ATTR_IV = "IV"; } namespace CKM { @@ -39,53 +39,53 @@ BufferHandler::~BufferHandler() {} void BufferHandler::Start(const XML::Parser::Attributes &attr) { - // get key type - if (attr.find(XML_ATTR_IV) != attr.end()) { - std::string IVstring = attr.at(XML_ATTR_IV); - Base64Decoder base64; - base64.reset(); - base64.append(RawBuffer(IVstring.begin(), IVstring.end())); - base64.finalize(); - m_IV = base64.get(); - } + // get key type + if (attr.find(XML_ATTR_IV) != attr.end()) { + std::string IVstring = attr.at(XML_ATTR_IV); + Base64Decoder base64; + base64.reset(); + base64.append(RawBuffer(IVstring.begin(), IVstring.end())); + base64.finalize(); + m_IV = base64.get(); + } } -void BufferHandler::Characters(const std::string & data) +void BufferHandler::Characters(const std::string &data) { - m_data.reserve(m_data.size() + data.size()); - m_data.insert(m_data.end(), data.begin(), data.end()); + m_data.reserve(m_data.size() + data.size()); + m_data.insert(m_data.end(), data.begin(), data.end()); } void BufferHandler::End() { - // decoding section - switch (m_encoding) { - // PEM requires that "----- END" section comes right after "\n" character - case PEM: - { - std::string trimmed = XML::trimEachLine(std::string(m_data.begin(), m_data.end())); - m_data = RawBuffer(trimmed.begin(), trimmed.end()); - break; - } + // decoding section + switch (m_encoding) { + // PEM requires that "----- END" section comes right after "\n" character + case PEM: { + std::string trimmed = XML::trimEachLine(std::string(m_data.begin(), + m_data.end())); + m_data = RawBuffer(trimmed.begin(), trimmed.end()); + break; + } - // Base64 decoder also does not accept any whitespaces - case DER: - case BASE64: - case ENCRYPTED: - { - std::string trimmed = XML::trimEachLine(std::string(m_data.begin(), m_data.end())); - Base64Decoder base64; - base64.reset(); - base64.append(RawBuffer(trimmed.begin(), trimmed.end())); - base64.finalize(); - m_data = base64.get(); - break; - } + // Base64 decoder also does not accept any whitespaces + case DER: + case BASE64: + case ENCRYPTED: { + std::string trimmed = XML::trimEachLine(std::string(m_data.begin(), + m_data.end())); + Base64Decoder base64; + base64.reset(); + base64.append(RawBuffer(trimmed.begin(), trimmed.end())); + base64.finalize(); + m_data = base64.get(); + break; + } - default: - break; - } + default: + break; + } } } diff --git a/src/manager/initial-values/BufferHandler.h b/src/manager/initial-values/BufferHandler.h index 2a44f450..572244db 100644 --- a/src/manager/initial-values/BufferHandler.h +++ b/src/manager/initial-values/BufferHandler.h @@ -33,34 +33,37 @@ namespace InitialValues { class BufferHandler : public XML::Parser::ElementHandler { public: - typedef std::shared_ptr<BufferHandler> BufferHandlerPtr; + typedef std::shared_ptr<BufferHandler> BufferHandlerPtr; - BufferHandler(EncodingType type); - virtual ~BufferHandler(); + BufferHandler(EncodingType type); + virtual ~BufferHandler(); - virtual void Start(const XML::Parser::Attributes &); - virtual void Characters(const std::string & data); - virtual void End(); + virtual void Start(const XML::Parser::Attributes &); + virtual void Characters(const std::string &data); + virtual void End(); - const RawBuffer & getData() const - { - return m_data; - } - bool isEncrypted() const - { - if (m_encoding == EncodingType::ENCRYPTED) - return true; - return false; - } - const RawBuffer & getIV() const - { - return m_IV; - } + const RawBuffer &getData() const + { + return m_data; + } + + bool isEncrypted() const + { + if (m_encoding == EncodingType::ENCRYPTED) + return true; + + return false; + } + + const RawBuffer &getIV() const + { + return m_IV; + } private: - EncodingType m_encoding; - RawBuffer m_IV; - RawBuffer m_data; + EncodingType m_encoding; + RawBuffer m_IV; + RawBuffer m_data; }; } diff --git a/src/manager/initial-values/CertHandler.cpp b/src/manager/initial-values/CertHandler.cpp index e7d37125..61e7ce97 100644 --- a/src/manager/initial-values/CertHandler.cpp +++ b/src/manager/initial-values/CertHandler.cpp @@ -31,7 +31,7 @@ CertHandler::~CertHandler() {} DataType CertHandler::getDataType() const { - return DataType::CERTIFICATE; + return DataType::CERTIFICATE; } } diff --git a/src/manager/initial-values/CertHandler.h b/src/manager/initial-values/CertHandler.h index 8e246d20..6729c613 100644 --- a/src/manager/initial-values/CertHandler.h +++ b/src/manager/initial-values/CertHandler.h @@ -31,11 +31,11 @@ namespace InitialValues { class CertHandler : public InitialValueHandler { public: - explicit CertHandler(CKMLogic & db_logic, const CKM::RawBuffer &encryptedKey) - : InitialValueHandler(db_logic, encryptedKey) {} - virtual ~CertHandler(); + explicit CertHandler(CKMLogic &db_logic, const CKM::RawBuffer &encryptedKey) + : InitialValueHandler(db_logic, encryptedKey) {} + virtual ~CertHandler(); - virtual DataType getDataType() const; + virtual DataType getDataType() const; }; } diff --git a/src/manager/initial-values/DataHandler.cpp b/src/manager/initial-values/DataHandler.cpp index b4d5945d..487750fe 100644 --- a/src/manager/initial-values/DataHandler.cpp +++ b/src/manager/initial-values/DataHandler.cpp @@ -31,7 +31,7 @@ DataHandler::~DataHandler() {} DataType DataHandler::getDataType() const { - return DataType::BINARY_DATA; + return DataType::BINARY_DATA; } } diff --git a/src/manager/initial-values/DataHandler.h b/src/manager/initial-values/DataHandler.h index bab8316f..6970496f 100644 --- a/src/manager/initial-values/DataHandler.h +++ b/src/manager/initial-values/DataHandler.h @@ -31,11 +31,11 @@ namespace InitialValues { class DataHandler : public InitialValueHandler { public: - explicit DataHandler(CKMLogic & db_logic, const CKM::RawBuffer &encryptedKey) : - InitialValueHandler(db_logic, encryptedKey) {} - virtual ~DataHandler(); + explicit DataHandler(CKMLogic &db_logic, const CKM::RawBuffer &encryptedKey) : + InitialValueHandler(db_logic, encryptedKey) {} + virtual ~DataHandler(); - virtual DataType getDataType() const; + virtual DataType getDataType() const; }; } diff --git a/src/manager/initial-values/EncodingType.h b/src/manager/initial-values/EncodingType.h index d40e2dd2..2868831f 100644 --- a/src/manager/initial-values/EncodingType.h +++ b/src/manager/initial-values/EncodingType.h @@ -27,12 +27,12 @@ namespace CKM { namespace InitialValues { enum EncodingType { - PEM, - DER, - ASCII, - BASE64, - // encrypted - ENCRYPTED + PEM, + DER, + ASCII, + BASE64, + // encrypted + ENCRYPTED }; } diff --git a/src/manager/initial-values/InitialValueHandler.cpp b/src/manager/initial-values/InitialValueHandler.cpp index d4d01bdb..c4bcd929 100644 --- a/src/manager/initial-values/InitialValueHandler.cpp +++ b/src/manager/initial-values/InitialValueHandler.cpp @@ -29,9 +29,9 @@ #include <ckm/ckm-type.h> namespace { -const char * const XML_ATTR_NAME = "name"; -const char * const XML_ATTR_PASSWORD = "password"; -const char * const XML_ATTR_EXPORTABLE = "exportable"; +const char *const XML_ATTR_NAME = "name"; +const char *const XML_ATTR_PASSWORD = "password"; +const char *const XML_ATTR_EXPORTABLE = "exportable"; } namespace CKM { @@ -39,76 +39,82 @@ namespace InitialValues { void InitialValueHandler::Start(const XML::Parser::Attributes &attr) { - // get name - if (attr.find(XML_ATTR_NAME) != attr.end()) - m_name = Alias(attr.at(XML_ATTR_NAME)); - - // get password - if (attr.find(XML_ATTR_PASSWORD) != attr.end()) - m_password = Password(attr.at(XML_ATTR_PASSWORD).c_str()); - - // get exportable - if (attr.find(XML_ATTR_EXPORTABLE) != attr.end()) { - std::string flagVal = attr.at(XML_ATTR_EXPORTABLE); - std::transform(flagVal.begin(), flagVal.end(), flagVal.begin(), ::tolower); - std::istringstream is(flagVal); - is >> std::boolalpha >> m_exportable; - } + // get name + if (attr.find(XML_ATTR_NAME) != attr.end()) + m_name = Alias(attr.at(XML_ATTR_NAME)); + + // get password + if (attr.find(XML_ATTR_PASSWORD) != attr.end()) + m_password = Password(attr.at(XML_ATTR_PASSWORD).c_str()); + + // get exportable + if (attr.find(XML_ATTR_EXPORTABLE) != attr.end()) { + std::string flagVal = attr.at(XML_ATTR_EXPORTABLE); + std::transform(flagVal.begin(), flagVal.end(), flagVal.begin(), ::tolower); + std::istringstream is(flagVal); + is >> std::boolalpha >> m_exportable; + } } void InitialValueHandler::End() { - if (!m_bufferHandler) { - LogError("Invalid data with name: " << m_name << ", reason: no key data!"); - return; - } - // save data - Policy policy(m_password, m_exportable); - - Crypto::DataEncryption de; - if (m_bufferHandler->isEncrypted()) { - de.encryptedKey = m_encryptedKey; - de.iv = m_bufferHandler->getIV(); - } - - int ec = m_db_logic.importInitialData(m_name, - Crypto::Data(getDataType(), m_bufferHandler->getData()), - de, - policy); - - if (CKM_API_SUCCESS != ec) { - LogError("Saving type: " << getDataType() << " with params: name(" << - m_name << "), exportable(" << m_exportable<< ") failed, code: " << ec); - return; - } - - // save permissions - for (const auto & permission : m_permissions) { - ec = m_db_logic.setPermissionHelper( - Credentials(CKMLogic::SYSTEM_DB_UID, OWNER_ID_SYSTEM), - m_name, - OWNER_ID_SYSTEM, - permission->getAccessor(), - Permission::READ); - if (CKM_API_SUCCESS != ec) { - LogError("Saving permission to: " << m_name << - " with params: accessor(" << permission->getAccessor() << - ") failed, code: " << ec); - } - } + if (!m_bufferHandler) { + LogError("Invalid data with name: " << m_name << ", reason: no key data!"); + return; + } + + // save data + Policy policy(m_password, m_exportable); + + Crypto::DataEncryption de; + + if (m_bufferHandler->isEncrypted()) { + de.encryptedKey = m_encryptedKey; + de.iv = m_bufferHandler->getIV(); + } + + int ec = m_db_logic.importInitialData(m_name, + Crypto::Data(getDataType(), m_bufferHandler->getData()), + de, + policy); + + if (CKM_API_SUCCESS != ec) { + LogError("Saving type: " << getDataType() << " with params: name(" << + m_name << "), exportable(" << m_exportable << ") failed, code: " << ec); + return; + } + + // save permissions + for (const auto &permission : m_permissions) { + ec = m_db_logic.setPermissionHelper( + Credentials(CKMLogic::SYSTEM_DB_UID, OWNER_ID_SYSTEM), + m_name, + OWNER_ID_SYSTEM, + permission->getAccessor(), + Permission::READ); + + if (CKM_API_SUCCESS != ec) { + LogError("Saving permission to: " << m_name << + " with params: accessor(" << permission->getAccessor() << + ") failed, code: " << ec); + } + } } -BufferHandler::BufferHandlerPtr InitialValueHandler::CreateBufferHandler(EncodingType type) +BufferHandler::BufferHandlerPtr InitialValueHandler::CreateBufferHandler( + EncodingType type) { - m_bufferHandler = std::make_shared<BufferHandler>(type); - return m_bufferHandler; + m_bufferHandler = std::make_shared<BufferHandler>(type); + return m_bufferHandler; } -PermissionHandler::PermissionHandlerPtr InitialValueHandler::CreatePermissionHandler() +PermissionHandler::PermissionHandlerPtr +InitialValueHandler::CreatePermissionHandler() { - PermissionHandler::PermissionHandlerPtr newPermission = std::make_shared<PermissionHandler>(); - m_permissions.push_back(newPermission); - return newPermission; + PermissionHandler::PermissionHandlerPtr newPermission = + std::make_shared<PermissionHandler>(); + m_permissions.push_back(newPermission); + return newPermission; } } diff --git a/src/manager/initial-values/InitialValueHandler.h b/src/manager/initial-values/InitialValueHandler.h index 29043d46..5a73ee92 100644 --- a/src/manager/initial-values/InitialValueHandler.h +++ b/src/manager/initial-values/InitialValueHandler.h @@ -37,28 +37,29 @@ namespace InitialValues { class InitialValueHandler : public NoCharactersHandler { public: - typedef std::shared_ptr<InitialValueHandler> InitialValueHandlerPtr; + typedef std::shared_ptr<InitialValueHandler> InitialValueHandlerPtr; - explicit InitialValueHandler(CKMLogic & db_logic, const CKM::RawBuffer &encryptedKey) - : m_exportable(false), m_db_logic(db_logic), m_encryptedKey(encryptedKey) {} - virtual ~InitialValueHandler() {} + explicit InitialValueHandler(CKMLogic &db_logic, + const CKM::RawBuffer &encryptedKey) + : m_exportable(false), m_db_logic(db_logic), m_encryptedKey(encryptedKey) {} + virtual ~InitialValueHandler() {} - BufferHandler::BufferHandlerPtr CreateBufferHandler(EncodingType type); - PermissionHandler::PermissionHandlerPtr CreatePermissionHandler(); - virtual void Start(const XML::Parser::Attributes &); - virtual void End(); + BufferHandler::BufferHandlerPtr CreateBufferHandler(EncodingType type); + PermissionHandler::PermissionHandlerPtr CreatePermissionHandler(); + virtual void Start(const XML::Parser::Attributes &); + virtual void End(); protected: - virtual DataType getDataType() const = 0; + virtual DataType getDataType() const = 0; - Alias m_name; - Password m_password; - bool m_exportable; - CKMLogic & m_db_logic; - const CKM::RawBuffer & m_encryptedKey; + Alias m_name; + Password m_password; + bool m_exportable; + CKMLogic &m_db_logic; + const CKM::RawBuffer &m_encryptedKey; - BufferHandler::BufferHandlerPtr m_bufferHandler; - std::vector<PermissionHandler::PermissionHandlerPtr> m_permissions; + BufferHandler::BufferHandlerPtr m_bufferHandler; + std::vector<PermissionHandler::PermissionHandlerPtr> m_permissions; }; } diff --git a/src/manager/initial-values/InitialValuesFile.cpp b/src/manager/initial-values/InitialValuesFile.cpp index d13e8218..854567e5 100644 --- a/src/manager/initial-values/InitialValuesFile.cpp +++ b/src/manager/initial-values/InitialValuesFile.cpp @@ -34,222 +34,203 @@ namespace { const int XML_CURRENT_VERSION = 1; -const char * const XML_TAG_INITIAL_VALUES = "InitialValues"; -const char * const XML_TAG_ENCRYPTION_KEY = "EncryptionKey"; -const char * const XML_TAG_KEY = "Key"; -const char * const XML_TAG_DATA = "Data"; -const char * const XML_TAG_CERT = "Cert"; -const char * const XML_TAG_PEM = "PEM"; -const char * const XML_TAG_DER = "DER"; -const char * const XML_TAG_ASCII = "ASCII"; -const char * const XML_TAG_BASE64 = "Base64"; -const char * const XML_TAG_ENCRYPTED_DER = "EncryptedDER"; -const char * const XML_TAG_ENCRYPTED_ASCII = "EncryptedASCII"; -const char * const XML_TAG_ENCRYPTED_BINARY = "EncryptedBinary"; -const char * const XML_TAG_PERMISSION = "Permission"; -const char * const XML_ATTR_VERSION = "version"; +const char *const XML_TAG_INITIAL_VALUES = "InitialValues"; +const char *const XML_TAG_ENCRYPTION_KEY = "EncryptionKey"; +const char *const XML_TAG_KEY = "Key"; +const char *const XML_TAG_DATA = "Data"; +const char *const XML_TAG_CERT = "Cert"; +const char *const XML_TAG_PEM = "PEM"; +const char *const XML_TAG_DER = "DER"; +const char *const XML_TAG_ASCII = "ASCII"; +const char *const XML_TAG_BASE64 = "Base64"; +const char *const XML_TAG_ENCRYPTED_DER = "EncryptedDER"; +const char *const XML_TAG_ENCRYPTED_ASCII = "EncryptedASCII"; +const char *const XML_TAG_ENCRYPTED_BINARY = "EncryptedBinary"; +const char *const XML_TAG_PERMISSION = "Permission"; +const char *const XML_ATTR_VERSION = "version"; } namespace CKM { namespace InitialValues { InitialValuesFile::InitialValuesFile(const std::string &XML_filename, - CKMLogic & db_logic) - : m_parser(XML_filename), m_db_logic(db_logic), - m_header(std::make_shared<HeaderHandler>(*this)), - m_encryptionKeyHandler(std::make_shared<EncryptionKeyHandler>(*this)) + CKMLogic &db_logic) + : m_parser(XML_filename), m_db_logic(db_logic), + m_header(std::make_shared<HeaderHandler>(*this)), + m_encryptionKeyHandler(std::make_shared<EncryptionKeyHandler>(*this)) { - m_parser.RegisterErrorCb(InitialValuesFile::Error); - m_parser.RegisterElementCb(XML_TAG_INITIAL_VALUES, - [this]() -> XML::Parser::ElementHandlerPtr - { - return m_header; - }, - [this](const XML::Parser::ElementHandlerPtr &) {}); - m_parser.RegisterElementCb(XML_TAG_ENCRYPTION_KEY, - [this]() -> XML::Parser::ElementHandlerPtr - { - return m_encryptionKeyHandler; - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - m_encryptedAESkey = m_encryptionKeyHandler->getEncryptedKey(); - }); + m_parser.RegisterErrorCb(InitialValuesFile::Error); + m_parser.RegisterElementCb(XML_TAG_INITIAL_VALUES, + [this]() -> XML::Parser::ElementHandlerPtr { + return m_header; + }, + [this](const XML::Parser::ElementHandlerPtr &) {}); + m_parser.RegisterElementCb(XML_TAG_ENCRYPTION_KEY, + [this]() -> XML::Parser::ElementHandlerPtr { + return m_encryptionKeyHandler; + }, + [this](const XML::Parser::ElementHandlerPtr &) { + m_encryptedAESkey = m_encryptionKeyHandler->getEncryptedKey(); + }); } void InitialValuesFile::registerElementListeners() { - m_parser.RegisterElementCb(XML_TAG_KEY, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetObjectHandler(ObjectType::KEY, m_encryptedAESkey); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseObjectHandler(ObjectType::KEY); - }); - m_parser.RegisterElementCb(XML_TAG_CERT, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetObjectHandler(ObjectType::CERT, m_encryptedAESkey); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseObjectHandler(ObjectType::CERT); - }); - m_parser.RegisterElementCb(XML_TAG_DATA, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetObjectHandler(ObjectType::DATA, m_encryptedAESkey); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseObjectHandler(ObjectType::DATA); - }); - - m_parser.RegisterElementCb(XML_TAG_PEM, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::PEM); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::PEM); - }); - m_parser.RegisterElementCb(XML_TAG_DER, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::DER); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::DER); - }); - m_parser.RegisterElementCb(XML_TAG_ASCII, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::ASCII); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::ASCII); - }); - m_parser.RegisterElementCb(XML_TAG_BASE64, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::BASE64); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::BASE64); - }); - m_parser.RegisterElementCb(XML_TAG_ENCRYPTED_DER, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::ENCRYPTED); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::ENCRYPTED); - }); - m_parser.RegisterElementCb(XML_TAG_ENCRYPTED_ASCII, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::ENCRYPTED); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::ENCRYPTED); - }); - m_parser.RegisterElementCb(XML_TAG_ENCRYPTED_BINARY, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetBufferHandler(EncodingType::ENCRYPTED); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleaseBufferHandler(EncodingType::ENCRYPTED); - }); - m_parser.RegisterElementCb(XML_TAG_PERMISSION, - [this]() -> XML::Parser::ElementHandlerPtr - { - return GetPermissionHandler(); - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - ReleasePermissionHandler(); - }); + m_parser.RegisterElementCb(XML_TAG_KEY, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetObjectHandler(ObjectType::KEY, m_encryptedAESkey); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseObjectHandler(ObjectType::KEY); + }); + m_parser.RegisterElementCb(XML_TAG_CERT, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetObjectHandler(ObjectType::CERT, m_encryptedAESkey); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseObjectHandler(ObjectType::CERT); + }); + m_parser.RegisterElementCb(XML_TAG_DATA, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetObjectHandler(ObjectType::DATA, m_encryptedAESkey); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseObjectHandler(ObjectType::DATA); + }); + + m_parser.RegisterElementCb(XML_TAG_PEM, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::PEM); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::PEM); + }); + m_parser.RegisterElementCb(XML_TAG_DER, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::DER); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::DER); + }); + m_parser.RegisterElementCb(XML_TAG_ASCII, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::ASCII); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::ASCII); + }); + m_parser.RegisterElementCb(XML_TAG_BASE64, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::BASE64); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::BASE64); + }); + m_parser.RegisterElementCb(XML_TAG_ENCRYPTED_DER, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::ENCRYPTED); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::ENCRYPTED); + }); + m_parser.RegisterElementCb(XML_TAG_ENCRYPTED_ASCII, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::ENCRYPTED); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::ENCRYPTED); + }); + m_parser.RegisterElementCb(XML_TAG_ENCRYPTED_BINARY, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetBufferHandler(EncodingType::ENCRYPTED); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleaseBufferHandler(EncodingType::ENCRYPTED); + }); + m_parser.RegisterElementCb(XML_TAG_PERMISSION, + [this]() -> XML::Parser::ElementHandlerPtr { + return GetPermissionHandler(); + }, + [this](const XML::Parser::ElementHandlerPtr &) { + ReleasePermissionHandler(); + }); } void InitialValuesFile::Error(const XML::Parser::ErrorType errorType, - const std::string & log_msg) + const std::string &log_msg) { - switch (errorType) { - case XML::Parser::VALIDATION_ERROR: - LogWarning("validating error: " << log_msg); - break; - case XML::Parser::PARSE_WARNING: - LogWarning("parsing warning: " << log_msg); - break; - case XML::Parser::PARSE_ERROR: - LogWarning("parsing error: " << log_msg); - break; - } + switch (errorType) { + case XML::Parser::VALIDATION_ERROR: + LogWarning("validating error: " << log_msg); + break; + + case XML::Parser::PARSE_WARNING: + LogWarning("parsing warning: " << log_msg); + break; + + case XML::Parser::PARSE_ERROR: + LogWarning("parsing error: " << log_msg); + break; + } } int InitialValuesFile::Validate(const std::string &XSD_file) { - return m_parser.Validate(XSD_file); + return m_parser.Validate(XSD_file); } int InitialValuesFile::Parse() { - int ec = m_parser.Parse(); - if (!m_header || !m_header->isCorrectVersion()) { - LogError("bypassing XML file: " << m_filename << " - wrong file version!"); - ec = XML::Parser::ERROR_INVALID_VERSION; - } - return ec; + int ec = m_parser.Parse(); + + if (!m_header || !m_header->isCorrectVersion()) { + LogError("bypassing XML file: " << m_filename << " - wrong file version!"); + ec = XML::Parser::ERROR_INVALID_VERSION; + } + + return ec; } -XML::Parser::ElementHandlerPtr InitialValuesFile::GetObjectHandler(ObjectType type, - const CKM::RawBuffer &encryptedKey) +XML::Parser::ElementHandlerPtr InitialValuesFile::GetObjectHandler( + ObjectType type, + const CKM::RawBuffer &encryptedKey) { - switch (type) { - case KEY: - m_currentHandler = std::make_shared<KeyHandler>(m_db_logic, encryptedKey); - break; + switch (type) { + case KEY: + m_currentHandler = std::make_shared<KeyHandler>(m_db_logic, encryptedKey); + break; - case CERT: - m_currentHandler = std::make_shared<CertHandler>(m_db_logic, encryptedKey); - break; + case CERT: + m_currentHandler = std::make_shared<CertHandler>(m_db_logic, encryptedKey); + break; - case DATA: - m_currentHandler = std::make_shared<DataHandler>(m_db_logic, encryptedKey); - break; + case DATA: + m_currentHandler = std::make_shared<DataHandler>(m_db_logic, encryptedKey); + break; - default: - m_currentHandler.reset(); - break; - } + default: + m_currentHandler.reset(); + break; + } - return m_currentHandler; + return m_currentHandler; } void InitialValuesFile::ReleaseObjectHandler(ObjectType /*type*/) { - m_currentHandler.reset(); + m_currentHandler.reset(); } -XML::Parser::ElementHandlerPtr InitialValuesFile::GetBufferHandler(EncodingType type) +XML::Parser::ElementHandlerPtr InitialValuesFile::GetBufferHandler( + EncodingType type) { - if ( !m_currentHandler ) - return XML::Parser::ElementHandlerPtr(); + if (!m_currentHandler) + return XML::Parser::ElementHandlerPtr(); - return m_currentHandler->CreateBufferHandler(type); + return m_currentHandler->CreateBufferHandler(type); } void InitialValuesFile::ReleaseBufferHandler(EncodingType /*type*/) { @@ -258,56 +239,60 @@ void InitialValuesFile::ReleaseBufferHandler(EncodingType /*type*/) XML::Parser::ElementHandlerPtr InitialValuesFile::GetPermissionHandler() { - if ( !m_currentHandler ) - return XML::Parser::ElementHandlerPtr(); + if (!m_currentHandler) + return XML::Parser::ElementHandlerPtr(); - return m_currentHandler->CreatePermissionHandler(); + return m_currentHandler->CreatePermissionHandler(); } void InitialValuesFile::ReleasePermissionHandler() { } -InitialValuesFile::EncryptionKeyHandler::EncryptionKeyHandler(InitialValuesFile & parent) : m_parent(parent) {} -void InitialValuesFile::EncryptionKeyHandler::Characters(const std::string &data) +InitialValuesFile::EncryptionKeyHandler::EncryptionKeyHandler( + InitialValuesFile &parent) : m_parent(parent) {} +void InitialValuesFile::EncryptionKeyHandler::Characters( + const std::string &data) { - m_encryptedKey.reserve(m_encryptedKey.size() + data.size()); - m_encryptedKey.insert(m_encryptedKey.end(), data.begin(), data.end()); + m_encryptedKey.reserve(m_encryptedKey.size() + data.size()); + m_encryptedKey.insert(m_encryptedKey.end(), data.begin(), data.end()); }; void InitialValuesFile::EncryptionKeyHandler::End() { - std::string trimmed = XML::trimEachLine(std::string(m_encryptedKey.begin(), m_encryptedKey.end())); - Base64Decoder base64; - base64.reset(); - base64.append(RawBuffer(trimmed.begin(), trimmed.end())); - base64.finalize(); - m_encryptedKey = base64.get(); + std::string trimmed = XML::trimEachLine(std::string(m_encryptedKey.begin(), + m_encryptedKey.end())); + Base64Decoder base64; + base64.reset(); + base64.append(RawBuffer(trimmed.begin(), trimmed.end())); + base64.finalize(); + m_encryptedKey = base64.get(); }; CKM::RawBuffer InitialValuesFile::EncryptionKeyHandler::getEncryptedKey() const { - return m_encryptedKey; + return m_encryptedKey; } -InitialValuesFile::HeaderHandler::HeaderHandler(InitialValuesFile & parent) : - m_version(-1), m_parent(parent) +InitialValuesFile::HeaderHandler::HeaderHandler(InitialValuesFile &parent) : + m_version(-1), m_parent(parent) { } -void InitialValuesFile::HeaderHandler::Start(const XML::Parser::Attributes & attr) +void InitialValuesFile::HeaderHandler::Start(const XML::Parser::Attributes + &attr) { - // get key type - if (attr.find(XML_ATTR_VERSION) != attr.end()) { - m_version = atoi(attr.at(XML_ATTR_VERSION).c_str()); + // get key type + if (attr.find(XML_ATTR_VERSION) != attr.end()) { + m_version = atoi(attr.at(XML_ATTR_VERSION).c_str()); - if (isCorrectVersion()) - m_parent.registerElementListeners(); - } + if (isCorrectVersion()) + m_parent.registerElementListeners(); + } } bool InitialValuesFile::HeaderHandler::isCorrectVersion() const { - return m_version == XML_CURRENT_VERSION; + return m_version == XML_CURRENT_VERSION; } } diff --git a/src/manager/initial-values/InitialValuesFile.h b/src/manager/initial-values/InitialValuesFile.h index bd450910..a11747b3 100644 --- a/src/manager/initial-values/InitialValuesFile.h +++ b/src/manager/initial-values/InitialValuesFile.h @@ -38,70 +38,71 @@ namespace InitialValues { class InitialValuesFile { public: - InitialValuesFile(const std::string &XML_filename, - CKMLogic & db_logic); + InitialValuesFile(const std::string &XML_filename, + CKMLogic &db_logic); - int Validate(const std::string &XSD_file); - int Parse(); + int Validate(const std::string &XSD_file); + int Parse(); protected: - enum ObjectType { - KEY, - CERT, - DATA - }; + enum ObjectType { + KEY, + CERT, + DATA + }; - XML::Parser::ElementHandlerPtr GetObjectHandler(ObjectType type, const CKM::RawBuffer &encryptedKey); - void ReleaseObjectHandler(ObjectType type); + XML::Parser::ElementHandlerPtr GetObjectHandler(ObjectType type, + const CKM::RawBuffer &encryptedKey); + void ReleaseObjectHandler(ObjectType type); - XML::Parser::ElementHandlerPtr GetBufferHandler(EncodingType type); - void ReleaseBufferHandler(EncodingType type); + XML::Parser::ElementHandlerPtr GetBufferHandler(EncodingType type); + void ReleaseBufferHandler(EncodingType type); - XML::Parser::ElementHandlerPtr GetPermissionHandler(); - void ReleasePermissionHandler(); + XML::Parser::ElementHandlerPtr GetPermissionHandler(); + void ReleasePermissionHandler(); private: - class HeaderHandler : public XML::Parser::ElementHandler { - public: - explicit HeaderHandler(InitialValuesFile & parent); - virtual void Start(const XML::Parser::Attributes & attr); - virtual void Characters(const std::string &) {} - virtual void End() {} - - bool isCorrectVersion() const; - - private: - int m_version; - InitialValuesFile & m_parent; - }; - - class EncryptionKeyHandler : public XML::Parser::ElementHandler { - public: - explicit EncryptionKeyHandler(InitialValuesFile & parent); - virtual void Start(const XML::Parser::Attributes &) {} - virtual void Characters(const std::string &data); - virtual void End(); - - CKM::RawBuffer getEncryptedKey() const; - - private: - CKM::RawBuffer m_encryptedKey; - InitialValuesFile & m_parent; - }; - - std::string m_filename; - XML::Parser m_parser; - InitialValueHandler::InitialValueHandlerPtr m_currentHandler; - CKMLogic & m_db_logic; - typedef std::shared_ptr<HeaderHandler> HeaderHandlerPtr; - typedef std::shared_ptr<EncryptionKeyHandler> EncryptionKeyHandlerPtr; - HeaderHandlerPtr m_header; - EncryptionKeyHandlerPtr m_encryptionKeyHandler; - CKM::RawBuffer m_encryptedAESkey; - - void registerElementListeners(); - static void Error(const XML::Parser::ErrorType errorType, - const std::string & logMsg); + class HeaderHandler : public XML::Parser::ElementHandler { + public: + explicit HeaderHandler(InitialValuesFile &parent); + virtual void Start(const XML::Parser::Attributes &attr); + virtual void Characters(const std::string &) {} + virtual void End() {} + + bool isCorrectVersion() const; + + private: + int m_version; + InitialValuesFile &m_parent; + }; + + class EncryptionKeyHandler : public XML::Parser::ElementHandler { + public: + explicit EncryptionKeyHandler(InitialValuesFile &parent); + virtual void Start(const XML::Parser::Attributes &) {} + virtual void Characters(const std::string &data); + virtual void End(); + + CKM::RawBuffer getEncryptedKey() const; + + private: + CKM::RawBuffer m_encryptedKey; + InitialValuesFile &m_parent; + }; + + std::string m_filename; + XML::Parser m_parser; + InitialValueHandler::InitialValueHandlerPtr m_currentHandler; + CKMLogic &m_db_logic; + typedef std::shared_ptr<HeaderHandler> HeaderHandlerPtr; + typedef std::shared_ptr<EncryptionKeyHandler> EncryptionKeyHandlerPtr; + HeaderHandlerPtr m_header; + EncryptionKeyHandlerPtr m_encryptionKeyHandler; + CKM::RawBuffer m_encryptedAESkey; + + void registerElementListeners(); + static void Error(const XML::Parser::ErrorType errorType, + const std::string &logMsg); }; } diff --git a/src/manager/initial-values/KeyHandler.cpp b/src/manager/initial-values/KeyHandler.cpp index ef358e82..4a98cb09 100644 --- a/src/manager/initial-values/KeyHandler.cpp +++ b/src/manager/initial-values/KeyHandler.cpp @@ -28,14 +28,14 @@ #include <ckm/ckm-type.h> namespace { -const char * const XML_ATTR_TYPE = "type"; -const char * const XML_ATTR_TYPE_VAL_RSA_PRV = "RSA_PRV"; -const char * const XML_ATTR_TYPE_VAL_RSA_PUB = "RSA_PUB"; -const char * const XML_ATTR_TYPE_VAL_DSA_PRV = "DSA_PRV"; -const char * const XML_ATTR_TYPE_VAL_DSA_PUB = "DSA_PUB"; -const char * const XML_ATTR_TYPE_VAL_ECDSA_PRV = "ECDSA_PRV"; -const char * const XML_ATTR_TYPE_VAL_ECDSA_PUB = "ECDSA_PUB"; -const char * const XML_ATTR_TYPE_VAL_AES = "AES"; +const char *const XML_ATTR_TYPE = "type"; +const char *const XML_ATTR_TYPE_VAL_RSA_PRV = "RSA_PRV"; +const char *const XML_ATTR_TYPE_VAL_RSA_PUB = "RSA_PUB"; +const char *const XML_ATTR_TYPE_VAL_DSA_PRV = "DSA_PRV"; +const char *const XML_ATTR_TYPE_VAL_DSA_PUB = "DSA_PUB"; +const char *const XML_ATTR_TYPE_VAL_ECDSA_PRV = "ECDSA_PRV"; +const char *const XML_ATTR_TYPE_VAL_ECDSA_PUB = "ECDSA_PUB"; +const char *const XML_ATTR_TYPE_VAL_AES = "AES"; } namespace CKM { @@ -45,29 +45,34 @@ KeyHandler::~KeyHandler() {} void KeyHandler::Start(const XML::Parser::Attributes &attr) { - InitialValueHandler::Start(attr); + InitialValueHandler::Start(attr); - // get key type - if (attr.find(XML_ATTR_TYPE) != attr.end()) - m_keyType = KeyHandler::parseType(attr.at(XML_ATTR_TYPE)); + // get key type + if (attr.find(XML_ATTR_TYPE) != attr.end()) + m_keyType = KeyHandler::parseType(attr.at(XML_ATTR_TYPE)); } -KeyType KeyHandler::parseType(const std::string & typeStr) +KeyType KeyHandler::parseType(const std::string &typeStr) { - if (typeStr == XML_ATTR_TYPE_VAL_RSA_PRV) return KeyType::KEY_RSA_PRIVATE; - else if (typeStr == XML_ATTR_TYPE_VAL_RSA_PUB) return KeyType::KEY_RSA_PUBLIC; - else if (typeStr == XML_ATTR_TYPE_VAL_DSA_PRV) return KeyType::KEY_DSA_PRIVATE; - else if (typeStr == XML_ATTR_TYPE_VAL_DSA_PUB) return KeyType::KEY_DSA_PUBLIC; - else if (typeStr == XML_ATTR_TYPE_VAL_ECDSA_PRV) return KeyType::KEY_ECDSA_PRIVATE; - else if (typeStr == XML_ATTR_TYPE_VAL_ECDSA_PUB) return KeyType::KEY_ECDSA_PUBLIC; - else if (typeStr == XML_ATTR_TYPE_VAL_AES) return KeyType::KEY_AES; - else // should not happen - throw std::runtime_error("error: invalid value discovered as key type"); + if (typeStr == XML_ATTR_TYPE_VAL_RSA_PRV) return KeyType::KEY_RSA_PRIVATE; + else if (typeStr == XML_ATTR_TYPE_VAL_RSA_PUB) return + KeyType::KEY_RSA_PUBLIC; + else if (typeStr == XML_ATTR_TYPE_VAL_DSA_PRV) return + KeyType::KEY_DSA_PRIVATE; + else if (typeStr == XML_ATTR_TYPE_VAL_DSA_PUB) return + KeyType::KEY_DSA_PUBLIC; + else if (typeStr == XML_ATTR_TYPE_VAL_ECDSA_PRV) return + KeyType::KEY_ECDSA_PRIVATE; + else if (typeStr == XML_ATTR_TYPE_VAL_ECDSA_PUB) return + KeyType::KEY_ECDSA_PUBLIC; + else if (typeStr == XML_ATTR_TYPE_VAL_AES) return KeyType::KEY_AES; + else // should not happen + throw std::runtime_error("error: invalid value discovered as key type"); } DataType KeyHandler::getDataType() const { - return DataType(m_keyType); + return DataType(m_keyType); } } diff --git a/src/manager/initial-values/KeyHandler.h b/src/manager/initial-values/KeyHandler.h index 9f374135..5f630b45 100644 --- a/src/manager/initial-values/KeyHandler.h +++ b/src/manager/initial-values/KeyHandler.h @@ -32,18 +32,18 @@ namespace InitialValues { class KeyHandler : public InitialValueHandler { public: - explicit KeyHandler(CKMLogic & db_logic, const CKM::RawBuffer &encryptedKey) : - InitialValueHandler(db_logic, encryptedKey), m_keyType(KeyType::KEY_NONE) {} - virtual ~KeyHandler(); + explicit KeyHandler(CKMLogic &db_logic, const CKM::RawBuffer &encryptedKey) : + InitialValueHandler(db_logic, encryptedKey), m_keyType(KeyType::KEY_NONE) {} + virtual ~KeyHandler(); - virtual void Start(const XML::Parser::Attributes &); + virtual void Start(const XML::Parser::Attributes &); - virtual DataType getDataType() const; + virtual DataType getDataType() const; protected: - static KeyType parseType(const std::string & typeStr); + static KeyType parseType(const std::string &typeStr); - KeyType m_keyType; + KeyType m_keyType; }; } diff --git a/src/manager/initial-values/NoCharactersHandler.cpp b/src/manager/initial-values/NoCharactersHandler.cpp index 0ee9ff93..e43c130e 100644 --- a/src/manager/initial-values/NoCharactersHandler.cpp +++ b/src/manager/initial-values/NoCharactersHandler.cpp @@ -28,12 +28,15 @@ namespace CKM { namespace InitialValues { -void NoCharactersHandler::Characters(const std::string & data) +void NoCharactersHandler::Characters(const std::string &data) { - auto f = find_if(data.begin(), data.end(), [](char c){ return std::isspace(c) == 0;}); - if (f != data.end()) - throw std::runtime_error( - "error: value handler detected raw data outside data-specific tag"); + auto f = find_if(data.begin(), data.end(), [](char c) { + return std::isspace(c) == 0; + }); + + if (f != data.end()) + throw std::runtime_error( + "error: value handler detected raw data outside data-specific tag"); } NoCharactersHandler::~NoCharactersHandler() diff --git a/src/manager/initial-values/NoCharactersHandler.h b/src/manager/initial-values/NoCharactersHandler.h index 63f16c8d..c581703f 100644 --- a/src/manager/initial-values/NoCharactersHandler.h +++ b/src/manager/initial-values/NoCharactersHandler.h @@ -29,9 +29,9 @@ namespace InitialValues { class NoCharactersHandler : public XML::Parser::ElementHandler { public: - void Characters(const std::string & data); + void Characters(const std::string &data); - virtual ~NoCharactersHandler(); + virtual ~NoCharactersHandler(); }; } // namespace InitialValues diff --git a/src/manager/initial-values/PermissionHandler.cpp b/src/manager/initial-values/PermissionHandler.cpp index 80ff0317..0a7f523c 100644 --- a/src/manager/initial-values/PermissionHandler.cpp +++ b/src/manager/initial-values/PermissionHandler.cpp @@ -24,7 +24,7 @@ #include <PermissionHandler.h> namespace { -const char * const XML_ATTR_ACCESSOR = "accessor"; +const char *const XML_ATTR_ACCESSOR = "accessor"; } namespace CKM { @@ -32,11 +32,11 @@ namespace InitialValues { PermissionHandler::~PermissionHandler() {} -void PermissionHandler::Start(const XML::Parser::Attributes & attr) +void PermissionHandler::Start(const XML::Parser::Attributes &attr) { - // get accessor label - if (attr.find(XML_ATTR_ACCESSOR) != attr.end()) - m_accessor = Label(attr.at(XML_ATTR_ACCESSOR)); + // get accessor label + if (attr.find(XML_ATTR_ACCESSOR) != attr.end()) + m_accessor = Label(attr.at(XML_ATTR_ACCESSOR)); } void PermissionHandler::End() diff --git a/src/manager/initial-values/PermissionHandler.h b/src/manager/initial-values/PermissionHandler.h index 5d1f44b0..d84ecb29 100644 --- a/src/manager/initial-values/PermissionHandler.h +++ b/src/manager/initial-values/PermissionHandler.h @@ -32,20 +32,20 @@ namespace InitialValues { class PermissionHandler : public NoCharactersHandler { public: - typedef std::shared_ptr<PermissionHandler> PermissionHandlerPtr; + typedef std::shared_ptr<PermissionHandler> PermissionHandlerPtr; - virtual ~PermissionHandler(); + virtual ~PermissionHandler(); - virtual void Start(const XML::Parser::Attributes &); - virtual void End(); + virtual void Start(const XML::Parser::Attributes &); + virtual void End(); - const Label & getAccessor() const - { - return m_accessor; - } + const Label &getAccessor() const + { + return m_accessor; + } private: - Label m_accessor; + Label m_accessor; }; } diff --git a/src/manager/initial-values/SWKeyFile.cpp b/src/manager/initial-values/SWKeyFile.cpp index e8605506..bacad902 100644 --- a/src/manager/initial-values/SWKeyFile.cpp +++ b/src/manager/initial-values/SWKeyFile.cpp @@ -29,124 +29,126 @@ namespace { const int XML_SW_KEY_CURRENT_VERSION = 1; -const char * const XML_TAG_DEVICE_KEY = "DeviceKey"; -const char * const XML_TAG_RSA_KEY = "RSAPrivateKey"; -const char * const XML_TAG_PEM = "PEM"; -const char * const XML_TAG_DER = "DERBase64"; -const char * const XML_TAG_BASE64 = "Base64"; -const char * const XML_ATTR_VERSION = "version"; +const char *const XML_TAG_DEVICE_KEY = "DeviceKey"; +const char *const XML_TAG_RSA_KEY = "RSAPrivateKey"; +const char *const XML_TAG_PEM = "PEM"; +const char *const XML_TAG_DER = "DERBase64"; +const char *const XML_TAG_BASE64 = "Base64"; +const char *const XML_ATTR_VERSION = "version"; } namespace CKM { namespace InitialValues { SWKeyFile::SWKeyFile(const std::string &XML_filename) : - m_parser(XML_filename), - m_header(std::make_shared<HeaderHandler>(*this)), - m_RSAKeyHandler(std::make_shared<RSAKeyHandler>(*this)) + m_parser(XML_filename), + m_header(std::make_shared<HeaderHandler>(*this)), + m_RSAKeyHandler(std::make_shared<RSAKeyHandler>(*this)) { - m_parser.RegisterErrorCb(SWKeyFile::Error); - m_parser.RegisterElementCb(XML_TAG_DEVICE_KEY, - [this]() -> XML::Parser::ElementHandlerPtr - { - return m_header; - }, - [this](const XML::Parser::ElementHandlerPtr &) {}); + m_parser.RegisterErrorCb(SWKeyFile::Error); + m_parser.RegisterElementCb(XML_TAG_DEVICE_KEY, + [this]() -> XML::Parser::ElementHandlerPtr { + return m_header; + }, + [this](const XML::Parser::ElementHandlerPtr &) {}); } void SWKeyFile::registerElementListeners() { - m_parser.RegisterElementCb(XML_TAG_RSA_KEY, - [this]() -> XML::Parser::ElementHandlerPtr - { - return m_RSAKeyHandler; - }, - [this](const XML::Parser::ElementHandlerPtr &) - { - m_deviceKey = m_RSAKeyHandler->getPrivKey(); - }); + m_parser.RegisterElementCb(XML_TAG_RSA_KEY, + [this]() -> XML::Parser::ElementHandlerPtr { + return m_RSAKeyHandler; + }, + [this](const XML::Parser::ElementHandlerPtr &) { + m_deviceKey = m_RSAKeyHandler->getPrivKey(); + }); } void SWKeyFile::Error(const XML::Parser::ErrorType errorType, - const std::string & log_msg) + const std::string &log_msg) { - switch (errorType) { - case XML::Parser::VALIDATION_ERROR: - LogWarning("validating error: " << log_msg); - break; - case XML::Parser::PARSE_WARNING: - LogWarning("parsing warning: " << log_msg); - break; - case XML::Parser::PARSE_ERROR: - LogWarning("parsing error: " << log_msg); - break; - } + switch (errorType) { + case XML::Parser::VALIDATION_ERROR: + LogWarning("validating error: " << log_msg); + break; + + case XML::Parser::PARSE_WARNING: + LogWarning("parsing warning: " << log_msg); + break; + + case XML::Parser::PARSE_ERROR: + LogWarning("parsing error: " << log_msg); + break; + } } int SWKeyFile::Validate(const std::string &XSD_file) { - return m_parser.Validate(XSD_file); + return m_parser.Validate(XSD_file); } int SWKeyFile::Parse() { - int ec = m_parser.Parse(); - if (!m_header || !m_header->isCorrectVersion()) { - LogError("bypassing XML file: " << m_filename << " - wrong file version!"); - ec = XML::Parser::ERROR_INVALID_VERSION; - } - return ec; + int ec = m_parser.Parse(); + + if (!m_header || !m_header->isCorrectVersion()) { + LogError("bypassing XML file: " << m_filename << " - wrong file version!"); + ec = XML::Parser::ERROR_INVALID_VERSION; + } + + return ec; } -SWKeyFile::RSAKeyHandler::RSAKeyHandler(SWKeyFile & parent) - : m_parent(parent) +SWKeyFile::RSAKeyHandler::RSAKeyHandler(SWKeyFile &parent) + : m_parent(parent) { } void SWKeyFile::RSAKeyHandler::Characters(const std::string &data) { - //m_encryptedKey.reserve(m_encryptedKey.size() + data.size()); - //m_encryptedKey.insert(m_encryptedKey.end(), data.begin(), data.end()); - std::copy(data.begin(), data.end(), std::back_inserter(m_encryptedKey)); + //m_encryptedKey.reserve(m_encryptedKey.size() + data.size()); + //m_encryptedKey.insert(m_encryptedKey.end(), data.begin(), data.end()); + std::copy(data.begin(), data.end(), std::back_inserter(m_encryptedKey)); } void SWKeyFile::RSAKeyHandler::End() { -// std::string trimmed = XML::trimEachLine(std::string(m_encryptedKey.begin(), m_encryptedKey.end())); + // std::string trimmed = XML::trimEachLine(std::string(m_encryptedKey.begin(), m_encryptedKey.end())); - Base64Decoder base64; - base64.reset(); - base64.append(XML::removeWhiteChars(m_encryptedKey)); - base64.finalize(); - m_encryptedKey = base64.get(); + Base64Decoder base64; + base64.reset(); + base64.append(XML::removeWhiteChars(m_encryptedKey)); + base64.finalize(); + m_encryptedKey = base64.get(); }; Crypto::GObjShPtr SWKeyFile::RSAKeyHandler::getPrivKey() { - return std::make_shared<Crypto::SW::AKey>(m_encryptedKey, DataType::KEY_RSA_PRIVATE); + return std::make_shared<Crypto::SW::AKey>(m_encryptedKey, + DataType::KEY_RSA_PRIVATE); } -SWKeyFile::HeaderHandler::HeaderHandler(SWKeyFile & parent) : - m_version(-1), m_parent(parent) +SWKeyFile::HeaderHandler::HeaderHandler(SWKeyFile &parent) : + m_version(-1), m_parent(parent) { } -void SWKeyFile::HeaderHandler::Start(const XML::Parser::Attributes & attr) +void SWKeyFile::HeaderHandler::Start(const XML::Parser::Attributes &attr) { - // get key type - if (attr.find(XML_ATTR_VERSION) != attr.end()) { - m_version = atoi(attr.at(XML_ATTR_VERSION).c_str()); + // get key type + if (attr.find(XML_ATTR_VERSION) != attr.end()) { + m_version = atoi(attr.at(XML_ATTR_VERSION).c_str()); - if (isCorrectVersion()) - m_parent.registerElementListeners(); - } + if (isCorrectVersion()) + m_parent.registerElementListeners(); + } } bool SWKeyFile::HeaderHandler::isCorrectVersion() const { - return m_version == XML_SW_KEY_CURRENT_VERSION; + return m_version == XML_SW_KEY_CURRENT_VERSION; } } diff --git a/src/manager/initial-values/SWKeyFile.h b/src/manager/initial-values/SWKeyFile.h index 8768ade1..e5642857 100644 --- a/src/manager/initial-values/SWKeyFile.h +++ b/src/manager/initial-values/SWKeyFile.h @@ -33,62 +33,62 @@ #include <base64.h> #include <generic-backend/gobj.h> #include <dpl/log/log.h> + namespace CKM { namespace InitialValues { - class SWKeyFile { public: - explicit SWKeyFile(const std::string &XML_filename); + explicit SWKeyFile(const std::string &XML_filename); - int Validate(const std::string &XSD_file); - int Parse(); + int Validate(const std::string &XSD_file); + int Parse(); - Crypto::GObjShPtr getPrivKey() - { - return m_deviceKey; - } + Crypto::GObjShPtr getPrivKey() + { + return m_deviceKey; + } private: - class HeaderHandler : public XML::Parser::ElementHandler { - public: - explicit HeaderHandler(SWKeyFile & parent); - virtual void Start(const XML::Parser::Attributes & attr); - virtual void Characters(const std::string &) {} - virtual void End() {} + class HeaderHandler : public XML::Parser::ElementHandler { + public: + explicit HeaderHandler(SWKeyFile &parent); + virtual void Start(const XML::Parser::Attributes &attr); + virtual void Characters(const std::string &) {} + virtual void End() {} - bool isCorrectVersion() const; + bool isCorrectVersion() const; - private: - int m_version; - SWKeyFile & m_parent; - }; + private: + int m_version; + SWKeyFile &m_parent; + }; - class RSAKeyHandler : public XML::Parser::ElementHandler { - public: - explicit RSAKeyHandler(SWKeyFile & parent); - virtual void Start(const XML::Parser::Attributes &) {} - virtual void Characters(const std::string &data); - virtual void End(); + class RSAKeyHandler : public XML::Parser::ElementHandler { + public: + explicit RSAKeyHandler(SWKeyFile &parent); + virtual void Start(const XML::Parser::Attributes &) {} + virtual void Characters(const std::string &data); + virtual void End(); - Crypto::GObjShPtr getPrivKey(); + Crypto::GObjShPtr getPrivKey(); - private: - CKM::RawBuffer m_encryptedKey; - SWKeyFile & m_parent; - }; + private: + CKM::RawBuffer m_encryptedKey; + SWKeyFile &m_parent; + }; - std::string m_filename; - XML::Parser m_parser; - typedef std::shared_ptr<HeaderHandler> HeaderHandlerPtr; - typedef std::shared_ptr<RSAKeyHandler> RSAKeyHandlerPtr; - HeaderHandlerPtr m_header; - RSAKeyHandlerPtr m_RSAKeyHandler; - Crypto::GObjShPtr m_deviceKey; + std::string m_filename; + XML::Parser m_parser; + typedef std::shared_ptr<HeaderHandler> HeaderHandlerPtr; + typedef std::shared_ptr<RSAKeyHandler> RSAKeyHandlerPtr; + HeaderHandlerPtr m_header; + RSAKeyHandlerPtr m_RSAKeyHandler; + Crypto::GObjShPtr m_deviceKey; - void registerElementListeners(); - static void Error(const XML::Parser::ErrorType errorType, - const std::string & logMsg); + void registerElementListeners(); + static void Error(const XML::Parser::ErrorType errorType, + const std::string &logMsg); }; } diff --git a/src/manager/initial-values/initial-value-loader.cpp b/src/manager/initial-values/initial-value-loader.cpp index ac1e4316..4cdfb2d8 100644 --- a/src/manager/initial-values/initial-value-loader.cpp +++ b/src/manager/initial-values/initial-value-loader.cpp @@ -26,8 +26,8 @@ #include <InitialValuesFile.h> namespace { -const char * const INIT_VALUES_XSD = RO_DATA_DIR "/initial_values.xsd"; -const char * const INIT_VALUES_FILE_SUFFIX = ".xml"; +const char *const INIT_VALUES_XSD = RO_DATA_DIR "/initial_values.xsd"; +const char *const INIT_VALUES_FILE_SUFFIX = ".xml"; } // namespace anonymous namespace CKM { @@ -35,35 +35,40 @@ namespace InitialValues { void LoadFiles(CKMLogic &logic) { - try { - std::vector<std::string> filesToParse; + try { + std::vector<std::string> filesToParse; - forEachFile(INITIAL_VALUES_DIR, [&filesToParse](const std::string &filename) { - std::string lowercaseFilename = filename; - std::transform(lowercaseFilename.begin(), lowercaseFilename.end(), lowercaseFilename.begin(), ::tolower); + forEachFile(INITIAL_VALUES_DIR, [&filesToParse](const std::string & filename) { + std::string lowercaseFilename = filename; + std::transform(lowercaseFilename.begin(), lowercaseFilename.end(), + lowercaseFilename.begin(), ::tolower); - if (lowercaseFilename.find(INIT_VALUES_FILE_SUFFIX) == std::string::npos) - return; + if (lowercaseFilename.find(INIT_VALUES_FILE_SUFFIX) == std::string::npos) + return; - filesToParse.emplace_back(std::string(INITIAL_VALUES_DIR) + "/" + filename); - }); + filesToParse.emplace_back(std::string(INITIAL_VALUES_DIR) + "/" + filename); + }); - // parse - for (const auto & file : filesToParse) { - InitialValues::InitialValuesFile xmlFile(file.c_str(), logic); - int rc = xmlFile.Validate(INIT_VALUES_XSD); - if (rc == XML::Parser::PARSE_SUCCESS) { - rc = xmlFile.Parse(); - if (rc != XML::Parser::PARSE_SUCCESS) - LogError("invalid initial values file: " << file << ", parsing code: " << rc); - } else { - LogError("invalid initial values file: " << file << ", validation code: " << rc); - } - unlink(file.c_str()); - } - } catch (...) { - LogError("The implementation of exception handling in xml parser is broken!"); - } + // parse + for (const auto &file : filesToParse) { + InitialValues::InitialValuesFile xmlFile(file.c_str(), logic); + int rc = xmlFile.Validate(INIT_VALUES_XSD); + + if (rc == XML::Parser::PARSE_SUCCESS) { + rc = xmlFile.Parse(); + + if (rc != XML::Parser::PARSE_SUCCESS) + LogError("invalid initial values file: " << file << ", parsing code: " << rc); + } else { + LogError("invalid initial values file: " << file << ", validation code: " << + rc); + } + + unlink(file.c_str()); + } + } catch (...) { + LogError("The implementation of exception handling in xml parser is broken!"); + } } } // namespace InitialValues diff --git a/src/manager/initial-values/parser.cpp b/src/manager/initial-values/parser.cpp index 170e9b52..6b393d4b 100644 --- a/src/manager/initial-values/parser.cpp +++ b/src/manager/initial-values/parser.cpp @@ -37,207 +37,238 @@ namespace XML { namespace { struct LibXmlCleanup { - ~LibXmlCleanup() { xmlCleanupParser(); } + ~LibXmlCleanup() + { + xmlCleanupParser(); + } } cleanup; } // namespace anonymous Parser::Parser(const std::string &XML_filename) : - m_errorCb(0) + m_errorCb(0) { - m_XMLfile = XML_filename; - memset(&m_saxHandler, 0, sizeof(m_saxHandler)); - m_saxHandler.startElement = &Parser::StartElement; - m_saxHandler.endElement = &Parser::EndElement; - m_saxHandler.characters = &Parser::Characters; - m_saxHandler.error = &Parser::Error; - m_saxHandler.warning = &Parser::Warning; + m_XMLfile = XML_filename; + memset(&m_saxHandler, 0, sizeof(m_saxHandler)); + m_saxHandler.startElement = &Parser::StartElement; + m_saxHandler.endElement = &Parser::EndElement; + m_saxHandler.characters = &Parser::Characters; + m_saxHandler.error = &Parser::Error; + m_saxHandler.warning = &Parser::Warning; } Parser::~Parser() { } +using SchemaParserCtxt = + std::unique_ptr<xmlSchemaParserCtxt, void(*)(xmlSchemaParserCtxtPtr)>; +using Schema = std::unique_ptr<xmlSchema, void(*)(xmlSchemaPtr)>; +using SchemaValidCtxt = + std::unique_ptr<xmlSchemaValidCtxt, void(*)(xmlSchemaValidCtxtPtr)>; int Parser::Validate(const std::string &XSD_schema) { - if (XSD_schema.empty()) { - LogError("no XSD file path given"); - return ERROR_INVALID_ARGUMENT; - } - - int retCode; - std::unique_ptr<xmlSchemaParserCtxt, void(*)(xmlSchemaParserCtxtPtr)> - parserCtxt(xmlSchemaNewParserCtxt(XSD_schema.c_str()), - [](xmlSchemaParserCtxtPtr ctx){ xmlSchemaFreeParserCtxt(ctx); }); - if (!parserCtxt) { - LogError("XSD file path is invalid"); - return ERROR_INVALID_ARGUMENT; - } - - std::unique_ptr<xmlSchema, void(*)(xmlSchemaPtr)> - schema(xmlSchemaParse(parserCtxt.get()), - [](xmlSchemaPtr schemaPtr){ xmlSchemaFree(schemaPtr); }); - if (!schema) { - LogError("Parsing XSD file failed"); - return ERROR_XSD_PARSE_FAILED; - } - - - std::unique_ptr<xmlSchemaValidCtxt, void(*)(xmlSchemaValidCtxtPtr)> - validCtxt(xmlSchemaNewValidCtxt(schema.get()), - [](xmlSchemaValidCtxtPtr validCtxPtr){ xmlSchemaFreeValidCtxt(validCtxPtr); }); - if (!validCtxt) { - LogError("Internal parser error"); - return ERROR_INTERNAL; - } - - xmlSetStructuredErrorFunc(NULL, NULL); - xmlSetGenericErrorFunc(this, &Parser::ErrorValidate); - xmlThrDefSetStructuredErrorFunc(NULL, NULL); - xmlThrDefSetGenericErrorFunc(this, &Parser::ErrorValidate); - - retCode = xmlSchemaValidateFile(validCtxt.get(), m_XMLfile.c_str(), 0); - if (0 != retCode) { - LogWarning("Validating XML file failed, ec: " << retCode); - retCode = ERROR_XML_VALIDATION_FAILED; - } else { - retCode = PARSE_SUCCESS; - } - - return retCode; + if (XSD_schema.empty()) { + LogError("no XSD file path given"); + return ERROR_INVALID_ARGUMENT; + } + + int retCode; + SchemaParserCtxt parserCtxt(xmlSchemaNewParserCtxt(XSD_schema.c_str()), + [](xmlSchemaParserCtxtPtr ctx) { + xmlSchemaFreeParserCtxt(ctx); + }); + + if (!parserCtxt) { + LogError("XSD file path is invalid"); + return ERROR_INVALID_ARGUMENT; + } + + Schema schema(xmlSchemaParse(parserCtxt.get()), [](xmlSchemaPtr schemaPtr) { + xmlSchemaFree(schemaPtr); + }); + + if (!schema) { + LogError("Parsing XSD file failed"); + return ERROR_XSD_PARSE_FAILED; + } + + SchemaValidCtxt validCtxt(xmlSchemaNewValidCtxt(schema.get()), []( + xmlSchemaValidCtxtPtr validCtxPtr) { + xmlSchemaFreeValidCtxt(validCtxPtr); + }); + + if (!validCtxt) { + LogError("Internal parser error"); + return ERROR_INTERNAL; + } + + xmlSetStructuredErrorFunc(NULL, NULL); + xmlSetGenericErrorFunc(this, &Parser::ErrorValidate); + xmlThrDefSetStructuredErrorFunc(NULL, NULL); + xmlThrDefSetGenericErrorFunc(this, &Parser::ErrorValidate); + + retCode = xmlSchemaValidateFile(validCtxt.get(), m_XMLfile.c_str(), 0); + + if (0 != retCode) { + LogWarning("Validating XML file failed, ec: " << retCode); + retCode = ERROR_XML_VALIDATION_FAILED; + } else { + retCode = PARSE_SUCCESS; + } + + return retCode; } int Parser::Parse() { - if (m_elementListenerMap.empty()) { - LogError("Can not parse XML file: no registered element callbacks."); - return ERROR_INVALID_ARGUMENT; - } - int retCode = xmlSAXUserParseFile(&m_saxHandler, this, m_XMLfile.c_str()); - if (0 != retCode) { - LogWarning("Parsing XML file failed, ec: " << retCode); - return ERROR_XML_PARSE_FAILED; - } - // if error detected while parsing - if (m_elementListenerMap.empty()) { - LogError("Critical error detected while parsing."); - return ERROR_INTERNAL; - } - return PARSE_SUCCESS; + if (m_elementListenerMap.empty()) { + LogError("Can not parse XML file: no registered element callbacks."); + return ERROR_INVALID_ARGUMENT; + } + + int retCode = xmlSAXUserParseFile(&m_saxHandler, this, m_XMLfile.c_str()); + + if (0 != retCode) { + LogWarning("Parsing XML file failed, ec: " << retCode); + return ERROR_XML_PARSE_FAILED; + } + + // if error detected while parsing + if (m_elementListenerMap.empty()) { + LogError("Critical error detected while parsing."); + return ERROR_INTERNAL; + } + + return PARSE_SUCCESS; } int Parser::RegisterErrorCb(const ErrorCb newCb) { - if (m_errorCb) { - LogError("Callback already registered!"); - return ERROR_CALLBACK_PRESENT; - } - m_errorCb = newCb; - return PARSE_SUCCESS; + if (m_errorCb) { + LogError("Callback already registered!"); + return ERROR_CALLBACK_PRESENT; + } + + m_errorCb = newCb; + return PARSE_SUCCESS; } -int Parser::RegisterElementCb(const char * elementName, - const StartCb startCb, - const EndCb endCb) +int Parser::RegisterElementCb(const char *elementName, + const StartCb startCb, + const EndCb endCb) { - if (!elementName) - return ERROR_INVALID_ARGUMENT; + if (!elementName) + return ERROR_INVALID_ARGUMENT; - std::string key(elementName); + std::string key(elementName); - if (m_elementListenerMap.find(elementName) != m_elementListenerMap.end()) { - LogError("Callback for element " << elementName << " already registered!"); - return ERROR_CALLBACK_PRESENT; - } + if (m_elementListenerMap.find(elementName) != m_elementListenerMap.end()) { + LogError("Callback for element " << elementName << " already registered!"); + return ERROR_CALLBACK_PRESENT; + } - m_elementListenerMap[key] = {startCb, endCb}; - return PARSE_SUCCESS; + m_elementListenerMap[key] = {startCb, endCb}; + return PARSE_SUCCESS; } void Parser::StartElement(const xmlChar *name, - const xmlChar **attrs) + const xmlChar **attrs) { - std::string key(reinterpret_cast<const char*>(name)); - if (m_elementListenerMap.find(key) == m_elementListenerMap.end()) - return; - - ElementHandlerPtr newHandler; - const ElementListener & current = m_elementListenerMap[key]; - if (current.startCb) { - Attributes attribs; - { - size_t numAttrs = 0; - std::string key; - while (attrs && attrs[numAttrs]) { - const char *attrChr = reinterpret_cast<const char*>(attrs[numAttrs]); - if ((numAttrs%2) == 0) - key = std::string(attrChr); - else - attribs[key] = std::string(attrChr); - numAttrs++; - } - } - - newHandler = current.startCb(); - if (newHandler) - newHandler->Start(attribs); - } - // always put a handler, even if it's empty. This will not break - // the sequence of queued elements when popping from the queue. - m_elementHandlerStack.push(newHandler); + std::string key(reinterpret_cast<const char *>(name)); + + if (m_elementListenerMap.find(key) == m_elementListenerMap.end()) + return; + + ElementHandlerPtr newHandler; + const ElementListener ¤t = m_elementListenerMap[key]; + + if (current.startCb) { + Attributes attribs; + + size_t numAttrs = 0; + std::string _key; + + while (attrs && attrs[numAttrs]) { + const char *attrChr = reinterpret_cast<const char *>(attrs[numAttrs]); + + if ((numAttrs % 2) == 0) + _key = std::string(attrChr); + else + attribs[_key] = std::string(attrChr); + + numAttrs++; + } + + newHandler = current.startCb(); + + if (newHandler) + newHandler->Start(attribs); + } + + // always put a handler, even if it's empty. This will not break + // the sequence of queued elements when popping from the queue. + m_elementHandlerStack.push(newHandler); } void Parser::EndElement(const xmlChar *name) { - std::string key(reinterpret_cast<const char*>(name)); - if (m_elementListenerMap.find(key) == m_elementListenerMap.end()) - return; + std::string key(reinterpret_cast<const char *>(name)); + + if (m_elementListenerMap.find(key) == m_elementListenerMap.end()) + return; - // this should never ever happen - if (m_elementHandlerStack.empty()) - throw std::runtime_error("internal error: element queue desynchronized!"); + // this should never ever happen + if (m_elementHandlerStack.empty()) + throw std::runtime_error("internal error: element queue desynchronized!"); - ElementHandlerPtr ¤tHandler = m_elementHandlerStack.top(); - if (currentHandler) - currentHandler->End(); + ElementHandlerPtr ¤tHandler = m_elementHandlerStack.top(); - const ElementListener & current = m_elementListenerMap[key]; - if (current.endCb) - current.endCb(currentHandler); + if (currentHandler) + currentHandler->End(); - m_elementHandlerStack.pop(); + const ElementListener ¤t = m_elementListenerMap[key]; + + if (current.endCb) + current.endCb(currentHandler); + + m_elementHandlerStack.pop(); } void Parser::Characters(const xmlChar *ch, size_t chLen) { - std::string chars(reinterpret_cast<const char*>(ch), chLen); - if (chars.empty()) - return; - - if (!m_elementHandlerStack.empty()) { - ElementHandlerPtr ¤tHandler = m_elementHandlerStack.top(); - if (currentHandler) - currentHandler->Characters(chars); - } + std::string chars(reinterpret_cast<const char *>(ch), chLen); + + if (chars.empty()) + return; + + if (!m_elementHandlerStack.empty()) { + ElementHandlerPtr ¤tHandler = m_elementHandlerStack.top(); + + if (currentHandler) + currentHandler->Characters(chars); + } } void Parser::Error(const ErrorType errorType, const char *msg, va_list &args) { - if (!m_errorCb) - return; - - va_list args2; - try { - va_copy(args2, args); - std::vector<char> buf(1 + std::vsnprintf(NULL, 0, msg, args)); - std::vsnprintf(buf.data(), buf.size(), msg, args2); - m_errorCb(errorType, trim(std::string(buf.begin(), buf.end()))); - } catch (...) { - LogError("Error callback throwed an exception."); - // if an error handler throwed exception, - // do not call further callbacks - m_elementListenerMap.clear(); - } - va_end(args2); + if (!m_errorCb) + return; + + va_list args2; + + try { + va_copy(args2, args); + std::vector<char> buf(1 + std::vsnprintf(NULL, 0, msg, args)); + std::vsnprintf(buf.data(), buf.size(), msg, args2); + m_errorCb(errorType, trim(std::string(buf.begin(), buf.end()))); + } catch (...) { + LogError("Error callback throwed an exception."); + // if an error handler throwed exception, + // do not call further callbacks + m_elementListenerMap.clear(); + } + + va_end(args2); } // @@ -245,73 +276,76 @@ void Parser::Error(const ErrorType errorType, const char *msg, va_list &args) // void Parser::CallbackHelper(std::function<void(void)> func) { - try { - func(); - return; - } catch (const std::exception &e) { - LogError("parser error: " << e.what()); - if (m_errorCb) - m_errorCb(PARSE_ERROR, e.what()); - } catch (...) { - LogError("unknown parser error"); - if (m_errorCb) - m_errorCb(PARSE_ERROR, "unknown parser error"); - } - // raise error flag - unregister listeners - m_elementListenerMap.clear(); + try { + func(); + return; + } catch (const std::exception &e) { + LogError("parser error: " << e.what()); + + if (m_errorCb) + m_errorCb(PARSE_ERROR, e.what()); + } catch (...) { + LogError("unknown parser error"); + + if (m_errorCb) + m_errorCb(PARSE_ERROR, "unknown parser error"); + } + + // raise error flag - unregister listeners + m_elementListenerMap.clear(); } void Parser::StartElement(void *userData, - const xmlChar *name, - const xmlChar **attrs) + const xmlChar *name, + const xmlChar **attrs) { - Parser *parser = static_cast<Parser *>(userData); - parser->CallbackHelper([&parser, &name, &attrs] { parser->StartElement(name, attrs); }); + Parser *parser = static_cast<Parser *>(userData); + parser->CallbackHelper([&parser, &name, &attrs] { parser->StartElement(name, attrs); }); } void Parser::EndElement(void *userData, - const xmlChar *name) + const xmlChar *name) { - Parser *parser = static_cast<Parser *>(userData); - parser->CallbackHelper([&parser, &name] { parser->EndElement(name); }); + Parser *parser = static_cast<Parser *>(userData); + parser->CallbackHelper([&parser, &name] { parser->EndElement(name); }); } void Parser::Characters(void *userData, - const xmlChar *ch, - int len) + const xmlChar *ch, + int len) { - Parser *parser = static_cast<Parser *>(userData); - parser->CallbackHelper([&parser, &ch, &len] { parser->Characters(ch, static_cast<size_t>(len)); }); + Parser *parser = static_cast<Parser *>(userData); + parser->CallbackHelper([&parser, &ch, &len] { parser->Characters(ch, static_cast<size_t>(len)); }); } void Parser::ErrorValidate(void *userData, - const char *msg, - ...) + const char *msg, + ...) { - va_list args; - va_start(args, msg); - Parser *parser = static_cast<Parser *>(userData); - parser->Error(VALIDATION_ERROR, msg, args); - va_end(args); + va_list args; + va_start(args, msg); + Parser *parser = static_cast<Parser *>(userData); + parser->Error(VALIDATION_ERROR, msg, args); + va_end(args); } void Parser::Error(void *userData, - const char *msg, - ...) + const char *msg, + ...) { - va_list args; - va_start(args, msg); - Parser *parser = static_cast<Parser *>(userData); - parser->Error(PARSE_ERROR, msg, args); - va_end(args); + va_list args; + va_start(args, msg); + Parser *parser = static_cast<Parser *>(userData); + parser->Error(PARSE_ERROR, msg, args); + va_end(args); } void Parser::Warning(void *userData, - const char *msg, - ...) + const char *msg, + ...) { - va_list args; - va_start(args, msg); - Parser &parser = *(static_cast<Parser *>(userData)); - parser.Error(PARSE_WARNING, msg, args); - va_end(args); + va_list args; + va_start(args, msg); + Parser &parser = *(static_cast<Parser *>(userData)); + parser.Error(PARSE_WARNING, msg, args); + va_end(args); } // // -------------------------- end of static wrappers -------------------------- diff --git a/src/manager/initial-values/parser.h b/src/manager/initial-values/parser.h index ab80f0eb..072b911a 100644 --- a/src/manager/initial-values/parser.h +++ b/src/manager/initial-values/parser.h @@ -37,92 +37,92 @@ namespace XML { class Parser { public: - enum ErrorCode { - PARSE_SUCCESS = 0, - ERROR_UNKNOWN = -1000, - ERROR_XML_VALIDATION_FAILED = -1001, - ERROR_XSD_PARSE_FAILED = -1002, - ERROR_XML_PARSE_FAILED = -1003, - ERROR_INVALID_ARGUMENT = -1004, - ERROR_CALLBACK_PRESENT = -1005, - ERROR_INVALID_VERSION = -1006, - ERROR_INTERNAL = -1007, - ERROR_NO_MEMORY = -1008 - }; - - explicit Parser(const std::string &XML_filename); - virtual ~Parser(); - - int Validate(const std::string &XSD_schema); - int Parse(); - - enum ErrorType { - VALIDATION_ERROR, - PARSE_ERROR, - PARSE_WARNING - }; - typedef std::function<void (const ErrorType, const std::string &)> ErrorCb; - int RegisterErrorCb(const ErrorCb newCb); - - typedef std::map<std::string, std::string> Attributes; - class ElementHandler { - public: - virtual ~ElementHandler() {} - - // methods below may throw std::exception to invalidate the parsing process - // and remove all element listeners. - // In this case, parsing error code returned to the user after std::exception. - virtual void Start(const Attributes &) = 0; - virtual void Characters(const std::string & data) = 0; - virtual void End() = 0; - }; - typedef std::shared_ptr<ElementHandler> ElementHandlerPtr; - - typedef std::function<ElementHandlerPtr ()> StartCb; - typedef std::function<void (const ElementHandlerPtr &)> EndCb; - int RegisterElementCb(const char * elementName, - const StartCb startCb, - const EndCb endCb); + enum ErrorCode { + PARSE_SUCCESS = 0, + ERROR_UNKNOWN = -1000, + ERROR_XML_VALIDATION_FAILED = -1001, + ERROR_XSD_PARSE_FAILED = -1002, + ERROR_XML_PARSE_FAILED = -1003, + ERROR_INVALID_ARGUMENT = -1004, + ERROR_CALLBACK_PRESENT = -1005, + ERROR_INVALID_VERSION = -1006, + ERROR_INTERNAL = -1007, + ERROR_NO_MEMORY = -1008 + }; + + explicit Parser(const std::string &XML_filename); + virtual ~Parser(); + + int Validate(const std::string &XSD_schema); + int Parse(); + + enum ErrorType { + VALIDATION_ERROR, + PARSE_ERROR, + PARSE_WARNING + }; + typedef std::function<void (const ErrorType, const std::string &)> ErrorCb; + int RegisterErrorCb(const ErrorCb newCb); + + typedef std::map<std::string, std::string> Attributes; + class ElementHandler { + public: + virtual ~ElementHandler() {} + + // methods below may throw std::exception to invalidate the parsing process + // and remove all element listeners. + // In this case, parsing error code returned to the user after std::exception. + virtual void Start(const Attributes &) = 0; + virtual void Characters(const std::string &data) = 0; + virtual void End() = 0; + }; + typedef std::shared_ptr<ElementHandler> ElementHandlerPtr; + + typedef std::function<ElementHandlerPtr()> StartCb; + typedef std::function<void (const ElementHandlerPtr &)> EndCb; + int RegisterElementCb(const char *elementName, + const StartCb startCb, + const EndCb endCb); protected: - void StartElement(const xmlChar *name, - const xmlChar **attrs); - void EndElement(const xmlChar *name); - void Characters(const xmlChar *ch, size_t chLen); - void Error(const ErrorType errorType, const char *msg, va_list &); + void StartElement(const xmlChar *name, + const xmlChar **attrs); + void EndElement(const xmlChar *name); + void Characters(const xmlChar *ch, size_t chLen); + void Error(const ErrorType errorType, const char *msg, va_list &); private: - static void StartElement(void *userData, - const xmlChar *name, - const xmlChar **attrs); - static void EndElement(void *userData, - const xmlChar *name); - static void Characters(void *userData, - const xmlChar *ch, - int len); - static void ErrorValidate(void *userData, - const char *msg, - ...); - static void Error(void *userData, - const char *msg, - ...); - static void Warning(void *userData, - const char *msg, - ...); + static void StartElement(void *userData, + const xmlChar *name, + const xmlChar **attrs); + static void EndElement(void *userData, + const xmlChar *name); + static void Characters(void *userData, + const xmlChar *ch, + int len); + static void ErrorValidate(void *userData, + const char *msg, + ...); + static void Error(void *userData, + const char *msg, + ...); + static void Warning(void *userData, + const char *msg, + ...); private: - xmlSAXHandler m_saxHandler; - std::string m_XMLfile; - ErrorCb m_errorCb; - - struct ElementListener { - StartCb startCb; - EndCb endCb; - }; - std::map<std::string, ElementListener> m_elementListenerMap; - std::stack<ElementHandlerPtr> m_elementHandlerStack; - - void CallbackHelper(std::function<void(void)> func); + xmlSAXHandler m_saxHandler; + std::string m_XMLfile; + ErrorCb m_errorCb; + + struct ElementListener { + StartCb startCb; + EndCb endCb; + }; + std::map<std::string, ElementListener> m_elementListenerMap; + std::stack<ElementHandlerPtr> m_elementHandlerStack; + + void CallbackHelper(std::function<void(void)> func); }; } diff --git a/src/manager/initial-values/xml-utils.cpp b/src/manager/initial-values/xml-utils.cpp index e7a3a909..5e10b432 100644 --- a/src/manager/initial-values/xml-utils.cpp +++ b/src/manager/initial-values/xml-utils.cpp @@ -26,24 +26,24 @@ #include <xml-utils.h> namespace { -const char * const WHITESPACE = " \n\r\t\v"; -const char * const LINE_WHITESPACE = " \r\t\v"; +const char *const WHITESPACE = " \n\r\t\v"; +const char *const LINE_WHITESPACE = " \r\t\v"; -std::string trim_left(const std::string& s, const char *whitespaces) +std::string trim_left(const std::string &s, const char *whitespaces) { - size_t startpos = s.find_first_not_of(whitespaces); - return (startpos == std::string::npos) ? "" : s.substr(startpos); + size_t startpos = s.find_first_not_of(whitespaces); + return (startpos == std::string::npos) ? "" : s.substr(startpos); } -std::string trim_right(const std::string& s, const char *whitespaces) +std::string trim_right(const std::string &s, const char *whitespaces) { - size_t endpos = s.find_last_not_of(whitespaces); - return (endpos == std::string::npos) ? "" : s.substr(0, endpos+1); + size_t endpos = s.find_last_not_of(whitespaces); + return (endpos == std::string::npos) ? "" : s.substr(0, endpos + 1); } -std::string trim(const std::string& s, const char *whitespaces) +std::string trim(const std::string &s, const char *whitespaces) { - return trim_right(trim_left(s, whitespaces), whitespaces); + return trim_right(trim_left(s, whitespaces), whitespaces); } } @@ -52,45 +52,46 @@ namespace CKM { namespace XML { template <typename T> -T removeChars(const T& input, const char *what) +T removeChars(const T &input, const char *what) { - T out(input); - auto endit = std::remove_if(out.begin(), out.end(), - [what](char c) - { - for (const char *ptr = what; *ptr; ++ptr) - if (*ptr == c) - return true; - return false; - }); - - out.erase(endit, out.end()); - return out; + T out(input); + auto endit = std::remove_if(out.begin(), out.end(), + [what](char c) { + for (const char *ptr = what; *ptr; ++ptr) + if (*ptr == c) + return true; + + return false; + }); + + out.erase(endit, out.end()); + return out; } RawBuffer removeWhiteChars(const RawBuffer &buffer) { - return removeChars(buffer, WHITESPACE); + return removeChars(buffer, WHITESPACE); } -std::string trimEachLine(const std::string& input) +std::string trimEachLine(const std::string &input) { - std::stringstream ss(input); - std::stringstream output; - std::string line; + std::stringstream ss(input); + std::stringstream output; + std::string line; - while (std::getline(ss, line, '\n')) { - auto afterTrim = ::trim(line, LINE_WHITESPACE); - if (!afterTrim.empty()) - output << afterTrim << std::endl; - } + while (std::getline(ss, line, '\n')) { + auto afterTrim = ::trim(line, LINE_WHITESPACE); - return output.str(); + if (!afterTrim.empty()) + output << afterTrim << std::endl; + } + + return output.str(); } std::string trim(const std::string &s) { - return removeChars(s, WHITESPACE); + return removeChars(s, WHITESPACE); } } // namespace XML diff --git a/src/manager/initial-values/xml-utils.h b/src/manager/initial-values/xml-utils.h index 94385954..cd7cdd39 100644 --- a/src/manager/initial-values/xml-utils.h +++ b/src/manager/initial-values/xml-utils.h @@ -29,7 +29,7 @@ namespace CKM { namespace XML { RawBuffer removeWhiteChars(const RawBuffer &buffer); -std::string trim(const std::string& s); +std::string trim(const std::string &s); std::string trimEachLine(const std::string &s); } diff --git a/src/manager/main/communication-manager.h b/src/manager/main/communication-manager.h index 92a0a1be..f2702c4f 100644 --- a/src/manager/main/communication-manager.h +++ b/src/manager/main/communication-manager.h @@ -33,31 +33,32 @@ namespace CKM { template <typename M> class MessageManager { public: - NONCOPYABLE(MessageManager); + NONCOPYABLE(MessageManager); - // Listener is an object callable with const M& as argument - template <typename L> - void Register(L&& listener) - { - m_listeners.push_back(std::move(listener)); - } + // Listener is an object callable with const M& as argument + template <typename L> + void Register(L &&listener) + { + m_listeners.push_back(std::move(listener)); + } - // Sends message of type M to all registered listeners - // Returns the number of listeners called - size_t SendMessage(const M& msg) const - { - for (auto& it : m_listeners) - it(msg); - return m_listeners.size(); - } + // Sends message of type M to all registered listeners + // Returns the number of listeners called + size_t SendMessage(const M &msg) const + { + for (auto &it : m_listeners) + it(msg); + + return m_listeners.size(); + } protected: - MessageManager() {} - // No one is going to destroy this class directly (only via inherited class). Hence no 'virtual' - ~MessageManager() {} + MessageManager() {} + // No one is going to destroy this class directly (only via inherited class). Hence no 'virtual' + ~MessageManager() {} private: - std::list<std::function<void(const M&)>> m_listeners; + std::list<std::function<void(const M &)>> m_listeners; }; // generic template declaration @@ -70,25 +71,25 @@ struct CommunicationManager; */ template <typename First, typename... Args> struct CommunicationManager<First, Args...> : - public MessageManager<First>, public CommunicationManager<Args...> { + public MessageManager<First>, public CommunicationManager<Args...> { public: - CommunicationManager() {} - NONCOPYABLE(CommunicationManager); + CommunicationManager() {} + NONCOPYABLE(CommunicationManager); - // M - message type, L - listener to register - template <typename M, typename L> - void Register(L&& listener) - { - MessageManager<M>::Register(std::move(listener)); - } + // M - message type, L - listener to register + template <typename M, typename L> + void Register(L &&listener) + { + MessageManager<M>::Register(std::move(listener)); + } - // M message type - // Sending a message calls an unknown listener callback on the receiving side. It may throw. - template <typename M> - size_t SendMessage(const M& msg) const - { - return MessageManager<M>::SendMessage(msg); - } + // M message type + // Sending a message calls an unknown listener callback on the receiving side. It may throw. + template <typename M> + size_t SendMessage(const M &msg) const + { + return MessageManager<M>::SendMessage(msg); + } }; // stop condition for recursive inheritance diff --git a/src/manager/main/credentials.h b/src/manager/main/credentials.h index e54f5dfd..bae9c852 100644 --- a/src/manager/main/credentials.h +++ b/src/manager/main/credentials.h @@ -27,11 +27,11 @@ namespace CKM { struct Credentials { - Credentials() : clientUid(0) {} - Credentials(uid_t socketUid, const Label & socketLabel) - : clientUid(socketUid), smackLabel(socketLabel) {} - uid_t clientUid; - Label smackLabel; + Credentials() : clientUid(0) {} + Credentials(uid_t socketUid, const Label &socketLabel) + : clientUid(socketUid), smackLabel(socketLabel) {} + uid_t clientUid; + Label smackLabel; }; } // namespace CKM diff --git a/src/manager/main/cynara-mockup.cpp b/src/manager/main/cynara-mockup.cpp index ecd84ab3..733bae2f 100644 --- a/src/manager/main/cynara-mockup.cpp +++ b/src/manager/main/cynara-mockup.cpp @@ -26,19 +26,19 @@ namespace CKM { Cynara::Cynara(GenericSocketManager *socketManager) : - m_socketManager(socketManager), - m_cynara(nullptr) + m_socketManager(socketManager), + m_cynara(nullptr) { } void Cynara::Request( - const std::string &, - const std::string &, - const std::string &, - const std::string &, - StatusCallback callback) + const std::string &, + const std::string &, + const std::string &, + const std::string &, + StatusCallback callback) { - callback(true); + callback(true); } void Cynara::ProcessSocket() {} @@ -46,56 +46,56 @@ void Cynara::ProcessSocket() {} Cynara::~Cynara() {} void Cynara::ChangeStatus( - int, - int, - cynara_async_status) + int, + int, + cynara_async_status) { } void Cynara::ProcessResponse( - cynara_check_id, - cynara_async_call_cause, - int) + cynara_check_id, + cynara_async_call_cause, + int) { } void Cynara::SendRequest( - const std::string &, - const std::string &, - const std::string &, - const std::string &, - StatusCallback) + const std::string &, + const std::string &, + const std::string &, + const std::string &, + StatusCallback) { } void Cynara::ChangeStatusCallback( - int, - int, - cynara_async_status, - void *) + int, + int, + cynara_async_status, + void *) { } void Cynara::ProcessResponseCallback( - cynara_check_id, - cynara_async_call_cause, - int, - void *) + cynara_check_id, + cynara_async_call_cause, + int, + void *) { } bool Cynara::GetUserFromSocket( - int, - std::string &) + int, + std::string &) { - return true; + return true; } bool Cynara::GetClientFromSocket( - int, - std::string &) + int, + std::string &) { - return true; + return true; } } // namespace CKM diff --git a/src/manager/main/cynara.cpp b/src/manager/main/cynara.cpp index a4c30be6..c25031fe 100644 --- a/src/manager/main/cynara.cpp +++ b/src/manager/main/cynara.cpp @@ -31,141 +31,150 @@ namespace CKM { Cynara::Cynara(GenericSocketManager *socketManager) - : m_socketManager(socketManager) - , m_cynara(nullptr) + : m_socketManager(socketManager) + , m_cynara(nullptr) { - if (CYNARA_API_SUCCESS != cynara_async_initialize(&m_cynara, NULL, ChangeStatusCallback, this)) { - LogError("Cynara initialization failed."); - throw std::runtime_error("Cynara initialization failed."); - } + if (CYNARA_API_SUCCESS != cynara_async_initialize(&m_cynara, NULL, + ChangeStatusCallback, this)) { + LogError("Cynara initialization failed."); + throw std::runtime_error("Cynara initialization failed."); + } } void Cynara::Request( - const std::string &user, - const std::string &client, - const std::string &session, - const std::string &privilege, - StatusCallback callback) + const std::string &user, + const std::string &client, + const std::string &session, + const std::string &privilege, + StatusCallback callback) { - int ret = cynara_async_check_cache( - m_cynara, - client.c_str(), - session.c_str(), - user.c_str(), - privilege.c_str()); - - switch (ret) { - default: - case CYNARA_API_ACCESS_DENIED: - callback(false); - break; - case CYNARA_API_ACCESS_ALLOWED: - callback(true); - break; - case CYNARA_API_CACHE_MISS: - SendRequest( - user, - client, - session, - privilege, - std::move(callback)); - } + int ret = cynara_async_check_cache( + m_cynara, + client.c_str(), + session.c_str(), + user.c_str(), + privilege.c_str()); + + switch (ret) { + default: + case CYNARA_API_ACCESS_DENIED: + callback(false); + break; + + case CYNARA_API_ACCESS_ALLOWED: + callback(true); + break; + + case CYNARA_API_CACHE_MISS: + SendRequest( + user, + client, + session, + privilege, + std::move(callback)); + } } void Cynara::ProcessSocket() { - if (CYNARA_API_SUCCESS != cynara_async_process(m_cynara)) - LogError("Function: cynara_async_process failed."); + if (CYNARA_API_SUCCESS != cynara_async_process(m_cynara)) + LogError("Function: cynara_async_process failed."); } Cynara::~Cynara() { - cynara_async_finish(m_cynara); + cynara_async_finish(m_cynara); } void Cynara::ChangeStatus(int oldFd, int newFd, cynara_async_status status) { - m_socketManager->CynaraSocket(oldFd, newFd, status == CYNARA_STATUS_FOR_RW); + m_socketManager->CynaraSocket(oldFd, newFd, status == CYNARA_STATUS_FOR_RW); } void Cynara::ProcessResponse( - cynara_check_id checkId, - cynara_async_call_cause cause, - int response) + cynara_check_id checkId, + cynara_async_call_cause cause, + int response) { - auto it = m_callbackMap.find(checkId); + auto it = m_callbackMap.find(checkId); - if (it == m_callbackMap.end()) - return; + if (it == m_callbackMap.end()) + return; - if (cause == CYNARA_CALL_CAUSE_ANSWER && response == CYNARA_API_ACCESS_ALLOWED) - it->second(true); - else - it->second(false); + if (cause == CYNARA_CALL_CAUSE_ANSWER && response == CYNARA_API_ACCESS_ALLOWED) + it->second(true); + else + it->second(false); - m_callbackMap.erase(it); + m_callbackMap.erase(it); } void Cynara::SendRequest( - const std::string &user, - const std::string &client, - const std::string &session, - const std::string &privilege, - StatusCallback callback) + const std::string &user, + const std::string &client, + const std::string &session, + const std::string &privilege, + StatusCallback callback) { - cynara_check_id checkId = 0; - int ret = cynara_async_create_request( - m_cynara, - client.c_str(), - session.c_str(), - user.c_str(), - privilege.c_str(), - &checkId, - ProcessResponseCallback, - this); - - if (ret != CYNARA_API_SUCCESS) - return callback(false); - - m_callbackMap.emplace(checkId, std::move(callback)); + cynara_check_id checkId = 0; + int ret = cynara_async_create_request( + m_cynara, + client.c_str(), + session.c_str(), + user.c_str(), + privilege.c_str(), + &checkId, + ProcessResponseCallback, + this); + + if (ret != CYNARA_API_SUCCESS) + return callback(false); + + m_callbackMap.emplace(checkId, std::move(callback)); } void Cynara::ChangeStatusCallback( - int oldFd, - int newFd, - cynara_async_status status, - void *ptr) + int oldFd, + int newFd, + cynara_async_status status, + void *ptr) { - static_cast<Cynara*>(ptr)->ChangeStatus(oldFd, newFd, status); + static_cast<Cynara *>(ptr)->ChangeStatus(oldFd, newFd, status); } void Cynara::ProcessResponseCallback( - cynara_check_id checkId, - cynara_async_call_cause cause, - int response, - void *ptr) + cynara_check_id checkId, + cynara_async_call_cause cause, + int response, + void *ptr) { - static_cast<Cynara*>(ptr)->ProcessResponse(checkId, cause, response); + static_cast<Cynara *>(ptr)->ProcessResponse(checkId, cause, response); } bool Cynara::GetUserFromSocket(int socket, std::string &user) { - char *ptr; - if (CYNARA_API_SUCCESS != cynara_creds_socket_get_user(socket, USER_METHOD_DEFAULT, &ptr)) - return false; - user = ptr; - free(ptr); - return true; + char *ptr; + + if (CYNARA_API_SUCCESS != cynara_creds_socket_get_user(socket, + USER_METHOD_DEFAULT, &ptr)) + return false; + + user = ptr; + free(ptr); + return true; } bool Cynara::GetClientFromSocket(int socket, std::string &client) { - char *ptr; - if (CYNARA_API_SUCCESS != cynara_creds_socket_get_client(socket, CLIENT_METHOD_DEFAULT, &ptr)) - return false; - client = ptr; - free(ptr); - return true; + char *ptr; + + if (CYNARA_API_SUCCESS != cynara_creds_socket_get_client(socket, + CLIENT_METHOD_DEFAULT, &ptr)) + return false; + + client = ptr; + free(ptr); + return true; } } // namespace CKM diff --git a/src/manager/main/cynara.h b/src/manager/main/cynara.h index 80fd7f05..a873bd59 100644 --- a/src/manager/main/cynara.h +++ b/src/manager/main/cynara.h @@ -33,49 +33,50 @@ namespace CKM { class Cynara { public: - typedef std::function<void(bool)> StatusCallback; - explicit Cynara(GenericSocketManager *socketManager); + typedef std::function<void(bool)> StatusCallback; + explicit Cynara(GenericSocketManager *socketManager); - NONCOPYABLE(Cynara) + NONCOPYABLE(Cynara) - void Request( - const std::string &user, - const std::string &client, - const std::string &session, - const std::string &privilege, - StatusCallback callback); + void Request( + const std::string &user, + const std::string &client, + const std::string &session, + const std::string &privilege, + StatusCallback callback); - void ProcessSocket(); + void ProcessSocket(); - virtual ~Cynara(); + virtual ~Cynara(); - static bool GetUserFromSocket(int socket, std::string &user); - static bool GetClientFromSocket(int socket, std::string &client); + static bool GetUserFromSocket(int socket, std::string &user); + static bool GetClientFromSocket(int socket, std::string &client); protected: - void ChangeStatus(int oldFd, int newFd, cynara_async_status status); - void ProcessResponse(cynara_check_id checkId, cynara_async_call_cause cause, int response); - void SendRequest( - const std::string &user, - const std::string &client, - const std::string &session, - const std::string &privilege, - StatusCallback callback); - static void ChangeStatusCallback( - int oldFd, - int newFd, - cynara_async_status status, - void *ptr); + void ChangeStatus(int oldFd, int newFd, cynara_async_status status); + void ProcessResponse(cynara_check_id checkId, cynara_async_call_cause cause, + int response); + void SendRequest( + const std::string &user, + const std::string &client, + const std::string &session, + const std::string &privilege, + StatusCallback callback); + static void ChangeStatusCallback( + int oldFd, + int newFd, + cynara_async_status status, + void *ptr); - static void ProcessResponseCallback( - cynara_check_id checkId, - cynara_async_call_cause cause, - int response, - void *ptr); + static void ProcessResponseCallback( + cynara_check_id checkId, + cynara_async_call_cause cause, + int response, + void *ptr); - GenericSocketManager *m_socketManager; - cynara_async *m_cynara; - std::map<cynara_check_id, StatusCallback> m_callbackMap; + GenericSocketManager *m_socketManager; + cynara_async *m_cynara; + std::map<cynara_check_id, StatusCallback> m_callbackMap; }; } // namespace CKM diff --git a/src/manager/main/generic-event.h b/src/manager/main/generic-event.h index 7b98f7c5..b50a9609 100644 --- a/src/manager/main/generic-event.h +++ b/src/manager/main/generic-event.h @@ -29,7 +29,7 @@ namespace CKM { struct GenericEvent { - virtual ~GenericEvent(){} + virtual ~GenericEvent() {} }; } // namespace CKM diff --git a/src/manager/main/generic-socket-manager.h b/src/manager/main/generic-socket-manager.h index fab3d8a0..bc06bac8 100644 --- a/src/manager/main/generic-socket-manager.h +++ b/src/manager/main/generic-socket-manager.h @@ -39,7 +39,7 @@ #include <service-messages.h> extern "C" { -struct msghdr; + struct msghdr; } // extern "C" namespace CKM { @@ -47,98 +47,102 @@ namespace CKM { typedef int InterfaceID; struct ConnectionID { - int sock; // This is decriptor used for connection - int counter; // Unique handler per socket - inline bool operator<(const ConnectionID &second) const { - return counter < second.counter; - } + int sock; // This is decriptor used for connection + int counter; // Unique handler per socket + inline bool operator<(const ConnectionID &second) const + { + return counter < second.counter; + } }; struct GenericSocketManager; struct GenericSocketService { - typedef std::string ServiceHandlerPath; - struct ServiceDescription { - ServiceDescription(const char *path, - const char *privilege, - InterfaceID interfaceID = 0, - bool useSendMsg = false) - : privilege(privilege) - , interfaceID(interfaceID) - , serviceHandlerPath(path) - , useSendMsg(useSendMsg) - {} - - std::string privilege; // privilege for socket - InterfaceID interfaceID; // All data from serviceHandlerPath will be marked with this interfaceHandler - ServiceHandlerPath serviceHandlerPath; // Path to file - bool useSendMsg; - }; - - typedef std::vector<ServiceDescription> ServiceDescriptionVector; - - struct AcceptEvent : public GenericEvent { - ConnectionID connectionID; - InterfaceID interfaceID; - Credentials credentials; - }; - - struct WriteEvent : public GenericEvent { - ConnectionID connectionID; - size_t size; - size_t left; - }; - - struct ReadEvent : public GenericEvent { - ConnectionID connectionID; - RawBuffer rawBuffer; - }; - - struct CloseEvent : public GenericEvent { - ConnectionID connectionID; - }; - - struct SecurityEvent : public GenericEvent { - ConnectionID connectionID; - bool allowed; - }; - - virtual void SetSocketManager(GenericSocketManager *manager) - { - m_serviceManager = manager; - } - - virtual void SetCommManager(CommMgr *manager) - { - m_commMgr = manager; - } - - virtual ServiceDescriptionVector GetServiceDescription() = 0; - virtual void Event(const AcceptEvent &event) = 0; - virtual void Event(const WriteEvent &event) = 0; - virtual void Event(const ReadEvent &event) = 0; - virtual void Event(const CloseEvent &event) = 0; - virtual void Event(const SecurityEvent &event) = 0; - - virtual void Start() = 0; - virtual void Stop() = 0; - - GenericSocketService() : m_serviceManager(NULL), m_commMgr(NULL) {} - virtual ~GenericSocketService() {} + typedef std::string ServiceHandlerPath; + struct ServiceDescription { + ServiceDescription(const char *path, + const char *privilege, + InterfaceID interfaceID = 0, + bool useSendMsg = false) : + privilege(privilege), + interfaceID(interfaceID), + serviceHandlerPath(path), + useSendMsg(useSendMsg) {} + + std::string privilege; + + // All data from serviceHandlerPath will be marked with this interfaceHandler + InterfaceID interfaceID; + + // Path to file + ServiceHandlerPath serviceHandlerPath; + bool useSendMsg; + }; + + typedef std::vector<ServiceDescription> ServiceDescriptionVector; + + struct AcceptEvent : public GenericEvent { + ConnectionID connectionID; + InterfaceID interfaceID; + Credentials credentials; + }; + + struct WriteEvent : public GenericEvent { + ConnectionID connectionID; + size_t size; + size_t left; + }; + + struct ReadEvent : public GenericEvent { + ConnectionID connectionID; + RawBuffer rawBuffer; + }; + + struct CloseEvent : public GenericEvent { + ConnectionID connectionID; + }; + + struct SecurityEvent : public GenericEvent { + ConnectionID connectionID; + bool allowed; + }; + + virtual void SetSocketManager(GenericSocketManager *manager) + { + m_serviceManager = manager; + } + + virtual void SetCommManager(CommMgr *manager) + { + m_commMgr = manager; + } + + virtual ServiceDescriptionVector GetServiceDescription() = 0; + virtual void Event(const AcceptEvent &event) = 0; + virtual void Event(const WriteEvent &event) = 0; + virtual void Event(const ReadEvent &event) = 0; + virtual void Event(const CloseEvent &event) = 0; + virtual void Event(const SecurityEvent &event) = 0; + + virtual void Start() = 0; + virtual void Stop() = 0; + + GenericSocketService() : m_serviceManager(NULL), m_commMgr(NULL) {} + virtual ~GenericSocketService() {} protected: - GenericSocketManager *m_serviceManager; - CommMgr *m_commMgr; + GenericSocketManager *m_serviceManager; + CommMgr *m_commMgr; }; struct GenericSocketManager { - virtual void MainLoop() = 0; - virtual void RegisterSocketService(GenericSocketService *ptr) = 0; - virtual void CynaraSocket(int oldFd, int newFd, bool isRW) = 0; - virtual void Close(ConnectionID connectionID) = 0; - virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer) = 0; - virtual void SecurityCheck(ConnectionID connectionID) = 0; - virtual ~GenericSocketManager(){} + virtual void MainLoop() = 0; + virtual void RegisterSocketService(GenericSocketService *ptr) = 0; + virtual void CynaraSocket(int oldFd, int newFd, bool isRW) = 0; + virtual void Close(ConnectionID connectionID) = 0; + virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer) = 0; + virtual void SecurityCheck(ConnectionID connectionID) = 0; + virtual ~GenericSocketManager() {} }; } // namespace CKM diff --git a/src/manager/main/key-manager-main.cpp b/src/manager/main/key-manager-main.cpp index e9c87a4e..47b5c34c 100644 --- a/src/manager/main/key-manager-main.cpp +++ b/src/manager/main/key-manager-main.cpp @@ -37,79 +37,86 @@ #include <file-system.h> #define REGISTER_SOCKET_SERVICE(manager, service) \ - registerSocketService<service>(manager, #service) + registerSocketService<service>(manager, #service) template<typename T> -void registerSocketService(CKM::SocketManager &manager, const std::string& serviceName) +void registerSocketService(CKM::SocketManager &manager, + const std::string &serviceName) { - T *service = NULL; - try { - service = new T(); - service->Start(); - manager.RegisterSocketService(service); - service = NULL; - } catch (const CKM::Exception &exception) { - LogError("Error in creating service " << serviceName << - ", details:\n" << exception.DumpToString()); - } catch (const std::exception& e) { - LogError("Error in creating service " << serviceName << - ", details:\n" << e.what()); - } catch (...) { - LogError("Error in creating service " << serviceName << - ", unknown exception occured"); - } - if (service) - delete service; + T *service = NULL; + + try { + service = new T(); + service->Start(); + manager.RegisterSocketService(service); + service = NULL; + } catch (const CKM::Exception &exception) { + LogError("Error in creating service " << serviceName << + ", details:\n" << exception.DumpToString()); + } catch (const std::exception &e) { + LogError("Error in creating service " << serviceName << + ", details:\n" << e.what()); + } catch (...) { + LogError("Error in creating service " << serviceName << + ", unknown exception occured"); + } + + if (service) + delete service; } int main(void) { - UNHANDLED_EXCEPTION_HANDLER_BEGIN - { - CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM"); - - int retCode = CKM::FileSystem::init(); - if (retCode) { - LogError("Fatal error in FileSystem::init()"); - return 1; - } - - CKM::FileLock fl = CKM::FileSystem::lock(); - - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGPIPE); - if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) { - LogError("Error in pthread_sigmask"); - return 1; - } - LogInfo("Init external libraries SKMM and openssl"); - - CKM::initOpenSsl(); - - CKM::KeyProvider::initializeLibrary(); - - { - LogInfo("Start!"); - CKM::SocketManager manager; - - REGISTER_SOCKET_SERVICE(manager, CKM::CKMService); - REGISTER_SOCKET_SERVICE(manager, CKM::OCSPService); - REGISTER_SOCKET_SERVICE(manager, CKM::EncryptionService); - REGISTER_SOCKET_SERVICE(manager, CKM::GLIBService); - - manager.MainLoop(); - } - // Manager has been destroyed and we may close external libraries. - LogInfo("Deinit SKMM and openssl"); - CKM::KeyProvider::closeLibrary(); - - CKM::deinitOpenSsl(); - } catch (const std::runtime_error& e) { - LogError(e.what()); - } - UNHANDLED_EXCEPTION_HANDLER_END - return 0; -} + try { + CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM"); + + int retCode = CKM::FileSystem::init(); + + if (retCode) { + LogError("Fatal error in FileSystem::init()"); + return 1; + } + + CKM::FileLock fl = CKM::FileSystem::lock(); + + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGPIPE); + + if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) { + LogError("Error in pthread_sigmask"); + return 1; + } + + LogInfo("Init external libraries SKMM and openssl"); + + CKM::initOpenSsl(); + CKM::KeyProvider::initializeLibrary(); + + { + LogInfo("Start!"); + CKM::SocketManager manager; + + REGISTER_SOCKET_SERVICE(manager, CKM::CKMService); + REGISTER_SOCKET_SERVICE(manager, CKM::OCSPService); + REGISTER_SOCKET_SERVICE(manager, CKM::EncryptionService); + REGISTER_SOCKET_SERVICE(manager, CKM::GLIBService); + + manager.MainLoop(); + } + + // Manager has been destroyed and we may close external libraries. + LogInfo("Deinit SKMM and openssl"); + CKM::KeyProvider::closeLibrary(); + + CKM::deinitOpenSsl(); + } catch (const std::runtime_error &e) { + LogError(e.what()); + } + + UNHANDLED_EXCEPTION_HANDLER_END + + return 0; +} diff --git a/src/manager/main/message-service.h b/src/manager/main/message-service.h index ab046acd..fc36cc6d 100644 --- a/src/manager/main/message-service.h +++ b/src/manager/main/message-service.h @@ -44,22 +44,23 @@ class MessageService; // aggregating template template <typename Msg, typename ...Msgs> -class MessageService<Msg, Msgs...> : public MessageService<Msg>, public MessageService<Msgs...> { +class MessageService<Msg, Msgs...> : public MessageService<Msg>, + public MessageService<Msgs...> { protected: - // RECEIVER THREAD - template <typename Mgr> - void Register(Mgr& mgr) - { - MessageService<Msg>::Register(mgr); - MessageService<Msgs...>::Register(mgr); - } - - // RECEIVER THREAD - void CheckMessages() - { - MessageService<Msg>::CheckMessages(); - MessageService<Msgs...>::CheckMessages(); - } + // RECEIVER THREAD + template <typename Mgr> + void Register(Mgr &mgr) + { + MessageService<Msg>::Register(mgr); + MessageService<Msgs...>::Register(mgr); + } + + // RECEIVER THREAD + void CheckMessages() + { + MessageService<Msg>::CheckMessages(); + MessageService<Msgs...>::CheckMessages(); + } }; @@ -67,98 +68,105 @@ protected: template <typename Msg> class MessageService<Msg> { public: - MessageService() {} - virtual ~MessageService() {} - NONCOPYABLE(MessageService); + MessageService() {} + virtual ~MessageService() {} + NONCOPYABLE(MessageService); protected: - // RECEIVER THREAD: register as a listener of Msg - template <typename Mgr> - void Register(Mgr& mgr); + // RECEIVER THREAD: register as a listener of Msg + template <typename Mgr> + void Register(Mgr &mgr); - // SENDER THREAD: notify about new message - virtual void Notify() = 0; + // SENDER THREAD: notify about new message + virtual void Notify() = 0; - // RECEIVER THREAD: check if there are new messages and process each of them - void CheckMessages(); + // RECEIVER THREAD: check if there are new messages and process each of them + void CheckMessages(); - // RECEIVER THREAD: process single message - virtual void ProcessMessage(Msg msg) = 0; + // RECEIVER THREAD: process single message + virtual void ProcessMessage(Msg msg) = 0; private: - // SENDER THREAD: add message to the list - void AddMessage(const Msg& msg); + // SENDER THREAD: add message to the list + void AddMessage(const Msg &msg); - std::mutex m_messagesMutex; - std::list<Msg> m_messages; + std::mutex m_messagesMutex; + std::list<Msg> m_messages; }; template <typename Msg> template <typename Mgr> -void MessageService<Msg>::Register(Mgr& mgr) +void MessageService<Msg>::Register(Mgr &mgr) { - mgr.Register<Msg>([this](const Msg& msg) { this->AddMessage(msg); }); + mgr.Register<Msg>([this](const Msg & msg) { + this->AddMessage(msg); + }); } template <typename Msg> -void MessageService<Msg>::AddMessage(const Msg& msg) +void MessageService<Msg>::AddMessage(const Msg &msg) { - m_messagesMutex.lock(); - m_messages.push_back(msg); - m_messagesMutex.unlock(); - Notify(); // notify about added message + m_messagesMutex.lock(); + m_messages.push_back(msg); + m_messagesMutex.unlock(); + Notify(); // notify about added message } template <typename Msg> void MessageService<Msg>::CheckMessages() { - while (true) { - m_messagesMutex.lock(); - if (m_messages.empty()) { - m_messagesMutex.unlock(); - break; - } - // move out the first message - Msg message = std::move(m_messages.front()); - m_messages.pop_front(); - m_messagesMutex.unlock(); - - try { - ProcessMessage(std::move(message)); - } catch(...) { - LogError("Uncaught exception in ProcessMessage"); - } - } + while (true) { + m_messagesMutex.lock(); + + if (m_messages.empty()) { + m_messagesMutex.unlock(); + break; + } + + // move out the first message + Msg message = std::move(m_messages.front()); + m_messages.pop_front(); + m_messagesMutex.unlock(); + + try { + ProcessMessage(std::move(message)); + } catch (...) { + LogError("Uncaught exception in ProcessMessage"); + } + } } // thread based service with messages support template <typename ...Msgs> -class ThreadMessageService : public ThreadService, public MessageService<Msgs...> { +class ThreadMessageService : public ThreadService, + public MessageService<Msgs...> { public: - ThreadMessageService() {} - virtual ~ThreadMessageService() {} - NONCOPYABLE(ThreadMessageService); + ThreadMessageService() {} + virtual ~ThreadMessageService() {} + NONCOPYABLE(ThreadMessageService); - // RECEIVER THREAD: register as a listener of all supported messages - template <typename Mgr> - void Register(Mgr& mgr) - { - MessageService<Msgs...>::Register(mgr); - } + // RECEIVER THREAD: register as a listener of all supported messages + template <typename Mgr> + void Register(Mgr &mgr) + { + MessageService<Msgs...>::Register(mgr); + } private: - // SENDER THREAD: adds callback to RECEIVER THREAD event queue and wakes it - virtual void Notify() - { - CreateEvent([this]() { this->CheckMessages(); }); - } - - // RECEIVER THREAD - void CheckMessages() - { - MessageService<Msgs...>::CheckMessages(); - } + // SENDER THREAD: adds callback to RECEIVER THREAD event queue and wakes it + virtual void Notify() + { + CreateEvent([this]() { + this->CheckMessages(); + }); + } + + // RECEIVER THREAD + void CheckMessages() + { + MessageService<Msgs...>::CheckMessages(); + } }; } /* namespace CKM */ diff --git a/src/manager/main/service-messages.h b/src/manager/main/service-messages.h index f7021a4c..0815f6df 100644 --- a/src/manager/main/service-messages.h +++ b/src/manager/main/service-messages.h @@ -35,54 +35,42 @@ namespace CKM { // inter-service communication message base class struct MsgBase { - explicit MsgBase(int id) : id(id) {} - virtual ~MsgBase() {} + explicit MsgBase(int id) : id(id) {} + virtual ~MsgBase() {} - int id; + int id; }; // key request struct MsgKeyRequest : public MsgBase { - MsgKeyRequest(int id, - const Credentials& cred, - const Name& name, - const Label& label, - const Password& password) : - MsgBase(id), - cred(cred), - name(name), - label(label), - password(password) - { - } + MsgKeyRequest(int id, const Credentials &cred, const Name &name, + const Label &label, const Password &password) : + MsgBase(id), cred(cred), name(name), label(label), password(password) {} - Credentials cred; - Name name; - Label label; - Password password; + Credentials cred; + Name name; + Label label; + Password password; }; // key response struct MsgKeyResponse : public MsgBase { - MsgKeyResponse(int id, const Crypto::GObjShPtr& key, int errorCode = CKM_API_SUCCESS) : - MsgBase(id), - key(key), - error(errorCode) - { - } + MsgKeyResponse(int id, const Crypto::GObjShPtr &key, + int errorCode = CKM_API_SUCCESS) : + MsgBase(id), key(key), error(errorCode) {} - Crypto::GObjShPtr key; - int error; + Crypto::GObjShPtr key; + int error; }; struct MsgRemoveAppData { - explicit MsgRemoveAppData(std::string pkgIdT) - : pkgId(std::move(pkgIdT)) - {} + explicit MsgRemoveAppData(std::string pkgIdT) : + pkgId(std::move(pkgIdT)) {} - std::string pkgId; + std::string pkgId; }; -typedef CommunicationManager<MsgKeyRequest, MsgKeyResponse, MsgRemoveAppData> CommMgr; +using CommMgr = + CommunicationManager<MsgKeyRequest, MsgKeyResponse, MsgRemoveAppData>; } /* namespace CKM */ diff --git a/src/manager/main/service-thread.h b/src/manager/main/service-thread.h index b459b96e..a1b9d0c9 100644 --- a/src/manager/main/service-thread.h +++ b/src/manager/main/service-thread.h @@ -46,99 +46,103 @@ namespace CKM { class ServiceThread { public: - typedef std::function<void(void)> EventDescription; - enum class State { - NoThread, - Work, - }; - - ServiceThread() - : m_state(State::NoThread) - , m_quit(false) - { - } - - void Create() - { - assert(m_state == State::NoThread); - m_thread = std::thread(ThreadLoopStatic, this); - m_state = State::Work; - } - - void Join() - { - assert(m_state != State::NoThread); - { - std::lock_guard<std::mutex> lock(m_eventQueueMutex); - m_quit = true; - m_waitCondition.notify_one(); - } - m_thread.join(); - m_state = State::NoThread; - } - - virtual ~ServiceThread() - { - assert((m_state == State::NoThread) && "Thread was not stopped before ServiceThread destruction!"); - } + typedef std::function<void(void)> EventDescription; + enum class State { + NoThread, + Work, + }; + + ServiceThread() : m_state(State::NoThread), m_quit(false) {} + + void Create() + { + assert(m_state == State::NoThread); + m_thread = std::thread(ThreadLoopStatic, this); + m_state = State::Work; + } + + void Join() + { + assert(m_state != State::NoThread); + + { + std::lock_guard<std::mutex> lock(this->m_eventQueueMutex); + m_quit = true; + m_waitCondition.notify_one(); + } + + m_thread.join(); + m_state = State::NoThread; + } + + virtual ~ServiceThread() + { + assert((m_state == State::NoThread) && + "Thread was not stopped before ServiceThread destruction!"); + } protected: - /* - * This function is always called from ThreadService::ThreadEvent where fun - * is created as a temporary object and therefore will not be copied. - */ - void CreateEvent(std::function<void(void)> fun) - { - EventDescription description; - description = std::move(fun); - { - std::lock_guard<std::mutex> lock(m_eventQueueMutex); - m_eventQueue.push(description); - } - m_waitCondition.notify_one(); - } - - static void ThreadLoopStatic(ServiceThread *ptr) - { - ptr->ThreadLoop(); - - // cleanup openssl in every thread - deinitOpenSslThread(); - } - - void ThreadLoop() - { - for (;;) { - EventDescription description; - { - std::unique_lock<std::mutex> ulock(m_eventQueueMutex); - if (m_quit) - return; - if (!m_eventQueue.empty()) { - description = m_eventQueue.front(); - m_eventQueue.pop(); - } else { - m_waitCondition.wait(ulock); - } - } - - if (description) { - UNHANDLED_EXCEPTION_HANDLER_BEGIN - { - description(); - } - UNHANDLED_EXCEPTION_HANDLER_END - } - } - } - - std::thread m_thread; - std::mutex m_eventQueueMutex; - std::queue<EventDescription> m_eventQueue; - std::condition_variable m_waitCondition; - - State m_state; - bool m_quit; + /* + * This function is always called from ThreadService::ThreadEvent where fun + * is created as a temporary object and therefore will not be copied. + */ + void CreateEvent(std::function<void(void)> fun) + { + EventDescription description; + description = std::move(fun); + + { + std::lock_guard<std::mutex> lock(this->m_eventQueueMutex); + m_eventQueue.push(description); + } + + m_waitCondition.notify_one(); + } + + static void ThreadLoopStatic(ServiceThread *ptr) + { + ptr->ThreadLoop(); + + // cleanup openssl in every thread + deinitOpenSslThread(); + } + + void ThreadLoop() + { + while (true) { + EventDescription description; + + { + std::unique_lock<std::mutex> ulock(m_eventQueueMutex); + + if (m_quit) + return; + + if (!m_eventQueue.empty()) { + description = m_eventQueue.front(); + m_eventQueue.pop(); + } else { + m_waitCondition.wait(ulock); + } + } + + if (description) { + try { + description(); + } + + UNHANDLED_EXCEPTION_HANDLER_END + } + } + } + + std::thread m_thread; + std::mutex m_eventQueueMutex; + std::queue<EventDescription> m_eventQueue; + std::condition_variable m_waitCondition; + + State m_state; + bool m_quit; }; } // namespace CKM diff --git a/src/manager/main/smack-check.cpp b/src/manager/main/smack-check.cpp index ce7899a6..70f71da7 100644 --- a/src/manager/main/smack-check.cpp +++ b/src/manager/main/smack-check.cpp @@ -9,25 +9,27 @@ namespace CKM { int smack_runtime_check(void) { - static int smack_present = -1; - if (-1 == smack_present) { - if (NULL == smack_smackfs_path()) { - LogDebug("no smack found on device"); - smack_present = 0; - } else { - LogDebug("found smack on device"); - smack_present = 1; - } - } - return smack_present; + static int smack_present = -1; + + if (-1 == smack_present) { + if (NULL == smack_smackfs_path()) { + LogDebug("no smack found on device"); + smack_present = 0; + } else { + LogDebug("found smack on device"); + smack_present = 1; + } + } + + return smack_present; } int smack_check(void) { #ifndef SMACK_ENABLED - return 0; + return 0; #else - return smack_runtime_check(); + return smack_runtime_check(); #endif } diff --git a/src/manager/main/socket-2-id-mockup.cpp b/src/manager/main/socket-2-id-mockup.cpp index 8f596802..6b21a32e 100644 --- a/src/manager/main/socket-2-id-mockup.cpp +++ b/src/manager/main/socket-2-id-mockup.cpp @@ -26,48 +26,50 @@ namespace { -int getPkgIdFromSmack(const std::string &smack, std::string &pkgId) { - static const std::string SMACK_PREFIX_APPID = "User::App::"; - - if (smack.empty()) { - LogError("Smack is empty. Connection will be rejected"); - return -1; - } - - if (smack.compare(0, SMACK_PREFIX_APPID.size(), SMACK_PREFIX_APPID)) { - pkgId = "/" + smack; - LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId); - return 0; - } - - std::string appId = smack.substr(SMACK_PREFIX_APPID.size(), std::string::npos); - - if (appId.empty()) { - LogError("After conversion (smack->pkgId) pkgId is empty. Label: " << appId); - return -1; - } - - pkgId = std::move(appId); - LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId); - return 0; +int getPkgIdFromSmack(const std::string &smack, std::string &pkgId) +{ + static const std::string SMACK_PREFIX_APPID = "User::App::"; + + if (smack.empty()) { + LogError("Smack is empty. Connection will be rejected"); + return -1; + } + + if (smack.compare(0, SMACK_PREFIX_APPID.size(), SMACK_PREFIX_APPID)) { + pkgId = "/" + smack; + LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId); + return 0; + } + + std::string appId = smack.substr(SMACK_PREFIX_APPID.size(), std::string::npos); + + if (appId.empty()) { + LogError("After conversion (smack->pkgId) pkgId is empty. Label: " << appId); + return -1; + } + + pkgId = std::move(appId); + LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId); + return 0; } } // namespace anonymous namespace CKM { -int Socket2Id::translate(int sock, std::string &result) { - std::string smack; - std::string pkgId; +int Socket2Id::translate(int sock, std::string &result) +{ + std::string smack; + std::string pkgId; - if (0 > getCredentialsFromSocket(sock, smack)) - return -1; + if (0 > getCredentialsFromSocket(sock, smack)) + return -1; - if (0 > getPkgIdFromSmack(smack, pkgId)) - return -1; + if (0 > getPkgIdFromSmack(smack, pkgId)) + return -1; - result = std::move(pkgId); - return 0; + result = std::move(pkgId); + return 0; } } // namespace CKM diff --git a/src/manager/main/socket-2-id-wrapper.cpp b/src/manager/main/socket-2-id-wrapper.cpp index c6590e78..3d30c4b7 100644 --- a/src/manager/main/socket-2-id-wrapper.cpp +++ b/src/manager/main/socket-2-id-wrapper.cpp @@ -28,60 +28,62 @@ namespace { -int getPkgIdFromSocket(int sock, std::string &pkgId) { - char *pkg = nullptr; - - int ret = security_manager_identify_app_from_socket(sock, &pkg, nullptr); - - if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) { - LogInfo("Owner of socket is not connected with pkgid. " - "This case must be special-labled client. e.g. User, System"); - return 1; - } - - if (ret != SECURITY_MANAGER_SUCCESS) { - LogError("security_manager_identify_app_from_socket failed with error: " - << ret); - return -1; - } - - pkgId = pkg; - free(pkg); - LogDebug("Socket: " << sock << " Was translated to owner id: " << pkgId); - return 0; +int getPkgIdFromSocket(int sock, std::string &pkgId) +{ + char *pkg = nullptr; + + int ret = security_manager_identify_app_from_socket(sock, &pkg, nullptr); + + if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) { + LogInfo("Owner of socket is not connected with pkgid. " + "This case must be special-labled client. e.g. User, System"); + return 1; + } + + if (ret != SECURITY_MANAGER_SUCCESS) { + LogError("security_manager_identify_app_from_socket failed with error: " + << ret); + return -1; + } + + pkgId = pkg; + free(pkg); + LogDebug("Socket: " << sock << " Was translated to owner id: " << pkgId); + return 0; } } // namespace anonymous namespace CKM { -int Socket2Id::translate(int sock, std::string &result) { - std::string smack; +int Socket2Id::translate(int sock, std::string &result) +{ + std::string smack; - if (0 > getCredentialsFromSocket(sock, smack)) - return -1; + if (0 > getCredentialsFromSocket(sock, smack)) + return -1; - StringMap::iterator it = m_stringMap.find(smack); + StringMap::iterator it = m_stringMap.find(smack); - if (it != m_stringMap.end()) { - result = it->second; - return 0; - } + if (it != m_stringMap.end()) { + result = it->second; + return 0; + } - std::string pkgId; - int retCode = getPkgIdFromSocket(sock, pkgId); + std::string pkgId; + int retCode = getPkgIdFromSocket(sock, pkgId); - if (retCode < 0) - return -1; + if (retCode < 0) + return -1; - if (retCode == 1) { - LogInfo("Special smack label case. label: " << smack); - pkgId = "/" + smack; - } + if (retCode == 1) { + LogInfo("Special smack label case. label: " << smack); + pkgId = "/" + smack; + } - result = pkgId; - m_stringMap.emplace(std::move(smack), std::move(pkgId)); - return 0; + result = pkgId; + m_stringMap.emplace(std::move(smack), std::move(pkgId)); + return 0; } } // namespace CKM diff --git a/src/manager/main/socket-2-id.cpp b/src/manager/main/socket-2-id.cpp index b71f88be..a9efe1b0 100644 --- a/src/manager/main/socket-2-id.cpp +++ b/src/manager/main/socket-2-id.cpp @@ -32,46 +32,47 @@ namespace { int assignToString(std::vector<char> &vec, socklen_t len, std::string &res) { - if (vec.size() <= len) - return -1; + if (vec.size() <= len) + return -1; - vec[len] = 0; // old implementation getsockopt returns cstring without 0 + vec[len] = + 0; // old implementation getsockopt returns cstring without 0 - if (vec[len-1] == 0) - --len; // new implementation of getsockopt returns cstring size+1 + if (vec[len - 1] == 0) + --len; // new implementation of getsockopt returns cstring size+1 - res.assign(vec.data(), len); - return 0; + res.assign(vec.data(), len); + return 0; } } // namespace anonymous int Socket2Id::getCredentialsFromSocket(int sock, std::string &res) { - std::vector<char> result(SMACK_LABEL_LEN+1); - socklen_t length = SMACK_LABEL_LEN; + std::vector<char> result(SMACK_LABEL_LEN + 1); + socklen_t length = SMACK_LABEL_LEN; - if (0 == getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) - return assignToString(result, length, res); + if (0 == getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) + return assignToString(result, length, res); - if (errno != ERANGE) { - LogError("getsockopt failed"); - return -1; - } + if (errno != ERANGE) { + LogError("getsockopt failed"); + return -1; + } - result.resize(length+1); + result.resize(length + 1); - if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) { - LogError("getsockopt failed with errno: " << errno); - return -1; - } + if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) { + LogError("getsockopt failed with errno: " << errno); + return -1; + } - return assignToString(result, length, res); + return assignToString(result, length, res); } void Socket2Id::resetCache() { - m_stringMap.clear(); + m_stringMap.clear(); } } // namespace CKM diff --git a/src/manager/main/socket-2-id.h b/src/manager/main/socket-2-id.h index 1fe025de..afa863ab 100644 --- a/src/manager/main/socket-2-id.h +++ b/src/manager/main/socket-2-id.h @@ -27,18 +27,18 @@ namespace CKM { class Socket2Id { public: - Socket2Id() {} + Socket2Id() {} - int translate(int sock, std::string &result); - void resetCache(); + int translate(int sock, std::string &result); + void resetCache(); - virtual ~Socket2Id() {} + virtual ~Socket2Id() {} private: - int getCredentialsFromSocket(int sock, std::string &res); + int getCredentialsFromSocket(int sock, std::string &res); - typedef std::map<std::string, std::string> StringMap; - StringMap m_stringMap; + typedef std::map<std::string, std::string> StringMap; + StringMap m_stringMap; }; } // namespace CKM diff --git a/src/manager/main/socket-manager.cpp b/src/manager/main/socket-manager.cpp index ab566cf2..9f20f62f 100644 --- a/src/manager/main/socket-manager.cpp +++ b/src/manager/main/socket-manager.cpp @@ -50,22 +50,22 @@ const time_t SOCKET_TIMEOUT = 1000; int getCredentialsFromSocket(int sock, CKM::Credentials &cred) { - static CKM::Socket2Id sock2id; - std::string ownerId; + static CKM::Socket2Id sock2id; + std::string ownerId; - if (0 > sock2id.translate(sock, ownerId)) - return -1; + if (0 > sock2id.translate(sock, ownerId)) + return -1; - ucred peerCred; - socklen_t length = sizeof(ucred); + ucred peerCred; + socklen_t length = sizeof(ucred); - if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) { - LogError("getsockopt failed"); - return -1; - } + if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) { + LogError("getsockopt failed"); + return -1; + } - cred = CKM::Credentials(peerCred.uid, std::move(ownerId)); - return 0; + cred = CKM::Credentials(peerCred.uid, std::move(ownerId)); + return 0; } } // namespace anonymous @@ -73,720 +73,754 @@ int getCredentialsFromSocket(int sock, CKM::Credentials &cred) namespace CKM { struct DummyService : public GenericSocketService { - ServiceDescriptionVector GetServiceDescription() - { - return ServiceDescriptionVector(); - } - - void Start() {} - void Stop() {} - - void Event(const AcceptEvent &) {} - void Event(const WriteEvent &) {} - void Event(const ReadEvent &) {} - void Event(const CloseEvent &) {} - void Event(const SecurityEvent &) {} + ServiceDescriptionVector GetServiceDescription() + { + return ServiceDescriptionVector(); + } + + void Start() {} + void Stop() {} + + void Event(const AcceptEvent &) {} + void Event(const WriteEvent &) {} + void Event(const ReadEvent &) {} + void Event(const CloseEvent &) {} + void Event(const SecurityEvent &) {} }; struct SignalService : public GenericSocketService { - int GetDescriptor() - { - LogInfo("set up"); - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) - return -1; - return signalfd(-1, &mask, 0); - } - - ServiceDescriptionVector GetServiceDescription() - { - return ServiceDescriptionVector(); - } - - void Start() {} - void Stop() {} - - void Event(const AcceptEvent &) {} // not supported - void Event(const WriteEvent &) {} // not supported - void Event(const CloseEvent &) {} // not supported - void Event(const SecurityEvent &) {} // not supported - - void Event(const ReadEvent &event) - { - LogDebug("Get signal information"); - - if (sizeof(struct signalfd_siginfo) != event.rawBuffer.size()) { - LogError("Wrong size of signalfd_siginfo struct. Expected: " - << sizeof(signalfd_siginfo) << " Get: " - << event.rawBuffer.size()); - return; - } - - signalfd_siginfo *siginfo = (signalfd_siginfo*)(&(event.rawBuffer[0])); - - if (siginfo->ssi_signo == SIGTERM) { - LogInfo("Got signal: SIGTERM"); - static_cast<SocketManager*>(m_serviceManager)->MainLoopStop(); - return; - } - - LogInfo("This should not happend. Got signal: " << siginfo->ssi_signo); - } + int GetDescriptor() + { + LogInfo("set up"); + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); + + if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) + return -1; + + return signalfd(-1, &mask, 0); + } + + ServiceDescriptionVector GetServiceDescription() + { + return ServiceDescriptionVector(); + } + + void Start() {} + void Stop() {} + + void Event(const AcceptEvent &) {} // not supported + void Event(const WriteEvent &) {} // not supported + void Event(const CloseEvent &) {} // not supported + void Event(const SecurityEvent &) {} // not supported + + void Event(const ReadEvent &event) + { + LogDebug("Get signal information"); + + if (sizeof(struct signalfd_siginfo) != event.rawBuffer.size()) { + LogError("Wrong size of signalfd_siginfo struct. Expected: " + << sizeof(signalfd_siginfo) << " Get: " + << event.rawBuffer.size()); + return; + } + + auto siginfo = reinterpret_cast<const signalfd_siginfo *> + (event.rawBuffer.data()); + + if (siginfo->ssi_signo == SIGTERM) { + LogInfo("Got signal: SIGTERM"); + dynamic_cast<SocketManager *>(m_serviceManager)->MainLoopStop(); + return; + } + + LogInfo("This should not happend. Got signal: " << siginfo->ssi_signo); + } }; -SocketManager::SocketDescription& +SocketManager::SocketDescription & SocketManager::CreateDefaultReadSocketDescription(int sock, bool timeout) { - if ((int)m_socketDescriptionVector.size() <= sock) - m_socketDescriptionVector.resize(sock+20); - - auto &desc = m_socketDescriptionVector[sock]; - desc.setListen(false); - desc.setOpen(true); - desc.setCynara(false); - desc.interfaceID = 0; - desc.service = NULL; - desc.counter = ++m_counter; - - if (timeout) { - desc.timeout = time(NULL) + SOCKET_TIMEOUT; - Timeout tm; - tm.time = desc.timeout; - tm.sock = sock; - m_timeoutQueue.push(tm); - } - - desc.setTimeout(timeout); - - FD_SET(sock, &m_readSet); - m_maxDesc = sock > m_maxDesc ? sock : m_maxDesc; - return desc; + if ((int)m_socketDescriptionVector.size() <= sock) + m_socketDescriptionVector.resize(sock + 20); + + auto &desc = m_socketDescriptionVector[sock]; + desc.setListen(false); + desc.setOpen(true); + desc.setCynara(false); + desc.interfaceID = 0; + desc.service = NULL; + desc.counter = ++m_counter; + + if (timeout) { + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + Timeout tm; + tm.time = desc.timeout; + tm.sock = sock; + m_timeoutQueue.push(tm); + } + + desc.setTimeout(timeout); + + FD_SET(sock, &m_readSet); + m_maxDesc = sock > m_maxDesc ? sock : m_maxDesc; + return desc; } SocketManager::SocketManager() : - m_maxDesc(0), - m_working(true), - m_counter(0) + m_maxDesc(0), + m_working(true), + m_counter(0) { - FD_ZERO(&m_readSet); - FD_ZERO(&m_writeSet); - - if (-1 == pipe(m_notifyMe)) { - int err = errno; - ThrowMsg(Exception::InitFailed, "Error in pipe: " << GetErrnoString(err)); - } - - LogInfo("Pipe: Read desc: " << m_notifyMe[0] << " Write desc: " << m_notifyMe[1]); - - auto &desc = CreateDefaultReadSocketDescription(m_notifyMe[0], false); - desc.service = new DummyService; - m_serviceVector.push_back(desc.service); - - // std::thread bases on pthread so this should work fine - sigset_t set; - sigemptyset(&set); - sigaddset(&set, SIGPIPE); - pthread_sigmask(SIG_BLOCK, &set, NULL); - - // add support for TERM signal (passed from systemd) - auto *signalService = new SignalService; - signalService->SetSocketManager(this); - int filefd = signalService->GetDescriptor(); - - if (-1 == filefd) { - LogError("Error in SignalService.GetDescriptor()"); - delete signalService; - } else { - auto &desc2 = CreateDefaultReadSocketDescription(filefd, false); - desc2.service = signalService; - LogInfo("SignalService mounted on " << filefd << " descriptor"); - } - - if (signalService) - m_serviceVector.push_back(signalService); - - // We cannot create Cynara earlier because descriptors are not initialized! - m_cynara.reset(new Cynara(this)); + FD_ZERO(&m_readSet); + FD_ZERO(&m_writeSet); + + if (-1 == pipe(m_notifyMe)) { + int err = errno; + ThrowMsg(Exception::InitFailed, "Error in pipe: " << GetErrnoString(err)); + } + + LogInfo("Pipe: Read desc: " << m_notifyMe[0] << " Write desc: " << + m_notifyMe[1]); + + auto &desc = CreateDefaultReadSocketDescription(m_notifyMe[0], false); + desc.service = new DummyService; + m_serviceVector.push_back(desc.service); + + // std::thread bases on pthread so this should work fine + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + // add support for TERM signal (passed from systemd) + auto *signalService = new SignalService; + signalService->SetSocketManager(this); + int filefd = signalService->GetDescriptor(); + + if (-1 == filefd) { + LogError("Error in SignalService.GetDescriptor()"); + delete signalService; + } else { + auto &desc2 = CreateDefaultReadSocketDescription(filefd, false); + desc2.service = signalService; + LogInfo("SignalService mounted on " << filefd << " descriptor"); + } + + if (signalService) + m_serviceVector.push_back(signalService); + + // We cannot create Cynara earlier because descriptors are not initialized! + m_cynara.reset(new Cynara(this)); } SocketManager::~SocketManager() { - m_cynara.reset(nullptr); - - // Time to destroy all services. - for (auto service : m_serviceVector) { - LogDebug("delete " << (void*)(service)); - if (service) - service->Stop(); - delete service; - } - - for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i) - if (m_socketDescriptionVector[i].isOpen()) - close(i); - - // All socket except one were closed. Now pipe input must be closed. - close(m_notifyMe[1]); + m_cynara.reset(nullptr); + + // Time to destroy all services. + for (auto service : m_serviceVector) { + LogDebug("delete " << (void *)(service)); + + if (service) + service->Stop(); + + delete service; + } + + for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i) + if (m_socketDescriptionVector[i].isOpen()) + close(i); + + // All socket except one were closed. Now pipe input must be closed. + close(m_notifyMe[1]); } void SocketManager::ReadyForAccept(int sock) { - struct sockaddr_un clientAddr; - unsigned int clientLen = sizeof(clientAddr); - int client = accept4(sock, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK); - - if (-1 == client) { - int err = errno; - LogDebug("Error in accept: " << GetErrnoString(err)); - return; - } - - std::string smack; - std::string user; - Credentials peerCred; - - if (0 > getCredentialsFromSocket(client, peerCred) - || !Cynara::GetUserFromSocket(client, user) - || !Cynara::GetClientFromSocket(client, smack)) { - LogDebug("Error in getting credentials from socket."); - TEMP_FAILURE_RETRY(close(client)); - return; - } - - auto &desc = CreateDefaultReadSocketDescription(client, true); - desc.interfaceID = m_socketDescriptionVector[sock].interfaceID; - desc.service = m_socketDescriptionVector[sock].service; - desc.cynaraPrivilege = m_socketDescriptionVector[sock].cynaraPrivilege; - desc.cynaraUser = std::move(user); - desc.cynaraClient = std::move(smack); - - GenericSocketService::AcceptEvent event; - event.connectionID.sock = client; - event.connectionID.counter = desc.counter; - event.interfaceID = desc.interfaceID; - event.credentials = peerCred; - desc.service->Event(event); + struct sockaddr_un clientAddr; + unsigned int clientLen = sizeof(clientAddr); + int client = accept4(sock, (struct sockaddr *) &clientAddr, &clientLen, + SOCK_NONBLOCK); + + if (-1 == client) { + int err = errno; + LogDebug("Error in accept: " << GetErrnoString(err)); + return; + } + + std::string smack; + std::string user; + Credentials peerCred; + + if (0 > getCredentialsFromSocket(client, peerCred) + || !Cynara::GetUserFromSocket(client, user) + || !Cynara::GetClientFromSocket(client, smack)) { + LogDebug("Error in getting credentials from socket."); + TEMP_FAILURE_RETRY(close(client)); + return; + } + + auto &desc = CreateDefaultReadSocketDescription(client, true); + desc.interfaceID = m_socketDescriptionVector[sock].interfaceID; + desc.service = m_socketDescriptionVector[sock].service; + desc.cynaraPrivilege = m_socketDescriptionVector[sock].cynaraPrivilege; + desc.cynaraUser = std::move(user); + desc.cynaraClient = std::move(smack); + + GenericSocketService::AcceptEvent event; + event.connectionID.sock = client; + event.connectionID.counter = desc.counter; + event.interfaceID = desc.interfaceID; + event.credentials = peerCred; + desc.service->Event(event); } void SocketManager::SecurityStatus(int sock, int counter, bool allowed) { - auto &desc = m_socketDescriptionVector[sock]; - if (!desc.isOpen()) { - LogDebug("Client from socket " << sock << - " closed connection before cynara answer was received."); - return; - } - - if (desc.counter != counter) { - LogDebug("Client from socket " << sock << - " closed connection before cynara answer was received."); - return; - } - - GenericSocketService::SecurityEvent event; - event.connectionID.sock = sock; - event.connectionID.counter = counter; - event.allowed = allowed; - desc.service->Event(event); + auto &desc = m_socketDescriptionVector[sock]; + + if (!desc.isOpen()) { + LogDebug("Client from socket " << sock << + " closed connection before cynara answer was received."); + return; + } + + if (desc.counter != counter) { + LogDebug("Client from socket " << sock << + " closed connection before cynara answer was received."); + return; + } + + GenericSocketService::SecurityEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = counter; + event.allowed = allowed; + desc.service->Event(event); } void SocketManager::ReadyForRead(int sock) { - if (m_socketDescriptionVector[sock].isListen()) { - ReadyForAccept(sock); - return; - } - - if (m_socketDescriptionVector[sock].isCynara()) { - m_cynara->ProcessSocket(); - return; - } - - GenericSocketService::ReadEvent event; - event.connectionID.sock = sock; - event.connectionID.counter = m_socketDescriptionVector[sock].counter; - event.rawBuffer.resize(4096); - - auto &desc = m_socketDescriptionVector[sock]; - desc.timeout = time(NULL) + SOCKET_TIMEOUT; - - ssize_t size = read(sock, &event.rawBuffer[0], 4096); - - if (size == 0) { - CloseSocket(sock); - } else if (size >= 0) { - event.rawBuffer.resize(size); - desc.service->Event(event); - } else if (size == -1) { - int err = errno; - switch (err) { - case EAGAIN: - case EINTR: - break; - default: - LogDebug("Reading sock error: " << GetErrnoString(err)); - CloseSocket(sock); - } - } + if (m_socketDescriptionVector[sock].isListen()) { + ReadyForAccept(sock); + return; + } + + if (m_socketDescriptionVector[sock].isCynara()) { + m_cynara->ProcessSocket(); + return; + } + + GenericSocketService::ReadEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = m_socketDescriptionVector[sock].counter; + event.rawBuffer.resize(4096); + + auto &desc = m_socketDescriptionVector[sock]; + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + + ssize_t size = read(sock, &event.rawBuffer[0], 4096); + + if (size == 0) { + CloseSocket(sock); + } else if (size >= 0) { + event.rawBuffer.resize(size); + desc.service->Event(event); + } else if (size == -1) { + int err = errno; + + switch (err) { + case EAGAIN: + case EINTR: + break; + + default: + LogDebug("Reading sock error: " << GetErrnoString(err)); + CloseSocket(sock); + } + } } void SocketManager::ReadyForWrite(int sock) { - if (m_socketDescriptionVector[sock].isCynara()) { - m_cynara->ProcessSocket(); - return; - } - - auto &desc = m_socketDescriptionVector[sock]; - size_t size = desc.rawBuffer.size(); - ssize_t result = write(sock, &desc.rawBuffer[0], size); - - if (result == -1) { - int err = errno; - switch (err) { - case EAGAIN: - case EINTR: - // select will trigger write once again, nothing to do - break; - case EPIPE: - default: - LogDebug("Error during write: " << GetErrnoString(err)); - CloseSocket(sock); - break; - } - return; // We do not want to propagate error to next layer - } - - desc.rawBuffer.erase(desc.rawBuffer.begin(), desc.rawBuffer.begin()+result); - - desc.timeout = time(NULL) + SOCKET_TIMEOUT; - - if (desc.rawBuffer.empty()) - FD_CLR(sock, &m_writeSet); - - GenericSocketService::WriteEvent event; - event.connectionID.sock = sock; - event.connectionID.counter = desc.counter; - event.size = result; - event.left = desc.rawBuffer.size(); - - desc.service->Event(event); + if (m_socketDescriptionVector[sock].isCynara()) { + m_cynara->ProcessSocket(); + return; + } + + auto &desc = m_socketDescriptionVector[sock]; + size_t size = desc.rawBuffer.size(); + ssize_t result = write(sock, &desc.rawBuffer[0], size); + + if (result == -1) { + int err = errno; + + switch (err) { + case EAGAIN: + case EINTR: + // select will trigger write once again, nothing to do + break; + + case EPIPE: + default: + LogDebug("Error during write: " << GetErrnoString(err)); + CloseSocket(sock); + break; + } + + return; // We do not want to propagate error to next layer + } + + desc.rawBuffer.erase(desc.rawBuffer.begin(), desc.rawBuffer.begin() + result); + + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + + if (desc.rawBuffer.empty()) + FD_CLR(sock, &m_writeSet); + + GenericSocketService::WriteEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = desc.counter; + event.size = result; + event.left = desc.rawBuffer.size(); + + desc.service->Event(event); } void SocketManager::MainLoop() { - // remove evironment values passed by systemd - sd_listen_fds(1); - - // Daemon is ready to work. - sd_notify(0, "READY=1"); - - m_working = true; - while (m_working) { - fd_set readSet = m_readSet; - fd_set writeSet = m_writeSet; - - timeval localTempTimeout; - timeval *ptrTimeout = &localTempTimeout; - - // I need to extract timeout from priority_queue. - // Timeout in priority_queue may be deprecated. - // I need to find some actual one. - while (!m_timeoutQueue.empty()) { - auto &top = m_timeoutQueue.top(); - auto &desc = m_socketDescriptionVector[top.sock]; - - if (top.time == desc.timeout) { - // This timeout matches timeout from socket. - // It can be used. - break; - } else { - // This socket was used after timeout in priority queue was set up. - // We need to update timeout and find some useable one. - Timeout tm = { desc.timeout , top.sock}; - m_timeoutQueue.pop(); - m_timeoutQueue.push(tm); - } - } - - if (m_timeoutQueue.empty()) { - LogDebug("No usaable timeout found."); - ptrTimeout = NULL; // select will wait without timeout - } else { - time_t currentTime = time(NULL); - auto &pqTimeout = m_timeoutQueue.top(); - - // 0 means that select won't block and socket will be closed ;-) - ptrTimeout->tv_sec = - currentTime < pqTimeout.time ? pqTimeout.time - currentTime : 0; - ptrTimeout->tv_usec = 0; - } - - int ret = select(m_maxDesc+1, &readSet, &writeSet, NULL, ptrTimeout); - - if (0 == ret) { // timeout - Assert(!m_timeoutQueue.empty()); - - Timeout pqTimeout = m_timeoutQueue.top(); - m_timeoutQueue.pop(); - - auto &desc = m_socketDescriptionVector[pqTimeout.sock]; - - if (!desc.isTimeout() || !desc.isOpen()) { - // Connection was closed. Timeout is useless... - desc.setTimeout(false); - continue; - } - - if (pqTimeout.time < desc.timeout) { - // Is it possible? - // This socket was used after timeout. We need to update timeout. - pqTimeout.time = desc.timeout; - m_timeoutQueue.push(pqTimeout); - continue; - } - - // timeout from m_timeoutQueue matches with socket.timeout - // and connection is open. Time to close it! - // Putting new timeout in queue here is pointless. - desc.setTimeout(false); - CloseSocket(pqTimeout.sock); - - // All done. Now we should process next select ;-) - continue; - } - - if (-1 == ret) { - switch (errno) { - case EINTR: - LogDebug("EINTR in select"); - break; - default: - int err = errno; - LogError("Error in select: " << GetErrnoString(err)); - return; - } - continue; - } - for (int i = 0; i < m_maxDesc+1 && ret; ++i) { - if (FD_ISSET(i, &readSet)) { - ReadyForRead(i); - --ret; - } - if (FD_ISSET(i, &writeSet)) { - ReadyForWrite(i); - --ret; - } - } - ProcessQueue(); - } + // remove evironment values passed by systemd + sd_listen_fds(1); + + // Daemon is ready to work. + sd_notify(0, "READY=1"); + + m_working = true; + + while (m_working) { + fd_set readSet = m_readSet; + fd_set writeSet = m_writeSet; + + timeval localTempTimeout; + timeval *ptrTimeout = &localTempTimeout; + + // I need to extract timeout from priority_queue. + // Timeout in priority_queue may be deprecated. + // I need to find some actual one. + while (!m_timeoutQueue.empty()) { + auto &top = m_timeoutQueue.top(); + auto &desc = m_socketDescriptionVector[top.sock]; + + if (top.time == desc.timeout) { + // This timeout matches timeout from socket. + // It can be used. + break; + } else { + // This socket was used after timeout in priority queue was set up. + // We need to update timeout and find some useable one. + Timeout tm = { desc.timeout , top.sock}; + m_timeoutQueue.pop(); + m_timeoutQueue.push(tm); + } + } + + if (m_timeoutQueue.empty()) { + LogDebug("No usaable timeout found."); + ptrTimeout = NULL; // select will wait without timeout + } else { + time_t currentTime = time(NULL); + auto &pqTimeout = m_timeoutQueue.top(); + + // 0 means that select won't block and socket will be closed ;-) + ptrTimeout->tv_sec = + currentTime < pqTimeout.time ? pqTimeout.time - currentTime : 0; + ptrTimeout->tv_usec = 0; + } + + int ret = select(m_maxDesc + 1, &readSet, &writeSet, NULL, ptrTimeout); + + if (0 == ret) { // timeout + Assert(!m_timeoutQueue.empty()); + + Timeout pqTimeout = m_timeoutQueue.top(); + m_timeoutQueue.pop(); + + auto &desc = m_socketDescriptionVector[pqTimeout.sock]; + + if (!desc.isTimeout() || !desc.isOpen()) { + // Connection was closed. Timeout is useless... + desc.setTimeout(false); + continue; + } + + if (pqTimeout.time < desc.timeout) { + // Is it possible? + // This socket was used after timeout. We need to update timeout. + pqTimeout.time = desc.timeout; + m_timeoutQueue.push(pqTimeout); + continue; + } + + // timeout from m_timeoutQueue matches with socket.timeout + // and connection is open. Time to close it! + // Putting new timeout in queue here is pointless. + desc.setTimeout(false); + CloseSocket(pqTimeout.sock); + + // All done. Now we should process next select ;-) + continue; + } + + if (-1 == ret) { + switch (errno) { + case EINTR: + LogDebug("EINTR in select"); + break; + + default: + int err = errno; + LogError("Error in select: " << GetErrnoString(err)); + return; + } + + continue; + } + + for (int i = 0; i < m_maxDesc + 1 && ret; ++i) { + if (FD_ISSET(i, &readSet)) { + ReadyForRead(i); + --ret; + } + + if (FD_ISSET(i, &writeSet)) { + ReadyForWrite(i); + --ret; + } + } + + ProcessQueue(); + } } void SocketManager::MainLoopStop() { - m_working = false; - NotifyMe(); + m_working = false; + NotifyMe(); } int SocketManager::GetSocketFromSystemD( - const GenericSocketService::ServiceDescription &desc) + const GenericSocketService::ServiceDescription &desc) { - int fd; - - // TODO optimalization - do it once in object constructor - // and remember all information path->sockfd - int n = sd_listen_fds(0); - - LogInfo("sd_listen_fds returns: " << n); - - if (n < 0) { - LogError("Error in sd_listend_fds"); - ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds"); - } - - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) { - if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, - desc.serviceHandlerPath.c_str(), 0)) { - LogInfo("Useable socket " << desc.serviceHandlerPath << - " was passed by SystemD under descriptor " << fd); - return fd; - } - } - LogError("No useable sockets were passed by systemd."); - return -1; + int fd; + + // TODO optimalization - do it once in object constructor + // and remember all information path->sockfd + int n = sd_listen_fds(0); + + LogInfo("sd_listen_fds returns: " << n); + + if (n < 0) { + LogError("Error in sd_listend_fds"); + ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds"); + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) { + if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, + desc.serviceHandlerPath.c_str(), 0)) { + LogInfo("Useable socket " << desc.serviceHandlerPath << + " was passed by SystemD under descriptor " << fd); + return fd; + } + } + + LogError("No useable sockets were passed by systemd."); + return -1; } int SocketManager::CreateDomainSocketHelp( - const GenericSocketService::ServiceDescription &desc) + const GenericSocketService::ServiceDescription &desc) { - int sockfd; - - if (desc.serviceHandlerPath.size()*sizeof(decltype(desc.serviceHandlerPath)::value_type) >= - sizeof(static_cast<sockaddr_un*>(0)->sun_path)) { - LogError("Service handler path too long: " << desc.serviceHandlerPath.size()); - ThrowMsg(Exception::InitFailed, - "Service handler path too long: " << desc.serviceHandlerPath.size()); - } - - if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) { - int err = errno; - LogError("Error in socket: " << GetErrnoString(err)); - ThrowMsg(Exception::InitFailed, "Error in socket: " << GetErrnoString(err)); - } - - if (smack_check()) { - LogInfo("Set up smack label: " << desc.privilege); - -// if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) { -// LogError("Error in smack_fsetlabel"); -// ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel"); -// } - } else { - LogInfo("No smack on platform. Socket won't be securied with smack label!"); - } - - int flags; - if (-1 == (flags = fcntl(sockfd, F_GETFL, 0))) - flags = 0; - - if (-1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) { - int err = errno; - close(sockfd); - LogError("Error in fcntl: " << GetErrnoString(err)); - ThrowMsg(Exception::InitFailed, "Error in fcntl: " << GetErrnoString(err)); - } - - sockaddr_un serverAddress; - memset(&serverAddress, 0, sizeof(serverAddress)); - serverAddress.sun_family = AF_UNIX; - strncpy(serverAddress.sun_path, desc.serviceHandlerPath.c_str(), sizeof(serverAddress.sun_path) - 1); - unlink(serverAddress.sun_path); - - mode_t originalUmask; - originalUmask = umask(0); - - if (-1 == bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress))) { - int err = errno; - close(sockfd); - LogError("Error in bind: " << GetErrnoString(err)); - ThrowMsg(Exception::InitFailed, "Error in bind: " << GetErrnoString(err)); - } - - umask(originalUmask); - - if (-1 == listen(sockfd, 5)) { - int err = errno; - close(sockfd); - LogError("Error in listen: " << GetErrnoString(err)); - ThrowMsg(Exception::InitFailed, "Error in listen: " << GetErrnoString(err)); - } - - return sockfd; + int sockfd; + + if (desc.serviceHandlerPath.size()*sizeof(decltype(desc.serviceHandlerPath) + ::value_type) >= + sizeof(static_cast<sockaddr_un *>(0)->sun_path)) { + LogError("Service handler path too long: " << desc.serviceHandlerPath.size()); + ThrowMsg(Exception::InitFailed, + "Service handler path too long: " << desc.serviceHandlerPath.size()); + } + + if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) { + int err = errno; + LogError("Error in socket: " << GetErrnoString(err)); + ThrowMsg(Exception::InitFailed, "Error in socket: " << GetErrnoString(err)); + } + + if (smack_check()) { + LogInfo("Set up smack label: " << desc.privilege); + + // if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) { + // LogError("Error in smack_fsetlabel"); + // ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel"); + // } + } else { + LogInfo("No smack on platform. Socket won't be securied with smack label!"); + } + + int flags; + + if (-1 == (flags = fcntl(sockfd, F_GETFL, 0))) + flags = 0; + + if (-1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) { + int err = errno; + close(sockfd); + LogError("Error in fcntl: " << GetErrnoString(err)); + ThrowMsg(Exception::InitFailed, "Error in fcntl: " << GetErrnoString(err)); + } + + sockaddr_un serverAddress; + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sun_family = AF_UNIX; + strncpy(serverAddress.sun_path, desc.serviceHandlerPath.c_str(), + sizeof(serverAddress.sun_path) - 1); + unlink(serverAddress.sun_path); + + mode_t originalUmask; + originalUmask = umask(0); + + if (-1 == bind(sockfd, (struct sockaddr *)&serverAddress, + sizeof(serverAddress))) { + int err = errno; + close(sockfd); + LogError("Error in bind: " << GetErrnoString(err)); + ThrowMsg(Exception::InitFailed, "Error in bind: " << GetErrnoString(err)); + } + + umask(originalUmask); + + if (-1 == listen(sockfd, 5)) { + int err = errno; + close(sockfd); + LogError("Error in listen: " << GetErrnoString(err)); + ThrowMsg(Exception::InitFailed, "Error in listen: " << GetErrnoString(err)); + } + + return sockfd; } void SocketManager::CreateDomainSocket( - GenericSocketService *service, - const GenericSocketService::ServiceDescription &desc) + GenericSocketService *service, + const GenericSocketService::ServiceDescription &desc) { - int sockfd = GetSocketFromSystemD(desc); - if (-1 == sockfd) - sockfd = CreateDomainSocketHelp(desc); + int sockfd = GetSocketFromSystemD(desc); + + if (-1 == sockfd) + sockfd = CreateDomainSocketHelp(desc); - auto &description = CreateDefaultReadSocketDescription(sockfd, false); + auto &description = CreateDefaultReadSocketDescription(sockfd, false); - description.setListen(true); - description.interfaceID = desc.interfaceID; - description.service = service; - description.cynaraPrivilege = desc.privilege; + description.setListen(true); + description.interfaceID = desc.interfaceID; + description.service = service; + description.cynaraPrivilege = desc.privilege; - LogDebug("Listen on socket: " << sockfd << - " Handler: " << desc.serviceHandlerPath.c_str()); + LogDebug("Listen on socket: " << sockfd << + " Handler: " << desc.serviceHandlerPath.c_str()); } void SocketManager::RegisterSocketService(GenericSocketService *service) { - service->SetSocketManager(this); - service->SetCommManager(&m_commMgr); - auto serviceVector = service->GetServiceDescription(); - m_serviceVector.push_back(service); - Try { - for (auto iter = serviceVector.begin(); iter != serviceVector.end(); ++iter) - CreateDomainSocket(service, *iter); - } Catch(Exception::Base) { - for (int i =0; i < (int)m_socketDescriptionVector.size(); ++i) { - auto &desc = m_socketDescriptionVector[i]; - if (desc.service == service && desc.isOpen()) { - close(i); - desc.setOpen(false); - } - } - ReThrow(Exception::Base); - } + service->SetSocketManager(this); + service->SetCommManager(&m_commMgr); + auto serviceVector = service->GetServiceDescription(); + m_serviceVector.push_back(service); + + try { + for (auto iter = serviceVector.begin(); iter != serviceVector.end(); ++iter) + CreateDomainSocket(service, *iter); + } catch (const Exception::Base &) { + for (int i = 0; i < (int)m_socketDescriptionVector.size(); ++i) { + auto &desc = m_socketDescriptionVector[i]; + + if (desc.service == service && desc.isOpen()) { + close(i); + desc.setOpen(false); + } + } + + throw; + } } void SocketManager::Close(ConnectionID connectionID) { - CloseEvent event; - event.sock = connectionID.sock; - event.counter = connectionID.counter; - AddEvent(event); + CloseEvent event; + event.sock = connectionID.sock; + event.counter = connectionID.counter; + AddEvent(event); } void SocketManager::Write(ConnectionID connectionID, const RawBuffer &rawBuffer) { - WriteEvent event{connectionID, rawBuffer}; - AddEvent(event); + WriteEvent event{connectionID, rawBuffer}; + AddEvent(event); } void SocketManager::SecurityCheck(ConnectionID connectionID) { - SecurityEvent event; - event.sock = connectionID.sock; - event.counter = connectionID.counter; - AddEvent(event); + SecurityEvent event; + event.sock = connectionID.sock; + event.counter = connectionID.counter; + AddEvent(event); } void SocketManager::CreateEvent(EventFunction fun) { - { - std::lock_guard<std::mutex> ulock(m_eventQueueMutex); - m_eventQueue.push(std::move(fun)); - } - NotifyMe(); + { + std::lock_guard<std::mutex> l(this->m_eventQueueMutex); + m_eventQueue.push(std::move(fun)); + } + + NotifyMe(); } void SocketManager::NotifyMe() { - TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1)); + TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1)); } void SocketManager::ProcessQueue() { - while (1) { - EventFunction fun; - { - std::lock_guard<std::mutex> ulock(m_eventQueueMutex); - if (m_eventQueue.empty()) - return; - fun = std::move(m_eventQueue.front()); - m_eventQueue.pop(); - } - fun(); - } + while (1) { + EventFunction fun; + + { + std::lock_guard<std::mutex> l(this->m_eventQueueMutex); + + if (m_eventQueue.empty()) + return; + + fun = std::move(m_eventQueue.front()); + m_eventQueue.pop(); + } + + fun(); + } } void SocketManager::Handle(const WriteEvent &event) { - auto &desc = m_socketDescriptionVector[event.connectionID.sock]; + auto &desc = m_socketDescriptionVector[event.connectionID.sock]; - if (!desc.isOpen()) { - LogDebug("Received packet for write but connection is closed. Packet ignored!"); - return; - } + if (!desc.isOpen()) { + LogDebug("Received packet for write but connection is closed. Packet ignored!"); + return; + } - if (desc.counter != event.connectionID.counter) { - LogDebug("Received packet for write but counter is broken. Packet ignored!"); - return; - } + if (desc.counter != event.connectionID.counter) { + LogDebug("Received packet for write but counter is broken. Packet ignored!"); + return; + } - std::copy( - event.rawBuffer.begin(), - event.rawBuffer.end(), - std::back_inserter(desc.rawBuffer)); + std::copy( + event.rawBuffer.begin(), + event.rawBuffer.end(), + std::back_inserter(desc.rawBuffer)); - FD_SET(event.connectionID.sock, &m_writeSet); + FD_SET(event.connectionID.sock, &m_writeSet); } void SocketManager::Handle(const CloseEvent &event) { - if (!m_socketDescriptionVector[event.sock].isOpen()) - return; + if (!m_socketDescriptionVector[event.sock].isOpen()) + return; - if (event.counter != m_socketDescriptionVector[event.sock].counter) - return; + if (event.counter != m_socketDescriptionVector[event.sock].counter) + return; - CloseSocket(event.sock); + CloseSocket(event.sock); } void SocketManager::Handle(const SecurityEvent &event) { - auto& desc = m_socketDescriptionVector[event.sock]; - if (!desc.isOpen()) - return; - - if (event.counter != desc.counter) - return; - - std::string session = std::to_string(desc.counter); - - m_cynara->Request(desc.cynaraUser, - desc.cynaraClient, - session, - desc.cynaraPrivilege, - [this, event](bool allowed) { - this->SecurityStatus(event.sock, event.counter, allowed); - }); + auto &desc = m_socketDescriptionVector[event.sock]; + + if (!desc.isOpen()) + return; + + if (event.counter != desc.counter) + return; + + std::string session = std::to_string(desc.counter); + + m_cynara->Request(desc.cynaraUser, + desc.cynaraClient, + session, + desc.cynaraPrivilege, + [this, event](bool allowed) { + this->SecurityStatus(event.sock, event.counter, allowed); + }); } void SocketManager::CloseSocket(int sock) { - auto &desc = m_socketDescriptionVector[sock]; - - if (!(desc.isOpen())) { - // This may happend when some information was waiting for write to the - // socket and in the same time socket was closed by the client. - LogError("Socket " << sock << " is not open. Nothing to do!"); - return; - } - - GenericSocketService::CloseEvent event; - event.connectionID.sock = sock; - event.connectionID.counter = desc.counter; - auto service = desc.service; - - desc.setOpen(false); - desc.service = NULL; - desc.interfaceID = -1; - desc.rawBuffer.clear(); - - if (service) - service->Event(event); - else - LogError("Critical! Service is NULL! This should never happend!"); - - TEMP_FAILURE_RETRY(close(sock)); - FD_CLR(sock, &m_readSet); - FD_CLR(sock, &m_writeSet); + auto &desc = m_socketDescriptionVector[sock]; + + if (!(desc.isOpen())) { + // This may happend when some information was waiting for write to the + // socket and in the same time socket was closed by the client. + LogError("Socket " << sock << " is not open. Nothing to do!"); + return; + } + + GenericSocketService::CloseEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = desc.counter; + auto service = desc.service; + + desc.setOpen(false); + desc.service = NULL; + desc.interfaceID = -1; + desc.rawBuffer.clear(); + + if (service) + service->Event(event); + else + LogError("Critical! Service is NULL! This should never happend!"); + + TEMP_FAILURE_RETRY(close(sock)); + FD_CLR(sock, &m_readSet); + FD_CLR(sock, &m_writeSet); } void SocketManager::CynaraSocket(int oldFd, int newFd, bool isRW) { - if (newFd != oldFd) { - if (newFd >= 0) { - auto &desc = CreateDefaultReadSocketDescription(newFd, false); - desc.service = nullptr; - desc.setCynara(true); - } - - if (oldFd >= 0) { - auto &old = m_socketDescriptionVector[oldFd]; - old.setOpen(false); - old.setCynara(false); - FD_CLR(oldFd, &m_writeSet); - FD_CLR(oldFd, &m_readSet); - } - } - - if (newFd >= 0) { - FD_SET(newFd, &m_readSet); - - if (isRW) - FD_SET(newFd, &m_writeSet); - else - FD_CLR(newFd, &m_writeSet); - } + if (newFd != oldFd) { + if (newFd >= 0) { + auto &desc = CreateDefaultReadSocketDescription(newFd, false); + desc.service = nullptr; + desc.setCynara(true); + } + + if (oldFd >= 0) { + auto &old = m_socketDescriptionVector[oldFd]; + old.setOpen(false); + old.setCynara(false); + FD_CLR(oldFd, &m_writeSet); + FD_CLR(oldFd, &m_readSet); + } + } + + if (newFd >= 0) { + FD_SET(newFd, &m_readSet); + + if (isRW) + FD_SET(newFd, &m_writeSet); + else + FD_CLR(newFd, &m_writeSet); + } } } // namespace CKM diff --git a/src/manager/main/socket-manager.h b/src/manager/main/socket-manager.h index 4e98dd5d..412d9f00 100644 --- a/src/manager/main/socket-manager.h +++ b/src/manager/main/socket-manager.h @@ -45,125 +45,156 @@ class Cynara; class SocketManager : public GenericSocketManager { public: - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, InitFailed) - }; + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InitFailed) + }; - SocketManager(); - virtual ~SocketManager(); - virtual void MainLoop(); - virtual void MainLoopStop(); + SocketManager(); + virtual ~SocketManager(); + virtual void MainLoop(); + virtual void MainLoopStop(); - virtual void CynaraSocket(int oldFd, int newFd, bool isRW); - void SecurityStatus(int sock, int counter, bool allowed); + virtual void CynaraSocket(int oldFd, int newFd, bool isRW); + void SecurityStatus(int sock, int counter, bool allowed); - virtual void RegisterSocketService(GenericSocketService *service); - virtual void Close(ConnectionID connectionID); - virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer); - virtual void SecurityCheck(ConnectionID connectionID); + virtual void RegisterSocketService(GenericSocketService *service); + virtual void Close(ConnectionID connectionID); + virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer); + virtual void SecurityCheck(ConnectionID connectionID); protected: - void CreateDomainSocket( - GenericSocketService *service, - const GenericSocketService::ServiceDescription &desc); - int CreateDomainSocketHelp( - const GenericSocketService::ServiceDescription &desc); - int GetSocketFromSystemD( - const GenericSocketService::ServiceDescription &desc); - - void ReadyForRead(int sock); - void ReadyForWrite(int sock); - void ReadyForAccept(int sock); - void ProcessQueue(void); - void NotifyMe(void); - void CloseSocket(int sock); - - struct SocketDescription { - bool isOpen() { return m_flags & OPEN; } - bool isListen() { return m_flags & LISTEN; } - bool isCynara() { return m_flags & CYNARA; } - bool isTimeout() { return m_flags & TIMEOUT; } - void setOpen(bool isSet) { isSet ? m_flags |= OPEN : m_flags &= ~OPEN; } - void setListen(bool isSet) { isSet ? m_flags |= LISTEN : m_flags &= ~LISTEN; } - void setCynara(bool isSet) { isSet ? m_flags |= CYNARA : m_flags &= ~CYNARA; } - void setTimeout(bool isSet) { isSet ? m_flags |= TIMEOUT : m_flags &= ~TIMEOUT; } - - InterfaceID interfaceID; - GenericSocketService *service; - time_t timeout; - RawBuffer rawBuffer; - int counter; - std::string cynaraPrivilege; - std::string cynaraUser; - std::string cynaraClient; - - SocketDescription() - : interfaceID(-1) - , service(nullptr) - , timeout(::time(nullptr)) - , counter(0) - , m_flags(0) - { - } - - private: - static const char LISTEN = 1 << 0; - static const char OPEN = 1 << 1; - static const char CYNARA = 1 << 2; - static const char TIMEOUT = 1 << 3; - int m_flags; - }; - - SocketDescription& CreateDefaultReadSocketDescription(int sock, bool timeout); - - typedef std::vector<SocketDescription> SocketDescriptionVector; - - // support for generic event Queue - typedef std::function<void(void)> EventFunction; - template <typename E> - void AddEvent(E event) - { - CreateEvent([this, event]() {this->Handle(event);}); - } - void CreateEvent(EventFunction fun); - - struct WriteEvent { - ConnectionID connectionID; - RawBuffer rawBuffer; - }; - - struct CloseEvent : public ConnectionID {}; - struct SecurityEvent : public ConnectionID {}; - - void Handle(const WriteEvent &event); - void Handle(const CloseEvent &event); - void Handle(const SecurityEvent &event); - // support for generic event Queue - - struct Timeout { - time_t time; - int sock; - bool operator<(const Timeout &second) const - { - return time > second.time; // mininum first! - } - }; - - SocketDescriptionVector m_socketDescriptionVector; - fd_set m_readSet; - fd_set m_writeSet; - int m_maxDesc; - bool m_working; - std::mutex m_eventQueueMutex; - std::queue<EventFunction> m_eventQueue; - int m_notifyMe[2]; - int m_counter; - std::priority_queue<Timeout> m_timeoutQueue; - CommMgr m_commMgr; - std::unique_ptr<Cynara> m_cynara; - std::vector<GenericSocketService*> m_serviceVector; + void CreateDomainSocket( + GenericSocketService *service, + const GenericSocketService::ServiceDescription &desc); + int CreateDomainSocketHelp( + const GenericSocketService::ServiceDescription &desc); + int GetSocketFromSystemD( + const GenericSocketService::ServiceDescription &desc); + + void ReadyForRead(int sock); + void ReadyForWrite(int sock); + void ReadyForAccept(int sock); + void ProcessQueue(void); + void NotifyMe(void); + void CloseSocket(int sock); + + struct SocketDescription { + bool isOpen() + { + return m_flags & OPEN; + } + + bool isListen() + { + return m_flags & LISTEN; + } + + bool isCynara() + { + return m_flags & CYNARA; + } + + bool isTimeout() + { + return m_flags & TIMEOUT; + } + + void setOpen(bool isSet) + { + isSet ? m_flags |= OPEN : m_flags &= ~OPEN; + } + + void setListen(bool isSet) + { + isSet ? m_flags |= LISTEN : m_flags &= ~LISTEN; + } + + void setCynara(bool isSet) + { + isSet ? m_flags |= CYNARA : m_flags &= ~CYNARA; + } + + void setTimeout(bool isSet) + { + isSet ? m_flags |= TIMEOUT : m_flags &= ~TIMEOUT; + } + + InterfaceID interfaceID; + GenericSocketService *service; + time_t timeout; + RawBuffer rawBuffer; + int counter; + std::string cynaraPrivilege; + std::string cynaraUser; + std::string cynaraClient; + + SocketDescription() : + interfaceID(-1), + service(nullptr), + timeout(::time(nullptr)), + counter(0), + m_flags(0) {} + + private: + static const char LISTEN = 1 << 0; + static const char OPEN = 1 << 1; + static const char CYNARA = 1 << 2; + static const char TIMEOUT = 1 << 3; + int m_flags; + }; + + SocketDescription &CreateDefaultReadSocketDescription(int sock, bool timeout); + + typedef std::vector<SocketDescription> SocketDescriptionVector; + + // support for generic event Queue + typedef std::function<void(void)> EventFunction; + template <typename E> + void AddEvent(E event) + { + CreateEvent([this, event]() { + this->Handle(event); + }); + } + void CreateEvent(EventFunction fun); + + struct WriteEvent { + ConnectionID connectionID; + RawBuffer rawBuffer; + }; + + struct CloseEvent : public ConnectionID {}; + struct SecurityEvent : public ConnectionID {}; + + void Handle(const WriteEvent &event); + void Handle(const CloseEvent &event); + void Handle(const SecurityEvent &event); + // support for generic event Queue + + struct Timeout { + time_t time; + int sock; + bool operator<(const Timeout &second) const + { + return time > second.time; // mininum first! + } + }; + + SocketDescriptionVector m_socketDescriptionVector; + fd_set m_readSet; + fd_set m_writeSet; + int m_maxDesc; + bool m_working; + std::mutex m_eventQueueMutex; + std::queue<EventFunction> m_eventQueue; + int m_notifyMe[2]; + int m_counter; + std::priority_queue<Timeout> m_timeoutQueue; + CommMgr m_commMgr; + std::unique_ptr<Cynara> m_cynara; + std::vector<GenericSocketService *> m_serviceVector; }; } // namespace CKM diff --git a/src/manager/main/thread-service.cpp b/src/manager/main/thread-service.cpp index 2e4e95d5..29d5d2d6 100644 --- a/src/manager/main/thread-service.cpp +++ b/src/manager/main/thread-service.cpp @@ -34,61 +34,62 @@ ThreadService::~ThreadService() void ThreadService::Handle(const AcceptEvent &event) { - LogDebug("Accept event"); - auto &info = m_connectionInfoMap[event.connectionID.counter]; - info.interfaceID = event.interfaceID; - info.credentials = event.credentials; + LogDebug("Accept event"); + auto &info = m_connectionInfoMap[event.connectionID.counter]; + info.interfaceID = event.interfaceID; + info.credentials = event.credentials; } void ThreadService::Handle(const WriteEvent &event) { - LogDebug("Write event (" << event.size << " bytes )"); + LogDebug("Write event (" << event.size << " bytes )"); } void ThreadService::Handle(const ReadEvent &event) { - LogDebug("Read event"); - auto &info = m_connectionInfoMap[event.connectionID.counter]; - info.buffer.Push(event.rawBuffer); + LogDebug("Read event"); + auto &info = m_connectionInfoMap[event.connectionID.counter]; + info.buffer.Push(event.rawBuffer); - if (!info.buffer.Ready()) - return; + if (!info.buffer.Ready()) + return; - if (info.checkInProgress) - return; + if (info.checkInProgress) + return; - info.checkInProgress = true; - m_serviceManager->SecurityCheck(event.connectionID); + info.checkInProgress = true; + m_serviceManager->SecurityCheck(event.connectionID); } void ThreadService::Handle(const CloseEvent &event) { - LogDebug("Close event"); - m_connectionInfoMap.erase(event.connectionID.counter); + LogDebug("Close event"); + m_connectionInfoMap.erase(event.connectionID.counter); } void ThreadService::Handle(const SecurityEvent &event) { - LogDebug("Security event"); - auto it = m_connectionInfoMap.find(event.connectionID.counter); - - if (it == m_connectionInfoMap.end()) { - LogDebug("Connection has been closed already"); - return; - } - auto &info = it->second; - - if (!info.checkInProgress) { - LogDebug("Wrong status in info.checkInProgress. Expected: true."); - return; - } - - ProcessOne(event.connectionID, info, event.allowed); - - if (info.buffer.Ready()) - m_serviceManager->SecurityCheck(event.connectionID); - else - info.checkInProgress = false; + LogDebug("Security event"); + auto it = m_connectionInfoMap.find(event.connectionID.counter); + + if (it == m_connectionInfoMap.end()) { + LogDebug("Connection has been closed already"); + return; + } + + auto &info = it->second; + + if (!info.checkInProgress) { + LogDebug("Wrong status in info.checkInProgress. Expected: true."); + return; + } + + ProcessOne(event.connectionID, info, event.allowed); + + if (info.buffer.Ready()) + m_serviceManager->SecurityCheck(event.connectionID); + else + info.checkInProgress = false; } } /* namespace CKM */ diff --git a/src/manager/main/thread-service.h b/src/manager/main/thread-service.h index 209375fd..3248811e 100644 --- a/src/manager/main/thread-service.h +++ b/src/manager/main/thread-service.h @@ -30,34 +30,51 @@ namespace CKM { class ThreadService: public GenericSocketService, public ServiceThread { public: - ThreadService(); - virtual ~ThreadService(); - NONCOPYABLE(ThreadService); + ThreadService(); + virtual ~ThreadService(); + NONCOPYABLE(ThreadService); - void Event(const AcceptEvent& event) { ThreadEvent(event); } - void Event(const WriteEvent& event) { ThreadEvent(event); } - void Event(const ReadEvent& event) { ThreadEvent(event); } - void Event(const CloseEvent& event) { ThreadEvent(event); } - void Event(const SecurityEvent &event) { ThreadEvent(event); } + void Event(const AcceptEvent &event) + { + ThreadEvent(event); + } + void Event(const WriteEvent &event) + { + ThreadEvent(event); + } + void Event(const ReadEvent &event) + { + ThreadEvent(event); + } + void Event(const CloseEvent &event) + { + ThreadEvent(event); + } + void Event(const SecurityEvent &event) + { + ThreadEvent(event); + } protected: - virtual bool ProcessOne(const ConnectionID &conn, - ConnectionInfo &info, - bool allowed) = 0; - - template <typename E> - void ThreadEvent(const E& event) - { - CreateEvent([this, event]() { this->Handle(event); }); - } - - void Handle(const AcceptEvent &event); - void Handle(const WriteEvent &event); - void Handle(const ReadEvent &event); - void Handle(const CloseEvent &event); - void Handle(const SecurityEvent &event); - - ConnectionInfoMap m_connectionInfoMap; + virtual bool ProcessOne(const ConnectionID &conn, + ConnectionInfo &info, + bool allowed) = 0; + + template <typename E> + void ThreadEvent(const E &event) + { + CreateEvent([this, event]() { + this->Handle(event); + }); + } + + void Handle(const AcceptEvent &event); + void Handle(const WriteEvent &event); + void Handle(const ReadEvent &event); + void Handle(const CloseEvent &event); + void Handle(const SecurityEvent &event); + + ConnectionInfoMap m_connectionInfoMap; }; } /* namespace CKM */ diff --git a/src/manager/service/access-control.cpp b/src/manager/service/access-control.cpp index a3cecb47..8faf36dd 100644 --- a/src/manager/service/access-control.cpp +++ b/src/manager/service/access-control.cpp @@ -33,101 +33,106 @@ namespace CKM { void AccessControl::updateCCMode() { - /* newMode should be extracted from global property like buxton in product */ - bool newMode = false; + /* newMode should be extracted from global property like buxton in product */ + bool newMode = false; - if (newMode == m_ccMode) - return; + if (newMode == m_ccMode) + return; - int iNewMode = newMode ? 1 : 0; + int iNewMode = newMode ? 1 : 0; - if (FIPS_mode_set(iNewMode) == 0) { - LogError("Error to FIPS_mode_set with param " << iNewMode); - return; - } + if (FIPS_mode_set(iNewMode) == 0) { + LogError("Error to FIPS_mode_set with param " << iNewMode); + return; + } - m_ccMode = newMode; + m_ccMode = newMode; } bool AccessControl::isCCMode() const { - return m_ccMode; + return m_ccMode; } bool AccessControl::isSystemService(const uid_t uid) const { - return uid <= SYSTEM_SVC_MAX_UID; + return uid <= SYSTEM_SVC_MAX_UID; } bool AccessControl::isSystemService(const CKM::Credentials &cred) const { - return isSystemService(cred.clientUid); + return isSystemService(cred.clientUid); } int AccessControl::canSave( - const CKM::Credentials &accessorCred, - const Label & ownerLabel) const + const CKM::Credentials &accessorCred, + const Label &ownerLabel) const { - if (isSystemService(accessorCred)) - return CKM_API_SUCCESS; - if (ownerLabel != accessorCred.smackLabel) - return CKM_API_ERROR_ACCESS_DENIED; + if (isSystemService(accessorCred)) + return CKM_API_SUCCESS; - return CKM_API_SUCCESS; + if (ownerLabel != accessorCred.smackLabel) + return CKM_API_ERROR_ACCESS_DENIED; + + return CKM_API_SUCCESS; } int AccessControl::canModify( - const CKM::Credentials &accessorCred, - const Label & ownerLabel) const + const CKM::Credentials &accessorCred, + const Label &ownerLabel) const { - return canSave(accessorCred, ownerLabel); + return canSave(accessorCred, ownerLabel); } int AccessControl::canRead( - const CKM::Credentials &accessorCred, - const PermissionForLabel & permissionLabel) const + const CKM::Credentials &accessorCred, + const PermissionForLabel &permissionLabel) const { - if (isSystemService(accessorCred)) - return CKM_API_SUCCESS; - if (permissionLabel & Permission::READ) - return CKM_API_SUCCESS; + if (isSystemService(accessorCred)) + return CKM_API_SUCCESS; + + if (permissionLabel & Permission::READ) + return CKM_API_SUCCESS; - return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; } int AccessControl::canExport( - const CKM::Credentials &accessorCred, - const DB::Row & row, - const PermissionForLabel & permissionLabel) const + const CKM::Credentials &accessorCred, + const DB::Row &row, + const PermissionForLabel &permissionLabel) const { - int ec; - if (CKM_API_SUCCESS != (ec = canRead(accessorCred, permissionLabel))) - return ec; + int ec; + + if (CKM_API_SUCCESS != (ec = canRead(accessorCred, permissionLabel))) + return ec; - // check if can export - if (row.exportable == 0) - return CKM_API_ERROR_NOT_EXPORTABLE; + // check if can export + if (row.exportable == 0) + return CKM_API_ERROR_NOT_EXPORTABLE; - // prevent extracting private keys during cc-mode on - if (isCCMode() && row.dataType.isKeyPrivate()) - return CKM_API_ERROR_BAD_REQUEST; + // prevent extracting private keys during cc-mode on + if (isCCMode() && row.dataType.isKeyPrivate()) + return CKM_API_ERROR_BAD_REQUEST; - return CKM_API_SUCCESS; + return CKM_API_SUCCESS; } int AccessControl::canDelete( - const CKM::Credentials &accessorCred, - const PermissionForLabel & permissionLabel) const + const CKM::Credentials &accessorCred, + const PermissionForLabel &permissionLabel) const { - if (isSystemService(accessorCred)) - return CKM_API_SUCCESS; - if (permissionLabel & Permission::REMOVE) - return CKM_API_SUCCESS; - if (permissionLabel & Permission::READ) - return CKM_API_ERROR_ACCESS_DENIED; - - return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + if (isSystemService(accessorCred)) + return CKM_API_SUCCESS; + + if (permissionLabel & Permission::REMOVE) + return CKM_API_SUCCESS; + + if (permissionLabel & Permission::READ) + return CKM_API_ERROR_ACCESS_DENIED; + + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; } diff --git a/src/manager/service/access-control.h b/src/manager/service/access-control.h index 0141af4b..f5c2fea9 100644 --- a/src/manager/service/access-control.h +++ b/src/manager/service/access-control.h @@ -32,53 +32,53 @@ namespace CKM { class AccessControl { public: - /** - * return true if client uid is from the system services uid space - */ - bool isSystemService(const uid_t uid) const; - bool isSystemService(const CKM::Credentials &cred) const; + /** + * return true if client uid is from the system services uid space + */ + bool isSystemService(const uid_t uid) const; + bool isSystemService(const CKM::Credentials &cred) const; - /** - * check if given data can be saved by current accessor - * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code - */ - int canSave(const CKM::Credentials &accessorCred, - const Label & ownerLabel) const; + /** + * check if given data can be saved by current accessor + * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code + */ + int canSave(const CKM::Credentials &accessorCred, + const Label &ownerLabel) const; - /** - * check if given label can be modified by accessor - * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code - */ - int canModify(const CKM::Credentials &accessorCred, - const Label & ownerLabel) const; + /** + * check if given label can be modified by accessor + * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code + */ + int canModify(const CKM::Credentials &accessorCred, + const Label &ownerLabel) const; - /** - * check if given row can be read (for internal use) - * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code - */ - int canRead(const CKM::Credentials &accessorCred, - const PermissionForLabel & permissionLabel) const; + /** + * check if given row can be read (for internal use) + * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code + */ + int canRead(const CKM::Credentials &accessorCred, + const PermissionForLabel &permissionLabel) const; - /** - * check if given row can be exported (data provided to the client) - * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code - */ - int canExport(const CKM::Credentials &accessorCred, - const DB::Row & row, - const PermissionForLabel & permissionLabel) const; + /** + * check if given row can be exported (data provided to the client) + * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code + */ + int canExport(const CKM::Credentials &accessorCred, + const DB::Row &row, + const PermissionForLabel &permissionLabel) const; - /** - * check if given accessor can delete ownerLabel's items. - * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code - */ - int canDelete(const CKM::Credentials &accessorCred, - const PermissionForLabel & permissionLabel) const; + /** + * check if given accessor can delete ownerLabel's items. + * @return CKM_API_SUCCESS if access is allowed, otherwise negative error code + */ + int canDelete(const CKM::Credentials &accessorCred, + const PermissionForLabel &permissionLabel) const; - void updateCCMode(); - bool isCCMode() const; + void updateCCMode(); + bool isCCMode() const; private: - bool m_ccMode; + bool m_ccMode; }; } // namespace CKM diff --git a/src/manager/service/certificate-config.h b/src/manager/service/certificate-config.h index 22c0caf4..243a11cd 100644 --- a/src/manager/service/certificate-config.h +++ b/src/manager/service/certificate-config.h @@ -28,31 +28,31 @@ namespace CKM { class CertificateConfig { public: - static void addSystemCertificateDir(const std::string& dir) - { - m_sysCertDirs.insert(dir); - } - static void addSystemCertificateFile(const std::string& file) - { - m_sysCertFiles.insert(file); - } - - typedef std::set<std::string> PathSet; - - static const PathSet& getSystemCertificateDirs() - { - return m_sysCertDirs; - } - static const PathSet& getSystemCertificateFiles() - { - return m_sysCertFiles; - } + static void addSystemCertificateDir(const std::string &dir) + { + m_sysCertDirs.insert(dir); + } + static void addSystemCertificateFile(const std::string &file) + { + m_sysCertFiles.insert(file); + } + + using PathSet = std::set<std::string>; + + static const PathSet &getSystemCertificateDirs() + { + return m_sysCertDirs; + } + static const PathSet &getSystemCertificateFiles() + { + return m_sysCertFiles; + } private: - CertificateConfig(); + CertificateConfig(); - static PathSet m_sysCertDirs; - static PathSet m_sysCertFiles; + static PathSet m_sysCertDirs; + static PathSet m_sysCertFiles; }; } /* namespace CKM */ diff --git a/src/manager/service/certificate-store.cpp b/src/manager/service/certificate-store.cpp index 66295e7a..f7ac84e3 100644 --- a/src/manager/service/certificate-store.cpp +++ b/src/manager/service/certificate-store.cpp @@ -33,147 +33,165 @@ namespace CKM { CertificateStore::CertificateStore() : - m_store(X509_STORE_new()) + m_store(X509_STORE_new()) { - if (!m_store) { - LogError("Failed to create store"); - throw std::runtime_error("Failed to create store"); - } + if (!m_store) { + LogError("Failed to create store"); + throw std::runtime_error("Failed to create store"); + } } CertificateStore::~CertificateStore() { - X509_STORE_free(m_store); + X509_STORE_free(m_store); } int CertificateStore::verifyCertificate( - const CertificateImpl &cert, - const CertificateImplVector &untrustedVector, - const CertificateImplVector &trustedVector, - bool useTrustedSystemCertificates, - bool stateCCMode, - CertificateImplVector &chainVector) + const CertificateImpl &cert, + const CertificateImplVector &untrustedVector, + const CertificateImplVector &trustedVector, + bool useTrustedSystemCertificates, + bool stateCCMode, + CertificateImplVector &chainVector) { - int ret; - LogDebug("Certificate for verfication ptr: " << (void*)cert.getX509()); - LogDebug("Verfication with " << untrustedVector.size() << " untrusted certificates" << - trustedVector.size() << "trusted certificates" << " and system certificates set to: " - << useTrustedSystemCertificates); - - X509_STORE_CTX_PTR csc = create_x509_store_ctx(); - if (!csc) { - LogError("failed to create csc"); - return CKM_API_ERROR_UNKNOWN; - } - - if (useTrustedSystemCertificates) { - ret = addSystemCertificateDirs(); - if (ret != CKM_API_SUCCESS) - return ret; - - ret = addSystemCertificateFiles(); - if (ret != CKM_API_SUCCESS) - return ret; - } - - ret = addCustomTrustedCertificates(trustedVector); - if (ret != CKM_API_SUCCESS) - return ret; - - // create stack of untrusted certificates - X509_STACK_PTR untrusted = create_x509_stack(); - if (!untrustedVector.empty()) { - for (auto &e : untrustedVector) { - // we don't want to free certificates because we wont create copies - sk_X509_push(untrusted.get(), e.getX509()); - } - } - - if (0 == X509_STORE_CTX_init(csc.get(), m_store, cert.getX509(), untrusted.get())) { - LogError("failed to X509_STORE_CTX_init"); - return CKM_API_ERROR_UNKNOWN; - } - - if (stateCCMode) - X509_VERIFY_PARAM_set_flags(csc->param, X509_V_FLAG_X509_STRICT); - - int result = X509_verify_cert(csc.get()); // 1 == ok; 0 == fail; -1 == error - - LogDebug("Openssl verification result: " << result); - - if (result > 0) { - STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(csc.get()); - for (int i = 0; i < sk_X509_num(chain); ++i) { - X509* icert = (X509*)sk_X509_value(chain, i); - chainVector.push_back(CertificateImpl(icert)); - } - } - - switch (result) { - case 0: - return CKM_API_ERROR_VERIFICATION_FAILED; - case 1: - return CKM_API_SUCCESS; - default: - return CKM_API_ERROR_UNKNOWN; - } + int ret; + LogDebug("Certificate for verfication ptr: " << (void *)cert.getX509()); + LogDebug("Verfication with " << untrustedVector.size() << + " untrusted certificates" << + trustedVector.size() << "trusted certificates" << + " and system certificates set to: " + << useTrustedSystemCertificates); + + X509_STORE_CTX_PTR csc = create_x509_store_ctx(); + + if (!csc) { + LogError("failed to create csc"); + return CKM_API_ERROR_UNKNOWN; + } + + if (useTrustedSystemCertificates) { + ret = addSystemCertificateDirs(); + + if (ret != CKM_API_SUCCESS) + return ret; + + ret = addSystemCertificateFiles(); + + if (ret != CKM_API_SUCCESS) + return ret; + } + + ret = addCustomTrustedCertificates(trustedVector); + + if (ret != CKM_API_SUCCESS) + return ret; + + // create stack of untrusted certificates + X509_STACK_PTR untrusted = create_x509_stack(); + + if (!untrustedVector.empty()) { + for (auto &e : untrustedVector) { + // we don't want to free certificates because we wont create copies + sk_X509_push(untrusted.get(), e.getX509()); + } + } + + if (0 == X509_STORE_CTX_init(csc.get(), m_store, cert.getX509(), + untrusted.get())) { + LogError("failed to X509_STORE_CTX_init"); + return CKM_API_ERROR_UNKNOWN; + } + + if (stateCCMode) + X509_VERIFY_PARAM_set_flags(csc->param, X509_V_FLAG_X509_STRICT); + + int result = X509_verify_cert(csc.get()); // 1 == ok; 0 == fail; -1 == error + + LogDebug("Openssl verification result: " << result); + + if (result > 0) { + STACK_OF(X509) *chain = X509_STORE_CTX_get_chain(csc.get()); + + for (int i = 0; i < sk_X509_num(chain); ++i) { + X509 *icert = (X509 *)sk_X509_value(chain, i); + chainVector.push_back(CertificateImpl(icert)); + } + } + + switch (result) { + case 0: + return CKM_API_ERROR_VERIFICATION_FAILED; + + case 1: + return CKM_API_SUCCESS; + + default: + return CKM_API_ERROR_UNKNOWN; + } } int CertificateStore::addSystemCertificateDirs() { - const auto& dirs = CertificateConfig::getSystemCertificateDirs(); - if (dirs.empty()) - return CKM_API_SUCCESS; - - // add system certificate directories - auto dir_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir()); - if (!dir_lookup) { - LogError("Error in X509_STORE_add_lookup"); - return CKM_API_ERROR_UNKNOWN; - } - - for (const auto& i : dirs) { - if (!X509_LOOKUP_add_dir(dir_lookup, i.c_str(), X509_FILETYPE_PEM)) { - LogError("Error in X509_LOOKUP_add_dir"); - return CKM_API_ERROR_UNKNOWN; - } - } - - return CKM_API_SUCCESS; + const auto &dirs = CertificateConfig::getSystemCertificateDirs(); + + if (dirs.empty()) + return CKM_API_SUCCESS; + + // add system certificate directories + auto dir_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir()); + + if (!dir_lookup) { + LogError("Error in X509_STORE_add_lookup"); + return CKM_API_ERROR_UNKNOWN; + } + + for (const auto &i : dirs) { + if (!X509_LOOKUP_add_dir(dir_lookup, i.c_str(), X509_FILETYPE_PEM)) { + LogError("Error in X509_LOOKUP_add_dir"); + return CKM_API_ERROR_UNKNOWN; + } + } + + return CKM_API_SUCCESS; } int CertificateStore::addSystemCertificateFiles() { - const auto& files = CertificateConfig::getSystemCertificateFiles(); - if (files.empty()) - return CKM_API_SUCCESS; - - // add system certificate files - auto file_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file()); - if (!file_lookup) { - LogError("Error in X509_STORE_add_lookup"); - return CKM_API_ERROR_UNKNOWN; - } - - for (const auto& i : files) { - if (!X509_LOOKUP_load_file(file_lookup, i.c_str(), X509_FILETYPE_PEM)) { - LogError("Error in X509_LOOKUP_load_file"); - return CKM_API_ERROR_UNKNOWN; - } - } - return CKM_API_SUCCESS; + const auto &files = CertificateConfig::getSystemCertificateFiles(); + + if (files.empty()) + return CKM_API_SUCCESS; + + // add system certificate files + auto file_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file()); + + if (!file_lookup) { + LogError("Error in X509_STORE_add_lookup"); + return CKM_API_ERROR_UNKNOWN; + } + + for (const auto &i : files) { + if (!X509_LOOKUP_load_file(file_lookup, i.c_str(), X509_FILETYPE_PEM)) { + LogError("Error in X509_LOOKUP_load_file"); + return CKM_API_ERROR_UNKNOWN; + } + } + + return CKM_API_SUCCESS; } -int CertificateStore::addCustomTrustedCertificates(const CertificateImplVector &trustedVector) +int CertificateStore::addCustomTrustedCertificates(const CertificateImplVector + &trustedVector) { - // add trusted certificates to store - for (const auto& i:trustedVector) { - if (1 != X509_STORE_add_cert(m_store, i.getX509())) { - LogError("failed to add certificate to the store"); - return CKM_API_ERROR_UNKNOWN; - } - } - return CKM_API_SUCCESS; + // add trusted certificates to store + for (const auto &i : trustedVector) { + if (1 != X509_STORE_add_cert(m_store, i.getX509())) { + LogError("failed to add certificate to the store"); + return CKM_API_ERROR_UNKNOWN; + } + } + + return CKM_API_SUCCESS; } } // namespace CKM diff --git a/src/manager/service/certificate-store.h b/src/manager/service/certificate-store.h index 250e05ea..39c7cc96 100644 --- a/src/manager/service/certificate-store.h +++ b/src/manager/service/certificate-store.h @@ -21,35 +21,35 @@ #include <certificate-impl.h> extern "C" { -struct x509_store_st; -typedef struct x509_store_st X509_STORE; + struct x509_store_st; + typedef struct x509_store_st X509_STORE; } namespace CKM { class CertificateStore { public: - CertificateStore(); - CertificateStore(const CertificateStore &) = delete; - CertificateStore(CertificateStore &&) = delete; - CertificateStore& operator=(CertificateStore &&) = delete; - CertificateStore& operator=(const CertificateStore &) = delete; - virtual ~CertificateStore(); - - int verifyCertificate( - const CertificateImpl &cert, - const CertificateImplVector &untrustedVector, - const CertificateImplVector &trustedVector, - bool useTrustedSystemCertificates, - bool stateCCMode, - CertificateImplVector &chainVector); + CertificateStore(); + CertificateStore(const CertificateStore &) = delete; + CertificateStore(CertificateStore &&) = delete; + CertificateStore &operator=(CertificateStore &&) = delete; + CertificateStore &operator=(const CertificateStore &) = delete; + virtual ~CertificateStore(); + + int verifyCertificate( + const CertificateImpl &cert, + const CertificateImplVector &untrustedVector, + const CertificateImplVector &trustedVector, + bool useTrustedSystemCertificates, + bool stateCCMode, + CertificateImplVector &chainVector); private: - int addSystemCertificateDirs(); - int addSystemCertificateFiles(); - int addCustomTrustedCertificates(const CertificateImplVector &trustedVector); + int addSystemCertificateDirs(); + int addSystemCertificateFiles(); + int addCustomTrustedCertificates(const CertificateImplVector &trustedVector); - X509_STORE* m_store; + X509_STORE *m_store; }; } // namespace CKM diff --git a/src/manager/service/ckm-logic.cpp b/src/manager/service/ckm-logic.cpp index 5eed7821..167f0136 100644 --- a/src/manager/service/ckm-logic.cpp +++ b/src/manager/service/ckm-logic.cpp @@ -35,22 +35,24 @@ #include <generic-backend/exception.h> namespace { -const char * const CERT_SYSTEM_DIR = CA_CERTS_DIR; -const char * const SYSTEM_DB_PASSWD = "cAtRugU7"; +const char *const CERT_SYSTEM_DIR = CA_CERTS_DIR; +const char *const SYSTEM_DB_PASSWD = "cAtRugU7"; bool isLabelValid(const CKM::Label &label) { - // TODO: copy code from libprivilege control (for check smack label) - if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos) - return false; - return true; + // TODO: copy code from libprivilege control (for check smack label) + if (label.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Label::npos) + return false; + + return true; } bool isNameValid(const CKM::Name &name) { - if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos) - return false; - return true; + if (name.find(CKM::LABEL_NAME_SEPARATOR) != CKM::Name::npos) + return false; + + return true; } } // anonymous namespace @@ -61,1602 +63,1758 @@ const uid_t CKMLogic::SYSTEM_DB_UID = 0; CKMLogic::CKMLogic() { - CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR); + CertificateConfig::addSystemCertificateDir(CERT_SYSTEM_DIR); - m_accessControl.updateCCMode(); + m_accessControl.updateCCMode(); } CKMLogic::~CKMLogic() {} void CKMLogic::loadDKEKFile(uid_t user, const Password &password) { - auto &handle = m_userDataMap[user]; + auto &handle = m_userDataMap[user]; - FileSystem fs(user); + FileSystem fs(user); - auto wrappedDKEK = fs.getDKEK(); + auto wrappedDKEK = fs.getDKEK(); - if (wrappedDKEK.empty()) { - wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password); - fs.saveDKEK(wrappedDKEK); - } + if (wrappedDKEK.empty()) { + wrappedDKEK = KeyProvider::generateDomainKEK(std::to_string(user), password); + fs.saveDKEK(wrappedDKEK); + } - handle.keyProvider = KeyProvider(wrappedDKEK, password); + handle.keyProvider = KeyProvider(wrappedDKEK, password); } void CKMLogic::saveDKEKFile(uid_t user, const Password &password) { - auto &handle = m_userDataMap[user]; + auto &handle = m_userDataMap[user]; - FileSystem fs(user); - fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password)); + FileSystem fs(user); + fs.saveDKEK(handle.keyProvider.getWrappedDomainKEK(password)); } -int CKMLogic::unlockDatabase(uid_t user, const Password & password) +int CKMLogic::unlockDatabase(uid_t user, const Password &password) { - if (0 < m_userDataMap.count(user) && m_userDataMap[user].keyProvider.isInitialized()) - return CKM_API_SUCCESS; - - int retCode = CKM_API_SUCCESS; - try { - auto &handle = m_userDataMap[user]; - - FileSystem fs(user); - loadDKEKFile(user, password); - - auto wrappedDatabaseDEK = fs.getDBDEK(); - if (wrappedDatabaseDEK.empty()) { - wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user)); - fs.saveDBDEK(wrappedDatabaseDEK); - } - - RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK); - - handle.database = DB::Crypto(fs.getDBPath(), key); - handle.crypto = CryptoLogic(); - - if (!m_accessControl.isSystemService(user)) { - // remove data of removed apps during locked state - AppLabelVector removedApps = fs.clearRemovedsApps(); - for (auto& appSmackLabel : removedApps) { - handle.crypto.removeKey(appSmackLabel); - handle.database.deleteKey(appSmackLabel); - } - } - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - if (CKM_API_SUCCESS != retCode) - m_userDataMap.erase(user); - - return retCode; + if (0 < m_userDataMap.count(user) && + m_userDataMap[user].keyProvider.isInitialized()) + return CKM_API_SUCCESS; + + int retCode = CKM_API_SUCCESS; + + try { + auto &handle = m_userDataMap[user]; + + FileSystem fs(user); + loadDKEKFile(user, password); + + auto wrappedDatabaseDEK = fs.getDBDEK(); + + if (wrappedDatabaseDEK.empty()) { + wrappedDatabaseDEK = handle.keyProvider.generateDEK(std::to_string(user)); + fs.saveDBDEK(wrappedDatabaseDEK); + } + + RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK); + + handle.database = DB::Crypto(fs.getDBPath(), key); + handle.crypto = CryptoLogic(); + + if (!m_accessControl.isSystemService(user)) { + // remove data of removed apps during locked state + AppLabelVector removedApps = fs.clearRemovedsApps(); + + for (auto &appSmackLabel : removedApps) { + handle.crypto.removeKey(appSmackLabel); + handle.database.deleteKey(appSmackLabel); + } + } + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + if (CKM_API_SUCCESS != retCode) + m_userDataMap.erase(user); + + return retCode; } int CKMLogic::unlockSystemDB() { - return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD); + return unlockDatabase(SYSTEM_DB_UID, SYSTEM_DB_PASSWD); } -UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incoming_label) +UserData &CKMLogic::selectDatabase(const Credentials &cred, + const Label &incoming_label) { - // if user trying to access system service - check: - // * if user database is unlocked [mandatory] - // * if not - proceed with regular user database - // * if explicit system database label given -> switch to system DB - if (!m_accessControl.isSystemService(cred)) { - if (0 == m_userDataMap.count(cred.clientUid)) - ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked"); - - if (0 != incoming_label.compare(OWNER_ID_SYSTEM)) - return m_userDataMap[cred.clientUid]; - } - - // system database selected, modify the label - if (CKM_API_SUCCESS != unlockSystemDB() ) - ThrowErr(Exc::DatabaseLocked, "can not unlock system database"); - - return m_userDataMap[SYSTEM_DB_UID]; + // if user trying to access system service - check: + // * if user database is unlocked [mandatory] + // * if not - proceed with regular user database + // * if explicit system database label given -> switch to system DB + if (!m_accessControl.isSystemService(cred)) { + if (0 == m_userDataMap.count(cred.clientUid)) + ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked"); + + if (0 != incoming_label.compare(OWNER_ID_SYSTEM)) + return m_userDataMap[cred.clientUid]; + } + + // system database selected, modify the label + if (CKM_API_SUCCESS != unlockSystemDB()) + ThrowErr(Exc::DatabaseLocked, "can not unlock system database"); + + return m_userDataMap[SYSTEM_DB_UID]; } RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) { - int retCode = CKM_API_SUCCESS; + int retCode = CKM_API_SUCCESS; - if (!m_accessControl.isSystemService(user)) - retCode = unlockDatabase(user, password); - else // do not allow lock/unlock operations for system users - retCode = CKM_API_ERROR_INPUT_PARAM; + if (!m_accessControl.isSystemService(user)) + retCode = unlockDatabase(user, password); + else // do not allow lock/unlock operations for system users + retCode = CKM_API_ERROR_INPUT_PARAM; - return MessageBuffer::Serialize(retCode).Pop(); + return MessageBuffer::Serialize(retCode).Pop(); } RawBuffer CKMLogic::updateCCMode() { - m_accessControl.updateCCMode(); - return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop(); + m_accessControl.updateCCMode(); + return MessageBuffer::Serialize(CKM_API_SUCCESS).Pop(); } RawBuffer CKMLogic::lockUserKey(uid_t user) { - int retCode = CKM_API_SUCCESS; - if (!m_accessControl.isSystemService(user)) - m_userDataMap.erase(user); - else // do not allow lock/unlock operations for system users - retCode = CKM_API_ERROR_INPUT_PARAM; + int retCode = CKM_API_SUCCESS; + + if (!m_accessControl.isSystemService(user)) + m_userDataMap.erase(user); + else // do not allow lock/unlock operations for system users + retCode = CKM_API_ERROR_INPUT_PARAM; - return MessageBuffer::Serialize(retCode).Pop(); + return MessageBuffer::Serialize(retCode).Pop(); } RawBuffer CKMLogic::removeUserData(uid_t user) { - int retCode = CKM_API_SUCCESS; + int retCode = CKM_API_SUCCESS; - if (m_accessControl.isSystemService(user)) - user = SYSTEM_DB_UID; + if (m_accessControl.isSystemService(user)) + user = SYSTEM_DB_UID; - m_userDataMap.erase(user); + m_userDataMap.erase(user); - FileSystem fs(user); - fs.removeUserData(); + FileSystem fs(user); + fs.removeUserData(); - return MessageBuffer::Serialize(retCode).Pop(); + return MessageBuffer::Serialize(retCode).Pop(); } int CKMLogic::changeUserPasswordHelper(uid_t user, - const Password &oldPassword, - const Password &newPassword) + const Password &oldPassword, + const Password &newPassword) { - // do not allow to change system database password - if (m_accessControl.isSystemService(user)) - return CKM_API_ERROR_INPUT_PARAM; + // do not allow to change system database password + if (m_accessControl.isSystemService(user)) + return CKM_API_ERROR_INPUT_PARAM; - loadDKEKFile(user, oldPassword); - saveDKEKFile(user, newPassword); + loadDKEKFile(user, oldPassword); + saveDKEKFile(user, newPassword); - return CKM_API_SUCCESS; + return CKM_API_SUCCESS; } RawBuffer CKMLogic::changeUserPassword( - uid_t user, - const Password &oldPassword, - const Password &newPassword) + uid_t user, + const Password &oldPassword, + const Password &newPassword) { - int retCode = CKM_API_SUCCESS; - try { - retCode = changeUserPasswordHelper(user, oldPassword, newPassword); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - return MessageBuffer::Serialize(retCode).Pop(); + int retCode = CKM_API_SUCCESS; + + try { + retCode = changeUserPasswordHelper(user, oldPassword, newPassword); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + return MessageBuffer::Serialize(retCode).Pop(); } int CKMLogic::resetUserPasswordHelper( - uid_t user, - const Password &newPassword) + uid_t user, + const Password &newPassword) { - // do not allow to reset system database password - if (m_accessControl.isSystemService(user)) - return CKM_API_ERROR_INPUT_PARAM; - - int retCode = CKM_API_SUCCESS; - if (0 == m_userDataMap.count(user)) { - // Check if key exists. If exists we must return error - FileSystem fs(user); - auto wrappedDKEKMain = fs.getDKEK(); - if (!wrappedDKEKMain.empty()) - retCode = CKM_API_ERROR_BAD_REQUEST; - } else { - saveDKEKFile(user, newPassword); - } - - return retCode; + // do not allow to reset system database password + if (m_accessControl.isSystemService(user)) + return CKM_API_ERROR_INPUT_PARAM; + + int retCode = CKM_API_SUCCESS; + + if (0 == m_userDataMap.count(user)) { + // Check if key exists. If exists we must return error + FileSystem fs(user); + auto wrappedDKEKMain = fs.getDKEK(); + + if (!wrappedDKEKMain.empty()) + retCode = CKM_API_ERROR_BAD_REQUEST; + } else { + saveDKEKFile(user, newPassword); + } + + return retCode; } RawBuffer CKMLogic::resetUserPassword( - uid_t user, - const Password &newPassword) + uid_t user, + const Password &newPassword) { - int retCode = CKM_API_SUCCESS; - try { - retCode = resetUserPasswordHelper(user, newPassword); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - return MessageBuffer::Serialize(retCode).Pop(); + int retCode = CKM_API_SUCCESS; + + try { + retCode = resetUserPasswordHelper(user, newPassword); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + return MessageBuffer::Serialize(retCode).Pop(); } RawBuffer CKMLogic::removeApplicationData(const Label &smackLabel) { - int retCode = CKM_API_SUCCESS; - - try { - if (smackLabel.empty()) { - retCode = CKM_API_ERROR_INPUT_PARAM; - } else { - UidVector uids = FileSystem::getUIDsFromDBFile(); - for (auto userId : uids) { - if (0 == m_userDataMap.count(userId)) { - FileSystem fs(userId); - fs.addRemovedApp(smackLabel); - } else { - auto &handle = m_userDataMap[userId]; - handle.crypto.removeKey(smackLabel); - handle.database.deleteKey(smackLabel); - } - } - } - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - return MessageBuffer::Serialize(retCode).Pop(); + int retCode = CKM_API_SUCCESS; + + try { + if (smackLabel.empty()) { + retCode = CKM_API_ERROR_INPUT_PARAM; + } else { + UidVector uids = FileSystem::getUIDsFromDBFile(); + + for (auto userId : uids) { + if (0 == m_userDataMap.count(userId)) { + FileSystem fs(userId); + fs.addRemovedApp(smackLabel); + } else { + auto &handle = m_userDataMap[userId]; + handle.crypto.removeKey(smackLabel); + handle.database.deleteKey(smackLabel); + } + } + } + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + return MessageBuffer::Serialize(retCode).Pop(); } int CKMLogic::checkSaveConditions( - const Credentials &cred, - UserData &handler, - const Name &name, - const Label &ownerLabel) + const Credentials &cred, + UserData &handler, + const Name &name, + const Label &ownerLabel) { - // verify name and label are correct - if (!isNameValid(name) || !isLabelValid(ownerLabel)) { - LogDebug("Invalid parameter passed to key-manager"); - return CKM_API_ERROR_INPUT_PARAM; - } - - // check if allowed to save using ownerLabel - int access_ec = m_accessControl.canSave(cred, ownerLabel); - if (access_ec != CKM_API_SUCCESS) { - LogDebug("label " << cred.smackLabel << " can not save rows using label " << ownerLabel); - return access_ec; - } - - // check if not a duplicate - if (handler.database.isNameLabelPresent(name, ownerLabel)) - return CKM_API_ERROR_DB_ALIAS_EXISTS; - - // encryption section - if (!handler.crypto.haveKey(ownerLabel)) { - RawBuffer got_key; - auto key_optional = handler.database.getKey(ownerLabel); - if (!key_optional) { - LogDebug("No Key in database found. Generating new one for label: " << ownerLabel); - got_key = handler.keyProvider.generateDEK(ownerLabel); - handler.database.saveKey(ownerLabel, got_key); - } else { - LogDebug("Key from DB"); - got_key = *key_optional; - } - - got_key = handler.keyProvider.getPureDEK(got_key); - handler.crypto.pushKey(ownerLabel, got_key); - } - - return CKM_API_SUCCESS; + // verify name and label are correct + if (!isNameValid(name) || !isLabelValid(ownerLabel)) { + LogDebug("Invalid parameter passed to key-manager"); + return CKM_API_ERROR_INPUT_PARAM; + } + + // check if allowed to save using ownerLabel + int access_ec = m_accessControl.canSave(cred, ownerLabel); + + if (access_ec != CKM_API_SUCCESS) { + LogDebug("label " << cred.smackLabel << " can not save rows using label " << + ownerLabel); + return access_ec; + } + + // check if not a duplicate + if (handler.database.isNameLabelPresent(name, ownerLabel)) + return CKM_API_ERROR_DB_ALIAS_EXISTS; + + // encryption section + if (!handler.crypto.haveKey(ownerLabel)) { + RawBuffer got_key; + auto key_optional = handler.database.getKey(ownerLabel); + + if (!key_optional) { + LogDebug("No Key in database found. Generating new one for label: " << + ownerLabel); + got_key = handler.keyProvider.generateDEK(ownerLabel); + handler.database.saveKey(ownerLabel, got_key); + } else { + LogDebug("Key from DB"); + got_key = *key_optional; + } + + got_key = handler.keyProvider.getPureDEK(got_key); + handler.crypto.pushKey(ownerLabel, got_key); + } + + return CKM_API_SUCCESS; } DB::Row CKMLogic::createEncryptedRow( - CryptoLogic &crypto, - const Name &name, - const Label &label, - const Crypto::Data &data, - const Policy &policy) const + CryptoLogic &crypto, + const Name &name, + const Label &label, + const Crypto::Data &data, + const Policy &policy) const { - Crypto::GStore& store = m_decider.getStore(data.type, policy.extractable); - - // do not encrypt data with password during cc_mode on - Token token = store.import(data, m_accessControl.isCCMode() ? "" : policy.password); - DB::Row row(std::move(token), name, label, static_cast<int>(policy.extractable)); - crypto.encryptRow(row); - return row; + Crypto::GStore &store = m_decider.getStore(data.type, policy.extractable); + + // do not encrypt data with password during cc_mode on + Token token = store.import(data, + m_accessControl.isCCMode() ? "" : policy.password); + DB::Row row(std::move(token), name, label, + static_cast<int>(policy.extractable)); + crypto.encryptRow(row); + return row; } int CKMLogic::verifyBinaryData(Crypto::Data &input) const { - Crypto::Data dummy; - return toBinaryData(input, dummy); + Crypto::Data dummy; + return toBinaryData(input, dummy); } -int CKMLogic::toBinaryData(const Crypto::Data &input, Crypto::Data &output) const +int CKMLogic::toBinaryData(const Crypto::Data &input, + Crypto::Data &output) const { - // verify the data integrity - if (input.type.isKey()) { - KeyShPtr output_key; - if (input.type.isSKey()) - output_key = CKM::Key::createAES(input.data); - else - output_key = CKM::Key::create(input.data); - - if (output_key.get() == NULL) { - LogDebug("provided binary data is not valid key data"); - return CKM_API_ERROR_INPUT_PARAM; - } - output = std::move(Crypto::Data(input.type, output_key->getDER())); - } else if (input.type.isCertificate() || input.type.isChainCert()) { - CertificateShPtr cert = CKM::Certificate::create(input.data, DataFormat::FORM_DER); - if (cert.get() == NULL) { - LogDebug("provided binary data is not valid certificate data"); - return CKM_API_ERROR_INPUT_PARAM; - } - output = std::move(Crypto::Data(input.type, cert->getDER())); - } else { - output = input; - } - // TODO: add here BINARY_DATA verification, i.e: max size etc. - return CKM_API_SUCCESS; + // verify the data integrity + if (input.type.isKey()) { + KeyShPtr output_key; + + if (input.type.isSKey()) + output_key = CKM::Key::createAES(input.data); + else + output_key = CKM::Key::create(input.data); + + if (output_key.get() == NULL) { + LogDebug("provided binary data is not valid key data"); + return CKM_API_ERROR_INPUT_PARAM; + } + + output = std::move(Crypto::Data(input.type, output_key->getDER())); + } else if (input.type.isCertificate() || input.type.isChainCert()) { + CertificateShPtr cert = CKM::Certificate::create(input.data, + DataFormat::FORM_DER); + + if (cert.get() == NULL) { + LogDebug("provided binary data is not valid certificate data"); + return CKM_API_ERROR_INPUT_PARAM; + } + + output = std::move(Crypto::Data(input.type, cert->getDER())); + } else { + output = input; + } + + // TODO: add here BINARY_DATA verification, i.e: max size etc. + return CKM_API_SUCCESS; } int CKMLogic::verifyAndSaveDataHelper( - const Credentials &cred, - const Name &name, - const Label &label, - const Crypto::Data &data, - const PolicySerializable &policy) + const Credentials &cred, + const Name &name, + const Label &label, + const Crypto::Data &data, + const PolicySerializable &policy) { - int retCode = CKM_API_ERROR_UNKNOWN; - - try { - // check if data is correct - Crypto::Data binaryData; - retCode = toBinaryData(data, binaryData); - if (retCode != CKM_API_SUCCESS) - return retCode; - else - return saveDataHelper(cred, name, label, binaryData, policy); - } catch (const Exc::Exception &e) { - return e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - return CKM_API_ERROR_SERVER_ERROR; - } + int retCode = CKM_API_ERROR_UNKNOWN; + + try { + // check if data is correct + Crypto::Data binaryData; + retCode = toBinaryData(data, binaryData); + + if (retCode != CKM_API_SUCCESS) + return retCode; + else + return saveDataHelper(cred, name, label, binaryData, policy); + } catch (const Exc::Exception &e) { + return e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + return CKM_API_ERROR_SERVER_ERROR; + } } int CKMLogic::getKeyForService( - const Credentials &cred, - const Name &name, - const Label &label, - const Password &pass, - Crypto::GObjShPtr &key) + const Credentials &cred, + const Name &name, + const Label &label, + const Password &pass, + Crypto::GObjShPtr &key) { - DB::Row row; - try { - // Key is for internal service use. It won't be exported to the client - Crypto::GObjUPtr obj; - int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, pass, obj); - if (retCode == CKM_API_SUCCESS) - key = std::move(obj); - return retCode; - } catch (const Exc::Exception &e) { - return e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - return CKM_API_ERROR_SERVER_ERROR; - } + DB::Row row; + + try { + // Key is for internal service use. It won't be exported to the client + Crypto::GObjUPtr obj; + int retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, name, label, + pass, obj); + + if (retCode == CKM_API_SUCCESS) + key = std::move(obj); + + return retCode; + } catch (const Exc::Exception &e) { + return e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + return CKM_API_ERROR_SERVER_ERROR; + } } RawBuffer CKMLogic::saveData( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label, - const Crypto::Data &data, - const PolicySerializable &policy) + const Credentials &cred, + int commandId, + const Name &name, + const Label &label, + const Crypto::Data &data, + const PolicySerializable &policy) { - int retCode = verifyAndSaveDataHelper(cred, name, label, data, policy); - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE), - commandId, - retCode, - static_cast<int>(data.type)); - return response.Pop(); + int retCode = verifyAndSaveDataHelper(cred, name, label, data, policy); + auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE), + commandId, + retCode, + static_cast<int>(data.type)); + return response.Pop(); } int CKMLogic::extractPKCS12Data( - CryptoLogic &crypto, - const Name &name, - const Label &ownerLabel, - const PKCS12Serializable &pkcs, - const PolicySerializable &keyPolicy, - const PolicySerializable &certPolicy, - DB::RowVector &output) const + CryptoLogic &crypto, + const Name &name, + const Label &ownerLabel, + const PKCS12Serializable &pkcs, + const PolicySerializable &keyPolicy, + const PolicySerializable &certPolicy, + DB::RowVector &output) const { - // private key is mandatory - auto key = pkcs.getKey(); - if (!key) { - LogError("Failed to get private key from pkcs"); - return CKM_API_ERROR_INVALID_FORMAT; - } - - Crypto::Data keyData(DataType(key->getType()), key->getDER()); - int retCode = verifyBinaryData(keyData); - if (retCode != CKM_API_SUCCESS) - return retCode; - output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyData, keyPolicy)); - - // certificate is mandatory - auto cert = pkcs.getCertificate(); - if (!cert) { - LogError("Failed to get certificate from pkcs"); - return CKM_API_ERROR_INVALID_FORMAT; - } - Crypto::Data certData(DataType::CERTIFICATE, cert->getDER()); - retCode = verifyBinaryData(certData); - if (retCode != CKM_API_SUCCESS) - return retCode; - output.push_back(createEncryptedRow(crypto, name, ownerLabel, certData, certPolicy)); - - // CA cert chain - unsigned int cert_index = 0; - for (const auto & ca : pkcs.getCaCertificateShPtrVector()) { - Crypto::Data caCertData(DataType::getChainDatatype(cert_index ++), ca->getDER()); - int retCode = verifyBinaryData(caCertData); - if (retCode != CKM_API_SUCCESS) - return retCode; - - output.push_back(createEncryptedRow(crypto, name, ownerLabel, caCertData, certPolicy)); - } - - return CKM_API_SUCCESS; + // private key is mandatory + auto key = pkcs.getKey(); + + if (!key) { + LogError("Failed to get private key from pkcs"); + return CKM_API_ERROR_INVALID_FORMAT; + } + + Crypto::Data keyData(DataType(key->getType()), key->getDER()); + int retCode = verifyBinaryData(keyData); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + output.push_back(createEncryptedRow(crypto, name, ownerLabel, keyData, + keyPolicy)); + + // certificate is mandatory + auto cert = pkcs.getCertificate(); + + if (!cert) { + LogError("Failed to get certificate from pkcs"); + return CKM_API_ERROR_INVALID_FORMAT; + } + + Crypto::Data certData(DataType::CERTIFICATE, cert->getDER()); + retCode = verifyBinaryData(certData); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + output.push_back(createEncryptedRow(crypto, name, ownerLabel, certData, + certPolicy)); + + // CA cert chain + unsigned int cert_index = 0; + + for (const auto &ca : pkcs.getCaCertificateShPtrVector()) { + Crypto::Data caCertData(DataType::getChainDatatype(cert_index ++), + ca->getDER()); + int retCode = verifyBinaryData(caCertData); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + output.push_back(createEncryptedRow(crypto, name, ownerLabel, caCertData, + certPolicy)); + } + + return CKM_API_SUCCESS; } RawBuffer CKMLogic::savePKCS12( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label, - const PKCS12Serializable &pkcs, - const PolicySerializable &keyPolicy, - const PolicySerializable &certPolicy) + const Credentials &cred, + int commandId, + const Name &name, + const Label &label, + const PKCS12Serializable &pkcs, + const PolicySerializable &keyPolicy, + const PolicySerializable &certPolicy) { - int retCode = CKM_API_ERROR_UNKNOWN; - try { - retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::SAVE_PKCS12), - commandId, - retCode); - return response.Pop(); + int retCode = CKM_API_ERROR_UNKNOWN; + + try { + retCode = saveDataHelper(cred, name, label, pkcs, keyPolicy, certPolicy); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::SAVE_PKCS12), + commandId, + retCode); + return response.Pop(); } int CKMLogic::removeDataHelper( - const Credentials &cred, - const Name &name, - const Label &label) + const Credentials &cred, + const Name &name, + const Label &label) { - auto &handler = selectDatabase(cred, label); - - // use client label if not explicitly provided - const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - if (!isNameValid(name) || !isLabelValid(ownerLabel)) { - LogDebug("Invalid label or name format"); - return CKM_API_ERROR_INPUT_PARAM; - } - - DB::Crypto::Transaction transaction(&handler.database); - - // read and check permissions - PermissionMaskOptional permissionRowOpt = - handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel); - int retCode = m_accessControl.canDelete(cred, - PermissionForLabel(cred.smackLabel, permissionRowOpt)); - if (retCode != CKM_API_SUCCESS) { - LogWarning("access control check result: " << retCode); - return retCode; - } - - // get all matching rows - DB::RowVector rows; - handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, DataType::DB_LAST, rows); - if (rows.empty()) { - LogDebug("No row for given name and label"); - return CKM_API_ERROR_DB_ALIAS_UNKNOWN; - } - - // load app key if needed - retCode = loadAppKey(handler, rows.front().ownerLabel); - if (CKM_API_SUCCESS != retCode) - return retCode; - - // destroy it in store - for (auto& r : rows) { - try { - handler.crypto.decryptRow(Password(), r); - m_decider.getStore(r).destroy(r); - } catch (const Exc::AuthenticationFailed&) { - LogDebug("Authentication failed when removing data. Ignored."); - } - } - - // delete row in db - handler.database.deleteRow(name, ownerLabel); - transaction.commit(); - - return CKM_API_SUCCESS; + auto &handler = selectDatabase(cred, label); + + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; + + if (!isNameValid(name) || !isLabelValid(ownerLabel)) { + LogDebug("Invalid label or name format"); + return CKM_API_ERROR_INPUT_PARAM; + } + + DB::Crypto::Transaction transaction(&handler.database); + + // read and check permissions + PermissionMaskOptional permissionRowOpt = + handler.database.getPermissionRow(name, ownerLabel, cred.smackLabel); + int retCode = m_accessControl.canDelete(cred, + PermissionForLabel(cred.smackLabel, permissionRowOpt)); + + if (retCode != CKM_API_SUCCESS) { + LogWarning("access control check result: " << retCode); + return retCode; + } + + // get all matching rows + DB::RowVector rows; + handler.database.getRows(name, ownerLabel, DataType::DB_FIRST, + DataType::DB_LAST, rows); + + if (rows.empty()) { + LogDebug("No row for given name and label"); + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + } + + // load app key if needed + retCode = loadAppKey(handler, rows.front().ownerLabel); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + // destroy it in store + for (auto &r : rows) { + try { + handler.crypto.decryptRow(Password(), r); + m_decider.getStore(r).destroy(r); + } catch (const Exc::AuthenticationFailed &) { + LogDebug("Authentication failed when removing data. Ignored."); + } + } + + // delete row in db + handler.database.deleteRow(name, ownerLabel); + transaction.commit(); + + return CKM_API_SUCCESS; } RawBuffer CKMLogic::removeData( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label) + const Credentials &cred, + int commandId, + const Name &name, + const Label &label) { - int retCode = CKM_API_ERROR_UNKNOWN; - - try { - retCode = removeDataHelper(cred, name, label); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("Error: " << e.GetMessage()); - retCode = CKM_API_ERROR_DB_ERROR; - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE), - commandId, - retCode); - return response.Pop(); + int retCode = CKM_API_ERROR_UNKNOWN; + + try { + retCode = removeDataHelper(cred, name, label); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("Error: " << e.GetMessage()); + retCode = CKM_API_ERROR_DB_ERROR; + } + + auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::REMOVE), + commandId, + retCode); + return response.Pop(); } int CKMLogic::readSingleRow(const Name &name, - const Label &ownerLabel, - DataType dataType, - DB::Crypto & database, - DB::Row &row) + const Label &ownerLabel, + DataType dataType, + DB::Crypto &database, + DB::Row &row) { - DB::Crypto::RowOptional row_optional; - if (dataType.isKey()) { - // read all key types - row_optional = database.getRow(name, - ownerLabel, - DataType::DB_KEY_FIRST, - DataType::DB_KEY_LAST); - } else { - // read anything else - row_optional = database.getRow(name, - ownerLabel, - dataType); - } - - if (!row_optional) { - LogDebug("No row for given name, label and type"); - return CKM_API_ERROR_DB_ALIAS_UNKNOWN; - } else { - row = *row_optional; - } - - return CKM_API_SUCCESS; + DB::Crypto::RowOptional row_optional; + + if (dataType.isKey()) { + // read all key types + row_optional = database.getRow(name, + ownerLabel, + DataType::DB_KEY_FIRST, + DataType::DB_KEY_LAST); + } else { + // read anything else + row_optional = database.getRow(name, + ownerLabel, + dataType); + } + + if (!row_optional) { + LogDebug("No row for given name, label and type"); + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + } else { + row = *row_optional; + } + + return CKM_API_SUCCESS; } int CKMLogic::readMultiRow(const Name &name, - const Label &ownerLabel, - DataType dataType, - DB::Crypto & database, - DB::RowVector &output) + const Label &ownerLabel, + DataType dataType, + DB::Crypto &database, + DB::RowVector &output) { - if (dataType.isKey()) - // read all key types - database.getRows(name, - ownerLabel, - DataType::DB_KEY_FIRST, - DataType::DB_KEY_LAST, - output); - else if (dataType.isChainCert()) - // read all key types - database.getRows(name, - ownerLabel, - DataType::DB_CHAIN_FIRST, - DataType::DB_CHAIN_LAST, - output); - else - // read anything else - database.getRows(name, - ownerLabel, - dataType, - output); - - if (!output.size()) { - LogDebug("No row for given name, label and type"); - return CKM_API_ERROR_DB_ALIAS_UNKNOWN; - } - - return CKM_API_SUCCESS; + if (dataType.isKey()) + // read all key types + database.getRows(name, + ownerLabel, + DataType::DB_KEY_FIRST, + DataType::DB_KEY_LAST, + output); + else if (dataType.isChainCert()) + // read all key types + database.getRows(name, + ownerLabel, + DataType::DB_CHAIN_FIRST, + DataType::DB_CHAIN_LAST, + output); + else + // read anything else + database.getRows(name, + ownerLabel, + dataType, + output); + + if (!output.size()) { + LogDebug("No row for given name, label and type"); + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + } + + return CKM_API_SUCCESS; } int CKMLogic::checkDataPermissionsHelper(const Credentials &cred, - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel, - const DB::Row &row, - bool exportFlag, - DB::Crypto & database) + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const DB::Row &row, + bool exportFlag, + DB::Crypto &database) { - PermissionMaskOptional permissionRowOpt = - database.getPermissionRow(name, ownerLabel, accessorLabel); + PermissionMaskOptional permissionRowOpt = + database.getPermissionRow(name, ownerLabel, accessorLabel); + + if (exportFlag) + return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, + permissionRowOpt)); - if (exportFlag) - return m_accessControl.canExport(cred, row, PermissionForLabel(accessorLabel, permissionRowOpt)); - return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, permissionRowOpt)); + return m_accessControl.canRead(cred, PermissionForLabel(accessorLabel, + permissionRowOpt)); } Crypto::GObjUPtr CKMLogic::rowToObject( - UserData& handler, - DB::Row row, - const Password& password) + UserData &handler, + DB::Row row, + const Password &password) { - Crypto::GStore& store = m_decider.getStore(row); + Crypto::GStore &store = m_decider.getStore(row); - Password pass = m_accessControl.isCCMode() ? "" : password; + Password pass = m_accessControl.isCCMode() ? "" : password; - // decrypt row - Crypto::GObjUPtr obj; - if (CryptoLogic::getSchemeVersion(row.encryptionScheme) == CryptoLogic::ENCRYPTION_V2) { - handler.crypto.decryptRow(Password(), row); + // decrypt row + Crypto::GObjUPtr obj; - obj = store.getObject(row, pass); - } else { - // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data - handler.crypto.decryptRow(pass, row); - // destroy it in store - store.destroy(row); + if (CryptoLogic::getSchemeVersion(row.encryptionScheme) == + CryptoLogic::ENCRYPTION_V2) { + handler.crypto.decryptRow(Password(), row); - // import it to store with new scheme: data -> pass(data) - Token token = store.import(Crypto::Data(row.dataType, row.data), pass); + obj = store.getObject(row, pass); + } else { + // decrypt entirely with old scheme: b64(pass(appkey(data))) -> data + handler.crypto.decryptRow(pass, row); + // destroy it in store + store.destroy(row); - // get it from the store (it can be different than the data we imported into store) - obj = store.getObject(token, pass); + // import it to store with new scheme: data -> pass(data) + Token token = store.import(Crypto::Data(row.dataType, row.data), pass); - // update row with new token - *static_cast<Token*>(&row) = std::move(token); + // get it from the store (it can be different than the data we imported into store) + obj = store.getObject(token, pass); - // encrypt it with app key: pass(data) -> b64(appkey(pass(data)) - handler.crypto.encryptRow(row); + // update row with new token + *static_cast<Token *>(&row) = std::move(token); - // update it in db - handler.database.updateRow(row); - } - return obj; + // encrypt it with app key: pass(data) -> b64(appkey(pass(data)) + handler.crypto.encryptRow(row); + + // update it in db + handler.database.updateRow(row); + } + + return obj; } int CKMLogic::readDataHelper( - bool exportFlag, - const Credentials &cred, - DataType dataType, - const Name &name, - const Label &label, - const Password &password, - Crypto::GObjUPtrVector &objs) + bool exportFlag, + const Credentials &cred, + DataType dataType, + const Name &name, + const Label &label, + const Password &password, + Crypto::GObjUPtrVector &objs) { - auto &handler = selectDatabase(cred, label); + auto &handler = selectDatabase(cred, label); + + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; + + if (!isNameValid(name) || !isLabelValid(ownerLabel)) + return CKM_API_ERROR_INPUT_PARAM; - // use client label if not explicitly provided - const Label &ownerLabel = label.empty() ? cred.smackLabel : label; + // read rows + DB::Crypto::Transaction transaction(&handler.database); + DB::RowVector rows; + int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows); - if (!isNameValid(name) || !isLabelValid(ownerLabel)) - return CKM_API_ERROR_INPUT_PARAM; + if (CKM_API_SUCCESS != retCode) + return retCode; - // read rows - DB::Crypto::Transaction transaction(&handler.database); - DB::RowVector rows; - int retCode = readMultiRow(name, ownerLabel, dataType, handler.database, rows); - if (CKM_API_SUCCESS != retCode) - return retCode; + // all read rows belong to the same owner + DB::Row &firstRow = rows.at(0); - // all read rows belong to the same owner - DB::Row & firstRow = rows.at(0); + // check access rights + retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, + firstRow, exportFlag, handler.database); - // check access rights - retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, firstRow, exportFlag, handler.database); - if (CKM_API_SUCCESS != retCode) - return retCode; + if (CKM_API_SUCCESS != retCode) + return retCode; - // load app key if needed - retCode = loadAppKey(handler, firstRow.ownerLabel); - if (CKM_API_SUCCESS != retCode) - return retCode; + // load app key if needed + retCode = loadAppKey(handler, firstRow.ownerLabel); - // decrypt row - for (auto &row : rows) - objs.push_back(rowToObject(handler, std::move(row), password)); - // rowToObject may modify db - transaction.commit(); + if (CKM_API_SUCCESS != retCode) + return retCode; - return CKM_API_SUCCESS; + // decrypt row + for (auto &row : rows) + objs.push_back(rowToObject(handler, std::move(row), password)); + + // rowToObject may modify db + transaction.commit(); + + return CKM_API_SUCCESS; } int CKMLogic::readDataHelper( - bool exportFlag, - const Credentials &cred, - DataType dataType, - const Name &name, - const Label &label, - const Password &password, - Crypto::GObjUPtr &obj) + bool exportFlag, + const Credentials &cred, + DataType dataType, + const Name &name, + const Label &label, + const Password &password, + Crypto::GObjUPtr &obj) { - DataType objDataType; - return readDataHelper(exportFlag, cred, dataType, name, label, password, obj, objDataType); + DataType objDataType; + return readDataHelper(exportFlag, cred, dataType, name, label, password, obj, + objDataType); } int CKMLogic::readDataHelper( - bool exportFlag, - const Credentials &cred, - DataType dataType, - const Name &name, - const Label &label, - const Password &password, - Crypto::GObjUPtr &obj, - DataType& objDataType) + bool exportFlag, + const Credentials &cred, + DataType dataType, + const Name &name, + const Label &label, + const Password &password, + Crypto::GObjUPtr &obj, + DataType &objDataType) { - auto &handler = selectDatabase(cred, label); + auto &handler = selectDatabase(cred, label); + + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - // use client label if not explicitly provided - const Label &ownerLabel = label.empty() ? cred.smackLabel : label; + if (!isNameValid(name) || !isLabelValid(ownerLabel)) + return CKM_API_ERROR_INPUT_PARAM; - if (!isNameValid(name) || !isLabelValid(ownerLabel)) - return CKM_API_ERROR_INPUT_PARAM; + // read row + DB::Crypto::Transaction transaction(&handler.database); + DB::Row row; + int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row); - // read row - DB::Crypto::Transaction transaction(&handler.database); - DB::Row row; - int retCode = readSingleRow(name, ownerLabel, dataType, handler.database, row); - if (CKM_API_SUCCESS != retCode) - return retCode; + if (CKM_API_SUCCESS != retCode) + return retCode; - objDataType = row.dataType; + objDataType = row.dataType; - // check access rights - retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, row, exportFlag, handler.database); - if (CKM_API_SUCCESS != retCode) - return retCode; + // check access rights + retCode = checkDataPermissionsHelper(cred, name, ownerLabel, cred.smackLabel, + row, exportFlag, handler.database); - // load app key if needed - retCode = loadAppKey(handler, row.ownerLabel); - if (CKM_API_SUCCESS != retCode) - return retCode; + if (CKM_API_SUCCESS != retCode) + return retCode; - obj = rowToObject(handler, std::move(row), password); - // rowToObject may modify db - transaction.commit(); + // load app key if needed + retCode = loadAppKey(handler, row.ownerLabel); - return CKM_API_SUCCESS; + if (CKM_API_SUCCESS != retCode) + return retCode; + + obj = rowToObject(handler, std::move(row), password); + // rowToObject may modify db + transaction.commit(); + + return CKM_API_SUCCESS; } RawBuffer CKMLogic::getData( - const Credentials &cred, - int commandId, - DataType dataType, - const Name &name, - const Label &label, - const Password &password) + const Credentials &cred, + int commandId, + DataType dataType, + const Name &name, + const Label &label, + const Password &password) { - int retCode = CKM_API_SUCCESS; - DB::Row row; - DataType objDataType; - - try { - Crypto::GObjUPtr obj; - retCode = readDataHelper(true, cred, dataType, name, label, password, obj, objDataType); - if (retCode == CKM_API_SUCCESS) - row.data = std::move(obj->getBinary()); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - if (CKM_API_SUCCESS != retCode) { - row.data.clear(); - row.dataType = dataType; - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET), - commandId, - retCode, - static_cast<int>(objDataType), - row.data); - return response.Pop(); + int retCode = CKM_API_SUCCESS; + DB::Row row; + DataType objDataType; + + try { + Crypto::GObjUPtr obj; + retCode = readDataHelper(true, cred, dataType, name, label, password, obj, + objDataType); + + if (retCode == CKM_API_SUCCESS) + row.data = std::move(obj->getBinary()); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + if (CKM_API_SUCCESS != retCode) { + row.data.clear(); + row.dataType = dataType; + } + + auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET), + commandId, + retCode, + static_cast<int>(objDataType), + row.data); + return response.Pop(); } int CKMLogic::getPKCS12Helper( - const Credentials &cred, - const Name &name, - const Label &label, - const Password &keyPassword, - const Password &certPassword, - KeyShPtr & privKey, - CertificateShPtr & cert, - CertificateShPtrVector & caChain) + const Credentials &cred, + const Name &name, + const Label &label, + const Password &keyPassword, + const Password &certPassword, + KeyShPtr &privKey, + CertificateShPtr &cert, + CertificateShPtrVector &caChain) { - int retCode; - - // read private key (mandatory) - Crypto::GObjUPtr keyObj; - retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, keyPassword, keyObj); - if (retCode != CKM_API_SUCCESS) - return retCode; - privKey = CKM::Key::create(keyObj->getBinary()); - - // read certificate (mandatory) - Crypto::GObjUPtr certObj; - retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, certPassword, certObj); - if (retCode != CKM_API_SUCCESS) - return retCode; - cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER); - - // read CA cert chain (optional) - Crypto::GObjUPtrVector caChainObjs; - retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, certPassword, caChainObjs); - if (retCode != CKM_API_SUCCESS && - retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN) - return retCode; - for (auto &caCertObj : caChainObjs) - caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(), DataFormat::FORM_DER)); - - // if anything found, return it - if (privKey || cert || caChain.size() > 0) - retCode = CKM_API_SUCCESS; - - return retCode; + int retCode; + + // read private key (mandatory) + Crypto::GObjUPtr keyObj; + retCode = readDataHelper(true, cred, DataType::DB_KEY_FIRST, name, label, + keyPassword, keyObj); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + privKey = CKM::Key::create(keyObj->getBinary()); + + // read certificate (mandatory) + Crypto::GObjUPtr certObj; + retCode = readDataHelper(true, cred, DataType::CERTIFICATE, name, label, + certPassword, certObj); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + cert = CKM::Certificate::create(certObj->getBinary(), DataFormat::FORM_DER); + + // read CA cert chain (optional) + Crypto::GObjUPtrVector caChainObjs; + retCode = readDataHelper(true, cred, DataType::DB_CHAIN_FIRST, name, label, + certPassword, caChainObjs); + + if (retCode != CKM_API_SUCCESS && + retCode != CKM_API_ERROR_DB_ALIAS_UNKNOWN) + return retCode; + + for (auto &caCertObj : caChainObjs) + caChain.push_back(CKM::Certificate::create(caCertObj->getBinary(), + DataFormat::FORM_DER)); + + // if anything found, return it + if (privKey || cert || caChain.size() > 0) + retCode = CKM_API_SUCCESS; + + return retCode; } RawBuffer CKMLogic::getPKCS12( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label, - const Password &keyPassword, - const Password &certPassword) + const Credentials &cred, + int commandId, + const Name &name, + const Label &label, + const Password &keyPassword, + const Password &certPassword) { - int retCode = CKM_API_ERROR_UNKNOWN; - - PKCS12Serializable output; - try { - KeyShPtr privKey; - CertificateShPtr cert; - CertificateShPtrVector caChain; - retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, cert, caChain); - - // prepare response - if (retCode == CKM_API_SUCCESS) - output = PKCS12Serializable(std::move(privKey), std::move(cert), std::move(caChain)); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_PKCS12), - commandId, - retCode, - output); - return response.Pop(); + int retCode = CKM_API_ERROR_UNKNOWN; + + PKCS12Serializable output; + + try { + KeyShPtr privKey; + CertificateShPtr cert; + CertificateShPtrVector caChain; + retCode = getPKCS12Helper(cred, name, label, keyPassword, certPassword, privKey, + cert, caChain); + + // prepare response + if (retCode == CKM_API_SUCCESS) + output = PKCS12Serializable(std::move(privKey), std::move(cert), + std::move(caChain)); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::GET_PKCS12), + commandId, + retCode, + output); + return response.Pop(); } int CKMLogic::getDataListHelper(const Credentials &cred, - const DataType dataType, - LabelNameVector &labelNameVector) + const DataType dataType, + LabelNameVector &labelNameVector) { - int retCode = CKM_API_ERROR_DB_LOCKED; - if (0 < m_userDataMap.count(cred.clientUid)) { - auto &database = m_userDataMap[cred.clientUid].database; - - try { - LabelNameVector tmpVector; - if (dataType.isKey()) { - // list all key types - database.listNames(cred.smackLabel, - tmpVector, - DataType::DB_KEY_FIRST, - DataType::DB_KEY_LAST); - } else { - // list anything else - database.listNames(cred.smackLabel, - tmpVector, - dataType); - } - labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), tmpVector.end()); - retCode = CKM_API_SUCCESS; - } catch (const CKM::Exception &e) { - LogError("Error: " << e.GetMessage()); - retCode = CKM_API_ERROR_DB_ERROR; - } catch (const Exc::Exception &e) { - retCode = e.error(); - } - } - return retCode; + int retCode = CKM_API_ERROR_DB_LOCKED; + + if (0 < m_userDataMap.count(cred.clientUid)) { + auto &database = m_userDataMap[cred.clientUid].database; + + try { + LabelNameVector tmpVector; + + if (dataType.isKey()) { + // list all key types + database.listNames(cred.smackLabel, + tmpVector, + DataType::DB_KEY_FIRST, + DataType::DB_KEY_LAST); + } else { + // list anything else + database.listNames(cred.smackLabel, + tmpVector, + dataType); + } + + labelNameVector.insert(labelNameVector.end(), tmpVector.begin(), + tmpVector.end()); + retCode = CKM_API_SUCCESS; + } catch (const CKM::Exception &e) { + LogError("Error: " << e.GetMessage()); + retCode = CKM_API_ERROR_DB_ERROR; + } catch (const Exc::Exception &e) { + retCode = e.error(); + } + } + + return retCode; } RawBuffer CKMLogic::getDataList( - const Credentials &cred, - int commandId, - DataType dataType) + const Credentials &cred, + int commandId, + DataType dataType) { - LabelNameVector systemVector; - LabelNameVector userVector; - LabelNameVector labelNameVector; - - int retCode = unlockSystemDB(); - if (CKM_API_SUCCESS == retCode) { - // system database - if (m_accessControl.isSystemService(cred)) { - // lookup system DB - retCode = getDataListHelper(Credentials(SYSTEM_DB_UID, - OWNER_ID_SYSTEM), - dataType, - systemVector); - } else { - // user - lookup system, then client DB - retCode = getDataListHelper(Credentials(SYSTEM_DB_UID, - cred.smackLabel), - dataType, - systemVector); - - // private database - if (retCode == CKM_API_SUCCESS) { - retCode = getDataListHelper(cred, - dataType, - userVector); - } - } - } - - if (retCode == CKM_API_SUCCESS) { - labelNameVector.insert(labelNameVector.end(), systemVector.begin(), systemVector.end()); - labelNameVector.insert(labelNameVector.end(), userVector.begin(), userVector.end()); - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_LIST), - commandId, - retCode, - static_cast<int>(dataType), - labelNameVector); - return response.Pop(); + LabelNameVector systemVector; + LabelNameVector userVector; + LabelNameVector labelNameVector; + + int retCode = unlockSystemDB(); + + if (CKM_API_SUCCESS == retCode) { + // system database + if (m_accessControl.isSystemService(cred)) { + // lookup system DB + retCode = getDataListHelper(Credentials(SYSTEM_DB_UID, + OWNER_ID_SYSTEM), + dataType, + systemVector); + } else { + // user - lookup system, then client DB + retCode = getDataListHelper(Credentials(SYSTEM_DB_UID, + cred.smackLabel), + dataType, + systemVector); + + // private database + if (retCode == CKM_API_SUCCESS) { + retCode = getDataListHelper(cred, + dataType, + userVector); + } + } + } + + if (retCode == CKM_API_SUCCESS) { + labelNameVector.insert(labelNameVector.end(), systemVector.begin(), + systemVector.end()); + labelNameVector.insert(labelNameVector.end(), userVector.begin(), + userVector.end()); + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::GET_LIST), + commandId, + retCode, + static_cast<int>(dataType), + labelNameVector); + return response.Pop(); } int CKMLogic::importInitialData( - const Name &name, - const Crypto::Data &data, - const Crypto::DataEncryption &enc, - const Policy &policy) + const Name &name, + const Crypto::Data &data, + const Crypto::DataEncryption &enc, + const Policy &policy) { - try { - // Inital values are always imported with root credentials. Label is not important. - Credentials rootCred(0, ""); - - auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM); - - // check if save is possible - DB::Crypto::Transaction transaction(&handler.database); - int retCode = checkSaveConditions(rootCred, handler, name, OWNER_ID_SYSTEM); - if (retCode != CKM_API_SUCCESS) - return retCode; - - Crypto::GStore& store = - m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty()); - - Token token; - - if (enc.encryptedKey.empty()) { - Crypto::Data binaryData; - if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData))) - return retCode; - token = store.import(binaryData, m_accessControl.isCCMode() ? "" : policy.password); - } else { - token = store.importEncrypted(data, m_accessControl.isCCMode() ? "" : policy.password, enc); - } - - DB::Row row(std::move(token), name, OWNER_ID_SYSTEM, static_cast<int>(policy.extractable)); - handler.crypto.encryptRow(row); - - handler.database.saveRow(row); - transaction.commit(); - } catch (const Exc::Exception &e) { - return e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - return CKM_API_ERROR_SERVER_ERROR; - } catch (const std::exception &e) { - LogError("Std::exception: " << e.what()); - return CKM_API_ERROR_SERVER_ERROR; - } - - return CKM_API_SUCCESS; + try { + // Inital values are always imported with root credentials. Label is not important. + Credentials rootCred(0, ""); + + auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM); + + // check if save is possible + DB::Crypto::Transaction transaction(&handler.database); + int retCode = checkSaveConditions(rootCred, handler, name, OWNER_ID_SYSTEM); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + Crypto::GStore &store = + m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty()); + + Token token; + + if (enc.encryptedKey.empty()) { + Crypto::Data binaryData; + + if (CKM_API_SUCCESS != (retCode = toBinaryData(data, binaryData))) + return retCode; + + token = store.import(binaryData, + m_accessControl.isCCMode() ? "" : policy.password); + } else { + token = store.importEncrypted(data, + m_accessControl.isCCMode() ? "" : policy.password, enc); + } + + DB::Row row(std::move(token), name, OWNER_ID_SYSTEM, + static_cast<int>(policy.extractable)); + handler.crypto.encryptRow(row); + + handler.database.saveRow(row); + transaction.commit(); + } catch (const Exc::Exception &e) { + return e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + return CKM_API_ERROR_SERVER_ERROR; + } catch (const std::exception &e) { + LogError("Std::exception: " << e.what()); + return CKM_API_ERROR_SERVER_ERROR; + } + + return CKM_API_SUCCESS; } int CKMLogic::saveDataHelper( - const Credentials &cred, - const Name &name, - const Label &label, - const Crypto::Data &data, - const PolicySerializable &policy) + const Credentials &cred, + const Name &name, + const Label &label, + const Crypto::Data &data, + const PolicySerializable &policy) { - auto &handler = selectDatabase(cred, label); + auto &handler = selectDatabase(cred, label); - // use client label if not explicitly provided - const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0) - return CKM_API_ERROR_INPUT_PARAM; + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - // check if save is possible - DB::Crypto::Transaction transaction(&handler.database); - int retCode = checkSaveConditions(cred, handler, name, ownerLabel); - if (retCode != CKM_API_SUCCESS) - return retCode; + if (m_accessControl.isSystemService(cred) && + ownerLabel.compare(OWNER_ID_SYSTEM) != 0) + return CKM_API_ERROR_INPUT_PARAM; - // save the data - DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, data, policy); - handler.database.saveRow(encryptedRow); + // check if save is possible + DB::Crypto::Transaction transaction(&handler.database); + int retCode = checkSaveConditions(cred, handler, name, ownerLabel); - transaction.commit(); - return CKM_API_SUCCESS; + if (retCode != CKM_API_SUCCESS) + return retCode; + + // save the data + DB::Row encryptedRow = createEncryptedRow(handler.crypto, name, ownerLabel, + data, policy); + handler.database.saveRow(encryptedRow); + + transaction.commit(); + return CKM_API_SUCCESS; } int CKMLogic::saveDataHelper( - const Credentials &cred, - const Name &name, - const Label &label, - const PKCS12Serializable &pkcs, - const PolicySerializable &keyPolicy, - const PolicySerializable &certPolicy) + const Credentials &cred, + const Name &name, + const Label &label, + const PKCS12Serializable &pkcs, + const PolicySerializable &keyPolicy, + const PolicySerializable &certPolicy) { - auto &handler = selectDatabase(cred, label); - - // use client label if not explicitly provided - const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0) - return CKM_API_ERROR_INPUT_PARAM; - - // check if save is possible - DB::Crypto::Transaction transaction(&handler.database); - int retCode = checkSaveConditions(cred, handler, name, ownerLabel); - if (retCode != CKM_API_SUCCESS) - return retCode; - - // extract and encrypt the data - DB::RowVector encryptedRows; - retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, certPolicy, encryptedRows); - if (retCode != CKM_API_SUCCESS) - return retCode; - - // save the data - handler.database.saveRows(name, ownerLabel, encryptedRows); - transaction.commit(); - - return CKM_API_SUCCESS; + auto &handler = selectDatabase(cred, label); + + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; + + if (m_accessControl.isSystemService(cred) && + ownerLabel.compare(OWNER_ID_SYSTEM) != 0) + return CKM_API_ERROR_INPUT_PARAM; + + // check if save is possible + DB::Crypto::Transaction transaction(&handler.database); + int retCode = checkSaveConditions(cred, handler, name, ownerLabel); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + // extract and encrypt the data + DB::RowVector encryptedRows; + retCode = extractPKCS12Data(handler.crypto, name, ownerLabel, pkcs, keyPolicy, + certPolicy, encryptedRows); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + // save the data + handler.database.saveRows(name, ownerLabel, encryptedRows); + transaction.commit(); + + return CKM_API_SUCCESS; } int CKMLogic::createKeyAESHelper( - const Credentials &cred, - const int size, - const Name &name, - const Label &label, - const PolicySerializable &policy) + const Credentials &cred, + const int size, + const Name &name, + const Label &label, + const PolicySerializable &policy) { - auto &handler = selectDatabase(cred, label); + auto &handler = selectDatabase(cred, label); + + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - // use client label if not explicitly provided - const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - if (m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM) != 0) - return CKM_API_ERROR_INPUT_PARAM; + if (m_accessControl.isSystemService(cred) && + ownerLabel.compare(OWNER_ID_SYSTEM) != 0) + return CKM_API_ERROR_INPUT_PARAM; - // check if save is possible - DB::Crypto::Transaction transaction(&handler.database); - int retCode = checkSaveConditions(cred, handler, name, ownerLabel); - if (retCode != CKM_API_SUCCESS) - return retCode; + // check if save is possible + DB::Crypto::Transaction transaction(&handler.database); + int retCode = checkSaveConditions(cred, handler, name, ownerLabel); - // create key in store - CryptoAlgorithm keyGenAlgorithm; - keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN); - keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size); - Token key = m_decider.getStore(DataType::KEY_AES, policy.extractable).generateSKey(keyGenAlgorithm, policy.password); + if (retCode != CKM_API_SUCCESS) + return retCode; - // save the data - DB::Row row(std::move(key), name, ownerLabel, static_cast<int>(policy.extractable)); - handler.crypto.encryptRow(row); + // create key in store + CryptoAlgorithm keyGenAlgorithm; + keyGenAlgorithm.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GEN); + keyGenAlgorithm.setParam(ParamName::GEN_KEY_LEN, size); + Token key = m_decider.getStore(DataType::KEY_AES, + policy.extractable).generateSKey(keyGenAlgorithm, policy.password); - handler.database.saveRow(row); + // save the data + DB::Row row(std::move(key), name, ownerLabel, + static_cast<int>(policy.extractable)); + handler.crypto.encryptRow(row); - transaction.commit(); - return CKM_API_SUCCESS; + handler.database.saveRow(row); + + transaction.commit(); + return CKM_API_SUCCESS; } int CKMLogic::createKeyPairHelper( - const Credentials &cred, - const CryptoAlgorithmSerializable & keyGenParams, - const Name &namePrivate, - const Label &labelPrivate, - const Name &namePublic, - const Label &labelPublic, - const PolicySerializable &policyPrivate, - const PolicySerializable &policyPublic) + const Credentials &cred, + const CryptoAlgorithmSerializable &keyGenParams, + const Name &namePrivate, + const Label &labelPrivate, + const Name &namePublic, + const Label &labelPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic) { - auto &handlerPriv = selectDatabase(cred, labelPrivate); - auto &handlerPub = selectDatabase(cred, labelPublic); - - AlgoType keyType = AlgoType::RSA_GEN; - if (!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType)) - ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found."); - - DataType dt(keyType); - if (!dt.isKey()) - ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value."); - - // use client label if not explicitly provided - const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel : labelPrivate; - if (m_accessControl.isSystemService(cred) && ownerLabelPrv.compare(OWNER_ID_SYSTEM) != 0) - return CKM_API_ERROR_INPUT_PARAM; - - const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel : labelPublic; - if (m_accessControl.isSystemService(cred) && ownerLabelPub.compare(OWNER_ID_SYSTEM) != 0) - return CKM_API_ERROR_INPUT_PARAM; - - bool exportable = policyPrivate.extractable || policyPublic.extractable; - TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams, - policyPrivate.password, - policyPublic.password); - - DB::Crypto::Transaction transactionPriv(&handlerPriv.database); - // in case the same database is used for private and public - the second - // transaction will not be executed - DB::Crypto::Transaction transactionPub(&handlerPub.database); - - int retCode; - retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv); - if (CKM_API_SUCCESS != retCode) - return retCode; - - retCode = checkSaveConditions(cred, handlerPub, namePublic, ownerLabelPub); - if (CKM_API_SUCCESS != retCode) - return retCode; - - // save the data - DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv, static_cast<int>(policyPrivate.extractable)); - handlerPriv.crypto.encryptRow(rowPrv); - handlerPriv.database.saveRow(rowPrv); - - DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub, static_cast<int>(policyPublic.extractable)); - handlerPub.crypto.encryptRow(rowPub); - handlerPub.database.saveRow(rowPub); - - transactionPub.commit(); - transactionPriv.commit(); - return CKM_API_SUCCESS; + auto &handlerPriv = selectDatabase(cred, labelPrivate); + auto &handlerPub = selectDatabase(cred, labelPublic); + + AlgoType keyType = AlgoType::RSA_GEN; + + if (!keyGenParams.getParam(ParamName::ALGO_TYPE, keyType)) + ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE not found."); + + DataType dt(keyType); + + if (!dt.isKey()) + ThrowErr(Exc::InputParam, "Error, parameter ALGO_TYPE with wrong value."); + + // use client label if not explicitly provided + const Label &ownerLabelPrv = labelPrivate.empty() ? cred.smackLabel : + labelPrivate; + + if (m_accessControl.isSystemService(cred) && + ownerLabelPrv.compare(OWNER_ID_SYSTEM) != 0) + return CKM_API_ERROR_INPUT_PARAM; + + const Label &ownerLabelPub = labelPublic.empty() ? cred.smackLabel : + labelPublic; + + if (m_accessControl.isSystemService(cred) && + ownerLabelPub.compare(OWNER_ID_SYSTEM) != 0) + return CKM_API_ERROR_INPUT_PARAM; + + bool exportable = policyPrivate.extractable || policyPublic.extractable; + TokenPair keys = m_decider.getStore(dt, exportable).generateAKey(keyGenParams, + policyPrivate.password, + policyPublic.password); + + DB::Crypto::Transaction transactionPriv(&handlerPriv.database); + // in case the same database is used for private and public - the second + // transaction will not be executed + DB::Crypto::Transaction transactionPub(&handlerPub.database); + + int retCode; + retCode = checkSaveConditions(cred, handlerPriv, namePrivate, ownerLabelPrv); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + retCode = checkSaveConditions(cred, handlerPub, namePublic, ownerLabelPub); + + if (CKM_API_SUCCESS != retCode) + return retCode; + + // save the data + DB::Row rowPrv(std::move(keys.first), namePrivate, ownerLabelPrv, + static_cast<int>(policyPrivate.extractable)); + handlerPriv.crypto.encryptRow(rowPrv); + handlerPriv.database.saveRow(rowPrv); + + DB::Row rowPub(std::move(keys.second), namePublic, ownerLabelPub, + static_cast<int>(policyPublic.extractable)); + handlerPub.crypto.encryptRow(rowPub); + handlerPub.database.saveRow(rowPub); + + transactionPub.commit(); + transactionPriv.commit(); + return CKM_API_SUCCESS; } RawBuffer CKMLogic::createKeyPair( - const Credentials &cred, - int commandId, - const CryptoAlgorithmSerializable & keyGenParams, - const Name &namePrivate, - const Label &labelPrivate, - const Name &namePublic, - const Label &labelPublic, - const PolicySerializable &policyPrivate, - const PolicySerializable &policyPublic) + const Credentials &cred, + int commandId, + const CryptoAlgorithmSerializable &keyGenParams, + const Name &namePrivate, + const Label &labelPrivate, + const Name &namePublic, + const Label &labelPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic) { - int retCode = CKM_API_SUCCESS; - - try { - retCode = createKeyPairHelper( - cred, - keyGenParams, - namePrivate, - labelPrivate, - namePublic, - labelPublic, - policyPrivate, - policyPublic); - } catch(const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR), - commandId, retCode).Pop(); + int retCode = CKM_API_SUCCESS; + + try { + retCode = createKeyPairHelper( + cred, + keyGenParams, + namePrivate, + labelPrivate, + namePublic, + labelPublic, + policyPrivate, + policyPublic); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_PAIR), + commandId, retCode).Pop(); } RawBuffer CKMLogic::createKeyAES( - const Credentials &cred, - int commandId, - const int size, - const Name &name, - const Label &label, - const PolicySerializable &policy) + const Credentials &cred, + int commandId, + const int size, + const Name &name, + const Label &label, + const PolicySerializable &policy) { - int retCode = CKM_API_SUCCESS; - - try { - retCode = createKeyAESHelper(cred, size, name, label, policy); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (std::invalid_argument &e) { - LogDebug("invalid argument error: " << e.what()); - retCode = CKM_API_ERROR_INPUT_PARAM; - } catch (const CKM::Exception &e) { - LogError("CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES), - commandId, retCode).Pop(); + int retCode = CKM_API_SUCCESS; + + try { + retCode = createKeyAESHelper(cred, size, name, label, policy); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (std::invalid_argument &e) { + LogDebug("invalid argument error: " << e.what()); + retCode = CKM_API_ERROR_INPUT_PARAM; + } catch (const CKM::Exception &e) { + LogError("CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + return MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_KEY_AES), + commandId, retCode).Pop(); } int CKMLogic::readCertificateHelper( - const Credentials &cred, - const LabelNameVector &labelNameVector, - CertificateImplVector &certVector) + const Credentials &cred, + const LabelNameVector &labelNameVector, + CertificateImplVector &certVector) { - DB::Row row; - for (auto &i: labelNameVector) { - // certificates can't be protected with custom user password - Crypto::GObjUPtr obj; - int ec; - ec = readDataHelper(true, - cred, - DataType::CERTIFICATE, - i.second, - i.first, - Password(), - obj); - if (ec != CKM_API_SUCCESS) - return ec; - - certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER); - - // try to read chain certificates (if present) - Crypto::GObjUPtrVector caChainObjs; - ec = readDataHelper(true, - cred, - DataType::DB_CHAIN_FIRST, - i.second, - i.first, - CKM::Password(), - caChainObjs); - if (ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN) - return ec; - for (auto &caCertObj : caChainObjs) - certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER); - } - return CKM_API_SUCCESS; + DB::Row row; + + for (auto &i : labelNameVector) { + // certificates can't be protected with custom user password + Crypto::GObjUPtr obj; + int ec; + ec = readDataHelper(true, + cred, + DataType::CERTIFICATE, + i.second, + i.first, + Password(), + obj); + + if (ec != CKM_API_SUCCESS) + return ec; + + certVector.emplace_back(obj->getBinary(), DataFormat::FORM_DER); + + // try to read chain certificates (if present) + Crypto::GObjUPtrVector caChainObjs; + ec = readDataHelper(true, + cred, + DataType::DB_CHAIN_FIRST, + i.second, + i.first, + CKM::Password(), + caChainObjs); + + if (ec != CKM_API_SUCCESS && ec != CKM_API_ERROR_DB_ALIAS_UNKNOWN) + return ec; + + for (auto &caCertObj : caChainObjs) + certVector.emplace_back(caCertObj->getBinary(), DataFormat::FORM_DER); + } + + return CKM_API_SUCCESS; } int CKMLogic::getCertificateChainHelper( - const CertificateImpl &cert, - const RawBufferVector &untrustedCertificates, - const RawBufferVector &trustedCertificates, - bool useTrustedSystemCertificates, - RawBufferVector &chainRawVector) + const CertificateImpl &cert, + const RawBufferVector &untrustedCertificates, + const RawBufferVector &trustedCertificates, + bool useTrustedSystemCertificates, + RawBufferVector &chainRawVector) { - CertificateImplVector untrustedCertVector; - CertificateImplVector trustedCertVector; - CertificateImplVector chainVector; - - if (cert.empty()) - return CKM_API_ERROR_INPUT_PARAM; - - for (auto &e: untrustedCertificates) { - CertificateImpl c(e, DataFormat::FORM_DER); - if (c.empty()) - return CKM_API_ERROR_INPUT_PARAM; - untrustedCertVector.push_back(std::move(c)); - } - for (auto &e: trustedCertificates) { - CertificateImpl c(e, DataFormat::FORM_DER); - if (c.empty()) - return CKM_API_ERROR_INPUT_PARAM; - trustedCertVector.push_back(std::move(c)); - } - - CertificateStore store; - int retCode = store.verifyCertificate(cert, - untrustedCertVector, - trustedCertVector, - useTrustedSystemCertificates, - m_accessControl.isCCMode(), - chainVector); - if (retCode != CKM_API_SUCCESS) - return retCode; - - for (auto &e : chainVector) - chainRawVector.push_back(e.getDER()); - return CKM_API_SUCCESS; + CertificateImplVector untrustedCertVector; + CertificateImplVector trustedCertVector; + CertificateImplVector chainVector; + + if (cert.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + for (auto &e : untrustedCertificates) { + CertificateImpl c(e, DataFormat::FORM_DER); + + if (c.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + untrustedCertVector.push_back(std::move(c)); + } + + for (auto &e : trustedCertificates) { + CertificateImpl c(e, DataFormat::FORM_DER); + + if (c.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + trustedCertVector.push_back(std::move(c)); + } + + CertificateStore store; + int retCode = store.verifyCertificate(cert, + untrustedCertVector, + trustedCertVector, + useTrustedSystemCertificates, + m_accessControl.isCCMode(), + chainVector); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + for (auto &e : chainVector) + chainRawVector.push_back(e.getDER()); + + return CKM_API_SUCCESS; } int CKMLogic::getCertificateChainHelper( - const Credentials &cred, - const CertificateImpl &cert, - const LabelNameVector &untrusted, - const LabelNameVector &trusted, - bool useTrustedSystemCertificates, - RawBufferVector &chainRawVector) + const Credentials &cred, + const CertificateImpl &cert, + const LabelNameVector &untrusted, + const LabelNameVector &trusted, + bool useTrustedSystemCertificates, + RawBufferVector &chainRawVector) { - CertificateImplVector untrustedCertVector; - CertificateImplVector trustedCertVector; - CertificateImplVector chainVector; - DB::Row row; - - if (cert.empty()) - return CKM_API_ERROR_INPUT_PARAM; - - int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector); - if (retCode != CKM_API_SUCCESS) - return retCode; - retCode = readCertificateHelper(cred, trusted, trustedCertVector); - if (retCode != CKM_API_SUCCESS) - return retCode; - - CertificateStore store; - retCode = store.verifyCertificate(cert, - untrustedCertVector, - trustedCertVector, - useTrustedSystemCertificates, - m_accessControl.isCCMode(), - chainVector); - if (retCode != CKM_API_SUCCESS) - return retCode; - - for (auto &i: chainVector) - chainRawVector.push_back(i.getDER()); - - return CKM_API_SUCCESS; + CertificateImplVector untrustedCertVector; + CertificateImplVector trustedCertVector; + CertificateImplVector chainVector; + DB::Row row; + + if (cert.empty()) + return CKM_API_ERROR_INPUT_PARAM; + + int retCode = readCertificateHelper(cred, untrusted, untrustedCertVector); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + retCode = readCertificateHelper(cred, trusted, trustedCertVector); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + CertificateStore store; + retCode = store.verifyCertificate(cert, + untrustedCertVector, + trustedCertVector, + useTrustedSystemCertificates, + m_accessControl.isCCMode(), + chainVector); + + if (retCode != CKM_API_SUCCESS) + return retCode; + + for (auto &i : chainVector) + chainRawVector.push_back(i.getDER()); + + return CKM_API_SUCCESS; } RawBuffer CKMLogic::getCertificateChain( - const Credentials & /*cred*/, - int commandId, - const RawBuffer &certificate, - const RawBufferVector &untrustedCertificates, - const RawBufferVector &trustedCertificates, - bool useTrustedSystemCertificates) + const Credentials & /*cred*/, + int commandId, + const RawBuffer &certificate, + const RawBufferVector &untrustedCertificates, + const RawBufferVector &trustedCertificates, + bool useTrustedSystemCertificates) { - CertificateImpl cert(certificate, DataFormat::FORM_DER); - RawBufferVector chainRawVector; - int retCode = CKM_API_ERROR_UNKNOWN; - try { - retCode = getCertificateChainHelper(cert, - untrustedCertificates, - trustedCertificates, - useTrustedSystemCertificates, - chainRawVector); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const std::exception& e) { - LogError("STD exception " << e.what()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } catch (...) { - LogError("Unknown error."); - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_CERT), - commandId, - retCode, - chainRawVector); - return response.Pop(); + CertificateImpl cert(certificate, DataFormat::FORM_DER); + RawBufferVector chainRawVector; + int retCode = CKM_API_ERROR_UNKNOWN; + + try { + retCode = getCertificateChainHelper(cert, + untrustedCertificates, + trustedCertificates, + useTrustedSystemCertificates, + chainRawVector); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } catch (...) { + LogError("Unknown error."); + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::GET_CHAIN_CERT), + commandId, + retCode, + chainRawVector); + return response.Pop(); } RawBuffer CKMLogic::getCertificateChain( - const Credentials &cred, - int commandId, - const RawBuffer &certificate, - const LabelNameVector &untrustedCertificates, - const LabelNameVector &trustedCertificates, - bool useTrustedSystemCertificates) + const Credentials &cred, + int commandId, + const RawBuffer &certificate, + const LabelNameVector &untrustedCertificates, + const LabelNameVector &trustedCertificates, + bool useTrustedSystemCertificates) { - int retCode = CKM_API_ERROR_UNKNOWN; - CertificateImpl cert(certificate, DataFormat::FORM_DER); - RawBufferVector chainRawVector; - try { - retCode = getCertificateChainHelper(cred, - cert, - untrustedCertificates, - trustedCertificates, - useTrustedSystemCertificates, - chainRawVector); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const std::exception& e) { - LogError("STD exception " << e.what()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } catch (...) { - LogError("Unknown error."); - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::GET_CHAIN_ALIAS), - commandId, - retCode, - chainRawVector); - return response.Pop(); + int retCode = CKM_API_ERROR_UNKNOWN; + CertificateImpl cert(certificate, DataFormat::FORM_DER); + RawBufferVector chainRawVector; + + try { + retCode = getCertificateChainHelper(cred, + cert, + untrustedCertificates, + trustedCertificates, + useTrustedSystemCertificates, + chainRawVector); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } catch (...) { + LogError("Unknown error."); + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::GET_CHAIN_ALIAS), + commandId, + retCode, + chainRawVector); + return response.Pop(); } RawBuffer CKMLogic::createSignature( - const Credentials &cred, - int commandId, - const Name &privateKeyName, - const Label & ownerLabel, - const Password &password, // password for private_key - const RawBuffer &message, - const CryptoAlgorithm &cryptoAlg) + const Credentials &cred, + int commandId, + const Name &privateKeyName, + const Label &ownerLabel, + const Password &password, // password for private_key + const RawBuffer &message, + const CryptoAlgorithm &cryptoAlg) { - DB::Row row; - RawBuffer signature; - - int retCode = CKM_API_SUCCESS; - - try { - Crypto::GObjUPtr obj; - retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, ownerLabel, password, obj); - if (retCode == CKM_API_SUCCESS) - signature = obj->sign(cryptoAlg, message); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("Unknown CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } catch (const std::exception &e) { - LogError("STD exception " << e.what()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::CREATE_SIGNATURE), - commandId, - retCode, - signature); - return response.Pop(); + DB::Row row; + RawBuffer signature; + + int retCode = CKM_API_SUCCESS; + + try { + Crypto::GObjUPtr obj; + retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, privateKeyName, + ownerLabel, password, obj); + + if (retCode == CKM_API_SUCCESS) + signature = obj->sign(cryptoAlg, message); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("Unknown CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::CREATE_SIGNATURE), + commandId, + retCode, + signature); + return response.Pop(); } RawBuffer CKMLogic::verifySignature( - const Credentials &cred, - int commandId, - const Name &publicKeyOrCertName, - const Label & ownerLabel, - const Password &password, // password for public_key (optional) - const RawBuffer &message, - const RawBuffer &signature, - const CryptoAlgorithm ¶ms) + const Credentials &cred, + int commandId, + const Name &publicKeyOrCertName, + const Label &ownerLabel, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const CryptoAlgorithm ¶ms) { - int retCode = CKM_API_ERROR_VERIFICATION_FAILED; - - try { - DB::Row row; - - // try certificate first - looking for a public key. - // in case of PKCS, pub key from certificate will be found first - // rather than private key from the same PKCS. - Crypto::GObjUPtr obj; - retCode = readDataHelper(false, cred, DataType::CERTIFICATE, publicKeyOrCertName, ownerLabel, password, obj); - if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) - retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, publicKeyOrCertName, ownerLabel, password, obj); - - if (retCode == CKM_API_SUCCESS) - retCode = obj->verify(params, message, signature); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("Unknown CKM::Exception: " << e.GetMessage()); - retCode = CKM_API_ERROR_SERVER_ERROR; - } - - auto response = MessageBuffer::Serialize(static_cast<int>(LogicCommand::VERIFY_SIGNATURE), - commandId, - retCode); - return response.Pop(); + int retCode = CKM_API_ERROR_VERIFICATION_FAILED; + + try { + DB::Row row; + + // try certificate first - looking for a public key. + // in case of PKCS, pub key from certificate will be found first + // rather than private key from the same PKCS. + Crypto::GObjUPtr obj; + retCode = readDataHelper(false, cred, DataType::CERTIFICATE, + publicKeyOrCertName, ownerLabel, password, obj); + + if (retCode == CKM_API_ERROR_DB_ALIAS_UNKNOWN) + retCode = readDataHelper(false, cred, DataType::DB_KEY_FIRST, + publicKeyOrCertName, ownerLabel, password, obj); + + if (retCode == CKM_API_SUCCESS) + retCode = obj->verify(params, message, signature); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("Unknown CKM::Exception: " << e.GetMessage()); + retCode = CKM_API_ERROR_SERVER_ERROR; + } + + auto response = MessageBuffer::Serialize(static_cast<int> + (LogicCommand::VERIFY_SIGNATURE), + commandId, + retCode); + return response.Pop(); } int CKMLogic::setPermissionHelper( - const Credentials &cred, // who's the client - const Name &name, - const Label &label, // who's the owner - const Label &accessorLabel, // who will get the access - const PermissionMask permissionMask) + const Credentials &cred, // who's the client + const Name &name, + const Label &label, // who's the owner + const Label &accessorLabel, // who will get the access + const PermissionMask permissionMask) { - auto &handler = selectDatabase(cred, label); + auto &handler = selectDatabase(cred, label); + + // we don't know the client + if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel)) + return CKM_API_ERROR_INPUT_PARAM; - // we don't know the client - if (cred.smackLabel.empty() || !isLabelValid(cred.smackLabel)) - return CKM_API_ERROR_INPUT_PARAM; + // use client label if not explicitly provided + const Label &ownerLabel = label.empty() ? cred.smackLabel : label; - // use client label if not explicitly provided - const Label& ownerLabel = label.empty() ? cred.smackLabel : label; + // verify name and label are correct + if (!isNameValid(name) || !isLabelValid(ownerLabel) || + !isLabelValid(accessorLabel)) + return CKM_API_ERROR_INPUT_PARAM; - // verify name and label are correct - if (!isNameValid(name) || !isLabelValid(ownerLabel) || !isLabelValid(accessorLabel)) - return CKM_API_ERROR_INPUT_PARAM; + // currently we don't support modification of owner's permissions to his own rows + if (ownerLabel == accessorLabel) + return CKM_API_ERROR_INPUT_PARAM; - // currently we don't support modification of owner's permissions to his own rows - if (ownerLabel == accessorLabel) - return CKM_API_ERROR_INPUT_PARAM; + // system database does not support write/remove permissions + if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) && + (permissionMask & Permission::REMOVE)) + return CKM_API_ERROR_INPUT_PARAM; - // system database does not support write/remove permissions - if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) && - (permissionMask & Permission::REMOVE)) - return CKM_API_ERROR_INPUT_PARAM; + // can the client modify permissions to owner's row? + int retCode = m_accessControl.canModify(cred, ownerLabel); - // can the client modify permissions to owner's row? - int retCode = m_accessControl.canModify(cred, ownerLabel); - if (retCode != CKM_API_SUCCESS) - return retCode; + if (retCode != CKM_API_SUCCESS) + return retCode; - DB::Crypto::Transaction transaction(&handler.database); + DB::Crypto::Transaction transaction(&handler.database); - if (!handler.database.isNameLabelPresent(name, ownerLabel)) - return CKM_API_ERROR_DB_ALIAS_UNKNOWN; + if (!handler.database.isNameLabelPresent(name, ownerLabel)) + return CKM_API_ERROR_DB_ALIAS_UNKNOWN; - // removing non-existing permissions: fail - if (permissionMask == Permission::NONE) { - if (!handler.database.getPermissionRow(name, ownerLabel, accessorLabel)) - return CKM_API_ERROR_INPUT_PARAM; - } + // removing non-existing permissions: fail + if (permissionMask == Permission::NONE) { + if (!handler.database.getPermissionRow(name, ownerLabel, accessorLabel)) + return CKM_API_ERROR_INPUT_PARAM; + } - // set permissions to the row owned by ownerLabel for accessorLabel - handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask); - transaction.commit(); + // set permissions to the row owned by ownerLabel for accessorLabel + handler.database.setPermission(name, ownerLabel, accessorLabel, permissionMask); + transaction.commit(); - return CKM_API_SUCCESS; + return CKM_API_SUCCESS; } RawBuffer CKMLogic::setPermission( - const Credentials &cred, - const int command, - const int msgID, - const Name &name, - const Label &label, - const Label &accessorLabel, - const PermissionMask permissionMask) + const Credentials &cred, + const int command, + const int msgID, + const Name &name, + const Label &label, + const Label &accessorLabel, + const PermissionMask permissionMask) { - int retCode; - try { - retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask); - } catch (const Exc::Exception &e) { - retCode = e.error(); - } catch (const CKM::Exception &e) { - LogError("Error: " << e.GetMessage()); - retCode = CKM_API_ERROR_DB_ERROR; - } - - return MessageBuffer::Serialize(command, msgID, retCode).Pop(); + int retCode; + + try { + retCode = setPermissionHelper(cred, name, label, accessorLabel, permissionMask); + } catch (const Exc::Exception &e) { + retCode = e.error(); + } catch (const CKM::Exception &e) { + LogError("Error: " << e.GetMessage()); + retCode = CKM_API_ERROR_DB_ERROR; + } + + return MessageBuffer::Serialize(command, msgID, retCode).Pop(); } -int CKMLogic::loadAppKey(UserData& handle, const Label& appLabel) +int CKMLogic::loadAppKey(UserData &handle, const Label &appLabel) { - if (!handle.crypto.haveKey(appLabel)) { - RawBuffer key; - auto key_optional = handle.database.getKey(appLabel); - if (!key_optional) { - LogError("No key for given label in database"); - return CKM_API_ERROR_DB_ERROR; - } - key = *key_optional; - key = handle.keyProvider.getPureDEK(key); - handle.crypto.pushKey(appLabel, key); - } - return CKM_API_SUCCESS; + if (!handle.crypto.haveKey(appLabel)) { + RawBuffer key; + auto key_optional = handle.database.getKey(appLabel); + + if (!key_optional) { + LogError("No key for given label in database"); + return CKM_API_ERROR_DB_ERROR; + } + + key = *key_optional; + key = handle.keyProvider.getPureDEK(key); + handle.crypto.pushKey(appLabel, key); + } + + return CKM_API_SUCCESS; } } // namespace CKM diff --git a/src/manager/service/ckm-logic.h b/src/manager/service/ckm-logic.h index dafe530d..a1182028 100644 --- a/src/manager/service/ckm-logic.h +++ b/src/manager/service/ckm-logic.h @@ -42,364 +42,364 @@ namespace CKM { struct UserData { - KeyProvider keyProvider; - DB::Crypto database; - CryptoLogic crypto; + KeyProvider keyProvider; + DB::Crypto database; + CryptoLogic crypto; }; class CKMLogic { public: - static const uid_t SYSTEM_DB_UID; - - CKMLogic(); - CKMLogic(const CKMLogic &) = delete; - CKMLogic(CKMLogic &&) = delete; - CKMLogic& operator=(const CKMLogic &) = delete; - CKMLogic& operator=(CKMLogic &&) = delete; - virtual ~CKMLogic(); - - RawBuffer unlockUserKey(uid_t user, const Password &password); - RawBuffer lockUserKey(uid_t user); - - RawBuffer removeUserData(uid_t user); - - RawBuffer changeUserPassword( - uid_t user, - const Password &oldPassword, - const Password &newPassword); - - RawBuffer resetUserPassword( - uid_t user, - const Password &newPassword); - - RawBuffer removeApplicationData( - const Label &smackLabel); - - RawBuffer saveData( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label, - const Crypto::Data &data, - const PolicySerializable &policy); - - RawBuffer savePKCS12( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label, - const PKCS12Serializable &pkcs, - const PolicySerializable &keyPolicy, - const PolicySerializable &certPolicy); - - RawBuffer removeData( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label); - - RawBuffer getData( - const Credentials &cred, - int commandId, - DataType dataType, - const Name &name, - const Label &label, - const Password &password); - - RawBuffer getPKCS12( - const Credentials &cred, - int commandId, - const Name &name, - const Label &label, - const Password &keyPassword, - const Password &certPassword); - - RawBuffer getDataList( - const Credentials &cred, - int commandId, - DataType dataType); - - RawBuffer createKeyPair( - const Credentials &cred, - int commandId, - const CryptoAlgorithmSerializable & keyGenParams, - const Name &namePrivate, - const Label &labelPrivate, - const Name &namePublic, - const Label &labelPublic, - const PolicySerializable &policyPrivate, - const PolicySerializable &policyPublic); - - RawBuffer createKeyAES( - const Credentials &cred, - int commandId, - const int size, - const Name &name, - const Label &label, - const PolicySerializable &policy); - - RawBuffer getCertificateChain( - const Credentials &cred, - int commandId, - const RawBuffer &certificate, - const RawBufferVector &untrustedCertificates, - const RawBufferVector &trustedCertificates, - bool useTrustedSystemCertificates); - - RawBuffer getCertificateChain( - const Credentials &cred, - int commandId, - const RawBuffer &certificate, - const LabelNameVector &untrustedCertificates, - const LabelNameVector &trustedCertificates, - bool useTrustedSystemCertificates); - - RawBuffer createSignature( - const Credentials &cred, - int commandId, - const Name &privateKeyName, - const Label & ownerLabel, - const Password &password, // password for private_key - const RawBuffer &message, - const CryptoAlgorithm &cryptoAlgorithm); - - RawBuffer verifySignature( - const Credentials &cred, - int commandId, - const Name &publicKeyOrCertName, - const Label &label, - const Password &password, // password for public_key (optional) - const RawBuffer &message, - const RawBuffer &signature, - const CryptoAlgorithm &cryptoAlgorithm); - - RawBuffer updateCCMode(); - - RawBuffer setPermission( - const Credentials &cred, - const int command, - const int msgID, - const Name &name, - const Label &label, - const Label &accessor_label, - const PermissionMask permissionMask); - - int setPermissionHelper( - const Credentials &cred, - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel, - const PermissionMask permissionMask); - - int verifyAndSaveDataHelper( - const Credentials &cred, - const Name &name, - const Label &label, - const Crypto::Data &data, - const PolicySerializable &policy); - - int getKeyForService( - const Credentials &cred, - const Name &name, - const Label &label, - const Password& pass, - Crypto::GObjShPtr& key); - - int importInitialData( - const Name &name, - const Crypto::Data &data, - const Crypto::DataEncryption &enc, - const Policy &policy); + static const uid_t SYSTEM_DB_UID; + + CKMLogic(); + CKMLogic(const CKMLogic &) = delete; + CKMLogic(CKMLogic &&) = delete; + CKMLogic &operator=(const CKMLogic &) = delete; + CKMLogic &operator=(CKMLogic &&) = delete; + virtual ~CKMLogic(); + + RawBuffer unlockUserKey(uid_t user, const Password &password); + RawBuffer lockUserKey(uid_t user); + + RawBuffer removeUserData(uid_t user); + + RawBuffer changeUserPassword( + uid_t user, + const Password &oldPassword, + const Password &newPassword); + + RawBuffer resetUserPassword( + uid_t user, + const Password &newPassword); + + RawBuffer removeApplicationData( + const Label &smackLabel); + + RawBuffer saveData( + const Credentials &cred, + int commandId, + const Name &name, + const Label &label, + const Crypto::Data &data, + const PolicySerializable &policy); + + RawBuffer savePKCS12( + const Credentials &cred, + int commandId, + const Name &name, + const Label &label, + const PKCS12Serializable &pkcs, + const PolicySerializable &keyPolicy, + const PolicySerializable &certPolicy); + + RawBuffer removeData( + const Credentials &cred, + int commandId, + const Name &name, + const Label &label); + + RawBuffer getData( + const Credentials &cred, + int commandId, + DataType dataType, + const Name &name, + const Label &label, + const Password &password); + + RawBuffer getPKCS12( + const Credentials &cred, + int commandId, + const Name &name, + const Label &label, + const Password &keyPassword, + const Password &certPassword); + + RawBuffer getDataList( + const Credentials &cred, + int commandId, + DataType dataType); + + RawBuffer createKeyPair( + const Credentials &cred, + int commandId, + const CryptoAlgorithmSerializable &keyGenParams, + const Name &namePrivate, + const Label &labelPrivate, + const Name &namePublic, + const Label &labelPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic); + + RawBuffer createKeyAES( + const Credentials &cred, + int commandId, + const int size, + const Name &name, + const Label &label, + const PolicySerializable &policy); + + RawBuffer getCertificateChain( + const Credentials &cred, + int commandId, + const RawBuffer &certificate, + const RawBufferVector &untrustedCertificates, + const RawBufferVector &trustedCertificates, + bool useTrustedSystemCertificates); + + RawBuffer getCertificateChain( + const Credentials &cred, + int commandId, + const RawBuffer &certificate, + const LabelNameVector &untrustedCertificates, + const LabelNameVector &trustedCertificates, + bool useTrustedSystemCertificates); + + RawBuffer createSignature( + const Credentials &cred, + int commandId, + const Name &privateKeyName, + const Label &ownerLabel, + const Password &password, // password for private_key + const RawBuffer &message, + const CryptoAlgorithm &cryptoAlgorithm); + + RawBuffer verifySignature( + const Credentials &cred, + int commandId, + const Name &publicKeyOrCertName, + const Label &label, + const Password &password, // password for public_key (optional) + const RawBuffer &message, + const RawBuffer &signature, + const CryptoAlgorithm &cryptoAlgorithm); + + RawBuffer updateCCMode(); + + RawBuffer setPermission( + const Credentials &cred, + const int command, + const int msgID, + const Name &name, + const Label &label, + const Label &accessor_label, + const PermissionMask permissionMask); + + int setPermissionHelper( + const Credentials &cred, + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const PermissionMask permissionMask); + + int verifyAndSaveDataHelper( + const Credentials &cred, + const Name &name, + const Label &label, + const Crypto::Data &data, + const PolicySerializable &policy); + + int getKeyForService( + const Credentials &cred, + const Name &name, + const Label &label, + const Password &pass, + Crypto::GObjShPtr &key); + + int importInitialData( + const Name &name, + const Crypto::Data &data, + const Crypto::DataEncryption &enc, + const Policy &policy); protected: - int unlockSystemDB(); + int unlockSystemDB(); private: - // select private/system database depending on asking uid and owner label. - // output: database handler and effective label - UserData & selectDatabase(const Credentials &incoming_cred, - const Label &incoming_label); - - int unlockDatabase(uid_t user, - const Password & password); - - void loadDKEKFile( - uid_t user, - const Password &password); - - void saveDKEKFile( - uid_t user, - const Password &password); - - int verifyBinaryData(Crypto::Data &input_data) const; - - int toBinaryData( - const Crypto::Data &input_data, - Crypto::Data &output_data) const; - - int checkSaveConditions( - const Credentials &cred, - UserData &handler, - const Name &name, - const Label &label); - - int saveDataHelper( - const Credentials &cred, - const Name &name, - const Label &label, - const Crypto::Data &data, - const PolicySerializable &policy); - - int saveDataHelper( - const Credentials &cred, - const Name &name, - const Label &label, - const PKCS12Serializable &pkcs, - const PolicySerializable &keyPolicy, - const PolicySerializable &certPolicy); - - DB::Row createEncryptedRow( - CryptoLogic &crypto, - const Name &name, - const Label &label, - const Crypto::Data &data, - const Policy &policy) const; - - int getPKCS12Helper( - const Credentials &cred, - const Name &name, - const Label &label, - const Password &keyPassword, - const Password &certPassword, - KeyShPtr & privKey, - CertificateShPtr & cert, - CertificateShPtrVector & caChain); - - int extractPKCS12Data( - CryptoLogic &crypto, - const Name &name, - const Label &ownerLabel, - const PKCS12Serializable &pkcs, - const PolicySerializable &keyPolicy, - const PolicySerializable &certPolicy, - DB::RowVector &output) const; - - int removeDataHelper( - const Credentials &cred, - const Name &name, - const Label &ownerLabel); - - int readSingleRow( - const Name &name, - const Label &ownerLabel, - DataType dataType, - DB::Crypto & database, - DB::Row &row); - - int readMultiRow(const Name &name, - const Label &ownerLabel, - DataType dataType, - DB::Crypto & database, - DB::RowVector &output); - - int checkDataPermissionsHelper( - const Credentials &cred, - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel, - const DB::Row &row, - bool exportFlag, - DB::Crypto & database); - - Crypto::GObjUPtr rowToObject( - UserData& handler, - DB::Row row, - const Password& password); - - int readDataHelper( - bool exportFlag, - const Credentials &cred, - DataType dataType, - const Name &name, - const Label &label, - const Password &password, - Crypto::GObjUPtr &obj); - - int readDataHelper( - bool exportFlag, - const Credentials &cred, - DataType dataType, - const Name &name, - const Label &label, - const Password &password, - Crypto::GObjUPtr &obj, - DataType& objDataType); - - int readDataHelper( - bool exportFlag, - const Credentials &cred, - DataType dataType, - const Name &name, - const Label &label, - const Password &password, - Crypto::GObjUPtrVector &objs); - - int createKeyAESHelper( - const Credentials &cred, - const int size, - const Name &name, - const Label &label, - const PolicySerializable &policy); - - int createKeyPairHelper( - const Credentials &cred, - const CryptoAlgorithmSerializable & keyGenParams, - const Name &namePrivate, - const Label &labelPrivate, - const Name &namePublic, - const Label &labelPublic, - const PolicySerializable &policyPrivate, - const PolicySerializable &policyPublic); - - int readCertificateHelper( - const Credentials &cred, - const LabelNameVector &labelNameVector, - CertificateImplVector &certVector); - - int getCertificateChainHelper( - const CertificateImpl &cert, - const RawBufferVector &untrustedCertificates, - const RawBufferVector &trustedCertificates, - bool useTrustedSystemCertificates, - RawBufferVector &chainRawVector); - - int getCertificateChainHelper( - const Credentials &cred, - const CertificateImpl &cert, - const LabelNameVector &untrusted, - const LabelNameVector &trusted, - bool useTrustedSystemCertificates, - RawBufferVector &chainRawVector); - - int getDataListHelper( - const Credentials &cred, - const DataType dataType, - LabelNameVector &labelNameVector); - - int changeUserPasswordHelper(uid_t user, - const Password &oldPassword, - const Password &newPassword); - - int resetUserPasswordHelper(uid_t user, const Password &newPassword); - - int loadAppKey(UserData& handle, const Label& appLabel); - - AccessControl m_accessControl; - Crypto::Decider m_decider; - //FileLock m_lock; + // select private/system database depending on asking uid and owner label. + // output: database handler and effective label + UserData &selectDatabase(const Credentials &incoming_cred, + const Label &incoming_label); + + int unlockDatabase(uid_t user, + const Password &password); + + void loadDKEKFile( + uid_t user, + const Password &password); + + void saveDKEKFile( + uid_t user, + const Password &password); + + int verifyBinaryData(Crypto::Data &input_data) const; + + int toBinaryData( + const Crypto::Data &input_data, + Crypto::Data &output_data) const; + + int checkSaveConditions( + const Credentials &cred, + UserData &handler, + const Name &name, + const Label &label); + + int saveDataHelper( + const Credentials &cred, + const Name &name, + const Label &label, + const Crypto::Data &data, + const PolicySerializable &policy); + + int saveDataHelper( + const Credentials &cred, + const Name &name, + const Label &label, + const PKCS12Serializable &pkcs, + const PolicySerializable &keyPolicy, + const PolicySerializable &certPolicy); + + DB::Row createEncryptedRow( + CryptoLogic &crypto, + const Name &name, + const Label &label, + const Crypto::Data &data, + const Policy &policy) const; + + int getPKCS12Helper( + const Credentials &cred, + const Name &name, + const Label &label, + const Password &keyPassword, + const Password &certPassword, + KeyShPtr &privKey, + CertificateShPtr &cert, + CertificateShPtrVector &caChain); + + int extractPKCS12Data( + CryptoLogic &crypto, + const Name &name, + const Label &ownerLabel, + const PKCS12Serializable &pkcs, + const PolicySerializable &keyPolicy, + const PolicySerializable &certPolicy, + DB::RowVector &output) const; + + int removeDataHelper( + const Credentials &cred, + const Name &name, + const Label &ownerLabel); + + int readSingleRow( + const Name &name, + const Label &ownerLabel, + DataType dataType, + DB::Crypto &database, + DB::Row &row); + + int readMultiRow(const Name &name, + const Label &ownerLabel, + DataType dataType, + DB::Crypto &database, + DB::RowVector &output); + + int checkDataPermissionsHelper( + const Credentials &cred, + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const DB::Row &row, + bool exportFlag, + DB::Crypto &database); + + Crypto::GObjUPtr rowToObject( + UserData &handler, + DB::Row row, + const Password &password); + + int readDataHelper( + bool exportFlag, + const Credentials &cred, + DataType dataType, + const Name &name, + const Label &label, + const Password &password, + Crypto::GObjUPtr &obj); + + int readDataHelper( + bool exportFlag, + const Credentials &cred, + DataType dataType, + const Name &name, + const Label &label, + const Password &password, + Crypto::GObjUPtr &obj, + DataType &objDataType); + + int readDataHelper( + bool exportFlag, + const Credentials &cred, + DataType dataType, + const Name &name, + const Label &label, + const Password &password, + Crypto::GObjUPtrVector &objs); + + int createKeyAESHelper( + const Credentials &cred, + const int size, + const Name &name, + const Label &label, + const PolicySerializable &policy); + + int createKeyPairHelper( + const Credentials &cred, + const CryptoAlgorithmSerializable &keyGenParams, + const Name &namePrivate, + const Label &labelPrivate, + const Name &namePublic, + const Label &labelPublic, + const PolicySerializable &policyPrivate, + const PolicySerializable &policyPublic); + + int readCertificateHelper( + const Credentials &cred, + const LabelNameVector &labelNameVector, + CertificateImplVector &certVector); + + int getCertificateChainHelper( + const CertificateImpl &cert, + const RawBufferVector &untrustedCertificates, + const RawBufferVector &trustedCertificates, + bool useTrustedSystemCertificates, + RawBufferVector &chainRawVector); + + int getCertificateChainHelper( + const Credentials &cred, + const CertificateImpl &cert, + const LabelNameVector &untrusted, + const LabelNameVector &trusted, + bool useTrustedSystemCertificates, + RawBufferVector &chainRawVector); + + int getDataListHelper( + const Credentials &cred, + const DataType dataType, + LabelNameVector &labelNameVector); + + int changeUserPasswordHelper(uid_t user, + const Password &oldPassword, + const Password &newPassword); + + int resetUserPasswordHelper(uid_t user, const Password &newPassword); + + int loadAppKey(UserData &handle, const Label &appLabel); + + AccessControl m_accessControl; + Crypto::Decider m_decider; + //FileLock m_lock; protected: - std::map<uid_t, UserData> m_userDataMap; + std::map<uid_t, UserData> m_userDataMap; }; } // namespace CKM diff --git a/src/manager/service/ckm-service.cpp b/src/manager/service/ckm-service.cpp index 2951063f..0e970047 100644 --- a/src/manager/service/ckm-service.cpp +++ b/src/manager/service/ckm-service.cpp @@ -37,403 +37,414 @@ const CKM::InterfaceID SOCKET_ID_STORAGE = 1; namespace CKM { CKMService::CKMService() : - m_logic(new CKMLogic) + m_logic(new CKMLogic) { - InitialValues::LoadFiles(*m_logic); + InitialValues::LoadFiles(*m_logic); } CKMService::~CKMService() { - delete m_logic; + delete m_logic; } void CKMService::Start() { - Create(); + Create(); } void CKMService::Stop() { - Join(); + Join(); } -GenericSocketService::ServiceDescriptionVector CKMService::GetServiceDescription() +GenericSocketService::ServiceDescriptionVector +CKMService::GetServiceDescription() { - return ServiceDescriptionVector { - {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/keymanager.admin", SOCKET_ID_CONTROL}, - {SERVICE_SOCKET_CKM_STORAGE, "http://tizen.org/privilege/keymanager", SOCKET_ID_STORAGE} - }; + return ServiceDescriptionVector { + {SERVICE_SOCKET_CKM_CONTROL, "http://tizen.org/privilege/keymanager.admin", SOCKET_ID_CONTROL}, + {SERVICE_SOCKET_CKM_STORAGE, "http://tizen.org/privilege/keymanager", SOCKET_ID_STORAGE} + }; } void CKMService::SetCommManager(CommMgr *manager) { - ThreadService::SetCommManager(manager); - Register(*manager); + ThreadService::SetCommManager(manager); + Register(*manager); } // CKMService does not support security check // so 3rd parameter is not used bool CKMService::ProcessOne( - const ConnectionID &conn, - ConnectionInfo &info, - bool /*allowed*/) + const ConnectionID &conn, + ConnectionInfo &info, + bool /*allowed*/) { - LogDebug("process One"); - RawBuffer response; - - Try { - if (!info.buffer.Ready()) - return false; - - if (info.interfaceID == SOCKET_ID_CONTROL) - response = ProcessControl(info.buffer); - else - response = ProcessStorage(info.credentials, info.buffer); - - m_serviceManager->Write(conn, response); - - return true; - } Catch(MessageBuffer::Exception::Base) { - LogError("Broken protocol. Closing socket."); - } Catch(Exception::BrokenProtocol) { - LogError("Broken protocol. Closing socket."); - } catch (const DataType::Exception::Base &e) { - LogError("Closing socket. DBDataType::Exception: " << e.DumpToString()); - } catch (const std::string &e) { - LogError("String exception(" << e << "). Closing socket"); - } catch (const std::exception &e) { - LogError("Std exception:: " << e.what()); - } catch (...) { - LogError("Unknown exception. Closing socket."); - } - - m_serviceManager->Close(conn); - return false; + LogDebug("process One"); + RawBuffer response; + + try { + if (!info.buffer.Ready()) + return false; + + if (info.interfaceID == SOCKET_ID_CONTROL) + response = ProcessControl(info.buffer); + else + response = ProcessStorage(info.credentials, info.buffer); + + m_serviceManager->Write(conn, response); + + return true; + } catch (const MessageBuffer::Exception::Base &e) { + LogError("Broken protocol. Closing socket: " << e.DumpToString()); + } catch (const Exception::BrokenProtocol &e) { + LogError("Broken protocol. Closing socket: " << e.DumpToString()); + } catch (const DataType::Exception::Base &e) { + LogError("Closing socket. DBDataType::Exception: " << e.DumpToString()); + } catch (const std::string &e) { + LogError("String exception(" << e << "). Closing socket"); + } catch (const std::exception &e) { + LogError("Std exception:: " << e.what()); + } catch (...) { + LogError("Unknown exception. Closing socket."); + } + + m_serviceManager->Close(conn); + return false; } RawBuffer CKMService::ProcessControl(MessageBuffer &buffer) { - int command = 0; - uid_t user = 0; - ControlCommand cc; - Password newPass, oldPass; - Label smackLabel; - - buffer.Deserialize(command); - - LogDebug("Process control. Command: " << command); - - cc = static_cast<ControlCommand>(command); - - switch (cc) { - case ControlCommand::UNLOCK_USER_KEY: - buffer.Deserialize(user, newPass); - return m_logic->unlockUserKey(user, newPass); - case ControlCommand::LOCK_USER_KEY: - buffer.Deserialize(user); - return m_logic->lockUserKey(user); - case ControlCommand::REMOVE_USER_DATA: - buffer.Deserialize(user); - return m_logic->removeUserData(user); - case ControlCommand::CHANGE_USER_PASSWORD: - buffer.Deserialize(user, oldPass, newPass); - return m_logic->changeUserPassword(user, oldPass, newPass); - case ControlCommand::RESET_USER_PASSWORD: - buffer.Deserialize(user, newPass); - return m_logic->resetUserPassword(user, newPass); - case ControlCommand::REMOVE_APP_DATA: - buffer.Deserialize(smackLabel); - return m_logic->removeApplicationData(smackLabel); - case ControlCommand::UPDATE_CC_MODE: - return m_logic->updateCCMode(); - case ControlCommand::SET_PERMISSION: - { - Name name; - Label label; - Label accessorLabel; - PermissionMask permissionMask = 0; - - buffer.Deserialize(user, name, label, accessorLabel, permissionMask); - - Credentials cred(user, label); - return m_logic->setPermission( - cred, - command, - 0, // dummy - name, - label, - accessorLabel, - permissionMask); - } - default: - Throw(Exception::BrokenProtocol); - } + int command = 0; + uid_t user = 0; + ControlCommand cc; + Password newPass, oldPass; + Label smackLabel; + + buffer.Deserialize(command); + + LogDebug("Process control. Command: " << command); + + cc = static_cast<ControlCommand>(command); + + switch (cc) { + case ControlCommand::UNLOCK_USER_KEY: + buffer.Deserialize(user, newPass); + return m_logic->unlockUserKey(user, newPass); + + case ControlCommand::LOCK_USER_KEY: + buffer.Deserialize(user); + return m_logic->lockUserKey(user); + + case ControlCommand::REMOVE_USER_DATA: + buffer.Deserialize(user); + return m_logic->removeUserData(user); + + case ControlCommand::CHANGE_USER_PASSWORD: + buffer.Deserialize(user, oldPass, newPass); + return m_logic->changeUserPassword(user, oldPass, newPass); + + case ControlCommand::RESET_USER_PASSWORD: + buffer.Deserialize(user, newPass); + return m_logic->resetUserPassword(user, newPass); + + case ControlCommand::REMOVE_APP_DATA: + buffer.Deserialize(smackLabel); + return m_logic->removeApplicationData(smackLabel); + + case ControlCommand::UPDATE_CC_MODE: + return m_logic->updateCCMode(); + + case ControlCommand::SET_PERMISSION: { + Name name; + Label label; + Label accessorLabel; + PermissionMask permissionMask = 0; + + buffer.Deserialize(user, name, label, accessorLabel, permissionMask); + + Credentials cred(user, label); + return m_logic->setPermission( + cred, + command, + 0, // dummy + name, + label, + accessorLabel, + permissionMask); + } + + default: + Throw(Exception::BrokenProtocol); + } } RawBuffer CKMService::ProcessStorage(Credentials &cred, MessageBuffer &buffer) { - int command = 0; - int msgID = 0; - int tmpDataType = 0; - Name name; - Label label, accessorLabel; - - buffer.Deserialize(command); - buffer.Deserialize(msgID); - - // This is a workaround solution for locktype=None in Tizen 2.2.1 - // When locktype is None, lockscreen app doesn't interfere with unlocking process. - // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None. - // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password. - // Even if the result is fail, it will be ignored. - Password nullPassword(""); - m_logic->unlockUserKey(cred.clientUid, nullPassword); - - LogDebug("Process storage. Command: " << command); - - switch (static_cast<LogicCommand>(command)) { - case LogicCommand::SAVE: - { - RawBuffer rawData; - PolicySerializable policy; - buffer.Deserialize(tmpDataType, name, label, rawData, policy); - return m_logic->saveData( - cred, - msgID, - name, - label, - Crypto::Data(DataType(tmpDataType), std::move(rawData)), - policy); - } - case LogicCommand::SAVE_PKCS12: - { - RawBuffer rawData; - PKCS12Serializable pkcs; - PolicySerializable keyPolicy, certPolicy; - buffer.Deserialize(name, label, pkcs, keyPolicy, certPolicy); - return m_logic->savePKCS12( - cred, - msgID, - name, - label, - pkcs, - keyPolicy, - certPolicy); - } - case LogicCommand::REMOVE: - { - buffer.Deserialize(name, label); - return m_logic->removeData( - cred, - msgID, - name, - label); - } - case LogicCommand::GET: - { - Password password; - buffer.Deserialize(tmpDataType, name, label, password); - return m_logic->getData( - cred, - msgID, - DataType(tmpDataType), - name, - label, - password); - } - case LogicCommand::GET_PKCS12: - { - Password passKey; - Password passCert; - buffer.Deserialize( - name, - label, - passKey, - passCert); - return m_logic->getPKCS12( - cred, - msgID, - name, - label, - passKey, - passCert); - } - case LogicCommand::GET_LIST: - { - buffer.Deserialize(tmpDataType); - return m_logic->getDataList( - cred, - msgID, - DataType(tmpDataType)); - } - case LogicCommand::CREATE_KEY_AES: - { - int size = 0; - Name keyName; - Label keyLabel; - PolicySerializable policyKey; - buffer.Deserialize( - size, - policyKey, - keyName, - keyLabel); - return m_logic->createKeyAES( - cred, - msgID, - size, - keyName, - keyLabel, - policyKey); - } - case LogicCommand::CREATE_KEY_PAIR: - { - CryptoAlgorithmSerializable keyGenAlgorithm; - Name privateKeyName; - Label privateKeyLabel; - Name publicKeyName; - Label publicKeyLabel; - PolicySerializable policyPrivateKey; - PolicySerializable policyPublicKey; - buffer.Deserialize(keyGenAlgorithm, - policyPrivateKey, - policyPublicKey, - privateKeyName, - privateKeyLabel, - publicKeyName, - publicKeyLabel); - return m_logic->createKeyPair( - cred, - msgID, - keyGenAlgorithm, - privateKeyName, - privateKeyLabel, - publicKeyName, - publicKeyLabel, - policyPrivateKey, - policyPublicKey); - } - case LogicCommand::GET_CHAIN_CERT: - { - RawBuffer certificate; - RawBufferVector untrustedVector; - RawBufferVector trustedVector; - bool systemCerts = false; - buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts); - return m_logic->getCertificateChain( - cred, - msgID, - certificate, - untrustedVector, - trustedVector, - systemCerts); - } - case LogicCommand::GET_CHAIN_ALIAS: - { - RawBuffer certificate; - LabelNameVector untrustedVector; - LabelNameVector trustedVector; - bool systemCerts = false; - buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts); - return m_logic->getCertificateChain( - cred, - msgID, - certificate, - untrustedVector, - trustedVector, - systemCerts); - } - case LogicCommand::CREATE_SIGNATURE: - { - Password password; // password for private_key - RawBuffer message; - - CryptoAlgorithmSerializable cAlgorithm; - buffer.Deserialize(name, label, password, message, cAlgorithm); - - return m_logic->createSignature( - cred, - msgID, - name, - label, - password, // password for private_key - message, - cAlgorithm); - } - case LogicCommand::VERIFY_SIGNATURE: - { - Password password; // password for public_key (optional) - RawBuffer message; - RawBuffer signature; - CryptoAlgorithmSerializable cAlg; - - buffer.Deserialize(name, - label, - password, - message, - signature, - cAlg); - - return m_logic->verifySignature( - cred, - msgID, - name, - label, - password, // password for public_key (optional) - message, - signature, - cAlg); - } - case LogicCommand::SET_PERMISSION: - { - PermissionMask permissionMask = 0; - buffer.Deserialize(name, label, accessorLabel, permissionMask); - return m_logic->setPermission( - cred, - command, - msgID, - name, - label, - accessorLabel, - permissionMask); - } - default: - Throw(Exception::BrokenProtocol); - } + int command = 0; + int msgID = 0; + int tmpDataType = 0; + Name name; + Label label, accessorLabel; + + buffer.Deserialize(command); + buffer.Deserialize(msgID); + + // This is a workaround solution for locktype=None in Tizen 2.2.1 + // When locktype is None, lockscreen app doesn't interfere with unlocking process. + // Therefor lockscreen app cannot notify unlock events to key-manager when locktype is None. + // So, to unlock user data when lock type is None, key-manager always try to unlock user data with null password. + // Even if the result is fail, it will be ignored. + Password nullPassword(""); + m_logic->unlockUserKey(cred.clientUid, nullPassword); + + LogDebug("Process storage. Command: " << command); + + switch (static_cast<LogicCommand>(command)) { + case LogicCommand::SAVE: { + RawBuffer rawData; + PolicySerializable policy; + buffer.Deserialize(tmpDataType, name, label, rawData, policy); + return m_logic->saveData( + cred, + msgID, + name, + label, + Crypto::Data(DataType(tmpDataType), std::move(rawData)), + policy); + } + + case LogicCommand::SAVE_PKCS12: { + RawBuffer rawData; + PKCS12Serializable pkcs; + PolicySerializable keyPolicy, certPolicy; + buffer.Deserialize(name, label, pkcs, keyPolicy, certPolicy); + return m_logic->savePKCS12( + cred, + msgID, + name, + label, + pkcs, + keyPolicy, + certPolicy); + } + + case LogicCommand::REMOVE: { + buffer.Deserialize(name, label); + return m_logic->removeData( + cred, + msgID, + name, + label); + } + + case LogicCommand::GET: { + Password password; + buffer.Deserialize(tmpDataType, name, label, password); + return m_logic->getData( + cred, + msgID, + DataType(tmpDataType), + name, + label, + password); + } + + case LogicCommand::GET_PKCS12: { + Password passKey; + Password passCert; + buffer.Deserialize( + name, + label, + passKey, + passCert); + return m_logic->getPKCS12( + cred, + msgID, + name, + label, + passKey, + passCert); + } + + case LogicCommand::GET_LIST: { + buffer.Deserialize(tmpDataType); + return m_logic->getDataList( + cred, + msgID, + DataType(tmpDataType)); + } + + case LogicCommand::CREATE_KEY_AES: { + int size = 0; + Name keyName; + Label keyLabel; + PolicySerializable policyKey; + buffer.Deserialize( + size, + policyKey, + keyName, + keyLabel); + return m_logic->createKeyAES( + cred, + msgID, + size, + keyName, + keyLabel, + policyKey); + } + + case LogicCommand::CREATE_KEY_PAIR: { + CryptoAlgorithmSerializable keyGenAlgorithm; + Name privateKeyName; + Label privateKeyLabel; + Name publicKeyName; + Label publicKeyLabel; + PolicySerializable policyPrivateKey; + PolicySerializable policyPublicKey; + buffer.Deserialize(keyGenAlgorithm, + policyPrivateKey, + policyPublicKey, + privateKeyName, + privateKeyLabel, + publicKeyName, + publicKeyLabel); + return m_logic->createKeyPair( + cred, + msgID, + keyGenAlgorithm, + privateKeyName, + privateKeyLabel, + publicKeyName, + publicKeyLabel, + policyPrivateKey, + policyPublicKey); + } + + case LogicCommand::GET_CHAIN_CERT: { + RawBuffer certificate; + RawBufferVector untrustedVector; + RawBufferVector trustedVector; + bool systemCerts = false; + buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts); + return m_logic->getCertificateChain( + cred, + msgID, + certificate, + untrustedVector, + trustedVector, + systemCerts); + } + + case LogicCommand::GET_CHAIN_ALIAS: { + RawBuffer certificate; + LabelNameVector untrustedVector; + LabelNameVector trustedVector; + bool systemCerts = false; + buffer.Deserialize(certificate, untrustedVector, trustedVector, systemCerts); + return m_logic->getCertificateChain( + cred, + msgID, + certificate, + untrustedVector, + trustedVector, + systemCerts); + } + + case LogicCommand::CREATE_SIGNATURE: { + Password password; // password for private_key + RawBuffer message; + + CryptoAlgorithmSerializable cAlgorithm; + buffer.Deserialize(name, label, password, message, cAlgorithm); + + return m_logic->createSignature( + cred, + msgID, + name, + label, + password, // password for private_key + message, + cAlgorithm); + } + + case LogicCommand::VERIFY_SIGNATURE: { + Password password; // password for public_key (optional) + RawBuffer message; + RawBuffer signature; + CryptoAlgorithmSerializable cAlg; + + buffer.Deserialize(name, + label, + password, + message, + signature, + cAlg); + + return m_logic->verifySignature( + cred, + msgID, + name, + label, + password, // password for public_key (optional) + message, + signature, + cAlg); + } + + case LogicCommand::SET_PERMISSION: { + PermissionMask permissionMask = 0; + buffer.Deserialize(name, label, accessorLabel, permissionMask); + return m_logic->setPermission( + cred, + command, + msgID, + name, + label, + accessorLabel, + permissionMask); + } + + default: + Throw(Exception::BrokenProtocol); + } } void CKMService::ProcessMessage(MsgKeyRequest msg) { - Crypto::GObjShPtr key; - int ret = m_logic->getKeyForService(msg.cred, - msg.name, - msg.label, - msg.password, - key); - MsgKeyResponse kResp(msg.id, key, ret); - try { - if (!m_commMgr->SendMessage(kResp)) - LogError("No listener found"); // can't do much more - } catch (...) { - LogError("Uncaught exception in SendMessage. Check listeners."); - } + Crypto::GObjShPtr key; + int ret = m_logic->getKeyForService(msg.cred, + msg.name, + msg.label, + msg.password, + key); + MsgKeyResponse kResp(msg.id, key, ret); + + try { + if (!m_commMgr->SendMessage(kResp)) + LogError("No listener found"); // can't do much more + } catch (...) { + LogError("Uncaught exception in SendMessage. Check listeners."); + } } -void CKMService::ProcessMessage(MsgRemoveAppData msg) { - LogDebug("Call removeApplicationData. pkgId: " << msg.pkgId); - m_logic->removeApplicationData(msg.pkgId); +void CKMService::ProcessMessage(MsgRemoveAppData msg) +{ + LogDebug("Call removeApplicationData. pkgId: " << msg.pkgId); + m_logic->removeApplicationData(msg.pkgId); } void CKMService::CustomHandle(const ReadEvent &event) { - LogDebug("Read event"); - auto &info = m_connectionInfoMap[event.connectionID.counter]; - info.buffer.Push(event.rawBuffer); - while (ProcessOne(event.connectionID, info, true)); + LogDebug("Read event"); + auto &info = m_connectionInfoMap[event.connectionID.counter]; + info.buffer.Push(event.rawBuffer); + + while (ProcessOne(event.connectionID, info, true)); } void CKMService::CustomHandle(const SecurityEvent & /*event*/) { - LogError("This should not happend! SecurityEvent was called on CKMService!"); + LogError("This should not happend! SecurityEvent was called on CKMService!"); } } // namespace CKM diff --git a/src/manager/service/ckm-service.h b/src/manager/service/ckm-service.h index 962e6147..b399529c 100644 --- a/src/manager/service/ckm-service.h +++ b/src/manager/service/ckm-service.h @@ -30,63 +30,68 @@ namespace CKM { class CKMLogic; -class CKMService : public ThreadMessageService<MsgKeyRequest, MsgRemoveAppData> { +class CKMService : public + ThreadMessageService<MsgKeyRequest, MsgRemoveAppData> { public: - CKMService(); - CKMService(const CKMService &) = delete; - CKMService(CKMService &&) = delete; - CKMService& operator=(const CKMService &) = delete; - CKMService& operator=(CKMService &&) = delete; - - // Custom add custom support for ReadEvent and SecurityEvent - // because we want to bypass security check in CKMService - virtual void Event(const ReadEvent &event) - { - CreateEvent([this, event]() { this->CustomHandle(event); }); - } - - virtual void Event(const SecurityEvent &event) - { - CreateEvent([this, event]() { this->CustomHandle(event); }); - } - - virtual void Start(void); - virtual void Stop(void); - - virtual ~CKMService(); - - ServiceDescriptionVector GetServiceDescription(); + CKMService(); + CKMService(const CKMService &) = delete; + CKMService(CKMService &&) = delete; + CKMService &operator=(const CKMService &) = delete; + CKMService &operator=(CKMService &&) = delete; + + // Custom add custom support for ReadEvent and SecurityEvent + // because we want to bypass security check in CKMService + virtual void Event(const ReadEvent &event) + { + CreateEvent([this, event]() { + this->CustomHandle(event); + }); + } + + virtual void Event(const SecurityEvent &event) + { + CreateEvent([this, event]() { + this->CustomHandle(event); + }); + } + + virtual void Start(void); + virtual void Stop(void); + + virtual ~CKMService(); + + ServiceDescriptionVector GetServiceDescription(); protected: - // CustomHandle is used to bypass security check - void CustomHandle(const ReadEvent &event); - void CustomHandle(const SecurityEvent &event); + // CustomHandle is used to bypass security check + void CustomHandle(const ReadEvent &event); + void CustomHandle(const SecurityEvent &event); private: - virtual void SetCommManager(CommMgr *manager); + virtual void SetCommManager(CommMgr *manager); - class Exception { - public: - DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, BrokenProtocol) - }; + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CKM::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, BrokenProtocol) + }; - bool ProcessOne( - const ConnectionID &conn, - ConnectionInfo &info, - bool allowed); + bool ProcessOne( + const ConnectionID &conn, + ConnectionInfo &info, + bool allowed); - RawBuffer ProcessControl( - MessageBuffer &buffer); + RawBuffer ProcessControl( + MessageBuffer &buffer); - RawBuffer ProcessStorage( - Credentials &cred, - MessageBuffer &buffer); + RawBuffer ProcessStorage( + Credentials &cred, + MessageBuffer &buffer); - virtual void ProcessMessage(MsgKeyRequest msg); - virtual void ProcessMessage(MsgRemoveAppData msg); + virtual void ProcessMessage(MsgKeyRequest msg); + virtual void ProcessMessage(MsgRemoveAppData msg); - CKMLogic *m_logic; + CKMLogic *m_logic; }; } // namespace CKM diff --git a/src/manager/service/crypto-backend.h b/src/manager/service/crypto-backend.h index def25a7f..2e1455ef 100644 --- a/src/manager/service/crypto-backend.h +++ b/src/manager/service/crypto-backend.h @@ -23,9 +23,9 @@ namespace CKM { enum class CryptoBackend { - None = 0, - OpenSSL = 1, - TrustZone = 2 + None = 0, + OpenSSL = 1, + TrustZone = 2 }; } // namespace CKM diff --git a/src/manager/service/crypto-logic.cpp b/src/manager/service/crypto-logic.cpp index 2fd9d7df..aed2e893 100644 --- a/src/manager/service/crypto-logic.cpp +++ b/src/manager/service/crypto-logic.cpp @@ -74,214 +74,221 @@ CryptoLogic::CryptoLogic() {} CryptoLogic::CryptoLogic(CryptoLogic &&second) { - m_keyMap = std::move(second.m_keyMap); + m_keyMap = std::move(second.m_keyMap); } -CryptoLogic& CryptoLogic::operator=(CryptoLogic &&second) +CryptoLogic &CryptoLogic::operator=(CryptoLogic &&second) { - if (this == &second) - return *this; - m_keyMap = std::move(second.m_keyMap); - return *this; + if (this == &second) + return *this; + + m_keyMap = std::move(second.m_keyMap); + return *this; } bool CryptoLogic::haveKey(const Label &smackLabel) { - return (m_keyMap.count(smackLabel) > 0); + return (m_keyMap.count(smackLabel) > 0); } void CryptoLogic::pushKey(const Label &smackLabel, - const RawBuffer &applicationKey) + const RawBuffer &applicationKey) { - if (smackLabel.length() == 0) - ThrowErr(Exc::InternalError, "Empty smack label."); + if (smackLabel.length() == 0) + ThrowErr(Exc::InternalError, "Empty smack label."); - if (applicationKey.size() == 0) - ThrowErr(Exc::InternalError, "Empty application key."); + if (applicationKey.size() == 0) + ThrowErr(Exc::InternalError, "Empty application key."); - if (haveKey(smackLabel)) - ThrowErr(Exc::InternalError, "Application key for ", smackLabel, - "label already exists."); + if (haveKey(smackLabel)) + ThrowErr(Exc::InternalError, "Application key for ", smackLabel, + "label already exists."); - m_keyMap[smackLabel] = applicationKey; + m_keyMap[smackLabel] = applicationKey; } void CryptoLogic::removeKey(const Label &smackLabel) { - m_keyMap.erase(smackLabel); + m_keyMap.erase(smackLabel); } RawBuffer CryptoLogic::passwordToKey( - const Password &password, - const RawBuffer &salt, - size_t keySize) const + const Password &password, + const RawBuffer &salt, + size_t keySize) const { - RawBuffer result(keySize); - - if (1 != PKCS5_PBKDF2_HMAC_SHA1( - password.c_str(), - password.size(), - salt.data(), - salt.size(), - 1024, - result.size(), - result.data())) - ThrowErr(Exc::InternalError, "PCKS5_PKKDF_HMAC_SHA1 failed."); - - return result; + RawBuffer result(keySize); + + if (1 != PKCS5_PBKDF2_HMAC_SHA1( + password.c_str(), + password.size(), + salt.data(), + salt.size(), + 1024, + result.size(), + result.data())) + ThrowErr(Exc::InternalError, "PCKS5_PKKDF_HMAC_SHA1 failed."); + + return result; } RawBuffer CryptoLogic::generateRandIV() const { - RawBuffer civ(EVP_MAX_IV_LENGTH); + RawBuffer civ(EVP_MAX_IV_LENGTH); - if (1 != RAND_bytes(civ.data(), civ.size())) - ThrowErr(Exc::InternalError, "RAND_bytes failed to generate IV."); + if (1 != RAND_bytes(civ.data(), civ.size())) + ThrowErr(Exc::InternalError, "RAND_bytes failed to generate IV."); - return civ; + return civ; } void CryptoLogic::encryptRow(DB::Row &row) { - try { - DB::Row crow = row; - RawBuffer key; - RawBuffer result1; - RawBuffer result2; + try { + DB::Row crow = row; + RawBuffer key; + RawBuffer result1; + RawBuffer result2; - crow.algorithmType = DBCMAlgType::AES_GCM_256; - crow.dataSize = crow.data.size(); + crow.algorithmType = DBCMAlgType::AES_GCM_256; + crow.dataSize = crow.data.size(); - if (crow.dataSize <= 0) - ThrowErr(Exc::InternalError, "Invalid dataSize."); + if (crow.dataSize <= 0) + ThrowErr(Exc::InternalError, "Invalid dataSize."); - if (!haveKey(row.ownerLabel)) - ThrowErr(Exc::InternalError, "Missing application key for ", - row.ownerLabel, " label."); + if (!haveKey(row.ownerLabel)) + ThrowErr(Exc::InternalError, "Missing application key for ", + row.ownerLabel, " label."); - if (crow.iv.empty()) - crow.iv = generateRandIV(); + if (crow.iv.empty()) + crow.iv = generateRandIV(); - key = m_keyMap[row.ownerLabel]; - crow.encryptionScheme = ENCR_APPKEY; + key = m_keyMap[row.ownerLabel]; + crow.encryptionScheme = ENCR_APPKEY; - auto dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data, crow.iv, AES_GCM_TAG_SIZE); - crow.data = dataPair.first; + auto dataPair = Crypto::SW::Internals::encryptDataAesGcm(key, crow.data, + crow.iv, AES_GCM_TAG_SIZE); + crow.data = dataPair.first; - crow.tag = dataPair.second; + crow.tag = dataPair.second; - encBase64(crow.data); - crow.encryptionScheme |= ENCR_BASE64; - encBase64(crow.iv); + encBase64(crow.data); + crow.encryptionScheme |= ENCR_BASE64; + encBase64(crow.iv); - crow.encryptionScheme &= ENCR_ORDER_CLEAR; - crow.encryptionScheme |= ENCR_ORDER_V2; + crow.encryptionScheme &= ENCR_ORDER_CLEAR; + crow.encryptionScheme |= ENCR_ORDER_V2; - row = std::move(crow); - } catch(const CKM::Base64Encoder::Exception::Base &e) { - ThrowErr(Exc::InternalError, e.GetMessage()); - } catch(const CKM::Base64Decoder::Exception::Base &e) { - ThrowErr(Exc::InternalError, e.GetMessage()); - } + row = std::move(crow); + } catch (const CKM::Base64Encoder::Exception::Base &e) { + ThrowErr(Exc::InternalError, e.GetMessage()); + } catch (const CKM::Base64Decoder::Exception::Base &e) { + ThrowErr(Exc::InternalError, e.GetMessage()); + } } int CryptoLogic::getSchemeVersion(int encryptionScheme) { - return encryptionScheme >> ENCR_ORDER_OFFSET; + return encryptionScheme >> ENCR_ORDER_OFFSET; } void CryptoLogic::decryptRow(const Password &password, DB::Row &row) { - try { - DB::Row crow = row; - RawBuffer key; - RawBuffer digest, dataDigest; - - if (row.algorithmType != DBCMAlgType::AES_GCM_256) - ThrowErr(Exc::AuthenticationFailed, "Invalid algorithm type."); - - if ((row.encryptionScheme & ENCR_PASSWORD) && password.empty()) - ThrowErr(Exc::AuthenticationFailed, - "DB row is password protected, but given password is empty."); - - if (!(row.encryptionScheme & ENCR_PASSWORD) && !password.empty()) - ThrowErr(Exc::AuthenticationFailed, - "DB row is not password protected, but given password is not empty."); - - if ((row.encryptionScheme & ENCR_APPKEY) && !haveKey(row.ownerLabel)) - ThrowErr(Exc::AuthenticationFailed, - "Missing application key for ", - row.ownerLabel, - " label."); - - decBase64(crow.iv); - if (crow.encryptionScheme & ENCR_BASE64) - decBase64(crow.data); - - if ((crow.encryptionScheme >> ENCR_ORDER_OFFSET) == ENCR_ORDER_V2) { - if (crow.encryptionScheme & ENCR_APPKEY) { - key = m_keyMap[crow.ownerLabel]; - crow.data = Crypto::SW::Internals::decryptDataAesGcm(key, crow.data, crow.iv, crow.tag); - } - } else { - if (crow.encryptionScheme & ENCR_PASSWORD) { - key = passwordToKey(password, crow.iv, AES_CBC_KEY_SIZE); - crow.data = Crypto::SW::Internals::decryptDataAes(AlgoType::AES_CBC, key, crow.data, crow.iv); - } - - if (crow.encryptionScheme & ENCR_APPKEY) { - key = m_keyMap[crow.ownerLabel]; - crow.data = Crypto::SW::Internals::decryptDataAesGcm(key, crow.data, crow.iv, crow.tag); - } - } - - if (static_cast<int>(crow.data.size()) < crow.dataSize) - ThrowErr(Exc::AuthenticationFailed, "Decrypted row size mismatch"); - - if (static_cast<int>(crow.data.size()) > crow.dataSize) - crow.data.resize(crow.dataSize); - - row = std::move(crow); - } catch(const CKM::Base64Encoder::Exception::Base &e) { - ThrowErr(Exc::InternalError, e.GetMessage()); - } catch(const CKM::Base64Decoder::Exception::Base &e) { - ThrowErr(Exc::InternalError, e.GetMessage()); - } catch(const Exc::Exception &e) { - ThrowErr(Exc::AuthenticationFailed, e.message()); - } + try { + DB::Row crow = row; + RawBuffer key; + RawBuffer digest, dataDigest; + + if (row.algorithmType != DBCMAlgType::AES_GCM_256) + ThrowErr(Exc::AuthenticationFailed, "Invalid algorithm type."); + + if ((row.encryptionScheme & ENCR_PASSWORD) && password.empty()) + ThrowErr(Exc::AuthenticationFailed, + "DB row is password protected, but given password is empty."); + + if (!(row.encryptionScheme & ENCR_PASSWORD) && !password.empty()) + ThrowErr(Exc::AuthenticationFailed, + "DB row is not password protected, but given password is not empty."); + + if ((row.encryptionScheme & ENCR_APPKEY) && !haveKey(row.ownerLabel)) + ThrowErr(Exc::AuthenticationFailed, + "Missing application key for ", + row.ownerLabel, + " label."); + + decBase64(crow.iv); + + if (crow.encryptionScheme & ENCR_BASE64) + decBase64(crow.data); + + if ((crow.encryptionScheme >> ENCR_ORDER_OFFSET) == ENCR_ORDER_V2) { + if (crow.encryptionScheme & ENCR_APPKEY) { + key = m_keyMap[crow.ownerLabel]; + crow.data = Crypto::SW::Internals::decryptDataAesGcm(key, crow.data, crow.iv, + crow.tag); + } + } else { + if (crow.encryptionScheme & ENCR_PASSWORD) { + key = passwordToKey(password, crow.iv, AES_CBC_KEY_SIZE); + crow.data = Crypto::SW::Internals::decryptDataAes(AlgoType::AES_CBC, key, + crow.data, crow.iv); + } + + if (crow.encryptionScheme & ENCR_APPKEY) { + key = m_keyMap[crow.ownerLabel]; + crow.data = Crypto::SW::Internals::decryptDataAesGcm(key, crow.data, crow.iv, + crow.tag); + } + } + + if (static_cast<int>(crow.data.size()) < crow.dataSize) + ThrowErr(Exc::AuthenticationFailed, "Decrypted row size mismatch"); + + if (static_cast<int>(crow.data.size()) > crow.dataSize) + crow.data.resize(crow.dataSize); + + row = std::move(crow); + } catch (const CKM::Base64Encoder::Exception::Base &e) { + ThrowErr(Exc::InternalError, e.GetMessage()); + } catch (const CKM::Base64Decoder::Exception::Base &e) { + ThrowErr(Exc::InternalError, e.GetMessage()); + } catch (const Exc::Exception &e) { + ThrowErr(Exc::AuthenticationFailed, e.message()); + } } void CryptoLogic::encBase64(RawBuffer &data) { - Base64Encoder benc; - RawBuffer encdata; + Base64Encoder benc; + RawBuffer encdata; - benc.append(data); - benc.finalize(); - encdata = benc.get(); + benc.append(data); + benc.finalize(); + encdata = benc.get(); - if (encdata.size() == 0) - ThrowErr(Exc::InternalError, "Base64Encoder returned empty data."); + if (encdata.size() == 0) + ThrowErr(Exc::InternalError, "Base64Encoder returned empty data."); - data = std::move(encdata); + data = std::move(encdata); } void CryptoLogic::decBase64(RawBuffer &data) { - Base64Decoder bdec; - RawBuffer decdata; + Base64Decoder bdec; + RawBuffer decdata; + + bdec.reset(); + bdec.append(data); - bdec.reset(); - bdec.append(data); - if (!bdec.finalize()) - ThrowErr(Exc::InternalError, "Failed in Base64Decoder.finalize."); + if (!bdec.finalize()) + ThrowErr(Exc::InternalError, "Failed in Base64Decoder.finalize."); - decdata = bdec.get(); + decdata = bdec.get(); - if (decdata.size() == 0) - ThrowErr(Exc::InternalError, "Base64Decoder returned empty data."); + if (decdata.size() == 0) + ThrowErr(Exc::InternalError, "Base64Decoder returned empty data."); - data = std::move(decdata); + data = std::move(decdata); } } // namespace CKM diff --git a/src/manager/service/crypto-logic.h b/src/manager/service/crypto-logic.h index 8bc25548..9415ead5 100644 --- a/src/manager/service/crypto-logic.h +++ b/src/manager/service/crypto-logic.h @@ -29,56 +29,56 @@ namespace CKM { class CryptoLogic { public: - CryptoLogic(); - CryptoLogic(const CryptoLogic &second) = delete; - CryptoLogic(CryptoLogic &&second); - CryptoLogic& operator=(CryptoLogic &&second); - CryptoLogic& operator=(const CryptoLogic &second) = delete; + CryptoLogic(); + CryptoLogic(const CryptoLogic &second) = delete; + CryptoLogic(CryptoLogic &&second); + CryptoLogic &operator=(CryptoLogic &&second); + CryptoLogic &operator=(const CryptoLogic &second) = delete; - virtual ~CryptoLogic() {} + virtual ~CryptoLogic() {} - void decryptRow(const Password &password, DB::Row &row); - void encryptRow(DB::Row &row); + void decryptRow(const Password &password, DB::Row &row); + void encryptRow(DB::Row &row); - static int getSchemeVersion(int encryptionScheme); + static int getSchemeVersion(int encryptionScheme); - bool haveKey(const Label &smackLabel); - void pushKey(const Label &smackLabel, - const RawBuffer &applicationKey); - void removeKey(const Label &smackLabel); + bool haveKey(const Label &smackLabel); + void pushKey(const Label &smackLabel, + const RawBuffer &applicationKey); + void removeKey(const Label &smackLabel); - static const int ENCRYPTION_V1 = 0; - static const int ENCRYPTION_V2 = 1; + static const int ENCRYPTION_V1 = 0; + static const int ENCRYPTION_V2 = 1; private: - // Encryption scheme flags (enable/disable specific encryption type, multiple choice) - static const int ENCR_BASE64 = 1 << 0; - static const int ENCR_APPKEY = 1 << 1; - static const int ENCR_PASSWORD = 1 << 2; + // Encryption scheme flags (enable/disable specific encryption type, multiple choice) + static const int ENCR_BASE64 = 1 << 0; + static const int ENCR_APPKEY = 1 << 1; + static const int ENCR_PASSWORD = 1 << 2; - // Encryption order flags (single choice) - static const int ENCR_ORDER_CLEAR = 0x00ffffff; - static const int ENCR_ORDER_FILTER = ~ENCR_ORDER_CLEAR; - /* - * ENCR_ORDER_V1 - v1 encryption order. Token returned from store is encrypted with app key and - * optionally by custom user password. Is such form it is stored in db. - */ - static const int ENCR_ORDER_V1 = ENCR_ORDER_CLEAR + 0; - /* - * ENCR_ORDER_V2 - v2 encryption order. Stored data is optionally encrypted by store with - * user password. Returned token is encrypted with app key and stored in db. - */ - static const int ENCR_ORDER_V2 = ENCR_ORDER_CLEAR + 1; + // Encryption order flags (single choice) + static const int ENCR_ORDER_CLEAR = 0x00ffffff; + static const int ENCR_ORDER_FILTER = ~ENCR_ORDER_CLEAR; + /* + * ENCR_ORDER_V1 - v1 encryption order. Token returned from store is encrypted with app key and + * optionally by custom user password. Is such form it is stored in db. + */ + static const int ENCR_ORDER_V1 = ENCR_ORDER_CLEAR + 0; + /* + * ENCR_ORDER_V2 - v2 encryption order. Stored data is optionally encrypted by store with + * user password. Returned token is encrypted with app key and stored in db. + */ + static const int ENCR_ORDER_V2 = ENCR_ORDER_CLEAR + 1; - std::map<Label, RawBuffer> m_keyMap; + std::map<Label, RawBuffer> m_keyMap; - RawBuffer generateRandIV() const; - RawBuffer passwordToKey(const Password &password, - const RawBuffer &salt, - size_t keySize) const; + RawBuffer generateRandIV() const; + RawBuffer passwordToKey(const Password &password, + const RawBuffer &salt, + size_t keySize) const; - void decBase64(RawBuffer &data); - void encBase64(RawBuffer &data); + void decBase64(RawBuffer &data); + void encBase64(RawBuffer &data); }; } // namespace CKM diff --git a/src/manager/service/crypto-request.h b/src/manager/service/crypto-request.h index c8c16bf4..83ccab5c 100644 --- a/src/manager/service/crypto-request.h +++ b/src/manager/service/crypto-request.h @@ -28,15 +28,15 @@ namespace CKM { struct CryptoRequest { - ConnectionID conn; - Credentials cred; - EncryptionCommand command; - int msgId; - CryptoAlgorithmSerializable cas; - Name name; - Label label; - Password password; - RawBuffer input; + ConnectionID conn; + Credentials cred; + EncryptionCommand command; + int msgId; + CryptoAlgorithmSerializable cas; + Name name; + Label label; + Password password; + RawBuffer input; }; } /* namespace CKM */ diff --git a/src/manager/service/db-crypto.cpp b/src/manager/service/db-crypto.cpp index 93530163..9395386e 100644 --- a/src/manager/service/db-crypto.cpp +++ b/src/manager/service/db-crypto.cpp @@ -31,818 +31,862 @@ #pragma GCC diagnostic warning "-Wdeprecated-declarations" namespace { - const CKM::PermissionMask DEFAULT_PERMISSIONS = - static_cast<CKM::PermissionMask>(CKM::Permission::READ | CKM::Permission::REMOVE); - - const char *SCRIPTS_PATH = RO_DATA_DIR "/scripts/"; - - enum DBVersion : int { - DB_VERSION_1 = 1, - DB_VERSION_2 = 2, - /* ... since version 3, there is no need to manually - * recognize database version. - * Remember only that if doing changes to the database, - * increment and update DB_VERSION_CURRENT, - * then provide migration mechanism! - */ - DB_VERSION_CURRENT = 4 - }; - - const char *SCRIPT_CREATE_SCHEMA = "create_schema"; - const char *SCRIPT_DROP_ALL_ITEMS = "drop_all"; - const char *SCRIPT_MIGRATE = "migrate_"; - - // common substitutions: - // 100 - idx - // 101 - name - // 102 - label - // 103 - value - // 104 - permissionLabel - // 105 - permissionMask - const char *DB_CMD_SCHEMA_SET = - "REPLACE INTO SCHEMA_INFO(name, value) " - " VALUES(?101, ?103);"; - - const char *DB_CMD_SCHEMA_GET = - "SELECT * FROM SCHEMA_INFO WHERE name=?101;"; - - const char *DB_SCHEMA_VERSION_FIELD = "schema_version"; - - - const char *DB_CMD_NAME_INSERT = - "INSERT INTO NAMES(" - " name, label) " - " VALUES(?101, ?102);"; - - const char *DB_CMD_NAME_COUNT_ROWS = - "SELECT COUNT(idx) FROM NAMES WHERE name=?101 AND label=?102;"; - - const char *DB_CMD_NAME_DELETE = - "DELETE FROM NAMES WHERE name=?101 AND label=?102;"; - - const char *DB_CMD_NAME_DELETE_BY_LABEL = - "DELETE FROM NAMES WHERE label=?102;"; - - - const char *DB_CMD_OBJECT_INSERT = - "INSERT INTO OBJECTS(" - " exportable, dataType," - " algorithmType, encryptionScheme," - " iv, dataSize, data, tag, idx, backendId) " - " VALUES(?001, ?002, ?003, ?004, ?005, " - " ?006, ?007, ?008," - " (SELECT idx FROM NAMES WHERE name=?101 and label=?102)," - " ?009" - " );"; - - const char *DB_CMD_OBJECT_UPDATE = - "UPDATE OR FAIL OBJECTS SET" - " algorithmType = ?003," - " encryptionScheme = ?004," - " iv = ?005," - " dataSize = ?006," - " data = ?007," - " tag = ?008" - " WHERE idx IN (SELECT idx FROM NAMES WHERE name=?101 and label=?102)" - " AND dataType = ?002;"; - - const char *DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL = - "SELECT * FROM [join_name_object_tables] " - " WHERE (dataType BETWEEN ?001 AND ?002) " - " AND name=?101 and label=?102;"; - - - const char *DB_CMD_KEY_INSERT = - "INSERT INTO KEYS(label, key) VALUES (?, ?);"; - const char *DB_CMD_KEY_SELECT = - "SELECT key FROM KEYS WHERE label=?;"; - const char *DB_CMD_KEY_DELETE = - "DELETE FROM KEYS WHERE label=?"; - - - const char *DB_CMD_PERMISSION_SET = // SQLite does not support updating views - "REPLACE INTO PERMISSIONS(permissionLabel, permissionMask, idx) " - " VALUES (?104, ?105, (SELECT idx FROM NAMES WHERE name=?101 and label=?102));"; - - const char *DB_CMD_PERMISSION_SELECT = - "SELECT permissionMask FROM [join_name_permission_tables] " - " WHERE permissionLabel=?104 " - " AND name=?101 and label=?102;"; - - const char *DB_CMD_PERMISSION_DELETE = // SQLite does not support updating views - "DELETE FROM PERMISSIONS WHERE permissionLabel=?104 AND " - " idx=(SELECT idx FROM NAMES WHERE name=?101 and label=?102);"; - - - /* - * GROUP BY is necessary because of the following case: - * -There are several permissions to L1, N1 (label, name) from other accessors. When listing - * objects accessible by L1 the query will produce one result (L1, N1) for each allowed - * accessor but GROUP BY will reduce them to one so L1 will have (L1, N1) on its list only once - */ - const char *DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION = - "SELECT label, name FROM [join_all_tables] " - " WHERE dataType>=?001 AND dataType<=?002 " - " AND permissionLabel=?104 AND permissionMask&?004!=0 GROUP BY idx;"; +const CKM::PermissionMask DEFAULT_PERMISSIONS = + static_cast<CKM::PermissionMask>(CKM::Permission::READ | + CKM::Permission::REMOVE); + +const char *SCRIPTS_PATH = RO_DATA_DIR "/scripts/"; + +enum DBVersion : int { + DB_VERSION_1 = 1, + DB_VERSION_2 = 2, + /* ... since version 3, there is no need to manually + * recognize database version. + * Remember only that if doing changes to the database, + * increment and update DB_VERSION_CURRENT, + * then provide migration mechanism! + */ + DB_VERSION_CURRENT = 4 +}; + +const char *SCRIPT_CREATE_SCHEMA = "create_schema"; +const char *SCRIPT_DROP_ALL_ITEMS = "drop_all"; +const char *SCRIPT_MIGRATE = "migrate_"; + +// common substitutions: +// 100 - idx +// 101 - name +// 102 - label +// 103 - value +// 104 - permissionLabel +// 105 - permissionMask +const char *DB_CMD_SCHEMA_SET = + "REPLACE INTO SCHEMA_INFO(name, value) " + " VALUES(?101, ?103);"; + +const char *DB_CMD_SCHEMA_GET = + "SELECT * FROM SCHEMA_INFO WHERE name=?101;"; + +const char *DB_SCHEMA_VERSION_FIELD = "schema_version"; + + +const char *DB_CMD_NAME_INSERT = + "INSERT INTO NAMES(" + " name, label) " + " VALUES(?101, ?102);"; + +const char *DB_CMD_NAME_COUNT_ROWS = + "SELECT COUNT(idx) FROM NAMES WHERE name=?101 AND label=?102;"; + +const char *DB_CMD_NAME_DELETE = + "DELETE FROM NAMES WHERE name=?101 AND label=?102;"; + +const char *DB_CMD_NAME_DELETE_BY_LABEL = + "DELETE FROM NAMES WHERE label=?102;"; + + +const char *DB_CMD_OBJECT_INSERT = + "INSERT INTO OBJECTS(" + " exportable, dataType," + " algorithmType, encryptionScheme," + " iv, dataSize, data, tag, idx, backendId) " + " VALUES(?001, ?002, ?003, ?004, ?005, " + " ?006, ?007, ?008," + " (SELECT idx FROM NAMES WHERE name=?101 and label=?102)," + " ?009" + " );"; + +const char *DB_CMD_OBJECT_UPDATE = + "UPDATE OR FAIL OBJECTS SET" + " algorithmType = ?003," + " encryptionScheme = ?004," + " iv = ?005," + " dataSize = ?006," + " data = ?007," + " tag = ?008" + " WHERE idx IN (SELECT idx FROM NAMES WHERE name=?101 and label=?102)" + " AND dataType = ?002;"; + +const char *DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL = + "SELECT * FROM [join_name_object_tables] " + " WHERE (dataType BETWEEN ?001 AND ?002) " + " AND name=?101 and label=?102;"; + + +const char *DB_CMD_KEY_INSERT = + "INSERT INTO KEYS(label, key) VALUES (?, ?);"; +const char *DB_CMD_KEY_SELECT = + "SELECT key FROM KEYS WHERE label=?;"; +const char *DB_CMD_KEY_DELETE = + "DELETE FROM KEYS WHERE label=?"; + + +const char *DB_CMD_PERMISSION_SET = // SQLite does not support updating views + "REPLACE INTO PERMISSIONS(permissionLabel, permissionMask, idx) " + " VALUES (?104, ?105, (SELECT idx FROM NAMES WHERE name=?101 and label=?102));"; + +const char *DB_CMD_PERMISSION_SELECT = + "SELECT permissionMask FROM [join_name_permission_tables] " + " WHERE permissionLabel=?104 " + " AND name=?101 and label=?102;"; + +const char *DB_CMD_PERMISSION_DELETE = // SQLite does not support updating views + "DELETE FROM PERMISSIONS WHERE permissionLabel=?104 AND " + " idx=(SELECT idx FROM NAMES WHERE name=?101 and label=?102);"; + + +/* + * GROUP BY is necessary because of the following case: + * -There are several permissions to L1, N1 (label, name) from other accessors. When listing + * objects accessible by L1 the query will produce one result (L1, N1) for each allowed + * accessor but GROUP BY will reduce them to one so L1 will have (L1, N1) on its list only once + */ +const char *DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION = + "SELECT label, name FROM [join_all_tables] " + " WHERE dataType>=?001 AND dataType<=?002 " + " AND permissionLabel=?104 AND permissionMask&?004!=0 GROUP BY idx;"; } namespace CKM { namespace DB { - Crypto::Crypto(const std::string& path, const RawBuffer &rawPass) - { - m_connection = NULL; - m_inUserTransaction = false; - Try { - m_connection = new SqlConnection(path, SqlConnection::Flag::Option::CRW); - m_connection->SetKey(rawPass); - initDatabase(); - m_connection->ExecCommand("VACUUM;"); - } Catch(SqlConnection::Exception::ConnectionBroken) { - ThrowErr(Exc::DatabaseFailed, "Couldn't connect to database: ", path, _rethrown_exception.GetMessage()); - } Catch(SqlConnection::Exception::InvalidArguments) { - ThrowErr(Exc::DatabaseFailed, "Couldn't set the key for database. ", _rethrown_exception.GetMessage()); - } Catch(SqlConnection::Exception::SyntaxError) { - ThrowErr(Exc::DatabaseFailed, "Couldn't initiate the database. ", _rethrown_exception.GetMessage()); - } Catch(SqlConnection::Exception::InternalError) { - ThrowErr(Exc::DatabaseFailed, "Couldn't create the database. ", _rethrown_exception.GetMessage()); - } - } - - Crypto::Crypto(Crypto &&other) : - m_connection(other.m_connection), - m_inUserTransaction(other.m_inUserTransaction) - { - other.m_connection = NULL; - other.m_inUserTransaction = false; - } - - Crypto::~Crypto() - { - delete m_connection; - } - - Crypto& Crypto::operator=(Crypto&& other) - { - if (this == &other) - return *this; - delete m_connection; - - m_connection = other.m_connection; - other.m_connection = NULL; - - m_inUserTransaction = other.m_inUserTransaction; - other.m_inUserTransaction = false; - - return *this; - } - - void Crypto::createTable( - const char* create_cmd, - const char *table_name) - { - Try { - m_connection->ExecCommand(create_cmd); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't create table : " << table_name << "!"); - throw; - } Catch(SqlConnection::Exception::InternalError) { - LogError("Sqlite got into infinite busy state"); - throw; - } - } - - void Crypto::createView( - const char* create_cmd) - { - Try { - m_connection->ExecCommand(create_cmd); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't create view!"); - throw; - } Catch(SqlConnection::Exception::InternalError) { - LogError("Sqlite got into infinite busy state"); - throw; - } - } - - bool Crypto::getDBVersion(int & schemaVersion) - { - SchemaInfo SchemaInfo(this); - if (SchemaInfo.getVersionInfo(schemaVersion)) { - LogDebug("Current DB version: " << schemaVersion); - return true; - } else { - LogDebug("No DB version known or DB not present"); - - // special case: old CKM_TABLE exists - if (m_connection->CheckTableExist("CKM_TABLE")) { - schemaVersion = DB_VERSION_1; - return true; - } - - // special case: new scheme exists, but no SCHEMA_INFO table present - else if (m_connection->CheckTableExist("NAME_TABLE")) { - schemaVersion = DB_VERSION_2; - return true; - } - } - // not recognized - proceed with an empty DBs - return false; - } - - void Crypto::initDatabase() - { - // run migration if old database is present - int schemaVersion; - if ( getDBVersion(schemaVersion) == false || // DB empty or corrupted - schemaVersion > DB_VERSION_CURRENT) { // or too new scheme - LogDebug("no database or database corrupted, initializing the DB"); - resetDB(); - } else { - // migration needed - LogDebug("DB migration from version " << schemaVersion << " to version " << DB_VERSION_CURRENT << " started."); - Transaction transaction(this); - for (int vi = schemaVersion; vi < DB_VERSION_CURRENT; vi++) { - ScriptOptional script = getMigrationScript(vi); - if (!script) { - LogError("Error, script to migrate database from version: " << vi << - " to version: " << vi+1 << " not available, resetting the DB"); - resetDB(); - break; - } - - LogInfo("migrating from version " << vi << " to version " << vi+1); - m_connection->ExecCommand((*script).c_str()); - } - // update DB version info - SchemaInfo SchemaInfo(this); - SchemaInfo.setVersionInfo(); - transaction.commit(); - } - } - - Crypto::ScriptOptional Crypto::getScript(const std::string &scriptName) const - { - std::string scriptPath = SCRIPTS_PATH + scriptName + std::string(".sql"); - std::ifstream is(scriptPath); - if (is.fail()) { - LogError("Script " << scriptPath << " not found!"); - return ScriptOptional(); - } - std::istreambuf_iterator<char> begin(is), end; - return ScriptOptional(std::string(begin, end)); - } - - Crypto::ScriptOptional Crypto::getMigrationScript(int db_version) const - { - std::string scriptPath = std::string(SCRIPT_MIGRATE) + std::to_string(db_version); - return getScript(scriptPath); - } - - void Crypto::createDBSchema() - { - Transaction transaction(this); - - ScriptOptional script = getScript(SCRIPT_CREATE_SCHEMA); - - if (!script) - ThrowErr(Exc::DatabaseFailed, "Can not create the database schema: no initialization script"); - - m_connection->ExecCommand((*script).c_str()); - SchemaInfo SchemaInfo(this); - SchemaInfo.setVersionInfo(); - transaction.commit(); - } - - void Crypto::resetDB() - { - Transaction transaction(this); - ScriptOptional script = getScript(SCRIPT_DROP_ALL_ITEMS); - if (!script) - ThrowErr(Exc::DatabaseFailed, "Can not clear the database: no clearing script"); - - m_connection->ExecCommand((*script).c_str()); - createDBSchema(); - transaction.commit(); - } - - bool Crypto::isNameLabelPresent(const Name &name, const Label &owner) const - { - Try { - NameTable nameTable(this->m_connection); - return nameTable.isPresent(name, owner); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare insert statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute insert statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't check if name and label pair is present"); - } - - void Crypto::saveRows(const Name &name, const Label &owner, const RowVector &rows) - { - Try { - // transaction is present in the layer above - NameTable nameTable(this->m_connection); - ObjectTable objectTable(this->m_connection); - PermissionTable permissionTable(this->m_connection); - nameTable.addRow(name, owner); - for (const auto &i: rows) - objectTable.addRow(i); - permissionTable.setPermission(name, - owner, - owner, - static_cast<int>(DEFAULT_PERMISSIONS)); - return; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare insert statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute insert statement: " << _rethrown_exception.GetMessage()); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't save Row"); - } - - void Crypto::saveRow(const Row &row) - { - Try { - // transaction is present in the layer above - NameTable nameTable(this->m_connection); - ObjectTable objectTable(this->m_connection); - PermissionTable permissionTable(this->m_connection); - nameTable.addRow(row.name, row.ownerLabel); - objectTable.addRow(row); - permissionTable.setPermission(row.name, - row.ownerLabel, - row.ownerLabel, - static_cast<int>(DEFAULT_PERMISSIONS)); - return; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare insert statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute insert statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't save Row"); - } - - void Crypto::updateRow(const Row &row) - { - Try { - // transaction is present in the layer above - ObjectTable objectTable(this->m_connection); - objectTable.updateRow(row); - return; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare update statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute update statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't update Row"); - } - - bool Crypto::deleteRow( - const Name &name, - const Label &ownerLabel) - { - Try { - // transaction is present in the layer above - NameTable nameTable(this->m_connection); - if (nameTable.isPresent(name, ownerLabel)) { - nameTable.deleteRow(name, ownerLabel); - return true; - } - return false; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare delete statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute delete statement"); - } - ThrowErr(Exc::DatabaseFailed, - "Couldn't delete Row for name ", name, " using ownerLabel ", ownerLabel); - } - - Row Crypto::getRow( - const SqlConnection::DataCommandUniquePtr &selectCommand) const - { - Row row; - row.name = selectCommand->GetColumnString(0); - row.ownerLabel = selectCommand->GetColumnString(1); - row.exportable = selectCommand->GetColumnInteger(2); - row.dataType = DataType(selectCommand->GetColumnInteger(3)); - row.algorithmType = static_cast<DBCMAlgType>(selectCommand->GetColumnInteger(4)); - row.encryptionScheme = selectCommand->GetColumnInteger(5); - row.iv = selectCommand->GetColumnBlob(6); - row.dataSize = selectCommand->GetColumnInteger(7); - row.data = selectCommand->GetColumnBlob(8); - row.tag = selectCommand->GetColumnBlob(9); - row.backendId = static_cast<CryptoBackend>(selectCommand->GetColumnInteger(11)); - return row; - } - - PermissionMaskOptional Crypto::getPermissionRow( - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel) const - { - Try { - PermissionTable permissionTable(this->m_connection); - return permissionTable.getPermissionRow(name, ownerLabel, accessorLabel); - } Catch(SqlConnection::Exception::InvalidColumn) { - LogError("Select statement invalid column error"); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare select statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute select statement"); - } - return PermissionMaskOptional(); - } - - Crypto::RowOptional Crypto::getRow( - const Name &name, - const Label &ownerLabel, - DataType type) - { - return getRow(name, ownerLabel, type, type); - } - - Crypto::RowOptional Crypto::getRow( - const Name &name, - const Label &ownerLabel, - DataType typeRangeStart, - DataType typeRangeStop) - { - Try { - SqlConnection::DataCommandUniquePtr selectCommand = - m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL); - selectCommand->BindInteger(1, typeRangeStart); - selectCommand->BindInteger(2, typeRangeStop); - - // name table reference - selectCommand->BindString(101, name.c_str()); - selectCommand->BindString(102, ownerLabel.c_str()); - - if (selectCommand->Step()) { - // extract data - Row current_row = getRow(selectCommand); - - // all okay, proceed - return RowOptional(current_row); - } else { - return RowOptional(); - } - } Catch(SqlConnection::Exception::InvalidColumn) { - LogError("Select statement invalid column error"); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare select statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute select statement"); - } - ThrowErr(Exc::DatabaseFailed, - "Couldn't get row of type <", - static_cast<int>(typeRangeStart), ",", - static_cast<int>(typeRangeStop), ">", - " name ", name, " with owner label ", ownerLabel); - } - - void Crypto::getRows( - const Name &name, - const Label &ownerLabel, - DataType type, - RowVector &output) - { - getRows(name, ownerLabel, type, type, output); - } - - void Crypto::getRows( - const Name &name, - const Label &ownerLabel, - DataType typeRangeStart, - DataType typeRangeStop, - RowVector &output) - { - Try { - SqlConnection::DataCommandUniquePtr selectCommand = - m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL); - selectCommand->BindInteger(1, typeRangeStart); - selectCommand->BindInteger(2, typeRangeStop); - - // name table reference - selectCommand->BindString(101, name.c_str()); - selectCommand->BindString(102, ownerLabel.c_str()); - - while (selectCommand->Step()) { - // extract data - output.push_back(getRow(selectCommand)); - } - return; - } Catch(SqlConnection::Exception::InvalidColumn) { - LogError("Select statement invalid column error"); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare select statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute select statement"); - } - ThrowErr(Exc::DatabaseFailed, - "Couldn't get row of type <", - static_cast<int>(typeRangeStart), ",", - static_cast<int>(typeRangeStop), ">", - " name ", name, " with owner label ", ownerLabel); - } - - void Crypto::listNames( - const Label &smackLabel, - LabelNameVector& labelNameVector, - DataType type) - { - listNames(smackLabel, labelNameVector, type, type); - } - - void Crypto::listNames( - const Label &smackLabel, - LabelNameVector& labelNameVector, - DataType typeRangeStart, - DataType typeRangeStop) - { - Try { - Transaction transaction(this); - SqlConnection::DataCommandUniquePtr selectCommand = - m_connection->PrepareDataCommand(DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION); - selectCommand->BindInteger(1, static_cast<int>(typeRangeStart)); - selectCommand->BindInteger(2, static_cast<int>(typeRangeStop)); - selectCommand->BindString(104, smackLabel.c_str()); - selectCommand->BindInteger(4, static_cast<int>(Permission::READ | Permission::REMOVE)); - - while (selectCommand->Step()) { - Label ownerLabel = selectCommand->GetColumnString(0); - Name name = selectCommand->GetColumnString(1); - labelNameVector.push_back(std::make_pair(ownerLabel, name)); - } - return; - } Catch(SqlConnection::Exception::InvalidColumn) { - LogError("Select statement invalid column error"); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare select statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute select statement"); - } - ThrowErr(Exc::DatabaseFailed, - "Couldn't list names of type <", - static_cast<int>(typeRangeStart), ",", - static_cast<int>(typeRangeStop), ">", - " accessible to client label ", smackLabel); - } - - void Crypto::saveKey( - const Label& label, - const RawBuffer &key) - { - Try { - SqlConnection::DataCommandUniquePtr insertCommand = - m_connection->PrepareDataCommand(DB_CMD_KEY_INSERT); - insertCommand->BindString(1, label.c_str()); - insertCommand->BindBlob(2, key); - insertCommand->Step(); - return; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare insert key statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute insert statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't save key for label ", label); - } - - Crypto::RawBufferOptional Crypto::getKey(const Label& label) - { - Try { - SqlConnection::DataCommandUniquePtr selectCommand = - m_connection->PrepareDataCommand(DB_CMD_KEY_SELECT); - selectCommand->BindString(1, label.c_str()); - - if (selectCommand->Step()) - return RawBufferOptional( - selectCommand->GetColumnBlob(0)); - else - return RawBufferOptional(); - } Catch(SqlConnection::Exception::InvalidColumn) { - LogError("Select statement invalid column error"); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare insert key statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute insert statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't get key for label ", label); - } - - void Crypto::deleteKey(const Label& label) - { - Try { - Transaction transaction(this); - - SqlConnection::DataCommandUniquePtr deleteCommand = - m_connection->PrepareDataCommand(DB_CMD_KEY_DELETE); - deleteCommand->BindString(1, label.c_str()); - deleteCommand->Step(); - - NameTable nameTable(this->m_connection); - nameTable.deleteAllRows(label); - - transaction.commit(); - return; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare insert key statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute insert statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't delete key for label ", label); - } - - void Crypto::setPermission( - const Name &name, - const Label& ownerLabel, - const Label& accessorLabel, - const PermissionMask permissionMask) - { - Try { - PermissionTable permissionTable(this->m_connection); - permissionTable.setPermission(name, ownerLabel, accessorLabel, permissionMask); - return; - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare set statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute set statement"); - } - ThrowErr(Exc::DatabaseFailed, "Couldn't set permissions for name ", name); - } - - void Crypto::SchemaInfo::setVersionInfo() - { - SqlConnection::DataCommandUniquePtr insertContextCommand = - m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_SET); - insertContextCommand->BindString(101, DB_SCHEMA_VERSION_FIELD); - insertContextCommand->BindString(103, std::to_string(DB_VERSION_CURRENT).c_str()); - insertContextCommand->Step(); - } - - bool Crypto::SchemaInfo::getVersionInfo(int & version) const - { - // Try..Catch mandatory here - we don't need to escalate the error - // if it happens - we just won't return the version, allowing CKM to work - Try { - SqlConnection::DataCommandUniquePtr selectCommand = - m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_GET); - selectCommand->BindString(101, DB_SCHEMA_VERSION_FIELD); - - if (selectCommand->Step()) { - version = static_cast<int>(atoi(selectCommand->GetColumnString(1).c_str())); - return true; - } - } Catch(SqlConnection::Exception::InvalidColumn) { - LogError("Select statement invalid column error"); - } Catch(SqlConnection::Exception::SyntaxError) { - LogError("Couldn't prepare select statement"); - } Catch(SqlConnection::Exception::InternalError) { - LogError("Couldn't execute select statement"); - } - return false; - } - - void Crypto::PermissionTable::setPermission( - const Name &name, - const Label& ownerLabel, - const Label& accessorLabel, - const PermissionMask permissionMask) - { - if (permissionMask == Permission::NONE) { - // clear permissions - SqlConnection::DataCommandUniquePtr deletePermissionCommand = - m_connection->PrepareDataCommand(DB_CMD_PERMISSION_DELETE); - deletePermissionCommand->BindString(104, accessorLabel.c_str()); - deletePermissionCommand->BindString(101, name.c_str()); - deletePermissionCommand->BindString(102, ownerLabel.c_str()); - deletePermissionCommand->Step(); - } else { - // add new permissions - SqlConnection::DataCommandUniquePtr setPermissionCommand = - m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SET); - setPermissionCommand->BindString(104, accessorLabel.c_str()); - setPermissionCommand->BindInteger(105, static_cast<int>(permissionMask)); - setPermissionCommand->BindString(101, name.c_str()); - setPermissionCommand->BindString(102, ownerLabel.c_str()); - setPermissionCommand->Step(); - } - } - - PermissionMaskOptional Crypto::PermissionTable::getPermissionRow( - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel) const - { - SqlConnection::DataCommandUniquePtr selectCommand = - m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SELECT); - selectCommand->BindString(104, accessorLabel.c_str()); - - // name table reference - selectCommand->BindString(101, name.c_str()); - selectCommand->BindString(102, ownerLabel.c_str()); - - if (selectCommand->Step()) { - // there is entry for the <name, ownerLabel> pair - return PermissionMaskOptional(PermissionMask(selectCommand->GetColumnInteger(0))); - } - return PermissionMaskOptional(); - } - - void Crypto::NameTable::addRow( - const Name &name, - const Label &ownerLabel) - { - // insert NAMES item - SqlConnection::DataCommandUniquePtr insertNameCommand = - m_connection->PrepareDataCommand(DB_CMD_NAME_INSERT); - insertNameCommand->BindString(101, name.c_str()); - insertNameCommand->BindString(102, ownerLabel.c_str()); - insertNameCommand->Step(); - } - - void Crypto::NameTable::deleteRow( - const Name &name, - const Label &ownerLabel) - { - SqlConnection::DataCommandUniquePtr deleteCommand = - m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE); - deleteCommand->BindString(101, name.c_str()); - deleteCommand->BindString(102, ownerLabel.c_str()); - - // Step() result code does not provide information whether - // anything was removed. - deleteCommand->Step(); - } - - void Crypto::NameTable::deleteAllRows(const Label &ownerLabel) - { - SqlConnection::DataCommandUniquePtr deleteData = - m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE_BY_LABEL); - deleteData->BindString(102, ownerLabel.c_str()); - - // Step() result code does not provide information whether - // anything was removed. - deleteData->Step(); - } - - bool Crypto::NameTable::isPresent(const Name &name, const Label &ownerLabel) const - { - SqlConnection::DataCommandUniquePtr checkCmd = - m_connection->PrepareDataCommand(DB_CMD_NAME_COUNT_ROWS); - checkCmd->BindString(101, name.c_str()); - checkCmd->BindString(102, ownerLabel.c_str()); - if (checkCmd->Step()) { - int element_count = checkCmd->GetColumnInteger(0); - LogDebug("Item name: " << name << " ownerLabel: " << ownerLabel << - " hit count: " << element_count); - if (element_count > 0) - return true; - } - return false; - } - - void Crypto::ObjectTable::addRow(const Row &row) - { - SqlConnection::DataCommandUniquePtr insertObjectCommand = - m_connection->PrepareDataCommand(DB_CMD_OBJECT_INSERT); - insertObjectCommand->BindInteger(1, row.exportable); - insertObjectCommand->BindInteger(2, static_cast<int>(row.dataType)); - insertObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType)); - insertObjectCommand->BindInteger(4, row.encryptionScheme); - insertObjectCommand->BindBlob(5, row.iv); - insertObjectCommand->BindInteger(6, row.dataSize); - insertObjectCommand->BindBlob(7, row.data); - insertObjectCommand->BindBlob(8, row.tag); - insertObjectCommand->BindInteger(9, static_cast<int>(row.backendId)); - - // name table reference - insertObjectCommand->BindString(101, row.name.c_str()); - insertObjectCommand->BindString(102, row.ownerLabel.c_str()); - - insertObjectCommand->Step(); - } - - void Crypto::ObjectTable::updateRow(const Row &row) - { - SqlConnection::DataCommandUniquePtr updateObjectCommand = - m_connection->PrepareDataCommand(DB_CMD_OBJECT_UPDATE); - updateObjectCommand->BindInteger(2, static_cast<int>(row.dataType)); - updateObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType)); - updateObjectCommand->BindInteger(4, row.encryptionScheme); - updateObjectCommand->BindBlob(5, row.iv); - updateObjectCommand->BindInteger(6, row.dataSize); - updateObjectCommand->BindBlob(7, row.data); - updateObjectCommand->BindBlob(8, row.tag); - - // name table reference - updateObjectCommand->BindString(101, row.name.c_str()); - updateObjectCommand->BindString(102, row.ownerLabel.c_str()); - - updateObjectCommand->Step(); - } +Crypto::Crypto(const std::string &path, const RawBuffer &rawPass) : + m_connection(nullptr), m_inUserTransaction(false) +{ + try { + m_connection = new SqlConnection(path, SqlConnection::Flag::Option::CRW); + m_connection->SetKey(rawPass); + initDatabase(); + m_connection->ExecCommand("VACUUM;"); + } catch (const SqlConnection::Exception::ConnectionBroken &e) { + ThrowErr(Exc::DatabaseFailed, "Couldn't connect to database: ", path, + e.GetMessage()); + } catch (const SqlConnection::Exception::InvalidArguments &e) { + ThrowErr(Exc::DatabaseFailed, "Couldn't set the key for database. ", + e.GetMessage()); + } catch (const SqlConnection::Exception::SyntaxError &e) { + ThrowErr(Exc::DatabaseFailed, "Couldn't initiate the database. ", + e.GetMessage()); + } catch (const SqlConnection::Exception::InternalError &e) { + ThrowErr(Exc::DatabaseFailed, "Couldn't create the database. ", + e.GetMessage()); + } +} + +Crypto::Crypto(Crypto &&other) : + m_connection(other.m_connection), + m_inUserTransaction(other.m_inUserTransaction) +{ + other.m_connection = NULL; + other.m_inUserTransaction = false; +} + +Crypto::~Crypto() +{ + delete m_connection; +} + +Crypto &Crypto::operator=(Crypto &&other) +{ + if (this == &other) + return *this; + + delete m_connection; + + m_connection = other.m_connection; + other.m_connection = NULL; + + m_inUserTransaction = other.m_inUserTransaction; + other.m_inUserTransaction = false; + + return *this; +} + +void Crypto::createTable(const char *create_cmd, const char *table_name) +{ + try { + m_connection->ExecCommand(create_cmd); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't create table : " << table_name << "!"); + throw; + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Sqlite got into infinite busy state"); + throw; + } +} + +void Crypto::createView(const char *create_cmd) +{ + try { + m_connection->ExecCommand(create_cmd); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't create view!"); + throw; + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Sqlite got into infinite busy state"); + throw; + } +} + +bool Crypto::getDBVersion(int &schemaVersion) +{ + SchemaInfo SchemaInfo(this); + + if (SchemaInfo.getVersionInfo(schemaVersion)) { + LogDebug("Current DB version: " << schemaVersion); + return true; + } else { + LogDebug("No DB version known or DB not present"); + + if (m_connection->CheckTableExist("CKM_TABLE")) { + // special case: old CKM_TABLE exists + schemaVersion = DB_VERSION_1; + return true; + } else if (m_connection->CheckTableExist("NAME_TABLE")) { + // special case: new scheme exists, but no SCHEMA_INFO table present + schemaVersion = DB_VERSION_2; + return true; + } + } + + // not recognized - proceed with an empty DBs + return false; +} + +void Crypto::initDatabase() +{ + // run migration if old database is present + int schemaVersion; + + if (getDBVersion(schemaVersion) == false || // DB empty or corrupted + schemaVersion > DB_VERSION_CURRENT) { // or too new scheme + LogDebug("no database or database corrupted, initializing the DB"); + resetDB(); + } else { + // migration needed + LogDebug("DB migration from version " << schemaVersion << " to version " << + DB_VERSION_CURRENT << " started."); + Transaction transaction(this); + + for (int vi = schemaVersion; vi < DB_VERSION_CURRENT; vi++) { + ScriptOptional script = getMigrationScript(vi); + + if (!script) { + LogError("Error, script to migrate database from version: " << vi << + " to version: " << vi + 1 << " not available, resetting the DB"); + resetDB(); + break; + } + + LogInfo("migrating from version " << vi << " to version " << vi + 1); + m_connection->ExecCommand((*script).c_str()); + } + + // update DB version info + SchemaInfo SchemaInfo(this); + SchemaInfo.setVersionInfo(); + transaction.commit(); + } +} + +Crypto::ScriptOptional Crypto::getScript(const std::string &scriptName) const +{ + std::string scriptPath = SCRIPTS_PATH + scriptName + std::string(".sql"); + std::ifstream is(scriptPath); + + if (is.fail()) { + LogError("Script " << scriptPath << " not found!"); + return ScriptOptional(); + } + + std::istreambuf_iterator<char> begin(is), end; + return ScriptOptional(std::string(begin, end)); +} + +Crypto::ScriptOptional Crypto::getMigrationScript(int db_version) const +{ + std::string scriptPath = std::string(SCRIPT_MIGRATE) + std::to_string( + db_version); + return getScript(scriptPath); +} + +void Crypto::createDBSchema() +{ + Transaction transaction(this); + + ScriptOptional script = getScript(SCRIPT_CREATE_SCHEMA); + + if (!script) + ThrowErr(Exc::DatabaseFailed, + "Can not create the database schema: no initialization script"); + + m_connection->ExecCommand((*script).c_str()); + SchemaInfo SchemaInfo(this); + SchemaInfo.setVersionInfo(); + transaction.commit(); +} + +void Crypto::resetDB() +{ + Transaction transaction(this); + ScriptOptional script = getScript(SCRIPT_DROP_ALL_ITEMS); + + if (!script) + ThrowErr(Exc::DatabaseFailed, "Can not clear the database: no clearing script"); + + m_connection->ExecCommand((*script).c_str()); + createDBSchema(); + transaction.commit(); +} + +bool Crypto::isNameLabelPresent(const Name &name, const Label &owner) const +{ + try { + NameTable nameTable(this->m_connection); + return nameTable.isPresent(name, owner); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare insert statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute insert statement"); + } + + ThrowErr(Exc::DatabaseFailed, + "Couldn't check if name and label pair is present"); +} + +void Crypto::saveRows(const Name &name, const Label &owner, + const RowVector &rows) +{ + try { + // transaction is present in the layer above + NameTable nameTable(this->m_connection); + ObjectTable objectTable(this->m_connection); + PermissionTable permissionTable(this->m_connection); + nameTable.addRow(name, owner); + + for (const auto &i : rows) + objectTable.addRow(i); + + permissionTable.setPermission(name, + owner, + owner, + static_cast<int>(DEFAULT_PERMISSIONS)); + return; + } catch (const SqlConnection::Exception::SyntaxError &e) { + LogError("Couldn't prepare insert statement: " << + e.GetMessage()); + } catch (const SqlConnection::Exception::InternalError &e) { + LogError("Couldn't execute insert statement: " << + e.GetMessage()); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't save Row"); +} + +void Crypto::saveRow(const Row &row) +{ + try { + // transaction is present in the layer above + NameTable nameTable(this->m_connection); + ObjectTable objectTable(this->m_connection); + PermissionTable permissionTable(this->m_connection); + nameTable.addRow(row.name, row.ownerLabel); + objectTable.addRow(row); + permissionTable.setPermission(row.name, + row.ownerLabel, + row.ownerLabel, + static_cast<int>(DEFAULT_PERMISSIONS)); + return; + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare insert statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute insert statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't save Row"); +} + +void Crypto::updateRow(const Row &row) +{ + try { + // transaction is present in the layer above + ObjectTable objectTable(this->m_connection); + objectTable.updateRow(row); + return; + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare update statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute update statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't update Row"); +} + +bool Crypto::deleteRow( + const Name &name, + const Label &ownerLabel) +{ + try { + // transaction is present in the layer above + NameTable nameTable(this->m_connection); + + if (nameTable.isPresent(name, ownerLabel)) { + nameTable.deleteRow(name, ownerLabel); + return true; + } + + return false; + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare delete statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute delete statement"); + } + + ThrowErr(Exc::DatabaseFailed, + "Couldn't delete Row for name ", name, " using ownerLabel ", ownerLabel); +} + +Row Crypto::getRow( + const SqlConnection::DataCommandUniquePtr &selectCommand) const +{ + Row row; + row.name = selectCommand->GetColumnString(0); + row.ownerLabel = selectCommand->GetColumnString(1); + row.exportable = selectCommand->GetColumnInteger(2); + row.dataType = DataType(selectCommand->GetColumnInteger(3)); + row.algorithmType = + static_cast<DBCMAlgType>(selectCommand->GetColumnInteger(4)); + row.encryptionScheme = selectCommand->GetColumnInteger(5); + row.iv = selectCommand->GetColumnBlob(6); + row.dataSize = selectCommand->GetColumnInteger(7); + row.data = selectCommand->GetColumnBlob(8); + row.tag = selectCommand->GetColumnBlob(9); + row.backendId = static_cast<CryptoBackend>(selectCommand->GetColumnInteger(11)); + return row; +} + +PermissionMaskOptional Crypto::getPermissionRow( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel) const +{ + try { + PermissionTable permissionTable(this->m_connection); + return permissionTable.getPermissionRow(name, ownerLabel, accessorLabel); + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare select statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute select statement"); + } + + return PermissionMaskOptional(); +} + +Crypto::RowOptional Crypto::getRow( + const Name &name, + const Label &ownerLabel, + DataType type) +{ + return getRow(name, ownerLabel, type, type); +} + +Crypto::RowOptional Crypto::getRow( + const Name &name, + const Label &ownerLabel, + DataType typeRangeStart, + DataType typeRangeStop) +{ + try { + SqlConnection::DataCommandUniquePtr selectCommand = + m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL); + selectCommand->BindInteger(1, typeRangeStart); + selectCommand->BindInteger(2, typeRangeStop); + + // name table reference + selectCommand->BindString(101, name.c_str()); + selectCommand->BindString(102, ownerLabel.c_str()); + + if (selectCommand->Step()) { + // extract data + Row current_row = getRow(selectCommand); + + // all okay, proceed + return RowOptional(current_row); + } else { + return RowOptional(); + } + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare select statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute select statement"); + } + + ThrowErr(Exc::DatabaseFailed, + "Couldn't get row of type <", + static_cast<int>(typeRangeStart), ",", + static_cast<int>(typeRangeStop), ">", + " name ", name, " with owner label ", ownerLabel); +} + +void Crypto::getRows( + const Name &name, + const Label &ownerLabel, + DataType type, + RowVector &output) +{ + getRows(name, ownerLabel, type, type, output); +} + +void Crypto::getRows( + const Name &name, + const Label &ownerLabel, + DataType typeRangeStart, + DataType typeRangeStop, + RowVector &output) +{ + try { + SqlConnection::DataCommandUniquePtr selectCommand = + m_connection->PrepareDataCommand(DB_CMD_OBJECT_SELECT_BY_NAME_AND_LABEL); + selectCommand->BindInteger(1, typeRangeStart); + selectCommand->BindInteger(2, typeRangeStop); + + // name table reference + selectCommand->BindString(101, name.c_str()); + selectCommand->BindString(102, ownerLabel.c_str()); + + while (selectCommand->Step()) { + // extract data + output.push_back(getRow(selectCommand)); + } + + return; + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare select statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute select statement"); + } + + ThrowErr(Exc::DatabaseFailed, + "Couldn't get row of type <", + static_cast<int>(typeRangeStart), ",", + static_cast<int>(typeRangeStop), ">", + " name ", name, " with owner label ", ownerLabel); +} + +void Crypto::listNames( + const Label &smackLabel, + LabelNameVector &labelNameVector, + DataType type) +{ + listNames(smackLabel, labelNameVector, type, type); +} + +void Crypto::listNames( + const Label &smackLabel, + LabelNameVector &labelNameVector, + DataType typeRangeStart, + DataType typeRangeStop) +{ + try { + Transaction transaction(this); + SqlConnection::DataCommandUniquePtr selectCommand = + m_connection->PrepareDataCommand(DB_CMD_NAME_SELECT_BY_TYPE_AND_PERMISSION); + selectCommand->BindInteger(1, static_cast<int>(typeRangeStart)); + selectCommand->BindInteger(2, static_cast<int>(typeRangeStop)); + selectCommand->BindString(104, smackLabel.c_str()); + selectCommand->BindInteger(4, + static_cast<int>(Permission::READ | Permission::REMOVE)); + + while (selectCommand->Step()) { + Label ownerLabel = selectCommand->GetColumnString(0); + Name name = selectCommand->GetColumnString(1); + labelNameVector.push_back(std::make_pair(ownerLabel, name)); + } + + return; + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare select statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute select statement"); + } + + ThrowErr(Exc::DatabaseFailed, + "Couldn't list names of type <", + static_cast<int>(typeRangeStart), ",", + static_cast<int>(typeRangeStop), ">", + " accessible to client label ", smackLabel); +} + +void Crypto::saveKey( + const Label &label, + const RawBuffer &key) +{ + try { + SqlConnection::DataCommandUniquePtr insertCommand = + m_connection->PrepareDataCommand(DB_CMD_KEY_INSERT); + insertCommand->BindString(1, label.c_str()); + insertCommand->BindBlob(2, key); + insertCommand->Step(); + return; + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare insert key statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute insert statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't save key for label ", label); +} + +Crypto::RawBufferOptional Crypto::getKey(const Label &label) +{ + try { + SqlConnection::DataCommandUniquePtr selectCommand = + m_connection->PrepareDataCommand(DB_CMD_KEY_SELECT); + selectCommand->BindString(1, label.c_str()); + + if (selectCommand->Step()) + return RawBufferOptional(selectCommand->GetColumnBlob(0)); + else + return RawBufferOptional(); + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare insert key statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute insert statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't get key for label ", label); +} + +void Crypto::deleteKey(const Label &label) +{ + try { + Transaction transaction(this); + + SqlConnection::DataCommandUniquePtr deleteCommand = + m_connection->PrepareDataCommand(DB_CMD_KEY_DELETE); + deleteCommand->BindString(1, label.c_str()); + deleteCommand->Step(); + + NameTable nameTable(this->m_connection); + nameTable.deleteAllRows(label); + + transaction.commit(); + return; + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare insert key statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute insert statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't delete key for label ", label); +} + +void Crypto::setPermission( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const PermissionMask permissionMask) +{ + try { + PermissionTable permissionTable(this->m_connection); + permissionTable.setPermission(name, ownerLabel, accessorLabel, permissionMask); + return; + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare set statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute set statement"); + } + + ThrowErr(Exc::DatabaseFailed, "Couldn't set permissions for name ", name); +} + +void Crypto::SchemaInfo::setVersionInfo() +{ + SqlConnection::DataCommandUniquePtr insertContextCommand = + m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_SET); + insertContextCommand->BindString(101, DB_SCHEMA_VERSION_FIELD); + insertContextCommand->BindString(103, + std::to_string(DB_VERSION_CURRENT).c_str()); + insertContextCommand->Step(); +} + +bool Crypto::SchemaInfo::getVersionInfo(int &version) const +{ + // Try..Catch mandatory here - we don't need to escalate the error + // if it happens - we just won't return the version, allowing CKM to work + try { + SqlConnection::DataCommandUniquePtr selectCommand = + m_db->m_connection->PrepareDataCommand(DB_CMD_SCHEMA_GET); + selectCommand->BindString(101, DB_SCHEMA_VERSION_FIELD); + + if (selectCommand->Step()) { + version = static_cast<int>(atoi(selectCommand->GetColumnString(1).c_str())); + return true; + } + } catch (const SqlConnection::Exception::InvalidColumn &) { + LogError("Select statement invalid column error"); + } catch (const SqlConnection::Exception::SyntaxError &) { + LogError("Couldn't prepare select statement"); + } catch (const SqlConnection::Exception::InternalError &) { + LogError("Couldn't execute select statement"); + } + + return false; +} + +void Crypto::PermissionTable::setPermission( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const PermissionMask permissionMask) +{ + if (permissionMask == Permission::NONE) { + // clear permissions + SqlConnection::DataCommandUniquePtr deletePermissionCommand = + m_connection->PrepareDataCommand(DB_CMD_PERMISSION_DELETE); + deletePermissionCommand->BindString(104, accessorLabel.c_str()); + deletePermissionCommand->BindString(101, name.c_str()); + deletePermissionCommand->BindString(102, ownerLabel.c_str()); + deletePermissionCommand->Step(); + } else { + // add new permissions + SqlConnection::DataCommandUniquePtr setPermissionCommand = + m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SET); + setPermissionCommand->BindString(104, accessorLabel.c_str()); + setPermissionCommand->BindInteger(105, static_cast<int>(permissionMask)); + setPermissionCommand->BindString(101, name.c_str()); + setPermissionCommand->BindString(102, ownerLabel.c_str()); + setPermissionCommand->Step(); + } +} + +PermissionMaskOptional Crypto::PermissionTable::getPermissionRow( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel) const +{ + SqlConnection::DataCommandUniquePtr selectCommand = + m_connection->PrepareDataCommand(DB_CMD_PERMISSION_SELECT); + selectCommand->BindString(104, accessorLabel.c_str()); + + // name table reference + selectCommand->BindString(101, name.c_str()); + selectCommand->BindString(102, ownerLabel.c_str()); + + if (selectCommand->Step()) { + // there is entry for the <name, ownerLabel> pair + return PermissionMaskOptional(PermissionMask(selectCommand->GetColumnInteger( + 0))); + } + + return PermissionMaskOptional(); +} + +void Crypto::NameTable::addRow( + const Name &name, + const Label &ownerLabel) +{ + // insert NAMES item + SqlConnection::DataCommandUniquePtr insertNameCommand = + m_connection->PrepareDataCommand(DB_CMD_NAME_INSERT); + insertNameCommand->BindString(101, name.c_str()); + insertNameCommand->BindString(102, ownerLabel.c_str()); + insertNameCommand->Step(); +} + +void Crypto::NameTable::deleteRow( + const Name &name, + const Label &ownerLabel) +{ + SqlConnection::DataCommandUniquePtr deleteCommand = + m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE); + deleteCommand->BindString(101, name.c_str()); + deleteCommand->BindString(102, ownerLabel.c_str()); + + // Step() result code does not provide information whether + // anything was removed. + deleteCommand->Step(); +} + +void Crypto::NameTable::deleteAllRows(const Label &ownerLabel) +{ + SqlConnection::DataCommandUniquePtr deleteData = + m_connection->PrepareDataCommand(DB_CMD_NAME_DELETE_BY_LABEL); + deleteData->BindString(102, ownerLabel.c_str()); + + // Step() result code does not provide information whether + // anything was removed. + deleteData->Step(); +} + +bool Crypto::NameTable::isPresent(const Name &name, + const Label &ownerLabel) const +{ + SqlConnection::DataCommandUniquePtr checkCmd = + m_connection->PrepareDataCommand(DB_CMD_NAME_COUNT_ROWS); + checkCmd->BindString(101, name.c_str()); + checkCmd->BindString(102, ownerLabel.c_str()); + + if (checkCmd->Step()) { + int element_count = checkCmd->GetColumnInteger(0); + LogDebug("Item name: " << name << " ownerLabel: " << ownerLabel << + " hit count: " << element_count); + + if (element_count > 0) + return true; + } + + return false; +} + +void Crypto::ObjectTable::addRow(const Row &row) +{ + SqlConnection::DataCommandUniquePtr insertObjectCommand = + m_connection->PrepareDataCommand(DB_CMD_OBJECT_INSERT); + insertObjectCommand->BindInteger(1, row.exportable); + insertObjectCommand->BindInteger(2, static_cast<int>(row.dataType)); + insertObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType)); + insertObjectCommand->BindInteger(4, row.encryptionScheme); + insertObjectCommand->BindBlob(5, row.iv); + insertObjectCommand->BindInteger(6, row.dataSize); + insertObjectCommand->BindBlob(7, row.data); + insertObjectCommand->BindBlob(8, row.tag); + insertObjectCommand->BindInteger(9, static_cast<int>(row.backendId)); + + // name table reference + insertObjectCommand->BindString(101, row.name.c_str()); + insertObjectCommand->BindString(102, row.ownerLabel.c_str()); + + insertObjectCommand->Step(); +} + +void Crypto::ObjectTable::updateRow(const Row &row) +{ + SqlConnection::DataCommandUniquePtr updateObjectCommand = + m_connection->PrepareDataCommand(DB_CMD_OBJECT_UPDATE); + updateObjectCommand->BindInteger(2, static_cast<int>(row.dataType)); + updateObjectCommand->BindInteger(3, static_cast<int>(row.algorithmType)); + updateObjectCommand->BindInteger(4, row.encryptionScheme); + updateObjectCommand->BindBlob(5, row.iv); + updateObjectCommand->BindInteger(6, row.dataSize); + updateObjectCommand->BindBlob(7, row.data); + updateObjectCommand->BindBlob(8, row.tag); + + // name table reference + updateObjectCommand->BindString(101, row.name.c_str()); + updateObjectCommand->BindString(102, row.ownerLabel.c_str()); + + updateObjectCommand->Step(); +} } // namespace DB } // namespace CKM diff --git a/src/manager/service/db-crypto.h b/src/manager/service/db-crypto.h index 8b8925b7..501a360b 100644 --- a/src/manager/service/db-crypto.h +++ b/src/manager/service/db-crypto.h @@ -19,9 +19,8 @@ * @version 1.0 * @brief Header of encrypted db access layer */ - -#ifndef DB_CRYPTO_H -#define DB_CRYPTO_H +#ifndef CKM_DB_CRYPTO_H +#define CKM_DB_CRYPTO_H #include <vector> #include <string> @@ -41,267 +40,266 @@ namespace CKM { namespace DB { class Crypto { public: - typedef boost::optional<Row> RowOptional; - typedef boost::optional<RawBuffer> RawBufferOptional; - Crypto() : - m_connection(NULL), - m_inUserTransaction(false) - { - } - // user name instead of path? - Crypto(const std::string &path, const RawBuffer &rawPass); - Crypto(const Crypto &other) = delete; - Crypto(Crypto &&other); - - Crypto& operator=(const Crypto& ) = delete; - Crypto& operator=(Crypto&& other); - - virtual ~Crypto(); - - void saveRow( - const Row &row); - - void saveRows( - const Name &name, - const Label &owner, - const RowVector &rows); - - void updateRow( - const Row &row); - - bool isNameLabelPresent( - const Name &name, - const Label &owner) const; - - RowOptional getRow( - const Name &name, - const Label &ownerLabel, - DataType type); - - RowOptional getRow( - const Name &name, - const Label &ownerLabel, - DataType typeRangeStart, - DataType typeRangeStop); - - void getRows( - const Name &name, - const Label &ownerLabel, - DataType type, - RowVector &output); - - void getRows( - const Name &name, - const Label &ownerLabel, - DataType typeRangeStart, - DataType typeRangeStop, - RowVector &output); - - void listNames( - const Label &smackLabel, - LabelNameVector& labelNameVector, - DataType type); - - void listNames( - const Label &smackLabel, - LabelNameVector& labelNameVector, - DataType typeRangeStart, - DataType typeRangeStop); - - bool deleteRow( - const Name &name, - const Label &ownerLabel); - - // keys - void saveKey(const Label& label, const RawBuffer &key); - RawBufferOptional getKey(const Label& label); - void deleteKey(const Label& label); - - - // permissions - void setPermission( - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel, - const PermissionMask permissionMask); - - PermissionMaskOptional getPermissionRow( - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel) const; - - - // transactions - int beginTransaction(); - int commitTransaction(); - int rollbackTransaction(); - - class Transaction { - public: - Transaction(Crypto *db) : - m_db(db), - m_inTransaction(false) - { - if (!m_db->m_inUserTransaction) { - Try { - m_db->m_connection->ExecCommand("BEGIN EXCLUSIVE"); - m_db->m_inUserTransaction = true; - m_inTransaction = true; - } Catch(SqlConnection::Exception::InternalError) { - ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); - } Catch(SqlConnection::Exception::Base) { - ThrowErr(Exc::TransactionFailed, "Couldn't begin transaction"); - } - } - } - void commit() - { - if (m_inTransaction) { - Try { - m_db->m_connection->CommitTransaction(); - m_db->m_inUserTransaction = false; - m_inTransaction = false; - } Catch(SqlConnection::Exception::InternalError) { - ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); - } Catch(SqlConnection::Exception::Base) { - ThrowErr(Exc::TransactionFailed, "Couldn't commit transaction"); - } - } - } - void rollback() - { - if (m_inTransaction) { - Try { - m_db->m_connection->RollbackTransaction(); - m_db->m_inUserTransaction = false; - m_inTransaction = false; - } Catch(SqlConnection::Exception::InternalError) { - ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); - } Catch(SqlConnection::Exception::Base) { - ThrowErr(Exc::TransactionFailed, "Couldn't rollback transaction"); - } - } - } - ~Transaction() - { - Try { - if (m_inTransaction) { - m_db->m_inUserTransaction = false; - m_db->m_connection->RollbackTransaction(); - } - } Catch(SqlConnection::Exception::InternalError) { - ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); - } Catch(SqlConnection::Exception::Base) { - LogError("Transaction rollback failed!"); - } - } - - private: - Crypto *m_db; - bool m_inTransaction; - }; + using RowOptional = boost::optional<Row>; + using RawBufferOptional = boost::optional<RawBuffer>; + + Crypto() : m_connection(nullptr), m_inUserTransaction(false) {} + + // user name instead of path? + Crypto(const std::string &path, const RawBuffer &rawPass); + Crypto(const Crypto &other) = delete; + Crypto(Crypto &&other); + + Crypto &operator=(const Crypto &) = delete; + Crypto &operator=(Crypto &&other); + + virtual ~Crypto(); + + void saveRow( + const Row &row); + + void saveRows( + const Name &name, + const Label &owner, + const RowVector &rows); + + void updateRow( + const Row &row); + + bool isNameLabelPresent( + const Name &name, + const Label &owner) const; + + RowOptional getRow( + const Name &name, + const Label &ownerLabel, + DataType type); + + RowOptional getRow( + const Name &name, + const Label &ownerLabel, + DataType typeRangeStart, + DataType typeRangeStop); + + void getRows( + const Name &name, + const Label &ownerLabel, + DataType type, + RowVector &output); + + void getRows( + const Name &name, + const Label &ownerLabel, + DataType typeRangeStart, + DataType typeRangeStop, + RowVector &output); + + void listNames( + const Label &smackLabel, + LabelNameVector &labelNameVector, + DataType type); + + void listNames( + const Label &smackLabel, + LabelNameVector &labelNameVector, + DataType typeRangeStart, + DataType typeRangeStop); + + bool deleteRow( + const Name &name, + const Label &ownerLabel); + + // keys + void saveKey(const Label &label, const RawBuffer &key); + RawBufferOptional getKey(const Label &label); + void deleteKey(const Label &label); + + // permissions + void setPermission( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const PermissionMask permissionMask); + + PermissionMaskOptional getPermissionRow( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel) const; + + // transactions + int beginTransaction(); + int commitTransaction(); + int rollbackTransaction(); + + class Transaction { + public: + Transaction(Crypto *db) : m_db(db), m_inTransaction(false) + { + if (!m_db->m_inUserTransaction) { + try { + m_db->m_connection->ExecCommand("BEGIN EXCLUSIVE"); + m_db->m_inUserTransaction = true; + m_inTransaction = true; + } catch (const SqlConnection::Exception::InternalError &) { + ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); + } catch (const SqlConnection::Exception::Base &) { + ThrowErr(Exc::TransactionFailed, "Couldn't begin transaction"); + } + } + } + + void commit() + { + if (m_inTransaction) { + try { + m_db->m_connection->CommitTransaction(); + m_db->m_inUserTransaction = false; + m_inTransaction = false; + } catch (const SqlConnection::Exception::InternalError &) { + ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); + } catch (const SqlConnection::Exception::Base &) { + ThrowErr(Exc::TransactionFailed, "Couldn't commit transaction"); + } + } + } + + void rollback() + { + if (m_inTransaction) { + try { + m_db->m_connection->RollbackTransaction(); + m_db->m_inUserTransaction = false; + m_inTransaction = false; + } catch (const SqlConnection::Exception::InternalError &) { + ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); + } catch (const SqlConnection::Exception::Base &) { + ThrowErr(Exc::TransactionFailed, "Couldn't rollback transaction"); + } + } + } + + ~Transaction() + { + try { + if (m_inTransaction) { + m_db->m_inUserTransaction = false; + m_db->m_connection->RollbackTransaction(); + } + } catch (const SqlConnection::Exception::InternalError &) { + ThrowErr(Exc::TransactionFailed, "sqlite got into infinite busy state"); + } catch (const SqlConnection::Exception::Base &) { + LogError("Transaction rollback failed!"); + } + } + + private: + Crypto *m_db; + bool m_inTransaction; + }; protected: - SqlConnection* m_connection; + SqlConnection *m_connection; private: - bool m_inUserTransaction; - - void resetDB(); - void initDatabase(); - void createDBSchema(); - /** - * return current database version - * - * @param[out] schemaVersion if success, will contain DB schema version code - * - * @return false on DB empty or corrupted, true if information read - */ - bool getDBVersion(int & schemaVersion); - typedef boost::optional<std::string> ScriptOptional; - ScriptOptional getScript(const std::string &scriptName) const; - ScriptOptional getMigrationScript(int db_version) const; - - Row getRow( - const SqlConnection::DataCommandUniquePtr &selectCommand) const; - - void createTable( - const char *create_cmd, - const char *table_name); - - void createView( - const char* create_cmd); - - class SchemaInfo { - public: - explicit SchemaInfo(const Crypto *db) : m_db(db) {} - - void setVersionInfo(); - bool getVersionInfo(int & version) const; - - private: - const Crypto *m_db; - }; + bool m_inUserTransaction; + + void resetDB(); + void initDatabase(); + void createDBSchema(); + /** + * return current database version + * + * @param[out] schemaVersion if success, will contain DB schema version code + * + * @return false on DB empty or corrupted, true if information read + */ + bool getDBVersion(int &schemaVersion); + + using ScriptOptional = boost::optional<std::string>; + ScriptOptional getScript(const std::string &scriptName) const; + ScriptOptional getMigrationScript(int db_version) const; + + Row getRow( + const SqlConnection::DataCommandUniquePtr &selectCommand) const; + + void createTable( + const char *create_cmd, + const char *table_name); + + void createView( + const char *create_cmd); + + class SchemaInfo { + public: + explicit SchemaInfo(const Crypto *db) : m_db(db) {} + + void setVersionInfo(); + bool getVersionInfo(int &version) const; + + private: + const Crypto *m_db; + }; public: - class NameTable { - public: - explicit NameTable(SqlConnection* connection) : m_connection(connection) {} - - void addRow( - const Name &name, - const Label &ownerLabel); - - void deleteRow( - const Name &name, - const Label &ownerLabel); - - void deleteAllRows( - const Label &ownerLabel); - - bool isPresent( - const Name &name, - const Label &ownerLabel) const; - - private: - SqlConnection* m_connection; - }; - - class ObjectTable { - public: - explicit ObjectTable(SqlConnection* connection) : m_connection(connection) {} - - void addRow( - const Row &row); - void updateRow( - const Row &row); - - private: - SqlConnection* m_connection; - }; - - class PermissionTable { - public: - explicit PermissionTable(SqlConnection* connection) : m_connection(connection) {} - - void setPermission( - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel, - const PermissionMask permissionMask); - - PermissionMaskOptional getPermissionRow( - const Name &name, - const Label &ownerLabel, - const Label &accessorLabel) const; - - private: - SqlConnection* m_connection; - }; + class NameTable { + public: + explicit NameTable(SqlConnection *connection) : m_connection(connection) {} + + void addRow( + const Name &name, + const Label &ownerLabel); + + void deleteRow( + const Name &name, + const Label &ownerLabel); + + void deleteAllRows( + const Label &ownerLabel); + + bool isPresent( + const Name &name, + const Label &ownerLabel) const; + + private: + SqlConnection *m_connection; + }; + + class ObjectTable { + public: + explicit ObjectTable(SqlConnection *connection) : m_connection(connection) {} + + void addRow( + const Row &row); + void updateRow( + const Row &row); + + private: + SqlConnection *m_connection; + }; + + class PermissionTable { + public: + explicit PermissionTable(SqlConnection *connection) : m_connection( + connection) {} + + void setPermission( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel, + const PermissionMask permissionMask); + + PermissionMaskOptional getPermissionRow( + const Name &name, + const Label &ownerLabel, + const Label &accessorLabel) const; + + private: + SqlConnection *m_connection; + }; }; + } // namespace DB } // namespace CKM #pragma GCC diagnostic pop -#endif //DB_CRYPTO_H - +#endif // CKM_DB_CRYPTO_H diff --git a/src/manager/service/db-row.h b/src/manager/service/db-row.h index 82f12739..722e1498 100644 --- a/src/manager/service/db-row.h +++ b/src/manager/service/db-row.h @@ -30,33 +30,28 @@ namespace CKM { namespace DB { struct Row : public Token { - Row() = default; - - Row(Token token, - const Name &pName, - const Label &pLabel, - int pExportable) : - Token(std::move(token)) - , name(pName) - , ownerLabel(pLabel) - , exportable(pExportable) - , algorithmType(DBCMAlgType::NONE) - , encryptionScheme(0) - , dataSize(data.size()) - { - } - - Name name; - Label ownerLabel; - int exportable; - DBCMAlgType algorithmType; // Algorithm type used for row data encryption - int encryptionScheme; // for example: (ENCR_BASE64 | ENCR_PASSWORD) - RawBuffer iv; // encoded in base64 - int dataSize; // size of information without hash and padding - RawBuffer tag; // tag for Aes Gcm algorithm + Row() = default; + + Row(Token token, const Name &pName, const Label &pLabel, int pExportable) : + Token(std::move(token)), + name(pName), + ownerLabel(pLabel), + exportable(pExportable), + algorithmType(DBCMAlgType::NONE), + encryptionScheme(0), + dataSize(data.size()) {} + + Name name; + Label ownerLabel; + int exportable; + DBCMAlgType algorithmType; // Algorithm type used for row data encryption + int encryptionScheme; // for example: (ENCR_BASE64 | ENCR_PASSWORD) + RawBuffer iv; // encoded in base64 + int dataSize; // size of information without hash and padding + RawBuffer tag; // tag for Aes Gcm algorithm }; -typedef std::vector<Row> RowVector; +using RowVector = std::vector<Row>; } // namespace DB } // namespace CKM diff --git a/src/manager/service/encryption-logic.cpp b/src/manager/service/encryption-logic.cpp index cefb0867..01dd966a 100644 --- a/src/manager/service/encryption-logic.cpp +++ b/src/manager/service/encryption-logic.cpp @@ -25,69 +25,74 @@ namespace CKM { -void EncryptionLogic::Crypt(const CryptoRequest& request) +void EncryptionLogic::Crypt(const CryptoRequest &request) { - // check arguments - if (request.input.empty()) { - LogError("No input data"); - m_service.RespondToClient(request, CKM_API_ERROR_INPUT_PARAM); - return; - } + // check arguments + if (request.input.empty()) { + LogError("No input data"); + m_service.RespondToClient(request, CKM_API_ERROR_INPUT_PARAM); + return; + } - // store request in the map - auto ret = m_requestsMap.insert(std::make_pair(request.msgId, request)); - if (!ret.second) { - LogError("Request with id " << request.msgId << " already exists"); - m_service.RespondToClient(request, CKM_API_ERROR_INPUT_PARAM); - return; - } + // store request in the map + auto ret = m_requestsMap.insert(std::make_pair(request.msgId, request)); - // request key - try { - m_service.RequestKey(request); - } catch (...) { - LogError("Key request failed"); - m_requestsMap.erase(request.msgId); - m_service.RespondToClient(request, CKM_API_ERROR_SERVER_ERROR); - } + if (!ret.second) { + LogError("Request with id " << request.msgId << " already exists"); + m_service.RespondToClient(request, CKM_API_ERROR_INPUT_PARAM); + return; + } + + // request key + try { + m_service.RequestKey(request); + } catch (...) { + LogError("Key request failed"); + m_requestsMap.erase(request.msgId); + m_service.RespondToClient(request, CKM_API_ERROR_SERVER_ERROR); + } } void EncryptionLogic::KeyRetrieved(MsgKeyResponse response) { - auto it = m_requestsMap.find(response.id); - if (it == m_requestsMap.end()) { - LogError("No matching request found"); // nothing we can do - return; - } - CryptoRequest req = std::move(it->second); - m_requestsMap.erase(it); + auto it = m_requestsMap.find(response.id); + + if (it == m_requestsMap.end()) { + LogError("No matching request found"); // nothing we can do + return; + } + + CryptoRequest req = std::move(it->second); + m_requestsMap.erase(it); + + if (response.error != CKM_API_SUCCESS) { + LogError("Attempt to retrieve key failed with error: " << response.error); + m_service.RespondToClient(req, response.error); + return; + } + + if (!response.key) { + LogError("Retrieved key is empty"); + m_service.RespondToClient(req, CKM_API_ERROR_SERVER_ERROR); + return; + } - if (response.error != CKM_API_SUCCESS) { - LogError("Attempt to retrieve key failed with error: " << response.error); - m_service.RespondToClient(req, response.error); - return; - } + // encrypt/decrypt + try { + RawBuffer output; - if (!response.key) { - LogError("Retrieved key is empty"); - m_service.RespondToClient(req, CKM_API_ERROR_SERVER_ERROR); - return; - } + if (req.command == EncryptionCommand::ENCRYPT) + output = response.key->encrypt(req.cas, req.input); + else + output = response.key->decrypt(req.cas, req.input); - // encrypt/decrypt - try { - RawBuffer output; - if (req.command == EncryptionCommand::ENCRYPT) - output = response.key->encrypt(req.cas, req.input); - else - output = response.key->decrypt(req.cas, req.input); - m_service.RespondToClient(req, CKM_API_SUCCESS, output); - } catch (const Exc::Exception& ex) { - m_service.RespondToClient(req, ex.error()); - } catch (...) { - LogError("Uncaught exception from encrypt/decrypt."); - m_service.RespondToClient(req, CKM_API_ERROR_SERVER_ERROR); - } + m_service.RespondToClient(req, CKM_API_SUCCESS, output); + } catch (const Exc::Exception &ex) { + m_service.RespondToClient(req, ex.error()); + } catch (...) { + LogError("Uncaught exception from encrypt/decrypt."); + m_service.RespondToClient(req, CKM_API_ERROR_SERVER_ERROR); + } } } /* namespace CKM */ diff --git a/src/manager/service/encryption-logic.h b/src/manager/service/encryption-logic.h index 91247bae..b51439e6 100644 --- a/src/manager/service/encryption-logic.h +++ b/src/manager/service/encryption-logic.h @@ -32,16 +32,16 @@ namespace CKM { class EncryptionLogic { public: - EncryptionLogic(IEncryptionService& service) : m_service(service) {} - virtual ~EncryptionLogic() {} + EncryptionLogic(IEncryptionService &service) : m_service(service) {} + virtual ~EncryptionLogic() {} - void Crypt(const CryptoRequest& request); - void KeyRetrieved(MsgKeyResponse response); + void Crypt(const CryptoRequest &request); + void KeyRetrieved(MsgKeyResponse response); private: - IEncryptionService& m_service; + IEncryptionService &m_service; - std::map<int, CryptoRequest> m_requestsMap; + std::map<int, CryptoRequest> m_requestsMap; }; } /* namespace CKM */ diff --git a/src/manager/service/encryption-service.cpp b/src/manager/service/encryption-service.cpp index e2ea7c69..f9678368 100644 --- a/src/manager/service/encryption-service.cpp +++ b/src/manager/service/encryption-service.cpp @@ -34,7 +34,7 @@ const CKM::InterfaceID SOCKET_ID_ENCRYPTION = 0; namespace CKM { EncryptionService::EncryptionService() : - m_logic(*this) + m_logic(*this) { } @@ -42,108 +42,116 @@ EncryptionService::~EncryptionService() { } -void EncryptionService::RespondToClient(const CryptoRequest& request, - int retCode, - const RawBuffer& data) +void EncryptionService::RespondToClient(const CryptoRequest &request, + int retCode, + const RawBuffer &data) { - try { - RawBuffer response = MessageBuffer::Serialize( - static_cast<int>(request.command), request.msgId, retCode, data).Pop(); - m_serviceManager->Write(request.conn, response); - } catch (...) { - LogError("Failed to send response to the client"); - } + try { + RawBuffer response = MessageBuffer::Serialize( + static_cast<int>(request.command), request.msgId, retCode, data).Pop(); + m_serviceManager->Write(request.conn, response); + } catch (...) { + LogError("Failed to send response to the client"); + } } -void EncryptionService::RequestKey(const CryptoRequest& request) +void EncryptionService::RequestKey(const CryptoRequest &request) { - MsgKeyRequest kReq(request.msgId, request.cred, request.name, request.label, request.password); - if (!m_commMgr->SendMessage(kReq)) - throw std::runtime_error("No listener found");// TODO + MsgKeyRequest kReq(request.msgId, request.cred, request.name, request.label, + request.password); + + if (!m_commMgr->SendMessage(kReq)) + throw std::runtime_error("No listener found");// TODO } -GenericSocketService::ServiceDescriptionVector EncryptionService::GetServiceDescription() +GenericSocketService::ServiceDescriptionVector +EncryptionService::GetServiceDescription() { - return ServiceDescriptionVector { - {SERVICE_SOCKET_ENCRYPTION, "http://tizen.org/privilege/keymanager", SOCKET_ID_ENCRYPTION} - }; + return ServiceDescriptionVector { + {SERVICE_SOCKET_ENCRYPTION, "http://tizen.org/privilege/keymanager", SOCKET_ID_ENCRYPTION} + }; } void EncryptionService::Start() { - Create(); + Create(); } void EncryptionService::Stop() { - Join(); + Join(); } void EncryptionService::SetCommManager(CommMgr *manager) { - ThreadService::SetCommManager(manager); - Register(*manager); + ThreadService::SetCommManager(manager); + Register(*manager); } // Encryption Service does not support any kind of security-check // and 3rd parameter is not required bool EncryptionService::ProcessOne( - const ConnectionID &conn, - ConnectionInfo &info, - bool /*allowed*/) + const ConnectionID &conn, + ConnectionInfo &info, + bool /*allowed*/) { - LogDebug("process One"); - try { - if (!info.buffer.Ready()) - return false; - - ProcessEncryption(conn, info.credentials, info.buffer); - return true; - } catch (MessageBuffer::Exception::Base) { - LogError("Broken protocol. Closing socket."); - } catch (const std::exception &e) { - LogError("Std exception:: " << e.what()); - } catch (...) { - LogError("Unknown exception. Closing socket."); - } - - m_serviceManager->Close(conn); - return false; + LogDebug("process One"); + + try { + if (!info.buffer.Ready()) + return false; + + ProcessEncryption(conn, info.credentials, info.buffer); + return true; + } catch (MessageBuffer::Exception::Base) { + LogError("Broken protocol. Closing socket."); + } catch (const std::exception &e) { + LogError("Std exception:: " << e.what()); + } catch (...) { + LogError("Unknown exception. Closing socket."); + } + + m_serviceManager->Close(conn); + return false; } void EncryptionService::ProcessMessage(MsgKeyResponse msg) { - m_logic.KeyRetrieved(std::move(msg)); + m_logic.KeyRetrieved(std::move(msg)); } void EncryptionService::ProcessEncryption(const ConnectionID &conn, - const Credentials &cred, - MessageBuffer &buffer) + const Credentials &cred, + MessageBuffer &buffer) { - int tmpCmd = 0; - CryptoRequest req; + int tmpCmd = 0; + CryptoRequest req; + + buffer.Deserialize(tmpCmd, req.msgId, req.cas, req.name, req.label, + req.password, req.input); + req.command = static_cast<EncryptionCommand>(tmpCmd); - buffer.Deserialize(tmpCmd, req.msgId, req.cas, req.name, req.label, req.password, req.input); - req.command = static_cast<EncryptionCommand>(tmpCmd); - if (req.command != EncryptionCommand::ENCRYPT && req.command != EncryptionCommand::DECRYPT) - throw std::runtime_error("Unsupported command: " + tmpCmd); + if (req.command != EncryptionCommand::ENCRYPT && + req.command != EncryptionCommand::DECRYPT) + throw std::runtime_error("Unsupported command: " + tmpCmd); - req.conn = conn; - req.cred = cred; - m_logic.Crypt(req); + req.conn = conn; + req.cred = cred; + m_logic.Crypt(req); } void EncryptionService::CustomHandle(const ReadEvent &event) { - LogDebug("Read event"); - auto &info = m_connectionInfoMap[event.connectionID.counter]; - info.buffer.Push(event.rawBuffer); - while (ProcessOne(event.connectionID, info, true)); + LogDebug("Read event"); + auto &info = m_connectionInfoMap[event.connectionID.counter]; + info.buffer.Push(event.rawBuffer); + + while (ProcessOne(event.connectionID, info, true)); } void EncryptionService::CustomHandle(const SecurityEvent &/*event*/) { - LogError("This should not happend! SecurityEvent was called on EncryptionService!"); + LogError("This should not happend! SecurityEvent was called on EncryptionService!"); } } /* namespace CKM */ diff --git a/src/manager/service/encryption-service.h b/src/manager/service/encryption-service.h index 4ea81e60..69eb4521 100644 --- a/src/manager/service/encryption-service.h +++ b/src/manager/service/encryption-service.h @@ -29,51 +29,56 @@ namespace CKM { -class EncryptionService : public ThreadMessageService<MsgKeyResponse>, public IEncryptionService { +class EncryptionService : public ThreadMessageService<MsgKeyResponse>, + public IEncryptionService { public: - EncryptionService(); - virtual ~EncryptionService(); - NONCOPYABLE(EncryptionService); + EncryptionService(); + virtual ~EncryptionService(); + NONCOPYABLE(EncryptionService); - // from ThreadService - ServiceDescriptionVector GetServiceDescription(); + // from ThreadService + ServiceDescriptionVector GetServiceDescription(); - // Custom add custom support for ReadEvent and SecurityEvent - // because we want to bypass security check in EncryptionService - virtual void Event(const ReadEvent &event) - { - CreateEvent([this, event]() { this->CustomHandle(event); }); - } + // Custom add custom support for ReadEvent and SecurityEvent + // because we want to bypass security check in EncryptionService + virtual void Event(const ReadEvent &event) + { + CreateEvent([this, event]() { + this->CustomHandle(event); + }); + } - virtual void Event(const SecurityEvent &event) - { - CreateEvent([this, event]() { this->CustomHandle(event); }); - } + virtual void Event(const SecurityEvent &event) + { + CreateEvent([this, event]() { + this->CustomHandle(event); + }); + } - void Start(); - void Stop(); + void Start(); + void Stop(); protected: - // CustomHandle is used to bypass security check - void CustomHandle(const ReadEvent &event); - void CustomHandle(const SecurityEvent &event); + // CustomHandle is used to bypass security check + void CustomHandle(const ReadEvent &event); + void CustomHandle(const SecurityEvent &event); private: - virtual void SetCommManager(CommMgr *manager); + virtual void SetCommManager(CommMgr *manager); - bool ProcessOne(const ConnectionID &conn, ConnectionInfo &info, bool allowed); - void ProcessMessage(MsgKeyResponse msg); - void ProcessEncryption(const ConnectionID &conn, - const Credentials &cred, - MessageBuffer &buffer); + bool ProcessOne(const ConnectionID &conn, ConnectionInfo &info, bool allowed); + void ProcessMessage(MsgKeyResponse msg); + void ProcessEncryption(const ConnectionID &conn, + const Credentials &cred, + MessageBuffer &buffer); - // from IEncryptionService - virtual void RespondToClient(const CryptoRequest& request, - int retCode, - const RawBuffer& data = RawBuffer()); - virtual void RequestKey(const CryptoRequest& request); + // from IEncryptionService + virtual void RespondToClient(const CryptoRequest &request, + int retCode, + const RawBuffer &data = RawBuffer()); + virtual void RequestKey(const CryptoRequest &request); - EncryptionLogic m_logic; + EncryptionLogic m_logic; }; } /* namespace CKM */ diff --git a/src/manager/service/file-lock.cpp b/src/manager/service/file-lock.cpp index 27803a05..e7e40323 100644 --- a/src/manager/service/file-lock.cpp +++ b/src/manager/service/file-lock.cpp @@ -40,42 +40,45 @@ namespace { // TODO replace it with custom exception when they are implemented template <typename... Args> -std::runtime_error io_exception(const Args&... args) +std::runtime_error io_exception(const Args &... args) { - return std::runtime_error(Stringify::Merge(args...)); + return std::runtime_error(Stringify::Merge(args...)); }; } // namespace anonymous -FileLock::FileLock(const char* const file) +FileLock::FileLock(const char *const file) { - // Open lock file - m_lockFd = TEMP_FAILURE_RETRY(creat(file, 0644)); - if (m_lockFd == -1) - throw io_exception("Cannot open lock file. Errno: ", GetErrnoString()); - - if (-1 == lockf(m_lockFd, F_TLOCK, 0)) { - if (errno == EACCES || errno == EAGAIN) - throw io_exception("Can't acquire lock. Another instance must be running."); - else - throw io_exception("Can't acquire lock. Errno: ", GetErrnoString()); - } - - std::string pid = std::to_string(getpid()); - - ssize_t written = TEMP_FAILURE_RETRY(write(m_lockFd, pid.c_str(), pid.size())); - if (-1 == written || static_cast<ssize_t>(pid.size()) > written) - throw io_exception("Can't write file lock. Errno: ", GetErrnoString()); - - int ret = fsync(m_lockFd); - if (-1 == ret) - throw io_exception("Fsync failed. Errno: ", GetErrnoString()); + // Open lock file + m_lockFd = TEMP_FAILURE_RETRY(creat(file, 0644)); + + if (m_lockFd == -1) + throw io_exception("Cannot open lock file. Errno: ", GetErrnoString()); + + if (-1 == lockf(m_lockFd, F_TLOCK, 0)) { + if (errno == EACCES || errno == EAGAIN) + throw io_exception("Can't acquire lock. Another instance must be running."); + else + throw io_exception("Can't acquire lock. Errno: ", GetErrnoString()); + } + + std::string pid = std::to_string(getpid()); + + ssize_t written = TEMP_FAILURE_RETRY(write(m_lockFd, pid.c_str(), pid.size())); + + if (-1 == written || static_cast<ssize_t>(pid.size()) > written) + throw io_exception("Can't write file lock. Errno: ", GetErrnoString()); + + int ret = fsync(m_lockFd); + + if (-1 == ret) + throw io_exception("Fsync failed. Errno: ", GetErrnoString()); } FileLock::~FileLock() { - // this will also release the lock - close(m_lockFd); + // this will also release the lock + close(m_lockFd); } } /* namespace CKM */ diff --git a/src/manager/service/file-lock.h b/src/manager/service/file-lock.h index ded400a4..b1a9b51c 100644 --- a/src/manager/service/file-lock.h +++ b/src/manager/service/file-lock.h @@ -27,16 +27,16 @@ namespace CKM { class FileLock { public: - explicit FileLock(const char* const file); - ~FileLock(); + explicit FileLock(const char *const file); + ~FileLock(); - NONCOPYABLE(FileLock); + NONCOPYABLE(FileLock); - FileLock(FileLock&&) = default; - FileLock& operator=(FileLock&&) = default; + FileLock(FileLock &&) = default; + FileLock &operator=(FileLock &&) = default; private: - int m_lockFd; + int m_lockFd; }; } /* namespace CKM */ diff --git a/src/manager/service/file-system.cpp b/src/manager/service/file-system.cpp index 9e32f999..2da77035 100644 --- a/src/manager/service/file-system.cpp +++ b/src/manager/service/file-system.cpp @@ -53,204 +53,216 @@ const std::string CKM_LOCK_FILE = RUN_DIR "/" SERVICE_NAME "/key-manager.pid"; namespace CKM { FileSystem::FileSystem(uid_t uid) - : m_uid(uid) + : m_uid(uid) { } std::string FileSystem::getDBPath() const { - std::stringstream ss; - ss << RW_DATA_DIR << "/" << CKM_DB_PREFIX << m_uid; - return ss.str(); + std::stringstream ss; + ss << RW_DATA_DIR << "/" << CKM_DB_PREFIX << m_uid; + return ss.str(); } std::string FileSystem::getDKEKPath() const { - std::stringstream ss; - ss << RW_DATA_DIR << "/" << CKM_KEY_PREFIX << m_uid; - return ss.str(); + std::stringstream ss; + ss << RW_DATA_DIR << "/" << CKM_KEY_PREFIX << m_uid; + return ss.str(); } std::string FileSystem::getDBDEKPath() const { - std::stringstream ss; - ss << RW_DATA_DIR << "/" << CKM_DB_KEY_PREFIX << m_uid; - return ss.str(); + std::stringstream ss; + ss << RW_DATA_DIR << "/" << CKM_DB_KEY_PREFIX << m_uid; + return ss.str(); } std::string FileSystem::getRemovedAppsPath() const { - std::stringstream ss; - ss << RW_DATA_DIR << "/" << CKM_REMOVED_APP_PREFIX << m_uid; - return ss.str(); + std::stringstream ss; + ss << RW_DATA_DIR << "/" << CKM_REMOVED_APP_PREFIX << m_uid; + return ss.str(); } RawBuffer FileSystem::loadFile(const std::string &path) const { - std::ifstream is(path); + std::ifstream is(path); - if (is.fail() && ENOENT == errno) - return RawBuffer(); + if (is.fail() && ENOENT == errno) + return RawBuffer(); - if (is.fail()) { - auto description = GetErrnoString(errno); - ThrowErr(Exc::FileSystemFailed, - "Error opening file: ", path, " Reason: ", description); - } + if (is.fail()) { + auto description = GetErrnoString(errno); + ThrowErr(Exc::FileSystemFailed, + "Error opening file: ", path, " Reason: ", description); + } - std::istreambuf_iterator<char> begin(is), end; - std::vector<char> buff(begin, end); // This trick does not work with boost vector + std::istreambuf_iterator<char> begin(is), end; + std::vector<char> buff(begin, + end); // This trick does not work with boost vector - RawBuffer buffer(buff.size()); - memcpy(buffer.data(), buff.data(), buff.size()); - return buffer; + RawBuffer buffer(buff.size()); + memcpy(buffer.data(), buff.data(), buff.size()); + return buffer; } RawBuffer FileSystem::getDKEK() const { - return loadFile(getDKEKPath()); + return loadFile(getDKEKPath()); } RawBuffer FileSystem::getDBDEK() const { - return loadFile(getDBDEKPath()); + return loadFile(getDBDEKPath()); } -void FileSystem::saveFile(const std::string &path, const RawBuffer &buffer) const +void FileSystem::saveFile(const std::string &path, + const RawBuffer &buffer) const { - std::ofstream os(path, std::ios::out | std::ofstream::binary | std::ofstream::trunc); - std::copy(buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os)); + std::ofstream os(path, std::ios::out | std::ofstream::binary | + std::ofstream::trunc); + std::copy(buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os)); - // Prevent desynchronization in batter remove test. - os.flush(); - fsync(FstreamAccessors<std::ofstream>::GetFd(os)); // flush kernel space buffer - os.close(); + // Prevent desynchronization in batter remove test. + os.flush(); + fsync(FstreamAccessors<std::ofstream>::GetFd(os)); // flush kernel space buffer + os.close(); - if (os.fail()) - ThrowErr(Exc::FileSystemFailed, "Failed to save file: ", path); + if (os.fail()) + ThrowErr(Exc::FileSystemFailed, "Failed to save file: ", path); } void FileSystem::saveDKEK(const RawBuffer &buffer) const { - saveFile(getDKEKPath(), buffer); + saveFile(getDKEKPath(), buffer); } void FileSystem::saveDBDEK(const RawBuffer &buffer) const { - saveFile(getDBDEKPath(), buffer); + saveFile(getDBDEKPath(), buffer); } void FileSystem::addRemovedApp(const std::string &smackLabel) const { - std::ofstream outfile; - outfile.open(getRemovedAppsPath(), std::ios_base::app); - outfile << smackLabel << std::endl; - outfile.close(); - if (outfile.fail()) { - auto desc = GetErrnoString(errno); - ThrowErr(Exc::FileSystemFailed, - "Could not update file: ", getRemovedAppsPath(), " Reason: ", desc); - } + std::ofstream outfile; + outfile.open(getRemovedAppsPath(), std::ios_base::app); + outfile << smackLabel << std::endl; + outfile.close(); + + if (outfile.fail()) { + auto desc = GetErrnoString(errno); + ThrowErr(Exc::FileSystemFailed, + "Could not update file: ", getRemovedAppsPath(), " Reason: ", desc); + } } AppLabelVector FileSystem::clearRemovedsApps() const { - // read the contents - AppLabelVector removedApps; - std::string line; - std::ifstream removedAppsFile(getRemovedAppsPath()); - if (removedAppsFile.is_open()) { - while (!removedAppsFile.eof()) { - getline(removedAppsFile, line); - if (line.size() > 0) - removedApps.push_back(line); - } - removedAppsFile.close(); - } - // truncate the contents - std::ofstream truncateFile; - truncateFile.open(getRemovedAppsPath(), std::ofstream::out | std::ofstream::trunc); - truncateFile.close(); - return removedApps; + // read the contents + AppLabelVector removedApps; + std::string line; + std::ifstream removedAppsFile(getRemovedAppsPath()); + + if (removedAppsFile.is_open()) { + while (!removedAppsFile.eof()) { + getline(removedAppsFile, line); + + if (line.size() > 0) + removedApps.push_back(line); + } + + removedAppsFile.close(); + } + + // truncate the contents + std::ofstream truncateFile; + truncateFile.open(getRemovedAppsPath(), + std::ofstream::out | std::ofstream::trunc); + truncateFile.close(); + return removedApps; } int FileSystem::init() { - errno = 0; - if ((mkdir(RW_DATA_DIR, 0700)) && (errno != EEXIST)) { - int err = errno; - LogError("Error in mkdir " << RW_DATA_DIR << ". Reason: " << GetErrnoString(err)); - return -1; // TODO set up some error code - } - return 0; + errno = 0; + + if ((mkdir(RW_DATA_DIR, 0700)) && (errno != EEXIST)) { + int err = errno; + LogError("Error in mkdir " << RW_DATA_DIR << ". Reason: " << GetErrnoString( + err)); + return -1; // TODO set up some error code + } + + return 0; } UidVector FileSystem::getUIDsFromDBFile() { - UidVector uids; - - forEachFile(RW_DATA_DIR, [&uids](const std::string &filename) { - if (strncmp(filename.c_str(), CKM_KEY_PREFIX.c_str(), CKM_KEY_PREFIX.size())) - return; - - try { - uids.emplace_back(static_cast<uid_t>(std::stoi((filename.c_str()) - + CKM_KEY_PREFIX.size()))); - } catch (const std::invalid_argument) { - LogDebug("Error in extracting uid from db file. " - "Error=std::invalid_argument. " - "This will be ignored.File=" << filename); - } catch(const std::out_of_range) { - LogDebug("Error in extracting uid from db file. " - "Error=std::out_of_range. " - "This will be ignored. File="<< filename); - } - - return; - }); - - return uids; + UidVector uids; + + forEachFile(RW_DATA_DIR, [&uids](const std::string & filename) { + if (strncmp(filename.c_str(), CKM_KEY_PREFIX.c_str(), CKM_KEY_PREFIX.size())) + return; + + try { + uids.emplace_back(static_cast<uid_t>(std::stoi((filename.c_str()) + + CKM_KEY_PREFIX.size()))); + } catch (const std::invalid_argument) { + LogDebug("Error in extracting uid from db file. " + "Error=std::invalid_argument. " + "This will be ignored.File=" << filename); + } catch (const std::out_of_range) { + LogDebug("Error in extracting uid from db file. " + "Error=std::out_of_range. " + "This will be ignored. File=" << filename); + } + + return; + }); + + return uids; } int FileSystem::removeUserData() const { - int err, retCode = 0; - - if (unlink(getDBPath().c_str())) { - retCode = -1; - err = errno; - LogDebug("Error in unlink user database: " << getDBPath() - << "Errno: " << errno << " " << GetErrnoString(err)); - } - - if (unlink(getDKEKPath().c_str())) { - retCode = -1; - err = errno; - LogDebug("Error in unlink user DKEK: " << getDKEKPath() - << "Errno: " << errno << " " << GetErrnoString(err)); - } - - if (unlink(getDBDEKPath().c_str())) { - retCode = -1; - err = errno; - LogDebug("Error in unlink user DBDEK: " << getDBDEKPath() - << "Errno: " << errno << " " << GetErrnoString(err)); - } - - if (unlink(getRemovedAppsPath().c_str())) { - retCode = -1; - err = errno; - LogDebug("Error in unlink user's Removed Apps File: " << getRemovedAppsPath() - << "Errno: " << errno << " " << GetErrnoString(err)); - } - - return retCode; + int err, retCode = 0; + + if (unlink(getDBPath().c_str())) { + retCode = -1; + err = errno; + LogDebug("Error in unlink user database: " << getDBPath() + << "Errno: " << errno << " " << GetErrnoString(err)); + } + + if (unlink(getDKEKPath().c_str())) { + retCode = -1; + err = errno; + LogDebug("Error in unlink user DKEK: " << getDKEKPath() + << "Errno: " << errno << " " << GetErrnoString(err)); + } + + if (unlink(getDBDEKPath().c_str())) { + retCode = -1; + err = errno; + LogDebug("Error in unlink user DBDEK: " << getDBDEKPath() + << "Errno: " << errno << " " << GetErrnoString(err)); + } + + if (unlink(getRemovedAppsPath().c_str())) { + retCode = -1; + err = errno; + LogDebug("Error in unlink user's Removed Apps File: " << getRemovedAppsPath() + << "Errno: " << errno << " " << GetErrnoString(err)); + } + + return retCode; } FileLock FileSystem::lock() { - FileLock fl(CKM_LOCK_FILE.c_str()); - return fl; + FileLock fl(CKM_LOCK_FILE.c_str()); + return fl; } } // namespace CKM diff --git a/src/manager/service/file-system.h b/src/manager/service/file-system.h index 145d77ef..2ed9e310 100644 --- a/src/manager/service/file-system.h +++ b/src/manager/service/file-system.h @@ -32,38 +32,38 @@ typedef std::vector<uid_t> UidVector; class FileSystem { public: - FileSystem(uid_t uid); + FileSystem(uid_t uid); - std::string getDBPath() const; + std::string getDBPath() const; - // Domain Key Encryption Key - RawBuffer getDKEK() const; - void saveDKEK(const RawBuffer &buffer) const; + // Domain Key Encryption Key + RawBuffer getDKEK() const; + void saveDKEK(const RawBuffer &buffer) const; - // Database Data Encryption Key - RawBuffer getDBDEK() const; - void saveDBDEK(const RawBuffer &buffer) const; + // Database Data Encryption Key + RawBuffer getDBDEK() const; + void saveDBDEK(const RawBuffer &buffer) const; - // Remove all ckm data related to user - int removeUserData() const; + // Remove all ckm data related to user + int removeUserData() const; - void addRemovedApp(const std::string &smackLabel) const; - AppLabelVector clearRemovedsApps() const; + void addRemovedApp(const std::string &smackLabel) const; + AppLabelVector clearRemovedsApps() const; - static int init(); - static UidVector getUIDsFromDBFile(); - static FileLock lock(); + static int init(); + static UidVector getUIDsFromDBFile(); + static FileLock lock(); - virtual ~FileSystem() {} + virtual ~FileSystem() {} protected: - std::string getDKEKPath() const; - std::string getDBDEKPath() const; - RawBuffer loadFile(const std::string &path) const; - void saveFile(const std::string &path, const RawBuffer &buffer) const; - std::string getRemovedAppsPath() const; + std::string getDKEKPath() const; + std::string getDBDEKPath() const; + RawBuffer loadFile(const std::string &path) const; + void saveFile(const std::string &path, const RawBuffer &buffer) const; + std::string getRemovedAppsPath() const; - uid_t m_uid; + uid_t m_uid; }; } // namespace CKM diff --git a/src/manager/service/for-each-file.cpp b/src/manager/service/for-each-file.cpp index f6e804d0..d992e4dd 100644 --- a/src/manager/service/for-each-file.cpp +++ b/src/manager/service/for-each-file.cpp @@ -34,28 +34,28 @@ namespace CKM { void forEachFile(const std::string &dirpath, ActionFunc func) { - std::unique_ptr<DIR, std::function<int(DIR*)>> - dirp(::opendir(dirpath.c_str()), ::closedir); + std::unique_ptr<DIR, std::function<int(DIR *)>> + dirp(::opendir(dirpath.c_str()), ::closedir); - if (!dirp.get()) - ThrowErr(Exc::FileSystemFailed, - "Cannot open dir: ", dirpath, " errno: ", GetErrnoString()); + if (!dirp.get()) + ThrowErr(Exc::FileSystemFailed, + "Cannot open dir: ", dirpath, " errno: ", GetErrnoString()); - size_t len = - offsetof(struct dirent, d_name) + pathconf(dirpath.c_str(), _PC_NAME_MAX) + 1; + size_t len = + offsetof(struct dirent, d_name) + pathconf(dirpath.c_str(), _PC_NAME_MAX) + 1; - std::unique_ptr<struct dirent, std::function<void(void*)>> - pEntry(static_cast<struct dirent*>(::malloc(len)), ::free); + std::unique_ptr<struct dirent, std::function<void(void *)>> + pEntry(static_cast<struct dirent *>(::malloc(len)), ::free); - if (!pEntry) - ThrowErr(Exc::InternalError, "Memory allocation failed for dir entry"); + if (!pEntry) + ThrowErr(Exc::InternalError, "Memory allocation failed for dir entry"); - struct dirent *pDirEntry = nullptr; + struct dirent *pDirEntry = nullptr; - while ((!readdir_r(dirp.get(), pEntry.get(), &pDirEntry)) && pDirEntry) { - /* run func for every file names in dirpath. d_name is only file name, not path */ - func(pDirEntry->d_name); - } + while ((!readdir_r(dirp.get(), pEntry.get(), &pDirEntry)) && pDirEntry) { + /* run func for every file names in dirpath. d_name is only file name, not path */ + func(pDirEntry->d_name); + } } } diff --git a/src/manager/service/glib-logic.cpp b/src/manager/service/glib-logic.cpp index a4a7426a..471ce8ce 100644 --- a/src/manager/service/glib-logic.cpp +++ b/src/manager/service/glib-logic.cpp @@ -33,37 +33,37 @@ namespace { struct PkgmgrEvent { - PkgmgrEvent(uid_t _uid, const char *_pkgid) - : uid(_uid) - , pkgid(_pkgid) {} - - inline bool operator==(const PkgmgrEvent &rhs) const - { - return uid == rhs.uid && pkgid.compare(rhs.pkgid) == 0; - } - - inline bool operator<(const PkgmgrEvent &rhs) const - { - if (uid < rhs.uid) - return true; - else if (uid > rhs.uid) - return false; - else - return pkgid.compare(rhs.pkgid) < 0; - } - - inline bool operator>(const PkgmgrEvent &rhs) const - { - if (uid > rhs.uid) - return true; - else if (uid < rhs.uid) - return false; - else - return pkgid.compare(rhs.pkgid) > 0; - } - - uid_t uid; - std::string pkgid; + PkgmgrEvent(uid_t _uid, const char *_pkgid) + : uid(_uid) + , pkgid(_pkgid) {} + + inline bool operator==(const PkgmgrEvent &rhs) const + { + return uid == rhs.uid && pkgid.compare(rhs.pkgid) == 0; + } + + inline bool operator<(const PkgmgrEvent &rhs) const + { + if (uid < rhs.uid) + return true; + else if (uid > rhs.uid) + return false; + else + return pkgid.compare(rhs.pkgid) < 0; + } + + inline bool operator>(const PkgmgrEvent &rhs) const + { + if (uid > rhs.uid) + return true; + else if (uid < rhs.uid) + return false; + else + return pkgid.compare(rhs.pkgid) > 0; + } + + uid_t uid; + std::string pkgid; }; std::set<PkgmgrEvent> pkgmgrEventSet; @@ -72,109 +72,114 @@ std::set<PkgmgrEvent> pkgmgrEventSet; namespace CKM { -GLIBLogic::GLIBLogic() - : m_commMgr(nullptr) - , m_reqid(0) +GLIBLogic::GLIBLogic() : m_commMgr(nullptr), m_reqid(0) { - LogDebug("Allocation g_main_loop"); - m_gMainLoop = g_main_loop_new(nullptr, FALSE); + LogDebug("Allocation g_main_loop"); + m_gMainLoop = g_main_loop_new(nullptr, FALSE); } -void GLIBLogic::LoopStart() { - LogDebug("Register uninstalledApp event callback start"); +void GLIBLogic::LoopStart() +{ + LogDebug("Register uninstalledApp event callback start"); + + std::unique_ptr<pkgmgr_client, int(*)(pkgmgr_client *)> client( + pkgmgr_client_new(PC_LISTENING), pkgmgr_client_free); - std::unique_ptr<pkgmgr_client, int(*)(pkgmgr_client *)> - client(pkgmgr_client_new(PC_LISTENING), pkgmgr_client_free); + if (!client) { + LogError("Error in pkgmgr_client_new"); + return; + } - if (!client) { - LogError("Error in pkgmgr_client_new"); - return; - } + m_reqid = pkgmgr_client_listen_status(client.get(), packageEventCallbackStatic, + this); - m_reqid = pkgmgr_client_listen_status(client.get(), packageEventCallbackStatic, this); - if (m_reqid < 0) { - LogError("Error in pkgmgr_client_listen_status. reqid(errcode): " << m_reqid); - return; - } + if (m_reqid < 0) { + LogError("Error in pkgmgr_client_listen_status. reqid(errcode): " << m_reqid); + return; + } - LogDebug("Starting g_main_loop"); - g_main_loop_run(m_gMainLoop); - LogDebug("...g_main_loop ended"); + LogDebug("Starting g_main_loop"); + g_main_loop_run(m_gMainLoop); + LogDebug("...g_main_loop ended"); } -void GLIBLogic::LoopStop() { - LogDebug("Closing g_main_loop"); - g_main_loop_quit(m_gMainLoop); +void GLIBLogic::LoopStop() +{ + LogDebug("Closing g_main_loop"); + g_main_loop_quit(m_gMainLoop); } -GLIBLogic::~GLIBLogic() { - LogDebug("Destroying g_main_loop"); - g_main_loop_unref(m_gMainLoop); +GLIBLogic::~GLIBLogic() +{ + LogDebug("Destroying g_main_loop"); + g_main_loop_unref(m_gMainLoop); } -void GLIBLogic::SetCommManager(CommMgr *manager) { - m_commMgr = manager; +void GLIBLogic::SetCommManager(CommMgr *manager) +{ + m_commMgr = manager; } int GLIBLogic::packageEventCallbackStatic( - uid_t uid, - int reqid, - const char *pkgtype, - const char *pkgid, - const char *key, - const char *val, - const void *pmsg, - void *data) + uid_t uid, + int reqid, + const char *pkgtype, + const char *pkgid, + const char *key, + const char *val, + const void *pmsg, + void *data) { - LogDebug("Some event was caught"); - - if (!data) - return -1; - else - return static_cast<GLIBLogic*>(data)->packageEventCallback( - uid, - reqid, - pkgtype, - pkgid, - key, - val, - pmsg, - data); + LogDebug("Some event was caught"); + + if (!data) + return -1; + else + return static_cast<GLIBLogic *>(data)->packageEventCallback( + uid, + reqid, + pkgtype, + pkgid, + key, + val, + pmsg, + data); } int GLIBLogic::packageEventCallback( - uid_t uid, - int reqid, - const char */*pkgtype*/, - const char *pkgid, - const char *key, - const char *val, - const void */*pmsg*/, - void */*data*/) + uid_t uid, + int reqid, + const char */*pkgtype*/, + const char *pkgid, + const char *key, + const char *val, + const void */*pmsg*/, + void */*data*/) { - if (reqid != m_reqid) { - LogError("pkgmgr event reqid[" << reqid - << "] isn't same with mine[" << m_reqid << "]"); - return -1; - } else if (pkgid == nullptr || key == nullptr || val == nullptr) { - LogError("Invalid parameter."); - return -1; - } - - PkgmgrEvent event(uid, pkgid); - std::string keystr(key); - std::string valstr(val); - if (keystr.compare("start") == 0 && valstr.compare("uninstall") == 0) { - pkgmgrEventSet.insert(event); - } else if (keystr.compare("end") == 0 && valstr.compare("ok") == 0) { - if (pkgmgrEventSet.count(event) != 0) { - LogDebug("PackageUninstalled Callback. Uninstallation of: " << event.pkgid); - m_commMgr->SendMessage(MsgRemoveAppData(event.pkgid)); - pkgmgrEventSet.erase(event); - } - } - - return 0; + if (reqid != m_reqid) { + LogError("pkgmgr event reqid[" << reqid + << "] isn't same with mine[" << m_reqid << "]"); + return -1; + } else if (pkgid == nullptr || key == nullptr || val == nullptr) { + LogError("Invalid parameter."); + return -1; + } + + PkgmgrEvent event(uid, pkgid); + std::string keystr(key); + std::string valstr(val); + + if (keystr.compare("start") == 0 && valstr.compare("uninstall") == 0) { + pkgmgrEventSet.insert(event); + } else if (keystr.compare("end") == 0 && valstr.compare("ok") == 0) { + if (pkgmgrEventSet.count(event) != 0) { + LogDebug("PackageUninstalled Callback. Uninstallation of: " << event.pkgid); + m_commMgr->SendMessage(MsgRemoveAppData(event.pkgid)); + pkgmgrEventSet.erase(event); + } + } + + return 0; } } // namespace CKM diff --git a/src/manager/service/glib-logic.h b/src/manager/service/glib-logic.h index ef3a3ff2..7cadbfeb 100644 --- a/src/manager/service/glib-logic.h +++ b/src/manager/service/glib-logic.h @@ -31,38 +31,39 @@ namespace CKM { class GLIBLogic { public: - GLIBLogic(); + GLIBLogic(); - NONCOPYABLE(GLIBLogic); + NONCOPYABLE(GLIBLogic); + + void LoopStart(); + void LoopStop(); + void SetCommManager(CommMgr *manager); + virtual ~GLIBLogic(); - void LoopStart(); - void LoopStop(); - void SetCommManager(CommMgr *manager); - virtual ~GLIBLogic(); protected: - static int packageEventCallbackStatic( - uid_t uid, - int reqid, - const char *pkgtype, - const char *pkgid, - const char *key, - const char *val, - const void *pmsg, - void *data); + static int packageEventCallbackStatic( + uid_t uid, + int reqid, + const char *pkgtype, + const char *pkgid, + const char *key, + const char *val, + const void *pmsg, + void *data); - int packageEventCallback( - uid_t uid, - int reqid, - const char *pkgtype, - const char *pkgid, - const char *key, - const char *val, - const void *pmsg, - void *data); + int packageEventCallback( + uid_t uid, + int reqid, + const char *pkgtype, + const char *pkgid, + const char *key, + const char *val, + const void *pmsg, + void *data); - CommMgr *m_commMgr; - GMainLoop *m_gMainLoop; - int m_reqid; + CommMgr *m_commMgr; + GMainLoop *m_gMainLoop; + int m_reqid; }; } // namespace CKM diff --git a/src/manager/service/glib-service.cpp b/src/manager/service/glib-service.cpp index e5560e80..3568384f 100644 --- a/src/manager/service/glib-service.cpp +++ b/src/manager/service/glib-service.cpp @@ -30,8 +30,8 @@ namespace CKM { GLIBService::GLIBService() - : m_state(State::NoThread) - , m_logic(new GLIBLogic()) + : m_state(State::NoThread) + , m_logic(new GLIBLogic()) {} void GLIBService::Event(const AcceptEvent &) {} @@ -40,41 +40,48 @@ void GLIBService::Event(const ReadEvent &) {} void GLIBService::Event(const CloseEvent &) {} void GLIBService::Event(const SecurityEvent &) {} -void GLIBService::Start(){ - LogDebug("Starting thread!"); - assert(m_state == State::NoThread); - m_thread = std::thread(ThreadLoopStatic, this); - m_state = State::Work; +void GLIBService::Start() +{ + LogDebug("Starting thread!"); + assert(m_state == State::NoThread); + m_thread = std::thread(ThreadLoopStatic, this); + m_state = State::Work; } -void GLIBService::Stop(){ - LogDebug("Stopping thread!"); - assert(m_state == State::Work); - m_logic->LoopStop(); - m_thread.join(); - m_state = State::NoThread; - LogDebug("Thread for glib joined!"); +void GLIBService::Stop() +{ + LogDebug("Stopping thread!"); + assert(m_state == State::Work); + m_logic->LoopStop(); + m_thread.join(); + m_state = State::NoThread; + LogDebug("Thread for glib joined!"); } -GLIBService::~GLIBService(){ - delete m_logic; +GLIBService::~GLIBService() +{ + delete m_logic; } -GLIBService::ServiceDescriptionVector GLIBService::GetServiceDescription() { - return ServiceDescriptionVector(); +GLIBService::ServiceDescriptionVector GLIBService::GetServiceDescription() +{ + return ServiceDescriptionVector(); } -void GLIBService::ThreadLoopStatic(GLIBService *ptr) { - ptr->ThreadLoop(); +void GLIBService::ThreadLoopStatic(GLIBService *ptr) +{ + ptr->ThreadLoop(); } -void GLIBService::ThreadLoop() { - m_logic->LoopStart(); +void GLIBService::ThreadLoop() +{ + m_logic->LoopStart(); } -void GLIBService::SetCommManager(CommMgr *manager) { - m_commMgr = manager; - m_logic->SetCommManager(manager); +void GLIBService::SetCommManager(CommMgr *manager) +{ + m_commMgr = manager; + m_logic->SetCommManager(manager); } } // namespace CKM diff --git a/src/manager/service/glib-service.h b/src/manager/service/glib-service.h index 726dcd5f..f0dd604e 100644 --- a/src/manager/service/glib-service.h +++ b/src/manager/service/glib-service.h @@ -32,35 +32,36 @@ class GLIBLogic; class GLIBService : public CKM::GenericSocketService { public: - enum class State { - NoThread, - Work, - }; + enum class State { + NoThread, + Work, + }; - GLIBService(); - NONCOPYABLE(GLIBService); + GLIBService(); + NONCOPYABLE(GLIBService); - // This service does not provide any socket for communication so no events will be supported - virtual void Event(const AcceptEvent &); - virtual void Event(const WriteEvent &); - virtual void Event(const ReadEvent &); - virtual void Event(const CloseEvent &); - virtual void Event(const SecurityEvent &); + // This service does not provide any socket for communication so no events will be supported + virtual void Event(const AcceptEvent &); + virtual void Event(const WriteEvent &); + virtual void Event(const ReadEvent &); + virtual void Event(const CloseEvent &); + virtual void Event(const SecurityEvent &); - virtual void Start(); - virtual void Stop(); + virtual void Start(); + virtual void Stop(); - virtual ~GLIBService(); + virtual ~GLIBService(); + + virtual ServiceDescriptionVector GetServiceDescription(); + virtual void SetCommManager(CommMgr *manager); - virtual ServiceDescriptionVector GetServiceDescription(); - virtual void SetCommManager(CommMgr *manager); protected: - static void ThreadLoopStatic(GLIBService *ptr); - void ThreadLoop(); + static void ThreadLoopStatic(GLIBService *ptr); + void ThreadLoop(); - State m_state; - std::thread m_thread; - GLIBLogic *m_logic; + State m_state; + std::thread m_thread; + GLIBLogic *m_logic; }; } // namespace CKM diff --git a/src/manager/service/iencryption-service.h b/src/manager/service/iencryption-service.h index d69800a3..35281e20 100644 --- a/src/manager/service/iencryption-service.h +++ b/src/manager/service/iencryption-service.h @@ -31,10 +31,10 @@ namespace CKM { class IEncryptionService { public: - virtual void RespondToClient(const CryptoRequest& request, - int retCode, - const RawBuffer& data = RawBuffer()) = 0; - virtual void RequestKey(const CryptoRequest& request) = 0; + virtual void RespondToClient(const CryptoRequest &request, + int retCode, + const RawBuffer &data = RawBuffer()) = 0; + virtual void RequestKey(const CryptoRequest &request) = 0; }; } // namespace CKM diff --git a/src/manager/service/key-provider.cpp b/src/manager/service/key-provider.cpp index 7abba872..4ca4f038 100644 --- a/src/manager/service/key-provider.cpp +++ b/src/manager/service/key-provider.cpp @@ -7,19 +7,21 @@ namespace { template<typename T> CKM::RawBuffer toRawBuffer(const T &data) { - CKM::RawBuffer output; - const unsigned char *ptr = reinterpret_cast<const unsigned char*>(&data); - output.assign(ptr, ptr + sizeof(T)); - return output; + CKM::RawBuffer output; + const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&data); + output.assign(ptr, ptr + sizeof(T)); + return output; } // You cannot use toRawBuffer template with pointers template<typename T> CKM::RawBuffer toRawBuffer(T *) { - class NoPointerAllowed { NoPointerAllowed(){} }; - NoPointerAllowed a; - return CKM::RawBuffer(); + class NoPointerAllowed { + NoPointerAllowed() {} + }; + NoPointerAllowed a; + return CKM::RawBuffer(); } } // anonymous namespace @@ -28,578 +30,601 @@ using namespace CKM; WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer() { - wrappedKeyAndInfo = new WrappedKeyAndInfo; - memset(wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo)); + wrappedKeyAndInfo = new WrappedKeyAndInfo; + memset(wrappedKeyAndInfo, 0, sizeof(WrappedKeyAndInfo)); } -WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char *data) +WrappedKeyAndInfoContainer::WrappedKeyAndInfoContainer(const unsigned char + *data) { - wrappedKeyAndInfo = new WrappedKeyAndInfo; - memcpy(wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo)); + wrappedKeyAndInfo = new WrappedKeyAndInfo; + memcpy(wrappedKeyAndInfo, data, sizeof(WrappedKeyAndInfo)); } -WrappedKeyAndInfo& WrappedKeyAndInfoContainer::getWrappedKeyAndInfo() +WrappedKeyAndInfo &WrappedKeyAndInfoContainer::getWrappedKeyAndInfo() { - return *wrappedKeyAndInfo; + return *wrappedKeyAndInfo; } void WrappedKeyAndInfoContainer::setKeyInfoKeyLength(const unsigned int length) { - wrappedKeyAndInfo->keyInfo.keyLength = length; + wrappedKeyAndInfo->keyInfo.keyLength = length; } void WrappedKeyAndInfoContainer::setKeyInfoLabel(const std::string label) { - strncpy( - wrappedKeyAndInfo->keyInfo.label, - label.c_str(), - MAX_LABEL_SIZE); + strncpy( + wrappedKeyAndInfo->keyInfo.label, + label.c_str(), + MAX_LABEL_SIZE); } -void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt, const int size) +void WrappedKeyAndInfoContainer::setKeyInfoSalt(const unsigned char *salt, + const int size) { - memcpy(wrappedKeyAndInfo->keyInfo.salt, salt, size); + memcpy(wrappedKeyAndInfo->keyInfo.salt, salt, size); } -void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo) +void WrappedKeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo + *keyComponentsInfo) { - memcpy(&(wrappedKeyAndInfo->keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo)); + memcpy(&(wrappedKeyAndInfo->keyInfo), keyComponentsInfo, + sizeof(KeyComponentsInfo)); } WrappedKeyAndInfoContainer::~WrappedKeyAndInfoContainer() { - delete wrappedKeyAndInfo; + delete wrappedKeyAndInfo; } KeyAndInfoContainer::KeyAndInfoContainer() { - keyAndInfo = new KeyAndInfo; - memset(keyAndInfo, 0, sizeof(KeyAndInfo)); + keyAndInfo = new KeyAndInfo; + memset(keyAndInfo, 0, sizeof(KeyAndInfo)); } KeyAndInfoContainer::KeyAndInfoContainer(const unsigned char *data) { - keyAndInfo = new KeyAndInfo; - memcpy(keyAndInfo, data, sizeof(KeyAndInfo)); + keyAndInfo = new KeyAndInfo; + memcpy(keyAndInfo, data, sizeof(KeyAndInfo)); } -KeyAndInfo& KeyAndInfoContainer::getKeyAndInfo() +KeyAndInfo &KeyAndInfoContainer::getKeyAndInfo() { - return *keyAndInfo; + return *keyAndInfo; } void KeyAndInfoContainer::setKeyInfoKeyLength(unsigned int length) { - keyAndInfo->keyInfo.keyLength = length; + keyAndInfo->keyInfo.keyLength = length; } void KeyAndInfoContainer::setKeyInfo(const KeyComponentsInfo *keyComponentsInfo) { - memcpy(&(keyAndInfo->keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo)); + memcpy(&(keyAndInfo->keyInfo), keyComponentsInfo, sizeof(KeyComponentsInfo)); } KeyAndInfoContainer::~KeyAndInfoContainer() { - // overwrite key - char *ptr = reinterpret_cast<char*>(keyAndInfo); - memset(ptr, 0, sizeof(KeyAndInfo)); - // verification - for (size_t size = 0; size < sizeof(KeyAndInfo); ++size) { - if (ptr[size]) - LogError("Write momory error! Memory used by key was not owerwritten."); - } - delete keyAndInfo; + // overwrite key + char *ptr = reinterpret_cast<char *>(keyAndInfo); + memset(ptr, 0, sizeof(KeyAndInfo)); + + // verification + for (size_t size = 0; size < sizeof(KeyAndInfo); ++size) { + if (ptr[size]) + LogError("Write momory error! Memory used by key was not owerwritten."); + } + + delete keyAndInfo; } KeyProvider::KeyProvider() : - m_kmcDKEK(NULL), - m_isInitialized(false) + m_kmcDKEK(NULL), + m_isInitialized(false) { - LogDebug("Created empty KeyProvider"); + LogDebug("Created empty KeyProvider"); } KeyProvider::KeyProvider( - const RawBuffer &domainKEKInWrapForm, - const Password &password) : - m_kmcDKEK(new KeyAndInfoContainer()), - m_isInitialized(true) -{ - if (!m_isInitialized) - ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened"); - - if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) { - LogError("input size:" << domainKEKInWrapForm.size() - << " Expected: " << sizeof(WrappedKeyAndInfo)); - ThrowErr(Exc::InternalError, "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor"); - } - - WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(domainKEKInWrapForm.data()); - - char *concat_user_pass = NULL; - uint8_t PKEK1[MAX_KEY_SIZE]; - - concat_user_pass = concat_password_user( - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.label, - password.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - - delete[] concat_user_pass; - - int keyLength; - - if (0 > (keyLength = decryptAes256Gcm( - wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK1, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, - m_kmcDKEK->getKeyAndInfo().key))) { - ThrowErr(Exc::AuthenticationFailed, "VerifyDomainKEK failed in KeyProvider Constructor"); - } - - m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo)); - m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength); -} - -KeyProvider& KeyProvider::operator=(KeyProvider &&second) -{ - LogDebug("Moving KeyProvider"); - if (this == &second) - return *this; - m_isInitialized = second.m_isInitialized; - m_kmcDKEK = second.m_kmcDKEK; - second.m_isInitialized = false; - second.m_kmcDKEK = NULL; - return *this; + const RawBuffer &domainKEKInWrapForm, + const Password &password) : + m_kmcDKEK(new KeyAndInfoContainer()), + m_isInitialized(true) +{ + if (!m_isInitialized) + ThrowErr(Exc::InternalError, "Object not initialized!. Should not happened"); + + if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) { + LogError("input size:" << domainKEKInWrapForm.size() + << " Expected: " << sizeof(WrappedKeyAndInfo)); + ThrowErr(Exc::InternalError, + "buffer doesn't have proper size to store WrappedKeyAndInfo in KeyProvider Constructor"); + } + + WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer( + domainKEKInWrapForm.data()); + + char *concat_user_pass = NULL; + uint8_t PKEK1[MAX_KEY_SIZE]; + + concat_user_pass = concat_password_user( + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.label, + password.c_str()); + + if (!PKCS5_PBKDF2_HMAC_SHA1( + concat_user_pass, + strlen(concat_user_pass), + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK1)) { + delete[] concat_user_pass; + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + } + + delete[] concat_user_pass; + + int keyLength; + + if (0 > (keyLength = decryptAes256Gcm( + wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag, + PKEK1, + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, + m_kmcDKEK->getKeyAndInfo().key))) { + ThrowErr(Exc::AuthenticationFailed, + "VerifyDomainKEK failed in KeyProvider Constructor"); + } + + m_kmcDKEK->setKeyInfo(&(wkmcDKEK.getWrappedKeyAndInfo().keyInfo)); + m_kmcDKEK->setKeyInfoKeyLength((unsigned int)keyLength); +} + +KeyProvider &KeyProvider::operator=(KeyProvider &&second) +{ + LogDebug("Moving KeyProvider"); + + if (this == &second) + return *this; + + m_isInitialized = second.m_isInitialized; + m_kmcDKEK = second.m_kmcDKEK; + second.m_isInitialized = false; + second.m_kmcDKEK = NULL; + return *this; } KeyProvider::KeyProvider(KeyProvider &&second) { - LogDebug("Moving KeyProvider"); - m_isInitialized = second.m_isInitialized; - m_kmcDKEK = second.m_kmcDKEK; - second.m_isInitialized = false; - second.m_kmcDKEK = NULL; + LogDebug("Moving KeyProvider"); + m_isInitialized = second.m_isInitialized; + m_kmcDKEK = second.m_kmcDKEK; + second.m_isInitialized = false; + second.m_kmcDKEK = NULL; } bool KeyProvider::isInitialized() { - return m_isInitialized; + return m_isInitialized; } RawBuffer KeyProvider::getPureDomainKEK() { - if (!m_isInitialized) - ThrowErr(Exc::InternalError, "Object not initialized!"); + if (!m_isInitialized) + ThrowErr(Exc::InternalError, "Object not initialized!"); - // TODO secure - return RawBuffer(m_kmcDKEK->getKeyAndInfo().key, (m_kmcDKEK->getKeyAndInfo().key) + m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength); + // TODO secure + return RawBuffer(m_kmcDKEK->getKeyAndInfo().key, + (m_kmcDKEK->getKeyAndInfo().key) + + m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength); } RawBuffer KeyProvider::getWrappedDomainKEK(const Password &password) { - if (!m_isInitialized) - ThrowErr(Exc::InternalError, "Object not initialized!"); + if (!m_isInitialized) + ThrowErr(Exc::InternalError, "Object not initialized!"); - WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); + WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); - char *concat_user_pass = NULL; - uint8_t PKEK1[MAX_KEY_SIZE]; + char *concat_user_pass = NULL; + uint8_t PKEK1[MAX_KEY_SIZE]; - concat_user_pass = concat_password_user( - m_kmcDKEK->getKeyAndInfo().keyInfo.label, - password.c_str()); + concat_user_pass = concat_password_user( + m_kmcDKEK->getKeyAndInfo().keyInfo.label, + password.c_str()); - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - m_kmcDKEK->getKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } + if (!PKCS5_PBKDF2_HMAC_SHA1( + concat_user_pass, + strlen(concat_user_pass), + m_kmcDKEK->getKeyAndInfo().keyInfo.salt, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK1)) { + delete[] concat_user_pass; + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + } - delete[] concat_user_pass; + delete[] concat_user_pass; - wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo)); + wkmcDKEK.setKeyInfo(&(m_kmcDKEK->getKeyAndInfo().keyInfo)); - int wrappedKeyLength; + int wrappedKeyLength; - if (0 > (wrappedKeyLength = encryptAes256Gcm( - m_kmcDKEK->getKeyAndInfo().key, - m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, - PKEK1, - m_kmcDKEK->getKeyAndInfo().keyInfo.iv, - wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, "WrapDKEK Failed in KeyProvider::getDomainKEK"); + if (0 > (wrappedKeyLength = encryptAes256Gcm( + m_kmcDKEK->getKeyAndInfo().key, + m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, + PKEK1, + m_kmcDKEK->getKeyAndInfo().keyInfo.iv, + wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) + ThrowErr(Exc::InternalError, "WrapDKEK Failed in KeyProvider::getDomainKEK"); - wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); + wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - LogDebug("getDomainKEK(password) Success"); - return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo()); + LogDebug("getDomainKEK(password) Success"); + return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo()); } RawBuffer KeyProvider::getPureDEK(const RawBuffer &DEKInWrapForm) { - if (!m_isInitialized) - ThrowErr(Exc::InternalError, "Object not initialized!"); - - if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) { - LogError("input size:" << DEKInWrapForm.size() - << " Expected: " << sizeof(WrappedKeyAndInfo)); - ThrowErr(Exc::InternalError, - "buffer doesn't have proper size to store " - "WrappedKeyAndInfo in KeyProvider::getPureDEK"); - } - - KeyAndInfoContainer kmcDEK = KeyAndInfoContainer(); - WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(DEKInWrapForm.data()); - - uint8_t PKEK2[MAX_KEY_SIZE]; - int keyLength; - - if (!PKCS5_PBKDF2_HMAC_SHA1( - wkmcDEK.getWrappedKeyAndInfo().keyInfo.label, - strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.label), - m_kmcDKEK->getKeyAndInfo().key, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK2)) - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - - if (0 > (keyLength = decryptAes256Gcm( - wkmcDEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength, - wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK2, - wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, - kmcDEK.getKeyAndInfo().key))) - ThrowErr(Exc::InternalError, - "UnwrapDEK Failed in KeyProvider::getPureDEK"); - - kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength); - - LogDebug("getPureDEK SUCCESS"); - return RawBuffer( - kmcDEK.getKeyAndInfo().key, - (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength); + if (!m_isInitialized) + ThrowErr(Exc::InternalError, "Object not initialized!"); + + if (DEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) { + LogError("input size:" << DEKInWrapForm.size() + << " Expected: " << sizeof(WrappedKeyAndInfo)); + ThrowErr(Exc::InternalError, + "buffer doesn't have proper size to store " + "WrappedKeyAndInfo in KeyProvider::getPureDEK"); + } + + KeyAndInfoContainer kmcDEK = KeyAndInfoContainer(); + WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer( + DEKInWrapForm.data()); + + uint8_t PKEK2[MAX_KEY_SIZE]; + int keyLength; + + if (!PKCS5_PBKDF2_HMAC_SHA1( + wkmcDEK.getWrappedKeyAndInfo().keyInfo.label, + strlen(wkmcDEK.getWrappedKeyAndInfo().keyInfo.label), + m_kmcDKEK->getKeyAndInfo().key, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK2)) + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + + if (0 > (keyLength = decryptAes256Gcm( + wkmcDEK.getWrappedKeyAndInfo().wrappedKey, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.keyLength, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag, + PKEK2, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, + kmcDEK.getKeyAndInfo().key))) + ThrowErr(Exc::InternalError, + "UnwrapDEK Failed in KeyProvider::getPureDEK"); + + kmcDEK.setKeyInfoKeyLength((unsigned int)keyLength); + + LogDebug("getPureDEK SUCCESS"); + return RawBuffer( + kmcDEK.getKeyAndInfo().key, + (kmcDEK.getKeyAndInfo().key) + kmcDEK.getKeyAndInfo().keyInfo.keyLength); } RawBuffer KeyProvider::generateDEK(const std::string &smackLabel) { - if (!m_isInitialized) - ThrowErr(Exc::InternalError, "Object not initialized!"); + if (!m_isInitialized) + ThrowErr(Exc::InternalError, "Object not initialized!"); - WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(); - std::string resized_smackLabel; + WrappedKeyAndInfoContainer wkmcDEK = WrappedKeyAndInfoContainer(); + std::string resized_smackLabel; - if (smackLabel.length() < APP_LABEL_SIZE) - resized_smackLabel = smackLabel; - else - resized_smackLabel = smackLabel.substr(0, APP_LABEL_SIZE-1); + if (smackLabel.length() < APP_LABEL_SIZE) + resized_smackLabel = smackLabel; + else + resized_smackLabel = smackLabel.substr(0, APP_LABEL_SIZE - 1); - uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE]; + uint8_t key[MAX_KEY_SIZE], PKEK2[MAX_KEY_SIZE]; - if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) || - !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + if (!RAND_bytes(key, m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength) || + !RAND_bytes(wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - if (!PKCS5_PBKDF2_HMAC_SHA1( - resized_smackLabel.c_str(), - strlen(resized_smackLabel.c_str()), - m_kmcDKEK->getKeyAndInfo().key, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK2)) - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + if (!PKCS5_PBKDF2_HMAC_SHA1( + resized_smackLabel.c_str(), + strlen(resized_smackLabel.c_str()), + m_kmcDKEK->getKeyAndInfo().key, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK2)) + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - int wrappedKeyLength; + int wrappedKeyLength; - if (0 > (wrappedKeyLength = encryptAes256Gcm( - key, - m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, - PKEK2, - wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, - wkmcDEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK"); + if (0 > (wrappedKeyLength = encryptAes256Gcm( + key, + m_kmcDKEK->getKeyAndInfo().keyInfo.keyLength, + PKEK2, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.iv, + wkmcDEK.getWrappedKeyAndInfo().wrappedKey, + wkmcDEK.getWrappedKeyAndInfo().keyInfo.tag))) + ThrowErr(Exc::InternalError, "GenerateDEK Failed in KeyProvider::generateDEK"); - wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - wkmcDEK.setKeyInfoLabel(resized_smackLabel); + wkmcDEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); + wkmcDEK.setKeyInfoLabel(resized_smackLabel); - LogDebug("GenerateDEK Success"); - return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo()); + LogDebug("GenerateDEK Success"); + return toRawBuffer(wkmcDEK.getWrappedKeyAndInfo()); } RawBuffer KeyProvider::reencrypt( - const RawBuffer &domainKEKInWrapForm, - const Password &oldPass, - const Password &newPass) -{ - if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) { - LogError("input size:" << domainKEKInWrapForm.size() - << " Expected: " << sizeof(WrappedKeyAndInfo)); - ThrowErr(Exc::InternalError, - "buffer doesn't have proper size to store " - "WrappedKeyAndInfo in KeyProvider::reencrypt"); - } - - WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer(domainKEKInWrapForm.data()); - WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer(); - KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer(); - - char *concat_user_pass = NULL; - uint8_t PKEK1[MAX_KEY_SIZE]; - int keyLength = 0; - - - concat_user_pass = concat_password_user( - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.label, - oldPass.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - delete[] concat_user_pass; - - if (0 > (keyLength = decryptAes256Gcm( - wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag, - PKEK1, - wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv, - kmcDKEK.getKeyAndInfo().key))) - ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password "); - - kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo)); - kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength); - - concat_user_pass = concat_password_user( - kmcDKEK.getKeyAndInfo().keyInfo.label, - newPass.c_str()); - - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - kmcDKEK.getKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - } - - delete[] concat_user_pass; - - int wrappedKeyLength = 0; - wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo)); - - if (0 > (wrappedKeyLength = encryptAes256Gcm( - kmcDKEK.getKeyAndInfo().key, - kmcDKEK.getKeyAndInfo().keyInfo.keyLength, - PKEK1, - kmcDKEK.getKeyAndInfo().keyInfo.iv, - wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, "UpdateDomainKEK in KeyProvider::reencrypt Failed"); - - wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - - LogDebug("reencrypt SUCCESS"); - return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo()); + const RawBuffer &domainKEKInWrapForm, + const Password &oldPass, + const Password &newPass) +{ + if (domainKEKInWrapForm.size() != sizeof(WrappedKeyAndInfo)) { + LogError("input size:" << domainKEKInWrapForm.size() + << " Expected: " << sizeof(WrappedKeyAndInfo)); + ThrowErr(Exc::InternalError, + "buffer doesn't have proper size to store " + "WrappedKeyAndInfo in KeyProvider::reencrypt"); + } + + WrappedKeyAndInfoContainer wkmcOldDKEK = WrappedKeyAndInfoContainer( + domainKEKInWrapForm.data()); + WrappedKeyAndInfoContainer wkmcNewDKEK = WrappedKeyAndInfoContainer(); + KeyAndInfoContainer kmcDKEK = KeyAndInfoContainer(); + + char *concat_user_pass = NULL; + uint8_t PKEK1[MAX_KEY_SIZE]; + int keyLength = 0; + + + concat_user_pass = concat_password_user( + wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.label, + oldPass.c_str()); + + if (!PKCS5_PBKDF2_HMAC_SHA1( + concat_user_pass, + strlen(concat_user_pass), + wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.salt, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK1)) { + delete[] concat_user_pass; + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + } + + delete[] concat_user_pass; + + if (0 > (keyLength = decryptAes256Gcm( + wkmcOldDKEK.getWrappedKeyAndInfo().wrappedKey, + wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.keyLength, + wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.tag, + PKEK1, + wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo.iv, + kmcDKEK.getKeyAndInfo().key))) + ThrowErr(Exc::AuthenticationFailed, "Incorrect Old Password "); + + kmcDKEK.setKeyInfo(&(wkmcOldDKEK.getWrappedKeyAndInfo().keyInfo)); + kmcDKEK.setKeyInfoKeyLength((unsigned int)keyLength); + + concat_user_pass = concat_password_user( + kmcDKEK.getKeyAndInfo().keyInfo.label, + newPass.c_str()); + + if (!PKCS5_PBKDF2_HMAC_SHA1( + concat_user_pass, + strlen(concat_user_pass), + kmcDKEK.getKeyAndInfo().keyInfo.salt, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK1)) { + delete[] concat_user_pass; + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + } + + delete[] concat_user_pass; + + int wrappedKeyLength = 0; + wkmcNewDKEK.setKeyInfo(&(kmcDKEK.getKeyAndInfo().keyInfo)); + + if (0 > (wrappedKeyLength = encryptAes256Gcm( + kmcDKEK.getKeyAndInfo().key, + kmcDKEK.getKeyAndInfo().keyInfo.keyLength, + PKEK1, + kmcDKEK.getKeyAndInfo().keyInfo.iv, + wkmcNewDKEK.getWrappedKeyAndInfo().wrappedKey, + wkmcNewDKEK.getWrappedKeyAndInfo().keyInfo.tag))) + ThrowErr(Exc::InternalError, + "UpdateDomainKEK in KeyProvider::reencrypt Failed"); + + wkmcNewDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); + + LogDebug("reencrypt SUCCESS"); + return toRawBuffer(wkmcNewDKEK.getWrappedKeyAndInfo()); } RawBuffer KeyProvider::generateDomainKEK( - const std::string &user, - const Password &userPassword) -{ - WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); - uint8_t key[MAX_KEY_SIZE], PKEK1[MAX_KEY_SIZE]; - - if (!RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, MAX_SALT_SIZE) || - !RAND_bytes(key, MAX_KEY_SIZE) || - !RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) - ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); - - int wrappedKeyLength; - char *concat_user_pass = NULL; - concat_user_pass = concat_password_user(user.c_str(), userPassword.c_str()); - if (!PKCS5_PBKDF2_HMAC_SHA1( - concat_user_pass, - strlen(concat_user_pass), - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, - MAX_SALT_SIZE, - PBKDF2_ITERATIONS, - MAX_KEY_SIZE, - PKEK1)) { - delete[] concat_user_pass; - ThrowErr(Exc::InternalError, "OPENSSL_ENGINED_ERROR"); - } - - delete[] concat_user_pass; - - if (0 > (wrappedKeyLength = encryptAes256Gcm( - key, - MAX_KEY_SIZE, - PKEK1, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, - wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, - wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) - ThrowErr(Exc::InternalError, - "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK"); - - wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); - wkmcDKEK.setKeyInfoLabel(user); - - LogDebug("generateDomainKEK Success"); - return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo()); + const std::string &user, + const Password &userPassword) +{ + WrappedKeyAndInfoContainer wkmcDKEK = WrappedKeyAndInfoContainer(); + uint8_t key[MAX_KEY_SIZE], PKEK1[MAX_KEY_SIZE]; + + if (!RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, MAX_SALT_SIZE) || + !RAND_bytes(key, MAX_KEY_SIZE) || + !RAND_bytes(wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, MAX_IV_SIZE)) + ThrowErr(Exc::InternalError, "OPENSSL_ENGINE_ERROR"); + + int wrappedKeyLength; + char *concat_user_pass = NULL; + concat_user_pass = concat_password_user(user.c_str(), userPassword.c_str()); + + if (!PKCS5_PBKDF2_HMAC_SHA1( + concat_user_pass, + strlen(concat_user_pass), + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.salt, + MAX_SALT_SIZE, + PBKDF2_ITERATIONS, + MAX_KEY_SIZE, + PKEK1)) { + delete[] concat_user_pass; + ThrowErr(Exc::InternalError, "OPENSSL_ENGINED_ERROR"); + } + + delete[] concat_user_pass; + + if (0 > (wrappedKeyLength = encryptAes256Gcm( + key, + MAX_KEY_SIZE, + PKEK1, + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.iv, + wkmcDKEK.getWrappedKeyAndInfo().wrappedKey, + wkmcDKEK.getWrappedKeyAndInfo().keyInfo.tag))) + ThrowErr(Exc::InternalError, + "GenerateDomainKEK Failed in KeyProvider::generateDomainKEK"); + + wkmcDKEK.setKeyInfoKeyLength((unsigned int)wrappedKeyLength); + wkmcDKEK.setKeyInfoLabel(user); + + LogDebug("generateDomainKEK Success"); + return toRawBuffer(wkmcDKEK.getWrappedKeyAndInfo()); } int KeyProvider::initializeLibrary() { - LogDebug("initializeLibrary Success"); - return SUCCESS; + LogDebug("initializeLibrary Success"); + return SUCCESS; } int KeyProvider::closeLibrary() { - LogDebug("closeLibrary Success"); - return SUCCESS; + LogDebug("closeLibrary Success"); + return SUCCESS; } KeyProvider::~KeyProvider() { - LogDebug("KeyProvider Destructor"); + LogDebug("KeyProvider Destructor"); } -int KeyProvider::encryptAes256Gcm(const unsigned char *plaintext, int plaintext_len, const unsigned char *key, const unsigned char *iv, unsigned char *ciphertext, unsigned char *tag) +int KeyProvider::encryptAes256Gcm(const unsigned char *plaintext, + int plaintext_len, const unsigned char *key, const unsigned char *iv, + unsigned char *ciphertext, unsigned char *tag) { - EVP_CIPHER_CTX *ctx; - int len; - int ciphertext_len = 0; + EVP_CIPHER_CTX *ctx; + int len; + int ciphertext_len = 0; - if (!(ctx = EVP_CIPHER_CTX_new())) - return OPENSSL_ENGINE_ERROR; + if (!(ctx = EVP_CIPHER_CTX_new())) + return OPENSSL_ENGINE_ERROR; - if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) + return OPENSSL_ENGINE_ERROR; - ciphertext_len = len; + ciphertext_len = len; - if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) + return OPENSSL_ENGINE_ERROR; - ciphertext_len += len; + ciphertext_len += len; - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, MAX_IV_SIZE, tag)) + return OPENSSL_ENGINE_ERROR; - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(ctx); - return ciphertext_len; + return ciphertext_len; } -int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext, int ciphertext_len, unsigned char *tag, const unsigned char *key, const unsigned char *iv, unsigned char *plaintext) +int KeyProvider::decryptAes256Gcm(const unsigned char *ciphertext, + int ciphertext_len, unsigned char *tag, const unsigned char *key, + const unsigned char *iv, unsigned char *plaintext) { - EVP_CIPHER_CTX *ctx; - int len; - int plaintext_len; - int ret; + EVP_CIPHER_CTX *ctx; + int len; + int plaintext_len; + int ret; - if (!(ctx = EVP_CIPHER_CTX_new())) - return OPENSSL_ENGINE_ERROR; + if (!(ctx = EVP_CIPHER_CTX_new())) + return OPENSSL_ENGINE_ERROR; - if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, MAX_IV_SIZE, NULL)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, MAX_IV_SIZE, tag)) + return OPENSSL_ENGINE_ERROR; - if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) - return OPENSSL_ENGINE_ERROR; + if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) + return OPENSSL_ENGINE_ERROR; - plaintext_len = len; + plaintext_len = len; - if (!(ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len))) - return OPENSSL_ENGINE_ERROR; + if (!(ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len))) + return OPENSSL_ENGINE_ERROR; - EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(ctx); - if (ret > 0) { - plaintext_len += len; - return plaintext_len; - } else { - return -1; - } + if (ret > 0) { + plaintext_len += len; + return plaintext_len; + } else { + return -1; + } } -char * KeyProvider::concat_password_user(const char *user, const char *password) +char *KeyProvider::concat_password_user(const char *user, const char *password) { - char *concat_user_pass = NULL; - char *resized_user = NULL; - int concat_user_pass_len = 0; + char *concat_user_pass = NULL; + char *resized_user = NULL; + int concat_user_pass_len = 0; - if (strlen(user) > MAX_LABEL_SIZE-1) { - resized_user = new char[MAX_LABEL_SIZE]; - memcpy(resized_user, user, MAX_LABEL_SIZE-1); - resized_user[MAX_LABEL_SIZE-1] = '\0'; - } else { - resized_user = new char[strlen(user)+1]; - memcpy(resized_user, user, strlen(user)); - resized_user[strlen(user)] = '\0'; - } + if (strlen(user) > MAX_LABEL_SIZE - 1) { + resized_user = new char[MAX_LABEL_SIZE]; + memcpy(resized_user, user, MAX_LABEL_SIZE - 1); + resized_user[MAX_LABEL_SIZE - 1] = '\0'; + } else { + resized_user = new char[strlen(user) + 1]; + memcpy(resized_user, user, strlen(user)); + resized_user[strlen(user)] = '\0'; + } - concat_user_pass_len = strlen(resized_user) + strlen(password) + 1; - concat_user_pass = new char[concat_user_pass_len]; + concat_user_pass_len = strlen(resized_user) + strlen(password) + 1; + concat_user_pass = new char[concat_user_pass_len]; - memset(concat_user_pass, '\0', concat_user_pass_len); - memcpy(concat_user_pass, password, strlen(password)); - memcpy(&(concat_user_pass[strlen(password)]), resized_user, strlen(resized_user)); - concat_user_pass[strlen(resized_user) + strlen(password)] = '\0'; + memset(concat_user_pass, '\0', concat_user_pass_len); + memcpy(concat_user_pass, password, strlen(password)); + memcpy(&(concat_user_pass[strlen(password)]), resized_user, + strlen(resized_user)); + concat_user_pass[strlen(resized_user) + strlen(password)] = '\0'; - delete[] resized_user; - return concat_user_pass; + delete[] resized_user; + return concat_user_pass; } diff --git a/src/manager/service/key-provider.h b/src/manager/service/key-provider.h index feaf8c4c..9242e11d 100644 --- a/src/manager/service/key-provider.h +++ b/src/manager/service/key-provider.h @@ -48,129 +48,130 @@ namespace CKM { typedef struct KeyComponentsInfo_ { - uint32_t keyLength; - char label[MAX_LABEL_SIZE]; - uint8_t salt[MAX_SALT_SIZE]; - uint8_t iv[MAX_IV_SIZE]; - uint8_t tag[MAX_IV_SIZE]; + uint32_t keyLength; + char label[MAX_LABEL_SIZE]; + uint8_t salt[MAX_SALT_SIZE]; + uint8_t iv[MAX_IV_SIZE]; + uint8_t tag[MAX_IV_SIZE]; } KeyComponentsInfo; typedef struct KeyAndInfo_ { - KeyComponentsInfo keyInfo; - uint8_t key[MAX_KEY_SIZE]; + KeyComponentsInfo keyInfo; + uint8_t key[MAX_KEY_SIZE]; } KeyAndInfo; typedef struct WrappedKeyAndInfo_ { - KeyComponentsInfo keyInfo; - uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE]; + KeyComponentsInfo keyInfo; + uint8_t wrappedKey[MAX_WRAPPED_KEY_SIZE]; } WrappedKeyAndInfo; class WrappedKeyAndInfoContainer { public: - WrappedKeyAndInfoContainer(); - WrappedKeyAndInfoContainer(const unsigned char*); - WrappedKeyAndInfo& getWrappedKeyAndInfo(); - void setKeyInfoKeyLength(const unsigned int); - void setKeyInfoLabel(const std::string); - void setKeyInfoSalt(const unsigned char*, const int); - void setKeyInfo(const KeyComponentsInfo*); - ~WrappedKeyAndInfoContainer(); + WrappedKeyAndInfoContainer(); + WrappedKeyAndInfoContainer(const unsigned char *); + WrappedKeyAndInfo &getWrappedKeyAndInfo(); + void setKeyInfoKeyLength(const unsigned int); + void setKeyInfoLabel(const std::string); + void setKeyInfoSalt(const unsigned char *, const int); + void setKeyInfo(const KeyComponentsInfo *); + ~WrappedKeyAndInfoContainer(); private: - WrappedKeyAndInfo *wrappedKeyAndInfo; + WrappedKeyAndInfo *wrappedKeyAndInfo; }; class KeyAndInfoContainer { public: - KeyAndInfoContainer(); - KeyAndInfoContainer(const unsigned char*); - KeyAndInfo& getKeyAndInfo(); - void setKeyInfoKeyLength(const unsigned int); - void setKeyInfo(const KeyComponentsInfo*); - ~KeyAndInfoContainer(); + KeyAndInfoContainer(); + KeyAndInfoContainer(const unsigned char *); + KeyAndInfo &getKeyAndInfo(); + void setKeyInfoKeyLength(const unsigned int); + void setKeyInfo(const KeyComponentsInfo *); + ~KeyAndInfoContainer(); private: - KeyAndInfo *keyAndInfo; + KeyAndInfo *keyAndInfo; }; // This is internal api so all functions should throw exception on errors. class KeyProvider { public: - // To store in std containers - KeyProvider(); - // In constructor you must check if SKMM is initialized. On error -> exception - // keyInWrapForm should be used like this: - // if (keyInWrapForm.size() != sizeof(WrappedKeyAndInfo)) - // throw exception; // buffer does not have proper size to store WrappedKeyAndInfo - // WrappedKeyAndInfo *wkm = static_cast<WrappedKeyAndInfo>(keyInWrapForm.data()); - KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password); - - KeyProvider(KeyProvider &&); - KeyProvider(const KeyProvider &) = delete; - KeyProvider& operator=(const KeyProvider &) = delete; - KeyProvider& operator=(KeyProvider &&); - - bool isInitialized(); - - // Returns Key used to decrypt database. - RawBuffer getPureDomainKEK(); - - // Returns Key in form used to store key in file - // Requied by Control::resetPassword(const RawBuffer &newPassword); - // This api should be used only on Tizen 2.2.1 - RawBuffer getWrappedDomainKEK(const Password &password); - - // EncryptedKey key extracted from database. Used to encrypt application data. - // This key will be used to decrypt/encrypt data in ROW - RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm); - - // Returns WRAPPED DEK. This will be written to datbase. - // This key will be used to encrypt all application information. - // All application are identified by smackLabel. - RawBuffer generateDEK(const std::string &smackLabel); - - // used by change user password. On error -> exception - static RawBuffer reencrypt( - const RawBuffer &domainKEKInWrapForm, - const Password &oldPass, - const Password &newPass); - - // First run of application for some user. DomainKEK was not created yet. We must create one. - // This key will be used to encrypt user database. - static RawBuffer generateDomainKEK(const std::string &user, const Password &userPassword); - - // This will be called by framework at the begin of the program - static int initializeLibrary(); - // This will be called by framework at the end of the program - static int closeLibrary(); - - virtual ~KeyProvider(); + // To store in std containers + KeyProvider(); + // In constructor you must check if SKMM is initialized. On error -> exception + // keyInWrapForm should be used like this: + // if (keyInWrapForm.size() != sizeof(WrappedKeyAndInfo)) + // throw exception; // buffer does not have proper size to store WrappedKeyAndInfo + // WrappedKeyAndInfo *wkm = static_cast<WrappedKeyAndInfo>(keyInWrapForm.data()); + KeyProvider(const RawBuffer &domainKEKInWrapForm, const Password &password); + + KeyProvider(KeyProvider &&); + KeyProvider(const KeyProvider &) = delete; + KeyProvider &operator=(const KeyProvider &) = delete; + KeyProvider &operator=(KeyProvider &&); + + bool isInitialized(); + + // Returns Key used to decrypt database. + RawBuffer getPureDomainKEK(); + + // Returns Key in form used to store key in file + // Requied by Control::resetPassword(const RawBuffer &newPassword); + // This api should be used only on Tizen 2.2.1 + RawBuffer getWrappedDomainKEK(const Password &password); + + // EncryptedKey key extracted from database. Used to encrypt application data. + // This key will be used to decrypt/encrypt data in ROW + RawBuffer getPureDEK(const RawBuffer &DEKInWrapForm); + + // Returns WRAPPED DEK. This will be written to datbase. + // This key will be used to encrypt all application information. + // All application are identified by smackLabel. + RawBuffer generateDEK(const std::string &smackLabel); + + // used by change user password. On error -> exception + static RawBuffer reencrypt( + const RawBuffer &domainKEKInWrapForm, + const Password &oldPass, + const Password &newPass); + + // First run of application for some user. DomainKEK was not created yet. We must create one. + // This key will be used to encrypt user database. + static RawBuffer generateDomainKEK(const std::string &user, + const Password &userPassword); + + // This will be called by framework at the begin of the program + static int initializeLibrary(); + // This will be called by framework at the end of the program + static int closeLibrary(); + + virtual ~KeyProvider(); private: - // KeyAndInfoContainer class - std::shared_ptr<KeyAndInfoContainer> m_kmcDKEK; - bool m_isInitialized; - - static int encryptAes256Gcm( - const unsigned char *plaintext, - int plaintext_len, - const unsigned char *key, - const unsigned char *iv, - unsigned char *ciphertext, - unsigned char *tag); - - static int decryptAes256Gcm( - const unsigned char *ciphertext, - int ciphertext_len, - unsigned char *tag, - const unsigned char *key, - const unsigned char *iv, - unsigned char *plaintext); - - static char * concat_password_user( - const char *user, - const char *password); + // KeyAndInfoContainer class + std::shared_ptr<KeyAndInfoContainer> m_kmcDKEK; + bool m_isInitialized; + + static int encryptAes256Gcm( + const unsigned char *plaintext, + int plaintext_len, + const unsigned char *key, + const unsigned char *iv, + unsigned char *ciphertext, + unsigned char *tag); + + static int decryptAes256Gcm( + const unsigned char *ciphertext, + int ciphertext_len, + unsigned char *tag, + const unsigned char *key, + const unsigned char *iv, + unsigned char *plaintext); + + static char *concat_password_user( + const char *user, + const char *password); }; } // namespace CKM diff --git a/src/manager/service/ocsp-logic.cpp b/src/manager/service/ocsp-logic.cpp index 5cc512a7..fe2a8d2b 100644 --- a/src/manager/service/ocsp-logic.cpp +++ b/src/manager/service/ocsp-logic.cpp @@ -39,10 +39,11 @@ namespace { const std::vector<std::string> FEATURES = { - "tizen.org/feature/network.internet", - "tizen.org/feature/network.telephony", - "tizen.org/feature/network.tethering.bluetooth", - "tizen.org/feature/network.ethernet"}; + "tizen.org/feature/network.internet", + "tizen.org/feature/network.telephony", + "tizen.org/feature/network.tethering.bluetooth", + "tizen.org/feature/network.ethernet" +}; } // namespace anonymous @@ -50,66 +51,69 @@ namespace CKM { OCSPLogic::OCSPLogic() : m_isNetAvailable(false) { - setNetAvailable(); + setNetAvailable(); } void OCSPLogic::setNetAvailable() { - bool value; - int ret; + bool value; + int ret; - for (const auto &feature : FEATURES) { - value = false; + for (const auto &feature : FEATURES) { + value = false; - ret = system_info_get_platform_bool(feature.c_str(), &value); - if (ret != SYSTEM_INFO_ERROR_NONE) { - LogError("Error in system_info_get_platform_bool. ret : " << ret); - continue; - } + ret = system_info_get_platform_bool(feature.c_str(), &value); - if (value) { - m_isNetAvailable = true; - return; - } - } + if (ret != SYSTEM_INFO_ERROR_NONE) { + LogError("Error in system_info_get_platform_bool. ret : " << ret); + continue; + } - m_isNetAvailable = false; + if (value) { + m_isNetAvailable = true; + return; + } + } + + m_isNetAvailable = false; } -RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain, bool allowed) +RawBuffer OCSPLogic::ocspCheck(int commandId, const RawBufferVector &rawChain, + bool allowed) { - CertificateImplVector certChain; - OCSPModule ocsp; - int retCode = CKM_API_SUCCESS; - int ocspStatus = CKM_API_OCSP_STATUS_INTERNAL_ERROR; - - if (!m_isNetAvailable) { - /* try again for in case of system-info error */ - setNetAvailable(); - } - - if (!m_isNetAvailable) { - retCode = CKM_API_ERROR_NOT_SUPPORTED; - } else if (!allowed) { - retCode = CKM_API_ERROR_ACCESS_DENIED; - } else if (rawChain.size() < 2) { - LogError("Certificate chain should contain at least 2 certificates"); - retCode = CKM_API_ERROR_INPUT_PARAM; - } else { - for (auto &e: rawChain) { - certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER)); - if (certChain.rbegin()->empty()) { - LogDebug("Error in parsing certificates!"); - retCode = CKM_API_ERROR_INPUT_PARAM; - break; - } - } - } - - if (retCode == CKM_API_SUCCESS) - ocspStatus = ocsp.verify(certChain); - - return MessageBuffer::Serialize(commandId, retCode, ocspStatus).Pop(); + CertificateImplVector certChain; + OCSPModule ocsp; + int retCode = CKM_API_SUCCESS; + int ocspStatus = CKM_API_OCSP_STATUS_INTERNAL_ERROR; + + if (!m_isNetAvailable) { + /* try again for in case of system-info error */ + setNetAvailable(); + } + + if (!m_isNetAvailable) { + retCode = CKM_API_ERROR_NOT_SUPPORTED; + } else if (!allowed) { + retCode = CKM_API_ERROR_ACCESS_DENIED; + } else if (rawChain.size() < 2) { + LogError("Certificate chain should contain at least 2 certificates"); + retCode = CKM_API_ERROR_INPUT_PARAM; + } else { + for (auto &e : rawChain) { + certChain.push_back(CertificateImpl(e, DataFormat::FORM_DER)); + + if (certChain.rbegin()->empty()) { + LogDebug("Error in parsing certificates!"); + retCode = CKM_API_ERROR_INPUT_PARAM; + break; + } + } + } + + if (retCode == CKM_API_SUCCESS) + ocspStatus = ocsp.verify(certChain); + + return MessageBuffer::Serialize(commandId, retCode, ocspStatus).Pop(); } } // namespace CKM diff --git a/src/manager/service/ocsp-logic.h b/src/manager/service/ocsp-logic.h index b700d86f..93577529 100644 --- a/src/manager/service/ocsp-logic.h +++ b/src/manager/service/ocsp-logic.h @@ -27,18 +27,19 @@ namespace CKM { class OCSPLogic { public: - OCSPLogic(); - OCSPLogic(const OCSPLogic &) = delete; - OCSPLogic(OCSPLogic &&) = delete; - OCSPLogic& operator=(const OCSPLogic &) = delete; - OCSPLogic& operator=(OCSPLogic &&) = delete; + OCSPLogic(); + OCSPLogic(const OCSPLogic &) = delete; + OCSPLogic(OCSPLogic &&) = delete; + OCSPLogic &operator=(const OCSPLogic &) = delete; + OCSPLogic &operator=(OCSPLogic &&) = delete; - RawBuffer ocspCheck(int commandId, const RawBufferVector &rawChain, bool allowed); - virtual ~OCSPLogic() {} + RawBuffer ocspCheck(int commandId, const RawBufferVector &rawChain, + bool allowed); + virtual ~OCSPLogic() {} private: - void setNetAvailable(); - bool m_isNetAvailable; + void setNetAvailable(); + bool m_isNetAvailable; }; } // namespace CKM diff --git a/src/manager/service/ocsp-service.cpp b/src/manager/service/ocsp-service.cpp index b6449d01..216d336d 100644 --- a/src/manager/service/ocsp-service.cpp +++ b/src/manager/service/ocsp-service.cpp @@ -35,63 +35,64 @@ const CKM::InterfaceID SOCKET_ID_OCSP = 0; namespace CKM { OCSPService::OCSPService() - : m_logic(new OCSPLogic()) + : m_logic(new OCSPLogic()) { } OCSPService::~OCSPService() { - delete m_logic; + delete m_logic; } void OCSPService::Start() { - Create(); + Create(); } void OCSPService::Stop() { - Join(); + Join(); } -GenericSocketService::ServiceDescriptionVector OCSPService::GetServiceDescription() +GenericSocketService::ServiceDescriptionVector +OCSPService::GetServiceDescription() { - return ServiceDescriptionVector { - {SERVICE_SOCKET_OCSP, "http://tizen.org/privilege/internet", SOCKET_ID_OCSP} - }; + return ServiceDescriptionVector { + {SERVICE_SOCKET_OCSP, "http://tizen.org/privilege/internet", SOCKET_ID_OCSP} + }; } bool OCSPService::ProcessOne( - const ConnectionID &conn, - ConnectionInfo &info, - bool allowed) + const ConnectionID &conn, + ConnectionInfo &info, + bool allowed) { - LogDebug("process One"); + LogDebug("process One"); - Try { - if (!info.buffer.Ready()) - return false; + try { + if (!info.buffer.Ready()) + return false; - auto &buffer = info.buffer; + auto &buffer = info.buffer; - int commandId = 0; - RawBufferVector chainVector; - buffer.Deserialize(commandId, chainVector); + int commandId = 0; + RawBufferVector chainVector; + buffer.Deserialize(commandId, chainVector); - RawBuffer response = m_logic->ocspCheck(commandId, chainVector, allowed); - m_serviceManager->Write(conn, response); + RawBuffer response = m_logic->ocspCheck(commandId, chainVector, allowed); + m_serviceManager->Write(conn, response); - return true; - } Catch(MessageBuffer::Exception::Base) { - LogError("Broken protocol. Closing socket."); - } catch (const std::string &e) { - LogError("String exception(" << e << "). Closing socket"); - } catch (...) { - LogError("Unknown exception. Closing socket."); - } + return true; + } catch (const MessageBuffer::Exception::Base &e) { + LogError("Broken protocol. Closing socket."); + } catch (const std::string &e) { + LogError("String exception(" << e << "). Closing socket"); + } catch (...) { + LogError("Unknown exception. Closing socket."); + } - m_serviceManager->Close(conn); - return false; + m_serviceManager->Close(conn); + return false; } } // namespace CKM diff --git a/src/manager/service/ocsp-service.h b/src/manager/service/ocsp-service.h index 725d0e49..1fbbd780 100644 --- a/src/manager/service/ocsp-service.h +++ b/src/manager/service/ocsp-service.h @@ -30,26 +30,26 @@ class OCSPLogic; class OCSPService : public CKM::ThreadService { public: - OCSPService(); - OCSPService(const OCSPService &) = delete; - OCSPService(OCSPService &&) = delete; - OCSPService& operator=(const OCSPService &) = delete; - OCSPService& operator=(OCSPService &&) = delete; + OCSPService(); + OCSPService(const OCSPService &) = delete; + OCSPService(OCSPService &&) = delete; + OCSPService &operator=(const OCSPService &) = delete; + OCSPService &operator=(OCSPService &&) = delete; - virtual void Start(); - virtual void Stop(); + virtual void Start(); + virtual void Stop(); - virtual ~OCSPService(); + virtual ~OCSPService(); - ServiceDescriptionVector GetServiceDescription(); + ServiceDescriptionVector GetServiceDescription(); private: - bool ProcessOne( - const ConnectionID &conn, - ConnectionInfo &info, - bool allowed); + bool ProcessOne( + const ConnectionID &conn, + ConnectionInfo &info, + bool allowed); - OCSPLogic *m_logic; + OCSPLogic *m_logic; }; } // namespace CKM diff --git a/src/manager/service/ocsp.cpp b/src/manager/service/ocsp.cpp index aa5fa968..25219fc4 100644 --- a/src/manager/service/ocsp.cpp +++ b/src/manager/service/ocsp.cpp @@ -39,350 +39,371 @@ namespace CKM { namespace { -typedef std::unique_ptr<BIO, std::function<void(BIO*)>> BioUniquePtr; +typedef std::unique_ptr<BIO, std::function<void(BIO *)>> BioUniquePtr; -void BIO_write_and_free(BIO* bio) +void BIO_write_and_free(BIO *bio) { - if (!bio) - return; + if (!bio) + return; - std::vector<char> message(1024); - int size = BIO_read(bio, message.data(), message.size()); - if (size > 0) { - message.resize(size); - LogError("OCSP error description:" << std::string(message.begin(), message.end())); - } + std::vector<char> message(1024); + int size = BIO_read(bio, message.data(), message.size()); - BIO_free_all(bio); + if (size > 0) { + message.resize(size); + LogError("OCSP error description:" << std::string(message.begin(), + message.end())); + } + + BIO_free_all(bio); } } // namespace anonymous OCSPModule::OCSPModule() { - // Do nothing. + // Do nothing. } OCSPModule::~OCSPModule() { - // Do nothing. + // Do nothing. } int OCSPModule::verify(const CertificateImplVector &certificateChain) { - bool unsupported = false; // ocsp is unsupported in certificate in chain (except root CA) - - // create trusted store - X509_STACK_PTR trustedCerts = create_x509_stack(); - - // skip first 2 certificates - for (auto it = certificateChain.cbegin() + 2; it < certificateChain.cend(); it++) { - if (it->empty()) { - LogError("Error. Broken certificate chain."); - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - sk_X509_push(trustedCerts.get(), it->getX509()); - } - - for (int i = 0; i < static_cast<int>(certificateChain.size()) - 1; i++) {// except root certificate - if (certificateChain[i].empty() || certificateChain[i+1].empty()) { - LogError("Error. Broken certificate chain."); - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - X509 *cert = certificateChain[i].getX509(); - X509 *issuer = certificateChain[i+1].getX509(); - - std::string url = certificateChain[i].getOCSPURL(); - - if (url.empty()) { - LogError("Certificate in certchain[" << i << "] does not provide OCSP extension."); - unsupported = true; - continue; - } - - int result = ocsp_verify(cert, issuer, trustedCerts.get(), url); - // remove first element from trustedCerts store - sk_X509_delete(trustedCerts.get(), 0); - - if (result != CKM_API_OCSP_STATUS_GOOD) { - LogError("Fail to OCSP certification check. Errorcode=[" << result << - "], on certChain[" << i << "]"); - return result; - } - } - - if (unsupported) - return CKM_API_OCSP_STATUS_UNSUPPORTED; - - return CKM_API_OCSP_STATUS_GOOD; + bool unsupported = + false; // ocsp is unsupported in certificate in chain (except root CA) + + // create trusted store + X509_STACK_PTR trustedCerts = create_x509_stack(); + + // skip first 2 certificates + for (auto it = certificateChain.cbegin() + 2; it < certificateChain.cend(); + it++) { + if (it->empty()) { + LogError("Error. Broken certificate chain."); + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + sk_X509_push(trustedCerts.get(), it->getX509()); + } + + for (int i = 0; i < static_cast<int>(certificateChain.size()) - 1; + i++) {// except root certificate + if (certificateChain[i].empty() || certificateChain[i + 1].empty()) { + LogError("Error. Broken certificate chain."); + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + X509 *cert = certificateChain[i].getX509(); + X509 *issuer = certificateChain[i + 1].getX509(); + + std::string url = certificateChain[i].getOCSPURL(); + + if (url.empty()) { + LogError("Certificate in certchain[" << i << + "] does not provide OCSP extension."); + unsupported = true; + continue; + } + + int result = ocsp_verify(cert, issuer, trustedCerts.get(), url); + // remove first element from trustedCerts store + sk_X509_delete(trustedCerts.get(), 0); + + if (result != CKM_API_OCSP_STATUS_GOOD) { + LogError("Fail to OCSP certification check. Errorcode=[" << result << + "], on certChain[" << i << "]"); + return result; + } + } + + if (unsupported) + return CKM_API_OCSP_STATUS_UNSUPPORTED; + + return CKM_API_OCSP_STATUS_GOOD; } -int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *trustedCerts, const std::string &constUrl) +int OCSPModule::ocsp_verify(X509 *cert, X509 *issuer, + STACK_OF(X509) *trustedCerts, const std::string &constUrl) { - OCSP_REQUEST *req = NULL; - OCSP_RESPONSE *resp = NULL; - OCSP_BASICRESP *bs = NULL; - OCSP_CERTID *certid = NULL; - BIO *cbio = NULL; - SSL_CTX *use_ssl_ctx = NULL; - char *host = NULL, *port = NULL, *path = NULL; - ASN1_GENERALIZEDTIME *rev = NULL; - ASN1_GENERALIZEDTIME *thisupd = NULL; - ASN1_GENERALIZEDTIME *nextupd = NULL; - int use_ssl = 0; - int ocspStatus = -1; - int i = 0; - long nsec = MAX_VALIDITY_PERIOD, maxage = -1; - char subj_buf[256]; - int reason = 0; - // const char *reason_str = NULL;0 - X509_STORE *trustedStore = NULL; - BioUniquePtr bioLogger(BIO_new(BIO_s_mem()), BIO_write_and_free); - - std::vector<char> url(constUrl.begin(), constUrl.end()); - url.push_back(0); - - if (!OCSP_parse_url(url.data(), &host, &port, &path, &use_ssl)) - /* report error */ - return CKM_API_OCSP_STATUS_INVALID_URL; - - LogDebug("Host: " << host); - LogDebug("Port: " << port); - LogDebug("Path: " << path); - LogDebug("Use_ssl: " << use_ssl); - - cbio = BIO_new_connect(host); - if (cbio == NULL) { - /*BIO_printf(bio_err, "Error creating connect BIO\n");*/ - /* report error */ - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - if (port != NULL) - BIO_set_conn_port(cbio, port); - - if (use_ssl == 1) { - BIO *sbio = NULL; - use_ssl_ctx = SSL_CTX_new(SSLv23_client_method()); - if (use_ssl_ctx == NULL) { - /* report error */ - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - SSL_CTX_set_mode(use_ssl_ctx, SSL_MODE_AUTO_RETRY); - sbio = BIO_new_ssl(use_ssl_ctx, 1); - if (sbio == NULL) { - /* report error */ - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - cbio = BIO_push(sbio, cbio); - if (cbio == NULL) { - /* report error */ - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - } - - if (BIO_do_connect(cbio) <= 0) { - LogDebug("Error in BIO_do_connect."); - ERR_print_errors(bioLogger.get()); - /* report error */ - - /* free stuff */ - if (host != NULL) - OPENSSL_free(host); - - if (port != NULL) - OPENSSL_free(port); - - if (path != NULL) - OPENSSL_free(path); - - host = port = path = NULL; - - if (use_ssl && use_ssl_ctx) - SSL_CTX_free(use_ssl_ctx); - - use_ssl_ctx = NULL; - - if (cbio != NULL) - BIO_free_all(cbio); - - cbio = NULL; - - return CKM_API_OCSP_STATUS_NET_ERROR; - } - - req = OCSP_REQUEST_new(); - if (req == NULL) { - LogDebug("Error in OCPS_REQUEST_new"); - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - certid = OCSP_cert_to_id(NULL, cert, issuer); - if (certid == NULL) { - LogDebug("Error in OCSP_cert_to_id"); - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - if (OCSP_request_add0_id(req, certid) == NULL) { - LogDebug("Error in OCSP_request_add0_id"); - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } - - resp = OCSP_sendreq_bio(cbio, path, req); - /* free some stuff we no longer need */ - if (host != NULL) - OPENSSL_free(host); - - if (port != NULL) - OPENSSL_free(port); - - if (path != NULL) - OPENSSL_free(path); - - host = port = path = NULL; - - if (use_ssl && use_ssl_ctx) - SSL_CTX_free(use_ssl_ctx); - - use_ssl_ctx = NULL; - - if (cbio != NULL) - BIO_free_all(cbio); - - cbio = NULL; - - if (!resp) { - /*BIO_printf(bio_err, "Error querying OCSP responsder\n");*/ - /* report error */ - /* free stuff */ - OCSP_REQUEST_free(req); - return CKM_API_OCSP_STATUS_NET_ERROR; - } - - i = OCSP_response_status(resp); - - if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - /* report error */ - ERR_print_errors(bioLogger.get()); - /* free stuff */ - OCSP_REQUEST_free(req); - OCSP_RESPONSE_free(resp); - return CKM_API_OCSP_STATUS_REMOTE_ERROR; - } - - bs = OCSP_response_get1_basic(resp); - if (!bs) { - /* report error */ - ERR_print_errors(bioLogger.get()); - /* free stuff */ - OCSP_REQUEST_free(req); - OCSP_RESPONSE_free(resp); - - LogDebug("Error in OCSP_response_get1_basic"); - return CKM_API_OCSP_STATUS_INVALID_RESPONSE; - } - - if (trustedCerts != NULL) { - trustedStore = X509_STORE_new(); - - for (int tmpIdx = 0; tmpIdx < sk_X509_num(trustedCerts); tmpIdx++) - X509_STORE_add_cert(trustedStore, sk_X509_value(trustedCerts, tmpIdx)); - - X509_STORE_add_cert(trustedStore, issuer); - } - - int response = OCSP_basic_verify(bs, NULL, trustedStore, 0); - if (response <= 0) { - OCSP_REQUEST_free(req); - OCSP_RESPONSE_free(resp); - OCSP_BASICRESP_free(bs); - X509_STORE_free(trustedStore); - ERR_print_errors(bioLogger.get()); - return CKM_API_OCSP_STATUS_INVALID_RESPONSE; - } - - if ((i = OCSP_check_nonce(req, bs)) <= 0) { - if (i == -1) { - ERR_print_errors(bioLogger.get()); - } else { - /* report error */ - ERR_print_errors(bioLogger.get()); - /* free stuff */ - OCSP_REQUEST_free(req); - OCSP_RESPONSE_free(resp); - OCSP_BASICRESP_free(bs); - X509_STORE_free(trustedStore); - LogDebug("Error in OCSP_check_nonce"); - return CKM_API_OCSP_STATUS_INVALID_RESPONSE; - } - } - - (void)X509_NAME_oneline(X509_get_subject_name(cert), subj_buf, 255); - if (!OCSP_resp_find_status(bs, certid, &ocspStatus, &reason, - &rev, &thisupd, &nextupd)) { - /* report error */ - ERR_print_errors(bioLogger.get()); - /* free stuff */ - OCSP_RESPONSE_free(resp); - OCSP_REQUEST_free(req); - OCSP_BASICRESP_free(bs); - X509_STORE_free(trustedStore); - - LogDebug("Error in OCSP_resp_find_status"); - return CKM_API_OCSP_STATUS_INVALID_RESPONSE; - } - - - /* Check validity: if invalid write to output BIO so we - * know which response this refers to. - */ - if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) { - /* report error */ - ERR_print_errors(bioLogger.get()); - /* free stuff */ - OCSP_REQUEST_free(req); - OCSP_RESPONSE_free(resp); - OCSP_BASICRESP_free(bs); - X509_STORE_free(trustedStore); - - LogDebug("Error in OCSP_check_validity"); - return CKM_API_OCSP_STATUS_INVALID_RESPONSE; - } - - if (req != NULL) { - OCSP_REQUEST_free(req); - req = NULL; - } - - if (resp != NULL) { - OCSP_RESPONSE_free(resp); - resp = NULL; - } - - if (bs != NULL) { - OCSP_BASICRESP_free(bs); - bs = NULL; - } - - if (trustedStore != NULL) { - X509_STORE_free(trustedStore); - trustedStore = NULL; - } - - switch (ocspStatus) { - case V_OCSP_CERTSTATUS_GOOD: - return CKM_API_OCSP_STATUS_GOOD; - case V_OCSP_CERTSTATUS_REVOKED: - return CKM_API_OCSP_STATUS_REVOKED; - case V_OCSP_CERTSTATUS_UNKNOWN: - return CKM_API_OCSP_STATUS_UNKNOWN; - default: - LogError("Internal openssl error: Certificate status have value is out of bound."); - return CKM_API_OCSP_STATUS_INTERNAL_ERROR; - } + OCSP_REQUEST *req = NULL; + OCSP_RESPONSE *resp = NULL; + OCSP_BASICRESP *bs = NULL; + OCSP_CERTID *certid = NULL; + BIO *cbio = NULL; + SSL_CTX *use_ssl_ctx = NULL; + char *host = NULL, *port = NULL, *path = NULL; + ASN1_GENERALIZEDTIME *rev = NULL; + ASN1_GENERALIZEDTIME *thisupd = NULL; + ASN1_GENERALIZEDTIME *nextupd = NULL; + int use_ssl = 0; + int ocspStatus = -1; + int i = 0; + long nsec = MAX_VALIDITY_PERIOD, maxage = -1; + char subj_buf[256]; + int reason = 0; + // const char *reason_str = NULL;0 + X509_STORE *trustedStore = NULL; + BioUniquePtr bioLogger(BIO_new(BIO_s_mem()), BIO_write_and_free); + + std::vector<char> url(constUrl.begin(), constUrl.end()); + url.push_back(0); + + if (!OCSP_parse_url(url.data(), &host, &port, &path, &use_ssl)) + /* report error */ + return CKM_API_OCSP_STATUS_INVALID_URL; + + LogDebug("Host: " << host); + LogDebug("Port: " << port); + LogDebug("Path: " << path); + LogDebug("Use_ssl: " << use_ssl); + + cbio = BIO_new_connect(host); + + if (cbio == NULL) { + /*BIO_printf(bio_err, "Error creating connect BIO\n");*/ + /* report error */ + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + if (port != NULL) + BIO_set_conn_port(cbio, port); + + if (use_ssl == 1) { + BIO *sbio = NULL; + use_ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + + if (use_ssl_ctx == NULL) { + /* report error */ + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + SSL_CTX_set_mode(use_ssl_ctx, SSL_MODE_AUTO_RETRY); + sbio = BIO_new_ssl(use_ssl_ctx, 1); + + if (sbio == NULL) { + /* report error */ + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + cbio = BIO_push(sbio, cbio); + + if (cbio == NULL) { + /* report error */ + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + } + + if (BIO_do_connect(cbio) <= 0) { + LogDebug("Error in BIO_do_connect."); + ERR_print_errors(bioLogger.get()); + /* report error */ + + /* free stuff */ + if (host != NULL) + OPENSSL_free(host); + + if (port != NULL) + OPENSSL_free(port); + + if (path != NULL) + OPENSSL_free(path); + + host = port = path = NULL; + + if (use_ssl && use_ssl_ctx) + SSL_CTX_free(use_ssl_ctx); + + use_ssl_ctx = NULL; + + if (cbio != NULL) + BIO_free_all(cbio); + + cbio = NULL; + + return CKM_API_OCSP_STATUS_NET_ERROR; + } + + req = OCSP_REQUEST_new(); + + if (req == NULL) { + LogDebug("Error in OCPS_REQUEST_new"); + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + certid = OCSP_cert_to_id(NULL, cert, issuer); + + if (certid == NULL) { + LogDebug("Error in OCSP_cert_to_id"); + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + if (OCSP_request_add0_id(req, certid) == NULL) { + LogDebug("Error in OCSP_request_add0_id"); + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } + + resp = OCSP_sendreq_bio(cbio, path, req); + + /* free some stuff we no longer need */ + if (host != NULL) + OPENSSL_free(host); + + if (port != NULL) + OPENSSL_free(port); + + if (path != NULL) + OPENSSL_free(path); + + host = port = path = NULL; + + if (use_ssl && use_ssl_ctx) + SSL_CTX_free(use_ssl_ctx); + + use_ssl_ctx = NULL; + + if (cbio != NULL) + BIO_free_all(cbio); + + cbio = NULL; + + if (!resp) { + /*BIO_printf(bio_err, "Error querying OCSP responsder\n");*/ + /* report error */ + /* free stuff */ + OCSP_REQUEST_free(req); + return CKM_API_OCSP_STATUS_NET_ERROR; + } + + i = OCSP_response_status(resp); + + if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + /* report error */ + ERR_print_errors(bioLogger.get()); + /* free stuff */ + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(resp); + return CKM_API_OCSP_STATUS_REMOTE_ERROR; + } + + bs = OCSP_response_get1_basic(resp); + + if (!bs) { + /* report error */ + ERR_print_errors(bioLogger.get()); + /* free stuff */ + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(resp); + + LogDebug("Error in OCSP_response_get1_basic"); + return CKM_API_OCSP_STATUS_INVALID_RESPONSE; + } + + if (trustedCerts != NULL) { + trustedStore = X509_STORE_new(); + + for (int tmpIdx = 0; tmpIdx < sk_X509_num(trustedCerts); tmpIdx++) + X509_STORE_add_cert(trustedStore, sk_X509_value(trustedCerts, tmpIdx)); + + X509_STORE_add_cert(trustedStore, issuer); + } + + int response = OCSP_basic_verify(bs, NULL, trustedStore, 0); + + if (response <= 0) { + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(resp); + OCSP_BASICRESP_free(bs); + X509_STORE_free(trustedStore); + ERR_print_errors(bioLogger.get()); + return CKM_API_OCSP_STATUS_INVALID_RESPONSE; + } + + if ((i = OCSP_check_nonce(req, bs)) <= 0) { + if (i == -1) { + ERR_print_errors(bioLogger.get()); + } else { + /* report error */ + ERR_print_errors(bioLogger.get()); + /* free stuff */ + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(resp); + OCSP_BASICRESP_free(bs); + X509_STORE_free(trustedStore); + LogDebug("Error in OCSP_check_nonce"); + return CKM_API_OCSP_STATUS_INVALID_RESPONSE; + } + } + + (void)X509_NAME_oneline(X509_get_subject_name(cert), subj_buf, 255); + + if (!OCSP_resp_find_status(bs, certid, &ocspStatus, &reason, + &rev, &thisupd, &nextupd)) { + /* report error */ + ERR_print_errors(bioLogger.get()); + /* free stuff */ + OCSP_RESPONSE_free(resp); + OCSP_REQUEST_free(req); + OCSP_BASICRESP_free(bs); + X509_STORE_free(trustedStore); + + LogDebug("Error in OCSP_resp_find_status"); + return CKM_API_OCSP_STATUS_INVALID_RESPONSE; + } + + + /* Check validity: if invalid write to output BIO so we + * know which response this refers to. + */ + if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) { + /* report error */ + ERR_print_errors(bioLogger.get()); + /* free stuff */ + OCSP_REQUEST_free(req); + OCSP_RESPONSE_free(resp); + OCSP_BASICRESP_free(bs); + X509_STORE_free(trustedStore); + + LogDebug("Error in OCSP_check_validity"); + return CKM_API_OCSP_STATUS_INVALID_RESPONSE; + } + + if (req != NULL) { + OCSP_REQUEST_free(req); + req = NULL; + } + + if (resp != NULL) { + OCSP_RESPONSE_free(resp); + resp = NULL; + } + + if (bs != NULL) { + OCSP_BASICRESP_free(bs); + bs = NULL; + } + + if (trustedStore != NULL) { + X509_STORE_free(trustedStore); + trustedStore = NULL; + } + + switch (ocspStatus) { + case V_OCSP_CERTSTATUS_GOOD: + return CKM_API_OCSP_STATUS_GOOD; + + case V_OCSP_CERTSTATUS_REVOKED: + return CKM_API_OCSP_STATUS_REVOKED; + + case V_OCSP_CERTSTATUS_UNKNOWN: + return CKM_API_OCSP_STATUS_UNKNOWN; + + default: + LogError("Internal openssl error: Certificate status have value is out of bound."); + return CKM_API_OCSP_STATUS_INTERNAL_ERROR; + } } } // namespace CKM diff --git a/src/manager/service/ocsp.h b/src/manager/service/ocsp.h index a1d7afea..e04b28c6 100644 --- a/src/manager/service/ocsp.h +++ b/src/manager/service/ocsp.h @@ -30,15 +30,16 @@ namespace CKM { class OCSPModule { public: - OCSPModule(); - virtual ~OCSPModule(); + OCSPModule(); + virtual ~OCSPModule(); - // all error code from project will be defined in public client api - // OK, UNKNOWN, REVOKED, NO_NETWORK, TIMEOUT - int verify(const CertificateImplVector &certificateChain); + // all error code from project will be defined in public client api + // OK, UNKNOWN, REVOKED, NO_NETWORK, TIMEOUT + int verify(const CertificateImplVector &certificateChain); private: - int ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *trustedCerts, const std::string &url); + int ocsp_verify(X509 *cert, X509 *issuer, STACK_OF(X509) *trustedCerts, + const std::string &url); }; } // namespace CKM diff --git a/src/manager/service/permission.h b/src/manager/service/permission.h index c2846999..b0218ba1 100644 --- a/src/manager/service/permission.h +++ b/src/manager/service/permission.h @@ -27,21 +27,22 @@ namespace CKM { typedef boost::optional<PermissionMask> PermissionMaskOptional; struct PermissionForLabel { - Label accessorLabel; // who is accessing the item - PermissionMask permissionMask; + Label accessorLabel; // who is accessing the item + PermissionMask permissionMask; - PermissionForLabel(const Label & accessor, const PermissionMaskOptional mask) - { - accessorLabel = accessor; - if (mask) - permissionMask = *mask; - else - permissionMask = Permission::NONE; - } + PermissionForLabel(const Label &accessor, const PermissionMaskOptional mask) + { + accessorLabel = accessor; - int operator&(const Permission &bit) const - { - return permissionMask & bit; - } + if (mask) + permissionMask = *mask; + else + permissionMask = Permission::NONE; + } + + int operator&(const Permission &bit) const + { + return permissionMask & bit; + } }; } // namespace CKM diff --git a/src/manager/service/token.h b/src/manager/service/token.h index 0173708a..02022b30 100644 --- a/src/manager/service/token.h +++ b/src/manager/service/token.h @@ -29,22 +29,18 @@ namespace CKM { struct Token { - Token() : - backendId(CryptoBackend::None) - { - } - - Token(CryptoBackend pBackendId, DataType pDataType, const RawBuffer &pData) : - backendId(pBackendId), - dataType(pDataType), - data(pData) - { - } - CryptoBackend backendId; - DataType dataType; - RawBuffer data; + Token() : backendId(CryptoBackend::None) {} + + Token(CryptoBackend pBackendId, DataType pDataType, const RawBuffer &pData) : + backendId(pBackendId), + dataType(pDataType), + data(pData) {} + + CryptoBackend backendId; + DataType dataType; + RawBuffer data; }; -typedef std::pair<Token, Token> TokenPair; +using TokenPair = std::pair<Token, Token>; } // namespace CKM diff --git a/src/manager/sqlcipher/sqlcipher.h b/src/manager/sqlcipher/sqlcipher.h index d13782d6..9d9954cd 100644 --- a/src/manager/sqlcipher/sqlcipher.h +++ b/src/manager/sqlcipher/sqlcipher.h @@ -161,8 +161,8 @@ extern "C" { ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlcipher3_libversion_number() function returns an integer equal to -** [SQLCIPHER_VERSION_NUMBER]. ^The sqlcipher3_sourceid() function returns -** a pointer to a string constant whose value is the same as the +** [SQLCIPHER_VERSION_NUMBER]. ^The sqlcipher3_sourceid() function returns +** a pointer to a string constant whose value is the same as the ** [SQLCIPHER_SOURCE_ID] C preprocessor macro. ** ** See also: [sqlcipher_version()] and [sqlcipher_source_id()]. @@ -175,20 +175,20 @@ SQLCIPHER_API int sqlcipher3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** -** ^The sqlcipher3_compileoption_used() function returns 0 or 1 -** indicating whether the specified option was defined at -** compile time. ^The SQLCIPHER_ prefix may be omitted from the -** option name passed to sqlcipher3_compileoption_used(). +** ^The sqlcipher3_compileoption_used() function returns 0 or 1 +** indicating whether the specified option was defined at +** compile time. ^The SQLCIPHER_ prefix may be omitted from the +** option name passed to sqlcipher3_compileoption_used(). ** ** ^The sqlcipher3_compileoption_get() function allows iterating ** over the list of options that were defined at compile time by ** returning the N-th compile time option string. ^If N is out of range, -** sqlcipher3_compileoption_get() returns a NULL pointer. ^The SQLCIPHER_ -** prefix is omitted from any strings returned by +** sqlcipher3_compileoption_get() returns a NULL pointer. ^The SQLCIPHER_ +** prefix is omitted from any strings returned by ** sqlcipher3_compileoption_get(). ** ** ^Support for the diagnostic functions sqlcipher3_compileoption_used() -** and sqlcipher3_compileoption_get() may be omitted by specifying the +** and sqlcipher3_compileoption_get() may be omitted by specifying the ** [SQLCIPHER_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlcipher_compileoption_used()] and @@ -209,7 +209,7 @@ SQLCIPHER_API const char *sqlcipher3_compileoption_get(int N); ** SQLite can be compiled with or without mutexes. When ** the [SQLCIPHER_THREADSAFE] C preprocessor macro is 1 or 2, mutexes ** are enabled and SQLite is threadsafe. When the -** [SQLCIPHER_THREADSAFE] macro is 0, +** [SQLCIPHER_THREADSAFE] macro is 0, ** the mutexes are omitted. Without the mutexes, it is not safe ** to use SQLite concurrently from more than one thread. ** @@ -265,18 +265,18 @@ typedef struct sqlcipher3 sqlcipher3; ** ** ^The sqlcipher3_int64 and sqlcipher_int64 types can store integer values ** between -9223372036854775808 and +9223372036854775807 inclusive. ^The -** sqlcipher3_uint64 and sqlcipher_uint64 types can store integer values +** sqlcipher3_uint64 and sqlcipher_uint64 types can store integer values ** between 0 and +18446744073709551615 inclusive. */ #ifdef SQLCIPHER_INT64_TYPE - typedef SQLCIPHER_INT64_TYPE sqlcipher_int64; - typedef unsigned SQLCIPHER_INT64_TYPE sqlcipher_uint64; +typedef SQLCIPHER_INT64_TYPE sqlcipher_int64; +typedef unsigned SQLCIPHER_INT64_TYPE sqlcipher_uint64; #elif defined(_MSC_VER) || defined(__BORLANDC__) - typedef __int64 sqlcipher_int64; - typedef unsigned __int64 sqlcipher_uint64; +typedef __int64 sqlcipher_int64; +typedef unsigned __int64 sqlcipher_uint64; #else - typedef long long int sqlcipher_int64; - typedef unsigned long long int sqlcipher_uint64; +typedef long long int sqlcipher_int64; +typedef unsigned long long int sqlcipher_uint64; #endif typedef sqlcipher_int64 sqlcipher3_int64; typedef sqlcipher_uint64 sqlcipher3_uint64; @@ -310,7 +310,7 @@ typedef sqlcipher_uint64 sqlcipher3_uint64; ** pointer or an [sqlcipher3] object pointer obtained ** from [sqlcipher3_open()], [sqlcipher3_open16()], or ** [sqlcipher3_open_v2()], and not previously closed. -** ^Calling sqlcipher3_close() with a NULL pointer argument is a +** ^Calling sqlcipher3_close() with a NULL pointer argument is a ** harmless no-op. */ SQLCIPHER_API int sqlcipher3_close(sqlcipher3 *); @@ -320,7 +320,7 @@ SQLCIPHER_API int sqlcipher3_close(sqlcipher3 *); ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ -typedef int (*sqlcipher3_callback)(void*,int,char**, char**); +typedef int (*sqlcipher3_callback)(void *, int, char **, char **); /* ** CAPI3REF: One-Step Query Execution Interface @@ -328,7 +328,7 @@ typedef int (*sqlcipher3_callback)(void*,int,char**, char**); ** The sqlcipher3_exec() interface is a convenience wrapper around ** [sqlcipher3_prepare_v2()], [sqlcipher3_step()], and [sqlcipher3_finalize()], ** that allows an application to run multiple statements of SQL -** without having to use a lot of C code. +** without having to use a lot of C code. ** ** ^The sqlcipher3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separate SQL statements passed into its 2nd argument, @@ -368,7 +368,7 @@ typedef int (*sqlcipher3_callback)(void*,int,char**, char**); ** from [sqlcipher3_column_name()]. ** ** ^If the 2nd parameter to sqlcipher3_exec() is a NULL pointer, a pointer -** to an empty string, or a pointer that contains only whitespace and/or +** to an empty string, or a pointer that contains only whitespace and/or ** SQL comments, then no SQL statements are evaluated and the database ** is not changed. ** @@ -384,11 +384,11 @@ typedef int (*sqlcipher3_callback)(void*,int,char**, char**); ** </ul> */ SQLCIPHER_API int sqlcipher3_exec( - sqlcipher3*, /* An open database */ - const char *sql, /* SQL to be evaluated */ - int (*callback)(void*,int,char**,char**), /* Callback function */ - void *, /* 1st argument to callback */ - char **errmsg /* Error msg written here */ + sqlcipher3 *, /* An open database */ + const char *sql, /* SQL to be evaluated */ + int (*callback)(void *, int, char **, char **), /* Callback function */ + void *, /* 1st argument to callback */ + char **errmsg /* Error msg written here */ ); /* @@ -596,7 +596,7 @@ SQLCIPHER_API int sqlcipher3_exec( /* ** CAPI3REF: OS Interface Open File Handle ** -** An [sqlcipher3_file] object represents an open file in the +** An [sqlcipher3_file] object represents an open file in the ** [sqlcipher3_vfs | OS interface layer]. Individual OS interface ** implementations will ** want to subclass this object by appending additional fields @@ -606,7 +606,7 @@ SQLCIPHER_API int sqlcipher3_exec( */ typedef struct sqlcipher3_file sqlcipher3_file; struct sqlcipher3_file { - const struct sqlcipher3_io_methods *pMethods; /* Methods for an open file */ + const struct sqlcipher3_io_methods *pMethods; /* Methods for an open file */ }; /* @@ -618,7 +618,7 @@ struct sqlcipher3_file { ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlcipher3_file] object. ** -** If the [sqlcipher3_vfs.xOpen] method sets the sqlcipher3_file.pMethods element +** If the [sqlcipher3_vfs.xOpen] method sets the sqlcipher3_file.pMethods element ** to a non-NULL pointer, then the sqlcipher3_io_methods.xClose method ** may be invoked even if the [sqlcipher3_vfs.xOpen] reported that it failed. The ** only way to prevent a call to xClose following a failed [sqlcipher3_vfs.xOpen] @@ -701,26 +701,27 @@ struct sqlcipher3_file { */ typedef struct sqlcipher3_io_methods sqlcipher3_io_methods; struct sqlcipher3_io_methods { - int iVersion; - int (*xClose)(sqlcipher3_file*); - int (*xRead)(sqlcipher3_file*, void*, int iAmt, sqlcipher3_int64 iOfst); - int (*xWrite)(sqlcipher3_file*, const void*, int iAmt, sqlcipher3_int64 iOfst); - int (*xTruncate)(sqlcipher3_file*, sqlcipher3_int64 size); - int (*xSync)(sqlcipher3_file*, int flags); - int (*xFileSize)(sqlcipher3_file*, sqlcipher3_int64 *pSize); - int (*xLock)(sqlcipher3_file*, int); - int (*xUnlock)(sqlcipher3_file*, int); - int (*xCheckReservedLock)(sqlcipher3_file*, int *pResOut); - int (*xFileControl)(sqlcipher3_file*, int op, void *pArg); - int (*xSectorSize)(sqlcipher3_file*); - int (*xDeviceCharacteristics)(sqlcipher3_file*); - /* Methods above are valid for version 1 */ - int (*xShmMap)(sqlcipher3_file*, int iPg, int pgsz, int, void volatile**); - int (*xShmLock)(sqlcipher3_file*, int offset, int n, int flags); - void (*xShmBarrier)(sqlcipher3_file*); - int (*xShmUnmap)(sqlcipher3_file*, int deleteFlag); - /* Methods above are valid for version 2 */ - /* Additional methods may be added in future releases */ + int iVersion; + int (*xClose)(sqlcipher3_file *); + int (*xRead)(sqlcipher3_file *, void *, int iAmt, sqlcipher3_int64 iOfst); + int (*xWrite)(sqlcipher3_file *, const void *, int iAmt, + sqlcipher3_int64 iOfst); + int (*xTruncate)(sqlcipher3_file *, sqlcipher3_int64 size); + int (*xSync)(sqlcipher3_file *, int flags); + int (*xFileSize)(sqlcipher3_file *, sqlcipher3_int64 *pSize); + int (*xLock)(sqlcipher3_file *, int); + int (*xUnlock)(sqlcipher3_file *, int); + int (*xCheckReservedLock)(sqlcipher3_file *, int *pResOut); + int (*xFileControl)(sqlcipher3_file *, int op, void *pArg); + int (*xSectorSize)(sqlcipher3_file *); + int (*xDeviceCharacteristics)(sqlcipher3_file *); + /* Methods above are valid for version 1 */ + int (*xShmMap)(sqlcipher3_file *, int iPg, int pgsz, int, void volatile **); + int (*xShmLock)(sqlcipher3_file *, int offset, int n, int flags); + void (*xShmBarrier)(sqlcipher3_file *); + int (*xShmUnmap)(sqlcipher3_file *, int deleteFlag); + /* Methods above are valid for version 2 */ + /* Additional methods may be added in future releases */ }; /* @@ -747,7 +748,7 @@ struct sqlcipher3_io_methods { ** ** The [SQLCIPHER_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified -** by the user. The fourth argument to [sqlcipher3_file_control()] should +** by the user. The fourth argument to [sqlcipher3_file_control()] should ** point to an integer (type int) containing the new chunk-size to use ** for the nominated database. Allocating database file space in large ** chunks (say 1MB at a time), may reduce file-system fragmentation and @@ -762,11 +763,11 @@ struct sqlcipher3_io_methods { ** SQLite and sent to all VFSes in place of a call to the xSync method ** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** Some specialized VFSes need this signal in order to operate correctly -** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most +** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** VFSes do not need this signal and should silently ignore this opcode. ** Applications should not call [sqlcipher3_file_control()] with this ** opcode as doing so may disrupt the operation of the specialized VFSes -** that do require it. +** that do require it. ** ** ^The [SQLCIPHER_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the @@ -800,7 +801,7 @@ struct sqlcipher3_io_methods { ** ** ^The [SQLCIPHER_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some -** reason, the entire database file will be overwritten by the current +** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. */ #define SQLCIPHER_FCNTL_LOCKSTATE 1 @@ -875,14 +876,14 @@ typedef struct sqlcipher3_mutex sqlcipher3_mutex; ** the [sqlcipher3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter to xOpen is a NULL pointer then xOpen -** must invent its own temporary name for the file. ^Whenever the +** must invent its own temporary name for the file. ^Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLCIPHER_OPEN_DELETEONCLOSE]. ** ** The flags argument to xOpen() includes all bits set in ** the flags argument to [sqlcipher3_open_v2()]. Or if [sqlcipher3_open()] ** or [sqlcipher3_open16()] is used, then flags includes at least -** [SQLCIPHER_OPEN_READWRITE] | [SQLCIPHER_OPEN_CREATE]. +** [SQLCIPHER_OPEN_READWRITE] | [SQLCIPHER_OPEN_CREATE]. ** If xOpen() opens a file read-only then it sets *pOutFlags to ** include [SQLCIPHER_OPEN_READONLY]. Other bits in *pOutFlags may be set. ** @@ -924,10 +925,10 @@ typedef struct sqlcipher3_mutex sqlcipher3_mutex; ** ^The [SQLCIPHER_OPEN_EXCLUSIVE] flag is always used in conjunction ** with the [SQLCIPHER_OPEN_CREATE] flag, which are both directly ** analogous to the O_EXCL and O_CREAT flags of the POSIX open() -** API. The SQLCIPHER_OPEN_EXCLUSIVE flag, when paired with the +** API. The SQLCIPHER_OPEN_EXCLUSIVE flag, when paired with the ** SQLCIPHER_OPEN_CREATE, is used to indicate that file should always ** be created, and that it is an error if it already exists. -** It is <i>not</i> used to indicate the file should be opened +** It is <i>not</i> used to indicate the file should be opened ** for exclusive access. ** ** ^At least szOsFile bytes of memory are allocated by SQLite @@ -965,16 +966,16 @@ typedef struct sqlcipher3_mutex sqlcipher3_mutex; ** method returns a Julian Day Number for the current date and time as ** a floating point value. ** ^The xCurrentTimeInt64() method returns, as an integer, the Julian -** Day Number multiplied by 86400000 (the number of milliseconds in -** a 24-hour day). +** Day Number multiplied by 86400000 (the number of milliseconds in +** a 24-hour day). ** ^SQLite will use the xCurrentTimeInt64() method to get the current -** date and time if that method is available (if iVersion is 2 or +** date and time if that method is available (if iVersion is 2 or ** greater and the function pointer is not NULL) and will fall back ** to xCurrentTime() if xCurrentTimeInt64() is unavailable. ** ** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces ** are not used by the SQLite core. These optional interfaces are provided -** by some VFSes to facilitate testing of the VFS code. By overriding +** by some VFSes to facilitate testing of the VFS code. By overriding ** system calls with functions under its control, a test program can ** simulate faults and error conditions that would otherwise be difficult ** or impossible to induce. The set of system calls that can be overridden @@ -987,42 +988,43 @@ typedef struct sqlcipher3_mutex sqlcipher3_mutex; typedef struct sqlcipher3_vfs sqlcipher3_vfs; typedef void (*sqlcipher3_syscall_ptr)(void); struct sqlcipher3_vfs { - int iVersion; /* Structure version number (currently 3) */ - int szOsFile; /* Size of subclassed sqlcipher3_file */ - int mxPathname; /* Maximum file pathname length */ - sqlcipher3_vfs *pNext; /* Next registered VFS */ - const char *zName; /* Name of this virtual file system */ - void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlcipher3_vfs*, const char *zName, sqlcipher3_file*, - int flags, int *pOutFlags); - int (*xDelete)(sqlcipher3_vfs*, const char *zName, int syncDir); - int (*xAccess)(sqlcipher3_vfs*, const char *zName, int flags, int *pResOut); - int (*xFullPathname)(sqlcipher3_vfs*, const char *zName, int nOut, char *zOut); - void *(*xDlOpen)(sqlcipher3_vfs*, const char *zFilename); - void (*xDlError)(sqlcipher3_vfs*, int nByte, char *zErrMsg); - void (*(*xDlSym)(sqlcipher3_vfs*,void*, const char *zSymbol))(void); - void (*xDlClose)(sqlcipher3_vfs*, void*); - int (*xRandomness)(sqlcipher3_vfs*, int nByte, char *zOut); - int (*xSleep)(sqlcipher3_vfs*, int microseconds); - int (*xCurrentTime)(sqlcipher3_vfs*, double*); - int (*xGetLastError)(sqlcipher3_vfs*, int, char *); - /* - ** The methods above are in version 1 of the sqlcipher_vfs object - ** definition. Those that follow are added in version 2 or later - */ - int (*xCurrentTimeInt64)(sqlcipher3_vfs*, sqlcipher3_int64*); - /* - ** The methods above are in versions 1 and 2 of the sqlcipher_vfs object. - ** Those below are for version 3 and greater. - */ - int (*xSetSystemCall)(sqlcipher3_vfs*, const char *zName, sqlcipher3_syscall_ptr); - sqlcipher3_syscall_ptr (*xGetSystemCall)(sqlcipher3_vfs*, const char *zName); - const char *(*xNextSystemCall)(sqlcipher3_vfs*, const char *zName); - /* - ** The methods above are in versions 1 through 3 of the sqlcipher_vfs object. - ** New fields may be appended in figure versions. The iVersion - ** value will increment whenever this happens. - */ + int iVersion; /* Structure version number (currently 3) */ + int szOsFile; /* Size of subclassed sqlcipher3_file */ + int mxPathname; /* Maximum file pathname length */ + sqlcipher3_vfs *pNext; /* Next registered VFS */ + const char *zName; /* Name of this virtual file system */ + void *pAppData; /* Pointer to application-specific data */ + int (*xOpen)(sqlcipher3_vfs *, const char *zName, sqlcipher3_file *, + int flags, int *pOutFlags); + int (*xDelete)(sqlcipher3_vfs *, const char *zName, int syncDir); + int (*xAccess)(sqlcipher3_vfs *, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlcipher3_vfs *, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlcipher3_vfs *, const char *zFilename); + void (*xDlError)(sqlcipher3_vfs *, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlcipher3_vfs *, void *, const char *zSymbol))(void); + void (*xDlClose)(sqlcipher3_vfs *, void *); + int (*xRandomness)(sqlcipher3_vfs *, int nByte, char *zOut); + int (*xSleep)(sqlcipher3_vfs *, int microseconds); + int (*xCurrentTime)(sqlcipher3_vfs *, double *); + int (*xGetLastError)(sqlcipher3_vfs *, int, char *); + /* + ** The methods above are in version 1 of the sqlcipher_vfs object + ** definition. Those that follow are added in version 2 or later + */ + int (*xCurrentTimeInt64)(sqlcipher3_vfs *, sqlcipher3_int64 *); + /* + ** The methods above are in versions 1 and 2 of the sqlcipher_vfs object. + ** Those below are for version 3 and greater. + */ + int (*xSetSystemCall)(sqlcipher3_vfs *, const char *zName, + sqlcipher3_syscall_ptr); + sqlcipher3_syscall_ptr(*xGetSystemCall)(sqlcipher3_vfs *, const char *zName); + const char *(*xNextSystemCall)(sqlcipher3_vfs *, const char *zName); + /* + ** The methods above are in versions 1 through 3 of the sqlcipher_vfs object. + ** New fields may be appended in figure versions. The iVersion + ** value will increment whenever this happens. + */ }; /* @@ -1065,7 +1067,7 @@ struct sqlcipher3_vfs { ** </ul> ** ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as -** was given no the corresponding lock. +** was given no the corresponding lock. ** ** The xShmLock method can transition between unlocked and SHARED or ** between unlocked and EXCLUSIVE. It cannot transition between SHARED @@ -1207,14 +1209,14 @@ SQLCIPHER_API int sqlcipher3_config(int, ...); ** [database connection] (specified in the first argument). ** ** The second argument to sqlcipher3_db_config(D,V,...) is the -** [SQLCIPHER_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** [SQLCIPHER_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** ** ^Calls to sqlcipher3_db_config() return SQLCIPHER_OK if and only if ** the call is considered successful. */ -SQLCIPHER_API int sqlcipher3_db_config(sqlcipher3*, int op, ...); +SQLCIPHER_API int sqlcipher3_db_config(sqlcipher3 *, int op, ...); /* ** CAPI3REF: Memory Allocation Routines @@ -1225,7 +1227,7 @@ SQLCIPHER_API int sqlcipher3_db_config(sqlcipher3*, int op, ...); ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlcipher3_config()] when the configuration option is -** [SQLCIPHER_CONFIG_MALLOC] or [SQLCIPHER_CONFIG_GETMALLOC]. +** [SQLCIPHER_CONFIG_MALLOC] or [SQLCIPHER_CONFIG_GETMALLOC]. ** By creating an instance of this object ** and passing it to [sqlcipher3_config]([SQLCIPHER_CONFIG_MALLOC]) ** during configuration, an application can specify an alternative @@ -1255,7 +1257,7 @@ SQLCIPHER_API int sqlcipher3_db_config(sqlcipher3*, int op, ...); ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. ** Every memory allocation request coming in through [sqlcipher3_malloc()] -** or [sqlcipher3_realloc()] first calls xRoundup. If xRoundup returns 0, +** or [sqlcipher3_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. (For example, @@ -1281,14 +1283,14 @@ SQLCIPHER_API int sqlcipher3_db_config(sqlcipher3*, int op, ...); */ typedef struct sqlcipher3_mem_methods sqlcipher3_mem_methods; struct sqlcipher3_mem_methods { - void *(*xMalloc)(int); /* Memory allocation function */ - void (*xFree)(void*); /* Free a prior allocation */ - void *(*xRealloc)(void*,int); /* Resize an allocation */ - int (*xSize)(void*); /* Return the size of an allocation */ - int (*xRoundup)(int); /* Round up request size to allocation size */ - int (*xInit)(void*); /* Initialize the memory allocator */ - void (*xShutdown)(void*); /* Deinitialize the memory allocator */ - void *pAppData; /* Argument to xInit() and xShutdown() */ + void *(*xMalloc)(int); /* Memory allocation function */ + void (*xFree)(void *); /* Free a prior allocation */ + void *(*xRealloc)(void *, int); /* Resize an allocation */ + int (*xSize)(void *); /* Return the size of an allocation */ + int (*xRoundup)(int); /* Round up request size to allocation size */ + int (*xInit)(void *); /* Initialize the memory allocator */ + void (*xShutdown)(void *); /* Deinitialize the memory allocator */ + void *pAppData; /* Argument to xInit() and xShutdown() */ }; /* @@ -1313,7 +1315,7 @@ struct sqlcipher3_mem_methods { ** by a single thread. ^If SQLite is compiled with ** the [SQLCIPHER_THREADSAFE | SQLCIPHER_THREADSAFE=0] compile-time option then ** it is not possible to change the [threading mode] from its default -** value of Single-thread and so [sqlcipher3_config()] will return +** value of Single-thread and so [sqlcipher3_config()] will return ** [SQLCIPHER_ERROR] if called with the SQLCIPHER_CONFIG_SINGLETHREAD ** configuration option.</dd> ** @@ -1364,9 +1366,9 @@ struct sqlcipher3_mem_methods { ** tracks memory usage, for example. </dd> ** ** [[SQLCIPHER_CONFIG_MEMSTATUS]] <dt>SQLCIPHER_CONFIG_MEMSTATUS</dt> -** <dd> ^This option takes single argument of type int, interpreted as a -** boolean, which enables or disables the collection of memory allocation -** statistics. ^(When memory allocation statistics are disabled, the +** <dd> ^This option takes single argument of type int, interpreted as a +** boolean, which enables or disables the collection of memory allocation +** statistics. ^(When memory allocation statistics are disabled, the ** following SQLite interfaces become non-operational: ** <ul> ** <li> [sqlcipher3_memory_used()] @@ -1392,12 +1394,12 @@ struct sqlcipher3_mem_methods { ** N should be set to twice the expected maximum number of threads. ** ^SQLite will never require a scratch buffer that is more than 6 ** times the database page size. ^If SQLite needs needs additional -** scratch memory beyond what is provided by this configuration option, then +** scratch memory beyond what is provided by this configuration option, then ** [sqlcipher3_malloc()] will be used to obtain the memory needed.</dd> ** ** [[SQLCIPHER_CONFIG_PAGECACHE]] <dt>SQLCIPHER_CONFIG_PAGECACHE</dt> ** <dd> ^This option specifies a static memory buffer that SQLite can use for -** the database page cache with the default page cache implementation. +** the database page cache with the default page cache implementation. ** This configuration should not be used if an application-define page ** cache implementation is loaded using the SQLCIPHER_CONFIG_PCACHE option. ** There are three arguments to this option: A pointer to 8-byte aligned @@ -1481,7 +1483,7 @@ struct sqlcipher3_mem_methods { ** ** [[SQLCIPHER_CONFIG_LOG]] <dt>SQLCIPHER_CONFIG_LOG</dt> ** <dd> ^The SQLCIPHER_CONFIG_LOG option takes two arguments: a pointer to a -** function with a call signature of void(*)(void*,int,const char*), +** function with a call signature of void(*)(void*,int,const char*), ** and a pointer to void. ^If the function pointer is not NULL, it is ** invoked by [sqlcipher3_log()] to process each logging event. ^If the ** function pointer is NULL, the [sqlcipher3_log()] interface becomes a no-op. @@ -1522,7 +1524,7 @@ struct sqlcipher3_mem_methods { #define SQLCIPHER_CONFIG_MEMSTATUS 9 /* boolean */ #define SQLCIPHER_CONFIG_MUTEX 10 /* sqlcipher3_mutex_methods* */ #define SQLCIPHER_CONFIG_GETMUTEX 11 /* sqlcipher3_mutex_methods* */ -/* previously SQLCIPHER_CONFIG_CHUNKALLOC 12 which is now unused. */ +/* previously SQLCIPHER_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLCIPHER_CONFIG_LOOKASIDE 13 /* int int */ #define SQLCIPHER_CONFIG_PCACHE 14 /* sqlcipher3_pcache_methods* */ #define SQLCIPHER_CONFIG_GETPCACHE 15 /* sqlcipher3_pcache_methods* */ @@ -1544,7 +1546,7 @@ struct sqlcipher3_mem_methods { ** ** <dl> ** <dt>SQLCIPHER_DBCONFIG_LOOKASIDE</dt> -** <dd> ^This option takes three additional arguments that determine the +** <dd> ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** ^The first argument (the third parameter to [sqlcipher3_db_config()] is a ** pointer to a memory buffer to use for lookaside memory. @@ -1562,7 +1564,7 @@ struct sqlcipher3_mem_methods { ** when the "current value" returned by ** [sqlcipher3_db_status](D,[SQLCIPHER_CONFIG_LOOKASIDE],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside -** memory is in use leaves the configuration unchanged and returns +** memory is in use leaves the configuration unchanged and returns ** [SQLCIPHER_BUSY].)^</dd> ** ** <dt>SQLCIPHER_DBCONFIG_ENABLE_FKEY</dt> @@ -1599,7 +1601,7 @@ struct sqlcipher3_mem_methods { ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ -SQLCIPHER_API int sqlcipher3_extended_result_codes(sqlcipher3*, int onoff); +SQLCIPHER_API int sqlcipher3_extended_result_codes(sqlcipher3 *, int onoff); /* ** CAPI3REF: Last Insert Rowid @@ -1621,7 +1623,7 @@ SQLCIPHER_API int sqlcipher3_extended_result_codes(sqlcipher3*, int onoff); ** ^(If an [INSERT] occurs within a trigger or within a [virtual table] ** method, then this routine will return the [rowid] of the inserted ** row as long as the trigger or virtual table method is running. -** But once the trigger or virtual table method ends, the value returned +** But once the trigger or virtual table method ends, the value returned ** by this routine reverts to what it was before the trigger or virtual ** table method began.)^ ** @@ -1648,7 +1650,7 @@ SQLCIPHER_API int sqlcipher3_extended_result_codes(sqlcipher3*, int onoff); ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ -SQLCIPHER_API sqlcipher3_int64 sqlcipher3_last_insert_rowid(sqlcipher3*); +SQLCIPHER_API sqlcipher3_int64 sqlcipher3_last_insert_rowid(sqlcipher3 *); /* ** CAPI3REF: Count The Number Of Rows Modified @@ -1672,7 +1674,7 @@ SQLCIPHER_API sqlcipher3_int64 sqlcipher3_last_insert_rowid(sqlcipher3*); ** mechanisms do not count as direct row changes.)^ ** ** A "trigger context" is a scope of execution that begins and -** ends with the script of a [CREATE TRIGGER | trigger]. +** ends with the script of a [CREATE TRIGGER | trigger]. ** Most SQL statements are ** evaluated outside of any trigger. This is the "top level" ** trigger context. If a trigger fires from the top level, a @@ -1702,7 +1704,7 @@ SQLCIPHER_API sqlcipher3_int64 sqlcipher3_last_insert_rowid(sqlcipher3*); ** while [sqlcipher3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ -SQLCIPHER_API int sqlcipher3_changes(sqlcipher3*); +SQLCIPHER_API int sqlcipher3_changes(sqlcipher3 *); /* ** CAPI3REF: Total Number Of Rows Modified @@ -1715,7 +1717,7 @@ SQLCIPHER_API int sqlcipher3_changes(sqlcipher3*); ** the count does not include changes used to implement [REPLACE] constraints, ** do rollbacks or ABORT processing, or [DROP TABLE] processing. The ** count does not include rows of views that fire an [INSTEAD OF trigger], -** though if the INSTEAD OF trigger makes changes of its own, those changes +** though if the INSTEAD OF trigger makes changes of its own, those changes ** are counted.)^ ** ^The sqlcipher3_total_changes() function counts the changes as soon as ** the statement that makes them is completed (when the statement handle @@ -1728,7 +1730,7 @@ SQLCIPHER_API int sqlcipher3_changes(sqlcipher3*); ** while [sqlcipher3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. */ -SQLCIPHER_API int sqlcipher3_total_changes(sqlcipher3*); +SQLCIPHER_API int sqlcipher3_total_changes(sqlcipher3 *); /* ** CAPI3REF: Interrupt A Long-Running Query @@ -1755,7 +1757,7 @@ SQLCIPHER_API int sqlcipher3_total_changes(sqlcipher3*); ** ** ^The sqlcipher3_interrupt(D) call is in effect until all currently running ** SQL statements on [database connection] D complete. ^Any new SQL statements -** that are started after the sqlcipher3_interrupt() call and before the +** that are started after the sqlcipher3_interrupt() call and before the ** running statements reaches zero are interrupted as if they had been ** running prior to the sqlcipher3_interrupt() call. ^New SQL statements ** that are started after the running statement count reaches zero are @@ -1767,7 +1769,7 @@ SQLCIPHER_API int sqlcipher3_total_changes(sqlcipher3*); ** If the database connection closes while [sqlcipher3_interrupt()] ** is running then bad things will likely happen. */ -SQLCIPHER_API void sqlcipher3_interrupt(sqlcipher3*); +SQLCIPHER_API void sqlcipher3_interrupt(sqlcipher3 *); /* ** CAPI3REF: Determine If An SQL Statement Is Complete @@ -1790,7 +1792,7 @@ SQLCIPHER_API void sqlcipher3_interrupt(sqlcipher3*); ** ^These routines do not parse the SQL statements thus ** will not detect syntactically incorrect SQL. ** -** ^(If SQLite has not been initialized using [sqlcipher3_initialize()] prior +** ^(If SQLite has not been initialized using [sqlcipher3_initialize()] prior ** to invoking sqlcipher3_complete16() then sqlcipher3_initialize() is invoked ** automatically by sqlcipher3_complete16(). If that initialization fails, ** then the return value from sqlcipher3_complete16() will be non-zero @@ -1865,11 +1867,12 @@ SQLCIPHER_API int sqlcipher3_complete16(const void *sql); ** The busy callback should not take any actions which modify the ** database connection that invoked the busy handler. Any such actions ** result in undefined behavior. -** +** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -SQLCIPHER_API int sqlcipher3_busy_handler(sqlcipher3*, int(*)(void*,int), void*); +SQLCIPHER_API int sqlcipher3_busy_handler(sqlcipher3 *, int(*)(void *, int), + void *); /* ** CAPI3REF: Set A Busy Timeout @@ -1889,7 +1892,7 @@ SQLCIPHER_API int sqlcipher3_busy_handler(sqlcipher3*, int(*)(void*,int), void*) ** was defined (using [sqlcipher3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ */ -SQLCIPHER_API int sqlcipher3_busy_timeout(sqlcipher3*, int ms); +SQLCIPHER_API int sqlcipher3_busy_timeout(sqlcipher3 *, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries @@ -1964,12 +1967,12 @@ SQLCIPHER_API int sqlcipher3_busy_timeout(sqlcipher3*, int ms); ** [sqlcipher3_errmsg()]. */ SQLCIPHER_API int sqlcipher3_get_table( - sqlcipher3 *db, /* An open database */ - const char *zSql, /* SQL to be evaluated */ - char ***pazResult, /* Results of the query */ - int *pnRow, /* Number of result rows written here */ - int *pnColumn, /* Number of result columns written here */ - char **pzErrmsg /* Error msg written here */ + sqlcipher3 *db, /* An open database */ + const char *zSql, /* SQL to be evaluated */ + char ***pazResult, /* Results of the query */ + int *pnRow, /* Number of result rows written here */ + int *pnColumn, /* Number of result columns written here */ + char **pzErrmsg /* Error msg written here */ ); SQLCIPHER_API void sqlcipher3_free_table(char **result); @@ -2067,10 +2070,10 @@ SQLCIPHER_API void sqlcipher3_free_table(char **result); ** addition that after the string has been read and copied into ** the result, [sqlcipher3_free()] is called on the input string.)^ */ -SQLCIPHER_API char *sqlcipher3_mprintf(const char*,...); -SQLCIPHER_API char *sqlcipher3_vmprintf(const char*, va_list); -SQLCIPHER_API char *sqlcipher3_snprintf(int,char*,const char*, ...); -SQLCIPHER_API char *sqlcipher3_vsnprintf(int,char*,const char*, va_list); +SQLCIPHER_API char *sqlcipher3_mprintf(const char *, ...); +SQLCIPHER_API char *sqlcipher3_vmprintf(const char *, va_list); +SQLCIPHER_API char *sqlcipher3_snprintf(int, char *, const char *, ...); +SQLCIPHER_API char *sqlcipher3_vsnprintf(int, char *, const char *, va_list); /* ** CAPI3REF: Memory Allocation Subsystem @@ -2143,8 +2146,8 @@ SQLCIPHER_API char *sqlcipher3_vsnprintf(int,char*,const char*, va_list); ** [sqlcipher3_free()] or [sqlcipher3_realloc()]. */ SQLCIPHER_API void *sqlcipher3_malloc(int); -SQLCIPHER_API void *sqlcipher3_realloc(void*, int); -SQLCIPHER_API void sqlcipher3_free(void*); +SQLCIPHER_API void *sqlcipher3_realloc(void *, int); +SQLCIPHER_API void sqlcipher3_free(void *); /* ** CAPI3REF: Memory Allocator Statistics @@ -2215,7 +2218,7 @@ SQLCIPHER_API void sqlcipher3_randomness(int N, void *P); ** requested is ok. ^When the callback returns [SQLCIPHER_DENY], the ** [sqlcipher3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that -** access is denied. +** access is denied. ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlcipher3_set_authorizer() interface. ^The second parameter @@ -2262,7 +2265,7 @@ SQLCIPHER_API void sqlcipher3_randomness(int N, void *P); ** database connections for the meaning of "modify" in this paragraph. ** ** ^When [sqlcipher3_prepare_v2()] is used to prepare a statement, the -** statement might be re-prepared during [sqlcipher3_step()] due to a +** statement might be re-prepared during [sqlcipher3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlcipher3_step()]. ** @@ -2273,9 +2276,10 @@ SQLCIPHER_API void sqlcipher3_randomness(int N, void *P); ** sqlcipher3_prepare_v2() to reprepare a statement after a schema change. */ SQLCIPHER_API int sqlcipher3_set_authorizer( - sqlcipher3*, - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), - void *pUserData + sqlcipher3 *, + int (*xAuth)(void *, int, const char *, const char *, const char *, + const char *), + void *pUserData ); /* @@ -2372,9 +2376,10 @@ SQLCIPHER_API int sqlcipher3_set_authorizer( ** sqlcipher3_profile() function is considered experimental and is ** subject to change in future versions of SQLite. */ -SQLCIPHER_API void *sqlcipher3_trace(sqlcipher3*, void(*xTrace)(void*,const char*), void*); -SQLCIPHER_API SQLCIPHER_EXPERIMENTAL void *sqlcipher3_profile(sqlcipher3*, - void(*xProfile)(void*,const char*,sqlcipher3_uint64), void*); +SQLCIPHER_API void *sqlcipher3_trace(sqlcipher3 *, void(*xTrace)(void *, + const char *), void *); +SQLCIPHER_API SQLCIPHER_EXPERIMENTAL void *sqlcipher3_profile(sqlcipher3 *, + void(*xProfile)(void *, const char *, sqlcipher3_uint64), void *); /* ** CAPI3REF: Query Progress Callbacks @@ -2385,8 +2390,8 @@ SQLCIPHER_API SQLCIPHER_EXPERIMENTAL void *sqlcipher3_profile(sqlcipher3*, ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** -** ^The parameter P is passed through as the only parameter to the -** callback function X. ^The parameter N is the number of +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the number of ** [virtual machine instructions] that are evaluated between successive ** invocations of the callback X. ** @@ -2406,12 +2411,13 @@ SQLCIPHER_API SQLCIPHER_EXPERIMENTAL void *sqlcipher3_profile(sqlcipher3*, ** database connections for the meaning of "modify" in this paragraph. ** */ -SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3*, int, int(*)(void*), void*); +SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3 *, int, + int(*)(void *), void *); /* ** CAPI3REF: Opening A New Database Connection ** -** ^These routines open an SQLite database file as specified by the +** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for ** sqlcipher3_open() and sqlcipher3_open_v2() and as UTF-16 in the native byte ** order for sqlcipher3_open16(). ^(A [database connection] handle is usually @@ -2436,7 +2442,7 @@ SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3*, int, int(*)(void*), ** except that it accepts two additional parameters for additional control ** over the new database connection. ^(The flags parameter to ** sqlcipher3_open_v2() can take one of -** the following three values, optionally combined with the +** the following three values, optionally combined with the ** [SQLCIPHER_OPEN_NOMUTEX], [SQLCIPHER_OPEN_FULLMUTEX], [SQLCIPHER_OPEN_SHAREDCACHE], ** [SQLCIPHER_OPEN_PRIVATECACHE], and/or [SQLCIPHER_OPEN_URI] flags:)^ ** @@ -2504,17 +2510,17 @@ SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3*, int, int(*)(void*), ** information. ** ** URI filenames are parsed according to RFC 3986. ^If the URI contains an -** authority, then it must be either an empty string or the string -** "localhost". ^If the authority is not an empty string or "localhost", an -** error is returned to the caller. ^The fragment component of a URI, if +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if ** present, is ignored. ** ** ^SQLite uses the path component of the URI as the name of the disk file -** which contains the database. ^If the path begins with a '/' character, -** then it is interpreted as an absolute path. ^If the path does not begin +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin ** with a '/' (meaning that the authority section is omitted from the URI) -** then the path is interpreted as a relative path. -** ^On windows, the first component of an absolute path +** then the path is interpreted as a relative path. +** ^On windows, the first component of an absolute path ** is a drive specification (e.g. "C:"). ** ** [[core URI query parameters]] @@ -2532,22 +2538,22 @@ SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3*, int, int(*)(void*), ** the value passed as the fourth parameter to sqlcipher3_open_v2(). ** ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or -** "rwc". Attempting to set it to any other value is an error)^. -** ^If "ro" is specified, then the database is opened for read-only -** access, just as if the [SQLCIPHER_OPEN_READONLY] flag had been set in the -** third argument to sqlcipher3_prepare_v2(). ^If the mode option is set to -** "rw", then the database is opened for read-write (but not create) -** access, as if SQLCIPHER_OPEN_READWRITE (but not SQLCIPHER_OPEN_CREATE) had -** been set. ^Value "rwc" is equivalent to setting both -** SQLCIPHER_OPEN_READWRITE and SQLCIPHER_OPEN_CREATE. ^If sqlcipher3_open_v2() is -** used, it is an error to specify a value for the mode parameter that is -** less restrictive than that specified by the flags passed as the third +** "rwc". Attempting to set it to any other value is an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLCIPHER_OPEN_READONLY] flag had been set in the +** third argument to sqlcipher3_prepare_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLCIPHER_OPEN_READWRITE (but not SQLCIPHER_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both +** SQLCIPHER_OPEN_READWRITE and SQLCIPHER_OPEN_CREATE. ^If sqlcipher3_open_v2() is +** used, it is an error to specify a value for the mode parameter that is +** less restrictive than that specified by the flags passed as the third ** parameter. ** ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLCIPHER_OPEN_SHAREDCACHE bit in the flags argument passed to -** sqlcipher3_open_v2(). ^Setting the cache parameter to "private" is +** sqlcipher3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLCIPHER_OPEN_PRIVATECACHE bit. ** ^If sqlcipher3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behaviour requested by setting @@ -2563,35 +2569,35 @@ SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3*, int, int(*)(void*), ** ** <table border="1" align=center cellpadding=5> ** <tr><th> URI filenames <th> Results -** <tr><td> file:data.db <td> +** <tr><td> file:data.db <td> ** Open the file "data.db" in the current directory. ** <tr><td> file:/home/fred/data.db<br> -** file:///home/fred/data.db <br> -** file://localhost/home/fred/data.db <br> <td> +** file:///home/fred/data.db <br> +** file://localhost/home/fred/data.db <br> <td> ** Open the database file "/home/fred/data.db". -** <tr><td> file://darkstar/home/fred/data.db <td> +** <tr><td> file://darkstar/home/fred/data.db <td> ** An error. "darkstar" is not a recognized authority. -** <tr><td style="white-space:nowrap"> +** <tr><td style="white-space:nowrap"> ** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db ** <td> Windows only: Open the file "data.db" on fred's desktop on drive -** C:. Note that the %20 escaping in this example is not strictly +** C:. Note that the %20 escaping in this example is not strictly ** necessary - space characters can be used literally ** in URI filenames. -** <tr><td> file:data.db?mode=ro&cache=private <td> +** <tr><td> file:data.db?mode=ro&cache=private <td> ** Open file "data.db" in the current directory for read-only access. ** Regardless of whether or not shared-cache mode is enabled by ** default, use a private cache. ** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td> ** Open file "/home/fred/data.db". Use the special VFS "unix-nolock". -** <tr><td> file:data.db?mode=readonly <td> +** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and ** query components of a URI. A hexadecimal escape sequence consists of a -** percent sign - "%" - followed by exactly two hexadecimal digits +** percent sign - "%" - followed by exactly two hexadecimal digits ** specifying an octet value. ^Before the path or query components of a -** URI filename are interpreted, they are encoded using UTF-8 and all +** URI filename are interpreted, they are encoded using UTF-8 and all ** hexadecimal escape sequences replaced by a single byte containing the ** corresponding octet. If this process generates an invalid UTF-8 encoding, ** the results are undefined. @@ -2603,25 +2609,25 @@ SQLCIPHER_API void sqlcipher3_progress_handler(sqlcipher3*, int, int(*)(void*), ** sqlcipher3_open() or sqlcipher3_open_v2(). */ SQLCIPHER_API int sqlcipher3_open( - const char *filename, /* Database filename (UTF-8) */ - sqlcipher3 **ppDb /* OUT: SQLite db handle */ + const char *filename, /* Database filename (UTF-8) */ + sqlcipher3 **ppDb /* OUT: SQLite db handle */ ); SQLCIPHER_API int sqlcipher3_open16( - const void *filename, /* Database filename (UTF-16) */ - sqlcipher3 **ppDb /* OUT: SQLite db handle */ + const void *filename, /* Database filename (UTF-16) */ + sqlcipher3 **ppDb /* OUT: SQLite db handle */ ); SQLCIPHER_API int sqlcipher3_open_v2( - const char *filename, /* Database filename (UTF-8) */ - sqlcipher3 **ppDb, /* OUT: SQLite db handle */ - int flags, /* Flags */ - const char *zVfs /* Name of VFS module to use */ + const char *filename, /* Database filename (UTF-8) */ + sqlcipher3 **ppDb, /* OUT: SQLite db handle */ + int flags, /* Flags */ + const char *zVfs /* Name of VFS module to use */ ); /* ** CAPI3REF: Obtain Values For URI Parameters ** ** This is a utility routine, useful to VFS implementations, that checks -** to see if a database file was a URI that contained a specific query +** to see if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of the query parameter. ** ** The zFilename argument is the filename pointer passed into the xOpen() @@ -2634,7 +2640,8 @@ SQLCIPHER_API int sqlcipher3_open_v2( ** passed into the xOpen VFS method, then the behavior of this routine ** is undefined and probably undesirable. */ -SQLCIPHER_API const char *sqlcipher3_uri_parameter(const char *zFilename, const char *zParam); +SQLCIPHER_API const char *sqlcipher3_uri_parameter(const char *zFilename, + const char *zParam); /* @@ -2645,7 +2652,7 @@ SQLCIPHER_API const char *sqlcipher3_uri_parameter(const char *zFilename, const ** associated with a [database connection]. If a prior API call failed ** but the most recent API call succeeded, the return value from ** sqlcipher3_errcode() is undefined. ^The sqlcipher3_extended_errcode() -** interface is the same except that it always returns the +** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** @@ -2672,8 +2679,8 @@ SQLCIPHER_API const char *sqlcipher3_uri_parameter(const char *zFilename, const */ SQLCIPHER_API int sqlcipher3_errcode(sqlcipher3 *db); SQLCIPHER_API int sqlcipher3_extended_errcode(sqlcipher3 *db); -SQLCIPHER_API const char *sqlcipher3_errmsg(sqlcipher3*); -SQLCIPHER_API const void *sqlcipher3_errmsg16(sqlcipher3*); +SQLCIPHER_API const char *sqlcipher3_errmsg(sqlcipher3 *); +SQLCIPHER_API const void *sqlcipher3_errmsg16(sqlcipher3 *); /* ** CAPI3REF: SQL Statement Object @@ -2712,7 +2719,7 @@ typedef struct sqlcipher3_stmt sqlcipher3_stmt; ** new limit for that construct.)^ ** ** ^If the new limit is a negative number, the limit is unchanged. -** ^(For each limit category SQLCIPHER_LIMIT_<i>NAME</i> there is a +** ^(For each limit category SQLCIPHER_LIMIT_<i>NAME</i> there is a ** [limits | hard upper bound] ** set at compile-time by a C preprocessor macro called ** [limits | SQLCIPHER_MAX_<i>NAME</i>]. @@ -2720,7 +2727,7 @@ typedef struct sqlcipher3_stmt sqlcipher3_stmt; ** ^Attempts to increase a limit above its hard upper bound are ** silently truncated to the hard upper bound. ** -** ^Regardless of whether or not the limit was changed, the +** ^Regardless of whether or not the limit was changed, the ** [sqlcipher3_limit()] interface returns the prior value of the limit. ** ^Hence, to find the current value of a limit without changing it, ** simply invoke this interface with the third parameter set to -1. @@ -2740,7 +2747,7 @@ typedef struct sqlcipher3_stmt sqlcipher3_stmt; ** ** New run-time limit categories may be added in future releases. */ -SQLCIPHER_API int sqlcipher3_limit(sqlcipher3*, int id, int newVal); +SQLCIPHER_API int sqlcipher3_limit(sqlcipher3 *, int id, int newVal); /* ** CAPI3REF: Run-Time Limit Categories @@ -2874,46 +2881,46 @@ SQLCIPHER_API int sqlcipher3_limit(sqlcipher3*, int id, int newVal); ** </li> ** ** <li> -** ^If the specific value bound to [parameter | host parameter] in the +** ^If the specific value bound to [parameter | host parameter] in the ** WHERE clause might influence the choice of query plan for a statement, -** then the statement will be automatically recompiled, as if there had been +** then the statement will be automatically recompiled, as if there had been ** a schema change, on the first [sqlcipher3_step()] call following any change -** to the [sqlcipher3_bind_text | bindings] of that [parameter]. -** ^The specific value of WHERE-clause [parameter] might influence the +** to the [sqlcipher3_bind_text | bindings] of that [parameter]. +** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLCIPHER_ENABLE_STAT3] compile-time option is enabled. -** the +** the ** </li> ** </ol> */ SQLCIPHER_API int sqlcipher3_prepare( - sqlcipher3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ + sqlcipher3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLCIPHER_API int sqlcipher3_prepare_v2( - sqlcipher3 *db, /* Database handle */ - const char *zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ - const char **pzTail /* OUT: Pointer to unused portion of zSql */ + sqlcipher3 *db, /* Database handle */ + const char *zSql, /* SQL statement, UTF-8 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ + const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLCIPHER_API int sqlcipher3_prepare16( - sqlcipher3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ + sqlcipher3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); SQLCIPHER_API int sqlcipher3_prepare16_v2( - sqlcipher3 *db, /* Database handle */ - const void *zSql, /* SQL statement, UTF-16 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ - const void **pzTail /* OUT: Pointer to unused portion of zSql */ + sqlcipher3 *db, /* Database handle */ + const void *zSql, /* SQL statement, UTF-16 encoded */ + int nByte, /* Maximum length of zSql in bytes. */ + sqlcipher3_stmt **ppStmt, /* OUT: Statement handle */ + const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); /* @@ -2933,8 +2940,8 @@ SQLCIPHER_API const char *sqlcipher3_sql(sqlcipher3_stmt *pStmt); ** the content of the database file. ** ** Note that [application-defined SQL functions] or -** [virtual tables] might change the database indirectly as a side effect. -** ^(For example, if an application defines a function "eval()" that +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that ** calls [sqlcipher3_exec()], then the following SQL statement would ** change the database file through side-effects: ** @@ -2948,10 +2955,10 @@ SQLCIPHER_API const char *sqlcipher3_sql(sqlcipher3_stmt *pStmt); ** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], ** [SAVEPOINT], and [RELEASE] cause sqlcipher3_stmt_readonly() to return true, ** since the statements themselves do not actually modify the database but -** rather they control the timing of when other statements modify the +** rather they control the timing of when other statements modify the ** database. ^The [ATTACH] and [DETACH] statements also cause ** sqlcipher3_stmt_readonly() to return true since, while those statements -** change the configuration of a database connection, they do not make +** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. */ SQLCIPHER_API int sqlcipher3_stmt_readonly(sqlcipher3_stmt *pStmt); @@ -2976,7 +2983,7 @@ SQLCIPHER_API int sqlcipher3_stmt_readonly(sqlcipher3_stmt *pStmt); ** sqlcipher3_value object but no mutex is held for an unprotected ** sqlcipher3_value object. If SQLite is compiled to be single-threaded ** (with [SQLCIPHER_THREADSAFE=0] and with [sqlcipher3_threadsafe()] returning 0) -** or if SQLite is run in one of reduced mutex modes +** or if SQLite is run in one of reduced mutex modes ** [SQLCIPHER_CONFIG_SINGLETHREAD] or [SQLCIPHER_CONFIG_MULTITHREAD] ** then there is no distinction between protected and unprotected ** sqlcipher3_value objects and they can be used interchangeably. However, @@ -3055,7 +3062,7 @@ typedef struct sqlcipher3_context sqlcipher3_context; ** If a non-negative fourth parameter is provided to sqlcipher3_bind_text() ** or sqlcipher3_bind_text16() then that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occur at byte offsets less than +** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. @@ -3064,7 +3071,7 @@ typedef struct sqlcipher3_context sqlcipher3_context; ** sqlcipher3_bind_text16() is a destructor used to dispose of the BLOB or ** string after SQLite has finished with it. ^The destructor is called ** to dispose of the BLOB or string even if the call to sqlcipher3_bind_blob(), -** sqlcipher3_bind_text(), or sqlcipher3_bind_text16() fails. +** sqlcipher3_bind_text(), or sqlcipher3_bind_text16() fails. ** ^If the fifth argument is ** the special value [SQLCIPHER_STATIC], then SQLite assumes that the ** information is in static, unmanaged space and does not need to be freed. @@ -3098,15 +3105,20 @@ typedef struct sqlcipher3_context sqlcipher3_context; ** See also: [sqlcipher3_bind_parameter_count()], ** [sqlcipher3_bind_parameter_name()], and [sqlcipher3_bind_parameter_index()]. */ -SQLCIPHER_API int sqlcipher3_bind_blob(sqlcipher3_stmt*, int, const void*, int n, void(*)(void*)); -SQLCIPHER_API int sqlcipher3_bind_double(sqlcipher3_stmt*, int, double); -SQLCIPHER_API int sqlcipher3_bind_int(sqlcipher3_stmt*, int, int); -SQLCIPHER_API int sqlcipher3_bind_int64(sqlcipher3_stmt*, int, sqlcipher3_int64); -SQLCIPHER_API int sqlcipher3_bind_null(sqlcipher3_stmt*, int); -SQLCIPHER_API int sqlcipher3_bind_text(sqlcipher3_stmt*, int, const char*, int n, void(*)(void*)); -SQLCIPHER_API int sqlcipher3_bind_text16(sqlcipher3_stmt*, int, const void*, int, void(*)(void*)); -SQLCIPHER_API int sqlcipher3_bind_value(sqlcipher3_stmt*, int, const sqlcipher3_value*); -SQLCIPHER_API int sqlcipher3_bind_zeroblob(sqlcipher3_stmt*, int, int n); +SQLCIPHER_API int sqlcipher3_bind_blob(sqlcipher3_stmt *, int, const void *, + int n, void(*)(void *)); +SQLCIPHER_API int sqlcipher3_bind_double(sqlcipher3_stmt *, int, double); +SQLCIPHER_API int sqlcipher3_bind_int(sqlcipher3_stmt *, int, int); +SQLCIPHER_API int sqlcipher3_bind_int64(sqlcipher3_stmt *, int, + sqlcipher3_int64); +SQLCIPHER_API int sqlcipher3_bind_null(sqlcipher3_stmt *, int); +SQLCIPHER_API int sqlcipher3_bind_text(sqlcipher3_stmt *, int, const char *, + int n, void(*)(void *)); +SQLCIPHER_API int sqlcipher3_bind_text16(sqlcipher3_stmt *, int, const void *, + int, void(*)(void *)); +SQLCIPHER_API int sqlcipher3_bind_value(sqlcipher3_stmt *, int, + const sqlcipher3_value *); +SQLCIPHER_API int sqlcipher3_bind_zeroblob(sqlcipher3_stmt *, int, int n); /* ** CAPI3REF: Number Of SQL Parameters @@ -3126,7 +3138,7 @@ SQLCIPHER_API int sqlcipher3_bind_zeroblob(sqlcipher3_stmt*, int, int n); ** [sqlcipher3_bind_parameter_name()], and ** [sqlcipher3_bind_parameter_index()]. */ -SQLCIPHER_API int sqlcipher3_bind_parameter_count(sqlcipher3_stmt*); +SQLCIPHER_API int sqlcipher3_bind_parameter_count(sqlcipher3_stmt *); /* ** CAPI3REF: Name Of A Host Parameter @@ -3153,7 +3165,8 @@ SQLCIPHER_API int sqlcipher3_bind_parameter_count(sqlcipher3_stmt*); ** [sqlcipher3_bind_parameter_count()], and ** [sqlcipher3_bind_parameter_index()]. */ -SQLCIPHER_API const char *sqlcipher3_bind_parameter_name(sqlcipher3_stmt*, int); +SQLCIPHER_API const char *sqlcipher3_bind_parameter_name(sqlcipher3_stmt *, + int); /* ** CAPI3REF: Index Of A Parameter With A Given Name @@ -3169,7 +3182,8 @@ SQLCIPHER_API const char *sqlcipher3_bind_parameter_name(sqlcipher3_stmt*, int); ** [sqlcipher3_bind_parameter_count()], and ** [sqlcipher3_bind_parameter_index()]. */ -SQLCIPHER_API int sqlcipher3_bind_parameter_index(sqlcipher3_stmt*, const char *zName); +SQLCIPHER_API int sqlcipher3_bind_parameter_index(sqlcipher3_stmt *, + const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement @@ -3178,7 +3192,7 @@ SQLCIPHER_API int sqlcipher3_bind_parameter_index(sqlcipher3_stmt*, const char * ** the [sqlcipher3_bind_blob | bindings] on a [prepared statement]. ** ^Use this routine to reset all host parameters to NULL. */ -SQLCIPHER_API int sqlcipher3_clear_bindings(sqlcipher3_stmt*); +SQLCIPHER_API int sqlcipher3_clear_bindings(sqlcipher3_stmt *); /* ** CAPI3REF: Number Of Columns In A Result Set @@ -3217,8 +3231,8 @@ SQLCIPHER_API int sqlcipher3_column_count(sqlcipher3_stmt *pStmt); ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ -SQLCIPHER_API const char *sqlcipher3_column_name(sqlcipher3_stmt*, int N); -SQLCIPHER_API const void *sqlcipher3_column_name16(sqlcipher3_stmt*, int N); +SQLCIPHER_API const char *sqlcipher3_column_name(sqlcipher3_stmt *, int N); +SQLCIPHER_API const void *sqlcipher3_column_name16(sqlcipher3_stmt *, int N); /* ** CAPI3REF: Source Of Data In A Query Result @@ -3265,12 +3279,16 @@ SQLCIPHER_API const void *sqlcipher3_column_name16(sqlcipher3_stmt*, int N); ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ -SQLCIPHER_API const char *sqlcipher3_column_database_name(sqlcipher3_stmt*,int); -SQLCIPHER_API const void *sqlcipher3_column_database_name16(sqlcipher3_stmt*,int); -SQLCIPHER_API const char *sqlcipher3_column_table_name(sqlcipher3_stmt*,int); -SQLCIPHER_API const void *sqlcipher3_column_table_name16(sqlcipher3_stmt*,int); -SQLCIPHER_API const char *sqlcipher3_column_origin_name(sqlcipher3_stmt*,int); -SQLCIPHER_API const void *sqlcipher3_column_origin_name16(sqlcipher3_stmt*,int); +SQLCIPHER_API const char *sqlcipher3_column_database_name(sqlcipher3_stmt *, + int); +SQLCIPHER_API const void *sqlcipher3_column_database_name16(sqlcipher3_stmt *, + int); +SQLCIPHER_API const char *sqlcipher3_column_table_name(sqlcipher3_stmt *, int); +SQLCIPHER_API const void *sqlcipher3_column_table_name16(sqlcipher3_stmt *, + int); +SQLCIPHER_API const char *sqlcipher3_column_origin_name(sqlcipher3_stmt *, int); +SQLCIPHER_API const void *sqlcipher3_column_origin_name16(sqlcipher3_stmt *, + int); /* ** CAPI3REF: Declared Datatype Of A Query Result @@ -3301,8 +3319,8 @@ SQLCIPHER_API const void *sqlcipher3_column_origin_name16(sqlcipher3_stmt*,int); ** is associated with individual values, not with the containers ** used to hold those values. */ -SQLCIPHER_API const char *sqlcipher3_column_decltype(sqlcipher3_stmt*,int); -SQLCIPHER_API const void *sqlcipher3_column_decltype16(sqlcipher3_stmt*,int); +SQLCIPHER_API const char *sqlcipher3_column_decltype(sqlcipher3_stmt *, int); +SQLCIPHER_API const void *sqlcipher3_column_decltype16(sqlcipher3_stmt *, int); /* ** CAPI3REF: Evaluate An SQL Statement @@ -3360,7 +3378,7 @@ SQLCIPHER_API const void *sqlcipher3_column_decltype16(sqlcipher3_stmt*,int); ** For all versions of SQLite up to and including 3.6.23.1, a call to ** [sqlcipher3_reset()] was required after sqlcipher3_step() returned anything ** other than [SQLCIPHER_ROW] before any subsequent invocation of -** sqlcipher3_step(). Failure to reset the prepared statement using +** sqlcipher3_step(). Failure to reset the prepared statement using ** [sqlcipher3_reset()] would result in an [SQLCIPHER_MISUSE] return from ** sqlcipher3_step(). But after version 3.6.23.1, sqlcipher3_step() began ** calling [sqlcipher3_reset()] automatically in this circumstance rather @@ -3381,7 +3399,7 @@ SQLCIPHER_API const void *sqlcipher3_column_decltype16(sqlcipher3_stmt*,int); ** then the more specific [error codes] are returned directly ** by sqlcipher3_step(). The use of the "v2" interface is recommended. */ -SQLCIPHER_API int sqlcipher3_step(sqlcipher3_stmt*); +SQLCIPHER_API int sqlcipher3_step(sqlcipher3_stmt *); /* ** CAPI3REF: Number of columns in a result set @@ -3490,7 +3508,7 @@ SQLCIPHER_API int sqlcipher3_data_count(sqlcipher3_stmt *pStmt); ** the number of bytes in that string. ** ^If the result is NULL, then sqlcipher3_column_bytes16() returns zero. ** -** ^The values returned by [sqlcipher3_column_bytes()] and +** ^The values returned by [sqlcipher3_column_bytes()] and ** [sqlcipher3_column_bytes16()] do not include the zero terminators at the end ** of the string. ^For clarity: the values returned by ** [sqlcipher3_column_bytes()] and [sqlcipher3_column_bytes16()] are the number of @@ -3597,16 +3615,19 @@ SQLCIPHER_API int sqlcipher3_data_count(sqlcipher3_stmt *pStmt); ** pointer. Subsequent calls to [sqlcipher3_errcode()] will return ** [SQLCIPHER_NOMEM].)^ */ -SQLCIPHER_API const void *sqlcipher3_column_blob(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API int sqlcipher3_column_bytes(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API int sqlcipher3_column_bytes16(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API double sqlcipher3_column_double(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API int sqlcipher3_column_int(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API sqlcipher3_int64 sqlcipher3_column_int64(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API const unsigned char *sqlcipher3_column_text(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API const void *sqlcipher3_column_text16(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API int sqlcipher3_column_type(sqlcipher3_stmt*, int iCol); -SQLCIPHER_API sqlcipher3_value *sqlcipher3_column_value(sqlcipher3_stmt*, int iCol); +SQLCIPHER_API const void *sqlcipher3_column_blob(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API int sqlcipher3_column_bytes(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API int sqlcipher3_column_bytes16(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API double sqlcipher3_column_double(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API int sqlcipher3_column_int(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API sqlcipher3_int64 sqlcipher3_column_int64(sqlcipher3_stmt *, + int iCol); +SQLCIPHER_API const unsigned char *sqlcipher3_column_text(sqlcipher3_stmt *, + int iCol); +SQLCIPHER_API const void *sqlcipher3_column_text16(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API int sqlcipher3_column_type(sqlcipher3_stmt *, int iCol); +SQLCIPHER_API sqlcipher3_value *sqlcipher3_column_value(sqlcipher3_stmt *, + int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object @@ -3683,7 +3704,7 @@ SQLCIPHER_API int sqlcipher3_reset(sqlcipher3_stmt *pStmt); ** ^The second parameter is the name of the SQL function to be created or ** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 ** representation, exclusive of the zero-terminator. ^Note that the name -** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. ** ^Any attempt to create a function with a longer name ** will result in [SQLCIPHER_MISUSE] being returned. ** @@ -3720,13 +3741,13 @@ SQLCIPHER_API int sqlcipher3_reset(sqlcipher3_stmt *pStmt); ** callbacks. ** ** ^(If the ninth parameter to sqlcipher3_create_function_v2() is not NULL, -** then it is destructor for the application data pointer. +** then it is destructor for the application data pointer. ** The destructor is invoked when the function is deleted, either by being ** overloaded or when the database connection closes.)^ ** ^The destructor is also invoked if the call to ** sqlcipher3_create_function_v2() fails. ** ^When the destructor callback of the tenth parameter is invoked, it -** is passed a single argument which is a copy of the application data +** is passed a single argument which is a copy of the application data ** pointer which was the fifth parameter to sqlcipher3_create_function_v2(). ** ** ^It is permitted to register multiple implementations of the same @@ -3737,7 +3758,7 @@ SQLCIPHER_API int sqlcipher3_reset(sqlcipher3_stmt *pStmt); ** nArg parameter is a better match than a function implementation with ** a negative nArg. ^A function where the preferred text encoding ** matches the database encoding is a better -** match than a function where the encoding is different. +** match than a function where the encoding is different. ** ^A function where the encoding difference is between UTF16le and UTF16be ** is a closer match than a function where the encoding difference is ** between UTF8 and UTF16. @@ -3750,35 +3771,35 @@ SQLCIPHER_API int sqlcipher3_reset(sqlcipher3_stmt *pStmt); ** statement in which the function is running. */ SQLCIPHER_API int sqlcipher3_create_function( - sqlcipher3 *db, - const char *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlcipher3_context*,int,sqlcipher3_value**), - void (*xStep)(sqlcipher3_context*,int,sqlcipher3_value**), - void (*xFinal)(sqlcipher3_context*) + sqlcipher3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlcipher3_context *, int, sqlcipher3_value **), + void (*xStep)(sqlcipher3_context *, int, sqlcipher3_value **), + void (*xFinal)(sqlcipher3_context *) ); SQLCIPHER_API int sqlcipher3_create_function16( - sqlcipher3 *db, - const void *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlcipher3_context*,int,sqlcipher3_value**), - void (*xStep)(sqlcipher3_context*,int,sqlcipher3_value**), - void (*xFinal)(sqlcipher3_context*) + sqlcipher3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlcipher3_context *, int, sqlcipher3_value **), + void (*xStep)(sqlcipher3_context *, int, sqlcipher3_value **), + void (*xFinal)(sqlcipher3_context *) ); SQLCIPHER_API int sqlcipher3_create_function_v2( - sqlcipher3 *db, - const char *zFunctionName, - int nArg, - int eTextRep, - void *pApp, - void (*xFunc)(sqlcipher3_context*,int,sqlcipher3_value**), - void (*xStep)(sqlcipher3_context*,int,sqlcipher3_value**), - void (*xFinal)(sqlcipher3_context*), - void(*xDestroy)(void*) + sqlcipher3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlcipher3_context *, int, sqlcipher3_value **), + void (*xStep)(sqlcipher3_context *, int, sqlcipher3_value **), + void (*xFinal)(sqlcipher3_context *), + void(*xDestroy)(void *) ); /* @@ -3799,18 +3820,21 @@ SQLCIPHER_API int sqlcipher3_create_function_v2( ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain -** backwards compatibility with older code, these functions continue +** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid ** the use of these functions. To help encourage people to avoid ** using these functions, we are not going to tell you what they do. */ #ifndef SQLCIPHER_OMIT_DEPRECATED -SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_aggregate_count(sqlcipher3_context*); -SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_expired(sqlcipher3_stmt*); -SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_transfer_bindings(sqlcipher3_stmt*, sqlcipher3_stmt*); +SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_aggregate_count( + sqlcipher3_context *); +SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_expired(sqlcipher3_stmt *); +SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_transfer_bindings( + sqlcipher3_stmt *, sqlcipher3_stmt *); SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_global_recover(void); SQLCIPHER_API SQLCIPHER_DEPRECATED void sqlcipher3_thread_cleanup(void); -SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_memory_alarm(void(*)(void*,sqlcipher3_int64,int),void*,sqlcipher3_int64); +SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_memory_alarm(void(*)(void *, + sqlcipher3_int64, int), void *, sqlcipher3_int64); #endif /* @@ -3858,18 +3882,18 @@ SQLCIPHER_API SQLCIPHER_DEPRECATED int sqlcipher3_memory_alarm(void(*)(void*,sql ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlcipher3_value*] parameters. */ -SQLCIPHER_API const void *sqlcipher3_value_blob(sqlcipher3_value*); -SQLCIPHER_API int sqlcipher3_value_bytes(sqlcipher3_value*); -SQLCIPHER_API int sqlcipher3_value_bytes16(sqlcipher3_value*); -SQLCIPHER_API double sqlcipher3_value_double(sqlcipher3_value*); -SQLCIPHER_API int sqlcipher3_value_int(sqlcipher3_value*); -SQLCIPHER_API sqlcipher3_int64 sqlcipher3_value_int64(sqlcipher3_value*); -SQLCIPHER_API const unsigned char *sqlcipher3_value_text(sqlcipher3_value*); -SQLCIPHER_API const void *sqlcipher3_value_text16(sqlcipher3_value*); -SQLCIPHER_API const void *sqlcipher3_value_text16le(sqlcipher3_value*); -SQLCIPHER_API const void *sqlcipher3_value_text16be(sqlcipher3_value*); -SQLCIPHER_API int sqlcipher3_value_type(sqlcipher3_value*); -SQLCIPHER_API int sqlcipher3_value_numeric_type(sqlcipher3_value*); +SQLCIPHER_API const void *sqlcipher3_value_blob(sqlcipher3_value *); +SQLCIPHER_API int sqlcipher3_value_bytes(sqlcipher3_value *); +SQLCIPHER_API int sqlcipher3_value_bytes16(sqlcipher3_value *); +SQLCIPHER_API double sqlcipher3_value_double(sqlcipher3_value *); +SQLCIPHER_API int sqlcipher3_value_int(sqlcipher3_value *); +SQLCIPHER_API sqlcipher3_int64 sqlcipher3_value_int64(sqlcipher3_value *); +SQLCIPHER_API const unsigned char *sqlcipher3_value_text(sqlcipher3_value *); +SQLCIPHER_API const void *sqlcipher3_value_text16(sqlcipher3_value *); +SQLCIPHER_API const void *sqlcipher3_value_text16le(sqlcipher3_value *); +SQLCIPHER_API const void *sqlcipher3_value_text16be(sqlcipher3_value *); +SQLCIPHER_API int sqlcipher3_value_type(sqlcipher3_value *); +SQLCIPHER_API int sqlcipher3_value_numeric_type(sqlcipher3_value *); /* ** CAPI3REF: Obtain Aggregate Function Context @@ -3877,7 +3901,7 @@ SQLCIPHER_API int sqlcipher3_value_numeric_type(sqlcipher3_value*); ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** -** ^The first time the sqlcipher3_aggregate_context(C,N) routine is called +** ^The first time the sqlcipher3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite ** allocates N of memory, zeroes out that memory, and returns a pointer ** to the new memory. ^On second and subsequent calls to @@ -3899,7 +3923,7 @@ SQLCIPHER_API int sqlcipher3_value_numeric_type(sqlcipher3_value*); ** the same aggregate function instance will not resize the memory ** allocation.)^ ** -** ^SQLite automatically frees the memory allocated by +** ^SQLite automatically frees the memory allocated by ** sqlcipher3_aggregate_context() when the aggregate query concludes. ** ** The first parameter must be a copy of the @@ -3910,7 +3934,8 @@ SQLCIPHER_API int sqlcipher3_value_numeric_type(sqlcipher3_value*); ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ -SQLCIPHER_API void *sqlcipher3_aggregate_context(sqlcipher3_context*, int nBytes); +SQLCIPHER_API void *sqlcipher3_aggregate_context(sqlcipher3_context *, + int nBytes); /* ** CAPI3REF: User Data For Functions @@ -3924,7 +3949,7 @@ SQLCIPHER_API void *sqlcipher3_aggregate_context(sqlcipher3_context*, int nBytes ** This routine must be called from the same thread in which ** the application-defined function is running. */ -SQLCIPHER_API void *sqlcipher3_user_data(sqlcipher3_context*); +SQLCIPHER_API void *sqlcipher3_user_data(sqlcipher3_context *); /* ** CAPI3REF: Database Connection For Functions @@ -3935,7 +3960,7 @@ SQLCIPHER_API void *sqlcipher3_user_data(sqlcipher3_context*); ** and [sqlcipher3_create_function16()] routines that originally ** registered the application defined function. */ -SQLCIPHER_API sqlcipher3 *sqlcipher3_context_db_handle(sqlcipher3_context*); +SQLCIPHER_API sqlcipher3 *sqlcipher3_context_db_handle(sqlcipher3_context *); /* ** CAPI3REF: Function Auxiliary Data @@ -3979,8 +4004,9 @@ SQLCIPHER_API sqlcipher3 *sqlcipher3_context_db_handle(sqlcipher3_context*); ** These routines must be called from the same thread in which ** the SQL function is running. */ -SQLCIPHER_API void *sqlcipher3_get_auxdata(sqlcipher3_context*, int N); -SQLCIPHER_API void sqlcipher3_set_auxdata(sqlcipher3_context*, int N, void*, void (*)(void*)); +SQLCIPHER_API void *sqlcipher3_get_auxdata(sqlcipher3_context *, int N); +SQLCIPHER_API void sqlcipher3_set_auxdata(sqlcipher3_context *, int N, void *, + void (*)(void *)); /* @@ -3997,7 +4023,7 @@ SQLCIPHER_API void sqlcipher3_set_auxdata(sqlcipher3_context*, int N, void*, voi ** The typedef is necessary to work around problems in certain ** C++ compilers. See ticket #2191. */ -typedef void (*sqlcipher3_destructor_type)(void*); +typedef void (*sqlcipher3_destructor_type)(void *); #define SQLCIPHER_STATIC ((sqlcipher3_destructor_type)0) #define SQLCIPHER_TRANSIENT ((sqlcipher3_destructor_type)-1) @@ -4111,22 +4137,31 @@ typedef void (*sqlcipher3_destructor_type)(void*); ** than the one containing the application-defined function that received ** the [sqlcipher3_context] pointer, the results are undefined. */ -SQLCIPHER_API void sqlcipher3_result_blob(sqlcipher3_context*, const void*, int, void(*)(void*)); -SQLCIPHER_API void sqlcipher3_result_double(sqlcipher3_context*, double); -SQLCIPHER_API void sqlcipher3_result_error(sqlcipher3_context*, const char*, int); -SQLCIPHER_API void sqlcipher3_result_error16(sqlcipher3_context*, const void*, int); -SQLCIPHER_API void sqlcipher3_result_error_toobig(sqlcipher3_context*); -SQLCIPHER_API void sqlcipher3_result_error_nomem(sqlcipher3_context*); -SQLCIPHER_API void sqlcipher3_result_error_code(sqlcipher3_context*, int); -SQLCIPHER_API void sqlcipher3_result_int(sqlcipher3_context*, int); -SQLCIPHER_API void sqlcipher3_result_int64(sqlcipher3_context*, sqlcipher3_int64); -SQLCIPHER_API void sqlcipher3_result_null(sqlcipher3_context*); -SQLCIPHER_API void sqlcipher3_result_text(sqlcipher3_context*, const char*, int, void(*)(void*)); -SQLCIPHER_API void sqlcipher3_result_text16(sqlcipher3_context*, const void*, int, void(*)(void*)); -SQLCIPHER_API void sqlcipher3_result_text16le(sqlcipher3_context*, const void*, int,void(*)(void*)); -SQLCIPHER_API void sqlcipher3_result_text16be(sqlcipher3_context*, const void*, int,void(*)(void*)); -SQLCIPHER_API void sqlcipher3_result_value(sqlcipher3_context*, sqlcipher3_value*); -SQLCIPHER_API void sqlcipher3_result_zeroblob(sqlcipher3_context*, int n); +SQLCIPHER_API void sqlcipher3_result_blob(sqlcipher3_context *, const void *, + int, void(*)(void *)); +SQLCIPHER_API void sqlcipher3_result_double(sqlcipher3_context *, double); +SQLCIPHER_API void sqlcipher3_result_error(sqlcipher3_context *, const char *, + int); +SQLCIPHER_API void sqlcipher3_result_error16(sqlcipher3_context *, const void *, + int); +SQLCIPHER_API void sqlcipher3_result_error_toobig(sqlcipher3_context *); +SQLCIPHER_API void sqlcipher3_result_error_nomem(sqlcipher3_context *); +SQLCIPHER_API void sqlcipher3_result_error_code(sqlcipher3_context *, int); +SQLCIPHER_API void sqlcipher3_result_int(sqlcipher3_context *, int); +SQLCIPHER_API void sqlcipher3_result_int64(sqlcipher3_context *, + sqlcipher3_int64); +SQLCIPHER_API void sqlcipher3_result_null(sqlcipher3_context *); +SQLCIPHER_API void sqlcipher3_result_text(sqlcipher3_context *, const char *, + int, void(*)(void *)); +SQLCIPHER_API void sqlcipher3_result_text16(sqlcipher3_context *, const void *, + int, void(*)(void *)); +SQLCIPHER_API void sqlcipher3_result_text16le(sqlcipher3_context *, + const void *, int, void(*)(void *)); +SQLCIPHER_API void sqlcipher3_result_text16be(sqlcipher3_context *, + const void *, int, void(*)(void *)); +SQLCIPHER_API void sqlcipher3_result_value(sqlcipher3_context *, + sqlcipher3_value *); +SQLCIPHER_API void sqlcipher3_result_zeroblob(sqlcipher3_context *, int n); /* ** CAPI3REF: Define New Collating Sequences @@ -4166,7 +4201,7 @@ SQLCIPHER_API void sqlcipher3_result_zeroblob(sqlcipher3_context*, int n); ** deleted. ^When all collating functions having the same name are deleted, ** that collation is no longer usable. ** -** ^The collating function callback is invoked with a copy of the pArg +** ^The collating function callback is invoked with a copy of the pArg ** application data pointer and with two strings in the encoding specified ** by the eTextRep argument. The collating function must return an ** integer that is negative, zero, or positive @@ -4196,38 +4231,38 @@ SQLCIPHER_API void sqlcipher3_result_zeroblob(sqlcipher3_context*, int n); ** calls to the collation creation functions or when the ** [database connection] is closed using [sqlcipher3_close()]. ** -** ^The xDestroy callback is <u>not</u> called if the +** ^The xDestroy callback is <u>not</u> called if the ** sqlcipher3_create_collation_v2() function fails. Applications that invoke -** sqlcipher3_create_collation_v2() with a non-NULL xDestroy argument should +** sqlcipher3_create_collation_v2() with a non-NULL xDestroy argument should ** check the return code and dispose of the application data pointer ** themselves rather than expecting SQLite to deal with it for them. -** This is different from every other SQLite interface. The inconsistency -** is unfortunate but cannot be changed without breaking backwards +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** ** See also: [sqlcipher3_collation_needed()] and [sqlcipher3_collation_needed16()]. */ SQLCIPHER_API int sqlcipher3_create_collation( - sqlcipher3*, - const char *zName, - int eTextRep, - void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*) + sqlcipher3 *, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void *, int, const void *, int, const void *) ); SQLCIPHER_API int sqlcipher3_create_collation_v2( - sqlcipher3*, - const char *zName, - int eTextRep, - void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*), - void(*xDestroy)(void*) + sqlcipher3 *, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void *, int, const void *, int, const void *), + void(*xDestroy)(void *) ); SQLCIPHER_API int sqlcipher3_create_collation16( - sqlcipher3*, - const void *zName, - int eTextRep, - void *pArg, - int(*xCompare)(void*,int,const void*,int,const void*) + sqlcipher3 *, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void *, int, const void *, int, const void *) ); /* @@ -4257,14 +4292,14 @@ SQLCIPHER_API int sqlcipher3_create_collation16( ** [sqlcipher3_create_collation_v2()]. */ SQLCIPHER_API int sqlcipher3_collation_needed( - sqlcipher3*, - void*, - void(*)(void*,sqlcipher3*,int eTextRep,const char*) + sqlcipher3 *, + void *, + void(*)(void *, sqlcipher3 *, int eTextRep, const char *) ); SQLCIPHER_API int sqlcipher3_collation_needed16( - sqlcipher3*, - void*, - void(*)(void*,sqlcipher3*,int eTextRep,const void*) + sqlcipher3 *, + void *, + void(*)(void *, sqlcipher3 *, int eTextRep, const void *) ); #ifdef SQLCIPHER_HAS_CODEC @@ -4276,8 +4311,8 @@ SQLCIPHER_API int sqlcipher3_collation_needed16( ** of SQLite. */ SQLCIPHER_API int sqlcipher3_key( - sqlcipher3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The key */ + sqlcipher3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The key */ ); /* @@ -4289,26 +4324,26 @@ SQLCIPHER_API int sqlcipher3_key( ** of SQLite. */ SQLCIPHER_API int sqlcipher3_rekey( - sqlcipher3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The new key */ + sqlcipher3 *db, /* Database to be rekeyed */ + const void *pKey, int nKey /* The new key */ ); /* -** Specify the activation key for a SEE database. Unless +** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ SQLCIPHER_API void sqlcipher3_activate_see( - const char *zPassPhrase /* Activation phrase */ + const char *zPassPhrase /* Activation phrase */ ); #endif #ifdef SQLCIPHER_ENABLE_CEROD /* -** Specify the activation key for a CEROD database. Unless +** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ SQLCIPHER_API void sqlcipher3_activate_cerod( - const char *zPassPhrase /* Activation phrase */ + const char *zPassPhrase /* Activation phrase */ ); #endif @@ -4353,7 +4388,7 @@ SQLCIPHER_API int sqlcipher3_sleep(int); ** ^The [temp_store_directory pragma] may modify this variable and cause ** it to point to memory obtained from [sqlcipher3_malloc]. ^Furthermore, ** the [temp_store_directory pragma] always assumes that any string -** that this variable points to is held in memory obtained from +** that this variable points to is held in memory obtained from ** [sqlcipher3_malloc] and the pragma may attempt to free that memory ** using [sqlcipher3_free]. ** Hence, if this variable is modified directly, either it should be @@ -4383,7 +4418,7 @@ SQLCIPHER_API SQLCIPHER_EXTERN char *sqlcipher3_temp_directory; ** connection while this routine is running, then the return value ** is undefined. */ -SQLCIPHER_API int sqlcipher3_get_autocommit(sqlcipher3*); +SQLCIPHER_API int sqlcipher3_get_autocommit(sqlcipher3 *); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement @@ -4395,7 +4430,7 @@ SQLCIPHER_API int sqlcipher3_get_autocommit(sqlcipher3*); ** to the [sqlcipher3_prepare_v2()] call (or its variants) that was used to ** create the statement in the first place. */ -SQLCIPHER_API sqlcipher3 *sqlcipher3_db_handle(sqlcipher3_stmt*); +SQLCIPHER_API sqlcipher3 *sqlcipher3_db_handle(sqlcipher3_stmt *); /* ** CAPI3REF: Find the next prepared statement @@ -4410,7 +4445,8 @@ SQLCIPHER_API sqlcipher3 *sqlcipher3_db_handle(sqlcipher3_stmt*); ** [sqlcipher3_next_stmt(D,S)] must refer to an open database ** connection and in particular must not be a NULL pointer. */ -SQLCIPHER_API sqlcipher3_stmt *sqlcipher3_next_stmt(sqlcipher3 *pDb, sqlcipher3_stmt *pStmt); +SQLCIPHER_API sqlcipher3_stmt *sqlcipher3_next_stmt(sqlcipher3 *pDb, + sqlcipher3_stmt *pStmt); /* ** CAPI3REF: Commit And Rollback Notification Callbacks @@ -4456,8 +4492,10 @@ SQLCIPHER_API sqlcipher3_stmt *sqlcipher3_next_stmt(sqlcipher3 *pDb, sqlcipher3_ ** ** See also the [sqlcipher3_update_hook()] interface. */ -SQLCIPHER_API void *sqlcipher3_commit_hook(sqlcipher3*, int(*)(void*), void*); -SQLCIPHER_API void *sqlcipher3_rollback_hook(sqlcipher3*, void(*)(void *), void*); +SQLCIPHER_API void *sqlcipher3_commit_hook(sqlcipher3 *, int(*)(void *), + void *); +SQLCIPHER_API void *sqlcipher3_rollback_hook(sqlcipher3 *, void(*)(void *), + void *); /* ** CAPI3REF: Data Change Notification Callbacks @@ -4506,9 +4544,9 @@ SQLCIPHER_API void *sqlcipher3_rollback_hook(sqlcipher3*, void(*)(void *), void* ** interfaces. */ SQLCIPHER_API void *sqlcipher3_update_hook( - sqlcipher3*, - void(*)(void *,int ,char const *,char const *,sqlcipher3_int64), - void* + sqlcipher3 *, + void(*)(void *, int , char const *, char const *, sqlcipher3_int64), + void * ); /* @@ -4564,7 +4602,7 @@ SQLCIPHER_API int sqlcipher3_release_memory(int); ** as heap memory usages approaches the limit. ** ^The soft heap limit is "soft" because even though SQLite strives to stay ** below the limit, it will exceed the limit rather than generate -** an [SQLCIPHER_NOMEM] error. In other words, the soft heap limit +** an [SQLCIPHER_NOMEM] error. In other words, the soft heap limit ** is advisory only. ** ** ^The return value from sqlcipher3_soft_heap_limit64() is the size of @@ -4680,15 +4718,15 @@ SQLCIPHER_API SQLCIPHER_DEPRECATED void sqlcipher3_soft_heap_limit(int N); ** [SQLCIPHER_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined. */ SQLCIPHER_API int sqlcipher3_table_column_metadata( - sqlcipher3 *db, /* Connection handle */ - const char *zDbName, /* Database name or NULL */ - const char *zTableName, /* Table name */ - const char *zColumnName, /* Column name */ - char const **pzDataType, /* OUTPUT: Declared data type */ - char const **pzCollSeq, /* OUTPUT: Collation sequence name */ - int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ - int *pPrimaryKey, /* OUTPUT: True if column part of PK */ - int *pAutoinc /* OUTPUT: True if column is auto-increment */ + sqlcipher3 *db, /* Connection handle */ + const char *zDbName, /* Database name or NULL */ + const char *zTableName, /* Table name */ + const char *zColumnName, /* Column name */ + char const **pzDataType, /* OUTPUT: Declared data type */ + char const **pzCollSeq, /* OUTPUT: Collation sequence name */ + int *pNotNull, /* OUTPUT: True if NOT NULL constraint exists */ + int *pPrimaryKey, /* OUTPUT: True if column part of PK */ + int *pAutoinc /* OUTPUT: True if column is auto-increment */ ); /* @@ -4717,10 +4755,10 @@ SQLCIPHER_API int sqlcipher3_table_column_metadata( ** See also the [load_extension() SQL function]. */ SQLCIPHER_API int sqlcipher3_load_extension( - sqlcipher3 *db, /* Load the extension into this database connection */ - const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Derived from zFile if 0 */ - char **pzErrMsg /* Put error message here if not 0 */ + sqlcipher3 *db, /* Load the extension into this database connection */ + const char *zFile, /* Name of the shared library containing extension */ + const char *zProc, /* Entry point. Derived from zFile if 0 */ + char **pzErrMsg /* Put error message here if not 0 */ ); /* @@ -4804,8 +4842,8 @@ typedef struct sqlcipher3_module sqlcipher3_module; ** CAPI3REF: Virtual Table Object ** KEYWORDS: sqlcipher3_module {virtual table module} ** -** This structure, sometimes called a "virtual table module", -** defines the implementation of a [virtual tables]. +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual tables]. ** This structure consists mostly of methods for the module. ** ** ^A virtual table module is created by filling in a persistent @@ -4817,38 +4855,38 @@ typedef struct sqlcipher3_module sqlcipher3_module; ** any database connection. */ struct sqlcipher3_module { - int iVersion; - int (*xCreate)(sqlcipher3*, void *pAux, - int argc, const char *const*argv, - sqlcipher3_vtab **ppVTab, char**); - int (*xConnect)(sqlcipher3*, void *pAux, - int argc, const char *const*argv, - sqlcipher3_vtab **ppVTab, char**); - int (*xBestIndex)(sqlcipher3_vtab *pVTab, sqlcipher3_index_info*); - int (*xDisconnect)(sqlcipher3_vtab *pVTab); - int (*xDestroy)(sqlcipher3_vtab *pVTab); - int (*xOpen)(sqlcipher3_vtab *pVTab, sqlcipher3_vtab_cursor **ppCursor); - int (*xClose)(sqlcipher3_vtab_cursor*); - int (*xFilter)(sqlcipher3_vtab_cursor*, int idxNum, const char *idxStr, - int argc, sqlcipher3_value **argv); - int (*xNext)(sqlcipher3_vtab_cursor*); - int (*xEof)(sqlcipher3_vtab_cursor*); - int (*xColumn)(sqlcipher3_vtab_cursor*, sqlcipher3_context*, int); - int (*xRowid)(sqlcipher3_vtab_cursor*, sqlcipher3_int64 *pRowid); - int (*xUpdate)(sqlcipher3_vtab *, int, sqlcipher3_value **, sqlcipher3_int64 *); - int (*xBegin)(sqlcipher3_vtab *pVTab); - int (*xSync)(sqlcipher3_vtab *pVTab); - int (*xCommit)(sqlcipher3_vtab *pVTab); - int (*xRollback)(sqlcipher3_vtab *pVTab); - int (*xFindFunction)(sqlcipher3_vtab *pVtab, int nArg, const char *zName, - void (**pxFunc)(sqlcipher3_context*,int,sqlcipher3_value**), - void **ppArg); - int (*xRename)(sqlcipher3_vtab *pVtab, const char *zNew); - /* The methods above are in version 1 of the sqlcipher_module object. Those - ** below are for version 2 and greater. */ - int (*xSavepoint)(sqlcipher3_vtab *pVTab, int); - int (*xRelease)(sqlcipher3_vtab *pVTab, int); - int (*xRollbackTo)(sqlcipher3_vtab *pVTab, int); + int iVersion; + int (*xCreate)(sqlcipher3 *, void *pAux, + int argc, const char *const *argv, + sqlcipher3_vtab **ppVTab, char **); + int (*xConnect)(sqlcipher3 *, void *pAux, + int argc, const char *const *argv, + sqlcipher3_vtab **ppVTab, char **); + int (*xBestIndex)(sqlcipher3_vtab *pVTab, sqlcipher3_index_info *); + int (*xDisconnect)(sqlcipher3_vtab *pVTab); + int (*xDestroy)(sqlcipher3_vtab *pVTab); + int (*xOpen)(sqlcipher3_vtab *pVTab, sqlcipher3_vtab_cursor **ppCursor); + int (*xClose)(sqlcipher3_vtab_cursor *); + int (*xFilter)(sqlcipher3_vtab_cursor *, int idxNum, const char *idxStr, + int argc, sqlcipher3_value **argv); + int (*xNext)(sqlcipher3_vtab_cursor *); + int (*xEof)(sqlcipher3_vtab_cursor *); + int (*xColumn)(sqlcipher3_vtab_cursor *, sqlcipher3_context *, int); + int (*xRowid)(sqlcipher3_vtab_cursor *, sqlcipher3_int64 *pRowid); + int (*xUpdate)(sqlcipher3_vtab *, int, sqlcipher3_value **, sqlcipher3_int64 *); + int (*xBegin)(sqlcipher3_vtab *pVTab); + int (*xSync)(sqlcipher3_vtab *pVTab); + int (*xCommit)(sqlcipher3_vtab *pVTab); + int (*xRollback)(sqlcipher3_vtab *pVTab); + int (*xFindFunction)(sqlcipher3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlcipher3_context *, int, sqlcipher3_value **), + void **ppArg); + int (*xRename)(sqlcipher3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlcipher_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlcipher3_vtab *pVTab, int); + int (*xRelease)(sqlcipher3_vtab *pVTab, int); + int (*xRollbackTo)(sqlcipher3_vtab *pVTab, int); }; /* @@ -4905,29 +4943,29 @@ struct sqlcipher3_module { ** cost of approximately log(N). */ struct sqlcipher3_index_info { - /* Inputs */ - int nConstraint; /* Number of entries in aConstraint */ - struct sqlcipher3_index_constraint { - int iColumn; /* Column on left-hand side of constraint */ - unsigned char op; /* Constraint operator */ - unsigned char usable; /* True if this constraint is usable */ - int iTermOffset; /* Used internally - xBestIndex should ignore */ - } *aConstraint; /* Table of WHERE clause constraints */ - int nOrderBy; /* Number of terms in the ORDER BY clause */ - struct sqlcipher3_index_orderby { - int iColumn; /* Column number */ - unsigned char desc; /* True for DESC. False for ASC. */ - } *aOrderBy; /* The ORDER BY clause */ - /* Outputs */ - struct sqlcipher3_index_constraint_usage { - int argvIndex; /* if >0, constraint is part of argv to xFilter */ - unsigned char omit; /* Do not code a test for this constraint */ - } *aConstraintUsage; - int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from sqlcipher3_malloc */ - int needToFreeIdxStr; /* Free idxStr using sqlcipher3_free() if true */ - int orderByConsumed; /* True if output is already ordered */ - double estimatedCost; /* Estimated cost of using this index */ + /* Inputs */ + int nConstraint; /* Number of entries in aConstraint */ + struct sqlcipher3_index_constraint { + int iColumn; /* Column on left-hand side of constraint */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *aConstraint; /* Table of WHERE clause constraints */ + int nOrderBy; /* Number of terms in the ORDER BY clause */ + struct sqlcipher3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *aOrderBy; /* The ORDER BY clause */ + /* Outputs */ + struct sqlcipher3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlcipher3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlcipher3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ }; /* @@ -4954,7 +4992,7 @@ struct sqlcipher3_index_info { ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified -** by the first parameter. ^The name of the module is given by the +** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through @@ -4971,17 +5009,17 @@ struct sqlcipher3_index_info { ** destructor. */ SQLCIPHER_API int sqlcipher3_create_module( - sqlcipher3 *db, /* SQLite connection to register module with */ - const char *zName, /* Name of the module */ - const sqlcipher3_module *p, /* Methods for the module */ - void *pClientData /* Client data for xCreate/xConnect */ + sqlcipher3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlcipher3_module *p, /* Methods for the module */ + void *pClientData /* Client data for xCreate/xConnect */ ); SQLCIPHER_API int sqlcipher3_create_module_v2( - sqlcipher3 *db, /* SQLite connection to register module with */ - const char *zName, /* Name of the module */ - const sqlcipher3_module *p, /* Methods for the module */ - void *pClientData, /* Client data for xCreate/xConnect */ - void(*xDestroy)(void*) /* Module destructor function */ + sqlcipher3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlcipher3_module *p, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void *) /* Module destructor function */ ); /* @@ -5003,10 +5041,10 @@ SQLCIPHER_API int sqlcipher3_create_module_v2( ** freed by sqlcipher3_free() and the zErrMsg field will be zeroed. */ struct sqlcipher3_vtab { - const sqlcipher3_module *pModule; /* The module for this virtual table */ - int nRef; /* NO LONGER USED */ - char *zErrMsg; /* Error message from sqlcipher3_mprintf() */ - /* Virtual table implementations will typically add additional fields */ + const sqlcipher3_module *pModule; /* The module for this virtual table */ + int nRef; /* NO LONGER USED */ + char *zErrMsg; /* Error message from sqlcipher3_mprintf() */ + /* Virtual table implementations will typically add additional fields */ }; /* @@ -5027,8 +5065,8 @@ struct sqlcipher3_vtab { ** are common to all implementations. */ struct sqlcipher3_vtab_cursor { - sqlcipher3_vtab *pVtab; /* Virtual table of this cursor */ - /* Virtual table implementations will typically add additional fields */ + sqlcipher3_vtab *pVtab; /* Virtual table of this cursor */ + /* Virtual table implementations will typically add additional fields */ }; /* @@ -5039,13 +5077,13 @@ struct sqlcipher3_vtab_cursor { ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ -SQLCIPHER_API int sqlcipher3_declare_vtab(sqlcipher3*, const char *zSQL); +SQLCIPHER_API int sqlcipher3_declare_vtab(sqlcipher3 *, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table ** ** ^(Virtual tables can provide alternative implementations of functions -** using the [xFindFunction] method of the [virtual table module]. +** using the [xFindFunction] method of the [virtual table module]. ** But global versions of those functions ** must exist in order to be overloaded.)^ ** @@ -5057,7 +5095,8 @@ SQLCIPHER_API int sqlcipher3_declare_vtab(sqlcipher3*, const char *zSQL); ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ -SQLCIPHER_API int sqlcipher3_overload_function(sqlcipher3*, const char *zFuncName, int nArg); +SQLCIPHER_API int sqlcipher3_overload_function(sqlcipher3 *, + const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up @@ -5096,8 +5135,8 @@ typedef struct sqlcipher3_blob sqlcipher3_blob; ** ** ^If the flags parameter is non-zero, then the BLOB is opened for read ** and write access. ^If it is zero, the BLOB is opened for read access. -** ^It is not possible to open a column that is part of an index or primary -** key for writing. ^If [foreign key constraints] are enabled, it is +** ^It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is ** not possible to open a column that is part of a [child key] for writing. ** ** ^Note that the database name is not the filename that contains @@ -5140,13 +5179,13 @@ typedef struct sqlcipher3_blob sqlcipher3_blob; ** be released by a call to [sqlcipher3_blob_close()]. */ SQLCIPHER_API int sqlcipher3_blob_open( - sqlcipher3*, - const char *zDb, - const char *zTable, - const char *zColumn, - sqlcipher3_int64 iRow, - int flags, - sqlcipher3_blob **ppBlob + sqlcipher3 *, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlcipher3_int64 iRow, + int flags, + sqlcipher3_blob **ppBlob ); /* @@ -5171,7 +5210,8 @@ SQLCIPHER_API int sqlcipher3_blob_open( ** ** ^This function sets the database handle error code and message. */ -SQLCIPHER_API SQLCIPHER_EXPERIMENTAL int sqlcipher3_blob_reopen(sqlcipher3_blob *, sqlcipher3_int64); +SQLCIPHER_API SQLCIPHER_EXPERIMENTAL int sqlcipher3_blob_reopen( + sqlcipher3_blob *, sqlcipher3_int64); /* ** CAPI3REF: Close A BLOB Handle @@ -5200,7 +5240,7 @@ SQLCIPHER_API int sqlcipher3_blob_close(sqlcipher3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB ** -** ^Returns the size in bytes of the BLOB accessible via the +** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. @@ -5238,7 +5278,8 @@ SQLCIPHER_API int sqlcipher3_blob_bytes(sqlcipher3_blob *); ** ** See also: [sqlcipher3_blob_write()]. */ -SQLCIPHER_API int sqlcipher3_blob_read(sqlcipher3_blob *, void *Z, int N, int iOffset); +SQLCIPHER_API int sqlcipher3_blob_read(sqlcipher3_blob *, void *Z, int N, + int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally @@ -5276,7 +5317,8 @@ SQLCIPHER_API int sqlcipher3_blob_read(sqlcipher3_blob *, void *Z, int N, int iO ** ** See also: [sqlcipher3_blob_read()]. */ -SQLCIPHER_API int sqlcipher3_blob_write(sqlcipher3_blob *, const void *z, int n, int iOffset); +SQLCIPHER_API int sqlcipher3_blob_write(sqlcipher3_blob *, const void *z, int n, + int iOffset); /* ** CAPI3REF: Virtual File System Objects @@ -5308,8 +5350,8 @@ SQLCIPHER_API int sqlcipher3_blob_write(sqlcipher3_blob *, const void *z, int n, ** the default. The choice for the new VFS is arbitrary.)^ */ SQLCIPHER_API sqlcipher3_vfs *sqlcipher3_vfs_find(const char *zVfsName); -SQLCIPHER_API int sqlcipher3_vfs_register(sqlcipher3_vfs*, int makeDflt); -SQLCIPHER_API int sqlcipher3_vfs_unregister(sqlcipher3_vfs*); +SQLCIPHER_API int sqlcipher3_vfs_register(sqlcipher3_vfs *, int makeDflt); +SQLCIPHER_API int sqlcipher3_vfs_unregister(sqlcipher3_vfs *); /* ** CAPI3REF: Mutexes @@ -5426,10 +5468,10 @@ SQLCIPHER_API int sqlcipher3_vfs_unregister(sqlcipher3_vfs*); ** See also: [sqlcipher3_mutex_held()] and [sqlcipher3_mutex_notheld()]. */ SQLCIPHER_API sqlcipher3_mutex *sqlcipher3_mutex_alloc(int); -SQLCIPHER_API void sqlcipher3_mutex_free(sqlcipher3_mutex*); -SQLCIPHER_API void sqlcipher3_mutex_enter(sqlcipher3_mutex*); -SQLCIPHER_API int sqlcipher3_mutex_try(sqlcipher3_mutex*); -SQLCIPHER_API void sqlcipher3_mutex_leave(sqlcipher3_mutex*); +SQLCIPHER_API void sqlcipher3_mutex_free(sqlcipher3_mutex *); +SQLCIPHER_API void sqlcipher3_mutex_enter(sqlcipher3_mutex *); +SQLCIPHER_API int sqlcipher3_mutex_try(sqlcipher3_mutex *); +SQLCIPHER_API void sqlcipher3_mutex_leave(sqlcipher3_mutex *); /* ** CAPI3REF: Mutex Methods Object @@ -5498,15 +5540,15 @@ SQLCIPHER_API void sqlcipher3_mutex_leave(sqlcipher3_mutex*); */ typedef struct sqlcipher3_mutex_methods sqlcipher3_mutex_methods; struct sqlcipher3_mutex_methods { - int (*xMutexInit)(void); - int (*xMutexEnd)(void); - sqlcipher3_mutex *(*xMutexAlloc)(int); - void (*xMutexFree)(sqlcipher3_mutex *); - void (*xMutexEnter)(sqlcipher3_mutex *); - int (*xMutexTry)(sqlcipher3_mutex *); - void (*xMutexLeave)(sqlcipher3_mutex *); - int (*xMutexHeld)(sqlcipher3_mutex *); - int (*xMutexNotheld)(sqlcipher3_mutex *); + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlcipher3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlcipher3_mutex *); + void (*xMutexEnter)(sqlcipher3_mutex *); + int (*xMutexTry)(sqlcipher3_mutex *); + void (*xMutexLeave)(sqlcipher3_mutex *); + int (*xMutexHeld)(sqlcipher3_mutex *); + int (*xMutexNotheld)(sqlcipher3_mutex *); }; /* @@ -5539,8 +5581,8 @@ struct sqlcipher3_mutex_methods { ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG -SQLCIPHER_API int sqlcipher3_mutex_held(sqlcipher3_mutex*); -SQLCIPHER_API int sqlcipher3_mutex_notheld(sqlcipher3_mutex*); +SQLCIPHER_API int sqlcipher3_mutex_held(sqlcipher3_mutex *); +SQLCIPHER_API int sqlcipher3_mutex_notheld(sqlcipher3_mutex *); #endif /* @@ -5567,13 +5609,13 @@ SQLCIPHER_API int sqlcipher3_mutex_notheld(sqlcipher3_mutex*); /* ** CAPI3REF: Retrieve the mutex for a database connection ** -** ^This interface returns a pointer the [sqlcipher3_mutex] object that +** ^This interface returns a pointer the [sqlcipher3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ -SQLCIPHER_API sqlcipher3_mutex *sqlcipher3_db_mutex(sqlcipher3*); +SQLCIPHER_API sqlcipher3_mutex *sqlcipher3_db_mutex(sqlcipher3 *); /* ** CAPI3REF: Low-Level Control Of Database Files @@ -5607,7 +5649,8 @@ SQLCIPHER_API sqlcipher3_mutex *sqlcipher3_db_mutex(sqlcipher3*); ** ** See also: [SQLCIPHER_FCNTL_LOCKSTATE] */ -SQLCIPHER_API int sqlcipher3_file_control(sqlcipher3*, const char *zDbName, int op, void*); +SQLCIPHER_API int sqlcipher3_file_control(sqlcipher3 *, const char *zDbName, + int op, void *); /* ** CAPI3REF: Testing Interface @@ -5686,7 +5729,8 @@ SQLCIPHER_API int sqlcipher3_test_control(int op, ...); ** ** See also: [sqlcipher3_db_status()] */ -SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, + int resetFlag); /* @@ -5711,7 +5755,7 @@ SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int ** <dd>This parameter records the largest memory allocation request ** handed to [sqlcipher3_malloc()] or [sqlcipher3_realloc()] (or their ** internal equivalents). Only the value returned in the -** *pHighwater parameter to [sqlcipher3_status()] is of interest. +** *pHighwater parameter to [sqlcipher3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLCIPHER_STATUS_MALLOC_COUNT]] ^(<dt>SQLCIPHER_STATUS_MALLOC_COUNT</dt> @@ -5720,11 +5764,11 @@ SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int ** ** [[SQLCIPHER_STATUS_PAGECACHE_USED]] ^(<dt>SQLCIPHER_STATUS_PAGECACHE_USED</dt> ** <dd>This parameter returns the number of pages used out of the -** [pagecache memory allocator] that was configured using +** [pagecache memory allocator] that was configured using ** [SQLCIPHER_CONFIG_PAGECACHE]. The ** value returned is in pages, not in bytes.</dd>)^ ** -** [[SQLCIPHER_STATUS_PAGECACHE_OVERFLOW]] +** [[SQLCIPHER_STATUS_PAGECACHE_OVERFLOW]] ** ^(<dt>SQLCIPHER_STATUS_PAGECACHE_OVERFLOW</dt> ** <dd>This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLCIPHER_CONFIG_PAGECACHE] @@ -5737,7 +5781,7 @@ SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int ** [[SQLCIPHER_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLCIPHER_STATUS_PAGECACHE_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [pagecache memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlcipher3_status()] is of interest. +** *pHighwater parameter to [sqlcipher3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLCIPHER_STATUS_SCRATCH_USED]] ^(<dt>SQLCIPHER_STATUS_SCRATCH_USED</dt> @@ -5761,7 +5805,7 @@ SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int ** [[SQLCIPHER_STATUS_SCRATCH_SIZE]] ^(<dt>SQLCIPHER_STATUS_SCRATCH_SIZE</dt> ** <dd>This parameter records the largest memory allocation request ** handed to [scratch memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlcipher3_status()] is of interest. +** *pHighwater parameter to [sqlcipher3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.</dd>)^ ** ** [[SQLCIPHER_STATUS_PARSER_STACK]] ^(<dt>SQLCIPHER_STATUS_PARSER_STACK</dt> @@ -5785,12 +5829,12 @@ SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int /* ** CAPI3REF: Database Connection Status ** -** ^This interface is used to retrieve runtime status information +** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the ** database connection object to be interrogated. ^The second argument ** is an integer constant, taken from the set of ** [SQLCIPHER_DBSTATUS options], that -** determines the parameter to interrogate. The set of +** determines the parameter to interrogate. The set of ** [SQLCIPHER_DBSTATUS options] is likely ** to grow in future releases of SQLite. ** @@ -5804,7 +5848,8 @@ SQLCIPHER_API int sqlcipher3_status(int op, int *pCurrent, int *pHighwater, int ** ** See also: [sqlcipher3_status()] and [sqlcipher3_stmt_status()]. */ -SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3 *, int op, int *pCur, + int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections @@ -5825,7 +5870,7 @@ SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3*, int op, int *pCur, int *pHiw ** checked out.</dd>)^ ** ** [[SQLCIPHER_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLCIPHER_DBSTATUS_LOOKASIDE_HIT</dt> -** <dd>This parameter returns the number malloc attempts that were +** <dd>This parameter returns the number malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; ** the current value is always zero.)^ ** @@ -5853,7 +5898,7 @@ SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3*, int op, int *pCur, int *pHiw ** [[SQLCIPHER_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLCIPHER_DBSTATUS_SCHEMA_USED</dt> ** <dd>This parameter returns the approximate number of of bytes of heap ** memory used to store the schema for all databases associated -** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ ** ^The full amount of memory used by the schemas is reported, even if the ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. @@ -5868,13 +5913,13 @@ SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3*, int op, int *pCur, int *pHiw ** ** [[SQLCIPHER_DBSTATUS_CACHE_HIT]] ^(<dt>SQLCIPHER_DBSTATUS_CACHE_HIT</dt> ** <dd>This parameter returns the number of pager cache hits that have -** occurred.)^ ^The highwater mark associated with SQLCIPHER_DBSTATUS_CACHE_HIT +** occurred.)^ ^The highwater mark associated with SQLCIPHER_DBSTATUS_CACHE_HIT ** is always 0. ** </dd> ** ** [[SQLCIPHER_DBSTATUS_CACHE_MISS]] ^(<dt>SQLCIPHER_DBSTATUS_CACHE_MISS</dt> ** <dd>This parameter returns the number of pager cache misses that have -** occurred.)^ ^The highwater mark associated with SQLCIPHER_DBSTATUS_CACHE_MISS +** occurred.)^ ^The highwater mark associated with SQLCIPHER_DBSTATUS_CACHE_MISS ** is always 0. ** </dd> ** </dl> @@ -5901,7 +5946,7 @@ SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3*, int op, int *pCur, int *pHiw ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate ** that the prepared statement is using a full table scan rather than -** an index. +** an index. ** ** ^(This interface is used to retrieve and reset counter values from ** a [prepared statement]. The first argument is the prepared statement @@ -5914,7 +5959,8 @@ SQLCIPHER_API int sqlcipher3_db_status(sqlcipher3*, int op, int *pCur, int *pHiw ** ** See also: [sqlcipher3_status()] and [sqlcipher3_db_status()]. */ -SQLCIPHER_API int sqlcipher3_stmt_status(sqlcipher3_stmt*, int op,int resetFlg); +SQLCIPHER_API int sqlcipher3_stmt_status(sqlcipher3_stmt *, int op, + int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements @@ -5928,7 +5974,7 @@ SQLCIPHER_API int sqlcipher3_stmt_status(sqlcipher3_stmt*, int op,int resetFlg); ** [[SQLCIPHER_STMTSTATUS_FULLSCAN_STEP]] <dt>SQLCIPHER_STMTSTATUS_FULLSCAN_STEP</dt> ** <dd>^This is the number of times that SQLite has stepped forward in ** a table as part of a full table scan. Large numbers for this counter -** may indicate opportunities for performance improvement through +** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** ** [[SQLCIPHER_STMTSTATUS_SORT]] <dt>SQLCIPHER_STMTSTATUS_SORT</dt> @@ -5966,15 +6012,15 @@ typedef struct sqlcipher3_pcache sqlcipher3_pcache; ** KEYWORDS: {page cache} ** ** ^(The [sqlcipher3_config]([SQLCIPHER_CONFIG_PCACHE], ...) interface can -** register an alternative page cache implementation by passing in an +** register an alternative page cache implementation by passing in an ** instance of the sqlcipher3_pcache_methods structure.)^ -** In many applications, most of the heap memory allocated by +** In many applications, most of the heap memory allocated by ** SQLite is used for the page cache. -** By implementing a +** By implementing a ** custom page cache using this API, an application can better control -** the amount of memory consumed by SQLite, the way in which -** that memory is allocated and released, and the policies used to -** determine exactly which parts of a database file are cached and for +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for ** how long. ** ** The alternative page cache mechanism is an @@ -5987,19 +6033,19 @@ typedef struct sqlcipher3_pcache sqlcipher3_pcache; ** [sqlcipher3_config()] returns.)^ ** ** [[the xInit() page cache method]] -** ^(The xInit() method is called once for each effective +** ^(The xInit() method is called once for each effective ** call to [sqlcipher3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() ** method is passed a copy of the sqlcipher3_pcache_methods.pArg value.)^ -** The intent of the xInit() method is to set up global data structures -** required by the custom page cache implementation. -** ^(If the xInit() method is NULL, then the +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache.)^ ** ** [[the xShutdown() page cache method]] ** ^The xShutdown() method is called by [sqlcipher3_shutdown()]. -** It can be used to clean up +** It can be used to clean up ** any outstanding resources before process shutdown, if required. ** ^The xShutdown() method may be NULL. ** @@ -6033,7 +6079,7 @@ typedef struct sqlcipher3_pcache sqlcipher3_pcache; ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to -** false will always have the "discard" flag set to true. +** false will always have the "discard" flag set to true. ** ^Hence, a cache created with bPurgeable false will ** never contain any unpinned pages. ** @@ -6048,13 +6094,13 @@ typedef struct sqlcipher3_pcache sqlcipher3_pcache; ** [[the xPagecount() page cache methods]] ** The xPagecount() method must return the number of pages currently ** stored in the cache, both pinned and unpinned. -** +** ** [[the xFetch() page cache methods]] -** The xFetch() method locates a page in the cache and returns a pointer to +** The xFetch() method locates a page in the cache and returns a pointer to ** the page, or a NULL pointer. ** A "page", in this context, means a buffer of szPage bytes aligned at an ** 8-byte boundary. The page to be fetched is determined by the key. ^The -** minimum key value is 1. After it has been retrieved using xFetch, the page +** minimum key value is 1. After it has been retrieved using xFetch, the page ** is considered to be "pinned". ** ** If the requested page is already in the page cache, then the page cache @@ -6087,8 +6133,8 @@ typedef struct sqlcipher3_pcache sqlcipher3_pcache; ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** -** The cache must not perform any reference counting. A single -** call to xUnpin() unpins the page regardless of the number of prior calls +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls ** to xFetch(). ** ** [[the xRekey() page cache methods]] @@ -6113,17 +6159,17 @@ typedef struct sqlcipher3_pcache sqlcipher3_pcache; */ typedef struct sqlcipher3_pcache_methods sqlcipher3_pcache_methods; struct sqlcipher3_pcache_methods { - void *pArg; - int (*xInit)(void*); - void (*xShutdown)(void*); - sqlcipher3_pcache *(*xCreate)(int szPage, int bPurgeable); - void (*xCachesize)(sqlcipher3_pcache*, int nCachesize); - int (*xPagecount)(sqlcipher3_pcache*); - void *(*xFetch)(sqlcipher3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(sqlcipher3_pcache*, void*, int discard); - void (*xRekey)(sqlcipher3_pcache*, void*, unsigned oldKey, unsigned newKey); - void (*xTruncate)(sqlcipher3_pcache*, unsigned iLimit); - void (*xDestroy)(sqlcipher3_pcache*); + void *pArg; + int (*xInit)(void *); + void (*xShutdown)(void *); + sqlcipher3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlcipher3_pcache *, int nCachesize); + int (*xPagecount)(sqlcipher3_pcache *); + void *(*xFetch)(sqlcipher3_pcache *, unsigned key, int createFlag); + void (*xUnpin)(sqlcipher3_pcache *, void *, int discard); + void (*xRekey)(sqlcipher3_pcache *, void *, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlcipher3_pcache *, unsigned iLimit); + void (*xDestroy)(sqlcipher3_pcache *); }; /* @@ -6143,7 +6189,7 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** ** The backup API copies the content of one database into another. ** It is useful either for creating backups of databases or -** for copying in-memory databases to or from persistent files. +** for copying in-memory databases to or from persistent files. ** ** See Also: [Using the SQLite Online Backup API] ** @@ -6154,28 +6200,28 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** ^Thus, the backup may be performed on a live source database without ** preventing other database connections from ** reading or writing to the source database while the backup is underway. -** -** ^(To perform a backup operation: +** +** ^(To perform a backup operation: ** <ol> ** <li><b>sqlcipher3_backup_init()</b> is called once to initialize the -** backup, -** <li><b>sqlcipher3_backup_step()</b> is called one or more times to transfer +** backup, +** <li><b>sqlcipher3_backup_step()</b> is called one or more times to transfer ** the data between the two databases, and finally -** <li><b>sqlcipher3_backup_finish()</b> is called to release all resources -** associated with the backup operation. +** <li><b>sqlcipher3_backup_finish()</b> is called to release all resources +** associated with the backup operation. ** </ol>)^ ** There should be exactly one call to sqlcipher3_backup_finish() for each ** successful call to sqlcipher3_backup_init(). ** ** [[sqlcipher3_backup_init()]] <b>sqlcipher3_backup_init()</b> ** -** ^The D and N arguments to sqlcipher3_backup_init(D,N,S,M) are the -** [database connection] associated with the destination database +** ^The D and N arguments to sqlcipher3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database ** and the database name, respectively. ** ^The database name is "main" for the main database, "temp" for the ** temporary database, or the name specified after the AS keyword in ** an [ATTACH] statement for an attached database. -** ^The S and M arguments passed to +** ^The S and M arguments passed to ** sqlcipher3_backup_init(D,N,S,M) identify the [database connection] ** and database name of the source database, respectively. ** ^The source and destination [database connections] (parameters S and D) @@ -6191,14 +6237,14 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** ^A successful call to sqlcipher3_backup_init() returns a pointer to an ** [sqlcipher3_backup] object. ** ^The [sqlcipher3_backup] object may be used with the sqlcipher3_backup_step() and -** sqlcipher3_backup_finish() functions to perform the specified backup +** sqlcipher3_backup_finish() functions to perform the specified backup ** operation. ** ** [[sqlcipher3_backup_step()]] <b>sqlcipher3_backup_step()</b> ** -** ^Function sqlcipher3_backup_step(B,N) will copy up to N pages between +** ^Function sqlcipher3_backup_step(B,N) will copy up to N pages between ** the source and destination databases specified by [sqlcipher3_backup] object B. -** ^If N is negative, all remaining source pages are copied. +** ^If N is negative, all remaining source pages are copied. ** ^If sqlcipher3_backup_step(B,N) successfully copies N pages and there ** are still more pages to be copied, then the function returns [SQLCIPHER_OK]. ** ^If sqlcipher3_backup_step(B,N) successfully finishes copying all pages @@ -6220,8 +6266,8 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** ** ^If sqlcipher3_backup_step() cannot obtain a required file-system lock, then ** the [sqlcipher3_busy_handler | busy-handler function] -** is invoked (if one is specified). ^If the -** busy-handler returns non-zero before the lock is available, then +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then ** [SQLCIPHER_BUSY] is returned to the caller. ^In this case the call to ** sqlcipher3_backup_step() can be retried later. ^If the source ** [database connection] @@ -6229,15 +6275,15 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** is called, then [SQLCIPHER_LOCKED] is returned immediately. ^Again, in this ** case the call to sqlcipher3_backup_step() can be retried later on. ^(If ** [SQLCIPHER_IOERR_ACCESS | SQLCIPHER_IOERR_XXX], [SQLCIPHER_NOMEM], or -** [SQLCIPHER_READONLY] is returned, then -** there is no point in retrying the call to sqlcipher3_backup_step(). These -** errors are considered fatal.)^ The application must accept -** that the backup operation has failed and pass the backup operation handle +** [SQLCIPHER_READONLY] is returned, then +** there is no point in retrying the call to sqlcipher3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle ** to the sqlcipher3_backup_finish() to release associated resources. ** ** ^The first call to sqlcipher3_backup_step() obtains an exclusive lock -** on the destination file. ^The exclusive lock is not released until either -** sqlcipher3_backup_finish() is called or the backup operation is complete +** on the destination file. ^The exclusive lock is not released until either +** sqlcipher3_backup_finish() is called or the backup operation is complete ** and sqlcipher3_backup_step() returns [SQLCIPHER_DONE]. ^Every call to ** sqlcipher3_backup_step() obtains a [shared lock] on the source database that ** lasts for the duration of the sqlcipher3_backup_step() call. @@ -6246,18 +6292,18 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically -** restarted by the next call to sqlcipher3_backup_step(). ^If the source +** restarted by the next call to sqlcipher3_backup_step(). ^If the source ** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** ** [[sqlcipher3_backup_finish()]] <b>sqlcipher3_backup_finish()</b> ** -** When sqlcipher3_backup_step() has returned [SQLCIPHER_DONE], or when the +** When sqlcipher3_backup_step() has returned [SQLCIPHER_DONE], or when the ** application wishes to abandon the backup operation, the application ** should destroy the [sqlcipher3_backup] by passing it to sqlcipher3_backup_finish(). ** ^The sqlcipher3_backup_finish() interfaces releases all -** resources associated with the [sqlcipher3_backup] object. +** resources associated with the [sqlcipher3_backup] object. ** ^If sqlcipher3_backup_step() has not yet returned [SQLCIPHER_DONE], then any ** active write-transaction on the destination database is rolled back. ** The [sqlcipher3_backup] object is invalid @@ -6297,8 +6343,8 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** connections, then the source database connection may be used concurrently ** from within other threads. ** -** However, the application must guarantee that the destination -** [database connection] is not passed to any other API (by any thread) after +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after ** sqlcipher3_backup_init() is called and before the corresponding call to ** sqlcipher3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] @@ -6309,11 +6355,11 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means -** that the application must guarantee that the disk file being +** that the application must guarantee that the disk file being ** backed up to is not accessed by any connection within the process, ** not just the specific connection that was passed to sqlcipher3_backup_init(). ** -** The [sqlcipher3_backup] object itself is partially threadsafe. Multiple +** The [sqlcipher3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlcipher3_backup_step(). ** However, the sqlcipher3_backup_remaining() and sqlcipher3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the @@ -6321,10 +6367,10 @@ typedef struct sqlcipher3_backup sqlcipher3_backup; ** possible that they return invalid values. */ SQLCIPHER_API sqlcipher3_backup *sqlcipher3_backup_init( - sqlcipher3 *pDest, /* Destination database handle */ - const char *zDestName, /* Destination database name */ - sqlcipher3 *pSource, /* Source database handle */ - const char *zSourceName /* Source database name */ + sqlcipher3 *pDest, /* Destination database handle */ + const char *zDestName, /* Destination database name */ + sqlcipher3 *pSource, /* Source database handle */ + const char *zSourceName /* Source database name */ ); SQLCIPHER_API int sqlcipher3_backup_step(sqlcipher3_backup *p, int nPage); SQLCIPHER_API int sqlcipher3_backup_finish(sqlcipher3_backup *p); @@ -6337,8 +6383,8 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLCIPHER_LOCKED] error if the required locks on the shared-cache or ** individual tables within the shared-cache cannot be obtained. See -** [SQLite Shared-Cache Mode] for a description of shared-cache locking. -** ^This API may be used to register a callback that SQLite will invoke +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke ** when the connection currently holding the required lock relinquishes it. ** ^This API is only available if the library was compiled with the ** [SQLCIPHER_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. @@ -6346,14 +6392,14 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** See Also: [Using the SQLite Unlock Notification Feature]. ** ** ^Shared-cache locks are released when a database connection concludes -** its current transaction, either by committing it or rolling it back. +** its current transaction, either by committing it or rolling it back. ** ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLCIPHER_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that -** has locked the required resource is stored internally. ^After an +** has locked the required resource is stored internally. ^After an ** application receives an SQLCIPHER_LOCKED error, it may call the -** sqlcipher3_unlock_notify() method with the blocked connection handle as +** sqlcipher3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlcipher3_step] or [sqlcipher3_close] @@ -6367,15 +6413,15 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds -** a read-lock on the same table, then SQLite arbitrarily selects one of +** a read-lock on the same table, then SQLite arbitrarily selects one of ** the other connections to use as the blocking connection. ** -** ^(There may be at most one unlock-notify callback registered by a +** ^(There may be at most one unlock-notify callback registered by a ** blocked connection. If sqlcipher3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlcipher3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlcipher3_close()]. ** @@ -6388,7 +6434,7 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** ** <b>Callback Invocation Details</b> ** -** When an unlock-notify callback is registered, the application provides a +** When an unlock-notify callback is registered, the application provides a ** single void* pointer that is passed to the callback when it is invoked. ** However, the signature of the callback function allows SQLite to pass ** it an array of void* context pointers. The first argument passed to @@ -6401,12 +6447,12 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** same callback function, then instead of invoking the callback function ** multiple times, it is invoked once with the set of void* context pointers ** specified by the blocked connections bundled together into an array. -** This gives the application an opportunity to prioritize any actions +** This gives the application an opportunity to prioritize any actions ** related to the set of unblocked database connections. ** ** <b>Deadlock Detection</b> ** -** Assuming that after registering for an unlock-notify callback a +** Assuming that after registering for an unlock-notify callback a ** database waits for the callback to be issued before taking any further ** action (a reasonable assumption), then using this API may cause the ** application to deadlock. For example, if connection X is waiting for @@ -6429,7 +6475,7 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** ** <b>The "DROP TABLE" Exception</b> ** -** When a call to [sqlcipher3_step()] returns SQLCIPHER_LOCKED, it is almost +** When a call to [sqlcipher3_step()] returns SQLCIPHER_LOCKED, it is almost ** always appropriate to call sqlcipher3_unlock_notify(). There is however, ** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, ** SQLite checks if there are any currently executing SELECT statements @@ -6442,13 +6488,13 @@ SQLCIPHER_API int sqlcipher3_backup_pagecount(sqlcipher3_backup *p); ** One way around this problem is to check the extended error code returned ** by an sqlcipher3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLCIPHER_LOCKED_SHAREDCACHE. Otherwise, in -** the special "DROP TABLE/INDEX" case, the extended error code is just +** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLCIPHER_LOCKED.)^ */ SQLCIPHER_API int sqlcipher3_unlock_notify( - sqlcipher3 *pBlocked, /* Waiting connection */ - void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ - void *pNotifyArg /* Argument to pass to xNotify */ + sqlcipher3 *pBlocked, /* Waiting connection */ + void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ + void *pNotifyArg /* Argument to pass to xNotify */ ); @@ -6457,7 +6503,7 @@ SQLCIPHER_API int sqlcipher3_unlock_notify( ** ** ^The [sqlcipher3_strnicmp()] API allows applications and extensions to ** compare the contents of two buffers containing UTF-8 strings in a -** case-independent fashion, using the same definition of case independence +** case-independent fashion, using the same definition of case independence ** that SQLite uses internally when comparing identifiers. */ SQLCIPHER_API int sqlcipher3_strnicmp(const char *, const char *, int); @@ -6491,10 +6537,10 @@ SQLCIPHER_API void sqlcipher3_log(int iErrCode, const char *zFormat, ...); ** ^The [sqlcipher3_wal_hook()] function is used to register a callback that ** will be invoked each time a database connection commits data to a ** [write-ahead log] (i.e. whenever a transaction is committed in -** [journal_mode | journal_mode=WAL mode]). +** [journal_mode | journal_mode=WAL mode]). ** -** ^The callback is invoked by SQLite after the commit has taken place and -** the associated write-lock on the database released, so the implementation +** ^The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released, so the implementation ** may read, write or [checkpoint] the database as required. ** ** ^The first parameter passed to the callback function when it is invoked @@ -6513,7 +6559,7 @@ SQLCIPHER_API void sqlcipher3_log(int iErrCode, const char *zFormat, ...); ** that does not correspond to any valid SQLite error code, the results ** are undefined. ** -** A single database handle may have at most a single write-ahead log callback +** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlcipher3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^Note that the ** [sqlcipher3_wal_autocheckpoint()] interface and the @@ -6521,9 +6567,9 @@ SQLCIPHER_API void sqlcipher3_log(int iErrCode, const char *zFormat, ...); ** those overwrite any prior [sqlcipher3_wal_hook()] settings. */ SQLCIPHER_API void *sqlcipher3_wal_hook( - sqlcipher3*, - int(*)(void *,sqlcipher3*,const char*,int), - void* + sqlcipher3 *, + int(*)(void *, sqlcipher3 *, const char *, int), + void * ); /* @@ -6533,7 +6579,7 @@ SQLCIPHER_API void *sqlcipher3_wal_hook( ** [sqlcipher3_wal_hook()] that causes any database on [database connection] D ** to automatically [checkpoint] ** after committing a transaction if there are N or -** more frames in the [write-ahead log] file. ^Passing zero or +** more frames in the [write-ahead log] file. ^Passing zero or ** a negative value as the nFrame parameter disables automatic ** checkpoints entirely. ** @@ -6574,15 +6620,15 @@ SQLCIPHER_API int sqlcipher3_wal_checkpoint(sqlcipher3 *db, const char *zDb); /* ** CAPI3REF: Checkpoint a database ** -** Run a checkpoint operation on WAL database zDb attached to database -** handle db. The specific operation is determined by the value of the +** Run a checkpoint operation on WAL database zDb attached to database +** handle db. The specific operation is determined by the value of the ** eMode parameter: ** ** <dl> ** <dt>SQLCIPHER_CHECKPOINT_PASSIVE<dd> -** Checkpoint as many frames as possible without waiting for any database +** Checkpoint as many frames as possible without waiting for any database ** readers or writers to finish. Sync the db file if all frames in the log -** are checkpointed. This mode is the same as calling +** are checkpointed. This mode is the same as calling ** sqlcipher3_wal_checkpoint(). The busy-handler callback is never invoked. ** ** <dt>SQLCIPHER_CHECKPOINT_FULL<dd> @@ -6593,10 +6639,10 @@ SQLCIPHER_API int sqlcipher3_wal_checkpoint(sqlcipher3 *db, const char *zDb); ** but not database readers. ** ** <dt>SQLCIPHER_CHECKPOINT_RESTART<dd> -** This mode works the same way as SQLCIPHER_CHECKPOINT_FULL, except after +** This mode works the same way as SQLCIPHER_CHECKPOINT_FULL, except after ** checkpointing the log file it blocks (calls the busy-handler callback) -** until all readers are reading from the database file only. This ensures -** that the next client to write to the database file restarts the log file +** until all readers are reading from the database file only. This ensures +** that the next client to write to the database file restarts the log file ** from the beginning. This call blocks database writers while it is running, ** but not database readers. ** </dl> @@ -6610,30 +6656,30 @@ SQLCIPHER_API int sqlcipher3_wal_checkpoint(sqlcipher3 *db, const char *zDb); ** before returning to communicate this to the caller. ** ** All calls obtain an exclusive "checkpoint" lock on the database file. If -** any other process is running a checkpoint operation at the same time, the -** lock cannot be obtained and SQLCIPHER_BUSY is returned. Even if there is a +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLCIPHER_BUSY is returned. Even if there is a ** busy-handler configured, it will not be invoked in this case. ** -** The SQLCIPHER_CHECKPOINT_FULL and RESTART modes also obtain the exclusive +** The SQLCIPHER_CHECKPOINT_FULL and RESTART modes also obtain the exclusive ** "writer" lock on the database file. If the writer lock cannot be obtained ** immediately, and a busy-handler is configured, it is invoked and the writer ** lock retried until either the busy-handler returns 0 or the lock is ** successfully obtained. The busy-handler is also invoked while waiting for ** database readers as described above. If the busy-handler returns 0 before ** the writer lock is obtained or while waiting for database readers, the -** checkpoint operation proceeds from that point in the same way as -** SQLCIPHER_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** checkpoint operation proceeds from that point in the same way as +** SQLCIPHER_CHECKPOINT_PASSIVE - checkpointing as many frames as possible ** without blocking any further. SQLCIPHER_BUSY is returned in this case. ** ** If parameter zDb is NULL or points to a zero length string, then the ** specified operation is attempted on all WAL databases. In this case the -** values written to output parameters *pnLog and *pnCkpt are undefined. If -** an SQLCIPHER_BUSY error is encountered when processing one or more of the -** attached WAL databases, the operation is still attempted on any remaining -** attached databases and SQLCIPHER_BUSY is returned to the caller. If any other -** error occurs while processing an attached database, processing is abandoned -** and the error code returned to the caller immediately. If no error -** (SQLCIPHER_BUSY or otherwise) is encountered while processing the attached +** values written to output parameters *pnLog and *pnCkpt are undefined. If +** an SQLCIPHER_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLCIPHER_BUSY is returned to the caller. If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code returned to the caller immediately. If no error +** (SQLCIPHER_BUSY or otherwise) is encountered while processing the attached ** databases, SQLCIPHER_OK is returned. ** ** If database zDb is the name of an attached database that is not in WAL @@ -6642,11 +6688,11 @@ SQLCIPHER_API int sqlcipher3_wal_checkpoint(sqlcipher3 *db, const char *zDb); ** attached database, SQLCIPHER_ERROR is returned to the caller. */ SQLCIPHER_API int sqlcipher3_wal_checkpoint_v2( - sqlcipher3 *db, /* Database handle */ - const char *zDb, /* Name of attached database (or NULL) */ - int eMode, /* SQLCIPHER_CHECKPOINT_* value */ - int *pnLog, /* OUT: Size of WAL log in frames */ - int *pnCkpt /* OUT: Total number of frames checkpointed */ + sqlcipher3 *db, /* Database handle */ + const char *zDb, /* Name of attached database (or NULL) */ + int eMode, /* SQLCIPHER_CHECKPOINT_* value */ + int *pnLog, /* OUT: Size of WAL log in frames */ + int *pnCkpt /* OUT: Total number of frames checkpointed */ ); /* @@ -6675,7 +6721,7 @@ SQLCIPHER_API int sqlcipher3_wal_checkpoint_v2( ** this function. (See [SQLCIPHER_VTAB_CONSTRAINT_SUPPORT].) Further options ** may be added in the future. */ -SQLCIPHER_API int sqlcipher3_vtab_config(sqlcipher3*, int op, ...); +SQLCIPHER_API int sqlcipher3_vtab_config(sqlcipher3 *, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options @@ -6699,20 +6745,20 @@ SQLCIPHER_API int sqlcipher3_vtab_config(sqlcipher3*, int op, ...); ** If X is non-zero, then the virtual table implementation guarantees ** that if [xUpdate] returns [SQLCIPHER_CONSTRAINT], it will do so before ** any modifications to internal or persistent data structures have been made. -** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite ** is able to roll back a statement or database transaction, and abandon -** or continue processing the current SQL statement as appropriate. +** or continue processing the current SQL statement as appropriate. ** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns ** [SQLCIPHER_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode ** had been ABORT. ** ** Virtual table implementations that are required to handle OR REPLACE -** must do so within the [xUpdate] method. If a call to the -** [sqlcipher3_vtab_on_conflict()] function indicates that the current ON -** CONFLICT policy is REPLACE, the virtual table implementation should +** must do so within the [xUpdate] method. If a call to the +** [sqlcipher3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should ** silently replace the appropriate rows within the xUpdate callback and ** return SQLCIPHER_OK. Or, if this is not possible, it may return -** SQLCIPHER_CONSTRAINT, in which case SQLite falls back to OR ABORT +** SQLCIPHER_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. ** </dl> */ @@ -6792,10 +6838,11 @@ typedef struct sqlcipher3_rtree_geometry sqlcipher3_rtree_geometry; ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLCIPHER_API int sqlcipher3_rtree_geometry_callback( - sqlcipher3 *db, - const char *zGeom, - int (*xGeom)(sqlcipher3_rtree_geometry *, int nCoord, double *aCoord, int *pRes), - void *pContext + sqlcipher3 *db, + const char *zGeom, + int (*xGeom)(sqlcipher3_rtree_geometry *, int nCoord, double *aCoord, + int *pRes), + void *pContext ); @@ -6804,11 +6851,11 @@ SQLCIPHER_API int sqlcipher3_rtree_geometry_callback( ** argument to callbacks registered using rtree_geometry_callback(). */ struct sqlcipher3_rtree_geometry { - void *pContext; /* Copy of pContext passed to s_r_g_c() */ - int nParam; /* Size of array aParam[] */ - double *aParam; /* Parameters passed to SQL geom function */ - void *pUser; /* Callback implementation user data */ - void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ + void *pContext; /* Copy of pContext passed to s_r_g_c() */ + int nParam; /* Size of array aParam[] */ + double *aParam; /* Parameters passed to SQL geom function */ + void *pUser; /* Callback implementation user data */ + void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ }; diff --git a/src/pam_plugin/pam-key-manager-plugin.cpp b/src/pam_plugin/pam-key-manager-plugin.cpp index 792e6aec..74a1d252 100644 --- a/src/pam_plugin/pam-key-manager-plugin.cpp +++ b/src/pam_plugin/pam-key-manager-plugin.cpp @@ -40,133 +40,157 @@ namespace { #define PASSWORD_SHADOWED "x" std::string old_password; -bool identify_user_pwd(pam_handle_t *pamh, uid_t & uid, std::string & passwd) +bool identify_user_pwd(pam_handle_t *pamh, uid_t &uid, std::string &passwd) { - int pam_err; - const char *user; - if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) - return true; - struct passwd *pwd; - if ((pwd = getpwnam(user)) == NULL) - return true; - if (strcmp(pwd->pw_passwd, PASSWORD_SHADOWED) == 0) { - struct spwd *pwd_sh; - if ((pwd_sh = getspnam(user)) == NULL) - return true; - passwd = std::string(pwd_sh->sp_pwdp); - } else { - passwd = std::string(pwd->pw_passwd); - } - uid = pwd->pw_uid; - return false; + int pam_err; + const char *user; + + if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) + return true; + + struct passwd *pwd; + + if ((pwd = getpwnam(user)) == NULL) + return true; + + if (strcmp(pwd->pw_passwd, PASSWORD_SHADOWED) == 0) { + struct spwd *pwd_sh; + + if ((pwd_sh = getspnam(user)) == NULL) + return true; + + passwd = std::string(pwd_sh->sp_pwdp); + } else { + passwd = std::string(pwd->pw_passwd); + } + + uid = pwd->pw_uid; + return false; } } COMMON_API PAM_EXTERN int -pam_sm_open_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/, const char **/*argv*/) +pam_sm_open_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/, + const char **/*argv*/) { - // identify user - uid_t uid = -1; - std::string passwd; - if (identify_user_pwd(pamh, uid, passwd)) - return PAM_SESSION_ERR; - - auto control = CKM::Control::create(); - int ec = control->unlockUserKey(uid, passwd.c_str()); - if (ec == CKM_API_SUCCESS) - return PAM_SUCCESS; - - if (ec == CKM_API_ERROR_AUTHENTICATION_FAILED) { - pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized," - "removing key-manager database for user: %d\n", uid); - - // key-manager<->system password desync - // remove the user content - ec = control->removeUserData(uid); - if (ec == CKM_API_SUCCESS) { - ec = CKM::Control::create()->unlockUserKey(uid, passwd.c_str()); - if (ec == CKM_API_SUCCESS) - return PAM_SUCCESS; - pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized," - "attempt to create new database failed: %d\n", ec); - } else { - pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized and" - "recovery attempt to remove broken database failed: %d\n", ec); - } - } - - return PAM_SESSION_ERR; + // identify user + uid_t uid = -1; + std::string passwd; + + if (identify_user_pwd(pamh, uid, passwd)) + return PAM_SESSION_ERR; + + auto control = CKM::Control::create(); + int ec = control->unlockUserKey(uid, passwd.c_str()); + + if (ec == CKM_API_SUCCESS) + return PAM_SUCCESS; + + if (ec == CKM_API_ERROR_AUTHENTICATION_FAILED) { + pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized," + "removing key-manager database for user: %d\n", uid); + + // key-manager<->system password desync + // remove the user content + ec = control->removeUserData(uid); + + if (ec == CKM_API_SUCCESS) { + ec = CKM::Control::create()->unlockUserKey(uid, passwd.c_str()); + + if (ec == CKM_API_SUCCESS) + return PAM_SUCCESS; + + pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized," + "attempt to create new database failed: %d\n", ec); + } else { + pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized and" + "recovery attempt to remove broken database failed: %d\n", ec); + } + } + + return PAM_SESSION_ERR; } COMMON_API PAM_EXTERN int -pam_sm_close_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/, const char **/*argv*/) +pam_sm_close_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/, + const char **/*argv*/) { - // identify user - uid_t uid = -1; - std::string passwd; - if (identify_user_pwd(pamh, uid, passwd)) - return PAM_SESSION_ERR; + // identify user + uid_t uid = -1; + std::string passwd; + + if (identify_user_pwd(pamh, uid, passwd)) + return PAM_SESSION_ERR; - if (CKM::Control::create()->lockUserKey(uid) == CKM_API_SUCCESS) - return PAM_SUCCESS; + if (CKM::Control::create()->lockUserKey(uid) == CKM_API_SUCCESS) + return PAM_SUCCESS; - return PAM_SESSION_ERR; + return PAM_SESSION_ERR; } COMMON_API PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { - if (argc == 0) { - pam_syslog(pamh, LOG_ERR, "key-manager plugin called with inappropriate arguments\n"); - return PAM_SERVICE_ERR; - } - - // identify user - uid_t uid = -1; - std::string passwd; - if (identify_user_pwd(pamh, uid, passwd)) - return PAM_USER_UNKNOWN; - - // attention: argv[0] is the argument, not the binary/so name - // args are in arg_name=value format - if (strstr(argv[0], "change_step")) { - if (strstr(argv[0], "before")) { - if (!(flags & PAM_PRELIM_CHECK)) - old_password = passwd; - return PAM_SUCCESS; - } else if (strstr(argv[0], "after")) { - if (flags & PAM_PRELIM_CHECK) - return PAM_SUCCESS; - - if (old_password.size() == 0) { - pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password w/o old password\n"); - return PAM_SERVICE_ERR; - } - std::string local_old_pwd = old_password; - old_password.clear(); - - // CKM does not allow to change user password if database does - // not exists. We must create database before change password. - auto ctrl = CKM::Control::create(); - int ec = ctrl->unlockUserKey(uid, local_old_pwd.c_str()); - if (CKM_API_SUCCESS != ec) { - // no DB reset here: somebody else might have changed password in mean time - // if desync happened, next login attempt will remove the DB - pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password failed:" - "can not open/create the database, ec: %d\n", ec); - return PAM_SERVICE_ERR; - } - - ec = ctrl->changeUserPassword(uid, local_old_pwd.c_str(), passwd.c_str()); - if (CKM_API_SUCCESS != ec) { - pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password ec: %d\n", ec); - return PAM_SERVICE_ERR; - } - - return PAM_SUCCESS; - } - } - - pam_syslog(pamh, LOG_ERR, "key-manager plugin called with no valid \"change_step\" option setting\n"); - return PAM_SERVICE_ERR; + if (argc == 0) { + pam_syslog(pamh, LOG_ERR, + "key-manager plugin called with inappropriate arguments\n"); + return PAM_SERVICE_ERR; + } + + // identify user + uid_t uid = -1; + std::string passwd; + + if (identify_user_pwd(pamh, uid, passwd)) + return PAM_USER_UNKNOWN; + + // attention: argv[0] is the argument, not the binary/so name + // args are in arg_name=value format + if (strstr(argv[0], "change_step")) { + if (strstr(argv[0], "before")) { + if (!(flags & PAM_PRELIM_CHECK)) + old_password = passwd; + + return PAM_SUCCESS; + } else if (strstr(argv[0], "after")) { + if (flags & PAM_PRELIM_CHECK) + return PAM_SUCCESS; + + if (old_password.size() == 0) { + pam_syslog(pamh, LOG_ERR, + "attempt to change key-manager password w/o old password\n"); + return PAM_SERVICE_ERR; + } + + std::string local_old_pwd = old_password; + old_password.clear(); + + // CKM does not allow to change user password if database does + // not exists. We must create database before change password. + auto ctrl = CKM::Control::create(); + int ec = ctrl->unlockUserKey(uid, local_old_pwd.c_str()); + + if (CKM_API_SUCCESS != ec) { + // no DB reset here: somebody else might have changed password in mean time + // if desync happened, next login attempt will remove the DB + pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password failed:" + "can not open/create the database, ec: %d\n", ec); + return PAM_SERVICE_ERR; + } + + ec = ctrl->changeUserPassword(uid, local_old_pwd.c_str(), passwd.c_str()); + + if (CKM_API_SUCCESS != ec) { + pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password ec: %d\n", + ec); + return PAM_SERVICE_ERR; + } + + return PAM_SUCCESS; + } + } + + pam_syslog(pamh, LOG_ERR, + "key-manager plugin called with no valid \"change_step\" option setting\n"); + return PAM_SERVICE_ERR; } diff --git a/tests/DBFixture.cpp b/tests/DBFixture.cpp index a6abfd2b..f08846be 100644 --- a/tests/DBFixture.cpp +++ b/tests/DBFixture.cpp @@ -32,214 +32,226 @@ using namespace std::chrono; DBFixture::DBFixture() { - BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT); - init(); + BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT); + init(); } DBFixture::DBFixture(const char *db_fname) { - BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT); + BOOST_CHECK(unlink(m_crypto_db_fname) == 0 || errno == ENOENT); - // copy file - std::ifstream f1(db_fname, std::fstream::binary); - std::ofstream f2(m_crypto_db_fname, std::fstream::trunc|std::fstream::binary); - f2 << f1.rdbuf(); - f2.close(); - f1.close(); + // copy file + std::ifstream f1(db_fname, std::fstream::binary); + std::ofstream f2(m_crypto_db_fname, std::fstream::trunc | std::fstream::binary); + f2 << f1.rdbuf(); + f2.close(); + f1.close(); - init(); + init(); } void DBFixture::init() { - high_resolution_clock::time_point srand_feed = high_resolution_clock::now(); - srand(srand_feed.time_since_epoch().count()); + high_resolution_clock::time_point srand_feed = high_resolution_clock::now(); + srand(srand_feed.time_since_epoch().count()); - BOOST_REQUIRE_NO_THROW(m_db = DB::Crypto(m_crypto_db_fname, defaultPass)); + BOOST_REQUIRE_NO_THROW(m_db = DB::Crypto(m_crypto_db_fname, defaultPass)); } double DBFixture::performance_get_time_elapsed_ms() { - return duration_cast<milliseconds>(m_end_time - m_start_time).count(); + return duration_cast<milliseconds>(m_end_time - m_start_time).count(); } void DBFixture::performance_start(const char *operation_name) { - m_operation = std::string(operation_name?operation_name:"unknown"); - BOOST_TEST_MESSAGE("\t<performance> running " << m_operation << " performance test..."); - m_start_time = high_resolution_clock::now(); + m_operation = std::string(operation_name ? operation_name : "unknown"); + BOOST_TEST_MESSAGE("\t<performance> running " << m_operation << + " performance test..."); + m_start_time = high_resolution_clock::now(); } void DBFixture::performance_stop(long num_operations_performed) { - m_end_time = high_resolution_clock::now(); - double time_elapsed_ms = performance_get_time_elapsed_ms(); - BOOST_TEST_MESSAGE("\t<performance> time elapsed: " << time_elapsed_ms << "[ms], number of " << m_operation << ": " << num_operations_performed); - if(num_operations_performed>0) - BOOST_TEST_MESSAGE("\t<performance> average time per " << m_operation << ": " << time_elapsed_ms/num_operations_performed << "[ms]"); + m_end_time = high_resolution_clock::now(); + double time_elapsed_ms = performance_get_time_elapsed_ms(); + BOOST_TEST_MESSAGE("\t<performance> time elapsed: " << time_elapsed_ms << + "[ms], number of " << m_operation << ": " << num_operations_performed); + + if (num_operations_performed > 0) + BOOST_TEST_MESSAGE("\t<performance> average time per " << m_operation << ": " << + time_elapsed_ms / num_operations_performed << "[ms]"); } -void DBFixture::generate_name(unsigned int id, Name & output) +void DBFixture::generate_name(unsigned int id, Name &output) { - std::stringstream ss; - ss << "name_no_" << id; - output = ss.str(); + std::stringstream ss; + ss << "name_no_" << id; + output = ss.str(); } -void DBFixture::generate_label(unsigned int id, Label & output) +void DBFixture::generate_label(unsigned int id, Label &output) { - std::stringstream ss; - ss << "label_no_" << id; - output = ss.str(); + std::stringstream ss; + ss << "label_no_" << id; + output = ss.str(); } -void DBFixture::generate_perf_DB(unsigned int num_name, unsigned int num_elements) +void DBFixture::generate_perf_DB(unsigned int num_name, + unsigned int num_elements) { - // to speed up data creation - cache the row - DB::Row rowPattern = create_default_row(DataType::BINARY_DATA); - rowPattern.data = RawBuffer(100, 20); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - - for(unsigned int i=0; i<num_name; i++) - { - generate_name(i, rowPattern.name); - generate_label(i/num_elements, rowPattern.ownerLabel); - - BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); - } + // to speed up data creation - cache the row + DB::Row rowPattern = create_default_row(DataType::BINARY_DATA); + rowPattern.data = RawBuffer(100, 20); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); + + for (unsigned int i = 0; i < num_name; i++) { + generate_name(i, rowPattern.name); + generate_label(i / num_elements, rowPattern.ownerLabel); + + BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); + } } -long DBFixture::add_full_access_rights(unsigned int num_name, unsigned int num_name_per_label) +long DBFixture::add_full_access_rights(unsigned int num_name, + unsigned int num_name_per_label) { - long iterations = 0; - unsigned int num_labels = num_name / num_name_per_label; - Name name; - Label owner_label, accessor_label; - for(unsigned int a=0; a<num_name; a++) - { - generate_name(a, name); - generate_label(a/num_name_per_label, owner_label); - for(unsigned int l=0; l<num_labels; l++) - { - // bypass the owner label - if(l == (a/num_name_per_label)) - continue; - - // add permission - generate_label(l, accessor_label); - add_permission(name, owner_label, accessor_label); - iterations ++; - } - } - - return iterations; + long iterations = 0; + unsigned int num_labels = num_name / num_name_per_label; + Name name; + Label owner_label, accessor_label; + + for (unsigned int a = 0; a < num_name; a++) { + generate_name(a, name); + generate_label(a / num_name_per_label, owner_label); + + for (unsigned int l = 0; l < num_labels; l++) { + // bypass the owner label + if (l == (a / num_name_per_label)) + continue; + + // add permission + generate_label(l, accessor_label); + add_permission(name, owner_label, accessor_label); + iterations++; + } + } + + return iterations; } DB::Row DBFixture::create_default_row(DataType type) { - return create_default_row(m_default_name, m_default_label, type); + return create_default_row(m_default_name, m_default_label, type); } DB::Row DBFixture::create_default_row(const Name &name, - const Label &label, - DataType type) + const Label &label, + DataType type) { - DB::Row row; - row.name = name; - row.ownerLabel = label; - row.exportable = 1; - row.algorithmType = DBCMAlgType::AES_GCM_256; - row.dataType = type; - row.iv = createDefaultPass(); - row.encryptionScheme = 0; - row.dataSize = 0; - row.backendId = CryptoBackend::OpenSSL; - - return row; + DB::Row row; + row.name = name; + row.ownerLabel = label; + row.exportable = 1; + row.algorithmType = DBCMAlgType::AES_GCM_256; + row.dataType = type; + row.iv = createDefaultPass(); + row.encryptionScheme = 0; + row.dataSize = 0; + row.backendId = CryptoBackend::OpenSSL; + + return row; } void DBFixture::compare_row(const DB::Row &lhs, const DB::Row &rhs) { - BOOST_CHECK_MESSAGE(lhs.name == rhs.name, - "namees didn't match! Got: " << rhs.name - << " , expected : " << lhs.name); + BOOST_CHECK_MESSAGE(lhs.name == rhs.name, + "namees didn't match! Got: " << rhs.name + << " , expected : " << lhs.name); - BOOST_CHECK_MESSAGE(lhs.ownerLabel == rhs.ownerLabel, - "smackLabel didn't match! Got: " << rhs.ownerLabel - << " , expected : " << lhs.ownerLabel); + BOOST_CHECK_MESSAGE(lhs.ownerLabel == rhs.ownerLabel, + "smackLabel didn't match! Got: " << rhs.ownerLabel + << " , expected : " << lhs.ownerLabel); - BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable, - "exportable didn't match! Got: " << rhs.exportable - << " , expected : " << lhs.exportable); + BOOST_CHECK_MESSAGE(lhs.exportable == rhs.exportable, + "exportable didn't match! Got: " << rhs.exportable + << " , expected : " << lhs.exportable); - BOOST_CHECK_MESSAGE(lhs.iv == rhs.iv, - "iv didn't match! Got: " << rhs.iv.size() - << " , expected : " << lhs.iv.size()); + BOOST_CHECK_MESSAGE(lhs.iv == rhs.iv, + "iv didn't match! Got: " << rhs.iv.size() + << " , expected : " << lhs.iv.size()); - BOOST_CHECK_MESSAGE(lhs.data == rhs.data, - "data didn't match! Got: " << rhs.data.size() - << " , expected : " << lhs.data.size()); + BOOST_CHECK_MESSAGE(lhs.data == rhs.data, + "data didn't match! Got: " << rhs.data.size() + << " , expected : " << lhs.data.size()); - BOOST_CHECK_MESSAGE(lhs.backendId == rhs.backendId, - "backendId didn't match! Got: " << static_cast<int>(rhs.backendId) - << " , expected : " << static_cast<int>(lhs.backendId)); + BOOST_CHECK_MESSAGE(lhs.backendId == rhs.backendId, + "backendId didn't match! Got: " << static_cast<int>(rhs.backendId) + << " , expected : " << static_cast<int>(lhs.backendId)); } void DBFixture::check_DB_integrity(const DB::Row &rowPattern) { - BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); - - DB::Crypto::RowOptional optional_row; - BOOST_REQUIRE_NO_THROW(optional_row = m_db.getRow("name", "label", DataType::BINARY_DATA)); - BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row"); - - compare_row(*optional_row, rowPattern); - DB::Row name_duplicate = rowPattern; - name_duplicate.data = createDefaultPass(); - name_duplicate.dataSize = name_duplicate.data.size(); - - unsigned int erased; - BOOST_REQUIRE_NO_THROW(erased = m_db.deleteRow("name", "label")); - BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db"); - - DB::Crypto::RowOptional row_optional; - BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow("name", "label", DataType::BINARY_DATA)); - BOOST_REQUIRE_MESSAGE(!row_optional, "Select should not return row after deletion"); + BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); + + DB::Crypto::RowOptional optional_row; + BOOST_REQUIRE_NO_THROW(optional_row = m_db.getRow("name", "label", + DataType::BINARY_DATA)); + BOOST_REQUIRE_MESSAGE(optional_row, "Select didn't return any row"); + + compare_row(*optional_row, rowPattern); + DB::Row name_duplicate = rowPattern; + name_duplicate.data = createDefaultPass(); + name_duplicate.dataSize = name_duplicate.data.size(); + + unsigned int erased; + BOOST_REQUIRE_NO_THROW(erased = m_db.deleteRow("name", "label")); + BOOST_REQUIRE_MESSAGE(erased > 0, "Inserted row didn't exist in db"); + + DB::Crypto::RowOptional row_optional; + BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow("name", "label", + DataType::BINARY_DATA)); + BOOST_REQUIRE_MESSAGE(!row_optional, + "Select should not return row after deletion"); } void DBFixture::insert_row() { - insert_row(m_default_name, m_default_label); + insert_row(m_default_name, m_default_label); } void DBFixture::insert_row(const Name &name, const Label &owner_label) { - DB::Row rowPattern = create_default_row(name, owner_label, DataType::BINARY_DATA); - rowPattern.data = RawBuffer(100, 20); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); + DB::Row rowPattern = create_default_row(name, owner_label, + DataType::BINARY_DATA); + rowPattern.data = RawBuffer(100, 20); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); + BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); } void DBFixture::delete_row(const Name &name, const Label &owner_label) { - bool exit_flag; - BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteRow(name, owner_label)); - BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed"); + bool exit_flag; + BOOST_REQUIRE_NO_THROW(exit_flag = m_db.deleteRow(name, owner_label)); + BOOST_REQUIRE_MESSAGE(true == exit_flag, "remove name failed: no rows removed"); } -void DBFixture::add_permission(const Name &name, const Label &owner_label, const Label &accessor_label) +void DBFixture::add_permission(const Name &name, const Label &owner_label, + const Label &accessor_label) { - BOOST_REQUIRE_NO_THROW(m_db.setPermission(name, - owner_label, - accessor_label, - CKM::Permission::READ | CKM::Permission::REMOVE)); + BOOST_REQUIRE_NO_THROW(m_db.setPermission(name, + owner_label, + accessor_label, + CKM::Permission::READ | CKM::Permission::REMOVE)); } -void DBFixture::read_row_expect_success(const Name &name, const Label &owner_label) +void DBFixture::read_row_expect_success(const Name &name, + const Label &owner_label) { - DB::Crypto::RowOptional row; - BOOST_REQUIRE_NO_THROW(row = m_db.getRow(name, owner_label, DataType::BINARY_DATA)); - BOOST_REQUIRE_MESSAGE(row, "row is empty"); - BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid"); + DB::Crypto::RowOptional row; + BOOST_REQUIRE_NO_THROW(row = m_db.getRow(name, owner_label, + DataType::BINARY_DATA)); + BOOST_REQUIRE_MESSAGE(row, "row is empty"); + BOOST_REQUIRE_MESSAGE(row->name == name, "name is not valid"); } diff --git a/tests/DBFixture.h b/tests/DBFixture.h index 2cd2cdc7..62f19a2a 100644 --- a/tests/DBFixture.h +++ b/tests/DBFixture.h @@ -27,44 +27,48 @@ #include <protocols.h> #include <chrono> -class DBFixture -{ - public: - DBFixture(); - DBFixture(const char *db_fname); +class DBFixture { +public: + DBFixture(); + DBFixture(const char *db_fname); - constexpr static const char* m_default_name = "name"; - constexpr static const char* m_default_label = "label"; + constexpr static const char *m_default_name = "name"; + constexpr static const char *m_default_label = "label"; - // ::::::::::::::::::::::::: helper methods ::::::::::::::::::::::::: - static void generate_name(unsigned int id, CKM::Name & output); - static void generate_label(unsigned int id, CKM::Label & output); - static CKM::DB::Row create_default_row(CKM::DataType type = CKM::DataType::BINARY_DATA); - static CKM::DB::Row create_default_row(const CKM::Name &name, - const CKM::Label &label, - CKM::DataType type = CKM::DataType::BINARY_DATA); - static void compare_row(const CKM::DB::Row &lhs, const CKM::DB::Row &rhs); + // ::::::::::::::::::::::::: helper methods ::::::::::::::::::::::::: + static void generate_name(unsigned int id, CKM::Name &output); + static void generate_label(unsigned int id, CKM::Label &output); + static CKM::DB::Row create_default_row(CKM::DataType type = + CKM::DataType::BINARY_DATA); + static CKM::DB::Row create_default_row(const CKM::Name &name, + const CKM::Label &label, + CKM::DataType type = CKM::DataType::BINARY_DATA); + static void compare_row(const CKM::DB::Row &lhs, const CKM::DB::Row &rhs); - // ::::::::::::::::::::::::: time measurement ::::::::::::::::::::::::: - void performance_start(const char *operation_name); - void performance_stop(long num_operations_performed); + // ::::::::::::::::::::::::: time measurement ::::::::::::::::::::::::: + void performance_start(const char *operation_name); + void performance_stop(long num_operations_performed); - // ::::::::::::::::::::::::: DB ::::::::::::::::::::::::: - void generate_perf_DB(unsigned int num_name, unsigned int num_label); - long add_full_access_rights(unsigned int num_name, unsigned int num_names_per_label); - void check_DB_integrity(const CKM::DB::Row &rowPattern); - void insert_row(); - void insert_row(const CKM::Name &name, const CKM::Label &owner_label); - void delete_row(const CKM::Name &name, const CKM::Label &owner_label); - void add_permission(const CKM::Name &name, const CKM::Label &owner_label, const CKM::Label &accessor_label); - void read_row_expect_success(const CKM::Name &name, const CKM::Label &owner_label); + // ::::::::::::::::::::::::: DB ::::::::::::::::::::::::: + void generate_perf_DB(unsigned int num_name, unsigned int num_label); + long add_full_access_rights(unsigned int num_name, + unsigned int num_names_per_label); + void check_DB_integrity(const CKM::DB::Row &rowPattern); + void insert_row(); + void insert_row(const CKM::Name &name, const CKM::Label &owner_label); + void delete_row(const CKM::Name &name, const CKM::Label &owner_label); + void add_permission(const CKM::Name &name, const CKM::Label &owner_label, + const CKM::Label &accessor_label); + void read_row_expect_success(const CKM::Name &name, + const CKM::Label &owner_label); - CKM::DB::Crypto m_db; - private: - void init(); - double performance_get_time_elapsed_ms(); + CKM::DB::Crypto m_db; - constexpr static const char* m_crypto_db_fname = "/tmp/testme.db"; - std::string m_operation; - std::chrono::high_resolution_clock::time_point m_start_time, m_end_time; +private: + void init(); + double performance_get_time_elapsed_ms(); + + constexpr static const char *m_crypto_db_fname = "/tmp/testme.db"; + std::string m_operation; + std::chrono::high_resolution_clock::time_point m_start_time, m_end_time; }; diff --git a/tests/colour_log_formatter.cpp b/tests/colour_log_formatter.cpp index 8857f740..efcb408b 100644 --- a/tests/colour_log_formatter.cpp +++ b/tests/colour_log_formatter.cpp @@ -40,19 +40,21 @@ namespace { const_string test_phase_identifier() { - return framework::is_initialized() - ? const_string( framework::current_test_case().p_name.get() ) - : BOOST_TEST_L( "Test setup" ); + return framework::is_initialized() + ? const_string(framework::current_test_case().p_name.get()) + : BOOST_TEST_L("Test setup"); } const_string -get_basename(const const_string &file_name) { - return basename(file_name.begin()); +get_basename(const const_string &file_name) +{ + return basename(file_name.begin()); } std::string -get_basename(const std::string &file_name) { - return basename(file_name.c_str()); +get_basename(const std::string &file_name) +{ + return basename(file_name.c_str()); } } // local namespace @@ -61,185 +63,206 @@ get_basename(const std::string &file_name) { void colour_log_formatter::log_start( - std::ostream& output, - counter_t test_cases_amount ) + std::ostream &output, + counter_t test_cases_amount) { - if( test_cases_amount > 0 ) - output << "Running " << test_cases_amount << " test " - << (test_cases_amount > 1 ? "cases" : "case") << "...\n"; + if (test_cases_amount > 0) + output << "Running " << test_cases_amount << " test " + << (test_cases_amount > 1 ? "cases" : "case") << "...\n"; } //____________________________________________________________________________// void -colour_log_formatter::log_finish( std::ostream& ostr ) +colour_log_formatter::log_finish(std::ostream &ostr) { - ostr.flush(); + ostr.flush(); } //____________________________________________________________________________// void -colour_log_formatter::log_build_info( std::ostream& output ) +colour_log_formatter::log_build_info(std::ostream &output) { - output << "Platform: " << BOOST_PLATFORM << '\n' - << "Compiler: " << BOOST_COMPILER << '\n' - << "STL : " << BOOST_STDLIB << '\n' - << "Boost : " << BOOST_VERSION/100000 << "." - << BOOST_VERSION/100 % 1000 << "." - << BOOST_VERSION % 100 << std::endl; + output << "Platform: " << BOOST_PLATFORM << '\n' + << "Compiler: " << BOOST_COMPILER << '\n' + << "STL : " << BOOST_STDLIB << '\n' + << "Boost : " << BOOST_VERSION / 100000 << "." + << BOOST_VERSION / 100 % 1000 << "." + << BOOST_VERSION % 100 << std::endl; } //____________________________________________________________________________// void colour_log_formatter::test_unit_start( - std::ostream& output, - test_unit const& tu ) + std::ostream &output, + test_unit const &tu) { - if (tu.p_type_name->find(const_string("suite")) == 0) { - output << "Starting test " << tu.p_type_name << " \"" << tu.p_name << "\"" << std::endl; - } else { - output << "Running test " << tu.p_type_name << " \"" << tu.p_name << "\"" << std::endl; - } + if (tu.p_type_name->find(const_string("suite")) == 0) { + output << "Starting test " << tu.p_type_name << " \"" << tu.p_name << "\"" << + std::endl; + } else { + output << "Running test " << tu.p_type_name << " \"" << tu.p_name << "\"" << + std::endl; + } } //____________________________________________________________________________// void colour_log_formatter::test_unit_finish( - std::ostream& output, - test_unit const& tu, - unsigned long elapsed ) + std::ostream &output, + test_unit const &tu, + unsigned long elapsed) { - if (tu.p_type_name->find(const_string("suite")) == 0) { - output << "Finished test " << tu.p_type_name << " \"" << tu.p_name << "\""<< std::endl; - return; - } - std::string color = CKM::Colors::Text::GREEN_BEGIN; - std::string status = "OK"; - if (m_isTestCaseFailed) { - color = CKM::Colors::Text::RED_BEGIN; - status = "FAIL"; - } - output << "\t" << "[ " << color << status << CKM::Colors::Text::COLOR_END << " ]"; - - - output << ", " << CKM::Colors::Text::CYAN_BEGIN << "time: "; - if( elapsed > 0 ) { - if( elapsed % 1000 == 0 ) - output << elapsed/1000 << "ms"; - else - output << elapsed << "mks"; - } else { - output << "N/A"; - } - - output << CKM::Colors::Text::COLOR_END << std::endl; - m_isTestCaseFailed = false; + if (tu.p_type_name->find(const_string("suite")) == 0) { + output << "Finished test " << tu.p_type_name << " \"" << tu.p_name << "\"" << + std::endl; + return; + } + + std::string color = CKM::Colors::Text::GREEN_BEGIN; + std::string status = "OK"; + + if (m_isTestCaseFailed) { + color = CKM::Colors::Text::RED_BEGIN; + status = "FAIL"; + } + + output << "\t" << "[ " << color << status << CKM::Colors::Text::COLOR_END << + " ]"; + + + output << ", " << CKM::Colors::Text::CYAN_BEGIN << "time: "; + + if (elapsed > 0) { + if (elapsed % 1000 == 0) + output << elapsed / 1000 << "ms"; + else + output << elapsed << "mks"; + } else { + output << "N/A"; + } + + output << CKM::Colors::Text::COLOR_END << std::endl; + m_isTestCaseFailed = false; } //____________________________________________________________________________// void colour_log_formatter::test_unit_skipped( - std::ostream& output, - test_unit const& tu ) + std::ostream &output, + test_unit const &tu) { - output << "Test " << tu.p_type_name << " \"" << tu.p_name << "\"" << "is skipped" << std::endl; + output << "Test " << tu.p_type_name << " \"" << tu.p_name << "\"" << + "is skipped" << std::endl; } //____________________________________________________________________________// void colour_log_formatter::log_exception( - std::ostream& output, - log_checkpoint_data const& checkpoint_data, - boost::execution_exception const& ex ) + std::ostream &output, + log_checkpoint_data const &checkpoint_data, + boost::execution_exception const &ex) { - boost::execution_exception::location const& loc = ex.where(); - output << '\t' << CKM::Colors::Text::BOLD_YELLOW_BEGIN << get_basename(loc.m_file_name) - << '(' << loc.m_line_num << "), "; + boost::execution_exception::location const &loc = ex.where(); + output << '\t' << CKM::Colors::Text::BOLD_YELLOW_BEGIN << get_basename( + loc.m_file_name) + << '(' << loc.m_line_num << "), "; + + output << "fatal error in \"" + << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function) << + "\": "; - output << "fatal error in \"" - << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function ) << "\": "; + output << CKM::Colors::Text::COLOR_END << ex.what(); - output << CKM::Colors::Text::COLOR_END << ex.what(); + if (!checkpoint_data.m_file_name.is_empty()) { + output << '\n'; + output << "\tlast checkpoint : " << get_basename(checkpoint_data.m_file_name) + << '(' << checkpoint_data.m_line_num << ")"; - if( !checkpoint_data.m_file_name.is_empty() ) { - output << '\n'; - output << "\tlast checkpoint : " << get_basename(checkpoint_data.m_file_name) - << '(' << checkpoint_data.m_line_num << ")"; - if( !checkpoint_data.m_message.empty() ) - output << ": " << checkpoint_data.m_message; - } + if (!checkpoint_data.m_message.empty()) + output << ": " << checkpoint_data.m_message; + } - output << std::endl; - m_isTestCaseFailed = true; + output << std::endl; + m_isTestCaseFailed = true; } //____________________________________________________________________________// void colour_log_formatter::log_entry_start( - std::ostream& output, - log_entry_data const& entry_data, - log_entry_types let ) + std::ostream &output, + log_entry_data const &entry_data, + log_entry_types let) { - switch( let ) { - case BOOST_UTL_ET_INFO: - output << '\t' << entry_data.m_file_name << '(' << entry_data.m_line_num << "), "; - output << "info: "; - break; - case BOOST_UTL_ET_MESSAGE: - break; - case BOOST_UTL_ET_WARNING: - output << '\t' << get_basename(entry_data.m_file_name) << '(' << entry_data.m_line_num << "), "; - output << "warning in \"" << test_phase_identifier() << "\": "; - break; - case BOOST_UTL_ET_ERROR: - output << '\t' << CKM::Colors::Text::BOLD_YELLOW_BEGIN << get_basename(entry_data.m_file_name) - << '(' << entry_data.m_line_num << "), "; - output << "error in \"" << test_phase_identifier() << "\": "; - m_isTestCaseFailed = true; - break; - case BOOST_UTL_ET_FATAL_ERROR: - output << '\t' << CKM::Colors::Text::BOLD_YELLOW_BEGIN << get_basename(entry_data.m_file_name) - << '(' << entry_data.m_line_num << "), "; - output << " fatal error in \"" << test_phase_identifier() << "\": "; - m_isTestCaseFailed = true; - break; - } - output << CKM::Colors::Text::COLOR_END; + switch (let) { + case BOOST_UTL_ET_INFO: + output << '\t' << entry_data.m_file_name << '(' << entry_data.m_line_num << + "), "; + output << "info: "; + break; + + case BOOST_UTL_ET_MESSAGE: + break; + + case BOOST_UTL_ET_WARNING: + output << '\t' << get_basename(entry_data.m_file_name) << '(' << + entry_data.m_line_num << "), "; + output << "warning in \"" << test_phase_identifier() << "\": "; + break; + + case BOOST_UTL_ET_ERROR: + output << '\t' << CKM::Colors::Text::BOLD_YELLOW_BEGIN << get_basename( + entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; + output << "error in \"" << test_phase_identifier() << "\": "; + m_isTestCaseFailed = true; + break; + + case BOOST_UTL_ET_FATAL_ERROR: + output << '\t' << CKM::Colors::Text::BOLD_YELLOW_BEGIN << get_basename( + entry_data.m_file_name) + << '(' << entry_data.m_line_num << "), "; + output << " fatal error in \"" << test_phase_identifier() << "\": "; + m_isTestCaseFailed = true; + break; + } + + output << CKM::Colors::Text::COLOR_END; } //____________________________________________________________________________// void colour_log_formatter::log_entry_value( - std::ostream& output, - const_string value ) + std::ostream &output, + const_string value) { - output << value; + output << value; } //____________________________________________________________________________// void colour_log_formatter::log_entry_value( - std::ostream& output, - lazy_ostream const& value ) + std::ostream &output, + lazy_ostream const &value) { - output << value; + output << value; } //____________________________________________________________________________// void colour_log_formatter::log_entry_finish( - std::ostream& output ) + std::ostream &output) { - output << std::endl; + output << std::endl; } //____________________________________________________________________________// diff --git a/tests/colour_log_formatter.h b/tests/colour_log_formatter.h index a9e44066..3c5dae00 100644 --- a/tests/colour_log_formatter.h +++ b/tests/colour_log_formatter.h @@ -18,42 +18,43 @@ namespace CKM { class colour_log_formatter : public boost::unit_test::unit_test_log_formatter { public: - // Formatter interface - colour_log_formatter() : m_isTestCaseFailed(false) {} - void log_start( - std::ostream&, - boost::unit_test::counter_t test_cases_amount ); - void log_finish( std::ostream& ); - void log_build_info( std::ostream& ); + // Formatter interface + colour_log_formatter() : m_isTestCaseFailed(false) {} + void log_start( + std::ostream &, + boost::unit_test::counter_t test_cases_amount); + void log_finish(std::ostream &); + void log_build_info(std::ostream &); - void test_unit_start( - std::ostream&, - boost::unit_test::test_unit const& tu ); - void test_unit_finish( - std::ostream&, - boost::unit_test::test_unit const& tu, - unsigned long elapsed ); - void test_unit_skipped( - std::ostream&, - boost::unit_test::test_unit const& tu ); + void test_unit_start( + std::ostream &, + boost::unit_test::test_unit const &tu); + void test_unit_finish( + std::ostream &, + boost::unit_test::test_unit const &tu, + unsigned long elapsed); + void test_unit_skipped( + std::ostream &, + boost::unit_test::test_unit const &tu); - void log_exception( - std::ostream&, - boost::unit_test::log_checkpoint_data const&, - boost::execution_exception const& ex ); + void log_exception( + std::ostream &, + boost::unit_test::log_checkpoint_data const &, + boost::execution_exception const &ex); + + void log_entry_start( + std::ostream &, + boost::unit_test::log_entry_data const &, + log_entry_types let); + void log_entry_value( + std::ostream &, + boost::unit_test::const_string value); + void log_entry_value( + std::ostream &, + boost::unit_test::lazy_ostream const &value); + void log_entry_finish(std::ostream &); - void log_entry_start( - std::ostream&, - boost::unit_test::log_entry_data const&, - log_entry_types let ); - void log_entry_value( - std::ostream&, - boost::unit_test::const_string value ); - void log_entry_value( - std::ostream&, - boost::unit_test::lazy_ostream const& value ); - void log_entry_finish( std::ostream& ); private: - bool m_isTestCaseFailed; + bool m_isTestCaseFailed; }; } // namespace CKM diff --git a/tests/encryption-scheme/generate-db.cpp b/tests/encryption-scheme/generate-db.cpp index 3177230a..8bb6e3c9 100644 --- a/tests/encryption-scheme/generate-db.cpp +++ b/tests/encryption-scheme/generate-db.cpp @@ -26,16 +26,16 @@ int main() { - try { - SchemeTest st; - st.FillDb(); - return 0; - } catch (const std::runtime_error& e) { - std::cerr << e.what() << std::endl; - return -1; - } catch (...) { - std::cerr << "Unknown exception occured!" << std::endl; - return -1; - } + try { + SchemeTest st; + st.FillDb(); + return 0; + } catch (const std::runtime_error &e) { + std::cerr << e.what() << std::endl; + return -1; + } catch (...) { + std::cerr << "Unknown exception occured!" << std::endl; + return -1; + } } diff --git a/tests/encryption-scheme/scheme-test.cpp b/tests/encryption-scheme/scheme-test.cpp index 47d15692..d0096ace 100644 --- a/tests/encryption-scheme/scheme-test.cpp +++ b/tests/encryption-scheme/scheme-test.cpp @@ -51,8 +51,8 @@ using namespace std; namespace { const uid_t UID = 7654; const gid_t GID = 7654; -const char* const DBPASS = "db-pass"; -const char* const LABEL = "my-label"; +const char *const DBPASS = "db-pass"; +const char *const LABEL = "my-label"; const Label DB_LABEL = "/" + string(LABEL); const int ENC_SCHEME_OFFSET = 24; const string TEST_DATA_STR = "test-data"; @@ -62,742 +62,846 @@ const size_t IV_LEN = 16; const size_t CHAIN_LEN = 3; enum { - NO_PASS = 0, - PASS = 1 + NO_PASS = 0, + PASS = 1 }; enum { - NO_EXP = 0, - EXP = 1 + NO_EXP = 0, + EXP = 1 }; // [password][exportable] Policy policy[2][2] = { - {{ Password(), false }, { Password(), true }}, - {{ TEST_PASS, false }, { TEST_PASS, true }}, + {{ Password(), false }, { Password(), true }}, + {{ TEST_PASS, false }, { TEST_PASS, true }}, }; struct Group { - enum { - SINGLE_ITEM, - KEY_PAIR_RSA, - CERT_CHAIN - } type; - Items items; + enum { + SINGLE_ITEM, + KEY_PAIR_RSA, + CERT_CHAIN + } type; + Items items; }; Group GROUPS[] = { - // Data - { Group::SINGLE_ITEM, { - Item("data-alias1", DataType::BINARY_DATA, policy[NO_PASS][EXP]) - }}, - { Group::SINGLE_ITEM, { - Item("data-alias2", DataType::BINARY_DATA, policy[PASS][EXP]) - }}, - - // RSA keys - { Group::KEY_PAIR_RSA, { - Item("key-rsa-alias-prv1", DataType::KEY_RSA_PRIVATE, policy[NO_PASS][NO_EXP]), - Item("key-rsa-alias-pub1", DataType::KEY_RSA_PUBLIC, policy[NO_PASS][NO_EXP]) - }}, - { Group::KEY_PAIR_RSA, { - Item("key-rsa-alias-prv2", DataType::KEY_RSA_PRIVATE, policy[NO_PASS][EXP]), - Item("key-rsa-alias-pub2", DataType::KEY_RSA_PUBLIC, policy[NO_PASS][EXP]), - }}, - { Group::KEY_PAIR_RSA, { - Item("key-rsa-alias-prv3", DataType::KEY_RSA_PRIVATE, policy[PASS][NO_EXP]), - Item("key-rsa-alias-pub3", DataType::KEY_RSA_PUBLIC, policy[PASS][NO_EXP]), - }}, - { Group::KEY_PAIR_RSA, { - Item("key-rsa-alias-prv4", DataType::KEY_RSA_PRIVATE, policy[PASS][EXP]), - Item("key-rsa-alias-pub4", DataType::KEY_RSA_PUBLIC, policy[PASS][EXP]), - }}, - // different policies - { Group::KEY_PAIR_RSA, { - Item("key-rsa-alias-prv5", DataType::KEY_RSA_PRIVATE, policy[PASS][NO_EXP]), - Item("key-rsa-alias-pub5", DataType::KEY_RSA_PUBLIC, policy[NO_PASS][EXP]), - }}, - - // AES - { Group::SINGLE_ITEM, { - Item("key-aes-alias1", DataType::KEY_AES, policy[NO_PASS][NO_EXP]), - }}, - { Group::SINGLE_ITEM, { - Item("key-aes-alias2", DataType::KEY_AES, policy[NO_PASS][EXP]), - }}, - { Group::SINGLE_ITEM, { - Item("key-aes-alias3", DataType::KEY_AES, policy[PASS][NO_EXP]), - }}, - { Group::SINGLE_ITEM, { - Item("key-aes-alias4", DataType::KEY_AES, policy[PASS][EXP]), - }}, - - // Certificates - { Group::CERT_CHAIN, { - Item("cert-root-alias1", DataType::CERTIFICATE, policy[NO_PASS][NO_EXP]), - Item("cert-im-ca-alias1", DataType::CERTIFICATE, policy[NO_PASS][NO_EXP]), - Item("cert-leaf-alias1", DataType::CERTIFICATE, policy[NO_PASS][NO_EXP]), - }}, - { Group::CERT_CHAIN, { - Item("cert-root-alias2", DataType::CERTIFICATE, policy[NO_PASS][EXP]), - Item("cert-im-ca-alias2", DataType::CERTIFICATE, policy[NO_PASS][EXP]), - Item("cert-leaf-alias2", DataType::CERTIFICATE, policy[NO_PASS][EXP]), - }}, - { Group::CERT_CHAIN, { - Item("cert-root-alias3", DataType::CERTIFICATE, policy[PASS][NO_EXP]), - Item("cert-im-ca-alias3", DataType::CERTIFICATE, policy[PASS][NO_EXP]), - Item("cert-leaf-alias3", DataType::CERTIFICATE, policy[PASS][NO_EXP]), - }}, - { Group::CERT_CHAIN, { - Item("cert-root-alias4", DataType::CERTIFICATE, policy[PASS][EXP]), - Item("cert-im-ca-alias4", DataType::CERTIFICATE, policy[PASS][EXP]), - Item("cert-leaf-alias4", DataType::CERTIFICATE, policy[PASS][EXP]), - }}, - - // PKCS - { Group::SINGLE_ITEM, { - Item("pkcs-alias1", DataType::CHAIN_CERT_0, policy[NO_PASS][NO_EXP]), - }}, - { Group::SINGLE_ITEM, { - Item("pkcs-alias2", DataType::CHAIN_CERT_0, policy[NO_PASS][EXP]), - }}, - { Group::SINGLE_ITEM, { - Item("pkcs-alias3", DataType::CHAIN_CERT_0, policy[PASS][NO_EXP]), - }}, - { Group::SINGLE_ITEM, { - Item("pkcs-alias4", DataType::CHAIN_CERT_0, policy[PASS][EXP]), - }}, + // Data + { + Group::SINGLE_ITEM, { + Item("data-alias1", DataType::BINARY_DATA, policy[NO_PASS][EXP]) + } + }, + { + Group::SINGLE_ITEM, { + Item("data-alias2", DataType::BINARY_DATA, policy[PASS][EXP]) + } + }, + + // RSA keys + { + Group::KEY_PAIR_RSA, { + Item("key-rsa-alias-prv1", DataType::KEY_RSA_PRIVATE, policy[NO_PASS][NO_EXP]), + Item("key-rsa-alias-pub1", DataType::KEY_RSA_PUBLIC, policy[NO_PASS][NO_EXP]) + } + }, + { + Group::KEY_PAIR_RSA, { + Item("key-rsa-alias-prv2", DataType::KEY_RSA_PRIVATE, policy[NO_PASS][EXP]), + Item("key-rsa-alias-pub2", DataType::KEY_RSA_PUBLIC, policy[NO_PASS][EXP]), + } + }, + { + Group::KEY_PAIR_RSA, { + Item("key-rsa-alias-prv3", DataType::KEY_RSA_PRIVATE, policy[PASS][NO_EXP]), + Item("key-rsa-alias-pub3", DataType::KEY_RSA_PUBLIC, policy[PASS][NO_EXP]), + } + }, + { + Group::KEY_PAIR_RSA, { + Item("key-rsa-alias-prv4", DataType::KEY_RSA_PRIVATE, policy[PASS][EXP]), + Item("key-rsa-alias-pub4", DataType::KEY_RSA_PUBLIC, policy[PASS][EXP]), + } + }, + // different policies + { + Group::KEY_PAIR_RSA, { + Item("key-rsa-alias-prv5", DataType::KEY_RSA_PRIVATE, policy[PASS][NO_EXP]), + Item("key-rsa-alias-pub5", DataType::KEY_RSA_PUBLIC, policy[NO_PASS][EXP]), + } + }, + + // AES + { + Group::SINGLE_ITEM, { + Item("key-aes-alias1", DataType::KEY_AES, policy[NO_PASS][NO_EXP]), + } + }, + { + Group::SINGLE_ITEM, { + Item("key-aes-alias2", DataType::KEY_AES, policy[NO_PASS][EXP]), + } + }, + { + Group::SINGLE_ITEM, { + Item("key-aes-alias3", DataType::KEY_AES, policy[PASS][NO_EXP]), + } + }, + { + Group::SINGLE_ITEM, { + Item("key-aes-alias4", DataType::KEY_AES, policy[PASS][EXP]), + } + }, + + // Certificates + { + Group::CERT_CHAIN, { + Item("cert-root-alias1", DataType::CERTIFICATE, policy[NO_PASS][NO_EXP]), + Item("cert-im-ca-alias1", DataType::CERTIFICATE, policy[NO_PASS][NO_EXP]), + Item("cert-leaf-alias1", DataType::CERTIFICATE, policy[NO_PASS][NO_EXP]), + } + }, + { + Group::CERT_CHAIN, { + Item("cert-root-alias2", DataType::CERTIFICATE, policy[NO_PASS][EXP]), + Item("cert-im-ca-alias2", DataType::CERTIFICATE, policy[NO_PASS][EXP]), + Item("cert-leaf-alias2", DataType::CERTIFICATE, policy[NO_PASS][EXP]), + } + }, + { + Group::CERT_CHAIN, { + Item("cert-root-alias3", DataType::CERTIFICATE, policy[PASS][NO_EXP]), + Item("cert-im-ca-alias3", DataType::CERTIFICATE, policy[PASS][NO_EXP]), + Item("cert-leaf-alias3", DataType::CERTIFICATE, policy[PASS][NO_EXP]), + } + }, + { + Group::CERT_CHAIN, { + Item("cert-root-alias4", DataType::CERTIFICATE, policy[PASS][EXP]), + Item("cert-im-ca-alias4", DataType::CERTIFICATE, policy[PASS][EXP]), + Item("cert-leaf-alias4", DataType::CERTIFICATE, policy[PASS][EXP]), + } + }, + + // PKCS + { + Group::SINGLE_ITEM, { + Item("pkcs-alias1", DataType::CHAIN_CERT_0, policy[NO_PASS][NO_EXP]), + } + }, + { + Group::SINGLE_ITEM, { + Item("pkcs-alias2", DataType::CHAIN_CERT_0, policy[NO_PASS][EXP]), + } + }, + { + Group::SINGLE_ITEM, { + Item("pkcs-alias3", DataType::CHAIN_CERT_0, policy[PASS][NO_EXP]), + } + }, + { + Group::SINGLE_ITEM, { + Item("pkcs-alias4", DataType::CHAIN_CERT_0, policy[PASS][EXP]), + } + }, }; const size_t CHAIN_SIZE = 3; // TEST_ROOT_CA, expires 2035 std::string TEST_ROOT_CA = - "-----BEGIN CERTIFICATE-----\n" - "MIIDnzCCAoegAwIBAgIJAMH/ADkC5YSTMA0GCSqGSIb3DQEBBQUAMGYxCzAJBgNV\n" - "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYD\n" - "VQQLDAdUZXN0aW5nMSEwHwYDVQQDDBhUZXN0IHJvb3QgY2EgY2VydGlmaWNhdGUw\n" - "HhcNMTQxMjMwMTcyMTUyWhcNMjQxMjI3MTcyMTUyWjBmMQswCQYDVQQGEwJBVTET\n" - "MBEGA1UECAwKU29tZS1TdGF0ZTENMAsGA1UECgwEQUNNRTEQMA4GA1UECwwHVGVz\n" - "dGluZzEhMB8GA1UEAwwYVGVzdCByb290IGNhIGNlcnRpZmljYXRlMIIBIjANBgkq\n" - "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0EJRdUtd2th0vTVF7QxvDKzyFCF3w9vC\n" - "9IDE/Yr12w+a9jd0s7/eG96qTHIYffS3B7x2MB+d4n+SR3W0qmYh7xk8qfEgH3da\n" - "eDoV59IZ9r543KM+g8jm6KffYGX1bIJVVY5OhBRbO9nY6byYpd5kbCIUB6dCf7/W\n" - "rQl1aIdLGFIegAzPGFPXDcU6F192686x54bxt/itMX4agHJ9ZC/rrTBIZghVsjJo\n" - "5/AH5WZpasv8sfrGiiohAxtieoYoJkv5MOYP4/2lPlOY+Cgw1Yoz+HHv31AllgFs\n" - "BquBb/kJVmCCNsAOcnvQzTZUsW/TXz9G2nwRdqI1nSy2JvVjZGsqGQIDAQABo1Aw\n" - "TjAdBgNVHQ4EFgQUt6pkzFt1PZlfYRL/HGnufF4frdwwHwYDVR0jBBgwFoAUt6pk\n" - "zFt1PZlfYRL/HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC\n" - "AQEAld7Qwq0cdzDQ51w1RVLwTR8Oy25PB3rzwEHcSGJmdqlMi3xOdaz80S1R1BBX\n" - "ldvGBG5Tn0vT7xSuhmSgI2/HnBpy9ocHVOmhtNB4473NieEpfTYrnGXrFxu46Wus\n" - "9m/ZnugcQ2G6C54A/NFtvgLmaC8uH8M7gKdS6uYUwJFQEofkjmd4UpOYSqmcRXhS\n" - "Jzd5FYFWkJhKJYp3nlENSOD8CUFFVGekm05nFN2gRVc/qaqQkEX77+XYvhodLRsV\n" - "qMn7nf7taidDKLO2T4bhujztnTYOhhaXKgPy7AtZ28N2wvX96VyAPB/vrchGmyBK\n" - "kOg11TpPdNDkhb1J4ZCh2gupDg==\n" - "-----END CERTIFICATE-----\n"; + "-----BEGIN CERTIFICATE-----\n" + "MIIDnzCCAoegAwIBAgIJAMH/ADkC5YSTMA0GCSqGSIb3DQEBBQUAMGYxCzAJBgNV\n" + "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYD\n" + "VQQLDAdUZXN0aW5nMSEwHwYDVQQDDBhUZXN0IHJvb3QgY2EgY2VydGlmaWNhdGUw\n" + "HhcNMTQxMjMwMTcyMTUyWhcNMjQxMjI3MTcyMTUyWjBmMQswCQYDVQQGEwJBVTET\n" + "MBEGA1UECAwKU29tZS1TdGF0ZTENMAsGA1UECgwEQUNNRTEQMA4GA1UECwwHVGVz\n" + "dGluZzEhMB8GA1UEAwwYVGVzdCByb290IGNhIGNlcnRpZmljYXRlMIIBIjANBgkq\n" + "hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0EJRdUtd2th0vTVF7QxvDKzyFCF3w9vC\n" + "9IDE/Yr12w+a9jd0s7/eG96qTHIYffS3B7x2MB+d4n+SR3W0qmYh7xk8qfEgH3da\n" + "eDoV59IZ9r543KM+g8jm6KffYGX1bIJVVY5OhBRbO9nY6byYpd5kbCIUB6dCf7/W\n" + "rQl1aIdLGFIegAzPGFPXDcU6F192686x54bxt/itMX4agHJ9ZC/rrTBIZghVsjJo\n" + "5/AH5WZpasv8sfrGiiohAxtieoYoJkv5MOYP4/2lPlOY+Cgw1Yoz+HHv31AllgFs\n" + "BquBb/kJVmCCNsAOcnvQzTZUsW/TXz9G2nwRdqI1nSy2JvVjZGsqGQIDAQABo1Aw\n" + "TjAdBgNVHQ4EFgQUt6pkzFt1PZlfYRL/HGnufF4frdwwHwYDVR0jBBgwFoAUt6pk\n" + "zFt1PZlfYRL/HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC\n" + "AQEAld7Qwq0cdzDQ51w1RVLwTR8Oy25PB3rzwEHcSGJmdqlMi3xOdaz80S1R1BBX\n" + "ldvGBG5Tn0vT7xSuhmSgI2/HnBpy9ocHVOmhtNB4473NieEpfTYrnGXrFxu46Wus\n" + "9m/ZnugcQ2G6C54A/NFtvgLmaC8uH8M7gKdS6uYUwJFQEofkjmd4UpOYSqmcRXhS\n" + "Jzd5FYFWkJhKJYp3nlENSOD8CUFFVGekm05nFN2gRVc/qaqQkEX77+XYvhodLRsV\n" + "qMn7nf7taidDKLO2T4bhujztnTYOhhaXKgPy7AtZ28N2wvX96VyAPB/vrchGmyBK\n" + "kOg11TpPdNDkhb1J4ZCh2gupDg==\n" + "-----END CERTIFICATE-----\n"; // TEST_IM_CA, signed by TEST_ROOT_CA, expires 2035 std::string TEST_IM_CA = - "-----BEGIN CERTIFICATE-----\n" - "MIIDljCCAn6gAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwZjELMAkGA1UEBhMCQVUx\n" - "EzARBgNVBAgMClNvbWUtU3RhdGUxDTALBgNVBAoMBEFDTUUxEDAOBgNVBAsMB1Rl\n" - "c3RpbmcxITAfBgNVBAMMGFRlc3Qgcm9vdCBjYSBjZXJ0aWZpY2F0ZTAeFw0xNTAx\n" - "MTYxNjQ1MzRaFw0zNTAxMTExNjQ1MzRaMGQxCzAJBgNVBAYTAkFVMRMwEQYDVQQI\n" - "DApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYDVQQLDAdUZXN0aW5nMR8w\n" - "HQYDVQQDDBZUZXN0IElNIENBIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEF\n" - "AAOCAQ8AMIIBCgKCAQEAzmBF78qClgoKfnLAncMXZwZ14TW+5kags1+QCYeg3c7j\n" - "L9+RvDxIaX2tKf1sukJcwQfYqUlQkwt+58LMOb2ORtkpj8Or6WCWCZ0BzneT8ug7\n" - "nxJT4m9+bohMF0JoKjjB2H4KNMHamLIwUxRKt6nyfk81kVhJOi2vzzxd+UCPi6Pc\n" - "UAbJNH48eNgOIg55nyFovVzYj8GIo/9GvHJj83PPa/KlJZ+Z1qZASZZ/VYorplVT\n" - "thsHXKfejhFy5YJ9t7n/vyAQsyBsagZsvX19xnH41fbYXHKf8UbXG23rNaZlchs6\n" - "XJVLQdzOpj3WTj/lCocVHqLaZISLhNQ3aI7kUBUdiwIDAQABo1AwTjAdBgNVHQ4E\n" - "FgQUoCYNaCBP4jl/3SYQuK8Ka+6i3QEwHwYDVR0jBBgwFoAUt6pkzFt1PZlfYRL/\n" - "HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjRzWiD97\n" - "Htv4Kxpm3P+C+xP9AEteCJfO+7p8MWgtWEJOknJyt55zeKS2JwZIq57KcbqD8U7v\n" - "vAUx1ymtUhlFPFd7J1mJ3pou+3aFYmGShYhGHpbrmUwjp7HVP588jrW1NoZVHdMc\n" - "4OgJWFrViXeu9+maIcekjMB/+9Y0dUgQuK5ZuT5H/Jwet7Th/o9uufTUZjBzRvrB\n" - "pbXgQpqgME2av4Q/6LuldPCTHLtWXgFUU2R+yCGmuGilvhFJnKoQryAbYnIQNWE8\n" - "SLoHQ9s1i7Zyb7HU6UAaqMOz15LBkyAqtNyJcO2p7Q/p5YK0xfD4xisI5qXucqVm\n" - "F2obL5qJSTN/RQ==\n" - "-----END CERTIFICATE-----\n"; + "-----BEGIN CERTIFICATE-----\n" + "MIIDljCCAn6gAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwZjELMAkGA1UEBhMCQVUx\n" + "EzARBgNVBAgMClNvbWUtU3RhdGUxDTALBgNVBAoMBEFDTUUxEDAOBgNVBAsMB1Rl\n" + "c3RpbmcxITAfBgNVBAMMGFRlc3Qgcm9vdCBjYSBjZXJ0aWZpY2F0ZTAeFw0xNTAx\n" + "MTYxNjQ1MzRaFw0zNTAxMTExNjQ1MzRaMGQxCzAJBgNVBAYTAkFVMRMwEQYDVQQI\n" + "DApTb21lLVN0YXRlMQ0wCwYDVQQKDARBQ01FMRAwDgYDVQQLDAdUZXN0aW5nMR8w\n" + "HQYDVQQDDBZUZXN0IElNIENBIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEF\n" + "AAOCAQ8AMIIBCgKCAQEAzmBF78qClgoKfnLAncMXZwZ14TW+5kags1+QCYeg3c7j\n" + "L9+RvDxIaX2tKf1sukJcwQfYqUlQkwt+58LMOb2ORtkpj8Or6WCWCZ0BzneT8ug7\n" + "nxJT4m9+bohMF0JoKjjB2H4KNMHamLIwUxRKt6nyfk81kVhJOi2vzzxd+UCPi6Pc\n" + "UAbJNH48eNgOIg55nyFovVzYj8GIo/9GvHJj83PPa/KlJZ+Z1qZASZZ/VYorplVT\n" + "thsHXKfejhFy5YJ9t7n/vyAQsyBsagZsvX19xnH41fbYXHKf8UbXG23rNaZlchs6\n" + "XJVLQdzOpj3WTj/lCocVHqLaZISLhNQ3aI7kUBUdiwIDAQABo1AwTjAdBgNVHQ4E\n" + "FgQUoCYNaCBP4jl/3SYQuK8Ka+6i3QEwHwYDVR0jBBgwFoAUt6pkzFt1PZlfYRL/\n" + "HGnufF4frdwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjRzWiD97\n" + "Htv4Kxpm3P+C+xP9AEteCJfO+7p8MWgtWEJOknJyt55zeKS2JwZIq57KcbqD8U7v\n" + "vAUx1ymtUhlFPFd7J1mJ3pou+3aFYmGShYhGHpbrmUwjp7HVP588jrW1NoZVHdMc\n" + "4OgJWFrViXeu9+maIcekjMB/+9Y0dUgQuK5ZuT5H/Jwet7Th/o9uufTUZjBzRvrB\n" + "pbXgQpqgME2av4Q/6LuldPCTHLtWXgFUU2R+yCGmuGilvhFJnKoQryAbYnIQNWE8\n" + "SLoHQ9s1i7Zyb7HU6UAaqMOz15LBkyAqtNyJcO2p7Q/p5YK0xfD4xisI5qXucqVm\n" + "F2obL5qJSTN/RQ==\n" + "-----END CERTIFICATE-----\n"; // TEST_LEAF, signed by TEST_IM_CA, expires 2035 std::string TEST_LEAF = - "-----BEGIN CERTIFICATE-----\n" - "MIIDOzCCAiMCAQEwDQYJKoZIhvcNAQEFBQAwZDELMAkGA1UEBhMCQVUxEzARBgNV\n" - "BAgMClNvbWUtU3RhdGUxDTALBgNVBAoMBEFDTUUxEDAOBgNVBAsMB1Rlc3Rpbmcx\n" - "HzAdBgNVBAMMFlRlc3QgSU0gQ0EgY2VydGlmaWNhdGUwHhcNMTUwMTE2MTY0ODE0\n" - "WhcNMzUwMTExMTY0ODE0WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1T\n" - "dGF0ZTENMAsGA1UECgwEQUNNRTEQMA4GA1UECwwHVGVzdGluZzEeMBwGA1UEAwwV\n" - "VGVzdCBsZWFmIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" - "CgKCAQEAzTdDIa2tDmRxFnIgiG+mBz8GoSVODs0ImNQGbqj+pLhBOFRH8fsah4Jl\n" - "z5YF9KwhMVLknnHGFLE/Nb7Ac35kEzhMQMpTRxohW83oxw3eZ8zN/FBoKqg4qHRq\n" - "QR8kS10YXTgrBR0ex/Vp+OUKEw6h7yL2r4Tpvrn9/qHwsxtLxqWbDIVf1O9b1Lfc\n" - "bllYMdmV5E62yN5tcwrDP8gvHjFnVeLzrG8wTpc9FR90/0Jkfp5jAJcArOBLrT0E\n" - "4VRqs+4HuwT8jAwFAmNnc7IYX5qSjtSWkmmHe73K/lzB+OiI0JEc/3eWUTWqwTSk\n" - "4tNCiQGBKJ39LXPTBBJdzmxVH7CUDQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAp\n" - "UdDOGu3hNiG+Vn10aQ6B1ZmOj3t+45gUV3sC+y8hB8EK1g4P5Ke9bVDts0T5eOnj\n" - "CSc+6VoND5O4adI0IFFRFljHNVnvjeosHfUZNnowsmA2ptQBtC1g5ZKRvKXlkC5/\n" - "i5BGgRqPFA7y9WB9Y05MrJHf3E+Oz/RBsLeeNiNN+rF5X1vYExvGHpo0M0zS0ze9\n" - "HtC0aOy8ocsTrQkf3ceHTAXx2i8ftoSSD4klojtWFpWMrNQa52F7wB9nU6FfKRuF\n" - "Zj/T1JkYXKkEwZU6nAR2jdZp3EP9xj3o15V/tyFcXHx6l8NTxn4cJb+Xe4VquQJz\n" - "6ON7PVe0ABN/AlwVQiFE\n" - "-----END CERTIFICATE-----\n"; + "-----BEGIN CERTIFICATE-----\n" + "MIIDOzCCAiMCAQEwDQYJKoZIhvcNAQEFBQAwZDELMAkGA1UEBhMCQVUxEzARBgNV\n" + "BAgMClNvbWUtU3RhdGUxDTALBgNVBAoMBEFDTUUxEDAOBgNVBAsMB1Rlc3Rpbmcx\n" + "HzAdBgNVBAMMFlRlc3QgSU0gQ0EgY2VydGlmaWNhdGUwHhcNMTUwMTE2MTY0ODE0\n" + "WhcNMzUwMTExMTY0ODE0WjBjMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1T\n" + "dGF0ZTENMAsGA1UECgwEQUNNRTEQMA4GA1UECwwHVGVzdGluZzEeMBwGA1UEAwwV\n" + "VGVzdCBsZWFmIGNlcnRpZmljYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" + "CgKCAQEAzTdDIa2tDmRxFnIgiG+mBz8GoSVODs0ImNQGbqj+pLhBOFRH8fsah4Jl\n" + "z5YF9KwhMVLknnHGFLE/Nb7Ac35kEzhMQMpTRxohW83oxw3eZ8zN/FBoKqg4qHRq\n" + "QR8kS10YXTgrBR0ex/Vp+OUKEw6h7yL2r4Tpvrn9/qHwsxtLxqWbDIVf1O9b1Lfc\n" + "bllYMdmV5E62yN5tcwrDP8gvHjFnVeLzrG8wTpc9FR90/0Jkfp5jAJcArOBLrT0E\n" + "4VRqs+4HuwT8jAwFAmNnc7IYX5qSjtSWkmmHe73K/lzB+OiI0JEc/3eWUTWqwTSk\n" + "4tNCiQGBKJ39LXPTBBJdzmxVH7CUDQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAp\n" + "UdDOGu3hNiG+Vn10aQ6B1ZmOj3t+45gUV3sC+y8hB8EK1g4P5Ke9bVDts0T5eOnj\n" + "CSc+6VoND5O4adI0IFFRFljHNVnvjeosHfUZNnowsmA2ptQBtC1g5ZKRvKXlkC5/\n" + "i5BGgRqPFA7y9WB9Y05MrJHf3E+Oz/RBsLeeNiNN+rF5X1vYExvGHpo0M0zS0ze9\n" + "HtC0aOy8ocsTrQkf3ceHTAXx2i8ftoSSD4klojtWFpWMrNQa52F7wB9nU6FfKRuF\n" + "Zj/T1JkYXKkEwZU6nAR2jdZp3EP9xj3o15V/tyFcXHx6l8NTxn4cJb+Xe4VquQJz\n" + "6ON7PVe0ABN/AlwVQiFE\n" + "-----END CERTIFICATE-----\n"; struct FdCloser { - void operator()(int* fd) { - if(fd) - close(*fd); - } + void operator()(int *fd) + { + if (fd) + close(*fd); + } }; typedef std::unique_ptr<int, FdCloser> FdPtr; -uid_t getUid(const char *name) { - struct passwd pwd; - struct passwd *result = nullptr; - int bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize <= 0) - bufsize = 16384; /* should be more than enough */ +uid_t getUid(const char *name) +{ + struct passwd pwd; + struct passwd *result = nullptr; + int bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (bufsize <= 0) + bufsize = 16384; /* should be more than enough */ - memset(&pwd, 0x00, sizeof(pwd)); + memset(&pwd, 0x00, sizeof(pwd)); - std::vector<char> buf(bufsize, 0); + std::vector<char> buf(bufsize, 0); - int ret = getpwnam_r(name, &pwd, buf.data(), bufsize, &result); - BOOST_REQUIRE_MESSAGE(ret == 0 && result, "getpwnam_r failed"); + int ret = getpwnam_r(name, &pwd, buf.data(), bufsize, &result); + BOOST_REQUIRE_MESSAGE(ret == 0 && result, "getpwnam_r failed"); - return pwd.pw_uid; + return pwd.pw_uid; } -gid_t getGid(const char *name) { - struct group grp; - struct group *result = nullptr; - size_t bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); - if (bufsize <= 0) - bufsize = 16384; /* should be more than enough */ +gid_t getGid(const char *name) +{ + struct group grp; + struct group *result = nullptr; + size_t bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); + + if (bufsize <= 0) + bufsize = 16384; /* should be more than enough */ - memset(&grp, 0x00, sizeof(grp)); + memset(&grp, 0x00, sizeof(grp)); - std::vector<char> buf(bufsize, 0); + std::vector<char> buf(bufsize, 0); - int ret = getgrnam_r(name, &grp, buf.data(), bufsize, &result); - BOOST_REQUIRE_MESSAGE(ret == 0 && result, "getgrnam_r failed"); + int ret = getgrnam_r(name, &grp, buf.data(), bufsize, &result); + BOOST_REQUIRE_MESSAGE(ret == 0 && result, "getgrnam_r failed"); - return grp.gr_gid; + return grp.gr_gid; } -void restoreFile(const string& filename) { - static uid_t CKM_UID = getUid(USER_NAME); - static gid_t CKM_GID = getGid(GROUP_NAME); - string sourcePath = string(DB_TEST_DIR) + "/" + filename; - string targetPath = string(RW_DATA_DIR) + "/" + filename; +void restoreFile(const string &filename) +{ + static uid_t CKM_UID = getUid(USER_NAME); + static gid_t CKM_GID = getGid(GROUP_NAME); + string sourcePath = string(DB_TEST_DIR) + "/" + filename; + string targetPath = string(RW_DATA_DIR) + "/" + filename; - int err, ret; + int err, ret; - int sourceFd = TEMP_FAILURE_RETRY(open(sourcePath.c_str(), O_RDONLY)); - err = errno; - BOOST_REQUIRE_MESSAGE(sourceFd > 0, "Opening " << sourcePath << " failed: " << GetErrnoString(err)); + int sourceFd = TEMP_FAILURE_RETRY(open(sourcePath.c_str(), O_RDONLY)); + err = errno; + BOOST_REQUIRE_MESSAGE(sourceFd > 0, + "Opening " << sourcePath << " failed: " << GetErrnoString(err)); - FdPtr sourceFdPtr(&sourceFd); + FdPtr sourceFdPtr(&sourceFd); - int targetFd = TEMP_FAILURE_RETRY(creat(targetPath.c_str(), 0644)); - err = errno; - BOOST_REQUIRE_MESSAGE(targetFd > 0, "Creating " << targetPath << " failed: " << GetErrnoString(err)); + int targetFd = TEMP_FAILURE_RETRY(creat(targetPath.c_str(), 0644)); + err = errno; + BOOST_REQUIRE_MESSAGE(targetFd > 0, + "Creating " << targetPath << " failed: " << GetErrnoString(err)); - ret = fchown(targetFd, CKM_UID, CKM_GID); - err = errno; - BOOST_REQUIRE_MESSAGE(ret != -1, "fchown() failed: " << GetErrnoString(err)); + ret = fchown(targetFd, CKM_UID, CKM_GID); + err = errno; + BOOST_REQUIRE_MESSAGE(ret != -1, "fchown() failed: " << GetErrnoString(err)); - FdPtr targetFdPtr(&targetFd); + FdPtr targetFdPtr(&targetFd); - struct stat sourceStat; - ret = fstat(sourceFd, &sourceStat); - err = errno; - BOOST_REQUIRE_MESSAGE(ret != -1, "fstat() failed: " << GetErrnoString(err)); + struct stat sourceStat; + ret = fstat(sourceFd, &sourceStat); + err = errno; + BOOST_REQUIRE_MESSAGE(ret != -1, "fstat() failed: " << GetErrnoString(err)); - ret = sendfile(targetFd, sourceFd, 0, sourceStat.st_size); - err = errno; - BOOST_REQUIRE_MESSAGE(ret != -1, "sendfile() failed: " << GetErrnoString(err)); + ret = sendfile(targetFd, sourceFd, 0, sourceStat.st_size); + err = errno; + BOOST_REQUIRE_MESSAGE(ret != -1, "sendfile() failed: " << GetErrnoString(err)); - ret = fsync(targetFd); - err = errno; - BOOST_REQUIRE_MESSAGE(ret != -1, "fsync() failed: " << GetErrnoString(err)); + ret = fsync(targetFd); + err = errno; + BOOST_REQUIRE_MESSAGE(ret != -1, "fsync() failed: " << GetErrnoString(err)); } void generateRandom(size_t random_bytes, unsigned char *output) { - if(random_bytes<=0 || !output) - throw runtime_error("Invalid param"); - - std::ifstream is("/dev/urandom", std::ifstream::binary); - if(!is) - throw runtime_error("Failed to read /dev/urandom"); - is.read(reinterpret_cast<char*>(output), random_bytes); - if(static_cast<std::streamsize>(random_bytes) != is.gcount()) - throw runtime_error("Not enough bytes read from /dev/urandom"); + if (random_bytes <= 0 || !output) + throw runtime_error("Invalid param"); + + std::ifstream is("/dev/urandom", std::ifstream::binary); + + if (!is) + throw runtime_error("Failed to read /dev/urandom"); + + is.read(reinterpret_cast<char *>(output), random_bytes); + + if (static_cast<std::streamsize>(random_bytes) != is.gcount()) + throw runtime_error("Not enough bytes read from /dev/urandom"); } RawBuffer createRandomBuffer(size_t random_bytes) { - RawBuffer buffer(random_bytes); - generateRandom(buffer.size(), buffer.data()); - return buffer; + RawBuffer buffer(random_bytes); + generateRandom(buffer.size(), buffer.data()); + return buffer; } } // namespace anonymous -SchemeTest::SchemeTest() : m_userChanged(false), m_directAccessEnabled(false) { - m_control = Control::create(); - m_mgr = Manager::create(); - initOpenSsl(); - - SmackAccess sa; - sa.add("System", LABEL, "rwx"); - sa.add(LABEL, "System", "rwx"); - sa.add(LABEL, "System::Run", "x"); - sa.apply(); +SchemeTest::SchemeTest() : m_userChanged(false), m_directAccessEnabled(false) +{ + m_control = Control::create(); + m_mgr = Manager::create(); + initOpenSsl(); + + SmackAccess sa; + sa.add("System", LABEL, "rwx"); + sa.add(LABEL, "System", "rwx"); + sa.add(LABEL, "System::Run", "x"); + sa.apply(); } -SchemeTest::~SchemeTest() { - try { - SwitchToRoot(); - } catch (...) {} +SchemeTest::~SchemeTest() +{ + try { + SwitchToRoot(); + } catch (...) {} } -void SchemeTest::RemoveUserData() { - if(CKM_API_SUCCESS != m_control->lockUserKey(UID)) - throw runtime_error("lockUserKey failed"); +void SchemeTest::RemoveUserData() +{ + if (CKM_API_SUCCESS != m_control->lockUserKey(UID)) + throw runtime_error("lockUserKey failed"); - if(CKM_API_SUCCESS != m_control->removeUserData(UID)) - throw runtime_error("removeUserData failed"); + if (CKM_API_SUCCESS != m_control->removeUserData(UID)) + throw runtime_error("removeUserData failed"); } -void SchemeTest::SwitchToUser() { - if (m_userChanged) - return; +void SchemeTest::SwitchToUser() +{ + if (m_userChanged) + return; - if(CKM_API_SUCCESS != m_control->unlockUserKey(UID, DBPASS)) - throw runtime_error("unlockUserKey failed"); + if (CKM_API_SUCCESS != m_control->unlockUserKey(UID, DBPASS)) + throw runtime_error("unlockUserKey failed"); - // get calling label - char* label = NULL; - if (smack_new_label_from_self(&label) <= 0) - throw runtime_error("smack_new_label_from_self failed"); + // get calling label + char *label = NULL; - m_origLabel = string(label); - free(label); + if (smack_new_label_from_self(&label) <= 0) + throw runtime_error("smack_new_label_from_self failed"); - if(0 > smack_set_label_for_self(LABEL)) - throw runtime_error("smack_set_label_for_self failed"); + m_origLabel = string(label); + free(label); - if(0 > setegid(GID)) - throw runtime_error("setegid failed"); + if (0 > smack_set_label_for_self(LABEL)) + throw runtime_error("smack_set_label_for_self failed"); - if(0 > seteuid(UID)) - throw runtime_error("seteuid failed"); + if (0 > setegid(GID)) + throw runtime_error("setegid failed"); - m_userChanged = true; -} + if (0 > seteuid(UID)) + throw runtime_error("seteuid failed"); -void SchemeTest::SwitchToRoot() { - if (!m_userChanged) - return; + m_userChanged = true; +} - if(0 > seteuid(0)) - throw runtime_error("seteuid failed"); - if(0 > setegid(0)) - throw runtime_error("setegid failed"); +void SchemeTest::SwitchToRoot() +{ + if (!m_userChanged) + return; - if(0 > smack_set_label_for_self(m_origLabel.c_str())) - throw runtime_error("smack_set_label_for_self failed"); + if (0 > seteuid(0)) + throw runtime_error("seteuid failed"); - if(m_control->lockUserKey(UID) != CKM_API_SUCCESS) - throw runtime_error("lockUserKey failed"); -} + if (0 > setegid(0)) + throw runtime_error("setegid failed"); -void SchemeTest::FillDb() { - // pkcs - ifstream is(DB_TEST_DIR "/encryption-scheme.p12"); - if(!is) - throw runtime_error("Failed to read pkcs"); - istreambuf_iterator<char> begin(is), end; - RawBuffer pkcsBuffer(begin, end); - auto pkcs = PKCS12::create(pkcsBuffer, Password()); - if(pkcs->empty()) - throw runtime_error("Empty pkcs"); - - SwitchToUser(); - - // certificates - RawBuffer rootCaBuffer(TEST_ROOT_CA.begin(), TEST_ROOT_CA.end()); - CertificateShPtr rootCa = CKM::Certificate::create(rootCaBuffer, CKM::DataFormat::FORM_PEM); - RawBuffer imCaBuffer(TEST_IM_CA.begin(), TEST_IM_CA.end()); - CertificateShPtr imCa = CKM::Certificate::create(imCaBuffer, CKM::DataFormat::FORM_PEM); - RawBuffer leafBuffer(TEST_LEAF.begin(), TEST_LEAF.end()); - CertificateShPtr leaf = CKM::Certificate::create(leafBuffer, CKM::DataFormat::FORM_PEM); - - for(const auto& g:GROUPS) { - switch (g.type) { - case Group::KEY_PAIR_RSA: - if(g.items.size() != 2) - throw runtime_error("Wrong number of keys"); - if( g.items[0].type != DataType::KEY_RSA_PRIVATE || - g.items[1].type != DataType::KEY_RSA_PUBLIC) - throw runtime_error("Invalid item type"); - - if(CKM_API_SUCCESS != m_mgr->createKeyPairRSA(1024, - g.items[0].alias, - g.items[1].alias, - g.items[0].policy, - g.items[1].policy)) - throw runtime_error("createKeyPair failed"); - break; - - case Group::CERT_CHAIN: - if(g.items.size() != CHAIN_SIZE) - throw runtime_error("Wrong number of certificates"); - if( g.items[0].type != DataType::CERTIFICATE || - g.items[1].type != DataType::CERTIFICATE || - g.items[2].type != DataType::CERTIFICATE) - throw runtime_error("Invalid item type"); - - if(CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[0].alias, rootCa, g.items[0].policy)) - throw runtime_error("saveCertificate failed"); - if(CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[1].alias, imCa, g.items[1].policy)) - throw runtime_error("saveCertificate failed"); - if(CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[2].alias, leaf, g.items[2].policy)) - throw runtime_error("saveCertificate failed"); - break; - - default: - for(const auto& i:g.items) { - switch (i.type) { - case DataType::BINARY_DATA: - if(CKM_API_SUCCESS != m_mgr->saveData(i.alias, TEST_DATA, i.policy)) - throw runtime_error("saveData failed"); - break; - - case DataType::KEY_AES: - if(CKM_API_SUCCESS != m_mgr->createKeyAES(256, i.alias, i.policy)) - throw runtime_error("createKeyAES failed"); - break; - - case DataType::CHAIN_CERT_0: // PKCS - if(CKM_API_SUCCESS != m_mgr->savePKCS12(i.alias, pkcs, i.policy, i.policy)) - throw runtime_error("savePkcs12 failed"); - break; - - default: - throw runtime_error("unsupported data type"); - } - } - break; - } - } -} + if (0 > smack_set_label_for_self(m_origLabel.c_str())) + throw runtime_error("smack_set_label_for_self failed"); -void SchemeTest::ReadAll(bool useWrongPass) { - SwitchToUser(); - - for(const auto& g:GROUPS) { - for(const auto& i:g.items) { - int ret; - Password pass = i.policy.password; - if(useWrongPass) { - if(pass.empty()) - pass = TEST_PASS; - else - pass = Password(); - } - - switch (i.type) { - case DataType::BINARY_DATA: - { - RawBuffer receivedData; - ret = m_mgr->getData(i.alias, pass, receivedData); - BOOST_REQUIRE_MESSAGE(useWrongPass || receivedData == TEST_DATA, - "Received data is different for " << i.alias); - break; - } - - case DataType::KEY_AES: - case DataType::KEY_RSA_PRIVATE: - case DataType::KEY_RSA_PUBLIC: - { - KeyShPtr receivedKey; - ret = m_mgr->getKey(i.alias, pass, receivedKey); - break; - } - - case DataType::CERTIFICATE: - { - CertificateShPtr receivedCert; - ret = m_mgr->getCertificate(i.alias, pass, receivedCert); - break; - } - - case DataType::CHAIN_CERT_0: // pkcs - { - PKCS12ShPtr pkcs; - ret = m_mgr->getPKCS12(i.alias, pass, pass, pkcs); - break; - } - - default: - BOOST_FAIL("Unsupported data type " << i.type); - } - - if(i.policy.extractable) { - if(useWrongPass) - BOOST_REQUIRE_MESSAGE(ret == CKM_API_ERROR_AUTHENTICATION_FAILED, - "Reading item " << i.alias << " should fail with " << - CKM_API_ERROR_AUTHENTICATION_FAILED << " got: " << ret); - else - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "Reading item " << i.alias << - " failed with " << ret); - } - else - BOOST_REQUIRE_MESSAGE(ret == CKM_API_ERROR_NOT_EXPORTABLE, "Item " << i.alias << - " should not be exportable"); - } - } + if (m_control->lockUserKey(UID) != CKM_API_SUCCESS) + throw runtime_error("lockUserKey failed"); } -void SchemeTest::SignVerify() { - SwitchToUser(); - - for(const auto& g:GROUPS) { - if(g.type == Group::KEY_PAIR_RSA) { - BOOST_REQUIRE_MESSAGE(g.items.size() == 2, "Wrong number of keys"); - BOOST_REQUIRE_MESSAGE(g.items[0].type == DataType::KEY_RSA_PRIVATE && - g.items[1].type == DataType::KEY_RSA_PUBLIC, "Wrong key"); - - SignVerifyItem(g.items[0], g.items[1]); - } else { - for(const auto& i:g.items) { - switch (i.type) { - case DataType::CHAIN_CERT_0: - SignVerifyItem(i, i); - break; - - default: - break; - } - } - } - } +void SchemeTest::FillDb() +{ + // pkcs + ifstream is(DB_TEST_DIR "/encryption-scheme.p12"); + + if (!is) + throw runtime_error("Failed to read pkcs"); + + istreambuf_iterator<char> begin(is), end; + RawBuffer pkcsBuffer(begin, end); + auto pkcs = PKCS12::create(pkcsBuffer, Password()); + + if (pkcs->empty()) + throw runtime_error("Empty pkcs"); + + SwitchToUser(); + + // certificates + RawBuffer rootCaBuffer(TEST_ROOT_CA.begin(), TEST_ROOT_CA.end()); + CertificateShPtr rootCa = CKM::Certificate::create(rootCaBuffer, + CKM::DataFormat::FORM_PEM); + RawBuffer imCaBuffer(TEST_IM_CA.begin(), TEST_IM_CA.end()); + CertificateShPtr imCa = CKM::Certificate::create(imCaBuffer, + CKM::DataFormat::FORM_PEM); + RawBuffer leafBuffer(TEST_LEAF.begin(), TEST_LEAF.end()); + CertificateShPtr leaf = CKM::Certificate::create(leafBuffer, + CKM::DataFormat::FORM_PEM); + + for (const auto &g : GROUPS) { + switch (g.type) { + case Group::KEY_PAIR_RSA: + if (g.items.size() != 2) + throw runtime_error("Wrong number of keys"); + + if (g.items[0].type != DataType::KEY_RSA_PRIVATE || + g.items[1].type != DataType::KEY_RSA_PUBLIC) + throw runtime_error("Invalid item type"); + + if (CKM_API_SUCCESS != m_mgr->createKeyPairRSA(1024, + g.items[0].alias, + g.items[1].alias, + g.items[0].policy, + g.items[1].policy)) + throw runtime_error("createKeyPair failed"); + + break; + + case Group::CERT_CHAIN: + if (g.items.size() != CHAIN_SIZE) + throw runtime_error("Wrong number of certificates"); + + if (g.items[0].type != DataType::CERTIFICATE || + g.items[1].type != DataType::CERTIFICATE || + g.items[2].type != DataType::CERTIFICATE) + throw runtime_error("Invalid item type"); + + if (CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[0].alias, rootCa, + g.items[0].policy)) + throw runtime_error("saveCertificate failed"); + + if (CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[1].alias, imCa, + g.items[1].policy)) + throw runtime_error("saveCertificate failed"); + + if (CKM_API_SUCCESS != m_mgr->saveCertificate(g.items[2].alias, leaf, + g.items[2].policy)) + throw runtime_error("saveCertificate failed"); + + break; + + default: + for (const auto &i : g.items) { + switch (i.type) { + case DataType::BINARY_DATA: + if (CKM_API_SUCCESS != m_mgr->saveData(i.alias, TEST_DATA, i.policy)) + throw runtime_error("saveData failed"); + + break; + + case DataType::KEY_AES: + if (CKM_API_SUCCESS != m_mgr->createKeyAES(256, i.alias, i.policy)) + throw runtime_error("createKeyAES failed"); + + break; + + case DataType::CHAIN_CERT_0: // PKCS + if (CKM_API_SUCCESS != m_mgr->savePKCS12(i.alias, pkcs, i.policy, i.policy)) + throw runtime_error("savePkcs12 failed"); + + break; + + default: + throw runtime_error("unsupported data type"); + } + } + + break; + } + } } -void SchemeTest::EncryptDecrypt() { - SwitchToUser(); - - for(const auto& g:GROUPS) { - if(g.type == Group::KEY_PAIR_RSA) { - BOOST_REQUIRE_MESSAGE(g.items.size() == 2, "Wrong number of keys"); - BOOST_REQUIRE_MESSAGE(g.items[0].type == DataType::KEY_RSA_PRIVATE && - g.items[1].type == DataType::KEY_RSA_PUBLIC, "Wrong key"); - - EncryptDecryptItem(g.items[0], g.items[1]); - } else { - for(const auto& i:g.items) { - switch (i.type) { - case DataType::KEY_AES: - EncryptDecryptItem(i); - break; - - case DataType::CHAIN_CERT_0: - EncryptDecryptItem(i, i); - break; - - default: - break; - } - } - } - } +void SchemeTest::ReadAll(bool useWrongPass) +{ + SwitchToUser(); + + for (const auto &g : GROUPS) { + for (const auto &i : g.items) { + int ret; + Password pass = i.policy.password; + + if (useWrongPass) { + if (pass.empty()) + pass = TEST_PASS; + else + pass = Password(); + } + + switch (i.type) { + case DataType::BINARY_DATA: { + RawBuffer receivedData; + ret = m_mgr->getData(i.alias, pass, receivedData); + BOOST_REQUIRE_MESSAGE(useWrongPass || receivedData == TEST_DATA, + "Received data is different for " << i.alias); + break; + } + + case DataType::KEY_AES: + case DataType::KEY_RSA_PRIVATE: + case DataType::KEY_RSA_PUBLIC: { + KeyShPtr receivedKey; + ret = m_mgr->getKey(i.alias, pass, receivedKey); + break; + } + + case DataType::CERTIFICATE: { + CertificateShPtr receivedCert; + ret = m_mgr->getCertificate(i.alias, pass, receivedCert); + break; + } + + case DataType::CHAIN_CERT_0: { // pkcs + PKCS12ShPtr pkcs; + ret = m_mgr->getPKCS12(i.alias, pass, pass, pkcs); + break; + } + + default: + BOOST_FAIL("Unsupported data type " << i.type); + } + + if (i.policy.extractable) { + if (useWrongPass) + BOOST_REQUIRE_MESSAGE(ret == CKM_API_ERROR_AUTHENTICATION_FAILED, + "Reading item " << i.alias << " should fail with " << + CKM_API_ERROR_AUTHENTICATION_FAILED << " got: " << ret); + else + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "Reading item " << i.alias << + " failed with " << ret); + } else { + BOOST_REQUIRE_MESSAGE(ret == CKM_API_ERROR_NOT_EXPORTABLE, "Item " << i.alias << + " should not be exportable"); + } + } + } } -void SchemeTest::CreateChain() { - SwitchToUser(); - - for(const auto& g:GROUPS) { - if(g.type == Group::CERT_CHAIN) { - BOOST_REQUIRE_MESSAGE(g.items.size() == CHAIN_SIZE, "Not enough certificates"); - for(const auto& c:g.items) - BOOST_REQUIRE_MESSAGE(c.type == DataType::CERTIFICATE, "Wrong item type"); - Items trusted(CHAIN_SIZE-1); - std::copy(g.items.begin(), g.items.begin() + CHAIN_SIZE-1, trusted.begin()); - - // last one is ee (leaf) - CreateChainItem(g.items.back(), trusted); - } else { - for(const auto& i:g.items) { - if(i.type == DataType::CHAIN_CERT_0) // PKCS - CreateChainItem(i, { i }); - } - } - } +void SchemeTest::SignVerify() +{ + SwitchToUser(); + + for (const auto &g : GROUPS) { + if (g.type == Group::KEY_PAIR_RSA) { + BOOST_REQUIRE_MESSAGE(g.items.size() == 2, "Wrong number of keys"); + BOOST_REQUIRE_MESSAGE(g.items[0].type == DataType::KEY_RSA_PRIVATE && + g.items[1].type == DataType::KEY_RSA_PUBLIC, "Wrong key"); + + SignVerifyItem(g.items[0], g.items[1]); + } else { + for (const auto &i : g.items) { + switch (i.type) { + case DataType::CHAIN_CERT_0: + SignVerifyItem(i, i); + break; + + default: + break; + } + } + } + } } -void SchemeTest::RemoveAll() { - SwitchToUser(); - - for(const auto& g:GROUPS) { - for(const auto& i:g.items) { - int ret = m_mgr->removeAlias(i.alias); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, - "removeAlias() failed with " << ret << " for " << i.alias); - } - } -} -size_t SchemeTest::CountObjects() { - EnableDirectDbAccess(); - - size_t ret = 0; - for(const auto& g:GROUPS) { - for(const auto& i:g.items) { - DB::RowVector rows; - // it is assumed that aliases are different - m_db->getRows(i.alias, DB_LABEL, DataType::DB_FIRST, DataType::DB_LAST, rows); - ret += rows.size(); - } - } - return ret; +void SchemeTest::EncryptDecrypt() +{ + SwitchToUser(); + + for (const auto &g : GROUPS) { + if (g.type == Group::KEY_PAIR_RSA) { + BOOST_REQUIRE_MESSAGE(g.items.size() == 2, "Wrong number of keys"); + BOOST_REQUIRE_MESSAGE(g.items[0].type == DataType::KEY_RSA_PRIVATE && + g.items[1].type == DataType::KEY_RSA_PUBLIC, "Wrong key"); + + EncryptDecryptItem(g.items[0], g.items[1]); + } else { + for (const auto &i : g.items) { + switch (i.type) { + case DataType::KEY_AES: + EncryptDecryptItem(i); + break; + + case DataType::CHAIN_CERT_0: + EncryptDecryptItem(i, i); + break; + + default: + break; + } + } + } + } } -void SchemeTest::RestoreDb() { - restoreFile("key-7654"); - restoreFile("db-key-7654"); - restoreFile("db-7654"); - m_db.reset(); - m_directAccessEnabled = false; +void SchemeTest::CreateChain() +{ + SwitchToUser(); + + for (const auto &g : GROUPS) { + if (g.type == Group::CERT_CHAIN) { + BOOST_REQUIRE_MESSAGE(g.items.size() == CHAIN_SIZE, "Not enough certificates"); + + for (const auto &c : g.items) + BOOST_REQUIRE_MESSAGE(c.type == DataType::CERTIFICATE, "Wrong item type"); + + Items trusted(CHAIN_SIZE - 1); + std::copy(g.items.begin(), g.items.begin() + CHAIN_SIZE - 1, trusted.begin()); + + // last one is ee (leaf) + CreateChainItem(g.items.back(), trusted); + } else { + for (const auto &i : g.items) { + if (i.type == DataType::CHAIN_CERT_0) // PKCS + CreateChainItem(i, { i }); + } + } + } } -void SchemeTest::CheckSchemeVersion(const ItemFilter& filter, int version) { - EnableDirectDbAccess(); - - for(const auto& g:GROUPS) { - for(const auto& i:g.items) { - if(!filter.Matches(i)) - continue; - - DB::RowVector rows; - m_db->getRows(i.alias, DB_LABEL, filter.typeFrom, filter.typeTo, rows); - BOOST_REQUIRE_MESSAGE(rows.size() > 0, "No rows found for " << i.alias); - for(const auto& r : rows) { - BOOST_REQUIRE_MESSAGE( - (r.encryptionScheme >> ENC_SCHEME_OFFSET) == version, - "Wrong encryption scheme for " << i.alias << ". Expected " << version << - " got: " << (r.encryptionScheme >> ENC_SCHEME_OFFSET)); - } - } - } +void SchemeTest::RemoveAll() +{ + SwitchToUser(); + + for (const auto &g : GROUPS) { + for (const auto &i : g.items) { + int ret = m_mgr->removeAlias(i.alias); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "removeAlias() failed with " << ret << " for " << i.alias); + } + } } +size_t SchemeTest::CountObjects() +{ + EnableDirectDbAccess(); -void SchemeTest::EnableDirectDbAccess() { - SwitchToRoot(); - - if(m_directAccessEnabled) - return; - - // direct access to db - FileSystem fs(UID); - auto wrappedDKEK = fs.getDKEK(); - auto keyProvider = KeyProvider(wrappedDKEK, DBPASS); + size_t ret = 0; - auto wrappedDatabaseDEK = fs.getDBDEK(); - RawBuffer key = keyProvider.getPureDEK(wrappedDatabaseDEK); + for (const auto &g : GROUPS) { + for (const auto &i : g.items) { + DB::RowVector rows; + // it is assumed that aliases are different + m_db->getRows(i.alias, DB_LABEL, DataType::DB_FIRST, DataType::DB_LAST, rows); + ret += rows.size(); + } + } - m_db.reset(new DB::Crypto(fs.getDBPath(), key)); - m_directAccessEnabled = true; + return ret; } -void SchemeTest::SignVerifyItem(const Item& itemPrv, const Item& itemPub) { - int ret; - KeyShPtr receivedKey; - RawBuffer signature; - // create/verify signature - ret = m_mgr->createSignature(itemPrv.alias, - itemPrv.policy.password, - TEST_DATA, - HashAlgorithm::SHA512, - RSAPaddingAlgorithm::X931, - signature); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "createSignature() failed with " << ret << - " for " << itemPrv.alias); - ret = m_mgr->verifySignature(itemPub.alias, - itemPub.policy.password, - TEST_DATA, - signature, - HashAlgorithm::SHA512, - RSAPaddingAlgorithm::X931); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "verifySignature() failed with " << ret << - " for " << itemPub.alias); +void SchemeTest::RestoreDb() +{ + restoreFile("key-7654"); + restoreFile("db-key-7654"); + restoreFile("db-7654"); + m_db.reset(); + m_directAccessEnabled = false; +} +void SchemeTest::CheckSchemeVersion(const ItemFilter &filter, int version) +{ + EnableDirectDbAccess(); + + for (const auto &g : GROUPS) { + for (const auto &i : g.items) { + if (!filter.Matches(i)) + continue; + + DB::RowVector rows; + m_db->getRows(i.alias, DB_LABEL, filter.typeFrom, filter.typeTo, rows); + BOOST_REQUIRE_MESSAGE(rows.size() > 0, "No rows found for " << i.alias); + + for (const auto &r : rows) { + BOOST_REQUIRE_MESSAGE( + (r.encryptionScheme >> ENC_SCHEME_OFFSET) == version, + "Wrong encryption scheme for " << i.alias << ". Expected " << version << + " got: " << (r.encryptionScheme >> ENC_SCHEME_OFFSET)); + } + } + } } -void SchemeTest::EncryptDecryptItem(const Item& item) { - CryptoAlgorithm algo; - RawBuffer iv = createRandomBuffer(IV_LEN); - RawBuffer encrypted, decrypted; - int ret; +void SchemeTest::EnableDirectDbAccess() +{ + SwitchToRoot(); - algo.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM); - algo.setParam(ParamName::ED_IV, iv); + if (m_directAccessEnabled) + return; - ret = m_mgr->encrypt(algo, item.alias, item.policy.password, TEST_DATA, encrypted); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "encrypt() failed iwth " << ret << " for " << - item.alias); + // direct access to db + FileSystem fs(UID); + auto wrappedDKEK = fs.getDKEK(); + auto keyProvider = KeyProvider(wrappedDKEK, DBPASS); - ret = m_mgr->decrypt(algo, item.alias, item.policy.password, encrypted, decrypted); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "decrypt() failed iwth " << ret << " for " << - item.alias); + auto wrappedDatabaseDEK = fs.getDBDEK(); + RawBuffer key = keyProvider.getPureDEK(wrappedDatabaseDEK); - BOOST_REQUIRE_MESSAGE(decrypted == TEST_DATA, "Decrypted data not equal to original"); + m_db.reset(new DB::Crypto(fs.getDBPath(), key)); + m_directAccessEnabled = true; } -void SchemeTest::EncryptDecryptItem(const Item& itemPrv, const Item& itemPub) { - CryptoAlgorithm algo; - RawBuffer encrypted, decrypted; - int ret; - - algo.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP); - - ret = m_mgr->encrypt(algo, itemPub.alias, itemPub.policy.password, TEST_DATA, encrypted); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "encrypt() failed iwth " << ret << " for " << - itemPub.alias); +void SchemeTest::SignVerifyItem(const Item &itemPrv, const Item &itemPub) +{ + int ret; + KeyShPtr receivedKey; + RawBuffer signature; + // create/verify signature + ret = m_mgr->createSignature(itemPrv.alias, + itemPrv.policy.password, + TEST_DATA, + HashAlgorithm::SHA512, + RSAPaddingAlgorithm::X931, + signature); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "createSignature() failed with " << ret << + " for " << itemPrv.alias); + ret = m_mgr->verifySignature(itemPub.alias, + itemPub.policy.password, + TEST_DATA, + signature, + HashAlgorithm::SHA512, + RSAPaddingAlgorithm::X931); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "verifySignature() failed with " << ret << + " for " << itemPub.alias); +} - ret = m_mgr->decrypt(algo, itemPrv.alias, itemPrv.policy.password, encrypted, decrypted); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, "decrypt() failed iwth " << ret << " for " << - itemPrv.alias); +void SchemeTest::EncryptDecryptItem(const Item &item) +{ + CryptoAlgorithm algo; + RawBuffer iv = createRandomBuffer(IV_LEN); + RawBuffer encrypted, decrypted; + int ret; + + algo.setParam(ParamName::ALGO_TYPE, AlgoType::AES_GCM); + algo.setParam(ParamName::ED_IV, iv); + + ret = m_mgr->encrypt(algo, item.alias, item.policy.password, TEST_DATA, + encrypted); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "encrypt() failed iwth " << ret << " for " << + item.alias); + + ret = m_mgr->decrypt(algo, item.alias, item.policy.password, encrypted, + decrypted); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "decrypt() failed iwth " << ret << " for " << + item.alias); + + BOOST_REQUIRE_MESSAGE(decrypted == TEST_DATA, + "Decrypted data not equal to original"); +} - BOOST_REQUIRE_MESSAGE(decrypted == TEST_DATA, "Decrypted data not equal to original"); +void SchemeTest::EncryptDecryptItem(const Item &itemPrv, const Item &itemPub) +{ + CryptoAlgorithm algo; + RawBuffer encrypted, decrypted; + int ret; + + algo.setParam(ParamName::ALGO_TYPE, AlgoType::RSA_OAEP); + + ret = m_mgr->encrypt(algo, itemPub.alias, itemPub.policy.password, TEST_DATA, + encrypted); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "encrypt() failed iwth " << ret << " for " << + itemPub.alias); + + ret = m_mgr->decrypt(algo, itemPrv.alias, itemPrv.policy.password, encrypted, + decrypted); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "decrypt() failed iwth " << ret << " for " << + itemPrv.alias); + + BOOST_REQUIRE_MESSAGE(decrypted == TEST_DATA, + "Decrypted data not equal to original"); } -void SchemeTest::CreateChainItem(const Item& leaf, const Items& certs) { - CertificateShPtrVector chain; - AliasVector trusted; - - if(!leaf.policy.extractable || !leaf.policy.password.empty()) - return; - - for(const auto& i : certs) { - if(!i.policy.extractable || !i.policy.password.empty()) - return; - trusted.push_back(i.alias); - } - - CertificateShPtr leafCrt; - int ret = m_mgr->getCertificate(leaf.alias, leaf.policy.password, leafCrt); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, - "getCertificate failed with " << ret << " for " << - leaf.alias); - - ret = m_mgr->getCertificateChain(leafCrt, AliasVector(), trusted, false, chain); - BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, - "getCertificateChain() failed with " << ret); - BOOST_REQUIRE_MESSAGE(chain.size() == CHAIN_LEN, "Wrong chain length: " << chain.size()); +void SchemeTest::CreateChainItem(const Item &leaf, const Items &certs) +{ + CertificateShPtrVector chain; + AliasVector trusted; + + if (!leaf.policy.extractable || !leaf.policy.password.empty()) + return; + + for (const auto &i : certs) { + if (!i.policy.extractable || !i.policy.password.empty()) + return; + + trusted.push_back(i.alias); + } + + CertificateShPtr leafCrt; + int ret = m_mgr->getCertificate(leaf.alias, leaf.policy.password, leafCrt); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "getCertificate failed with " << ret << " for " << + leaf.alias); + + ret = m_mgr->getCertificateChain(leafCrt, AliasVector(), trusted, false, chain); + BOOST_REQUIRE_MESSAGE(ret == CKM_API_SUCCESS, + "getCertificateChain() failed with " << ret); + BOOST_REQUIRE_MESSAGE(chain.size() == CHAIN_LEN, + "Wrong chain length: " << chain.size()); } diff --git a/tests/encryption-scheme/scheme-test.h b/tests/encryption-scheme/scheme-test.h index 96dab6cf..d9880842 100644 --- a/tests/encryption-scheme/scheme-test.h +++ b/tests/encryption-scheme/scheme-test.h @@ -37,92 +37,99 @@ class Crypto; } // CKM struct Item { - Item() : type(CKM::DataType::Type::DB_LAST) - { - } - - Item(const CKM::Alias& alias, - const CKM::DataType::Type type, - const CKM::Policy& policy) - : alias(alias), type(type), policy(policy) - { - } - - CKM::Alias alias; - CKM::DataType::Type type; - CKM::Policy policy; + Item() : type(CKM::DataType::Type::DB_LAST) + { + } + + Item(const CKM::Alias &alias, + const CKM::DataType::Type type, + const CKM::Policy &policy) + : alias(alias), type(type), policy(policy) + { + } + + CKM::Alias alias; + CKM::DataType::Type type; + CKM::Policy policy; }; typedef std::vector<Item> Items; struct ItemFilter { - ItemFilter() : - typeFrom(CKM::DataType::DB_FIRST), - typeTo(CKM::DataType::DB_LAST), - exportableOnly(false), - noPassword(false) - {} - - explicit ItemFilter(CKM::DataType::Type type) : - typeFrom(type), - typeTo(type), - exportableOnly(false), - noPassword(false) - {} - - ItemFilter(CKM::DataType::Type typeFrom, CKM::DataType::Type typeTo) : - typeFrom(typeFrom), - typeTo(typeTo), - exportableOnly(false), - noPassword(false) - {} - - bool Matches(const Item& item) const { - if(item.type < typeFrom || item.type > typeTo) - return false; - if(exportableOnly && !item.policy.extractable) - return false; - if(noPassword && !item.policy.password.empty()) - return false; - return true; - } - - CKM::DataType::Type typeFrom; - CKM::DataType::Type typeTo; - bool exportableOnly; - bool noPassword; + ItemFilter() : + typeFrom(CKM::DataType::DB_FIRST), + typeTo(CKM::DataType::DB_LAST), + exportableOnly(false), + noPassword(false) + { + } + + explicit ItemFilter(CKM::DataType::Type type) : + typeFrom(type), + typeTo(type), + exportableOnly(false), + noPassword(false) + { + } + + ItemFilter(CKM::DataType::Type typeFrom, CKM::DataType::Type typeTo) : + typeFrom(typeFrom), + typeTo(typeTo), + exportableOnly(false), + noPassword(false) + { + } + + bool Matches(const Item &item) const + { + if (item.type < typeFrom || item.type > typeTo) + return false; + + if (exportableOnly && !item.policy.extractable) + return false; + + if (noPassword && !item.policy.password.empty()) + return false; + + return true; + } + + CKM::DataType::Type typeFrom; + CKM::DataType::Type typeTo; + bool exportableOnly; + bool noPassword; }; class SchemeTest { public: - SchemeTest(); - ~SchemeTest(); - - void RemoveUserData(); - void FillDb(); - void ReadAll(bool useWrongPass = false); - void SignVerify(); - void EncryptDecrypt(); - void CreateChain(); - void RemoveAll(); - size_t CountObjects(); - void RestoreDb(); - void CheckSchemeVersion(const ItemFilter& filter, int version); + SchemeTest(); + ~SchemeTest(); + + void RemoveUserData(); + void FillDb(); + void ReadAll(bool useWrongPass = false); + void SignVerify(); + void EncryptDecrypt(); + void CreateChain(); + void RemoveAll(); + size_t CountObjects(); + void RestoreDb(); + void CheckSchemeVersion(const ItemFilter &filter, int version); private: - void SwitchToUser(); - void SwitchToRoot(); - void EnableDirectDbAccess(); - void SignVerifyItem(const Item& itemPrv, const Item& itemPub); - void EncryptDecryptItem(const Item& item); - void EncryptDecryptItem(const Item& itemPrv, const Item& itemPub); - void CreateChainItem(const Item& leaf, const Items& certs); - - CKM::ControlShPtr m_control; - CKM::ManagerShPtr m_mgr; - std::string m_origLabel; - bool m_userChanged; - - std::unique_ptr<CKM::DB::Crypto> m_db; - bool m_directAccessEnabled; + void SwitchToUser(); + void SwitchToRoot(); + void EnableDirectDbAccess(); + void SignVerifyItem(const Item &itemPrv, const Item &itemPub); + void EncryptDecryptItem(const Item &item); + void EncryptDecryptItem(const Item &itemPrv, const Item &itemPub); + void CreateChainItem(const Item &leaf, const Items &certs); + + CKM::ControlShPtr m_control; + CKM::ManagerShPtr m_mgr; + std::string m_origLabel; + bool m_userChanged; + + std::unique_ptr<CKM::DB::Crypto> m_db; + bool m_directAccessEnabled; }; diff --git a/tests/encryption-scheme/smack-access.cpp b/tests/encryption-scheme/smack-access.cpp index 89e1bcbf..8115e641 100644 --- a/tests/encryption-scheme/smack-access.cpp +++ b/tests/encryption-scheme/smack-access.cpp @@ -28,25 +28,28 @@ SmackAccess::SmackAccess() : m_handle(nullptr) { - if(0 != smack_accesses_new(&m_handle)) - throw std::runtime_error("smack_accesses_new failed"); + if (0 != smack_accesses_new(&m_handle)) + throw std::runtime_error("smack_accesses_new failed"); } void SmackAccess::add( - const std::string &subject, - const std::string &object, - const std::string &rights) + const std::string &subject, + const std::string &object, + const std::string &rights) { - if(0 != smack_accesses_add(m_handle, subject.c_str(), object.c_str(), rights.c_str())) - throw std::runtime_error("smack_accesses_add failed"); + if (0 != smack_accesses_add(m_handle, subject.c_str(), object.c_str(), + rights.c_str())) + throw std::runtime_error("smack_accesses_add failed"); } -void SmackAccess::apply() { - if(0 != smack_accesses_apply(m_handle)) - throw std::runtime_error("smack_accesses_apply failed"); +void SmackAccess::apply() +{ + if (0 != smack_accesses_apply(m_handle)) + throw std::runtime_error("smack_accesses_apply failed"); } -SmackAccess::~SmackAccess() { - if (m_handle) - smack_accesses_free(m_handle); +SmackAccess::~SmackAccess() +{ + if (m_handle) + smack_accesses_free(m_handle); } diff --git a/tests/encryption-scheme/smack-access.h b/tests/encryption-scheme/smack-access.h index 5fc740c0..1ee72c4c 100644 --- a/tests/encryption-scheme/smack-access.h +++ b/tests/encryption-scheme/smack-access.h @@ -28,15 +28,15 @@ struct smack_accesses; class SmackAccess { public: - SmackAccess(); - SmackAccess(const SmackAccess &second) = delete; - SmackAccess& operator=(const SmackAccess &second) = delete; + SmackAccess(); + SmackAccess(const SmackAccess &second) = delete; + SmackAccess &operator=(const SmackAccess &second) = delete; - void add(const std::string &subject, - const std::string &object, - const std::string &rights); - void apply(); - virtual ~SmackAccess(); + void add(const std::string &subject, + const std::string &object, + const std::string &rights); + void apply(); + virtual ~SmackAccess(); private: - struct smack_accesses *m_handle; + struct smack_accesses *m_handle; }; diff --git a/tests/main.cpp b/tests/main.cpp index efaf1be8..c3ff1ebd 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -31,41 +31,47 @@ #include <exception.h> struct TestConfig { - TestConfig() { - boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::log_test_units); - boost::unit_test::results_reporter::set_level(boost::unit_test::SHORT_REPORT); - boost::unit_test::unit_test_log.set_formatter(new CKM::colour_log_formatter); - } - ~TestConfig(){ - } + TestConfig() + { + boost::unit_test::unit_test_log.set_threshold_level( + boost::unit_test::log_test_units); + boost::unit_test::results_reporter::set_level(boost::unit_test::SHORT_REPORT); + boost::unit_test::unit_test_log.set_formatter(new CKM::colour_log_formatter); + } + ~TestConfig() + { + } }; bool isLibInitialized = false; struct KeyProviderLib { - KeyProviderLib() { - try { - CKM::KeyProvider::initializeLibrary(); - isLibInitialized = true; - } catch (const CKM::Exc::Exception &) { - std::cout << "Library initialization failed!" << std::endl; - } - } - ~KeyProviderLib() { - try { - CKM::KeyProvider::closeLibrary(); - } catch (const CKM::Exc::Exception &) { - std::cout << "Library deinitialization failed!" << std::endl; - } - } + KeyProviderLib() + { + try { + CKM::KeyProvider::initializeLibrary(); + isLibInitialized = true; + } catch (const CKM::Exc::Exception &) { + std::cout << "Library initialization failed!" << std::endl; + } + } + ~KeyProviderLib() + { + try { + CKM::KeyProvider::closeLibrary(); + } catch (const CKM::Exc::Exception &) { + std::cout << "Library deinitialization failed!" << std::endl; + } + } }; struct LogSetup { - LogSetup() { - CKM::SetupClientLogSystem(); - CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_INTERNAL_TESTS"); - } - ~LogSetup() {} + LogSetup() + { + CKM::SetupClientLogSystem(); + CKM::Singleton<CKM::Log::LogSystem>::Instance().SetTag("CKM_INTERNAL_TESTS"); + } + ~LogSetup() {} }; BOOST_GLOBAL_FIXTURE(KeyProviderLib) diff --git a/tests/test-key-provider.cpp b/tests/test-key-provider.cpp index 2f026abb..2186304b 100644 --- a/tests/test-key-provider.cpp +++ b/tests/test-key-provider.cpp @@ -39,118 +39,128 @@ const std::string SMACK_LABEL_2 = "SAMPLE_SMACK_LABEL_2"; extern bool isLibInitialized; BOOST_AUTO_TEST_SUITE(KEY_PROVIDER_TEST) -BOOST_AUTO_TEST_CASE(KeyDomainKEK){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); - BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), - "KeyProvider created, but uninitialized"); +BOOST_AUTO_TEST_CASE(KeyDomainKEK) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); + BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), + "KeyProvider created, but uninitialized"); } -BOOST_AUTO_TEST_CASE(KeyDomainKekInvalidPassword){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_THROW(keyProvider = CKM::KeyProvider(rb_test, INCORRECT_PASSWORD), - CKM::Exc::AuthenticationFailed); - BOOST_REQUIRE_MESSAGE(!keyProvider.isInitialized(), - "KeyProvider not created, but initialized"); +BOOST_AUTO_TEST_CASE(KeyDomainKekInvalidPassword) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_THROW(keyProvider = CKM::KeyProvider(rb_test, INCORRECT_PASSWORD), + CKM::Exc::AuthenticationFailed); + BOOST_REQUIRE_MESSAGE(!keyProvider.isInitialized(), + "KeyProvider not created, but initialized"); } -BOOST_AUTO_TEST_CASE(KeygetPureDomainKEK){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); - BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), - "KeyProvider created, but uninitialized"); - BOOST_REQUIRE_NO_THROW(rb_test = keyProvider.getPureDomainKEK()); +BOOST_AUTO_TEST_CASE(KeygetPureDomainKEK) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); + BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), + "KeyProvider created, but uninitialized"); + BOOST_REQUIRE_NO_THROW(rb_test = keyProvider.getPureDomainKEK()); } -BOOST_AUTO_TEST_CASE(KeyGetWrappedDomainKEK){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); - BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), - "KeyProvider created, but uninitialized"); - BOOST_REQUIRE_NO_THROW(rb_test = keyProvider.getWrappedDomainKEK(PASSWORD)); +BOOST_AUTO_TEST_CASE(KeyGetWrappedDomainKEK) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); + BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), + "KeyProvider created, but uninitialized"); + BOOST_REQUIRE_NO_THROW(rb_test = keyProvider.getWrappedDomainKEK(PASSWORD)); } -BOOST_AUTO_TEST_CASE(KeyGenerateDEK){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_test; - CKM::RawBuffer rb_DEK1; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); - BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), - "KeyProvider created, but uninitialized"); - BOOST_REQUIRE_NO_THROW(rb_DEK1 = keyProvider.generateDEK(SMACK_LABEL_1)); +BOOST_AUTO_TEST_CASE(KeyGenerateDEK) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_test; + CKM::RawBuffer rb_DEK1; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); + BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), + "KeyProvider created, but uninitialized"); + BOOST_REQUIRE_NO_THROW(rb_DEK1 = keyProvider.generateDEK(SMACK_LABEL_1)); } -BOOST_AUTO_TEST_CASE(KeyGetPureDEK){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_pureDEK1; - CKM::RawBuffer rb_DEK1; - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); - BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), - "KeyProvider created, but uninitialized"); - BOOST_REQUIRE_NO_THROW(rb_DEK1 = keyProvider.generateDEK(SMACK_LABEL_1)); - BOOST_REQUIRE_NO_THROW(rb_pureDEK1 = keyProvider.getPureDEK(rb_DEK1)); +BOOST_AUTO_TEST_CASE(KeyGetPureDEK) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_pureDEK1; + CKM::RawBuffer rb_DEK1; + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); + BOOST_REQUIRE_MESSAGE(keyProvider.isInitialized(), + "KeyProvider created, but uninitialized"); + BOOST_REQUIRE_NO_THROW(rb_DEK1 = keyProvider.generateDEK(SMACK_LABEL_1)); + BOOST_REQUIRE_NO_THROW(rb_pureDEK1 = keyProvider.getPureDEK(rb_DEK1)); } -BOOST_AUTO_TEST_CASE(KeyReencrypt){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(CKM::KeyProvider::reencrypt(rb_test, PASSWORD, - NEW_PASSWORD)); +BOOST_AUTO_TEST_CASE(KeyReencrypt) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(CKM::KeyProvider::reencrypt(rb_test, PASSWORD, + NEW_PASSWORD)); } -BOOST_AUTO_TEST_CASE(KeyReencrypt_incorrect_password){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_THROW((rb_test = CKM::KeyProvider::reencrypt(rb_test, INCORRECT_PASSWORD, - NEW_PASSWORD)), CKM::Exc::AuthenticationFailed); +BOOST_AUTO_TEST_CASE(KeyReencrypt_incorrect_password) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_THROW((rb_test = CKM::KeyProvider::reencrypt(rb_test, + INCORRECT_PASSWORD, + NEW_PASSWORD)), CKM::Exc::AuthenticationFailed); } -BOOST_AUTO_TEST_CASE(KeyGetPureDEK_after_reencrypt){ - BOOST_REQUIRE_MESSAGE(isLibInitialized, - "Library is not initialized!"); - CKM::KeyProvider keyProvider; - CKM::RawBuffer rb_DEK1; - CKM::RawBuffer rb_test; - BOOST_REQUIRE_NO_THROW(rb_test = - CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); - BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); - BOOST_REQUIRE_NO_THROW(rb_DEK1 = keyProvider.generateDEK(SMACK_LABEL_1)); - BOOST_REQUIRE_NO_THROW(keyProvider.getPureDEK(rb_DEK1)); +BOOST_AUTO_TEST_CASE(KeyGetPureDEK_after_reencrypt) +{ + BOOST_REQUIRE_MESSAGE(isLibInitialized, + "Library is not initialized!"); + CKM::KeyProvider keyProvider; + CKM::RawBuffer rb_DEK1; + CKM::RawBuffer rb_test; + BOOST_REQUIRE_NO_THROW(rb_test = + CKM::KeyProvider::generateDomainKEK(USERNAME_LONG, PASSWORD)); + BOOST_REQUIRE_NO_THROW(keyProvider = CKM::KeyProvider(rb_test, PASSWORD)); + BOOST_REQUIRE_NO_THROW(rb_DEK1 = keyProvider.generateDEK(SMACK_LABEL_1)); + BOOST_REQUIRE_NO_THROW(keyProvider.getPureDEK(rb_DEK1)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_base64.cpp b/tests/test_base64.cpp index 2f030aee..df1a2414 100644 --- a/tests/test_base64.cpp +++ b/tests/test_base64.cpp @@ -33,12 +33,12 @@ using CKM::RawBuffer; namespace { constexpr unsigned char RAW_DATA[] = { - 0xf8, 0x87, 0x0a, 0xc5, 0xd3, 0x6d, 0x44, 0x49, 0x03, 0x9f, 0xbd, 0x1e, 0xa8, 0x2f, 0xf6, 0xc3, - 0xdf, 0x3b, 0x02, 0x13, 0x58, 0x1b, 0x12, 0x30, 0x1c, 0xd7, 0xad, 0xa5, 0x1f, 0x5d, 0x01, 0x33 + 0xf8, 0x87, 0x0a, 0xc5, 0xd3, 0x6d, 0x44, 0x49, 0x03, 0x9f, 0xbd, 0x1e, 0xa8, 0x2f, 0xf6, 0xc3, + 0xdf, 0x3b, 0x02, 0x13, 0x58, 0x1b, 0x12, 0x30, 0x1c, 0xd7, 0xad, 0xa5, 0x1f, 0x5d, 0x01, 0x33 }; const std::vector<unsigned char> - RAW_DATA_VEC(RAW_DATA, RAW_DATA + sizeof(RAW_DATA) / sizeof(unsigned char)); +RAW_DATA_VEC(RAW_DATA, RAW_DATA + sizeof(RAW_DATA) / sizeof(unsigned char)); const RawBuffer rawbuf(RAW_DATA_VEC.begin(), RAW_DATA_VEC.end()); @@ -48,64 +48,69 @@ BOOST_AUTO_TEST_SUITE(BASE64_TEST) BOOST_AUTO_TEST_CASE(ENCODE_DECODE_POSITIVE) { - /* try encode */ - Base64Encoder encoder; - BOOST_REQUIRE_NO_THROW(encoder.append(rawbuf)); - BOOST_REQUIRE_NO_THROW(encoder.finalize()); - - RawBuffer encdata; - BOOST_REQUIRE_NO_THROW(encdata = encoder.get()); - BOOST_REQUIRE_NO_THROW(encoder.reset()); - - /* try decode */ - Base64Decoder decoder; - BOOST_REQUIRE_NO_THROW(decoder.append(encdata)); - BOOST_REQUIRE_NO_THROW(decoder.finalize()); - - RawBuffer decdata; - BOOST_REQUIRE_NO_THROW(decdata = decoder.get()); - BOOST_REQUIRE_NO_THROW(decoder.reset()); - - /* compare with orig data */ - BOOST_REQUIRE_MESSAGE( - rawbuf.size() == decdata.size() && memcmp(rawbuf.data(), decdata.data(), rawbuf.size()) == 0, - "Original data and encoded-decoded data is different!"); + /* try encode */ + Base64Encoder encoder; + BOOST_REQUIRE_NO_THROW(encoder.append(rawbuf)); + BOOST_REQUIRE_NO_THROW(encoder.finalize()); + + RawBuffer encdata; + BOOST_REQUIRE_NO_THROW(encdata = encoder.get()); + BOOST_REQUIRE_NO_THROW(encoder.reset()); + + /* try decode */ + Base64Decoder decoder; + BOOST_REQUIRE_NO_THROW(decoder.append(encdata)); + BOOST_REQUIRE_NO_THROW(decoder.finalize()); + + RawBuffer decdata; + BOOST_REQUIRE_NO_THROW(decdata = decoder.get()); + BOOST_REQUIRE_NO_THROW(decoder.reset()); + + /* compare with orig data */ + BOOST_REQUIRE_MESSAGE( + rawbuf.size() == decdata.size() && + memcmp(rawbuf.data(), decdata.data(), rawbuf.size()) == 0, + "Original data and encoded-decoded data is different!"); } BOOST_AUTO_TEST_CASE(THROW_SOMETHING) { - /* encode data */ - Base64Encoder encoder; - BOOST_REQUIRE_THROW(encoder.get(), Base64Encoder::Exception::NotFinalized); + /* encode data */ + Base64Encoder encoder; + BOOST_REQUIRE_THROW(encoder.get(), Base64Encoder::Exception::NotFinalized); - BOOST_REQUIRE_NO_THROW(encoder.append(rawbuf)); - BOOST_REQUIRE_NO_THROW(encoder.finalize()); + BOOST_REQUIRE_NO_THROW(encoder.append(rawbuf)); + BOOST_REQUIRE_NO_THROW(encoder.finalize()); - BOOST_REQUIRE_THROW(encoder.append(rawbuf), Base64Encoder::Exception::AlreadyFinalized); - BOOST_REQUIRE_THROW(encoder.finalize(), Base64Encoder::Exception::AlreadyFinalized); + BOOST_REQUIRE_THROW(encoder.append(rawbuf), + Base64Encoder::Exception::AlreadyFinalized); + BOOST_REQUIRE_THROW(encoder.finalize(), + Base64Encoder::Exception::AlreadyFinalized); - RawBuffer encdata; - BOOST_REQUIRE_NO_THROW(encdata = encoder.get()); + RawBuffer encdata; + BOOST_REQUIRE_NO_THROW(encdata = encoder.get()); - /* decode data */ - Base64Decoder decoder; - BOOST_REQUIRE_THROW(decoder.get(), Base64Decoder::Exception::NotFinalized); + /* decode data */ + Base64Decoder decoder; + BOOST_REQUIRE_THROW(decoder.get(), Base64Decoder::Exception::NotFinalized); - BOOST_REQUIRE_NO_THROW(decoder.append(encdata)); - BOOST_REQUIRE_NO_THROW(decoder.finalize()); + BOOST_REQUIRE_NO_THROW(decoder.append(encdata)); + BOOST_REQUIRE_NO_THROW(decoder.finalize()); - BOOST_REQUIRE_THROW(decoder.append(encdata), Base64Decoder::Exception::AlreadyFinalized); - BOOST_REQUIRE_THROW(decoder.finalize(), Base64Decoder::Exception::AlreadyFinalized); + BOOST_REQUIRE_THROW(decoder.append(encdata), + Base64Decoder::Exception::AlreadyFinalized); + BOOST_REQUIRE_THROW(decoder.finalize(), + Base64Decoder::Exception::AlreadyFinalized); - RawBuffer decdata; - BOOST_REQUIRE_NO_THROW(decdata = decoder.get()); + RawBuffer decdata; + BOOST_REQUIRE_NO_THROW(decdata = decoder.get()); } BOOST_AUTO_TEST_CASE(ILLEGAL_DATA) { - Base64Decoder decoder; - BOOST_REQUIRE_NO_THROW(decoder.append(rawbuf)); - BOOST_REQUIRE(!decoder.finalize()); + Base64Decoder decoder; + BOOST_REQUIRE_NO_THROW(decoder.append(rawbuf)); + BOOST_REQUIRE(!decoder.finalize()); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_comm-manager.cpp b/tests/test_comm-manager.cpp index facd20b9..b06a3acd 100644 --- a/tests/test_comm-manager.cpp +++ b/tests/test_comm-manager.cpp @@ -28,155 +28,182 @@ namespace { struct MessageA { - MessageA(int ai) : i(ai) {} - int i; + MessageA(int ai) : i(ai) {} + int i; }; struct MessageB { - MessageB(char ac) : c(ac) {} - char c; + MessageB(char ac) : c(ac) {} + char c; }; struct MessageC { - MessageC(const std::string& astr) : str(astr) {} - std::string str; + MessageC(const std::string &astr) : str(astr) {} + std::string str; }; struct Listener { - Listener() : i(0) {} + Listener() : i(0) {} - void Handle(const MessageA& msg) { - i = msg.i; - } + void Handle(const MessageA &msg) + { + i = msg.i; + } - void Handle(const MessageC& msg) { - str = msg.str; - } + void Handle(const MessageC &msg) + { + str = msg.str; + } - int i; - std::string str; + int i; + std::string str; }; } // namespace anonymous BOOST_AUTO_TEST_SUITE(MESSAGE_MANAGER_TEST) -BOOST_AUTO_TEST_CASE(TMM_0010_NoListener) { - CKM::CommunicationManager<MessageA> mgr; - BOOST_REQUIRE_MESSAGE(0 == mgr.SendMessage(MessageA(22)), "There should be no listener."); +BOOST_AUTO_TEST_CASE(TMM_0010_NoListener) +{ + CKM::CommunicationManager<MessageA> mgr; + BOOST_REQUIRE_MESSAGE(0 == mgr.SendMessage(MessageA(22)), + "There should be no listener."); } -BOOST_AUTO_TEST_CASE(TMM_0020_Basic) { - CKM::CommunicationManager<MessageA> mgr; - int received = 0; - mgr.Register<MessageA>([&](const MessageA& msg){ received = msg.i; }); - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(4)), "No listener found"); - BOOST_REQUIRE_MESSAGE(received != 0, "Message not received"); - BOOST_REQUIRE_MESSAGE(received == 4, "Wrong message received i=" << received); +BOOST_AUTO_TEST_CASE(TMM_0020_Basic) +{ + CKM::CommunicationManager<MessageA> mgr; + int received = 0; + mgr.Register<MessageA>([&](const MessageA & msg) { + received = msg.i; + }); + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(4)), "No listener found"); + BOOST_REQUIRE_MESSAGE(received != 0, "Message not received"); + BOOST_REQUIRE_MESSAGE(received == 4, "Wrong message received i=" << received); } -BOOST_AUTO_TEST_CASE(TMM_0030_MultipleMessages) { - CKM::CommunicationManager<MessageA, MessageB> mgr; - int reci = 0; - char recc = 0; - mgr.Register<MessageA>([&](const MessageA& msg){ reci = msg.i; }); - mgr.Register<MessageB>([&](const MessageB& msg){ recc = msg.c; }); - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageB('c')), "No listener found"); - BOOST_REQUIRE_MESSAGE(reci == 0, "Unexpected message received"); - BOOST_REQUIRE_MESSAGE(recc != 0, "Message not received"); - BOOST_REQUIRE_MESSAGE(recc == 'c', "Wrong message received c=" << recc); - - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(42)), "No listener found"); - BOOST_REQUIRE_MESSAGE(reci!= 0, "Message not received"); - BOOST_REQUIRE_MESSAGE(reci == 42, "Wrong message received i=" << reci); - BOOST_REQUIRE_MESSAGE(recc == 'c', "Previous message overwritten c=" << recc); +BOOST_AUTO_TEST_CASE(TMM_0030_MultipleMessages) +{ + CKM::CommunicationManager<MessageA, MessageB> mgr; + int reci = 0; + char recc = 0; + mgr.Register<MessageA>([&](const MessageA & msg) { + reci = msg.i; + }); + mgr.Register<MessageB>([&](const MessageB & msg) { + recc = msg.c; + }); + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageB('c')), "No listener found"); + BOOST_REQUIRE_MESSAGE(reci == 0, "Unexpected message received"); + BOOST_REQUIRE_MESSAGE(recc != 0, "Message not received"); + BOOST_REQUIRE_MESSAGE(recc == 'c', "Wrong message received c=" << recc); + + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(42)), "No listener found"); + BOOST_REQUIRE_MESSAGE(reci != 0, "Message not received"); + BOOST_REQUIRE_MESSAGE(reci == 42, "Wrong message received i=" << reci); + BOOST_REQUIRE_MESSAGE(recc == 'c', "Previous message overwritten c=" << recc); } -BOOST_AUTO_TEST_CASE(TMM_0040_Listener) { - CKM::CommunicationManager<MessageA, MessageB, MessageC> mgr; - Listener l; - mgr.Register<MessageC>([&](const MessageC& msg){ l.Handle(msg); }); - mgr.Register<MessageA>([&](const MessageA& msg){ l.Handle(msg); }); - - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageC("lorem ipsum")), "No listener found"); - BOOST_REQUIRE_MESSAGE(l.i == 0, "Unexpected message received"); - BOOST_REQUIRE_MESSAGE(!l.str.empty(), "Message not received"); - BOOST_REQUIRE_MESSAGE(l.str == "lorem ipsum", "Wrong message received c=" << l.str); - - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(3)), "No listener found"); - BOOST_REQUIRE_MESSAGE(l.i!= 0, "Message not received"); - BOOST_REQUIRE_MESSAGE(l.i == 3, "Wrong message received i=" << l.i); - BOOST_REQUIRE_MESSAGE(l.str == "lorem ipsum", "Previous message overwritten str=" << l.str); +BOOST_AUTO_TEST_CASE(TMM_0040_Listener) +{ + CKM::CommunicationManager<MessageA, MessageB, MessageC> mgr; + Listener l; + mgr.Register<MessageC>([&](const MessageC & msg) { + l.Handle(msg); + }); + mgr.Register<MessageA>([&](const MessageA & msg) { + l.Handle(msg); + }); + + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageC("lorem ipsum")), + "No listener found"); + BOOST_REQUIRE_MESSAGE(l.i == 0, "Unexpected message received"); + BOOST_REQUIRE_MESSAGE(!l.str.empty(), "Message not received"); + BOOST_REQUIRE_MESSAGE(l.str == "lorem ipsum", + "Wrong message received c=" << l.str); + + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(3)), "No listener found"); + BOOST_REQUIRE_MESSAGE(l.i != 0, "Message not received"); + BOOST_REQUIRE_MESSAGE(l.i == 3, "Wrong message received i=" << l.i); + BOOST_REQUIRE_MESSAGE(l.str == "lorem ipsum", + "Previous message overwritten str=" << l.str); } -BOOST_AUTO_TEST_CASE(TMM_0050_2Listeners) { - CKM::CommunicationManager<MessageA> mgr; - bool called[2]; - called[0] = false; - called[1] = false; - mgr.Register<MessageA>([&](const MessageA& msg){ - BOOST_REQUIRE_MESSAGE(msg.i == 5, "Unexpected message received i=" << msg.i); - called[0] = true; - }); - mgr.Register<MessageA>([&](const MessageA& msg){ - BOOST_REQUIRE_MESSAGE(msg.i == 5, "Unexpected message received i=" << msg.i); - called[1] = true; - }); - - BOOST_REQUIRE_MESSAGE(2 == mgr.SendMessage(MessageA(5)), "No listener found"); - BOOST_REQUIRE_MESSAGE(called[0], "First listener not called"); - BOOST_REQUIRE_MESSAGE(called[1], "Second listener not called"); +BOOST_AUTO_TEST_CASE(TMM_0050_2Listeners) +{ + CKM::CommunicationManager<MessageA> mgr; + bool called[2]; + called[0] = false; + called[1] = false; + mgr.Register<MessageA>([&](const MessageA & msg) { + BOOST_REQUIRE_MESSAGE(msg.i == 5, "Unexpected message received i=" << msg.i); + called[0] = true; + }); + mgr.Register<MessageA>([&](const MessageA & msg) { + BOOST_REQUIRE_MESSAGE(msg.i == 5, "Unexpected message received i=" << msg.i); + called[1] = true; + }); + + BOOST_REQUIRE_MESSAGE(2 == mgr.SendMessage(MessageA(5)), "No listener found"); + BOOST_REQUIRE_MESSAGE(called[0], "First listener not called"); + BOOST_REQUIRE_MESSAGE(called[1], "Second listener not called"); } -BOOST_AUTO_TEST_CASE(TMM_0060_Stress) { - CKM::CommunicationManager<MessageA, MessageB, MessageC> mgr; - - std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count()); - std::uniform_int_distribution<size_t> message_dist(0,2); - std::uniform_int_distribution<size_t> count_dist(1,10); - - size_t a = 0; - size_t b = 0; - size_t c = 0; - mgr.Register<MessageA>([&](const MessageA& msg) { - BOOST_REQUIRE_MESSAGE(msg.i == 42, "Wrong message: " << msg.i); - a++; - }); - mgr.Register<MessageB>([&](const MessageB& msg) { - BOOST_REQUIRE_MESSAGE(msg.c == 'c', "Wrong message: " << msg.c); - b++; - }); - mgr.Register<MessageC>([&](const MessageC& msg) { - BOOST_REQUIRE_MESSAGE(msg.str == "lorem ipsum", "Wrong message: " << msg.str); - c++; - }); - - for (size_t i=0; i < 1000; i++) - { - size_t cnt = count_dist(generator); - for (size_t s = 0; s < cnt; s++) { - switch(message_dist(generator)) - { - case 0: - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(42)), "No listener found"); - a--; - break; - case 1: - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageB('c')), "No listener found"); - b--; - break; - case 2: - BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageC("lorem ipsum")), "No listener found"); - c--; - break; - default: - BOOST_FAIL("Unexpected message type"); - } - } - } - BOOST_REQUIRE_MESSAGE(a == 0, "Unexpected number of MessageA: " << a); - BOOST_REQUIRE_MESSAGE(b == 0, "Unexpected number of MessageB: " << b); - BOOST_REQUIRE_MESSAGE(c == 0, "Unexpected number of MessageC: " << c); +BOOST_AUTO_TEST_CASE(TMM_0060_Stress) +{ + CKM::CommunicationManager<MessageA, MessageB, MessageC> mgr; + + std::default_random_engine generator( + std::chrono::system_clock::now().time_since_epoch().count()); + std::uniform_int_distribution<size_t> message_dist(0, 2); + std::uniform_int_distribution<size_t> count_dist(1, 10); + + size_t a = 0; + size_t b = 0; + size_t c = 0; + mgr.Register<MessageA>([&](const MessageA & msg) { + BOOST_REQUIRE_MESSAGE(msg.i == 42, "Wrong message: " << msg.i); + a++; + }); + mgr.Register<MessageB>([&](const MessageB & msg) { + BOOST_REQUIRE_MESSAGE(msg.c == 'c', "Wrong message: " << msg.c); + b++; + }); + mgr.Register<MessageC>([&](const MessageC & msg) { + BOOST_REQUIRE_MESSAGE(msg.str == "lorem ipsum", "Wrong message: " << msg.str); + c++; + }); + + for (size_t i = 0; i < 1000; i++) { + size_t cnt = count_dist(generator); + + for (size_t s = 0; s < cnt; s++) { + switch (message_dist(generator)) { + case 0: + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageA(42)), "No listener found"); + a--; + break; + + case 1: + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageB('c')), "No listener found"); + b--; + break; + + case 2: + BOOST_REQUIRE_MESSAGE(1 == mgr.SendMessage(MessageC("lorem ipsum")), + "No listener found"); + c--; + break; + + default: + BOOST_FAIL("Unexpected message type"); + } + } + } + + BOOST_REQUIRE_MESSAGE(a == 0, "Unexpected number of MessageA: " << a); + BOOST_REQUIRE_MESSAGE(b == 0, "Unexpected number of MessageB: " << b); + BOOST_REQUIRE_MESSAGE(c == 0, "Unexpected number of MessageC: " << c); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_common.cpp b/tests/test_common.cpp index b96e9138..ec2b2425 100644 --- a/tests/test_common.cpp +++ b/tests/test_common.cpp @@ -25,33 +25,37 @@ using namespace CKM; -RawBuffer createDefaultPass() { - return createPass(0, RAW_PASS_SIZE); +RawBuffer createDefaultPass() +{ + return createPass(0, RAW_PASS_SIZE); } -RawBuffer createPass(std::size_t from, std::size_t to) { - RawBuffer raw; +RawBuffer createPass(std::size_t from, std::size_t to) +{ + RawBuffer raw; - for (std::size_t i = from; i < to; i++) - raw.push_back(static_cast<unsigned char>(i)); + for (std::size_t i = from; i < to; i++) + raw.push_back(static_cast<unsigned char>(i)); - return raw; + return raw; } -RawBuffer createBigBlob(std::size_t size) { - return createPass(0, size); +RawBuffer createBigBlob(std::size_t size) +{ + return createPass(0, size); } //raw to hex string conversion from SqlConnection -std::string rawToHexString(const RawBuffer &raw) { - std::string dump; - - for (auto &e : raw) { - char buf[3]; - snprintf(buf, sizeof(buf), "%02x", (e & 0xff)); - dump.push_back(buf[0]); - dump.push_back(buf[1]); - } - - return dump; +std::string rawToHexString(const RawBuffer &raw) +{ + std::string dump; + + for (auto &e : raw) { + char buf[3]; + snprintf(buf, sizeof(buf), "%02x", (e & 0xff)); + dump.push_back(buf[0]); + dump.push_back(buf[1]); + } + + return dump; } diff --git a/tests/test_common.h b/tests/test_common.h index b9b70bfc..07aae64d 100644 --- a/tests/test_common.h +++ b/tests/test_common.h @@ -35,7 +35,7 @@ CKM::RawBuffer createBigBlob(std::size_t size); const CKM::RawBuffer defaultPass = createDefaultPass(); const std::string pattern = - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; const std::size_t RAW_PASS_SIZE = 32; const std::size_t HEX_PASS_SIZE = RAW_PASS_SIZE * 2; diff --git a/tests/test_data-type.cpp b/tests/test_data-type.cpp index 215f552b..e2ba333c 100644 --- a/tests/test_data-type.cpp +++ b/tests/test_data-type.cpp @@ -32,130 +32,136 @@ BOOST_AUTO_TEST_SUITE(DATA_TYPE_TEST) BOOST_AUTO_TEST_CASE(CONSTRUCTOR) { - BOOST_REQUIRE_THROW(DataType(static_cast<DataType::Type>(999)), DataType::Exception::OutOfRange); - BOOST_REQUIRE_THROW(DataType(static_cast<KeyType>(999)), DataType::Exception::OutOfRange); + BOOST_REQUIRE_THROW(DataType(static_cast<DataType::Type>(999)), + DataType::Exception::OutOfRange); + BOOST_REQUIRE_THROW(DataType(static_cast<KeyType>(999)), + DataType::Exception::OutOfRange); - std::vector<DataType> types; + std::vector<DataType> types; - types.emplace_back(AlgoType::AES_CTR); - types.emplace_back(AlgoType::AES_CBC); - types.emplace_back(AlgoType::AES_GCM); - types.emplace_back(AlgoType::AES_CFB); - types.emplace_back(AlgoType::AES_GEN); - for (auto &type : types) - BOOST_REQUIRE(type == DataType(DataType::KEY_AES)); + types.emplace_back(AlgoType::AES_CTR); + types.emplace_back(AlgoType::AES_CBC); + types.emplace_back(AlgoType::AES_GCM); + types.emplace_back(AlgoType::AES_CFB); + types.emplace_back(AlgoType::AES_GEN); - types.clear(); + for (auto &type : types) + BOOST_REQUIRE(type == DataType(DataType::KEY_AES)); - types.emplace_back(AlgoType::RSA_SV); - types.emplace_back(AlgoType::RSA_OAEP); - types.emplace_back(AlgoType::RSA_GEN); - for (auto &type : types) - BOOST_REQUIRE(type == DataType(DataType::KEY_RSA_PUBLIC)); + types.clear(); - types.clear(); + types.emplace_back(AlgoType::RSA_SV); + types.emplace_back(AlgoType::RSA_OAEP); + types.emplace_back(AlgoType::RSA_GEN); - types.emplace_back(AlgoType::DSA_SV); - types.emplace_back(AlgoType::DSA_GEN); - for (auto &type : types) - BOOST_REQUIRE(type == DataType(DataType::KEY_DSA_PUBLIC)); + for (auto &type : types) + BOOST_REQUIRE(type == DataType(DataType::KEY_RSA_PUBLIC)); - types.clear(); + types.clear(); - types.emplace_back(AlgoType::ECDSA_SV); - types.emplace_back(AlgoType::ECDSA_GEN); - for (auto &type : types) - BOOST_REQUIRE(type == DataType(DataType::KEY_ECDSA_PUBLIC)); + types.emplace_back(AlgoType::DSA_SV); + types.emplace_back(AlgoType::DSA_GEN); - types.clear(); + for (auto &type : types) + BOOST_REQUIRE(type == DataType(DataType::KEY_DSA_PUBLIC)); - BOOST_REQUIRE_THROW( - DataType(static_cast<AlgoType>(-1)), - DataType::Exception::OutOfRange); + types.clear(); + + types.emplace_back(AlgoType::ECDSA_SV); + types.emplace_back(AlgoType::ECDSA_GEN); + + for (auto &type : types) + BOOST_REQUIRE(type == DataType(DataType::KEY_ECDSA_PUBLIC)); + + types.clear(); + + BOOST_REQUIRE_THROW( + DataType(static_cast<AlgoType>(-1)), + DataType::Exception::OutOfRange); } BOOST_AUTO_TEST_CASE(KEY_TYPE_CASTING) { - std::vector<std::pair<DataType, KeyType>> pairs; + std::vector<std::pair<DataType, KeyType>> pairs; - pairs.emplace_back(DataType::KEY_RSA_PUBLIC, KeyType::KEY_RSA_PUBLIC); - pairs.emplace_back(DataType::KEY_RSA_PRIVATE, KeyType::KEY_RSA_PRIVATE); + pairs.emplace_back(DataType::KEY_RSA_PUBLIC, KeyType::KEY_RSA_PUBLIC); + pairs.emplace_back(DataType::KEY_RSA_PRIVATE, KeyType::KEY_RSA_PRIVATE); - pairs.emplace_back(DataType::KEY_DSA_PUBLIC, KeyType::KEY_DSA_PUBLIC); - pairs.emplace_back(DataType::KEY_DSA_PRIVATE, KeyType::KEY_DSA_PRIVATE); + pairs.emplace_back(DataType::KEY_DSA_PUBLIC, KeyType::KEY_DSA_PUBLIC); + pairs.emplace_back(DataType::KEY_DSA_PRIVATE, KeyType::KEY_DSA_PRIVATE); - pairs.emplace_back(DataType::KEY_ECDSA_PUBLIC, KeyType::KEY_ECDSA_PUBLIC); - pairs.emplace_back(DataType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PRIVATE); + pairs.emplace_back(DataType::KEY_ECDSA_PUBLIC, KeyType::KEY_ECDSA_PUBLIC); + pairs.emplace_back(DataType::KEY_ECDSA_PRIVATE, KeyType::KEY_ECDSA_PRIVATE); - pairs.emplace_back(DataType::KEY_AES, KeyType::KEY_AES); + pairs.emplace_back(DataType::KEY_AES, KeyType::KEY_AES); - for (auto &p : pairs) - BOOST_REQUIRE(p.second == DataType(static_cast<KeyType>(p.first))); + for (auto &p : pairs) + BOOST_REQUIRE(p.second == DataType(static_cast<KeyType>(p.first))); } BOOST_AUTO_TEST_CASE(UNARY_OPERATIONS) { - BOOST_REQUIRE(DataType(DataType::KEY_AES).isSKey()); - BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PUBLIC).isSKey()); - - BOOST_REQUIRE(DataType(DataType::DB_CHAIN_FIRST).isChainCert()); - BOOST_REQUIRE(DataType(DataType::DB_CHAIN_LAST).isChainCert()); - BOOST_REQUIRE(!DataType(DataType::KEY_AES).isChainCert()); - - BOOST_REQUIRE(DataType(DataType::KEY_RSA_PUBLIC).isKeyPublic()); - BOOST_REQUIRE(DataType(DataType::KEY_DSA_PUBLIC).isKeyPublic()); - BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PUBLIC).isKeyPublic()); - BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PRIVATE).isKeyPublic()); - BOOST_REQUIRE(!DataType(DataType::KEY_DSA_PRIVATE).isKeyPublic()); - BOOST_REQUIRE(!DataType(DataType::KEY_ECDSA_PRIVATE).isKeyPublic()); - BOOST_REQUIRE(!DataType(DataType::KEY_AES).isKeyPublic()); - BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_LAST).isKeyPublic()); - - BOOST_REQUIRE(DataType(DataType::KEY_RSA_PRIVATE).isKeyPrivate()); - BOOST_REQUIRE(DataType(DataType::KEY_DSA_PRIVATE).isKeyPrivate()); - BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PRIVATE).isKeyPrivate()); - BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PUBLIC).isKeyPrivate()); - BOOST_REQUIRE(!DataType(DataType::KEY_DSA_PUBLIC).isKeyPrivate()); - BOOST_REQUIRE(!DataType(DataType::KEY_ECDSA_PUBLIC).isKeyPrivate()); - BOOST_REQUIRE(!DataType(DataType::KEY_AES).isKeyPrivate()); - BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_FIRST).isKeyPrivate()); - - BOOST_REQUIRE(DataType(DataType::CERTIFICATE).isCertificate()); - BOOST_REQUIRE(!DataType(DataType::KEY_AES).isCertificate()); - BOOST_REQUIRE(!DataType().isCertificate()); - BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_FIRST).isCertificate()); - - BOOST_REQUIRE(DataType().isBinaryData()); - BOOST_REQUIRE(DataType(DataType::BINARY_DATA).isBinaryData()); - BOOST_REQUIRE(!DataType(DataType::KEY_AES).isBinaryData()); - BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PUBLIC).isBinaryData()); - BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_LAST).isBinaryData()); - - BOOST_REQUIRE(DataType(DataType::DB_KEY_FIRST).isKey()); - BOOST_REQUIRE(DataType(DataType::DB_KEY_LAST).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_AES).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_RSA_PUBLIC).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_RSA_PRIVATE).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_DSA_PUBLIC).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_DSA_PRIVATE).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PUBLIC).isKey()); - BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PRIVATE).isKey()); - BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_FIRST).isKey()); - BOOST_REQUIRE(!DataType(DataType::CERTIFICATE).isKey()); - BOOST_REQUIRE(!DataType().isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_AES).isSKey()); + BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PUBLIC).isSKey()); + + BOOST_REQUIRE(DataType(DataType::DB_CHAIN_FIRST).isChainCert()); + BOOST_REQUIRE(DataType(DataType::DB_CHAIN_LAST).isChainCert()); + BOOST_REQUIRE(!DataType(DataType::KEY_AES).isChainCert()); + + BOOST_REQUIRE(DataType(DataType::KEY_RSA_PUBLIC).isKeyPublic()); + BOOST_REQUIRE(DataType(DataType::KEY_DSA_PUBLIC).isKeyPublic()); + BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PUBLIC).isKeyPublic()); + BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PRIVATE).isKeyPublic()); + BOOST_REQUIRE(!DataType(DataType::KEY_DSA_PRIVATE).isKeyPublic()); + BOOST_REQUIRE(!DataType(DataType::KEY_ECDSA_PRIVATE).isKeyPublic()); + BOOST_REQUIRE(!DataType(DataType::KEY_AES).isKeyPublic()); + BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_LAST).isKeyPublic()); + + BOOST_REQUIRE(DataType(DataType::KEY_RSA_PRIVATE).isKeyPrivate()); + BOOST_REQUIRE(DataType(DataType::KEY_DSA_PRIVATE).isKeyPrivate()); + BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PRIVATE).isKeyPrivate()); + BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PUBLIC).isKeyPrivate()); + BOOST_REQUIRE(!DataType(DataType::KEY_DSA_PUBLIC).isKeyPrivate()); + BOOST_REQUIRE(!DataType(DataType::KEY_ECDSA_PUBLIC).isKeyPrivate()); + BOOST_REQUIRE(!DataType(DataType::KEY_AES).isKeyPrivate()); + BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_FIRST).isKeyPrivate()); + + BOOST_REQUIRE(DataType(DataType::CERTIFICATE).isCertificate()); + BOOST_REQUIRE(!DataType(DataType::KEY_AES).isCertificate()); + BOOST_REQUIRE(!DataType().isCertificate()); + BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_FIRST).isCertificate()); + + BOOST_REQUIRE(DataType().isBinaryData()); + BOOST_REQUIRE(DataType(DataType::BINARY_DATA).isBinaryData()); + BOOST_REQUIRE(!DataType(DataType::KEY_AES).isBinaryData()); + BOOST_REQUIRE(!DataType(DataType::KEY_RSA_PUBLIC).isBinaryData()); + BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_LAST).isBinaryData()); + + BOOST_REQUIRE(DataType(DataType::DB_KEY_FIRST).isKey()); + BOOST_REQUIRE(DataType(DataType::DB_KEY_LAST).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_AES).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_RSA_PUBLIC).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_RSA_PRIVATE).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_DSA_PUBLIC).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_DSA_PRIVATE).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PUBLIC).isKey()); + BOOST_REQUIRE(DataType(DataType::KEY_ECDSA_PRIVATE).isKey()); + BOOST_REQUIRE(!DataType(DataType::DB_CHAIN_FIRST).isKey()); + BOOST_REQUIRE(!DataType(DataType::CERTIFICATE).isKey()); + BOOST_REQUIRE(!DataType().isKey()); } BOOST_AUTO_TEST_CASE(GET_CHAIN_TYPE) { - DataType type; + DataType type; - BOOST_REQUIRE(type.getChainDatatype(0) == DataType(DataType::DB_CHAIN_FIRST)); - BOOST_REQUIRE(type.getChainDatatype(5) == DataType(DataType::CHAIN_CERT_5)); - BOOST_REQUIRE(type.getChainDatatype(8) == DataType(DataType::CHAIN_CERT_8)); - BOOST_REQUIRE(type.getChainDatatype(13) == DataType(DataType::CHAIN_CERT_13)); - BOOST_REQUIRE(type.getChainDatatype(15) == DataType(DataType::DB_CHAIN_LAST)); + BOOST_REQUIRE(type.getChainDatatype(0) == DataType(DataType::DB_CHAIN_FIRST)); + BOOST_REQUIRE(type.getChainDatatype(5) == DataType(DataType::CHAIN_CERT_5)); + BOOST_REQUIRE(type.getChainDatatype(8) == DataType(DataType::CHAIN_CERT_8)); + BOOST_REQUIRE(type.getChainDatatype(13) == DataType(DataType::CHAIN_CERT_13)); + BOOST_REQUIRE(type.getChainDatatype(15) == DataType(DataType::DB_CHAIN_LAST)); - BOOST_REQUIRE_THROW(type.getChainDatatype(16), DataType::Exception::OutOfRange); + BOOST_REQUIRE_THROW(type.getChainDatatype(16), DataType::Exception::OutOfRange); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_db_crypto.cpp b/tests/test_db_crypto.cpp index a598e4e8..e9f471bf 100644 --- a/tests/test_db_crypto.cpp +++ b/tests/test_db_crypto.cpp @@ -32,8 +32,7 @@ using namespace CKM; -namespace -{ +namespace { const int restricted_local = 1; const int restricted_global = 0; @@ -45,63 +44,69 @@ const unsigned int c_names_per_label = 15; } // namespace anonymous BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_TEST, DBFixture) -BOOST_AUTO_TEST_CASE(DBtestSimple) { - DB::Row rowPattern = create_default_row(); - rowPattern.data = RawBuffer(32, 1); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); +BOOST_AUTO_TEST_CASE(DBtestSimple) +{ + DB::Row rowPattern = create_default_row(); + rowPattern.data = RawBuffer(32, 1); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - check_DB_integrity(rowPattern); + check_DB_integrity(rowPattern); } -BOOST_AUTO_TEST_CASE(DBtestBIG) { - DB::Row rowPattern = create_default_row(); - rowPattern.data = createBigBlob(4096); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); +BOOST_AUTO_TEST_CASE(DBtestBIG) +{ + DB::Row rowPattern = create_default_row(); + rowPattern.data = createBigBlob(4096); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - check_DB_integrity(rowPattern); + check_DB_integrity(rowPattern); } -BOOST_AUTO_TEST_CASE(DBtestGlobal) { - DB::Row rowPattern = create_default_row(); - rowPattern.data = RawBuffer(1024, 2); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); +BOOST_AUTO_TEST_CASE(DBtestGlobal) +{ + DB::Row rowPattern = create_default_row(); + rowPattern.data = RawBuffer(1024, 2); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); + BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); - DB::Row name_duplicate = rowPattern; - rowPattern.ownerLabel = rowPattern.ownerLabel + "1"; + DB::Row name_duplicate = rowPattern; + rowPattern.ownerLabel = rowPattern.ownerLabel + "1"; } -BOOST_AUTO_TEST_CASE(DBtestTransaction) { - DB::Row rowPattern = create_default_row(); - rowPattern.data = RawBuffer(100, 20); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - DB::Crypto::Transaction transaction(&m_db); - - BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); - BOOST_REQUIRE_NO_THROW(transaction.rollback()); - - DB::Crypto::RowOptional row_optional; - BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow(m_default_name, m_default_label, - DataType::BINARY_DATA)); - BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback"); +BOOST_AUTO_TEST_CASE(DBtestTransaction) +{ + DB::Row rowPattern = create_default_row(); + rowPattern.data = RawBuffer(100, 20); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); + DB::Crypto::Transaction transaction(&m_db); + + BOOST_REQUIRE_NO_THROW(m_db.saveRow(rowPattern)); + BOOST_REQUIRE_NO_THROW(transaction.rollback()); + + DB::Crypto::RowOptional row_optional; + BOOST_REQUIRE_NO_THROW(row_optional = m_db.getRow(m_default_name, + m_default_label, + DataType::BINARY_DATA)); + BOOST_CHECK_MESSAGE(!row_optional, "Row still present after rollback"); } -BOOST_AUTO_TEST_CASE(DBtestBackend) { - DB::Row rowPattern = create_default_row(); - rowPattern.data = RawBuffer(32, 1); - rowPattern.dataSize = rowPattern.data.size(); - rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); +BOOST_AUTO_TEST_CASE(DBtestBackend) +{ + DB::Row rowPattern = create_default_row(); + rowPattern.data = RawBuffer(32, 1); + rowPattern.dataSize = rowPattern.data.size(); + rowPattern.tag = RawBuffer(AES_GCM_TAG_SIZE, 1); - rowPattern.backendId = CryptoBackend::OpenSSL; - check_DB_integrity(rowPattern); + rowPattern.backendId = CryptoBackend::OpenSSL; + check_DB_integrity(rowPattern); - rowPattern.backendId = CryptoBackend::TrustZone; - check_DB_integrity(rowPattern); + rowPattern.backendId = CryptoBackend::TrustZone; + check_DB_integrity(rowPattern); - rowPattern.backendId = CryptoBackend::None; - check_DB_integrity(rowPattern); + rowPattern.backendId = CryptoBackend::None; + check_DB_integrity(rowPattern); } BOOST_AUTO_TEST_SUITE_END() @@ -112,247 +117,253 @@ BOOST_FIXTURE_TEST_SUITE(DBCRYPTO_PERF_TEST, DBFixture) BOOST_AUTO_TEST_CASE(DBperfAddNames) { - // actual test - performance_start("saveRow"); - { - generate_perf_DB(c_num_names_add_test, c_names_per_label); - } - performance_stop(c_num_names_add_test); + // actual test + performance_start("saveRow"); + + { + generate_perf_DB(c_num_names_add_test, c_names_per_label); + } + + performance_stop(c_num_names_add_test); } BOOST_AUTO_TEST_CASE(DBperfLookupAliasByOwner) { - // prepare data - generate_perf_DB(c_num_names, c_names_per_label); - - unsigned int num_labels = c_num_names/c_names_per_label; - Name name; - Label label; - - // actual test - successful lookup - performance_start("getRow"); - for(unsigned int t=0; t<c_test_retries; t++) - { - int label_num = rand_r(&t) % num_labels; - generate_label(label_num, label); - - unsigned int start_name = label_num*c_names_per_label; - for(unsigned int name_num=start_name; name_num<(start_name+c_names_per_label); name_num++) - { - generate_name(name_num, name); - read_row_expect_success(name, label); - } - } - performance_stop(c_test_retries * c_num_names); + // prepare data + generate_perf_DB(c_num_names, c_names_per_label); + + unsigned int num_labels = c_num_names / c_names_per_label; + Name name; + Label label; + + // actual test - successful lookup + performance_start("getRow"); + + for (unsigned int t = 0; t < c_test_retries; t++) { + int label_num = rand_r(&t) % num_labels; + generate_label(label_num, label); + + unsigned int start_name = label_num * c_names_per_label; + + for (unsigned int name_num = start_name; + name_num < (start_name + c_names_per_label); name_num++) { + generate_name(name_num, name); + read_row_expect_success(name, label); + } + } + + performance_stop(c_test_retries * c_num_names); } BOOST_AUTO_TEST_CASE(DBperfLookupAliasRandomOwnershipNoPermissions) { - // prepare data - generate_perf_DB(c_num_names, c_names_per_label); - - Name name; - Label owner_label; - Label smack_label; - unsigned int num_labels = c_num_names / c_names_per_label; - - // actual test - random lookup - performance_start("getRow"); - for(unsigned int t=0; t<c_test_retries; t++) - { - int name_idx = rand_r(&t)%c_num_names; - generate_name(name_idx, name); - generate_label(name_idx/c_names_per_label, owner_label); - generate_label(rand_r(&t)%num_labels, smack_label); - - // do not care of result - m_db.getRow(name, owner_label, DataType::BINARY_DATA); - } - performance_stop(c_test_retries * c_num_names); + // prepare data + generate_perf_DB(c_num_names, c_names_per_label); + + Name name; + Label owner_label; + Label smack_label; + unsigned int num_labels = c_num_names / c_names_per_label; + + // actual test - random lookup + performance_start("getRow"); + + for (unsigned int t = 0; t < c_test_retries; t++) { + int name_idx = rand_r(&t) % c_num_names; + generate_name(name_idx, name); + generate_label(name_idx / c_names_per_label, owner_label); + generate_label(rand_r(&t) % num_labels, smack_label); + + // do not care of result + m_db.getRow(name, owner_label, DataType::BINARY_DATA); + } + + performance_stop(c_test_retries * c_num_names); } BOOST_AUTO_TEST_CASE(DBperfAddPermissions) { - // prepare data - generate_perf_DB(c_num_names, c_names_per_label); + // prepare data + generate_perf_DB(c_num_names, c_names_per_label); - // actual test - add access rights - performance_start("setPermission"); - long iterations = add_full_access_rights(c_num_names, c_names_per_label); - performance_stop(iterations); + // actual test - add access rights + performance_start("setPermission"); + long iterations = add_full_access_rights(c_num_names, c_names_per_label); + performance_stop(iterations); } BOOST_AUTO_TEST_CASE(DBperfAliasRemoval) { - // prepare data - generate_perf_DB(c_num_names, c_names_per_label); - add_full_access_rights(c_num_names, c_names_per_label); - - // actual test - random lookup - performance_start("deleteRow"); - Name name; - Label label; - for(unsigned int t=0; t<c_num_names; t++) - { - generate_name(t, name); - generate_label(t/c_names_per_label, label); - - BOOST_REQUIRE_NO_THROW(m_db.deleteRow(name, label)); - } - performance_stop(c_num_names); - - // verify everything has been removed - unsigned int num_labels = c_num_names / c_names_per_label; - for(unsigned int l=0; l<num_labels; l++) - { - generate_label(l, label); - LabelNameVector expect_no_data; - BOOST_REQUIRE_NO_THROW(m_db.listNames(label, expect_no_data, DataType::BINARY_DATA)); - BOOST_REQUIRE(0 == expect_no_data.size()); - } + // prepare data + generate_perf_DB(c_num_names, c_names_per_label); + add_full_access_rights(c_num_names, c_names_per_label); + + // actual test - random lookup + performance_start("deleteRow"); + Name name; + Label label; + + for (unsigned int t = 0; t < c_num_names; t++) { + generate_name(t, name); + generate_label(t / c_names_per_label, label); + + BOOST_REQUIRE_NO_THROW(m_db.deleteRow(name, label)); + } + + performance_stop(c_num_names); + + // verify everything has been removed + unsigned int num_labels = c_num_names / c_names_per_label; + + for (unsigned int l = 0; l < num_labels; l++) { + generate_label(l, label); + LabelNameVector expect_no_data; + BOOST_REQUIRE_NO_THROW(m_db.listNames(label, expect_no_data, + DataType::BINARY_DATA)); + BOOST_REQUIRE(0 == expect_no_data.size()); + } } BOOST_AUTO_TEST_CASE(DBperfGetAliasList) { - // prepare data - generate_perf_DB(c_num_names, c_names_per_label); - add_full_access_rights(c_num_names, c_names_per_label); - - unsigned int num_labels = c_num_names / c_names_per_label; - Label label; - - // actual test - random lookup - performance_start("listNames"); - for(unsigned int t=0; t<(c_test_retries/num_labels); t++) - { - LabelNameVector ret_list; - generate_label(rand_r(&t)%num_labels, label); - - BOOST_REQUIRE_NO_THROW(m_db.listNames(label, ret_list, DataType::BINARY_DATA)); - BOOST_REQUIRE(c_num_names == ret_list.size()); - ret_list.clear(); - } - performance_stop(c_test_retries/num_labels); + // prepare data + generate_perf_DB(c_num_names, c_names_per_label); + add_full_access_rights(c_num_names, c_names_per_label); + + unsigned int num_labels = c_num_names / c_names_per_label; + Label label; + + // actual test - random lookup + performance_start("listNames"); + + for (unsigned int t = 0; t < (c_test_retries / num_labels); t++) { + LabelNameVector ret_list; + generate_label(rand_r(&t) % num_labels, label); + + BOOST_REQUIRE_NO_THROW(m_db.listNames(label, ret_list, DataType::BINARY_DATA)); + BOOST_REQUIRE(c_num_names == ret_list.size()); + ret_list.clear(); + } + + performance_stop(c_test_retries / num_labels); } BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(DBCRYPTO_MIGRATION_TEST) -namespace -{ +namespace { const unsigned migration_names = 16107; const unsigned migration_labels = 273; const unsigned migration_reference_label_idx = 0; const unsigned migration_accessed_element_idx = 7; -void verifyDBisValid(DBFixture & fixture) +void verifyDBisValid(DBFixture &fixture) { - /** - * there are (migration_labels), each having (migration_names)/(migration_labels) entries. - * reference label (migration_reference_label_idx) exists such that it has access to - * all others' label element with index (migration_accessed_element_idx). - * - * Example: - * - migration_label_63 has access to all items owned by migration_label_63, - * which gives (migration_names)/(migration_labels) entries. - * - * - migration_label_0 (0 is the reference label) has access to all items - * owned by migration_label_0 and all others' label element index 7, - * which gives (migration_names)/(migration_labels) + (migration_labels-1) entries. - * - */ - Label reference_label; - fixture.generate_label(migration_reference_label_idx, reference_label); - - // check number of elements accessible to the reference label - LabelNameVector ret_list; - BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(reference_label, ret_list, DataType::BINARY_DATA)); - BOOST_REQUIRE((migration_names/migration_labels)/*own items*/ + (migration_labels-1)/*other labels'*/ == ret_list.size()); - ret_list.clear(); - - // check number of elements accessible to the other labels - for(unsigned int l=0; l<migration_labels; l++) - { - // bypass the reference owner label - if(l == migration_reference_label_idx) - continue; - - Label current_label; - fixture.generate_label(l, current_label); - BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(current_label, ret_list, DataType::BINARY_DATA)); - BOOST_REQUIRE((migration_names/migration_labels) == ret_list.size()); - for(auto it: ret_list) - BOOST_REQUIRE(it.first == current_label); - ret_list.clear(); - } + /** + * there are (migration_labels), each having (migration_names)/(migration_labels) entries. + * reference label (migration_reference_label_idx) exists such that it has access to + * all others' label element with index (migration_accessed_element_idx). + * + * Example: + * - migration_label_63 has access to all items owned by migration_label_63, + * which gives (migration_names)/(migration_labels) entries. + * + * - migration_label_0 (0 is the reference label) has access to all items + * owned by migration_label_0 and all others' label element index 7, + * which gives (migration_names)/(migration_labels) + (migration_labels-1) entries. + * + */ + Label reference_label; + fixture.generate_label(migration_reference_label_idx, reference_label); + + // check number of elements accessible to the reference label + LabelNameVector ret_list; + BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(reference_label, ret_list, + DataType::BINARY_DATA)); + BOOST_REQUIRE((migration_names / migration_labels)/*own items*/ + + (migration_labels - 1)/*other labels'*/ == ret_list.size()); + ret_list.clear(); + + // check number of elements accessible to the other labels + for (unsigned int l = 0; l < migration_labels; l++) { + // bypass the reference owner label + if (l == migration_reference_label_idx) + continue; + + Label current_label; + fixture.generate_label(l, current_label); + BOOST_REQUIRE_NO_THROW(fixture.m_db.listNames(current_label, ret_list, + DataType::BINARY_DATA)); + BOOST_REQUIRE((migration_names / migration_labels) == ret_list.size()); + + for (auto it : ret_list) + BOOST_REQUIRE(it.first == current_label); + + ret_list.clear(); + } } -struct DBVer1Migration : public DBFixture -{ - DBVer1Migration() : DBFixture(DB_TEST_DIR "/testme_ver1.db") - {} +struct DBVer1Migration : public DBFixture { + DBVer1Migration() : DBFixture(DB_TEST_DIR "/testme_ver1.db") {} }; -struct DBVer2Migration : public DBFixture -{ - DBVer2Migration() : DBFixture(DB_TEST_DIR "/testme_ver2.db") - {} +struct DBVer2Migration : public DBFixture { + DBVer2Migration() : DBFixture(DB_TEST_DIR "/testme_ver2.db") {} }; -struct DBVer3Migration : public DBFixture -{ - DBVer3Migration() : DBFixture(DB_TEST_DIR "/testme_ver3.db") - {} +struct DBVer3Migration : public DBFixture { + DBVer3Migration() : DBFixture(DB_TEST_DIR "/testme_ver3.db") {} }; } BOOST_AUTO_TEST_CASE(DBMigrationDBVer1) { - DBVer1Migration DBver1; - verifyDBisValid(DBver1); + DBVer1Migration DBver1; + verifyDBisValid(DBver1); } BOOST_AUTO_TEST_CASE(DBMigrationDBVer2) { - DBVer2Migration DBver2; - verifyDBisValid(DBver2); + DBVer2Migration DBver2; + verifyDBisValid(DBver2); } BOOST_AUTO_TEST_CASE(DBMigrationDBVer3) { - DBVer3Migration DBver3; - verifyDBisValid(DBver3); + DBVer3Migration DBver3; + verifyDBisValid(DBver3); } BOOST_AUTO_TEST_CASE(DBMigrationDBCurrent) { - DBFixture currentDB; - - // prepare data using current DB mechanism - Label reference_label; - currentDB.generate_label(migration_reference_label_idx, reference_label); - { - currentDB.generate_perf_DB(migration_names, migration_names/migration_labels); - - // only the reference label has access to the other labels element <migration_accessed_element_idx> - for(unsigned int l=0; l<migration_labels; l++) - { - // bypass the reference owner label - if(l == migration_reference_label_idx) - continue; - - unsigned element_index = migration_accessed_element_idx + l*migration_names/migration_labels; - - // add permission - Name accessed_name; - currentDB.generate_name(element_index, accessed_name); - Label current_label; - currentDB.generate_label(l, current_label); - currentDB.add_permission(accessed_name, current_label, reference_label); - } - } - - verifyDBisValid(currentDB); + DBFixture currentDB; + + // prepare data using current DB mechanism + Label reference_label; + currentDB.generate_label(migration_reference_label_idx, reference_label); + + { + currentDB.generate_perf_DB(migration_names, migration_names / migration_labels); + + // only the reference label has access to the other labels element <migration_accessed_element_idx> + for (unsigned int l = 0; l < migration_labels; l++) { + // bypass the reference owner label + if (l == migration_reference_label_idx) + continue; + + unsigned element_index = migration_accessed_element_idx + l * migration_names / + migration_labels; + + // add permission + Name accessed_name; + currentDB.generate_name(element_index, accessed_name); + Label current_label; + currentDB.generate_label(l, current_label); + currentDB.add_permission(accessed_name, current_label, reference_label); + } + } + + verifyDBisValid(currentDB); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_descriptor-set.cpp b/tests/test_descriptor-set.cpp index 443cdf58..4d345a8e 100644 --- a/tests/test_descriptor-set.cpp +++ b/tests/test_descriptor-set.cpp @@ -46,9 +46,10 @@ typedef std::unique_ptr<int[], std::function<void(int *)>> PipePtr; const short POLLALL = std::numeric_limits<short>::max(); -void closePipe(int* fd) { - close(fd[0]); - close(fd[1]); +void closePipe(int *fd) +{ + close(fd[0]); + close(fd[1]); } /* @@ -57,27 +58,30 @@ void closePipe(int* fd) { * Wraps pipe in unique_ptr */ #define PIPE(fd) \ - int (fd)[2]; \ - BOOST_REQUIRE_MESSAGE(0 == pipe((fd)),"Pipe creation failed: " << GetErrnoString()); \ - PipePtr fd##Ptr((fd), closePipe); + int (fd)[2]; \ + BOOST_REQUIRE_MESSAGE(0 == pipe((fd)), "Pipe creation failed: " << GetErrnoString()); \ + PipePtr fd##Ptr((fd), closePipe); -void unexpectedCallback(int, short) { - BOOST_FAIL("Unexpected callback"); +void unexpectedCallback(int, short) +{ + BOOST_FAIL("Unexpected callback"); } -void readFd(int fd, int expectedFd, short revents) { - char buf[1]; - BOOST_REQUIRE_MESSAGE(fd == expectedFd, "Unexpected descriptor"); - BOOST_REQUIRE_MESSAGE(revents & POLLIN, "Unexpected event"); - BOOST_REQUIRE_MESSAGE(1 == TEMP_FAILURE_RETRY(read(fd,buf,1)), - "Pipe read failed" << GetErrnoString()); +void readFd(int fd, int expectedFd, short revents) +{ + char buf[1]; + BOOST_REQUIRE_MESSAGE(fd == expectedFd, "Unexpected descriptor"); + BOOST_REQUIRE_MESSAGE(revents & POLLIN, "Unexpected event"); + BOOST_REQUIRE_MESSAGE(1 == TEMP_FAILURE_RETRY(read(fd, buf, 1)), + "Pipe read failed" << GetErrnoString()); } -void writeFd(int fd, int expectedFd, short revents) { - BOOST_REQUIRE_MESSAGE(fd == expectedFd, "Unexpected descriptor"); - BOOST_REQUIRE_MESSAGE(revents & POLLOUT, "Unexpected event"); - BOOST_REQUIRE_MESSAGE(1 == TEMP_FAILURE_RETRY(write(fd,"j",1)), - "Pipe writing failed" << GetErrnoString()); +void writeFd(int fd, int expectedFd, short revents) +{ + BOOST_REQUIRE_MESSAGE(fd == expectedFd, "Unexpected descriptor"); + BOOST_REQUIRE_MESSAGE(revents & POLLOUT, "Unexpected event"); + BOOST_REQUIRE_MESSAGE(1 == TEMP_FAILURE_RETRY(write(fd, "j", 1)), + "Pipe writing failed" << GetErrnoString()); } } // anonymous namespace @@ -87,148 +91,151 @@ BOOST_AUTO_TEST_SUITE(DESCRIPTOR_SET_TEST) /* * Wait on empty descriptor set. Function should return immediately. */ -BOOST_AUTO_TEST_CASE(T010_Empty) { - DescriptorSet descriptors; +BOOST_AUTO_TEST_CASE(T010_Empty) +{ + DescriptorSet descriptors; - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); } /* * Add and remove (twice) descriptor. Wait on empty set. No callback should be called. wait() should * return immediately. */ -BOOST_AUTO_TEST_CASE(T020_AddRemove) { - DescriptorSet descriptors; - descriptors.add(10, POLLALL, unexpectedCallback); - descriptors.remove(10); - descriptors.remove(10); - - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); +BOOST_AUTO_TEST_CASE(T020_AddRemove) +{ + DescriptorSet descriptors; + descriptors.add(10, POLLALL, unexpectedCallback); + descriptors.remove(10); + descriptors.remove(10); + + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); } /* * Add 2 descriptors and purge all. Wait on empty set. No callback should be called. wait() should * return immediately. */ -BOOST_AUTO_TEST_CASE(T030_AddPurge) { - DescriptorSet descriptors; - descriptors.add(10, POLLALL, unexpectedCallback); - descriptors.add(20, POLLALL, unexpectedCallback); - descriptors.purge(); - - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); +BOOST_AUTO_TEST_CASE(T030_AddPurge) +{ + DescriptorSet descriptors; + descriptors.add(10, POLLALL, unexpectedCallback); + descriptors.add(20, POLLALL, unexpectedCallback); + descriptors.purge(); + + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); } /* * Add pipe[1] descriptor and wait for write possibility. Provided callback should be called * immediately. */ -BOOST_AUTO_TEST_CASE(T040_Callback) { - DescriptorSet descriptors; - bool callback = false; +BOOST_AUTO_TEST_CASE(T040_Callback) +{ + DescriptorSet descriptors; + bool callback = false; - PIPE(fd); + PIPE(fd); - descriptors.add(fd[1],POLLALL, [&callback](int, short revents) - { - callback = true; - BOOST_REQUIRE_MESSAGE(revents & POLLOUT, "Not able to write"); - }); + descriptors.add(fd[1], POLLALL, [&callback](int, short revents) { + callback = true; + BOOST_REQUIRE_MESSAGE(revents & POLLOUT, "Not able to write"); + }); - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); - BOOST_REQUIRE_MESSAGE(callback, "Callback was not called"); + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + BOOST_REQUIRE_MESSAGE(callback, "Callback was not called"); } /* * Add pipe[1] descriptor twice with different callbacks. The first one should be overwritten and * shouldn't be called. The second one should be called instead. */ -BOOST_AUTO_TEST_CASE(T050_DoubleAdd) { - DescriptorSet descriptors; - bool callback = false; +BOOST_AUTO_TEST_CASE(T050_DoubleAdd) +{ + DescriptorSet descriptors; + bool callback = false; - PIPE(fd); + PIPE(fd); - descriptors.add(fd[1], POLLALL, unexpectedCallback); - descriptors.add(fd[1], POLLALL, [&callback](int, short revents) - { - callback = true; - BOOST_REQUIRE_MESSAGE(revents & POLLOUT, "Not able to write"); - }); + descriptors.add(fd[1], POLLALL, unexpectedCallback); + descriptors.add(fd[1], POLLALL, [&callback](int, short revents) { + callback = true; + BOOST_REQUIRE_MESSAGE(revents & POLLOUT, "Not able to write"); + }); - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); - BOOST_REQUIRE_MESSAGE(callback, "Callback was not called"); + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + BOOST_REQUIRE_MESSAGE(callback, "Callback was not called"); } /* * Add pipe[0] descriptor and wait. Callback should not be called. Instead the 8s timeout should * occur and a proper exception should be thrown. */ -BOOST_AUTO_TEST_CASE(T060_Timeout) { - DescriptorSet descriptors; +BOOST_AUTO_TEST_CASE(T060_Timeout) +{ + DescriptorSet descriptors; - PIPE(fd); + PIPE(fd); - descriptors.add(fd[0],POLLALL, unexpectedCallback); + descriptors.add(fd[0], POLLALL, unexpectedCallback); - BOOST_REQUIRE_THROW(descriptors.wait(POLL_TIMEOUT_SHORT), CKM::DescriptorSet::Timeout); + BOOST_REQUIRE_THROW(descriptors.wait(POLL_TIMEOUT_SHORT), + CKM::DescriptorSet::Timeout); } /* * Create pipe and try to write it. Start thread that will read it. */ -BOOST_AUTO_TEST_CASE(T070_Write) { - DescriptorSet descriptors; - bool callback = false; - - PIPE(fd); - - descriptors.add(fd[1],POLLOUT, [&fd, &callback](int desc, short revents) - { - callback = true; - writeFd(desc, fd[1], revents); - } ); - - { - auto thread = CreateWatchedThread([fd] - { - char buf[1]; - ssize_t tmp = TEMP_FAILURE_RETRY(read(fd[0], buf, 1)); - THREAD_REQUIRE_MESSAGE(tmp == 1, "Pipe reading failed " << GetErrnoString()); - }); - - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); - } - - BOOST_REQUIRE_MESSAGE(callback, "Callback not called"); +BOOST_AUTO_TEST_CASE(T070_Write) +{ + DescriptorSet descriptors; + bool callback = false; + + PIPE(fd); + + descriptors.add(fd[1], POLLOUT, [&fd, &callback](int desc, short revents) { + callback = true; + writeFd(desc, fd[1], revents); + }); + + { + auto thread = CreateWatchedThread([fd] { + char buf[1]; + ssize_t tmp = TEMP_FAILURE_RETRY(read(fd[0], buf, 1)); + THREAD_REQUIRE_MESSAGE(tmp == 1, "Pipe reading failed " << GetErrnoString()); + }); + + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + } + + BOOST_REQUIRE_MESSAGE(callback, "Callback not called"); } /* * Create pipe and try to read it. Start thread that will write it. */ -BOOST_AUTO_TEST_CASE(T080_Read) { - DescriptorSet descriptors; - bool callback = false; +BOOST_AUTO_TEST_CASE(T080_Read) +{ + DescriptorSet descriptors; + bool callback = false; - PIPE(fd); + PIPE(fd); - descriptors.add(fd[0],POLLIN, [&](int desc, short revents) - { - callback = true; - readFd(desc, fd[0], revents); - } ); + descriptors.add(fd[0], POLLIN, [&](int desc, short revents) { + callback = true; + readFd(desc, fd[0], revents); + }); - { - auto thread = CreateWatchedThread([fd] - { - ssize_t tmp = TEMP_FAILURE_RETRY(write(fd[1], "j", 1)); - THREAD_REQUIRE_MESSAGE(tmp == 1, "Pipe writing failed " << GetErrnoString()); - }); + { + auto thread = CreateWatchedThread([fd] { + ssize_t tmp = TEMP_FAILURE_RETRY(write(fd[1], "j", 1)); + THREAD_REQUIRE_MESSAGE(tmp == 1, "Pipe writing failed " << GetErrnoString()); + }); - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); - } + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + } - BOOST_REQUIRE_MESSAGE(callback, "Callback not called"); + BOOST_REQUIRE_MESSAGE(callback, "Callback not called"); } /* @@ -236,44 +243,43 @@ BOOST_AUTO_TEST_CASE(T080_Read) { * the pipe, remove it from the descriptor set and try to write the second pipe. The thread will * read it. In second pipe callback remove the second pipe descriptor from the set. */ -BOOST_AUTO_TEST_CASE(T090_WriteAfterRead) { - DescriptorSet descriptors; - bool callback1 = false; - bool callback2 = false; - - PIPE(fd); - PIPE(fd2); - - descriptors.add(fd[0],POLLIN, [&](int desc, short revents) - { - callback1 = true; - readFd(desc, fd[0], revents); - - descriptors.remove(desc); - descriptors.add(fd2[1],POLLOUT, [&](int desc, short revents) { - callback2 = true; - writeFd(desc, fd2[1], revents); - descriptors.remove(desc); - } ); - } ); - - { - auto thread = CreateWatchedThread([fd,fd2] - { - ssize_t tmp = TEMP_FAILURE_RETRY(write(fd[1], "j", 1)); - BOOST_REQUIRE_MESSAGE(tmp == 1, "Pipe writing failed " << GetErrnoString()); - - char buf[1]; - tmp = TEMP_FAILURE_RETRY(read(fd2[0], buf, 1)); - THREAD_REQUIRE_MESSAGE(tmp == 1, "Pipe reading failed " << GetErrnoString()); - }); - - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); - BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); - } - - BOOST_REQUIRE_MESSAGE(callback1, "First callback not called"); - BOOST_REQUIRE_MESSAGE(callback2, "Second callback not called"); +BOOST_AUTO_TEST_CASE(T090_WriteAfterRead) +{ + DescriptorSet descriptors; + bool callback1 = false; + bool callback2 = false; + + PIPE(fd); + PIPE(fd2); + + descriptors.add(fd[0], POLLIN, [&](int desc, short revents) { + callback1 = true; + readFd(desc, fd[0], revents); + + descriptors.remove(desc); + descriptors.add(fd2[1], POLLOUT, [&](int desc, short revents) { + callback2 = true; + writeFd(desc, fd2[1], revents); + descriptors.remove(desc); + }); + }); + + { + auto thread = CreateWatchedThread([fd, fd2] { + ssize_t tmp = TEMP_FAILURE_RETRY(write(fd[1], "j", 1)); + BOOST_REQUIRE_MESSAGE(tmp == 1, "Pipe writing failed " << GetErrnoString()); + + char buf[1]; + tmp = TEMP_FAILURE_RETRY(read(fd2[0], buf, 1)); + THREAD_REQUIRE_MESSAGE(tmp == 1, "Pipe reading failed " << GetErrnoString()); + }); + + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT)); + } + + BOOST_REQUIRE_MESSAGE(callback1, "First callback not called"); + BOOST_REQUIRE_MESSAGE(callback2, "Second callback not called"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_encryption-scheme.cpp b/tests/test_encryption-scheme.cpp index 9e4579a3..dc2e3bd0 100644 --- a/tests/test_encryption-scheme.cpp +++ b/tests/test_encryption-scheme.cpp @@ -36,117 +36,127 @@ const int NEW_ENC_SCHEME = 1; BOOST_AUTO_TEST_SUITE(ENCRYPTION_SCHEME_TEST) // Test database should have the old scheme -BOOST_AUTO_TEST_CASE(T010_Check_old_scheme) { - SchemeTest test; - test.RestoreDb(); +BOOST_AUTO_TEST_CASE(T010_Check_old_scheme) +{ + SchemeTest test; + test.RestoreDb(); - ItemFilter filter; - test.CheckSchemeVersion(filter, OLD_ENC_SCHEME); + ItemFilter filter; + test.CheckSchemeVersion(filter, OLD_ENC_SCHEME); } // Newly written data should use the new scheme -BOOST_AUTO_TEST_CASE(T020_Check_new_scheme) { - SchemeTest test; - test.RemoveUserData(); - test.FillDb(); - - ItemFilter filter; - test.CheckSchemeVersion(filter, NEW_ENC_SCHEME); +BOOST_AUTO_TEST_CASE(T020_Check_new_scheme) +{ + SchemeTest test; + test.RemoveUserData(); + test.FillDb(); + + ItemFilter filter; + test.CheckSchemeVersion(filter, NEW_ENC_SCHEME); } -BOOST_AUTO_TEST_CASE(T030_Remove_old_scheme) { - SchemeTest test; - test.RestoreDb(); - test.RemoveAll(); +BOOST_AUTO_TEST_CASE(T030_Remove_old_scheme) +{ + SchemeTest test; + test.RestoreDb(); + test.RemoveAll(); - size_t aliases = test.CountObjects(); - BOOST_REQUIRE_MESSAGE(aliases == 0, "All aliases should be removed"); + size_t aliases = test.CountObjects(); + BOOST_REQUIRE_MESSAGE(aliases == 0, "All aliases should be removed"); } -BOOST_AUTO_TEST_CASE(T040_Remove_new_scheme) { - SchemeTest test; - test.RemoveUserData(); - test.FillDb(); - test.RemoveAll(); +BOOST_AUTO_TEST_CASE(T040_Remove_new_scheme) +{ + SchemeTest test; + test.RemoveUserData(); + test.FillDb(); + test.RemoveAll(); - size_t aliases = test.CountObjects(); - BOOST_REQUIRE_MESSAGE(aliases == 0, "All aliases should be removed"); + size_t aliases = test.CountObjects(); + BOOST_REQUIRE_MESSAGE(aliases == 0, "All aliases should be removed"); } // Reading old db should reencrypt objects with new scheme -BOOST_AUTO_TEST_CASE(T100_Read) { - SchemeTest test; - test.RestoreDb(); - test.ReadAll(); - - ItemFilter filter; - filter.exportableOnly = true; - test.CheckSchemeVersion(filter, NEW_ENC_SCHEME); +BOOST_AUTO_TEST_CASE(T100_Read) +{ + SchemeTest test; + test.RestoreDb(); + test.ReadAll(); + + ItemFilter filter; + filter.exportableOnly = true; + test.CheckSchemeVersion(filter, NEW_ENC_SCHEME); } -BOOST_AUTO_TEST_CASE(T110_Count_objects_after_read) { - SchemeTest test; - test.RestoreDb(); - size_t orig = test.CountObjects(); - BOOST_REQUIRE_MESSAGE(orig > 0, "No objects in db"); +BOOST_AUTO_TEST_CASE(T110_Count_objects_after_read) +{ + SchemeTest test; + test.RestoreDb(); + size_t orig = test.CountObjects(); + BOOST_REQUIRE_MESSAGE(orig > 0, "No objects in db"); - test.ReadAll(); + test.ReadAll(); - size_t current = test.CountObjects(); - BOOST_REQUIRE_MESSAGE(current == orig, - "Original number of objects: " << orig << " Current: " << current); + size_t current = test.CountObjects(); + BOOST_REQUIRE_MESSAGE(current == orig, + "Original number of objects: " << orig << " Current: " << current); } // Reading old db with incorrect passwords should leave the scheme unchanged -BOOST_AUTO_TEST_CASE(T120_Read_wrong_pass) { - SchemeTest test; - test.RestoreDb(); - test.ReadAll(true); - - ItemFilter filter; - test.CheckSchemeVersion(filter, OLD_ENC_SCHEME); +BOOST_AUTO_TEST_CASE(T120_Read_wrong_pass) +{ + SchemeTest test; + test.RestoreDb(); + test.ReadAll(true); + + ItemFilter filter; + test.CheckSchemeVersion(filter, OLD_ENC_SCHEME); } // Signing/verification should reencrypt objects with new scheme -BOOST_AUTO_TEST_CASE(T200_SignVerify) { - SchemeTest test; - test.RestoreDb(); - test.SignVerify(); - - ItemFilter filter(DataType::KEY_RSA_PUBLIC, DataType::KEY_RSA_PRIVATE); - test.CheckSchemeVersion(filter, NEW_ENC_SCHEME); +BOOST_AUTO_TEST_CASE(T200_SignVerify) +{ + SchemeTest test; + test.RestoreDb(); + test.SignVerify(); + + ItemFilter filter(DataType::KEY_RSA_PUBLIC, DataType::KEY_RSA_PRIVATE); + test.CheckSchemeVersion(filter, NEW_ENC_SCHEME); } // Encryption/decryption should reencrypt objects with new scheme -BOOST_AUTO_TEST_CASE(T210_EncryptDecrypt) { - SchemeTest test; - test.RestoreDb(); - test.EncryptDecrypt(); +BOOST_AUTO_TEST_CASE(T210_EncryptDecrypt) +{ + SchemeTest test; + test.RestoreDb(); + test.EncryptDecrypt(); - ItemFilter filter1(DataType::KEY_RSA_PUBLIC, DataType::KEY_RSA_PRIVATE); - test.CheckSchemeVersion(filter1, NEW_ENC_SCHEME); + ItemFilter filter1(DataType::KEY_RSA_PUBLIC, DataType::KEY_RSA_PRIVATE); + test.CheckSchemeVersion(filter1, NEW_ENC_SCHEME); - ItemFilter filter2(DataType::KEY_AES); - test.CheckSchemeVersion(filter2, NEW_ENC_SCHEME); + ItemFilter filter2(DataType::KEY_AES); + test.CheckSchemeVersion(filter2, NEW_ENC_SCHEME); } // Chain creation should reencrypt objects with new scheme -BOOST_AUTO_TEST_CASE(T220_CreateChain) { - SchemeTest test; - test.RestoreDb(); - test.CreateChain(); - - // non exportable certificates and certificates protected with passwords can't be used for chain - // creation - ItemFilter filter1(DataType::CERTIFICATE); - filter1.exportableOnly = true; - filter1.noPassword = true; - test.CheckSchemeVersion(filter1, NEW_ENC_SCHEME); - - ItemFilter filter2(DataType::CHAIN_CERT_0, DataType::CHAIN_CERT_15); - filter2.exportableOnly = true; - filter2.noPassword = true; - test.CheckSchemeVersion(filter2, NEW_ENC_SCHEME); +BOOST_AUTO_TEST_CASE(T220_CreateChain) +{ + SchemeTest test; + test.RestoreDb(); + test.CreateChain(); + + // non exportable certificates and certificates protected with passwords can't be used for chain + // creation + ItemFilter filter1(DataType::CERTIFICATE); + filter1.exportableOnly = true; + filter1.noPassword = true; + test.CheckSchemeVersion(filter1, NEW_ENC_SCHEME); + + ItemFilter filter2(DataType::CHAIN_CERT_0, DataType::CHAIN_CERT_15); + filter2.exportableOnly = true; + filter2.noPassword = true; + test.CheckSchemeVersion(filter2, NEW_ENC_SCHEME); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_for-each-file.cpp b/tests/test_for-each-file.cpp index 60baf35e..543910b7 100644 --- a/tests/test_for-each-file.cpp +++ b/tests/test_for-each-file.cpp @@ -32,16 +32,17 @@ BOOST_AUTO_TEST_SUITE(TRAVERSE_DIR_TEST) BOOST_AUTO_TEST_CASE(T010_check_prefix) { - std::vector<std::string> files; + std::vector<std::string> files; - forEachFile(DB_TEST_DIR "/traverse", [&files](const std::string &filename) { - if (filename.find("res-") == std::string::npos) - return; + forEachFile(DB_TEST_DIR "/traverse", [&files](const std::string & filename) { + if (filename.find("res-") == std::string::npos) + return; - files.push_back(filename); - }); + files.push_back(filename); + }); - BOOST_REQUIRE_MESSAGE(files.size() == 10, "files num in traverse dir should be 10"); + BOOST_REQUIRE_MESSAGE(files.size() == 10, + "files num in traverse dir should be 10"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_safe-buffer.cpp b/tests/test_safe-buffer.cpp index a324fe14..fa42c369 100644 --- a/tests/test_safe-buffer.cpp +++ b/tests/test_safe-buffer.cpp @@ -33,45 +33,48 @@ namespace { const size_t LEN = 100; -struct Item -{ - Item(size_t a) : mA(a) {} - ~Item() {} +struct Item { + Item(size_t a) : mA(a) {} + ~Item() {} - bool operator==(const size_t& other) const { - return mA == other; - } + bool operator==(const size_t &other) const + { + return mA == other; + } - size_t mA; + size_t mA; }; template <typename T> size_t buffer_erase_test() { - typename T::value_type* data = NULL; - typename T::size_type i = 0; - { - T buffer; - for (i=0;i<LEN;++i) - buffer.push_back(typename T::value_type(i)); - - data = buffer.data(); - - for (i=0;i<LEN;++i) - BOOST_CHECK(data[i] == i); - } - - /* - * operator delete of RawBuffer which is called after buffer memory is erased - * (see erase_on_dealloc::deallocate) sometimes leaves garbage in the beginning of that memory. - * Therefore the test will be marked as failing only if more than 1/10 of the data matches - * original - */ - size_t cnt = 0; - for (i=0;i<LEN;++i) - cnt += (data[i] == i?1:0); - - return cnt; + typename T::value_type *data = NULL; + typename T::size_type i = 0; + + { + T buffer; + + for (i = 0; i < LEN; ++i) + buffer.push_back(typename T::value_type(i)); + + data = buffer.data(); + + for (i = 0; i < LEN; ++i) + BOOST_CHECK(data[i] == i); + } + + /* + * operator delete of RawBuffer which is called after buffer memory is erased + * (see erase_on_dealloc::deallocate) sometimes leaves garbage in the beginning of that memory. + * Therefore the test will be marked as failing only if more than 1/10 of the data matches + * original + */ + size_t cnt = 0; + + for (i = 0; i < LEN; ++i) + cnt += (data[i] == i ? 1 : 0); + + return cnt; } } // namespace anonymous @@ -80,28 +83,36 @@ BOOST_AUTO_TEST_SUITE(SAFE_BUFFER_TEST) // Tests for SafeBuffer. Checks if memory occupied by the buffer is wiped after it's deleted. -BOOST_AUTO_TEST_CASE(SafeBufferTest_uc_control_group) { - size_t cnt = buffer_erase_test<std::vector<unsigned char> >(); +BOOST_AUTO_TEST_CASE(SafeBufferTest_uc_control_group) +{ + size_t cnt = buffer_erase_test<std::vector<unsigned char>>(); - BOOST_REQUIRE_MESSAGE(cnt > LEN/2, "Less than 1/2 of data matches the original."); + BOOST_REQUIRE_MESSAGE(cnt > LEN / 2, + "Less than 1/2 of data matches the original."); } -BOOST_AUTO_TEST_CASE(SafeBufferTest_item_control_group) { - size_t cnt = buffer_erase_test<std::vector<Item> >(); +BOOST_AUTO_TEST_CASE(SafeBufferTest_item_control_group) +{ + size_t cnt = buffer_erase_test<std::vector<Item>>(); - BOOST_REQUIRE_MESSAGE(cnt > LEN/2, "Less than 1/2 of data matches the original."); + BOOST_REQUIRE_MESSAGE(cnt > LEN / 2, + "Less than 1/2 of data matches the original."); } -BOOST_AUTO_TEST_CASE(SafeBufferTest_uc) { - size_t cnt = buffer_erase_test<RawBuffer>(); +BOOST_AUTO_TEST_CASE(SafeBufferTest_uc) +{ + size_t cnt = buffer_erase_test<RawBuffer>(); - BOOST_REQUIRE_MESSAGE(cnt <= LEN/10, "More than 1/10 of data matches the original."); + BOOST_REQUIRE_MESSAGE(cnt <= LEN / 10, + "More than 1/10 of data matches the original."); } -BOOST_AUTO_TEST_CASE(SafeBufferTest_item) { - size_t cnt = buffer_erase_test<SafeBuffer<Item>::Type>(); +BOOST_AUTO_TEST_CASE(SafeBufferTest_item) +{ + size_t cnt = buffer_erase_test<SafeBuffer<Item>::Type>(); - BOOST_REQUIRE_MESSAGE(cnt <= LEN/10, "More than 1/10 of data matches the original."); + BOOST_REQUIRE_MESSAGE(cnt <= LEN / 10, + "More than 1/10 of data matches the original."); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_serialization.cpp b/tests/test_serialization.cpp index 653e5fd2..5fff3af8 100644 --- a/tests/test_serialization.cpp +++ b/tests/test_serialization.cpp @@ -36,103 +36,111 @@ std::string AAD_STR("sdfdsgsghrtkghwiuho3irhfoewituhre"); RawBuffer IV(IV_STR.begin(), IV_STR.end()); RawBuffer AAD(AAD_STR.begin(), AAD_STR.end()); -void checkIntParam(const CryptoAlgorithm& algo, ParamName name, uint64_t expected) +void checkIntParam(const CryptoAlgorithm &algo, ParamName name, + uint64_t expected) { - uint64_t integer; - BOOST_REQUIRE_MESSAGE(algo.getParam(name, integer), - "Failed to get parameter " << static_cast<int>(name)); - BOOST_REQUIRE_MESSAGE( - integer == expected, - "Parameter " << static_cast<int>(name) << - " expected value: " << expected << - " got: " << integer); + uint64_t integer; + BOOST_REQUIRE_MESSAGE(algo.getParam(name, integer), + "Failed to get parameter " << static_cast<int>(name)); + BOOST_REQUIRE_MESSAGE( + integer == expected, + "Parameter " << static_cast<int>(name) << + " expected value: " << expected << + " got: " << integer); } -void checkIntParamNegative(const CryptoAlgorithm& algo, ParamName name) +void checkIntParamNegative(const CryptoAlgorithm &algo, ParamName name) { - uint64_t integer; - BOOST_REQUIRE_MESSAGE(!algo.getParam(name, integer), - "Getting int parameter " << static_cast<int>(name) << " should fail"); + uint64_t integer; + BOOST_REQUIRE_MESSAGE(!algo.getParam(name, integer), + "Getting int parameter " << static_cast<int>(name) << " should fail"); } -void checkBufferParam(const CryptoAlgorithm& algo, ParamName name, RawBuffer expected) +void checkBufferParam(const CryptoAlgorithm &algo, ParamName name, + RawBuffer expected) { - RawBuffer buffer; - BOOST_REQUIRE_MESSAGE(algo.getParam(name, buffer), - "Failed to get buffer parameter " << static_cast<int>(name)); - BOOST_REQUIRE_MESSAGE(buffer == expected, - "Parameter " << static_cast<int>(name) << " different than expected"); + RawBuffer buffer; + BOOST_REQUIRE_MESSAGE(algo.getParam(name, buffer), + "Failed to get buffer parameter " << static_cast<int>(name)); + BOOST_REQUIRE_MESSAGE(buffer == expected, + "Parameter " << static_cast<int>(name) << " different than expected"); } -void checkBufferParamNegative(const CryptoAlgorithm& algo, ParamName name) +void checkBufferParamNegative(const CryptoAlgorithm &algo, ParamName name) { - RawBuffer buffer; - BOOST_REQUIRE_MESSAGE(!algo.getParam(name, buffer), - "Getting buffer parameter " << static_cast<int>(name) << " should fail"); + RawBuffer buffer; + BOOST_REQUIRE_MESSAGE(!algo.getParam(name, buffer), + "Getting buffer parameter " << static_cast<int>(name) << " should fail"); } template <typename T> -void setParam(CryptoAlgorithm& algo, ParamName name, const T& value, bool success) +void setParam(CryptoAlgorithm &algo, ParamName name, const T &value, + bool success) { - BOOST_REQUIRE_MESSAGE(success == algo.setParam(name, value), - "Adding param " << static_cast<int>(name) << - " should " << (success ? "succeed":"fail")); + BOOST_REQUIRE_MESSAGE(success == algo.setParam(name, value), + "Adding param " << static_cast<int>(name) << + " should " << (success ? "succeed" : "fail")); } } // namespace anonymous BOOST_AUTO_TEST_SUITE(SERIALIZATION_TEST) -BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm) { - CryptoAlgorithm ca; - setParam(ca,ParamName::ALGO_TYPE, static_cast<uint64_t>(AlgoType::AES_GCM), true); - setParam(ca,ParamName::ED_IV, AAD, true); - setParam(ca,ParamName::ED_IV, IV, true); // try to overwrite - setParam(ca,ParamName::ED_TAG_LEN, 128, true); - setParam(ca,ParamName::ED_AAD, AAD, true); - - CryptoAlgorithmSerializable input(ca); - CryptoAlgorithmSerializable output; - auto msg = MessageBuffer::Serialize(input); - RawBuffer buffer = msg.Pop(); - MessageBuffer resp; - resp.Push(buffer); - resp.Deserialize(output); - - checkIntParam(output, ParamName::ALGO_TYPE, static_cast<uint64_t>(AlgoType::AES_GCM)); - checkBufferParam(output, ParamName::ED_IV, IV); - checkIntParam(output, ParamName::ED_TAG_LEN, 128); - checkBufferParam(output, ParamName::ED_AAD, AAD); - - // wrong type - checkBufferParamNegative(output, ParamName::ALGO_TYPE); - checkIntParamNegative(output, ParamName::ED_IV); - - // non-existing - checkIntParamNegative(output, ParamName::ED_CTR_LEN); - checkBufferParamNegative(output, ParamName::ED_LABEL); - checkIntParamNegative(output, ParamName::GEN_KEY_LEN); - checkIntParamNegative(output, ParamName::GEN_EC); - checkIntParamNegative(output, ParamName::SV_HASH_ALGO); - checkIntParamNegative(output, ParamName::SV_RSA_PADDING); - - checkIntParamNegative(output, static_cast<ParamName>(666)); +BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm) +{ + CryptoAlgorithm ca; + setParam(ca, ParamName::ALGO_TYPE, static_cast<uint64_t>(AlgoType::AES_GCM), + true); + setParam(ca, ParamName::ED_IV, AAD, true); + setParam(ca, ParamName::ED_IV, IV, true); // try to overwrite + setParam(ca, ParamName::ED_TAG_LEN, 128, true); + setParam(ca, ParamName::ED_AAD, AAD, true); + + CryptoAlgorithmSerializable input(ca); + CryptoAlgorithmSerializable output; + auto msg = MessageBuffer::Serialize(input); + RawBuffer buffer = msg.Pop(); + MessageBuffer resp; + resp.Push(buffer); + resp.Deserialize(output); + + checkIntParam(output, ParamName::ALGO_TYPE, + static_cast<uint64_t>(AlgoType::AES_GCM)); + checkBufferParam(output, ParamName::ED_IV, IV); + checkIntParam(output, ParamName::ED_TAG_LEN, 128); + checkBufferParam(output, ParamName::ED_AAD, AAD); + + // wrong type + checkBufferParamNegative(output, ParamName::ALGO_TYPE); + checkIntParamNegative(output, ParamName::ED_IV); + + // non-existing + checkIntParamNegative(output, ParamName::ED_CTR_LEN); + checkBufferParamNegative(output, ParamName::ED_LABEL); + checkIntParamNegative(output, ParamName::GEN_KEY_LEN); + checkIntParamNegative(output, ParamName::GEN_EC); + checkIntParamNegative(output, ParamName::SV_HASH_ALGO); + checkIntParamNegative(output, ParamName::SV_RSA_PADDING); + + checkIntParamNegative(output, static_cast<ParamName>(666)); } -BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm_wrong_name) { - CryptoAlgorithm ca; - // param name out of range - setParam(ca, static_cast<ParamName>(666), 666, false); - // param name not supported by serializer - setParam(ca, static_cast<ParamName>(10), 666, true); - - CryptoAlgorithmSerializable input(ca); - CryptoAlgorithmSerializable output; - auto msg = MessageBuffer::Serialize(input); - RawBuffer buffer = msg.Pop(); - MessageBuffer resp; - resp.Push(buffer); - BOOST_REQUIRE_THROW(resp.Deserialize(output), CryptoAlgorithmSerializable::UnsupportedParam); +BOOST_AUTO_TEST_CASE(Serialization_CryptoAlgorithm_wrong_name) +{ + CryptoAlgorithm ca; + // param name out of range + setParam(ca, static_cast<ParamName>(666), 666, false); + // param name not supported by serializer + setParam(ca, static_cast<ParamName>(10), 666, true); + + CryptoAlgorithmSerializable input(ca); + CryptoAlgorithmSerializable output; + auto msg = MessageBuffer::Serialize(input); + RawBuffer buffer = msg.Pop(); + MessageBuffer resp; + resp.Push(buffer); + BOOST_REQUIRE_THROW(resp.Deserialize(output), + CryptoAlgorithmSerializable::UnsupportedParam); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_sql.cpp b/tests/test_sql.cpp index a07329e6..6b2a7a67 100644 --- a/tests/test_sql.cpp +++ b/tests/test_sql.cpp @@ -37,131 +37,145 @@ #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Wdeprecated-declarations" - const char *encrypt_me = "/tmp/encryptme.db"; const char *encrypt_me_not = "/tmp/encryptmenot.db"; const char *create_table = "CREATE TABLE t1(a,b);"; const char *insert_table = "INSERT INTO t1(a,b) VALUES (" - " 'one for the money'," - " 'two for the show');"; + " 'one for the money'," + " 'two for the show');"; const char *select_table = "SELECT * FROM t1"; CKM::RawBuffer raw_password = createDefaultPass(); BOOST_AUTO_TEST_SUITE(SQL_TEST) -BOOST_AUTO_TEST_CASE(sqlTestConversion){ - - BOOST_REQUIRE_MESSAGE(raw_password.size() == RAW_PASS_SIZE, - "Password should have 32 characters, got: " << raw_password.size()); - std::string pass_check = rawToHexString(raw_password); - BOOST_REQUIRE_MESSAGE(pass_check.length() == HEX_PASS_SIZE, - "Hex string should have 64 characters, got: " << pass_check.length()); - BOOST_CHECK(pass_check == pattern); +BOOST_AUTO_TEST_CASE(sqlTestConversion) +{ + BOOST_REQUIRE_MESSAGE(raw_password.size() == RAW_PASS_SIZE, + "Password should have 32 characters, got: " << raw_password.size()); + std::string pass_check = rawToHexString(raw_password); + BOOST_REQUIRE_MESSAGE(pass_check.length() == HEX_PASS_SIZE, + "Hex string should have 64 characters, got: " << pass_check.length()); + BOOST_CHECK(pass_check == pattern); } -BOOST_AUTO_TEST_CASE(sqlTestConversionBig){ - /* 192 ~ 208 in hex */ - const std::string tmppattern = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0"; +BOOST_AUTO_TEST_CASE(sqlTestConversionBig) +{ + /* 192 ~ 208 in hex */ + const std::string tmppattern = "c0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0"; - auto pass = createPass(192, 209); - BOOST_REQUIRE_MESSAGE(pass.size() == 17, "Password size should be 17"); + auto pass = createPass(192, 209); + BOOST_REQUIRE_MESSAGE(pass.size() == 17, "Password size should be 17"); - auto pass_hex = rawToHexString(pass); - BOOST_REQUIRE_MESSAGE(pass_hex.length() == 34, "Hexed password size should be 34"); - BOOST_CHECK(pass_hex == tmppattern); + auto pass_hex = rawToHexString(pass); + BOOST_REQUIRE_MESSAGE(pass_hex.length() == 34, + "Hexed password size should be 34"); + BOOST_CHECK(pass_hex == tmppattern); } -BOOST_AUTO_TEST_CASE(sqlTestSetKeyTooShort) { - using namespace CKM::DB; - BOOST_CHECK(unlink(encrypt_me_not) == 0 || errno == ENOENT); - SqlConnection connection(encrypt_me_not, - SqlConnection::Flag::CRW); - CKM::RawBuffer wrong_key(RAW_PASS_SIZE - 1, 1); - BOOST_REQUIRE_THROW(connection.SetKey(wrong_key), - SqlConnection::Exception::InvalidArguments); +BOOST_AUTO_TEST_CASE(sqlTestSetKeyTooShort) +{ + using namespace CKM::DB; + BOOST_CHECK(unlink(encrypt_me_not) == 0 || errno == ENOENT); + SqlConnection connection(encrypt_me_not, + SqlConnection::Flag::CRW); + CKM::RawBuffer wrong_key(RAW_PASS_SIZE - 1, 1); + BOOST_REQUIRE_THROW(connection.SetKey(wrong_key), + SqlConnection::Exception::InvalidArguments); } -BOOST_AUTO_TEST_CASE(sqlTestSetKeyTooLong) { - using namespace CKM::DB; - BOOST_CHECK(unlink(encrypt_me_not) == 0 || errno == ENOENT); - SqlConnection connection(encrypt_me_not, - SqlConnection::Flag::CRW); - CKM::RawBuffer wrong_key(RAW_PASS_SIZE + 1, 1); - BOOST_REQUIRE_THROW(connection.SetKey(wrong_key), - SqlConnection::Exception::InvalidArguments); +BOOST_AUTO_TEST_CASE(sqlTestSetKeyTooLong) +{ + using namespace CKM::DB; + BOOST_CHECK(unlink(encrypt_me_not) == 0 || errno == ENOENT); + SqlConnection connection(encrypt_me_not, + SqlConnection::Flag::CRW); + CKM::RawBuffer wrong_key(RAW_PASS_SIZE + 1, 1); + BOOST_REQUIRE_THROW(connection.SetKey(wrong_key), + SqlConnection::Exception::InvalidArguments); } -BOOST_AUTO_TEST_CASE(sqlTestConnectionUnencrypted) { - using namespace CKM::DB; - BOOST_CHECK(unlink(encrypt_me_not) == 0 || errno == ENOENT); - { - SqlConnection encrypting_you_not(encrypt_me_not, - SqlConnection::Flag::CRW); - BOOST_REQUIRE_NO_THROW(encrypting_you_not.ExecCommand(create_table)); - BOOST_REQUIRE_NO_THROW(encrypting_you_not.ExecCommand(insert_table)); - } - { - SqlConnection encrypting_you_not(encrypt_me_not, - SqlConnection::Flag::RW); - SqlConnection::DataCommandUniquePtr selectCommand; - BOOST_REQUIRE_NO_THROW(selectCommand = encrypting_you_not. - PrepareDataCommand(select_table)); - BOOST_REQUIRE_NO_THROW(selectCommand->Step()); - std::string value; - BOOST_REQUIRE_NO_THROW(value = selectCommand->GetColumnString(0)); - BOOST_REQUIRE(value == "one for the money"); - } +BOOST_AUTO_TEST_CASE(sqlTestConnectionUnencrypted) +{ + using namespace CKM::DB; + BOOST_CHECK(unlink(encrypt_me_not) == 0 || errno == ENOENT); + + { + SqlConnection encrypting_you_not(encrypt_me_not, + SqlConnection::Flag::CRW); + BOOST_REQUIRE_NO_THROW(encrypting_you_not.ExecCommand(create_table)); + BOOST_REQUIRE_NO_THROW(encrypting_you_not.ExecCommand(insert_table)); + } + + { + SqlConnection encrypting_you_not(encrypt_me_not, + SqlConnection::Flag::RW); + SqlConnection::DataCommandUniquePtr selectCommand; + BOOST_REQUIRE_NO_THROW(selectCommand = encrypting_you_not. + PrepareDataCommand(select_table)); + BOOST_REQUIRE_NO_THROW(selectCommand->Step()); + std::string value; + BOOST_REQUIRE_NO_THROW(value = selectCommand->GetColumnString(0)); + BOOST_REQUIRE(value == "one for the money"); + } } -BOOST_AUTO_TEST_CASE(sqlTestConnectionEncrypted) { - using namespace CKM::DB; - BOOST_CHECK(unlink(encrypt_me) == 0 || errno == ENOENT); - { - SqlConnection encrypting_you(encrypt_me, - SqlConnection::Flag::CRW); - BOOST_REQUIRE_NO_THROW(encrypting_you.SetKey(raw_password)); - BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(create_table)); - BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(insert_table)); - } - { - SqlConnection encrypting_you(encrypt_me, - SqlConnection::Flag::RW); - encrypting_you.SetKey(raw_password); - SqlConnection::DataCommandUniquePtr selectCommand; - BOOST_REQUIRE_NO_THROW(selectCommand = encrypting_you. - PrepareDataCommand(select_table)); - BOOST_REQUIRE_NO_THROW(selectCommand->Step()); - std::string value; - BOOST_REQUIRE_NO_THROW(value = selectCommand->GetColumnString(0)); - BOOST_REQUIRE(value == "one for the money"); - } +BOOST_AUTO_TEST_CASE(sqlTestConnectionEncrypted) +{ + using namespace CKM::DB; + BOOST_CHECK(unlink(encrypt_me) == 0 || errno == ENOENT); + + { + SqlConnection encrypting_you(encrypt_me, + SqlConnection::Flag::CRW); + BOOST_REQUIRE_NO_THROW(encrypting_you.SetKey(raw_password)); + BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(create_table)); + BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(insert_table)); + } + + { + SqlConnection encrypting_you(encrypt_me, + SqlConnection::Flag::RW); + encrypting_you.SetKey(raw_password); + SqlConnection::DataCommandUniquePtr selectCommand; + BOOST_REQUIRE_NO_THROW(selectCommand = encrypting_you. + PrepareDataCommand(select_table)); + BOOST_REQUIRE_NO_THROW(selectCommand->Step()); + std::string value; + BOOST_REQUIRE_NO_THROW(value = selectCommand->GetColumnString(0)); + BOOST_REQUIRE(value == "one for the money"); + } } -BOOST_AUTO_TEST_CASE(sqlTestConnectionEncryptedNegative) { - - using namespace CKM::DB; - BOOST_CHECK(unlink(encrypt_me) == 0 || errno == ENOENT); - { - SqlConnection encrypting_you(encrypt_me, - SqlConnection::Flag::CRW); - BOOST_REQUIRE_NO_THROW(encrypting_you.SetKey(raw_password)); - BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(create_table)); - BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(insert_table)); - } - { - SqlConnection encrypting_you(encrypt_me, - SqlConnection::Flag::RW); - CKM::RawBuffer wrong_password; - for(std::size_t i = 0; i < RAW_PASS_SIZE; i++) { - wrong_password.push_back(raw_password[i] + 1); - } - BOOST_REQUIRE_NO_THROW(encrypting_you.SetKey(wrong_password)); - - SqlConnection::DataCommandUniquePtr selectCommand; - BOOST_REQUIRE_THROW(selectCommand = encrypting_you.PrepareDataCommand(select_table), - SqlConnection::Exception::SyntaxError) - } +BOOST_AUTO_TEST_CASE(sqlTestConnectionEncryptedNegative) +{ + using namespace CKM::DB; + BOOST_CHECK(unlink(encrypt_me) == 0 || errno == ENOENT); + + { + SqlConnection encrypting_you(encrypt_me, + SqlConnection::Flag::CRW); + BOOST_REQUIRE_NO_THROW(encrypting_you.SetKey(raw_password)); + BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(create_table)); + BOOST_REQUIRE_NO_THROW(encrypting_you.ExecCommand(insert_table)); + } + + { + SqlConnection encrypting_you(encrypt_me, + SqlConnection::Flag::RW); + CKM::RawBuffer wrong_password; + + for (std::size_t i = 0; i < RAW_PASS_SIZE; i++) + wrong_password.push_back(raw_password[i] + 1); + + BOOST_REQUIRE_NO_THROW(encrypting_you.SetKey(wrong_password)); + + SqlConnection::DataCommandUniquePtr selectCommand; + BOOST_REQUIRE_THROW(selectCommand = encrypting_you.PrepareDataCommand( + select_table), + SqlConnection::Exception::SyntaxError) + } } + BOOST_AUTO_TEST_SUITE_END() #pragma GCC diagnostic pop diff --git a/tests/test_watched-thread.h b/tests/test_watched-thread.h index 57ae0cf0..fe65decf 100644 --- a/tests/test_watched-thread.h +++ b/tests/test_watched-thread.h @@ -34,46 +34,48 @@ DECLARE_EXCEPTION_TYPE(CKM::Exception, ThreadErrorMessage) template <typename F, typename... Args> class WatchedThread { public: - // can't use rreferences for Args because std::thread needs to copy all arguments - explicit WatchedThread(F&& function, const Args&... args) : - m_function(std::move(function)), - m_thread(&WatchedThread::Wrapper, this, args...) - {} + // can't use rreferences for Args because std::thread needs to copy all arguments + explicit WatchedThread(F &&function, const Args &... args) : + m_function(std::move(function)), + m_thread(&WatchedThread::Wrapper, this, args...) {} - ~WatchedThread() { - m_thread.join(); - if (!m_error.empty()) - BOOST_FAIL(m_error); - } + ~WatchedThread() + { + m_thread.join(); - NONCOPYABLE(WatchedThread); + if (!m_error.empty()) + BOOST_FAIL(m_error); + } - WatchedThread(WatchedThread&&) = default; - WatchedThread& operator=(WatchedThread&&) = default; + NONCOPYABLE(WatchedThread); -protected: + WatchedThread(WatchedThread &&) = default; + WatchedThread &operator=(WatchedThread &&) = default; - void Wrapper(const Args&... args) { - try { - m_function(args...); - } catch (const ThreadErrorMessage& e) { - m_error = e.DumpToString(); - } - } +protected: + void Wrapper(const Args &... args) + { + try { + m_function(args...); + } catch (const ThreadErrorMessage &e) { + m_error = e.DumpToString(); + } + } - std::string m_error; - F m_function; - std::thread m_thread; + std::string m_error; + F m_function; + std::thread m_thread; }; template <typename F, typename... Args> -WatchedThread<F, Args...> CreateWatchedThread(F&& function, const Args&... args) +WatchedThread<F, Args...> CreateWatchedThread(F &&function, + const Args &... args) { - return WatchedThread<F, Args...>(std::move(function), args...); + return WatchedThread<F, Args...>(std::move(function), args...); } -#define THREAD_REQUIRE_MESSAGE(expr, message) \ - do { \ - if (!(expr)) \ - ThrowMsg( ThreadErrorMessage, message); \ - } while (false); +#define THREAD_REQUIRE_MESSAGE(expr, message) \ + do { \ + if (!(expr)) \ + ThrowMsg(ThreadErrorMessage, message); \ + } while (false); diff --git a/tests/test_xml-parser.cpp b/tests/test_xml-parser.cpp index 44692611..ab25ce94 100644 --- a/tests/test_xml-parser.cpp +++ b/tests/test_xml-parser.cpp @@ -27,8 +27,7 @@ using namespace CKM; using namespace XML; -namespace -{ +namespace { const char *XML_1_okay = "XML_1_okay.xml"; const char *XSD_1_okay = "XML_1_okay.xsd"; const char *XML_1_wrong = "XML_1_wrong.xml"; @@ -41,20 +40,20 @@ const char *XSD_4_device_key = "XML_4_device_key.xsd"; std::string format_test_path(const char *file) { - return std::string(DB_TEST_DIR) + "/" + std::string(file); + return std::string(DB_TEST_DIR) + "/" + std::string(file); } bool startCallbackFlag = false; XML::Parser::ElementHandlerPtr dummyStartCallback() { - startCallbackFlag = true; - // return empty pointer - return XML::Parser::ElementHandlerPtr(); + startCallbackFlag = true; + // return empty pointer + return XML::Parser::ElementHandlerPtr(); } bool endCallbackFlag = false; void dummyEndCallback(const XML::Parser::ElementHandlerPtr &) { - endCallbackFlag = true; + endCallbackFlag = true; } } @@ -62,258 +61,270 @@ BOOST_AUTO_TEST_SUITE(XML_PARSER_TEST) BOOST_AUTO_TEST_CASE(XmlParserTest_wrong_argument) { - std::string emptyPath; - XML::Parser parser(emptyPath); - BOOST_REQUIRE(Parser::ErrorCode::ERROR_INVALID_ARGUMENT == parser.Validate(emptyPath)); + std::string emptyPath; + XML::Parser parser(emptyPath); + BOOST_REQUIRE(Parser::ErrorCode::ERROR_INVALID_ARGUMENT == parser.Validate( + emptyPath)); - // no listeners - BOOST_REQUIRE(Parser::ErrorCode::ERROR_INVALID_ARGUMENT == parser.Parse()); + // no listeners + BOOST_REQUIRE(Parser::ErrorCode::ERROR_INVALID_ARGUMENT == parser.Parse()); - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("Key", dummyStartCallback, dummyEndCallback)); - BOOST_REQUIRE(Parser::ErrorCode::ERROR_XML_PARSE_FAILED == parser.Parse()); + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("Key", dummyStartCallback, dummyEndCallback)); + BOOST_REQUIRE(Parser::ErrorCode::ERROR_XML_PARSE_FAILED == parser.Parse()); } BOOST_AUTO_TEST_CASE(XmlParserTest_no_XML_file) { - XML::Parser parser(format_test_path("i-am-not-here").c_str()); - BOOST_REQUIRE(Parser::ErrorCode::ERROR_XML_VALIDATION_FAILED == parser.Validate(format_test_path(XSD_1_okay).c_str())); + XML::Parser parser(format_test_path("i-am-not-here").c_str()); + BOOST_REQUIRE(Parser::ErrorCode::ERROR_XML_VALIDATION_FAILED == parser.Validate( + format_test_path(XSD_1_okay).c_str())); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML1_correct_verify) { - XML::Parser parser(format_test_path(XML_1_okay).c_str()); - BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_1_okay).c_str())); + XML::Parser parser(format_test_path(XML_1_okay).c_str()); + BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_1_okay).c_str())); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML1_wrong_verify) { - XML::Parser parser(format_test_path(XML_1_wrong).c_str()); - BOOST_REQUIRE(Parser::ErrorCode::ERROR_XML_VALIDATION_FAILED == parser.Validate(format_test_path(XSD_1_okay).c_str())); + XML::Parser parser(format_test_path(XML_1_wrong).c_str()); + BOOST_REQUIRE(Parser::ErrorCode::ERROR_XML_VALIDATION_FAILED == parser.Validate( + format_test_path(XSD_1_okay).c_str())); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML1_wrong_schema) { - XML::Parser parser(format_test_path(XML_1_okay).c_str()); - BOOST_REQUIRE(Parser::ErrorCode::ERROR_XSD_PARSE_FAILED == parser.Validate(format_test_path(XSD_1_wrong).c_str())); + XML::Parser parser(format_test_path(XML_1_okay).c_str()); + BOOST_REQUIRE(Parser::ErrorCode::ERROR_XSD_PARSE_FAILED == parser.Validate( + format_test_path(XSD_1_wrong).c_str())); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML1_correct_parse_incorrect_callbacks) { - XML::Parser parser(format_test_path(XML_1_okay).c_str()); - BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_1_okay).c_str())); + XML::Parser parser(format_test_path(XML_1_okay).c_str()); + BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_1_okay).c_str())); - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("Data", NULL, NULL)); - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("Data", NULL, NULL)); + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML1_correct_parse) { - XML::Parser parser(format_test_path(XML_1_okay).c_str()); - BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_1_okay).c_str())); - - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("Key", dummyStartCallback, NULL)); - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("Cert", NULL, dummyEndCallback)); - startCallbackFlag = false; - endCallbackFlag = false; - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); - BOOST_REQUIRE(startCallbackFlag == true); - BOOST_REQUIRE(endCallbackFlag == true); + XML::Parser parser(format_test_path(XML_1_okay).c_str()); + BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_1_okay).c_str())); + + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("Key", dummyStartCallback, NULL)); + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("Cert", NULL, dummyEndCallback)); + startCallbackFlag = false; + endCallbackFlag = false; + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); + BOOST_REQUIRE(startCallbackFlag == true); + BOOST_REQUIRE(endCallbackFlag == true); } -class StructureTest -{ +class StructureTest { public: - class ExpectedSumHandler : public XML::Parser::ElementHandler - { - public: - ExpectedSumHandler() : m_value(0) {} - - virtual void Start(const XML::Parser::Attributes &) {} - virtual void Characters(const std::string &data) { - m_value = atoi(data.c_str()); - } - virtual void End() {} - - int getSum() const { - return m_value; - } - - protected: - int m_value; - }; - - class MathHandler : public XML::Parser::ElementHandler - { - public: - MathHandler() : m_valueSet(false), m_value(0), m_powerFactor(1) {} - - virtual void Start(const XML::Parser::Attributes &attr) { - const auto & it = attr.find("powerFactor"); - if(it != attr.end()) - m_powerFactor = atoi(it->second.c_str()); - } - virtual void Characters(const std::string &data) { - m_value = pow(atoi(data.c_str()), m_powerFactor); - m_valueSet = true; - } - virtual void End() {} - - virtual int compute(int prevVal) = 0; - - protected: - bool m_valueSet; - int m_value; - int m_powerFactor; - }; - class AddHandler : public MathHandler - { - public: - virtual int compute(int prevVal) { - if( !m_valueSet ) - return prevVal; - - return prevVal + m_value; - } - }; - - class MultiplyHandler : public MathHandler - { - public: - virtual int compute(int prevVal) { - if( !m_valueSet ) - return prevVal; - - return prevVal * m_value; - } - }; - - class DivHandler : public MathHandler - { - public: - virtual int compute(int prevVal) { - if( !m_valueSet ) - return prevVal; - - if(m_value == 0) - return prevVal; - return prevVal / m_value; - } - }; - - StructureTest(const char *filename) : m_parser(filename), m_sum(0), m_expectedSum(0) - { - m_parser.RegisterErrorCb(StructureTest::Error); - m_parser.RegisterElementCb("Add", - [this]() -> XML::Parser::ElementHandlerPtr - { - return std::make_shared<AddHandler>(); - }, - [this](const XML::Parser::ElementHandlerPtr & element) - { - // add computation - if(element) - { - MathHandler *mathElement = reinterpret_cast<MathHandler*>(element.get()); - m_sum = mathElement->compute(m_sum); - } - }); - m_parser.RegisterElementCb("Multiply", - [this]() -> XML::Parser::ElementHandlerPtr - { - return std::make_shared<MultiplyHandler>(); - }, - [this](const XML::Parser::ElementHandlerPtr &element) - { - // multiply computation - if(element) - { - MathHandler *mathElement = reinterpret_cast<MathHandler*>(element.get()); - m_sum = mathElement->compute(m_sum); - } - }); - m_parser.RegisterElementCb("Div", - [this]() -> XML::Parser::ElementHandlerPtr - { - return std::make_shared<DivHandler>(); - }, - [this](const XML::Parser::ElementHandlerPtr &element) - { - // division computation - if(element) - { - MathHandler *mathElement = reinterpret_cast<MathHandler*>(element.get()); - m_sum = mathElement->compute(m_sum); - } - }); - m_parser.RegisterElementCb("ExpectedSum", - [this]() -> XML::Parser::ElementHandlerPtr - { - return std::make_shared<ExpectedSumHandler>(); - }, - [this](const XML::Parser::ElementHandlerPtr &element) - { - if(element) - { - ExpectedSumHandler *sumElement = reinterpret_cast<ExpectedSumHandler*>(element.get()); - m_expectedSum = sumElement->getSum(); - } - }); - } - - static void Error(const Parser::ErrorType /*errorType*/, - const std::string & log_msg) - { - BOOST_FAIL(log_msg); - } - - int Parse() - { - return m_parser.Parse(); - } - - int getSum() const { - return m_sum; - } - int getExpectedSum() const { - return m_expectedSum; - } + class ExpectedSumHandler : public XML::Parser::ElementHandler { + public: + ExpectedSumHandler() : m_value(0) {} + + virtual void Start(const XML::Parser::Attributes &) {} + virtual void Characters(const std::string &data) + { + m_value = atoi(data.c_str()); + } + virtual void End() {} + + int getSum() const + { + return m_value; + } + + protected: + int m_value; + }; + + class MathHandler : public XML::Parser::ElementHandler { + public: + MathHandler() : m_valueSet(false), m_value(0), m_powerFactor(1) {} + + virtual void Start(const XML::Parser::Attributes &attr) + { + const auto &it = attr.find("powerFactor"); + + if (it != attr.end()) + m_powerFactor = atoi(it->second.c_str()); + } + virtual void Characters(const std::string &data) + { + m_value = pow(atoi(data.c_str()), m_powerFactor); + m_valueSet = true; + } + virtual void End() {} + + virtual int compute(int prevVal) = 0; + + protected: + bool m_valueSet; + int m_value; + int m_powerFactor; + }; + class AddHandler : public MathHandler { + public: + virtual int compute(int prevVal) + { + if (!m_valueSet) + return prevVal; + + return prevVal + m_value; + } + }; + + class MultiplyHandler : public MathHandler { + public: + virtual int compute(int prevVal) + { + if (!m_valueSet) + return prevVal; + + return prevVal * m_value; + } + }; + + class DivHandler : public MathHandler { + public: + virtual int compute(int prevVal) + { + if (!m_valueSet) + return prevVal; + + if (m_value == 0) + return prevVal; + + return prevVal / m_value; + } + }; + + StructureTest(const char *filename) : m_parser(filename), m_sum(0), + m_expectedSum(0) + { + m_parser.RegisterErrorCb(StructureTest::Error); + m_parser.RegisterElementCb("Add", + [this]() -> XML::Parser::ElementHandlerPtr { + return std::make_shared<AddHandler>(); + }, + [this](const XML::Parser::ElementHandlerPtr & element) { + // add computation + if (element) { + MathHandler *mathElement = reinterpret_cast<MathHandler *>(element.get()); + m_sum = mathElement->compute(m_sum); + } + }); + + m_parser.RegisterElementCb("Multiply", + [this]() -> XML::Parser::ElementHandlerPtr { + return std::make_shared<MultiplyHandler>(); + }, + [this](const XML::Parser::ElementHandlerPtr & element) { + // multiply computation + if (element) { + MathHandler *mathElement = reinterpret_cast<MathHandler *>(element.get()); + m_sum = mathElement->compute(m_sum); + } + }); + + m_parser.RegisterElementCb("Div", + [this]() -> XML::Parser::ElementHandlerPtr { + return std::make_shared<DivHandler>(); + }, + [this](const XML::Parser::ElementHandlerPtr & element) { + // division computation + if (element) { + MathHandler *mathElement = reinterpret_cast<MathHandler *>(element.get()); + m_sum = mathElement->compute(m_sum); + } + }); + + m_parser.RegisterElementCb("ExpectedSum", + [this]() -> XML::Parser::ElementHandlerPtr { + return std::make_shared<ExpectedSumHandler>(); + }, + [this](const XML::Parser::ElementHandlerPtr & element) { + if (element) { + ExpectedSumHandler *sumElement = reinterpret_cast<ExpectedSumHandler *> + (element.get()); + m_expectedSum = sumElement->getSum(); + } + }); + } + + static void Error(const Parser::ErrorType /*errorType*/, + const std::string &log_msg) + { + BOOST_FAIL(log_msg); + } + + int Parse() + { + return m_parser.Parse(); + } + + int getSum() const + { + return m_sum; + } + + int getExpectedSum() const + { + return m_expectedSum; + } + private: - XML::Parser m_parser; - int m_sum; - int m_expectedSum; + XML::Parser m_parser; + int m_sum; + int m_expectedSum; }; BOOST_AUTO_TEST_CASE(XmlParserTest_XML2_structure) { - StructureTest parser(format_test_path(XML_2_structure).c_str()); - BOOST_REQUIRE(0 == parser.Parse()); - BOOST_REQUIRE_MESSAGE(parser.getSum() == parser.getExpectedSum(), - "got sum: " << parser.getSum() << " while expected: " << parser.getExpectedSum()); + StructureTest parser(format_test_path(XML_2_structure).c_str()); + BOOST_REQUIRE(0 == parser.Parse()); + BOOST_REQUIRE_MESSAGE(parser.getSum() == parser.getExpectedSum(), + "got sum: " << parser.getSum() << " while expected: " << + parser.getExpectedSum()); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML3_encrypted_correct_parse) { - XML::Parser parser(format_test_path(XML_3_encrypted).c_str()); - BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_3_encrypted).c_str())); - - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("Key", dummyStartCallback, NULL)); - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("Cert", NULL, dummyEndCallback)); - startCallbackFlag = false; - endCallbackFlag = false; - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); - BOOST_REQUIRE(startCallbackFlag == true); - BOOST_REQUIRE(endCallbackFlag == true); + XML::Parser parser(format_test_path(XML_3_encrypted).c_str()); + BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_3_encrypted).c_str())); + + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("Key", dummyStartCallback, NULL)); + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("Cert", NULL, dummyEndCallback)); + startCallbackFlag = false; + endCallbackFlag = false; + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); + BOOST_REQUIRE(startCallbackFlag == true); + BOOST_REQUIRE(endCallbackFlag == true); } BOOST_AUTO_TEST_CASE(XmlParserTest_XML4_device_key_correct_parse) { - XML::Parser parser(format_test_path(XML_4_device_key).c_str()); - BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_4_device_key).c_str())); - - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.RegisterElementCb("RSAPrivateKey", dummyStartCallback, NULL)); - startCallbackFlag = false; - BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); - BOOST_REQUIRE(startCallbackFlag == true); + XML::Parser parser(format_test_path(XML_4_device_key).c_str()); + BOOST_REQUIRE(0 == parser.Validate(format_test_path(XSD_4_device_key).c_str())); + + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == + parser.RegisterElementCb("RSAPrivateKey", dummyStartCallback, NULL)); + startCallbackFlag = false; + BOOST_REQUIRE(Parser::ErrorCode::PARSE_SUCCESS == parser.Parse()); + BOOST_REQUIRE(startCallbackFlag == true); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tools/ckm_db_tool/ckm-logic-ext.cpp b/tools/ckm_db_tool/ckm-logic-ext.cpp index 020c5799..a82b5db6 100644 --- a/tools/ckm_db_tool/ckm-logic-ext.cpp +++ b/tools/ckm_db_tool/ckm-logic-ext.cpp @@ -24,32 +24,36 @@ namespace CKM { -DB::SqlConnection::Output CKMLogicExt::Execute(uid_t user, const std::string& cmd) { - if(user < 5000 && !m_systemDbUnlocked) { - if(CKM_API_SUCCESS != unlockSystemDB()) - ThrowErr(Exc::DatabaseLocked, "can not unlock system database"); - m_systemDbUnlocked = true; - } - - DB::SqlConnection::Output output; - - /* - * We need to access to DB::Crypto::m_connection to call Execute() on it. We don't want to mess - * with DB::Crypto too much so adding a friend and extending public interface was not an option. - * That's why we need a derived class DB::CryptoExt. m_userDataMap must be left unchanged after - * this operation but DB::Crypto can't be copied. According to C++ standard static casting - * DB::Crypto pointer to DB::CryptoExt pointer is UB. Therefore DB::Crypto is temporarily moved - * into DB::CryptoExt and moved back to m_userDataMap after the call to Execute(). - */ - DB::CryptoExt db(std::move(m_userDataMap[user].database)); - try { - output = db.Execute(cmd); - m_userDataMap[user].database = std::move(*static_cast<DB::Crypto*>(&db)); - return output; - } catch (const DB::SqlConnection::Exception::Base& e) { - m_userDataMap[user].database = std::move(*static_cast<DB::Crypto*>(&db)); - throw; - } +DB::SqlConnection::Output CKMLogicExt::Execute(uid_t user, + const std::string &cmd) +{ + if (user < 5000 && !m_systemDbUnlocked) { + if (CKM_API_SUCCESS != unlockSystemDB()) + ThrowErr(Exc::DatabaseLocked, "can not unlock system database"); + + m_systemDbUnlocked = true; + } + + DB::SqlConnection::Output output; + + /* + * We need to access to DB::Crypto::m_connection to call Execute() on it. We don't want to mess + * with DB::Crypto too much so adding a friend and extending public interface was not an option. + * That's why we need a derived class DB::CryptoExt. m_userDataMap must be left unchanged after + * this operation but DB::Crypto can't be copied. According to C++ standard static casting + * DB::Crypto pointer to DB::CryptoExt pointer is UB. Therefore DB::Crypto is temporarily moved + * into DB::CryptoExt and moved back to m_userDataMap after the call to Execute(). + */ + DB::CryptoExt db(std::move(m_userDataMap[user].database)); + + try { + output = db.Execute(cmd); + m_userDataMap[user].database = std::move(*static_cast<DB::Crypto *>(&db)); + return output; + } catch (const DB::SqlConnection::Exception::Base &e) { + m_userDataMap[user].database = std::move(*static_cast<DB::Crypto *>(&db)); + throw; + } } } // namespace CKM diff --git a/tools/ckm_db_tool/ckm-logic-ext.h b/tools/ckm_db_tool/ckm-logic-ext.h index 515c41cd..ca6916f9 100644 --- a/tools/ckm_db_tool/ckm-logic-ext.h +++ b/tools/ckm_db_tool/ckm-logic-ext.h @@ -27,11 +27,11 @@ namespace CKM { struct CKMLogicExt : public CKMLogic { - CKMLogicExt() : m_systemDbUnlocked(false) {} + CKMLogicExt() : m_systemDbUnlocked(false) {} - DB::SqlConnection::Output Execute(uid_t user, const std::string& cmd); + DB::SqlConnection::Output Execute(uid_t user, const std::string &cmd); private: - bool m_systemDbUnlocked; + bool m_systemDbUnlocked; }; } // namespace CKM diff --git a/tools/ckm_db_tool/ckm_db_tool.cpp b/tools/ckm_db_tool/ckm_db_tool.cpp index ae5087e1..672cd86d 100644 --- a/tools/ckm_db_tool/ckm_db_tool.cpp +++ b/tools/ckm_db_tool/ckm_db_tool.cpp @@ -37,205 +37,225 @@ using namespace CKM; namespace { const size_t MAX_LEN = 32; const char ELLIPSIS[] = "..."; -const size_t ELLIPSIS_LEN = sizeof(ELLIPSIS)/sizeof(ELLIPSIS[0]); - -const char* const SQL_TABLES = "SELECT name FROM sqlcipher_master " - "WHERE type IN ('table','view') AND name NOT LIKE 'sqlcipher_%' " - "UNION ALL " - "SELECT name FROM sqlcipher_temp_master " - "WHERE type IN ('table','view') " - "ORDER BY 1"; - -const char* const SQL_SCHEMA = "SELECT sql FROM " - "(SELECT * FROM sqlcipher_master " - "UNION ALL " - "SELECT * FROM sqlcipher_temp_master) " - "WHERE type!='meta' AND sql!='NULL'" - "ORDER BY tbl_name, type DESC, name"; +const size_t ELLIPSIS_LEN = sizeof(ELLIPSIS) / sizeof(ELLIPSIS[0]); + +const char *const SQL_TABLES = "SELECT name FROM sqlcipher_master " + "WHERE type IN ('table','view') AND name NOT LIKE 'sqlcipher_%' " + "UNION ALL " + "SELECT name FROM sqlcipher_temp_master " + "WHERE type IN ('table','view') " + "ORDER BY 1"; + +const char *const SQL_SCHEMA = "SELECT sql FROM " + "(SELECT * FROM sqlcipher_master " + "UNION ALL " + "SELECT * FROM sqlcipher_temp_master) " + "WHERE type!='meta' AND sql!='NULL'" + "ORDER BY tbl_name, type DESC, name"; } // namespace anonymous class DbWrapper { public: - DbWrapper(uid_t uid, Password pw) : m_uid(uid), m_pw(pw) {} + DbWrapper(uid_t uid, Password pw) : m_uid(uid), m_pw(pw) {} - int unlock(); - void lock(); - void process(const string& cmd); + int unlock(); + void lock(); + void process(const string &cmd); private: - void displayRow(const DB::SqlConnection::Output::Row& row, bool trim); + void displayRow(const DB::SqlConnection::Output::Row &row, bool trim); - uid_t m_uid; - Password m_pw; - CKMLogicExt m_logic; + uid_t m_uid; + Password m_pw; + CKMLogicExt m_logic; }; int DbWrapper::unlock() { - // no unlock for system db - if (m_uid < 5000) - return CKM_API_SUCCESS; - - int retCode; - RawBuffer ret = m_logic.unlockUserKey(m_uid, m_pw); - MessageBuffer buff; - buff.Push(ret); - buff.Deserialize(retCode); - return retCode; + // no unlock for system db + if (m_uid < 5000) + return CKM_API_SUCCESS; + + int retCode; + RawBuffer ret = m_logic.unlockUserKey(m_uid, m_pw); + MessageBuffer buff; + buff.Push(ret); + buff.Deserialize(retCode); + return retCode; } void DbWrapper::lock() { - // no lock for system db - if (m_uid < 5000) - return; + // no lock for system db + if (m_uid < 5000) + return; - m_logic.lockUserKey(m_uid); + m_logic.lockUserKey(m_uid); } -void DbWrapper::process(const string& acmd) +void DbWrapper::process(const string &acmd) { - try { - string cmd = acmd; - bool trim = true; - if (acmd == ".tables") { - cmd = SQL_TABLES; - trim = false; - } - else if(acmd == ".schema") { - cmd = SQL_SCHEMA; - trim = false; - } - - DB::SqlConnection::Output output = m_logic.Execute(m_uid, cmd); - - if(output.GetNames().empty()) - return; - - displayRow(output.GetNames(), trim); - cout << "--------------------------" << endl; - for(const auto& row : output.GetValues()) { - displayRow(row, trim); - } - } catch (const DB::SqlConnection::Exception::Base& e) { - cerr << e.GetMessage() << endl; - } catch (const Exc::Exception &e) { - cerr << e.message() << endl; - } catch (const std::exception &e) { - cerr << e.what() << endl; - } catch (...) { - cerr << "Unexpected exception occurred" << endl; - } + try { + string cmd = acmd; + bool trim = true; + + if (acmd == ".tables") { + cmd = SQL_TABLES; + trim = false; + } else if (acmd == ".schema") { + cmd = SQL_SCHEMA; + trim = false; + } + + DB::SqlConnection::Output output = m_logic.Execute(m_uid, cmd); + + if (output.GetNames().empty()) + return; + + displayRow(output.GetNames(), trim); + cout << "--------------------------" << endl; + + for (const auto &row : output.GetValues()) { + displayRow(row, trim); + } + } catch (const DB::SqlConnection::Exception::Base &e) { + cerr << e.GetMessage() << endl; + } catch (const Exc::Exception &e) { + cerr << e.message() << endl; + } catch (const std::exception &e) { + cerr << e.what() << endl; + } catch (...) { + cerr << "Unexpected exception occurred" << endl; + } } -void DbWrapper::displayRow(const DB::SqlConnection::Output::Row& row, bool trim) +void DbWrapper::displayRow(const DB::SqlConnection::Output::Row &row, bool trim) { - for(auto it = row.begin();it != row.end();it++) { - std::string col = *it; - if(trim && col.size() > MAX_LEN) { - col.resize(MAX_LEN); - col.replace(MAX_LEN-ELLIPSIS_LEN, ELLIPSIS_LEN, ELLIPSIS); - } - cout << col; - if(it+1 != row.end()) - cout<< "|"; - } - cout << endl; + for (auto it = row.begin(); it != row.end(); it++) { + std::string col = *it; + + if (trim && col.size() > MAX_LEN) { + col.resize(MAX_LEN); + col.replace(MAX_LEN - ELLIPSIS_LEN, ELLIPSIS_LEN, ELLIPSIS); + } + + cout << col; + + if (it + 1 != row.end()) + cout << "|"; + } + + cout << endl; } -void usage() { - cout << "ckm_db_tool - the command line tool for accessing key-manager encrypted databases." << endl; - cout << endl; - cout << "Usage: ckm_db_tool uid [password] [sql_command]" << endl; - cout << endl; - cout << "uid (mandatory) User id as in <TZ_SYS_DATA>/ckm/db-<uid>" << endl; - cout << "password (optional) Password used for database encryption. For system database (uid < 5000) no password should be used." << endl; - cout << "sql_command (optional) Sqlite3 command to execute on database. If empty the tool will enter interactive mode." << endl; - cout << endl; - cout << "Example:" << endl; - cout << "cmd_db_tool 5000 user-pass \"select * from names\"" << endl; +void usage() +{ + cout << "ckm_db_tool - the command line tool for accessing key-manager encrypted databases." + << endl; + cout << endl; + cout << "Usage: ckm_db_tool uid [password] [sql_command]" << endl; + cout << endl; + cout << "uid (mandatory) User id as in <TZ_SYS_DATA>/ckm/db-<uid>" << + endl; + cout << "password (optional) Password used for database encryption. For system database (uid < 5000) no password should be used." + << endl; + cout << "sql_command (optional) Sqlite3 command to execute on database. If empty the tool will enter interactive mode." + << endl; + cout << endl; + cout << "Example:" << endl; + cout << "cmd_db_tool 5000 user-pass \"select * from names\"" << endl; } -void internalHelp() { - cout << "[sqlite_command] executes sqlite command on database" << endl; - cout << ".tables shows a list of table names" << endl; - cout << ".schema shows Sqlite3 command used to create tables in the database" << endl; - cout << "help shows this help" << endl; - cout << "exit (Ctrl-D) quits the program" << endl; +void internalHelp() +{ + cout << "[sqlite_command] executes sqlite command on database" << endl; + cout << ".tables shows a list of table names" << endl; + cout << ".schema shows Sqlite3 command used to create tables in the database" + << endl; + cout << "help shows this help" << endl; + cout << "exit (Ctrl-D) quits the program" << endl; } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - try { - if (argc < 2 || !argv[1]) { - usage(); - return -1; - } - - // read uid - stringstream ss(argv[1]); - uid_t uid; - if (!(ss >> uid)) { - usage(); - return -1; - } - - int idx = 2; - - // read password - Password pass; - if (uid >= 5000) { - if (argc > idx) { - pass = argv[idx]; - idx++; - } - } - - // read sqlite3 command - string argcmd; - if (argc > idx) - argcmd = argv[idx]; - - // unlock db - DbWrapper dbw(uid, pass); - int retCode = dbw.unlock(); - if (retCode != CKM_API_SUCCESS ) { - cerr << "Unlocking database failed: " << retCode << endl; - return -1; - } - cout << "Database unlocked" << endl; - - while (true) { - string cmd; - if (argcmd.empty()) { - cout << "> "; - if(!getline(cin, cmd)) { - cout << "exit" << endl; - break; // EOF - } - } else { - cmd = argcmd; - } - - if(cmd == "exit") - break; - if(cmd == "help") { - internalHelp(); - continue; - } - - dbw.process(cmd); - - if(!argcmd.empty()) - break; - } - - dbw.lock(); - cout << "Database locked" << endl; - - return 0; - } catch (...) { - cerr << "Unexpected exception occurred" << endl; - return -1; - } + try { + if (argc < 2 || !argv[1]) { + usage(); + return -1; + } + + // read uid + stringstream ss(argv[1]); + uid_t uid; + + if (!(ss >> uid)) { + usage(); + return -1; + } + + int idx = 2; + + // read password + Password pass; + + if (uid >= 5000) { + if (argc > idx) { + pass = argv[idx]; + idx++; + } + } + + // read sqlite3 command + string argcmd; + + if (argc > idx) + argcmd = argv[idx]; + + // unlock db + DbWrapper dbw(uid, pass); + int retCode = dbw.unlock(); + + if (retCode != CKM_API_SUCCESS) { + cerr << "Unlocking database failed: " << retCode << endl; + return -1; + } + + cout << "Database unlocked" << endl; + + while (true) { + string cmd; + + if (argcmd.empty()) { + cout << "> "; + + if (!getline(cin, cmd)) { + cout << "exit" << endl; + break; // EOF + } + } else { + cmd = argcmd; + } + + if (cmd == "exit") + break; + + if (cmd == "help") { + internalHelp(); + continue; + } + + dbw.process(cmd); + + if (!argcmd.empty()) + break; + } + + dbw.lock(); + cout << "Database locked" << endl; + + return 0; + } catch (...) { + cerr << "Unexpected exception occurred" << endl; + return -1; + } } diff --git a/tools/ckm_db_tool/db-crypto-ext.cpp b/tools/ckm_db_tool/db-crypto-ext.cpp index 92518aca..26671451 100644 --- a/tools/ckm_db_tool/db-crypto-ext.cpp +++ b/tools/ckm_db_tool/db-crypto-ext.cpp @@ -26,13 +26,17 @@ namespace CKM { namespace DB { -SqlConnection::Output CryptoExt::Execute(const std::string& cmd) { - SqlConnection::Output out; - if(!m_connection) { - ThrowMsg(SqlConnection::Exception::ConnectionBroken, "Not connected to database"); - } - m_connection->ExecCommand(&out, "%s", cmd.c_str()); - return out; +SqlConnection::Output CryptoExt::Execute(const std::string &cmd) +{ + SqlConnection::Output out; + + if (!m_connection) { + ThrowMsg(SqlConnection::Exception::ConnectionBroken, + "Not connected to database"); + } + + m_connection->ExecCommand(&out, "%s", cmd.c_str()); + return out; } } // namespace DB } // namespace CKM diff --git a/tools/ckm_db_tool/db-crypto-ext.h b/tools/ckm_db_tool/db-crypto-ext.h index c4baeafa..5991af18 100644 --- a/tools/ckm_db_tool/db-crypto-ext.h +++ b/tools/ckm_db_tool/db-crypto-ext.h @@ -30,9 +30,9 @@ namespace CKM { namespace DB { struct CryptoExt : public Crypto { - CryptoExt(Crypto orig) : Crypto(std::move(orig)) {} + CryptoExt(Crypto orig) : Crypto(std::move(orig)) {} - SqlConnection::Output Execute(const std::string& cmd); + SqlConnection::Output Execute(const std::string &cmd); }; } // namespace DB diff --git a/tools/ckm_so_loader.cpp b/tools/ckm_so_loader.cpp index 085c7367..7c3eadd8 100644 --- a/tools/ckm_so_loader.cpp +++ b/tools/ckm_so_loader.cpp @@ -34,94 +34,102 @@ using namespace std; enum { - CLEAR_CACHE = 1, - LAZY = 2 + CLEAR_CACHE = 1, + LAZY = 2 }; void clear_cache() { - sync(); - ofstream of("/proc/sys/vm/drop_caches"); - if (of.bad()) { - cerr << "Cache clearing failed with errno: " << errno << endl; - return; - } - of << "3"; + sync(); + ofstream of("/proc/sys/vm/drop_caches"); + + if (of.bad()) { + cerr << "Cache clearing failed with errno: " << errno << endl; + return; + } + + of << "3"; } -void test(int flags, const string& library, const string& symbol) +void test(int flags, const string &library, const string &symbol) { - bool lazy = (flags & LAZY); - if (flags & CLEAR_CACHE) - clear_cache(); - - chrono::time_point<chrono::high_resolution_clock> tp[4]; - - tp[0] = chrono::high_resolution_clock::now(); - void* handle = dlopen(library.c_str(), (lazy?RTLD_LAZY:RTLD_NOW)); - tp[1] = chrono::high_resolution_clock::now(); - if (!handle) { - cerr << "dlopen failed: " << dlerror() << endl; - exit(1); - } - - if (!symbol.empty()) - { - tp[2] = chrono::high_resolution_clock::now(); - void* sym = dlsym(handle, symbol.c_str()); - tp[3] = chrono::high_resolution_clock::now(); - if (!sym) { - cerr << "dlsym failed: " << dlerror() << endl; - exit(1); - } - } - dlclose(handle); - - cout << (tp[1] - tp[0]).count() << ";" << (tp[3] - tp[2]).count() << endl; + bool lazy = (flags & LAZY); + + if (flags & CLEAR_CACHE) + clear_cache(); + + chrono::time_point<chrono::high_resolution_clock> tp[4]; + + tp[0] = chrono::high_resolution_clock::now(); + void *handle = dlopen(library.c_str(), (lazy ? RTLD_LAZY : RTLD_NOW)); + tp[1] = chrono::high_resolution_clock::now(); + + if (!handle) { + cerr << "dlopen failed: " << dlerror() << endl; + exit(1); + } + + if (!symbol.empty()) { + tp[2] = chrono::high_resolution_clock::now(); + void *sym = dlsym(handle, symbol.c_str()); + tp[3] = chrono::high_resolution_clock::now(); + + if (!sym) { + cerr << "dlsym failed: " << dlerror() << endl; + exit(1); + } + } + + dlclose(handle); + + cout << (tp[1] - tp[0]).count() << ";" << (tp[3] - tp[2]).count() << endl; } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - if (argc < 5) { - cerr << "Usage: ckm_so_loader [flags] [repeats] [library] [symbol]" << endl; - cerr << " flags: 1-clear cache, 2-lazy binding" << endl; - cerr << "Example: ckm_so_loader 3 100 /usr/lib/libkey-manager-client.so ckmc_save_key" << endl; - return -1; - } - - try { - int flags = stoi(argv[1]); // let it throw - int repeats = stoi(argv[2]); // let it throw - string so_path(argv[3]); - string symbol(argv[4]); - - cout << "dlopen[us];dlsym[us]" << endl; - for (int cnt = 0 ; cnt < repeats; cnt++) { - /* - * It has to be a different process each time. Glibc somehow caches the library information - * and consecutive calls are faster - */ - pid_t pid = fork(); - if (pid < 0) { - cerr << "fork failed with errno: " << errno << endl; - return -1; - } else if (pid == 0) { - test(flags, so_path, symbol); - exit(0); - } else { - - int status; - pid_t ret = waitpid(pid, &status, 0); - if (ret != pid) { - cerr << "waitpid failed with errno: " << errno << endl; - exit(1); - } - } - } - - return 0; - } catch (...) { - cerr << "Unexpected exception occured" << endl; - return -1; - } + if (argc < 5) { + cerr << "Usage: ckm_so_loader [flags] [repeats] [library] [symbol]" << endl; + cerr << " flags: 1-clear cache, 2-lazy binding" << endl; + cerr << "Example: ckm_so_loader 3 100 /usr/lib/libkey-manager-client.so ckmc_save_key" + << endl; + return -1; + } + + try { + int flags = stoi(argv[1]); // let it throw + int repeats = stoi(argv[2]); // let it throw + string so_path(argv[3]); + string symbol(argv[4]); + + cout << "dlopen[us];dlsym[us]" << endl; + + for (int cnt = 0 ; cnt < repeats; cnt++) { + /* + * It has to be a different process each time. Glibc somehow caches the library information + * and consecutive calls are faster + */ + pid_t pid = fork(); + + if (pid < 0) { + cerr << "fork failed with errno: " << errno << endl; + return -1; + } else if (pid == 0) { + test(flags, so_path, symbol); + exit(0); + } else { + int status; + pid_t ret = waitpid(pid, &status, 0); + + if (ret != pid) { + cerr << "waitpid failed with errno: " << errno << endl; + exit(1); + } + } + } + + return 0; + } catch (...) { + cerr << "Unexpected exception occured" << endl; + return -1; + } } diff --git a/tools/ckm_tool.cpp b/tools/ckm_tool.cpp index ff9f6da9..fd4f5f53 100644 --- a/tools/ckm_tool.cpp +++ b/tools/ckm_tool.cpp @@ -31,56 +31,58 @@ using namespace std; bool parseLong(const char *buf_ptr, long int &val) { - char *temp; - errno = 0; - long int val_tmp = strtol(buf_ptr, &temp, 0); - if(errno) - return true; - val = val_tmp; - return false; + char *temp; + errno = 0; + long int val_tmp = strtol(buf_ptr, &temp, 0); + + if (errno) + return true; + + val = val_tmp; + return false; } -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { - if (argc < 3) { - cerr << "Usage: ckm_tool [option] [opt_arg]" << endl; - cerr << "option: " << endl; - cerr << "\t-d\tdelete user database, opt_arg specified the user UID" << endl; - cerr << "Example: ckm_tool -l 5000" << endl; - return -1; - } + if (argc < 3) { + cerr << "Usage: ckm_tool [option] [opt_arg]" << endl; + cerr << "option: " << endl; + cerr << "\t-d\tdelete user database, opt_arg specified the user UID" << endl; + cerr << "Example: ckm_tool -l 5000" << endl; + return -1; + } + + // simple input arg parser + for (int i = 1; i < argc - 1; i++) { + if (!strcmp(argv[i], "-d")) { + long int uid; + + if (parseLong(argv[i + 1], uid) || uid < 0) { + cerr << "parameter error: invalid UID provided to the -d option" << endl; + exit(-2); + } + + // lock the database + auto control = CKM::Control::create(); + int ec = control->lockUserKey(static_cast<uid_t>(uid)); - // simple input arg parser - for (int i=1; i<argc-1; i++) - { - if(!strcmp(argv[i], "-d")) - { - long int uid; - if(parseLong(argv[i+1], uid) || uid<0) { - cerr << "parameter error: invalid UID provided to the -d option" << endl; - exit(-2); - } + if (ec != CKM_API_SUCCESS) { + cerr << "Failed, lock DB error: " << ec << endl; + exit(ec); + } - // lock the database - auto control = CKM::Control::create(); - int ec = control->lockUserKey(static_cast<uid_t>(uid)); - if(ec != CKM_API_SUCCESS) { - cerr << "Failed, lock DB error: " << ec << endl; - exit(ec); - } + // remove the user content + ec = control->removeUserData(static_cast<uid_t>(uid)); - // remove the user content - ec = control->removeUserData(static_cast<uid_t>(uid)); - if(ec != CKM_API_SUCCESS) { - cerr << "Failed, remove user data error: " << ec << endl; - exit(ec); - } - } - else { - std::cout << "Not enough or invalid arguments, please try again.\n"; - exit(-1); - } - } + if (ec != CKM_API_SUCCESS) { + cerr << "Failed, remove user data error: " << ec << endl; + exit(ec); + } + } else { + std::cout << "Not enough or invalid arguments, please try again.\n"; + exit(-1); + } + } - return 0; + return 0; } |