OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2012 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 #ifndef WEBRTC_P2P_BASE_DTLSTRANSPORT_H_ | |
12 #define WEBRTC_P2P_BASE_DTLSTRANSPORT_H_ | |
13 | |
14 #include <memory> | |
15 | |
16 #include "webrtc/p2p/base/dtlstransportchannel.h" | |
17 #include "webrtc/p2p/base/transport.h" | |
18 | |
19 namespace rtc { | |
20 class SSLIdentity; | |
21 } | |
22 | |
23 namespace cricket { | |
24 | |
25 class PortAllocator; | |
26 | |
27 // Base should be a descendant of cricket::Transport and have a constructor | |
28 // that takes a transport name and PortAllocator. | |
29 // | |
30 // Everything in this class should be called on the network thread. | |
31 template<class Base> | |
32 class DtlsTransport : public Base { | |
33 public: | |
34 DtlsTransport(const std::string& name, | |
35 PortAllocator* allocator, | |
36 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) | |
37 : Base(name, allocator), | |
38 certificate_(certificate), | |
39 secure_role_(rtc::SSL_CLIENT), | |
40 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_12) {} | |
41 | |
42 ~DtlsTransport() { | |
43 Base::DestroyAllChannels(); | |
44 } | |
45 | |
46 void SetLocalCertificate( | |
47 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override { | |
48 certificate_ = certificate; | |
49 } | |
50 bool GetLocalCertificate( | |
51 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override { | |
52 if (!certificate_) | |
53 return false; | |
54 | |
55 *certificate = certificate_; | |
56 return true; | |
57 } | |
58 | |
59 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override { | |
60 ssl_max_version_ = version; | |
61 return true; | |
62 } | |
63 | |
64 bool ApplyLocalTransportDescription(TransportChannelImpl* channel, | |
65 std::string* error_desc) override { | |
66 rtc::SSLFingerprint* local_fp = | |
67 Base::local_description()->identity_fingerprint.get(); | |
68 | |
69 if (!local_fp) { | |
70 certificate_ = nullptr; | |
71 } else if (!Base::VerifyCertificateFingerprint(certificate_.get(), local_fp, | |
72 error_desc)) { | |
73 return false; | |
74 } | |
75 | |
76 if (!channel->SetLocalCertificate(certificate_)) { | |
77 return BadTransportDescription("Failed to set local identity.", | |
78 error_desc); | |
79 } | |
80 | |
81 // Apply the description in the base class. | |
82 return Base::ApplyLocalTransportDescription(channel, error_desc); | |
83 } | |
84 | |
85 bool NegotiateTransportDescription(ContentAction local_role, | |
86 std::string* error_desc) override { | |
87 if (!Base::local_description() || !Base::remote_description()) { | |
88 const std::string msg = "Local and Remote description must be set before " | |
89 "transport descriptions are negotiated"; | |
90 return BadTransportDescription(msg, error_desc); | |
91 } | |
92 rtc::SSLFingerprint* local_fp = | |
93 Base::local_description()->identity_fingerprint.get(); | |
94 rtc::SSLFingerprint* remote_fp = | |
95 Base::remote_description()->identity_fingerprint.get(); | |
96 if (remote_fp && local_fp) { | |
97 remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); | |
98 if (!Base::NegotiateRole(local_role, &secure_role_, error_desc)) { | |
99 return false; | |
100 } | |
101 } else if (local_fp && (local_role == CA_ANSWER)) { | |
102 return BadTransportDescription( | |
103 "Local fingerprint supplied when caller didn't offer DTLS.", | |
104 error_desc); | |
105 } else { | |
106 // We are not doing DTLS | |
107 remote_fingerprint_.reset(new rtc::SSLFingerprint("", nullptr, 0)); | |
108 } | |
109 // Now run the negotiation for the base class. | |
110 return Base::NegotiateTransportDescription(local_role, error_desc); | |
111 } | |
112 | |
113 DtlsTransportChannelWrapper* CreateTransportChannel(int component) override { | |
114 DtlsTransportChannelWrapper* channel = new DtlsTransportChannelWrapper( | |
115 Base::CreateTransportChannel(component)); | |
116 channel->SetSslMaxProtocolVersion(ssl_max_version_); | |
117 return channel; | |
118 } | |
119 | |
120 void DestroyTransportChannel(TransportChannelImpl* channel) override { | |
121 // Kind of ugly, but this lets us do the exact inverse of the create. | |
122 DtlsTransportChannelWrapper* dtls_channel = | |
123 static_cast<DtlsTransportChannelWrapper*>(channel); | |
124 TransportChannelImpl* base_channel = dtls_channel->channel(); | |
125 delete dtls_channel; | |
126 Base::DestroyTransportChannel(base_channel); | |
127 } | |
128 | |
129 bool GetSslRole(rtc::SSLRole* ssl_role) const override { | |
130 ASSERT(ssl_role != NULL); | |
131 *ssl_role = secure_role_; | |
132 return true; | |
133 } | |
134 | |
135 private: | |
136 bool ApplyNegotiatedTransportDescription(TransportChannelImpl* channel, | |
137 std::string* error_desc) override { | |
138 // Set ssl role. Role must be set before fingerprint is applied, which | |
139 // initiates DTLS setup. | |
140 if (!channel->SetSslRole(secure_role_)) { | |
141 return BadTransportDescription("Failed to set ssl role for the channel.", | |
142 error_desc); | |
143 } | |
144 // Apply remote fingerprint. | |
145 if (!channel->SetRemoteFingerprint(remote_fingerprint_->algorithm, | |
146 reinterpret_cast<const uint8_t*>( | |
147 remote_fingerprint_->digest.data()), | |
148 remote_fingerprint_->digest.size())) { | |
149 return BadTransportDescription("Failed to apply remote fingerprint.", | |
150 error_desc); | |
151 } | |
152 return Base::ApplyNegotiatedTransportDescription(channel, error_desc); | |
153 } | |
154 | |
155 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | |
156 rtc::SSLRole secure_role_; | |
157 rtc::SSLProtocolVersion ssl_max_version_; | |
158 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_; | |
159 }; | |
160 | |
161 } // namespace cricket | |
162 | |
163 #endif // WEBRTC_P2P_BASE_DTLSTRANSPORT_H_ | |
OLD | NEW |