OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/cdm/aes_decryptor.h" | 5 #include "media/cdm/aes_decryptor.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 | 217 |
218 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( | 218 scoped_refptr<DecoderBuffer> output = DecoderBuffer::CopyFrom( |
219 reinterpret_cast<const uint8*>(sample), sample_size); | 219 reinterpret_cast<const uint8*>(sample), sample_size); |
220 CopySubsamples(subsamples, kDstContainsClearBytes, | 220 CopySubsamples(subsamples, kDstContainsClearBytes, |
221 reinterpret_cast<const uint8*>(decrypted_text.data()), | 221 reinterpret_cast<const uint8*>(decrypted_text.data()), |
222 output->writable_data()); | 222 output->writable_data()); |
223 return output; | 223 return output; |
224 } | 224 } |
225 | 225 |
226 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb, | 226 AesDecryptor::AesDecryptor(const SessionMessageCB& session_message_cb, |
227 const SessionClosedCB& session_closed_cb) | 227 const SessionClosedCB& session_closed_cb, |
228 const SessionKeysChangeCB& session_keys_change_cb) | |
228 : session_message_cb_(session_message_cb), | 229 : session_message_cb_(session_message_cb), |
229 session_closed_cb_(session_closed_cb) { | 230 session_closed_cb_(session_closed_cb), |
231 session_keys_change_cb_(session_keys_change_cb) { | |
230 DCHECK(!session_message_cb_.is_null()); | 232 DCHECK(!session_message_cb_.is_null()); |
231 DCHECK(!session_closed_cb_.is_null()); | 233 DCHECK(!session_closed_cb_.is_null()); |
234 DCHECK(!session_keys_change_cb_.is_null()); | |
232 } | 235 } |
233 | 236 |
234 AesDecryptor::~AesDecryptor() { | 237 AesDecryptor::~AesDecryptor() { |
235 key_map_.clear(); | 238 key_map_.clear(); |
236 } | 239 } |
237 | 240 |
241 void AesDecryptor::SetServerCertificate(const uint8* certificate_data, | |
242 int certificate_data_length, | |
243 scoped_ptr<SimpleCdmPromise> promise) { | |
244 // AesDecryptor does not communicate with a license server, so no need to | |
245 // handle the server certificate. Simply resolve the promise. | |
246 promise->resolve(); | |
ddorwin
2014/09/12 21:46:30
Reject with not supported. CK key system does not
jrummell
2014/09/15 18:22:40
Done.
| |
247 } | |
248 | |
238 void AesDecryptor::CreateSession(const std::string& init_data_type, | 249 void AesDecryptor::CreateSession(const std::string& init_data_type, |
239 const uint8* init_data, | 250 const uint8* init_data, |
240 int init_data_length, | 251 int init_data_length, |
241 SessionType session_type, | 252 SessionType session_type, |
242 scoped_ptr<NewSessionCdmPromise> promise) { | 253 scoped_ptr<NewSessionCdmPromise> promise) { |
243 std::string web_session_id(base::UintToString(next_web_session_id_++)); | 254 std::string web_session_id(base::UintToString(next_web_session_id_++)); |
244 valid_sessions_.insert(web_session_id); | 255 valid_sessions_.insert(web_session_id); |
245 | 256 |
246 // For now, the AesDecryptor does not care about |init_data_type| or | 257 // For now, the AesDecryptor does not care about |init_data_type| or |
247 // |session_type|; just resolve the promise and then fire a message event | 258 // |session_type|; just resolve the promise and then fire a message event |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 base::AutoLock auto_lock(new_key_cb_lock_); | 322 base::AutoLock auto_lock(new_key_cb_lock_); |
312 | 323 |
313 if (!new_audio_key_cb_.is_null()) | 324 if (!new_audio_key_cb_.is_null()) |
314 new_audio_key_cb_.Run(); | 325 new_audio_key_cb_.Run(); |
315 | 326 |
316 if (!new_video_key_cb_.is_null()) | 327 if (!new_video_key_cb_.is_null()) |
317 new_video_key_cb_.Run(); | 328 new_video_key_cb_.Run(); |
318 } | 329 } |
319 | 330 |
320 promise->resolve(); | 331 promise->resolve(); |
332 | |
333 // Keys have been added, so send notification. | |
334 session_keys_change_cb_.Run(web_session_id, true); | |
ddorwin
2014/09/12 21:46:30
We should at least comment that we are assuming ke
jrummell
2014/09/15 18:22:40
Done.
| |
321 } | 335 } |
322 | 336 |
323 void AesDecryptor::GetUsableKeyIds(const std::string& web_session_id, | 337 void AesDecryptor::CloseSession(const std::string& web_session_id, |
324 scoped_ptr<KeyIdsPromise> promise) { | 338 scoped_ptr<SimpleCdmPromise> promise) { |
325 // Since |web_session_id| is not provided by the user, this should never | |
326 // happen. | |
327 DCHECK(valid_sessions_.find(web_session_id) != valid_sessions_.end()); | |
328 | |
329 KeyIdsVector keyids; | |
330 base::AutoLock auto_lock(key_map_lock_); | |
331 for (KeyIdToSessionKeysMap::iterator it = key_map_.begin(); | |
332 it != key_map_.end(); | |
333 ++it) { | |
334 if (it->second->Contains(web_session_id)) | |
335 keyids.push_back(std::vector<uint8>(it->first.begin(), it->first.end())); | |
336 } | |
337 promise->resolve(keyids); | |
338 } | |
339 | |
340 void AesDecryptor::ReleaseSession(const std::string& web_session_id, | |
341 scoped_ptr<SimpleCdmPromise> promise) { | |
342 // Validate that this is a reference to an active session and then forget it. | 339 // Validate that this is a reference to an active session and then forget it. |
ddorwin
2014/09/12 21:46:30
Since this either comes from line 360 or unprefixe
jrummell
2014/09/15 18:22:40
Done.
| |
343 std::set<std::string>::iterator it = valid_sessions_.find(web_session_id); | 340 std::set<std::string>::iterator it = valid_sessions_.find(web_session_id); |
344 // TODO(jrummell): Convert back to a DCHECK once prefixed EME is removed. | 341 // TODO(jrummell): Convert back to a DCHECK once prefixed EME is removed. |
345 if (it == valid_sessions_.end()) { | 342 if (it == valid_sessions_.end()) { |
346 promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); | 343 promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); |
347 return; | 344 return; |
348 } | 345 } |
349 | 346 |
350 valid_sessions_.erase(it); | 347 valid_sessions_.erase(it); |
351 | 348 |
352 // Close the session. | 349 // Close the session. |
353 DeleteKeysForSession(web_session_id); | 350 DeleteKeysForSession(web_session_id); |
354 promise->resolve(); | 351 promise->resolve(); |
355 session_closed_cb_.Run(web_session_id); | 352 session_closed_cb_.Run(web_session_id); |
356 } | 353 } |
357 | 354 |
355 void AesDecryptor::RemoveSession(const std::string& web_session_id, | |
356 scoped_ptr<SimpleCdmPromise> promise) { | |
357 // AesDecryptor doesn't keep any persistent data, so no work to do. | |
ddorwin
2014/09/12 21:46:30
This should be rejected: Step 2 of https://dvcs.w3
jrummell
2014/09/15 18:22:40
Done.
| |
358 // However, close the session if it exists. | |
359 if (valid_sessions_.find(web_session_id) != valid_sessions_.end()) { | |
360 CloseSession(web_session_id, promise.Pass()); | |
361 return; | |
362 } | |
363 | |
364 promise->resolve(); | |
ddorwin
2014/09/12 21:46:30
If it's not found (only prefixed case), we should
jrummell
2014/09/15 18:22:40
Done.
| |
365 } | |
366 | |
367 void AesDecryptor::GetUsableKeyIds(const std::string& web_session_id, | |
368 scoped_ptr<KeyIdsPromise> promise) { | |
369 // Since |web_session_id| is not provided by the user, this should never | |
370 // happen. | |
371 DCHECK(valid_sessions_.find(web_session_id) != valid_sessions_.end()); | |
372 | |
373 KeyIdsVector keyids; | |
374 base::AutoLock auto_lock(key_map_lock_); | |
375 for (KeyIdToSessionKeysMap::iterator it = key_map_.begin(); | |
376 it != key_map_.end(); | |
377 ++it) { | |
378 if (it->second->Contains(web_session_id)) | |
379 keyids.push_back(std::vector<uint8>(it->first.begin(), it->first.end())); | |
380 } | |
381 promise->resolve(keyids); | |
382 } | |
383 | |
358 Decryptor* AesDecryptor::GetDecryptor() { | 384 Decryptor* AesDecryptor::GetDecryptor() { |
359 return this; | 385 return this; |
360 } | 386 } |
361 | 387 |
362 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, | 388 void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, |
363 const NewKeyCB& new_key_cb) { | 389 const NewKeyCB& new_key_cb) { |
364 base::AutoLock auto_lock(new_key_cb_lock_); | 390 base::AutoLock auto_lock(new_key_cb_lock_); |
365 | 391 |
366 switch (stream_type) { | 392 switch (stream_type) { |
367 case kAudio: | 393 case kAudio: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
509 bool AesDecryptor::DecryptionKey::Init() { | 535 bool AesDecryptor::DecryptionKey::Init() { |
510 CHECK(!secret_.empty()); | 536 CHECK(!secret_.empty()); |
511 decryption_key_.reset(crypto::SymmetricKey::Import( | 537 decryption_key_.reset(crypto::SymmetricKey::Import( |
512 crypto::SymmetricKey::AES, secret_)); | 538 crypto::SymmetricKey::AES, secret_)); |
513 if (!decryption_key_) | 539 if (!decryption_key_) |
514 return false; | 540 return false; |
515 return true; | 541 return true; |
516 } | 542 } |
517 | 543 |
518 } // namespace media | 544 } // namespace media |
OLD | NEW |