Fix internal tests
[platform/core/security/cert-svc.git] / vcore / vcore / cert-svc-client.c
1 /**
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *  http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /**
17  * @file     cert-svc-client.c
18  * @author   Madhan A K (madhan.ak@samsung.com)
19  *           Kyungwook Tak (k.tak@samsung.com)
20  * @version  1.0
21  * @brief    cert-svc client interface for cert-server.
22  */
23
24 #include <sys/stat.h>
25 #include <sys/un.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 #include <cert-service-debug.h>
34
35 #include <vcore/cert-svc-client.h>
36
37 void initialize_res_data(VcoreResponseData *pData)
38 {
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;
43         pData->result = 0;
44         pData->isAliasUnique = 0;
45         pData->certList = NULL;
46         pData->certCount = 0;
47         pData->certBlockList = NULL;
48         pData->certBlockCount = 0;
49 }
50
51 void initialize_req_data(VcoreRequestData *pData)
52 {
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;
60         pData->reqType = -1;
61         pData->dataBlockLen = 0;
62         pData->is_root_app = -1;
63 }
64
65 int _recv_fixed_lenghth(int sockfd, char *buff, int length)
66 {
67         int offset = 0;
68         int remaining = length;
69         int read_len = 0;
70         while(remaining > 0) {
71                 read_len = recv(sockfd, buff + offset, remaining, 0);
72                 if(read_len <= 0)
73                         return offset;
74                 remaining -= read_len;
75                 offset += read_len;
76         }
77         return offset;
78 }
79
80 VcoreRequestData* set_request_data(
81         int reqType,
82         CertStoreType storeType,
83         int is_root_app,
84         const char *pGroupName,
85         const char *common_name,
86         const char *private_key_gname,
87         const char *associated_gname,
88         const char *pData,
89         size_t dataLen,
90         CertType certType,
91         CertStatus certStatus)
92 {
93         VcoreRequestData* pReqData = (VcoreRequestData*)malloc(sizeof(VcoreRequestData));
94         if (!pReqData) {
95                 LOGE("Failed to malloc VcoreRequestData");
96                 return NULL;
97         }
98         initialize_req_data(pReqData);
99
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;
106
107         if (pGroupName) {
108                 if (strlen(pGroupName) > VCORE_MAX_FILENAME_SIZE) {
109                         LOGE("The data name is too long");
110                         free(pReqData);
111                         return NULL;
112                 }
113                 strncpy(pReqData->gname, pGroupName, VCORE_MAX_FILENAME_SIZE);
114                 pReqData->gname[strlen(pGroupName)] = '\0';
115         }
116
117         if (common_name) {
118                 if (strlen(common_name) > VCORE_MAX_FILENAME_SIZE) {
119                         LOGE("The length of the path specified is too long");
120                         free(pReqData);
121                         return NULL;
122                 }
123                 strncpy(pReqData->common_name, common_name, VCORE_MAX_FILENAME_SIZE);
124                 pReqData->common_name[strlen(common_name)] = '\0';
125         }
126
127         if (private_key_gname) {
128                 if (strlen(private_key_gname) > VCORE_MAX_FILENAME_SIZE) {
129                         LOGE("The private key gname is too long");
130                         free(pReqData);
131                         return NULL;
132                 }
133                 strncpy(pReqData->private_key_gname, private_key_gname, VCORE_MAX_FILENAME_SIZE);
134                 pReqData->private_key_gname[strlen(private_key_gname)] = '\0';
135         }
136
137         if (associated_gname) {
138                 if (strlen(associated_gname) > VCORE_MAX_FILENAME_SIZE) {
139                         LOGE("The associated gname is too long");
140                         free(pReqData);
141                         return NULL;
142                 }
143                 strncpy(pReqData->associated_gname, associated_gname, VCORE_MAX_FILENAME_SIZE);
144                 pReqData->associated_gname[strlen(associated_gname)] = '\0';
145         }
146
147         if (dataLen != 0 && pData != NULL) {
148                 if (dataLen > VCORE_MAX_SEND_DATA_SIZE) {
149                         LOGE("The data length is too long [%d]", dataLen);
150                         free(pReqData);
151                         return NULL;
152                 }
153                 memcpy(pReqData->dataBlock, pData, dataLen);
154         }
155         return pReqData;
156 }
157
158
159 VcoreResponseData cert_svc_client_comm(VcoreRequestData* pClientData) {
160
161         int sockfd = 0;
162         int clientLen = 0;
163         int tempSockLen = 0;
164         int read_len = 0;
165         size_t i = 0;
166         struct sockaddr_un clientaddr;
167         VcoreResponseData recvData;
168         initialize_res_data(&recvData);
169
170         if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
171                 LOGE("Error in function socket()..");
172                 recvData.result = VCORE_SOCKET_ERROR;
173                 goto Error_exit;
174         }
175
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);
182
183         struct timeval timeout;
184         timeout.tv_sec = 10;
185         timeout.tv_usec = 0;
186
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;
191         }
192
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;
197         }
198
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;
203         }
204
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;
209         }
210
211         read_len = _recv_fixed_lenghth(sockfd, (char*)&recvData, sizeof(recvData));
212         if (read_len < 0) {
213                 LOGE("Error in function read()..");
214                 recvData.result = VCORE_SOCKET_ERROR;
215                 goto Error_close_exit;
216         }
217
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;
224                 }
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));
228                         if (read_len < 0) {
229                                 LOGE("Error in function read()..");
230                                 recvData.result = VCORE_SOCKET_ERROR;
231                                 goto Error_close_exit;
232                         }
233                 }
234         }
235
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;
242                 }
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));
246                         if (read_len < 0) {
247                                 LOGE("Error in function read()..");
248                                 recvData.result = VCORE_SOCKET_ERROR;
249                                 goto Error_close_exit;
250                         }
251                 }
252         }
253
254 Error_close_exit:
255         close(sockfd);
256         if (recvData.result == VCORE_SOCKET_ERROR) {
257                 free(recvData.certList);
258                 recvData.certList = NULL;
259                 recvData.certCount = 0;
260
261                 free(recvData.certBlockList);
262                 recvData.certBlockList = NULL;
263                 recvData.certBlockCount = 0;
264         }
265
266 Error_exit:
267         return recvData;
268 }
269
270 int vcore_client_install_certificate_to_store(
271         CertStoreType storeType,
272         const char *gname,
273         const char *common_name,
274         const char *private_key_gname,
275         const char *associated_gname,
276         const char *certData,
277         size_t certSize,
278         CertType certType)
279 {
280         VcoreRequestData* pSendData = NULL;
281         VcoreResponseData recvData;
282         initialize_res_data(&recvData);
283
284         if (!gname && !certData) {
285                 LOGE("Invalid input argument.");
286                 return CERTSVC_WRONG_ARGUMENT;
287         }
288
289         pSendData = set_request_data(
290                         CERTSVC_INSTALL_CERTIFICATE,
291                         storeType,
292                         DISABLED,
293                         gname,
294                         common_name,
295                         private_key_gname,
296                         associated_gname,
297                         certData,
298                         certSize,
299                         certType, 0);
300         if (pSendData == NULL) {
301                 LOGE("Failed to set request data");
302                 return CERTSVC_WRONG_ARGUMENT;
303         }
304
305         recvData = cert_svc_client_comm(pSendData);
306         free(pSendData);
307         return recvData.result;
308 }
309
310 int vcore_client_set_certificate_status_to_store(CertStoreType storeType, int is_root_app, const char* gname, CertStatus status) {
311
312         VcoreRequestData* pSendData = NULL;
313         VcoreResponseData recvData;
314         initialize_res_data(&recvData);
315
316         if (gname == NULL) {
317                 LOGE("Invalid input parameter.");
318                 return CERTSVC_WRONG_ARGUMENT;
319         }
320
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;
325         }
326
327         recvData = cert_svc_client_comm(pSendData);
328         free(pSendData);
329
330         return recvData.result;
331 }
332
333 int vcore_client_get_certificate_status_from_store(CertStoreType storeType, const char* gname, CertStatus *status) {
334
335         VcoreRequestData* pSendData = NULL;
336         VcoreResponseData recvData;
337         initialize_res_data(&recvData);
338
339         if (gname == NULL) {
340                 LOGE("Invalid input parameter.");
341                 return CERTSVC_WRONG_ARGUMENT;
342         }
343
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;
348         }
349
350         recvData = cert_svc_client_comm(pSendData);
351         free(pSendData);
352         *status = recvData.certStatus;
353         return recvData.result;
354 }
355
356 int vcore_client_check_alias_exist_in_store(CertStoreType storeType, const char* alias, int *isUnique) {
357
358         VcoreRequestData* pSendData = NULL;
359         VcoreResponseData recvData;
360         initialize_res_data(&recvData);
361
362         if (alias == NULL) {
363                 LOGE("Invalid input parameter.");
364                 return CERTSVC_WRONG_ARGUMENT;
365         }
366
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;
371         }
372
373         recvData = cert_svc_client_comm(pSendData);
374         free(pSendData);
375         *isUnique = recvData.isAliasUnique;
376         return recvData.result;
377 }
378
379 int vcore_client_get_certificate_from_store(CertStoreType storeType, const char* gname, char** certData, size_t* certSize, CertType certType) {
380
381         char* outData = NULL;
382         VcoreRequestData* pSendData = NULL;
383         VcoreResponseData recvData;
384
385         if (!gname || !certData || !certSize) {
386                 LOGE("Invalid input argument.");
387                 return CERTSVC_WRONG_ARGUMENT;
388         }
389
390         initialize_res_data(&recvData);
391
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);
396
397         if (pSendData == NULL) {
398                 LOGE("Failed to set request data.");
399                 return CERTSVC_WRONG_ARGUMENT;
400         }
401
402         recvData = cert_svc_client_comm(pSendData);
403         if (recvData.result < 0) {
404                 LOGE("An error occurred from server side err[%d]", recvData.result);
405                 free(pSendData);
406                 return recvData.result;
407         }
408         free(pSendData);
409
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);
414                 *certData = outData;
415                 *certSize = recvData.dataBlockLen;
416         }
417         else {
418                 LOGE("revcData length is wrong : %d", recvData.dataBlockLen);
419                 return CERTSVC_WRONG_ARGUMENT;
420         }
421
422         return recvData.result;
423 }
424
425 int vcore_client_delete_certificate_from_store(CertStoreType storeType, const char* gname) {
426
427         VcoreRequestData* pSendData = NULL;
428         VcoreResponseData recvData;
429         initialize_res_data(&recvData);
430
431         if (gname == NULL) {
432                 LOGE("Invalid input parameter.");
433                 return CERTSVC_WRONG_ARGUMENT;
434         }
435
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;
440         }
441
442         recvData = cert_svc_client_comm(pSendData);
443         free(pSendData);
444         return recvData.result;
445 }
446
447 int _vcore_client_get_certificate_list_from_store(int reqType, CertStoreType storeType, int is_root_app, 
448                                                                            CertSvcStoreCertList **certList, size_t *length)
449 {
450         VcoreRequestData* pSendData = NULL;
451         VcoreResponseData recvData;
452         CertSvcStoreCertList* curr = NULL;
453         CertSvcStoreCertList* prev = NULL;
454         VcoreCertResponseData* cert = NULL;
455         size_t tmplen = 0;
456         size_t i=0;
457         initialize_res_data(&recvData);
458
459
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;
464         }
465
466         recvData = cert_svc_client_comm(pSendData);
467
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));
473
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);
478
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);
483
484                    curr->status = cert->status;
485                    curr->storeType = cert->storeType;
486
487                    if(prev == NULL) {
488                            *certList = curr;
489                    }else {
490                            prev->next = curr;
491                    }
492                    prev = curr;
493                 }
494         }
495
496         *length = recvData.certCount;
497
498         LOGI("get_certificate_list_from_store: result=%d", recvData.result);
499         if(recvData.certList != NULL)
500                 free(recvData.certList);
501         free(pSendData);
502         return recvData.result;
503 }
504
505 int vcore_client_get_certificate_list_from_store(CertStoreType storeType, int is_root_app, 
506                                                                            CertSvcStoreCertList** certList, size_t *length)
507 {
508         return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_CERTIFICATE_LIST, storeType, is_root_app,
509                                                                            certList, length);
510 }
511
512 int vcore_client_get_root_certificate_list_from_store(CertStoreType storeType,  
513                                                                            CertSvcStoreCertList **certList, size_t *length)
514 {
515         return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_ROOT_CERTIFICATE_LIST, storeType, 0,
516                                                                            certList, length);
517 }
518
519 int vcore_client_get_end_user_certificate_list_from_store(CertStoreType storeType,  
520                                                                            CertSvcStoreCertList **certList, size_t *length)
521 {
522         return _vcore_client_get_certificate_list_from_store(CERTSVC_GET_USER_CERTIFICATE_LIST, storeType, 0,
523                                                                            certList, length);
524 }
525
526 int vcore_client_get_certificate_alias_from_store(CertStoreType storeType, const char *gname, char **alias)
527 {
528         VcoreRequestData* pSendData = NULL;
529         VcoreResponseData recvData;
530         initialize_res_data(&recvData);
531
532         if (gname == NULL) {
533                 LOGE("Invalid input parameter.");
534                 return CERTSVC_WRONG_ARGUMENT;
535         }
536
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;
541         }
542
543         recvData = cert_svc_client_comm(pSendData);
544
545         *alias = strndup(recvData.common_name, sizeof(recvData.common_name));
546         free(pSendData);
547         return recvData.result;
548 }
549
550 int vcore_client_load_certificates_from_store(CertStoreType storeType, const char *gname, char ***certs, size_t *ncerts)
551 {
552         VcoreRequestData* pSendData = NULL;
553         VcoreResponseData recvData;
554         ResponseCertBlock* cert = NULL;
555         size_t i = 0;
556         initialize_res_data(&recvData);
557
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;
562         }
563
564         recvData = cert_svc_client_comm(pSendData);
565
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]);
575                 }
576         }
577
578         if(recvData.certBlockList != NULL)
579                 free(recvData.certBlockList);
580         free(pSendData);
581         return recvData.result;
582
583 }