Bug 1271501 - Use mozilla::BitwiseCast instead of reinterpret_cast in PSM. r=keeler
authorCykesiopka <cykesiopka.bmo@gmail.com>
Wed, 18 May 2016 21:20:56 -0700
changeset 298159 1ef294cb3b47138416d559cb2f36f35dc0de7151
parent 298158 4525aaa132ff6f642c9a4aaf8f0bb0ac6e5aa2d9
child 298160 cc202e0ac0dd3401d340d1a8516a247a250c64b7
push id30273
push userkwierso@gmail.com
push dateFri, 20 May 2016 21:08:12 +0000
treeherdermozilla-central@c403ac05b8f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1271501
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1271501 - Use mozilla::BitwiseCast instead of reinterpret_cast in PSM. r=keeler mozilla::BitwiseCast does the same thing, but provides static asserts that mitigate some of the risk of using reinterpret_cast. MozReview-Commit-ID: ENQ8QC6Nl9o
security/apps/AppSignatureVerification.cpp
security/apps/AppTrustDomain.cpp
security/certverifier/NSSCertDBTrustDomain.cpp
security/certverifier/OCSPRequestor.cpp
security/manager/ssl/CertBlocklist.cpp
security/manager/ssl/ContentSignatureVerifier.cpp
security/manager/ssl/LocalCertService.cpp
security/manager/ssl/PSMContentListener.cpp
security/manager/ssl/PublicKeyPinningService.cpp
security/manager/ssl/SSLServerCertVerification.cpp
security/manager/ssl/ScopedNSSTypes.h
security/manager/ssl/TransportSecurityInfo.cpp
security/manager/ssl/nsDataSignatureVerifier.cpp
security/manager/ssl/nsNSSCallbacks.cpp
security/manager/ssl/nsNSSCertHelper.cpp
security/manager/ssl/nsNSSCertificate.cpp
security/manager/ssl/nsNSSCertificateDB.cpp
security/manager/ssl/nsNSSComponent.cpp
security/manager/ssl/nsNSSIOLayer.cpp
security/manager/ssl/nsNSSShutDown.cpp
security/manager/ssl/nsNSSU2FToken.cpp
security/manager/ssl/nsNTLMAuthModule.cpp
security/manager/ssl/nsPK11TokenDB.cpp
security/manager/ssl/nsPKCS11Slot.cpp
security/manager/ssl/nsPKCS12Blob.cpp
security/manager/ssl/tests/compiled/TestMD4.cpp
security/manager/ssl/tests/gtest/OCSPCacheTest.cpp
security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp
security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h
--- a/security/apps/AppSignatureVerification.cpp
+++ b/security/apps/AppSignatureVerification.cpp
@@ -7,16 +7,17 @@
 #include "nsNSSCertificateDB.h"
 
 #include "AppTrustDomain.h"
 #include "CryptoTask.h"
 #include "NSSCertDBTrustDomain.h"
 #include "ScopedNSSTypes.h"
 #include "base64.h"
 #include "certdb.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Logging.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsDataSignatureVerifier.h"
 #include "nsHashKeys.h"
 #include "nsIDirectoryEnumerator.h"
@@ -911,17 +912,17 @@ VerifySignedManifest(AppTrustedRoot aTru
                       const_cast<SECItem*>(&manifestCalculatedDigest.get())));
   if (NS_WARN_IF(!base64EncDigest)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // Calculate SHA1 digest of the base64 encoded string
   Digest doubleDigest;
   rv = doubleDigest.DigestBuf(SEC_OID_SHA1,
-                              reinterpret_cast<uint8_t*>(base64EncDigest.get()),
+                              BitwiseCast<uint8_t*, char*>(base64EncDigest.get()),
                               strlen(base64EncDigest.get()));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Verify the manifest signature (signed digest of the base64 encoded string)
   UniqueCERTCertList builtChain;
   rv = VerifySignature(aTrustedRoot, signatureBuffer,
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -1,26 +1,27 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "AppTrustDomain.h"
+#include "MainThreadUtils.h"
 #include "certdb.h"
-#include "pkix/pkixnss.h"
 #include "mozilla/ArrayUtils.h"
-#include "MainThreadUtils.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Preferences.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIFile.h"
 #include "nsIFileStreams.h"
 #include "nsIX509CertDB.h"
+#include "nsNSSCertificate.h"
 #include "nsNetUtil.h"
-#include "nsNSSCertificate.h"
+#include "pkix/pkixnss.h"
 #include "prerror.h"
 #include "secerr.h"
 
 // Generated in Makefile.in
 #include "marketplace-prod-public.inc"
 #include "marketplace-prod-reviewers.inc"
 #include "marketplace-dev-public.inc"
 #include "marketplace-dev-reviewers.inc"
@@ -147,17 +148,18 @@ AppTrustDomain::SetTrustedRoot(AppTruste
         auto data = MakeUnique<char[]>(length);
         rv = inputStream->Read(data.get(), length, &sDevImportedDERLen);
         if (NS_FAILED(rv)) {
           PR_SetError(SEC_ERROR_IO, 0);
           return SECFailure;
         }
 
         MOZ_ASSERT(length == sDevImportedDERLen);
-        sDevImportedDERData.reset(reinterpret_cast<unsigned char*>(data.release()));
+        sDevImportedDERData.reset(
+          BitwiseCast<unsigned char*, char*>(data.release()));
       }
 
       trustedDER.data = sDevImportedDERData.get();
       trustedDER.len = sDevImportedDERLen;
       break;
     }
 
     default:
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -10,16 +10,17 @@
 
 #include "ExtendedValidation.h"
 #include "NSSErrorsService.h"
 #include "OCSPRequestor.h"
 #include "OCSPVerificationTrustDomain.h"
 #include "PublicKeyPinningService.h"
 #include "cert.h"
 #include "certdb.h"
+#include "mozilla/Casting.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/unused.h"
 #include "nsNSSCertificate.h"
 #include "nsServiceManagerUtils.h"
 #include "nss.h"
 #include "pk11pub.h"
 #include "pkix/Result.h"
 #include "pkix/pkix.h"
@@ -773,17 +774,17 @@ NSSCertDBTrustDomain::IsChainValid(const
     }
     Digest digest;
     nsresult nsrv = digest.DigestBuf(SEC_OID_SHA256, cert->derCert.data,
                                      cert->derCert.len);
     if (NS_FAILED(nsrv)) {
       return Result::FATAL_ERROR_LIBRARY_FAILURE;
     }
     const uint8_t* certHash(
-      reinterpret_cast<const uint8_t*>(digest.get().data));
+      BitwiseCast<uint8_t*, unsigned char*>(digest.get().data));
     size_t certHashLen = digest.get().len;
     size_t unused;
     if (!mozilla::BinarySearchIf(WhitelistedCNNICHashes, 0,
                                  ArrayLength(WhitelistedCNNICHashes),
                                  WhitelistedCNNICHashBinarySearchComparator(
                                    certHash, certHashLen),
                                  &unused)) {
       return Result::ERROR_REVOKED_CERTIFICATE;
--- a/security/certverifier/OCSPRequestor.cpp
+++ b/security/certverifier/OCSPRequestor.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "OCSPRequestor.h"
 
 #include <limits>
 
 #include "ScopedNSSTypes.h"
 #include "mozilla/Base64.h"
+#include "mozilla/Casting.h"
 #include "nsIURLParser.h"
 #include "nsNSSCallbacks.h"
 #include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 #include "secerr.h"
 
 extern mozilla::LazyLogModule gCertVerifierLog;
 
@@ -44,17 +45,18 @@ MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(Un
 
 namespace mozilla { namespace psm {
 
 static nsresult
 AppendEscapedBase64Item(const SECItem* encodedRequest, nsACString& path)
 {
   nsresult rv;
   nsDependentCSubstring requestAsSubstring(
-    reinterpret_cast<const char*>(encodedRequest->data), encodedRequest->len);
+    BitwiseCast<char*, unsigned char*>(encodedRequest->data),
+    encodedRequest->len);
   nsCString base64Request;
   rv = Base64Encode(requestAsSubstring, base64Request);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
          ("Setting up OCSP GET path, pre path =%s\n",
@@ -175,17 +177,18 @@ DoOCSPRequest(const UniquePLArenaPool& a
   if (rv != Success) {
     return rv;
   }
 
   UniqueHTTPRequestSession requestSession(requestSessionPtr);
 
   if (!useGET) {
     rv = nsNSSHttpInterface::setPostDataFcn(
-      requestSession.get(), reinterpret_cast<char*>(encodedRequest->data),
+      requestSession.get(),
+      BitwiseCast<char*, unsigned char*>(encodedRequest->data),
       encodedRequest->len, "application/ocsp-request");
     if (rv != Success) {
       return rv;
     }
   }
 
   uint16_t httpResponseCode;
   const char* httpResponseData;
--- a/security/manager/ssl/CertBlocklist.cpp
+++ b/security/manager/ssl/CertBlocklist.cpp
@@ -1,32 +1,34 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "CertBlocklist.h"
+
 #include "mozilla/Base64.h"
+#include "mozilla/Casting.h"
+#include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsCRTGlue.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsICryptoHash.h"
 #include "nsIFileStreams.h"
 #include "nsILineInputStream.h"
 #include "nsISafeOutputStream.h"
 #include "nsIX509Cert.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsTHashtable.h"
 #include "nsThreadUtils.h"
 #include "pkix/Input.h"
-#include "mozilla/Logging.h"
 #include "prtime.h"
 
 NS_IMPL_ISUPPORTS(CertBlocklist, nsICertBlocklist)
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 
 #define PREF_BACKGROUND_UPDATE_TIMER "app.update.lastUpdateTime.blocklist-background-update-timer"
@@ -77,19 +79,19 @@ CertBlocklistItem::~CertBlocklistItem()
 {
   delete[] mDNData;
   delete[] mOtherData;
 }
 
 nsresult
 CertBlocklistItem::ToBase64(nsACString& b64DNOut, nsACString& b64OtherOut)
 {
-  nsDependentCSubstring DNString(reinterpret_cast<char*>(mDNData),
+  nsDependentCSubstring DNString(BitwiseCast<char*, uint8_t*>(mDNData),
                                  mDNLength);
-  nsDependentCSubstring otherString(reinterpret_cast<char*>(mOtherData),
+  nsDependentCSubstring otherString(BitwiseCast<char*, uint8_t*>(mOtherData),
                                     mOtherLength);
   nsresult rv = Base64Encode(DNString, b64DNOut);
   if (NS_FAILED(rv)) {
     return rv;
   }
   rv = Base64Encode(otherString, b64OtherOut);
   return rv;
 }
@@ -339,35 +341,34 @@ CertBlocklist::RevokeCertByIssuerAndSeri
 
 nsresult
 CertBlocklist::AddRevokedCertInternal(const nsACString& aEncodedDN,
                                       const nsACString& aEncodedOther,
                                       CertBlocklistItemMechanism aMechanism,
                                       CertBlocklistItemState aItemState,
                                       MutexAutoLock& /*proofOfLock*/)
 {
-    nsCString decodedDN;
-    nsCString decodedOther;
+  nsCString decodedDN;
+  nsCString decodedOther;
 
-    nsresult rv = Base64Decode(aEncodedDN, decodedDN);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
-    rv = Base64Decode(aEncodedOther, decodedOther);
-    if (NS_FAILED(rv)) {
-      return rv;
-    }
+  nsresult rv = Base64Decode(aEncodedDN, decodedDN);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  rv = Base64Decode(aEncodedOther, decodedOther);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
 
-    CertBlocklistItem item(reinterpret_cast<const uint8_t*>(decodedDN.get()),
-                           decodedDN.Length(),
-                           reinterpret_cast<const uint8_t*>(decodedOther.get()),
-                           decodedOther.Length(),
-                           aMechanism);
-
-
+  CertBlocklistItem item(
+    BitwiseCast<const uint8_t*, const char*>(decodedDN.get()),
+    decodedDN.Length(),
+    BitwiseCast<const uint8_t*, const char*>(decodedOther.get()),
+    decodedOther.Length(),
+    aMechanism);
 
   if (aItemState == CertNewFromBlocklist) {
     // We want SaveEntries to be a no-op if no new entries are added.
     nsGenericHashKey<CertBlocklistItem>* entry = mBlocklist.GetEntry(item);
     if (!entry) {
       mModified = true;
     } else {
       // Ensure that any existing item is replaced by a fresh one so we can
@@ -591,21 +592,22 @@ CertBlocklist::IsCertRevoked(const uint8
   }
 
   nsCString hashString;
   rv = crypto->Finish(false, hashString);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  CertBlocklistItem subjectPubKey(aSubject,
-                                  static_cast<size_t>(aSubjectLength),
-                                  reinterpret_cast<const uint8_t*>(hashString.get()),
-                                  hashString.Length(),
-                                  BlockBySubjectAndPubKey);
+  CertBlocklistItem subjectPubKey(
+    aSubject,
+    static_cast<size_t>(aSubjectLength),
+    BitwiseCast<const uint8_t*, const char*>(hashString.get()),
+    hashString.Length(),
+    BlockBySubjectAndPubKey);
 
   rv = subjectPubKey.ToBase64(encDN, encOther);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   MOZ_LOG(gCertBlockPRLog, LogLevel::Warning,
           ("CertBlocklist::IsCertRevoked subject %s - pubKey hash %s",
--- a/security/manager/ssl/ContentSignatureVerifier.cpp
+++ b/security/manager/ssl/ContentSignatureVerifier.cpp
@@ -2,28 +2,29 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 "ContentSignatureVerifier.h"
 
 #include "BRNameMatchingPolicy.h"
+#include "SharedCertVerifier.h"
 #include "cryptohi.h"
 #include "keyhi.h"
+#include "mozilla/Casting.h"
 #include "nsCOMPtr.h"
 #include "nsNSSComponent.h"
-#include "nssb64.h"
+#include "nsSecurityHeaderParser.h"
 #include "nsWhitespaceTokenizer.h"
 #include "nsXPCOMStrings.h"
+#include "nssb64.h"
 #include "pkix/pkix.h"
 #include "pkix/pkixtypes.h"
 #include "secerr.h"
-#include "SharedCertVerifier.h"
-#include "nsSecurityHeaderParser.h"
 
 NS_IMPL_ISUPPORTS(ContentSignatureVerifier, nsIContentSignatureVerifier)
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 using namespace mozilla::psm;
 
 static LazyLogModule gCSVerifierPRLog("ContentSignatureVerifier");
@@ -160,17 +161,17 @@ ContentSignatureVerifier::CreateContext(
   if (!node || !node->cert) {
     return NS_ERROR_FAILURE;
   }
 
   SECItem* certSecItem = &node->cert->derCert;
 
   Input certDER;
   Result result =
-    certDER.Init(reinterpret_cast<const uint8_t*>(certSecItem->data),
+    certDER.Init(BitwiseCast<uint8_t*, unsigned char*>(certSecItem->data),
                  certSecItem->len);
   if (result != Success) {
     return NS_ERROR_FAILURE;
   }
 
 
   // Check the signerCert chain is good
   CSTrustDomain trustDomain(certCertList);
--- a/security/manager/ssl/LocalCertService.cpp
+++ b/security/manager/ssl/LocalCertService.cpp
@@ -1,29 +1,30 @@
 /* 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 "LocalCertService.h"
 
+#include "CryptoTask.h"
+#include "ScopedNSSTypes.h"
+#include "cert.h"
+#include "mozilla/Casting.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/RefPtr.h"
-#include "cert.h"
-#include "CryptoTask.h"
 #include "nsIPK11Token.h"
 #include "nsIPK11TokenDB.h"
 #include "nsIX509Cert.h"
 #include "nsIX509CertDB.h"
 #include "nsIX509CertValidity.h"
 #include "nsLiteralString.h"
 #include "nsProxyRelease.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "pk11pub.h"
-#include "ScopedNSSTypes.h"
 
 namespace mozilla {
 
 class LocalCertTask : public CryptoTask
 {
 protected:
   explicit LocalCertTask(const nsACString& aNickname)
     : mNickname(aNickname)
@@ -176,20 +177,19 @@ private:
     ScopedCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
     if (!validity) {
       return mozilla::psm::GetXPCOMFromNSSError(PR_GetError());
     }
 
     // Generate random serial
     unsigned long serial;
     // This serial in principle could collide, but it's unlikely
-    rv = MapSECStatus(
-           PK11_GenerateRandomOnSlot(slot.get(),
-                                     reinterpret_cast<unsigned char *>(&serial),
-                                     sizeof(serial)));
+    rv = MapSECStatus(PK11_GenerateRandomOnSlot(
+           slot.get(), BitwiseCast<unsigned char*, unsigned long*>(&serial),
+           sizeof(serial)));
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     // Create the cert from these pieces
     ScopedCERTCertificate cert(
       CERT_CreateCertificate(serial, subjectName, validity, certRequest));
     if (!cert) {
--- a/security/manager/ssl/PSMContentListener.cpp
+++ b/security/manager/ssl/PSMContentListener.cpp
@@ -177,27 +177,30 @@ PSMContentStreamListener::ImportCertific
   }
 
   if (!certdb) {
     return;
   }
 
   switch (mType) {
   case X509_CA_CERT:
-    certdb->ImportCertificates(reinterpret_cast<uint8_t*>(mByteData.BeginWriting()),
+    certdb->ImportCertificates(BitwiseCast<uint8_t*, char*>(
+                                 mByteData.BeginWriting()),
                                mByteData.Length(), mType, ctx);
     break;
 
   case X509_USER_CERT:
-    certdb->ImportUserCertificate(reinterpret_cast<uint8_t*>(mByteData.BeginWriting()),
+    certdb->ImportUserCertificate(BitwiseCast<uint8_t*, char*>(
+                                    mByteData.BeginWriting()),
                                   mByteData.Length(), ctx);
     break;
 
   case X509_EMAIL_CERT:
-    certdb->ImportEmailCertificate(reinterpret_cast<uint8_t*>(mByteData.BeginWriting()),
+    certdb->ImportEmailCertificate(BitwiseCast<uint8_t*, char*>(
+                                     mByteData.BeginWriting()),
                                    mByteData.Length(), ctx);
     break;
 
   default:
     break;
   }
 }
 
--- a/security/manager/ssl/PublicKeyPinningService.cpp
+++ b/security/manager/ssl/PublicKeyPinningService.cpp
@@ -1,23 +1,24 @@
 /* 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 "PublicKeyPinningService.h"
 
+#include "RootCertificateTelemetryUtils.h"
 #include "mozilla/Base64.h"
+#include "mozilla/Casting.h"
+#include "mozilla/Logging.h"
 #include "mozilla/Telemetry.h"
 #include "nsISiteSecurityService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsSiteSecurityService.h"
 #include "nssb64.h"
 #include "pkix/pkixtypes.h"
-#include "mozilla/Logging.h"
-#include "RootCertificateTelemetryUtils.h"
 #include "seccomon.h"
 #include "sechash.h"
 
 #include "StaticHPKPins.h" // autogenerated by genHPKPStaticpins.js
 
 using namespace mozilla;
 using namespace mozilla::pkix;
 using namespace mozilla::psm;
@@ -34,17 +35,17 @@ GetBase64HashSPKI(const CERTCertificate*
   hashSPKIDigest.Truncate();
   Digest digest;
   nsresult rv = digest.DigestBuf(SEC_OID_SHA256, cert->derPublicKey.data,
                                  cert->derPublicKey.len);
   if (NS_FAILED(rv)) {
     return rv;
   }
   return Base64Encode(nsDependentCSubstring(
-                        reinterpret_cast<const char*>(digest.get().data),
+                        BitwiseCast<char*, unsigned char*>(digest.get().data),
                         digest.get().len),
                       hashSPKIDigest);
 }
 
 /*
  * Sets certMatchesPinset to true if a given cert matches any fingerprints from
  * the given pinset or the dynamicFingerprints array, or to false otherwise.
  */
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -102,16 +102,17 @@
 #include "ExtendedValidation.h"
 #include "NSSCertDBTrustDomain.h"
 #include "PSMRunnable.h"
 #include "RootCertificateTelemetryUtils.h"
 #include "ScopedNSSTypes.h"
 #include "SharedSSLState.h"
 #include "cert.h"
 #include "mozilla/Assertions.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/net/DNS.h"
 #include "mozilla/unused.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsIBadCertListener2.h"
@@ -958,17 +959,18 @@ GatherBaselineRequirementsTelemetry(cons
   CERTGeneralName* currentName = subjectAltNames;
   bool commonNameInSubjectAltNames = false;
   bool nonDNSNameOrIPAddressPresent = false;
   bool malformedDNSNameOrIPAddressPresent = false;
   bool nonFQDNPresent = false;
   do {
     nsAutoCString altName;
     if (currentName->type == certDNSName) {
-      altName.Assign(reinterpret_cast<char*>(currentName->name.other.data),
+      altName.Assign(BitwiseCast<char*, unsigned char*>(
+                       currentName->name.other.data),
                      currentName->name.other.len);
       nsDependentCString altNameWithoutWildcard(altName, 0);
       if (StringBeginsWith(altNameWithoutWildcard, NS_LITERAL_CSTRING("*."))) {
         altNameWithoutWildcard.Rebind(altName, 2);
         commonNameInSubjectAltNames |=
           TryMatchingWildcardSubjectAltName(commonName.get(), altName);
       }
       // net_IsValidHostName appears to return true for valid IP addresses,
--- a/security/manager/ssl/ScopedNSSTypes.h
+++ b/security/manager/ssl/ScopedNSSTypes.h
@@ -11,16 +11,17 @@
 #define ScopedNSSTypes_h
 
 #include <limits>
 
 #include "cert.h"
 #include "cms.h"
 #include "cryptohi.h"
 #include "keyhi.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/UniquePtr.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "NSSErrorsService.h"
 #include "pk11pub.h"
 #include "pkcs12.h"
@@ -32,31 +33,33 @@
 #include "secport.h"
 
 #ifndef MOZ_NO_MOZALLOC
 #include "mozilla/mozalloc_oom.h"
 #endif
 
 namespace mozilla {
 
+// Deprecated: Use something like |mozilla::BitwiseCast<char*, uint8_t*>(p)|
+//             instead.
 // It is very common to cast between char* and uint8_t* when doing crypto stuff.
 // Here, we provide more type-safe wrappers around reinterpret_cast so you don't
 // shoot yourself in the foot by reinterpret_casting completely unrelated types.
 
-inline char *
-char_ptr_cast(uint8_t * p) { return reinterpret_cast<char *>(p); }
+inline char*
+char_ptr_cast(uint8_t* p) { return BitwiseCast<char*>(p); }
 
-inline const char *
-char_ptr_cast(const uint8_t * p) { return reinterpret_cast<const char *>(p); }
+inline const char*
+char_ptr_cast(const uint8_t* p) { return BitwiseCast<const char*>(p); }
 
-inline uint8_t *
-uint8_t_ptr_cast(char * p) { return reinterpret_cast<uint8_t*>(p); }
+inline uint8_t*
+uint8_t_ptr_cast(char* p) { return BitwiseCast<uint8_t*>(p); }
 
-inline const uint8_t *
-uint8_t_ptr_cast(const char * p) { return reinterpret_cast<const uint8_t*>(p); }
+inline const uint8_t*
+uint8_t_ptr_cast(const char* p) { return BitwiseCast<const uint8_t*>(p); }
 
 // NSPR APIs use PRStatus/PR_GetError and NSS APIs use SECStatus/PR_GetError to
 // report success/failure. This function makes it more convenient and *safer*
 // to translate NSPR/NSS results to nsresult. It is safer because it
 // refuses to translate any bad PRStatus/SECStatus into an NS_OK, even when the
 // NSPR/NSS function forgot to call PR_SetError. The actual enforcement of
 // this happens in mozilla::psm::GetXPCOMFromNSSError.
 // IMPORTANT: This must be called immediately after the function returning the
--- a/security/manager/ssl/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/TransportSecurityInfo.cpp
@@ -1,38 +1,38 @@
 /* -*- 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 "TransportSecurityInfo.h"
 
-#include "pkix/pkixtypes.h"
-#include "nsNSSComponent.h"
-#include "nsIWebProgressListener.h"
-#include "nsNSSCertificate.h"
-#include "nsIX509CertValidity.h"
+#include "PSMRunnable.h"
+#include "mozilla/Casting.h"
+#include "nsComponentManagerUtils.h"
+#include "nsIArray.h"
+#include "nsICertOverrideService.h"
 #include "nsIDateTimeFormat.h"
-#include "nsICertOverrideService.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
+#include "nsIWebProgressListener.h"
+#include "nsIX509CertValidity.h"
 #include "nsNSSCertHelper.h"
-#include "nsIArray.h"
-#include "nsComponentManagerUtils.h"
+#include "nsNSSCertificate.h"
+#include "nsNSSComponent.h"
 #include "nsReadableUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsXULAppAPI.h"
-#include "PSMRunnable.h"
-
+#include "pkix/pkixtypes.h"
 #include "secerr.h"
 
 //#define DEBUG_SSL_VERBOSE //Enable this define to get minimal 
                             //reports when doing SSL read/write
-                            
+
 //#define DUMP_BUFFER  //Enable this define along with
                        //DEBUG_SSL_VERBOSE to dump SSL
                        //read/write buffer to a log.
                        //Uses PR_LOG except on Mac where
                        //we always write out to our own
                        //file.
 
 namespace mozilla { namespace psm {
@@ -416,17 +416,17 @@ TransportSecurityInfo::Read(nsIObjectInp
   // For successful connections and for connections with overridable errors,
   // mSSLStatus will be non-null. For connections with non-overridable errors,
   // it will be null.
   nsCOMPtr<nsISupports> supports;
   rv = NS_ReadOptionalObject(stream, true, getter_AddRefs(supports));
   if (NS_FAILED(rv)) {
     return rv;
   }
-  mSSLStatus = reinterpret_cast<nsSSLStatus*>(supports.get());
+  mSSLStatus = BitwiseCast<nsSSLStatus*, nsISupports*>(supports.get());
 
   nsCOMPtr<nsISupports> failedCertChainSupports;
   rv = NS_ReadOptionalObject(stream, true, getter_AddRefs(failedCertChainSupports));
   if (NS_FAILED(rv)) {
     return rv;
   }
   mFailedCertChain = do_QueryInterface(failedCertChainSupports);
 
@@ -645,19 +645,19 @@ GetSubjectAltNames(CERTCertificate* nssC
 
   uint32_t nameCount = 0;
   CERTGeneralName* current = sanNameList;
   do {
     nsAutoString name;
     switch (current->type) {
       case certDNSName:
         {
-          nsDependentCSubstring nameFromCert(reinterpret_cast<char*>
-                                              (current->name.other.data),
-                                              current->name.other.len);
+          nsDependentCSubstring nameFromCert(BitwiseCast<char*, unsigned char*>(
+                                               current->name.other.data),
+                                             current->name.other.len);
           // dNSName fields are defined as type IA5String and thus should
           // be limited to ASCII characters.
           if (IsASCII(nameFromCert)) {
             name.Assign(NS_ConvertASCIItoUTF16(nameFromCert));
             if (!allNames.IsEmpty()) {
               allNames.AppendLiteral(", ");
             }
             ++nameCount;
--- a/security/manager/ssl/nsDataSignatureVerifier.cpp
+++ b/security/manager/ssl/nsDataSignatureVerifier.cpp
@@ -2,16 +2,17 @@
  * 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 "nsDataSignatureVerifier.h"
 
 #include "cms.h"
 #include "cryptohi.h"
 #include "keyhi.h"
+#include "mozilla/Casting.h"
 #include "mozilla/unused.h"
 #include "nsCOMPtr.h"
 #include "nsNSSComponent.h"
 #include "nssb64.h"
 #include "pkix/pkixtypes.h"
 #include "ScopedNSSTypes.h"
 #include "secerr.h"
 #include "SharedCertVerifier.h"
@@ -103,17 +104,18 @@ nsDataSignatureVerifier::VerifyData(cons
                                          &signatureItem);
   if (srv != SECSuccess) {
     return NS_ERROR_FAILURE;
   }
 
   // Perform the final verification
   DER_ConvertBitString(&(sigData.signature));
   srv = VFY_VerifyDataWithAlgorithmID(
-    reinterpret_cast<const unsigned char*>(PromiseFlatCString(aData).get()),
+    BitwiseCast<const unsigned char*, const char*>(
+      PromiseFlatCString(aData).get()),
     aData.Length(), publicKey.get(), &(sigData.signature),
     &(sigData.signatureAlgorithm), nullptr, nullptr);
 
   *_retval = (srv == SECSuccess);
 
   return NS_OK;
 }
 
@@ -287,17 +289,17 @@ nsDataSignatureVerifier::VerifySignature
   nsresult rv = digest.DigestBuf(SEC_OID_SHA1, uint8_t_ptr_cast(aPlaintext),
                                  aPlaintextLen);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   SECItem buffer = {
     siBuffer,
-    reinterpret_cast<uint8_t*>(const_cast<char*>(aRSABuf)),
+    BitwiseCast<unsigned char*, const char*>(aRSABuf),
     aRSABufLen
   };
 
   VerifyCertificateContext context;
   // XXX: pinArg is missing
   rv = VerifyCMSDetachedSignatureIncludingCertificate(buffer, digest.get(),
                                                       VerifyCertificate,
                                                       &context, nullptr, locker);
--- a/security/manager/ssl/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/nsNSSCallbacks.cpp
@@ -1,16 +1,18 @@
 /* -*- 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 "nsNSSCallbacks.h"
 
+#include "mozilla/ArrayUtils.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "nsContentUtils.h"
 #include "nsICertOverrideService.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIPrompt.h"
 #include "nsISupportsPriority.h"
 #include "nsITokenDialogs.h"
@@ -856,27 +858,28 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
     return;
   }
 
   // Get the NPN value.
   SSLNextProtoState state;
   unsigned char npnbuf[256];
   unsigned int npnlen;
 
-  if (SSL_GetNextProto(fd, &state, npnbuf, &npnlen, 256) == SECSuccess) {
+  if (SSL_GetNextProto(fd, &state, npnbuf, &npnlen,
+                       AssertedCast<unsigned int>(ArrayLength(npnbuf)))
+        == SECSuccess) {
     if (state == SSL_NEXT_PROTO_NEGOTIATED ||
         state == SSL_NEXT_PROTO_SELECTED) {
-      infoObject->SetNegotiatedNPN(reinterpret_cast<char *>(npnbuf), npnlen);
-    }
-    else {
+      infoObject->SetNegotiatedNPN(BitwiseCast<char*, unsigned char*>(npnbuf),
+                                   npnlen);
+    } else {
       infoObject->SetNegotiatedNPN(nullptr, 0);
     }
     mozilla::Telemetry::Accumulate(Telemetry::SSL_NPN_TYPE, state);
-  }
-  else {
+  } else {
     infoObject->SetNegotiatedNPN(nullptr, 0);
   }
 
   infoObject->SetPreliminaryHandshakeDone();
 }
 
 SECStatus
 CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
--- a/security/manager/ssl/nsNSSCertHelper.cpp
+++ b/security/manager/ssl/nsNSSCertHelper.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 "nsNSSCertHelper.h"
 
 #include <algorithm>
 
+#include "mozilla/Casting.h"
 #include "mozilla/Snprintf.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsDateTimeFormatCID.h"
 #include "nsIDateTimeFormat.h"
 #include "nsNSSASN1Object.h"
 #include "nsNSSCertTrust.h"
@@ -95,17 +96,17 @@ ProcessVersion(SECItem* versionItem, nsI
 
   // Now to figure out what version this certificate is.
   unsigned int version;
   if (versionItem->data) {
     // Filter out totally bogus version values/encodings.
     if (versionItem->len != 1) {
       return NS_ERROR_FAILURE;
     }
-    version = *reinterpret_cast<const uint8_t*>(versionItem->data);
+    version = *BitwiseCast<uint8_t*, unsigned char*>(versionItem->data);
   } else {
     // If there is no version present in the cert, then RFC 5280 says we
     // default to v1 (0).
     version = 0;
   }
 
   // A value of n actually corresponds to version n + 1
   nsAutoString versionString;
--- a/security/manager/ssl/nsNSSCertificate.cpp
+++ b/security/manager/ssl/nsNSSCertificate.cpp
@@ -5,16 +5,17 @@
 
 #include "nsNSSCertificate.h"
 
 #include "CertVerifier.h"
 #include "ExtendedValidation.h"
 #include "NSSCertDBTrustDomain.h"
 #include "certdb.h"
 #include "mozilla/Base64.h"
+#include "mozilla/Casting.h"
 #include "mozilla/unused.h"
 #include "nsArray.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsCertVerificationThread.h"
 #include "nsICertificateDialogs.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIObjectInputStream.h"
@@ -527,22 +528,24 @@ nsNSSCertificate::GetDbKey(const UniqueC
   // 4 bytes: <serial number length in big-endian order>
   // 4 bytes: <DER-encoded issuer distinguished name length in big-endian order>
   // n bytes: <bytes of serial number>
   // m bytes: <DER-encoded issuer distinguished name>
   nsAutoCString buf;
   const char leadingZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0};
   buf.Append(leadingZeroes, sizeof(leadingZeroes));
   uint32_t serialNumberLen = htonl(cert->serialNumber.len);
-  buf.Append(reinterpret_cast<const char*>(&serialNumberLen), sizeof(uint32_t));
+  buf.Append(BitwiseCast<const char*, const uint32_t*>(&serialNumberLen),
+             sizeof(uint32_t));
   uint32_t issuerLen = htonl(cert->derIssuer.len);
-  buf.Append(reinterpret_cast<const char*>(&issuerLen), sizeof(uint32_t));
-  buf.Append(reinterpret_cast<const char*>(cert->serialNumber.data),
+  buf.Append(BitwiseCast<const char*, const uint32_t*>(&issuerLen),
+             sizeof(uint32_t));
+  buf.Append(BitwiseCast<char*, unsigned char*>(cert->serialNumber.data),
              cert->serialNumber.len);
-  buf.Append(reinterpret_cast<const char*>(cert->derIssuer.data),
+  buf.Append(BitwiseCast<char*, unsigned char*>(cert->derIssuer.data),
              cert->derIssuer.len);
 
   return Base64Encode(buf, aDbKey);
 }
 
 NS_IMETHODIMP
 nsNSSCertificate::GetWindowTitle(nsAString& aWindowTitle)
 {
@@ -1096,17 +1099,17 @@ nsNSSCertificate::GetSha256SubjectPublic
   aSha256SPKIDigest.Truncate();
   Digest digest;
   nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mCert->derPublicKey.data,
                                  mCert->derPublicKey.len);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   rv = Base64Encode(nsDependentCSubstring(
-                      reinterpret_cast<const char*> (digest.get().data),
+                      BitwiseCast<char*, unsigned char*>(digest.get().data),
                       digest.get().len),
                     aSha256SPKIDigest);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
--- a/security/manager/ssl/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/nsNSSCertificateDB.cpp
@@ -4,16 +4,17 @@
 
 #include "nsNSSCertificateDB.h"
 
 #include "CertVerifier.h"
 #include "ExtendedValidation.h"
 #include "NSSCertDBTrustDomain.h"
 #include "SharedSSLState.h"
 #include "mozilla/Base64.h"
+#include "mozilla/Casting.h"
 #include "mozilla/unused.h"
 #include "nsArray.h"
 #include "nsArrayUtils.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include "nsComponentManagerUtils.h"
 #include "nsICertificateDialogs.h"
 #include "nsIFile.h"
@@ -174,34 +175,38 @@ nsNSSCertificateDB::FindCertByDBKey(cons
   nsresult rv = Base64Decode(tmpDBKey, decoded);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (decoded.Length() < 16) {
     return NS_ERROR_ILLEGAL_INPUT;
   }
   const char* reader = decoded.BeginReading();
-  uint64_t zeroes = *reinterpret_cast<const uint64_t*>(reader);
+  uint64_t zeroes = *BitwiseCast<const uint64_t*, const char*>(reader);
   if (zeroes != 0) {
     return NS_ERROR_ILLEGAL_INPUT;
   }
   reader += sizeof(uint64_t);
-  uint32_t serialNumberLen = ntohl(*reinterpret_cast<const uint32_t*>(reader));
+  // Note: We surround the ntohl() argument with parentheses to stop the macro
+  //       from thinking two arguments were passed.
+  uint32_t serialNumberLen = ntohl(
+    (*BitwiseCast<const uint32_t*, const char*>(reader)));
   reader += sizeof(uint32_t);
-  uint32_t issuerLen = ntohl(*reinterpret_cast<const uint32_t*>(reader));
+  uint32_t issuerLen = ntohl(
+    (*BitwiseCast<const uint32_t*, const char*>(reader)));
   reader += sizeof(uint32_t);
   if (decoded.Length() != 16ULL + serialNumberLen + issuerLen) {
     return NS_ERROR_ILLEGAL_INPUT;
   }
   CERTIssuerAndSN issuerSN;
   issuerSN.serialNumber.len = serialNumberLen;
-  issuerSN.serialNumber.data = (unsigned char*)reader;
+  issuerSN.serialNumber.data = BitwiseCast<unsigned char*, const char*>(reader);
   reader += serialNumberLen;
   issuerSN.derIssuer.len = issuerLen;
-  issuerSN.derIssuer.data = (unsigned char*)reader;
+  issuerSN.derIssuer.data = BitwiseCast<unsigned char*, const char*>(reader);
   reader += issuerLen;
   MOZ_ASSERT(reader == decoded.EndReading());
 
   cert.reset(CERT_FindCertByIssuerAndSN(CERT_GetDefaultCertDB(), &issuerSN));
   return NS_OK;
 }
 
 SECStatus
@@ -459,19 +464,18 @@ nsNSSCertificateDB::ImportCertificates(u
   nsCOMPtr<nsIMutableArray> array = nsArrayBase::Create();
   if (!array) {
     return NS_ERROR_FAILURE;
   }
 
   // Now let's create some certs to work with
   for (int i = 0; i < certCollection->numcerts; i++) {
     SECItem* currItem = &certCollection->rawCerts[i];
-    nsCOMPtr<nsIX509Cert> cert =
-      nsNSSCertificate::ConstructFromDER(reinterpret_cast<char*>(currItem->data),
-                                         currItem->len);
+    nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::ConstructFromDER(
+      BitwiseCast<char*, unsigned char*>(currItem->data), currItem->len);
     if (!cert) {
       return NS_ERROR_FAILURE;
     }
     nsresult rv = array->AppendElement(cert, false);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -7,16 +7,17 @@
 #include "nsNSSComponent.h"
 
 #include "ExtendedValidation.h"
 #include "NSSCertDBTrustDomain.h"
 #include "ScopedNSSTypes.h"
 #include "SharedSSLState.h"
 #include "cert.h"
 #include "certdb.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PublicSSL.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/Telemetry.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsCRT.h"
@@ -435,17 +436,17 @@ GetUserSid(nsAString& sidString)
   WCHAR lpAccountName[UNLEN + 1];
   DWORD lcAccountName = sizeof(lpAccountName) / sizeof(lpAccountName[0]);
   BOOL success = GetUserName(lpAccountName, &lcAccountName);
   if (!success) {
     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("GetUserName failed"));
     return false;
   }
   char sid_buffer[SECURITY_MAX_SID_SIZE];
-  SID* sid = reinterpret_cast<SID*>(sid_buffer);
+  SID* sid = BitwiseCast<SID*, char*>(sid_buffer);
   DWORD cbSid = MOZ_ARRAY_LENGTH(sid_buffer);
   SID_NAME_USE eUse;
   // There doesn't appear to be a defined maximum length for the domain name
   // here. To deal with this, we start with a reasonable buffer length and
   // see if that works. If it fails and the error indicates insufficient length,
   // we use the indicated required length and try again.
   DWORD cchReferencedDomainName = 128;
   auto ReferencedDomainName(MakeUnique<WCHAR[]>(cchReferencedDomainName));
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -460,17 +460,17 @@ nsNSSSocketInfo::SetNPNList(nsTArray<nsC
       return NS_ERROR_ILLEGAL_VALUE;
 
     npnList.Append(protocolArray[index].Length());
     npnList.Append(protocolArray[index]);
   }
 
   if (SSL_SetNextProtoNego(
         mFd,
-        reinterpret_cast<const unsigned char*>(npnList.get()),
+        BitwiseCast<const unsigned char*, const char*>(npnList.get()),
         npnList.Length()) != SECSuccess)
     return NS_ERROR_FAILURE;
 
   return NS_OK;
 }
 
 nsresult
 nsNSSSocketInfo::ActivateSSL()
@@ -2038,17 +2038,17 @@ nsNSS_SSLGetClientAuthData(void* arg, PR
   nsNSSShutDownPreventionLock locker;
 
   if (!socket || !caNames || !pRetCert || !pRetKey) {
     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
     return SECFailure;
   }
 
   RefPtr<nsNSSSocketInfo> info(
-    reinterpret_cast<nsNSSSocketInfo*>(socket->higher->secret));
+    BitwiseCast<nsNSSSocketInfo*, PRFilePrivate*>(socket->higher->secret));
 
   UniqueCERTCertificate serverCert(SSL_PeerCertificate(socket));
   if (!serverCert) {
     NS_NOTREACHED("Missing server certificate should have been detected during "
                   "server cert authentication.");
     PR_SetError(SSL_ERROR_NO_CERTIFICATE, 0);
     return SECFailure;
   }
@@ -2235,17 +2235,17 @@ ClientAuthDataRunnable::RunOnTargetThrea
         certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
         if (certdb) {
           nsCOMPtr<nsIX509Cert> found_cert;
           nsresult find_rv =
             certdb->FindCertByDBKey(rememberedDBKey.get(),
             getter_AddRefs(found_cert));
           if (NS_SUCCEEDED(find_rv) && found_cert) {
             nsNSSCertificate* obj_cert =
-              reinterpret_cast<nsNSSCertificate*>(found_cert.get());
+              BitwiseCast<nsNSSCertificate*, nsIX509Cert*>(found_cert.get());
             if (obj_cert) {
               cert.reset(obj_cert->GetCert());
             }
           }
 
           if (!cert) {
             hasRemembered = false;
           }
--- a/security/manager/ssl/nsNSSShutDown.cpp
+++ b/security/manager/ssl/nsNSSShutDown.cpp
@@ -1,12 +1,13 @@
 /* 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 "mozilla/Casting.h"
 #include "nsNSSShutDown.h"
 #include "nsCOMPtr.h"
 
 using namespace mozilla;
 
 extern LazyLogModule gPIPNSSLog;
 
 struct ObjectHashEntry : PLDHashEntryHdr {
@@ -109,18 +110,18 @@ nsresult nsNSSShutDownList::doPK11Logout
   // Nobody else ever modifies that bool, only we do.
   // We only must ensure that our objects do not go away.
   // This is guaranteed by holding the list lock.
 
   for (auto iter = singleton->mPK11LogoutCancelObjects.Iter();
        !iter.Done();
        iter.Next()) {
     auto entry = static_cast<ObjectHashEntry*>(iter.Get());
-    nsOnPK11LogoutCancelObject *pklco =
-      reinterpret_cast<nsOnPK11LogoutCancelObject*>(entry->obj);
+    nsOnPK11LogoutCancelObject* pklco =
+      BitwiseCast<nsOnPK11LogoutCancelObject*, nsNSSShutDownObject*>(entry->obj);
     if (pklco) {
       pklco->logout();
     }
   }
 
   return NS_OK;
 }
 
--- a/security/manager/ssl/nsNSSU2FToken.cpp
+++ b/security/manager/ssl/nsNSSU2FToken.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "nsNSSU2FToken.h"
 
 #include "CryptoBuffer.h"
+#include "mozilla/Casting.h"
 #include "nsNSSComponent.h"
 #include "pk11pub.h"
 #include "prerror.h"
 #include "secerr.h"
 #include "WebCryptoCommon.h"
 
 using mozilla::dom::CreateECParamsForCurve;
 
@@ -240,17 +241,18 @@ GetAttestationCertificate(const UniquePK
   ScopedCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
   if (!validity) {
     MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
             ("Failed to gen validity, NSS error #%d", PORT_GetError()));
     return NS_ERROR_FAILURE;
   }
 
   unsigned long serial;
-  unsigned char* serialBytes = reinterpret_cast<unsigned char *>(&serial);
+  unsigned char* serialBytes =
+    mozilla::BitwiseCast<unsigned char*, unsigned long*>(&serial);
   SECStatus srv = PK11_GenerateRandomOnSlot(aSlot.get(), serialBytes,
                                             sizeof(serial));
   if (srv != SECSuccess) {
     MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
             ("Failed to gen serial, NSS error #%d", PORT_GetError()));
     return NS_ERROR_FAILURE;
   }
   // Ensure that the most significant bit isn't set (which would
--- a/security/manager/ssl/nsNTLMAuthModule.cpp
+++ b/security/manager/ssl/nsNTLMAuthModule.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsNTLMAuthModule.h"
 
 #include <time.h>
 
 #include "ScopedNSSTypes.h"
 #include "md4.h"
+#include "mozilla/Casting.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/Endian.h"
 #include "mozilla/Likely.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Snprintf.h"
 #include "mozilla/Telemetry.h"
 #include "nsCOMPtr.h"
@@ -489,17 +490,18 @@ ParseType2Msg(const void *inBuf, uint32_
   msg->flags = ReadUint32(cursor);
 
   // read challenge
   memcpy(msg->challenge, cursor, sizeof(msg->challenge));
   cursor += sizeof(msg->challenge);
 
   LOG(("NTLM type 2 message:\n"));
   LogBuf("target", msg->target, msg->targetLen);
-  LogBuf("flags", reinterpret_cast<const uint8_t*> (&msg->flags), 4);
+  LogBuf("flags",
+         mozilla::BitwiseCast<const uint8_t*, const uint32_t*>(&msg->flags), 4);
   LogFlags(msg->flags);
   LogBuf("challenge", msg->challenge, sizeof(msg->challenge));
 
   // Read (and skip) the reserved field
   ReadUint32(cursor);
   ReadUint32(cursor);
   // Read target name security buffer: ...
   // ... read target length.
@@ -683,17 +685,18 @@ GenerateType3Msg(const nsString &domain,
     domainUpperLen = ucsDomainUpperBuf.Length() * 2;
 #ifdef IS_BIG_ENDIAN
     WriteUnicodeLE(const_cast<void*>(domainUpperPtr),
                    static_cast<const char16_t*>(domainUpperPtr),
                    ucsDomainUpperBuf.Length());
 #endif
 
     NTLM_Hash(password, ntlmHash);
-    ntlmHashStr = nsAutoCString(reinterpret_cast<const char *>(ntlmHash), NTLM_HASH_LEN);
+    ntlmHashStr = nsAutoCString(
+      mozilla::BitwiseCast<const char*, const uint8_t*>(ntlmHash), NTLM_HASH_LEN);
 
     nsCOMPtr<nsIKeyObjectFactory> keyFactory =
         do_CreateInstance(NS_KEYMODULEOBJECTFACTORY_CONTRACTID, &rv);
 
     if (NS_FAILED(rv)) {
       return rv;
     }
 
@@ -812,17 +815,16 @@ GenerateType3Msg(const nsString &domain,
     ntlmRespLen += msg.targetInfoLen;
     if (!ntlmRespLen.isValid()) {
       NS_ERROR("failed to do NTLMv2: integer overflow?!?");
       return NS_ERROR_UNEXPECTED;
     }
   } else if (msg.flags & NTLM_NegotiateNTLM2Key) {
     // compute NTLM2 session response
     nsCString sessionHashString;
-    const uint8_t *sessionHash;
 
     PK11_GenerateRandom(lmResp, NTLM_CHAL_LEN);
     memset(lmResp + NTLM_CHAL_LEN, 0, LM_RESP_LEN - NTLM_CHAL_LEN);
 
     nsCOMPtr<nsICryptoHash> hasher =
         do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv);
     if (NS_FAILED(rv)) {
       return rv;
@@ -839,17 +841,18 @@ GenerateType3Msg(const nsString &domain,
     if (NS_FAILED(rv)) {
       return rv;
     }
     rv = hasher->Finish(false, sessionHashString);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    sessionHash = reinterpret_cast<const uint8_t*> (sessionHashString.get());
+    auto sessionHash = mozilla::BitwiseCast<const uint8_t*, const char*>(
+      sessionHashString.get());
 
     LogBuf("NTLM2 effective key: ", sessionHash, 8);
 
     NTLM_Hash(password, ntlmHash);
     LM_Response(ntlmHash, sessionHash, ntlmResp);
   } else {
     NTLM_Hash(password, ntlmHash);
     LM_Response(ntlmHash, msg.challenge, ntlmResp);
--- a/security/manager/ssl/nsPK11TokenDB.cpp
+++ b/security/manager/ssl/nsPK11TokenDB.cpp
@@ -1,15 +1,16 @@
 /* -*- 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 "nsPK11TokenDB.h"
 
+#include "mozilla/Casting.h"
 #include "mozilla/unused.h"
 #include "nsIMutableArray.h"
 #include "nsISupports.h"
 #include "nsNSSComponent.h"
 #include "nsReadableUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "prerror.h"
 #include "ScopedNSSTypes.h"
@@ -41,25 +42,26 @@ nsPK11Token::refreshTokenInfo(const nsNS
 
   CK_TOKEN_INFO tokInfo;
   nsresult rv = MapSECStatus(PK11_GetTokenInfo(mSlot.get(), &tokInfo));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // Set the Label field
-  const char* ccLabel = reinterpret_cast<const char*>(tokInfo.label);
+  const char* ccLabel = mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(tokInfo.label);
   const nsACString& cLabel = Substring(
     ccLabel,
     ccLabel + PL_strnlen(ccLabel, sizeof(tokInfo.label)));
   mTokenLabel = NS_ConvertUTF8toUTF16(cLabel);
   mTokenLabel.Trim(" ", false, true);
 
   // Set the Manufacturer field
-  const char* ccManID = reinterpret_cast<const char*>(tokInfo.manufacturerID);
+  const char* ccManID =
+    mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(tokInfo.manufacturerID);
   const nsACString& cManID = Substring(
     ccManID,
     ccManID + PL_strnlen(ccManID, sizeof(tokInfo.manufacturerID)));
   mTokenManID = NS_ConvertUTF8toUTF16(cManID);
   mTokenManID.Trim(" ", false, true);
 
   // Set the Hardware Version field
   mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.major);
@@ -67,17 +69,18 @@ nsPK11Token::refreshTokenInfo(const nsNS
   mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.minor);
 
   // Set the Firmware Version field
   mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.major);
   mTokenFWVersion.Append('.');
   mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.minor);
 
   // Set the Serial Number field
-  const char* ccSerial = reinterpret_cast<const char*>(tokInfo.serialNumber);
+  const char* ccSerial =
+    mozilla::BitwiseCast<char*, CK_CHAR*>(tokInfo.serialNumber);
   const nsACString& cSerial = Substring(
     ccSerial,
     ccSerial + PL_strnlen(ccSerial, sizeof(tokInfo.serialNumber)));
   mTokenSerialNum = NS_ConvertUTF8toUTF16(cSerial);
   mTokenSerialNum.Trim(" ", false, true);
 
   return NS_OK;
 }
--- a/security/manager/ssl/nsPKCS11Slot.cpp
+++ b/security/manager/ssl/nsPKCS11Slot.cpp
@@ -1,14 +1,15 @@
 /* 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 "nsPKCS11Slot.h"
 
+#include "mozilla/Casting.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsCOMPtr.h"
 #include "nsIMutableArray.h"
 #include "nsPK11TokenDB.h"
 #include "secmod.h"
 
@@ -36,25 +37,27 @@ nsPKCS11Slot::refreshSlotInfo(const nsNS
 {
   CK_SLOT_INFO slotInfo;
   nsresult rv = MapSECStatus(PK11_GetSlotInfo(mSlot.get(), &slotInfo));
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // Set the Description field
-  const char* ccDesc = reinterpret_cast<const char*>(slotInfo.slotDescription);
+  const char* ccDesc =
+    mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(slotInfo.slotDescription);
   const nsACString& cDesc = Substring(
     ccDesc,
     ccDesc + PL_strnlen(ccDesc, sizeof(slotInfo.slotDescription)));
   mSlotDesc = NS_ConvertUTF8toUTF16(cDesc);
   mSlotDesc.Trim(" ", false, true);
 
   // Set the Manufacturer field
-  const char* ccManID = reinterpret_cast<const char*>(slotInfo.manufacturerID);
+  const char* ccManID =
+    mozilla::BitwiseCast<char*, CK_UTF8CHAR*>(slotInfo.manufacturerID);
   const nsACString& cManID = Substring(
     ccManID,
     ccManID + PL_strnlen(ccManID, sizeof(slotInfo.manufacturerID)));
   mSlotManID = NS_ConvertUTF8toUTF16(cManID);
   mSlotManID.Trim(" ", false, true);
 
   // Set the Hardware Version field
   mSlotHWVersion = EmptyString();
--- a/security/manager/ssl/nsPKCS12Blob.cpp
+++ b/security/manager/ssl/nsPKCS12Blob.cpp
@@ -1,15 +1,16 @@
 /* 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 "mozilla/Casting.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
@@ -592,18 +593,18 @@ nsPKCS12Blob::digest_write(void *arg, un
 {
   auto cx = static_cast<nsPKCS12Blob*>(arg);
   NS_ENSURE_TRUE(cx, SECFailure);
   NS_ENSURE_TRUE(cx->mDigest, SECFailure);
 
   // make sure we are in write mode, read iterator has not yet been allocated
   NS_ENSURE_FALSE(cx->mDigestIterator, SECFailure);
 
-  cx->mDigest->Append(reinterpret_cast<char *>(buf),
-                     static_cast<uint32_t>(len));
+  cx->mDigest->Append(BitwiseCast<char*, unsigned char*>(buf),
+                      static_cast<uint32_t>(len));
 
   return len;
 }
 
 // nickname_collision
 // what to do when the nickname collides with one already in the db.
 // TODO: not handled, throw a dialog allowing the nick to be changed?
 SECItem *
--- a/security/manager/ssl/tests/compiled/TestMD4.cpp
+++ b/security/manager/ssl/tests/compiled/TestMD4.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "TestHarness.h"
 #include "md4.h"
+#include "mozilla/Casting.h"
 
 // The md4 implementation isn't built as a separate library. This is the easiest
 // way to expose the symbols necessary to test the implementation.
 #include "md4.c"
 
 struct rfc1320_test_value {
   const char* data;
   const uint8_t md4[16];
@@ -47,17 +48,18 @@ TestMD4()
     {
       "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
       { 0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36 },
     }
   };
 
   for (size_t i = 0; i < MOZ_ARRAY_LENGTH(rfc1320_test_values); i++) {
     uint8_t md4_result[16];
-    md4sum(reinterpret_cast<const uint8_t*>(rfc1320_test_values[i].data),
+    md4sum(mozilla::BitwiseCast<const uint8_t*, const char*>(
+             rfc1320_test_values[i].data),
            strlen(rfc1320_test_values[i].data), md4_result);
     if (memcmp(md4_result, rfc1320_test_values[i].md4, 16) != 0) {
       fail("MD4 comparison test value #%d from RFC1320 failed", i + 1);
       return NS_ERROR_FAILURE;
     }
     passed("MD4 comparison test value #%d from RFC1320 passed", i + 1);
   }
   return NS_OK;
--- a/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp
+++ b/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp
@@ -2,31 +2,35 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "CertVerifier.h"
 #include "OCSPCache.h"
 #include "gtest/gtest.h"
+#include "mozilla/Casting.h"
 #include "mozilla/Snprintf.h"
 #include "nss.h"
 #include "pkix/pkixtypes.h"
 #include "pkixtestutil.h"
 #include "prerr.h"
 #include "secerr.h"
 
 using namespace mozilla::pkix;
 using namespace mozilla::pkix::test;
 using namespace mozilla::psm;
 
 template <size_t N>
 inline Input
 LiteralInput(const char(&valueString)[N])
 {
+  // Ideally we would use mozilla::BitwiseCast() here rather than
+  // reinterpret_cast for better type checking, but the |N - 1| part trips
+  // static asserts.
   return Input(reinterpret_cast<const uint8_t(&)[N - 1]>(valueString));
 }
 
 const int MaxCacheEntries = 1024;
 
 class OCSPCacheTest : public ::testing::Test
 {
 protected:
@@ -80,17 +84,18 @@ TEST_F(OCSPCacheTest, TestPutAndGet)
                          resultOut, timeOut));
 }
 
 TEST_F(OCSPCacheTest, TestVariousGets)
 {
   SCOPED_TRACE("");
   for (int i = 0; i < MaxCacheEntries; i++) {
     uint8_t serialBuf[8];
-    snprintf(reinterpret_cast<char*>(serialBuf), sizeof(serialBuf), "%04d", i);
+    snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), sizeof(serialBuf),
+             "%04d", i);
     Input fakeSerial;
     ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4));
     Time timeIn(now);
     ASSERT_EQ(Success, timeIn.AddSeconds(i));
     PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial),
               Success, timeIn);
   }
 
@@ -129,17 +134,18 @@ TEST_F(OCSPCacheTest, TestVariousGets)
 
 TEST_F(OCSPCacheTest, TestEviction)
 {
   SCOPED_TRACE("");
   // By putting more distinct entries in the cache than it can hold,
   // we cause the least recently used entry to be evicted.
   for (int i = 0; i < MaxCacheEntries + 1; i++) {
     uint8_t serialBuf[8];
-    snprintf(reinterpret_cast<char*>(serialBuf), sizeof(serialBuf), "%04d", i);
+    snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), sizeof(serialBuf),
+             "%04d", i);
     Input fakeSerial;
     ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4));
     Time timeIn(now);
     ASSERT_EQ(Success, timeIn.AddSeconds(i));
     PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial),
               Success, timeIn);
   }
 
@@ -154,17 +160,18 @@ TEST_F(OCSPCacheTest, TestNoEvictionForR
   SCOPED_TRACE("");
   CertID notEvicted(fakeIssuer1, fakeKey000, fakeSerial0000);
   Time timeIn(now);
   PutAndGet(cache, notEvicted, Result::ERROR_REVOKED_CERTIFICATE, timeIn);
   // By putting more distinct entries in the cache than it can hold,
   // we cause the least recently used entry that isn't revoked to be evicted.
   for (int i = 1; i < MaxCacheEntries + 1; i++) {
     uint8_t serialBuf[8];
-    snprintf(reinterpret_cast<char*>(serialBuf), sizeof(serialBuf), "%04d", i);
+    snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), sizeof(serialBuf),
+             "%04d", i);
     Input fakeSerial;
     ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4));
     Time timeIn(now);
     ASSERT_EQ(Success, timeIn.AddSeconds(i));
     PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial),
               Success, timeIn);
   }
   Result resultOut;
@@ -180,17 +187,18 @@ TEST_F(OCSPCacheTest, TestNoEvictionForR
 
 TEST_F(OCSPCacheTest, TestEverythingIsRevoked)
 {
   SCOPED_TRACE("");
   Time timeIn(now);
   // Fill up the cache with revoked responses.
   for (int i = 0; i < MaxCacheEntries; i++) {
     uint8_t serialBuf[8];
-    snprintf(reinterpret_cast<char*>(serialBuf), sizeof(serialBuf), "%04d", i);
+    snprintf(mozilla::BitwiseCast<char*, uint8_t*>(serialBuf), sizeof(serialBuf),
+             "%04d", i);
     Input fakeSerial;
     ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4));
     Time timeIn(now);
     ASSERT_EQ(Success, timeIn.AddSeconds(i));
     PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial),
               Result::ERROR_REVOKED_CERTIFICATE, timeIn);
   }
   static const Input fakeSerial1025(LiteralInput("1025"));
--- a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp
@@ -124,17 +124,17 @@ AddKeyFromFile(const char* basePath, con
       *base64Ptr = *bufPtr;
       base64Ptr++;
     }
     bufPtr++;
   }
 
   unsigned int binLength;
   UniquePORTString bin(
-    reinterpret_cast<char*>(ATOB_AsciiToData(base64, &binLength)));
+    BitwiseCast<char*, unsigned char*>(ATOB_AsciiToData(base64, &binLength)));
   if (!bin || binLength == 0) {
     PrintPRError("ATOB_AsciiToData failed");
     return SECFailure;
   }
   ScopedSECItem secitem(::SECITEM_AllocItem(nullptr, nullptr, binLength));
   if (!secitem) {
     PrintPRError("SECITEM_AllocItem failed");
     return SECFailure;
--- a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h
@@ -9,18 +9,20 @@
 // The client is expected to connect and initiate an SSL handshake (with SNI
 // to indicate which "server" to connect to). If all is good, the client then
 // sends one encrypted byte and receives that same byte back.
 // This server also has the ability to "call back" another process waiting on
 // it. That is, when the server is all set up and ready to receive connections,
 // it will connect to a specified port and issue a simple HTTP request.
 
 #include <stdint.h>
+
+#include "ScopedNSSTypes.h"
+#include "mozilla/Casting.h"
 #include "prio.h"
-#include "ScopedNSSTypes.h"
 #include "secerr.h"
 #include "ssl.h"
 
 namespace mozilla {
 
 MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePRDir, PRDir, PR_CloseDir);
 
 } // namespace mozilla
@@ -58,17 +60,17 @@ StartServer(const char *nssCertDBDir, SS
 template <typename Host>
 inline const Host *
 GetHostForSNI(const SECItem *aSrvNameArr, uint32_t aSrvNameArrSize,
               const Host *hosts)
 {
   for (uint32_t i = 0; i < aSrvNameArrSize; i++) {
     for (const Host *host = hosts; host->mHostName; ++host) {
       SECItem hostName;
-      hostName.data = reinterpret_cast<uint8_t*>(const_cast<char*>(host->mHostName));
+      hostName.data = BitwiseCast<unsigned char*, const char*>(host->mHostName);
       hostName.len = strlen(host->mHostName);
       if (SECITEM_ItemsAreEqual(&hostName, &aSrvNameArr[i])) {
         if (gDebugLevel >= DEBUG_VERBOSE) {
           fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
         }
         return host;
       }
     }