Chromium Code Reviews| Index: components/gcm_driver/instance_id/instance_id_impl.cc |
| diff --git a/components/gcm_driver/instance_id/instance_id_impl.cc b/components/gcm_driver/instance_id/instance_id_impl.cc |
| index 4d76ad2286cde3fddb590f048170526d1b93b50c..c0ad8927f08863e79795308c12aa60f89cda3798 100644 |
| --- a/components/gcm_driver/instance_id/instance_id_impl.cc |
| +++ b/components/gcm_driver/instance_id/instance_id_impl.cc |
| @@ -4,7 +4,13 @@ |
| #include "components/gcm_driver/instance_id/instance_id_impl.h" |
| +#include <algorithm> |
| +#include "base/base64.h" |
| +#include "base/bind.h" |
| #include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/sha1.h" |
| +#include "crypto/rsa_private_key.h" |
| namespace instance_id { |
| @@ -21,13 +27,13 @@ InstanceIDImpl::~InstanceIDImpl() { |
| } |
| std::string InstanceIDImpl::GetID() { |
| - NOTIMPLEMENTED(); |
| - return std::string(); |
| + EnsureIDGenerated(); |
| + return id_; |
| } |
| base::Time InstanceIDImpl::GetCreationTime() { |
| - NOTIMPLEMENTED(); |
| - return base::Time(); |
| + EnsureIDGenerated(); |
|
fgorski
2015/04/30 22:13:12
Are you sure we should create ID when code queries
jianli
2015/05/02 00:30:18
Sounds reasonable. Changed.
|
| + return creation_time_; |
| } |
| void InstanceIDImpl::GetToken( |
| @@ -45,7 +51,62 @@ void InstanceIDImpl::DeleteToken(const std::string& audience, |
| } |
| void InstanceIDImpl::DeleteID(const DeleteIDCallback& callback) { |
| - NOTIMPLEMENTED(); |
| + // TODO(jianli): Delete the key pair from the store. |
| + key_pair_.reset(); |
| + id_.clear(); |
| + creation_time_ = base::Time(); |
| + |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(callback, this, InstanceID::SUCCESS)); |
| +} |
| + |
| +void InstanceIDImpl::EnsureIDGenerated() { |
| + if (!id_.empty()) |
| + return; |
| + |
| + // Generate the public/private key pair based on random number generator if |
| + // not yet. |
| + if (!key_pair_) { |
| + key_pair_.reset(crypto::RSAPrivateKey::Create(2048)); |
|
fgorski
2015/04/30 22:13:12
const kKeyLength?
jianli
2015/05/02 00:30:18
Not needed any more.
|
| + if (!key_pair_) { |
| + DVLOG(1) << "Cannot generate key pair."; |
| + return; |
| + } |
| + |
| + // Record the time. |
| + creation_time_ = base::Time::Now(); |
| + |
| + // TODO(jianli): Store the key pair. |
| + } |
| + |
| + // Now produce the ID based on the public key of the key pair. |
| + |
| + // 1) Computes the SHA1 of public key of the key pair. |
| + std::vector<uint8> public_key; |
| + if (!key_pair_->ExportPublicKey(&public_key)) { |
| + DVLOG(1) << "Cannot export public key."; |
| + return; |
| + } |
| + |
| + uint8 digest[base::kSHA1Length]; |
| + base::SHA1HashBytes(public_key.data(), public_key.size(), digest); |
| + |
| + // 2) Transforms the first 4 bits of the SHA1 value to 0x9. |
| + uint8 d0 = digest[0]; |
| + d0 = 0x90 + (0xF & d0); |
| + digest[0] = d0 & 0xFF; |
| + |
| + // 3) Truncates the transformed SHA1 value to 8 bytes and encode it in in |
| + // Android-compatible base64 scheme: |
|
fgorski
2015/04/30 22:13:12
move below as point 4
jianli
2015/05/02 00:30:17
Not needed any more.
|
| + // * URL safe: '/' replaced by '_' and '+' replaced by '-'. |
| + // * No padding: any trailing '=' will be removed. |
| + base::Base64Encode( |
| + base::StringPiece(reinterpret_cast<const char*>(digest), 8), |
| + &id_); |
| + std::replace(id_.begin(), id_.end(), '+', '-'); |
| + std::replace(id_.begin(), id_.end(), '/', '_'); |
| + id_.erase(std::remove(id_.begin(), id_.end(), '='), id_.end()); |
| } |
| } // namespace instance_id |