Bug 1082346 - 01. Convert PKCS12 password endian using copyAndSwapToBigEndian. r=keeler
MozReview-Commit-ID: 83fRWTRzoMd
--- a/security/manager/ssl/nsPKCS12Blob.cpp
+++ b/security/manager/ssl/nsPKCS12Blob.cpp
@@ -1,16 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsPKCS12Blob.h"
#include "ScopedNSSTypes.h"
#include "nsCRT.h"
+#include "nsCRTGlue.h"
#include "nsDirectoryServiceDefs.h"
#include "nsICertificateDialogs.h"
#include "nsIDirectoryService.h"
#include "nsIFile.h"
#include "nsIInputStream.h"
#include "nsKeygenHandler.h" // For GetSlotWithMechanism
#include "nsNSSCertificate.h"
#include "nsNSSComponent.h"
@@ -408,32 +409,27 @@ finish:
// private members
//
///////////////////////////////////////////////////////////////////////
// unicodeToItem
//
// 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?
-void
+nsresult
nsPKCS12Blob::unicodeToItem(const char16_t *uni, SECItem *item)
{
- int len = 0;
- while (uni[len++] != 0);
- SECITEM_AllocItem(nullptr, item, sizeof(char16_t) * len);
-#ifdef IS_LITTLE_ENDIAN
- int i = 0;
- for (i=0; i<len; i++) {
- item->data[2*i ] = (unsigned char )(uni[i] << 8);
- item->data[2*i+1] = (unsigned char )(uni[i]);
+ uint32_t len = NS_strlen(uni) + 1;
+ if (!SECITEM_AllocItem(nullptr, item, sizeof(char16_t) * len)) {
+ return NS_ERROR_OUT_OF_MEMORY;
}
-#else
- memcpy(item->data, uni, item->len);
-#endif
+
+ mozilla::NativeEndian::copyAndSwapToBigEndian(item->data, uni, len);
+
+ return NS_OK;
}
// newPKCS12FilePassword
//
// Launch a dialog requesting the user for a new PKCS#12 file passowrd.
// Handle user canceled by returning null password (caller must catch).
nsresult
nsPKCS12Blob::newPKCS12FilePassword(SECItem *unicodePw)
@@ -443,18 +439,17 @@ nsPKCS12Blob::newPKCS12FilePassword(SECI
nsCOMPtr<nsICertificateDialogs> certDialogs;
rv = ::getNSSDialogs(getter_AddRefs(certDialogs),
NS_GET_IID(nsICertificateDialogs),
NS_CERTIFICATEDIALOGS_CONTRACTID);
if (NS_FAILED(rv)) return rv;
bool pressedOK;
rv = certDialogs->SetPKCS12FilePassword(mUIContext, password, &pressedOK);
if (NS_FAILED(rv) || !pressedOK) return rv;
- unicodeToItem(password.get(), unicodePw);
- return NS_OK;
+ return unicodeToItem(password.get(), unicodePw);
}
// getPKCS12FilePassword
//
// Launch a dialog requesting the user for the password to a PKCS#12 file.
// Handle user canceled by returning null password (caller must catch).
nsresult
nsPKCS12Blob::getPKCS12FilePassword(SECItem *unicodePw)
@@ -464,18 +459,17 @@ nsPKCS12Blob::getPKCS12FilePassword(SECI
nsCOMPtr<nsICertificateDialogs> certDialogs;
rv = ::getNSSDialogs(getter_AddRefs(certDialogs),
NS_GET_IID(nsICertificateDialogs),
NS_CERTIFICATEDIALOGS_CONTRACTID);
if (NS_FAILED(rv)) return rv;
bool pressedOK;
rv = certDialogs->GetPKCS12FilePassword(mUIContext, password, &pressedOK);
if (NS_FAILED(rv) || !pressedOK) return rv;
- unicodeToItem(password.get(), unicodePw);
- return NS_OK;
+ return unicodeToItem(password.get(), unicodePw);
}
// inputToDecoder
//
// Given a decoder, read bytes from file and input them to the decoder.
nsresult
nsPKCS12Blob::inputToDecoder(SEC_PKCS12DecoderContext *dcx, nsIFile *file)
{
--- a/security/manager/ssl/nsPKCS12Blob.h
+++ b/security/manager/ssl/nsPKCS12Blob.h
@@ -49,17 +49,17 @@ private:
nsCOMPtr<nsIPK11Token> mToken;
nsCOMPtr<nsIMutableArray> mCertArray;
nsCOMPtr<nsIInterfaceRequestor> mUIContext;
// local helper functions
nsresult getPKCS12FilePassword(SECItem *);
nsresult newPKCS12FilePassword(SECItem *);
nsresult inputToDecoder(SEC_PKCS12DecoderContext *, nsIFile *);
- void unicodeToItem(const char16_t *, SECItem *);
+ nsresult unicodeToItem(const char16_t *, SECItem *);
void handleError(int myerr = 0);
// RetryReason and ImportMode are used when importing a PKCS12 file.
// There are two reasons that cause us to retry:
// - When the password entered by the user is incorrect.
// The user will be prompted to try again.
// - When the user entered a zero length password.
// An empty password should be represented as an empty