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-main.c
18 * @author Madhan A K (madhan.ak@samsung.com)
19 * Kyungwook Tak (k.tak@samsung.com)
21 * @brief cert-svc server.
28 #include <sys/types.h>
30 #include <sys/socket.h>
32 #include <sys/select.h>
33 #include <systemd/sd-daemon.h>
35 #include <cert-service-debug.h>
36 #include <cert-svc/cerror.h>
37 #include <cert-svc/ccert.h>
38 #include <vcore/cert-svc-client.h>
40 #include <cert-server-logic.h>
42 sqlite3 *cert_store_db = NULL;
44 int open_db(sqlite3 **db_handle, const char *db_path) {
46 int result = CERTSVC_FAIL;
49 if (access(db_path, F_OK) == 0) {
50 result = db_util_open(db_path, &handle, 0);
51 if (result != SQLITE_OK) {
52 SLOGE("connect db [%s] failed!", db_path);
56 return CERTSVC_SUCCESS;
58 SLOGD("%s DB does not exists. Creating one!!", db_path);
60 result = db_util_open(db_path, &handle, 0);
61 if (result != SQLITE_OK) {
62 SLOGE("connect to db [%s] failed!.", db_path);
66 return CERTSVC_SUCCESS;
69 int evaluate_query(sqlite3 *db_handle, char *query) {
71 int result = CERTSVC_SUCCESS;
72 sqlite3_stmt* p_statement;
75 SLOGE("Database not initialised.");
76 return CERTSVC_WRONG_ARGUMENT;
80 SLOGE("Query is NULL.");
81 return CERTSVC_WRONG_ARGUMENT;
84 result = sqlite3_prepare_v2(db_handle, query, strlen(query), &p_statement, NULL);
85 if (result != SQLITE_OK) {
86 SLOGE("Sqlite3 error [%d] : <%s> preparing <%s> query.", result, sqlite3_errmsg(db_handle), query);
90 result = sqlite3_step(p_statement);
91 if (result != SQLITE_DONE) {
92 SLOGE("Sqlite3 error [%d] : <%s> executing <%s> statement.", result, sqlite3_errmsg(db_handle), query);
96 result = sqlite3_finalize(p_statement);
97 if (result != SQLITE_OK) {
98 SLOGE("Sqlite3 error [%d] : <%s> finalising <%s> statement.", result, sqlite3_errmsg(db_handle), query);
101 return CERTSVC_SUCCESS;
104 int initialize_db(void)
106 int result = CERTSVC_SUCCESS;
108 if (cert_store_db != NULL)
109 return CERTSVC_SUCCESS;
111 result = open_db(&cert_store_db, CERTSVC_SYSTEM_STORE_DB);
112 if (result != CERTSVC_SUCCESS)
113 SLOGE("Certsvc store DB creation failed. result[%d]", result);
118 void CertSigHandler(int signo)
120 SLOGD("Got Signal %d, exiting now.", signo);
121 if (cert_store_db != NULL) {
122 sqlite3_close(cert_store_db);
123 cert_store_db = NULL;
128 int CertSvcGetSocketFromSystemd(int* pSockfd)
130 int n = sd_listen_fds(0);
133 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
134 if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, VCORE_SOCK_PATH, 0)) {
135 LOGD("Get socket from systemd. fd[%d]", fd);
137 return CERTSVC_SUCCESS;
143 void CertSvcServerComm()
145 int server_sockfd = 0;
146 int client_sockfd = 0;
149 struct sockaddr_un clientaddr;
150 int result = CERTSVC_SUCCESS;
151 char *certListBuffer = NULL;
152 char *certBlockBuffer = NULL;
153 size_t bufferLen = 0;
154 size_t blockBufferLen = 0;
156 struct timeval timeout;
160 SLOGI("cert-server is starting...");
162 VcoreRequestData recv_data;
163 VcoreResponseData send_data;
165 if (!CertSvcGetSocketFromSystemd(&server_sockfd)) {
166 SLOGE("Failed to get sockfd from systemd.");
170 client_len = sizeof(clientaddr);
171 signal(SIGINT, (void*)CertSigHandler);
173 result = initialize_db();
174 if (result != CERTSVC_SUCCESS) {
175 SLOGE("Failed to initialize database.");
176 result = CERTSVC_IO_ERROR;
177 goto Error_close_exit;
186 FD_SET(server_sockfd, &fd);
191 memset(&recv_data, 0x00, sizeof(VcoreRequestData));
192 memset(&send_data, 0x00, sizeof(VcoreResponseData));
194 int ret = select(server_sockfd + 1, &fd, NULL, NULL, &tv);
195 if (ret == 0) { // timeout
196 SLOGD("cert-server timeout. exit.");
201 SLOGE("select() error.");
205 if ((client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len)) < 0) {
206 SLOGE("Error in function accept().[socket desc :%d, error no :%d].", client_sockfd, errno);
210 SLOGD("cert-server Accept! client sock[%d]", client_sockfd);
212 if (setsockopt (client_sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
213 SLOGE("Error in Set SO_RCVTIMEO Socket Option");
214 send_data.result = CERTSVC_FAIL;
215 goto Error_close_exit;
218 if (setsockopt (client_sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
219 SLOGE("Error in Set SO_SNDTIMEO Socket Option");
220 send_data.result = CERTSVC_FAIL;
221 goto Error_close_exit;
224 SLOGD("Connected to a client...");
226 read_len = recv(client_sockfd, (char*)&recv_data, sizeof(recv_data), 0);
228 SLOGE("Error in function recv().");
229 send_data.result = CERTSVC_FAIL;
230 goto Error_close_exit;
233 SLOGD("revc request: reqType=%d", recv_data.reqType);
235 switch (recv_data.reqType) {
236 case CERTSVC_EXTRACT_CERT:
238 send_data.result = getCertificateDetailFromStore(
244 &send_data.dataBlockLen);
245 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
249 case CERTSVC_EXTRACT_SYSTEM_CERT:
251 send_data.result = getCertificateDetailFromSystemStore(
255 &send_data.dataBlockLen);
256 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
260 case CERTSVC_DELETE_CERT:
262 send_data.result = deleteCertificateFromStore(
266 if (send_data.result == CERTSVC_SUCCESS)
267 send_data.result = update_ca_certificate_file(cert_store_db, NULL, 0);
268 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
272 case CERTSVC_GET_CERTIFICATE_STATUS:
274 send_data.result = getCertificateStatusFromStore(
278 &send_data.certStatus);
279 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
283 case CERTSVC_SET_CERTIFICATE_STATUS:
285 send_data.result = setCertificateStatusToStore(
288 recv_data.is_root_app,
290 recv_data.certStatus);
291 if (send_data.result == CERTSVC_SUCCESS)
292 send_data.result = update_ca_certificate_file(cert_store_db, NULL, 0);
293 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
297 case CERTSVC_CHECK_ALIAS_EXISTS:
299 send_data.result = checkAliasExistsInStore(
303 &send_data.isAliasUnique);
304 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
308 case CERTSVC_INSTALL_CERTIFICATE:
310 send_data.result = installCertificateToStore(
314 recv_data.common_name,
315 recv_data.private_key_gname,
316 recv_data.associated_gname,
318 recv_data.dataBlockLen,
321 if ((send_data.result == CERTSVC_SUCCESS) && ((recv_data.certType == PEM_CRT) || (recv_data.certType == P12_TRUSTED)))
322 send_data.result = update_ca_certificate_file(cert_store_db, recv_data.dataBlock, recv_data.dataBlockLen);
323 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
327 case CERTSVC_GET_CERTIFICATE_LIST:
328 case CERTSVC_GET_USER_CERTIFICATE_LIST:
329 case CERTSVC_GET_ROOT_CERTIFICATE_LIST:
331 send_data.result = getCertificateListFromStore(
335 recv_data.is_root_app,
338 &send_data.certCount);
339 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
341 result = send(client_sockfd, certListBuffer, bufferLen, 0);
346 case CERTSVC_GET_CERTIFICATE_ALIAS:
348 send_data.result = getCertificateAliasFromStore(
352 send_data.common_name);
353 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
357 case CERTSVC_LOAD_CERTIFICATES:
359 send_data.result = loadCertificatesFromStore(
365 &send_data.certBlockCount);
366 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
367 if (blockBufferLen > 0)
368 result = send(client_sockfd, certBlockBuffer, blockBufferLen, 0);
373 SLOGE("Input error. Please check request type");
378 SLOGE("send failed :%d, errno %d try once", result, errno);
379 //result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
380 //SLOGE("retry result :%d, errno %d", result, errno);
385 close(server_sockfd);
387 sqlite3_close(cert_store_db);
388 cert_store_db = NULL;
392 free(certListBuffer);
395 free(certBlockBuffer);
397 if (client_sockfd >= 0) {
398 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
399 close(client_sockfd);
402 SLOGE("cannot connect to client socket.");
404 SLOGI("CertSvcServerComm done.");
409 SLOGI("cert-server start");
411 SLOGI("cert-server end");