Bug 1082346 - 01. Convert PKCS12 password endian using copyAndSwapToBigEndian. r=keeler draft
authorChuck Lee <chuckli0706@gmail.com>
Sat, 07 May 2016 15:58:12 +0800
changeset 365341 696d76f9676327ab336f826f2e86034015205ec4
parent 365273 1579b9e2e50f3a27ad02d58cc9170c91e0973fec
child 365342 ec6d6d7093dcffe9ab7762da5d6cf7c486bc8b10
child 365350 372a32aa49b73f4d54848b2ba77a731807fcc5b8
child 365352 5c4b2e94c380a491530bd88fc803d2b4399544cd
push id17715
push userchuckli0706@gmail.com
push dateTue, 10 May 2016 15:04:29 +0000
reviewerskeeler
bugs1082346
milestone49.0a1
Bug 1082346 - 01. Convert PKCS12 password endian using copyAndSwapToBigEndian. r=keeler MozReview-Commit-ID: 83fRWTRzoMd
security/manager/ssl/nsPKCS12Blob.cpp
security/manager/ssl/nsPKCS12Blob.h
--- 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