diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-23 18:49:18 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-23 18:49:18 +0000 |
commit | 40d33caad15e6c989f569a011f9803563d93c529 (patch) | |
tree | ccea729b503749063ca5e003409689bc4edc0fb7 /remoting/protocol/jingle_session_manager.cc | |
parent | f4ae0ed7eedbb35d59376c300a6147da2b41c2b7 (diff) | |
download | chromium_src-40d33caad15e6c989f569a011f9803563d93c529.zip chromium_src-40d33caad15e6c989f569a011f9803563d93c529.tar.gz chromium_src-40d33caad15e6c989f569a011f9803563d93c529.tar.bz2 |
Send certificate in content description in jingle for Chromoting
Transmit the server certificate to the client via content description. This
allow secure encryption between Chromoting host and client.
BUG=None
TEST=remoting_unittests
Review URL: http://codereview.chromium.org/5804001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70075 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/protocol/jingle_session_manager.cc')
-rw-r--r-- | remoting/protocol/jingle_session_manager.cc | 81 |
1 files changed, 69 insertions, 12 deletions
diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc index dbaed17..5a99a3f 100644 --- a/remoting/protocol/jingle_session_manager.cc +++ b/remoting/protocol/jingle_session_manager.cc @@ -4,6 +4,7 @@ #include "remoting/protocol/jingle_session_manager.h" +#include "base/base64.h" #include "base/message_loop.h" #include "base/string_number_conversions.h" #include "remoting/base/constants.h" @@ -31,6 +32,8 @@ const char kControlTag[] = "control"; const char kEventTag[] = "event"; const char kVideoTag[] = "video"; const char kResolutionTag[] = "initial-resolution"; +const char kAuthenticationTag[] = "authentication"; +const char kCertificateTag[] = "certificate"; const char kTransportAttr[] = "transport"; const char kVersionAttr[] = "version"; @@ -150,9 +153,11 @@ bool ParseChannelConfig(const XmlElement* element, bool codec_required, ContentDescription::ContentDescription( const CandidateSessionConfig* candidate_config, - const std::string& auth_token) + const std::string& auth_token, + scoped_refptr<net::X509Certificate> certificate) : candidate_config_(candidate_config), - auth_token_(auth_token) { + auth_token_(auth_token), + certificate_(certificate) { } ContentDescription::~ContentDescription() { } @@ -210,7 +215,6 @@ void JingleSessionManager::Close(Task* closed_task) { closed_ = true; } - key_.reset(); closed_task->Run(); delete closed_task; } @@ -226,7 +230,7 @@ scoped_refptr<protocol::Session> JingleSessionManager::Connect( protocol::Session::StateChangeCallback* state_change_callback) { // Can be called from any thread. scoped_refptr<JingleSession> jingle_session( - JingleSession::CreateClientSession(this, server_cert_)); + JingleSession::CreateClientSession(this)); jingle_session->set_candidate_config(candidate_config); jingle_session->set_receiver_token(receiver_token); message_loop()->PostTask( @@ -253,7 +257,7 @@ void JingleSessionManager::DoConnect( cricket_session->Initiate( host_jid, CreateSessionDescription(jingle_session->candidate_config()->Clone(), - receiver_token)); + receiver_token, NULL)); } JingleThread* JingleSessionManager::jingle_thread() { @@ -271,11 +275,20 @@ void JingleSessionManager::OnSessionCreate( // Allow local connections if neccessary. cricket_session->set_allow_local_ips(allow_local_ips_); - // If this is an outcoming session the connection object is already - // created. + // If this is an outcoming session the session object is already created. if (incoming) { + // Generate private key and certificate. + // TODO(hclam): Instead of generating we should restore them from the disk. + scoped_ptr<base::RSAPrivateKey> private_key( + base::RSAPrivateKey::Create(1024)); + std::string subject = "CN=chromoting"; + scoped_refptr<net::X509Certificate> x509_certificate = + net::X509Certificate::CreateSelfSigned( + private_key.get(), subject, 1, base::TimeDelta::FromDays(1)); + CHECK(x509_certificate); JingleSession* jingle_session = - JingleSession::CreateServerSession(this, server_cert_, key_.get()); + JingleSession::CreateServerSession(this, x509_certificate, + private_key.get()); sessions_.push_back(make_scoped_refptr(jingle_session)); jingle_session->Init(cricket_session); } @@ -318,6 +331,8 @@ void JingleSessionManager::AcceptConnection( // Always reject connection if there is no callback. IncomingSessionResponse response = protocol::SessionManager::DECLINE; + + // Use the callback to generate a response. if (incoming_session_callback_.get()) incoming_session_callback_->Run(jingle_session, &response); @@ -329,7 +344,8 @@ void JingleSessionManager::AcceptConnection( CandidateSessionConfig::CreateFrom(jingle_session->config()); cricket_session->Accept( CreateSessionDescription(candidate_config, - jingle_session->initiator_token())); + jingle_session->initiator_token(), + jingle_session->server_certificate())); break; } @@ -415,7 +431,25 @@ bool JingleSessionManager::ParseContent( std::string auth_token; // TODO(ajwong): Parse this out. - *content = new ContentDescription(config.release(), auth_token); + // Parse the certificate. + scoped_refptr<net::X509Certificate> certificate; + child = element->FirstNamed(QName(kChromotingXmlNamespace, + kAuthenticationTag)); + if (child) + child = child->FirstNamed(QName(kChromotingXmlNamespace, + kCertificateTag)); + + if (child) { + std::string base64_cert = child->BodyText(); + std::string der_cert; + bool ret = base::Base64Decode(base64_cert, &der_cert); + DCHECK(ret) << "Failed to decode certificate"; + certificate = net::X509Certificate::CreateFromBytes(der_cert.data(), + der_cert.length()); + } + + *content = new ContentDescription(config.release(), auth_token, + certificate); return true; } LOG(ERROR) << "Invalid description: " << element->Str(); @@ -429,6 +463,9 @@ bool JingleSessionManager::ParseContent( // <event transport="datagram" version="1" /> // <video transport="srtp" codec="vp8" version="1" /> // <initial-resolution width="800" height="600" /> +// <authentication> +// <certificate>[BASE64 Encoded Certificate]</certificate> +// </authentication>" /> // </description> // bool JingleSessionManager::WriteContent( @@ -470,17 +507,37 @@ bool JingleSessionManager::WriteContent( config->initial_resolution().height)); root->AddElement(resolution_tag); + if (desc->certificate()) { + XmlElement* authentication_tag = new XmlElement( + QName(kChromotingXmlNamespace, kAuthenticationTag)); + XmlElement* certificate_tag = new XmlElement( + QName(kChromotingXmlNamespace, kCertificateTag)); + + std::string der_cert; + bool ret = desc->certificate()->GetDEREncoded(&der_cert); + DCHECK(ret) << "Cannot obtain DER encoded certificate"; + + std::string base64_cert; + ret = base::Base64Encode(der_cert, &base64_cert); + DCHECK(ret) << "Cannot perform base64 encode on certificate"; + + certificate_tag->SetBodyText(base64_cert); + authentication_tag->AddElement(certificate_tag); + root->AddElement(authentication_tag); + } + *elem = root; return true; } cricket::SessionDescription* JingleSessionManager::CreateSessionDescription( const CandidateSessionConfig* config, - const std::string& auth_token) { + const std::string& auth_token, + scoped_refptr<net::X509Certificate> certificate) { cricket::SessionDescription* desc = new cricket::SessionDescription(); desc->AddContent(JingleSession::kChromotingContentName, kChromotingXmlNamespace, - new ContentDescription(config, auth_token)); + new ContentDescription(config, auth_token, certificate)); return desc; } |