Certificate provisioning verification

bug: 8620943

This is a merge of changes made to the Widevine CDM
repository during certificate provisioning verification.

The following changes are included:

Fixes for certificate based licensing
https://widevine-internal-review.googlesource.com/#/c/5162/

Base64 encode and decode now handles non-multiple of 24-bits input
https://widevine-internal-review.googlesource.com/#/c/4981/

Fixed issues with device provisioning response handling
https://widevine-internal-review.googlesource.com/#/c/5153/

Persistent storage to support device certificates
https://widevine-internal-review.googlesource.com/#/c/5161/

Enable loading of certificates
https://widevine-internal-review.googlesource.com/#/c/5172/

Provide license server url
https://widevine-internal-review.googlesource.com/#/c/5173/

Change-Id: I0c032c1ae0055dcc1a7a77ad4b0ea0898030dc7d
This commit is contained in:
Jeff Tinker
2013-04-22 20:05:55 -07:00
parent 3a28eeeb68
commit 958bbe6d05
30 changed files with 1497 additions and 290 deletions

View File

@@ -0,0 +1,206 @@
// Copyright 2013 Google Inc. All Rights Reserved.
//
// File class - provides a simple android specific file implementation
#include "file_store.h"
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include "log.h"
namespace {
const char* kCurrentDirectory = ".";
const char* kParentDirectory = "..";
}
namespace wvcdm {
class File::Impl {
public:
FILE* file_;
};
File::File() : impl_(new File::Impl()) {}
File::File(const std::string& file_path, int flags) :
impl_(new File::Impl()) {
Open(file_path, flags);
}
File::~File() {
Close();
delete impl_;
}
bool File::Open(const std::string& name, int flags) {
std::string openFlags = "";
if (((flags & File::kTruncate) && Exists(name)) ||
((flags & File::kCreate) && !Exists(name))) {
FILE* fp = fopen(name.c_str(), "w+");
if (fp) {
fclose(fp);
}
}
if (flags & File::kBinary) {
openFlags = (flags & File::kReadOnly)? "rb" : "rb+";
} else {
openFlags = (flags & File::kReadOnly)? "r" : "r+";
}
impl_->file_ = fopen(name.c_str(), openFlags.c_str());
if (!impl_->file_) {
LOGW("File::Open: fopen failed: %d", errno);
}
return IsOpen();
}
void File::Close() {
if (impl_->file_) {
fclose(impl_->file_);
impl_->file_ = NULL;
}
}
bool File::IsOpen() {
return impl_->file_ != NULL;
}
bool File::IsBad() {
if (impl_->file_)
return ferror(impl_->file_) != 0;
else
return true;
}
ssize_t File::Read(void* buffer, size_t bytes) {
if (impl_->file_) {
size_t len = fread(buffer, 1, bytes, impl_->file_);
if (len == 0) {
LOGW("File::Read: fread failed: %d", errno);
}
return len;
}
LOGW("File::Read: file not open");
return -1;
}
ssize_t File::Write(const void* buffer, size_t bytes) {
if (impl_->file_) {
size_t len = fwrite(buffer, 1, bytes, impl_->file_);
if (len == 0) {
LOGW("File::Write: fwrite failed: %d", errno);
}
return len;
}
LOGW("File::Write: file not open");
return -1;
}
bool File::Exists(const std::string& file) {
struct stat buf;
int res = stat(file.c_str(), &buf) == 0;
if (!res) {
LOGV("File::Exists: stat failed: %d", errno);
}
return res;
}
bool File::Remove(const std::string& file_path) {
if (IsDirectory(file_path)) {
DIR* dir;
if ((dir = opendir(file_path.c_str())) != NULL) {
// first remove files and dir within it
struct dirent* entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, kCurrentDirectory) &&
(strcmp(entry->d_name, kParentDirectory))) {
std::string file_path_to_remove = file_path + '/';
file_path_to_remove += entry->d_name;
if (!Remove(file_path_to_remove)) {
closedir(dir);
return false;
}
}
}
closedir(dir);
}
if (rmdir(file_path.c_str())) {
LOGW("File::Remove: rmdir failed: %d", errno);
return false;
}
return true;
} else {
if (unlink(file_path.c_str())) {
LOGW("File::Remove: unlink failed: %d", errno);
return false;
}
return true;
}
}
bool File::CreateDirectory(std::string path) {
size_t size = path.size();
if ((size == 1) && (path[0] == '/'))
return true;
if (size <= 1)
return false;
if (path.at(size-1) == '/') {
--size;
path.resize(size);
}
size_t pos = path.find('/', 1);
while (pos < size) {
path.at(pos) = '\0';
if (mkdir(path.c_str(), 0775) != 0) {
if (errno != EEXIST) {
LOGW("File::CreateDirectory: mkdir failed: %d\n", errno);
return false;
}
}
path.at(pos) = '/';
pos = path.find('/', pos+1);
}
if (mkdir(path.c_str(), 0775) != 0) {
if (errno != EEXIST) {
LOGW("File::CreateDirectory: mkdir failed: %d\n", errno);
return false;
}
}
return true;
}
bool File::IsDirectory(const std::string& path) {
struct stat buf;
if (stat(path.c_str(), &buf) == 0)
return buf.st_mode & S_IFDIR;
else
return false;
}
bool File::IsRegularFile(const std::string& path) {
struct stat buf;
if (stat(path.c_str(), &buf) == 0)
return buf.st_mode & S_IFREG;
else
return false;
}
ssize_t File::FileSize(const std::string& file_path) {
struct stat buf;
if (stat(file_path.c_str(), &buf) == 0)
return buf.st_size;
else
return -1;
}
} // namespace wvcdm

View File

@@ -34,20 +34,19 @@ CdmResponseType WvContentDecryptionModule::GenerateKeyRequest(
const CdmInitData& init_data,
const CdmLicenseType license_type,
CdmAppParameterMap& app_parameters,
CdmKeyMessage* key_request) {
CdmKeyMessage* key_request,
std::string* server_url) {
CdmKeySystem key_system;
return cdm_engine_->GenerateKeyRequest(session_id, false, key_system,
init_data, license_type,
app_parameters, key_request);
app_parameters, key_request,
server_url);
}
CdmResponseType WvContentDecryptionModule::AddKey(
const CdmSessionId& session_id,
const CdmKeyResponse& key_data) {
CdmKeySystem key_system;
CdmInitData init_data;
return cdm_engine_->AddKey(session_id, false, key_system,
init_data, key_data);
return cdm_engine_->AddKey(session_id, key_data);
}
CdmResponseType WvContentDecryptionModule::CancelKeyRequest(