Add tests for X509_NAME_hash and X509_NAME_hash_old.

These values figure into X509_LOOKUP_hash_dir's on-disk format, so they
must remain stable. Record a couple of values to ensure this remains the
case.

Change-Id: I63afa970f8564e0836d78d00375eb5cd6d383bea
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56485
Reviewed-by: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index 93dccda..ebd8262 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -2547,6 +2547,67 @@
   EXPECT_EQ(X509_NAME_ENTRY_set(X509_NAME_get_entry(name.get(), 2)), 2);
 }
 
+// Tests that |X509_NAME_hash| and |X509_NAME_hash_old|'s values never change.
+// These functions figure into |X509_LOOKUP_hash_dir|'s on-disk format, so they
+// must remain stable. In particular, if we ever remove name canonicalization,
+// we'll need to preserve it for |X509_NAME_hash|.
+TEST(X509Test, NameHash) {
+  struct {
+    std::vector<uint8_t> name_der;
+    unsigned long hash;
+    unsigned long hash_old;
+  } kTests[] = {
+      // SEQUENCE {
+      //   SET {
+      //     SEQUENCE {
+      //       # commonName
+      //       OBJECT_IDENTIFIER { 2.5.4.3 }
+      //       UTF8String { "Test Name" }
+      //     }
+      //   }
+      // }
+      {{0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
+        0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x65},
+       0xc90fba01,
+       0x8c0d4fea},
+
+      // This name canonicalizes to the same value, with OpenSSL's algorithm, as
+      // the above input, so |hash| matches. |hash_old| doesn't use
+      // canonicalization and does not match.
+      //
+      // SEQUENCE {
+      //   SET {
+      //     SEQUENCE {
+      //       # commonName
+      //       OBJECT_IDENTIFIER { 2.5.4.3 }
+      //       BMPString {
+      //         u"\x09\n\x0b\x0c\x0d tEST\x09\n\x0b\x0c\x0d "
+      //         u"\x09\n\x0b\x0c\x0d nAME\x09\n\x0b\x0c\x0d "
+      //       }
+      //     }
+      //   }
+      // }
+      {{0x30, 0x4b, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55, 0x04, 0x03,
+        0x1e, 0x40, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00,
+        0x0d, 0x00, 0x20, 0x00, 0x74, 0x00, 0x45, 0x00, 0x53, 0x00, 0x54,
+        0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00,
+        0x20, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d,
+        0x00, 0x20, 0x00, 0x6e, 0x00, 0x41, 0x00, 0x4d, 0x00, 0x45, 0x00,
+        0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x20},
+       0xc90fba01,
+       0xbe2dd8c8},
+  };
+  for (const auto &t : kTests) {
+    SCOPED_TRACE(Bytes(t.name_der));
+    const uint8_t *der = t.name_der.data();
+    bssl::UniquePtr<X509_NAME> name(
+        d2i_X509_NAME(nullptr, &der, t.name_der.size()));
+    ASSERT_TRUE(name);
+    EXPECT_EQ(t.hash, X509_NAME_hash(name.get()));
+    EXPECT_EQ(t.hash_old, X509_NAME_hash_old(name.get()));
+  }
+}
+
 TEST(X509Test, NoBasicConstraintsCertSign) {
   bssl::UniquePtr<X509> root(CertFromPEM(kSANTypesRoot));
   bssl::UniquePtr<X509> intermediate(