xref: /aosp_15_r20/external/webrtc/rtc_base/ssl_identity.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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