Merge pull request #1916 from reaperhulk/cdp-bindings

add bindings for CRLDistributionPoints
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index c91b7c7..5947b05 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -12,6 +12,9 @@
   actually dropping support, however we strongly encourage all users to upgrade
   their Python, as Python 2.6 no longer receives support from the Python core
   team.
+* Add support for the
+  :class:`~cryptography.hazmat.primitives.asymmetric.ec.SECP256K1` elliptic
+  curve.
 * Fixed compilation when using an OpenSSL which was compiled with the
   ``no-comp`` (``OPENSSL_NO_COMP``) option.
 * Support :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`
diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst
index 6f4afe7..71f6e6f 100644
--- a/docs/hazmat/primitives/asymmetric/ec.rst
+++ b/docs/hazmat/primitives/asymmetric/ec.rst
@@ -251,6 +251,14 @@
 
     SECG curve ``secp192r1``. Also called NIST P-192.
 
+
+.. class:: SECP256K1
+
+    .. versionadded:: 0.9
+
+    SECG curve ``secp256k1``.
+
+
 Key Interfaces
 ~~~~~~~~~~~~~~
 
diff --git a/src/cryptography/hazmat/bindings/openssl/ec.py b/src/cryptography/hazmat/bindings/openssl/ec.py
index 84a596e..c5052d3 100644
--- a/src/cryptography/hazmat/bindings/openssl/ec.py
+++ b/src/cryptography/hazmat/bindings/openssl/ec.py
@@ -17,6 +17,7 @@
 static const int Cryptography_HAS_EC_1_0_1;
 static const int Cryptography_HAS_EC_NISTP_64_GCC_128;
 static const int Cryptography_HAS_EC2M;
+static const int Cryptography_HAS_EC_1_0_2;
 
 static const int OPENSSL_EC_NAMED_CURVE;
 
@@ -188,6 +189,8 @@
 const EC_METHOD *EC_GF2m_simple_method();
 
 int EC_METHOD_get_field_type(const EC_METHOD *);
+
+const char *EC_curve_nid2nist(int);
 """
 
 CUSTOMIZATIONS = """
@@ -385,6 +388,14 @@
 #else
 static const long Cryptography_HAS_EC2M = 1;
 #endif
+
+#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000200f || \
+    defined(LIBRESSL_VERSION_NUMBER)
+static const long Cryptography_HAS_EC_1_0_2 = 0;
+const char *(*EC_curve_nid2nist)(int) = NULL;
+#else
+static const long Cryptography_HAS_EC_1_0_2 = 1;
+#endif
 """
 
 CONDITIONAL_NAMES = {
@@ -478,4 +489,8 @@
         "EC_GROUP_get_curve_GF2m",
         "EC_GROUP_new_curve_GF2m",
     ],
+
+    "Cryptography_HAS_EC_1_0_2": [
+        "EC_curve_nid2nist",
+    ],
 }
diff --git a/src/cryptography/hazmat/bindings/openssl/evp.py b/src/cryptography/hazmat/bindings/openssl/evp.py
index 780ce90..93aa83d 100644
--- a/src/cryptography/hazmat/bindings/openssl/evp.py
+++ b/src/cryptography/hazmat/bindings/openssl/evp.py
@@ -28,6 +28,7 @@
 typedef ... EVP_PKEY_CTX;
 static const int EVP_PKEY_RSA;
 static const int EVP_PKEY_DSA;
+static const int EVP_PKEY_DH;
 static const int EVP_PKEY_EC;
 static const int EVP_MAX_MD_SIZE;
 static const int EVP_CTRL_GCM_SET_IVLEN;
@@ -154,6 +155,7 @@
                     const unsigned char *, size_t);
 int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *);
 int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *);
+int EVP_PKEY_id(const EVP_PKEY *);
 
 /* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5
    we should move these back to FUNCTIONS. */
@@ -221,6 +223,7 @@
                                      const unsigned char *, size_t) = NULL;
 int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
                                      const unsigned char *, size_t) = NULL;
+int (*EVP_PKEY_id)(const EVP_PKEY *) = NULL;
 #endif
 #ifdef OPENSSL_NO_EC
 int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL;
@@ -252,6 +255,7 @@
         "Cryptography_EVP_PKEY_decrypt",
         "EVP_PKEY_decrypt_init",
         "EVP_PKEY_CTX_set_signature_md",
+        "EVP_PKEY_id",
     ],
     "Cryptography_HAS_EC": [
         "EVP_PKEY_assign_EC_KEY",
diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py
index fd719c5..c12624b 100644
--- a/src/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/src/cryptography/hazmat/bindings/openssl/ssl.py
@@ -23,6 +23,7 @@
 static const long Cryptography_HAS_TLSEXT_STATUS_REQ_CB;
 static const long Cryptography_HAS_STATUS_REQ_OCSP_RESP;
 static const long Cryptography_HAS_TLSEXT_STATUS_REQ_TYPE;
+static const long Cryptography_HAS_GET_SERVER_TMP_KEY;
 
 /* Internally invented symbol to tell us if SNI is supported */
 static const long Cryptography_HAS_TLSEXT_HOSTNAME;
@@ -383,6 +384,8 @@
                                          void *),
                                 void *);
 void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *);
+
+long SSL_get_server_tmp_key(SSL *, EVP_PKEY **);
 """
 
 CUSTOMIZATIONS = """
@@ -584,6 +587,7 @@
 #else
 static const long Cryptography_HAS_ALPN = 1;
 #endif
+
 #if defined(OPENSSL_NO_COMP) || defined(LIBRESSL_VERSION_NUMBER)
 static const long Cryptography_HAS_COMPRESSION = 0;
 typedef void COMP_METHOD;
@@ -591,6 +595,13 @@
 static const long Cryptography_HAS_COMPRESSION = 1;
 #endif
 
+#if defined(SSL_CTRL_GET_SERVER_TMP_KEY)
+static const long Cryptography_HAS_GET_SERVER_TMP_KEY = 1;
+#else
+static const long Cryptography_HAS_GET_SERVER_TMP_KEY = 0;
+long (*SSL_get_server_tmp_key)(SSL *, EVP_PKEY **) = NULL;
+#endif
+
 """
 
 CONDITIONAL_NAMES = {
@@ -692,5 +703,9 @@
         "SSL_get_current_compression",
         "SSL_get_current_expansion",
         "SSL_COMP_get_name",
-    ]
+    ],
+
+    "Cryptography_HAS_GET_SERVER_TMP_KEY": [
+        "SSL_get_server_tmp_key",
+    ],
 }
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py
index fa6a16b..3125016 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509.py
@@ -64,6 +64,7 @@
 
 typedef struct {
     X509_CRL_INFO *crl;
+    X509_ALGOR *sig_alg;
     ...;
 } X509_CRL;
 
@@ -183,6 +184,7 @@
 int X509_CRL_print(BIO *, X509_CRL *);
 int X509_CRL_set_issuer_name(X509_CRL *, X509_NAME *);
 int X509_CRL_sign(X509_CRL *, EVP_PKEY *, const EVP_MD *);
+int X509_CRL_verify(X509_CRL *, EVP_PKEY *);
 int X509_CRL_get_ext_count(X509_CRL *);
 X509_EXTENSION *X509_CRL_get_ext(X509_CRL *, int);
 int X509_CRL_add_ext(X509_CRL *, X509_EXTENSION *, int);
@@ -285,6 +287,7 @@
 ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *);
 ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *);
 X509_NAME *X509_CRL_get_issuer(X509_CRL *);
+Cryptography_STACK_OF_X509_REVOKED *X509_CRL_get_REVOKED(X509_CRL *);
 
 /* These aren't macros these arguments are all const X on openssl > 1.0.x */
 int X509_CRL_set_lastUpdate(X509_CRL *, ASN1_TIME *);
diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py
index bf1705d..96809c1 100644
--- a/src/cryptography/hazmat/primitives/asymmetric/ec.py
+++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py
@@ -202,6 +202,12 @@
 
 
 @utils.register_interface(EllipticCurve)
+class SECP256K1(object):
+    name = "secp256k1"
+    key_size = 256
+
+
+@utils.register_interface(EllipticCurve)
 class SECP224R1(object):
     name = "secp224r1"
     key_size = 224
@@ -222,6 +228,7 @@
     "secp256r1": SECP256R1,
     "secp384r1": SECP384R1,
     "secp521r1": SECP521R1,
+    "secp256k1": SECP256K1,
 
     "sect163k1": SECT163K1,
     "sect233k1": SECT233K1,
diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py
index 3273fe6..82b5b3a 100644
--- a/tests/hazmat/primitives/test_ec.py
+++ b/tests/hazmat/primitives/test_ec.py
@@ -305,10 +305,17 @@
 
     @pytest.mark.parametrize(
         "vector",
-        load_vectors_from_file(
-            os.path.join(
-                "asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt"),
-            load_fips_ecdsa_signing_vectors
+        itertools.chain(
+            load_vectors_from_file(
+                os.path.join(
+                    "asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt"),
+                load_fips_ecdsa_signing_vectors
+            ),
+            load_vectors_from_file(
+                os.path.join(
+                    "asymmetric", "ECDSA", "SECP256K1", "SigGen.txt"),
+                load_fips_ecdsa_signing_vectors
+            ),
         )
     )
     def test_signatures(self, backend, vector):