Refactoring pkcs12 import 69/49869/2
authorKyungwook Tak <k.tak@samsung.com>
Tue, 20 Oct 2015 06:17:39 +0000 (15:17 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Wed, 21 Oct 2015 05:31:41 +0000 (14:31 +0900)
 * Use same group name when pkcs12 imported to multiple db store at same time
 * Rollback db rows correctly in case of error
 * Don't write data to unique file to convert ossl type to pem
 * Downgrade useless nested loop
 * Reduce useless wrapper APIs in pkcs12.h

Change-Id: I5518abe04105bbc3b311014081bfe4085cf47284
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
vcore/server/src/cert-server-logic.c
vcore/vcore/api.cpp
vcore/vcore/pkcs12.cpp
vcore/vcore/pkcs12.h

index f356ac1..f6c08f1 100644 (file)
@@ -71,26 +71,26 @@ char *add_shared_owner_prefix(const char *name)
                return NULL;
        }
        memset(ckm_alias, 0, alias_len + 1);
-       strncat(ckm_alias, ckmc_owner_id_system, alias_len + 1);
-       strncat(ckm_alias, ckmc_owner_id_separator, alias_len + 1 - strlen(ckmc_owner_id_system));
-       strncat(ckm_alias, name, alias_len + 1 - strlen(ckmc_owner_id_system) + strlen(ckmc_owner_id_separator));
+       strcat(ckm_alias, ckmc_owner_id_system);
+       strcat(ckm_alias, ckmc_owner_id_separator);
+       strcat(ckm_alias, name);
 
        return ckm_alias;
 }
 
-int ckmc_remove_alias_with_shared_owner_prefix(const char *name, int *result)
+int ckmc_remove_alias_with_shared_owner_prefix(const char *name)
 {
        char *ckm_alias = add_shared_owner_prefix(name);
        if (!ckm_alias) {
                SLOGE("Failed to allocate memory");
-               return CERTSVC_BAD_ALLOC;
+               return CKMC_ERROR_OUT_OF_MEMORY;
        }
 
-       *result = ckmc_remove_alias(ckm_alias);
+       int result = ckmc_remove_alias(ckm_alias);
 
        free(ckm_alias);
 
-       return CERTSVC_SUCCESS;
+       return result;
 }
 
 char *get_complete_path(const char *str1, const char *str2)
@@ -303,6 +303,11 @@ int saveCertificateToStore(
        int result = ckmc_save_data(ckm_alias, cert_data, cert_policy);
        free(ckm_alias);
 
+       if (result == CKMC_ERROR_DB_ALIAS_EXISTS) {
+               SLOGI("same alias with gname[%s] alrady exist in ckm. Maybe other store type have it. skip.", pGname);
+               return CERTSVC_SUCCESS;
+       }
+
        if (result != CKMC_ERROR_NONE) {
                SLOGE("Failed to save trusted data. ckm errcode[%d]", result);
                return CERTSVC_FAIL;
@@ -409,7 +414,7 @@ int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t cert
        int records = 0;
        int count = 0;
        int counter = 0;
-       char *pValue = NULL;
+       char *gname = NULL;
        char *query = NULL;
        const char *text;
        sqlite3_stmt *stmt = NULL;
@@ -427,7 +432,7 @@ int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t cert
                goto error_and_exit;
        }
 
-       while (count < 4) {
+       for (count = 0; count < 4; count++) {
                /* get the ssl certificate from database */
                if (count == 0)
                        query = sqlite3_mprintf("select certificate from ssl where enabled=%d and is_root_app_enabled=%d", ENABLED, ENABLED);
@@ -437,71 +442,77 @@ int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t cert
                                                          ((count == 1)?"wifi":(count == 2)?"vpn":"email"), ENABLED, ENABLED, ENABLED);
 
                result = execute_select_query(db_handle, query, &stmt);
+
+               if (query) {
+                       sqlite3_free(query);
+                       query = NULL;
+               }
+
                if (result != CERTSVC_SUCCESS) {
                        SLOGE("Querying database failed.");
-                       goto next;
+                       goto error_and_exit;
                }
 
                /* update the ca-certificate.crt file */
                while (1) {
                        records = sqlite3_step(stmt);
-                       if (records != SQLITE_ROW || records == SQLITE_DONE) {
+                       if (records == SQLITE_DONE) {
                                result = CERTSVC_SUCCESS;
                                break;
                        }
 
-                       if (records == SQLITE_ROW) {
-                               certLength = 0;
-                               certBuffer = NULL;
-                               pValue = NULL;
-
-                               if (count == 0) {
-                                       /* gets the certificate from database for system store */
-                                       text = (const char *)sqlite3_column_text(stmt, 0);
-                                       if (text) {
-                                               certLength = strlen(text);
-                                               certBuffer = strndup(text, certLength);
-                                       }
-                               } else {
-                                       /* gets the certificate from key-manager for other stores */
-                                       text = (const char *)sqlite3_column_text(stmt, 0);
-                                       if (text)
-                                               pValue = strndup(text, strlen(text));
-
-                                       result = get_certificate_buffer_from_store(db_handle, storeType[count], pValue, &certBuffer, &certLength);
-                                       if (result != CERTSVC_SUCCESS) {
-                                               SLOGE("Failed to get certificate buffer from key-manager.");
-                                               goto error_and_exit;
-                                       }
-                               }
+                       if (records != SQLITE_ROW) {
+                               SLOGE("DB query error when select. result[%d].", records);
+                               result = CERTSVC_FAIL;
+                               goto error_and_exit;
+                       }
 
-                               if (certBuffer) {
-                                       if (counter++ == 0)
-                                               result = write_to_ca_cert_crt_file("wb", certBuffer, certLength);
-                                       else
-                                               result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
+                       certLength = 0;
+                       certBuffer = NULL;
+                       gname = NULL;
 
-                                       if (result != CERTSVC_SUCCESS) {
-                                               SLOGE("Failed to write to file.");
-                                               result = CERTSVC_FAIL;
-                                               goto error_and_exit;
-                                       }
+                       if (count == 0) {
+                               /* gets the certificate from database for system store */
+                               text = (const char *)sqlite3_column_text(stmt, 0);
+                               if (text) {
+                                       certLength = strlen(text);
+                                       certBuffer = strndup(text, certLength);
+                               }
+                       } else {
+                               /* gets the certificate from key-manager for other stores */
+                               text = (const char *)sqlite3_column_text(stmt, 0);
+                               if (text)
+                                       gname = strndup(text, strlen(text));
+
+                               result = get_certificate_buffer_from_store(db_handle, storeType[count], gname, &certBuffer, &certLength);
+                               if (result != CERTSVC_SUCCESS) {
+                                       SLOGE("Failed to get certificate buffer from key-manager.");
+                                       goto error_and_exit;
                                }
                        }
-               }
-next:
-               count++;
-               if (query) {
-                       sqlite3_free(query);
-                       query = NULL;
+
+                       if (certBuffer == NULL) {
+                               SLOGE("Failed to extract cert buffer to update ca-certificate.");
+                               result = CERTSVC_FAIL;
+                               goto error_and_exit;
+                       }
+
+                       if (counter++ == 0)
+                               result = write_to_ca_cert_crt_file("wb", certBuffer, certLength);
+                       else
+                               result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
+
+                       if (result != CERTSVC_SUCCESS) {
+                               SLOGE("Failed to write to file.");
+                               result = CERTSVC_FAIL;
+                               goto error_and_exit;
+                       }
                }
        }
+
        SLOGD("Successfully updated ca-certificate.crt file.");
 
 error_and_exit:
-       if (query)
-               sqlite3_free(query);
-
        if (stmt)
                sqlite3_finalize(stmt);
 
@@ -515,7 +526,6 @@ int enable_disable_cert_status(
        const char *pGname,
        CertStatus status)
 {
-       int ckmc_result = CKMC_ERROR_UNKNOWN;
        int result = CERTSVC_SUCCESS;
        int records = 0;
        size_t certSize = 0;
@@ -605,10 +615,10 @@ int enable_disable_cert_status(
                }
 
                if (storeType != SYSTEM_STORE) {
-                       result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
+                       result = ckmc_remove_alias_with_shared_owner_prefix(pGname);
 
-                       if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
-                               SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
+                       if (result != CKMC_ERROR_NONE) {
+                               SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", result);
                                return CERTSVC_FAIL;
                        }
 
@@ -1092,87 +1102,136 @@ int getCertificateDetailFromSystemStore(
        return CERTSVC_SUCCESS;
 }
 
-int deleteCertificateFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *pGname) {
-
+int deleteCertificateFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *pGname)
+{
        int result = CERTSVC_SUCCESS;
-       int ckmc_result = CKMC_ERROR_UNKNOWN;
        int records = 0;
        char *query = NULL;
        char *private_key_name = NULL;
        sqlite3_stmt *stmt = NULL;
 
+       SLOGD("Remove certificate of gname[%s] in store[%d]", pGname, storeType);
+
        if (!pGname) {
                SLOGE("Invalid input parameter passed.");
                return CERTSVC_WRONG_ARGUMENT;
        }
 
-       if (storeType != SYSTEM_STORE) {
-               /* start constructing query */
-               query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" :\
+       if (storeType == SYSTEM_STORE) {
+               SLOGE("Invalid store type passed.");
+               return CERTSVC_INVALID_STORE_TYPE;
+       }
+
+       /* start constructing query */
+       query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" :\
+                                                  (storeType == VPN_STORE)? "vpn" : "email"), pGname);
+
+       result = execute_select_query(db_handle, query, &stmt);
+       if (result != CERTSVC_SUCCESS) {
+               SLOGE("Querying database failed.");
+               result = CERTSVC_FAIL;
+               goto error;
+       }
+
+       records = sqlite3_step(stmt);
+       if (records != SQLITE_ROW) {
+               SLOGE("No valid records found for passed gname [%s]. result[%d].", pGname, records);
+               result = CERTSVC_FAIL;
+               goto error;
+       }
+
+       /* if a cert is having private-key in it, the private key should
+        * be deleted first from key-manager, then the actual cert */
+       if (sqlite3_column_text(stmt, 0) != NULL)
+               private_key_name = strdup((const char *)sqlite3_column_text(stmt, 0));
+
+       query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
+       result = execute_insert_update_query(db_handle, query);
+       if (result != CERTSVC_SUCCESS) {
+               SLOGE("Unable to delete certificate entry from database. result[%d]", result);
+               goto error;
+       }
+
+       if (query) {
+               sqlite3_free(query);
+               query = NULL;
+       }
+
+       if (stmt) {
+               sqlite3_finalize(stmt);
+               stmt = NULL;
+       }
+
+       query = sqlite3_mprintf("delete from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
                                                           (storeType == VPN_STORE)? "vpn" : "email"), pGname);
 
+       result = execute_insert_update_query(db_handle, query);
+       if (result != CERTSVC_SUCCESS) {
+               SLOGE("Unable to delete certificate entry from database. result[%d]", result);
+               goto error;
+       }
+
+       if (query) {
+               sqlite3_free(query);
+               query = NULL;
+       }
+
+       if (stmt) {
+               sqlite3_finalize(stmt);
+               stmt = NULL;
+       }
+
+       CertStoreType other = ALL_STORE & ~SYSTEM_STORE & ~storeType;
+       CertStoreType current;
+       int gname_exist = 0;
+       for (current = VPN_STORE; current < SYSTEM_STORE; current <<= 1) {
+               if ((other & current) == 0)
+                       continue;
+
+               query = sqlite3_mprintf("select * from %Q where gname=%Q", ((current == WIFI_STORE)? "wifi" :\
+                                                          (current == VPN_STORE)? "vpn" : "email"), pGname);
                result = execute_select_query(db_handle, query, &stmt);
                if (result != CERTSVC_SUCCESS) {
                        SLOGE("Querying database failed.");
                        result = CERTSVC_FAIL;
                        goto error;
                }
-
                records = sqlite3_step(stmt);
-               if ((records != SQLITE_ROW) || (records == SQLITE_DONE)) {
-                       SLOGE("No valid records found for passed gname [%s].",pGname);
-                       result = CERTSVC_FAIL;
-                       goto error;
+               if (records == SQLITE_ROW) {
+                       SLOGI("Same gname[%s] exist on store[%d].", pGname, current);
+                       gname_exist = 1;
+                       break;
                }
 
-               /* if a cert is having private-key in it, the private key should
-                * be deleted first from key-manager, then the actual cert */
-               if (sqlite3_column_text(stmt, 0) != NULL) {
-                       private_key_name = strdup((const char *)sqlite3_column_text(stmt, 0));
-                       result = ckmc_remove_alias_with_shared_owner_prefix(private_key_name, &ckmc_result);
-                       if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
-                               SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
-                               result = CERTSVC_FAIL;
-                               goto error;
-                       }
-               }
+               sqlite3_free(query);
+               sqlite3_finalize(stmt);
+               query = NULL;
+               stmt = NULL;
+       }
 
-               /* removing the actual cert */
-               result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
-               if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
-                       query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
-                       result = execute_insert_update_query(db_handle, query);
-                       if (result != CERTSVC_SUCCESS) {
-                               SLOGE("Unable to delete certificate entry from database.");
+       if (!gname_exist) {
+               SLOGD("The gname[%s] which is in store[%d] is the last one. so remove it from ckm either.", pGname, storeType);
+
+               if (private_key_name != NULL) {
+                       result = ckmc_remove_alias_with_shared_owner_prefix(private_key_name);
+                       if (result != CKMC_ERROR_NONE) {
+                               SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", result);
                                result = CERTSVC_FAIL;
                                goto error;
                        }
                }
 
-               if (query) {
-                       sqlite3_free(query);
-                       query = NULL;
-               }
-
-               if (stmt) {
-                       sqlite3_finalize(stmt);
-                       stmt = NULL;
-               }
-
-               query = sqlite3_mprintf("delete from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
-                                                          (storeType == VPN_STORE)? "vpn" : "email"), pGname);
-
-               result = execute_insert_update_query(db_handle, query);
-               if (result != CERTSVC_SUCCESS) {
-                       SLOGE("Unable to delete certificate entry from database.");
+               /* removing the actual cert */
+               result = ckmc_remove_alias_with_shared_owner_prefix(pGname);
+               if (result != CKMC_ERROR_NONE) {
+                       SLOGE("Failed to remove data in ckm with gname[%s]. ckm_result[%d]", pGname, result);
                        result = CERTSVC_FAIL;
                        goto error;
                }
-       } else {
-               SLOGE("Invalid store type passed.");
-               result = CERTSVC_INVALID_STORE_TYPE;
        }
+
        SLOGD("Success in deleting the certificate from store.");
+       result = CERTSVC_SUCCESS;
 
 error:
        if (query)
@@ -1182,6 +1241,7 @@ error:
                sqlite3_finalize(stmt);
 
        free(private_key_name);
+
        return result;
 }
 
index a4db1ac..3f7f9c7 100644 (file)
@@ -51,6 +51,7 @@
 #include "vcore/Certificate.h"
 #include "vcore/CertificateCollection.h"
 #include "vcore/pkcs12.h"
+#include "vcore/Client.h"
 
 #include "cert-svc/cinstance.h"
 #include "cert-svc/ccert.h"
@@ -835,7 +836,7 @@ out:
         CertSvcString pfxIdString,
         int *is_unique)
     {
-        return c_certsvc_pkcs12_alias_exists_in_store(storeType, pfxIdString.privateHandler, is_unique);
+        return vcore_client_check_alias_exist_in_store(storeType, pfxIdString.privateHandler, is_unique);
     }
 
     inline int getCertDetailFromStore(CertStoreType storeType,
@@ -843,7 +844,7 @@ out:
         char **certBuffer,
         size_t *certSize)
     {
-        return c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname.privateHandler, certBuffer, certSize);
+        return vcore_client_get_certificate_from_store(storeType, gname.privateHandler, certBuffer, certSize, PEM_CRT);
     }
 
     inline int pkcsDeleteCertFromStore(
@@ -851,14 +852,14 @@ out:
         CertSvcString gname
     )
     {
-        return c_certsvc_pkcs12_delete_certificate_from_store(storeType, gname.privateHandler);
+        return vcore_client_delete_certificate_from_store(storeType, gname.privateHandler);
     }
 
     inline int pkcsHasPassword(
         CertSvcString filepath,
         int *has_password)
     {
-        return c_certsvc_pkcs12_has_password(filepath.privateHandler, has_password);
+        return pkcs12_has_password(filepath.privateHandler, has_password);
     }
 
     inline int pkcsImportToStore(
@@ -867,14 +868,14 @@ out:
         CertSvcString pass,
         CertSvcString pfxIdString)
     {
-        return c_certsvc_pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
+        return pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler, pfxIdString.privateHandler);
     }
 
     inline int pkcsGetAliasNameForCertInStore(CertStoreType storeType,
         CertSvcString gname,
         char **alias)
     {
-        return c_certsvc_pkcs12_get_certificate_alias_from_store(storeType, gname.privateHandler, alias);
+        return vcore_client_get_certificate_alias_from_store(storeType, gname.privateHandler, alias);
     }
 
     inline int pkcsSetCertStatusToStore(CertStoreType storeType,
@@ -882,7 +883,7 @@ out:
        CertSvcString gname,
         CertStatus status)
     {
-        return c_certsvc_pkcs12_set_certificate_status_to_store(storeType, is_root_app, gname.privateHandler, status);
+           return vcore_client_set_certificate_status_to_store(storeType, is_root_app, gname.privateHandler, status);
     }
 
     inline int pkcsGetCertStatusFromStore(
@@ -890,7 +891,7 @@ out:
         CertSvcString gname,
         CertStatus *status)
     {
-        return c_certsvc_pkcs12_get_certificate_status_from_store(storeType, gname.privateHandler, status);
+        return vcore_client_get_certificate_status_from_store(storeType, gname.privateHandler, status);
     }
 
     inline int getCertFromStore(CertSvcInstance instance,
@@ -901,10 +902,22 @@ out:
            return certsvc_get_certificate(instance, storeType, gname, certificate);
     }
 
-    inline int freePkcsIdListFromStore(
-        CertSvcStoreCertList** certList)
+    inline int freePkcsIdListFromStore(CertSvcStoreCertList **certList)
     {
-        return c_certsvc_pkcs12_free_aliases_loaded_from_store(certList);
+        CertSvcStoreCertList *current;
+        CertSvcStoreCertList *next;
+
+        for (current = *certList; current != NULL; current = next) {
+            next = current->next;
+
+            free(current->title);
+            free(current->gname);
+            free(current);
+        }
+
+        *certList = NULL;
+
+        return CERTSVC_SUCCESS;
     }
 
     inline int getPkcsIdListFromStore(
@@ -913,7 +926,7 @@ out:
         CertSvcStoreCertList** certList,
         size_t *length)
     {
-        return c_certsvc_pkcs12_get_certificate_list_from_store(storeType, is_root_app, certList, length);
+        return vcore_client_get_certificate_list_from_store(storeType, is_root_app, certList, length);
     }
 
     inline int getPkcsIdEndUserListFromStore(
@@ -921,7 +934,7 @@ out:
         CertSvcStoreCertList** certList,
         size_t *length)
     {
-        return c_certsvc_pkcs12_get_end_user_certificate_list_from_store(storeType, certList, length);
+        return vcore_client_get_end_user_certificate_list_from_store(storeType, certList, length);
     }
 
     inline int getPkcsIdRootListFromStore(
@@ -929,7 +942,7 @@ out:
         CertSvcStoreCertList** certList,
         size_t *length)
     {
-        return c_certsvc_pkcs12_get_root_certificate_list_from_store(storeType, certList, length);
+        return vcore_client_get_root_certificate_list_from_store(storeType, certList, length);
     }
 
     inline int getPkcsPrivateKeyFromStore(
@@ -938,7 +951,7 @@ out:
         char **certBuffer,
         size_t *certSize)
     {
-        return c_certsvc_pkcs12_private_key_load_from_store(storeType, gname.privateHandler, certBuffer, certSize);
+        return vcore_client_get_certificate_from_store(storeType, gname.privateHandler, certBuffer, certSize, (CertType)P12_PKEY);
     }
 
     inline int getPkcsCertificateListFromStore(
@@ -949,7 +962,7 @@ out:
     {
         char **certs = NULL;
         size_t ncerts = 0;
-        int result = c_certsvc_pkcs12_load_certificates_from_store(storeType, pfxIdString.privateHandler, &certs, &ncerts);
+        int result = vcore_client_load_certificates_from_store(storeType, pfxIdString.privateHandler, &certs, &ncerts);
         if (result != CERTSVC_SUCCESS) {
             LogError("Unable to load certificates from store.");
             return result;
@@ -1077,7 +1090,7 @@ int certsvc_certificate_new_from_file(
         CertSvcCertificate *certificate)
 {
     try {
-        CertificatePtr cert(Certificate::createFromFile(location));
+        CertificatePtr cert = Certificate::createFromFile(location);
 
         certificate->privateInstance = instance;
         certificate->privateHandler = impl(instance)->addCert(cert);
@@ -1428,7 +1441,7 @@ int certsvc_get_certificate(CertSvcInstance instance,
     X509* x509Struct = NULL;
 
     try {
-        result = c_certsvc_pkcs12_get_certificate_buffer_from_store(storeType, gname, &certBuffer, &length);
+        result = vcore_client_get_certificate_from_store(storeType, gname, &certBuffer, &length, PEM_CRT);
         if (result != CERTSVC_SUCCESS) {
             LogError("Failed to get certificate buffer from store.");
             return result;
@@ -1630,17 +1643,16 @@ int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
     CertSvcString pfxIdString)
 {
     try {
-        if (path.privateHandler != NULL) {
-        if (!impl(instance)->checkValidStoreType(storeType)) {
+        if (path.privateHandler == NULL || !impl(instance)->checkValidStoreType(storeType)) {
             LogError("Invalid input parameter.");
             return CERTSVC_INVALID_STORE_TYPE;
         }
+
         return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString);
-    }
-    else
+    } catch (...) {
+        LogError("Exception occured from pkcsImportToStore");
         return CERTSVC_FAIL;
-    } catch (...) {}
-    return CERTSVC_FAIL;
+    }
 }
 
 int certsvc_pkcs12_get_alias_name_for_certificate_in_store(CertSvcInstance instance,
@@ -1782,9 +1794,7 @@ int certsvc_pkcs12_has_password(
     int *has_password)
 {
     try {
-        return impl(instance)->pkcsHasPassword(
-            filepath,
-            has_password);
+        return impl(instance)->pkcsHasPassword(filepath, has_password);
     } catch (...) {}
     return CERTSVC_FAIL;
 }
index 121cc09..54719b2 100644 (file)
@@ -20,6 +20,7 @@
  * @version     1.0
  * @brief       PKCS#12 container manipulation routines.
  */
+
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -27,6 +28,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <string>
+#include <memory>
+#include <functional>
 
 #include <openssl/err.h>
 #include <openssl/pkcs12.h>
 #include <openssl/pem.h>
 
 #include "dpl/log/log.h"
-#include "vcore/Certificate.h"
-#include "vcore/Client.h"
 #include "cert-svc/cerror.h"
 
+#include "vcore/Certificate.h"
+#include "vcore/Client.h"
 #include "vcore/pkcs12.h"
 
 #define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
 
-#define START_CERT      "-----BEGIN CERTIFICATE-----"
-#define END_CERT        "-----END CERTIFICATE-----"
-#define START_TRUSTED   "-----BEGIN TRUSTED CERTIFICATE-----"
-#define END_TRUSTED     "-----END TRUSTED CERTIFICATE-----"
-#define START_KEY       "-----BEGIN PRIVATE KEY-----"
-#define END_KEY         "-----END PRIVATE KEY-----"
+namespace {
 
-#define _CERT_SVC_VERIFY_PKCS12
+static const std::string START_CERT    = "-----BEGIN CERTIFICATE-----";
+static const std::string END_CERT      = "-----END CERTIFICATE-----";
+static const std::string START_TRUSTED = "-----BEGIN TRUSTED CERTIFICATE-----";
+static const std::string END_TRUSTED   = "-----END TRUSTED CERTIFICATE-----";
+static const std::string START_KEY     = "-----BEGIN PRIVATE KEY-----";
+static const std::string END_KEY       = "-----END PRIVATE KEY-----";
+
+using ValidationCore::CertificatePtr;
+using ValidationCore::Certificate;
 
-static int generate_random_filepath(char **filepath)
+using FileUniquePtr      = std::unique_ptr<FILE, std::function<int(FILE*)>>;
+using BioUniquePtr       = std::unique_ptr<BIO, std::function<void(BIO*)>>;
+using PKEYUniquePtr      = std::unique_ptr<EVP_PKEY, std::function<void(EVP_PKEY*)>>;
+using X509UniquePtr      = std::unique_ptr<X509, std::function<void(X509*)>>;
+using X509StackUniquePtr = std::unique_ptr<STACK_OF(X509), std::function<void(STACK_OF(X509)*)>>;
+
+void X509_stack_free(STACK_OF(X509) *stack)
 {
-  int generator;
-  int64_t random;
-  SHA_CTX ctx;
-  unsigned char d[SHA_DIGEST_LENGTH];
-  int result;
-
-  if(!filepath)
-    return CERTSVC_WRONG_ARGUMENT;
-
-  SYSCALL(generator = open("/dev/urandom", O_RDONLY));
-  if(generator == -1)
-    return CERTSVC_FAIL;
-  SYSCALL(result = read(generator, &random, sizeof(random)));
-  if(result == -1) {
-    SYSCALL(close(generator));
-    return CERTSVC_FAIL;
-  }
-  SYSCALL(result = close(generator));
-  if(result == -1)
-    return CERTSVC_FAIL;
-
-  SHA1_Init(&ctx);
-  SHA1_Update(&ctx, &random, sizeof(random));
-  SHA1_Final(d, &ctx);
-
-  result = asprintf(filepath, "%s/"                            \
-                    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
-                    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
-                    CERTSVC_PKCS12_STORAGE_DIR,
-                    d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9],
-                    d[10], d[11], d[12], d[13], d[14], d[15], d[16], d[17], d[18], d[19]);
-  return (result != -1) ? CERTSVC_SUCCESS : CERTSVC_BAD_ALLOC;
+    sk_X509_free(stack);
 }
 
-static int unique_filename(char **filepath)
+inline bool hasStore(CertStoreType types, CertStoreType type)
 {
-  int result;
-
-  for (unsigned trial = 0x00U; trial < 0xFFU; ++trial) {
-    result = generate_random_filepath(filepath);
-    if (result != CERTSVC_SUCCESS)
-        return result;
-
-    result = access(*filepath, F_OK);
-    if (result != 0)
-        return CERTSVC_SUCCESS;
-
-    free(*filepath);
-  }
-
-  return CERTSVC_FAIL;
+    return (types & type) != 0;
 }
 
-static char *bare_filename(char *filepath)
+inline CertStoreType nextStore(CertStoreType type)
 {
-  char *needle;
-  if(!filepath)
-    return NULL;
-  needle = strrchr(filepath, '/');
-  if(!needle)
-    return NULL;
-  return *(++needle) ? needle : NULL;
+    switch (type) {
+    case NONE_STORE:   return VPN_STORE;
+    case VPN_STORE:    return WIFI_STORE;
+    case WIFI_STORE:   return EMAIL_STORE;
+    case EMAIL_STORE:  return SYSTEM_STORE;
+    case SYSTEM_STORE: return NONE_STORE;
+    default:           return NONE_STORE;
+    }
 }
 
-int read_from_file(const char *fileName, char **certBuffer, int *length)
+std::string generateGname(void)
 {
-    int result = CERTSVC_SUCCESS;
-    FILE *fp_out = NULL;
-    int certLength = 0;
-    struct stat st;
-
-    if (stat(fileName, &st) == -1) {
-        LogError("Certificate does not exist in disable folder.");
-        result = CERTSVC_FAIL;
-        goto err;
+    int generator;
+    int64_t random;
+    SHA_CTX ctx;
+    unsigned char d[SHA_DIGEST_LENGTH];
+    int result;
+    char *gname = NULL;
+
+    SYSCALL(generator = open("/dev/urandom", O_RDONLY));
+    if (generator == -1)
+        return std::string();
+    SYSCALL(result = read(generator, &random, sizeof(random)));
+    if (result == -1) {
+        SYSCALL(close(generator));
+        return std::string();
     }
+    SYSCALL(result = close(generator));
+    if (result == -1)
+        return std::string();
 
-    if (!(fp_out = fopen(fileName, "rb"))) {
-        LogError("Fail to open file for reading, [" << fileName << "].");
-        result = CERTSVC_FAIL;
-        goto err;
-    }
+    SHA1_Init(&ctx);
+    SHA1_Update(&ctx, &random, sizeof(random));
+    SHA1_Final(d, &ctx);
 
-    fseek(fp_out, 0L, SEEK_END);
-    certLength = ftell(fp_out);
-    if (certLength < 1) {
-        LogError("Fail to get certificate length.");
-        result = CERTSVC_IO_ERROR;
-        goto err;
-    }
+    result = asprintf(&gname,
+             "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+             "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+             d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9],
+             d[10], d[11], d[12], d[13], d[14], d[15], d[16], d[17], d[18], d[19]);
 
-    *certBuffer = (char*)malloc(sizeof(char) * ((int)certLength + 1));
-    if (*certBuffer == NULL) {
-        LogError("Fail to allocate memory");
-        result = CERTSVC_BAD_ALLOC;
-        goto err;
-    }
+    if (result == -1)
+        return std::string();
 
-    memset(*certBuffer, 0x00, certLength+1);
-    rewind (fp_out);
-    if (fread(*certBuffer, sizeof(char), (size_t)certLength, fp_out) != (size_t)certLength) {
-        LogError("Fail to read file, [" << fileName << "]");
-        result = CERTSVC_IO_ERROR;
-        goto err;
-    }
-    *length = certLength;
+    std::string ret(gname);
 
-    LogDebug("Success to read from file[" << fileName << "]");
+    free(gname);
 
-err:
-    if (fp_out != NULL) {
-        fclose(fp_out);
-        fp_out = NULL;
-    }
-    return result;
+    return ret;
 }
 
-int c_certsvc_pkcs12_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char* gname, CertStatus status)
+std::string getCommonName(CertType type, const std::string &cert)
 {
-       return vcore_client_set_certificate_status_to_store(storeType, is_root_app, gname, status);
-}
+    BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
+    if (bio.get() == NULL) {
+        LogError("Failed to allocate memory.");
+        return std::string();
+    }
 
-int c_certsvc_pkcs12_get_certificate_buffer_from_store(CertStoreType storeType, const char* gname, char** certBuffer, size_t* certSize)
-{
-    return vcore_client_get_certificate_from_store(storeType, gname, certBuffer, certSize, PEM_CRT);
-}
+    auto readCount = BIO_write(bio.get(), (const void *)cert.data(), (int)cert.length());
+    if (readCount < 1) {
+        LogError("Failed to load cert into bio.");
+        return std::string();
+    }
 
-int c_certsvc_pkcs12_get_certificate_status_from_store(CertStoreType storeType, const char *gname, CertStatus *status)
-{
-    return vcore_client_get_certificate_status_from_store(storeType, gname, status);
-}
+    X509 *x509 = NULL;
+    switch (type) {
+    case P12_TRUSTED:
+    case P12_INTERMEDIATE:
+        x509 = PEM_read_bio_X509_AUX(bio.get(), NULL, 0, NULL);
+        break;
 
-int c_certsvc_pkcs12_alias_exists_in_store(CertStoreType storeType, const char *alias, int *isUnique)
-{
-    return vcore_client_check_alias_exist_in_store(storeType, alias, isUnique);
-}
+    default:
+        x509 = PEM_read_bio_X509(bio.get(), NULL, 0, NULL);
+        break;
+    }
 
-int c_certsvc_pkcs12_private_key_load_from_store(CertStoreType storeType, const char *gname, char **certBuffer, size_t *certSize)
-{
-    return vcore_client_get_certificate_from_store(storeType, gname, certBuffer, certSize, (CertType)P12_PKEY);
-}
+    if (x509 == NULL) {
+        LogError("Failed to create x509 structure.");
+        return std::string();
+    }
 
-int c_certsvc_pkcs12_delete_certificate_from_store(CertStoreType storeType, const char* gname)
-{
-       return vcore_client_delete_certificate_from_store(storeType, gname);
-}
+    X509UniquePtr x509Ptr(x509, X509_free);
 
-int c_certsvc_pkcs12_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias)
-{
-    return vcore_client_get_certificate_alias_from_store(storeType, gname, alias);
-}
+    const char *subject_c = X509_NAME_oneline(x509->cert_info->subject, NULL, 0);
+    if (subject_c == NULL) {
+        LogError("Failed to parse x509 structure");
+        return std::string();
+    }
 
-int c_certsvc_pkcs12_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, size_t *ncerts)
-{
-    return vcore_client_load_certificates_from_store(storeType, gname, certs, ncerts);
+    return std::string(subject_c);
 }
 
-int c_certsvc_pkcs12_free_aliases_loaded_from_store(CertSvcStoreCertList** certList)
-{
-    int result = CERTSVC_SUCCESS;
-    CertSvcStoreCertList* tmpNode = NULL;
-
-    while (*certList) {
-        tmpNode = *certList;
-        if (tmpNode->title)
-            free(tmpNode->title);
-        if (tmpNode->gname)
-            free(tmpNode->gname);
-        *certList = (*certList)->next;
-        free(tmpNode);
-    }
-    return result;
-}
+/*
+ *  column           / common name / associated gname / prikey gname /
+ *  PEM_CRT          : common name / gname            / none         /
+ *  P12_END_USER     : alias       / gname            / prikey gname /
+ *  P12_TRUSTED      : common name / end cert gname   / none         /
+ *  P12_INTERMEDIATE : common name / end cert gname   / none         /
+ */
 
-int c_certsvc_pkcs12_get_root_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, size_t *length)
+int installPKEY(CertStoreType storeType,
+                const std::string &key,
+                const std::string &gname)
 {
-    return vcore_client_get_root_certificate_list_from_store(storeType, certList, length);
+    return vcore_client_install_certificate_to_store(
+            storeType,
+            gname.c_str(),
+            NULL,
+            NULL,
+            NULL,
+            key.c_str(),
+            key.length(),
+            P12_PKEY);
 }
 
-int c_certsvc_pkcs12_get_end_user_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList** certList, size_t *length)
+int installEndCert(CertStoreType storeType,
+                   const std::string &cert,
+                   const std::string &alias,
+                   const std::string &gname,
+                   const std::string &prikeyGname)
 {
-    return vcore_client_get_end_user_certificate_list_from_store(storeType, certList, length);
+    return vcore_client_install_certificate_to_store(
+            storeType,
+            gname.c_str(),
+            alias.c_str(),
+            prikeyGname.c_str(),
+            gname.c_str(),
+            cert.c_str(),
+            cert.length(),
+            P12_END_USER);
 }
 
-int c_certsvc_pkcs12_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, CertSvcStoreCertList** certList, size_t *length)
+int installChainCert(CertStoreType storeType,
+                     const std::string &cert,
+                     const std::string &gname,
+                     const std::string &endCertGname,
+                     CertType type)
 {
-    return vcore_client_get_certificate_list_from_store(storeType, is_root_app, certList, length);
+    std::string commonName = getCommonName(type, cert);
+
+    return vcore_client_install_certificate_to_store(
+            storeType,
+            gname.c_str(),
+            commonName.c_str(),
+            NULL,
+            endCertGname.c_str(),
+            cert.c_str(),
+            cert.length(),
+            type);
 }
-
-int install_pem_file_format_to_store(CertStoreType storeType, const char *certBuffer, size_t certLength,
-               const char *alias, const char* path, char *private_key_gname, char *associated_gname, CertType decideCert)
+int installCert(CertStoreType storeType,
+                const std::string &cert,
+                const std::string &gname)
 {
-    int result = CERTSVC_SUCCESS;
-    char* fileName = NULL;
-    char *unique = NULL;
-    struct stat dirST;
-
-    if (!certBuffer || !certLength) {
-        LogError("Invalid argument. certBuffer is input cert.");
-        return CERTSVC_WRONG_ARGUMENT;
-    }
-
-    if (decideCert == PEM_CRT) {
-        result = unique_filename(&unique);
-        if (result != CERTSVC_SUCCESS) {
-            LogError("Fail to generate unique filename.");
-            return result;
-        }
-    }
-    else
-        unique = (char*)path;
-
-    if (unique == NULL)        {
-        LogError("Failed to get unique file name.");
-        return result;
-    }
-
-    std::string commonName;
-
-    if (stat(path, &dirST) != -1) {
-        try {
-            ValidationCore::CertificatePtr certPtr = ValidationCore::Certificate::createFromFile(std::string(path));
-            commonName = certPtr->getCommonName();
-            if (commonName.empty()) {
-                LogError("CommonName is NULL");
-                result = CERTSVC_FAIL;
-                goto error;
-            }
-            LogDebug("Certificate Common name to install : " << commonName);
-        } catch (const ValidationCore::Certificate::Exception::Base &e) {
-            LogError("Certificate exception : " << e.DumpToString());
-            result = CERTSVC_FAIL;
-            goto error;
-        }
-    }
-
-    /* storing the certificate to key-manager */
-    fileName = bare_filename(unique);
-    if ((decideCert == P12_END_USER) && (private_key_gname != NULL))
-        result =  vcore_client_install_certificate_to_store(storeType, fileName, alias, private_key_gname, fileName, certBuffer, certLength, decideCert);
-    else if ((decideCert == P12_TRUSTED) || (decideCert == P12_INTERMEDIATE))
-        result =  vcore_client_install_certificate_to_store(storeType, fileName, commonName.c_str(), NULL, associated_gname, certBuffer, certLength, decideCert);
-    else
-        result =  vcore_client_install_certificate_to_store(storeType, fileName, commonName.c_str(), NULL, fileName, certBuffer, certLength, decideCert);
-
-    if (result != CERTSVC_SUCCESS) {
-        LogError("Failed to intall certificate. result[" << result << "]");
-        result = CERTSVC_FAIL;
-        goto error;
-     }
-
-    LogDebug("Success to add certificate in store.");
-
-error:
-
-    return result;
+    std::string commonName = getCommonName(PEM_CRT, cert);
+
+    return vcore_client_install_certificate_to_store(
+            storeType,
+            gname.c_str(),
+            commonName.c_str(),
+            NULL,
+            NULL,
+            cert.c_str(),
+            cert.length(),
+            PEM_CRT);
 }
 
-int install_crt_file(
-        const char *path,
-        CertStoreType storeType,
-        const char *alias,
-               char *private_key_gname,
-        char *associated_gname,
-        CertType decideCert)
+std::string readFromFile(const std::string &path)
 {
-    int result = CERTSVC_SUCCESS;
-    int fileSize = 0;
-    int certLength = 0;
-    const char* header = NULL;
-    const char* trailer = NULL;
-    char* fileContent = NULL;
-    const char* tmpBuffer = NULL;
-    char* certBuffer = NULL;
-    const char* tailEnd = NULL;
-
-    if (read_from_file(path, &fileContent, &fileSize)!=CERTSVC_SUCCESS) {
-        LogError("Failed to read the file. [" << path << "]");
-        result = CERTSVC_IO_ERROR;
-       goto error;
+    FILE *fp = NULL;
+    if ((fp = fopen(path.c_str(), "rb")) == NULL) {
+        LogError("Fail to open file for reading : " << path);
+        return std::string();
     }
 
-    tmpBuffer = fileContent;
-    if (decideCert == PEM_CRT)
-        header = strstr(tmpBuffer, START_CERT);
-    else if (decideCert == P12_END_USER)
-        header = strstr(tmpBuffer, START_CERT);
-    else if ((decideCert == P12_TRUSTED)||(decideCert == P12_INTERMEDIATE))
-        header = strstr(tmpBuffer, START_TRUSTED);
-    else {
-        LogError("Invalid cert.");
-        result = CERTSVC_IO_ERROR;
-        goto error;
-    }
+    FileUniquePtr filePtr(fp, fclose);
 
-    if (header == NULL) {
-        LogError("Invalid file type passed.");
-        result = CERTSVC_INVALID_CERTIFICATE;
-        goto error;
+    fseek(fp, 0L, SEEK_END);
+    int len = ftell(fp);
+    if (len <= 0) {
+        LogError("Fail to get certificate length.");
+        return std::string();
     }
 
-    /* Supports installation of only one certificate present in a CRT file */
-    if (decideCert == PEM_CRT) {
-        trailer = strstr(header, END_CERT);
-        tailEnd = END_CERT;
-    }
-    else if (decideCert == P12_END_USER) {
-        trailer = strstr(header, END_CERT);
-        tailEnd = END_CERT;
-    }
-    else if ((decideCert == P12_TRUSTED)||(decideCert == P12_INTERMEDIATE)) {
-        trailer = strstr(header, END_TRUSTED);
-        tailEnd = END_TRUSTED;
-    }
-    else {
-        LogError("Invalid certificate passed.");
-        result = CERTSVC_IO_ERROR;
-        goto error;
-    }
+    rewind(fp);
 
-    if (trailer == NULL) {
-        LogError("Invalid certificate passed.");
-        result = CERTSVC_IO_ERROR;
-        goto error;
+    char *content = (char *)malloc(sizeof(char) * (len + 1));
+    if (content == NULL) {
+        LogError("Fail to allocate memory");
+        return std::string();
     }
 
-    tmpBuffer = trailer;
-    certLength = ((int)(trailer - header) + strlen(tailEnd));
-    certBuffer = (char*) malloc(sizeof(char) * (certLength+2));
-    if (certBuffer == NULL) {
-        result = CERTSVC_BAD_ALLOC;
-        LogError("Fail to allocate memory.");
-        goto error;
+    memset(content, 0x00, len + 1);
+    size_t readLen = fread(content, sizeof(char), (size_t)len, fp);
+    if (readLen != (size_t)len) {
+        LogError("Fail to read file : " << path);
+        free(content);
+        return std::string();
     }
 
-    memset(certBuffer, 0x00, certLength+2);
-    memcpy(certBuffer, header, certLength);
-    certBuffer[certLength] = '\0';
-
-    result = install_pem_file_format_to_store(storeType, certBuffer, certLength, alias, \
-                                              path, private_key_gname, associated_gname, decideCert);
-    if (result != CERTSVC_SUCCESS) {
-        result = CERTSVC_FAIL;
-        LogError("Fail to install certificate[" << path << "]");
-    }
+    content[len] = '\0';
 
-    LogDebug("Success to install certificate[" << path << "]");
+    std::string ret(content);
 
-error:
-    free(certBuffer);
-    free(fileContent);
+    free(content);
 
-    return result;
+    return ret;
 }
 
-int handle_crt_pem_file_installation(CertStoreType storeType, const char *path, const char *alias)
+std::string parseCRT(const std::string &cert)
 {
-    int result = CERTSVC_SUCCESS;
-
-    if ((strstr(path, ".crt")) != NULL || (strstr(path, ".pem")) != NULL) {
-        LogDebug("certificate extention is .crt/.pem file");
-
-        /* Installs CRT and PEM files. We will passing NULL for private_key_gname and associated_gname parameter in
-         * install_crt_file(). Which means that there is no private key involved in the certificate which we are
-         * installing and there are no other certificates related with the current certificate which is installed */
-        result = install_crt_file(path, storeType, alias, NULL, NULL, PEM_CRT);
-        if (result != CERTSVC_SUCCESS) {
-            LogError("Failed to install the certificate.");
-            result = CERTSVC_FAIL;
-            goto error;
-        }
+    size_t from = 0;
+    size_t to = 0;
+    size_t tailLen = 0;
+
+    from = cert.find(START_CERT);
+    to = cert.find(END_CERT);
+    tailLen = END_CERT.length();
+
+    if (from == std::string::npos || to == std::string::npos || from > to) {
+        from = cert.find(START_TRUSTED);
+        to = cert.find(END_TRUSTED);
+        tailLen = END_TRUSTED.length();
     }
-    else {
-        LogError("Invalid certificate passed.");
-        result = CERTSVC_FAIL;
-        goto error;
-    }
-    LogDebug("Success to install the certificate.");
 
-error:
-    return result;
+    if (from == std::string::npos || to == std::string::npos || from > to)
+        return std::string();
+
+    return std::string(cert, from, to - from + tailLen);
 }
 
-int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
+#define _CERT_SVC_VERIFY_PKCS12
+int verify_cert_details(X509 *cert, STACK_OF(X509) *certv)
 {
     int result = CERTSVC_SUCCESS;
     char* pSubject = NULL;
@@ -447,15 +319,15 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
     int res = 0;
 
 #ifdef _CERT_SVC_VERIFY_PKCS12
-    if (*certv == NULL) {
-        pSubject = X509_NAME_oneline((*cert)->cert_info->subject, NULL, 0);
+    if (certv == NULL) {
+        pSubject = X509_NAME_oneline(cert->cert_info->subject, NULL, 0);
         if (!pSubject) {
             LogError("Failed to get subject name");
             result = CERTSVC_FAIL;
             goto free_memory;
         }
 
-        pIssuerName = X509_NAME_oneline((*cert)->cert_info->issuer, NULL, 0);
+        pIssuerName = X509_NAME_oneline(cert->cert_info->issuer, NULL, 0);
         if (!pIssuerName) {
             LogError("Failed to get issuer name");
             result = CERTSVC_FAIL;
@@ -464,15 +336,15 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
 
         if (strcmp((const char*)pSubject, (const char*)pIssuerName) == 0) {
             /*self signed.. */
-            EVP_PKEYpKey = NULL;
-            pKey = X509_get_pubkey(*cert);
+            EVP_PKEY *pKey = NULL;
+            pKey = X509_get_pubkey(cert);
             if (!pKey) {
                 LogError("Failed to get public key");
                 result = CERTSVC_FAIL;
                 goto free_memory;
             }
 
-            if (X509_verify(*cert, pKey) <= 0) {
+            if (X509_verify(cert, pKey) <= 0) {
                 LogError("P12 verification failed");
                 EVP_PKEY_free(pKey);
                 result = CERTSVC_FAIL;
@@ -480,8 +352,7 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
             }
             LogDebug("P12 verification Success");
             EVP_PKEY_free(pKey);
-        }
-        else {
+        } else {
             cert_store = X509_STORE_new();
             if (!cert_store) {
                 LogError("Memory allocation failed");
@@ -514,7 +385,7 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
             }
 
             /* construct store context */
-            if (!X509_STORE_CTX_init(cert_ctx, cert_store, *cert, NULL)) {
+            if (!X509_STORE_CTX_init(cert_ctx, cert_store, cert, NULL)) {
                 LogError("Memory allocation failed");
                 result = CERTSVC_FAIL;
                 goto free_memory;
@@ -530,8 +401,7 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
             LogDebug("P12 verification Success");
 #endif
         }
-    }
-    else if (*certv != NULL) {
+    } else if (certv != NULL) {
         /* Cert Chain */
         cert_store = X509_STORE_new();
         if (!cert_store) {
@@ -563,13 +433,13 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
         }
 
         /* construct store context */
-        if (!X509_STORE_CTX_init(cert_ctx, cert_store, *cert, NULL)) {
+        if (!X509_STORE_CTX_init(cert_ctx, cert_store, cert, NULL)) {
             LogError("Memory allocation failed");
             result = CERTSVC_FAIL;
             goto free_memory;
         }
 
-        X509_STORE_CTX_trusted_stack(cert_ctx, *certv);
+        X509_STORE_CTX_trusted_stack(cert_ctx, certv);
 #ifdef P12_VERIFICATION_NEEDED
         res = X509_verify_cert(cert_ctx);
         if (res != 1) {
@@ -583,337 +453,351 @@ int verify_cert_details(X509** cert, STACK_OF(X509) **certv)
 #endif //_CERT_SVC_VERIFY_PKCS12
 
 free_memory:
-    if (pSubject != NULL) { free(pSubject); }
-    if (pIssuerName != NULL) { free(pIssuerName); }
-    if (cert_store != NULL) { X509_STORE_free(cert_store); }
-    if (cert_ctx) { X509_STORE_CTX_free(cert_ctx); }
+    if (cert_store != NULL)
+        X509_STORE_free(cert_store);
+    if (cert_ctx)
+        X509_STORE_CTX_free(cert_ctx);
+
+    free(pSubject);
+    free(pIssuerName);
+
     return result;
 }
 
-int c_certsvc_pkcs12_import_from_file_to_store(CertStoreType storeTypes, const char *path, const char *password, const char *alias)
+enum class OsslType : int {
+    PKEY = 1,
+    X509,
+    X509AUX
+};
+
+std::string osslToPEM(OsslType type, void *data)
+{
+    std::vector<char> buf(4096);
+    BioUniquePtr bio(BIO_new(BIO_s_mem()), BIO_free_all);
+    if (bio.get() == NULL)
+        return std::string();
+
+    switch (type) {
+    case OsslType::PKEY:
+        PEM_write_bio_PrivateKey(bio.get(), static_cast<EVP_PKEY *>(data), NULL, NULL, 0, NULL, NULL);
+        break;
+
+    case OsslType::X509:
+        PEM_write_bio_X509(bio.get(), static_cast<X509 *>(data));
+        break;
+
+    case OsslType::X509AUX:
+        PEM_write_bio_X509_AUX(bio.get(), static_cast<X509 *>(data));
+        break;
+
+    default:
+        break;
+    }
+
+    int size = BIO_read(bio.get(), buf.data(), 4096);
+    if (size <= 0)
+        return std::string();
+
+    buf[size] = '\0';
+
+    return std::string(buf.data());
+}
+
+int extractPkcs12(const std::string &path,
+                  const std::string &password,
+                  PKEYUniquePtr &keyPtr,
+                  X509UniquePtr &certPtr,
+                  X509StackUniquePtr &certvPtr)
 {
-    int        result = CERTSVC_SUCCESS;
-    int readLen = 0;
-    int tmpLen = 0;
-    int wr_res;
-    size_t nicerts = 0, i = 0, n = 0, ncerts = 0;
-    CertStoreType storeType = NONE_STORE;
-    FILE* stream = NULL;
-    PKCS12* container = NULL;
-    EVP_PKEY* key = NULL;
-    X509* cert = NULL;
+    FILE *stream = NULL;
+    if ((stream = fopen(path.c_str(), "rb")) == NULL) {
+        LogError("Unable to open the file for reading : " << path);
+        return CERTSVC_IO_ERROR;
+    }
+
+    PKCS12 *container = d2i_PKCS12_fp(stream, NULL);
+    fclose(stream);
+    if (container == NULL) {
+        LogError("Failed to parse the input file passed.");
+        return CERTSVC_FAIL;
+    }
+
+    EVP_PKEY *key = NULL;
+    X509 *cert = NULL;
     STACK_OF(X509) *certv = NULL;
-    char* bare = NULL;
-    char* pkvalue = NULL;
-    char** cvaluev = NULL;
-    char **certs = NULL;
-    char* tmpPkValue = NULL;
-    char* unique = NULL;
-    char fileBuffer[4096] = {0,};
-    int loopCount = 0;
-    CertType decideCert = INVALID_DATA;
-    int exists = 0;
-
-    if ((!alias) || (strlen(alias) < 1) || (!path) || (strlen(path) < 1)) {
-        LogError("Invalid input parameter.");
-        return CERTSVC_WRONG_ARGUMENT;
+    int result = PKCS12_parse(container, password.c_str(), &key, &cert, &certv);
+    PKCS12_free(container);
+    if (result != 1) {
+        LogError("Failed to parse the file passed. openssl err : " << ERR_get_error());
+        return CERTSVC_FAIL;
+    }
+
+    keyPtr.reset(key);
+    certPtr.reset(cert);
+    certvPtr.reset(certv);
+
+    return CERTSVC_SUCCESS;
+}
+
+void rollbackStore(CertStoreType storeTypes, const std::string &endCertName)
+{
+    for (CertStoreType storeType = VPN_STORE; storeType < SYSTEM_STORE; storeType = nextStore(storeType)) {
+        if (!hasStore(storeTypes, storeType))
+            continue;
+
+        char **certChainName = NULL;
+        size_t ncerts = 0;
+
+        int result = vcore_client_load_certificates_from_store(storeType, endCertName.c_str(), &certChainName, &ncerts);
+        if (result != CERTSVC_SUCCESS) {
+            LogError("Unable to load certificates from store. result : " << result);
+            continue;
+        }
+
+        for (size_t i = 0; i < ncerts; i++) {
+            if (certChainName[i] == NULL)
+                continue;
+
+            vcore_client_delete_certificate_from_store(storeType, certChainName[i]);
+            free(certChainName[i]);
+        }
+
+        vcore_client_delete_certificate_from_store(storeType, endCertName.c_str());
     }
+}
+
+int insertToStore(CertStoreType storeTypes,
+                  const std::string &alias,
+                  const std::string &prikeyName,
+                  const std::string &prikeyBuffer,
+                  const std::string &endCertName,
+                  const std::string &endCertBuffer,
+                  const std::vector<std::string> &certChainName,
+                  const std::vector<std::string> &certChainBuffer)
+{
+    size_t ncerts = certChainName.size();
+
+    for (CertStoreType storeType = VPN_STORE; storeType < SYSTEM_STORE; storeType = nextStore(storeType)) {
+        if (!hasStore(storeTypes, storeType))
+            continue;
 
-    while(1) {
-        /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
-        if (loopCount == (MAX_STORE_ENUMS-1)) break;
+        LogDebug("Processing store type : " << storeType);
+
+        int result = installPKEY(storeType, prikeyBuffer, prikeyName);
+        if (result != CERTSVC_SUCCESS) {
+            LogError("Failed to store the private key contents. result : " << result);
+            return result;
+        }
 
-        /* User should not install any form of certificates inside SYSTEM_STORE */
-        if (((1 << loopCount) & storeTypes) == SYSTEM_STORE) {
-            LogError("Not a valid store type installing certificate, store type passed [" << (1 << loopCount) << "]");
-            return CERTSVC_INVALID_STORE_TYPE;
+        result = installEndCert(storeType, endCertBuffer, alias, endCertName, prikeyName);
+        if (result != CERTSVC_SUCCESS) {
+            LogError("Failed to install the end user certificate. result : " << result);
+            return result;
         }
 
-        /* Iterating over all the stores */
-        if ((1 << loopCount) & storeTypes) {
-            storeType = NONE_STORE;
-            storeType = (CertStoreType) (1 << loopCount);
-            LogDebug("Processing store type : [" << ((storeType == VPN_STORE)? "VPN" : (storeType == WIFI_STORE)? "WIFI" : "EMAIL") << "]");
+        for (size_t i = 0; i < ncerts; i++) {
+            if (i == ncerts - 1)
+                result = installChainCert(storeType, certChainBuffer[i], certChainName[i], endCertName, P12_INTERMEDIATE);
+            else
+                result = installChainCert(storeType, certChainBuffer[i], certChainName[i], endCertName, P12_TRUSTED);
 
-            /* check if the alias exists before installing certificate */
-            result = c_certsvc_pkcs12_alias_exists_in_store(storeType, alias, &exists);
             if (result != CERTSVC_SUCCESS) {
-                LogError("Failure to access database.");
-                result = CERTSVC_FAIL;
-                goto error;
+                LogError("Failed to install the ca certificates. result : " << result);
+                return result;
             }
+        }
+    }
 
-            if (exists!=CERTSVC_TRUE) {
-                LogError("Alias exist in store [" << ((storeType == VPN_STORE)? "VPN" : (storeType == WIFI_STORE)? "WIFI" : "EMAIL") << "]");
-                result = CERTSVC_DUPLICATED_ALIAS;
-                goto error;
-            }
+    LogDebug("Success to insert extracted pkcs12 data to db");
 
-            /* Logic for handling crt/pem cert installation */
-            /* Check if the input file is a PEM/CRT, since a PFX cert can also be opened without a password */
-            if (password == NULL && ((strstr(path, ".pfx") == NULL) || (strstr(path, ".p12")))) {
-                result = handle_crt_pem_file_installation(storeType, path, alias);
-                if (result != CERTSVC_SUCCESS) {
-                    LogError("Failed to install PEM/CRT file to store.");
-                    result = CERTSVC_FAIL;
-                }
-                loopCount++;
-                continue;
-            }
+    return CERTSVC_SUCCESS;
+}
 
-            /* Logic for handling .pfx/.p12 cert installation */
-            if ((stream = fopen(path, "rb")) == NULL) {
-                LogError("Unable to open the file for reading [" << path << "]");
-                result = CERTSVC_IO_ERROR;
-                goto error;
-            }
+int insertToStorePEM(CertStoreType storeTypes, const std::string &path, const std::string &gname)
+{
+    std::string content = readFromFile(path);
+    if (content.empty()) {
+        LogError("Failed to read the file : " << path);
+        return CERTSVC_IO_ERROR;
+    }
 
-            if (container == NULL) {
-                container = d2i_PKCS12_fp(stream, NULL);
-                fclose(stream);
-                if (container == NULL) {
-                    LogError("Failed to parse the input file passed.");
-                    result = CERTSVC_FAIL;
-                    goto error;
-                }
-            }
+    std::string parsed = parseCRT(content);
+    if (parsed.empty()) {
+        LogError("Failed to parse CRT : " << path);
+        return CERTSVC_FAIL;
+    }
 
-            /* To ensure when the code re-enters, we should clean up */
-            if (key==NULL && cert==NULL && certv==NULL) {
-                result = PKCS12_parse(container, password, &key, &cert, &certv);
-                PKCS12_free(container);
-                if (result == CERTSVC_FAIL) {
-                    LogError("Failed to parse the file passed.");
-                    result = CERTSVC_FAIL;
-                    goto error;
-                }
-
-                result = verify_cert_details(&cert, &certv);
-                if (result == CERTSVC_FAIL) {
-                    LogError("Failed to verify p12 certificate.");
-                    goto error;
-                }
-            }
+    for (CertStoreType storeType = VPN_STORE; storeType < SYSTEM_STORE; storeType = nextStore(storeType)) {
+        if (!hasStore(storeTypes, storeType))
+            continue;
 
-            if (certv) {
-                int tempCertNum = sk_X509_num(certv);
-                if (tempCertNum < 0)
-                    nicerts = 0;
-                else
-                    nicerts = static_cast<size_t>(tempCertNum);
-            } else {
-                nicerts = 0;
-            }
+        int result = installCert(storeType, parsed, gname);
+        if (result != CERTSVC_SUCCESS) {
+            LogError("Failed to install PEM/CRT to db store : " << storeType << " result : " << result);
+            rollbackStore(storeTypes, gname);
+            return result;
+        }
 
-            if (cvaluev != NULL) {
-                for (i = 0; i < n; i++)
-                    free(cvaluev[i]);
-                if (cvaluev) free(cvaluev);
-                    cvaluev = NULL;
-            }
+        LogDebug("Success to install PEM/CRT to db store : " << storeType);
+    }
 
-            cvaluev = (char **)calloc(1 + nicerts, sizeof(char *));
-            if (unique != NULL) { free(unique); unique = NULL; }
-            result = unique_filename(&unique);
-            if (result != CERTSVC_SUCCESS || !unique) {
-                LogError("Unique filename generation failed.");
-                goto error;
-            }
+    LogDebug("Success to install PEM/CRT to db stores : " << storeTypes);
 
-            if ((stream = fopen(unique, "w+")) == NULL) {
-                LogError("Unable to open the file for writing [" << unique << "]");
-                result = CERTSVC_IO_ERROR;
-                goto error;
-            }
+    return CERTSVC_SUCCESS;
+}
 
-            result = PEM_write_PrivateKey(stream, key, NULL, NULL, 0, NULL, NULL);
-            if (result == 0) {
-                LogError("Writing the private key contents failed.");
-                result = CERTSVC_FAIL;
-                fclose(stream);
-                goto error;
-            }
+} // namespace anonymous
 
-            fseek(stream, 0, SEEK_SET);
-            memset(fileBuffer, 0, (sizeof(char)*4096));
-            readLen=0;
-            readLen = fread(fileBuffer, sizeof(char), 4096, stream);
-            fclose(stream);
-            if (readLen <= 0){
-                               LogError("Failed to read key file");
-                result = CERTSVC_FAIL;
-                goto error;
-            }
 
-            bare = bare_filename(unique);
-            if (bare) {
-                pkvalue = strdup(bare);
-                tmpLen = strlen((const char*)pkvalue);
-                tmpPkValue = (char*)malloc(sizeof(char) * (tmpLen + 1));
-                memset(tmpPkValue, 0x00, tmpLen+1);
-                memcpy(tmpPkValue, pkvalue, tmpLen);
-            }
+int pkcs12_import_from_file_to_store(CertStoreType storeTypes,
+                                     const char *_path,
+                                     const char *_password,
+                                     const char *_alias)
+{
 
-            decideCert = P12_PKEY;
-            result = vcore_client_install_certificate_to_store(storeType, tmpPkValue, NULL, NULL, NULL, fileBuffer, readLen, decideCert);
-            if (result != CERTSVC_SUCCESS) {
-                LogDebug("Failed to store the private key contents.");
-                result = CERTSVC_FAIL;
-                goto error;
-            }
+    int result = 0;
 
-            unlink(unique);
-            if (unique!=NULL) { free(unique); unique=NULL; }
-            result = unique_filename(&unique);
-            if (result != CERTSVC_SUCCESS || !unique) {
-                LogError("Unique filename generation failed.");
-                goto error;
-            }
+    if (_alias == NULL || _path == NULL || strlen(_path) < 4) {
+        LogError("Invalid input parameter.");
+        return CERTSVC_WRONG_ARGUMENT;
+    }
 
-            if ((stream = fopen(unique, "w")) == NULL) {
-                LogError("Unable to open the file for writing [" << unique << "]");
-                result = CERTSVC_IO_ERROR;
-                goto error;
-            }
+    std::string path(_path);
+    std::string alias(_alias);
+    std::string password;
+    if (_password != NULL)
+        password = std::string(_password);
 
-            result = PEM_write_X509(stream, cert);
-            fclose(stream);
-            if (result == 0) {
-                LogError("Failed to write contents to file.");
-                result = CERTSVC_FAIL;
-                goto error;
-            }
+    LogDebug("pkcs12_import_from_file_to_store start. path[" << path << "] password[" << password << "] alias[" << alias << "]");
 
-            n = 0;
-            bare = bare_filename(unique);
-            if (bare)
-                cvaluev[n++] = strdup(bare);
+    if (storeTypes & SYSTEM_STORE) {
+        LogError("User should not install any form of certificates in SYSTEM_STORE.");
+        return CERTSVC_INVALID_STORE_TYPE;
+    }
 
-            decideCert = P12_END_USER;
-            wr_res = install_crt_file(unique, storeType, alias, tmpPkValue, NULL, decideCert);
-            if (wr_res != CERTSVC_SUCCESS) {
-                result = CERTSVC_FAIL;
-                LogError("Failed to install the end user certificate.");
-                goto error;
-            }
+    /*
+     * Installs CRT and PEM files.
+     * We will passing NULL for private_key_gname and associated_gname parameter
+     * in installFilePEM(). Which means that there is no private key involved
+     * in the certificate which we are installing and there are no other
+     * certificates related with the current certificate which is installed
+     */
+    std::string suffix = path.substr(path.length() - 4, 4);
+    if (strcasecmp(suffix.c_str(), ".pem") == 0 || strcasecmp(suffix.c_str(), ".crt") == 0) {
+        std::string gnamePEM = generateGname();
+        result = insertToStorePEM(storeTypes, path, gnamePEM);
+        if (result != CERTSVC_SUCCESS)
+            LogError("Failed to install PEM/CRT file to store. gname : " << gnamePEM << " result : " << result);
+
+        return result;;
+    }
 
-            unlink(unique);
-            for (i=nicerts; i>0; i--) {
-                 result = unique_filename(&unique);
-                 if (result != CERTSVC_SUCCESS || !unique) {
-                     LogError("Unique filename generation failed.");
-                     goto error;
-                 }
-
-                 if ((stream = fopen(unique, "w")) == NULL) {
-                      result = CERTSVC_IO_ERROR;
-                      LogError("Unable to open the file for writing.");
-                      goto error;
-                 }
-
-                 result = PEM_write_X509_AUX(stream, sk_X509_value(certv, i-1));
-                 fclose(stream);
-                 if (result == 0) {
-                     result = CERTSVC_FAIL;
-                     LogError("Unable to extract the certificates.");
-                     goto error;
-                 }
-
-                 if (i==nicerts)
-                     decideCert = P12_INTERMEDIATE;
-                 else
-                     decideCert = P12_TRUSTED;
-                 wr_res = install_crt_file(unique, storeType, alias, NULL, cvaluev[0], decideCert);
-                 if (wr_res != CERTSVC_SUCCESS) {
-                     result = CERTSVC_FAIL;
-                     goto error;
-                 }
-
-                 unlink(unique);
-                 bare = bare_filename(unique);
-                 if (bare)
-                     cvaluev[n++] = strdup(bare);
-            }
-        }
-        loopCount++;
+    LogDebug("Convert ossl type to string start");
+
+    /* 0. extract pkcs12 data from file */
+    PKEYUniquePtr key(nullptr, EVP_PKEY_free);
+    X509UniquePtr cert(nullptr, X509_free);
+    X509StackUniquePtr certv(nullptr, X509_stack_free);
+    result = extractPkcs12(path, password, key, cert, certv);
+    if (result != CERTSVC_SUCCESS) {
+        LogError("Failed to extract pkcs12 file. result : " << result);
+        return result;
     }
 
-error:
-    /* if any certificate parsing/installation fails in middle,
-     * the below logic will delete the chain installed in DB */
+    LogDebug("extract pkcs12 to unique ptr success");
+
+    result = verify_cert_details(cert.get(), certv.get());
     if (result != CERTSVC_SUCCESS) {
-        if (nicerts > 0) {
-               nicerts = 0; i = 0;
-               /* cvaluev[0] holds the end user certificate identifier which will be associated
-                * to chain certs. Pull the cert chain based on end user cert and delete one by one. */
-            if (c_certsvc_pkcs12_load_certificates_from_store(storeType, cvaluev[0], &certs, &ncerts) != CERTSVC_SUCCESS) {
-                LogError("Unable to load certificates from store.");
-                return result;
-            }
+        LogError("Failed to verify p12 certificate. result : " << result);
+        return result;
+    }
 
-            for (i=0; i<ncerts; i++) {
-                if (certs[i] != NULL) {
-                    LogDebug("file to delete : " << certs[i]);
-                    c_certsvc_pkcs12_delete_certificate_from_store(storeType, (char *)certs[i]);
-                }
-            }
+    /* 1. handling private key */
+    std::string prikeyName = generateGname();
+    std::string prikeyBuffer = osslToPEM(OsslType::PKEY, key.get());
+    if (prikeyName.empty() || prikeyBuffer.empty()) {
+        LogError("Failed to transform pkey to PEM. result : " << result);
+        return CERTSVC_FAIL;
+    }
 
-            if (certs[i] != NULL) {
-                for (i=0; i<ncerts; i++)
-                    free(certs[i]);
-            }
+    LogDebug("Convert pkey to string success");
+
+    /* 2. handling end user certificate */
+    std::string endCertName = generateGname();
+    std::string endCertBuffer = osslToPEM(OsslType::X509, cert.get());
+    if (endCertName.empty() || endCertBuffer.empty()) {
+        LogError("Failed to transform x509 to PEM. result : " << result);
+        return CERTSVC_FAIL;
+    }
+
+    LogDebug("Convert end cert to string success");
+
+    /* 3. handling certificate chain */
+    std::vector<std::string> certChainName;
+    std::vector<std::string> certChainBuffer;
+    int ncerts = certv ? sk_X509_num(certv.get()) : 0;
+    for (int i = 0; i < ncerts; i++) {
+        std::string tempName = generateGname();
+        std::string tempBuffer = osslToPEM(OsslType::X509AUX, sk_X509_value(certv.get(), i));
+        if (tempName.empty() || tempBuffer.empty()) {
+            LogError("Failed to transform x509 AUX to PEM");
+            return CERTSVC_FAIL;
         }
+
+        certChainName.push_back(std::move(tempName));
+        certChainBuffer.push_back(std::move(tempBuffer));
     }
 
-    if (key != NULL) EVP_PKEY_free(key);
-    if (cert != NULL) X509_free(cert);
-    if (certv != NULL) sk_X509_free(certv);
-    if (pkvalue != NULL) free(pkvalue);
-    if (tmpPkValue != NULL) free(tmpPkValue);
-    if (unique != NULL) free(unique);
+    LogDebug("Convert cert chain to string success");
+
+    /* 4. insert extracted pkcs12 data to db */
+    result = insertToStore(storeTypes,
+                           alias,
+                           prikeyName,
+                           prikeyBuffer,
+                           endCertName,
+                           endCertBuffer,
+                           certChainName,
+                           certChainBuffer);
+
+    if (result != CERTSVC_SUCCESS)
+        rollbackStore(storeTypes, endCertName);
+
+    LogDebug("Success to import pkcs12 to store");
+
     return result;
 }
 
-int c_certsvc_pkcs12_has_password(const char *filepath, int *passworded)
+int pkcs12_has_password(const char *filepath, int *passworded)
 {
-  FILE *stream;
-  EVP_PKEY *pkey;
-  X509 *cert;
-  PKCS12 *container;
-  int result;
-
-  if(passworded == NULL)
-    return CERTSVC_WRONG_ARGUMENT;
-  if((stream = fopen(filepath, "rb")) == NULL)
-    return CERTSVC_IO_ERROR;
-  container = d2i_PKCS12_fp(stream, NULL);
-  fclose(stream);
-  if(container == NULL)
-    return CERTSVC_FAIL;
-  result = PKCS12_parse(container, NULL, &pkey, &cert, NULL);
-  PKCS12_free(container);
-  if(result == 1) {
-    EVP_PKEY_free(pkey);
-    X509_free(cert);
-    *passworded = 0;
-    return CERTSVC_SUCCESS;
-  }
-  else {
-    if(ERR_GET_REASON(ERR_peek_last_error()) == PKCS12_R_MAC_VERIFY_FAILURE) {
-      *passworded = 1;
-      return CERTSVC_SUCCESS;
-    }
-    else
-      return CERTSVC_FAIL;
-  }
-}
+    if (filepath == NULL || passworded == NULL)
+        return CERTSVC_WRONG_ARGUMENT;
 
-void c_certsvc_pkcs12_free_certificates(char **certs)
-{
-  size_t i = 0;
-  if (!certs)
-    return;
-  while (certs[i])
-    free(certs[i++]);
-  free(certs);
+    FILE *stream;
+    if ((stream = fopen(filepath, "rb")) == NULL)
+        return CERTSVC_IO_ERROR;
+
+    PKCS12 *container = d2i_PKCS12_fp(stream, NULL);
+    fclose(stream);
+
+    if (container == NULL)
+        return CERTSVC_FAIL;
+
+    EVP_PKEY *pkey = NULL;
+    X509 *cert = NULL;
+    int result = PKCS12_parse(container, NULL, &pkey, &cert, NULL);
+
+    PKCS12_free(container);
+
+    if (pkey != NULL)
+        EVP_PKEY_free(pkey);
+    if (cert != NULL)
+        X509_free(cert);
+
+    if (result != 1 && ERR_GET_REASON(ERR_peek_last_error()) != PKCS12_R_MAC_VERIFY_FAILURE)
+        return CERTSVC_FAIL;
+
+    *passworded = (result == 1) ? 1 : 0;
+
+    return CERTSVC_SUCCESS;
 }
index efbc2cb..dbf4854 100644 (file)
  *    limitations under the License.
  */
 /*
- * @file        pkcs12.c
+ * @file        pkcs12.h
  * @author      Jacek Migacz (j.migacz@samsung.com)
  * @version     1.0
  * @brief       PKCS#12 container manipulation routines.
  */
-#ifndef _PKCS12_H_
-#define _PKCS12_H_
+#pragma once
 
 #include <cert-svc/ccert.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * To import the p12/pfx/crt/pem file to specified store (WIFI_STORE/VPN_STORE/EMAIL_STORE).
  *
@@ -37,137 +32,7 @@ extern "C" {
  * @param[in] alias Logical name for certificate bundle identification (can't be empty).
  * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_DUPLICATED_ALIAS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
  */
-int  c_certsvc_pkcs12_import_from_file_to_store(CertStoreType storeType, const char *path, const char *password, const char *alias);
-
-/**
- * To get the list of certificate information present in a store. User will be getting
- * the information in a linked list where every list will contain Alias, Path to certificate,
- * Certificate status of all the certificates present in the specified store.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] is_root_app If set to ENABLED, can get all the certs without any restriction (should be used only by master application).
- *                        If set to DISABLED, only certs which are enabled by master application can only be retrieved.
- * @param[out] certList Linked-list having all the information about each certificate present in a store.
- * @param[out] length provides the length of the linked list.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
- */
-int  c_certsvc_pkcs12_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, CertSvcStoreCertList **certList, size_t *length);
-
-/**
- * To set the status for a specified certificate in a particular store to enabled / disabled.
- * The gname is the key for accessing the certificate.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] gname Referred as group name, is the key for accessing the certificate.
- * @param[in] is_root_app Set as ENABLED/DISABLED. Enabled, if used by master application is changing the status. Disabled, should be used by other applications.
- * @param[in] status Allows to set the status of the certificate to enabled / disabled.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
- */
-int  c_certsvc_pkcs12_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char *gname, CertStatus status);
-
-/**
- * To get the status (enabled/disabled) for the specified certificate in a particular store.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] gname Referred as group name, is the key for accessing the certificate.
- * @param[out] status Returns the status of the certificate. It will be set Disable=0, Enable=1, Fail=-1.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_ALIAS_DOES_NOT_EXIST, CERTSVC_IO_ERROR
- */
-int  c_certsvc_pkcs12_get_certificate_status_from_store(CertStoreType storeType, const char *gname, CertStatus *status);
-
-/**
- * To get the encoded form of the specified certificate from the specified store.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] gname Referred as group name, is the key for accessing the certificate.
- * @param[out] certBuffer Which will be having the encoded value of the certificate requested.
- * @param[out] certSize Which will be having the size of the buffer.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
- */
-int  c_certsvc_pkcs12_get_certificate_buffer_from_store(CertStoreType storeType, const char *gname, char **certBuffer, size_t *certSize);
-
-/**
- * To delete the certificate from the specified store (VPN_STORE, WIFI_STORE, EMAIL_STORE, SYSTEM_STORE, ALL_STORE).
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] gname Referred as group name, is the key for accessing the certificate.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_INVALID_STORE_TYPE.
- */
-int  c_certsvc_pkcs12_delete_certificate_from_store(CertStoreType storeType, const char* gname);
-
-/**
- * To free the certificate list which got generated from
- * c_certsvc_pkcs12_get_certificate_list_from_store() function.
- *
- * @param[in] certList Linked-list having all the information about each certificate present in a store.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL.
- */
-int  c_certsvc_pkcs12_free_aliases_loaded_from_store(CertSvcStoreCertList **certList);
-
-/**
- * Checks if the alias exist in the user store or not.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] Alias Logical name for certificate bundle identification (can't be empty).
- * @param[out] isUnique A Boolean value which states if the alias is unique or not.
- * @return CERTSVC_SUCCESS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT.
- */
-int  c_certsvc_pkcs12_alias_exists_in_store(CertStoreType storeType, const char *alias, int *isUnique);
-
-/**
- * Function to get the size of the file passed.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[in] gname Refers to unique name referring to the certificate.
- * @param[out] certs Provides the list of certificates matching the unique name provided.
- * @param[out] ncerts Provides the number of certs in certs.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
- */
-int c_certsvc_pkcs12_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, size_t *ncerts);
-
-/**
- * To load the private key for the specified certificate mapped by an Alias.
- *
- * @param[in] alias Logical name for certificate bundle identification (can't be empty).
- * @param[out] pkey Will hold the private key value of the certificate.
- * @param[out] count Will hold the siz of the private key buffer.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
- */
-int  c_certsvc_pkcs12_private_key_load_from_store(CertStoreType storeType, const char *gname, char **pkey, size_t *count);
-
-/**
- * Gets the alias name for the gname passed.
- *
- * @param[in] instance CertSvcInstance object.
- * @param[in] gname Certificate identification of pfx/pkcs file.
- * @param[out] alias Alias name for the given gname.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_WRONG_ARGUMENT
- */
-int c_certsvc_pkcs12_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias);
-
-/**
- * To get the list of only end user certificate information present in a store. User will be getting
- * the information in a linked list where every list will contain Alias, Path to certificate,
- * Certificate status of all the certificates present in the specified store.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[out] certList Linked-list having all the information about each certificate present in a store.
- * @param[out] length provides the length of the linked list.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
- */
-int c_certsvc_pkcs12_get_end_user_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList **certList, size_t *length);
-
-/**
- * To get the list of only root/trusted certificate information present in a store. User will be getting
- * the information in a linked list where every list will contain Alias, Path to certificate,
- * Certificate status of all the certificates present in the specified store.
- *
- * @param[in] storeType Refers to VPN_STORE / WIFI_STORE / EMAIL_STORE / SYSTEM_STORE / ALL_STORE.
- * @param[out] certList Linked-list having all the information about each certificate present in a store.
- * @param[out] length provides the length of the linked list.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_INVALID_STORE_TYPE.
- */
-int c_certsvc_pkcs12_get_root_certificate_list_from_store(CertStoreType storeType, CertSvcStoreCertList **certList, size_t *length);
+int pkcs12_import_from_file_to_store(CertStoreType storeType, const char *path, const char *password, const char *alias);
 
 /**
  * TO check if the p12/pfx file is protected by password or not.
@@ -176,19 +41,4 @@ int c_certsvc_pkcs12_get_root_certificate_list_from_store(CertStoreType storeTyp
  * @param[out] passworded A boolean value to state if the file is protected by password or not.
  * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT.
  */
-int  c_certsvc_pkcs12_has_password(const char *filepath, int *passworded);
-
-/**
- * To free the certificates from memory which was loaded by
- * c_certsvc_pkcs12_load_certificates() functon.
- *
- * @param[in] certs A pointer holding all the certificates in memory.
- * @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_IO_ERROR.
- */
-void c_certsvc_pkcs12_free_certificates(char **certs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+int pkcs12_has_password(const char *filepath, int *passworded);