OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 // Handling of certificates and keypairs for SSLStreamAdapter's peer mode. | 11 // Handling of certificates and keypairs for SSLStreamAdapter's peer mode. |
12 | 12 |
13 #ifndef WEBRTC_BASE_SSLIDENTITY_H_ | 13 #ifndef WEBRTC_BASE_SSLIDENTITY_H_ |
14 #define WEBRTC_BASE_SSLIDENTITY_H_ | 14 #define WEBRTC_BASE_SSLIDENTITY_H_ |
15 | 15 |
16 #include <algorithm> | |
17 #include <memory> | |
18 #include <string> | |
19 #include <vector> | |
20 | 16 |
21 #include "webrtc/base/buffer.h" | 17 // This header is deprecated and is just left here temporarily during |
22 #include "webrtc/base/constructormagic.h" | 18 // refactoring. See https://bugs.webrtc.org/7634 for more details. |
23 #include "webrtc/base/messagedigest.h" | 19 #include "webrtc/rtc_base/sslidentity.h" |
24 #include "webrtc/base/timeutils.h" | |
25 | |
26 namespace rtc { | |
27 | |
28 // Forward declaration due to circular dependency with SSLCertificate. | |
29 class SSLCertChain; | |
30 | |
31 struct SSLCertificateStats { | |
32 SSLCertificateStats(std::string&& fingerprint, | |
33 std::string&& fingerprint_algorithm, | |
34 std::string&& base64_certificate, | |
35 std::unique_ptr<SSLCertificateStats>&& issuer); | |
36 ~SSLCertificateStats(); | |
37 std::string fingerprint; | |
38 std::string fingerprint_algorithm; | |
39 std::string base64_certificate; | |
40 std::unique_ptr<SSLCertificateStats> issuer; | |
41 }; | |
42 | |
43 // Abstract interface overridden by SSL library specific | |
44 // implementations. | |
45 | |
46 // A somewhat opaque type used to encapsulate a certificate. | |
47 // Wraps the SSL library's notion of a certificate, with reference counting. | |
48 // The SSLCertificate object is pretty much immutable once created. | |
49 // (The OpenSSL implementation only does reference counting and | |
50 // possibly caching of intermediate results.) | |
51 class SSLCertificate { | |
52 public: | |
53 // Parses and builds a certificate from a PEM encoded string. | |
54 // Returns null on failure. | |
55 // The length of the string representation of the certificate is | |
56 // stored in *pem_length if it is non-null, and only if | |
57 // parsing was successful. | |
58 // Caller is responsible for freeing the returned object. | |
59 static SSLCertificate* FromPEMString(const std::string& pem_string); | |
60 virtual ~SSLCertificate() {} | |
61 | |
62 // Returns a new SSLCertificate object instance wrapping the same | |
63 // underlying certificate, including its chain if present. | |
64 // Caller is responsible for freeing the returned object. | |
65 virtual SSLCertificate* GetReference() const = 0; | |
66 | |
67 // Provides the cert chain, or null. The chain includes a copy of each | |
68 // certificate, excluding the leaf. | |
69 virtual std::unique_ptr<SSLCertChain> GetChain() const = 0; | |
70 | |
71 // Returns a PEM encoded string representation of the certificate. | |
72 virtual std::string ToPEMString() const = 0; | |
73 | |
74 // Provides a DER encoded binary representation of the certificate. | |
75 virtual void ToDER(Buffer* der_buffer) const = 0; | |
76 | |
77 // Gets the name of the digest algorithm that was used to compute this | |
78 // certificate's signature. | |
79 virtual bool GetSignatureDigestAlgorithm(std::string* algorithm) const = 0; | |
80 | |
81 // Compute the digest of the certificate given algorithm | |
82 virtual bool ComputeDigest(const std::string& algorithm, | |
83 unsigned char* digest, | |
84 size_t size, | |
85 size_t* length) const = 0; | |
86 | |
87 // Returns the time in seconds relative to epoch, 1970-01-01T00:00:00Z (UTC), | |
88 // or -1 if an expiration time could not be retrieved. | |
89 virtual int64_t CertificateExpirationTime() const = 0; | |
90 | |
91 // Gets information (fingerprint, etc.) about this certificate and its chain | |
92 // (if it has a certificate chain). This is used for certificate stats, see | |
93 // https://w3c.github.io/webrtc-stats/#certificatestats-dict*. | |
94 std::unique_ptr<SSLCertificateStats> GetStats() const; | |
95 | |
96 private: | |
97 std::unique_ptr<SSLCertificateStats> GetStats( | |
98 std::unique_ptr<SSLCertificateStats> issuer) const; | |
99 }; | |
100 | |
101 // SSLCertChain is a simple wrapper for a vector of SSLCertificates. It serves | |
102 // primarily to ensure proper memory management (especially deletion) of the | |
103 // SSLCertificate pointers. | |
104 class SSLCertChain { | |
105 public: | |
106 // These constructors copy the provided SSLCertificate(s), so the caller | |
107 // retains ownership. | |
108 explicit SSLCertChain(const std::vector<SSLCertificate*>& certs); | |
109 explicit SSLCertChain(const SSLCertificate* cert); | |
110 ~SSLCertChain(); | |
111 | |
112 // Vector access methods. | |
113 size_t GetSize() const { return certs_.size(); } | |
114 | |
115 // Returns a temporary reference, only valid until the chain is destroyed. | |
116 const SSLCertificate& Get(size_t pos) const { return *(certs_[pos]); } | |
117 | |
118 // Returns a new SSLCertChain object instance wrapping the same underlying | |
119 // certificate chain. Caller is responsible for freeing the returned object. | |
120 SSLCertChain* Copy() const { | |
121 return new SSLCertChain(certs_); | |
122 } | |
123 | |
124 private: | |
125 // Helper function for duplicating a vector of certificates. | |
126 static SSLCertificate* DupCert(const SSLCertificate* cert) { | |
127 return cert->GetReference(); | |
128 } | |
129 | |
130 // Helper function for deleting a vector of certificates. | |
131 static void DeleteCert(SSLCertificate* cert) { delete cert; } | |
132 | |
133 std::vector<SSLCertificate*> certs_; | |
134 | |
135 RTC_DISALLOW_COPY_AND_ASSIGN(SSLCertChain); | |
136 }; | |
137 | |
138 // KT_LAST is intended for vector declarations and loops over all key types; | |
139 // it does not represent any key type in itself. | |
140 // KT_DEFAULT is used as the default KeyType for KeyParams. | |
141 enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_ECDSA }; | |
142 | |
143 static const int kRsaDefaultModSize = 1024; | |
144 static const int kRsaDefaultExponent = 0x10001; // = 2^16+1 = 65537 | |
145 static const int kRsaMinModSize = 1024; | |
146 static const int kRsaMaxModSize = 8192; | |
147 | |
148 // Certificate default validity lifetime. | |
149 static const int kDefaultCertificateLifetimeInSeconds = | |
150 60 * 60 * 24 * 30; // 30 days | |
151 // Certificate validity window. | |
152 // This is to compensate for slightly incorrect system clocks. | |
153 static const int kCertificateWindowInSeconds = -60 * 60 * 24; | |
154 | |
155 struct RSAParams { | |
156 unsigned int mod_size; | |
157 unsigned int pub_exp; | |
158 }; | |
159 | |
160 enum ECCurve { EC_NIST_P256, /* EC_FANCY, */ EC_LAST }; | |
161 | |
162 class KeyParams { | |
163 public: | |
164 // Generate a KeyParams object from a simple KeyType, using default params. | |
165 explicit KeyParams(KeyType key_type = KT_DEFAULT); | |
166 | |
167 // Generate a a KeyParams for RSA with explicit parameters. | |
168 static KeyParams RSA(int mod_size = kRsaDefaultModSize, | |
169 int pub_exp = kRsaDefaultExponent); | |
170 | |
171 // Generate a a KeyParams for ECDSA specifying the curve. | |
172 static KeyParams ECDSA(ECCurve curve = EC_NIST_P256); | |
173 | |
174 // Check validity of a KeyParams object. Since the factory functions have | |
175 // no way of returning errors, this function can be called after creation | |
176 // to make sure the parameters are OK. | |
177 bool IsValid() const; | |
178 | |
179 RSAParams rsa_params() const; | |
180 | |
181 ECCurve ec_curve() const; | |
182 | |
183 KeyType type() const { return type_; } | |
184 | |
185 private: | |
186 KeyType type_; | |
187 union { | |
188 RSAParams rsa; | |
189 ECCurve curve; | |
190 } params_; | |
191 }; | |
192 | |
193 // TODO(hbos): Remove once rtc::KeyType (to be modified) and | |
194 // blink::WebRTCKeyType (to be landed) match. By using this function in Chromium | |
195 // appropriately we can change KeyType enum -> class without breaking Chromium. | |
196 KeyType IntKeyTypeFamilyToKeyType(int key_type_family); | |
197 | |
198 // Parameters for generating a certificate. If |common_name| is non-empty, it | |
199 // will be used for the certificate's subject and issuer name, otherwise a | |
200 // random string will be used. | |
201 struct SSLIdentityParams { | |
202 std::string common_name; | |
203 time_t not_before; // Absolute time since epoch in seconds. | |
204 time_t not_after; // Absolute time since epoch in seconds. | |
205 KeyParams key_params; | |
206 }; | |
207 | |
208 // Our identity in an SSL negotiation: a keypair and certificate (both | |
209 // with the same public key). | |
210 // This too is pretty much immutable once created. | |
211 class SSLIdentity { | |
212 public: | |
213 // Generates an identity (keypair and self-signed certificate). If | |
214 // |common_name| is non-empty, it will be used for the certificate's subject | |
215 // and issuer name, otherwise a random string will be used. The key type and | |
216 // parameters are defined in |key_param|. The certificate's lifetime in | |
217 // seconds from the current time is defined in |certificate_lifetime|; it | |
218 // should be a non-negative number. | |
219 // Returns null on failure. | |
220 // Caller is responsible for freeing the returned object. | |
221 static SSLIdentity* GenerateWithExpiration(const std::string& common_name, | |
222 const KeyParams& key_param, | |
223 time_t certificate_lifetime); | |
224 static SSLIdentity* Generate(const std::string& common_name, | |
225 const KeyParams& key_param); | |
226 static SSLIdentity* Generate(const std::string& common_name, | |
227 KeyType key_type); | |
228 | |
229 // Generates an identity with the specified validity period. | |
230 // TODO(torbjorng): Now that Generate() accepts relevant params, make tests | |
231 // use that instead of this function. | |
232 static SSLIdentity* GenerateForTest(const SSLIdentityParams& params); | |
233 | |
234 // Construct an identity from a private key and a certificate. | |
235 static SSLIdentity* FromPEMStrings(const std::string& private_key, | |
236 const std::string& certificate); | |
237 | |
238 virtual ~SSLIdentity() {} | |
239 | |
240 // Returns a new SSLIdentity object instance wrapping the same | |
241 // identity information. | |
242 // Caller is responsible for freeing the returned object. | |
243 // TODO(hbos,torbjorng): Rename to a less confusing name. | |
244 virtual SSLIdentity* GetReference() const = 0; | |
245 | |
246 // Returns a temporary reference to the certificate. | |
247 virtual const SSLCertificate& certificate() const = 0; | |
248 virtual std::string PrivateKeyToPEMString() const = 0; | |
249 virtual std::string PublicKeyToPEMString() const = 0; | |
250 | |
251 // Helpers for parsing converting between PEM and DER format. | |
252 static bool PemToDer(const std::string& pem_type, | |
253 const std::string& pem_string, | |
254 std::string* der); | |
255 static std::string DerToPem(const std::string& pem_type, | |
256 const unsigned char* data, | |
257 size_t length); | |
258 }; | |
259 | |
260 bool operator==(const SSLIdentity& a, const SSLIdentity& b); | |
261 bool operator!=(const SSLIdentity& a, const SSLIdentity& b); | |
262 | |
263 // Convert from ASN1 time as restricted by RFC 5280 to seconds from 1970-01-01 | |
264 // 00.00 ("epoch"). If the ASN1 time cannot be read, return -1. The data at | |
265 // |s| is not 0-terminated; its char count is defined by |length|. | |
266 int64_t ASN1TimeToSec(const unsigned char* s, size_t length, bool long_format); | |
267 | |
268 extern const char kPemTypeCertificate[]; | |
269 extern const char kPemTypeRsaPrivateKey[]; | |
270 extern const char kPemTypeEcPrivateKey[]; | |
271 | |
272 } // namespace rtc | |
273 | 20 |
274 #endif // WEBRTC_BASE_SSLIDENTITY_H_ | 21 #endif // WEBRTC_BASE_SSLIDENTITY_H_ |
OLD | NEW |