Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chrome / third_party / mozilla_security_manager / nsNSSCertHelper.cpp
blob563fae625326f1f38e82a0cf7de05f675cd1cbbf
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Ian McGreer <mcgreer@netscape.com>
23 * Javier Delgadillo <javi@netscape.com>
24 * John Gardiner Myers <jgmyers@speakeasy.net>
25 * Martin v. Loewis <martin@v.loewis.de>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h"
43 #include <certdb.h>
44 #include <keyhi.h>
45 #include <prprf.h>
46 #include <unicode/uidna.h>
48 #include "base/i18n/number_formatting.h"
49 #include "base/lazy_instance.h"
50 #include "base/strings/string_number_conversions.h"
51 #include "base/strings/stringprintf.h"
52 #include "base/strings/utf_string_conversions.h"
53 #include "chrome/common/net/x509_certificate_model.h"
54 #include "crypto/scoped_nss_types.h"
55 #include "chrome/grit/generated_resources.h"
56 #include "net/base/ip_endpoint.h"
57 #include "net/base/net_util.h"
58 #include "ui/base/l10n/l10n_util.h"
60 #if !defined(CERTDB_TERMINAL_RECORD)
61 /* NSS 3.13 renames CERTDB_VALID_PEER to CERTDB_TERMINAL_RECORD
62 * and marks CERTDB_VALID_PEER as deprecated.
63 * If we're using an older version, rename it ourselves.
65 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
66 #endif
68 namespace {
70 std::string BMPtoUTF8(PRArenaPool* arena, unsigned char* data,
71 unsigned int len) {
72 if (len % 2 != 0)
73 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
75 unsigned int utf8_val_len = len * 3 + 1;
76 std::vector<unsigned char> utf8_val(utf8_val_len);
77 if (!PORT_UCS2_UTF8Conversion(PR_FALSE, data, len,
78 &utf8_val.front(), utf8_val_len, &utf8_val_len))
79 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
80 return std::string(reinterpret_cast<char*>(&utf8_val.front()), utf8_val_len);
83 SECOidTag RegisterDynamicOid(const char* oid_string) {
84 SECOidTag rv = SEC_OID_UNKNOWN;
85 unsigned char buffer[1024];
86 SECOidData od;
87 od.oid.type = siDEROID;
88 od.oid.data = buffer;
89 od.oid.len = sizeof(buffer);
91 if (SEC_StringToOID(NULL, &od.oid, oid_string, 0) == SECSuccess) {
92 od.offset = SEC_OID_UNKNOWN;
93 od.mechanism = CKM_INVALID_MECHANISM;
94 od.supportedExtension = INVALID_CERT_EXTENSION;
95 od.desc = oid_string;
97 rv = SECOID_AddEntry(&od);
99 DCHECK_NE(rv, SEC_OID_UNKNOWN) << oid_string;
100 return rv;
103 // Format a SECItem as a space separated string, with 16 bytes on each line.
104 std::string ProcessRawBytes(SECItem* data) {
105 return x509_certificate_model::ProcessRawBytes(data->data, data->len);
108 SECOidTag ms_cert_ext_certtype = SEC_OID_UNKNOWN;
109 SECOidTag ms_certsrv_ca_version = SEC_OID_UNKNOWN;
110 SECOidTag ms_nt_principal_name = SEC_OID_UNKNOWN;
111 SECOidTag ms_ntds_replication = SEC_OID_UNKNOWN;
112 SECOidTag eku_ms_individual_code_signing = SEC_OID_UNKNOWN;
113 SECOidTag eku_ms_commercial_code_signing = SEC_OID_UNKNOWN;
114 SECOidTag eku_ms_trust_list_signing = SEC_OID_UNKNOWN;
115 SECOidTag eku_ms_time_stamping = SEC_OID_UNKNOWN;
116 SECOidTag eku_ms_server_gated_crypto = SEC_OID_UNKNOWN;
117 SECOidTag eku_ms_encrypting_file_system = SEC_OID_UNKNOWN;
118 SECOidTag eku_ms_file_recovery = SEC_OID_UNKNOWN;
119 SECOidTag eku_ms_windows_hardware_driver_verification = SEC_OID_UNKNOWN;
120 SECOidTag eku_ms_qualified_subordination = SEC_OID_UNKNOWN;
121 SECOidTag eku_ms_key_recovery = SEC_OID_UNKNOWN;
122 SECOidTag eku_ms_document_signing = SEC_OID_UNKNOWN;
123 SECOidTag eku_ms_lifetime_signing = SEC_OID_UNKNOWN;
124 SECOidTag eku_ms_smart_card_logon = SEC_OID_UNKNOWN;
125 SECOidTag eku_ms_key_recovery_agent = SEC_OID_UNKNOWN;
126 SECOidTag eku_netscape_international_step_up = SEC_OID_UNKNOWN;
127 SECOidTag cert_attribute_business_category = SEC_OID_UNKNOWN;
128 SECOidTag cert_attribute_ev_incorporation_country = SEC_OID_UNKNOWN;
130 class DynamicOidRegisterer {
131 public:
132 DynamicOidRegisterer() {
133 ms_cert_ext_certtype = RegisterDynamicOid("1.3.6.1.4.1.311.20.2");
134 ms_certsrv_ca_version = RegisterDynamicOid("1.3.6.1.4.1.311.21.1");
135 ms_nt_principal_name = RegisterDynamicOid("1.3.6.1.4.1.311.20.2.3");
136 ms_ntds_replication = RegisterDynamicOid("1.3.6.1.4.1.311.25.1");
138 eku_ms_individual_code_signing = RegisterDynamicOid("1.3.6.1.4.1.311.2.1.21");
139 eku_ms_commercial_code_signing = RegisterDynamicOid("1.3.6.1.4.1.311.2.1.22");
140 eku_ms_trust_list_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.1");
141 eku_ms_time_stamping = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.2");
142 eku_ms_server_gated_crypto = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.3");
143 eku_ms_encrypting_file_system = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.4");
144 eku_ms_file_recovery = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.4.1");
145 eku_ms_windows_hardware_driver_verification = RegisterDynamicOid(
146 "1.3.6.1.4.1.311.10.3.5");
147 eku_ms_qualified_subordination = RegisterDynamicOid(
148 "1.3.6.1.4.1.311.10.3.10");
149 eku_ms_key_recovery = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.11");
150 eku_ms_document_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.12");
151 eku_ms_lifetime_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.13");
152 eku_ms_smart_card_logon = RegisterDynamicOid("1.3.6.1.4.1.311.20.2.2");
153 eku_ms_key_recovery_agent = RegisterDynamicOid("1.3.6.1.4.1.311.21.6");
154 eku_netscape_international_step_up = RegisterDynamicOid(
155 "2.16.840.1.113730.4.1");
157 // These two OIDs will be built-in as SEC_OID_BUSINESS_CATEGORY and
158 // SEC_OID_EV_INCORPORATION_COUNTRY starting in NSS 3.13. Until then,
159 // we need to add them dynamically.
160 cert_attribute_business_category = RegisterDynamicOid("2.5.4.15");
161 cert_attribute_ev_incorporation_country = RegisterDynamicOid(
162 "1.3.6.1.4.1.311.60.2.1.3");
166 static base::LazyInstance<DynamicOidRegisterer>::Leaky
167 g_dynamic_oid_registerer = LAZY_INSTANCE_INITIALIZER;
169 } // namespace
171 namespace mozilla_security_manager {
173 std::string DumpOidString(SECItem* oid) {
174 char* pr_string = CERT_GetOidString(oid);
175 if (pr_string) {
176 std::string rv = pr_string;
177 PR_smprintf_free(pr_string);
178 return rv;
181 return ProcessRawBytes(oid);
184 std::string GetOIDText(SECItem* oid) {
185 g_dynamic_oid_registerer.Get();
187 int string_id;
188 SECOidTag oid_tag = SECOID_FindOIDTag(oid);
189 switch (oid_tag) {
190 case SEC_OID_AVA_COMMON_NAME:
191 string_id = IDS_CERT_OID_AVA_COMMON_NAME;
192 break;
193 case SEC_OID_AVA_STATE_OR_PROVINCE:
194 string_id = IDS_CERT_OID_AVA_STATE_OR_PROVINCE;
195 break;
196 case SEC_OID_AVA_ORGANIZATION_NAME:
197 string_id = IDS_CERT_OID_AVA_ORGANIZATION_NAME;
198 break;
199 case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
200 string_id = IDS_CERT_OID_AVA_ORGANIZATIONAL_UNIT_NAME;
201 break;
202 case SEC_OID_AVA_DN_QUALIFIER:
203 string_id = IDS_CERT_OID_AVA_DN_QUALIFIER;
204 break;
205 case SEC_OID_AVA_COUNTRY_NAME:
206 string_id = IDS_CERT_OID_AVA_COUNTRY_NAME;
207 break;
208 case SEC_OID_AVA_SERIAL_NUMBER:
209 string_id = IDS_CERT_OID_AVA_SERIAL_NUMBER;
210 break;
211 case SEC_OID_AVA_LOCALITY:
212 string_id = IDS_CERT_OID_AVA_LOCALITY;
213 break;
214 case SEC_OID_AVA_DC:
215 string_id = IDS_CERT_OID_AVA_DC;
216 break;
217 case SEC_OID_RFC1274_MAIL:
218 string_id = IDS_CERT_OID_RFC1274_MAIL;
219 break;
220 case SEC_OID_RFC1274_UID:
221 string_id = IDS_CERT_OID_RFC1274_UID;
222 break;
223 case SEC_OID_PKCS9_EMAIL_ADDRESS:
224 string_id = IDS_CERT_OID_PKCS9_EMAIL_ADDRESS;
225 break;
226 case SEC_OID_PKCS1_RSA_ENCRYPTION:
227 string_id = IDS_CERT_OID_PKCS1_RSA_ENCRYPTION;
228 break;
229 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
230 string_id = IDS_CERT_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
231 break;
232 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
233 string_id = IDS_CERT_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION;
234 break;
235 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
236 string_id = IDS_CERT_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
237 break;
238 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
239 string_id = IDS_CERT_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
240 break;
241 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
242 string_id = IDS_CERT_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
243 break;
244 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
245 string_id = IDS_CERT_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
246 break;
247 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
248 string_id = IDS_CERT_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
249 break;
250 case SEC_OID_NS_CERT_EXT_CERT_TYPE:
251 string_id = IDS_CERT_EXT_NS_CERT_TYPE;
252 break;
253 case SEC_OID_NS_CERT_EXT_BASE_URL:
254 string_id = IDS_CERT_EXT_NS_CERT_BASE_URL;
255 break;
256 case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
257 string_id = IDS_CERT_EXT_NS_CERT_REVOCATION_URL;
258 break;
259 case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
260 string_id = IDS_CERT_EXT_NS_CA_REVOCATION_URL;
261 break;
262 case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
263 string_id = IDS_CERT_EXT_NS_CERT_RENEWAL_URL;
264 break;
265 case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
266 string_id = IDS_CERT_EXT_NS_CA_POLICY_URL;
267 break;
268 case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
269 string_id = IDS_CERT_EXT_NS_SSL_SERVER_NAME;
270 break;
271 case SEC_OID_NS_CERT_EXT_COMMENT:
272 string_id = IDS_CERT_EXT_NS_COMMENT;
273 break;
274 case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
275 string_id = IDS_CERT_EXT_NS_LOST_PASSWORD_URL;
276 break;
277 case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME:
278 string_id = IDS_CERT_EXT_NS_CERT_RENEWAL_TIME;
279 break;
280 case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR:
281 string_id = IDS_CERT_X509_SUBJECT_DIRECTORY_ATTR;
282 break;
283 case SEC_OID_X509_SUBJECT_KEY_ID:
284 string_id = IDS_CERT_X509_SUBJECT_KEYID;
285 break;
286 case SEC_OID_X509_KEY_USAGE:
287 string_id = IDS_CERT_X509_KEY_USAGE;
288 break;
289 case SEC_OID_X509_SUBJECT_ALT_NAME:
290 string_id = IDS_CERT_X509_SUBJECT_ALT_NAME;
291 break;
292 case SEC_OID_X509_ISSUER_ALT_NAME:
293 string_id = IDS_CERT_X509_ISSUER_ALT_NAME;
294 break;
295 case SEC_OID_X509_BASIC_CONSTRAINTS:
296 string_id = IDS_CERT_X509_BASIC_CONSTRAINTS;
297 break;
298 case SEC_OID_X509_NAME_CONSTRAINTS:
299 string_id = IDS_CERT_X509_NAME_CONSTRAINTS;
300 break;
301 case SEC_OID_X509_CRL_DIST_POINTS:
302 string_id = IDS_CERT_X509_CRL_DIST_POINTS;
303 break;
304 case SEC_OID_X509_CERTIFICATE_POLICIES:
305 string_id = IDS_CERT_X509_CERT_POLICIES;
306 break;
307 case SEC_OID_X509_POLICY_MAPPINGS:
308 string_id = IDS_CERT_X509_POLICY_MAPPINGS;
309 break;
310 case SEC_OID_X509_POLICY_CONSTRAINTS:
311 string_id = IDS_CERT_X509_POLICY_CONSTRAINTS;
312 break;
313 case SEC_OID_X509_AUTH_KEY_ID:
314 string_id = IDS_CERT_X509_AUTH_KEYID;
315 break;
316 case SEC_OID_X509_EXT_KEY_USAGE:
317 string_id = IDS_CERT_X509_EXT_KEY_USAGE;
318 break;
319 case SEC_OID_X509_AUTH_INFO_ACCESS:
320 string_id = IDS_CERT_X509_AUTH_INFO_ACCESS;
321 break;
322 case SEC_OID_EXT_KEY_USAGE_SERVER_AUTH:
323 string_id = IDS_CERT_EKU_TLS_WEB_SERVER_AUTHENTICATION;
324 break;
325 case SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH:
326 string_id = IDS_CERT_EKU_TLS_WEB_CLIENT_AUTHENTICATION;
327 break;
328 case SEC_OID_EXT_KEY_USAGE_CODE_SIGN:
329 string_id = IDS_CERT_EKU_CODE_SIGNING;
330 break;
331 case SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT:
332 string_id = IDS_CERT_EKU_EMAIL_PROTECTION;
333 break;
334 case SEC_OID_EXT_KEY_USAGE_TIME_STAMP:
335 string_id = IDS_CERT_EKU_TIME_STAMPING;
336 break;
337 case SEC_OID_OCSP_RESPONDER:
338 string_id = IDS_CERT_EKU_OCSP_SIGNING;
339 break;
340 case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
341 string_id = IDS_CERT_PKIX_CPS_POINTER_QUALIFIER;
342 break;
343 case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
344 string_id = IDS_CERT_PKIX_USER_NOTICE_QUALIFIER;
345 break;
346 case SEC_OID_UNKNOWN:
347 string_id = -1;
348 break;
350 // There are a billionty other OIDs we could add here. I tried to get the
351 // important ones...
352 default:
353 if (oid_tag == ms_cert_ext_certtype)
354 string_id = IDS_CERT_EXT_MS_CERT_TYPE;
355 else if (oid_tag == ms_certsrv_ca_version)
356 string_id = IDS_CERT_EXT_MS_CA_VERSION;
357 else if (oid_tag == ms_nt_principal_name)
358 string_id = IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME;
359 else if (oid_tag == ms_ntds_replication)
360 string_id = IDS_CERT_EXT_MS_NTDS_REPLICATION;
361 else if (oid_tag == eku_ms_individual_code_signing)
362 string_id = IDS_CERT_EKU_MS_INDIVIDUAL_CODE_SIGNING;
363 else if (oid_tag == eku_ms_commercial_code_signing)
364 string_id = IDS_CERT_EKU_MS_COMMERCIAL_CODE_SIGNING;
365 else if (oid_tag == eku_ms_trust_list_signing)
366 string_id = IDS_CERT_EKU_MS_TRUST_LIST_SIGNING;
367 else if (oid_tag == eku_ms_time_stamping)
368 string_id = IDS_CERT_EKU_MS_TIME_STAMPING;
369 else if (oid_tag == eku_ms_server_gated_crypto)
370 string_id = IDS_CERT_EKU_MS_SERVER_GATED_CRYPTO;
371 else if (oid_tag == eku_ms_encrypting_file_system)
372 string_id = IDS_CERT_EKU_MS_ENCRYPTING_FILE_SYSTEM;
373 else if (oid_tag == eku_ms_file_recovery)
374 string_id = IDS_CERT_EKU_MS_FILE_RECOVERY;
375 else if (oid_tag == eku_ms_windows_hardware_driver_verification)
376 string_id = IDS_CERT_EKU_MS_WINDOWS_HARDWARE_DRIVER_VERIFICATION;
377 else if (oid_tag == eku_ms_qualified_subordination)
378 string_id = IDS_CERT_EKU_MS_QUALIFIED_SUBORDINATION;
379 else if (oid_tag == eku_ms_key_recovery)
380 string_id = IDS_CERT_EKU_MS_KEY_RECOVERY;
381 else if (oid_tag == eku_ms_document_signing)
382 string_id = IDS_CERT_EKU_MS_DOCUMENT_SIGNING;
383 else if (oid_tag == eku_ms_lifetime_signing)
384 string_id = IDS_CERT_EKU_MS_LIFETIME_SIGNING;
385 else if (oid_tag == eku_ms_smart_card_logon)
386 string_id = IDS_CERT_EKU_MS_SMART_CARD_LOGON;
387 else if (oid_tag == eku_ms_key_recovery_agent)
388 string_id = IDS_CERT_EKU_MS_KEY_RECOVERY_AGENT;
389 else if (oid_tag == eku_netscape_international_step_up)
390 string_id = IDS_CERT_EKU_NETSCAPE_INTERNATIONAL_STEP_UP;
391 else if (oid_tag == cert_attribute_business_category)
392 string_id = IDS_CERT_OID_BUSINESS_CATEGORY;
393 else if (oid_tag == cert_attribute_ev_incorporation_country)
394 string_id = IDS_CERT_OID_EV_INCORPORATION_COUNTRY;
395 else
396 string_id = -1;
397 break;
399 if (string_id >= 0)
400 return l10n_util::GetStringUTF8(string_id);
402 return DumpOidString(oid);
405 // Get a display string from a Relative Distinguished Name.
406 std::string ProcessRDN(CERTRDN* rdn) {
407 std::string rv;
409 CERTAVA** avas = rdn->avas;
410 for (size_t i = 0; avas[i] != NULL; ++i) {
411 rv += GetOIDText(&avas[i]->type);
412 SECItem* decode_item = CERT_DecodeAVAValue(&avas[i]->value);
413 if (decode_item) {
414 // TODO(mattm): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
415 rv += " = ";
416 std::string value(reinterpret_cast<char*>(decode_item->data),
417 decode_item->len);
418 if (SECOID_FindOIDTag(&avas[i]->type) == SEC_OID_AVA_COMMON_NAME)
419 value = x509_certificate_model::ProcessIDN(value);
420 rv += value;
421 SECITEM_FreeItem(decode_item, PR_TRUE);
423 rv += '\n';
426 return rv;
429 std::string ProcessName(CERTName* name) {
430 std::string rv;
431 CERTRDN** last_rdn;
433 // Find last non-NULL rdn.
434 for (last_rdn = name->rdns; last_rdn[0]; last_rdn++) {}
435 last_rdn--;
437 for (CERTRDN** rdn = last_rdn; rdn >= name->rdns; rdn--)
438 rv += ProcessRDN(*rdn);
439 return rv;
442 std::string ProcessBasicConstraints(SECItem* extension_data) {
443 CERTBasicConstraints value;
444 value.pathLenConstraint = -1;
445 if (CERT_DecodeBasicConstraintValue(&value, extension_data) != SECSuccess)
446 return ProcessRawBytes(extension_data);
448 std::string rv;
449 if (value.isCA)
450 rv = l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_CA);
451 else
452 rv = l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_NOT_CA);
453 rv += '\n';
454 if (value.pathLenConstraint != -1) {
455 base::string16 depth;
456 if (value.pathLenConstraint == CERT_UNLIMITED_PATH_CONSTRAINT) {
457 depth = l10n_util::GetStringUTF16(
458 IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN_UNLIMITED);
459 } else {
460 depth = base::FormatNumber(value.pathLenConstraint);
462 rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN,
463 depth);
465 return rv;
468 std::string ProcessGeneralName(PRArenaPool* arena,
469 CERTGeneralName* current) {
470 DCHECK(current);
472 std::string key;
473 std::string value;
475 switch (current->type) {
476 case certOtherName: {
477 key = GetOIDText(&current->name.OthName.oid);
478 // g_dynamic_oid_registerer.Get() will have been run by GetOIDText.
479 SECOidTag oid_tag = SECOID_FindOIDTag(&current->name.OthName.oid);
480 if (oid_tag == ms_nt_principal_name) {
481 // The type of this name is apparently nowhere explicitly
482 // documented. However, in the generated templates, it is always
483 // UTF-8. So try to decode this as UTF-8; if that fails, dump the
484 // raw data.
485 SECItem decoded;
486 if (SEC_ASN1DecodeItem(arena, &decoded,
487 SEC_ASN1_GET(SEC_UTF8StringTemplate),
488 &current->name.OthName.name) == SECSuccess) {
489 value = std::string(reinterpret_cast<char*>(decoded.data),
490 decoded.len);
491 } else {
492 value = ProcessRawBytes(&current->name.OthName.name);
494 break;
495 } else if (oid_tag == ms_ntds_replication) {
496 // This should be a 16-byte GUID.
497 SECItem guid;
498 if (SEC_ASN1DecodeItem(arena, &guid,
499 SEC_ASN1_GET(SEC_OctetStringTemplate),
500 &current->name.OthName.name) == SECSuccess &&
501 guid.len == 16) {
502 unsigned char* d = guid.data;
503 base::SStringPrintf(
504 &value,
505 "{%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-"
506 "%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}",
507 d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6],
508 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
509 } else {
510 value = ProcessRawBytes(&current->name.OthName.name);
512 } else {
513 value = ProcessRawBytes(&current->name.OthName.name);
515 break;
517 case certRFC822Name:
518 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_RFC822_NAME);
519 value = std::string(reinterpret_cast<char*>(current->name.other.data),
520 current->name.other.len);
521 break;
522 case certDNSName:
523 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DNS_NAME);
524 value = std::string(reinterpret_cast<char*>(current->name.other.data),
525 current->name.other.len);
526 value = x509_certificate_model::ProcessIDN(value);
527 break;
528 case certX400Address:
529 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_X400_ADDRESS);
530 value = ProcessRawBytes(&current->name.other);
531 break;
532 case certDirectoryName:
533 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DIRECTORY_NAME);
534 value = ProcessName(&current->name.directoryName);
535 break;
536 case certEDIPartyName:
537 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_EDI_PARTY_NAME);
538 value = ProcessRawBytes(&current->name.other);
539 break;
540 case certURI:
541 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_URI);
542 value = std::string(reinterpret_cast<char*>(current->name.other.data),
543 current->name.other.len);
544 break;
545 case certIPAddress: {
546 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_IP_ADDRESS);
548 net::IPAddressNumber ip(
549 current->name.other.data,
550 current->name.other.data + current->name.other.len);
552 if (net::GetAddressFamily(ip) != net::ADDRESS_FAMILY_UNSPECIFIED) {
553 value = net::IPAddressToString(ip);
554 } else {
555 // Invalid IP address.
556 value = ProcessRawBytes(&current->name.other);
558 break;
560 case certRegisterID:
561 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_REGISTERED_ID);
562 value = DumpOidString(&current->name.other);
563 break;
565 std::string rv(l10n_util::GetStringFUTF8(IDS_CERT_UNKNOWN_OID_INFO_FORMAT,
566 base::UTF8ToUTF16(key),
567 base::UTF8ToUTF16(value)));
568 rv += '\n';
569 return rv;
572 std::string ProcessGeneralNames(PRArenaPool* arena,
573 CERTGeneralName* name_list) {
574 std::string rv;
575 CERTGeneralName* current = name_list;
577 do {
578 std::string text = ProcessGeneralName(arena, current);
579 if (text.empty())
580 break;
581 rv += text;
582 current = CERT_GetNextGeneralName(current);
583 } while (current != name_list);
584 return rv;
587 std::string ProcessAltName(SECItem* extension_data) {
588 CERTGeneralName* name_list;
590 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
591 CHECK(arena.get());
593 name_list = CERT_DecodeAltNameExtension(arena.get(), extension_data);
594 if (!name_list)
595 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
597 return ProcessGeneralNames(arena.get(), name_list);
600 std::string ProcessSubjectKeyId(SECItem* extension_data) {
601 SECItem decoded;
602 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
603 CHECK(arena.get());
605 std::string rv;
606 if (SEC_QuickDERDecodeItem(arena.get(), &decoded,
607 SEC_ASN1_GET(SEC_OctetStringTemplate),
608 extension_data) != SECSuccess) {
609 rv = l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
610 return rv;
613 rv = l10n_util::GetStringFUTF8(IDS_CERT_KEYID_FORMAT,
614 base::ASCIIToUTF16(ProcessRawBytes(&decoded)));
615 return rv;
618 std::string ProcessAuthKeyId(SECItem* extension_data) {
619 CERTAuthKeyID* ret;
620 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
621 std::string rv;
623 CHECK(arena.get());
625 ret = CERT_DecodeAuthKeyID(arena.get(), extension_data);
627 if (ret->keyID.len > 0) {
628 rv += l10n_util::GetStringFUTF8(IDS_CERT_KEYID_FORMAT,
629 base::ASCIIToUTF16(
630 ProcessRawBytes(&ret->keyID)));
631 rv += '\n';
634 if (ret->authCertIssuer) {
635 rv += l10n_util::GetStringFUTF8(
636 IDS_CERT_ISSUER_FORMAT,
637 base::UTF8ToUTF16(
638 ProcessGeneralNames(arena.get(), ret->authCertIssuer)));
639 rv += '\n';
642 if (ret->authCertSerialNumber.len > 0) {
643 rv += l10n_util::GetStringFUTF8(
644 IDS_CERT_SERIAL_NUMBER_FORMAT,
645 base::ASCIIToUTF16(ProcessRawBytes(&ret->authCertSerialNumber)));
646 rv += '\n';
649 return rv;
652 std::string ProcessUserNotice(SECItem* der_notice) {
653 CERTUserNotice* notice = CERT_DecodeUserNotice(der_notice);
654 if (!notice)
655 return ProcessRawBytes(der_notice);
657 std::string rv;
658 if (notice->noticeReference.organization.len != 0) {
659 switch (notice->noticeReference.organization.type) {
660 case siAsciiString:
661 case siVisibleString:
662 case siUTF8String:
663 rv += std::string(
664 reinterpret_cast<char*>(notice->noticeReference.organization.data),
665 notice->noticeReference.organization.len);
666 break;
667 case siBMPString:
668 rv += ProcessBMPString(&notice->noticeReference.organization);
669 break;
670 default:
671 break;
673 rv += " - ";
674 SECItem** itemList = notice->noticeReference.noticeNumbers;
675 while (*itemList) {
676 unsigned long number;
677 if (SEC_ASN1DecodeInteger(*itemList, &number) == SECSuccess) {
678 if (itemList != notice->noticeReference.noticeNumbers)
679 rv += ", ";
680 rv += '#';
681 rv += base::UTF16ToUTF8(base::UintToString16(number));
683 itemList++;
686 if (notice->displayText.len != 0) {
687 rv += "\n ";
688 switch (notice->displayText.type) {
689 case siAsciiString:
690 case siVisibleString:
691 case siUTF8String:
692 rv += std::string(reinterpret_cast<char*>(notice->displayText.data),
693 notice->displayText.len);
694 break;
695 case siBMPString:
696 rv += ProcessBMPString(&notice->displayText);
697 break;
698 default:
699 break;
703 CERT_DestroyUserNotice(notice);
704 return rv;
707 std::string ProcessCertificatePolicies(SECItem* extension_data) {
708 std::string rv;
710 CERTCertificatePolicies* policies = CERT_DecodeCertificatePoliciesExtension(
711 extension_data);
712 if (!policies)
713 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
715 CERTPolicyInfo** policyInfos = policies->policyInfos;
716 while (*policyInfos) {
717 CERTPolicyInfo* policyInfo = *policyInfos++;
718 std::string key = GetOIDText(&policyInfo->policyID);
720 // If we have policy qualifiers, display the oid text
721 // with a ':', otherwise just put the oid text and a newline.
722 // TODO(mattm): Add extra note if this is the ev oid? (It's a bit
723 // complicated, since we don't want to do the EV check synchronously.)
724 if (policyInfo->policyQualifiers) {
725 rv += l10n_util::GetStringFUTF8(IDS_CERT_MULTILINE_INFO_START_FORMAT,
726 base::UTF8ToUTF16(key));
727 } else {
728 rv += key;
730 rv += '\n';
732 if (policyInfo->policyQualifiers) {
733 // Add all qualifiers on separate lines, indented.
734 CERTPolicyQualifier** policyQualifiers = policyInfo->policyQualifiers;
735 while (*policyQualifiers != NULL) {
736 rv += " ";
738 CERTPolicyQualifier* policyQualifier = *policyQualifiers++;
739 rv += l10n_util::GetStringFUTF8(
740 IDS_CERT_MULTILINE_INFO_START_FORMAT,
741 base::UTF8ToUTF16(GetOIDText(&policyQualifier->qualifierID)));
742 switch(policyQualifier->oid) {
743 case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
744 rv += " ";
745 /* The CPS pointer ought to be the cPSuri alternative
746 of the Qualifier choice. */
747 rv += ProcessIA5String(&policyQualifier->qualifierValue);
748 break;
749 case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
750 rv += ProcessUserNotice(&policyQualifier->qualifierValue);
751 break;
752 default:
753 rv += ProcessRawBytes(&policyQualifier->qualifierValue);
754 break;
756 rv += '\n';
761 CERT_DestroyCertificatePoliciesExtension(policies);
762 return rv;
765 std::string ProcessCrlDistPoints(SECItem* extension_data) {
766 std::string rv;
767 CERTCrlDistributionPoints* crldp;
768 CRLDistributionPoint** points;
769 CRLDistributionPoint* point;
770 bool comma;
772 static const struct {
773 int reason;
774 int string_id;
775 } reason_string_map[] = {
776 {RF_UNUSED, IDS_CERT_REVOCATION_REASON_UNUSED},
777 {RF_KEY_COMPROMISE, IDS_CERT_REVOCATION_REASON_KEY_COMPROMISE},
778 {RF_CA_COMPROMISE, IDS_CERT_REVOCATION_REASON_CA_COMPROMISE},
779 {RF_AFFILIATION_CHANGED, IDS_CERT_REVOCATION_REASON_AFFILIATION_CHANGED},
780 {RF_SUPERSEDED, IDS_CERT_REVOCATION_REASON_SUPERSEDED},
781 {RF_CESSATION_OF_OPERATION,
782 IDS_CERT_REVOCATION_REASON_CESSATION_OF_OPERATION},
783 {RF_CERTIFICATE_HOLD, IDS_CERT_REVOCATION_REASON_CERTIFICATE_HOLD},
786 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
787 CHECK(arena.get());
789 crldp = CERT_DecodeCRLDistributionPoints(arena.get(), extension_data);
790 if (!crldp || !crldp->distPoints) {
791 rv = l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
792 return rv;
795 for (points = crldp->distPoints; *points; ++points) {
796 point = *points;
797 switch (point->distPointType) {
798 case generalName:
799 // generalName is a typo in upstream NSS; fullName is actually a
800 // GeneralNames (SEQUENCE OF GeneralName). See Mozilla Bug #615100.
801 rv += ProcessGeneralNames(arena.get(), point->distPoint.fullName);
802 break;
803 case relativeDistinguishedName:
804 rv += ProcessRDN(&point->distPoint.relativeName);
805 break;
807 if (point->reasons.len) {
808 rv += ' ';
809 comma = false;
810 for (size_t i = 0; i < arraysize(reason_string_map); ++i) {
811 if (point->reasons.data[0] & reason_string_map[i].reason) {
812 if (comma)
813 rv += ',';
814 rv += l10n_util::GetStringUTF8(reason_string_map[i].string_id);
815 comma = true;
818 rv += '\n';
820 if (point->crlIssuer) {
821 rv += l10n_util::GetStringFUTF8(
822 IDS_CERT_ISSUER_FORMAT,
823 base::UTF8ToUTF16(
824 ProcessGeneralNames(arena.get(), point->crlIssuer)));
827 return rv;
830 std::string ProcessAuthInfoAccess(SECItem* extension_data) {
831 std::string rv;
832 CERTAuthInfoAccess** aia;
833 CERTAuthInfoAccess* desc;
834 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
835 CHECK(arena.get());
837 aia = CERT_DecodeAuthInfoAccessExtension(arena.get(), extension_data);
838 if (aia == NULL)
839 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
841 while (*aia != NULL) {
842 desc = *aia++;
843 base::string16 location_str =
844 base::UTF8ToUTF16(ProcessGeneralName(arena.get(), desc->location));
845 switch (SECOID_FindOIDTag(&desc->method)) {
846 case SEC_OID_PKIX_OCSP:
847 rv += l10n_util::GetStringFUTF8(IDS_CERT_OCSP_RESPONDER_FORMAT,
848 location_str);
849 break;
850 case SEC_OID_PKIX_CA_ISSUERS:
851 rv += l10n_util::GetStringFUTF8(IDS_CERT_CA_ISSUERS_FORMAT,
852 location_str);
853 break;
854 default:
855 rv += l10n_util::GetStringFUTF8(IDS_CERT_UNKNOWN_OID_INFO_FORMAT,
856 base::UTF8ToUTF16(
857 GetOIDText(&desc->method)),
858 location_str);
859 break;
862 return rv;
865 std::string ProcessIA5String(SECItem* extension_data) {
866 SECItem item;
867 if (SEC_ASN1DecodeItem(NULL, &item, SEC_ASN1_GET(SEC_IA5StringTemplate),
868 extension_data) != SECSuccess)
869 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
870 std::string rv((char*)item.data, item.len); // ASCII data.
871 PORT_Free(item.data);
872 return rv;
875 std::string ProcessBMPString(SECItem* extension_data) {
876 std::string rv;
877 SECItem item;
878 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
879 CHECK(arena.get());
881 if (SEC_ASN1DecodeItem(arena.get(), &item,
882 SEC_ASN1_GET(SEC_BMPStringTemplate), extension_data) ==
883 SECSuccess)
884 rv = BMPtoUTF8(arena.get(), item.data, item.len);
885 return rv;
888 struct MaskIdPair {
889 unsigned int mask;
890 int string_id;
893 static std::string ProcessBitField(SECItem* bitfield,
894 const MaskIdPair* string_map,
895 size_t len,
896 char separator) {
897 unsigned int bits = 0;
898 std::string rv;
899 for (size_t i = 0; i * 8 < bitfield->len && i < sizeof(bits); ++i)
900 bits |= bitfield->data[i] << (i * 8);
901 for (size_t i = 0; i < len; ++i) {
902 if (bits & string_map[i].mask) {
903 if (!rv.empty())
904 rv += separator;
905 rv += l10n_util::GetStringUTF8(string_map[i].string_id);
908 return rv;
911 static std::string ProcessBitStringExtension(SECItem* extension_data,
912 const MaskIdPair* string_map,
913 size_t len,
914 char separator) {
915 SECItem decoded;
916 decoded.type = siBuffer;
917 decoded.data = NULL;
918 decoded.len = 0;
919 if (SEC_ASN1DecodeItem(NULL, &decoded, SEC_ASN1_GET(SEC_BitStringTemplate),
920 extension_data) != SECSuccess)
921 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
922 std::string rv = ProcessBitField(&decoded, string_map, len, separator);
923 PORT_Free(decoded.data);
924 return rv;
927 std::string ProcessNSCertTypeExtension(SECItem* extension_data) {
928 static const MaskIdPair usage_string_map[] = {
929 {NS_CERT_TYPE_SSL_CLIENT, IDS_CERT_USAGE_SSL_CLIENT},
930 {NS_CERT_TYPE_SSL_SERVER, IDS_CERT_USAGE_SSL_SERVER},
931 {NS_CERT_TYPE_EMAIL, IDS_CERT_EXT_NS_CERT_TYPE_EMAIL},
932 {NS_CERT_TYPE_OBJECT_SIGNING, IDS_CERT_USAGE_OBJECT_SIGNER},
933 {NS_CERT_TYPE_SSL_CA, IDS_CERT_USAGE_SSL_CA},
934 {NS_CERT_TYPE_EMAIL_CA, IDS_CERT_EXT_NS_CERT_TYPE_EMAIL_CA},
935 {NS_CERT_TYPE_OBJECT_SIGNING_CA, IDS_CERT_USAGE_OBJECT_SIGNER},
937 return ProcessBitStringExtension(extension_data, usage_string_map,
938 arraysize(usage_string_map), '\n');
941 static const MaskIdPair key_usage_string_map[] = {
942 {KU_DIGITAL_SIGNATURE, IDS_CERT_X509_KEY_USAGE_SIGNING},
943 {KU_NON_REPUDIATION, IDS_CERT_X509_KEY_USAGE_NONREP},
944 {KU_KEY_ENCIPHERMENT, IDS_CERT_X509_KEY_USAGE_ENCIPHERMENT},
945 {KU_DATA_ENCIPHERMENT, IDS_CERT_X509_KEY_USAGE_DATA_ENCIPHERMENT},
946 {KU_KEY_AGREEMENT, IDS_CERT_X509_KEY_USAGE_KEY_AGREEMENT},
947 {KU_KEY_CERT_SIGN, IDS_CERT_X509_KEY_USAGE_CERT_SIGNER},
948 {KU_CRL_SIGN, IDS_CERT_X509_KEY_USAGE_CRL_SIGNER},
949 {KU_ENCIPHER_ONLY, IDS_CERT_X509_KEY_USAGE_ENCIPHER_ONLY},
950 // NSS is missing a flag for dechiperOnly, see:
951 // https://bugzilla.mozilla.org/show_bug.cgi?id=549952
954 std::string ProcessKeyUsageBitString(SECItem* bitstring, char sep) {
955 return ProcessBitField(bitstring, key_usage_string_map,
956 arraysize(key_usage_string_map), sep);
959 std::string ProcessKeyUsageExtension(SECItem* extension_data) {
960 return ProcessBitStringExtension(extension_data, key_usage_string_map,
961 arraysize(key_usage_string_map), '\n');
964 std::string ProcessExtKeyUsage(SECItem* extension_data) {
965 std::string rv;
966 CERTOidSequence* extension_key_usage = NULL;
967 extension_key_usage = CERT_DecodeOidSequence(extension_data);
968 if (extension_key_usage == NULL)
969 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR);
971 SECItem** oids;
972 SECItem* oid;
973 for (oids = extension_key_usage->oids; oids != NULL && *oids != NULL;
974 ++oids) {
975 oid = *oids;
976 std::string oid_dump = DumpOidString(oid);
977 std::string oid_text = GetOIDText(oid);
979 // If oid is one we recognize, oid_text will have a text description of the
980 // OID, which we display along with the oid_dump. If we don't recognize the
981 // OID, GetOIDText will return the same value as DumpOidString, so just
982 // display the OID alone.
983 if (oid_dump == oid_text)
984 rv += oid_dump;
985 else
986 rv += l10n_util::GetStringFUTF8(IDS_CERT_EXT_KEY_USAGE_FORMAT,
987 base::UTF8ToUTF16(oid_text),
988 base::UTF8ToUTF16(oid_dump));
989 rv += '\n';
991 CERT_DestroyOidSequence(extension_key_usage);
992 return rv;
995 std::string ProcessExtensionData(CERTCertExtension* extension) {
996 g_dynamic_oid_registerer.Get();
997 SECOidTag oid_tag = SECOID_FindOIDTag(&extension->id);
998 SECItem* extension_data = &extension->value;
1000 // This (and its sub-functions) are based on the same-named functions in
1001 // security/manager/ssl/src/nsNSSCertHelper.cpp.
1002 switch (oid_tag) {
1003 case SEC_OID_NS_CERT_EXT_CERT_TYPE:
1004 return ProcessNSCertTypeExtension(extension_data);
1005 case SEC_OID_X509_KEY_USAGE:
1006 return ProcessKeyUsageExtension(extension_data);
1007 case SEC_OID_X509_BASIC_CONSTRAINTS:
1008 return ProcessBasicConstraints(extension_data);
1009 case SEC_OID_X509_EXT_KEY_USAGE:
1010 return ProcessExtKeyUsage(extension_data);
1011 case SEC_OID_X509_ISSUER_ALT_NAME:
1012 case SEC_OID_X509_SUBJECT_ALT_NAME:
1013 return ProcessAltName(extension_data);
1014 case SEC_OID_X509_SUBJECT_KEY_ID:
1015 return ProcessSubjectKeyId(extension_data);
1016 case SEC_OID_X509_AUTH_KEY_ID:
1017 return ProcessAuthKeyId(extension_data);
1018 case SEC_OID_X509_CERTIFICATE_POLICIES:
1019 return ProcessCertificatePolicies(extension_data);
1020 case SEC_OID_X509_CRL_DIST_POINTS:
1021 return ProcessCrlDistPoints(extension_data);
1022 case SEC_OID_X509_AUTH_INFO_ACCESS:
1023 return ProcessAuthInfoAccess(extension_data);
1024 case SEC_OID_NS_CERT_EXT_BASE_URL:
1025 case SEC_OID_NS_CERT_EXT_REVOCATION_URL:
1026 case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL:
1027 case SEC_OID_NS_CERT_EXT_CA_CERT_URL:
1028 case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL:
1029 case SEC_OID_NS_CERT_EXT_CA_POLICY_URL:
1030 case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL:
1031 case SEC_OID_NS_CERT_EXT_COMMENT:
1032 case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME:
1033 case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL:
1034 return ProcessIA5String(extension_data);
1035 default:
1036 if (oid_tag == ms_cert_ext_certtype)
1037 return ProcessBMPString(extension_data);
1038 return ProcessRawBytes(extension_data);
1042 std::string ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki) {
1043 std::string rv;
1044 SECKEYPublicKey* key = SECKEY_ExtractPublicKey(spki);
1045 if (key) {
1046 switch (key->keyType) {
1047 case rsaKey: {
1048 rv = l10n_util::GetStringFUTF8(
1049 IDS_CERT_RSA_PUBLIC_KEY_DUMP_FORMAT,
1050 base::UintToString16(key->u.rsa.modulus.len * 8),
1051 base::UTF8ToUTF16(ProcessRawBytes(&key->u.rsa.modulus)),
1052 base::UintToString16(key->u.rsa.publicExponent.len * 8),
1053 base::UTF8ToUTF16(ProcessRawBytes(&key->u.rsa.publicExponent)));
1054 break;
1056 default:
1057 rv = x509_certificate_model::ProcessRawBits(
1058 spki->subjectPublicKey.data, spki->subjectPublicKey.len);
1059 break;
1061 SECKEY_DestroyPublicKey(key);
1063 return rv;
1066 net::CertType GetCertType(CERTCertificate *cert) {
1067 CERTCertTrust trust = {0};
1068 CERT_GetCertTrust(cert, &trust);
1070 unsigned all_flags = trust.sslFlags | trust.emailFlags |
1071 trust.objectSigningFlags;
1073 if (cert->nickname && (all_flags & CERTDB_USER))
1074 return net::USER_CERT;
1075 if ((all_flags & CERTDB_VALID_CA) || CERT_IsCACert(cert, NULL))
1076 return net::CA_CERT;
1077 // TODO(mattm): http://crbug.com/128633.
1078 if (trust.sslFlags & CERTDB_TERMINAL_RECORD)
1079 return net::SERVER_CERT;
1080 return net::OTHER_CERT;
1083 } // namespace mozilla_security_manager