Merge pull request #615 from reaperhulk/rsa-blinded-by-the-light

RSA Blinding Bindings
diff --git a/cryptography/hazmat/bindings/openssl/evp.py b/cryptography/hazmat/bindings/openssl/evp.py
index c7cc154..a883084 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 = """
@@ -110,6 +112,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 *, EVP_MD_CTX *);
+
+// 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 +139,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 *, EVP_MD_CTX *) = 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 +168,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 e2f8f0c..b6f7d04 100644
--- a/cryptography/hazmat/bindings/openssl/rsa.py
+++ b/cryptography/hazmat/bindings/openssl/rsa.py
@@ -54,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",
+    ]
+}