2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file cert-server-logic.c
18 * @author Madhan A K (madhan.ak@samsung.com)
19 * Kyungwook Tak (k.tak@samsung.com)
21 * @brief cert-server logic.
24 #include <sys/types.h>
30 #include <sys/smack.h>
31 #include <sys/socket.h>
33 #include <ckmc/ckmc-manager.h>
34 #include <ckmc/ckmc-error.h>
36 #include "orig/cert-service.h"
37 #include "orig/cert-service-debug.h"
38 #include <cert-svc/cerror.h>
39 #include <cert-svc/ccert.h>
40 #include <vcore/cert-svc-client.h>
42 #include <cert-server-logic.h>
44 static CertStatus int_to_CertStatus(int intval)
55 static int CertStatus_to_int(CertStatus status)
66 char *add_shared_owner_prefix(const char *name)
68 size_t alias_len = strlen(name) + strlen(ckmc_owner_id_system) + strlen(ckmc_owner_id_separator);
69 char *ckm_alias = (char *)malloc(alias_len + 1);
71 SLOGE("Failed to allocate memory");
74 memset(ckm_alias, 0, alias_len + 1);
75 strncat(ckm_alias, ckmc_owner_id_system, alias_len + 1);
76 strncat(ckm_alias, ckmc_owner_id_separator, alias_len + 1 - strlen(ckmc_owner_id_system));
77 strncat(ckm_alias, name, alias_len + 1 - strlen(ckmc_owner_id_system) + strlen(ckmc_owner_id_separator));
82 int ckmc_remove_alias_with_shared_owner_prefix(const char *name, int *result)
84 char *ckm_alias = add_shared_owner_prefix(name);
86 SLOGE("Failed to allocate memory");
87 return CERTSVC_BAD_ALLOC;
90 *result = ckmc_remove_alias(ckm_alias);
94 return CERTSVC_SUCCESS;
97 char *get_complete_path(const char *str1, const char *str2)
105 if (str1[strlen(str1) - 1] != '/')
106 as_result = asprintf(&result, "%s/%s", str1, str2);
108 as_result = asprintf(&result, "%s%s", str1, str2);
116 /* TODO: root ssl file system refactor */
117 int add_file_to_dir(const char* dir, const char* pGname, const char* pData, size_t dataLen)
119 char *systemFile = get_complete_path(dir, pGname);
121 SLOGE("Failed to get system file path.");
125 char realFile[FILENAME_MAX] = {0};
126 if (!realpath(systemFile, realFile)) {
127 SLOGE("Failed to get realpath. systemFile[%s]", systemFile);
131 FILE *stream = fopen(realFile, "ab");
133 SLOGE("Fail to open file [%s]", realFile);
137 if (fwrite(pData, sizeof(char), dataLen, stream) != dataLen) {
138 SLOGE("Fail to write file in system store.");
144 return CERTSVC_SUCCESS;
147 int add_file_to_system_cert_dir(const char* pGname, const char* pData, size_t dataLen)
149 return add_file_to_dir(SYSTEM_CERT_DIR, pGname, pData, dataLen);
152 /* TODO: root ssl file system refactor */
153 int del_file_from_dir(const char* dir, const char *pGname)
155 const char *systemFile = get_complete_path(dir, pGname);
157 SLOGE("Failed to construct source file path.");
161 char realFile[FILENAME_MAX] = {0};
162 if (!realpath(systemFile, realFile)) {
163 SLOGE("Failed to get realpath. systemFile[%s]", systemFile);
167 /* instead of removing the file, the file is trimmed to zero size */
168 FILE *stream = fopen(realFile, "wb");
170 SLOGE("Failed to open the file for writing, [%s].", realFile);
175 return CERTSVC_SUCCESS;
178 int del_file_from_system_cert_dir(const char *pGname)
180 return del_file_from_dir(SYSTEM_CERT_DIR, pGname);
183 int execute_insert_update_query(sqlite3 *db_handle, char *query)
186 SLOGE("Database not initialised.");
187 return CERTSVC_WRONG_ARGUMENT;
191 SLOGE("Query is NULL.");
192 return CERTSVC_WRONG_ARGUMENT;
195 /* Begin transaction */
196 int result = sqlite3_exec(db_handle, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
197 if (result != SQLITE_OK) {
198 SLOGE("Failed to begin transaction.");
202 /* Executing command */
203 result = sqlite3_exec(db_handle, query, NULL, NULL, NULL);
204 if (result != SQLITE_OK) {
205 SLOGE("Failed to execute query (%s).", query);
209 /* Committing the transaction */
210 result = sqlite3_exec(db_handle, "COMMIT", NULL, NULL, NULL);
212 SLOGE("Failed to commit transaction. Roll back now.");
213 result = sqlite3_exec(db_handle, "ROLLBACK", NULL, NULL, NULL);
214 if (result != SQLITE_OK)
215 SLOGE("Failed to commit transaction. Roll back now.");
220 SLOGD("Transaction Commit and End.");
222 return CERTSVC_SUCCESS;
225 int execute_select_query(sqlite3 *db_handle, char *query, sqlite3_stmt **stmt)
227 if (!db_handle || !query)
228 return CERTSVC_WRONG_ARGUMENT;
230 sqlite3_stmt *stmts = NULL;
231 if (sqlite3_prepare_v2(db_handle, query, strlen(query), &stmts, NULL) != SQLITE_OK) {
232 SLOGE("sqlite3_prepare_v2 failed [%s].", query);
237 return CERTSVC_SUCCESS;
240 int write_to_file(const char *fileName, const char *mode_of_writing, const char *certBuffer, size_t certLength)
242 int result = CERTSVC_SUCCESS;
243 FILE *fp_write = NULL;
245 if (!certBuffer || certLength <= 0) {
246 SLOGE("Input buffer is NULL.");
247 return CERTSVC_WRONG_ARGUMENT;
250 if (!(fp_write = fopen(fileName, mode_of_writing))) {
251 SLOGE("Failed to open the file for writing, [%s].", fileName);
255 /* if mode of writing is to append, then goto end of file */
256 if (strcmp(mode_of_writing,"ab") == 0)
257 fseek(fp_write, 0L, SEEK_END);
259 if (fwrite(certBuffer, sizeof(char), certLength, fp_write) != certLength) {
260 SLOGE("Fail to write into file.");
261 result = CERTSVC_FAIL;
265 /* adding empty line at the end */
266 fwrite("\n",sizeof(char), 1, fp_write);
275 int write_to_ca_cert_crt_file(const char *mode_of_writing, const char *certBuffer, size_t certLength)
277 return write_to_file(CERTSVC_CRT_FILE_PATH, mode_of_writing, certBuffer, certLength);
280 int saveCertificateToStore(
285 if (!pGname || !pData || dataLen < 1) {
286 SLOGE("Invalid input parameter passed.");
287 return CERTSVC_WRONG_ARGUMENT;
290 ckmc_policy_s cert_policy;
291 cert_policy.password = NULL;
292 cert_policy.extractable = true;
294 ckmc_raw_buffer_s cert_data;
295 cert_data.data = (unsigned char *)pData;
296 cert_data.size = dataLen;
298 char *ckm_alias = add_shared_owner_prefix(pGname);
300 SLOGE("Failed to make alias. memory allocation error.");
301 return CERTSVC_BAD_ALLOC;
304 int result = ckmc_save_data(ckm_alias, cert_data, cert_policy);
307 if (result != CKMC_ERROR_NONE) {
308 SLOGE("Failed to save trusted data. ckm errcode[%d]", result);
312 return CERTSVC_SUCCESS;
315 int saveCertificateToSystemStore(
320 if (!pGname || !pData || dataLen < 1) {
321 SLOGE("Invalid input parameter passed.");
322 return CERTSVC_WRONG_ARGUMENT;
325 int result = add_file_to_system_cert_dir(pGname, pData, dataLen);
326 if (result != CERTSVC_SUCCESS)
327 SLOGE("Failed to store the certificate in store.");
332 int get_certificate_buffer_from_store(
334 CertStoreType storeType,
339 int result = CERTSVC_SUCCESS;
341 char *tempBuffer = NULL;
343 sqlite3_stmt *stmt = NULL;
346 SLOGE("Invalid input parameter passed.");
347 return CERTSVC_WRONG_ARGUMENT;
350 if (storeType != SYSTEM_STORE)
351 query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
352 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
353 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
355 query = sqlite3_mprintf("select certificate from ssl where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
356 pGname, ENABLED, ENABLED);
358 result = execute_select_query(db_handle, query, &stmt);
359 if (result != CERTSVC_SUCCESS) {
360 SLOGE("Querying database failed.");
361 result = CERTSVC_FAIL;
365 records = sqlite3_step(stmt);
366 if (records != SQLITE_ROW || records == SQLITE_DONE) {
367 SLOGE("No valid records found for given gname [%s].",pGname);
368 result = CERTSVC_FAIL;
372 tempBuffer = (char *)malloc(sizeof(char) * VCORE_MAX_RECV_DATA_SIZE);
374 SLOGE("Fail to allocate memory");
375 result = CERTSVC_FAIL;
379 memset(tempBuffer, 0x00, VCORE_MAX_RECV_DATA_SIZE);
381 if (storeType == SYSTEM_STORE)
382 result = getCertificateDetailFromSystemStore(db_handle, pGname, tempBuffer, certSize);
384 result = getCertificateDetailFromStore(db_handle, storeType, PEM_CRT, pGname, tempBuffer, certSize);
386 if (result != CERTSVC_SUCCESS) {
387 SLOGE("Failed to set request data.");
388 result = CERTSVC_WRONG_ARGUMENT;
392 *certBuffer = tempBuffer;
395 if (result != CERTSVC_SUCCESS)
402 sqlite3_finalize(stmt);
407 int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t certLength)
409 int result = CERTSVC_SUCCESS;
416 sqlite3_stmt *stmt = NULL;
418 int storeType[4] = {SYSTEM_STORE, WIFI_STORE, VPN_STORE, EMAIL_STORE};
420 /* During install of a root certificate, the root certificate gets appended at
421 * the end to optimise the write operation onto ca-certificate.crt file. */
422 if (certBuffer && certLength > 0) {
423 result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
424 if (result != CERTSVC_SUCCESS) {
425 SLOGE("Failed to write to file.");
426 result = CERTSVC_FAIL;
432 /* get the ssl certificate from database */
434 query = sqlite3_mprintf("select certificate from ssl where enabled=%d and is_root_app_enabled=%d", ENABLED, ENABLED);
435 else if (count > 0 && count < 4)
436 /* gets all the gname which is marked as root certificate and enabled = TRUE */
437 query = sqlite3_mprintf("select gname from %Q where is_root_cert=%d and enabled=%d and is_root_app_enabled=%d", \
438 ((count == 1)?"wifi":(count == 2)?"vpn":"email"), ENABLED, ENABLED, ENABLED);
440 result = execute_select_query(db_handle, query, &stmt);
441 if (result != CERTSVC_SUCCESS) {
442 SLOGE("Querying database failed.");
446 /* update the ca-certificate.crt file */
448 records = sqlite3_step(stmt);
449 if (records != SQLITE_ROW || records == SQLITE_DONE) {
450 result = CERTSVC_SUCCESS;
454 if (records == SQLITE_ROW) {
460 /* gets the certificate from database for system store */
461 text = (const char *)sqlite3_column_text(stmt, 0);
463 certLength = strlen(text);
464 certBuffer = strndup(text, certLength);
467 /* gets the certificate from key-manager for other stores */
468 text = (const char *)sqlite3_column_text(stmt, 0);
470 pValue = strndup(text, strlen(text));
472 result = get_certificate_buffer_from_store(db_handle, storeType[count], pValue, &certBuffer, &certLength);
473 if (result != CERTSVC_SUCCESS) {
474 SLOGE("Failed to get certificate buffer from key-manager.");
481 result = write_to_ca_cert_crt_file("wb", certBuffer, certLength);
483 result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
485 if (result != CERTSVC_SUCCESS) {
486 SLOGE("Failed to write to file.");
487 result = CERTSVC_FAIL;
500 SLOGD("Successfully updated ca-certificate.crt file.");
507 sqlite3_finalize(stmt);
512 int enable_disable_cert_status(
514 CertStoreType storeType,
519 int ckmc_result = CKMC_ERROR_UNKNOWN;
520 int result = CERTSVC_SUCCESS;
523 size_t certLength = 0;
524 char *certBuffer = NULL;
526 const char *text = NULL;
527 sqlite3_stmt *stmt = NULL;
529 if (status != DISABLED && status != ENABLED) {
530 SLOGE("Invalid cert status");
531 return CERTSVC_INVALID_STATUS;
534 query = sqlite3_mprintf("select * from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
535 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
537 SLOGE("Failed to generate query");
538 return CERTSVC_BAD_ALLOC;
541 result = execute_select_query(db_handle, query, &stmt);
544 if (result != CERTSVC_SUCCESS || !stmt) {
545 SLOGE("Querying database failed.");
549 records = sqlite3_step(stmt);
550 sqlite3_finalize(stmt);
553 if (records != SQLITE_ROW) {
554 SLOGE("No valid records found.");
558 if (status == DISABLED) {
559 /* check certificate presence in disabled_certs table before inserting */
560 query = sqlite3_mprintf("select * from disabled_certs where gname=%Q", pGname);
562 SLOGE("Failed to generate query");
563 return CERTSVC_BAD_ALLOC;
566 result = execute_select_query(db_handle, query, &stmt);
570 if (result != CERTSVC_SUCCESS) {
571 SLOGE("Querying database failed.");
575 records = sqlite3_step(stmt);
576 sqlite3_finalize(stmt);
579 if (records == SQLITE_ROW) {
580 SLOGE("Selected certificate identifier is already disabled.", pGname);
584 /* get certificate from keymanager*/
585 result = get_certificate_buffer_from_store(db_handle, storeType, pGname, &certBuffer, &certSize);
586 if (result != CERTSVC_SUCCESS) {
587 SLOGE("Failed to get certificate buffer. result[%d]", result);
591 /* inserting the disabled certificate to disabled_certs table */
592 query = sqlite3_mprintf("insert into disabled_certs (gname, certificate) values (%Q, %Q)", pGname, certBuffer);
596 SLOGE("Failed to generate query");
597 return CERTSVC_BAD_ALLOC;
600 result = execute_insert_update_query(db_handle, query);
603 if (result != CERTSVC_SUCCESS) {
604 SLOGE("Insert to database failed.");
608 if (storeType != SYSTEM_STORE) {
609 result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
611 if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
612 SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
617 result = del_file_from_system_cert_dir(pGname);
618 if (result != CERTSVC_SUCCESS) {
619 SLOGE("Error in del_file_from_system_cert_dir. ret[%d]", result);
623 } else { /* moving the certificate to enabled state */
624 query = sqlite3_mprintf("select certificate from disabled_certs where gname=%Q", pGname);
626 SLOGE("Failed to generate query");
627 return CERTSVC_BAD_ALLOC;
630 result = execute_select_query(db_handle, query, &stmt);
633 if (result != CERTSVC_SUCCESS) {
634 SLOGE("Querying database failed.");
638 records = sqlite3_step(stmt);
639 if (records == SQLITE_ROW) {
640 text = (const char *)sqlite3_column_text(stmt, 0);
643 SLOGE("Invalid column text");
644 sqlite3_finalize(stmt);
648 certBuffer = strndup(text, strlen(text));
650 sqlite3_finalize(stmt);
653 SLOGE("Failed to allocate memory");
654 return CERTSVC_BAD_ALLOC;
657 certLength = strlen(certBuffer);
659 if (storeType == SYSTEM_STORE)
660 result = saveCertificateToSystemStore(pGname, certBuffer, certLength);
662 result = saveCertificateToStore(pGname, certBuffer, certLength);
666 if (result != CERTSVC_SUCCESS) {
667 SLOGE("Failed to save certificate to key-manager. ret[%d]", result);
671 query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
673 SLOGE("Failed to generate query");
674 return CERTSVC_BAD_ALLOC;
677 result = execute_insert_update_query(db_handle, query);
680 if (result != CERTSVC_SUCCESS) {
681 SLOGE("Unable to delete certificate entry from database. ret[%d]", result);
687 if (is_root_app == ENABLED)
688 query = sqlite3_mprintf("update %Q set is_root_app_enabled=%d , enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
689 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), CertStatus_to_int(status), status, pGname);
691 query = sqlite3_mprintf("update %Q set enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
692 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), CertStatus_to_int(status), pGname);
695 SLOGE("Failed to generate query");
696 return CERTSVC_BAD_ALLOC;
699 result = execute_insert_update_query(db_handle, query);
702 if (result != CERTSVC_SUCCESS) {
703 SLOGE("Update failed. ret[%d]", result);
710 int setCertificateStatusToStore(
712 CertStoreType storeType,
718 SLOGE("Invalid input parameter passed.");
719 return CERTSVC_WRONG_ARGUMENT;
722 int result = enable_disable_cert_status(db_handle, storeType, is_root_app, pGname, status);
723 if (result != CERTSVC_SUCCESS) {
724 SLOGE("Failed to disable certificate.");
728 SLOGD("Successfully updated the certificate status from %s to %s.",
729 (status == DISABLED) ? "ENABLED" : "DISABLED", (status == DISABLED) ? "DISABLED" : "ENABLED");
730 return CERTSVC_SUCCESS;
733 int getCertificateStatusFromStore(
735 CertStoreType storeType,
740 SLOGE("Invalid input parameter passed.");
741 return CERTSVC_WRONG_ARGUMENT;
744 char *query = sqlite3_mprintf("select gname, common_name, enabled from %Q where gname=%Q",\
745 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
746 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
748 SLOGE("Failed to generate query");
749 return CERTSVC_BAD_ALLOC;
752 sqlite3_stmt *stmt = NULL;
753 int result = execute_select_query(db_handle, query, &stmt);
756 if (result != CERTSVC_SUCCESS || !stmt) {
757 SLOGE("Querying database failed.");
762 result = sqlite3_step(stmt);
763 if (result != SQLITE_ROW || result == SQLITE_DONE) {
764 SLOGE("No valid records found.");
766 sqlite3_finalize(stmt);
770 *status = int_to_CertStatus(sqlite3_column_int(stmt, 2));
772 sqlite3_finalize(stmt);
774 return CERTSVC_SUCCESS;
777 int check_alias_exist_in_database(
779 CertStoreType storeType,
783 sqlite3_stmt *stmt = NULL;
785 if (!alias || !isUnique) {
786 SLOGE("Invalid input parameter passed.");
787 return CERTSVC_WRONG_ARGUMENT;
790 char *query = sqlite3_mprintf("select * from %Q where common_name=%Q", ((storeType == WIFI_STORE)? "wifi" : \
791 (storeType == VPN_STORE)? "vpn" : "email"),alias);
794 SLOGE("Failed to generate query");
795 return CERTSVC_BAD_ALLOC;
798 int result = execute_select_query(db_handle, query, &stmt);
801 if (result != CERTSVC_SUCCESS || !stmt) {
802 SLOGE("Querying database failed.");
806 result = sqlite3_step(stmt);
807 sqlite3_finalize(stmt);
809 if (result != SQLITE_ROW)
810 *isUnique = CERTSVC_TRUE;
812 *isUnique = CERTSVC_FALSE;
814 return CERTSVC_SUCCESS;
817 int installCertificateToStore(
819 CertStoreType storeType,
821 const char *common_name,
822 const char *private_key_gname,
823 const char *associated_gname,
824 const char *dataBlock,
829 || (certType == P12_END_USER && !common_name && !private_key_gname)
830 || (certType != P12_END_USER && !common_name && !associated_gname)) {
831 SLOGE("Invalid input parameter passed.");
832 return CERTSVC_WRONG_ARGUMENT;
835 if (storeType != SYSTEM_STORE
836 && saveCertificateToStore(
839 dataBlockLen) != CERTSVC_SUCCESS) {
840 SLOGE("FAIL to save certificate to key-manager.");
844 if (certType == P12_PKEY) {
845 SLOGD("Don't save private key in store");
846 return CERTSVC_SUCCESS;
850 if (certType == P12_END_USER && private_key_gname) {
851 query = sqlite3_mprintf("insert into %Q (gname, common_name, private_key_gname, associated_gname, enabled, is_root_app_enabled) "\
852 "values (%Q, %Q, %Q, %Q, %d, %d)",((storeType == WIFI_STORE)? "wifi" : \
853 (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, private_key_gname, pGname, ENABLED, ENABLED);
854 } else if (certType == PEM_CRT || certType == P12_TRUSTED) {
855 query = sqlite3_mprintf("insert into %Q (gname, common_name, is_root_cert, associated_gname, enabled, is_root_app_enabled) values "\
856 "(%Q, %Q, %d, %Q, %d, %d)", ((storeType == WIFI_STORE)? "wifi" : \
857 (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, ENABLED, associated_gname, ENABLED, ENABLED);
858 } else if (certType == P12_INTERMEDIATE) {
859 query = sqlite3_mprintf("insert into %Q (gname, common_name, associated_gname, enabled, is_root_app_enabled) values (%Q, %Q, %Q, %d, %d)", \
860 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"),
861 pGname, common_name, associated_gname, ENABLED, ENABLED);
865 SLOGE("Failed to generate query");
866 return CERTSVC_BAD_ALLOC;
869 int result = execute_insert_update_query(db_handle, query);
872 if (result != CERTSVC_SUCCESS) {
873 SLOGE("Insert to database failed.");
877 return CERTSVC_SUCCESS;
880 int checkAliasExistsInStore(
882 CertStoreType storeType,
887 SLOGE("Invalid input parameter passed.");
888 return CERTSVC_WRONG_ARGUMENT;
891 *isUnique = CERTSVC_FAIL;
892 int result = check_alias_exist_in_database(db_handle, storeType, alias, isUnique);
893 if (result != CERTSVC_SUCCESS) {
894 SLOGE("Failed to check_alias_exist_in_database. err[%d]", result);
898 if (*isUnique == CERTSVC_TRUE) {
899 SLOGD("Alias (%s) does not exist in %s store.",
901 (storeType == VPN_STORE) ? "VPN" :
902 (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
904 SLOGD("Alias (%s) exist in %s store.",
906 (storeType == VPN_STORE) ? "VPN" :
907 (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
910 return CERTSVC_SUCCESS;
913 int getCertificateDetailFromStore(
915 CertStoreType storeType,
921 int result = CERTSVC_SUCCESS;
924 const char *text = NULL;
925 sqlite3_stmt *stmt = NULL;
926 ckmc_raw_buffer_s *cert_data = NULL;
928 if (!pGname || !pOutData) {
929 SLOGE("Invalid input parameter passed.");
930 return CERTSVC_WRONG_ARGUMENT;
933 /* start constructing query */
934 if (certType == P12_PKEY) {
935 /* From the given certificate identifier, get the associated_gname for the certificate.
936 * Then query the database for records matching the associated_gname to get the private key */
937 query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", \
938 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), pGname);
940 SLOGE("Failed to generate query");
941 return CERTSVC_BAD_ALLOC;
944 result = execute_select_query(db_handle, query, &stmt);
947 if (result != CERTSVC_SUCCESS) {
948 SLOGE("Querying database failed.");
952 records = sqlite3_step(stmt);
953 if (records != SQLITE_ROW) {
954 SLOGE("No valid records found.");
955 sqlite3_finalize(stmt);
959 text = (const char *)sqlite3_column_text(stmt, 0);
962 SLOGE("No valid column text");
963 sqlite3_finalize(stmt);
967 query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
968 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), text, ENABLED, ENABLED);
970 sqlite3_finalize(stmt);
971 } else if (storeType != SYSTEM_STORE) {
972 query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
973 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
974 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
978 SLOGE("Failed to generate query");
979 return CERTSVC_BAD_ALLOC;
982 result = execute_select_query(db_handle, query, &stmt);
985 if (result != CERTSVC_SUCCESS) {
986 SLOGE("Querying database failed.");
990 records = sqlite3_step(stmt);
991 if (records != SQLITE_ROW) {
992 SLOGE("No valid records found.");
993 sqlite3_finalize(stmt);
997 if (certType == P12_PKEY) {
998 if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
999 SLOGE("No valid column text");
1000 sqlite3_finalize(stmt);
1001 return CERTSVC_FAIL;
1007 char *ckm_alias = add_shared_owner_prefix(pGname);
1009 SLOGE("Failed to make alias. memory allocation error.");
1010 return CERTSVC_BAD_ALLOC;
1013 result = ckmc_get_data(ckm_alias, NULL, &cert_data);
1016 sqlite3_finalize(stmt);
1018 if (result != CKMC_ERROR_NONE) {
1019 SLOGE("Failed to get certificate from key-manager. ckm ret[%d]", result);
1020 *size = CERTSVC_FAIL;
1021 return CERTSVC_FAIL;
1024 memcpy(pOutData, cert_data->data, cert_data->size);
1025 pOutData[cert_data->size] = 0;
1026 *size = cert_data->size;
1028 ckmc_buffer_free(cert_data);
1030 return CERTSVC_SUCCESS;
1033 int getCertificateDetailFromSystemStore(
1039 int result = CERTSVC_SUCCESS;
1041 size_t certLength = 0;
1043 const char *text = NULL;
1044 sqlite3_stmt *stmt = NULL;
1047 SLOGE("Invalid input parameter passed.");
1048 return CERTSVC_WRONG_ARGUMENT;
1051 query = sqlite3_mprintf("select certificate from ssl where gname=%Q and is_root_app_enabled=%d", \
1052 pGname, ENABLED, ENABLED);
1054 SLOGE("Query is NULL.");
1055 return CERTSVC_FAIL;
1058 result = execute_select_query(db_handle, query, &stmt);
1059 sqlite3_free(query);
1061 if (result != CERTSVC_SUCCESS) {
1062 SLOGE("Querying database failed.");
1066 records = sqlite3_step(stmt);
1067 if (records != SQLITE_ROW) {
1068 SLOGE("No valid records found for passed gname [%s].", pGname);
1069 sqlite3_finalize(stmt);
1070 return CERTSVC_FAIL;
1073 text = (const char *)sqlite3_column_text(stmt, 0);
1076 SLOGE("Fail to sqlite3_column_text");
1077 sqlite3_finalize(stmt);
1078 return CERTSVC_FAIL;
1081 certLength = strlen(text);
1082 if (certLength >= 4096) {
1083 sqlite3_finalize(stmt);
1084 SLOGE("certificate is too long");
1085 return CERTSVC_FAIL;
1088 memcpy(pOutData, text, certLength);
1089 pOutData[certLength] = 0;
1092 sqlite3_finalize(stmt);
1093 return CERTSVC_SUCCESS;
1096 int deleteCertificateFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *pGname) {
1098 int result = CERTSVC_SUCCESS;
1099 int ckmc_result = CKMC_ERROR_UNKNOWN;
1102 char *private_key_name = NULL;
1103 sqlite3_stmt *stmt = NULL;
1106 SLOGE("Invalid input parameter passed.");
1107 return CERTSVC_WRONG_ARGUMENT;
1110 if (storeType != SYSTEM_STORE) {
1111 /* start constructing query */
1112 query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" :\
1113 (storeType == VPN_STORE)? "vpn" : "email"), pGname);
1115 result = execute_select_query(db_handle, query, &stmt);
1116 if (result != CERTSVC_SUCCESS) {
1117 SLOGE("Querying database failed.");
1118 result = CERTSVC_FAIL;
1122 records = sqlite3_step(stmt);
1123 if ((records != SQLITE_ROW) || (records == SQLITE_DONE)) {
1124 SLOGE("No valid records found for passed gname [%s].",pGname);
1125 result = CERTSVC_FAIL;
1129 /* if a cert is having private-key in it, the private key should
1130 * be deleted first from key-manager, then the actual cert */
1131 if (sqlite3_column_text(stmt, 0) != NULL) {
1132 private_key_name = strdup((const char *)sqlite3_column_text(stmt, 0));
1133 result = ckmc_remove_alias_with_shared_owner_prefix(private_key_name, &ckmc_result);
1134 if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
1135 SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
1136 result = CERTSVC_FAIL;
1141 /* removing the actual cert */
1142 result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
1143 if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
1144 query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
1145 result = execute_insert_update_query(db_handle, query);
1146 if (result != CERTSVC_SUCCESS) {
1147 SLOGE("Unable to delete certificate entry from database.");
1148 result = CERTSVC_FAIL;
1154 sqlite3_free(query);
1159 sqlite3_finalize(stmt);
1163 query = sqlite3_mprintf("delete from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
1164 (storeType == VPN_STORE)? "vpn" : "email"), pGname);
1166 result = execute_insert_update_query(db_handle, query);
1167 if (result != CERTSVC_SUCCESS) {
1168 SLOGE("Unable to delete certificate entry from database.");
1169 result = CERTSVC_FAIL;
1173 SLOGE("Invalid store type passed.");
1174 result = CERTSVC_INVALID_STORE_TYPE;
1176 SLOGD("Success in deleting the certificate from store.");
1180 sqlite3_free(query);
1183 sqlite3_finalize(stmt);
1185 free(private_key_name);
1190 int getCertificateListFromStore(
1193 CertStoreType storeType,
1195 char **certListBuffer,
1199 int result = CERTSVC_SUCCESS;
1200 CertSvcStoreCertList *rootCertHead = NULL;
1201 CertSvcStoreCertList *tmpNode = NULL;
1202 CertSvcStoreCertList *currentNode = NULL;
1203 sqlite3_stmt *stmt = NULL;
1212 /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
1213 if (loopCount == (MAX_STORE_ENUMS - 1))
1216 /* Check if the passed store type matches with any of the in-built store type */
1217 if ((1 << loopCount) & storeType) {
1218 /* if a store type matches, put that value as storetype argument in the below function */
1219 CertStoreType tempStore = (CertStoreType) (1 << loopCount);
1220 SLOGD("Processing storetype [%s]", (tempStore == WIFI_STORE)? "WIFI" : (tempStore == VPN_STORE)? "VPN" : \
1221 (tempStore == EMAIL_STORE)? "EMAIL" : "SYSTEM");
1223 if (reqType == CERTSVC_GET_ROOT_CERTIFICATE_LIST) {
1224 // For get_root_certificate_list_from_store
1225 if (storeType == SYSTEM_STORE) {
1226 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where enabled=%d "\
1227 "and is_root_app_enabled=%d and order by common_name asc", "ssl", ENABLED, ENABLED);
1229 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1230 "is_root_cert IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
1231 (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
1232 (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1234 } else if (reqType == CERTSVC_GET_USER_CERTIFICATE_LIST) {
1235 // For get_end_user_certificate_list_from_store
1236 if (storeType == SYSTEM_STORE) {
1237 SLOGE("Invalid store type passed.");
1238 return CERTSVC_WRONG_ARGUMENT;
1240 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1241 "private_key_gname IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
1242 (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
1243 (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1246 // For get_certificate_list_from_store
1247 if (is_root_app != ENABLED) {
1248 /* Gets only the list of certificates where is_root_app = 1 (which are enabled by the master application) */
1249 if (tempStore == SYSTEM_STORE) {
1250 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1251 "is_root_app_enabled=%d order by common_name asc", \
1252 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1253 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1255 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where is_root_app_enabled=%d", \
1256 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1257 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1260 /* Gets all the certificates from store without any restrictions */
1261 if (tempStore == SYSTEM_STORE) {
1262 query = sqlite3_mprintf("select gname, common_name, enabled from %Q order by common_name asc", \
1263 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1264 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
1266 query = sqlite3_mprintf("select gname, common_name, enabled from %Q", \
1267 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1268 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
1273 result = execute_select_query(db_handle, query, &stmt);
1274 if (result != CERTSVC_SUCCESS) {
1275 SLOGE("Querying database failed.");
1276 result = CERTSVC_FAIL;
1281 records = sqlite3_step(stmt);
1282 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1284 SLOGE("No records found");
1285 result = CERTSVC_SUCCESS;
1292 if (records == SQLITE_ROW) {
1293 tmpNode = (CertSvcStoreCertList *)malloc(sizeof(CertSvcStoreCertList));
1295 SLOGE("Failed to allocate memory.");
1296 result = CERTSVC_BAD_ALLOC;
1299 tmpNode->next = NULL;
1300 const char *textGname = (const char *)sqlite3_column_text(stmt, 0);
1301 const char *textAlias = (const char *)sqlite3_column_text(stmt, 1);
1302 if (!textGname || !textAlias) {
1303 SLOGE("Failed to read texts from records");
1305 result = CERTSVC_FAIL;
1309 int gnameLen = strlen(textGname);
1310 int aliasLen = strlen(textAlias);
1312 tmpNode->gname = (char *)malloc(sizeof(char) * (gnameLen + 1));
1313 tmpNode->title = (char *)malloc(sizeof(char) * (aliasLen + 1));
1314 if (!tmpNode->title || !tmpNode->gname) {
1315 free(tmpNode->gname);
1316 free(tmpNode->title);
1318 SLOGE("Failed to allocate memory");
1319 result = CERTSVC_BAD_ALLOC;
1323 memset(tmpNode->gname, 0x00, gnameLen + 1);
1324 memset(tmpNode->title, 0x00, aliasLen + 1);
1326 memcpy(tmpNode->gname, textGname, gnameLen);
1327 memcpy(tmpNode->title, textAlias, aliasLen);
1329 tmpNode->status = (int)sqlite3_column_int(stmt, 2); /* for status */
1330 tmpNode->storeType = tempStore;
1333 /* When multiple stores are passed, we need to ensure that the rootcerthead is
1334 assigned to currentNode once, else previous store data gets overwritten */
1336 rootCertHead = tmpNode;
1337 currentNode = rootCertHead;
1340 currentNode->next = tmpNode;
1341 currentNode = tmpNode;
1349 SLOGD("No entries found in database.");
1350 result = CERTSVC_SUCCESS;
1354 sqlite3_free(query);
1359 sqlite3_finalize(stmt);
1367 VcoreCertResponseData *respCertData = (VcoreCertResponseData *)malloc(count * sizeof(VcoreCertResponseData));
1368 if (!respCertData) {
1369 SLOGE("Failed to allocate memory");
1370 result = CERTSVC_BAD_ALLOC;
1374 memset(respCertData, 0x00, count * sizeof(VcoreCertResponseData));
1375 VcoreCertResponseData* currRespCertData = NULL;
1377 currentNode = rootCertHead;
1378 for (i = 0; i < count; i++) {
1379 tmpNode = currentNode->next;
1381 currRespCertData = respCertData + i;
1382 if (strlen(currentNode->gname) > sizeof(currRespCertData->gname)
1383 || strlen(currentNode->title) > sizeof(currRespCertData->title)) {
1384 SLOGE("String is too long. [%s], [%s]", currentNode->gname, currentNode->title);
1385 result = CERTSVC_FAIL;
1386 *certListBuffer = NULL;
1390 strncpy(currRespCertData->gname, currentNode->gname, strlen(currentNode->gname));
1391 strncpy(currRespCertData->title, currentNode->title, strlen(currentNode->title));
1392 currRespCertData->status = currentNode->status;
1393 currRespCertData->storeType = currentNode->storeType;
1394 //SLOGD("get cert list: %d th cert: gname=%s, title=%s, status=%d, storeType=%d", i, currRespCertData->gname, currRespCertData->title, currRespCertData->status, currRespCertData->storeType);
1396 currentNode = tmpNode;
1399 *certListBuffer = (char *) respCertData;
1400 *bufferLen = count * sizeof(VcoreCertResponseData);
1402 SLOGD("Success to create certificate list. cert_count=%d", count);
1403 result= CERTSVC_SUCCESS;
1406 sqlite3_free(query);
1409 sqlite3_finalize(stmt);
1412 currentNode = rootCertHead;
1413 while (currentNode) {
1414 tmpNode = currentNode->next;
1415 free(currentNode->title);
1416 free(currentNode->gname);
1418 currentNode=tmpNode;
1420 rootCertHead = NULL;
1426 int getCertificateAliasFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *gname, char *alias)
1428 int result = CERTSVC_SUCCESS;
1430 sqlite3_stmt *stmt = NULL;
1432 const char *text = NULL;
1434 query = sqlite3_mprintf("select common_name from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
1435 (storeType==VPN_STORE)? "vpn" : "email"), gname);
1437 result = execute_select_query(db_handle, query, &stmt);
1438 if (result != CERTSVC_SUCCESS) {
1439 SLOGE("Querying database failed.");
1440 result = CERTSVC_FAIL;
1444 records = sqlite3_step(stmt);
1445 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1446 SLOGE("No valid records found for gname passed [%s].",gname);
1447 result = CERTSVC_FAIL;
1451 if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
1452 SLOGE("No column text in returned records");
1453 result = CERTSVC_FAIL;
1457 strncpy(alias, text, strlen(text));
1459 if (strlen(alias) == 0) {
1460 SLOGE("Unable to get the alias name for the gname passed.");
1461 result = CERTSVC_FAIL;
1465 result = CERTSVC_SUCCESS;
1467 SLOGD("success : getCertificateAliasFromStore");
1470 sqlite3_free(query);
1473 sqlite3_finalize(stmt);
1478 int loadCertificatesFromStore(
1480 CertStoreType storeType,
1482 char **ppCertBlockBuffer,
1484 size_t *certBlockCount)
1486 int result = CERTSVC_SUCCESS;
1489 sqlite3_stmt *stmt = NULL;
1491 char **certs = NULL;
1492 const char *tmpText = NULL;
1495 query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
1496 (storeType==VPN_STORE)? "vpn" : "email"), gname);
1498 result = execute_select_query(db_handle, query, &stmt);
1499 if (result != CERTSVC_SUCCESS) {
1500 SLOGE("Querying database failed.");
1501 result = CERTSVC_FAIL;
1505 records = sqlite3_step(stmt);
1506 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1507 SLOGE("No valid records found for gname passed [%s].",gname);
1508 result = CERTSVC_FAIL;
1513 if (records == SQLITE_ROW) {
1515 sqlite3_free(query);
1517 const char *columnText = (const char *)sqlite3_column_text(stmt, 0);
1519 SLOGE("Failed to sqlite3_column_text");
1520 result = CERTSVC_FAIL;
1524 query = sqlite3_mprintf("select gname from %Q where associated_gname=%Q and enabled=%d and is_root_app_enabled=%d", \
1525 ((storeType==WIFI_STORE)? "wifi" : (storeType==VPN_STORE)? "vpn" : "email"), \
1526 columnText, ENABLED, ENABLED);
1529 sqlite3_finalize(stmt);
1531 result = execute_select_query(db_handle, query, &stmt);
1532 if (result != CERTSVC_SUCCESS) {
1533 SLOGE("Querying database failed.");
1534 result = CERTSVC_FAIL;
1539 records = sqlite3_step(stmt);
1540 if (records != SQLITE_ROW || records == SQLITE_DONE)
1544 certs = (char**) malloc(4 * sizeof(char *));
1546 SLOGE("Failed to allocate memory");
1547 result = CERTSVC_BAD_ALLOC;
1550 memset(certs, 0x00, 4 * sizeof(char *));
1553 if (records == SQLITE_ROW) {
1554 tmpText = (const char *)sqlite3_column_text(stmt, 0);
1556 SLOGE("Failed to sqlite3_column_text.");
1557 result = CERTSVC_FAIL;
1561 if (!((certs)[count] = strdup(tmpText))) {
1562 SLOGE("Failed to allocate memory");
1563 result = CERTSVC_BAD_ALLOC;
1572 SLOGE("No valid records found for the gname passed [%s].",gname);
1573 return CERTSVC_FAIL;
1577 *certBlockCount = count;
1578 *bufferLen = count * sizeof(ResponseCertBlock);
1579 ResponseCertBlock *certBlockList = (ResponseCertBlock *) malloc(*bufferLen);
1580 if (!certBlockList) {
1581 SLOGE("Failed to allocate memory for ResponseCertBlock");
1582 result = CERTSVC_BAD_ALLOC;
1587 memset(certBlockList, 0x00, *bufferLen);
1589 ResponseCertBlock *currentBlock = NULL;
1590 for (i = 0; i < count; i++) {
1591 currentBlock = certBlockList + i;
1592 if (sizeof(currentBlock->dataBlock) < strlen(certs[i])) {
1593 SLOGE("src is longer than dst. src[%s] dst size[%d]", certs[i], sizeof(currentBlock->dataBlock));
1594 free(certBlockList);
1595 result = CERTSVC_FAIL;
1598 strncpy(currentBlock->dataBlock, certs[i], strlen(certs[i]));
1599 currentBlock->dataBlockLen = strlen(certs[i]);
1601 *ppCertBlockBuffer = (char *)certBlockList;
1603 result = CERTSVC_SUCCESS;
1605 SLOGD("success: loadCertificatesFromStore. CERT_COUNT=%d", count);
1609 sqlite3_free(query);
1612 sqlite3_finalize(stmt);
1615 for(i = 0; i < count; i++)