aboutsummaryrefslogtreecommitdiffstats
path: root/cryptography
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2013-10-21 14:44:42 -0700
committerAlex Gaynor <alex.gaynor@gmail.com>2013-10-21 14:44:42 -0700
commit6f874ff9279376b6962c514ae0e59b90e7082e15 (patch)
treedcbc2e2491bffc6ad19eea41bbeeba85d65a48b3 /cryptography
parentd6644815913e878462aa51c95c84e6d871406e27 (diff)
parent71ed449ffe7e26e9217b6c44bb27e19996315a64 (diff)
downloadcryptography-6f874ff9279376b6962c514ae0e59b90e7082e15.tar.gz
cryptography-6f874ff9279376b6962c514ae0e59b90e7082e15.tar.bz2
cryptography-6f874ff9279376b6962c514ae0e59b90e7082e15.zip
Merge branch 'master' into refactor-cipher-names
Conflicts: cryptography/bindings/openssl/api.py
Diffstat (limited to 'cryptography')
-rw-r--r--cryptography/bindings/openssl/api.py56
-rw-r--r--cryptography/bindings/openssl/asn1.py121
-rw-r--r--cryptography/bindings/openssl/evp.py41
-rw-r--r--cryptography/bindings/openssl/hmac.py32
-rw-r--r--cryptography/bindings/openssl/nid.py44
-rw-r--r--cryptography/bindings/openssl/pem.py44
-rw-r--r--cryptography/bindings/openssl/pkcs12.py34
-rw-r--r--cryptography/bindings/openssl/pkcs7.py34
-rw-r--r--cryptography/bindings/openssl/x509.py187
-rw-r--r--cryptography/bindings/openssl/x509name.py48
-rw-r--r--cryptography/bindings/openssl/x509v3.py94
-rw-r--r--cryptography/primitives/block/base.py6
-rw-r--r--cryptography/primitives/block/modes.py17
-rw-r--r--cryptography/primitives/hashes.py94
14 files changed, 831 insertions, 21 deletions
diff --git a/cryptography/bindings/openssl/api.py b/cryptography/bindings/openssl/api.py
index d804de43..7d189d62 100644
--- a/cryptography/bindings/openssl/api.py
+++ b/cryptography/bindings/openssl/api.py
@@ -37,6 +37,7 @@ class API(object):
OpenSSL API wrapper.
"""
_modules = [
+ "asn1",
"bignum",
"bio",
"conf",
@@ -46,10 +47,18 @@ class API(object):
"engine",
"err",
"evp",
+ "hmac",
+ "nid",
"opensslv",
+ "pem",
+ "pkcs7",
+ "pkcs12",
"rand",
"rsa",
"ssl",
+ "x509",
+ "x509name",
+ "x509v3",
]
def __init__(self):
@@ -128,14 +137,11 @@ class API(object):
)
def create_block_cipher_context(self, cipher, mode):
- ctx = self.ffi.new("EVP_CIPHER_CTX *")
- res = self.lib.EVP_CIPHER_CTX_init(ctx)
- assert res != 0
- ctx = self.ffi.gc(ctx, self.lib.EVP_CIPHER_CTX_cleanup)
+ ctx = self.lib.EVP_CIPHER_CTX_new()
+ ctx = self.ffi.gc(ctx, self.lib.EVP_CIPHER_CTX_free)
evp_cipher = self._cipher_registry[type(cipher), type(mode)](
self, cipher, mode
)
-
assert evp_cipher != self.ffi.NULL
if isinstance(mode, interfaces.ModeWithInitializationVector):
iv_nonce = mode.initialization_vector
@@ -156,7 +162,8 @@ class API(object):
return ctx
def update_encrypt_context(self, ctx, plaintext):
- buf = self.ffi.new("unsigned char[]", len(plaintext))
+ block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
+ buf = self.ffi.new("unsigned char[]", len(plaintext) + block_size - 1)
outlen = self.ffi.new("int *")
res = self.lib.EVP_EncryptUpdate(
ctx, buf, outlen, plaintext, len(plaintext)
@@ -165,15 +172,46 @@ class API(object):
return self.ffi.buffer(buf)[:outlen[0]]
def finalize_encrypt_context(self, ctx):
- cipher = self.lib.EVP_CIPHER_CTX_cipher(ctx)
- block_size = self.lib.EVP_CIPHER_block_size(cipher)
+ block_size = self.lib.EVP_CIPHER_CTX_block_size(ctx)
buf = self.ffi.new("unsigned char[]", block_size)
outlen = self.ffi.new("int *")
res = self.lib.EVP_EncryptFinal_ex(ctx, buf, outlen)
assert res != 0
res = self.lib.EVP_CIPHER_CTX_cleanup(ctx)
- assert res != 0
+ assert res == 1
return self.ffi.buffer(buf)[:outlen[0]]
+ def supports_hash(self, hash_cls):
+ return (self.ffi.NULL !=
+ self.lib.EVP_get_digestbyname(hash_cls.name.encode("ascii")))
+
+ def create_hash_context(self, hashobject):
+ ctx = self.lib.EVP_MD_CTX_create()
+ ctx = self.ffi.gc(ctx, self.lib.EVP_MD_CTX_destroy)
+ evp_md = self.lib.EVP_get_digestbyname(hashobject.name.encode("ascii"))
+ assert evp_md != self.ffi.NULL
+ res = self.lib.EVP_DigestInit_ex(ctx, evp_md, self.ffi.NULL)
+ assert res != 0
+ return ctx
+
+ def update_hash_context(self, ctx, data):
+ res = self.lib.EVP_DigestUpdate(ctx, data, len(data))
+ assert res != 0
+
+ def finalize_hash_context(self, ctx, digest_size):
+ buf = self.ffi.new("unsigned char[]", digest_size)
+ res = self.lib.EVP_DigestFinal_ex(ctx, buf, self.ffi.NULL)
+ assert res != 0
+ res = self.lib.EVP_MD_CTX_cleanup(ctx)
+ assert res == 1
+ return self.ffi.buffer(buf)[:digest_size]
+
+ def copy_hash_context(self, ctx):
+ copied_ctx = self.lib.EVP_MD_CTX_create()
+ copied_ctx = self.ffi.gc(copied_ctx, self.lib.EVP_MD_CTX_destroy)
+ res = self.lib.EVP_MD_CTX_copy_ex(copied_ctx, ctx)
+ assert res != 0
+ return copied_ctx
+
api = API()
diff --git a/cryptography/bindings/openssl/asn1.py b/cryptography/bindings/openssl/asn1.py
new file mode 100644
index 00000000..5bd72e9a
--- /dev/null
+++ b/cryptography/bindings/openssl/asn1.py
@@ -0,0 +1,121 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/asn1.h>
+"""
+
+TYPES = """
+typedef ... time_t;
+
+typedef int ASN1_BOOLEAN;
+typedef ... ASN1_INTEGER;
+
+struct asn1_string_st {
+ int length;
+ int type;
+ unsigned char *data;
+ long flags;
+};
+
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef ... ASN1_OBJECT;
+typedef ... ASN1_STRING;
+typedef ... ASN1_TYPE;
+typedef ... ASN1_GENERALIZEDTIME;
+typedef ... ASN1_ENUMERATED;
+typedef ... ASN1_ITEM;
+typedef ... ASN1_VALUE;
+
+typedef struct {
+ ...;
+} ASN1_TIME;
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+typedef ... ASN1_UTCTIME;
+
+static const int V_ASN1_GENERALIZEDTIME;
+
+static const int MBSTRING_UTF8;
+"""
+
+FUNCTIONS = """
+ASN1_OBJECT *ASN1_OBJECT_new();
+void ASN1_OBJECT_free(ASN1_OBJECT *);
+
+/* ASN1 OBJECT IDENTIFIER */
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **, const unsigned char **, long);
+int i2d_ASN1_OBJECT(ASN1_OBJECT *, unsigned char **);
+
+/* ASN1 STRING */
+ASN1_STRING *ASN1_STRING_new();
+ASN1_STRING *ASN1_STRING_type_new(int);
+void ASN1_STRING_free(ASN1_STRING *);
+unsigned char *ASN1_STRING_data(ASN1_STRING *);
+int ASN1_STRING_set(ASN1_STRING *, const void *, int);
+int ASN1_STRING_type(ASN1_STRING *);
+int ASN1_STRING_to_UTF8(unsigned char **, ASN1_STRING *);
+
+/* ASN1 OCTET STRING */
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_new();
+void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *);
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *, const unsigned char *, int);
+
+/* ASN1 INTEGER */
+ASN1_INTEGER *ASN1_INTEGER_new();
+void ASN1_INTEGER_free(ASN1_INTEGER *);
+int ASN1_INTEGER_set(ASN1_INTEGER *, long);
+int i2a_ASN1_INTEGER(BIO *, ASN1_INTEGER *);
+
+/* ASN1 TIME */
+ASN1_TIME *ASN1_TIME_new();
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *,
+ ASN1_GENERALIZEDTIME **);
+
+/* ASN1 UTCTIME */
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *, time_t);
+
+/* ASN1 GENERALIZEDTIME */
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *, const char *);
+void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *);
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *);
+
+/* ASN1 ENUMERATED */
+ASN1_ENUMERATED *ASN1_ENUMERATED_new();
+void ASN1_ENUMERATED_free(ASN1_ENUMERATED *);
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *, long);
+
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long,
+ const ASN1_ITEM *);
+"""
+
+MACROS = """
+ASN1_TIME *M_ASN1_TIME_dup(void *);
+ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM *);
+
+/* These aren't macros these arguments are all const X on openssl > 1.0.x */
+
+int ASN1_STRING_length(ASN1_STRING *);
+ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *);
+int ASN1_STRING_cmp(ASN1_STRING *, ASN1_STRING *);
+
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *);
+int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *, ASN1_OCTET_STRING *);
+
+ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *);
+int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *);
+long ASN1_INTEGER_get(ASN1_INTEGER *);
+
+BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *, BIGNUM *);
+"""
diff --git a/cryptography/bindings/openssl/evp.py b/cryptography/bindings/openssl/evp.py
index 63364374..2bb5b0f7 100644
--- a/cryptography/bindings/openssl/evp.py
+++ b/cryptography/bindings/openssl/evp.py
@@ -20,10 +20,20 @@ typedef struct {
...;
} EVP_CIPHER_CTX;
typedef ... EVP_CIPHER;
+typedef ... EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+
+typedef struct evp_pkey_st {
+ int type;
+ ...;
+} EVP_PKEY;
+static const int EVP_PKEY_RSA;
+static const int EVP_PKEY_DSA;
"""
FUNCTIONS = """
void OpenSSL_add_all_algorithms();
+
const EVP_CIPHER *EVP_get_cipherbyname(const char *);
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *, const EVP_CIPHER *, ENGINE *,
const unsigned char *, const unsigned char *);
@@ -35,7 +45,38 @@ int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *);
int EVP_CIPHER_block_size(const EVP_CIPHER *);
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new();
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *);
+
+EVP_MD_CTX *EVP_MD_CTX_create();
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *);
+int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *);
+int EVP_DigestUpdate(EVP_MD_CTX *, const void *, size_t);
+int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *);
+int EVP_MD_CTX_cleanup(EVP_MD_CTX *);
+void EVP_MD_CTX_destroy(EVP_MD_CTX *);
+const EVP_MD *EVP_get_digestbyname(const char *);
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *);
+int EVP_MD_size(const EVP_MD *);
+
+EVP_PKEY *EVP_PKEY_new();
+void EVP_PKEY_free(EVP_PKEY *);
+int EVP_PKEY_type(int);
+int EVP_PKEY_bits(EVP_PKEY *);
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *);
+
+int EVP_SignInit(EVP_MD_CTX *, const EVP_MD *);
+int EVP_SignUpdate(EVP_MD_CTX *, const void *, size_t);
+int EVP_SignFinal(EVP_MD_CTX *, unsigned char *, unsigned int *, EVP_PKEY *);
+
+int EVP_VerifyInit(EVP_MD_CTX *, const EVP_MD *);
+int EVP_VerifyUpdate(EVP_MD_CTX *, const void *, size_t);
+int EVP_VerifyFinal(EVP_MD_CTX *, const unsigned char *, unsigned int,
+ EVP_PKEY *);
"""
MACROS = """
+int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *);
+int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *);
"""
diff --git a/cryptography/bindings/openssl/hmac.py b/cryptography/bindings/openssl/hmac.py
new file mode 100644
index 00000000..e97ac35e
--- /dev/null
+++ b/cryptography/bindings/openssl/hmac.py
@@ -0,0 +1,32 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/hmac.h>
+"""
+
+TYPES = """
+typedef struct { ...; } HMAC_CTX;
+"""
+
+FUNCTIONS = """
+void HMAC_CTX_init(HMAC_CTX *);
+void HMAC_CTX_cleanup(HMAC_CTX *);
+int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *);
+int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t);
+int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *);
+int HMAC_CTX_copy(HMAC_CTX *, HMAC_CTX *);
+"""
+
+MACROS = """
+"""
diff --git a/cryptography/bindings/openssl/nid.py b/cryptography/bindings/openssl/nid.py
new file mode 100644
index 00000000..0f5b0003
--- /dev/null
+++ b/cryptography/bindings/openssl/nid.py
@@ -0,0 +1,44 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = ""
+
+TYPES = """
+static const int NID_undef;
+static const int NID_dsa;
+static const int NID_dsaWithSHA;
+static const int NID_dsaWithSHA1;
+static const int NID_md2;
+static const int NID_md4;
+static const int NID_md5;
+static const int NID_mdc2;
+static const int NID_ripemd160;
+static const int NID_sha;
+static const int NID_sha1;
+static const int NID_sha256;
+static const int NID_sha384;
+static const int NID_sha512;
+static const int NID_sha224;
+static const int NID_sha;
+static const int NID_ecdsa_with_SHA1;
+static const int NID_ecdsa_with_SHA224;
+static const int NID_ecdsa_with_SHA256;
+static const int NID_ecdsa_with_SHA384;
+static const int NID_ecdsa_with_SHA512;
+static const int NID_crl_reason;
+static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+"""
+
+FUNCTIONS = ""
+
+MACROS = ""
diff --git a/cryptography/bindings/openssl/pem.py b/cryptography/bindings/openssl/pem.py
new file mode 100644
index 00000000..8c8f736d
--- /dev/null
+++ b/cryptography/bindings/openssl/pem.py
@@ -0,0 +1,44 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/pem.h>
+"""
+
+TYPES = """
+typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
+"""
+
+FUNCTIONS = """
+X509 *PEM_read_bio_X509(BIO *, X509 **, pem_password_cb *, void *);
+int PEM_write_bio_X509(BIO *, X509 *);
+
+int PEM_write_bio_PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+ unsigned char *, int, pem_password_cb *, void *);
+
+EVP_PKEY *PEM_read_bio_PrivateKey(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 *);
+
+X509_CRL *PEM_read_bio_X509_CRL(BIO *, X509_CRL **, pem_password_cb *, void *);
+
+int PEM_write_bio_X509_CRL(BIO *, X509_CRL *);
+
+PKCS7 *PEM_read_bio_PKCS7(BIO *, PKCS7 **, pem_password_cb *, void *);
+DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *);
+"""
+
+MACROS = ""
diff --git a/cryptography/bindings/openssl/pkcs12.py b/cryptography/bindings/openssl/pkcs12.py
new file mode 100644
index 00000000..5c002b93
--- /dev/null
+++ b/cryptography/bindings/openssl/pkcs12.py
@@ -0,0 +1,34 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/pkcs12.h>
+"""
+
+TYPES = """
+typedef ... PKCS12;
+"""
+
+FUNCTIONS = """
+void PKCS12_free(PKCS12 *);
+
+PKCS12 *d2i_PKCS12_bio(BIO *, PKCS12 **);
+int i2d_PKCS12_bio(BIO *, PKCS12 *);
+"""
+
+MACROS = """
+int PKCS12_parse(PKCS12 *, const char *, EVP_PKEY **, X509 **,
+ struct stack_st_X509 **);
+PKCS12 *PKCS12_create(char *, char *, EVP_PKEY *, X509 *,
+ struct stack_st_X509 *, int, int, int, int, int);
+"""
diff --git a/cryptography/bindings/openssl/pkcs7.py b/cryptography/bindings/openssl/pkcs7.py
new file mode 100644
index 00000000..752bfa00
--- /dev/null
+++ b/cryptography/bindings/openssl/pkcs7.py
@@ -0,0 +1,34 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/pkcs7.h>
+"""
+
+TYPES = """
+typedef struct {
+ ASN1_OBJECT *type;
+ ...;
+} PKCS7;
+"""
+
+FUNCTIONS = """
+void PKCS7_free(PKCS7 *);
+"""
+
+MACROS = """
+int PKCS7_type_is_signed(PKCS7 *);
+int PKCS7_type_is_enveloped(PKCS7 *);
+int PKCS7_type_is_signedAndEnveloped(PKCS7 *);
+int PKCS7_type_is_data(PKCS7 *);
+"""
diff --git a/cryptography/bindings/openssl/x509.py b/cryptography/bindings/openssl/x509.py
new file mode 100644
index 00000000..9a51a6d0
--- /dev/null
+++ b/cryptography/bindings/openssl/x509.py
@@ -0,0 +1,187 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/ssl.h>
+"""
+
+TYPES = """
+typedef struct {
+ ASN1_OBJECT *algorithm;
+ ...;
+} X509_ALGOR;
+
+typedef struct {
+ X509_ALGOR *signature;
+ ...;
+} X509_CINF;
+
+typedef struct {
+ ASN1_OBJECT *object;
+ ASN1_BOOLEAN critical;
+ ASN1_OCTET_STRING *value;
+} X509_EXTENSION;
+
+typedef ... X509_EXTENSIONS;
+
+typedef ... X509_REQ;
+
+typedef ... x509_revoked_st;
+
+typedef struct {
+ ASN1_INTEGER *serialNumber;
+ ASN1_TIME *revocationDate;
+ X509_EXTENSIONS *extensions;
+ int sequence;
+ ...;
+} X509_REVOKED;
+
+typedef struct {
+ struct x509_revoked_st *revoked;
+ ...;
+} X509_CRL_INFO;
+
+typedef struct {
+ X509_CRL_INFO *crl;
+ ...;
+} X509_CRL;
+
+typedef struct {
+ X509_CINF *cert_info;
+ ...;
+} X509;
+
+typedef ... X509_STORE;
+typedef ... NETSCAPE_SPKI;
+"""
+
+FUNCTIONS = """
+X509 *X509_new();
+void X509_free(X509 *);
+X509 *X509_dup(X509 *);
+
+int X509_print_ex(BIO *, X509 *, unsigned long, unsigned long);
+
+int X509_set_version(X509 *, long);
+
+EVP_PKEY *X509_get_pubkey(X509 *);
+int X509_set_pubkey(X509 *, EVP_PKEY *);
+
+unsigned char *X509_alias_get0(X509 *, int *);
+int X509_sign(X509 *, EVP_PKEY *, const EVP_MD *);
+
+int X509_digest(const X509 *, const EVP_MD *, unsigned char *, unsigned int *);
+
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *, long);
+
+unsigned long X509_subject_name_hash(X509 *);
+
+X509_NAME *X509_get_subject_name(X509 *);
+int X509_set_subject_name(X509 *, X509_NAME *);
+
+X509_NAME *X509_get_issuer_name(X509 *);
+int X509_set_issuer_name(X509 *, X509_NAME *);
+
+int X509_get_ext_count(X509 *);
+int X509_add_ext(X509 *, X509_EXTENSION *, int);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *);
+X509_EXTENSION *X509_get_ext(X509 *, int);
+int X509_EXTENSION_get_critical(X509_EXTENSION *);
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *);
+void X509_EXTENSION_free(X509_EXTENSION *);
+
+int X509_REQ_set_version(X509_REQ *, long);
+X509_REQ *X509_REQ_new();
+void X509_REQ_free(X509_REQ *);
+int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *);
+int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *);
+int X509_REQ_verify(X509_REQ *, EVP_PKEY *);
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *);
+int X509_REQ_add_extensions(X509_REQ *, X509_EXTENSIONS *);
+int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long);
+
+int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *);
+
+X509_REVOKED *X509_REVOKED_new();
+void X509_REVOKED_free(X509_REVOKED *);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *, ASN1_INTEGER *);
+
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *, int, void *, int, unsigned long);
+
+X509_CRL *d2i_X509_CRL_bio(BIO *, X509_CRL **);
+X509_CRL *X509_CRL_new();
+void X509_CRL_free(X509_CRL *);
+int X509_CRL_add0_revoked(X509_CRL *, X509_REVOKED *);
+int i2d_X509_CRL_bio(BIO *, X509_CRL *);
+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 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 *);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *, EVP_PKEY *);
+NETSCAPE_SPKI *NETSCAPE_SPKI_new();
+void NETSCAPE_SPKI_free(NETSCAPE_SPKI *);
+
+/* ASN1 serialization */
+int i2d_X509_bio(BIO *, X509 *);
+X509 *d2i_X509_bio(BIO *, X509 **);
+
+int i2d_X509_REQ_bio(BIO *, X509_REQ *);
+X509_REQ *d2i_X509_REQ_bio(BIO *, X509_REQ **);
+
+int i2d_PrivateKey_bio(BIO *, EVP_PKEY *);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *, EVP_PKEY **);
+
+ASN1_INTEGER *X509_get_serialNumber(X509 *);
+int X509_set_serialNumber(X509 *, ASN1_INTEGER *);
+
+/* X509_STORE */
+X509_STORE *X509_STORE_new();
+void X509_STORE_free(X509_STORE *);
+int X509_STORE_add_cert(X509_STORE *, X509 *);
+"""
+
+MACROS = """
+long X509_get_version(X509 *);
+
+ASN1_TIME *X509_get_notBefore(X509 *);
+ASN1_TIME *X509_get_notAfter(X509 *);
+
+long X509_REQ_get_version(X509_REQ *);
+X509_NAME *X509_REQ_get_subject_name(X509_REQ *);
+
+struct stack_st_X509 *sk_X509_new_null();
+void sk_X509_free(struct stack_st_X509 *);
+int sk_X509_num(struct stack_st_X509 *);
+int sk_X509_push(struct stack_st_X509 *, X509 *);
+X509 *sk_X509_value(struct stack_st_X509 *, int);
+
+X509_EXTENSIONS *sk_X509_EXTENSION_new_null();
+int sk_X509_EXTENSION_num(X509_EXTENSIONS *);
+X509_EXTENSION *sk_X509_EXTENSION_value(X509_EXTENSIONS *, int);
+int sk_X509_EXTENSION_push(X509_EXTENSIONS *, X509_EXTENSION *);
+void sk_X509_EXTENSION_delete(X509_EXTENSIONS *, int);
+void sk_X509_EXTENSION_free(X509_EXTENSIONS *);
+
+int sk_X509_REVOKED_num(struct x509_revoked_st *);
+X509_REVOKED *sk_X509_REVOKED_value(struct x509_revoked_st *, int);
+
+/* These aren't macros these arguments are all const X on openssl > 1.0.x */
+int X509_CRL_set_lastUpdate(X509_CRL *, const ASN1_TIME *);
+int X509_CRL_set_nextUpdate(X509_CRL *, const ASN1_TIME *);
+"""
diff --git a/cryptography/bindings/openssl/x509name.py b/cryptography/bindings/openssl/x509name.py
new file mode 100644
index 00000000..bd7abe2d
--- /dev/null
+++ b/cryptography/bindings/openssl/x509name.py
@@ -0,0 +1,48 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/x509.h>
+"""
+
+TYPES = """
+typedef ... X509_NAME;
+typedef ... X509_NAME_ENTRY;
+"""
+
+FUNCTIONS = """
+int X509_NAME_entry_count(X509_NAME *);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *, int);
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *);
+ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *);
+unsigned long X509_NAME_hash(X509_NAME *);
+
+int i2d_X509_NAME(X509_NAME *, unsigned char **);
+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);
+void X509_NAME_ENTRY_free(X509_NAME_ENTRY *);
+int X509_NAME_get_index_by_NID(X509_NAME *, int, int);
+int X509_NAME_cmp(const X509_NAME *, const X509_NAME *);
+char *X509_NAME_oneline(X509_NAME *, char *, int);
+X509_NAME *X509_NAME_dup(X509_NAME *);
+void X509_NAME_free(X509_NAME *);
+"""
+
+MACROS = """
+struct stack_st_X509_NAME *sk_X509_NAME_new_null();
+int sk_X509_NAME_num(struct stack_st_X509_NAME *);
+int sk_X509_NAME_push(struct stack_st_X509_NAME *, X509_NAME *);
+X509_NAME *sk_X509_NAME_value(struct stack_st_X509_NAME *, int);
+void sk_X509_NAME_free(struct stack_st_X509_NAME *);
+"""
diff --git a/cryptography/bindings/openssl/x509v3.py b/cryptography/bindings/openssl/x509v3.py
new file mode 100644
index 00000000..413bde5f
--- /dev/null
+++ b/cryptography/bindings/openssl/x509v3.py
@@ -0,0 +1,94 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+INCLUDES = """
+#include <openssl/x509v3.h>
+"""
+
+TYPES = """
+typedef struct {
+ X509 *issuer_cert;
+ X509 *subject_cert;
+ ...;
+} X509V3_CTX;
+
+typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char **, long);
+
+typedef struct {
+ ASN1_ITEM_EXP *it;
+ X509V3_EXT_D2I d2i;
+ ...;
+} X509V3_EXT_METHOD;
+
+static const int GEN_OTHERNAME;
+static const int GEN_EMAIL;
+static const int GEN_X400;
+static const int GEN_DNS;
+static const int GEN_URI;
+static const int GEN_DIRNAME;
+static const int GEN_EDIPARTY;
+static const int GEN_IPADD;
+static const int GEN_RID;
+
+typedef struct {
+ ...;
+} OTHERNAME;
+
+typedef struct {
+ ...;
+} EDIPARTYNAME;
+
+typedef struct {
+ int type;
+ union {
+ char *ptr;
+ OTHERNAME *otherName; /* otherName */
+ ASN1_IA5STRING *rfc822Name;
+ ASN1_IA5STRING *dNSName;
+ ASN1_TYPE *x400Address;
+ X509_NAME *directoryName;
+ EDIPARTYNAME *ediPartyName;
+ ASN1_IA5STRING *uniformResourceIdentifier;
+ ASN1_OCTET_STRING *iPAddress;
+ ASN1_OBJECT *registeredID;
+
+ /* Old names */
+ ASN1_OCTET_STRING *ip; /* iPAddress */
+ X509_NAME *dirn; /* dirn */
+ ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, */
+ /* uniformResourceIdentifier */
+ ASN1_OBJECT *rid; /* registeredID */
+ ASN1_TYPE *other; /* x400Address */
+ } d;
+ ...;
+} GENERAL_NAME;
+
+typedef struct stack_st_GENERAL_NAME GENERAL_NAMES;
+"""
+
+FUNCTIONS = """
+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 *);
+"""
+
+MACROS = """
+void *X509V3_set_ctx_nodb(X509V3_CTX *);
+int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
+int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
+GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
+
+/* 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);
+"""
diff --git a/cryptography/primitives/block/base.py b/cryptography/primitives/block/base.py
index cb68361b..42c1f799 100644
--- a/cryptography/primitives/block/base.py
+++ b/cryptography/primitives/block/base.py
@@ -34,12 +34,6 @@ class BlockCipher(object):
self._ctx = api.create_block_cipher_context(cipher, mode)
self._operation = None
- @property
- def name(self):
- return "{0}-{1}-{2}".format(
- self.cipher.name, self.cipher.key_size, self.mode.name,
- )
-
def encrypt(self, plaintext):
if self._ctx is None:
raise ValueError("BlockCipher was already finalized")
diff --git a/cryptography/primitives/block/modes.py b/cryptography/primitives/block/modes.py
index 221e7393..43631801 100644
--- a/cryptography/primitives/block/modes.py
+++ b/cryptography/primitives/block/modes.py
@@ -16,6 +16,14 @@ from __future__ import absolute_import, division, print_function
from cryptography.primitives import interfaces
+def register(iface):
+ def register_decorator(klass):
+ iface.register(klass)
+ return klass
+ return register_decorator
+
+
+@register(interfaces.ModeWithInitializationVector)
class CBC(object):
name = "CBC"
@@ -28,6 +36,7 @@ class ECB(object):
name = "ECB"
+@register(interfaces.ModeWithInitializationVector)
class OFB(object):
name = "OFB"
@@ -36,6 +45,7 @@ class OFB(object):
self.initialization_vector = initialization_vector
+@register(interfaces.ModeWithInitializationVector)
class CFB(object):
name = "CFB"
@@ -44,15 +54,10 @@ class CFB(object):
self.initialization_vector = initialization_vector
+@register(interfaces.ModeWithNonce)
class CTR(object):
name = "CTR"
def __init__(self, nonce):
super(CTR, self).__init__()
self.nonce = nonce
-
-
-interfaces.ModeWithInitializationVector.register(CBC)
-interfaces.ModeWithInitializationVector.register(OFB)
-interfaces.ModeWithInitializationVector.register(CFB)
-interfaces.ModeWithNonce.register(CTR)
diff --git a/cryptography/primitives/hashes.py b/cryptography/primitives/hashes.py
new file mode 100644
index 00000000..e8c1f929
--- /dev/null
+++ b/cryptography/primitives/hashes.py
@@ -0,0 +1,94 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import absolute_import, division, print_function
+
+import abc
+
+import binascii
+
+import six
+
+from cryptography.bindings import _default_api
+
+
+class BaseHash(six.with_metaclass(abc.ABCMeta)):
+ def __init__(self, api=None, ctx=None):
+ if api is None:
+ api = _default_api
+ self._api = api
+ self._ctx = self._api.create_hash_context(self) if ctx is None else ctx
+
+ def update(self, data):
+ self._api.update_hash_context(self._ctx, data)
+
+ def copy(self):
+ return self.__class__(ctx=self._copy_ctx())
+
+ def digest(self):
+ return self._api.finalize_hash_context(self._copy_ctx(),
+ self.digest_size)
+
+ def hexdigest(self):
+ return binascii.hexlify(self.digest()).decode("ascii")
+
+ def _copy_ctx(self):
+ return self._api.copy_hash_context(self._ctx)
+
+
+class SHA1(BaseHash):
+ name = "sha1"
+ digest_size = 20
+ block_size = 64
+
+
+class SHA224(BaseHash):
+ name = "sha224"
+ digest_size = 28
+ block_size = 64
+
+
+class SHA256(BaseHash):
+ name = "sha256"
+ digest_size = 32
+ block_size = 64
+
+
+class SHA384(BaseHash):
+ name = "sha384"
+ digest_size = 48
+ block_size = 128
+
+
+class SHA512(BaseHash):
+ name = "sha512"
+ digest_size = 64
+ block_size = 128
+
+
+class RIPEMD160(BaseHash):
+ name = "ripemd160"
+ digest_size = 20
+ block_size = 64
+
+
+class Whirlpool(BaseHash):
+ name = "whirlpool"
+ digest_size = 64
+ block_size = 64
+
+
+class MD5(BaseHash):
+ name = "md5"
+ digest_size = 16
+ block_size = 64