aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/development/test-vectors.rst4
-rw-r--r--src/_cffi_src/openssl/crypto.py3
-rw-r--r--src/_cffi_src/openssl/ecdsa.py5
-rw-r--r--src/_cffi_src/openssl/engine.py35
-rw-r--r--src/_cffi_src/openssl/err.py8
-rw-r--r--src/_cffi_src/openssl/evp.py37
-rw-r--r--src/_cffi_src/openssl/rand.py3
-rw-r--r--src/_cffi_src/openssl/ssl.py18
-rw-r--r--src/_cffi_src/openssl/x509.py2
-rw-r--r--src/_cffi_src/openssl/x509_vfy.py6
-rw-r--r--src/_cffi_src/openssl/x509name.py12
-rw-r--r--src/cryptography/hazmat/backends/multibackend.py7
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py9
-rw-r--r--src/cryptography/hazmat/backends/openssl/decode_asn1.py9
-rw-r--r--src/cryptography/hazmat/backends/openssl/encode_asn1.py43
-rw-r--r--src/cryptography/hazmat/backends/openssl/hashes.py13
-rw-r--r--tests/hazmat/backends/test_multibackend.py20
-rw-r--r--vectors/cryptography_vectors/x509/e-trust.ru.derbin0 -> 1309 bytes
18 files changed, 130 insertions, 104 deletions
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index e4618927..73ddb976 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -113,6 +113,9 @@ X.509
* ``department-of-state-root.pem`` - The intermediary CA for the Department of
State, issued by the United States Federal Government's Common Policy CA.
Notably has a ``critical`` policy constraints extensions.
+* ``e-trust.ru.der`` - A certificate from a `Russian CA`_ signed using the GOST
+ cipher and containing numerous unusual encodings such as NUMERICSTRING in
+ the subject DN.
Custom X.509 Vectors
~~~~~~~~~~~~~~~~~~~~
@@ -450,3 +453,4 @@ header format (substituting the correct information):
.. _`root data`: https://hg.mozilla.org/projects/nss/file/25b2922cc564/security/nss/lib/ckfw/builtins/certdata.txt#l2053
.. _`asymmetric/public/PKCS1/dsa.pub.pem`: https://github.com/ruby/ruby/blob/4ccb387f3bc436a08fc6d72c4931994f5de95110/test/openssl/test_pkey_dsa.rb#L53
.. _`Mozilla bug`: https://bugzilla.mozilla.org/show_bug.cgi?id=233586
+.. _`Russian CA`: http://e-trust.gosuslugi.ru/MainCA
diff --git a/src/_cffi_src/openssl/crypto.py b/src/_cffi_src/openssl/crypto.py
index b40dae8d..9357815b 100644
--- a/src/_cffi_src/openssl/crypto.py
+++ b/src/_cffi_src/openssl/crypto.py
@@ -40,8 +40,6 @@ void CRYPTO_mem_leaks(struct bio_st *);
void CRYPTO_cleanup_all_ex_data(void);
int CRYPTO_num_locks(void);
void CRYPTO_set_locking_callback(void(*)(int, int, const char *, int));
-void CRYPTO_set_id_callback(unsigned long (*)(void));
-unsigned long (*CRYPTO_get_id_callback(void))(void);
void (*CRYPTO_get_locking_callback(void))(int, int, const char *, int);
void CRYPTO_lock(int, int, const char *, int);
@@ -57,7 +55,6 @@ unsigned long OpenSSL_version_num(void);
const char *OpenSSL_version(int);
void CRYPTO_add(int *, int, int);
-void CRYPTO_malloc_init(void);
"""
CUSTOMIZATIONS = """
diff --git a/src/_cffi_src/openssl/ecdsa.py b/src/_cffi_src/openssl/ecdsa.py
index 7cbe5215..f3e9fba0 100644
--- a/src/_cffi_src/openssl/ecdsa.py
+++ b/src/_cffi_src/openssl/ecdsa.py
@@ -13,10 +13,7 @@ INCLUDES = """
TYPES = """
static const int Cryptography_HAS_ECDSA;
-typedef struct {
- BIGNUM *r;
- BIGNUM *s;
-} ECDSA_SIG;
+typedef ... ECDSA_SIG;
typedef ... CRYPTO_EX_new;
typedef ... CRYPTO_EX_dup;
diff --git a/src/_cffi_src/openssl/engine.py b/src/_cffi_src/openssl/engine.py
index 60c6f3e2..afdd54e4 100644
--- a/src/_cffi_src/openssl/engine.py
+++ b/src/_cffi_src/openssl/engine.py
@@ -14,18 +14,13 @@ static const long Cryptography_HAS_ENGINE_CRYPTODEV;
typedef ... ENGINE;
typedef ... RSA_METHOD;
typedef ... DSA_METHOD;
-typedef ... ECDH_METHOD;
-typedef ... ECDSA_METHOD;
typedef ... DH_METHOD;
typedef struct {
- void (*seed)(const void *, int);
int (*bytes)(unsigned char *, int);
- void (*cleanup)();
- void (*add)(const void *, int, double);
int (*pseudorand)(unsigned char *, int);
int (*status)();
+ ...;
} RAND_METHOD;
-typedef ... STORE_METHOD;
typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
typedef ... *ENGINE_CTRL_FUNC_PTR;
typedef ... *ENGINE_LOAD_KEY_PTR;
@@ -37,11 +32,8 @@ typedef ... UI_METHOD;
static const unsigned int ENGINE_METHOD_RSA;
static const unsigned int ENGINE_METHOD_DSA;
static const unsigned int ENGINE_METHOD_RAND;
-static const unsigned int ENGINE_METHOD_ECDH;
-static const unsigned int ENGINE_METHOD_ECDSA;
static const unsigned int ENGINE_METHOD_CIPHERS;
static const unsigned int ENGINE_METHOD_DIGESTS;
-static const unsigned int ENGINE_METHOD_STORE;
static const unsigned int ENGINE_METHOD_ALL;
static const unsigned int ENGINE_METHOD_NONE;
@@ -58,22 +50,16 @@ int ENGINE_remove(ENGINE *);
ENGINE *ENGINE_by_id(const char *);
int ENGINE_init(ENGINE *);
int ENGINE_finish(ENGINE *);
-void ENGINE_load_openssl(void);
-void ENGINE_load_dynamic(void);
void ENGINE_load_builtin_engines(void);
void ENGINE_cleanup(void);
ENGINE *ENGINE_get_default_RSA(void);
ENGINE *ENGINE_get_default_DSA(void);
-ENGINE *ENGINE_get_default_ECDH(void);
-ENGINE *ENGINE_get_default_ECDSA(void);
ENGINE *ENGINE_get_default_DH(void);
ENGINE *ENGINE_get_default_RAND(void);
ENGINE *ENGINE_get_cipher_engine(int);
ENGINE *ENGINE_get_digest_engine(int);
int ENGINE_set_default_RSA(ENGINE *);
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 *);
@@ -88,21 +74,12 @@ void ENGINE_register_all_RSA(void);
int ENGINE_register_DSA(ENGINE *);
void ENGINE_unregister_DSA(ENGINE *);
void ENGINE_register_all_DSA(void);
-int ENGINE_register_ECDH(ENGINE *);
-void ENGINE_unregister_ECDH(ENGINE *);
-void ENGINE_register_all_ECDH(void);
-int ENGINE_register_ECDSA(ENGINE *);
-void ENGINE_unregister_ECDSA(ENGINE *);
-void ENGINE_register_all_ECDSA(void);
int ENGINE_register_DH(ENGINE *);
void ENGINE_unregister_DH(ENGINE *);
void ENGINE_register_all_DH(void);
int ENGINE_register_RAND(ENGINE *);
void ENGINE_unregister_RAND(ENGINE *);
void ENGINE_register_all_RAND(void);
-int ENGINE_register_STORE(ENGINE *);
-void ENGINE_unregister_STORE(ENGINE *);
-void ENGINE_register_all_STORE(void);
int ENGINE_register_ciphers(ENGINE *);
void ENGINE_unregister_ciphers(ENGINE *);
void ENGINE_register_all_ciphers(void);
@@ -123,11 +100,8 @@ int ENGINE_set_id(ENGINE *, const char *);
int ENGINE_set_name(ENGINE *, const char *);
int ENGINE_set_RSA(ENGINE *, const RSA_METHOD *);
int ENGINE_set_DSA(ENGINE *, const DSA_METHOD *);
-int ENGINE_set_ECDH(ENGINE *, const ECDH_METHOD *);
-int ENGINE_set_ECDSA(ENGINE *, const ECDSA_METHOD *);
int ENGINE_set_DH(ENGINE *, const DH_METHOD *);
int ENGINE_set_RAND(ENGINE *, const RAND_METHOD *);
-int ENGINE_set_STORE(ENGINE *, const STORE_METHOD *);
int ENGINE_set_destroy_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
int ENGINE_set_init_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
int ENGINE_set_finish_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
@@ -142,11 +116,8 @@ const char *ENGINE_get_id(const ENGINE *);
const char *ENGINE_get_name(const ENGINE *);
const RSA_METHOD *ENGINE_get_RSA(const ENGINE *);
const DSA_METHOD *ENGINE_get_DSA(const ENGINE *);
-const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *);
-const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *);
const DH_METHOD *ENGINE_get_DH(const ENGINE *);
const RAND_METHOD *ENGINE_get_RAND(const ENGINE *);
-const STORE_METHOD *ENGINE_get_STORE(const ENGINE *);
const EVP_CIPHER *ENGINE_get_cipher(ENGINE *, int);
const EVP_MD *ENGINE_get_digest(ENGINE *, int);
@@ -158,6 +129,10 @@ void ENGINE_add_conf_module(void);
"""
MACROS = """
+/* these became macros in 1.1.0 */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+
void ENGINE_load_cryptodev(void);
"""
diff --git a/src/_cffi_src/openssl/err.py b/src/_cffi_src/openssl/err.py
index f6e9632d..e31b1808 100644
--- a/src/_cffi_src/openssl/err.py
+++ b/src/_cffi_src/openssl/err.py
@@ -88,7 +88,6 @@ static const int ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM;
static const int ASN1_R_UNKNOWN_OBJECT_TYPE;
static const int ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE;
static const int ASN1_R_UNKNOWN_TAG;
-static const int ASN1_R_UNKOWN_FORMAT;
static const int ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE;
static const int ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM;
static const int ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE;
@@ -121,11 +120,6 @@ static const int EVP_F_EVP_PKEY2PKCS8_BROKEN;
static const int EVP_F_EVP_PKEY_COPY_PARAMETERS;
static const int EVP_F_EVP_PKEY_DECRYPT;
static const int EVP_F_EVP_PKEY_ENCRYPT;
-static const int EVP_F_EVP_PKEY_GET1_DH;
-static const int EVP_F_EVP_PKEY_GET1_DSA;
-static const int EVP_F_EVP_PKEY_GET1_ECDSA;
-static const int EVP_F_EVP_PKEY_GET1_EC_KEY;
-static const int EVP_F_EVP_PKEY_GET1_RSA;
static const int EVP_F_EVP_PKEY_NEW;
static const int EVP_F_EVP_RIJNDAEL;
static const int EVP_F_EVP_SIGNFINAL;
@@ -195,8 +189,6 @@ static const int PEM_F_PEM_READ;
static const int PEM_F_PEM_READ_BIO;
static const int PEM_F_PEM_READ_BIO_PRIVATEKEY;
static const int PEM_F_PEM_READ_PRIVATEKEY;
-static const int PEM_F_PEM_SEALFINAL;
-static const int PEM_F_PEM_SEALINIT;
static const int PEM_F_PEM_SIGNFINAL;
static const int PEM_F_PEM_WRITE;
static const int PEM_F_PEM_WRITE_BIO;
diff --git a/src/_cffi_src/openssl/evp.py b/src/_cffi_src/openssl/evp.py
index 1d37b814..5abc6451 100644
--- a/src/_cffi_src/openssl/evp.py
+++ b/src/_cffi_src/openssl/evp.py
@@ -10,16 +10,9 @@ INCLUDES = """
TYPES = """
typedef ... EVP_CIPHER;
-typedef struct {
- const EVP_CIPHER *cipher;
- ENGINE *engine;
- int encrypt;
- ...;
-} EVP_CIPHER_CTX;
+typedef ... EVP_CIPHER_CTX;
typedef ... EVP_MD;
-typedef struct env_md_ctx_st {
- ...;
-} EVP_MD_CTX;
+typedef struct { ...; } EVP_MD_CTX;
typedef ... EVP_PKEY;
typedef ... EVP_PKEY_CTX;
@@ -56,18 +49,15 @@ int EVP_CipherUpdate(EVP_CIPHER_CTX *, unsigned char *, int *,
const unsigned char *, int);
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
-void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *);
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *, int);
-EVP_MD_CTX *EVP_MD_CTX_create(void);
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 *);
EVP_PKEY *EVP_PKEY_new(void);
@@ -121,9 +111,18 @@ int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *);
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *);
int Cryptography_EVP_PKEY_id(const EVP_PKEY *);
+
+/* in 1.1.0 _create and _destroy were renamed to _new and _free. The following
+ two functions wrap both the old and new functions so we can call them
+ without worrying about what OpenSSL we're running against. */
+EVP_MD_CTX *Cryptography_EVP_MD_CTX_new(void);
+void Cryptography_EVP_MD_CTX_free(EVP_MD_CTX *);
"""
MACROS = """
+/* became a macro in 1.1.0 */
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
+
void OpenSSL_add_all_algorithms(void);
int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *);
int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *);
@@ -238,4 +237,18 @@ int Cryptography_EVP_PKEY_id(const EVP_PKEY *key) {
return key->type;
#endif
}
+EVP_MD_CTX *Cryptography_EVP_MD_CTX_new(void) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ return EVP_MD_CTX_create();
+#else
+ return EVP_MD_CTX_new();
+#endif
+}
+void Cryptography_EVP_MD_CTX_free(EVP_MD_CTX *ctx) {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ EVP_MD_CTX_destroy(ctx);
+#else
+ EVP_MD_CTX_free(ctx);
+#endif
+}
"""
diff --git a/src/_cffi_src/openssl/rand.py b/src/_cffi_src/openssl/rand.py
index 91e1a396..0a94d705 100644
--- a/src/_cffi_src/openssl/rand.py
+++ b/src/_cffi_src/openssl/rand.py
@@ -22,7 +22,6 @@ int RAND_load_file(const char *, long);
int RAND_write_file(const char *);
void RAND_cleanup(void);
int RAND_bytes(unsigned char *, int);
-int RAND_pseudo_bytes(unsigned char *, int);
"""
MACROS = """
@@ -32,7 +31,7 @@ int RAND_query_egd_bytes(const char *, unsigned char *, int);
"""
CUSTOMIZATIONS = """
-#if defined(LIBRESSL_VERSION_NUMBER)
+#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000L
static const long Cryptography_HAS_EGD = 0;
int (*RAND_egd)(const char *) = NULL;
int (*RAND_egd_bytes)(const char *, int) = NULL;
diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
index 98b396da..e97a1d7d 100644
--- a/src/_cffi_src/openssl/ssl.py
+++ b/src/_cffi_src/openssl/ssl.py
@@ -162,9 +162,6 @@ typedef ... COMP_METHOD;
"""
FUNCTIONS = """
-void SSL_load_error_strings(void);
-int SSL_library_init(void);
-
/* SSL */
const char *SSL_state_string_long(const SSL *);
SSL_SESSION *SSL_get1_session(SSL *);
@@ -253,20 +250,25 @@ char *SSL_CIPHER_get_version(const SSL_CIPHER *);
size_t SSL_get_finished(const SSL *, void *, size_t);
size_t SSL_get_peer_finished(const SSL *, void *, size_t);
+Cryptography_STACK_OF_X509_NAME *SSL_load_client_CA_file(const char *);
+"""
-/* CRYPTO_EX_DATA */
+MACROS = """
+/* These became macros in 1.1.0 */
+int SSL_library_init(void);
+void SSL_load_error_strings(void);
+
+/* these CRYPTO_EX_DATA functions became macros in 1.1.0 */
int SSL_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
CRYPTO_EX_free *);
int SSL_set_ex_data(SSL *, int, void *);
-
int SSL_CTX_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
CRYPTO_EX_free *);
int SSL_CTX_set_ex_data(SSL_CTX *, int, void *);
-Cryptography_STACK_OF_X509_NAME *SSL_load_client_CA_file(const char *);
-"""
+SSL_SESSION *SSL_get_session(const SSL *);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *, unsigned int *);
-MACROS = """
/* not a macro, but older OpenSSLs don't pass the args as const */
char *SSL_CIPHER_description(const SSL_CIPHER *, char *, int);
int SSL_SESSION_print(BIO *, const SSL_SESSION *);
diff --git a/src/_cffi_src/openssl/x509.py b/src/_cffi_src/openssl/x509.py
index c5eb600a..4cdc8274 100644
--- a/src/_cffi_src/openssl/x509.py
+++ b/src/_cffi_src/openssl/x509.py
@@ -36,6 +36,8 @@ typedef struct {
...;
} X509_CINF;
+/* TODO: opaque X509_EXTENSION. Cryptography no longer depends on it being
+ non-opaque but pyOpenSSL needs a release where it doesn't depend on this */
typedef struct {
ASN1_OBJECT *object;
ASN1_BOOLEAN critical;
diff --git a/src/_cffi_src/openssl/x509_vfy.py b/src/_cffi_src/openssl/x509_vfy.py
index f8467a76..13287797 100644
--- a/src/_cffi_src/openssl/x509_vfy.py
+++ b/src/_cffi_src/openssl/x509_vfy.py
@@ -173,8 +173,6 @@ 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 *);
-int X509_STORE_CTX_get_ex_new_index(long, void *, CRYPTO_EX_new *,
- CRYPTO_EX_dup *, CRYPTO_EX_free *);
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *, int, void *);
void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *, int);
@@ -194,6 +192,10 @@ int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *);
"""
MACROS = """
+/* this CRYPTO_EX_DATA function became a macro in 1.1.0 */
+int X509_STORE_CTX_get_ex_new_index(long, void *, CRYPTO_EX_new *,
+ CRYPTO_EX_dup *, CRYPTO_EX_free *);
+
/* X509_STORE_CTX */
void X509_STORE_CTX_set0_crls(X509_STORE_CTX *,
Cryptography_STACK_OF_X509_CRL *);
diff --git a/src/_cffi_src/openssl/x509name.py b/src/_cffi_src/openssl/x509name.py
index 7b833d61..86d50bbd 100644
--- a/src/_cffi_src/openssl/x509name.py
+++ b/src/_cffi_src/openssl/x509name.py
@@ -16,10 +16,7 @@ typedef STACK_OF(X509_NAME_ENTRY) Cryptography_STACK_OF_X509_NAME_ENTRY;
TYPES = """
typedef ... Cryptography_STACK_OF_X509_NAME_ENTRY;
-typedef struct {
- Cryptography_STACK_OF_X509_NAME_ENTRY *entries;
- ...;
-} X509_NAME;
+typedef ... X509_NAME;
typedef ... X509_NAME_ENTRY;
typedef ... Cryptography_STACK_OF_X509_NAME;
"""
@@ -47,6 +44,10 @@ 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 *);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **,
+ ASN1_OBJECT *, int,
+ const unsigned char *, int);
+int X509_NAME_add_entry(X509_NAME *, X509_NAME_ENTRY *, int, int);
"""
MACROS = """
@@ -56,6 +57,9 @@ int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *);
X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int);
void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *);
int sk_X509_NAME_ENTRY_num(Cryptography_STACK_OF_X509_NAME_ENTRY *);
+Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_new_null(void);
+int sk_X509_NAME_ENTRY_push(Cryptography_STACK_OF_X509_NAME_ENTRY *,
+ X509_NAME_ENTRY *);
X509_NAME_ENTRY *sk_X509_NAME_ENTRY_value(
Cryptography_STACK_OF_X509_NAME_ENTRY *, int);
Cryptography_STACK_OF_X509_NAME_ENTRY *sk_X509_NAME_ENTRY_dup(
diff --git a/src/cryptography/hazmat/backends/multibackend.py b/src/cryptography/hazmat/backends/multibackend.py
index 65f18531..48bc7d08 100644
--- a/src/cryptography/hazmat/backends/multibackend.py
+++ b/src/cryptography/hazmat/backends/multibackend.py
@@ -28,6 +28,13 @@ class MultiBackend(object):
name = "multibackend"
def __init__(self, backends):
+ if len(backends) == 0:
+ raise ValueError(
+ "Multibackend cannot be initialized with no backends. If you "
+ "are seeing this error when trying to use default_backend() "
+ "please try uninstalling and reinstalling cryptography."
+ )
+
self._backends = backends
def _filtered_backends(self, interface):
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index e47f747c..064f9ad6 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1003,11 +1003,14 @@ class Backend(object):
x509_revoked, serial_number
)
self.openssl_assert(res == 1)
- res = self._lib.ASN1_TIME_set(
- x509_revoked.revocationDate,
+ rev_date = self._lib.ASN1_TIME_set(
+ self._ffi.NULL,
calendar.timegm(builder._revocation_date.timetuple())
)
- self.openssl_assert(res != self._ffi.NULL)
+ self.openssl_assert(rev_date != self._ffi.NULL)
+ rev_date = self._ffi.gc(rev_date, self._lib.ASN1_TIME_free)
+ res = self._lib.X509_REVOKED_set_revocationDate(x509_revoked, rev_date)
+ self.openssl_assert(res == 1)
# add CRL entry extensions
self._create_x509_extensions(
extensions=builder._extensions,
diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
index 5f828c6b..140d3de4 100644
--- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
@@ -198,7 +198,9 @@ class _X509ExtensionParser(object):
backend.openssl_assert(ext != backend._ffi.NULL)
crit = backend._lib.X509_EXTENSION_get_critical(ext)
critical = crit == 1
- oid = x509.ObjectIdentifier(_obj2txt(backend, ext.object))
+ oid = x509.ObjectIdentifier(
+ _obj2txt(backend, backend._lib.X509_EXTENSION_get_object(ext))
+ )
if oid in seen_oids:
raise x509.DuplicateExtension(
"Duplicate {0} extension found".format(oid), oid
@@ -652,9 +654,10 @@ def _decode_cert_issuer(backend, ext):
"""
data_ptr_ptr = backend._ffi.new("const unsigned char **")
- data_ptr_ptr[0] = ext.value.data
+ value = backend._lib.X509_EXTENSION_get_data(ext)
+ data_ptr_ptr[0] = value.data
gns = backend._lib.d2i_GENERAL_NAMES(
- backend._ffi.NULL, data_ptr_ptr, ext.value.length
+ backend._ffi.NULL, data_ptr_ptr, value.length
)
# Check the result of d2i_GENERAL_NAMES() is valid. Usually this is covered
diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
index 8cdf4c4b..b56dfa70 100644
--- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py
@@ -97,17 +97,8 @@ def _encode_name(backend, attributes):
"""
subject = backend._lib.X509_NAME_new()
for attribute in attributes:
- value = attribute.value.encode('utf8')
- obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
- if attribute.oid == NameOID.COUNTRY_NAME:
- # Per RFC5280 Appendix A.1 countryName should be encoded as
- # PrintableString, not UTF8String
- type = backend._lib.MBSTRING_ASC
- else:
- type = backend._lib.MBSTRING_UTF8
- res = backend._lib.X509_NAME_add_entry_by_OBJ(
- subject, obj, type, value, -1, -1, 0,
- )
+ name_entry = _encode_name_entry(backend, attribute)
+ res = backend._lib.X509_NAME_add_entry(subject, name_entry, -1, 0)
backend.openssl_assert(res == 1)
return subject
@@ -118,6 +109,33 @@ def _encode_name_gc(backend, attributes):
return subject
+def _encode_sk_name_entry(backend, attributes):
+ """
+ The sk_X50_NAME_ENTRY created will not be gc'd.
+ """
+ stack = backend._lib.sk_X509_NAME_ENTRY_new_null()
+ for attribute in attributes:
+ name_entry = _encode_name_entry(backend, attribute)
+ res = backend._lib.sk_X509_NAME_ENTRY_push(stack, name_entry)
+ backend.openssl_assert(res == 1)
+ return stack
+
+
+def _encode_name_entry(backend, attribute):
+ value = attribute.value.encode('utf8')
+ obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
+ if attribute.oid == NameOID.COUNTRY_NAME:
+ # Per RFC5280 Appendix A.1 countryName should be encoded as
+ # PrintableString, not UTF8String
+ type = backend._lib.MBSTRING_ASC
+ else:
+ type = backend._lib.MBSTRING_UTF8
+ name_entry = backend._lib.X509_NAME_ENTRY_create_by_OBJ(
+ backend._ffi.NULL, obj, type, value, -1
+ )
+ return name_entry
+
+
def _encode_crl_number(backend, crl_number):
asn1int = _encode_asn1_int_gc(backend, crl_number.crl_number)
return _encode_extension_to_der(
@@ -516,8 +534,7 @@ def _encode_crl_distribution_points(backend, crl_distribution_points):
dpn = backend._lib.DIST_POINT_NAME_new()
backend.openssl_assert(dpn != backend._ffi.NULL)
dpn.type = _DISTPOINT_TYPE_RELATIVENAME
- name = _encode_name_gc(backend, point.relative_name)
- relativename = backend._lib.sk_X509_NAME_ENTRY_dup(name.entries)
+ relativename = _encode_sk_name_entry(backend, point.relative_name)
backend.openssl_assert(relativename != backend._ffi.NULL)
dpn.name.relativename = relativename
dp.distpoint = dpn
diff --git a/src/cryptography/hazmat/backends/openssl/hashes.py b/src/cryptography/hazmat/backends/openssl/hashes.py
index 02ce5f0d..2c8fce1a 100644
--- a/src/cryptography/hazmat/backends/openssl/hashes.py
+++ b/src/cryptography/hazmat/backends/openssl/hashes.py
@@ -18,9 +18,10 @@ class _HashContext(object):
self._backend = backend
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)
+ ctx = self._backend._lib.Cryptography_EVP_MD_CTX_new()
+ ctx = self._backend._ffi.gc(
+ ctx, self._backend._lib.Cryptography_EVP_MD_CTX_free
+ )
evp_md = self._backend._lib.EVP_get_digestbyname(
algorithm.name.encode("ascii"))
if evp_md == self._backend._ffi.NULL:
@@ -38,9 +39,9 @@ class _HashContext(object):
algorithm = utils.read_only_property("_algorithm")
def copy(self):
- copied_ctx = self._backend._lib.EVP_MD_CTX_create()
+ copied_ctx = self._backend._lib.Cryptography_EVP_MD_CTX_new()
copied_ctx = self._backend._ffi.gc(
- copied_ctx, self._backend._lib.EVP_MD_CTX_destroy
+ copied_ctx, self._backend._lib.Cryptography_EVP_MD_CTX_free
)
res = self._backend._lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx)
self._backend.openssl_assert(res != 0)
@@ -57,6 +58,4 @@ class _HashContext(object):
res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen)
self._backend.openssl_assert(res != 0)
self._backend.openssl_assert(outlen[0] == self.algorithm.digest_size)
- res = self._backend._lib.EVP_MD_CTX_cleanup(self._ctx)
- self._backend.openssl_assert(res == 1)
return self._backend._ffi.buffer(buf)[:outlen[0]]
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 74835716..bf54d5ce 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -4,6 +4,8 @@
from __future__ import absolute_import, division, print_function
+import pytest
+
from cryptography import utils
from cryptography.exceptions import (
UnsupportedAlgorithm, _Reasons
@@ -21,6 +23,10 @@ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from ...utils import raises_unsupported_algorithm
+class DummyBackend(object):
+ pass
+
+
@utils.register_interface(CipherBackend)
class DummyCipherBackend(object):
def __init__(self, supported_ciphers):
@@ -226,6 +232,10 @@ class DummyX509Backend(object):
class TestMultiBackend(object):
+ def test_raises_error_with_empty_list(self):
+ with pytest.raises(ValueError):
+ MultiBackend([])
+
def test_ciphers(self):
backend = MultiBackend([
DummyHashBackend([]),
@@ -310,7 +320,7 @@ class TestMultiBackend(object):
backend.load_rsa_public_numbers("public_numbers")
- backend = MultiBackend([])
+ backend = MultiBackend([DummyBackend()])
with raises_unsupported_algorithm(
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
):
@@ -353,7 +363,7 @@ class TestMultiBackend(object):
backend.load_dsa_public_numbers("numbers")
backend.load_dsa_parameter_numbers("numbers")
- backend = MultiBackend([])
+ backend = MultiBackend([DummyBackend()])
with raises_unsupported_algorithm(
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
):
@@ -491,7 +501,7 @@ class TestMultiBackend(object):
backend.load_pem_private_key(b"keydata", None)
backend.load_pem_public_key(b"keydata")
- backend = MultiBackend([])
+ backend = MultiBackend([DummyBackend()])
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
backend.load_pem_private_key(b"keydata", None)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
@@ -503,7 +513,7 @@ class TestMultiBackend(object):
backend.load_der_private_key(b"keydata", None)
backend.load_der_public_key(b"keydata")
- backend = MultiBackend([])
+ backend = MultiBackend([DummyBackend()])
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
backend.load_der_private_key(b"keydata", None)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_SERIALIZATION):
@@ -523,7 +533,7 @@ class TestMultiBackend(object):
backend.create_x509_crl(object(), b"privatekey", hashes.SHA1())
backend.create_x509_revoked_certificate(object())
- backend = MultiBackend([])
+ backend = MultiBackend([DummyBackend()])
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
backend.load_pem_x509_certificate(b"certdata")
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
diff --git a/vectors/cryptography_vectors/x509/e-trust.ru.der b/vectors/cryptography_vectors/x509/e-trust.ru.der
new file mode 100644
index 00000000..72b581fe
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/e-trust.ru.der
Binary files differ