1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/openssl_utility.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
14*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN)
15*d9f75844SAndroid Build Coastguard Worker // Must be included first before openssl headers.
16*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/win32.h" // NOLINT
17*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_WIN
18*d9f75844SAndroid Build Coastguard Worker
19*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
20*d9f75844SAndroid Build Coastguard Worker #include <openssl/pool.h>
21*d9f75844SAndroid Build Coastguard Worker #endif
22*d9f75844SAndroid Build Coastguard Worker #include <openssl/err.h>
23*d9f75844SAndroid Build Coastguard Worker #include <openssl/x509.h>
24*d9f75844SAndroid Build Coastguard Worker #include <openssl/x509v3.h>
25*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
26*d9f75844SAndroid Build Coastguard Worker
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/arraysize.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/numerics/safe_conversions.h"
30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/openssl.h"
31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_identity.h"
32*d9f75844SAndroid Build Coastguard Worker #ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
33*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_roots.h"
34*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
35*d9f75844SAndroid Build Coastguard Worker
36*d9f75844SAndroid Build Coastguard Worker namespace rtc {
37*d9f75844SAndroid Build Coastguard Worker namespace openssl {
38*d9f75844SAndroid Build Coastguard Worker
39*d9f75844SAndroid Build Coastguard Worker // Holds various helper methods.
40*d9f75844SAndroid Build Coastguard Worker namespace {
41*d9f75844SAndroid Build Coastguard Worker
42*d9f75844SAndroid Build Coastguard Worker // TODO(crbug.com/webrtc/11710): When OS certificate verification is available,
43*d9f75844SAndroid Build Coastguard Worker // and we don't need VerifyPeerCertMatchesHost, don't compile this in order to
44*d9f75844SAndroid Build Coastguard Worker // avoid a dependency on OpenSSL X509 objects (see crbug.com/webrtc/11410).
LogCertificates(SSL * ssl,X509 * certificate)45*d9f75844SAndroid Build Coastguard Worker void LogCertificates(SSL* ssl, X509* certificate) {
46*d9f75844SAndroid Build Coastguard Worker // Logging certificates is extremely verbose. So it is disabled by default.
47*d9f75844SAndroid Build Coastguard Worker #ifdef LOG_CERTIFICATES
48*d9f75844SAndroid Build Coastguard Worker BIO* mem = BIO_new(BIO_s_mem());
49*d9f75844SAndroid Build Coastguard Worker if (mem == nullptr) {
50*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_ERROR) << "BIO_new() failed to allocate memory.";
51*d9f75844SAndroid Build Coastguard Worker return;
52*d9f75844SAndroid Build Coastguard Worker }
53*d9f75844SAndroid Build Coastguard Worker
54*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_INFO) << "Certificate from server:";
55*d9f75844SAndroid Build Coastguard Worker X509_print_ex(mem, certificate, XN_FLAG_SEP_CPLUS_SPC, X509_FLAG_NO_HEADER);
56*d9f75844SAndroid Build Coastguard Worker BIO_write(mem, "\0", 1);
57*d9f75844SAndroid Build Coastguard Worker
58*d9f75844SAndroid Build Coastguard Worker char* buffer = nullptr;
59*d9f75844SAndroid Build Coastguard Worker BIO_get_mem_data(mem, &buffer);
60*d9f75844SAndroid Build Coastguard Worker if (buffer != nullptr) {
61*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_INFO) << buffer;
62*d9f75844SAndroid Build Coastguard Worker } else {
63*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_ERROR) << "BIO_get_mem_data() failed to get buffer.";
64*d9f75844SAndroid Build Coastguard Worker }
65*d9f75844SAndroid Build Coastguard Worker BIO_free(mem);
66*d9f75844SAndroid Build Coastguard Worker
67*d9f75844SAndroid Build Coastguard Worker const char* cipher_name = SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
68*d9f75844SAndroid Build Coastguard Worker if (cipher_name != nullptr) {
69*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_INFO) << "Cipher: " << cipher_name;
70*d9f75844SAndroid Build Coastguard Worker } else {
71*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_ERROR) << "SSL_CIPHER_DESCRIPTION() failed to get cipher_name.";
72*d9f75844SAndroid Build Coastguard Worker }
73*d9f75844SAndroid Build Coastguard Worker #endif
74*d9f75844SAndroid Build Coastguard Worker }
75*d9f75844SAndroid Build Coastguard Worker } // namespace
76*d9f75844SAndroid Build Coastguard Worker
77*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
ParseCertificate(CRYPTO_BUFFER * cert_buffer,CBS * signature_algorithm_oid,int64_t * expiration_time)78*d9f75844SAndroid Build Coastguard Worker bool ParseCertificate(CRYPTO_BUFFER* cert_buffer,
79*d9f75844SAndroid Build Coastguard Worker CBS* signature_algorithm_oid,
80*d9f75844SAndroid Build Coastguard Worker int64_t* expiration_time) {
81*d9f75844SAndroid Build Coastguard Worker CBS cbs;
82*d9f75844SAndroid Build Coastguard Worker CRYPTO_BUFFER_init_CBS(cert_buffer, &cbs);
83*d9f75844SAndroid Build Coastguard Worker
84*d9f75844SAndroid Build Coastguard Worker // Certificate ::= SEQUENCE {
85*d9f75844SAndroid Build Coastguard Worker CBS certificate;
86*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&cbs, &certificate, CBS_ASN1_SEQUENCE)) {
87*d9f75844SAndroid Build Coastguard Worker return false;
88*d9f75844SAndroid Build Coastguard Worker }
89*d9f75844SAndroid Build Coastguard Worker // tbsCertificate TBSCertificate,
90*d9f75844SAndroid Build Coastguard Worker CBS tbs_certificate;
91*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&certificate, &tbs_certificate, CBS_ASN1_SEQUENCE)) {
92*d9f75844SAndroid Build Coastguard Worker return false;
93*d9f75844SAndroid Build Coastguard Worker }
94*d9f75844SAndroid Build Coastguard Worker // signatureAlgorithm AlgorithmIdentifier,
95*d9f75844SAndroid Build Coastguard Worker CBS signature_algorithm;
96*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&certificate, &signature_algorithm, CBS_ASN1_SEQUENCE)) {
97*d9f75844SAndroid Build Coastguard Worker return false;
98*d9f75844SAndroid Build Coastguard Worker }
99*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&signature_algorithm, signature_algorithm_oid,
100*d9f75844SAndroid Build Coastguard Worker CBS_ASN1_OBJECT)) {
101*d9f75844SAndroid Build Coastguard Worker return false;
102*d9f75844SAndroid Build Coastguard Worker }
103*d9f75844SAndroid Build Coastguard Worker // signatureValue BIT STRING }
104*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&certificate, nullptr, CBS_ASN1_BITSTRING)) {
105*d9f75844SAndroid Build Coastguard Worker return false;
106*d9f75844SAndroid Build Coastguard Worker }
107*d9f75844SAndroid Build Coastguard Worker if (CBS_len(&certificate)) {
108*d9f75844SAndroid Build Coastguard Worker return false;
109*d9f75844SAndroid Build Coastguard Worker }
110*d9f75844SAndroid Build Coastguard Worker
111*d9f75844SAndroid Build Coastguard Worker // Now parse the inner TBSCertificate.
112*d9f75844SAndroid Build Coastguard Worker // version [0] EXPLICIT Version DEFAULT v1,
113*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_optional_asn1(
114*d9f75844SAndroid Build Coastguard Worker &tbs_certificate, nullptr, nullptr,
115*d9f75844SAndroid Build Coastguard Worker CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)) {
116*d9f75844SAndroid Build Coastguard Worker return false;
117*d9f75844SAndroid Build Coastguard Worker }
118*d9f75844SAndroid Build Coastguard Worker // serialNumber CertificateSerialNumber,
119*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_INTEGER)) {
120*d9f75844SAndroid Build Coastguard Worker return false;
121*d9f75844SAndroid Build Coastguard Worker }
122*d9f75844SAndroid Build Coastguard Worker // signature AlgorithmIdentifier
123*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
124*d9f75844SAndroid Build Coastguard Worker return false;
125*d9f75844SAndroid Build Coastguard Worker }
126*d9f75844SAndroid Build Coastguard Worker // issuer Name,
127*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
128*d9f75844SAndroid Build Coastguard Worker return false;
129*d9f75844SAndroid Build Coastguard Worker }
130*d9f75844SAndroid Build Coastguard Worker // validity Validity,
131*d9f75844SAndroid Build Coastguard Worker CBS validity;
132*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&tbs_certificate, &validity, CBS_ASN1_SEQUENCE)) {
133*d9f75844SAndroid Build Coastguard Worker return false;
134*d9f75844SAndroid Build Coastguard Worker }
135*d9f75844SAndroid Build Coastguard Worker // Skip over notBefore.
136*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_any_asn1_element(&validity, nullptr, nullptr, nullptr)) {
137*d9f75844SAndroid Build Coastguard Worker return false;
138*d9f75844SAndroid Build Coastguard Worker }
139*d9f75844SAndroid Build Coastguard Worker // Parse notAfter.
140*d9f75844SAndroid Build Coastguard Worker CBS not_after;
141*d9f75844SAndroid Build Coastguard Worker unsigned not_after_tag;
142*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_any_asn1(&validity, ¬_after, ¬_after_tag)) {
143*d9f75844SAndroid Build Coastguard Worker return false;
144*d9f75844SAndroid Build Coastguard Worker }
145*d9f75844SAndroid Build Coastguard Worker bool long_format;
146*d9f75844SAndroid Build Coastguard Worker if (not_after_tag == CBS_ASN1_UTCTIME) {
147*d9f75844SAndroid Build Coastguard Worker long_format = false;
148*d9f75844SAndroid Build Coastguard Worker } else if (not_after_tag == CBS_ASN1_GENERALIZEDTIME) {
149*d9f75844SAndroid Build Coastguard Worker long_format = true;
150*d9f75844SAndroid Build Coastguard Worker } else {
151*d9f75844SAndroid Build Coastguard Worker return false;
152*d9f75844SAndroid Build Coastguard Worker }
153*d9f75844SAndroid Build Coastguard Worker if (expiration_time) {
154*d9f75844SAndroid Build Coastguard Worker *expiration_time =
155*d9f75844SAndroid Build Coastguard Worker ASN1TimeToSec(CBS_data(¬_after), CBS_len(¬_after), long_format);
156*d9f75844SAndroid Build Coastguard Worker }
157*d9f75844SAndroid Build Coastguard Worker // subject Name,
158*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1_element(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
159*d9f75844SAndroid Build Coastguard Worker return false;
160*d9f75844SAndroid Build Coastguard Worker }
161*d9f75844SAndroid Build Coastguard Worker // subjectPublicKeyInfo SubjectPublicKeyInfo,
162*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_asn1(&tbs_certificate, nullptr, CBS_ASN1_SEQUENCE)) {
163*d9f75844SAndroid Build Coastguard Worker return false;
164*d9f75844SAndroid Build Coastguard Worker }
165*d9f75844SAndroid Build Coastguard Worker // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL
166*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_optional_asn1(&tbs_certificate, nullptr, nullptr,
167*d9f75844SAndroid Build Coastguard Worker 0x01 | CBS_ASN1_CONTEXT_SPECIFIC)) {
168*d9f75844SAndroid Build Coastguard Worker return false;
169*d9f75844SAndroid Build Coastguard Worker }
170*d9f75844SAndroid Build Coastguard Worker // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL
171*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_optional_asn1(&tbs_certificate, nullptr, nullptr,
172*d9f75844SAndroid Build Coastguard Worker 0x02 | CBS_ASN1_CONTEXT_SPECIFIC)) {
173*d9f75844SAndroid Build Coastguard Worker return false;
174*d9f75844SAndroid Build Coastguard Worker }
175*d9f75844SAndroid Build Coastguard Worker // extensions [3] EXPLICIT Extensions OPTIONAL
176*d9f75844SAndroid Build Coastguard Worker if (!CBS_get_optional_asn1(
177*d9f75844SAndroid Build Coastguard Worker &tbs_certificate, nullptr, nullptr,
178*d9f75844SAndroid Build Coastguard Worker 0x03 | CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC)) {
179*d9f75844SAndroid Build Coastguard Worker return false;
180*d9f75844SAndroid Build Coastguard Worker }
181*d9f75844SAndroid Build Coastguard Worker if (CBS_len(&tbs_certificate)) {
182*d9f75844SAndroid Build Coastguard Worker return false;
183*d9f75844SAndroid Build Coastguard Worker }
184*d9f75844SAndroid Build Coastguard Worker
185*d9f75844SAndroid Build Coastguard Worker return true;
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker #endif // OPENSSL_IS_BORINGSSL
188*d9f75844SAndroid Build Coastguard Worker
VerifyPeerCertMatchesHost(SSL * ssl,absl::string_view host)189*d9f75844SAndroid Build Coastguard Worker bool VerifyPeerCertMatchesHost(SSL* ssl, absl::string_view host) {
190*d9f75844SAndroid Build Coastguard Worker if (host.empty()) {
191*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_ERROR) << "Hostname is empty. Cannot verify peer certificate.";
192*d9f75844SAndroid Build Coastguard Worker return false;
193*d9f75844SAndroid Build Coastguard Worker }
194*d9f75844SAndroid Build Coastguard Worker
195*d9f75844SAndroid Build Coastguard Worker if (ssl == nullptr) {
196*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_ERROR) << "SSL is nullptr. Cannot verify peer certificate.";
197*d9f75844SAndroid Build Coastguard Worker return false;
198*d9f75844SAndroid Build Coastguard Worker }
199*d9f75844SAndroid Build Coastguard Worker
200*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
201*d9f75844SAndroid Build Coastguard Worker // We can't grab a X509 object directly, as the SSL context may have been
202*d9f75844SAndroid Build Coastguard Worker // initialized with TLS_with_buffers_method.
203*d9f75844SAndroid Build Coastguard Worker const STACK_OF(CRYPTO_BUFFER)* chain = SSL_get0_peer_certificates(ssl);
204*d9f75844SAndroid Build Coastguard Worker if (chain == nullptr || sk_CRYPTO_BUFFER_num(chain) == 0) {
205*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_ERROR)
206*d9f75844SAndroid Build Coastguard Worker << "SSL_get0_peer_certificates failed. This should never happen.";
207*d9f75844SAndroid Build Coastguard Worker return false;
208*d9f75844SAndroid Build Coastguard Worker }
209*d9f75844SAndroid Build Coastguard Worker CRYPTO_BUFFER* leaf = sk_CRYPTO_BUFFER_value(chain, 0);
210*d9f75844SAndroid Build Coastguard Worker bssl::UniquePtr<X509> x509(X509_parse_from_buffer(leaf));
211*d9f75844SAndroid Build Coastguard Worker if (!x509) {
212*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_ERROR) << "Failed to parse certificate to X509 object.";
213*d9f75844SAndroid Build Coastguard Worker return false;
214*d9f75844SAndroid Build Coastguard Worker }
215*d9f75844SAndroid Build Coastguard Worker LogCertificates(ssl, x509.get());
216*d9f75844SAndroid Build Coastguard Worker return X509_check_host(x509.get(), host.data(), host.size(), 0, nullptr) == 1;
217*d9f75844SAndroid Build Coastguard Worker #else // OPENSSL_IS_BORINGSSL
218*d9f75844SAndroid Build Coastguard Worker X509* certificate = SSL_get_peer_certificate(ssl);
219*d9f75844SAndroid Build Coastguard Worker if (certificate == nullptr) {
220*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_ERROR)
221*d9f75844SAndroid Build Coastguard Worker << "SSL_get_peer_certificate failed. This should never happen.";
222*d9f75844SAndroid Build Coastguard Worker return false;
223*d9f75844SAndroid Build Coastguard Worker }
224*d9f75844SAndroid Build Coastguard Worker
225*d9f75844SAndroid Build Coastguard Worker LogCertificates(ssl, certificate);
226*d9f75844SAndroid Build Coastguard Worker
227*d9f75844SAndroid Build Coastguard Worker bool is_valid_cert_name =
228*d9f75844SAndroid Build Coastguard Worker X509_check_host(certificate, host.data(), host.size(), 0, nullptr) == 1;
229*d9f75844SAndroid Build Coastguard Worker X509_free(certificate);
230*d9f75844SAndroid Build Coastguard Worker return is_valid_cert_name;
231*d9f75844SAndroid Build Coastguard Worker #endif // !defined(OPENSSL_IS_BORINGSSL)
232*d9f75844SAndroid Build Coastguard Worker }
233*d9f75844SAndroid Build Coastguard Worker
LogSSLErrors(absl::string_view prefix)234*d9f75844SAndroid Build Coastguard Worker void LogSSLErrors(absl::string_view prefix) {
235*d9f75844SAndroid Build Coastguard Worker char error_buf[200];
236*d9f75844SAndroid Build Coastguard Worker unsigned long err; // NOLINT
237*d9f75844SAndroid Build Coastguard Worker
238*d9f75844SAndroid Build Coastguard Worker while ((err = ERR_get_error()) != 0) {
239*d9f75844SAndroid Build Coastguard Worker ERR_error_string_n(err, error_buf, sizeof(error_buf));
240*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_ERROR) << prefix << ": " << error_buf << "\n";
241*d9f75844SAndroid Build Coastguard Worker }
242*d9f75844SAndroid Build Coastguard Worker }
243*d9f75844SAndroid Build Coastguard Worker
244*d9f75844SAndroid Build Coastguard Worker #ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
LoadBuiltinSSLRootCertificates(SSL_CTX * ctx)245*d9f75844SAndroid Build Coastguard Worker bool LoadBuiltinSSLRootCertificates(SSL_CTX* ctx) {
246*d9f75844SAndroid Build Coastguard Worker int count_of_added_certs = 0;
247*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) {
248*d9f75844SAndroid Build Coastguard Worker const unsigned char* cert_buffer = kSSLCertCertificateList[i];
249*d9f75844SAndroid Build Coastguard Worker size_t cert_buffer_len = kSSLCertCertificateSizeList[i];
250*d9f75844SAndroid Build Coastguard Worker X509* cert = d2i_X509(nullptr, &cert_buffer,
251*d9f75844SAndroid Build Coastguard Worker checked_cast<long>(cert_buffer_len)); // NOLINT
252*d9f75844SAndroid Build Coastguard Worker if (cert) {
253*d9f75844SAndroid Build Coastguard Worker int return_value = X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert);
254*d9f75844SAndroid Build Coastguard Worker if (return_value == 0) {
255*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_WARNING) << "Unable to add certificate.";
256*d9f75844SAndroid Build Coastguard Worker } else {
257*d9f75844SAndroid Build Coastguard Worker count_of_added_certs++;
258*d9f75844SAndroid Build Coastguard Worker }
259*d9f75844SAndroid Build Coastguard Worker X509_free(cert);
260*d9f75844SAndroid Build Coastguard Worker }
261*d9f75844SAndroid Build Coastguard Worker }
262*d9f75844SAndroid Build Coastguard Worker return count_of_added_certs > 0;
263*d9f75844SAndroid Build Coastguard Worker }
264*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
265*d9f75844SAndroid Build Coastguard Worker
266*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
GetBufferPool()267*d9f75844SAndroid Build Coastguard Worker CRYPTO_BUFFER_POOL* GetBufferPool() {
268*d9f75844SAndroid Build Coastguard Worker static CRYPTO_BUFFER_POOL* instance = CRYPTO_BUFFER_POOL_new();
269*d9f75844SAndroid Build Coastguard Worker return instance;
270*d9f75844SAndroid Build Coastguard Worker }
271*d9f75844SAndroid Build Coastguard Worker #endif
272*d9f75844SAndroid Build Coastguard Worker
273*d9f75844SAndroid Build Coastguard Worker } // namespace openssl
274*d9f75844SAndroid Build Coastguard Worker } // namespace rtc
275