ClearKeyPersistence.cpp (4451B)
1 /* 2 * Copyright 2015, Mozilla Foundation and contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "ClearKeyPersistence.h" 18 19 #include <assert.h> 20 #include <stdint.h> 21 #include <string.h> 22 23 #include <sstream> 24 25 #include "ClearKeySessionManager.h" 26 #include "ClearKeyStorage.h" 27 #include "ClearKeyUtils.h" 28 #include "RefCounted.h" 29 30 using namespace cdm; 31 32 using std::function; 33 using std::string; 34 using std::stringstream; 35 using std::vector; 36 37 void ClearKeyPersistence::ReadAllRecordsFromIndex( 38 function<void()>&& aOnComplete) { 39 // Clear what we think the index file contains, we're about to read it again. 40 mPersistentSessionIds.clear(); 41 42 // Hold a reference to the persistence manager, so it isn't released before 43 // we try and use it. 44 RefPtr<ClearKeyPersistence> self(this); 45 function<void(const uint8_t*, uint32_t)> onIndexSuccess = 46 [self, aOnComplete](const uint8_t* data, uint32_t size) { 47 CK_LOGD("ClearKeyPersistence: Loaded index file!"); 48 const char* charData = (const char*)data; 49 50 stringstream ss(string(charData, charData + size)); 51 string name; 52 while (getline(ss, name)) { 53 if (ClearKeyUtils::IsValidSessionId(name.data(), name.size())) { 54 self->mPersistentSessionIds.insert(atoi(name.c_str())); 55 } 56 } 57 58 self->mPersistentKeyState = PersistentKeyState::LOADED; 59 aOnComplete(); 60 }; 61 62 function<void()> onIndexFailed = [self, aOnComplete]() { 63 CK_LOGD( 64 "ClearKeyPersistence: Failed to load index file (it might not exist"); 65 self->mPersistentKeyState = PersistentKeyState::LOADED; 66 aOnComplete(); 67 }; 68 69 string filename = "index"; 70 ReadData(mHost, filename, std::move(onIndexSuccess), 71 std::move(onIndexFailed)); 72 } 73 74 void ClearKeyPersistence::WriteIndex() { 75 function<void()> onIndexSuccess = []() { 76 CK_LOGD("ClearKeyPersistence: Wrote index file"); 77 }; 78 79 function<void()> onIndexFail = []() { 80 CK_LOGD("ClearKeyPersistence: Failed to write index file (this is bad)"); 81 }; 82 83 stringstream ss; 84 85 for (const uint32_t& sessionId : mPersistentSessionIds) { 86 ss << sessionId; 87 ss << '\n'; 88 } 89 90 string dataString = ss.str(); 91 uint8_t* dataArray = (uint8_t*)dataString.data(); 92 vector<uint8_t> data(dataArray, dataArray + dataString.size()); 93 94 string filename = "index"; 95 WriteData(mHost, filename, data, std::move(onIndexSuccess), 96 std::move(onIndexFail)); 97 } 98 99 ClearKeyPersistence::ClearKeyPersistence(Host_11* aHost) : mHost(aHost) {} 100 101 void ClearKeyPersistence::EnsureInitialized(bool aPersistentStateAllowed, 102 function<void()>&& aOnInitialized) { 103 if (aPersistentStateAllowed && 104 mPersistentKeyState == PersistentKeyState::UNINITIALIZED) { 105 mPersistentKeyState = LOADING; 106 ReadAllRecordsFromIndex(std::move(aOnInitialized)); 107 } else { 108 mPersistentKeyState = PersistentKeyState::LOADED; 109 aOnInitialized(); 110 } 111 } 112 113 bool ClearKeyPersistence::IsLoaded() const { 114 return mPersistentKeyState == PersistentKeyState::LOADED; 115 } 116 117 string ClearKeyPersistence::GetNewSessionId(SessionType aSessionType) { 118 static uint32_t sNextSessionId = 1; 119 120 // Ensure we don't re-use a session id that was persisted. 121 while (Contains(mPersistentSessionIds, sNextSessionId)) { 122 sNextSessionId++; 123 } 124 125 string sessionId; 126 stringstream ss; 127 ss << sNextSessionId; 128 ss >> sessionId; 129 130 if (aSessionType == SessionType::kPersistentLicense) { 131 mPersistentSessionIds.insert(sNextSessionId); 132 133 // Save the updated index file. 134 WriteIndex(); 135 } 136 137 sNextSessionId++; 138 139 return sessionId; 140 } 141 142 bool ClearKeyPersistence::IsPersistentSessionId(const string& aSessionId) { 143 return Contains(mPersistentSessionIds, atoi(aSessionId.c_str())); 144 } 145 146 void ClearKeyPersistence::PersistentSessionRemoved(string& aSessionId) { 147 mPersistentSessionIds.erase(atoi(aSessionId.c_str())); 148 149 // Update the index file. 150 WriteIndex(); 151 }