Implement raising exceptions
[platform/core/connectivity/smartcard-service.git] / common / SignatureHelper.cpp
1 /*
2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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
18 /* standard library header */
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <list>
24 #include <string>
25 #include <vector>
26
27 /* SLP library header */
28 #include "package-manager.h"
29 #include "pkgmgr-info.h"
30 #include "aul.h"
31
32 /* local header */
33 #include "Debug.h"
34 #include "SignatureHelper.h"
35 #include "OpensslHelper.h"
36
37 #ifndef EXTERN_API
38 #define EXTERN_API __attribute__((visibility("default")))
39 #endif
40
41 namespace smartcard_service_api
42 {
43         int SignatureHelper::getProcessName(int pid, char *processName, uint32_t length)
44         {
45                 int ret = -1;
46                 char buffer[1024] = { 0, };
47                 char filename[2048] = { 0, };
48                 int len = 0;
49
50                 if (pid < 0 || processName == NULL || length == 0)
51                         return ret;
52
53                 snprintf(buffer, sizeof(buffer), "/proc/%d/exe", pid);
54                 SCARD_DEBUG("pid : %d, exe : %s", pid, buffer);
55
56                 if ((len = readlink(buffer, filename, sizeof(filename) - 1)) < sizeof(filename) - 1)
57                 {
58                         char *name = NULL;
59                         ByteArray hash, result;
60
61                         name = basename(filename);
62                         SCARD_DEBUG("file name : %s", name);
63
64                         OpensslHelper::digestBuffer("sha256", (uint8_t *)name, strlen(name), hash);
65                         SCARD_DEBUG("digest [%d] : %s", hash.getLength(), hash.toString());
66
67                         OpensslHelper::encodeBase64String(hash, result, false);
68
69                         memset(processName, 0, length);
70                         memcpy(processName, result.getBuffer(), (result.getLength() < length - 1) ? result.getLength() : length - 1);
71
72                         ret = 0;
73                 }
74                 else
75                 {
76                         SCARD_DEBUG_ERR("readlink failed");
77                 }
78
79                 return ret;
80         }
81
82         ByteArray SignatureHelper::getCertificationHash(const char *packageName)
83         {
84                 ByteArray result;
85                 int ret = 0;
86                 pkgmgr_certinfo_h handle = NULL;
87                 pkgmgrinfo_appinfo_h handle_appinfo;
88                 char *pkgid = NULL;
89
90                 if(pkgmgrinfo_appinfo_get_appinfo(packageName, &handle_appinfo) != PMINFO_R_OK)
91                 {
92                         SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_appinfo fail");
93                         return result;
94                 }
95
96                 if(pkgmgrinfo_appinfo_get_pkgid(handle_appinfo, &pkgid) != PMINFO_R_OK)
97                 {
98                         pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
99                         SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_pkgid fail");
100                         return result;
101                 }
102                 pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
103
104                 SCARD_DEBUG("package name : %s", pkgid);
105
106                 if ((ret = pkgmgr_pkginfo_create_certinfo(&handle)) == 0)
107                 {
108                         if ((ret = pkgmgr_pkginfo_load_certinfo(pkgid, handle)) == 0)
109                         {
110                                 int type;
111
112                                 for (type = (int)PM_AUTHOR_ROOT_CERT; type <= (int)PM_DISTRIBUTOR2_SIGNER_CERT; type++)
113                                 {
114                                         const char *value = NULL;
115
116                                         if ((ret = pkgmgr_pkginfo_get_cert_value(handle, (pkgmgr_cert_type)type, &value)) == 0)
117                                         {
118                                                 if (value != NULL && strlen(value) > 0)
119                                                 {
120                                                         OpensslHelper::decodeBase64String(value, result, false);
121                                                         if (result.getLength() > 0)
122                                                         {
123                                                                 SCARD_DEBUG("type [%d] hash [%d] : %s", type, result.getLength(), result.toString());
124                                                                 break;
125                                                         }
126                                                 }
127                                         }
128                                 }
129                         }
130                         else
131                         {
132                                 SCARD_DEBUG_ERR("pkgmgr_pkginfo_load_certinfo failed [%d]", ret);
133                         }
134
135                         pkgmgr_pkginfo_destroy_certinfo(handle);
136                 }
137                 else
138                 {
139                         SCARD_DEBUG_ERR("pkgmgr_pkginfo_create_certinfo failed [%d]", ret);
140                 }
141
142                 return result;
143         }
144
145         ByteArray SignatureHelper::getCertificationHash(int pid)
146         {
147                 ByteArray result;
148                 int error = 0;
149                 char pkgName[256] = { 0, };
150
151                 if ((error = aul_app_get_pkgname_bypid(pid, pkgName, sizeof(pkgName))) == 0)
152                 {
153                         result = getCertificationHash(pkgName);
154                 }
155                 else
156                 {
157                         SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
158                 }
159
160                 return result;
161         }
162
163         bool SignatureHelper::getCertificationHashes(int pid, vector<ByteArray> &certHashes)
164         {
165                 bool result = false;
166                 int error = 0;
167                 char pkgName[256] = { 0, };
168
169                 if ((error = aul_app_get_pkgname_bypid(pid, pkgName, sizeof(pkgName))) == 0)
170                 {
171                         result = getCertificationHashes(pkgName, certHashes);
172                 }
173                 else
174                 {
175                         SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
176                 }
177
178                 return result;
179         }
180
181         bool SignatureHelper::getCertificationHashes(const char *packageName, vector<ByteArray> &certHashes)
182         {
183                 bool result = false;
184                 int ret = 0;
185                 pkgmgr_certinfo_h handle = NULL;
186                 pkgmgrinfo_appinfo_h handle_appinfo;
187                 char *pkgid = NULL;
188
189                 if(pkgmgrinfo_appinfo_get_appinfo(packageName, &handle_appinfo) != PMINFO_R_OK)
190                 {
191                         SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_appinfo fail");
192                         return result;
193                 }
194
195                 if(pkgmgrinfo_appinfo_get_pkgid(handle_appinfo, &pkgid) != PMINFO_R_OK)
196                 {
197                         pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
198                         SCARD_DEBUG_ERR("pkgmgrinfo_appinfo_get_pkgid fail");
199                         return result;
200                 }
201                 pkgmgrinfo_appinfo_destroy_appinfo(handle_appinfo);
202
203                 SCARD_DEBUG("package name : %s", pkgid);
204
205                 if ((ret = pkgmgr_pkginfo_create_certinfo(&handle)) == 0)
206                 {
207                         if ((ret = pkgmgr_pkginfo_load_certinfo(pkgid, handle)) == 0)
208                         {
209                                 int type;
210
211                                 for (type = (int)PM_AUTHOR_ROOT_CERT; type <= (int)PM_DISTRIBUTOR2_SIGNER_CERT; type++)
212                                 {
213                                         const char *value = NULL;
214
215                                         if ((ret = pkgmgr_pkginfo_get_cert_value(handle, (pkgmgr_cert_type)type, &value)) == 0)
216                                         {
217                                                 if (value != NULL && strlen(value) > 0)
218                                                 {
219                                                         ByteArray decodeValue, hash;
220
221                                                         OpensslHelper::decodeBase64String(value, decodeValue, false);
222                                                         if (decodeValue.getLength() > 0)
223                                                         {
224                                                                 OpensslHelper::digestBuffer("sha1", decodeValue.getBuffer(), decodeValue.getLength(), hash);
225                                                                 if(hash.getLength() > 0)
226                                                                 {
227                                                                         SCARD_DEBUG("type [%d] hash [%d] : %s", type, hash.getLength(), hash.toString());
228                                                                         certHashes.push_back(hash);
229                                                                 }
230                                                         }
231                                                 }
232                                         }
233                                 }
234
235                                 result = true;
236                         }
237                         else
238                         {
239                                 SCARD_DEBUG_ERR("pkgmgr_pkginfo_load_certinfo failed [%d]", ret);
240                         }
241
242                         pkgmgr_pkginfo_destroy_certinfo(handle);
243                 }
244                 else
245                 {
246                         SCARD_DEBUG_ERR("pkgmgr_pkginfo_create_certinfo failed [%d]", ret);
247                 }
248
249                 return result;
250         }
251 } /* namespace smartcard_service_api */
252
253 /* export C API */
254 using namespace smartcard_service_api;
255
256 certiHash *__signature_helper_vector_to_linked_list(vector<ByteArray> &certHashes)
257 {
258         vector<ByteArray>::iterator item;
259         certiHash *head, *tail, *tmp;
260
261         head = tail = NULL;
262
263         for (item = certHashes.begin(); item != certHashes.end(); item++)
264         {
265                 if ((tmp = (certiHash *)calloc(1, sizeof(certiHash))) == NULL)
266                         goto ERROR;
267
268                 tmp->length = (*item).getLength();
269
270                 if ((tmp->value = (uint8_t *)calloc(tmp->length, sizeof(uint8_t))) == NULL)
271                 {
272                         free(tmp);
273                         goto ERROR;
274                 }
275
276                 memcpy(tmp->value, (*item).getBuffer(), tmp->length);
277                 tmp->next = NULL;
278
279                 if (head == NULL)
280                 {
281                         head = tail = tmp;
282                 }
283                 else
284                 {
285                         tail->next = tmp;
286                         tail = tmp;
287                 }
288         }
289         return head;
290
291 ERROR :
292         SCARD_DEBUG_ERR("mem alloc fail");
293
294         while (head)
295         {
296                 tmp = head;
297                 head = head->next;
298                 if (tmp->value != NULL)
299                         free(tmp->value);
300                 free(tmp);
301         }
302
303         return NULL;
304 }
305
306 EXTERN_API int signature_helper_get_process_name(int pid, char *processName, uint32_t length)
307 {
308         int ret = -1;
309
310         if (pid < 0 || processName == NULL || length == 0)
311                 return ret;
312
313         ret = SignatureHelper::getProcessName(pid, processName, length);
314
315         return ret;
316 }
317
318 EXTERN_API int signature_helper_get_certificate_hashes(const char *packageName, certiHash **hash)
319 {
320         int ret = -1;
321         vector<ByteArray> hashes;
322
323         if (packageName == NULL)
324                 return ret;
325
326         if (SignatureHelper::getCertificationHashes(packageName, hashes) == true)
327         {
328                 *hash = __signature_helper_vector_to_linked_list(hashes);
329                 ret = 0;
330         }
331
332         return ret;
333 }
334
335 EXTERN_API int signature_helper_get_certificate_hashes_by_pid(int pid, certiHash **hash)
336 {
337         int ret = -1;
338         vector<ByteArray> hashes;
339
340         if (pid <= 0)
341                 return ret;
342
343         if (SignatureHelper::getCertificationHashes(pid, hashes) == true)
344         {
345                 *hash = __signature_helper_vector_to_linked_list(hashes);
346                 ret = 0;
347         }
348
349         return ret;
350 }
351