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.
5 #include "chrome/common/net/x509_certificate_model.h"
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>
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"
27 namespace x509_util
= net::x509_util
;
29 namespace x509_certificate_model
{
33 std::string
ProcessRawAsn1String(ASN1_STRING
* data
) {
34 return ProcessRawBytes(ASN1_STRING_data(data
), ASN1_STRING_length(data
));
37 std::string
ProcessRawAsn1Type(ASN1_TYPE
* data
) {
38 int len
= i2d_ASN1_TYPE(data
, NULL
);
42 scoped_ptr
<unsigned char[]> buf(new unsigned char[len
]);
43 unsigned char* bufp
= buf
.get();
45 len
= i2d_ASN1_TYPE(data
, &bufp
);
47 return ProcessRawBytes(buf
.get(), len
);
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
);
57 std::string
Asn1StringToUTF8(ASN1_STRING
* asn1_string
) {
59 unsigned char* buf
= NULL
;
60 int len
= ASN1_STRING_to_UTF8(&buf
, asn1_string
);
63 rv
= std::string(reinterpret_cast<const char*>(buf
), len
);
68 std::string
AlternativeWhenEmpty(const std::string
& text
,
69 const std::string
& alternative
) {
70 return text
.empty() ? alternative
: text
;
73 std::string
GetKeyValuesFromNameEntry(X509_NAME_ENTRY
* entry
) {
77 if (!x509_util::ParsePrincipalKeyAndValue(entry
, &key
, &value
))
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());
85 std::string
GetKeyValuesFromNameEntries(STACK_OF(X509_NAME_ENTRY
)* entries
) {
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
);
92 base::StringAppendF(&ret
, "%s\n", GetKeyValuesFromNameEntry(entry
).c_str());
97 std::string
GetKeyValuesFromName(X509_NAME
* name
) {
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
);
104 base::StringAppendF(&ret
, "%s\n", GetKeyValuesFromNameEntry(entry
).c_str());
109 std::string
Asn1ObjectToOIDString(ASN1_OBJECT
* obj
) {
112 int buflen
= OBJ_obj2txt(buf
, sizeof(buf
), obj
, 1 /* no_name */);
118 if (static_cast<size_t>(buflen
) < sizeof(buf
)) {
119 s
.append(buf
, buflen
);
123 size_t prefix_len
= s
.size();
124 s
.resize(prefix_len
+ buflen
+ 1, ' ');
126 OBJ_obj2txt(&s
[prefix_len
], s
.size() - prefix_len
, obj
, 1 /* no_name */);
131 s
.resize(prefix_len
+ buflen
);
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;
152 int RegisterDynamicOid(const char* oid_string
, const char* short_name
) {
153 int nid
= OBJ_txt2nid(oid_string
);
155 DVLOG(1) << "found already existing nid " << nid
<< " for " << oid_string
;
158 return OBJ_create(oid_string
, short_name
, short_name
);
161 class DynamicOidRegisterer
{
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");
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");
189 cert_attribute_ev_incorporation_country
= RegisterDynamicOid(
190 "1.3.6.1.4.1.311.60.2.1.3", "cert_attribute_ev_incorporation_country");
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");
203 static base::LazyInstance
<DynamicOidRegisterer
>::Leaky
204 g_dynamic_oid_registerer
= LAZY_INSTANCE_INITIALIZER
;
206 std::string
Asn1ObjectToString(ASN1_OBJECT
* obj
) {
207 g_dynamic_oid_registerer
.Get();
210 int nid
= OBJ_obj2nid(obj
);
213 string_id
= IDS_CERT_OID_AVA_COMMON_NAME
;
215 case NID_stateOrProvinceName
:
216 string_id
= IDS_CERT_OID_AVA_STATE_OR_PROVINCE
;
218 case NID_organizationName
:
219 string_id
= IDS_CERT_OID_AVA_ORGANIZATION_NAME
;
221 case NID_organizationalUnitName
:
222 string_id
= IDS_CERT_OID_AVA_ORGANIZATIONAL_UNIT_NAME
;
224 case NID_dnQualifier
:
225 string_id
= IDS_CERT_OID_AVA_DN_QUALIFIER
;
227 case NID_countryName
:
228 string_id
= IDS_CERT_OID_AVA_COUNTRY_NAME
;
230 case NID_serialNumber
:
231 string_id
= IDS_CERT_OID_AVA_SERIAL_NUMBER
;
233 case NID_localityName
:
234 string_id
= IDS_CERT_OID_AVA_LOCALITY
;
236 case NID_domainComponent
:
237 string_id
= IDS_CERT_OID_AVA_DC
;
239 case NID_rfc822Mailbox
:
240 string_id
= IDS_CERT_OID_RFC1274_MAIL
;
243 string_id
= IDS_CERT_OID_RFC1274_UID
;
245 case NID_pkcs9_emailAddress
:
246 string_id
= IDS_CERT_OID_PKCS9_EMAIL_ADDRESS
;
248 case NID_rsaEncryption
:
249 string_id
= IDS_CERT_OID_PKCS1_RSA_ENCRYPTION
;
251 case NID_md2WithRSAEncryption
:
252 string_id
= IDS_CERT_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION
;
254 case NID_md4WithRSAEncryption
:
255 string_id
= IDS_CERT_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION
;
257 case NID_md5WithRSAEncryption
:
258 string_id
= IDS_CERT_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION
;
260 case NID_sha1WithRSAEncryption
:
261 string_id
= IDS_CERT_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
;
263 case NID_sha256WithRSAEncryption
:
264 string_id
= IDS_CERT_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
;
266 case NID_sha384WithRSAEncryption
:
267 string_id
= IDS_CERT_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION
;
269 case NID_sha512WithRSAEncryption
:
270 string_id
= IDS_CERT_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION
;
272 case NID_netscape_cert_type
:
273 string_id
= IDS_CERT_EXT_NS_CERT_TYPE
;
275 case NID_netscape_base_url
:
276 string_id
= IDS_CERT_EXT_NS_CERT_BASE_URL
;
278 case NID_netscape_revocation_url
:
279 string_id
= IDS_CERT_EXT_NS_CERT_REVOCATION_URL
;
281 case NID_netscape_ca_revocation_url
:
282 string_id
= IDS_CERT_EXT_NS_CA_REVOCATION_URL
;
284 case NID_netscape_renewal_url
:
285 string_id
= IDS_CERT_EXT_NS_CERT_RENEWAL_URL
;
287 case NID_netscape_ca_policy_url
:
288 string_id
= IDS_CERT_EXT_NS_CA_POLICY_URL
;
290 case NID_netscape_ssl_server_name
:
291 string_id
= IDS_CERT_EXT_NS_SSL_SERVER_NAME
;
293 case NID_netscape_comment
:
294 string_id
= IDS_CERT_EXT_NS_COMMENT
;
296 case NID_subject_directory_attributes
:
297 string_id
= IDS_CERT_X509_SUBJECT_DIRECTORY_ATTR
;
299 case NID_subject_key_identifier
:
300 string_id
= IDS_CERT_X509_SUBJECT_KEYID
;
303 string_id
= IDS_CERT_X509_KEY_USAGE
;
305 case NID_subject_alt_name
:
306 string_id
= IDS_CERT_X509_SUBJECT_ALT_NAME
;
308 case NID_issuer_alt_name
:
309 string_id
= IDS_CERT_X509_ISSUER_ALT_NAME
;
311 case NID_basic_constraints
:
312 string_id
= IDS_CERT_X509_BASIC_CONSTRAINTS
;
314 case NID_name_constraints
:
315 string_id
= IDS_CERT_X509_NAME_CONSTRAINTS
;
317 case NID_crl_distribution_points
:
318 string_id
= IDS_CERT_X509_CRL_DIST_POINTS
;
320 case NID_certificate_policies
:
321 string_id
= IDS_CERT_X509_CERT_POLICIES
;
323 case NID_policy_mappings
:
324 string_id
= IDS_CERT_X509_POLICY_MAPPINGS
;
326 case NID_policy_constraints
:
327 string_id
= IDS_CERT_X509_POLICY_CONSTRAINTS
;
329 case NID_authority_key_identifier
:
330 string_id
= IDS_CERT_X509_AUTH_KEYID
;
332 case NID_ext_key_usage
:
333 string_id
= IDS_CERT_X509_EXT_KEY_USAGE
;
335 case NID_info_access
:
336 string_id
= IDS_CERT_X509_AUTH_INFO_ACCESS
;
338 case NID_server_auth
:
339 string_id
= IDS_CERT_EKU_TLS_WEB_SERVER_AUTHENTICATION
;
341 case NID_client_auth
:
342 string_id
= IDS_CERT_EKU_TLS_WEB_CLIENT_AUTHENTICATION
;
345 string_id
= IDS_CERT_EKU_CODE_SIGNING
;
347 case NID_email_protect
:
348 string_id
= IDS_CERT_EKU_EMAIL_PROTECTION
;
351 string_id
= IDS_CERT_EKU_TIME_STAMPING
;
354 string_id
= IDS_CERT_EKU_OCSP_SIGNING
;
357 string_id
= IDS_CERT_PKIX_CPS_POINTER_QUALIFIER
;
359 case NID_id_qt_unotice
:
360 string_id
= IDS_CERT_PKIX_USER_NOTICE_QUALIFIER
;
363 string_id
= IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME
;
365 case NID_ms_code_ind
:
366 string_id
= IDS_CERT_EKU_MS_INDIVIDUAL_CODE_SIGNING
;
368 case NID_ms_code_com
:
369 string_id
= IDS_CERT_EKU_MS_COMMERCIAL_CODE_SIGNING
;
371 case NID_ms_ctl_sign
:
372 string_id
= IDS_CERT_EKU_MS_TRUST_LIST_SIGNING
;
375 string_id
= IDS_CERT_EKU_MS_SERVER_GATED_CRYPTO
;
378 string_id
= IDS_CERT_EKU_MS_ENCRYPTING_FILE_SYSTEM
;
380 case NID_ms_smartcard_login
:
381 string_id
= IDS_CERT_EKU_MS_SMART_CARD_LOGON
;
384 string_id
= IDS_CERT_EKU_NETSCAPE_INTERNATIONAL_STEP_UP
;
386 case NID_businessCategory
:
387 string_id
= IDS_CERT_OID_BUSINESS_CATEGORY
;
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
;
427 return l10n_util::GetStringUTF8(string_id
);
429 return Asn1ObjectToOIDString(obj
);
437 std::string
ProcessBitField(ASN1_BIT_STRING
* bitfield
,
438 const MaskIdPair
* string_map
,
441 unsigned int bits
= 0;
444 i
< sizeof(bits
) && static_cast<int>(i
) < ASN1_STRING_length(bitfield
);
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
) {
451 rv
+= l10n_util::GetStringUTF8(string_map
[i
].string_id
);
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
},
468 crypto::ScopedOpenSSL
<ASN1_BIT_STRING
, ASN1_BIT_STRING_free
> value(
469 reinterpret_cast<ASN1_BIT_STRING
*>(X509V3_EXT_d2i(ex
)));
471 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
472 return ProcessBitField(value
.get(),
474 arraysize(usage_string_map
),
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
},
491 crypto::ScopedOpenSSL
<ASN1_BIT_STRING
, ASN1_BIT_STRING_free
> value(
492 reinterpret_cast<ASN1_BIT_STRING
*>(X509V3_EXT_d2i(ex
)));
494 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
495 return ProcessBitField(value
.get(),
496 key_usage_string_map
,
497 arraysize(key_usage_string_map
),
501 std::string
ProcessBasicConstraints(X509_EXTENSION
* ex
) {
503 crypto::ScopedOpenSSL
<BASIC_CONSTRAINTS
, BASIC_CONSTRAINTS_free
> value(
504 reinterpret_cast<BASIC_CONSTRAINTS
*>(X509V3_EXT_d2i(ex
)));
506 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
508 rv
= l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_CA
);
510 rv
= l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_NOT_CA
);
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
);
518 depth
= base::FormatNumber(ASN1_INTEGER_get(value
.get()->pathlen
));
520 rv
+= l10n_util::GetStringFUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN
,
526 std::string
ProcessExtKeyUsage(X509_EXTENSION
* ex
) {
528 crypto::ScopedOpenSSL
<EXTENDED_KEY_USAGE
, EXTENDED_KEY_USAGE_free
> value(
529 reinterpret_cast<EXTENDED_KEY_USAGE
*>(X509V3_EXT_d2i(ex
)));
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
);
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
)
543 rv
+= l10n_util::GetStringFUTF8(IDS_CERT_EXT_KEY_USAGE_FORMAT
,
544 base::UTF8ToUTF16(oid_text
),
545 base::UTF8ToUTF16(oid_dump
));
551 std::string
ProcessGeneralName(GENERAL_NAME
* name
) {
555 switch (name
->type
) {
556 case GEN_OTHERNAME
: {
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
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
));
574 value
= ProcessRawAsn1Type(asn1_value
);
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
;
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]);
588 value
= ProcessRawAsn1Type(asn1_value
);
591 value
= ProcessRawAsn1Type(asn1_value
);
596 key
= l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_RFC822_NAME
);
598 reinterpret_cast<char*>(ASN1_STRING_data(name
->d
.rfc822Name
)),
599 ASN1_STRING_length(name
->d
.rfc822Name
));
602 key
= l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DNS_NAME
);
604 reinterpret_cast<char*>(ASN1_STRING_data(name
->d
.dNSName
)),
605 ASN1_STRING_length(name
->d
.dNSName
));
606 value
= ProcessIDN(value
);
609 key
= l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_X400_ADDRESS
);
610 value
= ProcessRawAsn1Type(name
->d
.x400Address
);
613 key
= l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DIRECTORY_NAME
);
614 value
= GetKeyValuesFromName(name
->d
.directoryName
);
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
,
623 Asn1StringToUTF8(name
->d
.ediPartyName
->nameAssigner
)));
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
,
631 Asn1StringToUTF8(name
->d
.ediPartyName
->partyName
)));
636 key
= l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_URI
);
638 std::string(reinterpret_cast<char*>(
639 ASN1_STRING_data(name
->d
.uniformResourceIdentifier
)),
640 ASN1_STRING_length(name
->d
.uniformResourceIdentifier
));
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
);
650 // Invalid IP address.
651 value
= ProcessRawBytes(ip
.data(), ip
.size());
656 key
= l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_REGISTERED_ID
);
657 value
= Asn1ObjectToString(name
->d
.registeredID
);
660 std::string
rv(l10n_util::GetStringFUTF8(IDS_CERT_UNKNOWN_OID_INFO_FORMAT
,
661 base::UTF8ToUTF16(key
),
662 base::UTF8ToUTF16(value
)));
667 std::string
ProcessGeneralNames(GENERAL_NAMES
* names
) {
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
);
676 std::string
ProcessAltName(X509_EXTENSION
* ex
) {
677 crypto::ScopedOpenSSL
<GENERAL_NAMES
, GENERAL_NAMES_free
> 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
);
682 return ProcessGeneralNames(alt_names
.get());
685 std::string
ProcessSubjectKeyId(X509_EXTENSION
* ex
) {
686 crypto::ScopedOpenSSL
<ASN1_OCTET_STRING
, ASN1_OCTET_STRING_free
> value(
687 reinterpret_cast<ASN1_OCTET_STRING
*>(X509V3_EXT_d2i(ex
)));
689 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
691 return l10n_util::GetStringFUTF8(
692 IDS_CERT_KEYID_FORMAT
,
693 base::ASCIIToUTF16(ProcessRawAsn1String(value
.get())));
696 std::string
ProcessAuthKeyId(X509_EXTENSION
* ex
) {
698 crypto::ScopedOpenSSL
<AUTHORITY_KEYID
, AUTHORITY_KEYID_free
> value(
699 reinterpret_cast<AUTHORITY_KEYID
*>(X509V3_EXT_d2i(ex
)));
701 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
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
)));
710 if (value
.get()->issuer
) {
711 rv
+= l10n_util::GetStringFUTF8(
712 IDS_CERT_ISSUER_FORMAT
,
713 base::UTF8ToUTF16(ProcessGeneralNames(value
.get()->issuer
)));
717 if (value
.get()->serial
) {
718 rv
+= l10n_util::GetStringFUTF8(
719 IDS_CERT_SERIAL_NUMBER_FORMAT
,
720 base::ASCIIToUTF16(ProcessRawAsn1String(value
.get()->serial
)));
727 std::string
ProcessUserNotice(USERNOTICE
* notice
) {
729 if (notice
->noticeref
) {
730 rv
+= Asn1StringToUTF8(notice
->noticeref
->organization
);
732 for (size_t i
= 0; i
< sk_ASN1_INTEGER_num(notice
->noticeref
->noticenos
);
735 sk_ASN1_INTEGER_value(notice
->noticeref
->noticenos
, i
);
736 long number
= ASN1_INTEGER_get(info
);
738 if (i
!= sk_ASN1_INTEGER_num(notice
->noticeref
->noticenos
) - 1)
741 rv
+= base::IntToString(number
);
745 if (notice
->exptext
&& notice
->exptext
->length
!= 0) {
747 rv
+= Asn1StringToUTF8(notice
->exptext
);
752 std::string
ProcessCertificatePolicies(X509_EXTENSION
* ex
) {
754 crypto::ScopedOpenSSL
<CERTIFICATEPOLICIES
, CERTIFICATEPOLICIES_free
> policies(
755 reinterpret_cast<CERTIFICATEPOLICIES
*>(X509V3_EXT_d2i(ex
)));
758 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
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
));
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
);
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
);
787 reinterpret_cast<char*>(ASN1_STRING_data(qualifier
->d
.cpsuri
)),
788 ASN1_STRING_length(qualifier
->d
.cpsuri
));
790 case NID_id_qt_unotice
:
791 rv
+= ProcessUserNotice(qualifier
->d
.usernotice
);
794 rv
+= ProcessRawAsn1Type(qualifier
->d
.other
);
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
},
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;
825 crypto::ScopedOpenSSL
<CRL_DIST_POINTS
, CRL_DIST_POINTS_free
> dist_points(
826 reinterpret_cast<CRL_DIST_POINTS
*>(X509V3_EXT_d2i(ex
)));
828 if (!dist_points
.get())
829 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
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
);
838 case kDistPointRelativeName
:
840 GetKeyValuesFromNameEntries(point
->distpoint
->name
.relativename
);
841 // TODO(mattm): should something be done with
842 // point->distpoint->dpname?
846 if (point
->reasons
) {
848 rv
+= ProcessBitField(point
->reasons
,
850 arraysize(reason_string_map
),
854 if (point
->CRLissuer
) {
855 rv
+= l10n_util::GetStringFUTF8(
856 IDS_CERT_ISSUER_FORMAT
,
857 base::UTF8ToUTF16(ProcessGeneralNames(point
->CRLissuer
)));
864 std::string
ProcessAuthInfoAccess(X509_EXTENSION
* ex
) {
866 crypto::ScopedOpenSSL
<AUTHORITY_INFO_ACCESS
, AUTHORITY_INFO_ACCESS_free
> aia(
867 reinterpret_cast<AUTHORITY_INFO_ACCESS
*>(X509V3_EXT_d2i(ex
)));
870 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
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
);
875 base::string16 location_str
=
876 base::UTF8ToUTF16(ProcessGeneralName(desc
->location
));
877 switch (OBJ_obj2nid(desc
->method
)) {
879 rv
+= l10n_util::GetStringFUTF8(IDS_CERT_OCSP_RESPONDER_FORMAT
,
882 case NID_ad_ca_issuers
:
884 l10n_util::GetStringFUTF8(IDS_CERT_CA_ISSUERS_FORMAT
, location_str
);
887 rv
+= l10n_util::GetStringFUTF8(
888 IDS_CERT_UNKNOWN_OID_INFO_FORMAT
,
889 base::UTF8ToUTF16(Asn1ObjectToString(desc
->method
)),
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
> ia5_string(
900 d2i_ASN1_IA5STRING(NULL
, &data
, ASN1_STRING_length(asn1_string
)));
902 if (!ia5_string
.get())
903 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
906 reinterpret_cast<char*>(ASN1_STRING_data(ia5_string
.get())),
907 ASN1_STRING_length(ia5_string
.get()));
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
> bmp_string(
913 d2i_ASN1_BMPSTRING(NULL
, &data
, ASN1_STRING_length(asn1_string
)));
915 if (!bmp_string
.get())
916 return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR
);
918 return Asn1StringToUTF8(bmp_string
.get());
921 std::string
X509ExtensionValueToString(X509_EXTENSION
* ex
) {
922 g_dynamic_oid_registerer
.Get();
923 int nid
= OBJ_obj2nid(X509_EXTENSION_get_object(ex
));
925 case NID_netscape_cert_type
:
926 return ProcessNSCertTypeExtension(ex
);
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
));
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
));
967 using net::X509Certificate
;
969 std::string
GetCertNameOrNickname(X509Certificate::OSCertHandle cert_handle
) {
971 ProcessIDN(GetSubjectCommonName(cert_handle
, std::string()));
975 crypto::ScopedBIO
bio(crypto::BIO_new_string(&name
));
978 X509_NAME_print_ex(bio
.get(),
979 X509_get_subject_name(cert_handle
),
981 XN_FLAG_RFC2253
& ~ASN1_STRFLGS_ESC_MSB
);
985 std::string
GetTokenName(X509Certificate::OSCertHandle cert_handle
) {
986 // TODO(bulach): implement me.
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);
997 net::CertType
GetType(X509Certificate::OSCertHandle os_cert
) {
998 // TODO(bulach): implement me.
999 return net::OTHER_CERT
;
1002 void GetUsageStrings(X509Certificate::OSCertHandle cert_handle
,
1003 std::vector
<std::string
>* usages
) {
1004 // TODO(bulach): implement me.
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
);
1017 std::string
GetIssuerCommonName(
1018 X509Certificate::OSCertHandle cert_handle
,
1019 const std::string
& alternative_text
) {
1021 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle
),
1022 NID_commonName
, &ret
);
1023 return AlternativeWhenEmpty(ret
, alternative_text
);
1026 std::string
GetIssuerOrgName(
1027 X509Certificate::OSCertHandle cert_handle
,
1028 const std::string
& alternative_text
) {
1030 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle
),
1031 NID_organizationName
, &ret
);
1032 return AlternativeWhenEmpty(ret
, alternative_text
);
1035 std::string
GetIssuerOrgUnitName(
1036 X509Certificate::OSCertHandle cert_handle
,
1037 const std::string
& alternative_text
) {
1039 x509_util::ParsePrincipalValueByNID(X509_get_issuer_name(cert_handle
),
1040 NID_organizationalUnitName
, &ret
);
1041 return AlternativeWhenEmpty(ret
, alternative_text
);
1044 std::string
GetSubjectOrgName(
1045 X509Certificate::OSCertHandle cert_handle
,
1046 const std::string
& alternative_text
) {
1048 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle
),
1049 NID_organizationName
, &ret
);
1050 return AlternativeWhenEmpty(ret
, alternative_text
);
1053 std::string
GetSubjectOrgUnitName(
1054 X509Certificate::OSCertHandle cert_handle
,
1055 const std::string
& alternative_text
) {
1057 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle
),
1058 NID_organizationalUnitName
, &ret
);
1059 return AlternativeWhenEmpty(ret
, alternative_text
);
1062 std::string
GetSubjectCommonName(X509Certificate::OSCertHandle cert_handle
,
1063 const std::string
& alternative_text
) {
1065 x509_util::ParsePrincipalValueByNID(X509_get_subject_name(cert_handle
),
1066 NID_commonName
, &ret
);
1067 return AlternativeWhenEmpty(ret
, alternative_text
);
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
);
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
1081 GetSubjectCommonName(cert_handle
, std::string());
1085 crypto::ScopedBIO
bio(crypto::BIO_new_string(&title
));
1088 X509_NAME_print_ex(bio
.get(),
1089 X509_get_subject_name(cert_handle
),
1091 XN_FLAG_RFC2253
& ~ASN1_STRFLGS_ESC_MSB
);
1095 std::string
GetIssuerName(net::X509Certificate::OSCertHandle cert_handle
) {
1096 return GetKeyValuesFromName(X509_get_issuer_name(cert_handle
));
1099 std::string
GetSubjectName(net::X509Certificate::OSCertHandle cert_handle
) {
1100 return GetKeyValuesFromName(X509_get_subject_name(cert_handle
));
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
);
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
);
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
);
1126 DCHECK_EQ(sha256_size
, sizeof(sha256_data
));
1127 return ProcessRawBytes(sha256_data
, sha256_size
);
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
);
1135 DCHECK_EQ(sha1_size
, sizeof(sha1_data
));
1136 return ProcessRawBytes(sha1_data
, sha1_size
);
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();
1143 for (size_t i
= start
; i
< end
; ++i
) {
1144 sk_X509_push(certs
, cert_chain
[i
]);
1148 CBB_init(&pkcs7
, 1024 * sk_X509_num(certs
));
1150 uint8_t *pkcs7_data
;
1152 if (!PKCS7_bundle_certificates(&pkcs7
, certs
) ||
1153 !CBB_finish(&pkcs7
, &pkcs7_data
, &pkcs7_len
)) {
1154 CBB_cleanup(&pkcs7
);
1155 sk_X509_free(certs
);
1159 std::string
ret(reinterpret_cast<char*>(pkcs7_data
), pkcs7_len
);
1160 OPENSSL_free(pkcs7_data
);
1161 sk_X509_free(certs
);
1166 std::string
ProcessSecAlgorithmSignature(
1167 net::X509Certificate::OSCertHandle cert_handle
) {
1168 return Asn1ObjectToString(cert_handle
->cert_info
->signature
->algorithm
);
1171 std::string
ProcessSecAlgorithmSubjectPublicKey(
1172 net::X509Certificate::OSCertHandle cert_handle
) {
1173 return Asn1ObjectToString(
1174 X509_get_X509_PUBKEY(cert_handle
)->algor
->algorithm
);
1177 std::string
ProcessSecAlgorithmSignatureWrap(
1178 net::X509Certificate::OSCertHandle cert_handle
) {
1179 return Asn1ObjectToString(cert_handle
->sig_alg
->algorithm
);
1182 std::string
ProcessSubjectPublicKeyInfo(
1183 net::X509Certificate::OSCertHandle cert_handle
) {
1185 crypto::ScopedEVP_PKEY
public_key(X509_get_pubkey(cert_handle
));
1186 if (!public_key
.get())
1188 switch (EVP_PKEY_type(public_key
.get()->type
)) {
1189 case EVP_PKEY_RSA
: {
1190 crypto::ScopedRSA
rsa_key(EVP_PKEY_get1_RSA(public_key
.get()));
1193 rv
= l10n_util::GetStringFUTF8(
1194 IDS_CERT_RSA_PUBLIC_KEY_DUMP_FORMAT
,
1195 base::UintToString16(BN_num_bits(rsa_key
.get()->n
)),
1196 base::UTF8ToUTF16(ProcessRawBignum(rsa_key
.get()->n
)),
1197 base::UintToString16(BN_num_bits(rsa_key
.get()->e
)),
1198 base::UTF8ToUTF16(ProcessRawBignum(rsa_key
.get()->e
)));
1202 rv
= ProcessRawAsn1String(X509_get_X509_PUBKEY(cert_handle
)->public_key
);
1207 std::string
ProcessRawBitsSignatureWrap(
1208 net::X509Certificate::OSCertHandle cert_handle
) {
1209 return ProcessRawAsn1String(cert_handle
->signature
);
1212 } // namespace x509_certificate_model