Bug 1344442 - Part 4: Misc cleanups. r=keeler draft
authorCykesiopka <cykesiopka.bmo@gmail.com>
Wed, 08 Mar 2017 20:54:02 +0800
changeset 495267 c7e1fe2933bc72ac82bce28ab02e116da9fa1aca
parent 495266 e26b0d69ba4e8b4688856a8b0cfaa4cfc522dac2
child 548329 61115a331dc390c0cecd3b200e9340122d342bd5
push id48280
push usercykesiopka.bmo@gmail.com
push dateWed, 08 Mar 2017 15:59:17 +0000
reviewerskeeler
bugs1344442
milestone55.0a1
Bug 1344442 - Part 4: Misc cleanups. r=keeler MozReview-Commit-ID: KRQGF3mUxEb
security/manager/ssl/nsCryptoHash.cpp
--- a/security/manager/ssl/nsCryptoHash.cpp
+++ b/security/manager/ssl/nsCryptoHash.cpp
@@ -1,28 +1,34 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * 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 "nsCryptoHash.h"
+
 #include <algorithm>
 
-#include "nsCryptoHash.h"
-
+#include "base64.h"
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Casting.h"
 #include "nsIInputStream.h"
 #include "nsIKeyModule.h"
-
 #include "nsString.h"
-
+#include "pk11pub.h"
 #include "sechash.h"
-#include "pk11pub.h"
-#include "base64.h"
+
+using namespace mozilla;
 
-#define NS_CRYPTO_HASH_BUFFER_SIZE 4096
+namespace {
+
+static const uint64_t STREAM_BUFFER_SIZE = 4096;
+
+} // namespace
 
 //---------------------------------------------
 // Implementing nsICryptoHash
 //---------------------------------------------
 
 nsCryptoHash::nsCryptoHash()
   : mHashContext(nullptr)
   , mInitialized(false)
@@ -56,17 +62,34 @@ NS_IMPL_ISUPPORTS(nsCryptoHash, nsICrypt
 NS_IMETHODIMP
 nsCryptoHash::Init(uint32_t algorithm)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  HASH_HashType hashType = (HASH_HashType)algorithm;
+  HASH_HashType hashType;
+  switch (algorithm) {
+    case nsICryptoHash::MD2:
+      hashType = HASH_AlgMD2; break;
+    case nsICryptoHash::MD5:
+      hashType = HASH_AlgMD5; break;
+    case nsICryptoHash::SHA1:
+      hashType = HASH_AlgSHA1; break;
+    case nsICryptoHash::SHA256:
+      hashType = HASH_AlgSHA256; break;
+    case nsICryptoHash::SHA384:
+      hashType = HASH_AlgSHA384; break;
+    case nsICryptoHash::SHA512:
+      hashType = HASH_AlgSHA512; break;
+    default:
+      return NS_ERROR_INVALID_ARG;
+  }
+
   if (mHashContext) {
     if (!mInitialized && HASH_GetType(mHashContext.get()) == hashType) {
       mInitialized = true;
       HASH_Begin(mHashContext.get());
       return NS_OK;
     }
 
     // Destroy current hash context if the type was different
@@ -83,21 +106,16 @@ nsCryptoHash::Init(uint32_t algorithm)
   HASH_Begin(mHashContext.get());
   mInitialized = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCryptoHash::InitWithString(const nsACString & aAlgorithm)
 {
-  nsNSSShutDownPreventionLock locker;
-  if (isAlreadyShutDown()) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
   if (aAlgorithm.LowerCaseEqualsLiteral("md2"))
     return Init(nsICryptoHash::MD2);
 
   if (aAlgorithm.LowerCaseEqualsLiteral("md5"))
     return Init(nsICryptoHash::MD5);
 
   if (aAlgorithm.LowerCaseEqualsLiteral("sha1"))
     return Init(nsICryptoHash::SHA1);
@@ -158,53 +176,55 @@ nsCryptoHash::UpdateFromStream(nsIInputS
 
   // So, if the stream has NO data available for the hash,
   // or if the data available is less then what the caller
   // requested, we can not fulfill the hash update.  In this
   // case, just return NS_ERROR_NOT_AVAILABLE indicating
   // that there is not enough data in the stream to satisify
   // the request.
 
-  if (n == 0 || n < len)
+  if (n == 0 || n < len) {
     return NS_ERROR_NOT_AVAILABLE;
-  
-  char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
-  uint32_t read, readLimit;
-  
-  while(NS_SUCCEEDED(rv) && len>0)
-  {
-    readLimit = (uint32_t)std::min<uint64_t>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
-    
-    rv = data->Read(buffer, readLimit, &read);
-    
-    if (NS_SUCCEEDED(rv))
-      rv = Update((const uint8_t*)buffer, read);
-    
+  }
+
+  char buffer[STREAM_BUFFER_SIZE];
+  while (len > 0) {
+    uint64_t readLimit = std::min<uint64_t>(STREAM_BUFFER_SIZE, len);
+    uint32_t read;
+    rv = data->Read(buffer, AssertedCast<uint32_t>(readLimit), &read);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    rv = Update(BitwiseCast<uint8_t*>(buffer), read);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
     len -= read;
   }
-  
-  return rv;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCryptoHash::Finish(bool ascii, nsACString & _retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
-  
-  if (!mInitialized)
+
+  if (!mInitialized) {
     return NS_ERROR_NOT_INITIALIZED;
-  
+  }
+
   uint32_t hashLen = 0;
   unsigned char buffer[HASH_LENGTH_MAX];
-  unsigned char* pbuffer = buffer;
-
-  HASH_End(mHashContext.get(), pbuffer, &hashLen, HASH_LENGTH_MAX);
+  HASH_End(mHashContext.get(), buffer, &hashLen, HASH_LENGTH_MAX);
 
   mInitialized = false;
 
   if (ascii)
   {
     UniquePORTString asciiData(BTOA_DataToAscii(buffer, hashLen));
     NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);
 
@@ -359,53 +379,60 @@ nsCryptoHMAC::UpdateFromStream(nsIInputS
   // or if the data available is less then what the caller
   // requested, we can not fulfill the HMAC update.  In this
   // case, just return NS_ERROR_NOT_AVAILABLE indicating
   // that there is not enough data in the stream to satisify
   // the request.
 
   if (n == 0 || n < len)
     return NS_ERROR_NOT_AVAILABLE;
-  
-  char buffer[NS_CRYPTO_HASH_BUFFER_SIZE];
-  uint32_t read, readLimit;
-  
-  while(NS_SUCCEEDED(rv) && len > 0)
-  {
-    readLimit = (uint32_t)std::min<uint64_t>(NS_CRYPTO_HASH_BUFFER_SIZE, len);
-    
-    rv = aStream->Read(buffer, readLimit, &read);
-    if (read == 0)
+
+  char buffer[STREAM_BUFFER_SIZE];
+  while (len > 0) {
+    uint64_t readLimit = std::min<uint64_t>(STREAM_BUFFER_SIZE, len);
+    uint32_t read;
+    rv = aStream->Read(buffer, AssertedCast<uint32_t>(readLimit), &read);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
+    if (read == 0) {
       return NS_BASE_STREAM_CLOSED;
-    
-    if (NS_SUCCEEDED(rv))
-      rv = Update((const uint8_t*)buffer, read);
-    
+    }
+
+    rv = Update(BitwiseCast<uint8_t*>(buffer), read);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
+
     len -= read;
   }
-  
-  return rv;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCryptoHMAC::Finish(bool aASCII, nsACString & _retval)
 {
   nsNSSShutDownPreventionLock locker;
   if (isAlreadyShutDown()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   if (!mHMACContext)
     return NS_ERROR_NOT_INITIALIZED;
 
   uint32_t hashLen = 0;
   unsigned char buffer[HASH_LENGTH_MAX];
-  unsigned char* pbuffer = buffer;
+  SECStatus srv = PK11_DigestFinal(mHMACContext.get(), buffer, &hashLen,
+                                   HASH_LENGTH_MAX);
+  if (srv != SECSuccess) {
+    return NS_ERROR_FAILURE;
+  }
 
-  PK11_DigestFinal(mHMACContext.get(), pbuffer, &hashLen, HASH_LENGTH_MAX);
   if (aASCII)
   {
     UniquePORTString asciiData(BTOA_DataToAscii(buffer, hashLen));
     NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);
 
     _retval.Assign(asciiData.get());
   }
   else