Index: net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp |
diff --git a/net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp b/net/third_party/mozilla_security_manager/nsPKCS12Blob.cpp |
index 7781bf76a7a5e5e663e1874e79093000eb5448ed..a664cf57ecf0514b4f845a9aca1a36b7a35671a3 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,69 @@ 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) |
+ continue; |
wtc
2011/12/08 00:07:43
BUG: we also need to call
CERT_DestroyCertificat
Greg Spencer (Chromium)
2011/12/09 18:51:38
Done.
|
- 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 +352,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 +369,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; |
} |