apply certificate DB
[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 <FUiLayout.h>
35 #include <FUiVerticalBoxLayout.h>
36 #include <FIo_DatabaseImpl.h>
37 #include <FUi_ControlManager.h>
38 #include <FUi_ResourceManager.h>
39 #include "FWebCtrl_CertificateConfirmPopup.h"
40 #include "FWebCtrl_EflWebkit.h"
41 #include "FWebCtrl_Utility.h"
42
43
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Utility;
47 using namespace Tizen::Graphics;
48 using namespace Tizen::Io;
49 using namespace Tizen::Security::Cert;
50 using namespace Tizen::Ui;
51 using namespace Tizen::Ui::Controls;
52
53
54 namespace Tizen { namespace Web { namespace Controls
55 {
56
57
58 _CertificateConfirmPopup::_CertificateConfirmPopup(void)
59                                                 : __certPopupMode(CERTIFICATE_POPUP_MODE_USER_CONFIRM)
60                                                 , __confirm(false)
61                                                 , __pCertificatePolicyData(null)
62 {
63 }
64
65
66 _CertificateConfirmPopup::~_CertificateConfirmPopup(void)
67 {
68 }
69
70
71 result
72 _CertificateConfirmPopup::Construct(_CertificatePopupMode certPopupMode, Ewk_Certificate_Policy_Decision* pPolicy)
73 {
74         SysTryReturnResult(NID_WEB_CTRL, pPolicy, E_INVALID_ARG, "Certificate Policy pointer is null.");
75         result r = E_SUCCESS;
76
77         _WebPopupData* pPopupData = _WebPopup::GetPopupData();
78         SysTryReturn(NID_WEB_CTRL, pPopupData, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
79
80         __pCertificatePolicyData = pPolicy;
81         __certPopupMode = certPopupMode;
82         String titleText = L"";
83         int popupMaxHeight = 0;
84         Rectangle rect(0, 0, 0, 0);
85
86         ArrayList idList;
87         r = idList.Construct();
88         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
89
90         ArrayList titleList;
91         r = titleList.Construct();
92         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
93
94         if( __certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
95         {
96                 titleText = L"Certificate";
97                 popupMaxHeight = pPopupData->popupDim.height;
98
99                 rect.height = pPopupData->popupDim.height - 4*pPopupData->sideMargin - 2*pPopupData->btnDim.height;
100                 rect.width = pPopupData->labelDim.width;
101
102                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_CLOSE)));
103                 titleList.Add(*(new String(L"Close")));
104         }
105         else    // CERTIFICATE_POPUP_MODE_CONFIRM
106         {
107                 titleText = L"Security Warning";
108                 popupMaxHeight = 2*pPopupData->labelDim.height + 2*pPopupData->btnDim.height + 6*pPopupData->sideMargin;
109
110                 rect.height = 2*pPopupData->labelDim.height;
111                 rect.width = pPopupData->labelDim.width;
112
113                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_ALLOW)));
114                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_VIEW)));
115                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_CANCEL)));
116
117                 titleList.Add(*(new String(L"Allow")));
118                 titleList.Add(*(new String(L"View")));
119                 titleList.Add(*(new String(L"Cancel")));
120         }
121
122         r = _WebPopup::Construct(true, Dimension(pPopupData->popupDim.width, popupMaxHeight));
123         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
124
125         SetTitleText(titleText);
126
127         std::unique_ptr<VerticalBoxLayout> pLayout(dynamic_cast< VerticalBoxLayout* >(GetLayoutN()));
128         SysTryReturn(NID_WEB_CTRL, pLayout.get(), r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
129
130         if( certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
131         {
132                 String certString;
133                 result r = GenerateCertifiate(certString);
134                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
135
136                 std::unique_ptr<TextBox> pTextBox(new (std::nothrow) TextBox());
137                 SysTryReturnResult(NID_WEB_CTRL, pTextBox.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
138
139                 r = pTextBox->Construct(rect, TEXT_BOX_BORDER_ROUNDED);
140                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
141
142                 r = pTextBox->SetTextSize(30);
143                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
144
145                 r = pTextBox->SetAutoLinkMask(LINK_TYPE_NONE);
146                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
147
148                 r = pTextBox->SetText(certString);
149                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
150
151                 r = AddControl(*pTextBox);
152                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
153
154                 TextBox* pCertBox = pTextBox.release();
155                 pLayout->SetHorizontalAlignment(*pCertBox, LAYOUT_HORIZONTAL_ALIGN_CENTER);
156         }
157         else    // CERTIFICATE_POPUP_MODE_CONFIRM
158         {
159                 std::unique_ptr<Label> pLabel(new (std::nothrow) Label());
160                 SysTryReturnResult(NID_WEB_CTRL, pLabel.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
161
162                 String message = L"";
163                 message = L"There are problems with the security certificate of this site.\n";
164                 message.Append(ewk_certificate_policy_decision_url_get(__pCertificatePolicyData));
165
166                 r = pLabel->Construct(rect, message);
167                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
168
169                 pLabel->SetTextConfig(pPopupData->labelFontSize, LABEL_TEXT_STYLE_NORMAL);
170
171                 r = AddControl(*pLabel);
172                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
173
174                 Label* pInfoLabel = pLabel.release();
175                 pLayout->SetHorizontalFitPolicy(*pInfoLabel, FIT_POLICY_PARENT);
176         }
177         Panel* pButtonPanel = CreateAndAddPanel();
178         SysTryReturn(NID_WEB_CTRL, pButtonPanel, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
179
180         r = CreateAndAddButtons(idList, titleList, pButtonPanel);
181         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
182
183         pLayout->SetHorizontalFitPolicy(*pButtonPanel, FIT_POLICY_PARENT);
184         pLayout->SetHorizontalAlignment(*pButtonPanel, LAYOUT_HORIZONTAL_ALIGN_CENTER);
185
186         pLayout->SetSpacing(*pButtonPanel, 2*pPopupData->sideMargin);
187
188         return E_SUCCESS;
189 }
190
191
192 void
193 _CertificateConfirmPopup::OnActionPerformed(const Control& source, int actionId)
194 {
195         result r = E_SUCCESS;
196
197         switch (actionId)
198         {
199         case ID_BUTTON_CERTIFICATE_ALLOW:
200                 HandleUserAction(true);
201                 break;
202
203         case ID_BUTTON_CERTIFICATE_VIEW:
204         {
205                 std::unique_ptr<_CertificateConfirmPopup> pCertificatePopup(new (std::nothrow) _CertificateConfirmPopup());
206                 SysTryReturnVoidResult(NID_WEB_CTRL, pCertificatePopup.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
207
208                 r = pCertificatePopup->Construct(CERTIFICATE_POPUP_MODE_VIEW, __pCertificatePolicyData);
209                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
210
211                 pCertificatePopup->SetOwner(this);
212                 
213                 r = pCertificatePopup->ShowPopup();
214                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
215
216                 pCertificatePopup.release();
217                 return;
218         }
219
220         case ID_BUTTON_CERTIFICATE_CANCEL:
221                 HandleUserAction(false);
222                 break;
223
224         case ID_BUTTON_CERTIFICATE_CLOSE:
225                 break;
226
227         default:
228                 SysAssert(false);
229                 break;
230         }
231
232         r = HidePopup();
233         if (IsFailed(r))
234         {
235                 SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
236         }
237         if (__certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
238         {
239                 delete this;
240         }
241 }
242
243
244 bool
245 _CertificateConfirmPopup::GetConfirmResult() const
246 {
247         return __confirm;
248 }
249
250
251 void
252 _CertificateConfirmPopup::HandleUserAction(bool allow)
253 {
254         __confirm = allow;
255
256         String pem(ewk_certificate_policy_decision_certificate_pem_get(__pCertificatePolicyData));
257         ewk_certificate_policy_decision_allowed_set(__pCertificatePolicyData, static_cast< Eina_Bool >(allow));
258         AddCertificateDb(pem, allow);
259 }
260
261
262 void
263 _CertificateConfirmPopup::AddCertificateDb(const String& pem, bool allow)
264 {
265         _DatabaseImpl db;
266         String certificatePath(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH + USER_CONFIRM_DB_NAME);
267         String table(CERTIFICATE_TABLE_NAME);
268
269         result r = db.Construct(certificatePath, "r+", null);
270         SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
271
272         std::unique_ptr<DbStatement> pStmt(db.CreateStatementN(L"Insert Into " + table + L" (pem, allow) Values (?, ?)"));
273         SysTryReturnVoidResult(NID_WEB_CTRL, pStmt.get(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
274
275         SysLog(NID_WEB_CTRL, "The current value of pem is %ls, allow is %d", pem.GetPointer(), allow);
276
277         pStmt->BindString(0, pem);
278         pStmt->BindInt(1, static_cast < int >(allow));
279
280         db.BeginTransaction();
281
282         std::unique_ptr<DbEnumerator> pEnum(db.ExecuteStatementN(*pStmt));
283
284         db.CommitTransaction();
285 }
286
287 result
288 _CertificateConfirmPopup::GenerateCertifiate(String& certString)
289 {
290         SysTryReturnResult(NID_WEB_CTRL, __pCertificatePolicyData, E_INVALID_ARG, "Certificate Policy pointer is null.");
291
292         String pemString(ewk_certificate_policy_decision_certificate_pem_get(__pCertificatePolicyData));
293         std::unique_ptr<ByteBuffer> pByteBuf(StringUtil::StringToUtf8N(pemString));
294         SysTryReturnResult(NID_WEB_CTRL, pByteBuf.get(), E_INVALID_DATA, "Certificate pem information is Empty.");
295
296         X509Certificate certificate;
297         result r = certificate.Construct(*pByteBuf);
298         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
299
300         //Issued to
301         certString.Append(L"ISSUED TO:\n\n");
302         String subject = certificate.GetSubject();
303
304         certString.Append(L"Common Name:\n");
305         certString.Append(GetStringOfToken(subject, L"/CN=") + L"\n");
306
307         certString.Append(L"Organization:\n");
308         certString.Append(GetStringOfToken(subject, L"/O=") + L"\n");
309
310         certString.Append(L"Organizational Unit:\n");
311         certString.Append(GetStringOfToken(subject, L"/OU=") + L"\n");
312
313         certString.Append(L"Serial Number:\n");
314         certString.Append(certificate.GetSerialNumber() + L"\n\n\n");
315
316         //Issued by
317         certString.Append(L"ISSUER:\n\n");
318         String issuer = certificate.GetIssuer();
319
320         certString.Append(L"Common Name:\n");
321         certString.Append(GetStringOfToken(issuer, L"/CN=") + L"\n");
322
323         certString.Append(L"Organization:\n");
324         certString.Append(GetStringOfToken(issuer, L"/O=") + L"\n");
325
326         certString.Append(L"Organizational Unit:\n");
327         certString.Append(GetStringOfToken(issuer, L"/OU=") + L"\n\n");
328
329         //Validity
330         certString.Append(L"VALIDITY:\n\n");
331         certString.Append(L"Valid From:\n");
332         certString.Append(certificate.GetNotBefore() + L"\n\n");
333
334         certString.Append(L"Valid Till:\n");
335         certString.Append(certificate.GetNotAfter() + L"\n\n\n");
336
337         //FingerPrints
338         certString.Append(L"FINGERPRINTS:\n\n");
339         certString.Append(L"Signature Algorithm:\n");
340         certString.Append(certificate.GetSignatureAlgorithm() + L"\n\n");
341
342         std::unique_ptr<ByteBuffer> pFingerPrint(certificate.GetFingerprintN());
343         if (pFingerPrint.get() && pFingerPrint->GetPointer())
344         {
345                 String fingerPrint;
346                 StringUtil::Utf8ToString((const char*)pFingerPrint->GetPointer(), fingerPrint);
347                 certString.Append(fingerPrint + L"\n\n");
348         }
349
350         return E_SUCCESS;
351 }
352
353
354 String
355 _CertificateConfirmPopup::GetStringOfToken(const String& parseString, const String& parseToken)
356 {
357         String inString(parseString);
358         int index = 0;
359
360         String outString;
361         outString.Append(L"\n");
362
363         result r = inString.IndexOf(parseToken, 0, index);
364         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
365
366         int prsTokLen = parseToken.GetLength();
367         r = inString.Remove(0, index + prsTokLen);
368         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
369
370         while (true)
371         {
372                 r = inString.IndexOf(parseToken, 0, index);
373
374                 switch (r)
375                 {
376                 case E_SUCCESS:
377                         r = inString.Remove(index, prsTokLen);
378                         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
379
380                         inString.Insert(L"\n", index);
381                         continue;
382
383                 case E_OBJ_NOT_FOUND:
384                         r = inString.IndexOf('=', 0, index);
385                         if (r == E_SUCCESS)
386                         {
387                                 int slashIndex = 0;
388                                 r = inString.LastIndexOf('/', index - 3, slashIndex);
389
390                                 if (!IsFailed(r) && (slashIndex == index - 2 || slashIndex == index - 3))
391                                 {
392                                         inString.Remove(slashIndex, inString.GetLength() - slashIndex);
393                                 }
394                         }
395                         inString.Append(L"\n");
396                         outString = inString;
397                         return outString;
398
399                 default:
400                         return outString;
401                 }
402         }
403 }
404
405
406 }}} // Tizen::Web::Controls