Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(479)

Unified Diff: webrtc/libjingle/session/tunnel/securetunnelsessionclient.cc

Issue 1175243003: Remove webrtc/libjingle/{examples,session}. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/libjingle/session/tunnel/securetunnelsessionclient.cc
diff --git a/webrtc/libjingle/session/tunnel/securetunnelsessionclient.cc b/webrtc/libjingle/session/tunnel/securetunnelsessionclient.cc
deleted file mode 100644
index 5f6f9dfdf95a234bd5a0fe20a93ec009fcb56399..0000000000000000000000000000000000000000
--- a/webrtc/libjingle/session/tunnel/securetunnelsessionclient.cc
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * libjingle
- * Copyright 2004--2008, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// SecureTunnelSessionClient and SecureTunnelSession implementation.
-
-#include "webrtc/p2p/base/transportchannel.h"
-#include "webrtc/libjingle/session/tunnel/pseudotcpchannel.h"
-#include "webrtc/libjingle/session/tunnel/securetunnelsessionclient.h"
-#include "webrtc/libjingle/xmllite/xmlelement.h"
-#include "webrtc/base/basicdefs.h"
-#include "webrtc/base/basictypes.h"
-#include "webrtc/base/common.h"
-#include "webrtc/base/helpers.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/sslidentity.h"
-#include "webrtc/base/sslstreamadapter.h"
-#include "webrtc/base/stringutils.h"
-
-namespace cricket {
-
-// XML elements and namespaces for XMPP stanzas used in content exchanges.
-
-const char NS_SECURE_TUNNEL[] = "http://www.google.com/talk/securetunnel";
-const buzz::StaticQName QN_SECURE_TUNNEL_DESCRIPTION =
- { NS_SECURE_TUNNEL, "description" };
-const buzz::StaticQName QN_SECURE_TUNNEL_TYPE =
- { NS_SECURE_TUNNEL, "type" };
-const buzz::StaticQName QN_SECURE_TUNNEL_CLIENT_CERT =
- { NS_SECURE_TUNNEL, "client-cert" };
-const buzz::StaticQName QN_SECURE_TUNNEL_SERVER_CERT =
- { NS_SECURE_TUNNEL, "server-cert" };
-const char CN_SECURE_TUNNEL[] = "securetunnel";
-
-// SecureTunnelContentDescription
-
-// TunnelContentDescription is extended to hold string forms of the
-// client and server certificate, PEM encoded.
-
-struct SecureTunnelContentDescription : public ContentDescription {
- std::string description;
- std::string client_pem_certificate;
- std::string server_pem_certificate;
-
- SecureTunnelContentDescription(const std::string& desc,
- const std::string& client_pem_cert,
- const std::string& server_pem_cert)
- : description(desc),
- client_pem_certificate(client_pem_cert),
- server_pem_certificate(server_pem_cert) {
- }
- virtual ContentDescription* Copy() const {
- return new SecureTunnelContentDescription(*this);
- }
-};
-
-// SecureTunnelSessionClient
-
-SecureTunnelSessionClient::SecureTunnelSessionClient(
- const buzz::Jid& jid, SessionManager* manager)
- : TunnelSessionClient(jid, manager, NS_SECURE_TUNNEL) {
-}
-
-void SecureTunnelSessionClient::SetIdentity(rtc::SSLIdentity* identity) {
- ASSERT(identity_.get() == NULL);
- identity_.reset(identity);
-}
-
-bool SecureTunnelSessionClient::GenerateIdentity() {
- ASSERT(identity_.get() == NULL);
- identity_.reset(rtc::SSLIdentity::Generate(
- // The name on the certificate does not matter: the peer will
- // make sure the cert it gets during SSL negotiation matches the
- // one it got from XMPP. It would be neat to put something
- // recognizable in there such as the JID, except this will show
- // in clear during the SSL negotiation and so it could be a
- // privacy issue. Specifying an empty string here causes
- // it to use a random string.
-#ifdef _DEBUG
- jid().Str()
-#else
- ""
-#endif
- ));
- if (identity_.get() == NULL) {
- LOG(LS_ERROR) << "Failed to generate SSL identity";
- return false;
- }
- return true;
-}
-
-rtc::SSLIdentity& SecureTunnelSessionClient::GetIdentity() const {
- ASSERT(identity_.get() != NULL);
- return *identity_;
-}
-
-// Parses a certificate from a PEM encoded string.
-// Returns NULL on failure.
-// The caller is responsible for freeing the returned object.
-static rtc::SSLCertificate* ParseCertificate(
- const std::string& pem_cert) {
- if (pem_cert.empty())
- return NULL;
- return rtc::SSLCertificate::FromPEMString(pem_cert);
-}
-
-TunnelSession* SecureTunnelSessionClient::MakeTunnelSession(
- Session* session, rtc::Thread* stream_thread,
- TunnelSessionRole role) {
- return new SecureTunnelSession(this, session, stream_thread, role);
-}
-
-bool FindSecureTunnelContent(const cricket::SessionDescription* sdesc,
- std::string* name,
- const SecureTunnelContentDescription** content) {
- const ContentInfo* cinfo = sdesc->FirstContentByType(NS_SECURE_TUNNEL);
- if (cinfo == NULL)
- return false;
-
- *name = cinfo->name;
- *content = static_cast<const SecureTunnelContentDescription*>(
- cinfo->description);
- return true;
-}
-
-void SecureTunnelSessionClient::OnIncomingTunnel(const buzz::Jid &jid,
- Session *session) {
- std::string content_name;
- const SecureTunnelContentDescription* content = NULL;
- if (!FindSecureTunnelContent(session->remote_description(),
- &content_name, &content)) {
- ASSERT(false);
- }
-
- // Validate the certificate
- rtc::scoped_ptr<rtc::SSLCertificate> peer_cert(
- ParseCertificate(content->client_pem_certificate));
- if (peer_cert.get() == NULL) {
- LOG(LS_ERROR)
- << "Rejecting incoming secure tunnel with invalid cetificate";
- DeclineTunnel(session);
- return;
- }
- // If there were a convenient place we could have cached the
- // peer_cert so as not to have to parse it a second time when
- // configuring the tunnel.
- SignalIncomingTunnel(this, jid, content->description, session);
-}
-
-// The XML representation of a session initiation request (XMPP IQ),
-// containing the initiator's SecureTunnelContentDescription,
-// looks something like this:
-// <iq from="INITIATOR@gmail.com/pcpE101B7F4"
-// to="RECIPIENT@gmail.com/pcp8B87F0A3"
-// type="set" id="3">
-// <session xmlns="http://www.google.com/session"
-// type="initiate" id="2508605813"
-// initiator="INITIATOR@gmail.com/pcpE101B7F4">
-// <description xmlns="http://www.google.com/talk/securetunnel">
-// <type>send:filename</type>
-// <client-cert>
-// -----BEGIN CERTIFICATE-----
-// INITIATOR'S CERTIFICATE IN PERM FORMAT (ASCII GIBBERISH)
-// -----END CERTIFICATE-----
-// </client-cert>
-// </description>
-// <transport xmlns="http://www.google.com/transport/p2p"/>
-// </session>
-// </iq>
-
-// The session accept iq, containing the recipient's certificate and
-// echoing the initiator's certificate, looks something like this:
-// <iq from="RECIPIENT@gmail.com/pcpE101B7F4"
-// to="INITIATOR@gmail.com/pcpE101B7F4"
-// type="set" id="5">
-// <session xmlns="http://www.google.com/session"
-// type="accept" id="2508605813"
-// initiator="sdoyon911@gmail.com/pcpE101B7F4">
-// <description xmlns="http://www.google.com/talk/securetunnel">
-// <type>send:FILENAME</type>
-// <client-cert>
-// -----BEGIN CERTIFICATE-----
-// INITIATOR'S CERTIFICATE IN PERM FORMAT (ASCII GIBBERISH)
-// -----END CERTIFICATE-----
-// </client-cert>
-// <server-cert>
-// -----BEGIN CERTIFICATE-----
-// RECIPIENT'S CERTIFICATE IN PERM FORMAT (ASCII GIBBERISH)
-// -----END CERTIFICATE-----
-// </server-cert>
-// </description>
-// </session>
-// </iq>
-
-
-bool SecureTunnelSessionClient::ParseContent(SignalingProtocol protocol,
- const buzz::XmlElement* elem,
- ContentDescription** content,
- ParseError* error) {
- const buzz::XmlElement* type_elem = elem->FirstNamed(QN_SECURE_TUNNEL_TYPE);
-
- if (type_elem == NULL)
- // Missing mandatory XML element.
- return false;
-
- // Here we consider the certificate components to be optional. In
- // practice the client certificate is always present, and the server
- // certificate is initially missing from the session description
- // sent during session initiation. OnAccept() will enforce that we
- // have a certificate for our peer.
- const buzz::XmlElement* client_cert_elem =
- elem->FirstNamed(QN_SECURE_TUNNEL_CLIENT_CERT);
- const buzz::XmlElement* server_cert_elem =
- elem->FirstNamed(QN_SECURE_TUNNEL_SERVER_CERT);
- *content = new SecureTunnelContentDescription(
- type_elem->BodyText(),
- client_cert_elem ? client_cert_elem->BodyText() : "",
- server_cert_elem ? server_cert_elem->BodyText() : "");
- return true;
-}
-
-bool SecureTunnelSessionClient::WriteContent(
- SignalingProtocol protocol, const ContentDescription* untyped_content,
- buzz::XmlElement** elem, WriteError* error) {
- const SecureTunnelContentDescription* content =
- static_cast<const SecureTunnelContentDescription*>(untyped_content);
-
- buzz::XmlElement* root =
- new buzz::XmlElement(QN_SECURE_TUNNEL_DESCRIPTION, true);
- buzz::XmlElement* type_elem = new buzz::XmlElement(QN_SECURE_TUNNEL_TYPE);
- type_elem->SetBodyText(content->description);
- root->AddElement(type_elem);
- if (!content->client_pem_certificate.empty()) {
- buzz::XmlElement* client_cert_elem =
- new buzz::XmlElement(QN_SECURE_TUNNEL_CLIENT_CERT);
- client_cert_elem->SetBodyText(content->client_pem_certificate);
- root->AddElement(client_cert_elem);
- }
- if (!content->server_pem_certificate.empty()) {
- buzz::XmlElement* server_cert_elem =
- new buzz::XmlElement(QN_SECURE_TUNNEL_SERVER_CERT);
- server_cert_elem->SetBodyText(content->server_pem_certificate);
- root->AddElement(server_cert_elem);
- }
- *elem = root;
- return true;
-}
-
-SessionDescription* NewSecureTunnelSessionDescription(
- const std::string& content_name, ContentDescription* content) {
- SessionDescription* sdesc = new SessionDescription();
- sdesc->AddContent(content_name, NS_SECURE_TUNNEL, content);
- return sdesc;
-}
-
-SessionDescription* SecureTunnelSessionClient::CreateOffer(
- const buzz::Jid &jid, const std::string &description) {
- // We are the initiator so we are the client. Put our cert into the
- // description.
- std::string pem_cert = GetIdentity().certificate().ToPEMString();
- return NewSecureTunnelSessionDescription(
- CN_SECURE_TUNNEL,
- new SecureTunnelContentDescription(description, pem_cert, ""));
-}
-
-SessionDescription* SecureTunnelSessionClient::CreateAnswer(
- const SessionDescription* offer) {
- std::string content_name;
- const SecureTunnelContentDescription* offer_tunnel = NULL;
- if (!FindSecureTunnelContent(offer, &content_name, &offer_tunnel))
- return NULL;
-
- // We are accepting a session request. We need to add our cert, the
- // server cert, into the description. The client cert was validated
- // in OnIncomingTunnel().
- ASSERT(!offer_tunnel->client_pem_certificate.empty());
- return NewSecureTunnelSessionDescription(
- content_name,
- new SecureTunnelContentDescription(
- offer_tunnel->description,
- offer_tunnel->client_pem_certificate,
- GetIdentity().certificate().ToPEMString()));
-}
-
-// SecureTunnelSession
-
-SecureTunnelSession::SecureTunnelSession(
- SecureTunnelSessionClient* client, Session* session,
- rtc::Thread* stream_thread, TunnelSessionRole role)
- : TunnelSession(client, session, stream_thread),
- role_(role) {
-}
-
-rtc::StreamInterface* SecureTunnelSession::MakeSecureStream(
- rtc::StreamInterface* stream) {
- rtc::SSLStreamAdapter* ssl_stream =
- rtc::SSLStreamAdapter::Create(stream);
- rtc::SSLIdentity* identity =
- static_cast<SecureTunnelSessionClient*>(client_)->
- GetIdentity().GetReference();
- ssl_stream->SetIdentity(identity);
- if (role_ == RESPONDER)
- ssl_stream->SetServerRole();
- ssl_stream->StartSSLWithPeer();
-
- // SSL negotiation will start on the stream as soon as it
- // opens. However our SSLStreamAdapter still hasn't been told what
- // certificate to allow for our peer. If we are the initiator, we do
- // not have the peer's certificate yet: we will obtain it from the
- // session accept message which we will receive later (see
- // OnAccept()). We won't Connect() the PseudoTcpChannel until we get
- // that, so the stream will stay closed until then. Keep a handle
- // on the streem so we can configure the peer certificate later.
- ssl_stream_reference_.reset(new rtc::StreamReference(ssl_stream));
- return ssl_stream_reference_->NewReference();
-}
-
-rtc::StreamInterface* SecureTunnelSession::GetStream() {
- ASSERT(channel_ != NULL);
- ASSERT(ssl_stream_reference_.get() == NULL);
- return MakeSecureStream(channel_->GetStream());
-}
-
-void SecureTunnelSession::OnAccept() {
- // We have either sent or received a session accept: it's time to
- // connect the tunnel. First we must set the peer certificate.
- ASSERT(channel_ != NULL);
- ASSERT(session_ != NULL);
- std::string content_name;
- const SecureTunnelContentDescription* remote_tunnel = NULL;
- if (!FindSecureTunnelContent(session_->remote_description(),
- &content_name, &remote_tunnel)) {
- session_->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
- return;
- }
-
- const std::string& cert_pem =
- role_ == INITIATOR ? remote_tunnel->server_pem_certificate :
- remote_tunnel->client_pem_certificate;
- rtc::scoped_ptr<rtc::SSLCertificate> peer_cert(
- ParseCertificate(cert_pem));
- if (peer_cert == NULL) {
- ASSERT(role_ == INITIATOR); // when RESPONDER we validated it earlier
- LOG(LS_ERROR)
- << "Rejecting secure tunnel accept with invalid cetificate";
- session_->Reject(STR_TERMINATE_INCOMPATIBLE_PARAMETERS);
- return;
- }
- ASSERT(ssl_stream_reference_.get() != NULL);
- rtc::SSLStreamAdapter* ssl_stream =
- static_cast<rtc::SSLStreamAdapter*>(
- ssl_stream_reference_->GetStream());
-
- std::string algorithm;
- if (!peer_cert->GetSignatureDigestAlgorithm(&algorithm)) {
- LOG(LS_ERROR) << "Failed to get the algorithm for the peer cert signature";
- return;
- }
- unsigned char digest[rtc::MessageDigest::kMaxSize];
- size_t digest_len;
- peer_cert->ComputeDigest(algorithm, digest, ARRAY_SIZE(digest), &digest_len);
- ssl_stream->SetPeerCertificateDigest(algorithm, digest, digest_len);
-
- // We no longer need our handle to the ssl stream.
- ssl_stream_reference_.reset();
- LOG(LS_INFO) << "Connecting tunnel";
- // This will try to connect the PseudoTcpChannel. If and when that
- // succeeds, then ssl negotiation will take place, and when that
- // succeeds, the tunnel stream will finally open.
- VERIFY(channel_->Connect(
- content_name, "tcp", ICE_CANDIDATE_COMPONENT_DEFAULT));
-}
-
-} // namespace cricket
« no previous file with comments | « webrtc/libjingle/session/tunnel/securetunnelsessionclient.h ('k') | webrtc/libjingle/session/tunnel/tunnelsessionclient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698