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 strncat(ckm_alias, ckmc_owner_id_system, alias_len + 1);
75 strncat(ckm_alias, ckmc_owner_id_separator, alias_len + 1 - strlen(ckmc_owner_id_system));
76 strncat(ckm_alias, name, alias_len + 1 - strlen(ckmc_owner_id_system) + strlen(ckmc_owner_id_separator));
81 int ckmc_remove_alias_with_shared_owner_prefix(const char *name, int *result)
83 char *ckm_alias = add_shared_owner_prefix(name);
85 SLOGE("Failed to allocate memory");
86 return CERTSVC_BAD_ALLOC;
89 *result = ckmc_remove_alias(ckm_alias);
93 return CERTSVC_SUCCESS;
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_NONE) {
307 SLOGE("Failed to save trusted data. ckm errcode[%d]", result);
311 return CERTSVC_SUCCESS;
314 int saveCertificateToSystemStore(
319 if (!pGname || !pData || dataLen < 1) {
320 SLOGE("Invalid input parameter passed.");
321 return CERTSVC_WRONG_ARGUMENT;
324 int result = add_file_to_system_cert_dir(pGname, pData, dataLen);
325 if (result != CERTSVC_SUCCESS)
326 SLOGE("Failed to store the certificate in store.");
331 int get_certificate_buffer_from_store(
333 CertStoreType storeType,
338 int result = CERTSVC_SUCCESS;
340 char *tempBuffer = NULL;
342 sqlite3_stmt *stmt = NULL;
345 SLOGE("Invalid input parameter passed.");
346 return CERTSVC_WRONG_ARGUMENT;
349 if (storeType != SYSTEM_STORE)
350 query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
351 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
352 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
354 query = sqlite3_mprintf("select certificate from ssl where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
355 pGname, ENABLED, ENABLED);
357 result = execute_select_query(db_handle, query, &stmt);
358 if (result != CERTSVC_SUCCESS) {
359 SLOGE("Querying database failed.");
360 result = CERTSVC_FAIL;
364 records = sqlite3_step(stmt);
365 if (records != SQLITE_ROW || records == SQLITE_DONE) {
366 SLOGE("No valid records found for given gname [%s].",pGname);
367 result = CERTSVC_FAIL;
371 tempBuffer = (char *)malloc(sizeof(char) * VCORE_MAX_RECV_DATA_SIZE);
373 SLOGE("Fail to allocate memory");
374 result = CERTSVC_FAIL;
378 memset(tempBuffer, 0x00, VCORE_MAX_RECV_DATA_SIZE);
380 if (storeType == SYSTEM_STORE)
381 result = getCertificateDetailFromSystemStore(db_handle, pGname, tempBuffer, certSize);
383 result = getCertificateDetailFromStore(db_handle, storeType, PEM_CRT, pGname, tempBuffer, certSize);
385 if (result != CERTSVC_SUCCESS) {
386 SLOGE("Failed to set request data.");
387 result = CERTSVC_WRONG_ARGUMENT;
391 *certBuffer = tempBuffer;
394 if (result != CERTSVC_SUCCESS)
401 sqlite3_finalize(stmt);
406 int update_ca_certificate_file(sqlite3 *db_handle, char *certBuffer, size_t certLength)
408 int result = CERTSVC_SUCCESS;
415 sqlite3_stmt *stmt = NULL;
417 int storeType[4] = {SYSTEM_STORE, WIFI_STORE, VPN_STORE, EMAIL_STORE};
419 /* During install of a root certificate, the root certificate gets appended at
420 * the end to optimise the write operation onto ca-certificate.crt file. */
421 if (certBuffer && certLength > 0) {
422 result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
423 if (result != CERTSVC_SUCCESS) {
424 SLOGE("Failed to write to file.");
425 result = CERTSVC_FAIL;
431 /* get the ssl certificate from database */
433 query = sqlite3_mprintf("select certificate from ssl where enabled=%d and is_root_app_enabled=%d", ENABLED, ENABLED);
434 else if (count > 0 && count < 4)
435 /* gets all the gname which is marked as root certificate and enabled = TRUE */
436 query = sqlite3_mprintf("select gname from %Q where is_root_cert=%d and enabled=%d and is_root_app_enabled=%d", \
437 ((count == 1)?"wifi":(count == 2)?"vpn":"email"), ENABLED, ENABLED, ENABLED);
439 result = execute_select_query(db_handle, query, &stmt);
440 if (result != CERTSVC_SUCCESS) {
441 SLOGE("Querying database failed.");
445 /* update the ca-certificate.crt file */
447 records = sqlite3_step(stmt);
448 if (records != SQLITE_ROW || records == SQLITE_DONE) {
449 result = CERTSVC_SUCCESS;
453 if (records == SQLITE_ROW) {
459 /* gets the certificate from database for system store */
460 text = (const char *)sqlite3_column_text(stmt, 0);
462 certLength = strlen(text);
463 certBuffer = strndup(text, certLength);
466 /* gets the certificate from key-manager for other stores */
467 text = (const char *)sqlite3_column_text(stmt, 0);
469 pValue = strndup(text, strlen(text));
471 result = get_certificate_buffer_from_store(db_handle, storeType[count], pValue, &certBuffer, &certLength);
472 if (result != CERTSVC_SUCCESS) {
473 SLOGE("Failed to get certificate buffer from key-manager.");
480 result = write_to_ca_cert_crt_file("wb", certBuffer, certLength);
482 result = write_to_ca_cert_crt_file("ab", certBuffer, certLength);
484 if (result != CERTSVC_SUCCESS) {
485 SLOGE("Failed to write to file.");
486 result = CERTSVC_FAIL;
499 SLOGD("Successfully updated ca-certificate.crt file.");
506 sqlite3_finalize(stmt);
511 int enable_disable_cert_status(
513 CertStoreType storeType,
518 int ckmc_result = CKMC_ERROR_UNKNOWN;
519 int result = CERTSVC_SUCCESS;
522 size_t certLength = 0;
523 char *certBuffer = NULL;
525 const char *text = NULL;
526 sqlite3_stmt *stmt = NULL;
528 if (status != DISABLED && status != ENABLED) {
529 SLOGE("Invalid cert status");
530 return CERTSVC_INVALID_STATUS;
533 query = sqlite3_mprintf("select * from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
534 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
536 SLOGE("Failed to generate query");
537 return CERTSVC_BAD_ALLOC;
540 result = execute_select_query(db_handle, query, &stmt);
543 if (result != CERTSVC_SUCCESS || !stmt) {
544 SLOGE("Querying database failed.");
548 records = sqlite3_step(stmt);
549 sqlite3_finalize(stmt);
552 if (records != SQLITE_ROW) {
553 SLOGE("No valid records found.");
557 if (status == DISABLED) {
558 /* check certificate presence in disabled_certs table before inserting */
559 query = sqlite3_mprintf("select * from disabled_certs where gname=%Q", pGname);
561 SLOGE("Failed to generate query");
562 return CERTSVC_BAD_ALLOC;
565 result = execute_select_query(db_handle, query, &stmt);
569 if (result != CERTSVC_SUCCESS) {
570 SLOGE("Querying database failed.");
574 records = sqlite3_step(stmt);
575 sqlite3_finalize(stmt);
578 if (records == SQLITE_ROW) {
579 SLOGE("Selected certificate identifier is already disabled.", pGname);
583 /* get certificate from keymanager*/
584 result = get_certificate_buffer_from_store(db_handle, storeType, pGname, &certBuffer, &certSize);
585 if (result != CERTSVC_SUCCESS) {
586 SLOGE("Failed to get certificate buffer. result[%d]", result);
590 /* inserting the disabled certificate to disabled_certs table */
591 query = sqlite3_mprintf("insert into disabled_certs (gname, certificate) values (%Q, %Q)", pGname, certBuffer);
595 SLOGE("Failed to generate query");
596 return CERTSVC_BAD_ALLOC;
599 result = execute_insert_update_query(db_handle, query);
602 if (result != CERTSVC_SUCCESS) {
603 SLOGE("Insert to database failed.");
607 if (storeType != SYSTEM_STORE) {
608 result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
610 if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
611 SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
616 result = del_file_from_system_cert_dir(pGname);
617 if (result != CERTSVC_SUCCESS) {
618 SLOGE("Error in del_file_from_system_cert_dir. ret[%d]", result);
622 } else { /* moving the certificate to enabled state */
623 query = sqlite3_mprintf("select certificate from disabled_certs where gname=%Q", pGname);
625 SLOGE("Failed to generate query");
626 return CERTSVC_BAD_ALLOC;
629 result = execute_select_query(db_handle, query, &stmt);
632 if (result != CERTSVC_SUCCESS) {
633 SLOGE("Querying database failed.");
637 records = sqlite3_step(stmt);
638 if (records == SQLITE_ROW) {
639 text = (const char *)sqlite3_column_text(stmt, 0);
642 SLOGE("Invalid column text");
643 sqlite3_finalize(stmt);
647 certBuffer = strndup(text, strlen(text));
649 sqlite3_finalize(stmt);
652 SLOGE("Failed to allocate memory");
653 return CERTSVC_BAD_ALLOC;
656 certLength = strlen(certBuffer);
658 if (storeType == SYSTEM_STORE)
659 result = saveCertificateToSystemStore(pGname, certBuffer, certLength);
661 result = saveCertificateToStore(pGname, certBuffer, certLength);
665 if (result != CERTSVC_SUCCESS) {
666 SLOGE("Failed to save certificate to key-manager. ret[%d]", result);
670 query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
672 SLOGE("Failed to generate query");
673 return CERTSVC_BAD_ALLOC;
676 result = execute_insert_update_query(db_handle, query);
679 if (result != CERTSVC_SUCCESS) {
680 SLOGE("Unable to delete certificate entry from database. ret[%d]", result);
686 if (is_root_app == ENABLED)
687 query = sqlite3_mprintf("update %Q set is_root_app_enabled=%d , enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
688 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), CertStatus_to_int(status), status, pGname);
690 query = sqlite3_mprintf("update %Q set enabled=%d where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
691 (storeType == VPN_STORE)? "vpn" : (storeType == EMAIL_STORE)? "email" : "ssl"), CertStatus_to_int(status), pGname);
694 SLOGE("Failed to generate query");
695 return CERTSVC_BAD_ALLOC;
698 result = execute_insert_update_query(db_handle, query);
701 if (result != CERTSVC_SUCCESS) {
702 SLOGE("Update failed. ret[%d]", result);
709 int setCertificateStatusToStore(
711 CertStoreType storeType,
717 SLOGE("Invalid input parameter passed.");
718 return CERTSVC_WRONG_ARGUMENT;
721 int result = enable_disable_cert_status(db_handle, storeType, is_root_app, pGname, status);
722 if (result != CERTSVC_SUCCESS) {
723 SLOGE("Failed to disable certificate.");
727 SLOGD("Successfully updated the certificate status from %s to %s.",
728 (status == DISABLED) ? "ENABLED" : "DISABLED", (status == DISABLED) ? "DISABLED" : "ENABLED");
729 return CERTSVC_SUCCESS;
732 int getCertificateStatusFromStore(
734 CertStoreType storeType,
739 SLOGE("Invalid input parameter passed.");
740 return CERTSVC_WRONG_ARGUMENT;
743 char *query = sqlite3_mprintf("select gname, common_name, enabled from %Q where gname=%Q",\
744 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
745 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname);
747 SLOGE("Failed to generate query");
748 return CERTSVC_BAD_ALLOC;
751 sqlite3_stmt *stmt = NULL;
752 int result = execute_select_query(db_handle, query, &stmt);
755 if (result != CERTSVC_SUCCESS || !stmt) {
756 SLOGE("Querying database failed.");
761 result = sqlite3_step(stmt);
762 if (result != SQLITE_ROW || result == SQLITE_DONE) {
763 SLOGE("No valid records found.");
765 sqlite3_finalize(stmt);
769 *status = int_to_CertStatus(sqlite3_column_int(stmt, 2));
771 sqlite3_finalize(stmt);
773 return CERTSVC_SUCCESS;
776 int check_alias_exist_in_database(
778 CertStoreType storeType,
782 sqlite3_stmt *stmt = NULL;
784 if (!alias || !isUnique) {
785 SLOGE("Invalid input parameter passed.");
786 return CERTSVC_WRONG_ARGUMENT;
789 char *query = sqlite3_mprintf("select * from %Q where common_name=%Q", ((storeType == WIFI_STORE)? "wifi" : \
790 (storeType == VPN_STORE)? "vpn" : "email"),alias);
793 SLOGE("Failed to generate query");
794 return CERTSVC_BAD_ALLOC;
797 int result = execute_select_query(db_handle, query, &stmt);
800 if (result != CERTSVC_SUCCESS || !stmt) {
801 SLOGE("Querying database failed.");
805 result = sqlite3_step(stmt);
806 sqlite3_finalize(stmt);
808 if (result != SQLITE_ROW)
809 *isUnique = CERTSVC_TRUE;
811 *isUnique = CERTSVC_FALSE;
813 return CERTSVC_SUCCESS;
816 int installCertificateToStore(
818 CertStoreType storeType,
820 const char *common_name,
821 const char *private_key_gname,
822 const char *associated_gname,
823 const char *dataBlock,
828 || (certType == P12_END_USER && !common_name && !private_key_gname)
829 || (certType != P12_END_USER && !common_name && !associated_gname)) {
830 SLOGE("Invalid input parameter passed.");
831 return CERTSVC_WRONG_ARGUMENT;
834 if (storeType != SYSTEM_STORE
835 && saveCertificateToStore(
838 dataBlockLen) != CERTSVC_SUCCESS) {
839 SLOGE("FAIL to save certificate to key-manager.");
843 if (certType == P12_PKEY) {
844 SLOGD("Don't save private key in store");
845 return CERTSVC_SUCCESS;
849 if (certType == P12_END_USER && private_key_gname) {
850 query = sqlite3_mprintf("insert into %Q (gname, common_name, private_key_gname, associated_gname, enabled, is_root_app_enabled) "\
851 "values (%Q, %Q, %Q, %Q, %d, %d)",((storeType == WIFI_STORE)? "wifi" : \
852 (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, private_key_gname, pGname, ENABLED, ENABLED);
853 } else if (certType == PEM_CRT || certType == P12_TRUSTED) {
854 query = sqlite3_mprintf("insert into %Q (gname, common_name, is_root_cert, associated_gname, enabled, is_root_app_enabled) values "\
855 "(%Q, %Q, %d, %Q, %d, %d)", ((storeType == WIFI_STORE)? "wifi" : \
856 (storeType == VPN_STORE)? "vpn" : "email"), pGname, common_name, ENABLED, associated_gname, ENABLED, ENABLED);
857 } else if (certType == P12_INTERMEDIATE) {
858 query = sqlite3_mprintf("insert into %Q (gname, common_name, associated_gname, enabled, is_root_app_enabled) values (%Q, %Q, %Q, %d, %d)", \
859 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"),
860 pGname, common_name, associated_gname, ENABLED, ENABLED);
864 SLOGE("Failed to generate query");
865 return CERTSVC_BAD_ALLOC;
868 int result = execute_insert_update_query(db_handle, query);
871 if (result != CERTSVC_SUCCESS) {
872 SLOGE("Insert to database failed.");
876 return CERTSVC_SUCCESS;
879 int checkAliasExistsInStore(
881 CertStoreType storeType,
886 SLOGE("Invalid input parameter passed.");
887 return CERTSVC_WRONG_ARGUMENT;
890 *isUnique = CERTSVC_FAIL;
891 int result = check_alias_exist_in_database(db_handle, storeType, alias, isUnique);
892 if (result != CERTSVC_SUCCESS) {
893 SLOGE("Failed to check_alias_exist_in_database. err[%d]", result);
897 if (*isUnique == CERTSVC_TRUE) {
898 SLOGD("Alias (%s) does not exist in %s store.",
900 (storeType == VPN_STORE) ? "VPN" :
901 (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
903 SLOGD("Alias (%s) exist in %s store.",
905 (storeType == VPN_STORE) ? "VPN" :
906 (storeType == WIFI_STORE) ? "WIFI" : "EMAIL");
909 return CERTSVC_SUCCESS;
912 int getCertificateDetailFromStore(
914 CertStoreType storeType,
920 int result = CERTSVC_SUCCESS;
923 const char *text = NULL;
924 sqlite3_stmt *stmt = NULL;
925 ckmc_raw_buffer_s *cert_data = NULL;
927 if (!pGname || !pOutData) {
928 SLOGE("Invalid input parameter passed.");
929 return CERTSVC_WRONG_ARGUMENT;
932 /* start constructing query */
933 if (certType == P12_PKEY) {
934 /* From the given certificate identifier, get the associated_gname for the certificate.
935 * Then query the database for records matching the associated_gname to get the private key */
936 query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", \
937 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), pGname);
939 SLOGE("Failed to generate query");
940 return CERTSVC_BAD_ALLOC;
943 result = execute_select_query(db_handle, query, &stmt);
946 if (result != CERTSVC_SUCCESS) {
947 SLOGE("Querying database failed.");
951 records = sqlite3_step(stmt);
952 if (records != SQLITE_ROW) {
953 SLOGE("No valid records found.");
954 sqlite3_finalize(stmt);
958 text = (const char *)sqlite3_column_text(stmt, 0);
961 SLOGE("No valid column text");
962 sqlite3_finalize(stmt);
966 query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
967 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : "email"), text, ENABLED, ENABLED);
969 sqlite3_finalize(stmt);
970 } else if (storeType != SYSTEM_STORE) {
971 query = sqlite3_mprintf("select * from %Q where gname=%Q and enabled=%d and is_root_app_enabled=%d", \
972 ((storeType == WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
973 (storeType == EMAIL_STORE)? "email" : "ssl"), pGname, ENABLED, ENABLED);
977 SLOGE("Failed to generate query");
978 return CERTSVC_BAD_ALLOC;
981 result = execute_select_query(db_handle, query, &stmt);
984 if (result != CERTSVC_SUCCESS) {
985 SLOGE("Querying database failed.");
989 records = sqlite3_step(stmt);
990 if (records != SQLITE_ROW) {
991 SLOGE("No valid records found.");
992 sqlite3_finalize(stmt);
996 if (certType == P12_PKEY) {
997 if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
998 SLOGE("No valid column text");
999 sqlite3_finalize(stmt);
1000 return CERTSVC_FAIL;
1006 char *ckm_alias = add_shared_owner_prefix(pGname);
1008 SLOGE("Failed to make alias. memory allocation error.");
1009 return CERTSVC_BAD_ALLOC;
1012 result = ckmc_get_data(ckm_alias, NULL, &cert_data);
1015 sqlite3_finalize(stmt);
1017 if (result != CKMC_ERROR_NONE) {
1018 SLOGE("Failed to get certificate from key-manager. ckm ret[%d]", result);
1019 *size = CERTSVC_FAIL;
1020 return CERTSVC_FAIL;
1023 memcpy(pOutData, cert_data->data, cert_data->size);
1024 pOutData[cert_data->size] = 0;
1025 *size = cert_data->size;
1027 ckmc_buffer_free(cert_data);
1029 return CERTSVC_SUCCESS;
1032 int getCertificateDetailFromSystemStore(
1038 int result = CERTSVC_SUCCESS;
1040 size_t certLength = 0;
1042 const char *text = NULL;
1043 sqlite3_stmt *stmt = NULL;
1046 SLOGE("Invalid input parameter passed.");
1047 return CERTSVC_WRONG_ARGUMENT;
1050 query = sqlite3_mprintf("select certificate from ssl where gname=%Q and is_root_app_enabled=%d", \
1051 pGname, ENABLED, ENABLED);
1053 SLOGE("Query is NULL.");
1054 return CERTSVC_FAIL;
1057 result = execute_select_query(db_handle, query, &stmt);
1058 sqlite3_free(query);
1060 if (result != CERTSVC_SUCCESS) {
1061 SLOGE("Querying database failed.");
1065 records = sqlite3_step(stmt);
1066 if (records != SQLITE_ROW) {
1067 SLOGE("No valid records found for passed gname [%s].", pGname);
1068 sqlite3_finalize(stmt);
1069 return CERTSVC_FAIL;
1072 text = (const char *)sqlite3_column_text(stmt, 0);
1075 SLOGE("Fail to sqlite3_column_text");
1076 sqlite3_finalize(stmt);
1077 return CERTSVC_FAIL;
1080 certLength = strlen(text);
1081 if (certLength >= 4096) {
1082 sqlite3_finalize(stmt);
1083 SLOGE("certificate is too long");
1084 return CERTSVC_FAIL;
1087 memcpy(pOutData, text, certLength);
1088 pOutData[certLength] = 0;
1091 sqlite3_finalize(stmt);
1092 return CERTSVC_SUCCESS;
1095 int deleteCertificateFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *pGname) {
1097 int result = CERTSVC_SUCCESS;
1098 int ckmc_result = CKMC_ERROR_UNKNOWN;
1101 char *private_key_name = NULL;
1102 sqlite3_stmt *stmt = NULL;
1105 SLOGE("Invalid input parameter passed.");
1106 return CERTSVC_WRONG_ARGUMENT;
1109 if (storeType != SYSTEM_STORE) {
1110 /* start constructing query */
1111 query = sqlite3_mprintf("select private_key_gname from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" :\
1112 (storeType == VPN_STORE)? "vpn" : "email"), pGname);
1114 result = execute_select_query(db_handle, query, &stmt);
1115 if (result != CERTSVC_SUCCESS) {
1116 SLOGE("Querying database failed.");
1117 result = CERTSVC_FAIL;
1121 records = sqlite3_step(stmt);
1122 if ((records != SQLITE_ROW) || (records == SQLITE_DONE)) {
1123 SLOGE("No valid records found for passed gname [%s].",pGname);
1124 result = CERTSVC_FAIL;
1128 /* if a cert is having private-key in it, the private key should
1129 * be deleted first from key-manager, then the actual cert */
1130 if (sqlite3_column_text(stmt, 0) != NULL) {
1131 private_key_name = strdup((const char *)sqlite3_column_text(stmt, 0));
1132 result = ckmc_remove_alias_with_shared_owner_prefix(private_key_name, &ckmc_result);
1133 if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
1134 SLOGE("Failed to delete certificate from key-manager. ckmc_result[%d]", ckmc_result);
1135 result = CERTSVC_FAIL;
1140 /* removing the actual cert */
1141 result = ckmc_remove_alias_with_shared_owner_prefix(pGname, &ckmc_result);
1142 if (result != CERTSVC_SUCCESS || ckmc_result != CKMC_ERROR_NONE) {
1143 query = sqlite3_mprintf("delete from disabled_certs where gname=%Q", pGname);
1144 result = execute_insert_update_query(db_handle, query);
1145 if (result != CERTSVC_SUCCESS) {
1146 SLOGE("Unable to delete certificate entry from database.");
1147 result = CERTSVC_FAIL;
1153 sqlite3_free(query);
1158 sqlite3_finalize(stmt);
1162 query = sqlite3_mprintf("delete from %Q where gname=%Q", ((storeType == WIFI_STORE)? "wifi" : \
1163 (storeType == VPN_STORE)? "vpn" : "email"), pGname);
1165 result = execute_insert_update_query(db_handle, query);
1166 if (result != CERTSVC_SUCCESS) {
1167 SLOGE("Unable to delete certificate entry from database.");
1168 result = CERTSVC_FAIL;
1172 SLOGE("Invalid store type passed.");
1173 result = CERTSVC_INVALID_STORE_TYPE;
1175 SLOGD("Success in deleting the certificate from store.");
1179 sqlite3_free(query);
1182 sqlite3_finalize(stmt);
1184 free(private_key_name);
1189 int getCertificateListFromStore(
1192 CertStoreType storeType,
1194 char **certListBuffer,
1198 int result = CERTSVC_SUCCESS;
1199 CertSvcStoreCertList *rootCertHead = NULL;
1200 CertSvcStoreCertList *tmpNode = NULL;
1201 CertSvcStoreCertList *currentNode = NULL;
1202 sqlite3_stmt *stmt = NULL;
1211 /* Iteration only possible from VPN_STORE till SYSTEM_STORE */
1212 if (loopCount == (MAX_STORE_ENUMS - 1))
1215 /* Check if the passed store type matches with any of the in-built store type */
1216 if ((1 << loopCount) & storeType) {
1217 /* if a store type matches, put that value as storetype argument in the below function */
1218 CertStoreType tempStore = (CertStoreType) (1 << loopCount);
1219 SLOGD("Processing storetype [%s]", (tempStore == WIFI_STORE)? "WIFI" : (tempStore == VPN_STORE)? "VPN" : \
1220 (tempStore == EMAIL_STORE)? "EMAIL" : "SYSTEM");
1222 if (reqType == CERTSVC_GET_ROOT_CERTIFICATE_LIST) {
1223 // For get_root_certificate_list_from_store
1224 if (storeType == SYSTEM_STORE) {
1225 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where enabled=%d "\
1226 "and is_root_app_enabled=%d and order by common_name asc", "ssl", ENABLED, ENABLED);
1228 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1229 "is_root_cert IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
1230 (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
1231 (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1233 } else if (reqType == CERTSVC_GET_USER_CERTIFICATE_LIST) {
1234 // For get_end_user_certificate_list_from_store
1235 if (storeType == SYSTEM_STORE) {
1236 SLOGE("Invalid store type passed.");
1237 return CERTSVC_WRONG_ARGUMENT;
1239 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1240 "private_key_gname IS NOT NULL and is_root_app_enabled=%d and enabled=%d", \
1241 (storeType== WIFI_STORE)? "wifi" : (storeType == VPN_STORE)? "vpn" : \
1242 (storeType == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1245 // For get_certificate_list_from_store
1246 if (is_root_app != ENABLED) {
1247 /* Gets only the list of certificates where is_root_app = 1 (which are enabled by the master application) */
1248 if (tempStore == SYSTEM_STORE) {
1249 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where "\
1250 "is_root_app_enabled=%d order by common_name asc", \
1251 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1252 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1254 query = sqlite3_mprintf("select gname, common_name, enabled from %Q where is_root_app_enabled=%d", \
1255 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1256 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED, ENABLED);
1259 /* Gets all the certificates from store without any restrictions */
1260 if (tempStore == SYSTEM_STORE) {
1261 query = sqlite3_mprintf("select gname, common_name, enabled from %Q order by common_name asc", \
1262 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1263 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
1265 query = sqlite3_mprintf("select gname, common_name, enabled from %Q", \
1266 (tempStore== WIFI_STORE)? "wifi" : (tempStore == VPN_STORE)? "vpn" : \
1267 (tempStore == EMAIL_STORE)? "email" : "ssl", ENABLED);
1272 result = execute_select_query(db_handle, query, &stmt);
1273 if (result != CERTSVC_SUCCESS) {
1274 SLOGE("Querying database failed.");
1275 result = CERTSVC_FAIL;
1280 records = sqlite3_step(stmt);
1281 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1283 SLOGE("No records found");
1284 result = CERTSVC_SUCCESS;
1291 if (records == SQLITE_ROW) {
1292 tmpNode = (CertSvcStoreCertList *)malloc(sizeof(CertSvcStoreCertList));
1294 SLOGE("Failed to allocate memory.");
1295 result = CERTSVC_BAD_ALLOC;
1298 tmpNode->next = NULL;
1299 const char *textGname = (const char *)sqlite3_column_text(stmt, 0);
1300 const char *textAlias = (const char *)sqlite3_column_text(stmt, 1);
1301 if (!textGname || !textAlias) {
1302 SLOGE("Failed to read texts from records");
1304 result = CERTSVC_FAIL;
1308 int gnameLen = strlen(textGname);
1309 int aliasLen = strlen(textAlias);
1311 tmpNode->gname = (char *)malloc(sizeof(char) * (gnameLen + 1));
1312 tmpNode->title = (char *)malloc(sizeof(char) * (aliasLen + 1));
1313 if (!tmpNode->title || !tmpNode->gname) {
1314 free(tmpNode->gname);
1315 free(tmpNode->title);
1317 SLOGE("Failed to allocate memory");
1318 result = CERTSVC_BAD_ALLOC;
1322 memset(tmpNode->gname, 0x00, gnameLen + 1);
1323 memset(tmpNode->title, 0x00, aliasLen + 1);
1325 memcpy(tmpNode->gname, textGname, gnameLen);
1326 memcpy(tmpNode->title, textAlias, aliasLen);
1328 tmpNode->status = (int)sqlite3_column_int(stmt, 2); /* for status */
1329 tmpNode->storeType = tempStore;
1332 /* When multiple stores are passed, we need to ensure that the rootcerthead is
1333 assigned to currentNode once, else previous store data gets overwritten */
1335 rootCertHead = tmpNode;
1336 currentNode = rootCertHead;
1339 currentNode->next = tmpNode;
1340 currentNode = tmpNode;
1348 SLOGD("No entries found in database.");
1349 result = CERTSVC_SUCCESS;
1353 sqlite3_free(query);
1358 sqlite3_finalize(stmt);
1366 VcoreCertResponseData *respCertData = (VcoreCertResponseData *)malloc(count * sizeof(VcoreCertResponseData));
1367 if (!respCertData) {
1368 SLOGE("Failed to allocate memory");
1369 result = CERTSVC_BAD_ALLOC;
1373 memset(respCertData, 0x00, count * sizeof(VcoreCertResponseData));
1374 VcoreCertResponseData* currRespCertData = NULL;
1376 currentNode = rootCertHead;
1377 for (i = 0; i < count; i++) {
1378 tmpNode = currentNode->next;
1380 currRespCertData = respCertData + i;
1381 if (strlen(currentNode->gname) > sizeof(currRespCertData->gname)
1382 || strlen(currentNode->title) > sizeof(currRespCertData->title)) {
1383 SLOGE("String is too long. [%s], [%s]", currentNode->gname, currentNode->title);
1384 result = CERTSVC_FAIL;
1385 *certListBuffer = NULL;
1389 strncpy(currRespCertData->gname, currentNode->gname, strlen(currentNode->gname));
1390 strncpy(currRespCertData->title, currentNode->title, strlen(currentNode->title));
1391 currRespCertData->status = currentNode->status;
1392 currRespCertData->storeType = currentNode->storeType;
1393 //SLOGD("get cert list: %d th cert: gname=%s, title=%s, status=%d, storeType=%d", i, currRespCertData->gname, currRespCertData->title, currRespCertData->status, currRespCertData->storeType);
1395 currentNode = tmpNode;
1398 *certListBuffer = (char *) respCertData;
1399 *bufferLen = count * sizeof(VcoreCertResponseData);
1401 SLOGD("Success to create certificate list. cert_count=%d", count);
1402 result= CERTSVC_SUCCESS;
1405 sqlite3_free(query);
1408 sqlite3_finalize(stmt);
1411 currentNode = rootCertHead;
1412 while (currentNode) {
1413 tmpNode = currentNode->next;
1414 free(currentNode->title);
1415 free(currentNode->gname);
1417 currentNode=tmpNode;
1419 rootCertHead = NULL;
1425 int getCertificateAliasFromStore(sqlite3 *db_handle, CertStoreType storeType, const char *gname, char *alias)
1427 int result = CERTSVC_SUCCESS;
1429 sqlite3_stmt *stmt = NULL;
1431 const char *text = NULL;
1433 query = sqlite3_mprintf("select common_name from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
1434 (storeType==VPN_STORE)? "vpn" : "email"), gname);
1436 result = execute_select_query(db_handle, query, &stmt);
1437 if (result != CERTSVC_SUCCESS) {
1438 SLOGE("Querying database failed.");
1439 result = CERTSVC_FAIL;
1443 records = sqlite3_step(stmt);
1444 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1445 SLOGE("No valid records found for gname passed [%s].",gname);
1446 result = CERTSVC_FAIL;
1450 if (!(text = (const char *)sqlite3_column_text(stmt, 0))) {
1451 SLOGE("No column text in returned records");
1452 result = CERTSVC_FAIL;
1456 strncpy(alias, text, strlen(text));
1458 if (strlen(alias) == 0) {
1459 SLOGE("Unable to get the alias name for the gname passed.");
1460 result = CERTSVC_FAIL;
1464 result = CERTSVC_SUCCESS;
1466 SLOGD("success : getCertificateAliasFromStore");
1469 sqlite3_free(query);
1472 sqlite3_finalize(stmt);
1477 int loadCertificatesFromStore(
1479 CertStoreType storeType,
1481 char **ppCertBlockBuffer,
1483 size_t *certBlockCount)
1485 int result = CERTSVC_SUCCESS;
1488 sqlite3_stmt *stmt = NULL;
1490 char **certs = NULL;
1491 const char *tmpText = NULL;
1494 query = sqlite3_mprintf("select associated_gname from %Q where gname=%Q", ((storeType==WIFI_STORE)? "wifi" : \
1495 (storeType==VPN_STORE)? "vpn" : "email"), gname);
1497 result = execute_select_query(db_handle, query, &stmt);
1498 if (result != CERTSVC_SUCCESS) {
1499 SLOGE("Querying database failed.");
1500 result = CERTSVC_FAIL;
1504 records = sqlite3_step(stmt);
1505 if (records != SQLITE_ROW || records == SQLITE_DONE) {
1506 SLOGE("No valid records found for gname passed [%s].",gname);
1507 result = CERTSVC_FAIL;
1512 if (records == SQLITE_ROW) {
1514 sqlite3_free(query);
1516 const char *columnText = (const char *)sqlite3_column_text(stmt, 0);
1518 SLOGE("Failed to sqlite3_column_text");
1519 result = CERTSVC_FAIL;
1523 query = sqlite3_mprintf("select gname from %Q where associated_gname=%Q and enabled=%d and is_root_app_enabled=%d", \
1524 ((storeType==WIFI_STORE)? "wifi" : (storeType==VPN_STORE)? "vpn" : "email"), \
1525 columnText, ENABLED, ENABLED);
1528 sqlite3_finalize(stmt);
1530 result = execute_select_query(db_handle, query, &stmt);
1531 if (result != CERTSVC_SUCCESS) {
1532 SLOGE("Querying database failed.");
1533 result = CERTSVC_FAIL;
1538 records = sqlite3_step(stmt);
1539 if (records != SQLITE_ROW || records == SQLITE_DONE)
1543 certs = (char**) malloc(4 * sizeof(char *));
1545 SLOGE("Failed to allocate memory");
1546 result = CERTSVC_BAD_ALLOC;
1549 memset(certs, 0x00, 4 * sizeof(char *));
1552 if (records == SQLITE_ROW) {
1553 tmpText = (const char *)sqlite3_column_text(stmt, 0);
1555 SLOGE("Failed to sqlite3_column_text.");
1556 result = CERTSVC_FAIL;
1560 if (!((certs)[count] = strdup(tmpText))) {
1561 SLOGE("Failed to allocate memory");
1562 result = CERTSVC_BAD_ALLOC;
1571 SLOGE("No valid records found for the gname passed [%s].",gname);
1572 return CERTSVC_FAIL;
1576 *certBlockCount = count;
1577 *bufferLen = count * sizeof(ResponseCertBlock);
1578 ResponseCertBlock *certBlockList = (ResponseCertBlock *) malloc(*bufferLen);
1579 if (!certBlockList) {
1580 SLOGE("Failed to allocate memory for ResponseCertBlock");
1581 result = CERTSVC_BAD_ALLOC;
1586 memset(certBlockList, 0x00, *bufferLen);
1588 ResponseCertBlock *currentBlock = NULL;
1589 for (i = 0; i < count; i++) {
1590 currentBlock = certBlockList + i;
1591 if (sizeof(currentBlock->dataBlock) < strlen(certs[i])) {
1592 SLOGE("src is longer than dst. src[%s] dst size[%d]", certs[i], sizeof(currentBlock->dataBlock));
1593 free(certBlockList);
1594 result = CERTSVC_FAIL;
1597 strncpy(currentBlock->dataBlock, certs[i], strlen(certs[i]));
1598 currentBlock->dataBlockLen = strlen(certs[i]);
1600 *ppCertBlockBuffer = (char *)certBlockList;
1602 result = CERTSVC_SUCCESS;
1604 SLOGD("success: loadCertificatesFromStore. CERT_COUNT=%d", count);
1608 sqlite3_free(query);
1611 sqlite3_finalize(stmt);
1614 for(i = 0; i < count; i++)