Home | History | Annotate | Download | only in dbus
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/json/json_string_value_serializer.h"
      6 #include "base/strings/stringprintf.h"
      7 #include "chromeos/dbus/fake_easy_unlock_client.h"
      8 
      9 namespace {
     10 
     11 // Keys generated using |GenerateEcP256KeyPair| are in the following format:
     12 // "{<key_type>: <key_pair_index>}".
     13 // <key_pair_index> is an integer identifying
     14 // the key pair.
     15 // <key_type> specifies whether the key is public or private. It can have one
     16 // of the following valies:
     17 const char kEc256PrivateKeyKey[] = "ec_p256_private_key";
     18 const char kEc256PublicKeyKey[] = "ec_p256_public_key";
     19 
     20 // Extracts key pair index from a key in format "<key_type>: <key_pair_index>}".
     21 int ExtractKeyPairIndexFromKey(const std::string& key,
     22                                const std::string& key_type) {
     23   JSONStringValueSerializer serializer(key);
     24   scoped_ptr<base::Value> json_value(serializer.Deserialize(NULL, NULL));
     25   if (!json_value)
     26     return -1;
     27 
     28   base::DictionaryValue* json_dictionary = NULL;
     29   if (!json_value->GetAsDictionary(&json_dictionary))
     30     return -1;
     31 
     32   int key_pair_index = -1;
     33   if (!json_dictionary->GetInteger(key_type, &key_pair_index))
     34     return -1;
     35   return key_pair_index;
     36 }
     37 
     38 }  // namespace
     39 
     40 namespace chromeos {
     41 
     42 // static
     43 bool FakeEasyUnlockClient::IsEcP256KeyPair(const std::string& private_key,
     44                                            const std::string& public_key) {
     45   int private_key_index =
     46       ExtractKeyPairIndexFromKey(private_key, kEc256PrivateKeyKey);
     47   int public_key_index =
     48       ExtractKeyPairIndexFromKey(public_key, kEc256PublicKeyKey);
     49 
     50   return private_key_index > 0  && public_key_index == private_key_index;
     51 }
     52 
     53 FakeEasyUnlockClient::FakeEasyUnlockClient() : generated_keys_count_(0) {}
     54 
     55 FakeEasyUnlockClient::~FakeEasyUnlockClient() {}
     56 
     57 void FakeEasyUnlockClient::Init(dbus::Bus* bus) {}
     58 
     59 void FakeEasyUnlockClient::GenerateEcP256KeyPair(
     60     const KeyPairCallback& callback) {
     61   ++generated_keys_count_;
     62 
     63   callback.Run(
     64       base::StringPrintf("{\"%s\": %d}",
     65                          kEc256PrivateKeyKey,
     66                          generated_keys_count_),
     67       base::StringPrintf("{\"%s\": %d}",
     68                          kEc256PublicKeyKey,
     69                          generated_keys_count_));
     70 }
     71 
     72 void FakeEasyUnlockClient::PerformECDHKeyAgreement(
     73     const std::string& private_key,
     74     const std::string& public_key,
     75     const DataCallback& callback) {
     76   int private_key_index =
     77       ExtractKeyPairIndexFromKey(private_key, kEc256PrivateKeyKey);
     78   int public_key_index =
     79       ExtractKeyPairIndexFromKey(public_key, kEc256PublicKeyKey);
     80   if (private_key_index < 0 || public_key_index < 0) {
     81     callback.Run("");
     82     return;
     83   }
     84 
     85   // ECDH key agreement should be commutative in respect to key pairs to which
     86   // used keys belong, i.e. (key_pair[1].private_key, key_pair[2].public_key)
     87   // and (key_pair[2].private_key, key_pair[1].public_key) should produce the
     88   // same shared key. To achieve this, identify the created key by sum and
     89   // product of the used key pairs.
     90   callback.Run(base::StringPrintf(
     91       "{\"secret_key\": [%d, %d]}",
     92       private_key_index + public_key_index,
     93       private_key_index * public_key_index));
     94 }
     95 
     96 void FakeEasyUnlockClient::CreateSecureMessage(
     97     const std::string& payload,
     98     const CreateSecureMessageOptions& options,
     99     const DataCallback& callback) {
    100   callback.Run(base::StringPrintf(
    101       "{\"securemessage\": {"
    102           "\"payload\": \"%s\","
    103           "\"key\": \"%s\","
    104           "\"associated_data\": \"%s\","
    105           "\"public_metadata\": \"%s\","
    106           "\"verification_key_id\": \"%s\","
    107           "\"decryption_key_id\": \"%s\","
    108           "\"encryption_type\": \"%s\","
    109           "\"signature_type\": \"%s\""
    110       "}}",
    111       payload.c_str(),
    112       options.key.c_str(),
    113       options.associated_data.c_str(),
    114       options.public_metadata.c_str(),
    115       options.verification_key_id.c_str(),
    116       options.decryption_key_id.c_str(),
    117       options.encryption_type.c_str(),
    118       options.signature_type.c_str()));
    119 }
    120 
    121 void FakeEasyUnlockClient::UnwrapSecureMessage(
    122     const std::string& message,
    123     const UnwrapSecureMessageOptions& options,
    124     const DataCallback& callback) {
    125   // TODO(tbarzic): Verify that |message| is in the format returned by
    126   // |CreateSecureMessage| and extract payload, metadata and
    127   // verification_key_id from there.
    128   callback.Run(base::StringPrintf(
    129       "{\"unwrapped_securemessage\": {"
    130           "\"message\": \"%s\","
    131           "\"key\": \"%s\","
    132           "\"associated_data\": \"%s\","
    133           "\"encryption_type\": \"%s\","
    134           "\"signature_type\": \"%s\""
    135       "}}",
    136       message.c_str(),
    137       options.key.c_str(),
    138       options.associated_data.c_str(),
    139       options.encryption_type.c_str(),
    140       options.signature_type.c_str()));
    141 }
    142 
    143 }  // namespace chromeos
    144