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-svc-client.c
18 * @author Madhan A K (madhan.ak@samsung.com)
19 * Kyungwook Tak (k.tak@samsung.com)
21 * @brief cert-svc client interface for cert-server.
26 #include <sys/types.h>
27 #include <sys/socket.h>
33 #include <cert-service-debug.h>
35 #include <cert-svc-client.h>
37 void initialize_res_data(VcoreResponseData *pData)
39 memset(pData->dataBlock, 0, VCORE_MAX_RECV_DATA_SIZE);
40 memset(pData->common_name, 0, VCORE_MAX_FILENAME_SIZE * 2 + 1);
41 pData->dataBlockLen = 0;
42 pData->certStatus = DISABLED;
44 pData->isAliasUnique = 0;
45 pData->certList = NULL;
47 pData->certBlockList = NULL;
48 pData->certBlockCount = 0;
51 void initialize_req_data(VcoreRequestData *pData)
53 memset(pData->gname, 0, VCORE_MAX_FILENAME_SIZE+1);
54 memset(pData->common_name, 0, VCORE_MAX_FILENAME_SIZE+1);
55 memset(pData->private_key_gname, 0, VCORE_MAX_FILENAME_SIZE+1);
56 memset(pData->associated_gname, 0, VCORE_MAX_FILENAME_SIZE+1);
57 memset(pData->dataBlock, 0, VCORE_MAX_SEND_DATA_SIZE);
58 pData->certStatus = DISABLED;
59 pData->storeType = NONE_STORE;
61 pData->dataBlockLen = 0;
62 pData->is_root_app = -1;
65 int _recv_fixed_lenghth(int sockfd, char *buff, int length)
68 int remaining = length;
70 while(remaining > 0) {
71 read_len = recv(sockfd, buff + offset, remaining, 0);
74 remaining -= read_len;
80 VcoreRequestData* set_request_data(
82 CertStoreType storeType,
84 const char *pGroupName,
85 const char *common_name,
86 const char *private_key_gname,
87 const char *associated_gname,
91 CertStatus certStatus)
93 VcoreRequestData* pReqData = (VcoreRequestData*)malloc(sizeof(VcoreRequestData));
95 LOGE("Failed to malloc VcoreRequestData");
98 initialize_req_data(pReqData);
100 pReqData->reqType = reqType;
101 pReqData->storeType = (CertStoreType) storeType;
102 pReqData->dataBlockLen = dataLen;
103 pReqData->certType = certType;
104 pReqData->certStatus = certStatus;
105 pReqData->is_root_app = is_root_app;
108 if (strlen(pGroupName) > VCORE_MAX_FILENAME_SIZE) {
109 LOGE("The data name is too long");
113 strncpy(pReqData->gname, pGroupName, VCORE_MAX_FILENAME_SIZE);
114 pReqData->gname[strlen(pGroupName)] = '\0';
118 if (strlen(common_name) > VCORE_MAX_FILENAME_SIZE) {
119 LOGE("The length of the path specified is too long");
123 strncpy(pReqData->common_name, common_name, VCORE_MAX_FILENAME_SIZE);
124 pReqData->common_name[strlen(common_name)] = '\0';
127 if (private_key_gname) {
128 if (strlen(private_key_gname) > VCORE_MAX_FILENAME_SIZE) {
129 LOGE("The private key gname is too long");
133 strncpy(pReqData->private_key_gname, private_key_gname, VCORE_MAX_FILENAME_SIZE);
134 pReqData->private_key_gname[strlen(private_key_gname)] = '\0';
137 if (associated_gname) {
138 if (strlen(associated_gname) > VCORE_MAX_FILENAME_SIZE) {
139 LOGE("The associated gname is too long");
143 strncpy(pReqData->associated_gname, associated_gname, VCORE_MAX_FILENAME_SIZE);
144 pReqData->associated_gname[strlen(associated_gname)] = '\0';
147 if (dataLen != 0 && pData != NULL) {
148 if (dataLen > VCORE_MAX_SEND_DATA_SIZE) {
149 LOGE("The data length is too long [%d]", dataLen);
153 memcpy(pReqData->dataBlock, pData, dataLen);
159 VcoreResponseData cert_svc_client_comm(VcoreRequestData* pClientData) {
166 struct sockaddr_un clientaddr;
167 VcoreResponseData recvData;
168 initialize_res_data(&recvData);
170 if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
171 LOGE("Error in function socket()..");
172 recvData.result = VCORE_SOCKET_ERROR;
176 tempSockLen = strlen(VCORE_SOCK_PATH);
177 bzero(&clientaddr, sizeof(clientaddr));
178 clientaddr.sun_family = AF_UNIX;
179 strncpy(clientaddr.sun_path, VCORE_SOCK_PATH, tempSockLen);
180 clientaddr.sun_path[tempSockLen] = '\0';
181 clientLen = sizeof(clientaddr);
183 struct timeval timeout;
187 if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
188 LOGE("Error in Set SO_RCVTIMEO Socket Option");
189 recvData.result = VCORE_SOCKET_ERROR;
190 goto Error_close_exit;
193 if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
194 LOGE("Error in Set SO_SNDTIMEO Socket Option");
195 recvData.result = VCORE_SOCKET_ERROR;
196 goto Error_close_exit;
199 if (connect(sockfd, (struct sockaddr*)&clientaddr, clientLen) < 0) {
200 LOGE("Error in function connect()..");
201 recvData.result = VCORE_SOCKET_ERROR;
202 goto Error_close_exit;
205 if (write(sockfd, (char*)pClientData, sizeof(VcoreRequestData)) < 0) {
206 LOGE("Error in function write()..");
207 recvData.result = VCORE_SOCKET_ERROR;
208 goto Error_close_exit;
211 read_len = _recv_fixed_lenghth(sockfd, (char*)&recvData, sizeof(recvData));
213 LOGE("Error in function read()..");
214 recvData.result = VCORE_SOCKET_ERROR;
215 goto Error_close_exit;
218 if(recvData.certCount > 0) {
219 recvData.certList = (VcoreCertResponseData *) malloc(recvData.certCount * sizeof(VcoreCertResponseData));
220 if (!recvData.certList) {
221 LOGE("Failed to allocate memory");
222 recvData.result = VCORE_SOCKET_ERROR;
223 goto Error_close_exit;
225 memset(recvData.certList, 0x00, recvData.certCount * sizeof(VcoreCertResponseData));
226 for(i=0; i<recvData.certCount; i++) {
227 read_len = _recv_fixed_lenghth(sockfd, (char*)(recvData.certList + i), sizeof(VcoreCertResponseData));
229 LOGE("Error in function read()..");
230 recvData.result = VCORE_SOCKET_ERROR;
231 goto Error_close_exit;
236 if(recvData.certBlockCount > 0) {
237 recvData.certBlockList = (ResponseCertBlock *) malloc(recvData.certBlockCount * sizeof(ResponseCertBlock));
238 if (!recvData.certBlockList) {
239 LOGE("Failed to allocate memory");
240 recvData.result = VCORE_SOCKET_ERROR;
241 goto Error_close_exit;
243 memset(recvData.certBlockList, 0x00, recvData.certBlockCount * sizeof(ResponseCertBlock));
244 for(i=0; i<recvData.certBlockCount; i++) {
245 read_len = _recv_fixed_lenghth(sockfd, (char*)(recvData.certBlockList + i), sizeof(ResponseCertBlock));
247 LOGE("Error in function read()..");
248 recvData.result = VCORE_SOCKET_ERROR;
249 goto Error_close_exit;
256 if (recvData.result == VCORE_SOCKET_ERROR) {
257 free(recvData.certList);
258 recvData.certList = NULL;
259 recvData.certCount = 0;
261 free(recvData.certBlockList);
262 recvData.certBlockList = NULL;
263 recvData.certBlockCount = 0;
270 int vcore_client_install_certificate_to_store(
271 CertStoreType storeType,
273 const char *common_name,
274 const char *private_key_gname,
275 const char *associated_gname,
276 const char *certData,
280 VcoreRequestData* pSendData = NULL;
281 VcoreResponseData recvData;
282 initialize_res_data(&recvData);
284 if (!gname && !certData) {
285 LOGE("Invalid input argument.");
286 return CERTSVC_WRONG_ARGUMENT;
289 pSendData = set_request_data(
290 CERTSVC_INSTALL_CERTIFICATE,
300 if (pSendData == NULL) {
301 LOGE("Failed to set request data");
302 return CERTSVC_WRONG_ARGUMENT;
305 recvData = cert_svc_client_comm(pSendData);
307 return recvData.result;
310 int vcore_client_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char* gname, CertStatus status) {
312 VcoreRequestData* pSendData = NULL;
313 VcoreResponseData recvData;
314 initialize_res_data(&recvData);
317 LOGE("Invalid input parameter.");
318 return CERTSVC_WRONG_ARGUMENT;
321 pSendData = set_request_data(CERTSVC_SET_CERTIFICATE_STATUS, storeType, is_root_app, gname, NULL, NULL, NULL, NULL, 0, 0, status);
322 if (pSendData == NULL) {
323 LOGE("Failed to set request data");
324 return CERTSVC_WRONG_ARGUMENT;
327 recvData = cert_svc_client_comm(pSendData);
330 return recvData.result;
333 int vcore_client_get_certificate_status_from_store(CertStoreType storeType, const char* gname, CertStatus *status) {
335 VcoreRequestData* pSendData = NULL;
336 VcoreResponseData recvData;
337 initialize_res_data(&recvData);
340 LOGE("Invalid input parameter.");
341 return CERTSVC_WRONG_ARGUMENT;
344 pSendData = set_request_data(CERTSVC_GET_CERTIFICATE_STATUS, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
345 if (pSendData == NULL) {
346 LOGE("Failed to set request data");
347 return CERTSVC_WRONG_ARGUMENT;
350 recvData = cert_svc_client_comm(pSendData);
352 *status = recvData.certStatus;
353 return recvData.result;
356 int vcore_client_check_alias_exist_in_store(CertStoreType storeType, const char* alias, int *isUnique) {
358 VcoreRequestData* pSendData = NULL;
359 VcoreResponseData recvData;
360 initialize_res_data(&recvData);
363 LOGE("Invalid input parameter.");
364 return CERTSVC_WRONG_ARGUMENT;
367 pSendData = set_request_data(CERTSVC_CHECK_ALIAS_EXISTS, storeType, DISABLED,alias, NULL, NULL, NULL, NULL, 0, 0, 0);
368 if (pSendData == NULL) {
369 LOGE("Failed to set request data");
370 return CERTSVC_WRONG_ARGUMENT;
373 recvData = cert_svc_client_comm(pSendData);
375 *isUnique = recvData.isAliasUnique;
376 return recvData.result;
379 int vcore_client_get_certificate_from_store(CertStoreType storeType, const char* gname, char** certData, size_t* certSize, CertType certType) {
381 char* outData = NULL;
382 VcoreRequestData* pSendData = NULL;
383 VcoreResponseData recvData;
385 if (!gname || !certData || !certSize) {
386 LOGE("Invalid input argument.");
387 return CERTSVC_WRONG_ARGUMENT;
390 initialize_res_data(&recvData);
392 if (storeType == SYSTEM_STORE) /* for extracting certificate from system store */
393 pSendData = set_request_data(CERTSVC_EXTRACT_SYSTEM_CERT, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, certType, 0);
394 else /* for extracting certificate from other stores */
395 pSendData = set_request_data(CERTSVC_EXTRACT_CERT, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, certType, 0);
397 if (pSendData == NULL) {
398 LOGE("Failed to set request data.");
399 return CERTSVC_WRONG_ARGUMENT;
402 recvData = cert_svc_client_comm(pSendData);
403 if (recvData.result < 0) {
404 LOGE("An error occurred from server side err[%d]", recvData.result);
406 return recvData.result;
410 if (recvData.dataBlockLen > 0 && recvData.dataBlockLen <= VCORE_MAX_RECV_DATA_SIZE) {
411 outData = (char*)malloc(recvData.dataBlockLen + 1);
412 memset(outData, 0x00, recvData.dataBlockLen +1);
413 memcpy(outData, recvData.dataBlock, recvData.dataBlockLen);
415 *certSize = recvData.dataBlockLen;
418 LOGE("revcData length is wrong : %d", recvData.dataBlockLen);
419 return CERTSVC_WRONG_ARGUMENT;
422 return recvData.result;
425 int vcore_client_delete_certificate_from_store(CertStoreType storeType, const char* gname) {
427 VcoreRequestData* pSendData = NULL;
428 VcoreResponseData recvData;
429 initialize_res_data(&recvData);
432 LOGE("Invalid input parameter.");
433 return CERTSVC_WRONG_ARGUMENT;
436 pSendData = set_request_data(CERTSVC_DELETE_CERT, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
437 if (pSendData == NULL) {
438 LOGE("Failed to set request data");
439 return CERTSVC_WRONG_ARGUMENT;
442 recvData = cert_svc_client_comm(pSendData);
444 return recvData.result;
447 int _vcore_client_get_certificate_list_from_store(int reqType, CertStoreType storeType, int is_root_app,
448 CertSvcStoreCertList **certList, size_t *length)
450 VcoreRequestData* pSendData = NULL;
451 VcoreResponseData recvData;
452 CertSvcStoreCertList* curr = NULL;
453 CertSvcStoreCertList* prev = NULL;
454 VcoreCertResponseData* cert = NULL;
457 initialize_res_data(&recvData);
460 pSendData = set_request_data(reqType, storeType, is_root_app, NULL, NULL, NULL, NULL, NULL, 0, 0, 0);
461 if (pSendData == NULL) {
462 LOGE("Failed to set request data");
463 return CERTSVC_WRONG_ARGUMENT;
466 recvData = cert_svc_client_comm(pSendData);
468 if(recvData.certCount > 0) {
469 for(i=0; i<recvData.certCount; i++) {
470 cert = recvData.certList + i ;
471 curr = (CertSvcStoreCertList*) malloc(sizeof(CertSvcStoreCertList));
472 memset(curr, 0x00, sizeof(CertSvcStoreCertList));
474 tmplen = strlen(cert->gname);
475 curr->gname = (char*) malloc (sizeof(char) * (tmplen+ 1));
476 memset(curr->gname, 0x00, tmplen + 1);
477 memcpy(curr->gname, cert->gname, tmplen);
479 tmplen = strlen(cert->title);
480 curr->title = (char*) malloc (sizeof(char) * (tmplen+ 1));
481 memset(curr->title, 0x00, tmplen + 1);
482 memcpy(curr->title, cert->title, tmplen);
484 curr->status = cert->status;
485 curr->storeType = cert->storeType;
496 *length = recvData.certCount;
498 LOGI("get_certificate_list_from_store: result=%d", recvData.result);
499 if(recvData.certList != NULL)
500 free(recvData.certList);
502 return recvData.result;
505 int vcore_client_get_certificate_list_from_store(CertStoreType storeType, int is_root_app,
506 CertSvcStoreCertList** certList, size_t *length)
508 return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_CERTIFICATE_LIST, storeType, is_root_app,
512 int vcore_client_get_root_certificate_list_from_store(CertStoreType storeType,
513 CertSvcStoreCertList **certList, size_t *length)
515 return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_ROOT_CERTIFICATE_LIST, storeType, 0,
519 int vcore_client_get_end_user_certificate_list_from_store(CertStoreType storeType,
520 CertSvcStoreCertList **certList, size_t *length)
522 return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_USER_CERTIFICATE_LIST, storeType, 0,
526 int vcore_client_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias)
528 VcoreRequestData* pSendData = NULL;
529 VcoreResponseData recvData;
530 initialize_res_data(&recvData);
533 LOGE("Invalid input parameter.");
534 return CERTSVC_WRONG_ARGUMENT;
537 pSendData = set_request_data(CERTSVC_GET_CERTIFICATE_ALIAS, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
538 if (pSendData == NULL) {
539 LOGE("Failed to set request data");
540 return CERTSVC_WRONG_ARGUMENT;
543 recvData = cert_svc_client_comm(pSendData);
545 *alias = strndup(recvData.common_name, sizeof(recvData.common_name));
547 return recvData.result;
550 int vcore_client_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, size_t *ncerts)
552 VcoreRequestData* pSendData = NULL;
553 VcoreResponseData recvData;
554 ResponseCertBlock* cert = NULL;
556 initialize_res_data(&recvData);
558 pSendData = set_request_data(CERTSVC_LOAD_CERTIFICATES, storeType, DISABLED, gname, NULL, NULL, NULL, NULL, 0, 0, 0);
559 if (pSendData == NULL) {
560 LOGE("Failed to set request data");
561 return CERTSVC_WRONG_ARGUMENT;
564 recvData = cert_svc_client_comm(pSendData);
566 *ncerts = recvData.certBlockCount;
567 *certs = (char**)malloc((recvData.certBlockCount+1) * sizeof(char *));
568 (*certs)[recvData.certBlockCount] = NULL;
569 LOGD("vcore_client_load_certificates_from_store. result=%d, ncerts=%d", recvData.result, *ncerts);
570 if(recvData.certBlockCount > 0) {
571 for(i=0; i<recvData.certBlockCount; i++) {
572 cert = recvData.certBlockList + i ;
573 (*certs)[i] = strndup(cert->dataBlock, cert->dataBlockLen);
574 LOGD("vcore_client_load_certificates_from_store. cert=%s", (*certs)[i]);
578 if(recvData.certBlockList != NULL)
579 free(recvData.certBlockList);
581 return recvData.result;