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

Side by Side Diff: remoting/protocol/secure_p2p_socket.cc

Issue 7522014: Add WARN_UNUSED_RESULT to crypto/hmac.h (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase onto CL 7532020 and update remoting Created 9 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/protocol/jingle_session.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/secure_p2p_socket.h" 5 #include "remoting/protocol/secure_p2p_socket.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/rand_util.h" 8 #include "base/rand_util.h"
9 #include "crypto/symmetric_key.h" 9 #include "crypto/symmetric_key.h"
10 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 msg_hasher_(crypto::HMAC::SHA1) { 84 msg_hasher_(crypto::HMAC::SHA1) {
85 // Make sure the key is valid. 85 // Make sure the key is valid.
86 CHECK(ice_key.size() == kKeySize); 86 CHECK(ice_key.size() == kKeySize);
87 87
88 // Create the mask key from ice key. 88 // Create the mask key from ice key.
89 crypto::HMAC mask_hasher(crypto::HMAC::SHA1); 89 crypto::HMAC mask_hasher(crypto::HMAC::SHA1);
90 bool ret = mask_hasher.Init( 90 bool ret = mask_hasher.Init(
91 reinterpret_cast<const unsigned char*>(ice_key.data()), kKeySize); 91 reinterpret_cast<const unsigned char*>(ice_key.data()), kKeySize);
92 DCHECK(ret) << "Initialize HMAC-SHA1 for mask failed."; 92 DCHECK(ret) << "Initialize HMAC-SHA1 for mask failed.";
93 scoped_array<uint8> mask_digest(new uint8[mask_hasher.DigestLength()]); 93 scoped_array<uint8> mask_digest(new uint8[mask_hasher.DigestLength()]);
94 mask_hasher.Sign(kMaskSaltStr, mask_digest.get(), 94 ret = mask_hasher.Sign(kMaskSaltStr, mask_digest.get(),
95 mask_hasher.DigestLength()); 95 mask_hasher.DigestLength());
96 DCHECK(ret) << "Sign with HMAC-SHA1 for mask failed.";
96 mask_key_.reset(crypto::SymmetricKey::Import( 97 mask_key_.reset(crypto::SymmetricKey::Import(
97 crypto::SymmetricKey::AES, 98 crypto::SymmetricKey::AES,
98 std::string(mask_digest.get(), mask_digest.get() + kKeySize))); 99 std::string(mask_digest.get(), mask_digest.get() + kKeySize)));
99 DCHECK(mask_key_.get()) << "Import symmetric key failed."; 100 DCHECK(mask_key_.get()) << "Import symmetric key failed.";
100 101
101 // Initialize the encryptor with mask key. 102 // Initialize the encryptor with mask key.
102 encryptor_.Init(mask_key_.get(), crypto::Encryptor::CTR, ""); 103 encryptor_.Init(mask_key_.get(), crypto::Encryptor::CTR, "");
103 104
104 // Create the hash key from ice key. 105 // Create the hash key from ice key.
105 crypto::HMAC hash_hasher(crypto::HMAC::SHA1); 106 crypto::HMAC hash_hasher(crypto::HMAC::SHA1);
106 ret = hash_hasher.Init( 107 ret = hash_hasher.Init(
107 reinterpret_cast<const unsigned char*>(ice_key.data()), kKeySize); 108 reinterpret_cast<const unsigned char*>(ice_key.data()), kKeySize);
108 DCHECK(ret) << "Initialize HMAC-SHA1 for hash failed."; 109 DCHECK(ret) << "Initialize HMAC-SHA1 for hash failed.";
109 scoped_array<uint8> hash_key(new uint8[hash_hasher.DigestLength()]); 110 scoped_array<uint8> hash_key(new uint8[hash_hasher.DigestLength()]);
110 hash_hasher.Sign(kHashSaltStr, hash_key.get(), hash_hasher.DigestLength()); 111 ret = hash_hasher.Sign(kHashSaltStr, hash_key.get(),
111 112 hash_hasher.DigestLength());
113 DCHECK(ret) << "Sign with HMAC-SHA1 for hash failed.";
112 // Create a hasher for message. 114 // Create a hasher for message.
113 ret = msg_hasher_.Init(hash_key.get(), kKeySize); 115 ret = msg_hasher_.Init(hash_key.get(), kKeySize);
114 DCHECK(ret) << "Initialize HMAC-SHA1 for message failed."; 116 DCHECK(ret) << "Initialize HMAC-SHA1 for message failed.";
115 } 117 }
116 118
117 SecureP2PSocket::~SecureP2PSocket() { 119 SecureP2PSocket::~SecureP2PSocket() {
118 } 120 }
119 121
120 int SecureP2PSocket::Read(IOBuffer* buf, int buf_len, 122 int SecureP2PSocket::Read(IOBuffer* buf, int buf_len,
121 CompletionCallback* callback) { 123 CompletionCallback* callback) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 std::string encrypted_message; 159 std::string encrypted_message;
158 CHECK(encryptor_.Encrypt(raw_message, &encrypted_message)); 160 CHECK(encryptor_.Encrypt(raw_message, &encrypted_message));
159 memcpy(encrypted_buf->data() + kRawMessagePosition, 161 memcpy(encrypted_buf->data() + kRawMessagePosition,
160 encrypted_message.data(), encrypted_message.size()); 162 encrypted_message.data(), encrypted_message.size());
161 163
162 // 8. Concatenate nonce and encrypted message to form masked message. 164 // 8. Concatenate nonce and encrypted message to form masked message.
163 memcpy(encrypted_buf->data() + kNoncePosition, nonce.data(), kKeySize); 165 memcpy(encrypted_buf->data() + kNoncePosition, nonce.data(), kKeySize);
164 166
165 // 10. Create hash from masked message with nonce. 167 // 10. Create hash from masked message with nonce.
166 scoped_array<uint8> msg_digest(new uint8[msg_hasher_.DigestLength()]); 168 scoped_array<uint8> msg_digest(new uint8[msg_hasher_.DigestLength()]);
167 msg_hasher_.Sign( 169 CHECK(msg_hasher_.Sign(
168 base::StringPiece(encrypted_buf->data() + kNoncePosition, 170 base::StringPiece(encrypted_buf->data() + kNoncePosition,
169 kRawMessageSize + kKeySize), 171 kRawMessageSize + kKeySize),
170 msg_digest.get(), msg_hasher_.DigestLength()); 172 msg_digest.get(), msg_hasher_.DigestLength()));
171 memcpy(encrypted_buf->data() + kHashPosition, msg_digest.get(), kKeySize); 173 memcpy(encrypted_buf->data() + kHashPosition, msg_digest.get(), kKeySize);
172 174
173 // Write to the socket. 175 // Write to the socket.
174 int ret = socket_->Write(encrypted_buf, encrypted_buffer_size, 176 int ret = socket_->Write(encrypted_buf, encrypted_buffer_size,
175 write_callback_.get()); 177 write_callback_.get());
176 if (ret == net::ERR_IO_PENDING) { 178 if (ret == net::ERR_IO_PENDING) {
177 DCHECK(callback); 179 DCHECK(callback);
178 user_write_callback_ = callback; 180 user_write_callback_ = callback;
179 user_write_buf_len_ = buf_len; 181 user_write_buf_len_ = buf_len;
180 return ret; 182 return ret;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 } 250 }
249 callback->Run(err); 251 callback->Run(err);
250 } 252 }
251 253
252 int SecureP2PSocket::DecryptBuffer(int size) { 254 int SecureP2PSocket::DecryptBuffer(int size) {
253 if (size < kRawMessagePosition) 255 if (size < kRawMessagePosition)
254 return net::ERR_INVALID_RESPONSE; 256 return net::ERR_INVALID_RESPONSE;
255 257
256 // See the spec for the steps taken in this method: 258 // See the spec for the steps taken in this method:
257 // http://www.whatwg.org/specs/web-apps/current-work/complete/video-conferenci ng-and-peer-to-peer-communication.html#peer-to-peer-connections 259 // http://www.whatwg.org/specs/web-apps/current-work/complete/video-conferenci ng-and-peer-to-peer-communication.html#peer-to-peer-connections
258 // 5. Compute hash of the message. 260 // 4-7: Verify that the HMAC-SHA1 of all but the first 16 bytes of the
259 scoped_array<uint8> msg_digest(new uint8[msg_hasher_.DigestLength()]); 261 // masked message with nonce equals the first 16 bytes of the masked message
260 msg_hasher_.Sign( 262 // with nonce.
263 if (!msg_hasher_.VerifyTruncated(
261 base::StringPiece(read_buf_->data() + kNoncePosition, 264 base::StringPiece(read_buf_->data() + kNoncePosition,
262 size - kNoncePosition), 265 size - kNoncePosition),
263 msg_digest.get(), msg_hasher_.DigestLength()); 266 base::StringPiece(read_buf_->data(), kKeySize))) {
267 return net::ERR_INVALID_RESPONSE;
268 }
264 269
265 // 6. Compare the hash values. 270 // 8-11. Decrypt the message.
266 int ret = memcmp(read_buf_->data(), msg_digest.get(), kKeySize);
267 if (ret)
268 return net::ERR_INVALID_RESPONSE;
269
270 // 7. Decrypt the message.
271 std::string nonce = std::string( 271 std::string nonce = std::string(
272 read_buf_->data() + kNoncePosition, kKeySize); 272 read_buf_->data() + kNoncePosition, kKeySize);
273 CHECK(encryptor_.SetCounter(nonce)); 273 CHECK(encryptor_.SetCounter(nonce));
274 const int raw_message_size = size - kRawMessagePosition; 274 const int raw_message_size = size - kRawMessagePosition;
275 275
276 // TODO(hclam): Change Encryptor API to trim this memcpy. 276 // TODO(hclam): Change Encryptor API to trim this memcpy.
277 std::string encrypted_message(read_buf_->data() + kRawMessagePosition, 277 std::string encrypted_message(read_buf_->data() + kRawMessagePosition,
278 raw_message_size); 278 raw_message_size);
279 std::string raw_message; 279 std::string raw_message;
280 CHECK(encryptor_.Decrypt(encrypted_message, &raw_message)); 280 CHECK(encryptor_.Decrypt(encrypted_message, &raw_message));
281 281
282 if (raw_message_size < kSeqNumberSize) 282 if (raw_message_size < kSeqNumberSize)
283 return net::ERR_INVALID_RESPONSE; 283 return net::ERR_INVALID_RESPONSE;
284 284
285 // 12. Read the sequence number. 285 // 12. Read the sequence number.
286 uint64 seq_number = GetBE64(raw_message.data()); 286 uint64 seq_number = GetBE64(raw_message.data());
287 287
288 // The spec says we reject the packet if it is out of order. We don't do 288 // The spec says we reject the packet if it is out of order. We don't do
289 // this so allow upper levels to do reordering. 289 // this so allow upper levels to do reordering.
290 290
291 // 14. Save the most recent sequence number. 291 // 14. Save the most recent sequence number.
292 read_seq_ = seq_number; 292 read_seq_ = seq_number;
293 293
294 // 15. Parse the frame type. 294 // 15. Parse the frame type.
295 if (raw_message_size < kSeqNumberSize + kFrameTypeSize) 295 if (raw_message_size < kSeqNumberSize + kFrameTypeSize)
296 return net::ERR_INVALID_RESPONSE; 296 return net::ERR_INVALID_RESPONSE;
297 ret = memcmp(raw_message.data() + kSeqNumberSize, kFrameType, 297 if (memcmp(raw_message.data() + kSeqNumberSize, kFrameType,
298 kFrameTypeSize); 298 kFrameTypeSize) != 0) {
299 if (ret)
300 return net::ERR_INVALID_RESPONSE; 299 return net::ERR_INVALID_RESPONSE;
300 }
301 301
302 // 16. Read the message. 302 // 16. Read the message.
303 const int kMessageSize = raw_message_size - kSeqNumberSize - kFrameTypeSize; 303 const int kMessageSize = raw_message_size - kSeqNumberSize - kFrameTypeSize;
304 memcpy(user_read_buf_->data(), 304 memcpy(user_read_buf_->data(),
305 raw_message.data() + kSeqNumberSize + kFrameTypeSize, kMessageSize); 305 raw_message.data() + kSeqNumberSize + kFrameTypeSize, kMessageSize);
306 return kMessageSize; 306 return kMessageSize;
307 } 307 }
308 308
309 } // namespace protocol 309 } // namespace protocol
310 } // namespace remoting 310 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/protocol/jingle_session.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698