1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Handling of certificates and keypairs for SSLStreamAdapter's peer mode.
#ifndef RTC_BASE_SSL_IDENTITY_H_
#define RTC_BASE_SSL_IDENTITY_H_
#include <stdint.h>
#include <ctime>
#include <memory>
#include <string>
#include "absl/strings/string_view.h"
#include "rtc_base/system/rtc_export.h"
namespace rtc {
class SSLCertChain;
class SSLCertificate;
// KT_LAST is intended for vector declarations and loops over all key types;
// it does not represent any key type in itself.
// KT_DEFAULT is used as the default KeyType for KeyParams.
enum KeyType { KT_RSA, KT_ECDSA, KT_LAST, KT_DEFAULT = KT_ECDSA };
static const int kRsaDefaultModSize = 1024;
static const int kRsaDefaultExponent = 0x10001; // = 2^16+1 = 65537
static const int kRsaMinModSize = 1024;
static const int kRsaMaxModSize = 8192;
// Certificate default validity lifetime.
static const int kDefaultCertificateLifetimeInSeconds =
60 * 60 * 24 * 30; // 30 days
// Certificate validity window.
// This is to compensate for slightly incorrect system clocks.
static const int kCertificateWindowInSeconds = -60 * 60 * 24;
struct RSAParams {
unsigned int mod_size;
unsigned int pub_exp;
};
enum ECCurve { EC_NIST_P256, /* EC_FANCY, */ EC_LAST };
class RTC_EXPORT KeyParams {
public:
// Generate a KeyParams object from a simple KeyType, using default params.
explicit KeyParams(KeyType key_type = KT_DEFAULT);
// Generate a a KeyParams for RSA with explicit parameters.
static KeyParams RSA(int mod_size = kRsaDefaultModSize,
int pub_exp = kRsaDefaultExponent);
// Generate a a KeyParams for ECDSA specifying the curve.
static KeyParams ECDSA(ECCurve curve = EC_NIST_P256);
// Check validity of a KeyParams object. Since the factory functions have
// no way of returning errors, this function can be called after creation
// to make sure the parameters are OK.
bool IsValid() const;
RSAParams rsa_params() const;
ECCurve ec_curve() const;
KeyType type() const { return type_; }
private:
KeyType type_;
union {
RSAParams rsa;
ECCurve curve;
} params_;
};
// TODO(hbos): Remove once rtc::KeyType (to be modified) and
// blink::WebRTCKeyType (to be landed) match. By using this function in Chromium
// appropriately we can change KeyType enum -> class without breaking Chromium.
KeyType IntKeyTypeFamilyToKeyType(int key_type_family);
// Parameters for generating a certificate. If `common_name` is non-empty, it
// will be used for the certificate's subject and issuer name, otherwise a
// random string will be used.
struct SSLIdentityParams {
std::string common_name;
time_t not_before; // Absolute time since epoch in seconds.
time_t not_after; // Absolute time since epoch in seconds.
KeyParams key_params;
};
// Our identity in an SSL negotiation: a keypair and certificate (both
// with the same public key).
// This too is pretty much immutable once created.
class RTC_EXPORT SSLIdentity {
public:
// Generates an identity (keypair and self-signed certificate). If
// `common_name` is non-empty, it will be used for the certificate's subject
// and issuer name, otherwise a random string will be used. The key type and
// parameters are defined in `key_param`. The certificate's lifetime in
// seconds from the current time is defined in `certificate_lifetime`; it
// should be a non-negative number.
// Returns null on failure.
// Caller is responsible for freeing the returned object.
static std::unique_ptr<SSLIdentity> Create(absl::string_view common_name,
const KeyParams& key_param,
time_t certificate_lifetime);
static std::unique_ptr<SSLIdentity> Create(absl::string_view common_name,
const KeyParams& key_param);
static std::unique_ptr<SSLIdentity> Create(absl::string_view common_name,
KeyType key_type);
// Allows fine-grained control over expiration time.
static std::unique_ptr<SSLIdentity> CreateForTest(
const SSLIdentityParams& params);
// Construct an identity from a private key and a certificate.
static std::unique_ptr<SSLIdentity> CreateFromPEMStrings(
absl::string_view private_key,
absl::string_view certificate);
// Construct an identity from a private key and a certificate chain.
static std::unique_ptr<SSLIdentity> CreateFromPEMChainStrings(
absl::string_view private_key,
absl::string_view certificate_chain);
virtual ~SSLIdentity() {}
// Returns a new SSLIdentity object instance wrapping the same
// identity information.
std::unique_ptr<SSLIdentity> Clone() const { return CloneInternal(); }
// Returns a temporary reference to the end-entity (leaf) certificate.
virtual const SSLCertificate& certificate() const = 0;
// Returns a temporary reference to the entire certificate chain.
virtual const SSLCertChain& cert_chain() const = 0;
virtual std::string PrivateKeyToPEMString() const = 0;
virtual std::string PublicKeyToPEMString() const = 0;
// Helpers for parsing converting between PEM and DER format.
static bool PemToDer(absl::string_view pem_type,
absl::string_view pem_string,
std::string* der);
static std::string DerToPem(absl::string_view pem_type,
const unsigned char* data,
size_t length);
protected:
virtual std::unique_ptr<SSLIdentity> CloneInternal() const = 0;
};
bool operator==(const SSLIdentity& a, const SSLIdentity& b);
bool operator!=(const SSLIdentity& a, const SSLIdentity& b);
// Convert from ASN1 time as restricted by RFC 5280 to seconds from 1970-01-01
// 00.00 ("epoch"). If the ASN1 time cannot be read, return -1. The data at
// `s` is not 0-terminated; its char count is defined by `length`.
int64_t ASN1TimeToSec(const unsigned char* s, size_t length, bool long_format);
extern const char kPemTypeCertificate[];
extern const char kPemTypeRsaPrivateKey[];
extern const char kPemTypeEcPrivateKey[];
} // namespace rtc
#endif // RTC_BASE_SSL_IDENTITY_H_
|