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..343646b1850b6a04a65e92ab0b9e521e3321d96f 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,34 @@ namespace extensions { |
namespace api_pk = api::platform_keys; |
namespace api_pki = api::platform_keys_internal; |
+namespace { |
+ |
+const char kErrorAlgorithmNotSupported[] = "Algorithm not supported."; |
+ |
+// Builds a partial WebCrypto Algorithm object from the parameters available in |
+// |key_info|. This doesn't include sign/hash parameters and thus isn't |
+// complete. |
+// For RSA, the default public exponent 65537 is assumed. |
+void BuildWebCryptoAlgorithmDictionary( |
+ const chromeos::platform_keys::PublicKeyInfo& key_info, |
+ base::DictionaryValue* algorithm) { |
+ algorithm->SetStringWithoutPathExpansion("name", "RSASSA-PKCS1-v1_5"); |
+ algorithm->SetIntegerWithoutPathExpansion("modulusLength", |
+ key_info.modulus_length_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 +79,34 @@ 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()); |
Ryan Sleevi
2015/02/03 01:44:50
SECURITY BUG: Validate that |cert_x509| is valid h
pneubeck (no reviews)
2015/02/03 20:15:00
Done.
|
+ |
+ chromeos::platform_keys::PublicKeyInfo 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; |
+ BuildWebCryptoAlgorithmDictionary(info, &algorithm.additional_properties); |
+ |
+ return RespondNow(ArgumentList(api_pki::GetPublicKey::Results::Create( |
+ info.public_key_spki_der, algorithm))); |
+} |
+ |
PlatformKeysInternalSelectClientCertificatesFunction:: |
~PlatformKeysInternalSelectClientCertificatesFunction() { |
} |
@@ -95,12 +148,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::PublicKeyInfo 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()); |
+ |
+ BuildWebCryptoAlgorithmDictionary( |
+ key_info, &result_match->key_algorithm.additional_properties); |
result_matches.push_back(result_match); |
} |
Respond(ArgumentList( |
@@ -115,11 +181,16 @@ 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") |
+ if (params->hash_algorithm_name == "none") |
+ hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_NONE; |
+ else 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; |
@@ -128,7 +199,7 @@ ExtensionFunction::ResponseAction PlatformKeysInternalSignFunction::Run() { |
else if (params->hash_algorithm_name == "SHA-512") |
hash_algorithm = chromeos::platform_keys::HASH_ALGORITHM_SHA512; |
else |
- return RespondNow(Error(platform_keys::kErrorAlgorithmNotSupported)); |
+ return RespondNow(Error(kErrorAlgorithmNotSupported)); |
chromeos::PlatformKeysService* service = |
chromeos::PlatformKeysServiceFactory::GetForBrowserContext( |