Securely clear memory containing key information / passwords before freeing.

The previously used "memset(ptr, 0, size)" can get optimized away by compilers
if "ptr" is not used afterwards.

A new class "ZeroOnFreeBuffer" is introduced that can hold sensitive data and
that automatically clears underlying memory when it's no longer used.

Bug: webrtc:8806, webrtc:8897, webrtc:8905
Change-Id: Iedddddf80790f9af0addaab3346ec5bff102917d
Reviewed-on: https://webrtc-review.googlesource.com/41941
Commit-Queue: Joachim Bauch <jbauch@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22334}
diff --git a/rtc_base/httpcommon.cc b/rtc_base/httpcommon.cc
index e60ad47..f23cb63 100644
--- a/rtc_base/httpcommon.cc
+++ b/rtc_base/httpcommon.cc
@@ -28,6 +28,7 @@
 #include "rtc_base/httpcommon.h"
 #include "rtc_base/messagedigest.h"
 #include "rtc_base/socketaddress.h"
+#include "rtc_base/zero_memory.h"
 
 namespace rtc {
 namespace {
@@ -775,8 +776,10 @@
 
     context = new HttpAuthContext(auth_method);
 
-    // TODO: convert sensitive to a secure buffer that gets securely deleted
-    //std::string decoded = username + ":" + password;
+    // TODO(bugs.webrtc.org/8905): Convert sensitive to a CryptString and also
+    // return response as CryptString so contents get securely deleted
+    // automatically.
+    // std::string decoded = username + ":" + password;
     size_t len = username.size() + password.GetLength() + 2;
     char * sensitive = new char[len];
     size_t pos = strcpyn(sensitive, len, username.data(), username.size());
@@ -787,7 +790,7 @@
     response.append(" ");
     // TODO: create a sensitive-source version of Base64::encode
     response.append(Base64::Encode(sensitive));
-    memset(sensitive, 0, len);
+    ExplicitZeroMemory(sensitive, len);
     delete [] sensitive;
     return HAR_RESPONSE;
   }
@@ -813,8 +816,10 @@
     bool has_qop = HttpHasAttribute(args, "qop", &qop);
     bool has_opaque = HttpHasAttribute(args, "opaque", &opaque);
 
-    // TODO: convert sensitive to be secure buffer
-    //std::string A1 = username + ":" + realm + ":" + password;
+    // TODO(bugs.webrtc.org/8905): Convert sensitive to a CryptString and also
+    // return response as CryptString so contents get securely deleted
+    // automatically.
+    // std::string A1 = username + ":" + realm + ":" + password;
     size_t len = username.size() + realm.size() + password.GetLength() + 3;
     char * sensitive = new char[len];  // A1
     size_t pos = strcpyn(sensitive, len, username.data(), username.size());
@@ -832,7 +837,7 @@
       middle = nonce;
     }
     std::string HA1 = MD5(sensitive);
-    memset(sensitive, 0, len);
+    ExplicitZeroMemory(sensitive, len);
     delete [] sensitive;
     std::string HA2 = MD5(A2);
     std::string dig_response = MD5(HA1 + ":" + middle + ":" + HA2);
@@ -981,7 +986,7 @@
           memcpy(passbuf, sensitive, auth_id.PasswordLength);
           passbuf[auth_id.PasswordLength] = 0;
         }
-        memset(sensitive, 0, len);
+        ExplicitZeroMemory(sensitive, len);
         delete [] sensitive;
         auth_id.User = userbuf;
         auth_id.Domain = domainbuf;