OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "base/json/json_string_value_serializer.h" |
| 6 #include "base/strings/stringprintf.h" |
5 #include "chromeos/dbus/fake_easy_unlock_client.h" | 7 #include "chromeos/dbus/fake_easy_unlock_client.h" |
6 | 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 |
7 namespace chromeos { | 40 namespace chromeos { |
8 | 41 |
9 FakeEasyUnlockClient::FakeEasyUnlockClient() {} | 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) {} |
10 | 54 |
11 FakeEasyUnlockClient::~FakeEasyUnlockClient() {} | 55 FakeEasyUnlockClient::~FakeEasyUnlockClient() {} |
12 | 56 |
13 void FakeEasyUnlockClient::Init(dbus::Bus* bus) {} | 57 void FakeEasyUnlockClient::Init(dbus::Bus* bus) {} |
14 | 58 |
15 void FakeEasyUnlockClient::GenerateEcP256KeyPair( | 59 void FakeEasyUnlockClient::GenerateEcP256KeyPair( |
16 const KeyPairCallback& callback) { | 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_)); |
17 } | 70 } |
18 | 71 |
19 void FakeEasyUnlockClient::PerformECDHKeyAgreement( | 72 void FakeEasyUnlockClient::PerformECDHKeyAgreement( |
20 const std::string& private_key, | 73 const std::string& private_key, |
21 const std::string& public_key, | 74 const std::string& public_key, |
22 const DataCallback& callback) { | 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)); |
23 } | 94 } |
24 | 95 |
25 void FakeEasyUnlockClient::CreateSecureMessage( | 96 void FakeEasyUnlockClient::CreateSecureMessage( |
26 const std::string& payload, | 97 const std::string& payload, |
27 const std::string& secret_key, | 98 const std::string& key, |
28 const std::string& associated_data, | 99 const std::string& associated_data, |
29 const std::string& public_metadata, | 100 const std::string& public_metadata, |
30 const std::string& verification_key_id, | 101 const std::string& verification_key_id, |
31 const std::string& encryption_type, | 102 const std::string& encryption_type, |
32 const std::string& signature_type, | 103 const std::string& signature_type, |
33 const DataCallback& callback) { | 104 const DataCallback& callback) { |
| 105 callback.Run(base::StringPrintf( |
| 106 "{\"securemessage\": {" |
| 107 "\"payload\": \"%s\"," |
| 108 "\"key\": \"%s\"," |
| 109 "\"associated_data\": \"%s\"," |
| 110 "\"public_metadata\": \"%s\"," |
| 111 "\"verification_key_id\": \"%s\"," |
| 112 "\"encryption_type\": \"%s\"," |
| 113 "\"signature_type\": \"%s\"" |
| 114 "}}", |
| 115 payload.c_str(), |
| 116 key.c_str(), |
| 117 associated_data.c_str(), |
| 118 public_metadata.c_str(), |
| 119 verification_key_id.c_str(), |
| 120 encryption_type.c_str(), |
| 121 signature_type.c_str())); |
34 } | 122 } |
35 | 123 |
36 void FakeEasyUnlockClient::UnwrapSecureMessage( | 124 void FakeEasyUnlockClient::UnwrapSecureMessage( |
37 const std::string& message, | 125 const std::string& message, |
38 const std::string& secret_key, | 126 const std::string& key, |
39 const std::string& associated_data, | 127 const std::string& associated_data, |
40 const std::string& encryption_type, | 128 const std::string& encryption_type, |
41 const std::string& signature_type, | 129 const std::string& signature_type, |
42 const DataCallback& callback) { | 130 const DataCallback& callback) { |
| 131 // TODO(tbarzic): Verify that |message| is in the format returned by |
| 132 // |CreateSecureMessage| and extract payload, metadata and |
| 133 // verification_key_id from there. |
| 134 callback.Run(base::StringPrintf( |
| 135 "{\"unwrapped_securemessage\": {" |
| 136 "\"message\": \"%s\"," |
| 137 "\"key\": \"%s\"," |
| 138 "\"associated_data\": \"%s\"," |
| 139 "\"encryption_type\": \"%s\"," |
| 140 "\"signature_type\": \"%s\"" |
| 141 "}}", |
| 142 message.c_str(), |
| 143 key.c_str(), |
| 144 associated_data.c_str(), |
| 145 encryption_type.c_str(), |
| 146 signature_type.c_str())); |
43 } | 147 } |
44 | 148 |
45 } // namespace chromeos | 149 } // namespace chromeos |
OLD | NEW |