| Index: chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
|
| diff --git a/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc b/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
|
| index 9a4e2d29a5b39b1a1640573e98e742d965f4d367..08f5f6f77111667ec47f4c7d078c07b5ffa76fd0 100644
|
| --- a/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
|
| +++ b/chrome/browser/extensions/api/platform_keys/platform_keys_api.cc
|
| @@ -8,6 +8,7 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/logging.h"
|
| +#include "base/values.h"
|
| #include "chrome/browser/chromeos/platform_keys/platform_keys.h"
|
| #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
|
| #include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h"
|
| @@ -20,10 +21,37 @@ namespace extensions {
|
| namespace api_pk = api::platform_keys;
|
| namespace api_pki = api::platform_keys_internal;
|
|
|
| +namespace {
|
| +
|
| +const char kErrorAlgorithmNotSupported[] = "Algorithm not supported.";
|
| +const char kErrorInvalidX509Cert[] =
|
| + "Certificate is not a valid X.509 certificate.";
|
| +
|
| +// Builds a partial WebCrypto Algorithm object from the parameters available in
|
| +// |key_info|, which must the info of a RSA key. This doesn't include sign/hash
|
| +// parameters and thus isn't complete.
|
| +// platform_keys::GetPublicKey() enforced the public exponent 65537.
|
| +void BuildWebCryptoRSAAlgorithmDictionary(
|
| + const chromeos::platform_keys::GetPublicKeyResult& key_info,
|
| + base::DictionaryValue* algorithm) {
|
| + CHECK_EQ(net::X509Certificate::kPublicKeyTypeRSA, key_info.key_type);
|
| + algorithm->SetStringWithoutPathExpansion("name", "RSASSA-PKCS1-v1_5");
|
| + algorithm->SetIntegerWithoutPathExpansion("modulusLength",
|
| + key_info.key_size_bits);
|
| +
|
| + // Equals 65537.
|
| + const char defaultPublicExponent[] = {0x01, 0x00, 0x01};
|
| + algorithm->SetWithoutPathExpansion(
|
| + "publicExponent",
|
| + base::BinaryValue::CreateWithCopiedBuffer(
|
| + defaultPublicExponent, arraysize(defaultPublicExponent)));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| namespace platform_keys {
|
|
|
| const char kErrorInvalidToken[] = "The token is not valid.";
|
| -const char kErrorAlgorithmNotSupported[] = "Algorithm not supported.";
|
| const char kTokenIdUser[] = "user";
|
| const char kTokenIdSystem[] = "system";
|
|
|
| @@ -54,6 +82,38 @@ std::string PlatformKeysTokenIdToApiId(
|
|
|
| } // namespace platform_keys
|
|
|
| +PlatformKeysInternalGetPublicKeyFunction::
|
| + ~PlatformKeysInternalGetPublicKeyFunction() {
|
| +}
|
| +
|
| +ExtensionFunction::ResponseAction
|
| +PlatformKeysInternalGetPublicKeyFunction::Run() {
|
| + scoped_ptr<api_pki::GetPublicKey::Params> params(
|
| + api_pki::GetPublicKey::Params::Create(*args_));
|
| + EXTENSION_FUNCTION_VALIDATE(params);
|
| +
|
| + const std::vector<char>& cert_der = params->certificate;
|
| + scoped_refptr<net::X509Certificate> cert_x509 =
|
| + net::X509Certificate::CreateFromBytes(vector_as_array(&cert_der),
|
| + cert_der.size());
|
| + if (!cert_x509)
|
| + return RespondNow(Error(kErrorInvalidX509Cert));
|
| +
|
| + chromeos::platform_keys::GetPublicKeyResult info;
|
| + if (!chromeos::platform_keys::GetPublicKey(cert_x509, &info) ||
|
| + info.key_type != net::X509Certificate::kPublicKeyTypeRSA) {
|
| + return RespondNow(Error(kErrorAlgorithmNotSupported));
|
| + }
|
| +
|
| + api_pki::GetPublicKey::Results::Algorithm algorithm;
|
| + BuildWebCryptoRSAAlgorithmDictionary(info, &algorithm.additional_properties);
|
| +
|
| + return RespondNow(ArgumentList(api_pki::GetPublicKey::Results::Create(
|
| + std::vector<char>(info.public_key_spki_der.begin(),
|
| + info.public_key_spki_der.end()),
|
| + algorithm)));
|
| +}
|
| +
|
| PlatformKeysInternalSelectClientCertificatesFunction::
|
| ~PlatformKeysInternalSelectClientCertificatesFunction() {
|
| }
|
| @@ -95,12 +155,25 @@ void PlatformKeysInternalSelectClientCertificatesFunction::
|
| DCHECK(matches);
|
| std::vector<linked_ptr<api_pk::Match>> result_matches;
|
| for (const scoped_refptr<net::X509Certificate>& match : *matches) {
|
| + chromeos::platform_keys::GetPublicKeyResult key_info;
|
| + if (!chromeos::platform_keys::GetPublicKey(match, &key_info)) {
|
| + LOG(ERROR) << "Could not retrieve public key info.";
|
| + continue;
|
| + }
|
| + if (key_info.key_type != net::X509Certificate::kPublicKeyTypeRSA) {
|
| + LOG(ERROR) << "Skipping unsupported certificate with non-RSA key.";
|
| + continue;
|
| + }
|
| +
|
| linked_ptr<api_pk::Match> result_match(new api_pk::Match);
|
| std::string der_encoded_cert;
|
| net::X509Certificate::GetDEREncoded(match->os_cert_handle(),
|
| &der_encoded_cert);
|
| result_match->certificate.assign(der_encoded_cert.begin(),
|
| der_encoded_cert.end());
|
| +
|
| + BuildWebCryptoRSAAlgorithmDictionary(
|
| + key_info, &result_match->key_algorithm.additional_properties);
|
| result_matches.push_back(result_match);
|
| }
|
| Respond(ArgumentList(
|
| @@ -115,31 +188,46 @@ ExtensionFunction::ResponseAction PlatformKeysInternalSignFunction::Run() {
|
| api_pki::Sign::Params::Create(*args_));
|
| EXTENSION_FUNCTION_VALIDATE(params);
|
| std::string platform_keys_token_id;
|
| - if (!platform_keys::ValidateToken(params->token_id, &platform_keys_token_id))
|
| + if (!params->token_id.empty() &&
|
| + !platform_keys::ValidateToken(params->token_id,
|
| + &platform_keys_token_id)) {
|
| return RespondNow(Error(platform_keys::kErrorInvalidToken));
|
| + }
|
|
|
| - chromeos::platform_keys::HashAlgorithm hash_algorithm;
|
| - if (params->hash_algorithm_name == "SHA-1")
|
| - hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA1;
|
| - else if (params->hash_algorithm_name == "SHA-256")
|
| - hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA256;
|
| - else if (params->hash_algorithm_name == "SHA-384")
|
| - hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA384;
|
| - else if (params->hash_algorithm_name == "SHA-512")
|
| - hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA512;
|
| - else
|
| - return RespondNow(Error(platform_keys::kErrorAlgorithmNotSupported));
|
| + scoped_ptr<chromeos::platform_keys::SignRSAParams> sign_params;
|
| +
|
| + if (params->hash_algorithm_name == "none") {
|
| + sign_params =
|
| + chromeos::platform_keys::SignRSAParams::CreateDirectSignParams(
|
| + std::string(params->data.begin(), params->data.end()),
|
| + std::string(params->public_key.begin(), params->public_key.end()));
|
| + } else {
|
| + chromeos::platform_keys::HashAlgorithm hash_algorithm;
|
| + if (params->hash_algorithm_name == "SHA-1") {
|
| + hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA1;
|
| + } else if (params->hash_algorithm_name == "SHA-256") {
|
| + hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA256;
|
| + } else if (params->hash_algorithm_name == "SHA-384") {
|
| + hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA384;
|
| + } else if (params->hash_algorithm_name == "SHA-512") {
|
| + hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA512;
|
| + } else {
|
| + return RespondNow(Error(kErrorAlgorithmNotSupported));
|
| + }
|
| + sign_params =
|
| + chromeos::platform_keys::SignRSAParams::CreateSignParamsWithHashing(
|
| + std::string(params->data.begin(), params->data.end()),
|
| + std::string(params->public_key.begin(), params->public_key.end()),
|
| + hash_algorithm);
|
| + }
|
|
|
| chromeos::PlatformKeysService* service =
|
| chromeos::PlatformKeysServiceFactory::GetForBrowserContext(
|
| browser_context());
|
| DCHECK(service);
|
|
|
| - service->Sign(
|
| - platform_keys_token_id,
|
| - std::string(params->public_key.begin(), params->public_key.end()),
|
| - hash_algorithm, std::string(params->data.begin(), params->data.end()),
|
| - extension_id(),
|
| + service->SignRSA(
|
| + platform_keys_token_id, sign_params.Pass(), extension_id(),
|
| base::Bind(&PlatformKeysInternalSignFunction::OnSigned, this));
|
| return RespondLater();
|
| }
|
|
|