Adjust API change request review result
[platform/core/security/key-manager.git] / src / manager / client-capi / ckmc-type.cpp
index a549a96..c1db6c0 100644 (file)
@@ -14,7 +14,7 @@
  *  limitations under the License
  *
  *
- * @file        ckmc-type.h
+ * @file        ckmc-type.cpp
  * @author      Yuseok Jeon(yuseok.jeon@samsung.com)
  * @version     1.0
  * @brief       new and free methods for the struct of CAPI
 #include <ckmc/ckmc-type.h>
 #include <ckmc/ckmc-error.h>
 #include <ckmc-type-converter.h>
+#include <protocols.h>
 #include <openssl/x509v3.h>
 #include <openssl/pkcs12.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#include <fstream>
+#include <crypto-init.h>
 
-int _ckmc_load_cert_from_x509(X509 *xCert, ckmc_cert_s **cert);
+namespace {
+
+const size_t DEFAULT_IV_LEN = 16;
+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;
+    }
+
+    BIO *bcert = BIO_new(BIO_s_mem());
+
+    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;
+    }
+    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_label_shared_owner      = CKM::OWNER_ID_SYSTEM;
+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)
@@ -161,7 +197,7 @@ int ckmc_cert_new(unsigned char *raw_cert, size_t cert_size, ckmc_data_format_e
 KEY_MANAGER_CAPI
 int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert)
 {
-    OpenSSL_add_all_algorithms();
+    CKM::initOpenSslOnce();
 
     FILE *fp = fopen(file_path, "r");
     if(fp == NULL)
@@ -184,6 +220,43 @@ int ckmc_load_cert_from_file(const char *file_path, ckmc_cert_s **cert)
 }
 
 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);
+}
+
+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_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;
+    }
+
+    pkcs12 = static_cast<ckmc_pkcs12_s*>(malloc(sizeof(ckmc_pkcs12_s)));
+    if(pkcs12 == NULL) {
+        return CKMC_ERROR_OUT_OF_MEMORY;
+    }
+    // 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)
 {
     class Pkcs12Converter {
@@ -324,7 +397,7 @@ int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ck
 
     };
 
-    OpenSSL_add_all_algorithms();
+    CKM::initOpenSslOnce();
 
     int ret = CKMC_ERROR_NONE;
 
@@ -350,16 +423,42 @@ int ckmc_load_from_pkcs12_file(const char *file_path, const char *passphrase, ck
 }
 
 KEY_MANAGER_CAPI
-void ckmc_cert_free(ckmc_cert_s *cert)
+int ckmc_pkcs12_load(const char *file_path, const char *passphrase, ckmc_pkcs12_s **pkcs12_bundle)
 {
-    if(cert == NULL)
-        return;
+    int ec;
+    ckmc_key_s *private_key = 0;
+    ckmc_cert_s *cert = 0;
+    ckmc_cert_list_s *ca_cert_list = 0;
 
-    if(cert->raw_cert != NULL) {
-        memset(cert->raw_cert, 0, cert->cert_size);
-        free(cert->raw_cert);
+    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;
     }
-    free(cert);
+
+    return CKMC_ERROR_NONE;
+}
+
+KEY_MANAGER_CAPI
+void ckmc_pkcs12_free(ckmc_pkcs12_s *pkcs12)
+{
+    if(pkcs12 == NULL)
+        return;
+
+    ckmc_key_free(pkcs12->priv_key);
+    ckmc_cert_free(pkcs12->cert);
+    ckmc_cert_list_free(pkcs12->ca_chain);
+    free(pkcs12);
 }
 
 KEY_MANAGER_CAPI
@@ -472,24 +571,121 @@ void ckmc_cert_list_all_free(ckmc_cert_list_s *first)
     }
 }
 
-int _ckmc_load_cert_from_x509(X509 *xCert, ckmc_cert_s **cert)
+KEY_MANAGER_CAPI
+int ckmc_param_list_new(ckmc_param_list_h *pparams)
 {
-    if(xCert == NULL) {
-        return CKMC_ERROR_INVALID_FORMAT;
-    }
+    if (!pparams || *pparams)
+        return CKMC_ERROR_INVALID_PARAMETER;
 
-    BIO *bcert = BIO_new(BIO_s_mem());
+    *pparams = reinterpret_cast<ckmc_param_list_h>(new(std::nothrow)(CKM::CryptoAlgorithm));
+    if (!*pparams)
+        return CKMC_ERROR_OUT_OF_MEMORY;
+    return CKMC_ERROR_NONE;
+}
 
-    i2d_X509_bio(bcert, xCert);
+KEY_MANAGER_CAPI
+int ckmc_param_list_set_integer(ckmc_param_list_h params,
+                                ckmc_param_name_e name,
+                                uint64_t value)
+{
+    if (!params)
+        return CKMC_ERROR_INVALID_PARAMETER;
 
-    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;
-    }
-    output.resize(size);
+    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);
+}
 
-    return ckmc_cert_new(output.data(), output.size(), CKMC_FORM_DER, cert);
+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)
+{
+    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);
+}
+
+KEY_MANAGER_CAPI
+int ckmc_param_list_get_integer(ckmc_param_list_h params,
+                                ckmc_param_name_e name,
+                                uint64_t *pvalue)
+{
+    if (!params || !pvalue)
+        return CKMC_ERROR_INVALID_PARAMETER;
+
+    const CKM::CryptoAlgorithm* algo = reinterpret_cast<const CKM::CryptoAlgorithm*>(params);
+    if (!algo->getParam(static_cast<CKM::ParamName>(name), *pvalue))
+        return CKMC_ERROR_INVALID_PARAMETER;
+
+    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)
+{
+    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;
+
+    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;
+}
+
+KEY_MANAGER_CAPI
+int ckmc_generate_new_params(ckmc_algo_type_e type, ckmc_param_list_h *pparams)
+{
+    if (!pparams || *pparams)
+        return CKMC_ERROR_INVALID_PARAMETER;
+
+    ckmc_param_list_h params = NULL;
+    int ret = ckmc_param_list_new(&params);
+    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;
+}