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 <cert-svc/cerror.h>
37 #include <cert-svc/ccert.h>
38 #include <vcore/Client.h>
40 #include <cert-server-debug.h>
41 #include <cert-server-logic.h>
43 static CertStatus int_to_CertStatus(int intval)
54 static int CertStatus_to_int(CertStatus status)
65 char *add_shared_owner_prefix(const char *name)
67 size_t alias_len = strlen(name) + strlen(ckmc_owner_id_system) + strlen(ckmc_owner_id_separator);
68 char *ckm_alias = (char *)malloc(alias_len + 1);
70 SLOGE("Failed to allocate memory");
73 memset(ckm_alias, 0, alias_len + 1);
74 strcat(ckm_alias, ckmc_owner_id_system);
75 strcat(ckm_alias, ckmc_owner_id_separator);
76 strcat(ckm_alias, name);
81 int ckmc_remove_alias_with_shared_owner_prefix(const char *name)
83 char *ckm_alias = add_shared_owner_prefix(name);
85 SLOGE("Failed to allocate memory");
86 return CKMC_ERROR_OUT_OF_MEMORY;
89 int result = ckmc_remove_alias(ckm_alias);
96 char *get_complete_path(const char *str1, const char *str2)
104 if (str1[strlen(str1) - 1] != '/')
105 as_result = asprintf(&result, "%s/%s", str1, str2);
107 as_result = asprintf(&result, "%s%s", str1, str2);
115 /* TODO: root ssl file system refactor */
116 int add_file_to_dir(const char* dir, const char* pGname, const char* pData, size_t dataLen)
118 char *systemFile = get_complete_path(dir, pGname);
120 SLOGE("Failed to get system file path.");
124 char realFile[FILENAME_MAX] = {0};
125 if (!realpath(systemFile, realFile)) {
126 SLOGE("Failed to get realpath. systemFile[%s]", systemFile);
130 FILE *stream = fopen(realFile, "ab");
132 SLOGE("Fail to open file [%s]", realFile);
136 if (fwrite(pData, sizeof(char), dataLen, stream) != dataLen) {
137 SLOGE("Fail to write file in system store.");
143 return CERTSVC_SUCCESS;
146 int add_file_to_system_cert_dir(const char* pGname, const char* pData, size_t dataLen)
148 return add_file_to_dir(SYSTEM_CERT_DIR, pGname, pData, dataLen);
151 /* TODO: root ssl file system refactor */
152 int del_file_from_dir(const char* dir, const char *pGname)
154 const char *systemFile = get_complete_path(dir, pGname);
156 SLOGE("Failed to construct source file path.");
160 char realFile[FILENAME_MAX] = {0};
161 if (!realpath(systemFile, realFile)) {
162 SLOGE("Failed to get realpath. systemFile[%s]", systemFile);
166 /* instead of removing the file, the file is trimmed to zero size */
167 FILE *stream = fopen(realFile, "wb");
169 SLOGE("Failed to open the file for writing, [%s].", realFile);
174 return CERTSVC_SUCCESS;
177 int del_file_from_system_cert_dir(const char *pGname)
179 return del_file_from_dir(SYSTEM_CERT_DIR, pGname);
182 int execute_insert_update_query(sqlite3 *db_handle, char *query)
185 SLOGE("Database not initialised.");
186 return CERTSVC_WRONG_ARGUMENT;
190 SLOGE("Query is NULL.");
191 return CERTSVC_WRONG_ARGUMENT;
194 /* Begin transaction */
195 int result = sqlite3_exec(db_handle, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
196 if (result != SQLITE_OK) {
197 SLOGE("Failed to begin transaction.");
201 /* Executing command */
202 result = sqlite3_exec(db_handle, query, NULL, NULL, NULL);
203 if (result != SQLITE_OK) {
204 SLOGE("Failed to execute query (%s).", query);
208 /* Committing the transaction */
209 result = sqlite3_exec(db_handle, "COMMIT", NULL, NULL, NULL);
211 SLOGE("Failed to commit transaction. Roll back now.");
212 result = sqlite3_exec(db_handle, "ROLLBACK", NULL, NULL, NULL);
213 if (result != SQLITE_OK)
214 SLOGE("Failed to commit transaction. Roll back now.");
219 SLOGD("Transaction Commit and End.");
221 return CERTSVC_SUCCESS;
224 int execute_select_query(sqlite3 *db_handle, char *query, sqlite3_stmt **stmt)
226 if (!db_handle || !query)
227 return CERTSVC_WRONG_ARGUMENT;
229 sqlite3_stmt *stmts = NULL;
230 if (sqlite3_prepare_v2(db_handle, query, strlen(query), &stmts, NULL) != SQLITE_OK) {
231 SLOGE("sqlite3_prepare_v2 failed [%s].", query);
236 return CERTSVC_SUCCESS;
239 int write_to_file(const char *fileName, const char *mode_of_writing, const char *certBuffer, size_t certLength)
241 int result = CERTSVC_SUCCESS;
242 FILE *fp_write = NULL;
244 if (!certBuffer || certLength <= 0) {
245 SLOGE("Input buffer is NULL.");
246 return CERTSVC_WRONG_ARGUMENT;
249 if (!(fp_write = fopen(fileName, mode_of_writing))) {
250 SLOGE("Failed to open the file for writing, [%s].", fileName);
254 /* if mode of writing is to append, then goto end of file */
255 if (strcmp(mode_of_writing,"ab") == 0)
256 fseek(fp_write, 0L, SEEK_END);
258 if (fwrite(certBuffer, sizeof(char), certLength, fp_write) != certLength) {
259 SLOGE("Fail to write into file.");
260 result = CERTSVC_FAIL;
264 /* adding empty line at the end */
265 fwrite("\n",sizeof(char), 1, fp_write);
274 int write_to_ca_cert_crt_file(const char *mode_of_writing, const char *certBuffer, size_t certLength)
276 return write_to_file(CERTSVC_CRT_FILE_PATH, mode_of_writing, certBuffer, certLength);
279 int saveCertificateToStore(
284 if (!pGname || !pData || dataLen < 1) {
285 SLOGE("Invalid input parameter passed.");
286 return CERTSVC_WRONG_ARGUMENT;
289 ckmc_policy_s cert_policy;
290 cert_policy.password = NULL;
291 cert_policy.extractable = true;
293 ckmc_raw_buffer_s cert_data;
294 cert_data.data = (unsigned char *)pData;
295 cert_data.size = dataLen;
297 char *ckm_alias = add_shared_owner_prefix(pGname);
299 SLOGE("Failed to make alias. memory allocation error.");
300 return CERTSVC_BAD_ALLOC;
303 int result = ckmc_save_data(ckm_alias, cert_data, cert_policy);
306 if (result == CKMC_ERROR_DB_ALIAS_EXISTS) {
307 SLOGI("same alias with gname[%s] alrady exist in ckm. Maybe other store type have it. skip.", pGname);
308 return CERTSVC_SUCCESS;
311 if (result != CKMC_ERROR_NONE) {
312 SLOGE("Failed to save trusted data. ckm errcode[%d]", result);
316 return CERTSVC_SUCCESS;
319 int saveCertificateToSystemStore(
324 if (!pGname || !pData || dataLen < 1) {
325 SLOGE("Invalid input parameter passed.");
326 return CERTSVC_WRONG_ARGUMENT;
329 int result = add_file_to_system_cert_dir(pGname, pData, dataLen);
330 if (result != CERTSVC_SUCCESS)
331 SLOGE("Failed to store the certificate in store.");
336 int get_certificate_buffer_from_store(
338 CertStoreType storeType,
343 int result = CERTSVC_SUCCESS;
345 char *tempBuffer = NULL;
347 sqlite3_stmt *stmt = NULL;
350 SLOGE("Invalid input parameter passed.");
351 return CERTSVC_WRONG_ARGUMENT;
354 if (storeType != SYSTEM_STORE)
355 query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
356 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
357 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
359 query = sqlite3_mprintf("select certificate from ssl where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
360 pGname, ENABLED, ENABLED);
362 result = execute_select_query(db_handle, query, &stmt);
363 if (result != CERTSVC_SUCCESS) {
364 SLOGE("Querying database failed.");
365 result = CERTSVC_FAIL;
369 records = sqlite3_step(stmt);
370 if (records != SQLITE_ROW || records == SQLITE_DONE) {
371 SLOGE("No valid records found for given gname [%s].",pGname);
372 result = CERTSVC_FAIL;
376 tempBuffer = (char *)malloc(sizeof(char) * VCORE_MAX_RECV_DATA_SIZE);
378 SLOGE("Fail to allocate memory");
379 result = CERTSVC_FAIL;
383 memset(tempBuffer, 0x00, VCORE_MAX_RECV_DATA_SIZE);
385 if (storeType == SYSTEM_STORE)
386 result = getCertificateDetailFromSystemStore(db_handle, pGname, tempBuffer, certSize);
388 result = getCertificateDetailFromStore(db_handle, storeType, PEM_CRT, pGname, tempBuffer, certSize);
390 if (result != CERTSVC_SUCCESS) {
391 SLOGE("Failed to set request data.");
392 result = CERTSVC_WRONG_ARGUMENT;
396 *certBuffer = tempBuffer;
399 if (result != CERTSVC_SUCCESS)
406 sqlite3_finalize(stmt);
411 int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t certLength)
413 int result = CERTSVC_SUCCESS;
420 sqlite3_stmt *stmt = NULL;
422 int storeType[4] = {SYSTEM_STORE, WIFI_STORE, VPN_STORE, EMAIL_STORE};
424 /* During install of a root certificate, the root certificate gets appended at
425 * the end to optimise the write operation onto ca-certificate.crt file. */
426 if (certBuffer && certLength > 0) {
427 result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
428 if (result != CERTSVC_SUCCESS) {
429 SLOGE("Failed to write to file.");
430 result = CERTSVC_FAIL;
435 for (count = 0; count < 4; count++) {
436 /* get the ssl certificate from database */
438 query = sqlite3_mprintf("select certificate from ssl where enabled=%d and is_root_app_enabled=%d", ENABLED, ENABLED);
439 else if (count > 0 && count < 4)
440 /* gets all the gname which is marked as root certificate and enabled = TRUE */
441 query = sqlite3_mprintf("select gname from %Q where is_root_cert=%d and enabled=%d and is_root_app_enabled=%d", \
442 ((count == 1)?"wifi":(count == 2)?"vpn":"email"), ENABLED, ENABLED, ENABLED);
444 result = execute_select_query(db_handle, query, &stmt);
451 if (result != CERTSVC_SUCCESS) {
452 SLOGE("Querying database failed.");
456 /* update the ca-certificate.crt file */
458 records = sqlite3_step(stmt);
459 if (records == SQLITE_DONE) {
460 result = CERTSVC_SUCCESS;
464 if (records != SQLITE_ROW) {
465 SLOGE("DB query error when select. result[%d].", records);
466 result = CERTSVC_FAIL;
475 /* gets the certificate from database for system store */
476 text = (const char *)sqlite3_column_text(stmt, 0);
478 certLength = strlen(text);
479 certBuffer = strndup(text, certLength);
482 /* gets the certificate from key-manager for other stores */
483 text = (const char *)sqlite3_column_text(stmt, 0);
485 gname = strndup(text, strlen(text));
487 result = get_certificate_buffer_from_store(db_handle, storeType[count], gname, &certBuffer, &certLength);
488 if (result != CERTSVC_SUCCESS) {
489 SLOGE("Failed to get certificate buffer from key-manager.");
494 if (certBuffer == NULL) {
495 SLOGE("Failed to extract cert buffer to update ca-certificate.");
496 result = CERTSVC_FAIL;
501 result = write_to_ca_cert_crt_file("wb", certBuffer, certLength);
503 result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
505 if (result != CERTSVC_SUCCESS) {
506 SLOGE("Failed to write to file.");
507 result = CERTSVC_FAIL;
513 SLOGD("Successfully updated ca-certificate.crt file.");
517 sqlite3_finalize(stmt);
522 int enable_disable_cert_status(
524 CertStoreType storeType,
529 int result = CERTSVC_SUCCESS;
532 size_t certLength = 0;
533 char *certBuffer = NULL;
535 const char *text = NULL;
536 sqlite3_stmt *stmt = NULL;
538 if (status != DISABLED && status != ENABLED) {
539 SLOGE("Invalid cert status");
540 return CERTSVC_INVALID_STATUS;
543 query = sqlite3_mprintf("select * from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
544 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
546 SLOGE("Failed to generate query");
547 return CERTSVC_BAD_ALLOC;
550 result = execute_select_query(db_handle, query, &stmt);
553 if (result != CERTSVC_SUCCESS || !stmt) {
554 SLOGE("Querying database failed.");
558 records = sqlite3_step(stmt);
559 sqlite3_finalize(stmt);
562 if (records != SQLITE_ROW) {
563 SLOGE("No valid records found.");
567 if (status == DISABLED) {
568 /* check certificate presence in disabled_certs table before inserting */
569 query = sqlite3_mprintf("select * from disabled_certs where gname=%Q", pGname);
571 SLOGE("Failed to generate query");
572 return CERTSVC_BAD_ALLOC;
575 result = execute_select_query(db_handle, query, &stmt);
579 if (result != CERTSVC_SUCCESS) {
580 SLOGE("Querying database failed.");
584 records = sqlite3_step(stmt);
585 sqlite3_finalize(stmt);
588 if (records == SQLITE_ROW) {
589 SLOGE("Selected certificate identifier is already disabled.", pGname);
593 /* get certificate from keymanager*/
594 result = get_certificate_buffer_from_store(db_handle, storeType, pGname, &certBuffer, &certSize);
595 if (result != CERTSVC_SUCCESS) {
596 SLOGE("Failed to get certificate buffer. result[%d]", result);
600 /* inserting the disabled certificate to disabled_certs table */
601 query = sqlite3_mprintf("insert into disabled_certs (gname, certificate) values (%Q, %Q)", pGname, certBuffer);
605 SLOGE("Failed to generate query");
606 return CERTSVC_BAD_ALLOC;
609 result = execute_insert_update_query(db_handle, query);
612 if (result != CERTSVC_SUCCESS) {
613 SLOGE("Insert to database failed.");
617 if (storeType != SYSTEM_STORE) {
618 result = ckmc_remove_alias_with_shared_owner_prefix(pGname);
620 if (result != CKMC_ERROR_NONE) {
621 SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", result);
626 result = del_file_from_system_cert_dir(pGname);
627 if (result != CERTSVC_SUCCESS) {
628 SLOGE("Error in del_file_from_system_cert_dir. ret[%d]", result);
632 } else { /* moving the certificate to enabled state */
633 query = sqlite3_mprintf("select certificate from disabled_certs where gname=%Q", pGname);
635 SLOGE("Failed to generate query");
636 return CERTSVC_BAD_ALLOC;
639 result = execute_select_query(db_handle, query, &stmt);
642 if (result != CERTSVC_SUCCESS) {
643 SLOGE("Querying database failed.");
647 records = sqlite3_step(stmt);
648 if (records == SQLITE_ROW) {
649 text = (const char *)sqlite3_column_text(stmt, 0);
652 SLOGE("Invalid column text");
653 sqlite3_finalize(stmt);
657 certBuffer = strndup(text, strlen(text));
659 sqlite3_finalize(stmt);
662 SLOGE("Failed to allocate memory");
663 return CERTSVC_BAD_ALLOC;
666 certLength = strlen(certBuffer);
668 if (storeType == SYSTEM_STORE)
669 result = saveCertificateToSystemStore(pGname, certBuffer, certLength);
671 result = saveCertificateToStore(pGname, certBuffer, certLength);
675 if (result != CERTSVC_SUCCESS) {
676 SLOGE("Failed to save certificate to key-manager. ret[%d]", result);
680 query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
682 SLOGE("Failed to generate query");
683 return CERTSVC_BAD_ALLOC;
686 result = execute_insert_update_query(db_handle, query);
689 if (result != CERTSVC_SUCCESS) {
690 SLOGE("Unable to delete certificate entry from database. ret[%d]", result);
696 if (is_root_app == ENABLED)
697 query = sqlite3_mprintf("update %Q set is_root_app_enabled=%d , enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
698 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), CertStatus_to_int(status), status, pGname);
700 query = sqlite3_mprintf("update %Q set enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
701 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), CertStatus_to_int(status), pGname);
704 SLOGE("Failed to generate query");
705 return CERTSVC_BAD_ALLOC;
708 result = execute_insert_update_query(db_handle, query);
711 if (result != CERTSVC_SUCCESS) {
712 SLOGE("Update failed. ret[%d]", result);
719 int setCertificateStatusToStore(
721 CertStoreType storeType,
727 SLOGE("Invalid input parameter passed.");
728 return CERTSVC_WRONG_ARGUMENT;
731 int result = enable_disable_cert_status(db_handle, storeType, is_root_app, pGname, status);
732 if (result != CERTSVC_SUCCESS) {
733 SLOGE("Failed to disable certificate.");
737 SLOGD("Successfully updated the certificate status from %s to %s.",
738 (status == DISABLED) ? "ENABLED" : "DISABLED", (status == DISABLED) ? "DISABLED" : "ENABLED");
739 return CERTSVC_SUCCESS;
742 int getCertificateStatusFromStore(
744 CertStoreType storeType,
749 SLOGE("Invalid input parameter passed.");
750 return CERTSVC_WRONG_ARGUMENT;
753 char *query = sqlite3_mprintf("select gname, common_name, enabled from %Q where gname=%Q",\
754 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
755 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
757 SLOGE("Failed to generate query");
758 return CERTSVC_BAD_ALLOC;
761 sqlite3_stmt *stmt = NULL;
762 int result = execute_select_query(db_handle, query, &stmt);
765 if (result != CERTSVC_SUCCESS || !stmt) {
766 SLOGE("Querying database failed.");
771 result = sqlite3_step(stmt);
772 if (result != SQLITE_ROW || result == SQLITE_DONE) {
773 SLOGE("No valid records found.");
775 sqlite3_finalize(stmt);
779 *status = int_to_CertStatus(sqlite3_column_int(stmt, 2));
781 sqlite3_finalize(stmt);
783 return CERTSVC_SUCCESS;
786 int check_alias_exist_in_database(
788 CertStoreType storeType,
792 sqlite3_stmt *stmt = NULL;
794 if (!alias || !isUnique) {
795 SLOGE("Invalid input parameter passed.");
796 return CERTSVC_WRONG_ARGUMENT;
799 char *query = sqlite3_mprintf("select * from %Q where common_name=%Q", ((storeType == WIFI_STORE)? "wifi" : \
800 (storeType == VPN_STORE)? "vpn" : "email"),alias);
803 SLOGE("Failed to generate query");
804 return CERTSVC_BAD_ALLOC;
807 int result = execute_select_query(db_handle, query, &stmt);
810 if (result != CERTSVC_SUCCESS || !stmt) {
811 SLOGE("Querying database failed.");
815 result = sqlite3_step(stmt);
816 sqlite3_finalize(stmt);
818 if (result != SQLITE_ROW)
819 *isUnique = CERTSVC_TRUE;
821 *isUnique = CERTSVC_FALSE;
823 return CERTSVC_SUCCESS;
826 int installCertificateToStore(
828 CertStoreType storeType,
830 const char *common_name,
831 const char *private_key_gname,
832 const char *associated_gname,
833 const char *dataBlock,
838 || (certType == P12_END_USER && !common_name && !private_key_gname)
839 || (certType != P12_END_USER && !common_name && !associated_gname)) {
840 SLOGE("Invalid input parameter passed.");
841 return CERTSVC_WRONG_ARGUMENT;
844 if (storeType != SYSTEM_STORE
845 && saveCertificateToStore(
848 dataBlockLen) != CERTSVC_SUCCESS) {
849 SLOGE("FAIL to save certificate to key-manager.");
853 if (certType == P12_PKEY) {
854 SLOGD("Don't save private key in store");
855 return CERTSVC_SUCCESS;
859 if (certType == P12_END_USER && private_key_gname) {
860 query = sqlite3_mprintf("insert into %Q (gname, common_name, private_key_gname, associated_gname, enabled, is_root_app_enabled) "\
861 "values (%Q, %Q, %Q, %Q, %d, %d)",((storeType == WIFI_STORE)? "wifi" : \
862 (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, private_key_gname, pGname, ENABLED, ENABLED);
863 } else if (certType == PEM_CRT || certType == P12_TRUSTED) {
864 query = sqlite3_mprintf("insert into %Q (gname, common_name, is_root_cert, associated_gname, enabled, is_root_app_enabled) values "\
865 "(%Q, %Q, %d, %Q, %d, %d)", ((storeType == WIFI_STORE)? "wifi" : \
866 (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, ENABLED, associated_gname, ENABLED, ENABLED);
867 } else if (certType == P12_INTERMEDIATE) {
868 query = sqlite3_mprintf("insert into %Q (gname, common_name, associated_gname, enabled, is_root_app_enabled) values (%Q, %Q, %Q, %d, %d)", \
869 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"),
870 pGname, common_name, associated_gname, ENABLED, ENABLED);
874 SLOGE("Failed to generate query");
875 return CERTSVC_BAD_ALLOC;
878 int result = execute_insert_update_query(db_handle, query);
881 if (result != CERTSVC_SUCCESS) {
882 SLOGE("Insert to database failed.");
886 return CERTSVC_SUCCESS;
889 int checkAliasExistsInStore(
891 CertStoreType storeType,
896 SLOGE("Invalid input parameter passed.");
897 return CERTSVC_WRONG_ARGUMENT;
900 *isUnique = CERTSVC_FAIL;
901 int result = check_alias_exist_in_database(db_handle, storeType, alias, isUnique);
902 if (result != CERTSVC_SUCCESS) {
903 SLOGE("Failed to check_alias_exist_in_database. err[%d]", result);
907 if (*isUnique == CERTSVC_TRUE) {
908 SLOGD("Alias (%s) does not exist in %s store.",
910 (storeType == VPN_STORE) ? "VPN" :
911 (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
913 SLOGD("Alias (%s) exist in %s store.",
915 (storeType == VPN_STORE) ? "VPN" :
916 (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
919 return CERTSVC_SUCCESS;
922 int getCertificateDetailFromStore(
924 CertStoreType storeType,
930 int result = CERTSVC_SUCCESS;
933 const char *text = NULL;
934 sqlite3_stmt *stmt = NULL;
935 ckmc_raw_buffer_s *cert_data = NULL;
937 if (!pGname || !pOutData) {
938 SLOGE("Invalid input parameter passed.");
939 return CERTSVC_WRONG_ARGUMENT;
942 /* start constructing query */
943 if (certType == P12_PKEY) {
944 /* From the given certificate identifier, get the associated_gname for the certificate.
945 * Then query the database for records matching the associated_gname to get the private key */
946 query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", \
947 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), pGname);
949 SLOGE("Failed to generate query");
950 return CERTSVC_BAD_ALLOC;
953 result = execute_select_query(db_handle, query, &stmt);
956 if (result != CERTSVC_SUCCESS) {
957 SLOGE("Querying database failed.");
961 records = sqlite3_step(stmt);
962 if (records != SQLITE_ROW) {
963 SLOGE("No valid records found.");
964 sqlite3_finalize(stmt);
968 text = (const char *)sqlite3_column_text(stmt, 0);
971 SLOGE("No valid column text");
972 sqlite3_finalize(stmt);
976 query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
977 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), text, ENABLED, ENABLED);
979 sqlite3_finalize(stmt);
980 } else if (storeType != SYSTEM_STORE) {
981 query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
982 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
983 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
987 SLOGE("Failed to generate query");
988 return CERTSVC_BAD_ALLOC;
991 result = execute_select_query(db_handle, query, &stmt);
994 if (result != CERTSVC_SUCCESS) {
995 SLOGE("Querying database failed.");
999 records = sqlite3_step(stmt);
1000 if (records != SQLITE_ROW) {
1001 SLOGE("No valid records found.");
1002 sqlite3_finalize(stmt);
1003 return CERTSVC_FAIL;
1006 if (certType == P12_PKEY) {
1007 if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
1008 SLOGE("No valid column text");
1009 sqlite3_finalize(stmt);
1010 return CERTSVC_FAIL;
1016 char *ckm_alias = add_shared_owner_prefix(pGname);
1018 SLOGE("Failed to make alias. memory allocation error.");
1019 return CERTSVC_BAD_ALLOC;
1022 result = ckmc_get_data(ckm_alias, NULL, &cert_data);
1025 sqlite3_finalize(stmt);
1027 if (result != CKMC_ERROR_NONE) {
1028 SLOGE("Failed to get certificate from key-manager. ckm ret[%d]", result);
1029 *size = CERTSVC_FAIL;
1030 return CERTSVC_FAIL;
1033 memcpy(pOutData, cert_data->data, cert_data->size);
1034 pOutData[cert_data->size] = 0;
1035 *size = cert_data->size;
1037 ckmc_buffer_free(cert_data);
1039 return CERTSVC_SUCCESS;
1042 int getCertificateDetailFromSystemStore(
1048 int result = CERTSVC_SUCCESS;
1050 size_t certLength = 0;
1052 const char *text = NULL;
1053 sqlite3_stmt *stmt = NULL;
1056 SLOGE("Invalid input parameter passed.");
1057 return CERTSVC_WRONG_ARGUMENT;
1060 query = sqlite3_mprintf("select certificate from ssl where gname=%Q and is_root_app_enabled=%d", \
1061 pGname, ENABLED, ENABLED);
1063 SLOGE("Query is NULL.");
1064 return CERTSVC_FAIL;
1067 result = execute_select_query(db_handle, query, &stmt);
1068 sqlite3_free(query);
1070 if (result != CERTSVC_SUCCESS) {
1071 SLOGE("Querying database failed.");
1075 records = sqlite3_step(stmt);
1076 if (records != SQLITE_ROW) {
1077 SLOGE("No valid records found for passed gname [%s].", pGname);
1078 sqlite3_finalize(stmt);
1079 return CERTSVC_FAIL;
1082 text = (const char *)sqlite3_column_text(stmt, 0);
1085 SLOGE("Fail to sqlite3_column_text");
1086 sqlite3_finalize(stmt);
1087 return CERTSVC_FAIL;
1090 certLength = strlen(text);
1091 if (certLength >= 4096) {
1092 sqlite3_finalize(stmt);
1093 SLOGE("certificate is too long");
1094 return CERTSVC_FAIL;
1097 memcpy(pOutData, text, certLength);
1098 pOutData[certLength] = 0;
1101 sqlite3_finalize(stmt);
1102 return CERTSVC_SUCCESS;
1105 int deleteCertificateFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *pGname)
1107 int result = CERTSVC_SUCCESS;
1110 char *private_key_name = NULL;
1111 sqlite3_stmt *stmt = NULL;
1113 SLOGD("Remove certificate of gname[%s] in store[%d]", pGname, storeType);
1116 SLOGE("Invalid input parameter passed.");
1117 return CERTSVC_WRONG_ARGUMENT;
1120 if (storeType == SYSTEM_STORE) {
1121 SLOGE("Invalid store type passed.");
1122 return CERTSVC_INVALID_STORE_TYPE;
1125 /* start constructing query */
1126 query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" :\
1127 (storeType == VPN_STORE)? "vpn" : "email"), pGname);
1129 result = execute_select_query(db_handle, query, &stmt);
1130 if (result != CERTSVC_SUCCESS) {
1131 SLOGE("Querying database failed.");
1132 result = CERTSVC_FAIL;
1136 records = sqlite3_step(stmt);
1137 if (records != SQLITE_ROW) {
1138 SLOGE("No valid records found for passed gname [%s]. result[%d].", pGname, records);
1139 result = CERTSVC_FAIL;
1143 /* if a cert is having private-key in it, the private key should
1144 * be deleted first from key-manager, then the actual cert */
1145 if (sqlite3_column_text(stmt, 0) != NULL)
1146 private_key_name = strdup((const char *)sqlite3_column_text(stmt, 0));
1148 query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
1149 result = execute_insert_update_query(db_handle, query);
1150 if (result != CERTSVC_SUCCESS) {
1151 SLOGE("Unable to delete certificate entry from database. result[%d]", result);
1156 sqlite3_free(query);
1161 sqlite3_finalize(stmt);
1165 query = sqlite3_mprintf("delete from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
1166 (storeType == VPN_STORE)? "vpn" : "email"), pGname);
1168 result = execute_insert_update_query(db_handle, query);
1169 if (result != CERTSVC_SUCCESS) {
1170 SLOGE("Unable to delete certificate entry from database. result[%d]", result);
1175 sqlite3_free(query);
1180 sqlite3_finalize(stmt);
1184 CertStoreType other = ALL_STORE & ~SYSTEM_STORE & ~storeType;
1185 CertStoreType current;
1186 int gname_exist = 0;
1187 for (current = VPN_STORE; current < SYSTEM_STORE; current <<= 1) {
1188 if ((other & current) == 0)
1191 query = sqlite3_mprintf("select * from %Q where gname=%Q", ((current == WIFI_STORE)? "wifi" :\
1192 (current == VPN_STORE)? "vpn" : "email"), pGname);
1193 result = execute_select_query(db_handle, query, &stmt);
1194 if (result != CERTSVC_SUCCESS) {
1195 SLOGE("Querying database failed.");
1196 result = CERTSVC_FAIL;
1199 records = sqlite3_step(stmt);
1200 if (records == SQLITE_ROW) {
1201 SLOGI("Same gname[%s] exist on store[%d].", pGname, current);
1206 sqlite3_free(query);
1207 sqlite3_finalize(stmt);
1213 SLOGD("The gname[%s] which is in store[%d] is the last one. so remove it from ckm either.", pGname, storeType);
1215 if (private_key_name != NULL) {
1216 result = ckmc_remove_alias_with_shared_owner_prefix(private_key_name);
1217 if (result != CKMC_ERROR_NONE) {
1218 SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", result);
1219 result = CERTSVC_FAIL;
1224 /* removing the actual cert */
1225 result = ckmc_remove_alias_with_shared_owner_prefix(pGname);
1226 if (result != CKMC_ERROR_NONE) {
1227 SLOGE("Failed to remove data in ckm with gname[%s]. ckm_result[%d]", pGname, result);
1228 result = CERTSVC_FAIL;
1233 SLOGD("Success in deleting the certificate from store.");
1234 result = CERTSVC_SUCCESS;
1238 sqlite3_free(query);
1241 sqlite3_finalize(stmt);
1243 free(private_key_name);
1249 int getCertificateListFromStore(
1252 CertStoreType storeType,
1254 char **certListBuffer,
1258 int result = CERTSVC_SUCCESS;
1259 CertSvcStoreCertList *rootCertHead = NULL;
1260 CertSvcStoreCertList *tmpNode = NULL;
1261 CertSvcStoreCertList *currentNode = NULL;
1262 sqlite3_stmt *stmt = NULL;
1271 /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
1272 if (loopCount == (MAX_STORE_ENUMS - 1))
1275 /* Check if the passed store type matches with any of the in-built store type */
1276 if ((1 << loopCount) & storeType) {
1277 /* if a store type matches, put that value as storetype argument in the below function */
1278 CertStoreType tempStore = (CertStoreType) (1 << loopCount);
1279 SLOGD("Processing storetype [%s]", (tempStore == WIFI_STORE)? "WIFI" : (tempStore == VPN_STORE)? "VPN" : \
1280 (tempStore == EMAIL_STORE)? "EMAIL" : "SYSTEM");
1282 if (reqType == CERTSVC_GET_ROOT_CERTIFICATE_LIST) {
1283 // For get_root_certificate_list_from_store
1284 if (storeType == SYSTEM_STORE) {
1285 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where enabled=%d "\
1286 "and is_root_app_enabled=%d and order by common_name asc", "ssl", ENABLED, ENABLED);
1288 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1289 "is_root_cert IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
1290 (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
1291 (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1293 } else if (reqType == CERTSVC_GET_USER_CERTIFICATE_LIST) {
1294 // For get_end_user_certificate_list_from_store
1295 if (storeType == SYSTEM_STORE) {
1296 SLOGE("Invalid store type passed.");
1297 return CERTSVC_WRONG_ARGUMENT;
1299 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1300 "private_key_gname IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
1301 (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
1302 (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1305 // For get_certificate_list_from_store
1306 if (is_root_app != ENABLED) {
1307 /* Gets only the list of certificates where is_root_app = 1 (which are enabled by the master application) */
1308 if (tempStore == SYSTEM_STORE) {
1309 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1310 "is_root_app_enabled=%d order by common_name asc", \
1311 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1312 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1314 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where is_root_app_enabled=%d", \
1315 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1316 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1319 /* Gets all the certificates from store without any restrictions */
1320 if (tempStore == SYSTEM_STORE) {
1321 query = sqlite3_mprintf("select gname, common_name, enabled from %Q order by common_name asc", \
1322 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1323 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
1325 query = sqlite3_mprintf("select gname, common_name, enabled from %Q", \
1326 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1327 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
1332 result = execute_select_query(db_handle, query, &stmt);
1333 if (result != CERTSVC_SUCCESS) {
1334 SLOGE("Querying database failed.");
1335 result = CERTSVC_FAIL;
1340 records = sqlite3_step(stmt);
1341 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1343 SLOGE("No records found");
1344 result = CERTSVC_SUCCESS;
1351 if (records == SQLITE_ROW) {
1352 tmpNode = (CertSvcStoreCertList *)malloc(sizeof(CertSvcStoreCertList));
1354 SLOGE("Failed to allocate memory.");
1355 result = CERTSVC_BAD_ALLOC;
1358 tmpNode->next = NULL;
1359 const char *textGname = (const char *)sqlite3_column_text(stmt, 0);
1360 const char *textAlias = (const char *)sqlite3_column_text(stmt, 1);
1361 if (!textGname || !textAlias) {
1362 SLOGE("Failed to read texts from records");
1364 result = CERTSVC_FAIL;
1368 int gnameLen = strlen(textGname);
1369 int aliasLen = strlen(textAlias);
1371 tmpNode->gname = (char *)malloc(sizeof(char) * (gnameLen + 1));
1372 tmpNode->title = (char *)malloc(sizeof(char) * (aliasLen + 1));
1373 if (!tmpNode->title || !tmpNode->gname) {
1374 free(tmpNode->gname);
1375 free(tmpNode->title);
1377 SLOGE("Failed to allocate memory");
1378 result = CERTSVC_BAD_ALLOC;
1382 memset(tmpNode->gname, 0x00, gnameLen + 1);
1383 memset(tmpNode->title, 0x00, aliasLen + 1);
1385 memcpy(tmpNode->gname, textGname, gnameLen);
1386 memcpy(tmpNode->title, textAlias, aliasLen);
1388 tmpNode->status = (int)sqlite3_column_int(stmt, 2); /* for status */
1389 tmpNode->storeType = tempStore;
1392 /* When multiple stores are passed, we need to ensure that the rootcerthead is
1393 assigned to currentNode once, else previous store data gets overwritten */
1395 rootCertHead = tmpNode;
1396 currentNode = rootCertHead;
1399 currentNode->next = tmpNode;
1400 currentNode = tmpNode;
1408 SLOGD("No entries found in database.");
1409 result = CERTSVC_SUCCESS;
1413 sqlite3_free(query);
1418 sqlite3_finalize(stmt);
1426 VcoreCertResponseData *respCertData = (VcoreCertResponseData *)malloc(count * sizeof(VcoreCertResponseData));
1427 if (!respCertData) {
1428 SLOGE("Failed to allocate memory");
1429 result = CERTSVC_BAD_ALLOC;
1433 memset(respCertData, 0x00, count * sizeof(VcoreCertResponseData));
1434 VcoreCertResponseData* currRespCertData = NULL;
1436 currentNode = rootCertHead;
1437 for (i = 0; i < count; i++) {
1438 tmpNode = currentNode->next;
1440 currRespCertData = respCertData + i;
1441 if (strlen(currentNode->gname) > sizeof(currRespCertData->gname)
1442 || strlen(currentNode->title) > sizeof(currRespCertData->title)) {
1443 SLOGE("String is too long. [%s], [%s]", currentNode->gname, currentNode->title);
1444 result = CERTSVC_FAIL;
1445 *certListBuffer = NULL;
1449 strncpy(currRespCertData->gname, currentNode->gname, strlen(currentNode->gname));
1450 strncpy(currRespCertData->title, currentNode->title, strlen(currentNode->title));
1451 currRespCertData->status = currentNode->status;
1452 currRespCertData->storeType = currentNode->storeType;
1453 //SLOGD("get cert list: %d th cert: gname=%s, title=%s, status=%d, storeType=%d", i, currRespCertData->gname, currRespCertData->title, currRespCertData->status, currRespCertData->storeType);
1455 currentNode = tmpNode;
1458 *certListBuffer = (char *) respCertData;
1459 *bufferLen = count * sizeof(VcoreCertResponseData);
1461 SLOGD("Success to create certificate list. cert_count=%d", count);
1462 result= CERTSVC_SUCCESS;
1465 sqlite3_free(query);
1468 sqlite3_finalize(stmt);
1471 currentNode = rootCertHead;
1472 while (currentNode) {
1473 tmpNode = currentNode->next;
1474 free(currentNode->title);
1475 free(currentNode->gname);
1477 currentNode=tmpNode;
1479 rootCertHead = NULL;
1485 int getCertificateAliasFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *gname, char *alias)
1487 int result = CERTSVC_SUCCESS;
1489 sqlite3_stmt *stmt = NULL;
1491 const char *text = NULL;
1493 query = sqlite3_mprintf("select common_name from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
1494 (storeType==VPN_STORE)? "vpn" : "email"), gname);
1496 result = execute_select_query(db_handle, query, &stmt);
1497 if (result != CERTSVC_SUCCESS) {
1498 SLOGE("Querying database failed.");
1499 result = CERTSVC_FAIL;
1503 records = sqlite3_step(stmt);
1504 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1505 SLOGE("No valid records found for gname passed [%s].",gname);
1506 result = CERTSVC_FAIL;
1510 if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
1511 SLOGE("No column text in returned records");
1512 result = CERTSVC_FAIL;
1516 strncpy(alias, text, strlen(text));
1518 if (strlen(alias) == 0) {
1519 SLOGE("Unable to get the alias name for the gname passed.");
1520 result = CERTSVC_FAIL;
1524 result = CERTSVC_SUCCESS;
1526 SLOGD("success : getCertificateAliasFromStore");
1529 sqlite3_free(query);
1532 sqlite3_finalize(stmt);
1537 int loadCertificatesFromStore(
1539 CertStoreType storeType,
1541 char **ppCertBlockBuffer,
1543 size_t *certBlockCount)
1545 int result = CERTSVC_SUCCESS;
1548 sqlite3_stmt *stmt = NULL;
1550 char **certs = NULL;
1551 const char *tmpText = NULL;
1554 query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
1555 (storeType==VPN_STORE)? "vpn" : "email"), gname);
1557 result = execute_select_query(db_handle, query, &stmt);
1558 if (result != CERTSVC_SUCCESS) {
1559 SLOGE("Querying database failed.");
1560 result = CERTSVC_FAIL;
1564 records = sqlite3_step(stmt);
1565 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1566 SLOGE("No valid records found for gname passed [%s].",gname);
1567 result = CERTSVC_FAIL;
1572 if (records == SQLITE_ROW) {
1574 sqlite3_free(query);
1576 const char *columnText = (const char *)sqlite3_column_text(stmt, 0);
1578 SLOGE("Failed to sqlite3_column_text");
1579 result = CERTSVC_FAIL;
1583 query = sqlite3_mprintf("select gname from %Q where associated_gname=%Q and enabled=%d and is_root_app_enabled=%d", \
1584 ((storeType==WIFI_STORE)? "wifi" : (storeType==VPN_STORE)? "vpn" : "email"), \
1585 columnText, ENABLED, ENABLED);
1588 sqlite3_finalize(stmt);
1590 result = execute_select_query(db_handle, query, &stmt);
1591 if (result != CERTSVC_SUCCESS) {
1592 SLOGE("Querying database failed.");
1593 result = CERTSVC_FAIL;
1598 records = sqlite3_step(stmt);
1599 if (records != SQLITE_ROW || records == SQLITE_DONE)
1603 certs = (char**) malloc(4 * sizeof(char *));
1605 SLOGE("Failed to allocate memory");
1606 result = CERTSVC_BAD_ALLOC;
1609 memset(certs, 0x00, 4 * sizeof(char *));
1612 if (records == SQLITE_ROW) {
1613 tmpText = (const char *)sqlite3_column_text(stmt, 0);
1615 SLOGE("Failed to sqlite3_column_text.");
1616 result = CERTSVC_FAIL;
1620 if (!((certs)[count] = strdup(tmpText))) {
1621 SLOGE("Failed to allocate memory");
1622 result = CERTSVC_BAD_ALLOC;
1631 SLOGE("No valid records found for the gname passed [%s].",gname);
1632 return CERTSVC_FAIL;
1636 *certBlockCount = count;
1637 *bufferLen = count * sizeof(ResponseCertBlock);
1638 ResponseCertBlock *certBlockList = (ResponseCertBlock *) malloc(*bufferLen);
1639 if (!certBlockList) {
1640 SLOGE("Failed to allocate memory for ResponseCertBlock");
1641 result = CERTSVC_BAD_ALLOC;
1646 memset(certBlockList, 0x00, *bufferLen);
1648 ResponseCertBlock *currentBlock = NULL;
1649 for (i = 0; i < count; i++) {
1650 currentBlock = certBlockList + i;
1651 if (sizeof(currentBlock->dataBlock) < strlen(certs[i])) {
1652 SLOGE("src is longer than dst. src[%s] dst size[%d]", certs[i], sizeof(currentBlock->dataBlock));
1653 free(certBlockList);
1654 result = CERTSVC_FAIL;
1657 strncpy(currentBlock->dataBlock, certs[i], strlen(certs[i]));
1658 currentBlock->dataBlockLen = strlen(certs[i]);
1660 *ppCertBlockBuffer = (char *)certBlockList;
1662 result = CERTSVC_SUCCESS;
1664 SLOGD("success: loadCertificatesFromStore. CERT_COUNT=%d", count);
1668 sqlite3_free(query);
1671 sqlite3_finalize(stmt);
1674 for(i = 0; i < count; i++)