Merge pull request #1498 from reaperhulk/x509-more-vectors

add several new x509 test vectors
diff --git a/.travis.yml b/.travis.yml
index cacd1e2..da7ecde 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,21 +7,21 @@
     - gcc
 env:
     matrix:
-        - TOX_ENV=py26
-        - TOX_ENV=py27
-        - TOX_ENV=py32
-        - TOX_ENV=py33
-        - TOX_ENV=py34
-        - TOX_ENV=pypy
-        - TOX_ENV=py26 OPENSSL=0.9.8
-        - TOX_ENV=py27 OPENSSL=0.9.8
-        - TOX_ENV=py32 OPENSSL=0.9.8
-        - TOX_ENV=py33 OPENSSL=0.9.8
-        - TOX_ENV=py34 OPENSSL=0.9.8
-        - TOX_ENV=pypy OPENSSL=0.9.8
-        - TOX_ENV=docs
-        - TOX_ENV=pep8
-        - TOX_ENV=py3pep8
+        - TOXENV=py26
+        - TOXENV=py27
+        - TOXENV=py32
+        - TOXENV=py33
+        - TOXENV=py34
+        - TOXENV=pypy
+        - TOXENV=py26 OPENSSL=0.9.8
+        - TOXENV=py27 OPENSSL=0.9.8
+        - TOXENV=py32 OPENSSL=0.9.8
+        - TOXENV=py33 OPENSSL=0.9.8
+        - TOXENV=py34 OPENSSL=0.9.8
+        - TOXENV=pypy OPENSSL=0.9.8
+        - TOXENV=docs
+        - TOXENV=pep8
+        - TOXENV=py3pep8
 
 install:
     - ./.travis/install.sh
@@ -44,18 +44,18 @@
         - os: osx
           compiler: gcc
         - os: osx
-          env: TOX_ENV=pep8
+          env: TOXENV=pep8
           compiler: clang
         - os: osx
-          env: TOX_ENV=py3pep8
+          env: TOXENV=py3pep8
           compiler: clang
 
         - os: linux
-          env: TOX_ENV=docs
+          env: TOXENV=docs
           compiler: clang
         - os: linux
-          env: TOX_ENV=pep8
+          env: TOXENV=pep8
           compiler: clang
         - os: linux
-          env: TOX_ENV=py3pep8
+          env: TOXENV=py3pep8
           compiler: clang
diff --git a/.travis/install.sh b/.travis/install.sh
index 51d3097..6dd84f2 100755
--- a/.travis/install.sh
+++ b/.travis/install.sh
@@ -20,7 +20,7 @@
         eval "$(pyenv init -)"
     fi
 
-    case "${TOX_ENV}" in
+    case "${TOXENV}" in
         py26)
             curl -O https://bootstrap.pypa.io/get-pip.py
             sudo python get-pip.py
@@ -62,7 +62,7 @@
 else
     sudo add-apt-repository -y ppa:fkrull/deadsnakes
 
-    if [[ "${TOX_ENV}" == "pypy" ]]; then
+    if [[ "${TOXENV}" == "pypy" ]]; then
         sudo add-apt-repository -y ppa:pypy/ppa
     fi
 
@@ -76,7 +76,7 @@
         sudo apt-get install -y --force-yes libssl-dev/lucid
     fi
 
-    case "${TOX_ENV}" in
+    case "${TOXENV}" in
         py26)
             sudo apt-get install python2.6 python2.6-dev
             ;;
diff --git a/.travis/run.sh b/.travis/run.sh
index e4ff266..1efbd60 100755
--- a/.travis/run.sh
+++ b/.travis/run.sh
@@ -18,4 +18,4 @@
     fi
 fi
 source ~/.venv/bin/activate
-tox -e $TOX_ENV -- $TOX_FLAGS
+tox -- $TOX_FLAGS
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index a0d8150..b8a799a 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -16,6 +16,8 @@
 * Added :class:`~cryptography.hazmat.primitives.interfaces.MACContext` as a
   common interface for CMAC and HMAC and deprecated
   :class:`~cryptography.hazmat.primitives.interfaces.CMACContext`.
+* Added support for encoding and decoding :rfc:`6979` signatures in
+  :doc:`/hazmat/primitives/asymmetric/utils`.
 
 0.6.1 - 2014-10-15
 ~~~~~~~~~~~~~~~~~~
diff --git a/dev-requirements.txt b/dev-requirements.txt
index 4fff76b..092b991 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -5,7 +5,6 @@
 iso8601
 pep8-naming
 pretend
-pyasn1
 pytest
 requests
 sphinx
diff --git a/docs/community.rst b/docs/community.rst
index bf1cd1c..2b7cdc6 100644
--- a/docs/community.rst
+++ b/docs/community.rst
@@ -17,4 +17,4 @@
 .. _`Source code`: https://github.com/pyca/cryptography
 .. _`Issue tracker`: https://github.com/pyca/cryptography/issues
 .. _`Documentation`: https://cryptography.io/
-.. _`Python Community Code of Conduct`: http://www.python.org/psf/codeofconduct/
+.. _`Python Community Code of Conduct`: https://www.python.org/psf/codeofconduct/
diff --git a/docs/conf.py b/docs/conf.py
index b70114d..fc16b38 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -268,6 +268,6 @@
 # texinfo_show_urls = 'footnote'
 
 # Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'http://docs.python.org/': None}
+intersphinx_mapping = {'https://docs.python.org/': None}
 
 epub_theme = 'epub'
diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst
index 5696337..993a4ab 100644
--- a/docs/development/c-bindings.rst
+++ b/docs/development/c-bindings.rst
@@ -3,10 +3,14 @@
 
 C bindings are bindings to C libraries, using cffi_ whenever possible.
 
-.. _cffi: http://cffi.readthedocs.org
+.. _cffi: https://cffi.readthedocs.org
 
 Bindings live in :py:mod:`cryptography.hazmat.bindings`.
 
+When modifying the bindings you will need to recompile the C extensions to
+test the changes. This can be accomplished with ``pip install -e .`` in the
+project root. If you do not do this a ``RuntimeError`` will be raised.
+
 Style guide
 -----------
 
diff --git a/docs/development/submitting-patches.rst b/docs/development/submitting-patches.rst
index ff650c4..810b874 100644
--- a/docs/development/submitting-patches.rst
+++ b/docs/development/submitting-patches.rst
@@ -25,6 +25,9 @@
 
 `Write comments as complete sentences.`_
 
+Class names which contains acronyms or initialisms should always be
+capitalized. A class should be named ``HTTPClient``, not ``HttpClient``.
+
 Every code file must start with the boilerplate licensing notice:
 
 .. code-block:: python
diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst
index e829798..b48e502 100644
--- a/docs/hazmat/backends/openssl.rst
+++ b/docs/hazmat/backends/openssl.rst
@@ -78,5 +78,5 @@
 
 .. _`OpenSSL`: https://www.openssl.org/
 .. _`initializing the RNG`: https://en.wikipedia.org/wiki/OpenSSL#Predictable_keys_.28Debian-specific.29
-.. _`Yarrow`: http://en.wikipedia.org/wiki/Yarrow_algorithm
+.. _`Yarrow`: https://en.wikipedia.org/wiki/Yarrow_algorithm
 .. _`Microsoft documentation`: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx
diff --git a/docs/hazmat/bindings/openssl.rst b/docs/hazmat/bindings/openssl.rst
index a6d1c48..36255b5 100644
--- a/docs/hazmat/bindings/openssl.rst
+++ b/docs/hazmat/bindings/openssl.rst
@@ -46,4 +46,4 @@
 
 .. _`CFFI`: https://cffi.readthedocs.org/
 .. _`OpenSSL`: https://www.openssl.org/
-.. _`thread safety facilities`: http://www.openssl.org/docs/crypto/threads.html
+.. _`thread safety facilities`: https://www.openssl.org/docs/crypto/threads.html
diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst
index 43741ed..df3c99f 100644
--- a/docs/hazmat/primitives/asymmetric/dsa.rst
+++ b/docs/hazmat/primitives/asymmetric/dsa.rst
@@ -80,7 +80,8 @@
     >>> signature = signer.finalize()
 
 The ``signature`` is a ``bytes`` object, whose contents is DER encoded as
-described in :rfc:`6979`.
+described in :rfc:`6979`. This can be decoded using
+:func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_rfc6979_signature`.
 
 Verification
 ~~~~~~~~~~~~
diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst
index fd20cbb..13ab7c1 100644
--- a/docs/hazmat/primitives/asymmetric/ec.rst
+++ b/docs/hazmat/primitives/asymmetric/ec.rst
@@ -53,7 +53,9 @@
         >>> signature = signer.finalize()
 
     The ``signature`` is a ``bytes`` object, whose contents is DER encoded as
-    described in :rfc:`6979`.
+    described in :rfc:`6979`. This can be decoded using
+    :func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_rfc6979_signature`.
+
 
 
 .. class:: EllipticCurvePrivateNumbers(private_value, public_numbers)
diff --git a/docs/hazmat/primitives/asymmetric/index.rst b/docs/hazmat/primitives/asymmetric/index.rst
index 6a5228b..24f0f5b 100644
--- a/docs/hazmat/primitives/asymmetric/index.rst
+++ b/docs/hazmat/primitives/asymmetric/index.rst
@@ -11,3 +11,4 @@
     rsa
     padding
     serialization
+    utils
diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst
index a5cebb1..6c96090 100644
--- a/docs/hazmat/primitives/asymmetric/rsa.rst
+++ b/docs/hazmat/primitives/asymmetric/rsa.rst
@@ -271,4 +271,4 @@
 .. _`use 65537`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html
 .. _`at least 2048`: http://www.ecrypt.eu.org/documents/D.SPA.20.pdf
 .. _`OpenPGP`: https://en.wikipedia.org/wiki/Pretty_Good_Privacy
-.. _`Chinese Remainder Theorem`: http://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Using_the_Chinese_remainder_algorithm
+.. _`Chinese Remainder Theorem`: https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Using_the_Chinese_remainder_algorithm
diff --git a/docs/hazmat/primitives/asymmetric/utils.rst b/docs/hazmat/primitives/asymmetric/utils.rst
new file mode 100644
index 0000000..6b34880
--- /dev/null
+++ b/docs/hazmat/primitives/asymmetric/utils.rst
@@ -0,0 +1,26 @@
+.. hazmat::
+
+Asymmetric Utilities
+====================
+
+.. currentmodule:: cryptography.hazmat.primitives.asymmetric.utils
+
+
+.. function:: decode_rfc6979_signature(signature)
+
+    Takes in :rfc:`6979` signatures generated by the DSA/ECDSA signers and
+    returns a tuple ``(r, s)``.
+
+    :param bytes signature: The signature to decode.
+
+    :returns: The decoded tuple ``(r, s)``.
+
+.. function:: encode_rfc6979_signature(r, s)
+
+    Creates an :rfc:`6979` byte string from raw signature values.
+
+    :param int r: The raw signature value ``r``.
+
+    :param int s: The raw signature value ``s``.
+
+    :return bytes: The encoded signature.
diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst
index d964f25..d87e8d6 100644
--- a/docs/hazmat/primitives/interfaces.rst
+++ b/docs/hazmat/primitives/interfaces.rst
@@ -9,7 +9,7 @@
 this information to influence their operation. Interfaces should also be used
 to document argument and return types.
 
-.. _`Abstract Base Classes`: http://docs.python.org/3.2/library/abc.html
+.. _`Abstract Base Classes`: https://docs.python.org/3/library/abc.html
 
 
 Symmetric ciphers
@@ -752,5 +752,5 @@
 .. _`Chinese remainder theorem`: https://en.wikipedia.org/wiki/Chinese_remainder_theorem
 .. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm
 .. _`CMAC`: https://en.wikipedia.org/wiki/CMAC
-.. _`ECDSA`: http://en.wikipedia.org/wiki/ECDSA
-.. _`EdDSA`: http://en.wikipedia.org/wiki/EdDSA
+.. _`ECDSA`: https://en.wikipedia.org/wiki/ECDSA
+.. _`EdDSA`: https://en.wikipedia.org/wiki/EdDSA
diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst
index 586285b..b21ef61 100644
--- a/docs/hazmat/primitives/symmetric-encryption.rst
+++ b/docs/hazmat/primitives/symmetric-encryption.rst
@@ -510,6 +510,6 @@
 .. _`Communications Security Establishment`: http://www.cse-cst.gc.ca
 .. _`encrypt`: https://ssd.eff.org/tech/encryption
 .. _`CRYPTREC`: http://www.cryptrec.go.jp/english/
-.. _`significant patterns in the output`: http://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29
+.. _`significant patterns in the output`: https://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29
 .. _`International Data Encryption Algorithm`: https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm
 .. _`OpenPGP`: http://www.openpgp.org
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index b7b3343..003e37d 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -24,6 +24,7 @@
 Fernet
 hazmat
 indistinguishability
+initialisms
 interoperable
 introspectability
 invariants
diff --git a/setup.py b/setup.py
index 7a76909..3e2ab3e 100644
--- a/setup.py
+++ b/setup.py
@@ -36,6 +36,7 @@
 
 requirements = [
     CFFI_DEPENDENCY,
+    "pyasn1",
     SIX_DEPENDENCY,
     SETUPTOOLS_DEPENDENCY
 ]
@@ -43,7 +44,6 @@
 # If you add a new dep here you probably need to add it in the tox.ini as well
 test_requirements = [
     "pytest",
-    "pyasn1",
     "pretend",
     "iso8601",
 ]
diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py
index 4270cb2..b0e1a99 100644
--- a/src/cryptography/exceptions.py
+++ b/src/cryptography/exceptions.py
@@ -14,6 +14,7 @@
     UNSUPPORTED_PUBLIC_KEY_ALGORITHM = object()
     UNSUPPORTED_ELLIPTIC_CURVE = object()
     UNSUPPORTED_SERIALIZATION = object()
+    UNSUPPORTED_X509 = object()
 
 
 class UnsupportedAlgorithm(Exception):
diff --git a/src/cryptography/hazmat/backends/multibackend.py b/src/cryptography/hazmat/backends/multibackend.py
index fce6c8e..ffc569f 100644
--- a/src/cryptography/hazmat/backends/multibackend.py
+++ b/src/cryptography/hazmat/backends/multibackend.py
@@ -12,7 +12,7 @@
     CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend,
     HashBackend, PBKDF2HMACBackend, PEMSerializationBackend,
     PKCS8SerializationBackend, RSABackend,
-    TraditionalOpenSSLSerializationBackend
+    TraditionalOpenSSLSerializationBackend, X509Backend
 )
 
 
@@ -27,6 +27,7 @@
 @utils.register_interface(DSABackend)
 @utils.register_interface(EllipticCurveBackend)
 @utils.register_interface(PEMSerializationBackend)
+@utils.register_interface(X509Backend)
 class MultiBackend(object):
     name = "multibackend"
 
@@ -347,3 +348,25 @@
             "This backend does not support this key serialization.",
             _Reasons.UNSUPPORTED_SERIALIZATION
         )
+
+    def load_pem_x509_certificate(self, data):
+        for b in self._filtered_backends(
+            X509Backend
+        ):
+            return b.load_pem_x509_certificate(data)
+
+        raise UnsupportedAlgorithm(
+            "This backend does not support X.509.",
+            _Reasons.UNSUPPORTED_X509
+        )
+
+    def load_der_x509_certificate(self, data):
+        for b in self._filtered_backends(
+            X509Backend
+        ):
+            return b.load_der_x509_certificate(data)
+
+        raise UnsupportedAlgorithm(
+            "This backend does not support X.509.",
+            _Reasons.UNSUPPORTED_X509
+        )
diff --git a/src/cryptography/hazmat/bindings/openssl/asn1.py b/src/cryptography/hazmat/bindings/openssl/asn1.py
index 2681dd9..a73dc32 100644
--- a/src/cryptography/hazmat/bindings/openssl/asn1.py
+++ b/src/cryptography/hazmat/bindings/openssl/asn1.py
@@ -57,7 +57,11 @@
 
 static const int V_ASN1_GENERALIZEDTIME;
 
+static const int MBSTRING_FLAG;
+static const int MBSTRING_ASC;
+static const int MBSTRING_BMP;
 static const int MBSTRING_UTF8;
+static const int MBSTRING_UNIV;
 """
 
 FUNCTIONS = """
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
index 1aed28d..87c1429 100644
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -15,7 +15,7 @@
  * Internally invented symbols to tell which versions of SSL/TLS are supported.
 */
 static const long Cryptography_HAS_SSL2;
-static const long Cryptography_HAS_SSL3_METHOD;
+static const long Cryptography_HAS_SSL3;
 static const long Cryptography_HAS_TLSv1_1;
 static const long Cryptography_HAS_TLSv1_2;
 static const long Cryptography_HAS_SECURE_RENEGOTIATION;
@@ -211,6 +211,8 @@
 int SSL_CTX_use_certificate_chain_file(SSL_CTX *, const char *);
 int SSL_CTX_use_PrivateKey(SSL_CTX *, EVP_PKEY *);
 int SSL_CTX_use_PrivateKey_file(SSL_CTX *, const char *, int);
+int SSL_CTX_check_private_key(const SSL_CTX *);
+
 void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
 int SSL_CTX_add_client_CA(SSL_CTX *, X509 *);
@@ -385,13 +387,13 @@
 static const long Cryptography_HAS_SSL2 = 1;
 #endif
 
-#ifdef OPENSSL_NO_SSL3_METHOD
-static const long Cryptography_HAS_SSL3_METHOD = 0;
+#ifdef OPENSSL_NO_SSL3
+static const long Cryptography_HAS_SSL3 = 0;
 SSL_METHOD* (*SSLv3_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_client_method)(void) = NULL;
 SSL_METHOD* (*SSLv3_server_method)(void) = NULL;
 #else
-static const long Cryptography_HAS_SSL3_METHOD = 1;
+static const long Cryptography_HAS_SSL3 = 1;
 #endif
 
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -564,7 +566,7 @@
         "SSLv2_server_method",
     ],
 
-    "Cryptography_HAS_SSL3_METHOD": [
+    "Cryptography_HAS_SSL3": [
         "SSLv3_method",
         "SSLv3_client_method",
         "SSLv3_server_method",
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py
index 2fdba0f..a6e1cb6 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509.py
@@ -70,6 +70,39 @@
 } X509;
 
 typedef ... NETSCAPE_SPKI;
+
+static const int X509_FLAG_COMPAT;
+static const int X509_FLAG_NO_HEADER;
+static const int X509_FLAG_NO_VERSION;
+static const int X509_FLAG_NO_SERIAL;
+static const int X509_FLAG_NO_SIGNAME;
+static const int X509_FLAG_NO_ISSUER;
+static const int X509_FLAG_NO_VALIDITY;
+static const int X509_FLAG_NO_SUBJECT;
+static const int X509_FLAG_NO_PUBKEY;
+static const int X509_FLAG_NO_EXTENSIONS;
+static const int X509_FLAG_NO_SIGDUMP;
+static const int X509_FLAG_NO_AUX;
+static const int X509_FLAG_NO_ATTRIBUTES;
+
+static const int XN_FLAG_SEP_MASK;
+static const int XN_FLAG_COMPAT;
+static const int XN_FLAG_SEP_COMMA_PLUS;
+static const int XN_FLAG_SEP_CPLUS_SPC;
+static const int XN_FLAG_SEP_SPLUS_SPC;
+static const int XN_FLAG_SEP_MULTILINE;
+static const int XN_FLAG_DN_REV;
+static const int XN_FLAG_FN_MASK;
+static const int XN_FLAG_FN_SN;
+static const int XN_FLAG_FN_LN;
+static const int XN_FLAG_FN_OID;
+static const int XN_FLAG_FN_NONE;
+static const int XN_FLAG_SPC_EQ;
+static const int XN_FLAG_DUMP_UNKNOWN_FIELDS;
+static const int XN_FLAG_FN_ALIGN;
+static const int XN_FLAG_RFC2253;
+static const int XN_FLAG_ONELINE;
+static const int XN_FLAG_MULTILINE;
 """
 
 FUNCTIONS = """
@@ -140,6 +173,7 @@
 int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *, EVP_PKEY *);
 int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *, EVP_PKEY *, const EVP_MD *);
 char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *);
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *, int);
 EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *);
 int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *, EVP_PKEY *);
 NETSCAPE_SPKI *NETSCAPE_SPKI_new(void);
diff --git a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
index 5b31023..6f05f4d 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py
@@ -131,6 +131,8 @@
 X509_STORE *X509_STORE_new(void);
 void X509_STORE_free(X509_STORE *);
 int X509_STORE_add_cert(X509_STORE *, X509 *);
+int X509_STORE_load_locations(X509_STORE *, const char *, const char *);
+int X509_STORE_set_default_paths(X509_STORE *);
 
 /* X509_STORE_CTX */
 X509_STORE_CTX *X509_STORE_CTX_new(void);
diff --git a/src/cryptography/hazmat/bindings/openssl/x509name.py b/src/cryptography/hazmat/bindings/openssl/x509name.py
index 59ce757..9863c19 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509name.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509name.py
@@ -27,6 +27,8 @@
 unsigned long X509_NAME_hash(X509_NAME *);
 
 int i2d_X509_NAME(X509_NAME *, unsigned char **);
+int X509_NAME_add_entry_by_txt(X509_NAME *, const char *, int,
+                               const unsigned char *, int, int, int);
 int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, unsigned char *,
                                int, int, int);
 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *, int);
diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py
index 364f3fa..3b00724 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509v3.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py
@@ -6,6 +6,19 @@
 
 INCLUDES = """
 #include <openssl/x509v3.h>
+
+/*
+ * This is part of a work-around for the difficulty cffi has in dealing with
+ * `LHASH_OF(foo)` as the name of a type.  We invent a new, simpler name that
+ * will be an alias for this type and use the alias throughout.  This works
+ * together with another opaque typedef for the same name in the TYPES section.
+ * Note that the result is an opaque type.
+ */
+#if OPENSSL_VERSION_NUMBER >= 0x10000000
+typedef LHASH_OF(CONF_VALUE) Cryptography_LHASH_OF_CONF_VALUE;
+#else
+typedef LHASH Cryptography_LHASH_OF_CONF_VALUE;
+#endif
 """
 
 TYPES = """
@@ -67,9 +80,13 @@
 } GENERAL_NAME;
 
 typedef struct stack_st_GENERAL_NAME GENERAL_NAMES;
+
+typedef ... Cryptography_LHASH_OF_CONF_VALUE;
 """
 
+
 FUNCTIONS = """
+int X509V3_EXT_add_alias(int, int);
 void X509V3_set_ctx(X509V3_CTX *, X509 *, X509 *, X509_REQ *, X509_CRL *, int);
 X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, char *, char *);
 int GENERAL_NAME_print(BIO *, GENERAL_NAME *);
@@ -83,9 +100,13 @@
 int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
 GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
 
+X509_EXTENSION *X509V3_EXT_conf_nid(Cryptography_LHASH_OF_CONF_VALUE *,
+                                    X509V3_CTX *, int, char *);
+
 /* These aren't macros these functions are all const X on openssl > 1.0.x */
 const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *);
 const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int);
+
 """
 
 CUSTOMIZATIONS = """
diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
index 5d942e0..9b06f3e 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py
@@ -59,6 +59,15 @@
     def parameters(self, backend):
         return backend.load_dsa_parameter_numbers(self)
 
+    def __eq__(self, other):
+        if not isinstance(other, DSAParameterNumbers):
+            return NotImplemented
+
+        return self.p == other.p and self.q == other.q and self.g == other.g
+
+    def __ne__(self, other):
+        return not self == other
+
 
 class DSAPublicNumbers(object):
     def __init__(self, y, parameter_numbers):
@@ -79,6 +88,18 @@
     def public_key(self, backend):
         return backend.load_dsa_public_numbers(self)
 
+    def __eq__(self, other):
+        if not isinstance(other, DSAPublicNumbers):
+            return NotImplemented
+
+        return (
+            self.y == other.y and
+            self.parameter_numbers == other.parameter_numbers
+        )
+
+    def __ne__(self, other):
+        return not self == other
+
 
 class DSAPrivateNumbers(object):
     def __init__(self, x, public_numbers):
@@ -97,3 +118,14 @@
 
     def private_key(self, backend):
         return backend.load_dsa_private_numbers(self)
+
+    def __eq__(self, other):
+        if not isinstance(other, DSAPrivateNumbers):
+            return NotImplemented
+
+        return (
+            self.x == other.x and self.public_numbers == other.public_numbers
+        )
+
+    def __ne__(self, other):
+        return not self == other
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
index d9c41c1..202f1c9 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -161,6 +161,20 @@
     x = utils.read_only_property("_x")
     y = utils.read_only_property("_y")
 
+    def __eq__(self, other):
+        if not isinstance(other, EllipticCurvePublicNumbers):
+            return NotImplemented
+
+        return (
+            self.x == other.x and
+            self.y == other.y and
+            self.curve.name == other.curve.name and
+            self.curve.key_size == other.curve.key_size
+        )
+
+    def __ne__(self, other):
+        return not self == other
+
 
 class EllipticCurvePrivateNumbers(object):
     def __init__(self, private_value, public_numbers):
@@ -184,3 +198,15 @@
 
     private_value = utils.read_only_property("_private_value")
     public_numbers = utils.read_only_property("_public_numbers")
+
+    def __eq__(self, other):
+        if not isinstance(other, EllipticCurvePrivateNumbers):
+            return NotImplemented
+
+        return (
+            self.private_value == other.private_value and
+            self.public_numbers == other.public_numbers
+        )
+
+    def __ne__(self, other):
+        return not self == other
diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
index 6aeed00..0cc6b22 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py
@@ -160,6 +160,23 @@
     def private_key(self, backend):
         return backend.load_rsa_private_numbers(self)
 
+    def __eq__(self, other):
+        if not isinstance(other, RSAPrivateNumbers):
+            return NotImplemented
+
+        return (
+            self.p == other.p and
+            self.q == other.q and
+            self.d == other.d and
+            self.dmp1 == other.dmp1 and
+            self.dmq1 == other.dmq1 and
+            self.iqmp == other.iqmp and
+            self.public_numbers == other.public_numbers
+        )
+
+    def __ne__(self, other):
+        return not self == other
+
 
 class RSAPublicNumbers(object):
     def __init__(self, e, n):
@@ -180,3 +197,12 @@
 
     def __repr__(self):
         return "<RSAPublicNumbers(e={0}, n={1})>".format(self._e, self._n)
+
+    def __eq__(self, other):
+        if not isinstance(other, RSAPublicNumbers):
+            return NotImplemented
+
+        return self.e == other.e and self.n == other.n
+
+    def __ne__(self, other):
+        return not self == other
diff --git a/src/cryptography/hazmat/primitives/asymmetric/utils.py b/src/cryptography/hazmat/primitives/asymmetric/utils.py
new file mode 100644
index 0000000..71f4ff8
--- /dev/null
+++ b/src/cryptography/hazmat/primitives/asymmetric/utils.py
@@ -0,0 +1,46 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+from pyasn1.codec.der import decoder, encoder
+from pyasn1.error import PyAsn1Error
+from pyasn1.type import namedtype, univ
+
+import six
+
+
+class _DSSSigValue(univ.Sequence):
+    componentType = namedtype.NamedTypes(
+        namedtype.NamedType('r', univ.Integer()),
+        namedtype.NamedType('s', univ.Integer())
+    )
+
+
+def decode_rfc6979_signature(signature):
+    try:
+        data, remaining = decoder.decode(signature, asn1Spec=_DSSSigValue())
+    except PyAsn1Error:
+        raise ValueError("Invalid signature data. Unable to decode ASN.1")
+
+    if remaining:
+        raise ValueError(
+            "The signature contains bytes after the end of the ASN.1 sequence."
+        )
+    r = int(data.getComponentByName('r'))
+    s = int(data.getComponentByName('s'))
+    return (r, s)
+
+
+def encode_rfc6979_signature(r, s):
+    if (
+        not isinstance(r, six.integer_types) or
+        not isinstance(s, six.integer_types)
+    ):
+        raise ValueError("Both r and s must be integers")
+
+    sig = _DSSSigValue()
+    sig.setComponentByName('r', r)
+    sig.setComponentByName('s', s)
+    return encoder.encode(sig)
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 112247c..03aa3cd 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -14,7 +14,7 @@
     CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend,
     HashBackend, PBKDF2HMACBackend, PEMSerializationBackend,
     PKCS8SerializationBackend, RSABackend,
-    TraditionalOpenSSLSerializationBackend
+    TraditionalOpenSSLSerializationBackend, X509Backend
 )
 from cryptography.hazmat.backends.multibackend import MultiBackend
 from cryptography.hazmat.primitives import cmac, hashes, hmac
@@ -203,6 +203,15 @@
         pass
 
 
+@utils.register_interface(X509Backend)
+class DummyX509Backend(object):
+    def load_pem_x509_certificate(self, data):
+        pass
+
+    def load_der_x509_certificate(self, data):
+        pass
+
+
 class TestMultiBackend(object):
     def test_ciphers(self):
         backend = MultiBackend([
@@ -522,3 +531,15 @@
             backend.load_pem_private_key(b"keydata", None)
         with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
             backend.load_pem_public_key(b"keydata")
+
+    def test_x509_backend(self):
+        backend = MultiBackend([DummyX509Backend()])
+
+        backend.load_pem_x509_certificate(b"certdata")
+        backend.load_der_x509_certificate(b"certdata")
+
+        backend = MultiBackend([])
+        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
+            backend.load_pem_x509_certificate(b"certdata")
+        with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
+            backend.load_der_x509_certificate(b"certdata")
diff --git a/tests/hazmat/primitives/test_asym_utils.py b/tests/hazmat/primitives/test_asym_utils.py
new file mode 100644
index 0000000..bf55bad
--- /dev/null
+++ b/tests/hazmat/primitives/test_asym_utils.py
@@ -0,0 +1,65 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import pytest
+
+from cryptography.hazmat.primitives.asymmetric.utils import (
+    decode_rfc6979_signature, encode_rfc6979_signature
+)
+
+
+def test_rfc6979_signature():
+    sig = encode_rfc6979_signature(1, 1)
+    assert sig == b"0\x06\x02\x01\x01\x02\x01\x01"
+    assert decode_rfc6979_signature(sig) == (1, 1)
+
+    r_s1 = (
+        1037234182290683143945502320610861668562885151617,
+        559776156650501990899426031439030258256861634312
+    )
+    sig2 = encode_rfc6979_signature(*r_s1)
+    assert sig2 == (
+        b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b'
+        b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08'
+    )
+    assert decode_rfc6979_signature(sig2) == r_s1
+
+    sig3 = encode_rfc6979_signature(0, 0)
+    assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00"
+    assert decode_rfc6979_signature(sig3) == (0, 0)
+
+    sig4 = encode_rfc6979_signature(-1, 0)
+    assert sig4 == b"0\x06\x02\x01\xFF\x02\x01\x00"
+    assert decode_rfc6979_signature(sig4) == (-1, 0)
+
+
+def test_encode_rfc6979_non_integer():
+    with pytest.raises(ValueError):
+        encode_rfc6979_signature("h", 3)
+
+    with pytest.raises(ValueError):
+        encode_rfc6979_signature("3", "2")
+
+    with pytest.raises(ValueError):
+        encode_rfc6979_signature(3, "h")
+
+    with pytest.raises(ValueError):
+        encode_rfc6979_signature(3.3, 1.2)
+
+    with pytest.raises(ValueError):
+        encode_rfc6979_signature("hello", "world")
+
+
+def test_decode_rfc6979_trailing_bytes():
+    with pytest.raises(ValueError):
+        decode_rfc6979_signature(b"0\x06\x02\x01\x01\x02\x01\x01\x00\x00\x00")
+
+
+def test_decode_rfc6979_invalid_asn1():
+    with pytest.raises(ValueError):
+        # This byte sequence has an invalid ASN.1 sequence length as well as
+        # an invalid integer length for the second integer.
+        decode_rfc6979_signature(b"0\x07\x02\x01\x01\x02\x02\x01")
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 6411b7f..8c0fb80 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -12,14 +12,17 @@
 from cryptography.hazmat.backends.interfaces import DSABackend
 from cryptography.hazmat.primitives import hashes, interfaces
 from cryptography.hazmat.primitives.asymmetric import dsa
+from cryptography.hazmat.primitives.asymmetric.utils import (
+    encode_rfc6979_signature
+)
 from cryptography.utils import bit_length
 
 from .fixtures_dsa import (
     DSA_KEY_1024, DSA_KEY_2048, DSA_KEY_3072
 )
 from ...utils import (
-    der_encode_dsa_signature, load_fips_dsa_key_pair_vectors,
-    load_fips_dsa_sig_vectors, load_vectors_from_file,
+    load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors,
+    load_vectors_from_file,
 )
 
 
@@ -557,7 +560,7 @@
             ),
             y=vector['y']
         ).public_key(backend)
-        sig = der_encode_dsa_signature(vector['r'], vector['s'])
+        sig = encode_rfc6979_signature(vector['r'], vector['s'])
         verifier = public_key.verifier(sig, algorithm())
         verifier.update(vector['msg'])
         if vector['result'] == "F":
@@ -702,3 +705,67 @@
 
         with pytest.raises(TypeError):
             dsa.DSAPrivateNumbers(x=None, public_numbers=public_numbers)
+
+
+class TestDSANumberEquality(object):
+    def test_parameter_numbers_eq(self):
+        param = dsa.DSAParameterNumbers(1, 2, 3)
+        assert param == dsa.DSAParameterNumbers(1, 2, 3)
+
+    def test_parameter_numbers_ne(self):
+        param = dsa.DSAParameterNumbers(1, 2, 3)
+        assert param != dsa.DSAParameterNumbers(1, 2, 4)
+        assert param != dsa.DSAParameterNumbers(1, 1, 3)
+        assert param != dsa.DSAParameterNumbers(2, 2, 3)
+        assert param != object()
+
+    def test_public_numbers_eq(self):
+        pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3))
+        assert pub == dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3))
+
+    def test_public_numbers_ne(self):
+        pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3))
+        assert pub != dsa.DSAPublicNumbers(2, dsa.DSAParameterNumbers(1, 2, 3))
+        assert pub != dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(2, 2, 3))
+        assert pub != dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 3, 3))
+        assert pub != dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 4))
+        assert pub != object()
+
+    def test_private_numbers_eq(self):
+        pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3))
+        priv = dsa.DSAPrivateNumbers(1, pub)
+        assert priv == dsa.DSAPrivateNumbers(
+            1, dsa.DSAPublicNumbers(
+                1, dsa.DSAParameterNumbers(1, 2, 3)
+            )
+        )
+
+    def test_private_numbers_ne(self):
+        pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3))
+        priv = dsa.DSAPrivateNumbers(1, pub)
+        assert priv != dsa.DSAPrivateNumbers(
+            2, dsa.DSAPublicNumbers(
+                1, dsa.DSAParameterNumbers(1, 2, 3)
+            )
+        )
+        assert priv != dsa.DSAPrivateNumbers(
+            1, dsa.DSAPublicNumbers(
+                2, dsa.DSAParameterNumbers(1, 2, 3)
+            )
+        )
+        assert priv != dsa.DSAPrivateNumbers(
+            1, dsa.DSAPublicNumbers(
+                1, dsa.DSAParameterNumbers(2, 2, 3)
+            )
+        )
+        assert priv != dsa.DSAPrivateNumbers(
+            1, dsa.DSAPublicNumbers(
+                1, dsa.DSAParameterNumbers(1, 3, 3)
+            )
+        )
+        assert priv != dsa.DSAPrivateNumbers(
+            1, dsa.DSAPublicNumbers(
+                1, dsa.DSAParameterNumbers(1, 2, 4)
+            )
+        )
+        assert priv != object()
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 3080a6c..84c447c 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -13,11 +13,13 @@
 from cryptography.hazmat.backends.interfaces import EllipticCurveBackend
 from cryptography.hazmat.primitives import hashes, interfaces
 from cryptography.hazmat.primitives.asymmetric import ec
+from cryptography.hazmat.primitives.asymmetric.utils import (
+    encode_rfc6979_signature
+)
 
 from ...utils import (
-    der_encode_dsa_signature, load_fips_ecdsa_key_pair_vectors,
-    load_fips_ecdsa_signing_vectors, load_vectors_from_file,
-    raises_unsupported_algorithm
+    load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors,
+    load_vectors_from_file, raises_unsupported_algorithm
 )
 
 _HASH_TYPES = {
@@ -305,10 +307,7 @@
             curve_type()
         ).public_key(backend)
 
-        signature = der_encode_dsa_signature(
-            vector['r'],
-            vector['s']
-        )
+        signature = encode_rfc6979_signature(vector['r'], vector['s'])
 
         verifier = key.verifier(
             signature,
@@ -337,10 +336,7 @@
             curve_type()
         ).public_key(backend)
 
-        signature = der_encode_dsa_signature(
-            vector['r'],
-            vector['s']
-        )
+        signature = encode_rfc6979_signature(vector['r'], vector['s'])
 
         verifier = key.verifier(
             signature,
@@ -364,3 +360,40 @@
         numbers = ec.EllipticCurvePrivateNumbers(1, pub_numbers)
         assert numbers.private_key(b) == b"private_key"
         assert pub_numbers.public_key(b) == b"public_key"
+
+
+class TestECNumbersEquality(object):
+    def test_public_numbers_eq(self):
+        pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+        assert pub == ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+
+    def test_public_numbers_ne(self):
+        pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+        assert pub != ec.EllipticCurvePublicNumbers(1, 2, ec.SECP384R1())
+        assert pub != ec.EllipticCurvePublicNumbers(1, 3, ec.SECP192R1())
+        assert pub != ec.EllipticCurvePublicNumbers(2, 2, ec.SECP192R1())
+        assert pub != object()
+
+    def test_private_numbers_eq(self):
+        pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+        priv = ec.EllipticCurvePrivateNumbers(1, pub)
+        assert priv == ec.EllipticCurvePrivateNumbers(
+            1, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+        )
+
+    def test_private_numbers_ne(self):
+        pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+        priv = ec.EllipticCurvePrivateNumbers(1, pub)
+        assert priv != ec.EllipticCurvePrivateNumbers(
+            2, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1())
+        )
+        assert priv != ec.EllipticCurvePrivateNumbers(
+            1, ec.EllipticCurvePublicNumbers(2, 2, ec.SECP192R1())
+        )
+        assert priv != ec.EllipticCurvePrivateNumbers(
+            1, ec.EllipticCurvePublicNumbers(1, 3, ec.SECP192R1())
+        )
+        assert priv != ec.EllipticCurvePrivateNumbers(
+            1, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP521R1())
+        )
+        assert priv != object()
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index 581976a..095ed03 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -18,7 +18,9 @@
 from cryptography.hazmat.backends.interfaces import RSABackend
 from cryptography.hazmat.primitives import hashes, interfaces
 from cryptography.hazmat.primitives.asymmetric import padding, rsa
-from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
+from cryptography.hazmat.primitives.asymmetric.rsa import (
+    RSAPrivateNumbers, RSAPublicNumbers
+)
 
 from .fixtures_rsa import (
     RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027, RSA_KEY_1028,
@@ -1647,3 +1649,52 @@
     def test_public_number_repr(self):
         num = RSAPublicNumbers(1, 1)
         assert repr(num) == "<RSAPublicNumbers(e=1, n=1)>"
+
+
+class TestRSANumbersEquality(object):
+    def test_public_numbers_eq(self):
+        num = RSAPublicNumbers(1, 2)
+        num2 = RSAPublicNumbers(1, 2)
+        assert num == num2
+
+    def test_public_numbers_ne(self):
+        num = RSAPublicNumbers(1, 2)
+        assert num != RSAPublicNumbers(2, 2)
+        assert num != RSAPublicNumbers(1, 3)
+        assert num != object()
+
+    def test_private_numbers_eq(self):
+        pub = RSAPublicNumbers(1, 2)
+        num = RSAPrivateNumbers(1, 2, 3, 4, 5, 6, pub)
+        pub2 = RSAPublicNumbers(1, 2)
+        num2 = RSAPrivateNumbers(1, 2, 3, 4, 5, 6, pub2)
+        assert num == num2
+
+    def test_private_numbers_ne(self):
+        pub = RSAPublicNumbers(1, 2)
+        num = RSAPrivateNumbers(1, 2, 3, 4, 5, 6, pub)
+        assert num != RSAPrivateNumbers(
+            1, 2, 3, 4, 5, 7, RSAPublicNumbers(1, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            1, 2, 3, 4, 4, 6, RSAPublicNumbers(1, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            1, 2, 3, 5, 5, 6, RSAPublicNumbers(1, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            1, 2, 4, 4, 5, 6, RSAPublicNumbers(1, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            1, 3, 3, 4, 5, 6, RSAPublicNumbers(1, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            2, 2, 3, 4, 5, 6, RSAPublicNumbers(1, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            1, 2, 3, 4, 5, 6, RSAPublicNumbers(2, 2)
+        )
+        assert num != RSAPrivateNumbers(
+            1, 2, 3, 4, 5, 6, RSAPublicNumbers(1, 3)
+        )
+        assert num != object()
diff --git a/tests/test_fernet.py b/tests/test_fernet.py
index 455d985..5b7a9f9 100644
--- a/tests/test_fernet.py
+++ b/tests/test_fernet.py
@@ -7,6 +7,7 @@
 import base64
 import calendar
 import json
+import os
 import time
 
 import iso8601
@@ -24,7 +25,9 @@
 
 
 def json_parametrize(keys, filename):
-    vector_file = cryptography_vectors.open_vector_file('fernet', filename)
+    vector_file = cryptography_vectors.open_vector_file(
+        os.path.join('fernet', filename), "r"
+    )
     with vector_file:
         data = json.load(vector_file)
         return pytest.mark.parametrize(keys, [
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 637c42b..bc5f2e1 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -18,7 +18,7 @@
 import cryptography_vectors
 
 from .utils import (
-    check_backend_support, der_encode_dsa_signature, load_cryptrec_vectors,
+    check_backend_support, load_cryptrec_vectors,
     load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors,
     load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors,
     load_hash_vectors, load_kasvs_dh_vectors, load_nist_vectors,
@@ -110,26 +110,6 @@
         check_backend_support(item)
 
 
-def test_der_encode_dsa_signature_values():
-    sig = der_encode_dsa_signature(1, 1)
-    assert sig == b"0\x06\x02\x01\x01\x02\x01\x01"
-
-    sig2 = der_encode_dsa_signature(
-        1037234182290683143945502320610861668562885151617,
-        559776156650501990899426031439030258256861634312
-    )
-    assert sig2 == (
-        b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b'
-        b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08'
-    )
-
-    sig3 = der_encode_dsa_signature(0, 0)
-    assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00"
-
-    sig4 = der_encode_dsa_signature(-1, 0)
-    assert sig4 == b"0\x06\x02\x01\xFF\x02\x01\x00"
-
-
 def test_load_nist_vectors():
     vector_data = textwrap.dedent("""
     # CAVS 11.1
diff --git a/tests/utils.py b/tests/utils.py
index ad38000..37efc58 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -9,9 +9,6 @@
 import re
 from contextlib import contextmanager
 
-from pyasn1.codec.der import encoder
-from pyasn1.type import namedtype, univ
-
 import pytest
 
 import six
@@ -73,22 +70,8 @@
     assert exc_info.value._reason is reason
 
 
-class _DSSSigValue(univ.Sequence):
-    componentType = namedtype.NamedTypes(
-        namedtype.NamedType('r', univ.Integer()),
-        namedtype.NamedType('s', univ.Integer())
-    )
-
-
-def der_encode_dsa_signature(r, s):
-    sig = _DSSSigValue()
-    sig.setComponentByName('r', r)
-    sig.setComponentByName('s', s)
-    return encoder.encode(sig)
-
-
-def load_vectors_from_file(filename, loader):
-    with cryptography_vectors.open_vector_file(filename) as vector_file:
+def load_vectors_from_file(filename, loader, mode="r"):
+    with cryptography_vectors.open_vector_file(filename, mode) as vector_file:
         return loader(vector_file)
 
 
diff --git a/tox.ini b/tox.ini
index 4d4ac20..85a095b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,7 +7,6 @@
     coverage
     iso8601
     pretend
-    pyasn1
     pytest
     ./vectors
 commands =
@@ -63,6 +62,13 @@
 commands =
     flake8 .
 
+[testenv:randomorder]
+deps =
+    {[testenv]deps}
+    pytest-random
+commands =
+    py.test --capture=no --strict --random {posargs}
+
 [flake8]
 exclude = .tox,*.egg
 select = E,W,F,N,I
diff --git a/vectors/cryptography_vectors/__init__.py b/vectors/cryptography_vectors/__init__.py
index 34cf442..abcfe14 100644
--- a/vectors/cryptography_vectors/__init__.py
+++ b/vectors/cryptography_vectors/__init__.py
@@ -18,6 +18,6 @@
 ]
 
 
-def open_vector_file(*args):
+def open_vector_file(filename, mode):
     base = os.path.dirname(__file__)
-    return open(os.path.join(base, *args), "r")
+    return open(os.path.join(base, filename), mode)