1 // Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "libcef/browser/x509_certificate_impl.h"
6
7 #include "libcef/browser/x509_cert_principal_impl.h"
8 #include "libcef/common/time_util.h"
9
10 #include "net/cert/x509_util.h"
11 #include "net/ssl/ssl_private_key.h"
12
13 namespace {
14
EncodeCertificate(const CRYPTO_BUFFER * cert_buffer,bool der)15 CefRefPtr<CefBinaryValue> EncodeCertificate(const CRYPTO_BUFFER* cert_buffer,
16 bool der) {
17 std::string encoded;
18 if (der) {
19 encoded =
20 std::string(net::x509_util::CryptoBufferAsStringPiece(cert_buffer));
21 } else if (!net::X509Certificate::GetPEMEncoded(cert_buffer, &encoded)) {
22 return nullptr;
23 }
24 if (encoded.empty())
25 return nullptr;
26 return CefBinaryValue::Create(encoded.c_str(), encoded.size());
27 }
28
29 } // namespace
30
CefX509CertificateImpl(std::unique_ptr<net::ClientCertIdentity> identity)31 CefX509CertificateImpl::CefX509CertificateImpl(
32 std::unique_ptr<net::ClientCertIdentity> identity)
33 : identity_(std::move(identity)), cert_(identity_->certificate()) {}
34
CefX509CertificateImpl(scoped_refptr<net::X509Certificate> cert)35 CefX509CertificateImpl::CefX509CertificateImpl(
36 scoped_refptr<net::X509Certificate> cert)
37 : cert_(cert) {}
38
GetSubject()39 CefRefPtr<CefX509CertPrincipal> CefX509CertificateImpl::GetSubject() {
40 if (cert_)
41 return new CefX509CertPrincipalImpl(cert_->subject());
42 return nullptr;
43 }
44
GetIssuer()45 CefRefPtr<CefX509CertPrincipal> CefX509CertificateImpl::GetIssuer() {
46 if (cert_)
47 return new CefX509CertPrincipalImpl(cert_->issuer());
48 return nullptr;
49 }
50
GetSerialNumber()51 CefRefPtr<CefBinaryValue> CefX509CertificateImpl::GetSerialNumber() {
52 if (cert_) {
53 const std::string& serial = cert_->serial_number();
54 return CefBinaryValue::Create(serial.c_str(), serial.size());
55 }
56 return nullptr;
57 }
58
GetValidStart()59 CefTime CefX509CertificateImpl::GetValidStart() {
60 CefTime validity;
61 if (cert_) {
62 const base::Time& valid_time = cert_->valid_start();
63 if (!valid_time.is_null())
64 cef_time_from_basetime(valid_time, validity);
65 }
66 return validity;
67 }
68
GetValidExpiry()69 CefTime CefX509CertificateImpl::GetValidExpiry() {
70 CefTime validity;
71 if (cert_) {
72 const base::Time& valid_time = cert_->valid_expiry();
73 if (!valid_time.is_null())
74 cef_time_from_basetime(valid_time, validity);
75 }
76 return validity;
77 }
78
GetDEREncoded()79 CefRefPtr<CefBinaryValue> CefX509CertificateImpl::GetDEREncoded() {
80 if (cert_) {
81 const CRYPTO_BUFFER* cert_buffer = cert_->cert_buffer();
82 if (cert_buffer)
83 return EncodeCertificate(cert_buffer, true);
84 }
85 return nullptr;
86 }
87
GetPEMEncoded()88 CefRefPtr<CefBinaryValue> CefX509CertificateImpl::GetPEMEncoded() {
89 if (cert_) {
90 const CRYPTO_BUFFER* cert_buffer = cert_->cert_buffer();
91 if (cert_buffer)
92 return EncodeCertificate(cert_buffer, false);
93 }
94 return nullptr;
95 }
96
GetIssuerChainSize()97 size_t CefX509CertificateImpl::GetIssuerChainSize() {
98 if (cert_)
99 return cert_->intermediate_buffers().size();
100 return 0;
101 }
102
AcquirePrivateKey(base::OnceCallback<void (scoped_refptr<net::SSLPrivateKey>)> private_key_callback)103 void CefX509CertificateImpl::AcquirePrivateKey(
104 base::OnceCallback<void(scoped_refptr<net::SSLPrivateKey>)>
105 private_key_callback) {
106 if (identity_)
107 identity_->AcquirePrivateKey(std::move(private_key_callback));
108 else
109 std::move(private_key_callback).Run(nullptr);
110 }
111
GetEncodedIssuerChain(CefX509Certificate::IssuerChainBinaryList & chain,bool der)112 void CefX509CertificateImpl::GetEncodedIssuerChain(
113 CefX509Certificate::IssuerChainBinaryList& chain,
114 bool der) {
115 chain.clear();
116 if (cert_) {
117 for (const auto& it : cert_->intermediate_buffers()) {
118 // Add each to the chain, even if one conversion unexpectedly failed.
119 // GetIssuerChainSize depends on these being the same length.
120 chain.push_back(EncodeCertificate(it.get(), der));
121 }
122 }
123 }
124
GetDEREncodedIssuerChain(CefX509Certificate::IssuerChainBinaryList & chain)125 void CefX509CertificateImpl::GetDEREncodedIssuerChain(
126 CefX509Certificate::IssuerChainBinaryList& chain) {
127 if (der_encoded_issuer_chain_.empty())
128 GetEncodedIssuerChain(der_encoded_issuer_chain_, true);
129 chain = der_encoded_issuer_chain_;
130 }
131
GetPEMEncodedIssuerChain(CefX509Certificate::IssuerChainBinaryList & chain)132 void CefX509CertificateImpl::GetPEMEncodedIssuerChain(
133 CefX509Certificate::IssuerChainBinaryList& chain) {
134 if (pem_encoded_issuer_chain_.empty())
135 GetEncodedIssuerChain(pem_encoded_issuer_chain_, false);
136 chain = pem_encoded_issuer_chain_;
137 }
138