• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 // Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
12 #if HAVE_CONFIG_H
13 #include "config.h"
14 #endif  // HAVE_CONFIG_H
15 
16 #include "webrtc/base/sslidentity.h"
17 
18 #include <string>
19 
20 #include "webrtc/base/base64.h"
21 #include "webrtc/base/logging.h"
22 #include "webrtc/base/sslconfig.h"
23 
24 #if SSL_USE_SCHANNEL
25 
26 #elif SSL_USE_OPENSSL  // !SSL_USE_SCHANNEL
27 
28 #include "webrtc/base/opensslidentity.h"
29 
30 #elif SSL_USE_NSS  // !SSL_USE_SCHANNEL && !SSL_USE_OPENSSL
31 
32 #include "webrtc/base/nssidentity.h"
33 
34 #endif  // SSL_USE_SCHANNEL
35 
36 namespace rtc {
37 
38 const char kPemTypeCertificate[] = "CERTIFICATE";
39 const char kPemTypeRsaPrivateKey[] = "RSA PRIVATE KEY";
40 
PemToDer(const std::string & pem_type,const std::string & pem_string,std::string * der)41 bool SSLIdentity::PemToDer(const std::string& pem_type,
42                            const std::string& pem_string,
43                            std::string* der) {
44   // Find the inner body. We need this to fulfill the contract of
45   // returning pem_length.
46   size_t header = pem_string.find("-----BEGIN " + pem_type + "-----");
47   if (header == std::string::npos)
48     return false;
49 
50   size_t body = pem_string.find("\n", header);
51   if (body == std::string::npos)
52     return false;
53 
54   size_t trailer = pem_string.find("-----END " + pem_type + "-----");
55   if (trailer == std::string::npos)
56     return false;
57 
58   std::string inner = pem_string.substr(body + 1, trailer - (body + 1));
59 
60   *der = Base64::Decode(inner, Base64::DO_PARSE_WHITE |
61                         Base64::DO_PAD_ANY |
62                         Base64::DO_TERM_BUFFER);
63   return true;
64 }
65 
DerToPem(const std::string & pem_type,const unsigned char * data,size_t length)66 std::string SSLIdentity::DerToPem(const std::string& pem_type,
67                                   const unsigned char* data,
68                                   size_t length) {
69   std::stringstream result;
70 
71   result << "-----BEGIN " << pem_type << "-----\n";
72 
73   std::string b64_encoded;
74   Base64::EncodeFromArray(data, length, &b64_encoded);
75 
76   // Divide the Base-64 encoded data into 64-character chunks, as per
77   // 4.3.2.4 of RFC 1421.
78   static const size_t kChunkSize = 64;
79   size_t chunks = (b64_encoded.size() + (kChunkSize - 1)) / kChunkSize;
80   for (size_t i = 0, chunk_offset = 0; i < chunks;
81        ++i, chunk_offset += kChunkSize) {
82     result << b64_encoded.substr(chunk_offset, kChunkSize);
83     result << "\n";
84   }
85 
86   result << "-----END " << pem_type << "-----\n";
87 
88   return result.str();
89 }
90 
91 #if SSL_USE_SCHANNEL
92 
FromPEMString(const std::string & pem_string)93 SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) {
94   return NULL;
95 }
96 
Generate(const std::string & common_name)97 SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
98   return NULL;
99 }
100 
GenerateForTest(const SSLIdentityParams & params)101 SSLIdentity* GenerateForTest(const SSLIdentityParams& params) {
102   return NULL;
103 }
104 
FromPEMStrings(const std::string & private_key,const std::string & certificate)105 SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key,
106                                          const std::string& certificate) {
107   return NULL;
108 }
109 
110 #elif SSL_USE_OPENSSL  // !SSL_USE_SCHANNEL
111 
FromPEMString(const std::string & pem_string)112 SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) {
113   return OpenSSLCertificate::FromPEMString(pem_string);
114 }
115 
Generate(const std::string & common_name)116 SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
117   return OpenSSLIdentity::Generate(common_name);
118 }
119 
GenerateForTest(const SSLIdentityParams & params)120 SSLIdentity* SSLIdentity::GenerateForTest(const SSLIdentityParams& params) {
121   return OpenSSLIdentity::GenerateForTest(params);
122 }
123 
FromPEMStrings(const std::string & private_key,const std::string & certificate)124 SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key,
125                                          const std::string& certificate) {
126   return OpenSSLIdentity::FromPEMStrings(private_key, certificate);
127 }
128 
129 #elif SSL_USE_NSS  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL
130 
FromPEMString(const std::string & pem_string)131 SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) {
132   return NSSCertificate::FromPEMString(pem_string);
133 }
134 
Generate(const std::string & common_name)135 SSLIdentity* SSLIdentity::Generate(const std::string& common_name) {
136   return NSSIdentity::Generate(common_name);
137 }
138 
GenerateForTest(const SSLIdentityParams & params)139 SSLIdentity* SSLIdentity::GenerateForTest(const SSLIdentityParams& params) {
140   return NSSIdentity::GenerateForTest(params);
141 }
142 
FromPEMStrings(const std::string & private_key,const std::string & certificate)143 SSLIdentity* SSLIdentity::FromPEMStrings(const std::string& private_key,
144                                          const std::string& certificate) {
145   return NSSIdentity::FromPEMStrings(private_key, certificate);
146 }
147 
148 #else  // !SSL_USE_OPENSSL && !SSL_USE_SCHANNEL && !SSL_USE_NSS
149 
150 #error "No SSL implementation"
151 
152 #endif  // SSL_USE_SCHANNEL
153 
154 }  // namespace rtc
155