Added DSA keys support. 42/28842/1
authorMaciej J. Karpiuk <m.karpiuk2@samsung.com>
Wed, 24 Sep 2014 08:27:04 +0000 (10:27 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 16 Oct 2014 13:44:30 +0000 (15:44 +0200)
Change-Id: I0c360eae90df1961e8de8a4e74f2a7c964494643

18 files changed:
src/include/ckm/ckm-manager.h
src/include/ckm/ckm-type.h
src/include/ckmc/ckmc-manager.h
src/include/ckmc/ckmc-type.h
src/manager/client-capi/ckmc-manager.cpp
src/manager/client-capi/ckmc-type.cpp
src/manager/client/client-manager-impl.cpp
src/manager/client/client-manager-impl.h
src/manager/common/certificate-impl.cpp
src/manager/common/key-impl.cpp
src/manager/common/pkcs12-impl.cpp
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/service/CryptoService.cpp
src/manager/service/CryptoService.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp

index 8e62afe..9a20ae4 100644 (file)
@@ -72,6 +72,13 @@ public:
         const Policy &policyPrivateKey = Policy(),
         const Policy &policyPublicKey = Policy()) = 0;
 
+    virtual 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()) = 0;
+
     virtual int createKeyPairECDSA(
         const ElipticCurve type,
         const Alias &privateKeyAlias,
index a5e038d..34956dc 100644 (file)
@@ -40,6 +40,8 @@ enum class KeyType : int {
     KEY_RSA_PRIVATE,
     KEY_ECDSA_PUBLIC,
     KEY_ECDSA_PRIVATE,
+    KEY_DSA_PUBLIC,
+    KEY_DSA_PRIVATE,
     KEY_AES
 };
 
index fd44619..df56bf6 100644 (file)
@@ -46,7 +46,7 @@ extern "C" {
  * @privlevel public
  * @privilege %http://tizen.org/privilege/keymanager
  *
- * @remarks Currently only four types of keys are supported for this API. These are RSA public/private key and ECDSA public/private key.
+ * @remarks Currently only six types of keys are supported for this API. These are RSA public/private key, DSA public/private key and ECDSA public/private key.
  * @remarks key_type in key may be set to #CKMC_KEY_NONE as an input. key_type is determined inside key manager during storing keys.
  * @remarks Some private key files are protected by a password. If raw_key in key read from those encrypted files is encrypted with a password, the password should be provided in the #ckmc_key_s structure.
  * @remarks If password in policy is provided, the key is additionally encrypted with the password in policy.
@@ -452,6 +452,7 @@ int ckmc_get_data_alias_list(ckmc_alias_list_s** ppalias_list);
  *
  * @pre User is already logged in and the user key is already loaded into memory in plain text form.
  *
+ * @see ckmc_create_key_pair_dsa()
  * @see ckmc_create_key_pair_ecdsa()
  * @see ckmc_create_signature()
  * @see ckmc_verify_signature()
@@ -459,6 +460,41 @@ int ckmc_get_data_alias_list(ckmc_alias_list_s** ppalias_list);
 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);
 
 /**
+ * @brief Creates DSA private/public key pair and stores them inside key manager based on each policy.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/keymanager
+ *
+ * @remarks If password in policy is provided, the key is additionally encrypted with the password in policy.
+ *
+ * @param[in] size                The size of key strength to be created \n
+ *                                @c 1024, @c 2048, @c 3072 and @c 4096 are supported.
+ * @param[in] private_key_alias   The name of private key to be stored
+ * @param[in] public_key_alias    The name of public key to be stored
+ * @param[in] policy_private_key  The policy about how to store a private key securely
+ * @param[in] policy_public_key   The policy about how to store a public key securely
+ *
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ *
+ * @retval #CKMC_ERROR_NONE               Successful
+ * @retval #CKMC_ERROR_INVALID_PARAMETER  Input parameter is invalid
+ * @retval #CKMC_ERROR_DB_LOCKED          A user key is not loaded in memory (a user is not logged in)
+ * @retval #CKMC_ERROR_DB_ALIAS_EXISTS    Alias already exists
+ * @retval #CKMC_ERROR_DB_ERROR           Failed due to other DB transaction unexpectedly
+ * @retval #CKMC_ERROR_PERMISSION_DENIED  Failed to access key manager
+ *
+ * @pre User is already logged in and the user key is already loaded into memory in plain text form.
+ *
+ * @see ckmc_create_key_pair_rsa()
+ * @see ckmc_create_key_pair_ecdsa()
+ * @see ckmc_create_signature()
+ * @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);
+
+/**
  * @brief Creates ECDSA private/public key pair and stores them inside key manager based on each policy.
  *
  * @since_tizen 2.3
@@ -486,6 +522,7 @@ int ckmc_create_key_pair_rsa(const size_t size, const char *private_key_alias, c
  * @pre User is already logged in and the user key is already loaded into memory in plain text form.
  *
  * @see ckmc_create_key_pair_rsa()
+ * @see ckmc_create_key_pair_dsa()
  * @see ckmc_create_signature()
  * @see ckmc_verify_signature()
  * @see #ckmc_ec_type_e
index a79b95e..c459b1f 100644 (file)
@@ -47,6 +47,9 @@ typedef enum __ckmc_key_type {
     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, MJK: kept for binary compatibility with ckm-type.h::KeyType::KEY_AES*/
 } ckmc_key_type_e;
 
 /**
index da8e607..a8f89fd 100644 (file)
@@ -402,7 +402,30 @@ int ckmc_create_key_pair_rsa(const size_t size,
     CKM::Policy ckmPrivateKeyPolicy(_tostring(policy_private_key.password), policy_private_key.extractable);
     CKM::Policy ckmPublicKeyPolicy(_tostring(policy_public_key.password), policy_public_key.extractable);
 
-    ret = mgr->createKeyPairRSA(size, ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy);
+    ret = mgr->createKeyPairRSA(static_cast<int>(size), ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy);
+    return to_ckmc_error(ret);
+}
+
+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)
+{
+    int ret;
+    CKM::ManagerShPtr mgr = CKM::Manager::create();
+
+    if(private_key_alias == NULL || public_key_alias == NULL) {
+        return CKMC_ERROR_INVALID_PARAMETER;
+    }
+
+    CKM::Alias ckmPrivakeKeyAlias(private_key_alias);
+    CKM::Alias ckmPublicKeyAlias(public_key_alias);
+    CKM::Policy ckmPrivateKeyPolicy(_tostring(policy_private_key.password), policy_private_key.extractable);
+    CKM::Policy ckmPublicKeyPolicy(_tostring(policy_public_key.password), policy_public_key.extractable);
+
+    ret = mgr->createKeyPairDSA(static_cast<int>(size), ckmPrivakeKeyAlias, ckmPublicKeyAlias, ckmPrivateKeyPolicy, ckmPublicKeyPolicy);
     return to_ckmc_error(ret);
 }
 
index 6c2d3d5..a549a96 100644 (file)
@@ -282,6 +282,9 @@ int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ck
             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;
index 6e82722..27a5705 100644 (file)
@@ -327,7 +327,9 @@ int ManagerImpl::getBinaryDataAliasVector(DBDataType dataType, AliasVector &alia
 }
 
 int ManagerImpl::getKeyAliasVector(AliasVector &aliasVector) {
-    return getBinaryDataAliasVector(DBDataType::KEY_RSA_PUBLIC, 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(DBDataType::DB_KEY_LAST, aliasVector);
 }
 
 int ManagerImpl::getCertificateAliasVector(AliasVector &aliasVector) {
@@ -339,46 +341,23 @@ int ManagerImpl::getDataAliasVector(AliasVector &aliasVector) {
 }
 
 int ManagerImpl::createKeyPairRSA(
-    const int size,              // size in bits [1024, 2048, 4096]
+    const int size,
     const Alias &privateKeyAlias,
     const Alias &publicKeyAlias,
     const Policy &policyPrivateKey,
     const Policy &policyPublicKey)
 {
-    m_counter++;
-    int my_counter = m_counter;
-    return try_catch([&] {
-
-        MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
-        Serialization::Serialize(send, my_counter);
-        Serialization::Serialize(send, static_cast<int>(size));
-        Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
-        Serialization::Serialize(send, PolicySerializable(policyPublicKey));
-        Serialization::Serialize(send, privateKeyAlias);
-        Serialization::Serialize(send, publicKeyAlias);
-
-        int retCode = sendToServer(
-            SERVICE_SOCKET_CKM_STORAGE,
-            send.Pop(),
-            recv);
-
-        if (CKM_API_SUCCESS != retCode) {
-            return retCode;
-        }
-
-        int command;
-        int counter;
-
-        Deserialization::Deserialize(recv, command);
-        Deserialization::Deserialize(recv, counter);
-        Deserialization::Deserialize(recv, retCode);
-        if (counter != my_counter) {
-            return CKM_API_ERROR_UNKNOWN;
-        }
+    return this->createKeyPair(CKM::KeyType::KEY_RSA_PUBLIC, size, privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
+}
 
-        return retCode;
-    });
+int ManagerImpl::createKeyPairDSA(
+    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);
 }
 
 int ManagerImpl::createKeyPairECDSA(
@@ -388,14 +367,49 @@ int ManagerImpl::createKeyPairECDSA(
     const Policy &policyPrivateKey,
     const Policy &policyPublicKey)
 {
+    return this->createKeyPair(CKM::KeyType::KEY_ECDSA_PUBLIC, static_cast<int>(type), privateKeyAlias, publicKeyAlias, policyPrivateKey, policyPublicKey);
+}
+
+int ManagerImpl::createKeyPair(
+    const KeyType key_type,
+    const int     additional_param,
+    const Alias  &privateKeyAlias,
+    const Alias  &publicKeyAlias,
+    const Policy &policyPrivateKey,
+    const Policy &policyPublicKey)
+{
+    // input type check
+    LogicCommand cmd_type;
+    switch(key_type)
+    {
+        case KeyType::KEY_RSA_PUBLIC:
+        case KeyType::KEY_RSA_PRIVATE:
+            cmd_type = LogicCommand::CREATE_KEY_PAIR_RSA;
+            break;
+
+        case KeyType::KEY_DSA_PUBLIC:
+        case KeyType::KEY_DSA_PRIVATE:
+            cmd_type = LogicCommand::CREATE_KEY_PAIR_DSA;
+            break;
+
+        case KeyType::KEY_ECDSA_PUBLIC:
+        case KeyType::KEY_ECDSA_PRIVATE:
+            cmd_type = LogicCommand::CREATE_KEY_PAIR_ECDSA;
+            break;
+
+        default:
+            return CKM_API_ERROR_INPUT_PARAM;
+    }
+
+    // proceed with sending request
     m_counter++;
     int my_counter = m_counter;
     return try_catch([&] {
 
         MessageBuffer send, recv;
-        Serialization::Serialize(send, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_ECDSA));
+        Serialization::Serialize(send, static_cast<int>(cmd_type));
         Serialization::Serialize(send, my_counter);
-        Serialization::Serialize(send, static_cast<unsigned int>(type));
+        Serialization::Serialize(send, static_cast<int>(additional_param));
         Serialization::Serialize(send, PolicySerializable(policyPrivateKey));
         Serialization::Serialize(send, PolicySerializable(policyPublicKey));
         Serialization::Serialize(send, privateKeyAlias);
@@ -416,7 +430,6 @@ int ManagerImpl::createKeyPairECDSA(
         Deserialization::Deserialize(recv, command);
         Deserialization::Deserialize(recv, counter);
         Deserialization::Deserialize(recv, retCode);
-
         if (counter != my_counter) {
             return CKM_API_ERROR_UNKNOWN;
         }
@@ -425,6 +438,7 @@ int ManagerImpl::createKeyPairECDSA(
     });
 }
 
+
 template <class T>
 int getCertChain(
     LogicCommand command,
index a54ec31..07b405d 100644 (file)
@@ -55,6 +55,13 @@ public:
         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,
@@ -112,6 +119,14 @@ protected:
         DBDataType 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 m_counter;
     static bool s_isInit;
 };
index 51af437..f4d7c24 100644 (file)
@@ -135,11 +135,18 @@ KeyImpl::EvpShPtr CertificateImpl::getEvpShPtr() const {
 
 KeyImpl CertificateImpl::getKeyImpl() const {
     KeyImpl::EvpShPtr evp(X509_get_pubkey(m_x509), EVP_PKEY_free);
-    if (EVP_PKEY_type(evp->type) == EVP_PKEY_RSA)
-        return KeyImpl(evp, KeyType::KEY_RSA_PUBLIC);
-    if (EVP_PKEY_type(evp->type) == EVP_PKEY_EC)
-        return KeyImpl(evp, KeyType::KEY_ECDSA_PUBLIC);
-    LogError("Unsupported key type in certificate.");
+    switch(EVP_PKEY_type(evp->type))
+    {
+        case EVP_PKEY_RSA:
+            return KeyImpl(evp, KeyType::KEY_RSA_PUBLIC);
+        case EVP_PKEY_DSA:
+            return KeyImpl(evp, KeyType::KEY_DSA_PUBLIC);
+        case EVP_PKEY_EC:
+            return KeyImpl(evp, KeyType::KEY_ECDSA_PUBLIC);
+        default:
+            LogError("Unsupported key type in certificate.");
+            break;
+    }
     return KeyImpl();
 }
 
index 79d248b..a0349ef 100644 (file)
@@ -147,32 +147,59 @@ KeyImpl::KeyImpl(const RawBuffer &buf, const Password &password)
 
     m_pkey.reset(pkey, EVP_PKEY_free);
 
-    int type = EVP_PKEY_type(pkey->type);
-
-    if (type == EVP_PKEY_RSA) {
-        m_type = isPrivate ? KeyType::KEY_RSA_PRIVATE : KeyType::KEY_RSA_PUBLIC;
-    }
-
-    if (type == EVP_PKEY_EC) {
-        m_type = isPrivate ? KeyType::KEY_ECDSA_PRIVATE : KeyType::KEY_ECDSA_PUBLIC;
+    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: " << (int)m_type << " isPrivate: " << isPrivate);
 }
 
-KeyImpl::KeyImpl(EvpShPtr pkey, KeyType type)
-  : m_pkey(pkey)
-  , m_type(type)
+KeyImpl::KeyImpl(EvpShPtr pkey, KeyType type) : m_pkey(pkey), m_type(type)
 {
-    if (type == KeyType::KEY_RSA_PRIVATE || type == KeyType::KEY_RSA_PUBLIC)
-        if (EVP_PKEY_RSA != EVP_PKEY_type(pkey->type)) {
-            m_pkey.reset();
-            m_type = KeyType::KEY_NONE;
-        }
-    if (type == KeyType::KEY_ECDSA_PRIVATE || type == KeyType::KEY_ECDSA_PUBLIC)
-        if (EVP_PKEY_EC != EVP_PKEY_type(pkey->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 {
@@ -196,10 +223,20 @@ RawBuffer KeyImpl::getDERPUB() const {
 }
 
 RawBuffer KeyImpl::getDER() const {
-    if (m_type == KeyType::KEY_ECDSA_PRIVATE || m_type == KeyType::KEY_RSA_PRIVATE) {
-        return getDERPRV();
-    } else if (m_type == KeyType::KEY_RSA_PUBLIC || m_type == KeyType::KEY_ECDSA_PUBLIC) {
-        return getDERPUB();
+    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();
 }
index 394b649..94ffa3f 100644 (file)
@@ -72,13 +72,24 @@ PKCS12Impl::PKCS12Impl(const RawBuffer &buffer, const Password &password)
 
     if (pkey) {
         KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free);
-        if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) {
-            m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_RSA_PRIVATE);
-        } else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_EC) {
-            m_pkey = std::make_shared<KeyImpl>(ptr, KeyType::KEY_ECDSA_PRIVATE);
-        } else {
-            LogError("Unsupported private key type.");
-            EVP_PKEY_free(pkey);
+        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;
         }
     }
 
index ed94794..c3c5492 100644 (file)
@@ -37,6 +37,8 @@ DBDataType toDBDataType(KeyType key) {
     switch(key) {
     case KeyType::KEY_RSA_PUBLIC:  return DBDataType::KEY_RSA_PUBLIC;
     case KeyType::KEY_RSA_PRIVATE: return DBDataType::KEY_RSA_PRIVATE;
+    case KeyType::KEY_DSA_PUBLIC:  return DBDataType::KEY_DSA_PUBLIC;
+    case KeyType::KEY_DSA_PRIVATE: return DBDataType::KEY_DSA_PRIVATE;
     case KeyType::KEY_ECDSA_PUBLIC: return DBDataType::KEY_ECDSA_PUBLIC;
     case KeyType::KEY_ECDSA_PRIVATE: return DBDataType::KEY_ECDSA_PRIVATE;
     case KeyType::KEY_AES: return DBDataType::KEY_AES;
@@ -50,6 +52,8 @@ KeyType toKeyType(DBDataType dbtype) {
     switch(dbtype) {
     case DBDataType::KEY_RSA_PUBLIC: return KeyType::KEY_RSA_PUBLIC;
     case DBDataType::KEY_RSA_PRIVATE: return KeyType::KEY_RSA_PRIVATE;
+    case DBDataType::KEY_DSA_PUBLIC: return KeyType::KEY_DSA_PUBLIC;
+    case DBDataType::KEY_DSA_PRIVATE: return KeyType::KEY_DSA_PRIVATE;
     case DBDataType::KEY_ECDSA_PRIVATE: return KeyType::KEY_ECDSA_PRIVATE;
     case DBDataType::KEY_ECDSA_PUBLIC: return KeyType::KEY_ECDSA_PUBLIC;
     case DBDataType::KEY_AES: return KeyType::KEY_AES;
index 5b267a4..a3cf3ad 100644 (file)
@@ -52,7 +52,9 @@ enum class LogicCommand : int {
     GET_CHAIN_CERT,
     GET_CHAIN_ALIAS,
     CREATE_SIGNATURE,
-    VERIFY_SIGNATURE
+    VERIFY_SIGNATURE,
+    CREATE_KEY_PAIR_DSA
+    // for backward compatibility append new on the end
 };
 
 // Do not use DB_KEY_FIRST and DB_KEY_LAST in the code.
@@ -63,10 +65,12 @@ enum class DBDataType : int {
     KEY_RSA_PRIVATE,
     KEY_ECDSA_PUBLIC,
     KEY_ECDSA_PRIVATE,
+    KEY_DSA_PUBLIC,
+    KEY_DSA_PRIVATE,
     KEY_AES,
     DB_KEY_LAST = KEY_AES,
     CERTIFICATE,
-    BINARY_DATA
+    BINARY_DATA,
 };
 
 DBDataType toDBDataType(KeyType key);
index b705a93..431296b 100644 (file)
@@ -157,6 +157,116 @@ int CryptoService::createKeyPairRSA(const int size, // size in bits [1024, 2048,
        return CKM_CRYPTO_CREATEKEY_SUCCESS;
 }
 
+
+int CryptoService::createKeyPairDSA(const int size, // size in bits [1024, 2048, 3072, 4096]
+               KeyImpl &createdPrivateKey,  // returned value
+               KeyImpl &createdPublicKey)  // returned value
+{
+       EVP_PKEY_CTX *pctx = NULL;
+       EVP_PKEY_CTX *kctx = NULL;
+       EVP_PKEY *pkey = NULL;
+       EVP_PKEY *pparam = NULL;
+
+       // check the parameters of functions
+       if(size != 1024 && size !=2048 && size !=3072 && size != 4096) {
+               LogError("Error in DSA input size");
+               ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in DSA input size");
+       }
+
+       // check the parameters of functions
+       if(&createdPrivateKey == NULL) {
+               LogError("Error in createdPrivateKey value");
+               ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPrivateKey value");
+       }
+
+       // check the parameters of functions
+       if(&createdPublicKey == NULL) {
+               LogError("Error in createdPrivateKey value");
+               ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in createdPublicKey value");
+       }
+
+       Try {
+               /* Create the context for generating the parameters */
+               if(!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL))) {
+                       LogError("Error in EVP_PKEY_CTX_new_id function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new_id function");
+               }
+
+               if(EVP_SUCCESS != EVP_PKEY_paramgen_init(pctx)) {
+                       LogError("Error in EVP_PKEY_paramgen_init function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen_init function");
+               }
+
+               if(EVP_SUCCESS != EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, size)) {
+                       LogError("Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_set_dsa_paramgen_bits(" << size << ") function");
+               }
+
+               /* Generate parameters */
+               if(EVP_SUCCESS != EVP_PKEY_paramgen(pctx, &pparam)) {
+                       LogError("Error in EVP_PKEY_paramgen function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_paramgen function");
+               }
+
+               // Start to generate key
+               if(!(kctx = EVP_PKEY_CTX_new(pparam, NULL))) {
+                       LogError("Error in EVP_PKEY_CTX_new function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_CTX_new function");
+               }
+
+               if(EVP_SUCCESS != EVP_PKEY_keygen_init(kctx)) {
+                       LogError("Error in EVP_PKEY_keygen_init function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen_init function");
+               }
+
+               /* Generate the key */
+               if(EVP_SUCCESS != EVP_PKEY_keygen(kctx, &pkey)) {
+                       LogError("Error in EVP_PKEY_keygen function");
+                       ThrowMsg(CryptoService::Exception::opensslError, "Error in EVP_PKEY_keygen function");
+               }
+       }
+       Catch(CryptoService::Exception::opensslError)
+       {
+               if(pkey) {
+                       EVP_PKEY_free(pkey);
+               }
+
+               if(pparam) {
+                       EVP_PKEY_free(pparam);
+               }
+
+               if(pctx) {
+                       EVP_PKEY_CTX_free(pctx);
+               }
+
+               if(kctx) {
+                       EVP_PKEY_CTX_free(kctx);
+               }
+
+               ReThrowMsg(CryptoService::Exception::opensslError,"Error in openssl function !!");
+       }
+
+       KeyImpl::EvpShPtr ptr(pkey, EVP_PKEY_free); // shared ptr will free pkey
+
+       createdPrivateKey = KeyImpl(ptr, KeyType::KEY_DSA_PRIVATE);
+       createdPublicKey = KeyImpl(ptr, KeyType::KEY_DSA_PUBLIC);
+
+       if(pparam) {
+               EVP_PKEY_free(pparam);
+       }
+
+       if(pctx) {
+               EVP_PKEY_CTX_free(pctx);
+       }
+
+       if(kctx) {
+               EVP_PKEY_CTX_free(kctx);
+       }
+
+       return CKM_CRYPTO_CREATEKEY_SUCCESS;
+}
+
+
 int CryptoService::createKeyPairECDSA(ElipticCurve type,
                KeyImpl &createdPrivateKey,  // returned value
                KeyImpl &createdPublicKey)  // returned value
@@ -314,7 +424,10 @@ int CryptoService::createSignature(const KeyImpl &privateKey,
                ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in hashAlgorithm value");
        }
 
-       if((privateKey.getType() != KeyType::KEY_RSA_PRIVATE) && (privateKey.getType() != KeyType::KEY_ECDSA_PRIVATE)) {
+       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");
                ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type");
        }
@@ -447,7 +560,10 @@ int CryptoService::verifySignature(const KeyImpl &publicKey,
                ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in hashAlgorithm value");
        }
 
-       if((publicKey.getType() != KeyType::KEY_RSA_PUBLIC) && (publicKey.getType() != KeyType::KEY_ECDSA_PUBLIC)) {
+       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");
                ThrowMsg(CryptoService::Exception::Crypto_internal, "Error in private key type");
        }
index 44eff2f..039527a 100644 (file)
@@ -20,8 +20,8 @@
 #define DEV_HW_RANDOM_FILE     "/dev/hwrng"
 #define DEV_URANDOM_FILE       "/dev/urandom"
 
-#define EVP_SUCCESS    1       // DO NOTCHANGE THIS VALUE
-#define EVP_FAIL       0       // DO NOTCHANGE THIS VALUE
+#define EVP_SUCCESS 1  // DO NOTCHANGE THIS VALUE
+#define EVP_FAIL    0  // DO NOTCHANGE THIS VALUE
 
 #define CKM_CRYPTO_INIT_SUCCESS 1
 #define CKM_CRYPTO_CREATEKEY_SUCCESS 2
@@ -35,53 +35,57 @@ namespace CKM {
  // typedef std::vector<unsigned char> RawData; this must be defined in common header.
  // This is internal api so all functions should throw exception on errors.
 class CryptoService {
- public:
-     CryptoService();
-     virtual ~CryptoService();
-
-     class Exception {
-       public:
-            DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
-                DECLARE_EXCEPTION_TYPE(Base, Crypto_internal);
-            DECLARE_EXCEPTION_TYPE(Base, opensslError);
-     };
-
-     // During initialization, FIPS_MODE and the antropy source are set.
-     // And system certificates are loaded in the memory during initialization.
-     //    FIPS_MODE - ON, OFF(Default)
-     //    antropy source - /dev/random,/dev/urandom(Default)
-     static int initialize();
-
-     static int createKeyPairRSA(const int size,      // size in bits [1024, 2048, 4096]
-                         KeyImpl &createdPrivateKey,  // returned value ==> Key &createdPrivateKey,
-                         KeyImpl &createdPublicKey);  // returned value ==> Key &createdPublicKey
-
-     static int createKeyPairECDSA(ElipticCurve type1,
-                                        KeyImpl &createdPrivateKey,  // returned value
-                                        KeyImpl &createdPublicKey);  // returned value
-
-     int createSignature(const KeyImpl &privateKey,
-                         const RawBuffer &message,
-                         const HashAlgorithm hashAlgo,
-                         const RSAPaddingAlgorithm padAlgo,
-                         RawBuffer &signature);
-
-     int verifySignature(const KeyImpl &publicKey,
-                         const RawBuffer &message,
-                         const RawBuffer &signature,
-                         const HashAlgorithm hashAlgo,
-                         const RSAPaddingAlgorithm padAlgo);
-
-     int verifyCertificateChain(const CertificateImpl &certificate,
-                           const CertificateImplVector &untrustedCertificates,
-                           const CertificateImplVector &userTrustedCertificates,
-                           CertificateImplVector &certificateChainVector);
-
- private:
-     std::vector<X509 *> verifyCertChain(X509 *cert,
-                    std::vector<X509 *> &trustedCerts,
-                    std::vector<X509 *> &userTrustedCerts,
-                    std::vector<X509 *> &untrustedchain);
+public:
+    CryptoService();
+    virtual ~CryptoService();
+
+    class Exception {
+        public:
+            DECLARE_EXCEPTION_TYPE(CKM::Exception, Base)
+            DECLARE_EXCEPTION_TYPE(Base, Crypto_internal);
+            DECLARE_EXCEPTION_TYPE(Base, opensslError);
+    };
+
+    // During initialization, FIPS_MODE and the antropy source are set.
+    // And system certificates are loaded in the memory during initialization.
+    //    FIPS_MODE - ON, OFF(Default)
+    //    antropy source - /dev/random,/dev/urandom(Default)
+    static int initialize();
+
+    static int createKeyPairRSA(const int size,      // size in bits [1024, 2048, 4096]
+                        KeyImpl &createdPrivateKey,  // returned value ==> Key &createdPrivateKey,
+                        KeyImpl &createdPublicKey);  // returned value ==> Key &createdPublicKey
+
+    static int createKeyPairDSA(const int size,      // size in bits [1024, 2048, 3072, 4096]
+                        KeyImpl &createdPrivateKey,  // returned value ==> Key &createdPrivateKey,
+                        KeyImpl &createdPublicKey);  // returned value ==> Key &createdPublicKey
+
+    static int createKeyPairECDSA(ElipticCurve type1,
+                        KeyImpl &createdPrivateKey,  // returned value
+                        KeyImpl &createdPublicKey);  // returned value
+
+    int createSignature(const KeyImpl &privateKey,
+                        const RawBuffer &message,
+                        const HashAlgorithm hashAlgo,
+                        const RSAPaddingAlgorithm padAlgo,
+                        RawBuffer &signature);
+
+    int verifySignature(const KeyImpl &publicKey,
+                        const RawBuffer &message,
+                        const RawBuffer &signature,
+                        const HashAlgorithm hashAlgo,
+                        const RSAPaddingAlgorithm padAlgo);
+
+    int verifyCertificateChain(const CertificateImpl &certificate,
+                               const CertificateImplVector &untrustedCertificates,
+                               const CertificateImplVector &userTrustedCertificates,
+                               CertificateImplVector &certificateChainVector);
+
+private:
+    std::vector<X509 *> verifyCertChain(X509 *cert,
+                                        std::vector<X509 *> &trustedCerts,
+                                        std::vector<X509 *> &userTrustedCerts,
+                                        std::vector<X509 *> &untrustedchain);
 
     bool hasValidCAFlag(std::vector<X509 *> &certChain);
 };
index 331536c..649440f 100644 (file)
@@ -448,9 +448,11 @@ RawBuffer CKMLogic::getDataList(
     return response.Pop();
 }
 
-int CKMLogic::createKeyPairRSAHelper(
+
+int CKMLogic::createKeyPairHelper(
     Credentials &cred,
-    int size,
+    const KeyType key_type,
+    const int additional_param,
     const Alias &aliasPrivate,
     const Alias &aliasPublic,
     const PolicySerializable &policyPrivate,
@@ -462,9 +464,28 @@ int CKMLogic::createKeyPairRSAHelper(
     auto &handler = m_userDataMap[cred.uid];
     KeyImpl prv, pub;
     int retCode;
+    switch(key_type)
+    {
+        case KeyType::KEY_RSA_PUBLIC:
+        case KeyType::KEY_RSA_PRIVATE:
+            retCode = CryptoService::createKeyPairRSA(additional_param, prv, pub);
+            break;
+
+        case KeyType::KEY_DSA_PUBLIC:
+        case KeyType::KEY_DSA_PRIVATE:
+            retCode = CryptoService::createKeyPairDSA(additional_param, prv, pub);
+            break;
+
+        case KeyType::KEY_ECDSA_PUBLIC:
+        case KeyType::KEY_ECDSA_PRIVATE:
+            retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(additional_param), prv, pub);
+            break;
+
+        default:
+            return CKM_API_ERROR_INPUT_PARAM;
+    }
 
-    if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
-        (retCode = CryptoService::createKeyPairRSA(size, prv, pub)))
+    if (CKM_CRYPTO_CREATEKEY_SUCCESS != retCode)
     {
         LogDebug("CryptoService error with code: " << retCode);
         return CKM_API_ERROR_SERVER_ERROR; // TODO error code
@@ -494,10 +515,11 @@ int CKMLogic::createKeyPairRSAHelper(
     return retCode;
 }
 
-RawBuffer CKMLogic::createKeyPairRSA(
+RawBuffer CKMLogic::createKeyPair(
     Credentials &cred,
+    LogicCommand protocol_cmd,
     int commandId,
-    int size,
+    const int additional_param,
     const Alias &aliasPrivate,
     const Alias &aliasPublic,
     const PolicySerializable &policyPrivate,
@@ -505,10 +527,27 @@ RawBuffer CKMLogic::createKeyPairRSA(
 {
     int retCode = CKM_API_SUCCESS;
 
+    KeyType key_type = KeyType::KEY_NONE;
+    switch(protocol_cmd)
+    {
+        case LogicCommand::CREATE_KEY_PAIR_RSA:
+            key_type = KeyType::KEY_RSA_PUBLIC;
+            break;
+        case LogicCommand::CREATE_KEY_PAIR_DSA:
+            key_type = KeyType::KEY_DSA_PUBLIC;
+            break;
+        case LogicCommand::CREATE_KEY_PAIR_ECDSA:
+            key_type = KeyType::KEY_ECDSA_PUBLIC;
+            break;
+        default:
+            break;
+    }
+
     try {
-        retCode = createKeyPairRSAHelper(
+        retCode = createKeyPairHelper(
                         cred,
-                        size,
+                        key_type,
+                        additional_param,
                         aliasPrivate,
                         aliasPublic,
                         policyPrivate,
@@ -529,95 +568,7 @@ RawBuffer CKMLogic::createKeyPairRSA(
     }
 
     MessageBuffer response;
-    Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
-    Serialization::Serialize(response, commandId);
-    Serialization::Serialize(response, retCode);
-
-    return response.Pop();
-}
-
-int CKMLogic::createKeyPairECDSAHelper(
-    Credentials &cred,
-    int type,
-    const Alias &aliasPrivate,
-    const Alias &aliasPublic,
-    const PolicySerializable &policyPrivate,
-    const PolicySerializable &policyPublic)
-{
-    if (0 >= m_userDataMap.count(cred.uid))
-        return CKM_API_ERROR_DB_LOCKED;
-
-    auto &handler = m_userDataMap[cred.uid];
-    KeyImpl prv, pub;
-    int retCode;
-
-    if (CKM_CRYPTO_CREATEKEY_SUCCESS !=
-        (retCode = CryptoService::createKeyPairECDSA(static_cast<ElipticCurve>(type), prv, pub)))
-    {
-        LogError("CryptoService failed with code: " << retCode);
-        return CKM_API_ERROR_SERVER_ERROR; // TODO error code
-    }
-
-    DBCrypto::Transaction transaction(&handler.database);
-
-    retCode = saveDataHelper(cred,
-                            toDBDataType(prv.getType()),
-                            aliasPrivate,
-                            prv.getDER(),
-                            policyPrivate);
-
-    if (CKM_API_SUCCESS != retCode)
-        return retCode;
-
-    retCode = saveDataHelper(cred,
-                            toDBDataType(pub.getType()),
-                            aliasPublic,
-                            pub.getDER(),
-                            policyPublic);
-
-    if (CKM_API_SUCCESS != retCode)
-        return retCode;
-
-    transaction.commit();
-
-    return retCode;
-}
-
-RawBuffer CKMLogic::createKeyPairECDSA(
-    Credentials &cred,
-    int commandId,
-    int type,
-    const Alias &aliasPrivate,
-    const Alias &aliasPublic,
-    const PolicySerializable &policyPrivate,
-    const PolicySerializable &policyPublic)
-{
-    int retCode = CKM_API_SUCCESS;
-
-    try {
-        retCode = createKeyPairECDSAHelper(
-                        cred,
-                        type,
-                        aliasPrivate,
-                        aliasPublic,
-                        policyPrivate,
-                        policyPublic);
-    } catch (const DBCrypto::Exception::AliasExists &e) {
-        LogDebug("DBCrypto error: alias exists: " << e.GetMessage());
-        retCode = CKM_API_ERROR_DB_ALIAS_EXISTS;
-    } catch (const DBCrypto::Exception::TransactionError &e) {
-        LogDebug("DBCrypto error: transaction error: " << e.GetMessage());
-        retCode = CKM_API_ERROR_DB_ERROR;
-    } catch (const CKM::CryptoLogic::Exception::Base &e) {
-        LogDebug("CryptoLogic error: " << e.GetMessage());
-        retCode = CKM_API_ERROR_SERVER_ERROR;
-    } catch (const DBCrypto::Exception::InternalError &e) {
-        LogDebug("DBCrypto internal error: " << e.GetMessage());
-        retCode = CKM_API_ERROR_DB_ERROR;
-    }
-
-    MessageBuffer response;
-    Serialization::Serialize(response, static_cast<int>(LogicCommand::CREATE_KEY_PAIR_RSA));
+    Serialization::Serialize(response, static_cast<int>(protocol_cmd));
     Serialization::Serialize(response, commandId);
     Serialization::Serialize(response, retCode);
 
index 1a6971f..e089d16 100644 (file)
@@ -93,24 +93,16 @@ public:
         int commandId,
         DBDataType dataType);
 
-    RawBuffer createKeyPairRSA(
+    RawBuffer createKeyPair(
         Credentials &cred,
+        LogicCommand protocol_cmd,
         int commandId,
-        int size,
+        const int additional_param,
         const Alias &aliasPrivate,
         const Alias &alaisPublic,
         const PolicySerializable &policyPrivate,
         const PolicySerializable &policyPublic);
 
-    RawBuffer createKeyPairECDSA(
-        Credentials &cred,
-        int commandId,
-        int type,
-        const Alias &aliasPrivate,
-        const Alias &aliasPublic,
-        const PolicySerializable &policyPrivate,
-        const PolicySerializable &policyPublic);
-
     RawBuffer getCertificateChain(
         Credentials &cred,
         int commandId,
@@ -158,17 +150,10 @@ private:
         const Password &password,
         DBRow &row);
 
-    int createKeyPairRSAHelper(
-        Credentials &cred,
-        int size,
-        const Alias &aliasPrivate,
-        const Alias &aliasPublic,
-        const PolicySerializable &policyPrivate,
-        const PolicySerializable &policyPublic);
-
-    int createKeyPairECDSAHelper(
+    int createKeyPairHelper(
         Credentials &cred,
-        int type,
+        const KeyType key_type,
+        const int additional_param,
         const Alias &aliasPrivate,
         const Alias &aliasPublic,
         const PolicySerializable &policyPrivate,
index 764d3e9..b60d185 100644 (file)
@@ -215,42 +215,24 @@ RawBuffer CKMService::processStorage(Credentials &cred, MessageBuffer &buffer){
                 static_cast<DBDataType>(tmpDataType));
         }
         case LogicCommand::CREATE_KEY_PAIR_RSA:
-        {
-            int size;
-            Alias privateKeyAlias;
-            Alias publicKeyAlias;
-            PolicySerializable policyPrivateKey;
-            PolicySerializable policyPublicKey;
-            Deserialization::Deserialize(buffer, size);
-            Deserialization::Deserialize(buffer, policyPrivateKey);
-            Deserialization::Deserialize(buffer, policyPublicKey);
-            Deserialization::Deserialize(buffer, privateKeyAlias);
-            Deserialization::Deserialize(buffer, publicKeyAlias);
-            return m_logic->createKeyPairRSA(
-                cred,
-                commandId,
-                size,
-                privateKeyAlias,
-                publicKeyAlias,
-                policyPrivateKey,
-                policyPublicKey);
-        }
+        case LogicCommand::CREATE_KEY_PAIR_DSA:
         case LogicCommand::CREATE_KEY_PAIR_ECDSA:
         {
-            unsigned int type;
+            int additional_param;
             Alias privateKeyAlias;
             Alias publicKeyAlias;
             PolicySerializable policyPrivateKey;
             PolicySerializable policyPublicKey;
-            Deserialization::Deserialize(buffer, type);
+            Deserialization::Deserialize(buffer, additional_param);
             Deserialization::Deserialize(buffer, policyPrivateKey);
             Deserialization::Deserialize(buffer, policyPublicKey);
             Deserialization::Deserialize(buffer, privateKeyAlias);
             Deserialization::Deserialize(buffer, publicKeyAlias);
-            return m_logic->createKeyPairECDSA(
+            return m_logic->createKeyPair(
                 cred,
+                static_cast<LogicCommand>(command),
                 commandId,
-                type,
+                additional_param,
                 privateKeyAlias,
                 publicKeyAlias,
                 policyPrivateKey,