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