Merge pull request #605 from reaperhulk/add-crt-coefficients

Add RSA CRT Coefficients
diff --git a/cryptography/hazmat/bindings/openssl/evp.py b/cryptography/hazmat/bindings/openssl/evp.py
index c7cc154..0277649 100644
--- a/cryptography/hazmat/bindings/openssl/evp.py
+++ b/cryptography/hazmat/bindings/openssl/evp.py
@@ -32,6 +32,7 @@
     int type;
     ...;
 } EVP_PKEY;
+typedef ... EVP_PKEY_CTX;
 static const int EVP_PKEY_RSA;
 static const int EVP_PKEY_DSA;
 static const int EVP_MAX_MD_SIZE;
@@ -41,6 +42,7 @@
 
 static const int Cryptography_HAS_GCM;
 static const int Cryptography_HAS_PBKDF2_HMAC;
+static const int Cryptography_HAS_PKEY_CTX;
 """
 
 FUNCTIONS = """
@@ -99,6 +101,9 @@
 
 int PKCS5_PBKDF2_HMAC_SHA1(const char *, int, const unsigned char *, int, int,
                            int, unsigned char *);
+
+int EVP_PKEY_set1_RSA(EVP_PKEY *, struct rsa_st *);
+int EVP_PKEY_set1_DSA(EVP_PKEY *, struct dsa_st *);
 """
 
 MACROS = """
@@ -110,6 +115,20 @@
 
 int PKCS5_PBKDF2_HMAC(const char *, int, const unsigned char *, int, int,
                       const EVP_MD *, int, unsigned char *);
+
+int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *, const EVP_MD *);
+
+// not macros but must be in this section since they're not available in 0.9.8
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *, ENGINE *);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int, ENGINE *);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *);
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *);
+int EVP_PKEY_sign(EVP_PKEY_CTX *, unsigned char *, size_t *,
+                  const unsigned char *, size_t);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *);
+int EVP_PKEY_verify(EVP_PKEY_CTX *, const unsigned char *, size_t,
+                    const unsigned char *, size_t);
 """
 
 CUSTOMIZATIONS = """
@@ -123,10 +142,24 @@
 #endif
 #if OPENSSL_VERSION_NUMBER >= 0x10000000
 const long Cryptography_HAS_PBKDF2_HMAC = 1;
+const long Cryptography_HAS_PKEY_CTX = 1;
 #else
 const long Cryptography_HAS_PBKDF2_HMAC = 0;
 int (*PKCS5_PBKDF2_HMAC)(const char *, int, const unsigned char *, int, int,
                          const EVP_MD *, int, unsigned char *) = NULL;
+const long Cryptography_HAS_PKEY_CTX = 0;
+typedef void EVP_PKEY_CTX;
+int (*EVP_PKEY_CTX_set_signature_md)(EVP_PKEY_CTX *, const EVP_MD *) = NULL;
+int (*EVP_PKEY_sign_init)(EVP_PKEY_CTX *) = NULL;
+int (*EVP_PKEY_sign)(EVP_PKEY_CTX *, unsigned char *, size_t *,
+                     const unsigned char *, size_t) = NULL;
+int (*EVP_PKEY_verify_init)(EVP_PKEY_CTX *) = NULL;
+int (*EVP_PKEY_verify)(EVP_PKEY_CTX *, const unsigned char *, size_t,
+                       const unsigned char *, size_t) = NULL;
+EVP_PKEY_CTX *(*EVP_PKEY_CTX_new)(EVP_PKEY *, ENGINE *) = NULL;
+EVP_PKEY_CTX *(*EVP_PKEY_CTX_new_id)(int, ENGINE *) = NULL;
+EVP_PKEY_CTX *(*EVP_PKEY_CTX_dup)(EVP_PKEY_CTX *) = NULL;
+void (*EVP_PKEY_CTX_free)(EVP_PKEY_CTX *) = NULL;
 #endif
 """
 
@@ -138,5 +171,16 @@
     ],
     "Cryptography_HAS_PBKDF2_HMAC": [
         "PKCS5_PBKDF2_HMAC"
+    ],
+    "Cryptography_HAS_PKEY_CTX": [
+        "EVP_PKEY_CTX_new",
+        "EVP_PKEY_CTX_new_id",
+        "EVP_PKEY_CTX_dup",
+        "EVP_PKEY_CTX_free",
+        "EVP_PKEY_sign",
+        "EVP_PKEY_sign_init",
+        "EVP_PKEY_verify",
+        "EVP_PKEY_verify_init",
+        "EVP_PKEY_CTX_set_signature_md",
     ]
 }
diff --git a/cryptography/hazmat/bindings/openssl/rsa.py b/cryptography/hazmat/bindings/openssl/rsa.py
index a44ca4a..b6f7d04 100644
--- a/cryptography/hazmat/bindings/openssl/rsa.py
+++ b/cryptography/hazmat/bindings/openssl/rsa.py
@@ -43,6 +43,8 @@
 int RSA_generate_key_ex(RSA *, int, BIGNUM *, BN_GENCB *);
 int RSA_check_key(const RSA *);
 RSA *RSAPublicKey_dup(RSA *);
+int RSA_blinding_on(RSA *, BN_CTX *);
+void RSA_blinding_off(RSA *);
 int RSA_public_encrypt(int, const unsigned char *, unsigned char *,
                        RSA *, int);
 int RSA_private_encrypt(int, const unsigned char *, unsigned char *,
@@ -52,12 +54,32 @@
 int RSA_private_decrypt(int, const unsigned char *, unsigned char *,
                         RSA *, int);
 int RSA_print(BIO *, const RSA *, int);
+int RSA_verify_PKCS1_PSS(RSA *, const unsigned char *, const EVP_MD *,
+                         const unsigned char *, int);
+int RSA_padding_add_PKCS1_PSS(RSA *, unsigned char *, const unsigned char *,
+                              const EVP_MD *, int);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *, int, const unsigned char *,
+                               int, const unsigned char *, int);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *, int, const unsigned char *,
+                                 int, int, const unsigned char *, int);
 """
 
 MACROS = """
+int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *, int);
+int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *, int);
 """
 
 CUSTOMIZATIONS = """
+#if OPENSSL_VERSION_NUMBER < 0x10000000
+// see evp.py for the definition of Cryptography_HAS_PKEY_CTX
+int (*EVP_PKEY_CTX_set_rsa_padding)(EVP_PKEY_CTX *, int) = NULL;
+int (*EVP_PKEY_CTX_set_rsa_pss_saltlen)(EVP_PKEY_CTX *, int) = NULL;
+#endif
 """
 
-CONDITIONAL_NAMES = {}
+CONDITIONAL_NAMES = {
+    "Cryptography_HAS_PKEY_CTX": [
+        "EVP_PKEY_CTX_set_rsa_padding",
+        "EVP_PKEY_CTX_set_rsa_pss_saltlen",
+    ]
+}
diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py
index 6c5795b..038ea54 100644
--- a/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/cryptography/hazmat/bindings/openssl/ssl.py
@@ -117,6 +117,7 @@
 static const int SSL3_RANDOM_SIZE;
 typedef ... X509_STORE_CTX;
 static const int X509_V_OK;
+static const int X509_V_ERR_APPLICATION_VERIFICATION;
 typedef ... SSL_METHOD;
 typedef ... SSL_CTX;
 
diff --git a/docs/installation.rst b/docs/installation.rst
index f9c3574..63555ab 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -29,16 +29,20 @@
 compiler, headers for Python (if you're not using ``pypy``), and headers for
 the OpenSSL and ``libffi`` libraries available on your system.
 
-Debian and Ubuntu systems
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For Debian and Ubuntu, the following command line will ensure the required
+For Debian and Ubuntu, the following command will ensure that the required
 dependencies are installed:
 
 .. code-block:: console
 
     $ sudo apt-get install build-essential libssl-dev libffi-dev python-dev
 
+For Fedora and RHEL-derivatives, the following command will ensure that the
+required dependencies are installed:
+
+.. code-block:: console
+
+    $ sudo yum install gcc libffi-devel python-devel openssl-devel
+
 You should now be able to build and install cryptography with the usual
 
 .. code-block:: console
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index b258420..14b0b77 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1,6 +1,9 @@
 backend
 backends
+Backends
+Blowfish
 boolean
+Changelog
 ciphertext
 committer
 committers
@@ -10,7 +13,9 @@
 decrypt
 decrypted
 decrypting
+Docstrings
 fernet
+Fernet
 hazmat
 indistinguishability
 introspectability
@@ -19,13 +24,8 @@
 pickleable
 plaintext
 pseudorandom
+Schneier
 testability
 unencrypted
 unpadded
 unpadding
-Backends
-Blowfish
-Changelog
-Docstrings
-Fernet
-Schneier