1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2004 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 // Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
12*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_identity.h"
13*d9f75844SAndroid Build Coastguard Worker
14*d9f75844SAndroid Build Coastguard Worker #include <openssl/ossl_typ.h>
15*d9f75844SAndroid Build Coastguard Worker #include <string.h>
16*d9f75844SAndroid Build Coastguard Worker #include <time.h>
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
20*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/boringssl_identity.h"
22*d9f75844SAndroid Build Coastguard Worker #else
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/openssl_identity.h"
24*d9f75844SAndroid Build Coastguard Worker #endif
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_certificate.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/third_party/base64/base64.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
29*d9f75844SAndroid Build Coastguard Worker
30*d9f75844SAndroid Build Coastguard Worker namespace rtc {
31*d9f75844SAndroid Build Coastguard Worker
32*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
33*d9f75844SAndroid Build Coastguard Worker // Helper Functions
34*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
35*d9f75844SAndroid Build Coastguard Worker
36*d9f75844SAndroid Build Coastguard Worker namespace {
37*d9f75844SAndroid Build Coastguard Worker // Read `n` bytes from ASN1 number string at *`pp` and return the numeric value.
38*d9f75844SAndroid Build Coastguard Worker // Update *`pp` and *`np` to reflect number of read bytes.
39*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/9860) - Remove this code.
ASN1ReadInt(const unsigned char ** pp,size_t * np,size_t n)40*d9f75844SAndroid Build Coastguard Worker inline int ASN1ReadInt(const unsigned char** pp, size_t* np, size_t n) {
41*d9f75844SAndroid Build Coastguard Worker const unsigned char* p = *pp;
42*d9f75844SAndroid Build Coastguard Worker int x = 0;
43*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < n; i++) {
44*d9f75844SAndroid Build Coastguard Worker x = 10 * x + p[i] - '0';
45*d9f75844SAndroid Build Coastguard Worker }
46*d9f75844SAndroid Build Coastguard Worker *pp = p + n;
47*d9f75844SAndroid Build Coastguard Worker *np = *np - n;
48*d9f75844SAndroid Build Coastguard Worker return x;
49*d9f75844SAndroid Build Coastguard Worker }
50*d9f75844SAndroid Build Coastguard Worker
51*d9f75844SAndroid Build Coastguard Worker } // namespace
52*d9f75844SAndroid Build Coastguard Worker
53*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/9860) - Remove this code.
ASN1TimeToSec(const unsigned char * s,size_t length,bool long_format)54*d9f75844SAndroid Build Coastguard Worker int64_t ASN1TimeToSec(const unsigned char* s, size_t length, bool long_format) {
55*d9f75844SAndroid Build Coastguard Worker size_t bytes_left = length;
56*d9f75844SAndroid Build Coastguard Worker // Make sure the string ends with Z. Doing it here protects the strspn call
57*d9f75844SAndroid Build Coastguard Worker // from running off the end of the string in Z's absense.
58*d9f75844SAndroid Build Coastguard Worker if (length == 0 || s[length - 1] != 'Z') {
59*d9f75844SAndroid Build Coastguard Worker return -1;
60*d9f75844SAndroid Build Coastguard Worker }
61*d9f75844SAndroid Build Coastguard Worker // Make sure we only have ASCII digits so that we don't need to clutter the
62*d9f75844SAndroid Build Coastguard Worker // code below and ASN1ReadInt with error checking.
63*d9f75844SAndroid Build Coastguard Worker size_t n = strspn(reinterpret_cast<const char*>(s), "0123456789");
64*d9f75844SAndroid Build Coastguard Worker if (n + 1 != length) {
65*d9f75844SAndroid Build Coastguard Worker return -1;
66*d9f75844SAndroid Build Coastguard Worker }
67*d9f75844SAndroid Build Coastguard Worker // Read out ASN1 year, in either 2-char "UTCTIME" or 4-char "GENERALIZEDTIME"
68*d9f75844SAndroid Build Coastguard Worker // format. Both format use UTC in this context.
69*d9f75844SAndroid Build Coastguard Worker int year = 0;
70*d9f75844SAndroid Build Coastguard Worker if (long_format) {
71*d9f75844SAndroid Build Coastguard Worker // ASN1 format: yyyymmddhh[mm[ss[.fff]]]Z where the Z is literal, but
72*d9f75844SAndroid Build Coastguard Worker // RFC 5280 requires us to only support exactly yyyymmddhhmmssZ.
73*d9f75844SAndroid Build Coastguard Worker if (bytes_left < 11) {
74*d9f75844SAndroid Build Coastguard Worker return -1;
75*d9f75844SAndroid Build Coastguard Worker }
76*d9f75844SAndroid Build Coastguard Worker year = ASN1ReadInt(&s, &bytes_left, 4);
77*d9f75844SAndroid Build Coastguard Worker year -= 1900;
78*d9f75844SAndroid Build Coastguard Worker } else {
79*d9f75844SAndroid Build Coastguard Worker // ASN1 format: yymmddhhmm[ss]Z where the Z is literal, but RFC 5280
80*d9f75844SAndroid Build Coastguard Worker // requires us to only support exactly yymmddhhmmssZ.
81*d9f75844SAndroid Build Coastguard Worker if (bytes_left < 9) {
82*d9f75844SAndroid Build Coastguard Worker return -1;
83*d9f75844SAndroid Build Coastguard Worker }
84*d9f75844SAndroid Build Coastguard Worker year = ASN1ReadInt(&s, &bytes_left, 2);
85*d9f75844SAndroid Build Coastguard Worker // Per RFC 5280 4.1.2.5.1
86*d9f75844SAndroid Build Coastguard Worker if (year < 50) {
87*d9f75844SAndroid Build Coastguard Worker year += 100;
88*d9f75844SAndroid Build Coastguard Worker }
89*d9f75844SAndroid Build Coastguard Worker }
90*d9f75844SAndroid Build Coastguard Worker
91*d9f75844SAndroid Build Coastguard Worker // Read out remaining ASN1 time data and store it in `tm` in documented
92*d9f75844SAndroid Build Coastguard Worker // std::tm format.
93*d9f75844SAndroid Build Coastguard Worker tm tm;
94*d9f75844SAndroid Build Coastguard Worker tm.tm_year = year;
95*d9f75844SAndroid Build Coastguard Worker tm.tm_mon = ASN1ReadInt(&s, &bytes_left, 2) - 1;
96*d9f75844SAndroid Build Coastguard Worker tm.tm_mday = ASN1ReadInt(&s, &bytes_left, 2);
97*d9f75844SAndroid Build Coastguard Worker tm.tm_hour = ASN1ReadInt(&s, &bytes_left, 2);
98*d9f75844SAndroid Build Coastguard Worker tm.tm_min = ASN1ReadInt(&s, &bytes_left, 2);
99*d9f75844SAndroid Build Coastguard Worker tm.tm_sec = ASN1ReadInt(&s, &bytes_left, 2);
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard Worker // Now just Z should remain. Its existence was asserted above.
102*d9f75844SAndroid Build Coastguard Worker if (bytes_left != 1) {
103*d9f75844SAndroid Build Coastguard Worker return -1;
104*d9f75844SAndroid Build Coastguard Worker }
105*d9f75844SAndroid Build Coastguard Worker return TmToSeconds(tm);
106*d9f75844SAndroid Build Coastguard Worker }
107*d9f75844SAndroid Build Coastguard Worker
108*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
109*d9f75844SAndroid Build Coastguard Worker // KeyParams
110*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
111*d9f75844SAndroid Build Coastguard Worker
112*d9f75844SAndroid Build Coastguard Worker const char kPemTypeCertificate[] = "CERTIFICATE";
113*d9f75844SAndroid Build Coastguard Worker const char kPemTypeRsaPrivateKey[] = "RSA PRIVATE KEY";
114*d9f75844SAndroid Build Coastguard Worker const char kPemTypeEcPrivateKey[] = "EC PRIVATE KEY";
115*d9f75844SAndroid Build Coastguard Worker
KeyParams(KeyType key_type)116*d9f75844SAndroid Build Coastguard Worker KeyParams::KeyParams(KeyType key_type) {
117*d9f75844SAndroid Build Coastguard Worker if (key_type == KT_ECDSA) {
118*d9f75844SAndroid Build Coastguard Worker type_ = KT_ECDSA;
119*d9f75844SAndroid Build Coastguard Worker params_.curve = EC_NIST_P256;
120*d9f75844SAndroid Build Coastguard Worker } else if (key_type == KT_RSA) {
121*d9f75844SAndroid Build Coastguard Worker type_ = KT_RSA;
122*d9f75844SAndroid Build Coastguard Worker params_.rsa.mod_size = kRsaDefaultModSize;
123*d9f75844SAndroid Build Coastguard Worker params_.rsa.pub_exp = kRsaDefaultExponent;
124*d9f75844SAndroid Build Coastguard Worker } else {
125*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_NOTREACHED();
126*d9f75844SAndroid Build Coastguard Worker }
127*d9f75844SAndroid Build Coastguard Worker }
128*d9f75844SAndroid Build Coastguard Worker
129*d9f75844SAndroid Build Coastguard Worker // static
RSA(int mod_size,int pub_exp)130*d9f75844SAndroid Build Coastguard Worker KeyParams KeyParams::RSA(int mod_size, int pub_exp) {
131*d9f75844SAndroid Build Coastguard Worker KeyParams kt(KT_RSA);
132*d9f75844SAndroid Build Coastguard Worker kt.params_.rsa.mod_size = mod_size;
133*d9f75844SAndroid Build Coastguard Worker kt.params_.rsa.pub_exp = pub_exp;
134*d9f75844SAndroid Build Coastguard Worker return kt;
135*d9f75844SAndroid Build Coastguard Worker }
136*d9f75844SAndroid Build Coastguard Worker
137*d9f75844SAndroid Build Coastguard Worker // static
ECDSA(ECCurve curve)138*d9f75844SAndroid Build Coastguard Worker KeyParams KeyParams::ECDSA(ECCurve curve) {
139*d9f75844SAndroid Build Coastguard Worker KeyParams kt(KT_ECDSA);
140*d9f75844SAndroid Build Coastguard Worker kt.params_.curve = curve;
141*d9f75844SAndroid Build Coastguard Worker return kt;
142*d9f75844SAndroid Build Coastguard Worker }
143*d9f75844SAndroid Build Coastguard Worker
IsValid() const144*d9f75844SAndroid Build Coastguard Worker bool KeyParams::IsValid() const {
145*d9f75844SAndroid Build Coastguard Worker if (type_ == KT_RSA) {
146*d9f75844SAndroid Build Coastguard Worker return (params_.rsa.mod_size >= kRsaMinModSize &&
147*d9f75844SAndroid Build Coastguard Worker params_.rsa.mod_size <= kRsaMaxModSize &&
148*d9f75844SAndroid Build Coastguard Worker params_.rsa.pub_exp > params_.rsa.mod_size);
149*d9f75844SAndroid Build Coastguard Worker } else if (type_ == KT_ECDSA) {
150*d9f75844SAndroid Build Coastguard Worker return (params_.curve == EC_NIST_P256);
151*d9f75844SAndroid Build Coastguard Worker }
152*d9f75844SAndroid Build Coastguard Worker return false;
153*d9f75844SAndroid Build Coastguard Worker }
154*d9f75844SAndroid Build Coastguard Worker
rsa_params() const155*d9f75844SAndroid Build Coastguard Worker RSAParams KeyParams::rsa_params() const {
156*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(type_ == KT_RSA);
157*d9f75844SAndroid Build Coastguard Worker return params_.rsa;
158*d9f75844SAndroid Build Coastguard Worker }
159*d9f75844SAndroid Build Coastguard Worker
ec_curve() const160*d9f75844SAndroid Build Coastguard Worker ECCurve KeyParams::ec_curve() const {
161*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(type_ == KT_ECDSA);
162*d9f75844SAndroid Build Coastguard Worker return params_.curve;
163*d9f75844SAndroid Build Coastguard Worker }
164*d9f75844SAndroid Build Coastguard Worker
IntKeyTypeFamilyToKeyType(int key_type_family)165*d9f75844SAndroid Build Coastguard Worker KeyType IntKeyTypeFamilyToKeyType(int key_type_family) {
166*d9f75844SAndroid Build Coastguard Worker return static_cast<KeyType>(key_type_family);
167*d9f75844SAndroid Build Coastguard Worker }
168*d9f75844SAndroid Build Coastguard Worker
169*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
170*d9f75844SAndroid Build Coastguard Worker // SSLIdentity
171*d9f75844SAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////
172*d9f75844SAndroid Build Coastguard Worker
PemToDer(absl::string_view pem_type,absl::string_view pem_string,std::string * der)173*d9f75844SAndroid Build Coastguard Worker bool SSLIdentity::PemToDer(absl::string_view pem_type,
174*d9f75844SAndroid Build Coastguard Worker absl::string_view pem_string,
175*d9f75844SAndroid Build Coastguard Worker std::string* der) {
176*d9f75844SAndroid Build Coastguard Worker // Find the inner body. We need this to fulfill the contract of returning
177*d9f75844SAndroid Build Coastguard Worker // pem_length.
178*d9f75844SAndroid Build Coastguard Worker std::string pem_type_str(pem_type);
179*d9f75844SAndroid Build Coastguard Worker size_t header = pem_string.find("-----BEGIN " + pem_type_str + "-----");
180*d9f75844SAndroid Build Coastguard Worker if (header == absl::string_view::npos) {
181*d9f75844SAndroid Build Coastguard Worker return false;
182*d9f75844SAndroid Build Coastguard Worker }
183*d9f75844SAndroid Build Coastguard Worker size_t body = pem_string.find('\n', header);
184*d9f75844SAndroid Build Coastguard Worker if (body == absl::string_view::npos) {
185*d9f75844SAndroid Build Coastguard Worker return false;
186*d9f75844SAndroid Build Coastguard Worker }
187*d9f75844SAndroid Build Coastguard Worker size_t trailer = pem_string.find("-----END " + pem_type_str + "-----");
188*d9f75844SAndroid Build Coastguard Worker if (trailer == absl::string_view::npos) {
189*d9f75844SAndroid Build Coastguard Worker return false;
190*d9f75844SAndroid Build Coastguard Worker }
191*d9f75844SAndroid Build Coastguard Worker std::string inner(pem_string.substr(body + 1, trailer - (body + 1)));
192*d9f75844SAndroid Build Coastguard Worker *der = Base64::Decode(inner, Base64::DO_PARSE_WHITE | Base64::DO_PAD_ANY |
193*d9f75844SAndroid Build Coastguard Worker Base64::DO_TERM_BUFFER);
194*d9f75844SAndroid Build Coastguard Worker return true;
195*d9f75844SAndroid Build Coastguard Worker }
196*d9f75844SAndroid Build Coastguard Worker
DerToPem(absl::string_view pem_type,const unsigned char * data,size_t length)197*d9f75844SAndroid Build Coastguard Worker std::string SSLIdentity::DerToPem(absl::string_view pem_type,
198*d9f75844SAndroid Build Coastguard Worker const unsigned char* data,
199*d9f75844SAndroid Build Coastguard Worker size_t length) {
200*d9f75844SAndroid Build Coastguard Worker rtc::StringBuilder result;
201*d9f75844SAndroid Build Coastguard Worker result << "-----BEGIN " << pem_type << "-----\n";
202*d9f75844SAndroid Build Coastguard Worker
203*d9f75844SAndroid Build Coastguard Worker std::string b64_encoded;
204*d9f75844SAndroid Build Coastguard Worker Base64::EncodeFromArray(data, length, &b64_encoded);
205*d9f75844SAndroid Build Coastguard Worker // Divide the Base-64 encoded data into 64-character chunks, as per 4.3.2.4
206*d9f75844SAndroid Build Coastguard Worker // of RFC 1421.
207*d9f75844SAndroid Build Coastguard Worker static const size_t kChunkSize = 64;
208*d9f75844SAndroid Build Coastguard Worker size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize;
209*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0, chunk_offset = 0; i < chunks;
210*d9f75844SAndroid Build Coastguard Worker ++i, chunk_offset += kChunkSize) {
211*d9f75844SAndroid Build Coastguard Worker result << b64_encoded.substr(chunk_offset, kChunkSize);
212*d9f75844SAndroid Build Coastguard Worker result << "\n";
213*d9f75844SAndroid Build Coastguard Worker }
214*d9f75844SAndroid Build Coastguard Worker result << "-----END " << pem_type << "-----\n";
215*d9f75844SAndroid Build Coastguard Worker return result.Release();
216*d9f75844SAndroid Build Coastguard Worker }
217*d9f75844SAndroid Build Coastguard Worker
218*d9f75844SAndroid Build Coastguard Worker // static
Create(absl::string_view common_name,const KeyParams & key_param,time_t certificate_lifetime)219*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SSLIdentity> SSLIdentity::Create(absl::string_view common_name,
220*d9f75844SAndroid Build Coastguard Worker const KeyParams& key_param,
221*d9f75844SAndroid Build Coastguard Worker time_t certificate_lifetime) {
222*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
223*d9f75844SAndroid Build Coastguard Worker return BoringSSLIdentity::CreateWithExpiration(common_name, key_param,
224*d9f75844SAndroid Build Coastguard Worker certificate_lifetime);
225*d9f75844SAndroid Build Coastguard Worker #else
226*d9f75844SAndroid Build Coastguard Worker return OpenSSLIdentity::CreateWithExpiration(common_name, key_param,
227*d9f75844SAndroid Build Coastguard Worker certificate_lifetime);
228*d9f75844SAndroid Build Coastguard Worker #endif
229*d9f75844SAndroid Build Coastguard Worker }
230*d9f75844SAndroid Build Coastguard Worker
231*d9f75844SAndroid Build Coastguard Worker // static
Create(absl::string_view common_name,const KeyParams & key_param)232*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SSLIdentity> SSLIdentity::Create(absl::string_view common_name,
233*d9f75844SAndroid Build Coastguard Worker const KeyParams& key_param) {
234*d9f75844SAndroid Build Coastguard Worker return Create(common_name, key_param, kDefaultCertificateLifetimeInSeconds);
235*d9f75844SAndroid Build Coastguard Worker }
236*d9f75844SAndroid Build Coastguard Worker
237*d9f75844SAndroid Build Coastguard Worker // static
Create(absl::string_view common_name,KeyType key_type)238*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SSLIdentity> SSLIdentity::Create(absl::string_view common_name,
239*d9f75844SAndroid Build Coastguard Worker KeyType key_type) {
240*d9f75844SAndroid Build Coastguard Worker return Create(common_name, KeyParams(key_type),
241*d9f75844SAndroid Build Coastguard Worker kDefaultCertificateLifetimeInSeconds);
242*d9f75844SAndroid Build Coastguard Worker }
243*d9f75844SAndroid Build Coastguard Worker
244*d9f75844SAndroid Build Coastguard Worker // static
CreateForTest(const SSLIdentityParams & params)245*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SSLIdentity> SSLIdentity::CreateForTest(
246*d9f75844SAndroid Build Coastguard Worker const SSLIdentityParams& params) {
247*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
248*d9f75844SAndroid Build Coastguard Worker return BoringSSLIdentity::CreateForTest(params);
249*d9f75844SAndroid Build Coastguard Worker #else
250*d9f75844SAndroid Build Coastguard Worker return OpenSSLIdentity::CreateForTest(params);
251*d9f75844SAndroid Build Coastguard Worker #endif
252*d9f75844SAndroid Build Coastguard Worker }
253*d9f75844SAndroid Build Coastguard Worker
254*d9f75844SAndroid Build Coastguard Worker // Construct an identity from a private key and a certificate.
255*d9f75844SAndroid Build Coastguard Worker // static
CreateFromPEMStrings(absl::string_view private_key,absl::string_view certificate)256*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SSLIdentity> SSLIdentity::CreateFromPEMStrings(
257*d9f75844SAndroid Build Coastguard Worker absl::string_view private_key,
258*d9f75844SAndroid Build Coastguard Worker absl::string_view certificate) {
259*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
260*d9f75844SAndroid Build Coastguard Worker return BoringSSLIdentity::CreateFromPEMStrings(private_key, certificate);
261*d9f75844SAndroid Build Coastguard Worker #else
262*d9f75844SAndroid Build Coastguard Worker return OpenSSLIdentity::CreateFromPEMStrings(private_key, certificate);
263*d9f75844SAndroid Build Coastguard Worker #endif
264*d9f75844SAndroid Build Coastguard Worker }
265*d9f75844SAndroid Build Coastguard Worker
266*d9f75844SAndroid Build Coastguard Worker // Construct an identity from a private key and a certificate chain.
267*d9f75844SAndroid Build Coastguard Worker // static
CreateFromPEMChainStrings(absl::string_view private_key,absl::string_view certificate_chain)268*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<SSLIdentity> SSLIdentity::CreateFromPEMChainStrings(
269*d9f75844SAndroid Build Coastguard Worker absl::string_view private_key,
270*d9f75844SAndroid Build Coastguard Worker absl::string_view certificate_chain) {
271*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
272*d9f75844SAndroid Build Coastguard Worker return BoringSSLIdentity::CreateFromPEMChainStrings(private_key,
273*d9f75844SAndroid Build Coastguard Worker certificate_chain);
274*d9f75844SAndroid Build Coastguard Worker #else
275*d9f75844SAndroid Build Coastguard Worker return OpenSSLIdentity::CreateFromPEMChainStrings(private_key,
276*d9f75844SAndroid Build Coastguard Worker certificate_chain);
277*d9f75844SAndroid Build Coastguard Worker #endif
278*d9f75844SAndroid Build Coastguard Worker }
279*d9f75844SAndroid Build Coastguard Worker
operator ==(const SSLIdentity & a,const SSLIdentity & b)280*d9f75844SAndroid Build Coastguard Worker bool operator==(const SSLIdentity& a, const SSLIdentity& b) {
281*d9f75844SAndroid Build Coastguard Worker #ifdef OPENSSL_IS_BORINGSSL
282*d9f75844SAndroid Build Coastguard Worker return static_cast<const BoringSSLIdentity&>(a) ==
283*d9f75844SAndroid Build Coastguard Worker static_cast<const BoringSSLIdentity&>(b);
284*d9f75844SAndroid Build Coastguard Worker #else
285*d9f75844SAndroid Build Coastguard Worker return static_cast<const OpenSSLIdentity&>(a) ==
286*d9f75844SAndroid Build Coastguard Worker static_cast<const OpenSSLIdentity&>(b);
287*d9f75844SAndroid Build Coastguard Worker #endif
288*d9f75844SAndroid Build Coastguard Worker }
operator !=(const SSLIdentity & a,const SSLIdentity & b)289*d9f75844SAndroid Build Coastguard Worker bool operator!=(const SSLIdentity& a, const SSLIdentity& b) {
290*d9f75844SAndroid Build Coastguard Worker return !(a == b);
291*d9f75844SAndroid Build Coastguard Worker }
292*d9f75844SAndroid Build Coastguard Worker
293*d9f75844SAndroid Build Coastguard Worker } // namespace rtc
294