aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography/hazmat/bindings/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'cryptography/hazmat/bindings/openssl')
-rw-r--r--cryptography/hazmat/bindings/openssl/backend.py365
-rw-r--r--cryptography/hazmat/bindings/openssl/bignum.py3
-rw-r--r--cryptography/hazmat/bindings/openssl/engine.py10
-rw-r--r--cryptography/hazmat/bindings/openssl/err.py14
-rw-r--r--cryptography/hazmat/bindings/openssl/evp.py5
-rw-r--r--cryptography/hazmat/bindings/openssl/pem.py9
-rw-r--r--cryptography/hazmat/bindings/openssl/rsa.py27
-rw-r--r--cryptography/hazmat/bindings/openssl/ssl.py189
8 files changed, 489 insertions, 133 deletions
diff --git a/cryptography/hazmat/bindings/openssl/backend.py b/cryptography/hazmat/bindings/openssl/backend.py
index 0c3d22d5..6ab4dc26 100644
--- a/cryptography/hazmat/bindings/openssl/backend.py
+++ b/cryptography/hazmat/bindings/openssl/backend.py
@@ -18,16 +18,23 @@ import sys
import cffi
-from cryptography.exceptions import UnsupportedAlgorithm
+from cryptography import utils
+from cryptography.exceptions import UnsupportedAlgorithm, InvalidTag
+from cryptography.hazmat.bindings.interfaces import (
+ CipherBackend, HashBackend, HMACBackend
+)
from cryptography.hazmat.primitives import interfaces
from cryptography.hazmat.primitives.ciphers.algorithms import (
- AES, Blowfish, Camellia, CAST5, TripleDES,
+ AES, Blowfish, Camellia, CAST5, TripleDES, ARC4,
)
from cryptography.hazmat.primitives.ciphers.modes import (
- CBC, CTR, ECB, OFB, CFB
+ CBC, CTR, ECB, OFB, CFB, GCM,
)
+@utils.register_interface(CipherBackend)
+@utils.register_interface(HashBackend)
+@utils.register_interface(HMACBackend)
class Backend(object):
"""
OpenSSL API wrapper.
@@ -63,9 +70,8 @@ class Backend(object):
def __init__(self):
self._ensure_ffi_initialized()
- self.ciphers = Ciphers(self)
- self.hashes = Hashes(self)
- self.hmacs = HMACs(self)
+ self._cipher_registry = {}
+ self._register_default_ciphers()
@classmethod
def _ensure_ffi_initialized(cls):
@@ -123,6 +129,104 @@ class Backend(object):
"""
return self.ffi.string(self.lib.OPENSSL_VERSION_TEXT).decode("ascii")
+ def create_hmac_ctx(self, key, algorithm):
+ return _HMACContext(self, key, algorithm)
+
+ def hash_supported(self, algorithm):
+ digest = self.lib.EVP_get_digestbyname(algorithm.name.encode("ascii"))
+ return digest != self.ffi.NULL
+
+ def create_hash_ctx(self, algorithm):
+ return _HashContext(self, algorithm)
+
+ def cipher_supported(self, cipher, mode):
+ try:
+ adapter = self._cipher_registry[type(cipher), type(mode)]
+ except KeyError:
+ return False
+ evp_cipher = adapter(self, cipher, mode)
+ return self.ffi.NULL != evp_cipher
+
+ def register_cipher_adapter(self, cipher_cls, mode_cls, adapter):
+ if (cipher_cls, mode_cls) in self._cipher_registry:
+ raise ValueError("Duplicate registration for: {0} {1}".format(
+ cipher_cls, mode_cls)
+ )
+ self._cipher_registry[cipher_cls, mode_cls] = adapter
+
+ def _register_default_ciphers(self):
+ for cipher_cls, mode_cls in itertools.product(
+ [AES, Camellia],
+ [CBC, CTR, ECB, OFB, CFB],
+ ):
+ self.register_cipher_adapter(
+ cipher_cls,
+ mode_cls,
+ GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}")
+ )
+ for mode_cls in [CBC, CFB, OFB]:
+ self.register_cipher_adapter(
+ TripleDES,
+ mode_cls,
+ GetCipherByName("des-ede3-{mode.name}")
+ )
+ for mode_cls in [CBC, CFB, OFB, ECB]:
+ self.register_cipher_adapter(
+ Blowfish,
+ mode_cls,
+ GetCipherByName("bf-{mode.name}")
+ )
+ self.register_cipher_adapter(
+ CAST5,
+ ECB,
+ GetCipherByName("cast5-ecb")
+ )
+ self.register_cipher_adapter(
+ ARC4,
+ type(None),
+ GetCipherByName("rc4")
+ )
+ self.register_cipher_adapter(
+ AES,
+ GCM,
+ GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}")
+ )
+
+ def create_symmetric_encryption_ctx(self, cipher, mode):
+ return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT)
+
+ def create_symmetric_decryption_ctx(self, cipher, mode):
+ return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT)
+
+ def _handle_error(self, mode):
+ code = self.lib.ERR_get_error()
+ if not code and isinstance(mode, GCM):
+ raise InvalidTag
+ assert code != 0
+ lib = self.lib.ERR_GET_LIB(code)
+ func = self.lib.ERR_GET_FUNC(code)
+ reason = self.lib.ERR_GET_REASON(code)
+ return self._handle_error_code(lib, func, reason)
+
+ def _handle_error_code(self, lib, func, reason):
+ if lib == self.lib.ERR_LIB_EVP:
+ if func == self.lib.EVP_F_EVP_ENCRYPTFINAL_EX:
+ if reason == self.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
+ raise ValueError(
+ "The length of the provided data is not a multiple of "
+ "the block length"
+ )
+ elif func == self.lib.EVP_F_EVP_DECRYPTFINAL_EX:
+ if reason == self.lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
+ raise ValueError(
+ "The length of the provided data is not a multiple of "
+ "the block length"
+ )
+
+ raise SystemError(
+ "Unknown error code from OpenSSL, you should probably file a bug."
+ )
+
class GetCipherByName(object):
def __init__(self, fmt):
@@ -133,18 +237,24 @@ class GetCipherByName(object):
return backend.lib.EVP_get_cipherbyname(cipher_name.encode("ascii"))
-@interfaces.register(interfaces.CipherContext)
+@utils.register_interface(interfaces.CipherContext)
+@utils.register_interface(interfaces.AEADCipherContext)
+@utils.register_interface(interfaces.AEADEncryptionContext)
class _CipherContext(object):
_ENCRYPT = 1
_DECRYPT = 0
def __init__(self, backend, cipher, mode, operation):
self._backend = backend
+ self._cipher = cipher
+ self._mode = mode
+ self._operation = operation
+ self._tag = None
ctx = self._backend.lib.EVP_CIPHER_CTX_new()
ctx = self._backend.ffi.gc(ctx, self._backend.lib.EVP_CIPHER_CTX_free)
- registry = self._backend.ciphers._cipher_registry
+ registry = self._backend._cipher_registry
try:
adapter = registry[type(cipher), type(mode)]
except KeyError:
@@ -172,6 +282,26 @@ class _CipherContext(object):
ctx, len(cipher.key)
)
assert res != 0
+ if isinstance(mode, GCM):
+ res = self._backend.lib.EVP_CIPHER_CTX_ctrl(
+ ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_IVLEN,
+ len(iv_nonce), self._backend.ffi.NULL
+ )
+ assert res != 0
+ if operation == self._DECRYPT:
+ if not mode.tag:
+ raise ValueError("Authentication tag must be supplied "
+ "when decrypting")
+ res = self._backend.lib.EVP_CIPHER_CTX_ctrl(
+ ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_SET_TAG,
+ len(mode.tag), mode.tag
+ )
+ assert res != 0
+ else:
+ if mode.tag:
+ raise ValueError("Authentication tag must be None when "
+ "encrypting")
+
# pass key/iv
res = self._backend.lib.EVP_CipherInit_ex(ctx, self._backend.ffi.NULL,
self._backend.ffi.NULL,
@@ -185,9 +315,8 @@ class _CipherContext(object):
self._ctx = ctx
def update(self, data):
- block_size = self._backend.lib.EVP_CIPHER_CTX_block_size(self._ctx)
buf = self._backend.ffi.new("unsigned char[]",
- len(data) + block_size - 1)
+ len(data) + self._cipher.block_size - 1)
outlen = self._backend.ffi.new("int *")
res = self._backend.lib.EVP_CipherUpdate(self._ctx, buf, outlen, data,
len(data))
@@ -195,156 +324,132 @@ class _CipherContext(object):
return self._backend.ffi.buffer(buf)[:outlen[0]]
def finalize(self):
- block_size = self._backend.lib.EVP_CIPHER_CTX_block_size(self._ctx)
- buf = self._backend.ffi.new("unsigned char[]", block_size)
+ buf = self._backend.ffi.new("unsigned char[]", self._cipher.block_size)
outlen = self._backend.ffi.new("int *")
res = self._backend.lib.EVP_CipherFinal_ex(self._ctx, buf, outlen)
- assert res != 0
+ if res == 0:
+ self._backend._handle_error(self._mode)
+
+ if (isinstance(self._mode, GCM) and
+ self._operation == self._ENCRYPT):
+ block_byte_size = self._cipher.block_size // 8
+ tag_buf = self._backend.ffi.new("unsigned char[]", block_byte_size)
+ res = self._backend.lib.EVP_CIPHER_CTX_ctrl(
+ self._ctx, self._backend.lib.Cryptography_EVP_CTRL_GCM_GET_TAG,
+ block_byte_size, tag_buf
+ )
+ assert res != 0
+ self._tag = self._backend.ffi.buffer(tag_buf)[:]
+
res = self._backend.lib.EVP_CIPHER_CTX_cleanup(self._ctx)
assert res == 1
return self._backend.ffi.buffer(buf)[:outlen[0]]
-
-class Ciphers(object):
- def __init__(self, backend):
- super(Ciphers, self).__init__()
- self._backend = backend
- self._cipher_registry = {}
- self._register_default_ciphers()
-
- def supported(self, cipher, mode):
- try:
- adapter = self._cipher_registry[type(cipher), type(mode)]
- except KeyError:
- return False
- evp_cipher = adapter(self._backend, cipher, mode)
- return self._backend.ffi.NULL != evp_cipher
-
- def register_cipher_adapter(self, cipher_cls, mode_cls, adapter):
- if (cipher_cls, mode_cls) in self._cipher_registry:
- raise ValueError("Duplicate registration for: {0} {1}".format(
- cipher_cls, mode_cls)
- )
- self._cipher_registry[cipher_cls, mode_cls] = adapter
-
- def _register_default_ciphers(self):
- for cipher_cls, mode_cls in itertools.product(
- [AES, Camellia],
- [CBC, CTR, ECB, OFB, CFB],
- ):
- self.register_cipher_adapter(
- cipher_cls,
- mode_cls,
- GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}")
- )
- for mode_cls in [CBC, CFB, OFB]:
- self.register_cipher_adapter(
- TripleDES,
- mode_cls,
- GetCipherByName("des-ede3-{mode.name}")
- )
- for mode_cls in [CBC, CFB, OFB, ECB]:
- self.register_cipher_adapter(
- Blowfish,
- mode_cls,
- GetCipherByName("bf-{mode.name}")
- )
- self.register_cipher_adapter(
- CAST5,
- ECB,
- GetCipherByName("cast5-ecb")
+ def authenticate_additional_data(self, data):
+ outlen = self._backend.ffi.new("int *")
+ res = self._backend.lib.EVP_CipherUpdate(
+ self._ctx, self._backend.ffi.NULL, outlen, data, len(data)
)
+ assert res != 0
- def create_encrypt_ctx(self, cipher, mode):
- return _CipherContext(self._backend, cipher, mode,
- _CipherContext._ENCRYPT)
+ @property
+ def tag(self):
+ return self._tag
- def create_decrypt_ctx(self, cipher, mode):
- return _CipherContext(self._backend, cipher, mode,
- _CipherContext._DECRYPT)
+@utils.register_interface(interfaces.HashContext)
+class _HashContext(object):
+ def __init__(self, backend, algorithm, ctx=None):
+ self.algorithm = algorithm
-class Hashes(object):
- def __init__(self, backend):
- super(Hashes, self).__init__()
self._backend = backend
- def supported(self, hash_cls):
- return (self._backend.ffi.NULL !=
- self._backend.lib.EVP_get_digestbyname(
- hash_cls.name.encode("ascii")))
-
- def create_ctx(self, hashobject):
- ctx = self._backend.lib.EVP_MD_CTX_create()
- ctx = self._backend.ffi.gc(ctx, self._backend.lib.EVP_MD_CTX_destroy)
- evp_md = self._backend.lib.EVP_get_digestbyname(
- hashobject.name.encode("ascii"))
- assert evp_md != self._backend.ffi.NULL
- res = self._backend.lib.EVP_DigestInit_ex(ctx, evp_md,
- self._backend.ffi.NULL)
+ if ctx is None:
+ ctx = self._backend.lib.EVP_MD_CTX_create()
+ ctx = self._backend.ffi.gc(ctx,
+ self._backend.lib.EVP_MD_CTX_destroy)
+ evp_md = self._backend.lib.EVP_get_digestbyname(
+ algorithm.name.encode("ascii"))
+ assert evp_md != self._backend.ffi.NULL
+ res = self._backend.lib.EVP_DigestInit_ex(ctx, evp_md,
+ self._backend.ffi.NULL)
+ assert res != 0
+
+ self._ctx = ctx
+
+ def copy(self):
+ copied_ctx = self._backend.lib.EVP_MD_CTX_create()
+ copied_ctx = self._backend.ffi.gc(copied_ctx,
+ self._backend.lib.EVP_MD_CTX_destroy)
+ res = self._backend.lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx)
assert res != 0
- return ctx
+ return _HashContext(self._backend, self.algorithm, ctx=copied_ctx)
- def update_ctx(self, ctx, data):
- res = self._backend.lib.EVP_DigestUpdate(ctx, data, len(data))
+ def update(self, data):
+ res = self._backend.lib.EVP_DigestUpdate(self._ctx, data, len(data))
assert res != 0
- def finalize_ctx(self, ctx, digest_size):
- buf = self._backend.ffi.new("unsigned char[]", digest_size)
- res = self._backend.lib.EVP_DigestFinal_ex(ctx, buf,
+ def finalize(self):
+ buf = self._backend.ffi.new("unsigned char[]",
+ self.algorithm.digest_size)
+ res = self._backend.lib.EVP_DigestFinal_ex(self._ctx, buf,
self._backend.ffi.NULL)
assert res != 0
- res = self._backend.lib.EVP_MD_CTX_cleanup(ctx)
+ res = self._backend.lib.EVP_MD_CTX_cleanup(self._ctx)
assert res == 1
- return self._backend.ffi.buffer(buf)[:digest_size]
-
- def copy_ctx(self, ctx):
- copied_ctx = self._backend.lib.EVP_MD_CTX_create()
- copied_ctx = self._backend.ffi.gc(copied_ctx,
- self._backend.lib.EVP_MD_CTX_destroy)
- res = self._backend.lib.EVP_MD_CTX_copy_ex(copied_ctx, ctx)
- assert res != 0
- return copied_ctx
+ return self._backend.ffi.buffer(buf)[:]
-class HMACs(object):
- def __init__(self, backend):
- super(HMACs, self).__init__()
+@utils.register_interface(interfaces.HashContext)
+class _HMACContext(object):
+ def __init__(self, backend, key, algorithm, ctx=None):
+ self.algorithm = algorithm
self._backend = backend
- def create_ctx(self, key, hash_cls):
- ctx = self._backend.ffi.new("HMAC_CTX *")
- self._backend.lib.HMAC_CTX_init(ctx)
- ctx = self._backend.ffi.gc(ctx, self._backend.lib.HMAC_CTX_cleanup)
- evp_md = self._backend.lib.EVP_get_digestbyname(
- hash_cls.name.encode('ascii'))
- assert evp_md != self._backend.ffi.NULL
- res = self._backend.lib.Cryptography_HMAC_Init_ex(
- ctx, key, len(key), evp_md, self._backend.ffi.NULL
- )
- assert res != 0
- return ctx
+ if ctx is None:
+ ctx = self._backend.ffi.new("HMAC_CTX *")
+ self._backend.lib.HMAC_CTX_init(ctx)
+ ctx = self._backend.ffi.gc(ctx, self._backend.lib.HMAC_CTX_cleanup)
+ evp_md = self._backend.lib.EVP_get_digestbyname(
+ algorithm.name.encode('ascii'))
+ assert evp_md != self._backend.ffi.NULL
+ res = self._backend.lib.Cryptography_HMAC_Init_ex(
+ ctx, key, len(key), evp_md, self._backend.ffi.NULL
+ )
+ assert res != 0
+
+ self._ctx = ctx
+ self._key = key
- def update_ctx(self, ctx, data):
- res = self._backend.lib.Cryptography_HMAC_Update(ctx, data, len(data))
+ def copy(self):
+ copied_ctx = self._backend.ffi.new("HMAC_CTX *")
+ self._backend.lib.HMAC_CTX_init(copied_ctx)
+ copied_ctx = self._backend.ffi.gc(
+ copied_ctx, self._backend.lib.HMAC_CTX_cleanup
+ )
+ res = self._backend.lib.Cryptography_HMAC_CTX_copy(
+ copied_ctx, self._ctx
+ )
assert res != 0
+ return _HMACContext(
+ self._backend, self._key, self.algorithm, ctx=copied_ctx
+ )
- def finalize_ctx(self, ctx, digest_size):
- buf = self._backend.ffi.new("unsigned char[]", digest_size)
- buflen = self._backend.ffi.new("unsigned int *", digest_size)
- res = self._backend.lib.Cryptography_HMAC_Final(ctx, buf, buflen)
+ def update(self, data):
+ res = self._backend.lib.Cryptography_HMAC_Update(
+ self._ctx, data, len(data)
+ )
assert res != 0
- self._backend.lib.HMAC_CTX_cleanup(ctx)
- return self._backend.ffi.buffer(buf)[:digest_size]
- def copy_ctx(self, ctx):
- copied_ctx = self._backend.ffi.new("HMAC_CTX *")
- self._backend.lib.HMAC_CTX_init(copied_ctx)
- copied_ctx = self._backend.ffi.gc(copied_ctx,
- self._backend.lib.HMAC_CTX_cleanup)
- res = self._backend.lib.Cryptography_HMAC_CTX_copy(copied_ctx, ctx)
+ def finalize(self):
+ buf = self._backend.ffi.new("unsigned char[]",
+ self.algorithm.digest_size)
+ buflen = self._backend.ffi.new("unsigned int *",
+ self.algorithm.digest_size)
+ res = self._backend.lib.Cryptography_HMAC_Final(self._ctx, buf, buflen)
assert res != 0
- return copied_ctx
+ self._backend.lib.HMAC_CTX_cleanup(self._ctx)
+ return self._backend.ffi.buffer(buf)[:]
backend = Backend()
diff --git a/cryptography/hazmat/bindings/openssl/bignum.py b/cryptography/hazmat/bindings/openssl/bignum.py
index fcfadff1..1b0fe5ab 100644
--- a/cryptography/hazmat/bindings/openssl/bignum.py
+++ b/cryptography/hazmat/bindings/openssl/bignum.py
@@ -28,6 +28,9 @@ int BN_set_word(BIGNUM *, BN_ULONG);
char *BN_bn2hex(const BIGNUM *);
int BN_hex2bn(BIGNUM **, const char *);
+int BN_dec2bn(BIGNUM **, const char *);
+
+int BN_num_bits(const BIGNUM *);
"""
MACROS = """
diff --git a/cryptography/hazmat/bindings/openssl/engine.py b/cryptography/hazmat/bindings/openssl/engine.py
index b76befce..1f377665 100644
--- a/cryptography/hazmat/bindings/openssl/engine.py
+++ b/cryptography/hazmat/bindings/openssl/engine.py
@@ -36,6 +36,16 @@ void ENGINE_load_builtin_engines();
int ENGINE_ctrl_cmd_string(ENGINE *, const char *, const char *, int);
int ENGINE_set_default(ENGINE *, unsigned int);
int ENGINE_register_complete(ENGINE *);
+
+int ENGINE_set_default_RSA(ENGINE *);
+int ENGINE_set_default_string(ENGINE *, const char *);
+int ENGINE_set_default_DSA(ENGINE *);
+int ENGINE_set_default_ECDH(ENGINE *);
+int ENGINE_set_default_ECDSA(ENGINE *);
+int ENGINE_set_default_DH(ENGINE *);
+int ENGINE_set_default_RAND(ENGINE *);
+int ENGINE_set_default_ciphers(ENGINE *);
+int ENGINE_set_default_digests(ENGINE *);
"""
MACROS = """
diff --git a/cryptography/hazmat/bindings/openssl/err.py b/cryptography/hazmat/bindings/openssl/err.py
index 6a36dee0..f31c2405 100644
--- a/cryptography/hazmat/bindings/openssl/err.py
+++ b/cryptography/hazmat/bindings/openssl/err.py
@@ -21,6 +21,20 @@ struct ERR_string_data_st {
const char *string;
};
typedef struct ERR_string_data_st ERR_STRING_DATA;
+
+static const int ERR_LIB_EVP;
+static const int ERR_LIB_PEM;
+
+static const int EVP_F_EVP_ENCRYPTFINAL_EX;
+static const int EVP_F_EVP_DECRYPTFINAL_EX;
+
+static const int EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH;
+
+static const int PEM_F_PEM_READ_BIO_PRIVATEKEY;
+static const int PEM_F_D2I_PKCS8PRIVATEKEY_BIO;
+
+static const int PEM_R_BAD_PASSWORD_READ;
+static const int ASN1_R_BAD_PASSWORD_READ;
"""
FUNCTIONS = """
diff --git a/cryptography/hazmat/bindings/openssl/evp.py b/cryptography/hazmat/bindings/openssl/evp.py
index da54f89d..8cb44610 100644
--- a/cryptography/hazmat/bindings/openssl/evp.py
+++ b/cryptography/hazmat/bindings/openssl/evp.py
@@ -16,10 +16,13 @@ INCLUDES = """
"""
TYPES = """
+typedef ... EVP_CIPHER;
typedef struct {
+ const EVP_CIPHER *cipher;
+ ENGINE *engine;
+ int encrypt;
...;
} EVP_CIPHER_CTX;
-typedef ... EVP_CIPHER;
typedef ... EVP_MD;
typedef struct env_md_ctx_st EVP_MD_CTX;
diff --git a/cryptography/hazmat/bindings/openssl/pem.py b/cryptography/hazmat/bindings/openssl/pem.py
index 00f0dc36..cef7839f 100644
--- a/cryptography/hazmat/bindings/openssl/pem.py
+++ b/cryptography/hazmat/bindings/openssl/pem.py
@@ -29,6 +29,15 @@ int PEM_write_bio_PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *, EVP_PKEY **, pem_password_cb *,
void *);
+int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+ char *, int, pem_password_cb *, void *);
+
+int i2d_PKCS8PrivateKey_bio(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+ char *, int, pem_password_cb *, void *);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *, EVP_PKEY **, pem_password_cb *,
+ void *);
+
int PEM_write_bio_X509_REQ(BIO *, X509_REQ *);
X509_REQ *PEM_read_bio_X509_REQ(BIO *, X509_REQ **, pem_password_cb *, void *);
diff --git a/cryptography/hazmat/bindings/openssl/rsa.py b/cryptography/hazmat/bindings/openssl/rsa.py
index 21ed5d67..ad0d37b4 100644
--- a/cryptography/hazmat/bindings/openssl/rsa.py
+++ b/cryptography/hazmat/bindings/openssl/rsa.py
@@ -16,15 +16,40 @@ INCLUDES = """
"""
TYPES = """
-typedef ... RSA;
+typedef struct rsa_st {
+ BIGNUM *n;
+ BIGNUM *e;
+ BIGNUM *d;
+ BIGNUM *p;
+ BIGNUM *q;
+ BIGNUM *dmp1;
+ BIGNUM *dmq1;
+ BIGNUM *iqmp;
+ ...;
+} RSA;
typedef ... BN_GENCB;
+static const int RSA_PKCS1_PADDING;
+static const int RSA_SSLV23_PADDING;
+static const int RSA_NO_PADDING;
+static const int RSA_PKCS1_OAEP_PADDING;
+static const int RSA_X931_PADDING;
"""
FUNCTIONS = """
RSA *RSA_new();
void RSA_free(RSA *);
+int RSA_size(const RSA *);
int RSA_generate_key_ex(RSA *, int, BIGNUM *, BN_GENCB *);
int RSA_check_key(const RSA *);
+RSA *RSAPublicKey_dup(RSA *);
+int RSA_public_encrypt(int, const unsigned char *, unsigned char *,
+ RSA *, int);
+int RSA_private_encrypt(int, const unsigned char *, unsigned char *,
+ RSA *, int);
+int RSA_public_decrypt(int, const unsigned char *, unsigned char *,
+ RSA *, int);
+int RSA_private_decrypt(int, const unsigned char *, unsigned char *,
+ RSA *, int);
"""
MACROS = """
diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py
index 58a64f0b..04611309 100644
--- a/cryptography/hazmat/bindings/openssl/ssl.py
+++ b/cryptography/hazmat/bindings/openssl/ssl.py
@@ -16,13 +16,200 @@ INCLUDES = """
"""
TYPES = """
+static const int SSL_FILETYPE_PEM;
+static const int SSL_FILETYPE_ASN1;
+static const int SSL_ERROR_NONE;
+static const int SSL_ERROR_ZERO_RETURN;
+static const int SSL_ERROR_WANT_READ;
+static const int SSL_ERROR_WANT_WRITE;
+static const int SSL_ERROR_WANT_X509_LOOKUP;
+static const int SSL_ERROR_SYSCALL;
+static const int SSL_ERROR_SSL;
+static const int SSL_SENT_SHUTDOWN;
+static const int SSL_RECEIVED_SHUTDOWN;
+static const int SSL_OP_NO_SSLv2;
+static const int SSL_OP_NO_SSLv3;
+static const int SSL_OP_NO_TLSv1;
+static const int SSL_OP_SINGLE_DH_USE;
+static const int SSL_OP_EPHEMERAL_RSA;
+static const int SSL_OP_MICROSOFT_SESS_ID_BUG;
+static const int SSL_OP_NETSCAPE_CHALLENGE_BUG;
+static const int SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
+static const int SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG;
+static const int SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER;
+static const int SSL_OP_MSIE_SSLV2_RSA_PADDING;
+static const int SSL_OP_SSLEAY_080_CLIENT_DH_BUG;
+static const int SSL_OP_TLS_D5_BUG;
+static const int SSL_OP_TLS_BLOCK_PADDING_BUG;
+static const int SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+static const int SSL_OP_CIPHER_SERVER_PREFERENCE;
+static const int SSL_OP_TLS_ROLLBACK_BUG;
+static const int SSL_OP_PKCS1_CHECK_1;
+static const int SSL_OP_PKCS1_CHECK_2;
+static const int SSL_OP_NETSCAPE_CA_DN_BUG;
+static const int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG;
+static const int SSL_OP_NO_QUERY_MTU;
+static const int SSL_OP_COOKIE_EXCHANGE;
+static const int SSL_OP_NO_TICKET;
+static const int SSL_OP_ALL;
+static const int SSL_VERIFY_PEER;
+static const int SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+static const int SSL_VERIFY_CLIENT_ONCE;
+static const int SSL_VERIFY_NONE;
+static const int SSL_SESS_CACHE_OFF;
+static const int SSL_SESS_CACHE_CLIENT;
+static const int SSL_SESS_CACHE_SERVER;
+static const int SSL_SESS_CACHE_BOTH;
+static const int SSL_SESS_CACHE_NO_AUTO_CLEAR;
+static const int SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
+static const int SSL_SESS_CACHE_NO_INTERNAL_STORE;
+static const int SSL_SESS_CACHE_NO_INTERNAL;
+static const int SSL_ST_CONNECT;
+static const int SSL_ST_ACCEPT;
+static const int SSL_ST_MASK;
+static const int SSL_ST_INIT;
+static const int SSL_ST_BEFORE;
+static const int SSL_ST_OK;
+static const int SSL_ST_RENEGOTIATE;
+static const int SSL_CB_LOOP;
+static const int SSL_CB_EXIT;
+static const int SSL_CB_READ;
+static const int SSL_CB_WRITE;
+static const int SSL_CB_ALERT;
+static const int SSL_CB_READ_ALERT;
+static const int SSL_CB_WRITE_ALERT;
+static const int SSL_CB_ACCEPT_LOOP;
+static const int SSL_CB_ACCEPT_EXIT;
+static const int SSL_CB_CONNECT_LOOP;
+static const int SSL_CB_CONNECT_EXIT;
+static const int SSL_CB_HANDSHAKE_START;
+static const int SSL_CB_HANDSHAKE_DONE;
+static const int SSL_MODE_ENABLE_PARTIAL_WRITE;
+static const int SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
+static const int SSL_MODE_AUTO_RETRY;
+static const int SSL3_RANDOM_SIZE;
+typedef ... X509_STORE_CTX;
+static const int X509_V_OK;
+typedef ... SSL_METHOD;
+typedef ... SSL_CTX;
+
+typedef struct {
+ int master_key_length;
+ unsigned char master_key[...];
+ ...;
+} SSL_SESSION;
+
+typedef struct {
+ unsigned char server_random[...];
+ unsigned char client_random[...];
+ ...;
+} SSL3_STATE;
+
+typedef struct {
+ SSL3_STATE *s3;
+ SSL_SESSION *session;
+ ...;
+} SSL;
+
+static const int TLSEXT_NAMETYPE_host_name;
"""
FUNCTIONS = """
void SSL_load_error_strings();
+
+int SSL_library_init();
+
+/* SSL */
+SSL_CTX *SSL_set_SSL_CTX(SSL *, SSL_CTX *);
+SSL_SESSION *SSL_get1_session(SSL *);
+int SSL_set_session(SSL *, SSL_SESSION *);
+int SSL_get_verify_mode(const SSL *);
+void SSL_set_verify_depth(SSL *, int);
+int SSL_get_verify_depth(const SSL *);
+SSL *SSL_new(SSL_CTX *);
+void SSL_free(SSL *);
+int SSL_set_fd(SSL *, int);
+void SSL_set_bio(SSL *, BIO *, BIO *);
+void SSL_set_connect_state(SSL *);
+void SSL_set_accept_state(SSL *);
+void SSL_set_shutdown(SSL *, int);
+int SSL_get_shutdown(const SSL *);
+int SSL_pending(const SSL *);
+int SSL_write(SSL *, const void *, int);
+int SSL_read(SSL *, void *, int);
+X509 *SSL_get_peer_certificate(const SSL *);
+int SSL_get_error(const SSL *, int);
+int SSL_do_handshake(SSL *);
+int SSL_shutdown(SSL *);
+const char *SSL_get_cipher_list(const SSL *, int);
+
+/* context */
+void SSL_CTX_free(SSL_CTX *);
+long SSL_CTX_set_timeout(SSL_CTX *, long);
+int SSL_CTX_set_default_verify_paths(SSL_CTX *);
+void SSL_CTX_set_verify_depth(SSL_CTX *, int);
+int SSL_CTX_get_verify_mode(const SSL_CTX *);
+int SSL_CTX_get_verify_depth(const SSL_CTX *);
+int SSL_CTX_set_cipher_list(SSL_CTX *, const char *);
+int SSL_CTX_load_verify_locations(SSL_CTX *, const char *, const char *);
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *, pem_password_cb *);
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void *);
+int SSL_CTX_use_certificate(SSL_CTX *, X509 *);
+int SSL_CTX_use_certificate_file(SSL_CTX *, const char *, int);
+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);
+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 *);
+
+/* X509_STORE_CTX */
+int X509_STORE_CTX_get_error(X509_STORE_CTX *);
+void X509_STORE_CTX_set_error(X509_STORE_CTX *, int);
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *);
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *);
+
+/* SSL_SESSION */
+void SSL_SESSION_free(SSL_SESSION *);
"""
-MACROS = """
+MACROS = MACROS = """
+long SSL_set_mode(SSL *, long);
+long SSL_get_mode(SSL *);
+
+long SSL_set_options(SSL *, long);
+long SSL_get_options(SSL *);
+
+int SSL_want_read(const SSL *);
+int SSL_want_write(const SSL *);
+
+int SSL_total_renegotiations(const SSL *);
+
+long SSL_CTX_set_options(SSL_CTX *, long);
+long SSL_CTX_get_options(SSL_CTX *);
+long SSL_CTX_set_mode(SSL_CTX *, long);
+long SSL_CTX_get_mode(SSL_CTX *);
+long SSL_CTX_set_session_cache_mode(SSL_CTX *, long);
+long SSL_CTX_get_session_cache_mode(SSL_CTX *);
+long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *);
+long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *);
+
+/*- These aren't macros these functions are all const X on openssl > 1.0.x -*/
+
+/* methods */
+const SSL_METHOD *SSLv3_method();
+const SSL_METHOD *SSLv3_server_method();
+const SSL_METHOD *SSLv3_client_method();
+const SSL_METHOD *TLSv1_method();
+const SSL_METHOD *TLSv1_server_method();
+const SSL_METHOD *TLSv1_client_method();
+const SSL_METHOD *SSLv23_method();
+const SSL_METHOD *SSLv23_server_method();
+const SSL_METHOD *SSLv23_client_method();
+
+/*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *);
+long SSL_CTX_get_timeout(const SSL_CTX *);
"""
CUSTOMIZATIONS = """