fix certificate popup crash issue
[framework/osp/web.git] / src / controls / FWebCtrl_CertificateConfirmPopup.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 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                FWebCtrl_CertificateConfirmPopup.cpp
20  * @brief               The file contains the definition of _CertificateConfirmPopup class.
21  */
22 #include <FAppApp.h>
23 #include <FBaseColArrayList.h>
24 #include <FBaseSysLog.h>
25 #include <FBaseUtilUri.h>
26 #include <FGrpDimension.h>
27 #include <FGrpRectangle.h>
28 #include <FIoDbEnumerator.h>
29 #include <FIoDbStatement.h>
30 #include <FSecCertX509Certificate.h>
31 #include <FUiCtrlButton.h>
32 #include <FUiCtrlLabel.h>
33 #include <FUiCtrlPanel.h>
34 #include <FUiKeyEventInfo.h>
35 #include <FUiLayout.h>
36 #include <FUiVerticalBoxLayout.h>
37 #include <FIo_DatabaseImpl.h>
38 #include <FSys_SystemResource.h>
39 #include <FUi_ControlManager.h>
40 #include <FUi_ResourceManager.h>
41 #include "FWebCtrl_CertificateConfirmPopup.h"
42 #include "FWebCtrl_EflWebkit.h"
43 #include "FWebCtrl_Utility.h"
44 #include "FWebCtrl_WebImpl.h"
45
46
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Collection;
49 using namespace Tizen::Base::Utility;
50 using namespace Tizen::Graphics;
51 using namespace Tizen::Io;
52 using namespace Tizen::Security::Cert;
53 using namespace Tizen::System;
54 using namespace Tizen::Ui;
55 using namespace Tizen::Ui::Controls;
56
57
58 namespace Tizen { namespace Web { namespace Controls
59 {
60
61
62 static const int EDIT_TEXT_SIZE = 30;
63
64
65 _CertificateConfirmPopup::_CertificateConfirmPopup(void)
66                                                 : __certPopupMode(CERTIFICATE_POPUP_MODE_USER_CONFIRM)
67                                                 , __confirm(false)
68                                                 , __pCertificatePolicyData(null)
69                                                 , __pImpl(null)
70 {
71 }
72
73
74 _CertificateConfirmPopup::~_CertificateConfirmPopup(void)
75 {
76         if (IsModalPopup() == true)
77         {
78                 HandleUserAction(false);
79         }
80 }
81
82
83 result
84 _CertificateConfirmPopup::Construct(_CertificatePopupMode certPopupMode, Ewk_Certificate_Policy_Decision* pPolicy, Tizen::Web::Controls::_WebImpl* pImpl)
85 {
86         SysTryReturnResult(NID_WEB_CTRL, pPolicy, E_INVALID_ARG, "Certificate Policy pointer is null.");
87         result r = E_SUCCESS;
88
89         _SystemResource* pSysResource = _SystemResource::GetInstance();
90         SysAssertf(pSysResource != null, "Failed to get _SystemResource instance");
91
92         _WebPopupData* pPopupData = _WebPopup::GetPopupData();
93         SysTryReturn(NID_WEB_CTRL, pPopupData, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
94
95         __pCertificatePolicyData = pPolicy;
96         __certPopupMode = certPopupMode;
97         String titleText = L"";
98         int popupMaxHeight = 0;
99         Rectangle rect(0, 0, 0, 0);
100
101         if (pImpl == null)
102         {
103                 __pImpl = pImpl;
104         }
105
106         ArrayList idList;
107         r = idList.Construct();
108         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
109
110         ArrayList titleList;
111         r = titleList.Construct();
112         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
113
114         if( __certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
115         {
116                 titleText = pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_CERTIFICATES");
117                 popupMaxHeight = 4*pPopupData->labelDim.height + pPopupData->btnDim.height + 2*pPopupData->sideMargin;
118
119                 rect.height = 4*pPopupData->labelDim.height;
120                 rect.width = pPopupData->labelDim.width;
121
122                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_CLOSE)));
123                 titleList.Add(*(new String(pSysResource->GetString("sys_string", "IDS_COM_BODY_DONE"))));
124         }
125         else    // CERTIFICATE_POPUP_MODE_CONFIRM
126         {
127                 titleText = pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_SECURITY_WARNING");
128                 popupMaxHeight = 2*pPopupData->labelDim.height + pPopupData->btnDim.height + 2*pPopupData->sideMargin;
129
130                 rect.height = 2*pPopupData->labelDim.height;
131                 rect.width = pPopupData->labelDim.width;
132
133                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_CANCEL)));
134                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_VIEW)));
135                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_ALLOW)));
136
137                 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_OPT_CANCEL"))));
138                 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_OPT_VIEW"))));
139                 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_OPT_ALLOW"))));
140         }
141
142         r = _WebPopup::Construct(true, Dimension(pPopupData->popupDim.width, popupMaxHeight));
143         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
144
145         SetTitleText(titleText);
146
147         std::unique_ptr<VerticalBoxLayout> pLayout(dynamic_cast< VerticalBoxLayout* >(GetLayoutN()));
148         SysTryReturn(NID_WEB_CTRL, pLayout.get(), r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
149
150         if( certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
151         {
152                 String certString;
153                 result r = GenerateCertifiate(certString);
154                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
155
156                 std::unique_ptr<TextBox> pTextBox(new (std::nothrow) TextBox());
157                 SysTryReturnResult(NID_WEB_CTRL, pTextBox.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
158
159                 r = pTextBox->Construct(rect, TEXT_BOX_BORDER_ROUNDED);
160                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
161
162                 r = pTextBox->SetTextSize(EDIT_TEXT_SIZE);
163                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
164
165                 r = pTextBox->SetAutoLinkMask(LINK_TYPE_NONE);
166                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
167
168                 r = pTextBox->SetText(certString);
169                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
170
171                 r = AddControl(*pTextBox);
172                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
173
174                 TextBox* pCertBox = pTextBox.release();
175                 pLayout->SetHorizontalAlignment(*pCertBox, LAYOUT_HORIZONTAL_ALIGN_CENTER);
176         }
177         else    // CERTIFICATE_POPUP_MODE_CONFIRM
178         {
179                 std::unique_ptr<Label> pLabel(new (std::nothrow) Label());
180                 SysTryReturnResult(NID_WEB_CTRL, pLabel.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
181
182                 String message = L"";
183                 message = pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_SECURITY_CERTIFICATE_PROBLEM_MSG");
184                 message.Append(L"\n");
185                 message.Append(ewk_certificate_policy_decision_url_get(__pCertificatePolicyData));
186
187                 r = pLabel->Construct(rect, message);
188                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
189
190                 pLabel->SetTextConfig(pPopupData->labelFontSize, LABEL_TEXT_STYLE_NORMAL);
191
192                 r = AddControl(*pLabel);
193                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
194
195                 Label* pInfoLabel = pLabel.release();
196                 pLayout->SetHorizontalFitPolicy(*pInfoLabel, FIT_POLICY_PARENT);
197         }
198         Panel* pButtonPanel = CreateAndAddPanel();
199         SysTryReturn(NID_WEB_CTRL, pButtonPanel, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
200
201         r = CreateAndAddButtons(idList, titleList, pButtonPanel);
202         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
203
204         pLayout->SetHorizontalFitPolicy(*pButtonPanel, FIT_POLICY_PARENT);
205         pLayout->SetHorizontalAlignment(*pButtonPanel, LAYOUT_HORIZONTAL_ALIGN_CENTER);
206
207         pLayout->SetSpacing(*pButtonPanel, 2*pPopupData->sideMargin);
208
209         SetPropagatedKeyEventListener(this);
210
211         return E_SUCCESS;
212 }
213
214
215 void
216 _CertificateConfirmPopup::OnActionPerformed(const Control& source, int actionId)
217 {
218         result r = E_SUCCESS;
219
220         switch (actionId)
221         {
222         case ID_BUTTON_CERTIFICATE_ALLOW:
223                 HandleUserAction(true);
224                 break;
225
226         case ID_BUTTON_CERTIFICATE_VIEW:
227         {
228                 std::unique_ptr<_CertificateConfirmPopup> pCertificatePopup(new (std::nothrow) _CertificateConfirmPopup());
229                 SysTryReturnVoidResult(NID_WEB_CTRL, pCertificatePopup.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
230
231                 r = pCertificatePopup->Construct(CERTIFICATE_POPUP_MODE_VIEW, __pCertificatePolicyData, __pImpl);
232                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
233
234                 r = pCertificatePopup->ShowPopup();
235                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
236
237                 pCertificatePopup.release();
238                 return;
239         }
240
241         case ID_BUTTON_CERTIFICATE_CANCEL:
242                 HandleUserAction(false);
243                 break;
244
245         case ID_BUTTON_CERTIFICATE_CLOSE:
246                 break;
247
248         default:
249                 SysAssert(false);
250                 break;
251         }
252
253         r = HidePopup();
254         if (IsFailed(r))
255         {
256                 SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
257         }
258         if (__certPopupMode == CERTIFICATE_POPUP_MODE_VIEW)
259         {
260                 __pImpl->SendUserEvent(ID_CERTIFICATE_CONFIRM_POPUP_CLOSE, null);
261         }
262 }
263
264 bool
265 _CertificateConfirmPopup::OnKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
266 {
267         return false;
268 }
269
270 bool
271 _CertificateConfirmPopup::OnKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
272 {
273         result r = E_SUCCESS;
274         if ((keyEventInfo.GetKeyCode() == KEY_ESC || keyEventInfo.GetKeyCode() == KEY_BACK) && source.GetShowState() == true)
275         {
276                 if (__certPopupMode == CERTIFICATE_POPUP_MODE_USER_CONFIRM)
277                 {
278                         HandleUserAction(false);
279                 }
280                 r = HidePopup();
281                 if (IsFailed(r))
282                 {
283                         SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
284                 }
285                 if (__certPopupMode == CERTIFICATE_POPUP_MODE_VIEW)
286                 {
287                         __pImpl->SendUserEvent(ID_CERTIFICATE_CONFIRM_POPUP_CLOSE, null);
288                 }
289         }
290
291         return false;
292 }
293
294 bool
295 _CertificateConfirmPopup::OnPreviewKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
296 {
297         return false;
298 }
299
300 bool
301 _CertificateConfirmPopup::OnPreviewKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
302 {
303         return false;
304 }
305
306 bool
307 _CertificateConfirmPopup::TranslateKeyEventInfo(Control& source, KeyEventInfo& keyEventInfo)
308 {
309         return false;
310 }
311
312 bool
313 _CertificateConfirmPopup::GetConfirmResult() const
314 {
315         return __confirm;
316 }
317
318
319 void
320 _CertificateConfirmPopup::HandleUserAction(bool allow)
321 {
322         __confirm = allow;
323
324         String pem(ewk_certificate_policy_decision_certificate_pem_get(__pCertificatePolicyData));
325         ewk_certificate_policy_decision_allowed_set(__pCertificatePolicyData, static_cast< Eina_Bool >(allow));
326         AddCertificateDb(pem, allow);
327 }
328
329
330 void
331 _CertificateConfirmPopup::AddCertificateDb(const String& pem, bool allow)
332 {
333         _DatabaseImpl db;
334         String certificatePath(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH + USER_CONFIRM_DB_NAME);
335         String table(CERTIFICATE_TABLE_NAME);
336
337         result r = db.Construct(certificatePath, "r+", null);
338         SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
339
340         std::unique_ptr<DbStatement> pStmt(db.CreateStatementN(L"Insert Into " + table + L" (pem, allow) Values (?, ?)"));
341         SysTryReturnVoidResult(NID_WEB_CTRL, pStmt.get(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
342
343         SysLog(NID_WEB_CTRL, "The current value of pem is %ls, allow is %d", pem.GetPointer(), allow);
344
345         pStmt->BindString(0, pem);
346         pStmt->BindInt(1, static_cast < int >(allow));
347
348         db.BeginTransaction();
349
350         std::unique_ptr<DbEnumerator> pEnum(db.ExecuteStatementN(*pStmt));
351
352         db.CommitTransaction();
353 }
354
355
356 result
357 _CertificateConfirmPopup::GenerateCertifiate(String& certString)
358 {
359         SysTryReturnResult(NID_WEB_CTRL, __pCertificatePolicyData, E_INVALID_ARG, "Certificate Policy pointer is null.");
360
361         _SystemResource* pSysResource = _SystemResource::GetInstance();
362         SysAssertf(pSysResource != null, "Failed to get _SystemResource instance");
363
364         String pemString(ewk_certificate_policy_decision_certificate_pem_get(__pCertificatePolicyData));
365         std::unique_ptr<ByteBuffer> pByteBuf(StringUtil::StringToUtf8N(pemString));
366         SysTryReturnResult(NID_WEB_CTRL, pByteBuf.get(), E_INVALID_DATA, "Certificate pem information is Empty.");
367
368         X509Certificate certificate;
369         result r = certificate.Construct(*pByteBuf);
370         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
371
372         //Issued to
373         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_ISSUED_TO_C"));
374         certString.Append(L"\n\n");
375         String subject = certificate.GetSubject();
376
377         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_COMMON_NAME_C"));
378         certString.Append(L"\n");
379         certString.Append(GetStringOfToken(subject, L"/CN=") + L"\n");
380
381         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_ORGANIZATION_C"));
382         certString.Append(L"\n");
383         certString.Append(GetStringOfToken(subject, L"/O=") + L"\n");
384
385         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP ,"IDS_BR_HEADER_ORGANIZATIONAL_UNIT_C"));
386         certString.Append(L"\n");
387         certString.Append(GetStringOfToken(subject, L"/OU=") + L"\n");
388
389         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_CERTIFICATE_SERIAL_NUMBER"));
390         certString.Append(L":\n");
391         certString.Append(certificate.GetSerialNumber() + L"\n\n\n");
392
393         //Issued by
394         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_ISSUED_BY_C"));
395         certString.Append(L"\n\n");
396         String issuer = certificate.GetIssuer();
397
398         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_COMMON_NAME_C"));
399         certString.Append(L"\n");
400         certString.Append(GetStringOfToken(issuer, L"/CN=") + L"\n");
401
402         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_ORGANIZATION_C"));
403         certString.Append(L"\n");
404         certString.Append(GetStringOfToken(issuer, L"/O=") + L"\n");
405
406         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_ORGANIZATIONAL_UNIT_C"));
407         certString.Append(L"\n");
408         certString.Append(GetStringOfToken(issuer, L"/OU=") + L"\n\n");
409
410         //Validity
411         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_HEADER_VALIDITY_C"));
412         certString.Append(L"\n\n");
413         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_POP_CERTI_VALID_FROM_C"));
414         certString.Append(L"\n");
415         certString.Append(certificate.GetNotBefore() + L"\n\n");
416
417         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_CERTIFICATE_VALID_TILL"));
418         certString.Append(L":\n");
419         certString.Append(certificate.GetNotAfter() + L"\n\n\n");
420
421         //FingerPrints
422         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_ROOTCERTIFICATES_FINGER_PRINT"));
423         certString.Append(L":\n\n");
424         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_SIGNATURE_ALGORITHM_VODA"));
425         certString.Append(L":\n");
426         certString.Append(certificate.GetSignatureAlgorithm() + L"\n\n");
427
428         std::unique_ptr<ByteBuffer> pFingerPrint(certificate.GetFingerprintN());
429         if (pFingerPrint.get() && pFingerPrint->GetPointer())
430         {
431                 String fingerPrint;
432                 StringUtil::Utf8ToString((const char*)pFingerPrint->GetPointer(), fingerPrint);
433                 certString.Append(fingerPrint + L"\n\n");
434         }
435
436         return E_SUCCESS;
437 }
438
439
440 String
441 _CertificateConfirmPopup::GetStringOfToken(const String& parseString, const String& parseToken)
442 {
443         String inString(parseString);
444         int index = 0;
445
446         String outString;
447         outString.Append(L"\n");
448
449         result r = inString.IndexOf(parseToken, 0, index);
450         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
451
452         int prsTokLen = parseToken.GetLength();
453         r = inString.Remove(0, index + prsTokLen);
454         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
455
456         while (true)
457         {
458                 r = inString.IndexOf(parseToken, 0, index);
459
460                 switch (r)
461                 {
462                 case E_SUCCESS:
463                         r = inString.Remove(index, prsTokLen);
464                         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
465
466                         inString.Insert(L"\n", index);
467                         continue;
468
469                 case E_OBJ_NOT_FOUND:
470                         r = inString.IndexOf('=', 0, index);
471                         if (r == E_SUCCESS)
472                         {
473                                 int slashIndex = 0;
474                                 r = inString.LastIndexOf('/', index - 3, slashIndex);
475
476                                 if (!IsFailed(r) && (slashIndex == index - 2 || slashIndex == index - 3))
477                                 {
478                                         inString.Remove(slashIndex, inString.GetLength() - slashIndex);
479                                 }
480                         }
481                         inString.Append(L"\n");
482                         outString = inString;
483                         return outString;
484
485                 default:
486                         return outString;
487                 }
488         }
489 }
490
491
492 }}} // Tizen::Web::Controls