1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file.
4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#ifndef CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <string>
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/callback_forward.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/macros.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/memory/weak_ptr.h"
146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/keyed_service/core/keyed_service.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace content {
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class BrowserContext;
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace base {
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ListValue;
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class Value;
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace extensions {
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class StateStore;
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace chromeos {
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class PlatformKeysService : public KeyedService {
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public:
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Stores registration information in |state_store|, i.e. for each extension
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // the list of public keys that are valid to be used for signing. Each key can
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // be used for signing at most once.
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The format written to |state_store| is:
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  //   kStateStorePlatformKeys maps to a list of strings.
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  //   Each string is the base64 encoding of the DER representation of a public
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  //   key's SPKI.
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit PlatformKeysService(content::BrowserContext* browser_context,
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                               extensions::StateStore* state_store);
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~PlatformKeysService();
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the generation was successful, |public_key_spki_der| will contain the
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // DER encoding of the SubjectPublicKeyInfo of the generated key and
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // |error_message| will be empty. If it failed, |public_key_spki_der| will be
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // empty and |error_message| contain an error message.
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  typedef base::Callback<void(const std::string& public_key_spki_der,
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const std::string& error_message)>
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GenerateKeyCallback;
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Generates a RSA key pair with |modulus_length_bits| and registers the key
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // to allow a single sign operation by the given extension. |token_id| is
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // currently ignored, instead the user token associated with |browser_context|
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // is always used. |callback| will be invoked with the resulting public key or
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // an error.
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Will only call back during the lifetime of this object.
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void GenerateRSAKey(const std::string& token_id,
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      unsigned int modulus_length_bits,
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      const std::string& extension_id,
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      const GenerateKeyCallback& callback);
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If signing was successful, |signature| will be contain the signature and
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // |error_message| will be empty. If it failed, |signature| will be empty and
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // |error_message| contain an error message.
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  typedef base::Callback<void(const std::string& signature,
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const std::string& error_message)> SignCallback;
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Digests |data| with |hash_algorithm| and afterwards signs the digest with
716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // the private key matching |public_key_spki_der|, if that key is stored in
726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // the given token and wasn't used for signing before.
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Unregisters the key so that every future attempt to sign data with this key
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // is rejected. |token_id| is currently ignored, instead the user token
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // associated with |browser_context| is always used. |public_key_spki_der|
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // must be the DER encoding of a SubjectPublicKeyInfo. |callback| will be
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // invoked with the signature or an error message. Currently supports RSA keys
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // only.
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Will only call back during the lifetime of this object.
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void Sign(const std::string& token_id,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            const std::string& public_key_spki_der,
826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            platform_keys::HashAlgorithm hash_algorithm,
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            const std::string& data,
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            const std::string& extension_id,
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            const SignCallback& callback);
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private:
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  typedef base::Callback<void(scoped_ptr<base::ListValue> platform_keys)>
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GetPlatformKeysCallback;
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Registers the given public key as newly generated key, which is allowed to
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // be used for signing for a single time. Afterwards, calls |callback|. If
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // registration was successful, passes |true| otherwise |false| to the
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // callback.
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void RegisterPublicKey(const std::string& extension_id,
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         const std::string& public_key_spki_der,
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         const base::Callback<void(bool)>& callback);
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Gets the current validity of the given public key by reading StateStore.
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Invalidates the key if it was found to be valid. Finally, calls |callback|
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // with the old validity.
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void ReadValidityAndInvalidateKey(const std::string& extension_id,
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    const std::string& public_key_spki_der,
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    const base::Callback<void(bool)>& callback);
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Reads the list of public keys currently registered for |extension_id| from
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // StateStore. Calls |callback| with the read list, or a new empty list if
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // none existed. If an error occurred, calls |callback| with NULL.
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void GetPlatformKeysOfExtension(const std::string& extension_id,
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                  const GetPlatformKeysCallback& callback);
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Callback used by |GenerateRSAKey|.
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the key generation was successful, registers the generated public key
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // for the given extension. If any error occurs during key generation or
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // registration, calls |callback| with an error. Otherwise, on success, calls
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // |callback| with the public key.
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void GenerateRSAKeyCallback(const std::string& extension_id,
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const GenerateKeyCallback& callback,
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const std::string& public_key_spki_der,
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const std::string& error_message);
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Callback used by |RegisterPublicKey|.
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Updates the old |platform_keys| read from the StateStore and writes the
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // updated value back to the StateStore.
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void RegisterPublicKeyGotPlatformKeys(
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const std::string& extension_id,
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const std::string& public_key_spki_der,
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const base::Callback<void(bool)>& callback,
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<base::ListValue> platform_keys);
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Callback used by |ReadValidityAndInvalidateKey|.
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Invalidates the given public key so that future signing is prohibited and
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // calls |callback| with the old validity.
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void InvalidateKey(const std::string& extension_id,
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     const std::string& public_key_spki_der,
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     const base::Callback<void(bool)>& callback,
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     scoped_ptr<base::ListValue> platform_keys);
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Callback used by |GetPlatformKeysOfExtension|.
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Is called with |value| set to the PlatformKeys value read from the
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // StateStore, which it forwards to |callback|. On error, calls |callback|
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // with NULL; if no value existed, with an empty list.
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void GotPlatformKeysOfExtension(const std::string& extension_id,
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                  const GetPlatformKeysCallback& callback,
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                  scoped_ptr<base::Value> value);
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  content::BrowserContext* browser_context_;
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  extensions::StateStore* state_store_;
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::WeakPtrFactory<PlatformKeysService> weak_factory_;
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PlatformKeysService);
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)};
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace chromeos
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // CHROME_BROWSER_CHROMEOS_PLATFORM_KEYS_PLATFORM_KEYS_SERVICE_H_
157