update the latest source
[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 <list>
20 #include <string>
21
22 /* SLP library header */
23 #include "dpl/wrt-dao-ro/WrtDatabase.h"
24 #include "dpl/wrt-dao-ro/widget_dao_read_only.h"
25 #include "dpl/wrt-dao-ro/wrt_db_types.h"
26 #include "dpl/db/sql_connection.h"
27 #include "aul.h"
28
29 /* local header */
30 #include "Debug.h"
31 #include "SignatureHelper.h"
32 #include "OpensslHelper.h"
33
34 #ifndef EXTERN_API
35 #define EXTERN_API __attribute__((visibility("default")))
36 #endif
37
38 using namespace WrtDB;
39 using namespace std;
40
41 namespace smartcard_service_api
42 {
43         int SignatureHelper::getProcessName(int pid, char *processName, uint32_t length)
44         {
45                 int ret = -1;
46                 FILE *file = NULL;
47                 char filename[1024] = { 0, };
48
49                 if (pid < 0 || processName == NULL || length == 0)
50                         return ret;
51
52                 snprintf(filename, sizeof(filename), "/proc/%d/cmdline", pid);
53                 SCARD_DEBUG("pid : %d, file name : %s", pid, filename);
54
55                 if ((file = fopen(filename, "r")) != NULL)
56                 {
57                         char *name = NULL;
58                         ByteArray hash, result;
59                         size_t len;
60
61                         memset(filename, 0, sizeof(filename));
62                         len = fread(filename, 1, sizeof(filename) - 1, file);
63                         fclose(file);
64
65                         name = basename(filename);
66                         SCARD_DEBUG("file name : %s", name);
67
68                         OpensslHelper::digestBuffer("sha256", (uint8_t *)name, strlen(name), hash);
69                         SCARD_DEBUG("digest [%d] : %s", hash.getLength(), hash.toString());
70
71                         OpensslHelper::encodeBase64String(hash, result, false);
72
73                         memset(processName, 0, length);
74                         memcpy(processName, result.getBuffer(), (result.getLength() < length - 1) ? result.getLength() : length - 1);
75
76                         ret = 0;
77                 }
78                 else
79                 {
80
81                 }
82
83                 return ret;
84         }
85
86         ByteArray SignatureHelper::getCertificationHash(const char *packageName)
87         {
88                 ByteArray result;
89                 list<string>::iterator item;
90                 CertificateChainList certList;
91
92                 SCARD_DEBUG("package name : %s", packageName);
93
94                 try
95                 {
96                         WrtDatabase::attachToThreadRO();
97
98                         int handle = WidgetDAOReadOnly::getHandle(DPL::FromUTF8String(packageName));
99                         WidgetDAOReadOnly widget(handle);
100                         certList = widget.getWidgetCertificate();
101
102                         SCARD_DEBUG("certList.size [%d]", certList.size());
103
104                         WrtDatabase::detachFromThread();
105                 }
106                 catch(...)
107                 {
108                         SCARD_DEBUG_ERR("exception occurs!!!");
109                         return result;
110                 }
111
112                 if (certList.size() > 0)
113                 {
114                         string certString;
115                         ByteArray certArray;
116
117 #if 0
118                         for (item = certList.begin(); item != certList.end(); item++)
119                         {
120                                 SCARD_DEBUG("certList : %s", item->data());
121                         }
122 #endif
123                         certString = certList.back();
124                         SCARD_DEBUG("certString[%d] :\n%s", certString.size(), certString.data());
125
126                         /* base64 decoding */
127                         if (OpensslHelper::decodeBase64String(certString.data(), certArray) == true)
128                         {
129                                 int count = 0, offset = 0, length;
130 //                              int i;
131                                 ByteArray cert;
132
133                                 SCARD_DEBUG("decoded[%d] : %s", certArray.getLength(), certArray.toString());
134
135                                 /* get count */
136                                 count = *(int *)certArray.getBuffer();
137                                 offset += sizeof(int);
138                                 SCARD_DEBUG("certificate count [%d]", count);
139
140 //                              for (i = 0; i < count; i++)
141                                 if (count > 0)
142                                 {
143                                         /* certificate length */
144                                         length = *(int *)certArray.getBuffer(offset);
145                                         offset += sizeof(int);
146                                         SCARD_DEBUG("certificate length [%d]", length);
147
148                                         /* certificate byte stream */
149                                         cert.setBuffer(certArray.getBuffer(offset), length);
150                                         offset += length;
151
152                                         SCARD_DEBUG("certificate buffer [%d] : %s", cert.getLength(), cert.toString());
153
154                                         /* sha1 digest */
155                                         if (OpensslHelper::digestBuffer("sha1", cert, result) == true)
156                                         {
157                                                 SCARD_DEBUG("digest[%d] : %s", result.getLength(), result.toString());
158                                         }
159                                         else
160                                         {
161                                                 SCARD_DEBUG_ERR("digestBuffer failed");
162                                         }
163                                 }
164                                 else
165                                 {
166                                         SCARD_DEBUG_ERR("invalid certificate count [%d]", count);
167                                 }
168                         }
169                         else
170                         {
171                                 SCARD_DEBUG_ERR("decodeBase64String failed");
172                         }
173                 }
174                 else
175                 {
176                         SCARD_DEBUG_ERR("certList.size is zero");
177                 }
178
179                 return result;
180         }
181
182         ByteArray SignatureHelper::getCertificationHash(int pid)
183         {
184                 ByteArray result;
185                 int error = 0;
186                 char pkgName[256] = { 0, };
187
188                 if ((error = aul_app_get_pkgname_bypid(pid, pkgName, sizeof(pkgName))) == 0)
189                 {
190                         result = getCertificationHash(pkgName);
191                 }
192                 else
193                 {
194                         SCARD_DEBUG_ERR("aul_app_get_pkgname_bypid failed [%d]", error);
195                 }
196
197                 return result;
198         }
199
200 } /* namespace smartcard_service_api */
201
202 /* export C API */
203 using namespace smartcard_service_api;
204
205 EXTERN_API int signature_helper_get_certificate_hash(const char *packageName, uint8_t *hash, uint32_t *length)
206 {
207         int ret = -1;
208         ByteArray result;
209
210         if (packageName == NULL || strlen(packageName) == 0 || hash == NULL || length == NULL || *length < 20)
211                 return ret;
212
213         result = SignatureHelper::getCertificationHash(packageName);
214
215         if (result.isEmpty() == false)
216         {
217                 memcpy(hash, result.getBuffer(), (result.getLength() < *length) ? result.getLength() : *length);
218                 *length = result.getLength();
219
220                 ret = 0;
221         }
222         else
223         {
224                 ret = -1;
225         }
226
227         return ret;
228 }
229
230 EXTERN_API int signature_helper_get_certificate_hash_by_pid(int pid, uint8_t *hash, uint32_t *length)
231 {
232         int ret = -1;
233         ByteArray result;
234
235         if (pid < 0 || hash == NULL || length == NULL || *length < 20)
236                 return ret;
237
238         result = SignatureHelper::getCertificationHash(pid);
239
240         if (result.isEmpty() == false && result.getLength() < *length)
241         {
242                 memcpy(hash, result.getBuffer(), result.getLength());
243                 *length = result.getLength();
244
245                 ret = 0;
246         }
247         else
248         {
249                 ret = -1;
250         }
251
252         return ret;
253 }
254
255 EXTERN_API int signature_helper_get_process_name(int pid, char *processName, uint32_t length)
256 {
257         int ret = -1;
258
259         if (pid < 0 || processName == NULL || length == 0)
260                 return ret;
261
262         ret = SignatureHelper::getProcessName(pid, processName, length);
263
264         return ret;
265 }
266