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.
29 #include <sys/types.h>
31 #include <sys/socket.h>
33 #include <sys/select.h>
34 #include <systemd/sd-daemon.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>
42 #include <cert-server-db.h>
44 void CertSigHandler(int signo)
46 SLOGD("Got Signal %d, exiting now.", signo);
53 int CertSvcGetSocketFromSystemd(int *pSockfd)
55 int n = sd_listen_fds(0);
58 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
59 if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, VCORE_SOCK_PATH, 0)) {
60 LOGD("Get socket from systemd. fd[%d]", fd);
62 return CERTSVC_SUCCESS;
69 void CertSvcServerComm(void)
71 int server_sockfd = 0;
72 int client_sockfd = 0;
75 struct sockaddr_un clientaddr;
76 int result = CERTSVC_SUCCESS;
77 char *certListBuffer = NULL;
78 char *certBlockBuffer = NULL;
80 size_t blockBufferLen = 0;
82 struct timeval timeout;
86 SLOGI("cert-server is starting...");
88 VcoreRequestData recv_data;
89 VcoreResponseData send_data;
91 if (CertSvcGetSocketFromSystemd(&server_sockfd) != CERTSVC_SUCCESS) {
92 SLOGE("Failed to get sockfd from systemd.");
96 client_len = sizeof(clientaddr);
97 signal(SIGINT, (void*)CertSigHandler);
99 result = initialize_db();
100 if (result != CERTSVC_SUCCESS) {
101 SLOGE("Failed to initialize database.");
102 result = CERTSVC_IO_ERROR;
103 goto Error_close_exit;
112 FD_SET(server_sockfd, &fd);
117 memset(&recv_data, 0x00, sizeof(VcoreRequestData));
118 memset(&send_data, 0x00, sizeof(VcoreResponseData));
120 int ret = select(server_sockfd + 1, &fd, NULL, NULL, &tv);
121 if (ret == 0) { // timeout
122 SLOGD("cert-server timeout. exit.");
127 SLOGE("select() error.");
131 if ((client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len)) < 0) {
132 SLOGE("Error in function accept().[socket desc :%d, error no :%d].", client_sockfd, errno);
136 SLOGD("cert-server Accept! client sock[%d]", client_sockfd);
138 if (setsockopt(client_sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
139 SLOGE("Error in Set SO_RCVTIMEO Socket Option");
140 send_data.result = CERTSVC_FAIL;
141 goto Error_close_exit;
144 if (setsockopt(client_sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
145 SLOGE("Error in Set SO_SNDTIMEO Socket Option");
146 send_data.result = CERTSVC_FAIL;
147 goto Error_close_exit;
150 SLOGD("Connected to a client...");
152 read_len = recv(client_sockfd, (char*)&recv_data, sizeof(recv_data), 0);
154 SLOGE("Error in function recv().");
155 send_data.result = CERTSVC_FAIL;
156 goto Error_close_exit;
159 SLOGD("revc request: reqType=%d", recv_data.reqType);
161 switch (recv_data.reqType) {
162 case CERTSVC_EXTRACT_CERT:
164 send_data.result = getCertificateDetailFromStore(
168 send_data.dataBlock);
169 send_data.dataBlockLen = strlen(send_data.dataBlock);
170 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
174 case CERTSVC_EXTRACT_SYSTEM_CERT:
176 send_data.result = getCertificateDetailFromSystemStore(
178 send_data.dataBlock);
179 send_data.dataBlockLen = strlen(send_data.dataBlock);
180 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
184 case CERTSVC_DELETE_CERT:
186 send_data.result = deleteCertificateFromStore(
189 if (send_data.result == CERTSVC_SUCCESS)
190 send_data.result = update_ca_certificate_file(NULL);
191 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
195 case CERTSVC_GET_CERTIFICATE_STATUS:
197 send_data.result = getCertificateStatusFromStore(
200 &send_data.certStatus);
201 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
205 case CERTSVC_SET_CERTIFICATE_STATUS:
207 send_data.result = setCertificateStatusToStore(
209 recv_data.is_root_app,
211 recv_data.certStatus);
212 if (send_data.result == CERTSVC_SUCCESS)
213 send_data.result = update_ca_certificate_file(NULL);
214 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
218 case CERTSVC_CHECK_ALIAS_EXISTS:
220 send_data.result = checkAliasExistsInStore(
223 &send_data.isAliasUnique);
224 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
228 case CERTSVC_INSTALL_CERTIFICATE:
230 send_data.result = installCertificateToStore(
233 recv_data.common_name,
234 recv_data.private_key_gname,
235 recv_data.associated_gname,
239 if (send_data.result == CERTSVC_SUCCESS && (recv_data.certType == PEM_CRT || recv_data.certType == P12_TRUSTED))
240 send_data.result = update_ca_certificate_file(recv_data.dataBlock);
241 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
245 case CERTSVC_GET_CERTIFICATE_LIST:
246 case CERTSVC_GET_USER_CERTIFICATE_LIST:
247 case CERTSVC_GET_ROOT_CERTIFICATE_LIST:
249 send_data.result = getCertificateListFromStore(
252 recv_data.is_root_app,
255 &send_data.certCount);
256 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
258 result = send(client_sockfd, certListBuffer, bufferLen, 0);
262 case CERTSVC_GET_CERTIFICATE_ALIAS:
264 send_data.result = getCertificateAliasFromStore(
267 send_data.common_name);
268 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
272 case CERTSVC_LOAD_CERTIFICATES:
274 send_data.result = loadCertificatesFromStore(
279 &send_data.certBlockCount);
280 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
281 if (blockBufferLen > 0)
282 result = send(client_sockfd, certBlockBuffer, blockBufferLen, 0);
287 SLOGE("Input error. Please check request type");
292 SLOGE("send failed :%d, errno %d try once", result, errno);
296 close(server_sockfd);
300 free(certListBuffer);
301 free(certBlockBuffer);
303 if (client_sockfd >= 0) {
304 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
305 close(client_sockfd);
307 SLOGE("cannot connect to client socket.");
310 SLOGI("CertSvcServerComm done.");
315 SLOGI("cert-server start");
317 SLOGI("cert-server end");