summaryrefslogtreecommitdiffstats
path: root/remoting/protocol/jingle_session_manager.cc
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-23 18:49:18 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-23 18:49:18 +0000
commit40d33caad15e6c989f569a011f9803563d93c529 (patch)
treeccea729b503749063ca5e003409689bc4edc0fb7 /remoting/protocol/jingle_session_manager.cc
parentf4ae0ed7eedbb35d59376c300a6147da2b41c2b7 (diff)
downloadchromium_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.cc81
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;
}