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