OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/jingle_session.h" | 5 #include "remoting/protocol/jingle_session.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 namespace protocol { | 28 namespace protocol { |
29 | 29 |
30 const char JingleSession::kChromotingContentName[] = "chromoting"; | 30 const char JingleSession::kChromotingContentName[] = "chromoting"; |
31 | 31 |
32 namespace { | 32 namespace { |
33 | 33 |
34 const char kControlChannelName[] = "control"; | 34 const char kControlChannelName[] = "control"; |
35 const char kEventChannelName[] = "event"; | 35 const char kEventChannelName[] = "event"; |
36 | 36 |
37 const int kMasterKeyLength = 16; | |
38 const int kChannelKeyLength = 16; | |
39 | |
40 std::string GenerateRandomMasterKey() { | |
41 std::string result; | |
42 result.resize(kMasterKeyLength); | |
43 base::RandBytes(&result[0], result.size()); | |
44 return result; | |
45 } | |
46 | |
47 std::string EncryptMasterKey(const std::string& host_public_key, | |
48 const std::string& master_key) { | |
49 // TODO(sergeyu): Implement RSA public key encryption in src/crypto | |
50 // and actually encrypt the key here. | |
51 return master_key; | |
52 } | |
53 | |
54 bool DecryptMasterKey(const crypto::RSAPrivateKey* private_key, | |
55 const std::string& encrypted_master_key, | |
56 std::string* master_key) { | |
57 // TODO(sergeyu): Implement RSA public key encryption in src/crypto | |
58 // and actually encrypt the key here. | |
59 *master_key = encrypted_master_key; | |
60 return true; | |
61 } | |
62 | |
63 // Generates channel key from master key and channel name. Must be | |
64 // used to generate channel key so that we don't use the same key for | |
65 // different channels. The key is calculated as | |
66 // HMAC_SHA256(master_key, channel_name) | |
67 bool GetChannelKey(const std::string& channel_name, | |
68 const std::string& master_key, | |
69 std::string* channel_key) { | |
70 crypto::HMAC hmac(crypto::HMAC::SHA256); | |
71 if (!hmac.Init(channel_name)) { | |
72 channel_key->clear(); | |
73 return false; | |
74 } | |
75 channel_key->resize(kChannelKeyLength); | |
76 if (!hmac.Sign(master_key, | |
77 reinterpret_cast<unsigned char*>(&(*channel_key)[0]), | |
78 channel_key->size())) { | |
79 channel_key->clear(); | |
80 return false; | |
81 } | |
82 return true; | |
83 } | |
84 | |
85 } // namespace | 37 } // namespace |
86 | 38 |
87 // static | 39 // static |
88 JingleSession* JingleSession::CreateClientSession( | 40 JingleSession* JingleSession::CreateClientSession( |
89 JingleSessionManager* manager, const std::string& host_public_key) { | 41 JingleSessionManager* manager, const std::string& host_public_key) { |
90 return new JingleSession(manager, "", NULL, host_public_key); | 42 return new JingleSession(manager, "", NULL, host_public_key); |
91 } | 43 } |
92 | 44 |
93 // static | 45 // static |
94 JingleSession* JingleSession::CreateServerSession( | 46 JingleSession* JingleSession::CreateServerSession( |
95 JingleSessionManager* manager, | 47 JingleSessionManager* manager, |
96 const std::string& certificate, | 48 const std::string& certificate, |
97 crypto::RSAPrivateKey* key) { | 49 crypto::RSAPrivateKey* key) { |
98 return new JingleSession(manager, certificate, key, ""); | 50 return new JingleSession(manager, certificate, key, ""); |
99 } | 51 } |
100 | 52 |
101 JingleSession::JingleSession( | 53 JingleSession::JingleSession( |
102 JingleSessionManager* jingle_session_manager, | 54 JingleSessionManager* jingle_session_manager, |
103 const std::string& local_cert, | 55 const std::string& local_cert, |
104 crypto::RSAPrivateKey* local_private_key, | 56 crypto::RSAPrivateKey* local_private_key, |
105 const std::string& peer_public_key) | 57 const std::string& peer_public_key) |
106 : jingle_session_manager_(jingle_session_manager), | 58 : jingle_session_manager_(jingle_session_manager), |
107 local_cert_(local_cert), | 59 local_cert_(local_cert), |
108 master_key_(GenerateRandomMasterKey()), | |
109 state_(INITIALIZING), | 60 state_(INITIALIZING), |
110 closed_(false), | 61 closed_(false), |
111 closing_(false), | 62 closing_(false), |
112 cricket_session_(NULL), | 63 cricket_session_(NULL), |
113 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { | 64 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { |
114 // TODO(hclam): Need a better way to clone a key. | 65 // TODO(hclam): Need a better way to clone a key. |
115 if (local_private_key) { | 66 if (local_private_key) { |
116 std::vector<uint8> key_bytes; | 67 std::vector<uint8> key_bytes; |
117 CHECK(local_private_key->ExportPrivateKey(&key_bytes)); | 68 CHECK(local_private_key->ExportPrivateKey(&key_bytes)); |
118 local_private_key_.reset( | 69 local_private_key_.reset( |
(...skipping 13 matching lines...) Expand all Loading... |
132 DCHECK(CalledOnValidThread()); | 83 DCHECK(CalledOnValidThread()); |
133 | 84 |
134 cricket_session_ = cricket_session; | 85 cricket_session_ = cricket_session; |
135 jid_ = cricket_session_->remote_name(); | 86 jid_ = cricket_session_->remote_name(); |
136 cricket_session_->SignalState.connect( | 87 cricket_session_->SignalState.connect( |
137 this, &JingleSession::OnSessionState); | 88 this, &JingleSession::OnSessionState); |
138 cricket_session_->SignalError.connect( | 89 cricket_session_->SignalError.connect( |
139 this, &JingleSession::OnSessionError); | 90 this, &JingleSession::OnSessionError); |
140 } | 91 } |
141 | 92 |
142 std::string JingleSession::GetEncryptedMasterKey() const { | |
143 DCHECK(CalledOnValidThread()); | |
144 return EncryptMasterKey(peer_public_key_, master_key_); | |
145 } | |
146 | |
147 void JingleSession::CloseInternal(int result, bool failed) { | 93 void JingleSession::CloseInternal(int result, bool failed) { |
148 DCHECK(CalledOnValidThread()); | 94 DCHECK(CalledOnValidThread()); |
149 | 95 |
150 if (!closed_ && !closing_) { | 96 if (!closed_ && !closing_) { |
151 closing_ = true; | 97 closing_ = true; |
152 | 98 |
153 // Inform the StateChangeCallback, so calling code knows not to touch any | 99 // Inform the StateChangeCallback, so calling code knows not to touch any |
154 // channels. | 100 // channels. |
155 if (failed) | 101 if (failed) |
156 SetState(FAILED); | 102 SetState(FAILED); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 | 299 |
354 void JingleSession::OnInitiate() { | 300 void JingleSession::OnInitiate() { |
355 DCHECK(CalledOnValidThread()); | 301 DCHECK(CalledOnValidThread()); |
356 jid_ = cricket_session_->remote_name(); | 302 jid_ = cricket_session_->remote_name(); |
357 | 303 |
358 if (!cricket_session_->initiator()) { | 304 if (!cricket_session_->initiator()) { |
359 const protocol::ContentDescription* content_description = | 305 const protocol::ContentDescription* content_description = |
360 static_cast<const protocol::ContentDescription*>( | 306 static_cast<const protocol::ContentDescription*>( |
361 GetContentInfo()->description); | 307 GetContentInfo()->description); |
362 CHECK(content_description); | 308 CHECK(content_description); |
363 | |
364 if (!DecryptMasterKey(local_private_key_.get(), | |
365 content_description->master_key(), &master_key_)) { | |
366 LOG(ERROR) << "Failed to decrypt master-key"; | |
367 CloseInternal(net::ERR_CONNECTION_FAILED, true); | |
368 return; | |
369 } | |
370 } | 309 } |
371 | 310 |
372 if (cricket_session_->initiator()) { | 311 if (cricket_session_->initiator()) { |
373 // Set state to CONNECTING if this is an outgoing message. We need | 312 // Set state to CONNECTING if this is an outgoing message. We need |
374 // to post this task because channel creation works only after we | 313 // to post this task because channel creation works only after we |
375 // return from this method. This is because | 314 // return from this method. This is because |
376 // JingleChannelConnector::Connect() needs to call | 315 // JingleChannelConnector::Connect() needs to call |
377 // set_incoming_only() on P2PTransportChannel, but | 316 // set_incoming_only() on P2PTransportChannel, but |
378 // P2PTransportChannel is created only after we return from this | 317 // P2PTransportChannel is created only after we return from this |
379 // method. | 318 // method. |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 | 478 |
540 state_ = new_state; | 479 state_ = new_state; |
541 if (!closed_ && state_change_callback_.get()) | 480 if (!closed_ && state_change_callback_.get()) |
542 state_change_callback_->Run(new_state); | 481 state_change_callback_->Run(new_state); |
543 } | 482 } |
544 } | 483 } |
545 | 484 |
546 } // namespace protocol | 485 } // namespace protocol |
547 | 486 |
548 } // namespace remoting | 487 } // namespace remoting |
OLD | NEW |