summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Sawicki <p.sawicki2@partner.samsung.com>2017-09-06 09:22:36 +0200
committerPiotr Sawicki <p.sawicki2@partner.samsung.com>2017-09-08 09:08:00 +0200
commit57055817ef087214dcfc6b9cca4e22191d9dbb46 (patch)
tree9678ca589bf37442ee61adda7a974b7417571344
parentd91be673b26b8549957545855016748c72a4b853 (diff)
downloadcert-svc-57055817ef087214dcfc6b9cca4e22191d9dbb46.tar.gz
cert-svc-57055817ef087214dcfc6b9cca4e22191d9dbb46.tar.bz2
cert-svc-57055817ef087214dcfc6b9cca4e22191d9dbb46.zip
Introduce certsvc_pkcs12_import_from_file_to_store_ret_list()
This new function works in the same way as the certsvc_pkcs12_import_from_file_to_store does, but additionally it returns the list of imported certificates. Change-Id: Id8af8229e7e5dc0eedc208ec940c1e1e5430ab8d
-rw-r--r--src/cert-svc/cpkcs12.h33
-rw-r--r--src/vcore/api.cpp36
-rw-r--r--src/vcore/pkcs12.cpp110
-rw-r--r--src/vcore/pkcs12.h8
-rw-r--r--tests/pkcs12/new_test_cases.cpp102
5 files changed, 278 insertions, 11 deletions
diff --git a/src/cert-svc/cpkcs12.h b/src/cert-svc/cpkcs12.h
index 101d2e3..5bd8c9f 100644
--- a/src/cert-svc/cpkcs12.h
+++ b/src/cert-svc/cpkcs12.h
@@ -282,6 +282,39 @@ int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
CertSvcString password,
CertSvcString alias);
+
+/**
+ * Import PKCS#12 bundle(with .pfx or .p12) or certificate(base64 form with .crt
+ * or .pem suffix) from file to specified store and return imported list of certificates.
+ * If password isn't needed, create CertSvcString @a password with null input on
+ * certsvc_string_new(). Refer certsvc_string_new() API description
+ *
+ * @param[in] instance CertSvcInstance object
+ * @param[in] storeType cert-svc store type to query
+ * @param[in] path Path of the certificate which needs to be imported
+ * @param[in] password Password if the file to import is password-protected which can be
+ * empty CertSvcString in case of not-password-protected
+ * @param[in] alias Primary key for certificate bundle identification (can't be empty)
+ * @param[out] certList cert list in store returned in linked list. Free by
+ * certsvc_pkcs12_free_certificate_list_loaded_from_store() after use
+ * @param[out] length length of output @a certList
+ *
+ * @return #CERTSVC_SUCCESS on success, otherwise a zero or negative error value
+ *
+ * @see certsvc_instance_new()
+ * @see certsvc_instance_free()
+ * @see certsvc_string_new()
+ * @see certsvc_string_free()
+ * @see #CertStoreType
+ */
+int certsvc_pkcs12_import_from_file_to_store_ret_list(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString path,
+ CertSvcString password,
+ CertSvcString alias,
+ CertSvcStoreCertList **certList,
+ size_t *length);
+
/**
* Delete the certificate with gname provided from cert-svc store.
*
diff --git a/src/vcore/api.cpp b/src/vcore/api.cpp
index 1059c72..58fc882 100644
--- a/src/vcore/api.cpp
+++ b/src/vcore/api.cpp
@@ -891,10 +891,12 @@ err:
CertStoreType storeType,
CertSvcString path,
CertSvcString pass,
- CertSvcString pfxIdString)
+ CertSvcString pfxIdString,
+ CertSvcStoreCertList **certList,
+ size_t *length)
{
return pkcs12_import_from_file_to_store(storeType, path.privateHandler, pass.privateHandler,
- pfxIdString.privateHandler);
+ pfxIdString.privateHandler, certList, length);
}
inline int pkcsGetAliasNameForCertInStore(CertStoreType storeType,
@@ -1726,7 +1728,35 @@ int certsvc_pkcs12_import_from_file_to_store(CertSvcInstance instance,
return CERTSVC_INVALID_STORE_TYPE;
}
- return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString);
+ return impl(instance)->pkcsImportToStore(storeType, path, password, pfxIdString,
+ NULL, NULL);
+ } catch (...) {
+ LogError("Exception occured from pkcsImportToStore");
+ return CERTSVC_FAIL;
+ }
+}
+
+int certsvc_pkcs12_import_from_file_to_store_ret_list(CertSvcInstance instance,
+ CertStoreType storeType,
+ CertSvcString path,
+ CertSvcString password,
+ CertSvcString pfxIdString,
+ CertSvcStoreCertList **certList,
+ size_t *length)
+{
+ try {
+ if (certList == NULL || length == NULL) {
+ LogError("Wrong argument.");
+ return CERTSVC_WRONG_ARGUMENT;
+ }
+
+ 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,
+ certList, length);
} catch (...) {
LogError("Exception occured from pkcsImportToStore");
return CERTSVC_FAIL;
diff --git a/src/vcore/pkcs12.cpp b/src/vcore/pkcs12.cpp
index d2ec9d8..3e0cc70 100644
--- a/src/vcore/pkcs12.cpp
+++ b/src/vcore/pkcs12.cpp
@@ -98,6 +98,73 @@ inline CertStoreType nextStore(CertStoreType type)
}
}
+CertSvcStoreCertList *createStoreListNode(const std::string &gname, const std::string &title,
+ CertStoreType storeType)
+{
+ CertSvcStoreCertList *node = (CertSvcStoreCertList *)malloc(sizeof(CertSvcStoreCertList));
+
+ if (node == NULL)
+ return NULL;
+
+ node->gname = strdup(gname.c_str());
+ node->title = strdup(title.c_str());
+ node->status = ENABLED;
+ node->storeType = storeType;
+ node->next = NULL;
+
+ if (node->gname == NULL || node->title == NULL) {
+ free(node->gname);
+ free(node->title);
+ free(node);
+ return NULL;
+ }
+
+ return node;
+}
+
+void destroyStoreList(CertSvcStoreCertList **certList, size_t *length)
+{
+ if (certList == NULL || length == NULL) {
+ return;
+ }
+
+ CertSvcStoreCertList *list = *certList;
+
+ while (list) {
+ CertSvcStoreCertList *next = list->next;
+ free(list->gname);
+ free(list->title);
+ free(list);
+ list = next;
+ }
+
+ *length = 0;
+}
+
+void addStoreListNode(CertSvcStoreCertList **list, CertSvcStoreCertList *node)
+{
+ node->next = *list;
+ *list = node;
+}
+
+int appendStoreListNode(CertSvcStoreCertList **certList, size_t *length,
+ const std::string &gname, const std::string &alias,
+ CertStoreType storeType)
+{
+ if (certList == NULL || length == NULL)
+ return CERTSVC_SUCCESS;
+
+ CertSvcStoreCertList *node = createStoreListNode(gname, alias, storeType);
+ if (node == NULL) {
+ return CERTSVC_BAD_ALLOC;
+ }
+
+ addStoreListNode(certList, node);
+ (*length)++;
+
+ return CERTSVC_SUCCESS;
+}
+
std::string generateGname(void)
{
int generator;
@@ -610,7 +677,9 @@ int insertToStore(CertStoreType storeTypes,
const std::string &endCertName,
const std::string &endCertBuffer,
const std::vector<std::string> &certChainName,
- const std::vector<std::string> &certChainBuffer)
+ const std::vector<std::string> &certChainBuffer,
+ CertSvcStoreCertList **certList,
+ size_t *length)
{
size_t ncerts = certChainName.size();
@@ -634,6 +703,12 @@ int insertToStore(CertStoreType storeTypes,
return result;
}
+ int res = appendStoreListNode(certList, length, endCertName, alias, storeType);
+ if (res != CERTSVC_SUCCESS) {
+ LogError("Failed to append store list node.");
+ return result;
+ }
+
for (size_t i = 0; i < ncerts; i++) {
if (i == ncerts - 1)
result = installChainCert(storeType, certChainBuffer[i], certChainName[i], endCertName,
@@ -646,6 +721,12 @@ int insertToStore(CertStoreType storeTypes,
LogError("Failed to install the ca certificates. result : " << result);
return result;
}
+
+ int res = appendStoreListNode(certList, length, certChainName[i], alias, storeType);
+ if (res != CERTSVC_SUCCESS) {
+ LogError("Failed to append store list node.");
+ return result;
+ }
}
}
@@ -654,7 +735,7 @@ int insertToStore(CertStoreType storeTypes,
}
int insertToStorePEM(CertStoreType storeTypes, const std::string &path, const std::string &gname,
- const std::string &alias)
+ const std::string &alias, CertSvcStoreCertList **certList, size_t *length)
{
std::string content = readFromFile(path);
@@ -683,6 +764,13 @@ int insertToStorePEM(CertStoreType storeTypes, const std::string &path, const st
return result;
}
+ int res = appendStoreListNode(certList, length, gname, alias, storeType);
+ if (res != CERTSVC_SUCCESS) {
+ rollbackStore(storeTypes, gname);
+ LogError("Failed to append store list node.");
+ return result;
+ }
+
LogDebug("Success to install PEM/CRT to db store : " << storeType);
}
@@ -696,7 +784,9 @@ int insertToStorePEM(CertStoreType storeTypes, const std::string &path, const st
int pkcs12_import_from_file_to_store(CertStoreType storeTypes,
const char *_path,
const char *_password,
- const char *_alias)
+ const char *_alias,
+ CertSvcStoreCertList **certList,
+ size_t *length)
{
int result = 0;
@@ -731,10 +821,12 @@ int pkcs12_import_from_file_to_store(CertStoreType storeTypes,
if (strcasecmp(suffix.c_str(), ".pem") == 0 || strcasecmp(suffix.c_str(), ".crt") == 0) {
std::string gnamePEM = generateGname();
- result = insertToStorePEM(storeTypes, path, gnamePEM, alias);
+ result = insertToStorePEM(storeTypes, path, gnamePEM, alias, certList, length);
- if (result != CERTSVC_SUCCESS)
+ if (result != CERTSVC_SUCCESS) {
+ destroyStoreList(certList, length);
LogError("Failed to install PEM/CRT file to store. gname : " << gnamePEM << " result : " << result);
+ }
return result;;
}
@@ -806,10 +898,14 @@ int pkcs12_import_from_file_to_store(CertStoreType storeTypes,
endCertName,
endCertBuffer,
certChainName,
- certChainBuffer);
+ certChainBuffer,
+ certList,
+ length);
- if (result != CERTSVC_SUCCESS)
+ if (result != CERTSVC_SUCCESS) {
+ destroyStoreList(certList, length);
rollbackStore(storeTypes, endCertName);
+ }
LogDebug("Success to import pkcs12 to store");
return result;
diff --git a/src/vcore/pkcs12.h b/src/vcore/pkcs12.h
index 89c1809..54df9a5 100644
--- a/src/vcore/pkcs12.h
+++ b/src/vcore/pkcs12.h
@@ -30,10 +30,16 @@
* @param[in] path Path to file.
* @param[in] password Password for opening the file.
* @param[in] alias Logical name for certificate bundle identification (can't be empty).
+ * @param[out] certList cert list in store returned in linked list. Free by
+ * certsvc_pkcs12_free_certificate_list_loaded_from_store()
+ * after use. Pass NULL if you don't want to return a list.
+ * @param[out] length length of output @a certList. Pass NULL if you don't
+ * want to return a list.
* @return CERTSVC_SUCCESS, CERTSVC_FAIL, CERTSVC_DUPLICATED_ALIAS, CERTSVC_IO_ERROR, CERTSVC_WRONG_ARGUMENT, CERTSVC_BAD_ALLOC.
*/
int pkcs12_import_from_file_to_store(CertStoreType storeType, const char *path,
- const char *password, const char *alias);
+ const char *password, const char *alias, CertSvcStoreCertList **certList,
+ size_t *length);
/**
* TO check if the p12/pfx file is protected by password or not.
diff --git a/tests/pkcs12/new_test_cases.cpp b/tests/pkcs12/new_test_cases.cpp
index 69ac7b7..6004125 100644
--- a/tests/pkcs12/new_test_cases.cpp
+++ b/tests/pkcs12/new_test_cases.cpp
@@ -952,3 +952,105 @@ RUNNER_TEST(CERTSVC_PKCS12_1028_certsvc_set_cert_to_disabled_and_get_status_for_
FREE_INSTANCE
}
+static void remove_certificates_from_store(CertSvcInstance &instance, CertStoreType storeType)
+{
+ int result;
+ size_t length = 0;
+ CertSvcStoreCertList *certList = NULL;
+ CertSvcStoreCertList *certListIter = NULL;
+
+ result = certsvc_pkcs12_get_certificate_list_from_store(instance, storeType, DISABLED, &certList,
+ &length);
+ RUNNER_ASSERT_MSG(result == CERTSVC_SUCCESS, "Getting certificate list from system store failed");
+
+ certListIter = certList;
+
+ while (certListIter) {
+ CertSvcString Gname = wrapper_certsvc_string_new(certListIter->gname);
+
+ result = certsvc_pkcs12_delete_certificate_from_store(instance, storeType, Gname);
+
+ certsvc_string_free(Gname);
+ certListIter = certListIter->next;
+ }
+}
+
+size_t count_certificates_on_list(CertSvcStoreCertList *certList)
+{
+ size_t counter = 0;
+
+ while (certList) {
+ counter++;
+ certList = certList->next;
+ }
+
+ return counter;
+}
+
+RUNNER_TEST(CERTSVC_PKCS12_1029_install_certs_from_p12_file_using_wifi_store_ret_list)
+{
+ int result;
+ CertSvcStoreCertList *certList = NULL;
+ size_t length = 0;
+
+ CREATE_INSTANCE
+
+ remove_certificates_from_store(instance, WIFI_STORE);
+
+ CertSvcString Alias = wrapper_certsvc_string_new("P12-WifiUser-wifi-store");
+ CertSvcString Path = wrapper_certsvc_string_new(TestData::UserP12WithPassPath.c_str());
+ CertSvcString Pass = wrapper_certsvc_string_new(TestData::UserP12Pass.c_str());
+
+ result = certsvc_pkcs12_import_from_file_to_store_ret_list(instance, WIFI_STORE, Path, Pass, Alias,
+ &certList, &length);
+ RUNNER_ASSERT_MSG(result == CERTSVC_SUCCESS, "Importing P12 file to WIFI store failed.");
+ RUNNER_ASSERT_MSG(length == 3, "There should be 3 imported certificates");
+ size_t count = count_certificates_on_list(certList);
+ RUNNER_ASSERT_MSG(length == count, "The length is different than number of elements on the list");
+
+ result = certsvc_pkcs12_free_certificate_list_loaded_from_store(instance, &certList);
+ RUNNER_ASSERT_MSG(result == CERTSVC_SUCCESS, "Freeing certificate list from system store failed");
+
+ remove_certificates_from_store(instance, WIFI_STORE);
+
+ certsvc_string_free(Alias);
+ certsvc_string_free(Path);
+ certsvc_string_free(Pass);
+
+ FREE_INSTANCE
+}
+
+RUNNER_TEST(CERTSVC_PKCS12_1030_install_certs_from_pem_file_using_wifi_store_ret_list)
+{
+ int result;
+ CertSvcStoreCertList *certList = NULL;
+ size_t length = 0;
+
+ CREATE_INSTANCE
+
+ remove_certificates_from_store(instance, WIFI_STORE);
+
+ CertSvcString PEMPath = wrapper_certsvc_string_new(TestData::ServerCertPemPath.c_str());
+ CertSvcString PEMPass = wrapper_certsvc_string_new(NULL);
+ // alias has been taken from PEM file
+ CertSvcString PEMAlias = wrapper_certsvc_string_new("PEM-WifiUser-wifi-store");
+
+ result = certsvc_pkcs12_import_from_file_to_store_ret_list(instance, WIFI_STORE, PEMPath, PEMPass, PEMAlias,
+ &certList, &length);
+ RUNNER_ASSERT_MSG(result == CERTSVC_SUCCESS, "Importing PEM file to WIFI store failed.");
+ RUNNER_ASSERT_MSG(length == 1, "There should be 3 imported certificates");
+ size_t count = count_certificates_on_list(certList);
+ RUNNER_ASSERT_MSG(length == count, "The length is different than number of elements on the list");
+
+ result = certsvc_pkcs12_free_certificate_list_loaded_from_store(instance, &certList);
+ RUNNER_ASSERT_MSG(result == CERTSVC_SUCCESS, "Freeing certificate list from system store failed");
+
+ remove_certificates_from_store(instance, WIFI_STORE);
+
+ certsvc_string_free(PEMAlias);
+ certsvc_string_free(PEMPath);
+ certsvc_string_free(PEMPass);
+
+ FREE_INSTANCE
+}
+