diff options
author | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-18 17:45:35 +0000 |
---|---|---|
committer | wtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-18 17:45:35 +0000 |
commit | 53ae7c4c5f08e73d66ef8b2303691d893f5d9e47 (patch) | |
tree | c7ae41ec0c4737fadfa2e280dc62dbd75ef44840 /net/third_party/mozilla_security_manager | |
parent | 1dc71e991f01466e70e86d42a89667e36ec211de (diff) | |
download | chromium_src-53ae7c4c5f08e73d66ef8b2303691d893f5d9e47.zip chromium_src-53ae7c4c5f08e73d66ef8b2303691d893f5d9e47.tar.gz chromium_src-53ae7c4c5f08e73d66ef8b2303691d893f5d9e47.tar.bz2 |
Move the Mozilla-derived code in net/base/keygen_handler_nss.cc
to the new net/third_party/mozilla_security_manager directory.
Fix nits.
R=mattm,davidben
BUG=148
TEST=none
Review URL: http://codereview.chromium.org/2824014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50259 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party/mozilla_security_manager')
4 files changed, 388 insertions, 0 deletions
diff --git a/net/third_party/mozilla_security_manager/LICENSE b/net/third_party/mozilla_security_manager/LICENSE new file mode 100644 index 0000000..17de8fb --- /dev/null +++ b/net/third_party/mozilla_security_manager/LICENSE @@ -0,0 +1,35 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ diff --git a/net/third_party/mozilla_security_manager/README.chromium b/net/third_party/mozilla_security_manager/README.chromium new file mode 100644 index 0000000..d030d65 --- /dev/null +++ b/net/third_party/mozilla_security_manager/README.chromium @@ -0,0 +1,12 @@ +Name: Mozilla Personal Security Manager +URL: http://mxr.mozilla.org/mozilla1.9.2/source/security/manager/ +InfoURL: http://www.mozilla.org/ +Version: Mozilla 1.9.2 + +Description: +This is selected code bits from Mozilla's Personal Security Manager. + +Local Modifications: +Files are forked from Mozilla's because of the heavy adaptations necessary. +Differences are using Chromium localization and other libraries instead of +Mozilla's, matching the Chromium style, etc. diff --git a/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp b/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp new file mode 100644 index 0000000..e6ab574 --- /dev/null +++ b/net/third_party/mozilla_security_manager/nsKeygenHandler.cpp @@ -0,0 +1,285 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Vipul Gupta <vipul.gupta@sun.com> + * Douglas Stebila <douglas@stebila.ca> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "net/third_party/mozilla_security_manager/nsKeygenHandler.h" + +#include <pk11pub.h> +#include <secmod.h> +#include <secder.h> // DER_Encode() +#include <cryptohi.h> // SEC_DerSignData() +#include <keyhi.h> // SECKEY_CreateSubjectPublicKeyInfo() + +#include "base/base64.h" +#include "base/nss_util_internal.h" +#include "base/nss_util.h" +#include "base/logging.h" +#include "net/base/keygen_handler.h" + +namespace { + +// Template for creating the signed public key structure to be sent to the CA. +DERTemplate SECAlgorithmIDTemplate[] = { + { DER_SEQUENCE, + 0, NULL, sizeof(SECAlgorithmID) }, + { DER_OBJECT_ID, + offsetof(SECAlgorithmID, algorithm), }, + { DER_OPTIONAL | DER_ANY, + offsetof(SECAlgorithmID, parameters), }, + { 0, } +}; + +DERTemplate CERTSubjectPublicKeyInfoTemplate[] = { + { DER_SEQUENCE, + 0, NULL, sizeof(CERTSubjectPublicKeyInfo) }, + { DER_INLINE, + offsetof(CERTSubjectPublicKeyInfo, algorithm), + SECAlgorithmIDTemplate, }, + { DER_BIT_STRING, + offsetof(CERTSubjectPublicKeyInfo, subjectPublicKey), }, + { 0, } +}; + +DERTemplate CERTPublicKeyAndChallengeTemplate[] = { + { DER_SEQUENCE, + 0, NULL, sizeof(CERTPublicKeyAndChallenge) }, + { DER_ANY, + offsetof(CERTPublicKeyAndChallenge, spki), }, + { DER_IA5_STRING, + offsetof(CERTPublicKeyAndChallenge, challenge), }, + { 0, } +}; + +void StoreKeyLocationInCache(const SECItem& public_key_info, + PK11SlotInfo *slot) { + net::KeygenHandler::Cache* cache = net::KeygenHandler::Cache::GetInstance(); + net::KeygenHandler::KeyLocation key_location; + const char* slot_name = PK11_GetSlotName(slot); + key_location.slot_name.assign(slot_name); + cache->Insert(std::string(reinterpret_cast<char*>(public_key_info.data), + public_key_info.len), key_location); +} + +} // namespace + +namespace mozilla_security_manager { + +// This function is based on the nsKeygenFormProcessor::GetPublicKey function +// in mozilla/security/manager/ssl/src/nsKeygenHandler.cpp. +std::string GenKeyAndSignChallenge(int key_size_in_bits, + const std::string& challenge, + 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 + + // Temporary structures used for generating the result + // in the right format. + PK11SlotInfo *slot = NULL; + PK11RSAGenParams rsaKeyGenParams; // Keygen parameters. + SECOidTag algTag; // used by SEC_DerSignData(). + SECKEYPrivateKey *privateKey = NULL; + SECKEYPublicKey *publicKey = NULL; + CERTSubjectPublicKeyInfo *spkInfo = NULL; + PRArenaPool *arena = NULL; + SECStatus sec_rv =SECFailure; + SECItem spkiItem; + SECItem pkacItem; + SECItem signedItem; + CERTPublicKeyAndChallenge pkac; + void *keyGenParams; + pkac.challenge.data = NULL; + bool isSuccess = true; // Set to false as soon as a step fails. + + std::string result_blob; // the result. + + // Ensure NSS is initialized. + base::EnsureNSSInit(); + + slot = base::GetDefaultNSSKeySlot(); + if (!slot) { + LOG(ERROR) << "Couldn't get Internal key slot!"; + isSuccess = false; + goto failure; + } + + switch (keyGenMechanism) { + case CKM_RSA_PKCS_KEY_PAIR_GEN: + rsaKeyGenParams.keySizeInBits = key_size_in_bits; + rsaKeyGenParams.pe = DEFAULT_RSA_KEYGEN_PE; + keyGenParams = &rsaKeyGenParams; + + algTag = DEFAULT_RSA_KEYGEN_ALG; + break; + default: + // TODO(gauravsh): If we ever support other mechanisms, + // this can be changed. + LOG(ERROR) << "Only RSA keygen mechanism is supported"; + isSuccess = false; + goto failure; + } + + // Need to make sure that the token was initialized. + // Assume a null password. + sec_rv = PK11_Authenticate(slot, PR_TRUE, NULL); + if (SECSuccess != sec_rv) { + LOG(ERROR) << "Couldn't initialze PK11 token!"; + isSuccess = false; + goto failure; + } + + LOG(INFO) << "Creating key pair..."; + privateKey = PK11_GenerateKeyPair(slot, + keyGenMechanism, + keyGenParams, + &publicKey, + PR_TRUE, // isPermanent? + PR_TRUE, // isSensitive? + NULL); + LOG(INFO) << "done."; + + if (!privateKey) { + LOG(INFO) << "Generation of Keypair failed!"; + isSuccess = false; + goto failure; + } + + // The CA expects the signed public key in a specific format + // Let's create that now. + + // Create a subject public key info from the public key. + spkInfo = SECKEY_CreateSubjectPublicKeyInfo(publicKey); + if (!spkInfo) { + LOG(ERROR) << "Couldn't create SubjectPublicKeyInfo from public key"; + isSuccess = false; + goto failure; + } + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!arena) { + LOG(ERROR) << "PORT_NewArena: Couldn't allocate memory"; + isSuccess = false; + goto failure; + } + + // DER encode the whole subjectPublicKeyInfo. + sec_rv = DER_Encode(arena, &spkiItem, CERTSubjectPublicKeyInfoTemplate, + spkInfo); + if (SECSuccess != sec_rv) { + LOG(ERROR) << "Couldn't DER Encode subjectPublicKeyInfo"; + isSuccess = false; + goto failure; + } + + // Set up the PublicKeyAndChallenge data structure, then DER encode it. + pkac.spki = spkiItem; + pkac.challenge.len = challenge.length(); + pkac.challenge.data = (unsigned char *)strdup(challenge.c_str()); + if (!pkac.challenge.data) { + LOG(ERROR) << "Out of memory while making a copy of challenge data"; + isSuccess = false; + goto failure; + } + sec_rv = DER_Encode(arena, &pkacItem, CERTPublicKeyAndChallengeTemplate, + &pkac); + if (SECSuccess != sec_rv) { + LOG(ERROR) << "Couldn't DER Encode PublicKeyAndChallenge"; + isSuccess = false; + goto failure; + } + + // Sign the DER encoded PublicKeyAndChallenge. + sec_rv = SEC_DerSignData(arena, &signedItem, pkacItem.data, pkacItem.len, + privateKey, algTag); + if (SECSuccess != sec_rv) { + LOG(ERROR) << "Couldn't sign the DER encoded PublicKeyandChallenge"; + isSuccess = false; + goto failure; + } + + // Convert the signed public key and challenge into base64/ascii. + if (!base::Base64Encode(std::string(reinterpret_cast<char*>(signedItem.data), + signedItem.len), + &result_blob)) { + LOG(ERROR) << "Couldn't convert signed public key into base64"; + isSuccess = false; + goto failure; + } + + StoreKeyLocationInCache(spkiItem, slot); + + failure: + if (!isSuccess) { + LOG(ERROR) << "SSL Keygen failed!"; + } else { + LOG(INFO) << "SSL Keygen succeeded!"; + } + + // Do cleanups + if (privateKey) { + // On successful keygen we need to keep the private key, of course, + // or we won't be able to use the client certificate. + if (!isSuccess || !stores_key) { + PK11_DestroyTokenObject(privateKey->pkcs11Slot, privateKey->pkcs11ID); + } + SECKEY_DestroyPrivateKey(privateKey); + } + + if (publicKey) { + if (!isSuccess || !stores_key) { + PK11_DestroyTokenObject(publicKey->pkcs11Slot, publicKey->pkcs11ID); + } + SECKEY_DestroyPublicKey(publicKey); + } + if (spkInfo) { + SECKEY_DestroySubjectPublicKeyInfo(spkInfo); + } + if (arena) { + PORT_FreeArena(arena, PR_TRUE); + } + if (slot != NULL) { + PK11_FreeSlot(slot); + } + if (pkac.challenge.data) { + free(pkac.challenge.data); + } + + return (isSuccess ? result_blob : std::string()); +} + +} // namespace mozilla_security_manager diff --git a/net/third_party/mozilla_security_manager/nsKeygenHandler.h b/net/third_party/mozilla_security_manager/nsKeygenHandler.h new file mode 100644 index 0000000..1a0d44c --- /dev/null +++ b/net/third_party/mozilla_security_manager/nsKeygenHandler.h @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * David Drinan. (ddrinan@netscape.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _NSKEYGENHANDLER_H_ +#define _NSKEYGENHANDLER_H_ + +#include <string> + +namespace mozilla_security_manager { + +#define DEFAULT_RSA_KEYGEN_PE 65537L +#define DEFAULT_RSA_KEYGEN_ALG SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION + +std::string GenKeyAndSignChallenge(int key_size_in_bits, + const std::string& challenge, + bool stores_key); + +} // namespace mozilla_security_manager + +#endif //_NSKEYGENHANDLER_H_ |