1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/views/signed_certificate_timestamp_info_view.h"
6
7#include <algorithm>
8
9#include "base/i18n/time_formatting.h"
10#include "base/strings/string16.h"
11#include "base/strings/string_number_conversions.h"
12#include "base/strings/utf_string_conversions.h"
13#include "chrome/common/net/x509_certificate_model.h"
14#include "chrome/grit/generated_resources.h"
15#include "net/cert/signed_certificate_timestamp.h"
16#include "ui/base/l10n/l10n_util.h"
17#include "ui/native_theme/native_theme.h"
18#include "ui/views/controls/label.h"
19#include "ui/views/layout/grid_layout.h"
20#include "ui/views/layout/layout_constants.h"
21
22namespace {
23
24// Adjustment to the spacing between subsequent label-field lines.
25const int kExtraLineHeightPadding = 3;
26
27int HashAlgorithmToResourceID(
28    net::ct::DigitallySigned::HashAlgorithm hash_algorithm) {
29  switch (hash_algorithm) {
30    case net::ct::DigitallySigned::HASH_ALGO_NONE:
31      return IDS_SCT_HASH_ALGORITHM_NONE;
32    case net::ct::DigitallySigned::HASH_ALGO_MD5:
33      return IDS_SCT_HASH_ALGORITHM_MD5;
34    case net::ct::DigitallySigned::HASH_ALGO_SHA1:
35      return IDS_SCT_HASH_ALGORITHM_SHA1;
36    case net::ct::DigitallySigned::HASH_ALGO_SHA224:
37      return IDS_SCT_HASH_ALGORITHM_SHA224;
38    case net::ct::DigitallySigned::HASH_ALGO_SHA256:
39      return IDS_SCT_HASH_ALGORITHM_SHA256;
40    case net::ct::DigitallySigned::HASH_ALGO_SHA384:
41      return IDS_SCT_HASH_ALGORITHM_SHA384;
42    case net::ct::DigitallySigned::HASH_ALGO_SHA512:
43      return IDS_SCT_HASH_ALGORITHM_SHA512;
44  }
45  return IDS_SCT_HASH_ALGORITHM_NONE;
46}
47
48int SignatureAlgorithmToResourceID(
49    net::ct::DigitallySigned::SignatureAlgorithm signature_algorithm) {
50  switch (signature_algorithm) {
51    case net::ct::DigitallySigned::SIG_ALGO_ANONYMOUS:
52      return IDS_SCT_SIGNATURE_ALGORITHM_ANONYMOUS;
53    case net::ct::DigitallySigned::SIG_ALGO_RSA:
54      return IDS_SCT_SIGNATURE_ALGORITHM_RSA;
55    case net::ct::DigitallySigned::SIG_ALGO_DSA:
56      return IDS_SCT_SIGNATURE_ALGORITHM_DSA;
57    case net::ct::DigitallySigned::SIG_ALGO_ECDSA:
58      return IDS_SCT_SIGNATURE_ALGORITHM_ECDSA;
59  }
60  return IDS_SCT_SIGNATURE_ALGORITHM_ANONYMOUS;
61}
62
63int VersionToResourceID(int version) {
64  return version == 0 ? IDS_SCT_VERSION_V1 : IDS_SCT_VERSION_UNKNOWN;
65}
66
67}  // namespace
68
69namespace chrome {
70namespace ct {
71
72int StatusToResourceID(net::ct::SCTVerifyStatus status) {
73  switch (status) {
74    case net::ct::SCT_STATUS_NONE:
75      return IDS_SCT_STATUS_NONE;
76    case net::ct::SCT_STATUS_LOG_UNKNOWN:
77      return IDS_SCT_STATUS_LOG_UNKNOWN;
78    case net::ct::SCT_STATUS_INVALID:
79      return IDS_SCT_STATUS_INVALID;
80    case net::ct::SCT_STATUS_OK:
81      return IDS_SCT_STATUS_OK;
82    case net::ct::SCT_STATUS_MAX:
83      break;
84  }
85
86  return IDS_SCT_STATUS_NONE;
87}
88
89int SCTOriginToResourceID(const net::ct::SignedCertificateTimestamp& sct) {
90  switch (sct.origin) {
91    case net::ct::SignedCertificateTimestamp::SCT_EMBEDDED:
92      return IDS_SCT_ORIGIN_EMBEDDED;
93    case net::ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION:
94      return IDS_SCT_ORIGIN_TLS_EXTENSION;
95    case net::ct::SignedCertificateTimestamp::SCT_FROM_OCSP_RESPONSE:
96      return IDS_SCT_ORIGIN_OCSP;
97    case net::ct::SignedCertificateTimestamp::SCT_ORIGIN_MAX:
98      break;
99  }
100  return IDS_SCT_ORIGIN_UNKNOWN;
101}
102
103}  // namespace ct
104}  // namespace chrome
105
106// SignedCertificateTimestampInfoView, public:
107
108SignedCertificateTimestampInfoView::SignedCertificateTimestampInfoView()
109    : status_value_field_(NULL),
110      origin_value_field_(NULL),
111      version_value_field_(NULL),
112      log_id_value_field_(NULL),
113      timestamp_value_field_(NULL),
114      hash_algorithm_value_field_(NULL),
115      signature_algorithm_value_field_(NULL),
116      signature_data_value_field_(NULL) {}
117
118SignedCertificateTimestampInfoView::~SignedCertificateTimestampInfoView() {}
119
120void SignedCertificateTimestampInfoView::SetSignedCertificateTimestamp(
121    const net::ct::SignedCertificateTimestamp& sct,
122    net::ct::SCTVerifyStatus status) {
123  status_value_field_->SetText(
124      l10n_util::GetStringUTF16(chrome::ct::StatusToResourceID(status)));
125  origin_value_field_->SetText(
126      l10n_util::GetStringUTF16(chrome::ct::SCTOriginToResourceID(sct)));
127  version_value_field_->SetText(
128      l10n_util::GetStringUTF16(VersionToResourceID(sct.version)));
129  log_description_value_field_->SetText(base::UTF8ToUTF16(sct.log_description));
130  timestamp_value_field_->SetText(
131      base::TimeFormatFriendlyDateAndTime(sct.timestamp));
132
133  hash_algorithm_value_field_->SetText(l10n_util::GetStringUTF16(
134      HashAlgorithmToResourceID(sct.signature.hash_algorithm)));
135  signature_algorithm_value_field_->SetText(l10n_util::GetStringUTF16(
136      SignatureAlgorithmToResourceID(sct.signature.signature_algorithm)));
137
138  // The log_id and signature_data fields contain binary data, format it
139  // accordingly before displaying.
140  log_id_value_field_->SetText(
141      base::UTF8ToUTF16(x509_certificate_model::ProcessRawBytes(
142          reinterpret_cast<const unsigned char*>(sct.log_id.c_str()),
143          sct.log_id.length())));
144  signature_data_value_field_->SetText(
145      base::UTF8ToUTF16(x509_certificate_model::ProcessRawBytes(
146          reinterpret_cast<const unsigned char*>(
147              sct.signature.signature_data.c_str()),
148          sct.signature.signature_data.length())));
149
150  Layout();
151}
152
153void SignedCertificateTimestampInfoView::ViewHierarchyChanged(
154    const ViewHierarchyChangedDetails& details) {
155  if (details.is_add && details.child == this)
156    Init();
157}
158
159void SignedCertificateTimestampInfoView::AddLabelRow(int layout_id,
160                                                     views::GridLayout* layout,
161                                                     int label_message_id,
162                                                     views::Label* data_label) {
163  layout->StartRow(0, layout_id);
164  layout->AddView(
165      new views::Label(l10n_util::GetStringUTF16(label_message_id)));
166  layout->AddView(
167      data_label, 2, 1, views::GridLayout::LEADING, views::GridLayout::CENTER);
168  layout->AddPaddingRow(0, kExtraLineHeightPadding);
169}
170
171void SignedCertificateTimestampInfoView::Init() {
172  status_value_field_ = new views::Label;
173  origin_value_field_ = new views::Label;
174  version_value_field_ = new views::Label;
175  log_description_value_field_ = new views::Label;
176  log_id_value_field_ = new views::Label;
177  log_id_value_field_->SetMultiLine(true);
178  log_id_value_field_->SetAllowCharacterBreak(true);
179  log_id_value_field_->SetTooltipText(
180      l10n_util::GetStringUTF16(IDS_SCT_RAW_DATA_HELP));
181
182  timestamp_value_field_ = new views::Label;
183  hash_algorithm_value_field_ = new views::Label;
184  signature_algorithm_value_field_ = new views::Label;
185  signature_data_value_field_ = new views::Label;
186  signature_data_value_field_->SetMultiLine(true);
187  signature_data_value_field_->SetAllowCharacterBreak(true);
188  signature_data_value_field_->SetTooltipText(
189      l10n_util::GetStringUTF16(IDS_SCT_RAW_DATA_HELP));
190
191  views::GridLayout* layout = new views::GridLayout(this);
192  layout->SetInsets(
193      0, views::kButtonHEdgeMarginNew, 0, views::kButtonHEdgeMarginNew);
194  SetLayoutManager(layout);
195
196  const int three_column_layout_id = 0;
197  views::ColumnSet* column_set = layout->AddColumnSet(three_column_layout_id);
198  column_set->AddColumn(views::GridLayout::LEADING,
199                        views::GridLayout::CENTER,
200                        0,
201                        views::GridLayout::USE_PREF,
202                        0,
203                        0);
204  column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
205  column_set->AddColumn(views::GridLayout::TRAILING,
206                        views::GridLayout::CENTER,
207                        0,
208                        views::GridLayout::USE_PREF,
209                        0,
210                        0);
211  column_set->AddColumn(views::GridLayout::FILL,
212                        views::GridLayout::CENTER,
213                        1,
214                        views::GridLayout::USE_PREF,
215                        0,
216                        0);
217
218  AddLabelRow(three_column_layout_id,
219              layout,
220              IDS_SCT_VALIDATION_INFO,
221              status_value_field_);
222  AddLabelRow(
223      three_column_layout_id, layout, IDS_SCT_ORIGIN, origin_value_field_);
224  AddLabelRow(
225      three_column_layout_id, layout, IDS_SCT_VERSION, version_value_field_);
226  AddLabelRow(three_column_layout_id,
227              layout,
228              IDS_SCT_LOG_DESCRIPTION,
229              log_description_value_field_);
230  AddLabelRow(
231      three_column_layout_id, layout, IDS_SCT_LOGID, log_id_value_field_);
232  AddLabelRow(three_column_layout_id,
233              layout,
234              IDS_SCT_TIMESTAMP,
235              timestamp_value_field_);
236  AddLabelRow(three_column_layout_id,
237              layout,
238              IDS_SCT_HASH_ALGORITHM,
239              hash_algorithm_value_field_);
240  AddLabelRow(three_column_layout_id,
241              layout,
242              IDS_SCT_SIGNATURE_ALGORITHM,
243              signature_algorithm_value_field_);
244  AddLabelRow(three_column_layout_id,
245              layout,
246              IDS_SCT_SIGNATURE_DATA,
247              signature_data_value_field_);
248}
249