OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2012 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 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override { | 59 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override { |
60 ssl_max_version_ = version; | 60 ssl_max_version_ = version; |
61 return true; | 61 return true; |
62 } | 62 } |
63 | 63 |
64 bool ApplyLocalTransportDescription(TransportChannelImpl* channel, | 64 bool ApplyLocalTransportDescription(TransportChannelImpl* channel, |
65 std::string* error_desc) override { | 65 std::string* error_desc) override { |
66 rtc::SSLFingerprint* local_fp = | 66 rtc::SSLFingerprint* local_fp = |
67 Base::local_description()->identity_fingerprint.get(); | 67 Base::local_description()->identity_fingerprint.get(); |
68 | 68 |
69 if (local_fp) { | 69 if (!local_fp) { |
70 // Sanity check local fingerprint. | |
71 if (certificate_) { | |
72 std::unique_ptr<rtc::SSLFingerprint> local_fp_tmp( | |
73 rtc::SSLFingerprint::Create(local_fp->algorithm, | |
74 certificate_->identity())); | |
75 ASSERT(local_fp_tmp.get() != NULL); | |
76 if (!(*local_fp_tmp == *local_fp)) { | |
77 std::ostringstream desc; | |
78 desc << "Local fingerprint does not match identity. Expected: "; | |
79 desc << local_fp_tmp->ToString(); | |
80 desc << " Got: " << local_fp->ToString(); | |
81 return BadTransportDescription(desc.str(), error_desc); | |
82 } | |
83 } else { | |
84 return BadTransportDescription( | |
85 "Local fingerprint provided but no identity available.", | |
86 error_desc); | |
87 } | |
88 } else { | |
89 certificate_ = nullptr; | 70 certificate_ = nullptr; |
| 71 } else if (!Base::VerifyCertificateFingerprint(certificate_.get(), local_fp, |
| 72 error_desc)) { |
| 73 return false; |
90 } | 74 } |
91 | 75 |
92 if (!channel->SetLocalCertificate(certificate_)) { | 76 if (!channel->SetLocalCertificate(certificate_)) { |
93 return BadTransportDescription("Failed to set local identity.", | 77 return BadTransportDescription("Failed to set local identity.", |
94 error_desc); | 78 error_desc); |
95 } | 79 } |
96 | 80 |
97 // Apply the description in the base class. | 81 // Apply the description in the base class. |
98 return Base::ApplyLocalTransportDescription(channel, error_desc); | 82 return Base::ApplyLocalTransportDescription(channel, error_desc); |
99 } | 83 } |
100 | 84 |
101 bool NegotiateTransportDescription(ContentAction local_role, | 85 bool NegotiateTransportDescription(ContentAction local_role, |
102 std::string* error_desc) override { | 86 std::string* error_desc) override { |
103 if (!Base::local_description() || !Base::remote_description()) { | 87 if (!Base::local_description() || !Base::remote_description()) { |
104 const std::string msg = "Local and Remote description must be set before " | 88 const std::string msg = "Local and Remote description must be set before " |
105 "transport descriptions are negotiated"; | 89 "transport descriptions are negotiated"; |
106 return BadTransportDescription(msg, error_desc); | 90 return BadTransportDescription(msg, error_desc); |
107 } | 91 } |
108 | |
109 rtc::SSLFingerprint* local_fp = | 92 rtc::SSLFingerprint* local_fp = |
110 Base::local_description()->identity_fingerprint.get(); | 93 Base::local_description()->identity_fingerprint.get(); |
111 rtc::SSLFingerprint* remote_fp = | 94 rtc::SSLFingerprint* remote_fp = |
112 Base::remote_description()->identity_fingerprint.get(); | 95 Base::remote_description()->identity_fingerprint.get(); |
113 | |
114 if (remote_fp && local_fp) { | 96 if (remote_fp && local_fp) { |
115 remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); | 97 remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); |
116 | 98 if (!Base::NegotiateRole(local_role, &secure_role_, error_desc)) { |
117 // From RFC 4145, section-4.1, The following are the values that the | 99 return false; |
118 // 'setup' attribute can take in an offer/answer exchange: | |
119 // Offer Answer | |
120 // ________________ | |
121 // active passive / holdconn | |
122 // passive active / holdconn | |
123 // actpass active / passive / holdconn | |
124 // holdconn holdconn | |
125 // | |
126 // Set the role that is most conformant with RFC 5763, Section 5, bullet 1 | |
127 // The endpoint MUST use the setup attribute defined in [RFC4145]. | |
128 // The endpoint that is the offerer MUST use the setup attribute | |
129 // value of setup:actpass and be prepared to receive a client_hello | |
130 // before it receives the answer. The answerer MUST use either a | |
131 // setup attribute value of setup:active or setup:passive. Note that | |
132 // if the answerer uses setup:passive, then the DTLS handshake will | |
133 // not begin until the answerer is received, which adds additional | |
134 // latency. setup:active allows the answer and the DTLS handshake to | |
135 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever | |
136 // party is active MUST initiate a DTLS handshake by sending a | |
137 // ClientHello over each flow (host/port quartet). | |
138 // IOW - actpass and passive modes should be treated as server and | |
139 // active as client. | |
140 ConnectionRole local_connection_role = | |
141 Base::local_description()->connection_role; | |
142 ConnectionRole remote_connection_role = | |
143 Base::remote_description()->connection_role; | |
144 | |
145 bool is_remote_server = false; | |
146 if (local_role == CA_OFFER) { | |
147 if (local_connection_role != CONNECTIONROLE_ACTPASS) { | |
148 return BadTransportDescription( | |
149 "Offerer must use actpass value for setup attribute.", | |
150 error_desc); | |
151 } | |
152 | |
153 if (remote_connection_role == CONNECTIONROLE_ACTIVE || | |
154 remote_connection_role == CONNECTIONROLE_PASSIVE || | |
155 remote_connection_role == CONNECTIONROLE_NONE) { | |
156 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); | |
157 } else { | |
158 const std::string msg = | |
159 "Answerer must use either active or passive value " | |
160 "for setup attribute."; | |
161 return BadTransportDescription(msg, error_desc); | |
162 } | |
163 // If remote is NONE or ACTIVE it will act as client. | |
164 } else { | |
165 if (remote_connection_role != CONNECTIONROLE_ACTPASS && | |
166 remote_connection_role != CONNECTIONROLE_NONE) { | |
167 return BadTransportDescription( | |
168 "Offerer must use actpass value for setup attribute.", | |
169 error_desc); | |
170 } | |
171 | |
172 if (local_connection_role == CONNECTIONROLE_ACTIVE || | |
173 local_connection_role == CONNECTIONROLE_PASSIVE) { | |
174 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); | |
175 } else { | |
176 const std::string msg = | |
177 "Answerer must use either active or passive value " | |
178 "for setup attribute."; | |
179 return BadTransportDescription(msg, error_desc); | |
180 } | |
181 | |
182 // If local is passive, local will act as server. | |
183 } | 100 } |
184 | |
185 secure_role_ = is_remote_server ? rtc::SSL_CLIENT : | |
186 rtc::SSL_SERVER; | |
187 | |
188 } else if (local_fp && (local_role == CA_ANSWER)) { | 101 } else if (local_fp && (local_role == CA_ANSWER)) { |
189 return BadTransportDescription( | 102 return BadTransportDescription( |
190 "Local fingerprint supplied when caller didn't offer DTLS.", | 103 "Local fingerprint supplied when caller didn't offer DTLS.", |
191 error_desc); | 104 error_desc); |
192 } else { | 105 } else { |
193 // We are not doing DTLS | 106 // We are not doing DTLS |
194 remote_fingerprint_.reset(new rtc::SSLFingerprint( | 107 remote_fingerprint_.reset(new rtc::SSLFingerprint("", nullptr, 0)); |
195 "", NULL, 0)); | |
196 } | 108 } |
197 | |
198 // Now run the negotiation for the base class. | 109 // Now run the negotiation for the base class. |
199 return Base::NegotiateTransportDescription(local_role, error_desc); | 110 return Base::NegotiateTransportDescription(local_role, error_desc); |
200 } | 111 } |
201 | 112 |
202 DtlsTransportChannelWrapper* CreateTransportChannel(int component) override { | 113 DtlsTransportChannelWrapper* CreateTransportChannel(int component) override { |
203 DtlsTransportChannelWrapper* channel = new DtlsTransportChannelWrapper( | 114 DtlsTransportChannelWrapper* channel = new DtlsTransportChannelWrapper( |
204 Base::CreateTransportChannel(component)); | 115 Base::CreateTransportChannel(component)); |
205 channel->SetSslMaxProtocolVersion(ssl_max_version_); | 116 channel->SetSslMaxProtocolVersion(ssl_max_version_); |
206 return channel; | 117 return channel; |
207 } | 118 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 154 |
244 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | 155 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
245 rtc::SSLRole secure_role_; | 156 rtc::SSLRole secure_role_; |
246 rtc::SSLProtocolVersion ssl_max_version_; | 157 rtc::SSLProtocolVersion ssl_max_version_; |
247 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_; | 158 std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint_; |
248 }; | 159 }; |
249 | 160 |
250 } // namespace cricket | 161 } // namespace cricket |
251 | 162 |
252 #endif // WEBRTC_P2P_BASE_DTLSTRANSPORT_H_ | 163 #endif // WEBRTC_P2P_BASE_DTLSTRANSPORT_H_ |
OLD | NEW |