Initialize Tizen 2.3
[framework/osp/security-service.git] / src / DrmService.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied..
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                DrmService.cpp
20  * @brief               This is the implementation file for DrmService class.
21  */
22
23 #include "DrmService.h"
24 #include "DrmServiceDl.h"
25
26 #include <dlfcn.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <vconf.h>
32
33 #include <FApp.h>
34 #include <FBase.h>
35 #include <FIo.h>
36
37 using namespace Tizen::App;
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Io;
41
42 DrmService* DrmService::m_pInstance = null;
43
44 const char *DRM_SAPPS_API[] = {
45         "drm_oem_sapps_generate_license_request",
46         "drm_oem_sapps_register_license",
47         "drm_oem_sapps_is_drm_file",
48         "drm_oem_sapps_decrypt_package",
49         "drm_oem_sapps_generate_purchase_request",
50         "\0"
51 };
52
53 DrmService::DrmService(void)
54         : m_sapps_handle(null)
55         , m_isdlopened(false)
56         , __pLocalMessagePort(null)
57 {
58 }
59
60 DrmService::~DrmService(void)
61 {
62 }
63
64 DrmService*
65 DrmService::GetInstance(void)
66 {
67         if (m_pInstance == null)
68         {
69                 m_pInstance = new (std::nothrow) DrmService();
70
71                 if (m_pInstance == null)
72                 {
73                         AppLogException("DrmService : Creating DrmService m_pInstance failed.");
74
75                         return m_pInstance;
76                 }
77
78                 m_pInstance->Construct();
79                 AppLog("DrmService : m_pInstance is created.");
80         }
81
82         return m_pInstance;
83 }
84
85 void
86 DrmService::FreeInstance(void)
87 {
88         if (m_pInstance != null)
89         {
90                 delete m_pInstance;
91                 m_pInstance = null;
92         }
93 }
94
95 result
96 DrmService::Construct(void)
97 {
98         static const wchar_t* LOCAL_MESSAGE_PORT_NAME = L"SAPPS_DRM_SERVER_PORT";
99
100         result r = E_SUCCESS;
101
102         AppLog("DrmService::Construct is called.");
103
104         __pLocalMessagePort = MessagePortManager::RequestLocalMessagePort(LOCAL_MESSAGE_PORT_NAME);
105         r = GetLastResult();
106         TryCatchTag(DRM_SERVICE, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] DrmService failed to get LocalMessagePort instance, %s", GetErrorMessage(r));
107         AppLog("DrmService::RequestLocalMessagePort successfully called.");
108
109         __pLocalMessagePort->AddMessagePortListener(*this);
110         r = GetLastResult();
111         TryCatchTag(DRM_SERVICE, r == E_SUCCESS, r = E_SYSTEM, "[E_SYSTEM] DrmService failed to run AddMessagePortListner, %s", GetErrorMessage(r));
112         AppLog("DrmService : LocalMessagePort is ready.");
113
114 CATCH:
115         if (__pLocalMessagePort == null)
116         {
117                 AppLogException("DrmService : RequestLocalMessagePort failed.");
118                 FreeInstance();
119         }
120
121         return r;
122 }
123
124 void
125 DrmService::OnMessageReceivedN(RemoteMessagePort* pRemoteMessagePort, IMap* pMessage)
126 {
127         result r = E_SUCCESS;
128         String *pData = NULL;
129
130         HashMap *pMap = new HashMap(SingleObjectDeleter);
131
132         TryCatchTag(DRM_SERVICE, pMessage != NULL, r = E_INVALID_ARG, "DrmService : OnMessageReceivedN() failed. pMessage is invalid.");
133         TryCatchTag(DRM_SERVICE, pMap != NULL, r = E_OUT_OF_MEMORY, "DrmService : OnMessageReceivedN() failed. pMap is NULL.");
134
135         pMap->Construct();
136
137         pData = static_cast<String *>(pMessage->GetValue(String(L"CLIENT_NAME")));
138         r = GetLastResult();
139
140         if (r == E_OBJ_NOT_FOUND)
141         {
142                 AppLogException("Osp-Security-Service : [E_OBJ_NOT_FOUND] Failed to get CLIENT_NAME value.");
143                 pMap->Add(new String(L"RESULT"), new String(L"CLIENT_NAME_NULL"));
144                 goto CATCH;
145         }
146
147         if (m_isdlopened != true)
148         {
149                 int retDrmDlCall = 0;
150
151                 retDrmDlCall = DrmDlCall();
152
153                 if (retDrmDlCall == DLOPEN_FAILED)
154                 {
155                         AppLogException("Osp-Security-Service : [DLOPEN_FAILED] Failed to load DRM-ENGINE");
156                         pMap->Add(new String(L"RESULT"), new String(L"DLOPEN_FAILED"));
157                         goto CATCH;
158                 }
159
160                 if (retDrmDlCall == DLSYM_FAILED)
161                 {
162                         AppLogException("Osp-Security-Service : [DLSYM_FAILED] Failed to load DRM-ENGINE.");
163                         pMap->Add(new String(L"RESULT"), new String(L"DLSYM_FAILED"));
164                         goto CATCH;
165                 }
166         }
167
168         AppLog("Osp-Security-Service : Received length=%d, data=%ls", pData->GetLength(), pData->GetPointer());
169
170         if (pData->CompareTo(L"STORE_CLIENT") == 0)
171         {
172                 int result = 0;
173                 char respBuf[1024*8] = {0,};
174                 unsigned int respBufLen = sizeof(respBuf);
175                 char reqBuf[1024] = {0,};
176                 unsigned int reqBufLen = sizeof(reqBuf);
177                 char licenseUrl[1024] = {0,};
178                 unsigned int licenseUrlLen = sizeof(licenseUrl);
179                 int count = 0;
180
181                 String *pDataAPI = static_cast<String *>(pMessage->GetValue(String(L"REQUEST_API")));
182                 r = GetLastResult();
183
184                 if (r == E_OBJ_NOT_FOUND)
185                 {
186                         AppLogException("DrmService : Failed to get REQUEST_API field.");
187                         pMap->Add(new String(L"RESULT"), new String(L"LICENSE_REQUEST_PROTOCOL_INVALID"));
188                         goto CATCH;
189                 }
190
191                 if (pDataAPI->CompareTo(L"GENERATE_DRM_LICENSE_REQUEST") == 0)
192                 {
193                         String *pInputParam = static_cast<String *>(pMessage->GetValue(String(L"INPUT_PARAM")));
194                         r = GetLastResult();
195                         if (r == E_OBJ_NOT_FOUND)
196                         {
197                                 AppLogException("DrmService : [GENERATE_DRM_LICENSE_REQUEST] Failed to get INPUT_PARAM.");
198                                 pMap->Add(new String(L"RESULT"), new String(L"LICENSE_REQUEST_INPUT_PARAM_NULL"));
199                                 goto CATCH;
200                         }
201
202                         AppLog("API : %ls, INPUT_PARAM : %ls", pDataAPI->GetPointer(), pInputParam->GetPointer());
203                         count = wcstombs(respBuf, pInputParam->GetPointer(), pInputParam->GetLength());
204
205                         if (count != pInputParam->GetLength() || (int)strlen(respBuf) != count)
206                         {
207                                 AppLogException("DrmService : [GENERATE_DRM_LICENSE_REQUEST] Failed to get the argument.");
208                                 pMap->Add(new String(L"RESULT"), new String(L"LICENSE_REQUEST_INPUT_PARAM_INVALID"));
209                                 goto CATCH;
210                         }
211
212                         respBufLen = count;
213                         result = m_sapps_symbol.drm_oem_sapps_generate_license_request(respBuf, respBufLen, reqBuf, &reqBufLen, licenseUrl, &licenseUrlLen);
214
215                         if (result != SADC_SUCCESS)
216                         {
217                                 AppLogException("DrmService : [GENERATE_DRM_LICENSE_REQUEST] drm_oem_sapps_generate_license_request() failed. ret=%x", result);
218                                 pMap->Add(new String(L"RESULT"), new String(L"LICENSE_REQUEST_INTERNAL_ERROR"));
219                                 goto CATCH;
220                         }
221
222                         pMap->Add(new String(L"RESULT"), new String(L"LICENSE_REQUEST_SUCCESS"));
223                         pMap->Add(new String(L"LICENSE_MSG"), new String(reqBuf));
224                         pMap->Add(new String(L"LICENSE_URL"), new String(licenseUrl));
225                 }
226                 else if (pDataAPI->CompareTo(L"WRITE_DRM_LICESE") == 0)
227                 {
228                         String *pInputParam = static_cast<String *>(pMessage->GetValue(String(L"INPUT_PARAM")));
229                         r = GetLastResult();
230                         if (r == E_OBJ_NOT_FOUND)
231                         {
232                                 AppLogException("DrmService : [WRITE_DRM_LICESE] Failed to get INPUT_PARAM.");
233                                 pMap->Add(new String(L"RESULT"), new String(L"LICENSE_WRITE_INPUT_PARAM_NULL"));
234                                 goto CATCH;
235                         }
236
237                         AppLog("DrmService : API=%ls, INPUT_PARAM_Length=%d, INPUT_PARAM=%ls", pDataAPI->GetPointer(), pInputParam->GetLength() , pInputParam->GetPointer());
238                         count = wcstombs(respBuf, pInputParam->GetPointer(), pInputParam->GetLength());
239
240                         if (count != pInputParam->GetLength())
241                         {
242                                 AppLogException("DrmService : [WRITE_DRM_LICESE] Failed to get the argument.");
243                                 pMap->Add(new String(L"RESULT"), new String(L"LICENSE_WRITE_INPUT_PARAM_INVALID"));
244                                 goto CATCH;
245                         }
246
247                         respBufLen = count;
248                         result = m_sapps_symbol.drm_oem_sapps_register_license(respBuf, respBufLen);
249
250                         if (result != SADC_SUCCESS)
251                         {
252                                 AppLogException("DrmService : [WRITE_DRM_LICESE] drm_oem_sapps_register_license() failed. ret=%x", result);
253                                 pMap->Add(new String(L"RESULT"), new String(L"LICENSE_WRITE_INTERNAL_ERROR"));
254                                 goto CATCH;
255                         }
256
257                         pMap->Add(new String(L"RESULT"), new String(L"LICENSE_WRITE_SUCCESS"));
258                 }
259                 else
260                 {
261                         AppLogException("DrmService : UNSURPPORTED_API requested.");
262                         pMap->Add(new String(L"RESULT"), new String(L"UNSURPPORTED_API"));
263                         goto CATCH;
264                 }
265         }
266         else
267         {
268                 AppLogException("DrmService : Unauthorized client called.");
269                 pMap->Add(new String(L"RESULT"), new String(L"UNAUTHORIZED_CLIENT"));
270                 goto CATCH;
271         }
272
273 CATCH:
274         pRemoteMessagePort->SendMessage(__pLocalMessagePort, pMap);
275         r = GetLastResult();
276         AppLogExceptionIf(r != E_SUCCESS, "DrmService : [E_SYSTEM] DrmService failed to SendMessage(), %s", GetErrorMessage(r));
277
278         if (pMap != NULL)
279         {
280                 delete pMap;
281         }
282         if (pMessage != NULL)
283         {
284                 delete pMessage;
285         }
286 }
287
288 int
289 DrmService::DrmDlCall(void)
290 {
291         void *handle = NULL;
292         int     ret = SADC_SUCCESS;
293         char *error = NULL;
294         void *sappshandle[FUNC_DRM_SAPPS_MAX] = {0,};
295
296         AppLog("DrmService : DrmDlCall is called.");
297
298         m_sapps_handle = dlopen(DRM_SAPPS_SO_PATH, RTLD_LAZY);
299         error = dlerror();
300         TryCatchTag(DRM_SERVICE, error == NULL, ret = DLOPEN_FAILED, "DrmService : dlopen() failed. err=%s", error);
301         AppLog("Osp-Security-Service : dlopen success.");
302
303         for (int i = 0; i < FUNC_DRM_SAPPS_MAX ; i++)
304         {
305                 handle = dlsym(m_sapps_handle, DRM_SAPPS_API[i]);
306                 error = dlerror();
307
308                 TryCatchTag(DRM_SERVICE, error == NULL, ret = DLSYM_FAILED, "DrmService : dlsym() failed. err=%s", error);
309                 AppLog("DrmService : drm_sapps_api is loaded : dlsym(%d)\n", i);
310
311                 sappshandle[i] = handle;
312         }
313
314         memcpy(&m_sapps_symbol, sappshandle, sizeof(sappshandle));
315         m_isdlopened = true;
316
317         AppLog("DrmService : DrmDlCall is totally success.");
318
319 CATCH:
320         return ret;
321 }