summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc5
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h1
-rw-r--r--net/base/keygen_handler.h16
-rw-r--r--net/base/keygen_handler_mac.cc31
-rw-r--r--net/base/keygen_handler_nss.cc2
-rw-r--r--net/base/keygen_handler_unittest.cc5
-rw-r--r--net/third_party/mozilla_security_manager/nsKeygenHandler.cpp17
-rw-r--r--net/third_party/mozilla_security_manager/nsKeygenHandler.h4
8 files changed, 69 insertions, 12 deletions
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 797ed3c..b6bf854 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -1558,7 +1558,7 @@ void ResourceMessageFilter::OnKeygen(uint32 key_size_index,
FROM_HERE,
NewRunnableMethod(
this, &ResourceMessageFilter::OnKeygenOnWorkerThread,
- key_size_in_bits, challenge_string, reply_msg),
+ key_size_in_bits, challenge_string, url, reply_msg),
true)) {
NOTREACHED() << "Failed to dispatch keygen task to worker pool";
ViewHostMsg_Keygen::WriteReplyParams(reply_msg, std::string());
@@ -1570,13 +1570,14 @@ void ResourceMessageFilter::OnKeygen(uint32 key_size_index,
void ResourceMessageFilter::OnKeygenOnWorkerThread(
int key_size_in_bits,
const std::string& challenge_string,
+ const GURL& url,
IPC::Message* reply_msg) {
DCHECK(reply_msg);
// Verify we are on a worker thread.
DCHECK(!MessageLoop::current());
// Generate a signed public key and challenge, then send it back.
- net::KeygenHandler keygen_handler(key_size_in_bits, challenge_string);
+ net::KeygenHandler keygen_handler(key_size_in_bits, challenge_string, url);
ViewHostMsg_Keygen::WriteReplyParams(
reply_msg,
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 16e329b..6f47917 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -359,6 +359,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnKeygenOnWorkerThread(
int key_size_in_bits,
const std::string& challenge_string,
+ const GURL& url,
IPC::Message* reply_msg);
void OnGetExtensionMessageBundle(const std::string& extension_id,
IPC::Message* reply_msg);
diff --git a/net/base/keygen_handler.h b/net/base/keygen_handler.h
index 3f3a115..5ca6027 100644
--- a/net/base/keygen_handler.h
+++ b/net/base/keygen_handler.h
@@ -8,6 +8,8 @@
#include <string>
+#include "googleurl/src/gurl.h"
+
namespace net {
// This class handles keypair generation for generating client
@@ -17,9 +19,12 @@ namespace net {
class KeygenHandler {
public:
- // Creates a handler that will generate a key with the given key size
- // and incorporate the |challenge| into the Netscape SPKAC structure.
- inline KeygenHandler(int key_size_in_bits, const std::string& challenge);
+ // Creates a handler that will generate a key with the given key size and
+ // incorporate the |challenge| into the Netscape SPKAC structure. The request
+ // for the key originated from |url|.
+ inline KeygenHandler(int key_size_in_bits,
+ const std::string& challenge,
+ const GURL& url);
// Actually generates the key-pair and the cert request (SPKAC), and returns
// a base64-encoded string suitable for use as the form value of <keygen>.
@@ -31,13 +36,16 @@ class KeygenHandler {
private:
int key_size_in_bits_; // key size in bits (usually 2048)
std::string challenge_; // challenge string sent by server
+ GURL url_; // the URL that requested the key
bool stores_key_; // should the generated key-pair be stored persistently?
};
KeygenHandler::KeygenHandler(int key_size_in_bits,
- const std::string& challenge)
+ const std::string& challenge,
+ const GURL& url)
: key_size_in_bits_(key_size_in_bits),
challenge_(challenge),
+ url_(url),
stores_key_(true) {
}
diff --git a/net/base/keygen_handler_mac.cc b/net/base/keygen_handler_mac.cc
index c2c63d7..f5097a3 100644
--- a/net/base/keygen_handler_mac.cc
+++ b/net/base/keygen_handler_mac.cc
@@ -13,6 +13,8 @@
#include "base/lock.h"
#include "base/logging.h"
#include "base/scoped_cftyperef.h"
+#include "base/string_util.h"
+#include "base/sys_string_conversions.h"
// These are in Security.framework but not declared in a public header.
extern const SecAsn1Template kSecAsn1AlgorithmIDTemplate[];
@@ -89,6 +91,7 @@ static const SecAsn1Template kSignedPublicKeyAndChallengeTemplate[] = {
static OSStatus CreateRSAKeyPair(int size_in_bits,
+ SecAccessRef initial_access,
SecKeyRef* out_pub_key,
SecKeyRef* out_priv_key);
static OSStatus SignData(CSSM_DATA data,
@@ -98,14 +101,31 @@ static OSStatus SignData(CSSM_DATA data,
std::string KeygenHandler::GenKeyAndSignChallenge() {
std::string result;
OSStatus err;
+ SecAccessRef initial_access = NULL;
SecKeyRef public_key = NULL;
SecKeyRef private_key = NULL;
SecAsn1CoderRef coder = NULL;
CSSM_DATA signature = {0, NULL};
{
+ if (url_.has_host()) {
+ // TODO(davidben): Use something like "Key generated for
+ // example.com", but localize it.
+ scoped_cftyperef<CFStringRef> label(
+ base::SysUTF8ToCFStringRef(url_.host()));
+ // Create an initial access object to set the SecAccessRef. This
+ // sets a label on the Keychain dialogs. Pass NULL as the second
+ // argument to use the default trusted list; only allow the
+ // current application to access without user confirmation.
+ err = SecAccessCreate(label, NULL, &initial_access);
+ // If we fail, just continue without a label.
+ if (err)
+ base::LogCSSMError("SecAccessCreate", err);
+ }
+
// Create the key-pair.
- err = CreateRSAKeyPair(key_size_in_bits_, &public_key, &private_key);
+ err = CreateRSAKeyPair(key_size_in_bits_, initial_access,
+ &public_key, &private_key);
if (err)
goto failure;
@@ -188,6 +208,8 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
free(signature.Data);
if (coder)
SecAsn1CoderRelease(coder);
+ if (initial_access)
+ CFRelease(initial_access);
if (public_key)
CFRelease(public_key);
if (private_key)
@@ -196,7 +218,12 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
}
+// Create an RSA key pair with size |size_in_bits|. |initial_access|
+// is passed as the initial access control list in Keychain. The
+// public and private keys are placed in |out_pub_key| and
+// |out_priv_key|, respectively.
static OSStatus CreateRSAKeyPair(int size_in_bits,
+ SecAccessRef initial_access,
SecKeyRef* out_pub_key,
SecKeyRef* out_priv_key) {
OSStatus err;
@@ -221,7 +248,7 @@ static OSStatus CreateRSAKeyPair(int size_in_bits,
CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP,
CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT |
CSSM_KEYATTR_SENSITIVE,
- NULL,
+ initial_access,
out_pub_key, out_priv_key);
}
if (err)
diff --git a/net/base/keygen_handler_nss.cc b/net/base/keygen_handler_nss.cc
index 638fbd5..215244c 100644
--- a/net/base/keygen_handler_nss.cc
+++ b/net/base/keygen_handler_nss.cc
@@ -12,7 +12,7 @@ namespace psm = mozilla_security_manager;
namespace net {
std::string KeygenHandler::GenKeyAndSignChallenge() {
- return psm::GenKeyAndSignChallenge(key_size_in_bits_, challenge_,
+ return psm::GenKeyAndSignChallenge(key_size_in_bits_, challenge_, url_,
stores_key_);
}
diff --git a/net/base/keygen_handler_unittest.cc b/net/base/keygen_handler_unittest.cc
index 9f6902e..85fd0bc 100644
--- a/net/base/keygen_handler_unittest.cc
+++ b/net/base/keygen_handler_unittest.cc
@@ -73,7 +73,7 @@ void AssertValidSignedPublicKeyAndChallenge(const std::string& result,
}
TEST_F(KeygenHandlerTest, SmokeTest) {
- KeygenHandler handler(768, "some challenge");
+ KeygenHandler handler(768, "some challenge", GURL("http://www.example.com"));
handler.set_stores_key(false); // Don't leave the key-pair behind
std::string result = handler.GenKeyAndSignChallenge();
LOG(INFO) << "KeygenHandler produced: " << result;
@@ -90,7 +90,8 @@ class ConcurrencyTestTask : public Task {
}
virtual void Run() {
- KeygenHandler handler(768, "some challenge");
+ KeygenHandler handler(768, "some challenge",
+ GURL("http://www.example.com"));
handler.set_stores_key(false); // Don't leave the key-pair behind.
*result_ = handler.GenKeyAndSignChallenge();
event_->Signal();
diff --git a/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp b/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp
index ffef66d..99d5206 100644
--- a/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp
+++ b/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp
@@ -48,9 +48,11 @@
#include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo()
#include "base/base64.h"
+#include "base/logging.h"
#include "base/nss_util_internal.h"
#include "base/nss_util.h"
-#include "base/logging.h"
+#include "base/string_util.h"
+#include "googleurl/src/gurl.h"
namespace {
@@ -94,6 +96,7 @@ namespace mozilla_security_manager {
// in mozilla/security/manager/ssl/src/nsKeygenHandler.cpp.
std::string GenKeyAndSignChallenge(int key_size_in_bits,
const std::string& challenge,
+ const GURL& url,
bool stores_key) {
// Key pair generation mechanism - only RSA is supported at present.
PRUint32 keyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; // from nss/pkcs11t.h
@@ -171,6 +174,18 @@ std::string GenKeyAndSignChallenge(int key_size_in_bits,
goto failure;
}
+ // Set friendly names for the keys.
+ if (url.has_host()) {
+ // TODO(davidben): Use something like "Key generated for
+ // example.com", but localize it.
+ const std::string& label = url.host();
+ {
+ base::AutoNSSWriteLock lock;
+ PK11_SetPublicKeyNickname(publicKey, label.c_str());
+ PK11_SetPrivateKeyNickname(privateKey, label.c_str());
+ }
+ }
+
// The CA expects the signed public key in a specific format
// Let's create that now.
diff --git a/net/third_party/mozilla_security_manager/nsKeygenHandler.h b/net/third_party/mozilla_security_manager/nsKeygenHandler.h
index 75703bb..ae1f5a3 100644
--- a/net/third_party/mozilla_security_manager/nsKeygenHandler.h
+++ b/net/third_party/mozilla_security_manager/nsKeygenHandler.h
@@ -42,6 +42,8 @@
#include <string>
+class GURL;
+
namespace mozilla_security_manager {
#define DEFAULT_RSA_KEYGEN_PE 65537L
@@ -52,9 +54,11 @@ namespace mozilla_security_manager {
// Parameters:
// key_size_in_bits: key size in bits (usually 2048)
// challenge: challenge string sent by server
+// url: the URL which requested the SPKAC
// stores_key: should the generated key pair be stored persistently?
std::string GenKeyAndSignChallenge(int key_size_in_bits,
const std::string& challenge,
+ const GURL& url,
bool stores_key);
} // namespace mozilla_security_manager