summaryrefslogtreecommitdiffstats
path: root/net/third_party
diff options
context:
space:
mode:
authorgspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-12 08:46:16 +0000
committergspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-12 08:46:16 +0000
commit8a9378308da3edfed5b1d53d0c82345f1f11a420 (patch)
tree14f15b0bc11d09efd89cd11f730f2483a98b4013 /net/third_party
parent6b76e20c87381f2b1b22e86d571daa451e1c710b (diff)
downloadchromium_src-8a9378308da3edfed5b1d53d0c82345f1f11a420.zip
chromium_src-8a9378308da3edfed5b1d53d0c82345f1f11a420.tar.gz
chromium_src-8a9378308da3edfed5b1d53d0c82345f1f11a420.tar.bz2
This applies GUIDs to certificate and key nicknames when
imported via ONC. It also centralizes the label creation for nicknames and certificates so that we can better control their values. BUG=chromium-os:19403 TEST=Ran new unit tests, imported certs into certificate store via ONC. Review URL: http://codereview.chromium.org/8566056 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113993 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party')
-rw-r--r--net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp38
-rw-r--r--net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp93
-rw-r--r--net/third_party/mozilla_security_manager/nsPKCS12Blob.h8
3 files changed, 80 insertions, 59 deletions
diff --git a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
index 3e50cd1..0cf430d 100644
--- a/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
+++ b/net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp
@@ -80,14 +80,12 @@ bool ImportCACerts(const net::CertificateList& certificates,
// Mozilla uses CERT_AddTempCertToPerm, however it is privately exported,
// and it doesn't take the slot as an argument either. Instead, we use
// PK11_ImportCert and CERT_ChangeCertTrust.
- char* nickname = CERT_MakeCANickname(root->os_cert_handle());
- if (!nickname)
- return false;
- SECStatus srv = PK11_ImportCert(slot.get(), root->os_cert_handle(),
- CK_INVALID_HANDLE,
- nickname,
- PR_FALSE /* includeTrust (unused) */);
- PORT_Free(nickname);
+ SECStatus srv = PK11_ImportCert(
+ slot.get(),
+ root->os_cert_handle(),
+ CK_INVALID_HANDLE,
+ root->GetDefaultNickname(net::CA_CERT).c_str(),
+ PR_FALSE /* includeTrust (unused) */);
if (srv != SECSuccess) {
LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
return false;
@@ -139,14 +137,12 @@ bool ImportCACerts(const net::CertificateList& certificates,
// Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use
// PK11_ImportCert instead.
- char* nickname = CERT_MakeCANickname(cert->os_cert_handle());
- if (!nickname)
- return false;
- SECStatus srv = PK11_ImportCert(slot.get(), cert->os_cert_handle(),
- CK_INVALID_HANDLE,
- nickname,
- PR_FALSE /* includeTrust (unused) */);
- PORT_Free(nickname);
+ SECStatus srv = PK11_ImportCert(
+ slot.get(),
+ cert->os_cert_handle(),
+ CK_INVALID_HANDLE,
+ cert->GetDefaultNickname(net::CA_CERT).c_str(),
+ PR_FALSE /* includeTrust (unused) */);
if (srv != SECSuccess) {
LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
// TODO(mattm): Should we bail or continue on error here? Mozilla doesn't
@@ -174,10 +170,12 @@ bool ImportServerCert(const net::CertificateList& certificates,
// Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use
// PK11_ImportCert instead.
- SECStatus srv = PK11_ImportCert(slot.get(), cert->os_cert_handle(),
- CK_INVALID_HANDLE,
- cert->subject().GetDisplayName().c_str(),
- PR_FALSE /* includeTrust (unused) */);
+ SECStatus srv = PK11_ImportCert(
+ slot.get(),
+ cert->os_cert_handle(),
+ CK_INVALID_HANDLE,
+ cert->GetDefaultNickname(net::SERVER_CERT).c_str(),
+ PR_FALSE /* includeTrust (unused) */);
if (srv != SECSuccess) {
LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
not_imported->push_back(net::CertDatabase::ImportCertFailure(
diff --git a/net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp b/net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp
index 7781bf7..3087cec 100644
--- a/net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp
+++ b/net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp
@@ -57,7 +57,7 @@ namespace {
//
// For the NSS PKCS#12 library, must convert PRUnichars (shorts) to
// a buffer of octets. Must handle byte order correctly.
-// TODO: Is there a mozilla way to do this? In the string lib?
+// TODO: Is there a Mozilla way to do this? In the string lib?
void unicodeToItem(const PRUnichar *uni, SECItem *item)
{
int len = 0;
@@ -138,7 +138,7 @@ pip_ucs2_ascii_conversion_fn(PRBool toUnicode,
PRBool swapBytes)
{
CHECK_GE(maxOutBufLen, inBufLen);
- // do a no-op, since I've already got unicode. Hah!
+ // do a no-op, since I've already got Unicode. Hah!
*outBufLen = inBufLen;
memcpy(outBuf, inBuf, inBufLen);
return PR_TRUE;
@@ -151,7 +151,8 @@ nsPKCS12Blob_ImportHelper(const char* pkcs12_data,
const string16& password,
bool is_extractable,
bool try_zero_length_secitem,
- PK11SlotInfo *slot)
+ PK11SlotInfo *slot,
+ net::CertificateList* imported_certs)
{
DCHECK(pkcs12_data);
DCHECK(slot);
@@ -159,6 +160,10 @@ nsPKCS12Blob_ImportHelper(const char* pkcs12_data,
SECStatus srv = SECSuccess;
SEC_PKCS12DecoderContext *dcx = NULL;
SECItem unicodePw;
+ SECItem attribute_value;
+ CK_BBOOL attribute_data = CK_FALSE;
+ const SEC_PKCS12DecoderItem* decoder_item = NULL;
+
unicodePw.type = siBuffer;
unicodePw.len = 0;
unicodePw.data = NULL;
@@ -188,57 +193,71 @@ nsPKCS12Blob_ImportHelper(const char* pkcs12_data,
// validate bags
srv = SEC_PKCS12DecoderValidateBags(dcx, nickname_collision);
if (srv) goto finish;
- // import cert and key
+ // import certificate and key
srv = SEC_PKCS12DecoderImportBags(dcx);
if (srv) goto finish;
- if (!is_extractable) {
- SECItem attribute_value;
- CK_BBOOL attribute_data = CK_FALSE;
- attribute_value.data = &attribute_data;
- attribute_value.len = sizeof(attribute_data);
+ attribute_value.data = &attribute_data;
+ attribute_value.len = sizeof(attribute_data);
- srv = SEC_PKCS12DecoderIterateInit(dcx);
- if (srv) goto finish;
+ srv = SEC_PKCS12DecoderIterateInit(dcx);
+ if (srv) goto finish;
+
+ if (imported_certs)
+ imported_certs->clear();
+
+ // Collect the list of decoded certificates, and mark private keys
+ // non-extractable if needed.
+ while (SEC_PKCS12DecoderIterateNext(dcx, &decoder_item) == SECSuccess) {
+ if (decoder_item->type != SEC_OID_PKCS12_V1_CERT_BAG_ID)
+ continue;
+
+ CERTCertificate* cert = PK11_FindCertFromDERCertItem(
+ slot, decoder_item->der,
+ NULL); // wincx
+ if (!cert) {
+ LOG(ERROR) << "Could not grab a handle to the certificate in the slot "
+ << "from the corresponding PKCS#12 DER certificate.";
+ continue;
+ }
+
+ // Add the cert to the list
+ if (imported_certs) {
+ // Empty list of intermediates.
+ net::X509Certificate::OSCertHandles intermediates;
+ imported_certs->push_back(
+ net::X509Certificate::CreateFromHandle(cert, intermediates));
+ }
+
+ // Once we have determined that the imported certificate has an
+ // associated private key too, only then can we mark the key as
+ // non-extractable.
+ if (!decoder_item->hasKey) {
+ CERT_DestroyCertificate(cert);
+ continue;
+ }
- const SEC_PKCS12DecoderItem* decoder_item = NULL;
// Iterate through all the imported PKCS12 items and mark any accompanying
- // private keys as unextractable.
- while (SEC_PKCS12DecoderIterateNext(dcx, &decoder_item) == SECSuccess) {
- if (decoder_item->type != SEC_OID_PKCS12_V1_CERT_BAG_ID)
- continue;
- if (!decoder_item->hasKey)
- continue;
-
- // Once we have determined that the imported certificate has an
- // associated private key too, only then can we mark the key as
- // unextractable.
- CERTCertificate* cert = PK11_FindCertFromDERCertItem(
- slot, decoder_item->der,
- NULL); // wincx
- if (!cert) {
- LOG(ERROR) << "Could not grab a handle to the certificate in the slot "
- << "from the corresponding PKCS#12 DER certificate.";
- continue;
- }
+ // private keys as non-extractable.
+ if (!is_extractable) {
SECKEYPrivateKey* privKey = PK11_FindPrivateKeyFromCert(slot, cert,
NULL); // wincx
- CERT_DestroyCertificate(cert);
if (privKey) {
- // Mark the private key as unextractable.
+ // Mark the private key as non-extractable.
srv = PK11_WriteRawAttribute(PK11_TypePrivKey, privKey, CKA_EXTRACTABLE,
&attribute_value);
SECKEY_DestroyPrivateKey(privKey);
if (srv) {
LOG(ERROR) << "Could not set CKA_EXTRACTABLE attribute on private "
<< "key.";
+ CERT_DestroyCertificate(cert);
break;
}
}
}
+ CERT_DestroyCertificate(cert);
if (srv) goto finish;
}
-
import_result = net::OK;
finish:
// If srv != SECSuccess, NSS probably set a specific error code.
@@ -335,10 +354,12 @@ int nsPKCS12Blob_Import(PK11SlotInfo* slot,
const char* pkcs12_data,
size_t pkcs12_len,
const string16& password,
- bool is_extractable) {
+ bool is_extractable,
+ net::CertificateList* imported_certs) {
int rv = nsPKCS12Blob_ImportHelper(pkcs12_data, pkcs12_len, password,
- is_extractable, false, slot);
+ is_extractable, false, slot,
+ imported_certs);
// When the user entered a zero length password:
// An empty password should be represented as an empty
@@ -350,7 +371,7 @@ int nsPKCS12Blob_Import(PK11SlotInfo* slot,
// flavors.
if (rv == net::ERR_PKCS12_IMPORT_BAD_PASSWORD && password.empty()) {
rv = nsPKCS12Blob_ImportHelper(pkcs12_data, pkcs12_len, password,
- is_extractable, true, slot);
+ is_extractable, true, slot, imported_certs);
}
return rv;
}
diff --git a/net/third_party/mozilla_security_manager/nsPKCS12Blob.h b/net/third_party/mozilla_security_manager/nsPKCS12Blob.h
index ace6baa..d0c8da1 100644
--- a/net/third_party/mozilla_security_manager/nsPKCS12Blob.h
+++ b/net/third_party/mozilla_security_manager/nsPKCS12Blob.h
@@ -57,13 +57,15 @@ namespace mozilla_security_manager {
void EnsurePKCS12Init();
// Import the private key and certificate from a PKCS#12 blob into the slot.
-// If |is_extractable| is false, mark the private key as unextractable.
-// Returns a net error code.
+// If |is_extractable| is false, mark the private key as non-extractable.
+// Returns a net error code. |imported_certs|, if non-NULL, returns a list of
+// certs that were imported.
int nsPKCS12Blob_Import(PK11SlotInfo* slot,
const char* pkcs12_data,
size_t pkcs12_len,
const string16& password,
- bool is_extractable);
+ bool is_extractable,
+ net::CertificateList* imported_certs);
// Export the given certificates into a PKCS#12 blob, storing into output.
// Returns the number of certificates exported.