1 // Copyright (c) 2011 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/common/net/x509_certificate_model.h" 6 7 #include <openssl/obj_mac.h> 8 #include <openssl/sha.h> 9 #include <openssl/stack.h> 10 #include <openssl/x509.h> 11 #include <openssl/x509v3.h> 12 13 #include "base/i18n/number_formatting.h" 14 #include "base/lazy_instance.h" 15 #include "base/logging.h" 16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/stringprintf.h" 18 #include "base/strings/utf_string_conversions.h" 19 #include "chrome/grit/generated_resources.h" 20 #include "crypto/openssl_bio_string.h" 21 #include "crypto/openssl_util.h" 22 #include "crypto/scoped_openssl_types.h" 23 #include "net/base/net_util.h" 24 #include "net/cert/x509_util_openssl.h" 25 #include "ui/base/l10n/l10n_util.h" 26 27 namespace x509_util = net::x509_util; 28 29 namespace x509_certificate_model { 30 31 namespace { 32 33 std::string ProcessRawAsn1String(ASN1_STRING* data) { 34 return ProcessRawBytes(ASN1_STRING_data(data), ASN1_STRING_length(data)); 35 } 36 37 std::string ProcessRawAsn1Type(ASN1_TYPE* data) { 38 int len = i2d_ASN1_TYPE(data, NULL); 39 if (len <= 0) 40 return std::string(); 41 42 scoped_ptr<unsigned char[]> buf(new unsigned char[len]); 43 unsigned char* bufp = buf.get(); 44 45 len = i2d_ASN1_TYPE(data, &bufp); 46 47 return ProcessRawBytes(buf.get(), len); 48 } 49 50 std::string ProcessRawBignum(BIGNUM* n) { 51 int len = BN_num_bytes(n); 52 scoped_ptr<unsigned char[]> buf(new unsigned char[len]); 53 len = BN_bn2bin(n, buf.get()); 54 return ProcessRawBytes(buf.get(), len); 55 } 56 57 std::string Asn1StringToUTF8(ASN1_STRING* asn1_string) { 58 std::string rv; 59 unsigned char* buf = NULL; 60 int len = ASN1_STRING_to_UTF8(&buf, asn1_string); 61 if (len < 0) 62 return rv; 63 rv = std::string(reinterpret_cast<const char*>(buf), len); 64 OPENSSL_free(buf); 65 return rv; 66 } 67 68 std::string AlternativeWhenEmpty(const std::string& text, 69 const std::string& alternative) { 70 return text.empty() ? alternative : text; 71 } 72 73 std::string GetKeyValuesFromNameEntry(X509_NAME_ENTRY* entry) { 74 std::string ret; 75 std::string key; 76 std::string value; 77 if (!x509_util::ParsePrincipalKeyAndValue(entry, &key, &value)) 78 return ret; 79 if (OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry)) == NID_commonName) 80 value = x509_certificate_model::ProcessIDN(value); 81 ret = base::StringPrintf("%s = %s", key.c_str(), value.c_str()); 82 return ret; 83 } 84 85 std::string GetKeyValuesFromNameEntries(STACK_OF(X509_NAME_ENTRY)* entries) { 86 std::string ret; 87 size_t rdns = sk_X509_NAME_ENTRY_num(entries); 88 for (size_t i = rdns - 1; i < rdns; --i) { 89 X509_NAME_ENTRY* entry = sk_X509_NAME_ENTRY_value(entries, i); 90 if (!entry) 91 continue; 92 base::StringAppendF(&ret, "%s\n", GetKeyValuesFromNameEntry(entry).c_str()); 93 } 94 return ret; 95 } 96 97 std::string GetKeyValuesFromName(X509_NAME* name) { 98 std::string ret; 99 size_t rdns = X509_NAME_entry_count(name); 100 for (size_t i = rdns - 1; i < rdns; --i) { 101 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, i); 102 if (!entry) 103 continue; 104 base::StringAppendF(&ret, "%s\n", GetKeyValuesFromNameEntry(entry).c_str()); 105 } 106 return ret; 107 } 108 109 std::string Asn1ObjectToOIDString(ASN1_OBJECT* obj) { 110 std::string s; 111 char buf[80]; 112 int buflen = OBJ_obj2txt(buf, sizeof(buf), obj, 1 /* no_name */); 113 if (buflen < 0) 114 return s; 115 116 s = "OID."; 117 118 if (static_cast<size_t>(buflen) < sizeof(buf)) { 119 s.append(buf, buflen); 120 return s; 121 } 122 123 size_t prefix_len = s.size(); 124 s.resize(prefix_len + buflen + 1, ' '); 125 buflen = 126 OBJ_obj2txt(&s[prefix_len], s.size() - prefix_len, obj, 1 /* no_name */); 127 if (buflen < 0) { 128 s.clear(); 129 return s; 130 } 131 s.resize(prefix_len + buflen); 132 return s; 133 } 134 135 int ms_cert_ext_certtype = -1; 136 int ms_certsrv_ca_version = -1; 137 int ms_ntds_replication = -1; 138 int eku_ms_time_stamping = -1; 139 int eku_ms_file_recovery = -1; 140 int eku_ms_windows_hardware_driver_verification = -1; 141 int eku_ms_qualified_subordination = -1; 142 int eku_ms_key_recovery = -1; 143 int eku_ms_document_signing = -1; 144 int eku_ms_lifetime_signing = -1; 145 int eku_ms_key_recovery_agent = -1; 146 int cert_attribute_ev_incorporation_country = -1; 147 int ns_cert_ext_ca_cert_url = -1; 148 int ns_cert_ext_homepage_url = -1; 149 int ns_cert_ext_lost_password_url = -1; 150 int ns_cert_ext_cert_renewal_time = -1; 151 152 int RegisterDynamicOid(const char* oid_string, const char* short_name) { 153 int nid = OBJ_txt2nid(oid_string); 154 if (nid > 0) { 155 DVLOG(1) << "found already existing nid " << nid << " for " << oid_string; 156 return nid; 157 } 158 return OBJ_create(oid_string, short_name, short_name); 159 } 160 161 class DynamicOidRegisterer { 162 public: 163 DynamicOidRegisterer() { 164 ms_cert_ext_certtype = 165 RegisterDynamicOid("1.3.6.1.4.1.311.20.2", "ms_cert_ext_certtype"); 166 ms_certsrv_ca_version = 167 RegisterDynamicOid("1.3.6.1.4.1.311.21.1", "ms_certsrv_ca_version"); 168 ms_ntds_replication = 169 RegisterDynamicOid("1.3.6.1.4.1.311.25.1", "ms_ntds_replication"); 170 171 eku_ms_time_stamping = 172 RegisterDynamicOid("1.3.6.1.4.1.311.10.3.2", "eku_ms_time_stamping"); 173 eku_ms_file_recovery = 174 RegisterDynamicOid("1.3.6.1.4.1.311.10.3.4.1", "eku_ms_file_recovery"); 175 eku_ms_windows_hardware_driver_verification = 176 RegisterDynamicOid("1.3.6.1.4.1.311.10.3.5", 177 "eku_ms_windows_hardware_driver_verification"); 178 eku_ms_qualified_subordination = RegisterDynamicOid( 179 "1.3.6.1.4.1.311.10.3.10", "eku_ms_qualified_subordination"); 180 eku_ms_key_recovery = 181 RegisterDynamicOid("1.3.6.1.4.1.311.10.3.11", "eku_ms_key_recovery"); 182 eku_ms_document_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.12", 183 "eku_ms_document_signing"); 184 eku_ms_lifetime_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.13", 185 "eku_ms_lifetime_signing"); 186 eku_ms_key_recovery_agent = 187 RegisterDynamicOid("1.3.6.1.4.1.311.21.6", "eku_ms_key_recovery_agent"); 188 189 cert_attribute_ev_incorporation_country = RegisterDynamicOid( 190 "1.3.6.1.4.1.311.60.2.1.3", "cert_attribute_ev_incorporation_country"); 191 192 ns_cert_ext_ca_cert_url = RegisterDynamicOid( 193 "2.16.840.1.113730.1.6", "ns_cert_ext_ca_cert_url"); 194 ns_cert_ext_homepage_url = RegisterDynamicOid( 195 "2.16.840.1.113730.1.9", "ns_cert_ext_homepage_url"); 196 ns_cert_ext_lost_password_url = RegisterDynamicOid( 197 "2.16.840.1.113730.1.14", "ns_cert_ext_lost_password_url"); 198 ns_cert_ext_cert_renewal_time = RegisterDynamicOid( 199 "2.16.840.1.113730.1.15", "ns_cert_ext_cert_renewal_time"); 200 } 201 }; 202 203 static base::LazyInstance<DynamicOidRegisterer>::Leaky 204 g_dynamic_oid_registerer = LAZY_INSTANCE_INITIALIZER; 205 206 std::string Asn1ObjectToString(ASN1_OBJECT* obj) { 207 g_dynamic_oid_registerer.Get(); 208 209 int string_id; 210 int nid = OBJ_obj2nid(obj); 211 switch (nid) { 212 case NID_commonName: 213 string_id = IDS_CERT_OID_AVA_COMMON_NAME; 214 break; 215 case NID_stateOrProvinceName: 216 string_id = IDS_CERT_OID_AVA_STATE_OR_PROVINCE; 217 break; 218 case NID_organizationName: 219 string_id = IDS_CERT_OID_AVA_ORGANIZATION_NAME; 220 break; 221 case NID_organizationalUnitName: 222 string_id = IDS_CERT_OID_AVA_ORGANIZATIONAL_UNIT_NAME; 223 break; 224 case NID_dnQualifier: 225 string_id = IDS_CERT_OID_AVA_DN_QUALIFIER; 226 break; 227 case NID_countryName: 228 string_id = IDS_CERT_OID_AVA_COUNTRY_NAME; 229 break; 230 case NID_serialNumber: 231 string_id = IDS_CERT_OID_AVA_SERIAL_NUMBER; 232 break; 233 case NID_localityName: 234 string_id = IDS_CERT_OID_AVA_LOCALITY; 235 break; 236 case NID_domainComponent: 237 string_id = IDS_CERT_OID_AVA_DC; 238 break; 239 case NID_rfc822Mailbox: 240 string_id = IDS_CERT_OID_RFC1274_MAIL; 241 break; 242 case NID_userId: 243 string_id = IDS_CERT_OID_RFC1274_UID; 244 break; 245 case NID_pkcs9_emailAddress: 246 string_id = IDS_CERT_OID_PKCS9_EMAIL_ADDRESS; 247 break; 248 case NID_rsaEncryption: 249 string_id = IDS_CERT_OID_PKCS1_RSA_ENCRYPTION; 250 break; 251 case NID_md2WithRSAEncryption: 252 string_id = IDS_CERT_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; 253 break; 254 case NID_md4WithRSAEncryption: 255 string_id = IDS_CERT_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION; 256 break; 257 case NID_md5WithRSAEncryption: 258 string_id = IDS_CERT_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; 259 break; 260 case NID_sha1WithRSAEncryption: 261 string_id = IDS_CERT_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 262 break; 263 case NID_sha256WithRSAEncryption: 264 string_id = IDS_CERT_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 265 break; 266 case NID_sha384WithRSAEncryption: 267 string_id = IDS_CERT_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 268 break; 269 case NID_sha512WithRSAEncryption: 270 string_id = IDS_CERT_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 271 break; 272 case NID_netscape_cert_type: 273 string_id = IDS_CERT_EXT_NS_CERT_TYPE; 274 break; 275 case NID_netscape_base_url: 276 string_id = IDS_CERT_EXT_NS_CERT_BASE_URL; 277 break; 278 case NID_netscape_revocation_url: 279 string_id = IDS_CERT_EXT_NS_CERT_REVOCATION_URL; 280 break; 281 case NID_netscape_ca_revocation_url: 282 string_id = IDS_CERT_EXT_NS_CA_REVOCATION_URL; 283 break; 284 case NID_netscape_renewal_url: 285 string_id = IDS_CERT_EXT_NS_CERT_RENEWAL_URL; 286 break; 287 case NID_netscape_ca_policy_url: 288 string_id = IDS_CERT_EXT_NS_CA_POLICY_URL; 289 break; 290 case NID_netscape_ssl_server_name: 291 string_id = IDS_CERT_EXT_NS_SSL_SERVER_NAME; 292 break; 293 case NID_netscape_comment: 294 string_id = IDS_CERT_EXT_NS_COMMENT; 295 break; 296 case NID_subject_directory_attributes: 297 string_id = IDS_CERT_X509_SUBJECT_DIRECTORY_ATTR; 298 break; 299 case NID_subject_key_identifier: 300 string_id = IDS_CERT_X509_SUBJECT_KEYID; 301 break; 302 case NID_key_usage: 303 string_id = IDS_CERT_X509_KEY_USAGE; 304 break; 305 case NID_subject_alt_name: 306 string_id = IDS_CERT_X509_SUBJECT_ALT_NAME; 307 break; 308 case NID_issuer_alt_name: 309 string_id = IDS_CERT_X509_ISSUER_ALT_NAME; 310 break; 311 case NID_basic_constraints: 312 string_id = IDS_CERT_X509_BASIC_CONSTRAINTS; 313 break; 314 case NID_name_constraints: 315 string_id = IDS_CERT_X509_NAME_CONSTRAINTS; 316 break; 317 case NID_crl_distribution_points: 318 string_id = IDS_CERT_X509_CRL_DIST_POINTS; 319 break; 320 case NID_certificate_policies: 321 string_id = IDS_CERT_X509_CERT_POLICIES; 322 break; 323 case NID_policy_mappings: 324 string_id = IDS_CERT_X509_POLICY_MAPPINGS; 325 break; 326 case NID_policy_constraints: 327 string_id = IDS_CERT_X509_POLICY_CONSTRAINTS; 328 break; 329 case NID_authority_key_identifier: 330 string_id = IDS_CERT_X509_AUTH_KEYID; 331 break; 332 case NID_ext_key_usage: 333 string_id = IDS_CERT_X509_EXT_KEY_USAGE; 334 break; 335 case NID_info_access: 336 string_id = IDS_CERT_X509_AUTH_INFO_ACCESS; 337 break; 338 case NID_server_auth: 339 string_id = IDS_CERT_EKU_TLS_WEB_SERVER_AUTHENTICATION; 340 break; 341 case NID_client_auth: 342 string_id = IDS_CERT_EKU_TLS_WEB_CLIENT_AUTHENTICATION; 343 break; 344 case NID_code_sign: 345 string_id = IDS_CERT_EKU_CODE_SIGNING; 346 break; 347 case NID_email_protect: 348 string_id = IDS_CERT_EKU_EMAIL_PROTECTION; 349 break; 350 case NID_time_stamp: 351 string_id = IDS_CERT_EKU_TIME_STAMPING; 352 break; 353 case NID_OCSP_sign: 354 string_id = IDS_CERT_EKU_OCSP_SIGNING; 355 break; 356 case NID_id_qt_cps: 357 string_id = IDS_CERT_PKIX_CPS_POINTER_QUALIFIER; 358 break; 359 case NID_id_qt_unotice: 360 string_id = IDS_CERT_PKIX_USER_NOTICE_QUALIFIER; 361 break; 362 case NID_ms_upn: 363 string_id = IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME; 364 break; 365 case NID_ms_code_ind: 366 string_id = IDS_CERT_EKU_MS_INDIVIDUAL_CODE_SIGNING; 367 break; 368 case NID_ms_code_com: 369 string_id = IDS_CERT_EKU_MS_COMMERCIAL_CODE_SIGNING; 370 break; 371 case NID_ms_ctl_sign: 372 string_id = IDS_CERT_EKU_MS_TRUST_LIST_SIGNING; 373 break; 374 case NID_ms_sgc: 375 string_id = IDS_CERT_EKU_MS_SERVER_GATED_CRYPTO; 376 break; 377 case NID_ms_efs: 378 string_id = IDS_CERT_EKU_MS_ENCRYPTING_FILE_SYSTEM; 379 break; 380 case NID_ms_smartcard_login: 381 string_id = IDS_CERT_EKU_MS_SMART_CARD_LOGON; 382 break; 383 case NID_ns_sgc: 384 string_id = IDS_CERT_EKU_NETSCAPE_INTERNATIONAL_STEP_UP; 385 break; 386 case NID_businessCategory: 387 string_id = IDS_CERT_OID_BUSINESS_CATEGORY; 388 break; 389 case NID_undef: 390 string_id = -1; 391 break; 392 393 default: 394 if (nid == ms_cert_ext_certtype) 395 string_id = IDS_CERT_EXT_MS_CERT_TYPE; 396 else if (nid == ms_certsrv_ca_version) 397 string_id = IDS_CERT_EXT_MS_CA_VERSION; 398 else if (nid == ms_ntds_replication) 399 string_id = IDS_CERT_EXT_MS_NTDS_REPLICATION; 400 else if (nid == eku_ms_time_stamping) 401 string_id = IDS_CERT_EKU_MS_TIME_STAMPING; 402 else if (nid == eku_ms_file_recovery) 403 string_id = IDS_CERT_EKU_MS_FILE_RECOVERY; 404 else if (nid == eku_ms_windows_hardware_driver_verification) 405 string_id = IDS_CERT_EKU_MS_WINDOWS_HARDWARE_DRIVER_VERIFICATION; 406 else if (nid == eku_ms_qualified_subordination) 407 string_id = IDS_CERT_EKU_MS_QUALIFIED_SUBORDINATION; 408 else if (nid == eku_ms_key_recovery) 409 string_id = IDS_CERT_EKU_MS_KEY_RECOVERY; 410 else if (nid == eku_ms_document_signing) 411 string_id = IDS_CERT_EKU_MS_DOCUMENT_SIGNING; 412 else if (nid == eku_ms_lifetime_signing) 413 string_id = IDS_CERT_EKU_MS_LIFETIME_SIGNING; 414 else if (nid == eku_ms_key_recovery_agent) 415 string_id = IDS_CERT_EKU_MS_KEY_RECOVERY_AGENT; 416 else if (nid == cert_attribute_ev_incorporation_country) 417 string_id = IDS_CERT_OID_EV_INCORPORATION_COUNTRY; 418 else if (nid == ns_cert_ext_lost_password_url) 419 string_id = IDS_CERT_EXT_NS_LOST_PASSWORD_URL; 420 else if (nid == ns_cert_ext_cert_renewal_time) 421 string_id = IDS_CERT_EXT_NS_CERT_RENEWAL_TIME; 422 else 423 string_id = -1; 424 break; 425 } 426 if (string_id >= 0) 427 return l10n_util::GetStringUTF8(string_id); 428 429 return Asn1ObjectToOIDString(obj); 430 } 431 432 struct MaskIdPair { 433 unsigned int mask; 434 int string_id; 435 }; 436 437 std::string ProcessBitField(ASN1_BIT_STRING* bitfield, 438 const MaskIdPair* string_map, 439 size_t len, 440 char separator) { 441 unsigned int bits = 0; 442 std::string rv; 443 for (size_t i = 0; 444 i < sizeof(bits) && static_cast<int>(i) < ASN1_STRING_length(bitfield); 445 ++i) 446 bits |= ASN1_STRING_data(bitfield)[i] << (i * 8); 447 for (size_t i = 0; i < len; ++i) { 448 if (bits & string_map[i].mask) { 449 if (!rv.empty()) 450 rv += separator; 451 rv += l10n_util::GetStringUTF8(string_map[i].string_id); 452 } 453 } 454 return rv; 455 } 456 457 std::string ProcessNSCertTypeExtension(X509_EXTENSION* ex) { 458 static const MaskIdPair usage_string_map[] = { 459 {NS_SSL_CLIENT, IDS_CERT_USAGE_SSL_CLIENT}, 460 {NS_SSL_SERVER, IDS_CERT_USAGE_SSL_SERVER}, 461 {NS_SMIME, IDS_CERT_EXT_NS_CERT_TYPE_EMAIL}, 462 {NS_OBJSIGN, IDS_CERT_USAGE_OBJECT_SIGNER}, 463 {NS_SSL_CA, IDS_CERT_USAGE_SSL_CA}, 464 {NS_SMIME_CA, IDS_CERT_EXT_NS_CERT_TYPE_EMAIL_CA}, 465 {NS_OBJSIGN_CA, IDS_CERT_USAGE_OBJECT_SIGNER}, 466 }; 467 468 crypto::ScopedOpenSSL<ASN1_BIT_STRING, ASN1_BIT_STRING_free>::Type value( 469 reinterpret_cast<ASN1_BIT_STRING*>(X509V3_EXT_d2i(ex))); 470 if (!value.get()) 471 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 472 return ProcessBitField(value.get(), 473 usage_string_map, 474 ARRAYSIZE_UNSAFE(usage_string_map), 475 '\n'); 476 } 477 478 std::string ProcessKeyUsageExtension(X509_EXTENSION* ex) { 479 static const MaskIdPair key_usage_string_map[] = { 480 {KU_DIGITAL_SIGNATURE, IDS_CERT_X509_KEY_USAGE_SIGNING}, 481 {KU_NON_REPUDIATION, IDS_CERT_X509_KEY_USAGE_NONREP}, 482 {KU_KEY_ENCIPHERMENT, IDS_CERT_X509_KEY_USAGE_ENCIPHERMENT}, 483 {KU_DATA_ENCIPHERMENT, IDS_CERT_X509_KEY_USAGE_DATA_ENCIPHERMENT}, 484 {KU_KEY_AGREEMENT, IDS_CERT_X509_KEY_USAGE_KEY_AGREEMENT}, 485 {KU_KEY_CERT_SIGN, IDS_CERT_X509_KEY_USAGE_CERT_SIGNER}, 486 {KU_CRL_SIGN, IDS_CERT_X509_KEY_USAGE_CRL_SIGNER}, 487 {KU_ENCIPHER_ONLY, IDS_CERT_X509_KEY_USAGE_ENCIPHER_ONLY}, 488 {KU_DECIPHER_ONLY, IDS_CERT_X509_KEY_USAGE_DECIPHER_ONLY}, 489 }; 490 491 crypto::ScopedOpenSSL<ASN1_BIT_STRING, ASN1_BIT_STRING_free>::Type value( 492 reinterpret_cast<ASN1_BIT_STRING*>(X509V3_EXT_d2i(ex))); 493 if (!value.get()) 494 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 495 return ProcessBitField(value.get(), 496 key_usage_string_map, 497 ARRAYSIZE_UNSAFE(key_usage_string_map), 498 '\n'); 499 } 500 501 std::string ProcessBasicConstraints(X509_EXTENSION* ex) { 502 std::string rv; 503 crypto::ScopedOpenSSL<BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free>::Type value( 504 reinterpret_cast<BASIC_CONSTRAINTS*>(X509V3_EXT_d2i(ex))); 505 if (!value.get()) 506 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 507 if (value.get()->ca) 508 rv = l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_CA); 509 else 510 rv = l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_NOT_CA); 511 rv += '\n'; 512 if (value.get()->ca) { 513 base::string16 depth; 514 if (!value.get()->pathlen) { 515 depth = l10n_util::GetStringUTF16( 516 IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN_UNLIMITED); 517 } else { 518 depth = base::FormatNumber(ASN1_INTEGER_get(value.get()->pathlen)); 519 } 520 rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN, 521 depth); 522 } 523 return rv; 524 } 525 526 std::string ProcessExtKeyUsage(X509_EXTENSION* ex) { 527 std::string rv; 528 crypto::ScopedOpenSSL<EXTENDED_KEY_USAGE, EXTENDED_KEY_USAGE_free>::Type 529 value(reinterpret_cast<EXTENDED_KEY_USAGE*>(X509V3_EXT_d2i(ex))); 530 if (!value.get()) 531 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 532 for (size_t i = 0; i < sk_ASN1_OBJECT_num(value.get()); i++) { 533 ASN1_OBJECT* obj = sk_ASN1_OBJECT_value(value.get(), i); 534 std::string oid_dump = Asn1ObjectToOIDString(obj); 535 std::string oid_text = Asn1ObjectToString(obj); 536 537 // If oid is one we recognize, oid_text will have a text description of the 538 // OID, which we display along with the oid_dump. If we don't recognize the 539 // OID, they will be the same, so just display the OID alone. 540 if (oid_dump == oid_text) 541 rv += oid_dump; 542 else 543 rv += l10n_util::GetStringFUTF8(IDS_CERT_EXT_KEY_USAGE_FORMAT, 544 base::UTF8ToUTF16(oid_text), 545 base::UTF8ToUTF16(oid_dump)); 546 rv += '\n'; 547 } 548 return rv; 549 } 550 551 std::string ProcessGeneralName(GENERAL_NAME* name) { 552 std::string key; 553 std::string value; 554 555 switch (name->type) { 556 case GEN_OTHERNAME: { 557 ASN1_OBJECT* oid; 558 ASN1_TYPE* asn1_value; 559 GENERAL_NAME_get0_otherName(name, &oid, &asn1_value); 560 key = Asn1ObjectToString(oid); 561 // g_dynamic_oid_registerer.Get() will have been run by 562 // Asn1ObjectToString. 563 int nid = OBJ_obj2nid(oid); 564 if (nid == IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME) { 565 // The type of this name is apparently nowhere explicitly 566 // documented. However, in the generated templates, it is always 567 // UTF-8. So try to decode this as UTF-8; if that fails, dump the 568 // raw data. 569 if (asn1_value->type == V_ASN1_UTF8STRING) { 570 value = std::string(reinterpret_cast<char*>(ASN1_STRING_data( 571 asn1_value->value.utf8string)), 572 ASN1_STRING_length(asn1_value->value.utf8string)); 573 } else { 574 value = ProcessRawAsn1Type(asn1_value); 575 } 576 } else if (nid == ms_ntds_replication) { 577 // This should be a 16-byte GUID. 578 if (asn1_value->type == V_ASN1_OCTET_STRING && 579 asn1_value->value.octet_string->length == 16) { 580 unsigned char* d = asn1_value->value.octet_string->data; 581 base::SStringPrintf( 582 &value, 583 "{%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-" 584 "%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}", 585 d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6], 586 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 587 } else { 588 value = ProcessRawAsn1Type(asn1_value); 589 } 590 } else { 591 value = ProcessRawAsn1Type(asn1_value); 592 } 593 break; 594 } 595 case GEN_EMAIL: 596 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_RFC822_NAME); 597 value = std::string( 598 reinterpret_cast<char*>(ASN1_STRING_data(name->d.rfc822Name)), 599 ASN1_STRING_length(name->d.rfc822Name)); 600 break; 601 case GEN_DNS: 602 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DNS_NAME); 603 value = std::string( 604 reinterpret_cast<char*>(ASN1_STRING_data(name->d.dNSName)), 605 ASN1_STRING_length(name->d.dNSName)); 606 value = ProcessIDN(value); 607 break; 608 case GEN_X400: 609 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_X400_ADDRESS); 610 value = ProcessRawAsn1Type(name->d.x400Address); 611 break; 612 case GEN_DIRNAME: 613 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DIRECTORY_NAME); 614 value = GetKeyValuesFromName(name->d.directoryName); 615 break; 616 case GEN_EDIPARTY: 617 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_EDI_PARTY_NAME); 618 if (name->d.ediPartyName->nameAssigner && 619 ASN1_STRING_length(name->d.ediPartyName->nameAssigner) > 0) { 620 value += l10n_util::GetStringFUTF8( 621 IDS_CERT_EDI_NAME_ASSIGNER, 622 base::UTF8ToUTF16( 623 Asn1StringToUTF8(name->d.ediPartyName->nameAssigner))); 624 value += "\n"; 625 } 626 if (name->d.ediPartyName->partyName && 627 ASN1_STRING_length(name->d.ediPartyName->partyName) > 0) { 628 value += l10n_util::GetStringFUTF8( 629 IDS_CERT_EDI_PARTY_NAME, 630 base::UTF8ToUTF16( 631 Asn1StringToUTF8(name->d.ediPartyName->partyName))); 632 value += "\n"; 633 } 634 break; 635 case GEN_URI: 636 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_URI); 637 value = 638 std::string(reinterpret_cast<char*>( 639 ASN1_STRING_data(name->d.uniformResourceIdentifier)), 640 ASN1_STRING_length(name->d.uniformResourceIdentifier)); 641 break; 642 case GEN_IPADD: { 643 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_IP_ADDRESS); 644 net::IPAddressNumber ip(ASN1_STRING_data(name->d.iPAddress), 645 ASN1_STRING_data(name->d.iPAddress) + 646 ASN1_STRING_length(name->d.iPAddress)); 647 if (net::GetAddressFamily(ip) != net::ADDRESS_FAMILY_UNSPECIFIED) { 648 value = net::IPAddressToString(ip); 649 } else { 650 // Invalid IP address. 651 value = ProcessRawBytes(ip.data(), ip.size()); 652 } 653 break; 654 } 655 case GEN_RID: 656 key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_REGISTERED_ID); 657 value = Asn1ObjectToString(name->d.registeredID); 658 break; 659 } 660 std::string rv(l10n_util::GetStringFUTF8(IDS_CERT_UNKNOWN_OID_INFO_FORMAT, 661 base::UTF8ToUTF16(key), 662 base::UTF8ToUTF16(value))); 663 rv += '\n'; 664 return rv; 665 } 666 667 std::string ProcessGeneralNames(GENERAL_NAMES* names) { 668 std::string rv; 669 for (size_t i = 0; i < sk_GENERAL_NAME_num(names); ++i) { 670 GENERAL_NAME* name = sk_GENERAL_NAME_value(names, i); 671 rv += ProcessGeneralName(name); 672 } 673 return rv; 674 } 675 676 std::string ProcessAltName(X509_EXTENSION* ex) { 677 crypto::ScopedOpenSSL<GENERAL_NAMES, GENERAL_NAMES_free>::Type alt_names( 678 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(ex))); 679 if (!alt_names.get()) 680 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 681 682 return ProcessGeneralNames(alt_names.get()); 683 } 684 685 std::string ProcessSubjectKeyId(X509_EXTENSION* ex) { 686 crypto::ScopedOpenSSL<ASN1_OCTET_STRING, ASN1_OCTET_STRING_free>::Type value( 687 reinterpret_cast<ASN1_OCTET_STRING*>(X509V3_EXT_d2i(ex))); 688 if (!value.get()) 689 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 690 691 return l10n_util::GetStringFUTF8( 692 IDS_CERT_KEYID_FORMAT, 693 base::ASCIIToUTF16(ProcessRawAsn1String(value.get()))); 694 } 695 696 std::string ProcessAuthKeyId(X509_EXTENSION* ex) { 697 std::string rv; 698 crypto::ScopedOpenSSL<AUTHORITY_KEYID, AUTHORITY_KEYID_free>::Type value( 699 reinterpret_cast<AUTHORITY_KEYID*>(X509V3_EXT_d2i(ex))); 700 if (!value.get()) 701 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 702 703 if (value.get()->keyid && ASN1_STRING_length(value.get()->keyid) > 0) { 704 rv += l10n_util::GetStringFUTF8( 705 IDS_CERT_KEYID_FORMAT, 706 base::ASCIIToUTF16(ProcessRawAsn1String(value.get()->keyid))); 707 rv += '\n'; 708 } 709 710 if (value.get()->issuer) { 711 rv += l10n_util::GetStringFUTF8( 712 IDS_CERT_ISSUER_FORMAT, 713 base::UTF8ToUTF16(ProcessGeneralNames(value.get()->issuer))); 714 rv += '\n'; 715 } 716 717 if (value.get()->serial) { 718 rv += l10n_util::GetStringFUTF8( 719 IDS_CERT_SERIAL_NUMBER_FORMAT, 720 base::ASCIIToUTF16(ProcessRawAsn1String(value.get()->serial))); 721 rv += '\n'; 722 } 723 724 return rv; 725 } 726 727 std::string ProcessUserNotice(USERNOTICE* notice) { 728 std::string rv; 729 if (notice->noticeref) { 730 rv += Asn1StringToUTF8(notice->noticeref->organization); 731 rv += " - "; 732 for (size_t i = 0; i < sk_ASN1_INTEGER_num(notice->noticeref->noticenos); 733 ++i) { 734 ASN1_INTEGER* info = 735 sk_ASN1_INTEGER_value(notice->noticeref->noticenos, i); 736 long number = ASN1_INTEGER_get(info); 737 if (number != -1) { 738 if (i != sk_ASN1_INTEGER_num(notice->noticeref->noticenos) - 1) 739 rv += ", "; 740 rv += '#'; 741 rv += base::IntToString(number); 742 } 743 } 744 } 745 if (notice->exptext && notice->exptext->length != 0) { 746 rv += "\n "; 747 rv += Asn1StringToUTF8(notice->exptext); 748 } 749 return rv; 750 } 751 752 std::string ProcessCertificatePolicies(X509_EXTENSION* ex) { 753 std::string rv; 754 crypto::ScopedOpenSSL<CERTIFICATEPOLICIES, CERTIFICATEPOLICIES_free>::Type 755 policies(reinterpret_cast<CERTIFICATEPOLICIES*>(X509V3_EXT_d2i(ex))); 756 757 if (!policies.get()) 758 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 759 760 for (size_t i = 0; i < sk_POLICYINFO_num(policies.get()); ++i) { 761 POLICYINFO* info = sk_POLICYINFO_value(policies.get(), i); 762 std::string key = Asn1ObjectToString(info->policyid); 763 // If we have policy qualifiers, display the oid text 764 // with a ':', otherwise just put the oid text and a newline. 765 if (info->qualifiers && sk_POLICYQUALINFO_num(info->qualifiers)) { 766 rv += l10n_util::GetStringFUTF8(IDS_CERT_MULTILINE_INFO_START_FORMAT, 767 base::UTF8ToUTF16(key)); 768 } else { 769 rv += key; 770 } 771 rv += '\n'; 772 773 if (info->qualifiers && sk_POLICYQUALINFO_num(info->qualifiers)) { 774 // Add all qualifiers on separate lines, indented. 775 for (size_t i = 0; i < sk_POLICYQUALINFO_num(info->qualifiers); ++i) { 776 POLICYQUALINFO* qualifier = 777 sk_POLICYQUALINFO_value(info->qualifiers, i); 778 rv += " "; 779 rv += l10n_util::GetStringFUTF8( 780 IDS_CERT_MULTILINE_INFO_START_FORMAT, 781 base::UTF8ToUTF16(Asn1ObjectToString(qualifier->pqualid))); 782 int nid = OBJ_obj2nid(qualifier->pqualid); 783 switch (nid) { 784 case NID_id_qt_cps: 785 rv += " "; 786 rv += std::string( 787 reinterpret_cast<char*>(ASN1_STRING_data(qualifier->d.cpsuri)), 788 ASN1_STRING_length(qualifier->d.cpsuri)); 789 break; 790 case NID_id_qt_unotice: 791 rv += ProcessUserNotice(qualifier->d.usernotice); 792 break; 793 default: 794 rv += ProcessRawAsn1Type(qualifier->d.other); 795 break; 796 } 797 rv += '\n'; 798 } 799 } 800 } 801 return rv; 802 } 803 804 std::string ProcessCrlDistPoints(X509_EXTENSION* ex) { 805 static const MaskIdPair reason_string_map[] = { 806 // OpenSSL doesn't define contants for these. (The CRL_REASON_ defines in 807 // x509v3.h are for the "X509v3 CRL Reason Code" extension.) 808 // These are from RFC5280 section 4.2.1.13. 809 {0, IDS_CERT_REVOCATION_REASON_UNUSED}, 810 {1, IDS_CERT_REVOCATION_REASON_KEY_COMPROMISE}, 811 {2, IDS_CERT_REVOCATION_REASON_CA_COMPROMISE}, 812 {3, IDS_CERT_REVOCATION_REASON_AFFILIATION_CHANGED}, 813 {4, IDS_CERT_REVOCATION_REASON_SUPERSEDED}, 814 {5, IDS_CERT_REVOCATION_REASON_CESSATION_OF_OPERATION}, 815 {6, IDS_CERT_REVOCATION_REASON_CERTIFICATE_HOLD}, 816 {7, IDS_CERT_REVOCATION_REASON_PRIVILEGE_WITHDRAWN}, 817 {8, IDS_CERT_REVOCATION_REASON_AA_COMPROMISE}, 818 }; 819 // OpenSSL doesn't define constants for the DIST_POINT type field. These 820 // values are from reading openssl/crypto/x509v3/v3_crld.c 821 const int kDistPointFullName = 0; 822 const int kDistPointRelativeName = 1; 823 824 std::string rv; 825 crypto::ScopedOpenSSL<CRL_DIST_POINTS, CRL_DIST_POINTS_free>::Type 826 dist_points(reinterpret_cast<CRL_DIST_POINTS*>(X509V3_EXT_d2i(ex))); 827 828 if (!dist_points.get()) 829 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 830 831 for (size_t i = 0; i < sk_DIST_POINT_num(dist_points.get()); ++i) { 832 DIST_POINT* point = sk_DIST_POINT_value(dist_points.get(), i); 833 if (point->distpoint) { 834 switch (point->distpoint->type) { 835 case kDistPointFullName: 836 rv += ProcessGeneralNames(point->distpoint->name.fullname); 837 break; 838 case kDistPointRelativeName: 839 rv += 840 GetKeyValuesFromNameEntries(point->distpoint->name.relativename); 841 // TODO(mattm): should something be done with 842 // point->distpoint->dpname? 843 break; 844 } 845 } 846 if (point->reasons) { 847 rv += ' '; 848 rv += ProcessBitField(point->reasons, 849 reason_string_map, 850 ARRAYSIZE_UNSAFE(reason_string_map), 851 ','); 852 rv += '\n'; 853 } 854 if (point->CRLissuer) { 855 rv += l10n_util::GetStringFUTF8( 856 IDS_CERT_ISSUER_FORMAT, 857 base::UTF8ToUTF16(ProcessGeneralNames(point->CRLissuer))); 858 } 859 } 860 861 return rv; 862 } 863 864 std::string ProcessAuthInfoAccess(X509_EXTENSION* ex) { 865 std::string rv; 866 crypto::ScopedOpenSSL<AUTHORITY_INFO_ACCESS, AUTHORITY_INFO_ACCESS_free>::Type 867 aia(reinterpret_cast<AUTHORITY_INFO_ACCESS*>(X509V3_EXT_d2i(ex))); 868 869 if (!aia.get()) 870 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 871 872 for (size_t i = 0; i < sk_ACCESS_DESCRIPTION_num(aia.get()); ++i) { 873 ACCESS_DESCRIPTION* desc = sk_ACCESS_DESCRIPTION_value(aia.get(), i); 874 875 base::string16 location_str = 876 base::UTF8ToUTF16(ProcessGeneralName(desc->location)); 877 switch (OBJ_obj2nid(desc->method)) { 878 case NID_ad_OCSP: 879 rv += l10n_util::GetStringFUTF8(IDS_CERT_OCSP_RESPONDER_FORMAT, 880 location_str); 881 break; 882 case NID_ad_ca_issuers: 883 rv += 884 l10n_util::GetStringFUTF8(IDS_CERT_CA_ISSUERS_FORMAT, location_str); 885 break; 886 default: 887 rv += l10n_util::GetStringFUTF8( 888 IDS_CERT_UNKNOWN_OID_INFO_FORMAT, 889 base::UTF8ToUTF16(Asn1ObjectToString(desc->method)), 890 location_str); 891 break; 892 } 893 } 894 return rv; 895 } 896 897 std::string ProcessIA5StringData(ASN1_OCTET_STRING* asn1_string) { 898 const unsigned char* data = ASN1_STRING_data(asn1_string); 899 crypto::ScopedOpenSSL<ASN1_IA5STRING, ASN1_IA5STRING_free>::Type ia5_string( 900 d2i_ASN1_IA5STRING(NULL, &data, ASN1_STRING_length(asn1_string))); 901 902 if (!ia5_string.get()) 903 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 904 905 return std::string( 906 reinterpret_cast<char*>(ASN1_STRING_data(ia5_string.get())), 907 ASN1_STRING_length(ia5_string.get())); 908 } 909 910 std::string ProcessBMPStringData(ASN1_OCTET_STRING* asn1_string) { 911 const unsigned char* data = ASN1_STRING_data(asn1_string); 912 crypto::ScopedOpenSSL<ASN1_BMPSTRING, ASN1_BMPSTRING_free>::Type bmp_string( 913 d2i_ASN1_BMPSTRING(NULL, &data, ASN1_STRING_length(asn1_string))); 914 915 if (!bmp_string.get()) 916 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); 917 918 return Asn1StringToUTF8(bmp_string.get()); 919 } 920 921 std::string X509ExtensionValueToString(X509_EXTENSION* ex) { 922 g_dynamic_oid_registerer.Get(); 923 int nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); 924 switch (nid) { 925 case NID_netscape_cert_type: 926 return ProcessNSCertTypeExtension(ex); 927 case NID_key_usage: 928 return ProcessKeyUsageExtension(ex); 929 case NID_basic_constraints: 930 return ProcessBasicConstraints(ex); 931 case NID_ext_key_usage: 932 return ProcessExtKeyUsage(ex); 933 case NID_issuer_alt_name: 934 case NID_subject_alt_name: 935 return ProcessAltName(ex); 936 case NID_subject_key_identifier: 937 return ProcessSubjectKeyId(ex); 938 case NID_authority_key_identifier: 939 return ProcessAuthKeyId(ex); 940 case NID_certificate_policies: 941 return ProcessCertificatePolicies(ex); 942 case NID_crl_distribution_points: 943 return ProcessCrlDistPoints(ex); 944 case NID_info_access: 945 return ProcessAuthInfoAccess(ex); 946 case NID_netscape_base_url: 947 case NID_netscape_revocation_url: 948 case NID_netscape_ca_revocation_url: 949 case NID_netscape_renewal_url: 950 case NID_netscape_ca_policy_url: 951 case NID_netscape_comment: 952 case NID_netscape_ssl_server_name: 953 return ProcessIA5StringData(X509_EXTENSION_get_data(ex)); 954 default: 955 if (nid == ns_cert_ext_ca_cert_url || 956 nid == ns_cert_ext_homepage_url || 957 nid == ns_cert_ext_lost_password_url) 958 return ProcessIA5StringData(X509_EXTENSION_get_data(ex)); 959 if (nid == ms_cert_ext_certtype) 960 return ProcessBMPStringData(X509_EXTENSION_get_data(ex)); 961 return ProcessRawAsn1String(X509_EXTENSION_get_data(ex)); 962 } 963 } 964 965 } // namespace 966 967 using net::X509Certificate; 968 969 std::string GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle) { 970 std::string name = 971 ProcessIDN(GetSubjectCommonName(cert_handle, std::string())); 972 if (!name.empty()) 973 return name; 974 975 crypto::ScopedBIO bio(crypto::BIO_new_string(&name)); 976 if (!bio.get()) 977 return name; 978 X509_NAME_print_ex(bio.get(), 979 X509_get_subject_name(cert_handle), 980 0 /* indent */, 981 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB); 982 return name; 983 } 984 985 std::string GetTokenName(X509Certificate::OSCertHandle cert_handle) { 986 // TODO(bulach): implement me. 987 return ""; 988 } 989 990 std::string GetVersion(net::X509Certificate::OSCertHandle cert_handle) { 991 unsigned long version = X509_get_version(cert_handle); 992 if (version != ULONG_MAX) 993 return base::UintToString(version + 1); 994 return ""; 995 } 996 997 net::CertType GetType(X509Certificate::OSCertHandle os_cert) { 998 // TODO(bulach): implement me. 999 return net::OTHER_CERT; 1000 } 1001 1002 void GetUsageStrings(X509Certificate::OSCertHandle cert_handle, 1003 std::vector<std::string>* usages) { 1004 // TODO(bulach): implement me. 1005 } 1006 1007 std::string GetSerialNumberHexified( 1008 X509Certificate::OSCertHandle cert_handle, 1009 const std::string& alternative_text) { 1010 ASN1_INTEGER* num = X509_get_serialNumber(cert_handle); 1011 const char kSerialNumberSeparator = ':'; 1012 std::string hex_string = ProcessRawBytesWithSeparators( 1013 num->data, num->length, kSerialNumberSeparator, kSerialNumberSeparator); 1014 return AlternativeWhenEmpty(hex_string, alternative_text); 1015 } 1016 1017 std::string GetIssuerCommonName( 1018 X509Certificate::OSCertHandle cert_handle, 1019 const std::string& alternative_text) { 1020 std::string ret; 1021 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle), 1022 NID_commonName, &ret); 1023 return AlternativeWhenEmpty(ret, alternative_text); 1024 } 1025 1026 std::string GetIssuerOrgName( 1027 X509Certificate::OSCertHandle cert_handle, 1028 const std::string& alternative_text) { 1029 std::string ret; 1030 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle), 1031 NID_organizationName, &ret); 1032 return AlternativeWhenEmpty(ret, alternative_text); 1033 } 1034 1035 std::string GetIssuerOrgUnitName( 1036 X509Certificate::OSCertHandle cert_handle, 1037 const std::string& alternative_text) { 1038 std::string ret; 1039 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle), 1040 NID_organizationalUnitName, &ret); 1041 return AlternativeWhenEmpty(ret, alternative_text); 1042 } 1043 1044 std::string GetSubjectOrgName( 1045 X509Certificate::OSCertHandle cert_handle, 1046 const std::string& alternative_text) { 1047 std::string ret; 1048 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle), 1049 NID_organizationName, &ret); 1050 return AlternativeWhenEmpty(ret, alternative_text); 1051 } 1052 1053 std::string GetSubjectOrgUnitName( 1054 X509Certificate::OSCertHandle cert_handle, 1055 const std::string& alternative_text) { 1056 std::string ret; 1057 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle), 1058 NID_organizationalUnitName, &ret); 1059 return AlternativeWhenEmpty(ret, alternative_text); 1060 } 1061 1062 std::string GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle, 1063 const std::string& alternative_text) { 1064 std::string ret; 1065 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle), 1066 NID_commonName, &ret); 1067 return AlternativeWhenEmpty(ret, alternative_text); 1068 } 1069 1070 bool GetTimes(X509Certificate::OSCertHandle cert_handle, 1071 base::Time* issued, base::Time* expires) { 1072 return x509_util::ParseDate(X509_get_notBefore(cert_handle), issued) && 1073 x509_util::ParseDate(X509_get_notAfter(cert_handle), expires); 1074 } 1075 1076 std::string GetTitle(net::X509Certificate::OSCertHandle cert_handle) { 1077 // TODO(mattm): merge GetTitle and GetCertNameOrNickname? 1078 // Is there any reason GetCertNameOrNickname calls ProcessIDN and this 1079 // doesn't? 1080 std::string title = 1081 GetSubjectCommonName(cert_handle, std::string()); 1082 if (!title.empty()) 1083 return title; 1084 1085 crypto::ScopedBIO bio(crypto::BIO_new_string(&title)); 1086 if (!bio.get()) 1087 return title; 1088 X509_NAME_print_ex(bio.get(), 1089 X509_get_subject_name(cert_handle), 1090 0 /* indent */, 1091 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB); 1092 return title; 1093 } 1094 1095 std::string GetIssuerName(net::X509Certificate::OSCertHandle cert_handle) { 1096 return GetKeyValuesFromName(X509_get_issuer_name(cert_handle)); 1097 } 1098 1099 std::string GetSubjectName(net::X509Certificate::OSCertHandle cert_handle) { 1100 return GetKeyValuesFromName(X509_get_subject_name(cert_handle)); 1101 } 1102 1103 void GetExtensions( 1104 const std::string& critical_label, 1105 const std::string& non_critical_label, 1106 net::X509Certificate::OSCertHandle cert_handle, 1107 Extensions* extensions) { 1108 for (int i = 0; i < X509_get_ext_count(cert_handle); ++i) { 1109 X509_EXTENSION* ex = X509_get_ext(cert_handle, i); 1110 ASN1_OBJECT* obj = X509_EXTENSION_get_object(ex); 1111 1112 Extension extension; 1113 extension.name = Asn1ObjectToString(obj); 1114 extension.value = (X509_EXTENSION_get_critical(ex) ? critical_label 1115 : non_critical_label) + 1116 "\n" + X509ExtensionValueToString(ex); 1117 extensions->push_back(extension); 1118 } 1119 } 1120 1121 std::string HashCertSHA256(net::X509Certificate::OSCertHandle cert_handle) { 1122 unsigned char sha256_data[SHA256_DIGEST_LENGTH] = {0}; 1123 unsigned int sha256_size = sizeof(sha256_data); 1124 int ret = X509_digest(cert_handle, EVP_sha256(), sha256_data, &sha256_size); 1125 DCHECK(ret); 1126 DCHECK_EQ(sha256_size, sizeof(sha256_data)); 1127 return ProcessRawBytes(sha256_data, sha256_size); 1128 } 1129 1130 std::string HashCertSHA1(net::X509Certificate::OSCertHandle cert_handle) { 1131 unsigned char sha1_data[SHA_DIGEST_LENGTH] = {0}; 1132 unsigned int sha1_size = sizeof(sha1_data); 1133 int ret = X509_digest(cert_handle, EVP_sha1(), sha1_data, &sha1_size); 1134 DCHECK(ret); 1135 DCHECK_EQ(sha1_size, sizeof(sha1_data)); 1136 return ProcessRawBytes(sha1_data, sha1_size); 1137 } 1138 1139 std::string GetCMSString(const net::X509Certificate::OSCertHandles& cert_chain, 1140 size_t start, size_t end) { 1141 STACK_OF(X509)* certs = sk_X509_new_null(); 1142 1143 for (size_t i = start; i < end; ++i) { 1144 sk_X509_push(certs, cert_chain[i]); 1145 } 1146 1147 CBB pkcs7; 1148 CBB_init(&pkcs7, 1024 * sk_X509_num(certs)); 1149 1150 uint8_t *pkcs7_data; 1151 size_t pkcs7_len; 1152 if (!PKCS7_bundle_certificates(&pkcs7, certs) || 1153 !CBB_finish(&pkcs7, &pkcs7_data, &pkcs7_len)) { 1154 CBB_cleanup(&pkcs7); 1155 sk_X509_free(certs); 1156 return ""; 1157 } 1158 1159 std::string ret(reinterpret_cast<char*>(pkcs7_data), pkcs7_len); 1160 OPENSSL_free(pkcs7_data); 1161 sk_X509_free(certs); 1162 1163 return ret; 1164 } 1165 1166 std::string ProcessSecAlgorithmSignature( 1167 net::X509Certificate::OSCertHandle cert_handle) { 1168 return Asn1ObjectToString(cert_handle->cert_info->signature->algorithm); 1169 } 1170 1171 std::string ProcessSecAlgorithmSubjectPublicKey( 1172 net::X509Certificate::OSCertHandle cert_handle) { 1173 return Asn1ObjectToString( 1174 X509_get_X509_PUBKEY(cert_handle)->algor->algorithm); 1175 } 1176 1177 std::string ProcessSecAlgorithmSignatureWrap( 1178 net::X509Certificate::OSCertHandle cert_handle) { 1179 return Asn1ObjectToString(cert_handle->sig_alg->algorithm); 1180 } 1181 1182 std::string ProcessSubjectPublicKeyInfo( 1183 net::X509Certificate::OSCertHandle cert_handle) { 1184 std::string rv; 1185 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free>::Type public_key( 1186 X509_get_pubkey(cert_handle)); 1187 if (!public_key.get()) 1188 return rv; 1189 switch (EVP_PKEY_type(public_key.get()->type)) { 1190 case EVP_PKEY_RSA: { 1191 crypto::ScopedOpenSSL<RSA, RSA_free>::Type rsa_key( 1192 EVP_PKEY_get1_RSA(public_key.get())); 1193 if (!rsa_key.get()) 1194 return rv; 1195 rv = l10n_util::GetStringFUTF8( 1196 IDS_CERT_RSA_PUBLIC_KEY_DUMP_FORMAT, 1197 base::UintToString16(BN_num_bits(rsa_key.get()->n)), 1198 base::UTF8ToUTF16(ProcessRawBignum(rsa_key.get()->n)), 1199 base::UintToString16(BN_num_bits(rsa_key.get()->e)), 1200 base::UTF8ToUTF16(ProcessRawBignum(rsa_key.get()->e))); 1201 return rv; 1202 } 1203 default: 1204 rv = ProcessRawAsn1String(X509_get_X509_PUBKEY(cert_handle)->public_key); 1205 return rv; 1206 } 1207 } 1208 1209 std::string ProcessRawBitsSignatureWrap( 1210 net::X509Certificate::OSCertHandle cert_handle) { 1211 return ProcessRawAsn1String(cert_handle->signature); 1212 } 1213 1214 } // namespace x509_certificate_model 1215