Index: webrtc/p2p/base/transport.cc |
diff --git a/webrtc/p2p/base/transport.cc b/webrtc/p2p/base/transport.cc |
index f523502c21c7942536d64dc89d109bbac8a074ed..e682c1abbcff01b67d8437957e2f03ea9568bf26 100644 |
--- a/webrtc/p2p/base/transport.cc |
+++ b/webrtc/p2p/base/transport.cc |
@@ -400,4 +400,107 @@ bool Transport::NegotiateTransportDescription(ContentAction local_role, |
return true; |
} |
+bool Transport::VerifyCertificateFingerprint( |
+ const rtc::RTCCertificate* certificate, |
+ const rtc::SSLFingerprint* fingerprint, |
+ std::string* error_desc) const { |
+ if (!fingerprint) { |
+ return BadTransportDescription("No fingerprint.", error_desc); |
+ } |
+ if (!certificate) { |
+ return BadTransportDescription( |
+ "Fingerprint provided but no identity available.", error_desc); |
+ } |
+ rtc::scoped_ptr<rtc::SSLFingerprint> fp_tmp(rtc::SSLFingerprint::Create( |
+ fingerprint->algorithm, certificate->identity())); |
+ ASSERT(fp_tmp.get() != NULL); |
+ if (*fp_tmp == *fingerprint) { |
+ return true; |
+ } |
+ std::ostringstream desc; |
+ desc << "Local fingerprint does not match identity. Expected: "; |
+ desc << fp_tmp->ToString(); |
+ desc << " Got: " << fingerprint->ToString(); |
+ return BadTransportDescription(desc.str(), error_desc); |
+} |
+ |
+bool Transport::NegotiateRole(ContentAction local_role, |
+ rtc::SSLRole* ssl_role, |
+ std::string* error_desc) const { |
+ RTC_DCHECK(ssl_role); |
+ if (!local_description() || !remote_description()) { |
+ const std::string msg = |
+ "Local and Remote description must be set before " |
+ "transport descriptions are negotiated"; |
+ return BadTransportDescription(msg, error_desc); |
+ } |
+ |
+ // From RFC 4145, section-4.1, The following are the values that the |
+ // 'setup' attribute can take in an offer/answer exchange: |
+ // Offer Answer |
+ // ________________ |
+ // active passive / holdconn |
+ // passive active / holdconn |
+ // actpass active / passive / holdconn |
+ // holdconn holdconn |
+ // |
+ // Set the role that is most conformant with RFC 5763, Section 5, bullet 1 |
+ // The endpoint MUST use the setup attribute defined in [RFC4145]. |
+ // The endpoint that is the offerer MUST use the setup attribute |
+ // value of setup:actpass and be prepared to receive a client_hello |
+ // before it receives the answer. The answerer MUST use either a |
+ // setup attribute value of setup:active or setup:passive. Note that |
+ // if the answerer uses setup:passive, then the DTLS handshake will |
+ // not begin until the answerer is received, which adds additional |
+ // latency. setup:active allows the answer and the DTLS handshake to |
+ // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever |
+ // party is active MUST initiate a DTLS handshake by sending a |
+ // ClientHello over each flow (host/port quartet). |
+ // IOW - actpass and passive modes should be treated as server and |
+ // active as client. |
+ ConnectionRole local_connection_role = local_description()->connection_role; |
+ ConnectionRole remote_connection_role = remote_description()->connection_role; |
+ |
+ bool is_remote_server = false; |
+ if (local_role == CA_OFFER) { |
+ if (local_connection_role != CONNECTIONROLE_ACTPASS) { |
+ return BadTransportDescription( |
+ "Offerer must use actpass value for setup attribute.", error_desc); |
+ } |
+ |
+ if (remote_connection_role == CONNECTIONROLE_ACTIVE || |
+ remote_connection_role == CONNECTIONROLE_PASSIVE || |
+ remote_connection_role == CONNECTIONROLE_NONE) { |
+ is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); |
+ } else { |
+ const std::string msg = |
+ "Answerer must use either active or passive value " |
+ "for setup attribute."; |
+ return BadTransportDescription(msg, error_desc); |
+ } |
+ // If remote is NONE or ACTIVE it will act as client. |
+ } else { |
+ if (remote_connection_role != CONNECTIONROLE_ACTPASS && |
+ remote_connection_role != CONNECTIONROLE_NONE) { |
+ return BadTransportDescription( |
+ "Offerer must use actpass value for setup attribute.", error_desc); |
+ } |
+ |
+ if (local_connection_role == CONNECTIONROLE_ACTIVE || |
+ local_connection_role == CONNECTIONROLE_PASSIVE) { |
+ is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); |
+ } else { |
+ const std::string msg = |
+ "Answerer must use either active or passive value " |
+ "for setup attribute."; |
+ return BadTransportDescription(msg, error_desc); |
+ } |
+ |
+ // If local is passive, local will act as server. |
+ } |
+ |
+ *ssl_role = is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER; |
+ return true; |
+} |
+ |
} // namespace cricket |