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