Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Unified Diff: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc

Issue 884073002: Implement chrome.platformKeys.getKeyPair(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert_impl2
Patch Set: Rebased. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
index e9e32558b2818ee555c57f4988ac945b1ae05177..dc3dbf50e115c8b9dbba947097b41740dd2db11e 100644
--- a/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
+++ b/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc
@@ -4,7 +4,9 @@
#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
+#include <cert.h>
#include <cryptohi.h>
+#include <keyhi.h>
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -14,6 +16,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/worker_pool.h"
#include "chrome/browser/browser_process.h"
@@ -425,41 +428,67 @@ void RSASignOnWorkerThread(scoped_ptr<SignState> state) {
// TODO(pneubeck): This searches all slots. Change to look only at |slot_|.
scoped_ptr<crypto::RSAPrivateKey> rsa_key(
crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector));
- if (!rsa_key || rsa_key->key()->pkcs11Slot != state->slot_) {
+
+ // Fail if the key was not found. If a specific slot was requested, also fail
+ // if the key was found in the wrong slot.
+ if (!rsa_key ||
+ (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) {
state->OnError(FROM_HERE, kErrorKeyNotFound);
return;
}
- SECOidTag sign_alg_tag = SEC_OID_UNKNOWN;
- switch (state->hash_algorithm_) {
- case HASH_ALGORITHM_SHA1:
- sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
- break;
- case HASH_ALGORITHM_SHA256:
- sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
- break;
- case HASH_ALGORITHM_SHA384:
- sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
- break;
- case HASH_ALGORITHM_SHA512:
- sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
- break;
+ std::vector<unsigned char> data_vec(state->data_.begin(), state->data_.end());
+ std::string signature_str;
+ if (state->hash_algorithm_ == HASH_ALGORITHM_NONE) {
+ SECItem input = {siBuffer, vector_as_array(&data_vec), data_vec.size()};
+
+ // Compute signature of hash.
+ int signature_len = PK11_SignatureLen(rsa_key->key());
+ if (signature_len <= 0) {
+ state->OnError(FROM_HERE, kErrorInternal);
+ return;
+ }
+
+ std::vector<unsigned char> signature(signature_len);
+ SECItem signature_output = {
+ siBuffer, vector_as_array(&signature), signature.size()};
+ if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess)
+ signature_str.assign(signature.begin(), signature.end());
+ } else {
+ SECOidTag sign_alg_tag = SEC_OID_UNKNOWN;
+ switch (state->hash_algorithm_) {
+ case HASH_ALGORITHM_SHA1:
+ sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
+ break;
+ case HASH_ALGORITHM_SHA256:
+ sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
+ break;
+ case HASH_ALGORITHM_SHA384:
+ sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
+ break;
+ case HASH_ALGORITHM_SHA512:
+ sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
+ break;
+ case HASH_ALGORITHM_NONE:
+ NOTREACHED();
+ break;
+ }
+
+ SECItem sign_result = {siBuffer, nullptr, 0};
+ if (SEC_SignData(&sign_result, vector_as_array(&data_vec), data_vec.size(),
+ rsa_key->key(), sign_alg_tag) == SECSuccess) {
+ signature_str.assign(sign_result.data,
+ sign_result.data + sign_result.len);
+ }
}
- crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0));
- if (SEC_SignData(sign_result.get(),
- reinterpret_cast<const unsigned char*>(state->data_.data()),
- state->data_.size(),
- rsa_key->key(),
- sign_alg_tag) != SECSuccess) {
+ if (signature_str.empty()) {
LOG(ERROR) << "Couldn't sign.";
state->OnError(FROM_HERE, kErrorInternal);
return;
}
- std::string signature(reinterpret_cast<const char*>(sign_result->data),
- sign_result->len);
- state->CallBack(FROM_HERE, signature, std::string() /* no error */);
+ state->CallBack(FROM_HERE, signature_str, std::string() /* no error */);
}
// Continues signing with the obtained NSSCertDatabase. Used by Sign().
@@ -706,6 +735,34 @@ void SelectClientCertificates(const ClientCertificateRequest& request,
} // namespace subtle
+bool GetPublicKey(scoped_refptr<net::X509Certificate> certificate,
+ PublicKeyInfo* info) {
+ crypto::ScopedSECKEYPublicKey public_key(
+ CERT_ExtractPublicKey(certificate->os_cert_handle()));
+ if (!public_key) {
+ LOG(WARNING) << "Could not extract public key of certificate.";
+ return false;
+ }
+ const crypto::ScopedSECItem spki_der(
+ SECKEY_EncodeDERSubjectPublicKeyInfo(public_key.get()));
Ryan Sleevi 2015/02/03 01:44:50 Why this round trip? why not just certificate->os
pneubeck (no reviews) 2015/02/03 20:15:00 didn't know about that. changed, although it's tot
+ if (!spki_der) {
+ LOG(WARNING) << "Could not encode public key as SPKI.";
+ return false;
+ }
+
+ *info = PublicKeyInfo();
+ info->public_key_spki_der.assign(spki_der->data,
+ spki_der->data + spki_der->len);
+
+ if (public_key->keyType == rsaKey) {
+ info->key_type = net::X509Certificate::kPublicKeyTypeRSA;
+ info->modulus_length_bits =
+ SECKEY_PublicKeyStrengthInBits(public_key.get());
+ // TODO(pneubeck): Verify that the public exponent equals 65537.
Ryan Sleevi 2015/02/03 01:44:50 Yes, please do :)
pneubeck (no reviews) 2015/02/04 20:59:20 Done.
+ }
+ return true;
+}
+
void GetCertificates(const std::string& token_id,
const GetCertificatesCallback& callback,
BrowserContext* browser_context) {

Powered by Google App Engine
This is Rietveld 408576698