1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/values.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h"
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/api/enterprise_platform_keys.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/api/enterprise_platform_keys_internal.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/cert/x509_certificate.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace extensions {
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace {
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace api_epk = api::enterprise_platform_keys;
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace api_epki = api::enterprise_platform_keys_internal;
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This error will occur if a token is removed and will be exposed to the
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// extension. Keep this in sync with the custom binding in Javascript.
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorInvalidToken[] = "The token is not valid.";
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kErrorInternal[] = "Internal Error.";
296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const char kErrorAlgorithmNotSupported[] = "Algorithm not supported.";
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorInvalidX509Cert[] =
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "Certificate is not a valid X.509 certificate.";
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kTokenIdUser[] = "user";
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kTokenIdSystem[] = "system";
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Returns whether |token_id| references a known Token.
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ValidateToken(const std::string& token_id,
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   std::string* platform_keys_token_id) {
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  platform_keys_token_id->clear();
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (token_id == kTokenIdUser) {
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *platform_keys_token_id = chromeos::platform_keys::kTokenIdUser;
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (token_id == kTokenIdSystem) {
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *platform_keys_token_id = chromeos::platform_keys::kTokenIdSystem;
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return true;
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return false;
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string PlatformKeysTokenIdToApiId(
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& platform_keys_token_id) {
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (platform_keys_token_id == chromeos::platform_keys::kTokenIdUser)
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return kTokenIdUser;
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (platform_keys_token_id == chromeos::platform_keys::kTokenIdSystem)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return kTokenIdSystem;
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return std::string();
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysInternalGenerateKeyFunction::
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ~EnterprisePlatformKeysInternalGenerateKeyFunction() {
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysInternalGenerateKeyFunction::Run() {
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<api_epki::GenerateKey::Params> params(
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      api_epki::GenerateKey::Params::Create(*args_));
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // TODO(pneubeck): Add support for unsigned integers to IDL.
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params && params->modulus_length >= 0);
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string platform_keys_token_id;
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ValidateToken(params->token_id, &platform_keys_token_id))
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidToken));
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  chromeos::PlatformKeysService* service =
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      chromeos::PlatformKeysServiceFactory::GetForBrowserContext(
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          browser_context());
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(service);
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  service->GenerateRSAKey(
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      platform_keys_token_id,
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      params->modulus_length,
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension_id(),
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &EnterprisePlatformKeysInternalGenerateKeyFunction::OnGeneratedKey,
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          this));
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return RespondLater();
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void EnterprisePlatformKeysInternalGenerateKeyFunction::OnGeneratedKey(
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& public_key_der,
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& error_message) {
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error_message.empty()) {
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ArgumentList(api_epki::GenerateKey::Results::Create(public_key_der)));
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(Error(error_message));
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysInternalSignFunction::
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ~EnterprisePlatformKeysInternalSignFunction() {
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysInternalSignFunction::Run() {
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<api_epki::Sign::Params> params(
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      api_epki::Sign::Params::Create(*args_));
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string platform_keys_token_id;
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ValidateToken(params->token_id, &platform_keys_token_id))
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidToken));
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  chromeos::platform_keys::HashAlgorithm hash_algorithm;
1176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (params->hash_algorithm_name == "SHA-1")
1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA1;
1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  else if (params->hash_algorithm_name == "SHA-256")
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA256;
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  else if (params->hash_algorithm_name == "SHA-384")
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA384;
1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  else if (params->hash_algorithm_name == "SHA-512")
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA512;
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  else
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return RespondNow(Error(kErrorAlgorithmNotSupported));
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  chromeos::PlatformKeysService* service =
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      chromeos::PlatformKeysServiceFactory::GetForBrowserContext(
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          browser_context());
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(service);
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  service->Sign(
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      platform_keys_token_id,
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      params->public_key,
1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      hash_algorithm,
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      params->data,
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension_id(),
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&EnterprisePlatformKeysInternalSignFunction::OnSigned, this));
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return RespondLater();
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void EnterprisePlatformKeysInternalSignFunction::OnSigned(
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& signature,
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& error_message) {
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error_message.empty())
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(ArgumentList(api_epki::Sign::Results::Create(signature)));
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(Error(error_message));
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysGetCertificatesFunction::
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ~EnterprisePlatformKeysGetCertificatesFunction() {
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysGetCertificatesFunction::Run() {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<api_epk::GetCertificates::Params> params(
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      api_epk::GetCertificates::Params::Create(*args_));
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string platform_keys_token_id;
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ValidateToken(params->token_id, &platform_keys_token_id))
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidToken));
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos::platform_keys::GetCertificates(
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      platform_keys_token_id,
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          &EnterprisePlatformKeysGetCertificatesFunction::OnGotCertificates,
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this),
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      browser_context());
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return RespondLater();
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void EnterprisePlatformKeysGetCertificatesFunction::OnGotCertificates(
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scoped_ptr<net::CertificateList> certs,
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& error_message) {
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!error_message.empty()) {
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(Error(error_message));
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::ListValue> client_certs(new base::ListValue());
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (net::CertificateList::const_iterator it = certs->begin();
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != certs->end();
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++it) {
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string der_encoding;
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    net::X509Certificate::GetDEREncoded((*it)->os_cert_handle(), &der_encoding);
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    client_certs->Append(base::BinaryValue::CreateWithCopiedBuffer(
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        der_encoding.data(), der_encoding.size()));
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<base::ListValue> results(new base::ListValue());
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  results->Append(client_certs.release());
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Respond(ArgumentList(results.Pass()));
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysImportCertificateFunction::
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ~EnterprisePlatformKeysImportCertificateFunction() {
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysImportCertificateFunction::Run() {
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<api_epk::ImportCertificate::Params> params(
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      api_epk::ImportCertificate::Params::Create(*args_));
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string platform_keys_token_id;
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ValidateToken(params->token_id, &platform_keys_token_id))
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidToken));
211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::string& cert_der = params->certificate;
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<net::X509Certificate> cert_x509 =
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!cert_x509.get())
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidX509Cert));
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos::platform_keys::ImportCertificate(
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      platform_keys_token_id,
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      cert_x509,
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&EnterprisePlatformKeysImportCertificateFunction::
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     OnImportedCertificate,
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 this),
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      browser_context());
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return RespondLater();
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void EnterprisePlatformKeysImportCertificateFunction::OnImportedCertificate(
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& error_message) {
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error_message.empty())
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(NoArguments());
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(Error(error_message));
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysRemoveCertificateFunction::
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ~EnterprisePlatformKeysRemoveCertificateFunction() {
239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysRemoveCertificateFunction::Run() {
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<api_epk::RemoveCertificate::Params> params(
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      api_epk::RemoveCertificate::Params::Create(*args_));
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string platform_keys_token_id;
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!ValidateToken(params->token_id, &platform_keys_token_id))
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidToken));
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const std::string& cert_der = params->certificate;
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<net::X509Certificate> cert_x509 =
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      net::X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!cert_x509.get())
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return RespondNow(Error(kErrorInvalidX509Cert));
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chromeos::platform_keys::RemoveCertificate(
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      platform_keys_token_id,
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      cert_x509,
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&EnterprisePlatformKeysRemoveCertificateFunction::
260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     OnRemovedCertificate,
261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 this),
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      browser_context());
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return RespondLater();
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void EnterprisePlatformKeysRemoveCertificateFunction::OnRemovedCertificate(
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& error_message) {
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (error_message.empty())
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(NoArguments());
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Respond(Error(error_message));
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysInternalGetTokensFunction::
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ~EnterprisePlatformKeysInternalGetTokensFunction() {
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)EnterprisePlatformKeysInternalGetTokensFunction::Run() {
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(args_->empty());
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  chromeos::platform_keys::GetTokens(
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&EnterprisePlatformKeysInternalGetTokensFunction::OnGotTokens,
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 this),
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      browser_context());
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return RespondLater();
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void EnterprisePlatformKeysInternalGetTokensFunction::OnGotTokens(
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<std::vector<std::string> > platform_keys_token_ids,
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& error_message) {
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!error_message.empty()) {
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Respond(Error(error_message));
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> token_ids;
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (std::vector<std::string>::const_iterator it =
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           platform_keys_token_ids->begin();
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != platform_keys_token_ids->end();
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string token_id = PlatformKeysTokenIdToApiId(*it);
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (token_id.empty()) {
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Respond(Error(kErrorInternal));
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return;
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    token_ids.push_back(token_id);
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Respond(ArgumentList(api_epki::GetTokens::Results::Create(token_ids)));
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace extensions
316