Add a helper for comparing byte strings.

We compare pointer/length pairs constantly. To avoid needing to type it
everywhere and get GTest's output, add a StringPiece-alike for byte
slices which supports ==, !=, and std::ostream.

BUG=129

Change-Id: I108342cbd2c6a58fec0b9cb87ebdf50364bda099
Reviewed-on: https://boringssl-review.googlesource.com/13625
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/test/test_util.cc b/crypto/test/test_util.cc
index 928972a..493b124 100644
--- a/crypto/test/test_util.cc
+++ b/crypto/test/test_util.cc
@@ -12,11 +12,12 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
 
-#include <stdint.h>
-#include <stdio.h>
-
 #include "test_util.h"
 
+#include <ostream>
+
+#include "../internal.h"
+
 
 void hexdump(FILE *fp, const char *msg, const void *in, size_t len) {
   const uint8_t *data = reinterpret_cast<const uint8_t*>(in);
@@ -27,3 +28,13 @@
   }
   fputs("\n", fp);
 }
+
+std::ostream &operator<<(std::ostream &os, const Bytes &in) {
+  // Print a byte slice as hex.
+  static const char hex[] = "0123456789abcdef";
+  for (size_t i = 0; i < in.len; i++) {
+    os << hex[in.data[i] >> 4];
+    os << hex[in.data[i] & 0xf];
+  }
+  return os;
+}
diff --git a/crypto/test/test_util.h b/crypto/test/test_util.h
index 972e206..d834973 100644
--- a/crypto/test/test_util.h
+++ b/crypto/test/test_util.h
@@ -16,20 +16,38 @@
 #define OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H
 
 #include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+#include <iosfwd>
+
+#include "../internal.h"
 
 
-/* hexdump writes |msg| to |fp| followed by the hex encoding of |len| bytes
- * from |in|. */
+// hexdump writes |msg| to |fp| followed by the hex encoding of |len| bytes
+// from |in|.
 void hexdump(FILE *fp, const char *msg, const void *in, size_t len);
 
+// Bytes is a wrapper over a byte slice which may be compared for equality. This
+// allows it to be used in EXPECT_EQ macros.
+struct Bytes {
+  Bytes(const uint8_t *data_arg, size_t len_arg)
+      : data(data_arg), len(len_arg) {}
 
-#if defined(__cplusplus)
+  template <size_t N>
+  Bytes(const uint8_t (&array)[N]) : data(array), len(N) {}
+
+  const uint8_t *data;
+  size_t len;
+};
+
+inline bool operator==(const Bytes &a, const Bytes &b) {
+  return a.len == b.len && OPENSSL_memcmp(a.data, b.data, a.len) == 0;
 }
-#endif
+
+inline bool operator!=(const Bytes &a, const Bytes &b) { return !(a == b); }
+
+std::ostream &operator<<(std::ostream &os, const Bytes &in);
+
 
 #endif /* OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H */
diff --git a/crypto/x509/pkcs7_test.c b/crypto/x509/pkcs7_test.c
index 7bf4b81..f620b9b 100644
--- a/crypto/x509/pkcs7_test.c
+++ b/crypto/x509/pkcs7_test.c
@@ -23,7 +23,6 @@
 #include <openssl/x509.h>
 
 #include "../internal.h"
-#include "../test/test_util.h"
 
 
 /* kPKCS7NSS contains the certificate chain of mail.google.com, as saved by NSS