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 "chromeos/dbus/easy_unlock_client.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/bind.h"
     10 #include "base/compiler_specific.h"
     11 #include "dbus/bus.h"
     12 #include "dbus/message.h"
     13 #include "dbus/object_path.h"
     14 #include "dbus/object_proxy.h"
     15 #include "third_party/cros_system_api/dbus/service_constants.h"
     16 
     17 namespace chromeos {
     18 
     19 namespace {
     20 
     21 // Reads array of bytes from a dbus message reader and converts it to string.
     22 std::string PopResponseData(dbus::MessageReader* reader) {
     23   const uint8* bytes = NULL;
     24   size_t length = 0;
     25   if (!reader->PopArrayOfBytes(&bytes, &length))
     26     return "";
     27 
     28   return std::string(reinterpret_cast<const char*>(bytes), length);
     29 }
     30 
     31 // Converts string to array of bytes and writes it using dbus meddage writer.
     32 void AppendStringAsByteArray(const std::string& data,
     33                              dbus::MessageWriter* writer) {
     34   writer->AppendArrayOfBytes(reinterpret_cast<const uint8*>(data.data()),
     35                              data.length());
     36 }
     37 
     38 // The EasyUnlockClient used in production (and returned by
     39 // EasyUnlockClient::Create).
     40 class EasyUnlockClientImpl : public EasyUnlockClient {
     41  public:
     42   EasyUnlockClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {}
     43 
     44   virtual ~EasyUnlockClientImpl() {}
     45 
     46   // EasyUnlockClient override.
     47   virtual void PerformECDHKeyAgreement(const std::string& private_key,
     48                                        const std::string& public_key,
     49                                        const DataCallback& callback) OVERRIDE {
     50     dbus::MethodCall method_call(
     51         easy_unlock::kEasyUnlockServiceInterface,
     52         easy_unlock::kPerformECDHKeyAgreementMethod);
     53     dbus::MessageWriter writer(&method_call);
     54     // NOTE: DBus expects that data sent as string is UTF-8 encoded. This is
     55     //     not guaranteed here, so the method uses byte arrays.
     56     AppendStringAsByteArray(private_key, &writer);
     57     AppendStringAsByteArray(public_key, &writer);
     58     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
     59                        base::Bind(&EasyUnlockClientImpl::OnData,
     60                                   weak_ptr_factory_.GetWeakPtr(),
     61                                   callback));
     62   }
     63 
     64   // EasyUnlockClient override.
     65   virtual void GenerateEcP256KeyPair(const KeyPairCallback& callback) OVERRIDE {
     66     dbus::MethodCall method_call(
     67         easy_unlock::kEasyUnlockServiceInterface,
     68         easy_unlock::kGenerateEcP256KeyPairMethod);
     69     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
     70                        base::Bind(&EasyUnlockClientImpl::OnKeyPair,
     71                                   weak_ptr_factory_.GetWeakPtr(),
     72                                   callback));
     73   }
     74 
     75   // EasyUnlockClient override.
     76   virtual void CreateSecureMessage(const std::string& payload,
     77                                    const CreateSecureMessageOptions& options,
     78                                    const DataCallback& callback) OVERRIDE {
     79     dbus::MethodCall method_call(
     80         easy_unlock::kEasyUnlockServiceInterface,
     81         easy_unlock::kCreateSecureMessageMethod);
     82     dbus::MessageWriter writer(&method_call);
     83     // NOTE: DBus expects that data sent as string is UTF-8 encoded. This is
     84     //     not guaranteed here, so the method uses byte arrays.
     85     AppendStringAsByteArray(payload, &writer);
     86     AppendStringAsByteArray(options.key, &writer);
     87     AppendStringAsByteArray(options.associated_data, &writer);
     88     AppendStringAsByteArray(options.public_metadata, &writer);
     89     AppendStringAsByteArray(options.verification_key_id, &writer);
     90     AppendStringAsByteArray(options.decryption_key_id, &writer);
     91     writer.AppendString(options.encryption_type);
     92     writer.AppendString(options.signature_type);
     93     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
     94                        base::Bind(&EasyUnlockClientImpl::OnData,
     95                                   weak_ptr_factory_.GetWeakPtr(),
     96                                   callback));
     97   }
     98 
     99   // EasyUnlockClient override.
    100   virtual void UnwrapSecureMessage(const std::string& message,
    101                                    const UnwrapSecureMessageOptions& options,
    102                                    const DataCallback& callback) OVERRIDE {
    103     dbus::MethodCall method_call(
    104         easy_unlock::kEasyUnlockServiceInterface,
    105         easy_unlock::kUnwrapSecureMessageMethod);
    106     dbus::MessageWriter writer(&method_call);
    107     // NOTE: DBus expects that data sent as string is UTF-8 encoded. This is
    108     //     not guaranteed here, so the method uses byte arrays.
    109     AppendStringAsByteArray(message, &writer);
    110     AppendStringAsByteArray(options.key, &writer);
    111     AppendStringAsByteArray(options.associated_data, &writer);
    112     writer.AppendString(options.encryption_type);
    113     writer.AppendString(options.signature_type);
    114     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    115                        base::Bind(&EasyUnlockClientImpl::OnData,
    116                                   weak_ptr_factory_.GetWeakPtr(),
    117                                   callback));
    118   }
    119 
    120  protected:
    121   virtual void Init(dbus::Bus* bus) OVERRIDE {
    122     proxy_ =
    123         bus->GetObjectProxy(
    124             easy_unlock::kEasyUnlockServiceName,
    125             dbus::ObjectPath(easy_unlock::kEasyUnlockServicePath));
    126   }
    127 
    128  private:
    129   void OnData(const DataCallback& callback, dbus::Response* response) {
    130     if (!response) {
    131       callback.Run("");
    132       return;
    133     }
    134 
    135     dbus::MessageReader reader(response);
    136     callback.Run(PopResponseData(&reader));
    137   }
    138 
    139   void OnKeyPair(const KeyPairCallback& callback, dbus::Response* response) {
    140     if (!response) {
    141       callback.Run("", "");
    142       return;
    143     }
    144 
    145     dbus::MessageReader reader(response);
    146     std::string private_key = PopResponseData(&reader);
    147     std::string public_key = PopResponseData(&reader);
    148 
    149     if (public_key.empty() || private_key.empty()) {
    150       callback.Run("", "");
    151       return;
    152     }
    153 
    154     callback.Run(private_key, public_key);
    155   }
    156 
    157   dbus::ObjectProxy* proxy_;
    158 
    159   // Note: This should remain the last member so it'll be destroyed and
    160   // invalidate its weak pointers before any other members are destroyed.
    161   base::WeakPtrFactory<EasyUnlockClientImpl> weak_ptr_factory_;
    162 
    163   DISALLOW_COPY_AND_ASSIGN(EasyUnlockClientImpl);
    164 };
    165 
    166 }  // namespace
    167 
    168 EasyUnlockClient::CreateSecureMessageOptions::CreateSecureMessageOptions() {}
    169 
    170 EasyUnlockClient::CreateSecureMessageOptions::~CreateSecureMessageOptions() {}
    171 
    172 EasyUnlockClient::UnwrapSecureMessageOptions::UnwrapSecureMessageOptions() {}
    173 
    174 EasyUnlockClient::UnwrapSecureMessageOptions::~UnwrapSecureMessageOptions() {}
    175 
    176 EasyUnlockClient::EasyUnlockClient() {
    177 }
    178 
    179 EasyUnlockClient::~EasyUnlockClient() {
    180 }
    181 
    182 // static
    183 EasyUnlockClient* EasyUnlockClient::Create() {
    184   return new EasyUnlockClientImpl();
    185 }
    186 
    187 }  // namespace chromeos
    188