Fix implementation of sw-backend. 76/52676/3
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 25 Nov 2015 13:20:37 +0000 (14:20 +0100)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Mon, 30 Nov 2015 15:00:14 +0000 (16:00 +0100)
sw-backend cound not depend from certificate-impl.h and key-impl.h.

Change-Id: I7826f0c94bf18d1ad92ac59820120b6ee45531eb

src/manager/crypto/sw-backend/internals.cpp
src/manager/crypto/sw-backend/internals.h
src/manager/crypto/sw-backend/store.cpp
src/manager/service/ckm-logic.cpp

index 861f623..15775ec 100644 (file)
@@ -990,33 +990,65 @@ int digestVerifyMessage(EVP_PKEY *pubKey,
     return CKM_API_ERROR_VERIFICATION_FAILED;
 }
 
-RawBuffer toBinaryData(DataType dataType, const RawBuffer &buffer)
+bool verifyBinaryData(DataType dataType, const RawBuffer &buffer)
 {
-    // verify the data integrity
-    if (dataType.isKey())
-    {
-        KeyShPtr output_key;
-        if(dataType.isSKey())
-            output_key = CKM::Key::createAES(buffer);
-        else
-            output_key = CKM::Key::create(buffer);
-        if(output_key.get() == NULL)
-            ThrowErr(Exc::Crypto::InputParam, "Provided data is not valid key data");
+    if (dataType.isSKey()) {
+        switch (buffer.size()) {
+            default:
+                LogError("AES key have wrong size.");
+                return false;
+            case 128:
+            case 192:
+            case 256:
+                LogDebug("AES key verified.");
+                return true;
+        }
+    }
+
+    if (dataType.isKeyPublic()) {
+        BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
 
-        return output_key->getDER();
+        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;
     }
-    else if (dataType.isCertificate() || dataType.isChainCert())
-    {
-        CertificateShPtr cert = CKM::Certificate::create(buffer, DataFormat::FORM_DER);
 
-        if(cert.get() == NULL)
-            ThrowErr(Exc::Crypto::InputParam, "Provided data is not valid certificate");
+    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;
+    }
 
-        return cert->getDER();
+    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;
     }
 
-    // TODO: add here BINARY_DATA verification, i.e: max size etc.
-    return buffer;
+    LogDebug("Importing binary data...");
+    return true;
 }
 
 } // namespace Internals
index eac23ee..b19dcfb 100644 (file)
@@ -20,8 +20,6 @@
  */
 #pragma once
 
-#include <key-impl.h>
-#include <certificate-impl.h>
 #include <ckm/ckm-type.h>
 #include <openssl/evp.h>
 #include <sw-backend/obj.h>
@@ -122,7 +120,7 @@ int digestVerifyMessage(EVP_PKEY *pubKey,
     const EVP_MD *md_algo,
     const int rsa_padding);
 
-RawBuffer toBinaryData(DataType dataType, const RawBuffer &buffer);
+bool verifyBinaryData(DataType dataType, const RawBuffer &buffer);
 
 } // namespace Internals
 } // namespace SW
index 29cf08a..2605f4d 100644 (file)
@@ -215,8 +215,7 @@ Token Store::generateSKey(const CryptoAlgorithm &algorithm, const Password &pass
 }
 
 Token Store::import(const Data &data, const Password &pass) {
-    RawBuffer converted = Internals::toBinaryData(data.type, data.data);
-    return Token(m_backendId, data.type, pack(converted, pass));
+    return Token(m_backendId, data.type, pack(data.data, pass));
 }
 
 Token Store::importEncrypted(const Data &data, const Password &pass, const DataEncryption &enc) {
@@ -233,8 +232,10 @@ Token Store::importEncrypted(const Data &data, const Password &pass, const DataE
     algorithmAESCBC.setParam(ParamName::ALGO_TYPE, AlgoType::AES_CBC);
     algorithmAESCBC.setParam(ParamName::ED_IV, enc.iv);
     RawBuffer rawData = aesKey.decrypt(algorithmAESCBC, data.data);
-    RawBuffer converted = Internals::toBinaryData(data.type, rawData);
-    return Token(m_backendId, data.type, pack(converted, pass));
+    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
index 2a6e9b1..2f2ee4b 100644 (file)
@@ -1098,31 +1098,46 @@ int CKMLogic::importInitialData(
     const Crypto::DataEncryption &enc,
     const Policy &policy)
 {
-    // Inital values are always imported with root credentials. Label is not important.
-    Credentials rootCred(0,"");
+    try {
+        // Inital values are always imported with root credentials. Label is not important.
+        Credentials rootCred(0,"");
 
-    auto &handler = selectDatabase(rootCred, OWNER_ID_SYSTEM);
+        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;
+        // 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());
+        Crypto::GStore& store =
+          m_decider.getStore(data.type, policy.extractable, !enc.encryptedKey.empty());
 
-    Token token;
-    if (enc.encryptedKey.empty())
-        token = store.import(data, m_accessControl.isCCMode() ? "" : policy.password);
-    else
-        token = store.importEncrypted(data, m_accessControl.isCCMode() ? "" : policy.password, enc);
+        Token token;
 
-    DB::Row row(std::move(token), name, OWNER_ID_SYSTEM, static_cast<int>(policy.extractable));
-    handler.crypto.encryptRow(row);
+        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);
+        }
 
-    handler.database.saveRow(row);
-    transaction.commit();
+        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;
 }