Bug 1271501 - Use mozilla::BitwiseCast instead of reinterpret_cast in PSM. r=keeler draft
authorCykesiopka <cykesiopka.bmo@gmail.com>
Wed, 18 May 2016 21:20:56 -0700
changeset 368593 b73d0cb47ecf7ff48f5e2f81adc5a02346ca4ac2
parent 368591 857796af22807857af260f0cc00bf7304b76dbd5
child 521333 5b6ce58df6fb29eb3e4164e0b8afb0ee1490eee2
push id18598
push usercykesiopka.bmo@gmail.com
push dateThu, 19 May 2016 04:21:44 +0000
reviewerskeeler
bugs1271501
milestone49.0a1
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()
@@ -2032,17 +2032,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;
   }
@@ -2229,17 +2229,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;
       }
     }