implement __hash__ on CertificatePolicies and its child classes (#3914)

diff --git a/src/cryptography/x509/extensions.py b/src/cryptography/x509/extensions.py
index 8880f74..9d6b3e7 100644
--- a/src/cryptography/x509/extensions.py
+++ b/src/cryptography/x509/extensions.py
@@ -597,6 +597,9 @@
     def __getitem__(self, idx):
         return self._policies[idx]
 
+    def __hash__(self):
+        return hash(tuple(self._policies))
+
 
 class PolicyInformation(object):
     def __init__(self, policy_identifier, policy_qualifiers):
@@ -636,6 +639,14 @@
     def __ne__(self, other):
         return not self == other
 
+    def __hash__(self):
+        if self.policy_qualifiers is not None:
+            pq = tuple(self.policy_qualifiers)
+        else:
+            pq = None
+
+        return hash((self.policy_identifier, pq))
+
     policy_identifier = utils.read_only_property("_policy_identifier")
     policy_qualifiers = utils.read_only_property("_policy_qualifiers")
 
@@ -670,6 +681,9 @@
     def __ne__(self, other):
         return not self == other
 
+    def __hash__(self):
+        return hash((self.notice_reference, self.explicit_text))
+
     notice_reference = utils.read_only_property("_notice_reference")
     explicit_text = utils.read_only_property("_explicit_text")
 
@@ -703,6 +717,9 @@
     def __ne__(self, other):
         return not self == other
 
+    def __hash__(self):
+        return hash((self.organization, tuple(self.notice_numbers)))
+
     organization = utils.read_only_property("_organization")
     notice_numbers = utils.read_only_property("_notice_numbers")
 
diff --git a/tests/x509/test_x509_ext.py b/tests/x509/test_x509_ext.py
index 22b4cc5..8d13753 100644
--- a/tests/x509/test_x509_ext.py
+++ b/tests/x509/test_x509_ext.py
@@ -369,6 +369,13 @@
         assert nr != nr3
         assert nr != object()
 
+    def test_hash(self):
+        nr = x509.NoticeReference("org", [1, 2])
+        nr2 = x509.NoticeReference("org", [1, 2])
+        nr3 = x509.NoticeReference(None, [1, 2])
+        assert hash(nr) == hash(nr2)
+        assert hash(nr) != hash(nr3)
+
 
 class TestUserNotice(object):
     def test_notice_reference_invalid(self):
@@ -410,6 +417,15 @@
         assert un != un3
         assert un != object()
 
+    def test_hash(self):
+        nr = x509.NoticeReference("org", [1, 2])
+        nr2 = x509.NoticeReference("org", [1, 2])
+        un = x509.UserNotice(nr, "text")
+        un2 = x509.UserNotice(nr2, "text")
+        un3 = x509.UserNotice(None, "text")
+        assert hash(un) == hash(un2)
+        assert hash(un) != hash(un3)
+
 
 class TestPolicyInformation(object):
     def test_invalid_policy_identifier(self):
@@ -477,6 +493,19 @@
         assert pi != pi3
         assert pi != object()
 
+    def test_hash(self):
+        pi = x509.PolicyInformation(
+            x509.ObjectIdentifier("1.2.3"),
+            [u"string", x509.UserNotice(None, u"hi")]
+        )
+        pi2 = x509.PolicyInformation(
+            x509.ObjectIdentifier("1.2.3"),
+            [u"string", x509.UserNotice(None, u"hi")]
+        )
+        pi3 = x509.PolicyInformation(x509.ObjectIdentifier("1.2.3"), None)
+        assert hash(pi) == hash(pi2)
+        assert hash(pi) != hash(pi3)
+
 
 @pytest.mark.requires_backend_interface(interface=X509Backend)
 class TestCertificatePolicies(object):
@@ -571,6 +600,22 @@
 
         assert ext.value[0].policy_identifier == oid
 
+    def test_hash(self):
+        pi = x509.PolicyInformation(
+            x509.ObjectIdentifier("1.2.3"), [u"string"]
+        )
+        cp = x509.CertificatePolicies([pi])
+        pi2 = x509.PolicyInformation(
+            x509.ObjectIdentifier("1.2.3"), [u"string"]
+        )
+        cp2 = x509.CertificatePolicies([pi2])
+        pi3 = x509.PolicyInformation(
+            x509.ObjectIdentifier("1.2.3"), [x509.UserNotice(None, b"text")]
+        )
+        cp3 = x509.CertificatePolicies([pi3])
+        assert hash(cp) == hash(cp2)
+        assert hash(cp) != hash(cp3)
+
 
 @pytest.mark.requires_backend_interface(interface=RSABackend)
 @pytest.mark.requires_backend_interface(interface=X509Backend)