1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Use of this source code is governed by a BSD-style license that can be 3731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// found in the LICENSE file. 4731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 5731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/net/x509_certificate_model.h" 6731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <unicode/uidna.h> 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/utf_string_conversions.h" 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "grit/generated_resources.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 13731df977c0511bca2206b5f333555b1205ff1f43Iain Merricknamespace x509_certificate_model { 14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string ProcessIDN(const std::string& input) { 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Convert the ASCII input to a string16 for ICU. 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string16 input16; 18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick input16.reserve(input.length()); 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen input16.insert(input16.end(), input.begin(), input.end()); 20731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick string16 output16; 22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick output16.resize(input.length()); 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UErrorCode status = U_ZERO_ERROR; 25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int output_chars = uidna_IDNToUnicode(input16.data(), input.length(), 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &output16[0], output16.length(), 27731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UIDNA_DEFAULT, NULL, &status); 28731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (status == U_ZERO_ERROR) { 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick output16.resize(output_chars); 30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (status != U_BUFFER_OVERFLOW_ERROR) { 31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return input; 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else { 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick output16.resize(output_chars); 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick output_chars = uidna_IDNToUnicode(input16.data(), input.length(), 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &output16[0], output16.length(), 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick UIDNA_DEFAULT, NULL, &status); 37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (status != U_ZERO_ERROR) 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return input; 39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK_EQ(static_cast<size_t>(output_chars), output16.length()); 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick output16.resize(output_chars); // Just to be safe. 41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (input16 == output16) 44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return input; // Input did not contain any encoded data. 45731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Input contained encoded data, return formatted string showing original and 47731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // decoded forms. 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return l10n_util::GetStringFUTF8(IDS_CERT_INFO_IDN_VALUE_FORMAT, 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick input16, output16); 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::string ProcessRawBytesWithSeparators(const unsigned char* data, 53513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t data_length, 54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch char hex_separator, 55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch char line_separator) { 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch static const char kHexChars[] = "0123456789ABCDEF"; 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Each input byte creates two output hex characters + a space or newline, 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // except for the last byte. 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string ret; 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t kMin = 0U; 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ret.reserve(std::max(kMin, data_length * 3 - 1)); 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (size_t i = 0; i < data_length; ++i) { 65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch unsigned char b = data[i]; 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ret.push_back(kHexChars[(b >> 4) & 0xf]); 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ret.push_back(kHexChars[b & 0xf]); 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (i + 1 < data_length) { 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if ((i + 1) % 16 == 0) 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ret.push_back(line_separator); 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch else 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ret.push_back(hex_separator); 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ret; 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::string ProcessRawBytes(const unsigned char* data, size_t data_length) { 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ProcessRawBytesWithSeparators(data, data_length, ' ', '\n'); 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(USE_NSS) 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::string ProcessRawBits(const unsigned char* data, size_t data_length) { 84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ProcessRawBytes(data, (data_length + 7) / 8); 85513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif // USE_NSS 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} // x509_certificate_model 89731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 90