summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Paul Calderone <exarkun@twistedmatrix.com>2013-12-28 18:04:00 -0500
committerJean-Paul Calderone <exarkun@twistedmatrix.com>2013-12-28 18:04:00 -0500
commit6037d073170d054554405df944136c1ddd9bbf22 (patch)
treece2ac436d23a9f194b581979ce91648fa19ae2e9
parent56bff94b52ae982b45856e09413caed118aae0d3 (diff)
downloadpyopenssl-6037d073170d054554405df944136c1ddd9bbf22.tar.gz
Switch from opentls to cryptography
-rw-r--r--OpenSSL/SSL.py442
-rw-r--r--OpenSSL/__init__.py6
-rw-r--r--OpenSSL/crypto.py762
-rw-r--r--OpenSSL/rand.py30
4 files changed, 623 insertions, 617 deletions
diff --git a/OpenSSL/SSL.py b/OpenSSL/SSL.py
index 521bf78..11edbce 100644
--- a/OpenSSL/SSL.py
+++ b/OpenSSL/SSL.py
@@ -4,7 +4,9 @@ from itertools import count
from weakref import WeakValueDictionary
from errno import errorcode
-from tls.c import api as _api
+from cryptography.hazmat.backends.openssl import backend
+_ffi = backend.ffi
+_lib = backend.lib
from OpenSSL.crypto import (
FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store,
@@ -13,15 +15,15 @@ from OpenSSL.crypto import (
_unspecified = object()
-OPENSSL_VERSION_NUMBER = _api.OPENSSL_VERSION_NUMBER
-SSLEAY_VERSION = _api.SSLEAY_VERSION
-SSLEAY_CFLAGS = _api.SSLEAY_CFLAGS
-SSLEAY_PLATFORM = _api.SSLEAY_PLATFORM
-SSLEAY_DIR = _api.SSLEAY_DIR
-SSLEAY_BUILT_ON = _api.SSLEAY_BUILT_ON
+OPENSSL_VERSION_NUMBER = _lib.OPENSSL_VERSION_NUMBER
+SSLEAY_VERSION = _lib.SSLEAY_VERSION
+SSLEAY_CFLAGS = _lib.SSLEAY_CFLAGS
+SSLEAY_PLATFORM = _lib.SSLEAY_PLATFORM
+SSLEAY_DIR = _lib.SSLEAY_DIR
+SSLEAY_BUILT_ON = _lib.SSLEAY_BUILT_ON
-SENT_SHUTDOWN = _api.SSL_SENT_SHUTDOWN
-RECEIVED_SHUTDOWN = _api.SSL_RECEIVED_SHUTDOWN
+SENT_SHUTDOWN = _lib.SSL_SENT_SHUTDOWN
+RECEIVED_SHUTDOWN = _lib.SSL_RECEIVED_SHUTDOWN
SSLv2_METHOD = 1
SSLv3_METHOD = 2
@@ -30,75 +32,75 @@ TLSv1_METHOD = 4
TLSv1_1_METHOD = 5
TLSv1_2_METHOD = 6
-OP_NO_SSLv2 = _api.SSL_OP_NO_SSLv2
-OP_NO_SSLv3 = _api.SSL_OP_NO_SSLv3
-OP_NO_TLSv1 = _api.SSL_OP_NO_TLSv1
-OP_NO_TLSv1_1 = _api.SSL_OP_NO_TLSv1_1
-OP_NO_TLSv1_2 = _api.SSL_OP_NO_TLSv1_2
-
-MODE_RELEASE_BUFFERS = _api.SSL_MODE_RELEASE_BUFFERS
-
-OP_SINGLE_DH_USE = _api.SSL_OP_SINGLE_DH_USE
-OP_EPHEMERAL_RSA = _api.SSL_OP_EPHEMERAL_RSA
-OP_MICROSOFT_SESS_ID_BUG = _api.SSL_OP_MICROSOFT_SESS_ID_BUG
-OP_NETSCAPE_CHALLENGE_BUG = _api.SSL_OP_NETSCAPE_CHALLENGE_BUG
-OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _api.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
-OP_SSLREF2_REUSE_CERT_TYPE_BUG = _api.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
-OP_MICROSOFT_BIG_SSLV3_BUFFER = _api.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
-OP_MSIE_SSLV2_RSA_PADDING = _api.SSL_OP_MSIE_SSLV2_RSA_PADDING
-OP_SSLEAY_080_CLIENT_DH_BUG = _api.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
-OP_TLS_D5_BUG = _api.SSL_OP_TLS_D5_BUG
-OP_TLS_BLOCK_PADDING_BUG = _api.SSL_OP_TLS_BLOCK_PADDING_BUG
-OP_DONT_INSERT_EMPTY_FRAGMENTS = _api.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
-OP_CIPHER_SERVER_PREFERENCE = _api.SSL_OP_CIPHER_SERVER_PREFERENCE
-OP_TLS_ROLLBACK_BUG = _api.SSL_OP_TLS_ROLLBACK_BUG
-OP_PKCS1_CHECK_1 = _api.SSL_OP_PKCS1_CHECK_1
-OP_PKCS1_CHECK_2 = _api.SSL_OP_PKCS1_CHECK_2
-OP_NETSCAPE_CA_DN_BUG = _api.SSL_OP_NETSCAPE_CA_DN_BUG
-OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _api.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
-OP_NO_COMPRESSION = _api.SSL_OP_NO_COMPRESSION
-
-OP_NO_QUERY_MTU = _api.SSL_OP_NO_QUERY_MTU
-OP_COOKIE_EXCHANGE = _api.SSL_OP_COOKIE_EXCHANGE
-OP_NO_TICKET = _api.SSL_OP_NO_TICKET
-
-OP_ALL = _api.SSL_OP_ALL
-
-VERIFY_PEER = _api.SSL_VERIFY_PEER
-VERIFY_FAIL_IF_NO_PEER_CERT = _api.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
-VERIFY_CLIENT_ONCE = _api.SSL_VERIFY_CLIENT_ONCE
-VERIFY_NONE = _api.SSL_VERIFY_NONE
-
-SESS_CACHE_OFF = _api.SSL_SESS_CACHE_OFF
-SESS_CACHE_CLIENT = _api.SSL_SESS_CACHE_CLIENT
-SESS_CACHE_SERVER = _api.SSL_SESS_CACHE_SERVER
-SESS_CACHE_BOTH = _api.SSL_SESS_CACHE_BOTH
-SESS_CACHE_NO_AUTO_CLEAR = _api.SSL_SESS_CACHE_NO_AUTO_CLEAR
-SESS_CACHE_NO_INTERNAL_LOOKUP = _api.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
-SESS_CACHE_NO_INTERNAL_STORE = _api.SSL_SESS_CACHE_NO_INTERNAL_STORE
-SESS_CACHE_NO_INTERNAL = _api.SSL_SESS_CACHE_NO_INTERNAL
-
-SSL_ST_CONNECT = _api.SSL_ST_CONNECT
-SSL_ST_ACCEPT = _api.SSL_ST_ACCEPT
-SSL_ST_MASK = _api.SSL_ST_MASK
-SSL_ST_INIT = _api.SSL_ST_INIT
-SSL_ST_BEFORE = _api.SSL_ST_BEFORE
-SSL_ST_OK = _api.SSL_ST_OK
-SSL_ST_RENEGOTIATE = _api.SSL_ST_RENEGOTIATE
-
-SSL_CB_LOOP = _api.SSL_CB_LOOP
-SSL_CB_EXIT = _api.SSL_CB_EXIT
-SSL_CB_READ = _api.SSL_CB_READ
-SSL_CB_WRITE = _api.SSL_CB_WRITE
-SSL_CB_ALERT = _api.SSL_CB_ALERT
-SSL_CB_READ_ALERT = _api.SSL_CB_READ_ALERT
-SSL_CB_WRITE_ALERT = _api.SSL_CB_WRITE_ALERT
-SSL_CB_ACCEPT_LOOP = _api.SSL_CB_ACCEPT_LOOP
-SSL_CB_ACCEPT_EXIT = _api.SSL_CB_ACCEPT_EXIT
-SSL_CB_CONNECT_LOOP = _api.SSL_CB_CONNECT_LOOP
-SSL_CB_CONNECT_EXIT = _api.SSL_CB_CONNECT_EXIT
-SSL_CB_HANDSHAKE_START = _api.SSL_CB_HANDSHAKE_START
-SSL_CB_HANDSHAKE_DONE = _api.SSL_CB_HANDSHAKE_DONE
+OP_NO_SSLv2 = _lib.SSL_OP_NO_SSLv2
+OP_NO_SSLv3 = _lib.SSL_OP_NO_SSLv3
+OP_NO_TLSv1 = _lib.SSL_OP_NO_TLSv1
+# OP_NO_TLSv1_1 = _lib.SSL_OP_NO_TLSv1_1
+# OP_NO_TLSv1_2 = _lib.SSL_OP_NO_TLSv1_2
+
+MODE_RELEASE_BUFFERS = _lib.SSL_MODE_RELEASE_BUFFERS
+
+OP_SINGLE_DH_USE = _lib.SSL_OP_SINGLE_DH_USE
+OP_EPHEMERAL_RSA = _lib.SSL_OP_EPHEMERAL_RSA
+OP_MICROSOFT_SESS_ID_BUG = _lib.SSL_OP_MICROSOFT_SESS_ID_BUG
+OP_NETSCAPE_CHALLENGE_BUG = _lib.SSL_OP_NETSCAPE_CHALLENGE_BUG
+OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _lib.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+OP_SSLREF2_REUSE_CERT_TYPE_BUG = _lib.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+OP_MICROSOFT_BIG_SSLV3_BUFFER = _lib.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+OP_MSIE_SSLV2_RSA_PADDING = getattr(_lib, "SSL_OP_MSIE_SSLV2_RSA_PADDING", 0)
+OP_SSLEAY_080_CLIENT_DH_BUG = _lib.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+OP_TLS_D5_BUG = _lib.SSL_OP_TLS_D5_BUG
+OP_TLS_BLOCK_PADDING_BUG = _lib.SSL_OP_TLS_BLOCK_PADDING_BUG
+OP_DONT_INSERT_EMPTY_FRAGMENTS = _lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+OP_CIPHER_SERVER_PREFERENCE = _lib.SSL_OP_CIPHER_SERVER_PREFERENCE
+OP_TLS_ROLLBACK_BUG = _lib.SSL_OP_TLS_ROLLBACK_BUG
+OP_PKCS1_CHECK_1 = _lib.SSL_OP_PKCS1_CHECK_1
+OP_PKCS1_CHECK_2 = _lib.SSL_OP_PKCS1_CHECK_2
+OP_NETSCAPE_CA_DN_BUG = _lib.SSL_OP_NETSCAPE_CA_DN_BUG
+OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _lib.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+OP_NO_COMPRESSION = _lib.SSL_OP_NO_COMPRESSION
+
+OP_NO_QUERY_MTU = _lib.SSL_OP_NO_QUERY_MTU
+OP_COOKIE_EXCHANGE = _lib.SSL_OP_COOKIE_EXCHANGE
+OP_NO_TICKET = _lib.SSL_OP_NO_TICKET
+
+OP_ALL = _lib.SSL_OP_ALL
+
+VERIFY_PEER = _lib.SSL_VERIFY_PEER
+VERIFY_FAIL_IF_NO_PEER_CERT = _lib.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+VERIFY_CLIENT_ONCE = _lib.SSL_VERIFY_CLIENT_ONCE
+VERIFY_NONE = _lib.SSL_VERIFY_NONE
+
+SESS_CACHE_OFF = _lib.SSL_SESS_CACHE_OFF
+SESS_CACHE_CLIENT = _lib.SSL_SESS_CACHE_CLIENT
+SESS_CACHE_SERVER = _lib.SSL_SESS_CACHE_SERVER
+SESS_CACHE_BOTH = _lib.SSL_SESS_CACHE_BOTH
+SESS_CACHE_NO_AUTO_CLEAR = _lib.SSL_SESS_CACHE_NO_AUTO_CLEAR
+SESS_CACHE_NO_INTERNAL_LOOKUP = _lib.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
+SESS_CACHE_NO_INTERNAL_STORE = _lib.SSL_SESS_CACHE_NO_INTERNAL_STORE
+SESS_CACHE_NO_INTERNAL = _lib.SSL_SESS_CACHE_NO_INTERNAL
+
+SSL_ST_CONNECT = _lib.SSL_ST_CONNECT
+SSL_ST_ACCEPT = _lib.SSL_ST_ACCEPT
+SSL_ST_MASK = _lib.SSL_ST_MASK
+SSL_ST_INIT = _lib.SSL_ST_INIT
+SSL_ST_BEFORE = _lib.SSL_ST_BEFORE
+SSL_ST_OK = _lib.SSL_ST_OK
+SSL_ST_RENEGOTIATE = _lib.SSL_ST_RENEGOTIATE
+
+SSL_CB_LOOP = _lib.SSL_CB_LOOP
+SSL_CB_EXIT = _lib.SSL_CB_EXIT
+SSL_CB_READ = _lib.SSL_CB_READ
+SSL_CB_WRITE = _lib.SSL_CB_WRITE
+SSL_CB_ALERT = _lib.SSL_CB_ALERT
+SSL_CB_READ_ALERT = _lib.SSL_CB_READ_ALERT
+SSL_CB_WRITE_ALERT = _lib.SSL_CB_WRITE_ALERT
+SSL_CB_ACCEPT_LOOP = _lib.SSL_CB_ACCEPT_LOOP
+SSL_CB_ACCEPT_EXIT = _lib.SSL_CB_ACCEPT_EXIT
+SSL_CB_CONNECT_LOOP = _lib.SSL_CB_CONNECT_LOOP
+SSL_CB_CONNECT_EXIT = _lib.SSL_CB_CONNECT_EXIT
+SSL_CB_HANDSHAKE_START = _lib.SSL_CB_HANDSHAKE_START
+SSL_CB_HANDSHAKE_DONE = _lib.SSL_CB_HANDSHAKE_DONE
class _VerifyHelper(object):
@@ -108,9 +110,9 @@ class _VerifyHelper(object):
@wraps(callback)
def wrapper(ok, store_ctx):
cert = X509.__new__(X509)
- cert._x509 = _api.X509_STORE_CTX_get_current_cert(store_ctx)
- error_number = _api.X509_STORE_CTX_get_error(store_ctx)
- error_depth = _api.X509_STORE_CTX_get_error_depth(store_ctx)
+ cert._x509 = _lib.X509_STORE_CTX_get_current_cert(store_ctx)
+ error_number = _lib.X509_STORE_CTX_get_error(store_ctx)
+ error_depth = _lib.X509_STORE_CTX_get_error_depth(store_ctx)
try:
result = callback(connection, cert, error_number, error_depth, ok)
@@ -119,12 +121,13 @@ class _VerifyHelper(object):
return 0
else:
if result:
- _api.X509_STORE_CTX_set_error(store_ctx, _api.X509_V_OK)
+ _lib.X509_STORE_CTX_set_error(store_ctx, _lib.X509_V_OK)
return 1
else:
return 0
- self.callback = _api.ffi.callback("verify_callback", wrapper)
+ self.callback = _ffi.callback(
+ "int (*)(int, X509_STORE_CTX *)", wrapper)
def raise_if_problem(self):
@@ -192,7 +195,7 @@ def SSLeay_version(type):
:param type: One of the SSLEAY_ constants defined in this module.
"""
- return _api.string(_api.SSLeay_version(type))
+ return _ffi.string(_lib.SSLeay_version(type))
@@ -207,15 +210,15 @@ class Context(object):
new SSL connections.
"""
_methods = {
- SSLv3_METHOD: _api.SSLv3_method,
- TLSv1_METHOD: _api.TLSv1_method,
- TLSv1_1_METHOD: _api.TLSv1_1_method,
- TLSv1_2_METHOD: _api.TLSv1_2_method,
- SSLv23_METHOD: _api.SSLv23_method,
+ SSLv3_METHOD: _lib.SSLv3_method,
+ TLSv1_METHOD: _lib.TLSv1_method,
+ # TLSv1_1_METHOD: _lib.TLSv1_1_method,
+ # TLSv1_2_METHOD: _lib.TLSv1_2_method,
+ SSLv23_METHOD: _lib.SSLv23_method,
}
- if not _api.PYOPENSSL_NO_SSL2:
- _methods[SSLv2_METHOD] = _api.SSLv2_method
+ if False and not _lib.PYOPENSSL_NO_SSL2:
+ _methods[SSLv2_METHOD] = _lib.SSLv2_method
def __init__(self, method):
"""
@@ -231,14 +234,14 @@ class Context(object):
raise ValueError("No such protocol")
method_obj = method_func()
- if method_obj == _api.NULL:
+ if method_obj == _ffi.NULL:
# XXX TODO what :(
1/0
- context = _api.SSL_CTX_new(method_obj)
- if context == _api.NULL:
+ context = _lib.SSL_CTX_new(method_obj)
+ if context == _ffi.NULL:
1/0
- context = _api.ffi.gc(context, _api.SSL_CTX_free)
+ context = _ffi.gc(context, _lib.SSL_CTX_free)
self._context = context
self._passphrase_helper = None
@@ -254,7 +257,7 @@ class Context(object):
# SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
# SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
# SSL_MODE_AUTO_RETRY);
- self.set_mode(_api.SSL_MODE_ENABLE_PARTIAL_WRITE)
+ self.set_mode(_lib.SSL_MODE_ENABLE_PARTIAL_WRITE)
def load_verify_locations(self, cafile, capath=None):
@@ -267,16 +270,16 @@ class Context(object):
:return: None
"""
if cafile is None:
- cafile = _api.NULL
+ cafile = _ffi.NULL
elif not isinstance(cafile, bytes):
raise TypeError("cafile must be None or a byte string")
if capath is None:
- capath = _api.NULL
+ capath = _ffi.NULL
elif not isinstance(capath, bytes):
raise TypeError("capath must be None or a byte string")
- load_result = _api.SSL_CTX_load_verify_locations(self._context, cafile, capath)
+ load_result = _lib.SSL_CTX_load_verify_locations(self._context, cafile, capath)
if not load_result:
_raise_current_error(Error)
@@ -303,7 +306,7 @@ class Context(object):
self._passphrase_helper = self._wrap_callback(callback)
self._passphrase_callback = self._passphrase_helper.callback
- _api.SSL_CTX_set_default_passwd_cb(
+ _lib.SSL_CTX_set_default_passwd_cb(
self._context, self._passphrase_callback)
self._passphrase_userdata = userdata
@@ -314,7 +317,7 @@ class Context(object):
:return: None
"""
- set_result = _api.SSL_CTX_set_default_verify_paths(self._context)
+ set_result = _lib.SSL_CTX_set_default_verify_paths(self._context)
if not set_result:
1/0
_raise_current_error(Error)
@@ -330,7 +333,7 @@ class Context(object):
if not isinstance(certfile, bytes):
raise TypeError("certfile must be a byte string")
- result = _api.SSL_CTX_use_certificate_chain_file(self._context, certfile)
+ result = _lib.SSL_CTX_use_certificate_chain_file(self._context, certfile)
if not result:
_raise_current_error(Error)
@@ -348,7 +351,7 @@ class Context(object):
if not isinstance(filetype, int):
raise TypeError("filetype must be an integer")
- use_result = _api.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
+ use_result = _lib.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
if not use_result:
_raise_current_error(Error)
@@ -363,7 +366,7 @@ class Context(object):
if not isinstance(cert, X509):
raise TypeError("cert must be an X509 instance")
- use_result = _api.SSL_CTX_use_certificate(self._context, cert._x509)
+ use_result = _lib.SSL_CTX_use_certificate(self._context, cert._x509)
if not use_result:
_raise_current_error(Error)
@@ -378,10 +381,10 @@ class Context(object):
if not isinstance(certobj, X509):
raise TypeError("certobj must be an X509 instance")
- copy = _api.X509_dup(certobj._x509)
- add_result = _api.SSL_CTX_add_extra_chain_cert(self._context, copy)
+ copy = _lib.X509_dup(certobj._x509)
+ add_result = _lib.SSL_CTX_add_extra_chain_cert(self._context, copy)
if not add_result:
- # _api.X509_free(copy)
+ # _lib.X509_free(copy)
# _raise_current_error(Error)
1/0
@@ -410,7 +413,7 @@ class Context(object):
elif not isinstance(filetype, int):
raise TypeError("filetype must be an integer")
- use_result = _api.SSL_CTX_use_PrivateKey_file(
+ use_result = _lib.SSL_CTX_use_PrivateKey_file(
self._context, keyfile, filetype)
if not use_result:
self._raise_passphrase_exception()
@@ -426,7 +429,7 @@ class Context(object):
if not isinstance(pkey, PKey):
raise TypeError("pkey must be a PKey instance")
- use_result = _api.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
+ use_result = _lib.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
if not use_result:
self._raise_passphrase_exception()
@@ -469,14 +472,14 @@ class Context(object):
if not isinstance(mode, int):
raise TypeError("mode must be an integer")
- return _api.SSL_CTX_set_session_cache_mode(self._context, mode)
+ return _lib.SSL_CTX_set_session_cache_mode(self._context, mode)
def get_session_cache_mode(self):
"""
:returns: The currently used cache mode.
"""
- return _api.SSL_CTX_get_session_cache_mode(self._context)
+ return _lib.SSL_CTX_get_session_cache_mode(self._context)
def set_verify(self, mode, callback):
@@ -498,7 +501,7 @@ class Context(object):
self._verify_helper = _VerifyHelper(self, callback)
self._verify_callback = self._verify_helper.callback
- _api.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
+ _lib.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
def set_verify_depth(self, depth):
@@ -511,7 +514,7 @@ class Context(object):
if not isinstance(depth, int):
raise TypeError("depth must be an integer")
- _api.SSL_CTX_set_verify_depth(self._context, depth)
+ _lib.SSL_CTX_set_verify_depth(self._context, depth)
def get_verify_mode(self):
@@ -520,7 +523,7 @@ class Context(object):
:return: The verify mode
"""
- return _api.SSL_CTX_get_verify_mode(self._context)
+ return _lib.SSL_CTX_get_verify_mode(self._context)
def get_verify_depth(self):
@@ -529,7 +532,7 @@ class Context(object):
:return: The verify depth
"""
- return _api.SSL_CTX_get_verify_depth(self._context)
+ return _lib.SSL_CTX_get_verify_depth(self._context)
def load_tmp_dh(self, dhfile):
@@ -542,14 +545,14 @@ class Context(object):
if not isinstance(dhfile, bytes):
raise TypeError("dhfile must be a byte string")
- bio = _api.BIO_new_file(dhfile, "r")
- if bio == _api.NULL:
+ bio = _lib.BIO_new_file(dhfile, "r")
+ if bio == _ffi.NULL:
_raise_current_error(Error)
- bio = _api.ffi.gc(bio, _api.BIO_free)
+ bio = _ffi.gc(bio, _lib.BIO_free)
- dh = _api.PEM_read_bio_DHparams(bio, _api.NULL, _api.NULL, _api.NULL)
- dh = _api.ffi.gc(dh, _api.DH_free)
- _api.SSL_CTX_set_tmp_dh(self._context, dh)
+ dh = _lib.PEM_read_bio_DHparams(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
+ dh = _ffi.gc(dh, _lib.DH_free)
+ _lib.SSL_CTX_set_tmp_dh(self._context, dh)
def set_cipher_list(self, cipher_list):
@@ -562,7 +565,7 @@ class Context(object):
if not isinstance(cipher_list, bytes):
raise TypeError("cipher_list must be a byte string")
- result = _api.SSL_CTX_set_cipher_list(self._context, cipher_list)
+ result = _lib.SSL_CTX_set_cipher_list(self._context, cipher_list)
if not result:
_raise_current_error(Error)
@@ -577,8 +580,8 @@ class Context(object):
:param certificate_authorities: a sequence of X509Names.
:return: None
"""
- name_stack = _api.sk_X509_NAME_new_null()
- if name_stack == _api.NULL:
+ name_stack = _lib.sk_X509_NAME_new_null()
+ if name_stack == _ffi.NULL:
1/0
_raise_current_error(Error)
@@ -588,19 +591,19 @@ class Context(object):
raise TypeError(
"client CAs must be X509Name objects, not %s objects" % (
type(ca_name).__name__,))
- copy = _api.X509_NAME_dup(ca_name._name)
- if copy == _api.NULL:
+ copy = _lib.X509_NAME_dup(ca_name._name)
+ if copy == _ffi.NULL:
1/0
_raise_current_error(Error)
- push_result = _api.sk_X509_NAME_push(name_stack, copy)
+ push_result = _lib.sk_X509_NAME_push(name_stack, copy)
if not push_result:
- _api.X509_NAME_free(copy)
+ _lib.X509_NAME_free(copy)
_raise_current_error(Error)
except:
- _api.sk_X509_NAME_free(name_stack)
+ _lib.sk_X509_NAME_free(name_stack)
raise
- _api.SSL_CTX_set_client_CA_list(self._context, name_stack)
+ _lib.SSL_CTX_set_client_CA_list(self._context, name_stack)
def add_client_ca(self, certificate_authority):
@@ -616,7 +619,7 @@ class Context(object):
if not isinstance(certificate_authority, X509):
raise TypeError("certificate_authority must be an X509 instance")
- add_result = _api.SSL_CTX_add_client_CA(
+ add_result = _lib.SSL_CTX_add_client_CA(
self._context, certificate_authority._x509)
if not add_result:
1/0
@@ -633,7 +636,7 @@ class Context(object):
if not isinstance(timeout, int):
raise TypeError("timeout must be an integer")
- return _api.SSL_CTX_set_timeout(self._context, timeout)
+ return _lib.SSL_CTX_set_timeout(self._context, timeout)
def get_timeout(self):
@@ -642,7 +645,7 @@ class Context(object):
:return: The session timeout
"""
- return _api.SSL_CTX_get_timeout(self._context)
+ return _lib.SSL_CTX_get_timeout(self._context)
def set_info_callback(self, callback):
@@ -655,8 +658,9 @@ class Context(object):
@wraps(callback)
def wrapper(ssl, where, return_code):
callback(self, where, return_code)
- self._info_callback = _api.callback('info_callback', wrapper)
- _api.SSL_CTX_set_info_callback(self._context, self._info_callback)
+ self._info_callback = _ffi.callback(
+ "void (*)(const SSL *, int, int)", wrapper)
+ _lib.SSL_CTX_set_info_callback(self._context, self._info_callback)
def get_app_data(self):
@@ -684,8 +688,8 @@ class Context(object):
:return: A X509Store object
"""
- store = _api.SSL_CTX_get_cert_store(self._context)
- if store == _api.NULL:
+ store = _lib.SSL_CTX_get_cert_store(self._context)
+ if store == _ffi.NULL:
1/0
return None
@@ -704,7 +708,7 @@ class Context(object):
if not isinstance(options, int):
raise TypeError("options must be an integer")
- return _api.SSL_CTX_set_options(self._context, options)
+ return _lib.SSL_CTX_set_options(self._context, options)
def set_mode(self, mode):
@@ -717,7 +721,7 @@ class Context(object):
if not isinstance(mode, int):
raise TypeError("mode must be an integer")
- return _api.SSL_CTX_set_mode(self._context, mode)
+ return _lib.SSL_CTX_set_mode(self._context, mode)
def set_tlsext_servername_callback(self, callback):
@@ -732,9 +736,9 @@ class Context(object):
callback(Connection._reverse_mapping[ssl])
return 0
- self._tlsext_servername_callback = _api.callback(
- "tlsext_servername_callback", wrapper)
- _api.SSL_CTX_set_tlsext_servername_callback(
+ self._tlsext_servername_callback = _ffi.callback(
+ "int (*)(const SSL *, int *, void *)", wrapper)
+ _lib.SSL_CTX_set_tlsext_servername_callback(
self._context, self._tlsext_servername_callback)
ContextType = Context
@@ -757,8 +761,8 @@ class Connection(object):
if not isinstance(context, Context):
raise TypeError("context must be a Context instance")
- ssl = _api.SSL_new(context._context)
- self._ssl = _api.ffi.gc(ssl, _api.SSL_free)
+ ssl = _lib.SSL_new(context._context)
+ self._ssl = _ffi.gc(ssl, _lib.SSL_free)
self._context = context
self._reverse_mapping[self._ssl] = self
@@ -766,18 +770,18 @@ class Connection(object):
if socket is None:
self._socket = None
# Don't set up any gc for these, SSL_free will take care of them.
- self._into_ssl = _api.BIO_new(_api.BIO_s_mem())
- self._from_ssl = _api.BIO_new(_api.BIO_s_mem())
+ self._into_ssl = _lib.BIO_new(_lib.BIO_s_mem())
+ self._from_ssl = _lib.BIO_new(_lib.BIO_s_mem())
- if self._into_ssl == _api.NULL or self._from_ssl == _api.NULL:
+ if self._into_ssl == _ffi.NULL or self._from_ssl == _ffi.NULL:
1/0
- _api.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
+ _lib.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
else:
self._into_ssl = None
self._from_ssl = None
self._socket = socket
- set_result = _api.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
+ set_result = _lib.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
if not set_result:
1/0
@@ -794,29 +798,29 @@ class Connection(object):
if self._context._verify_helper is not None:
self._context._verify_helper.raise_if_problem()
- error = _api.SSL_get_error(ssl, result)
- if error == _api.SSL_ERROR_WANT_READ:
+ error = _lib.SSL_get_error(ssl, result)
+ if error == _lib.SSL_ERROR_WANT_READ:
raise WantReadError()
- elif error == _api.SSL_ERROR_WANT_WRITE:
+ elif error == _lib.SSL_ERROR_WANT_WRITE:
raise WantWriteError()
- elif error == _api.SSL_ERROR_ZERO_RETURN:
+ elif error == _lib.SSL_ERROR_ZERO_RETURN:
raise ZeroReturnError()
- elif error == _api.SSL_ERROR_WANT_X509_LOOKUP:
+ elif error == _lib.SSL_ERROR_WANT_X509_LOOKUP:
# TODO Untested
1/0
raise WantX509LookupError()
- elif error == _api.SSL_ERROR_SYSCALL:
- if _api.ERR_peek_error() == 0:
+ elif error == _lib.SSL_ERROR_SYSCALL:
+ if _lib.ERR_peek_error() == 0:
if result < 0:
raise SysCallError(
- _api.ffi.errno, errorcode[_api.ffi.errno])
+ _ffi.errno, errorcode[_ffi.errno])
else:
raise SysCallError(-1, "Unexpected EOF")
else:
# TODO Untested
1/0
_raise_current_error(Error)
- elif error == _api.SSL_ERROR_NONE:
+ elif error == _lib.SSL_ERROR_NONE:
pass
else:
_raise_current_error(Error)
@@ -839,7 +843,7 @@ class Connection(object):
if not isinstance(context, Context):
raise TypeError("context must be a Context instance")
- _api.SSL_set_SSL_CTX(self._ssl, context._context)
+ _lib.SSL_set_SSL_CTX(self._ssl, context._context)
self._context = context
@@ -850,11 +854,11 @@ class Connection(object):
:return: A byte string giving the server name or :py:data:`None`.
"""
- name = _api.SSL_get_servername(self._ssl, _api.TLSEXT_NAMETYPE_host_name)
- if name == _api.NULL:
+ name = _lib.SSL_get_servername(self._ssl, _lib.TLSEXT_NAMETYPE_host_name)
+ if name == _ffi.NULL:
return None
- return _api.string(name)
+ return _ffi.string(name)
def set_tlsext_host_name(self, name):
@@ -869,7 +873,7 @@ class Connection(object):
raise TypeError("name must not contain NUL byte")
# XXX I guess this can fail sometimes?
- _api.SSL_set_tlsext_host_name(self._ssl, name)
+ _lib.SSL_set_tlsext_host_name(self._ssl, name)
def pending(self):
@@ -878,7 +882,7 @@ class Connection(object):
:return: The number of bytes available in the receive buffer.
"""
- return _api.SSL_pending(self._ssl)
+ return _lib.SSL_pending(self._ssl)
def send(self, buf, flags=0):
@@ -899,7 +903,7 @@ class Connection(object):
if not isinstance(flags, int):
raise TypeError("flags must be an integer")
- result = _api.SSL_write(self._ssl, buf, len(buf))
+ result = _lib.SSL_write(self._ssl, buf, len(buf))
self._raise_ssl_error(self._ssl, result)
return result
write = send
@@ -925,10 +929,10 @@ class Connection(object):
left_to_send = len(buf)
total_sent = 0
- data = _api.new("char[]", buf)
+ data = _ffi.new("char[]", buf)
while left_to_send:
- result = _api.SSL_write(self._ssl, data + total_sent, left_to_send)
+ result = _lib.SSL_write(self._ssl, data + total_sent, left_to_send)
self._raise_ssl_error(self._ssl, result)
total_sent += result
left_to_send -= result
@@ -945,22 +949,22 @@ class Connection(object):
API, the value is ignored
:return: The string read from the Connection
"""
- buf = _api.new("char[]", bufsiz)
- result = _api.SSL_read(self._ssl, buf, bufsiz)
+ buf = _ffi.new("char[]", bufsiz)
+ result = _lib.SSL_read(self._ssl, buf, bufsiz)
self._raise_ssl_error(self._ssl, result)
- return _api.buffer(buf, result)[:]
+ return _ffi.buffer(buf, result)[:]
read = recv
def _handle_bio_errors(self, bio, result):
- if _api.BIO_should_retry(bio):
- if _api.BIO_should_read(bio):
+ if _lib.BIO_should_retry(bio):
+ if _lib.BIO_should_read(bio):
raise WantReadError()
- elif _api.BIO_should_write(bio):
+ elif _lib.BIO_should_write(bio):
# TODO Untested
1/0
raise WantWriteError()
- elif _api.BIO_should_io_special(bio):
+ elif _lib.BIO_should_io_special(bio):
1/0
# TODO Untested. I think io_special means the socket BIO has a
# not-yet connected socket.
@@ -989,12 +993,12 @@ class Connection(object):
if not isinstance(bufsiz, int):
raise TypeError("bufsiz must be an integer")
- buf = _api.new("char[]", bufsiz)
- result = _api.BIO_read(self._from_ssl, buf, bufsiz)
+ buf = _ffi.new("char[]", bufsiz)
+ result = _lib.BIO_read(self._from_ssl, buf, bufsiz)
if result <= 0:
self._handle_bio_errors(self._from_ssl, result)
- return _api.buffer(buf, result)[:]
+ return _ffi.buffer(buf, result)[:]
def bio_write(self, buf):
@@ -1011,7 +1015,7 @@ class Connection(object):
if not isinstance(buf, bytes):
raise TypeError("buf must be a byte string")
- result = _api.BIO_write(self._into_ssl, buf, len(buf))
+ result = _lib.BIO_write(self._into_ssl, buf, len(buf))
if result <= 0:
self._handle_bio_errors(self._into_ssl, result)
return result
@@ -1031,7 +1035,7 @@ class Connection(object):
:return: None.
"""
- result = _api.SSL_do_handshake(self._ssl)
+ result = _lib.SSL_do_handshake(self._ssl)
self._raise_ssl_error(self._ssl, result)
@@ -1049,7 +1053,7 @@ class Connection(object):
:return: The number of renegotiations.
"""
- return _api.SSL_total_renegotiations(self._ssl)
+ return _lib.SSL_total_renegotiations(self._ssl)
def connect(self, addr):
@@ -1059,7 +1063,7 @@ class Connection(object):
:param addr: A remote address
:return: What the socket's connect method returns
"""
- _api.SSL_set_connect_state(self._ssl)
+ _lib.SSL_set_connect_state(self._ssl)
return self._socket.connect(addr)
@@ -1099,7 +1103,7 @@ class Connection(object):
if self._from_ssl is None:
raise TypeError("Connection sock was not None")
- _api.BIO_set_mem_eof_return(self._into_ssl, 0)
+ _lib.BIO_set_mem_eof_return(self._into_ssl, 0)
def shutdown(self):
@@ -1110,7 +1114,7 @@ class Connection(object):
have sent closure alerts), false otherwise (i.e. you have to
wait for a ZeroReturnError on a recv() method call
"""
- result = _api.SSL_shutdown(self._ssl)
+ result = _lib.SSL_shutdown(self._ssl)
if result < 0:
1/0
elif result > 0:
@@ -1127,10 +1131,10 @@ class Connection(object):
"""
ciphers = []
for i in count():
- result = _api.SSL_get_cipher_list(self._ssl, i)
- if result == _api.NULL:
+ result = _lib.SSL_get_cipher_list(self._ssl, i)
+ if result == _ffi.NULL:
break
- ciphers.append(_api.string(result))
+ ciphers.append(_ffi.string(result))
return ciphers
@@ -1144,21 +1148,21 @@ class Connection(object):
the list of such X509Names sent by the server, or an empty list if that
has not yet happened.
"""
- ca_names = _api.SSL_get_client_CA_list(self._ssl)
- if ca_names == _api.NULL:
+ ca_names = _lib.SSL_get_client_CA_list(self._ssl)
+ if ca_names == _ffi.NULL:
1/0
return []
result = []
- for i in range(_api.sk_X509_NAME_num(ca_names)):
- name = _api.sk_X509_NAME_value(ca_names, i)
- copy = _api.X509_NAME_dup(name)
- if copy == _api.NULL:
+ for i in range(_lib.sk_X509_NAME_num(ca_names)):
+ name = _lib.sk_X509_NAME_value(ca_names, i)
+ copy = _lib.X509_NAME_dup(name)
+ if copy == _ffi.NULL:
1/0
_raise_current_error(Error)
pyname = X509Name.__new__(X509Name)
- pyname._name = _api.ffi.gc(copy, _api.X509_NAME_free)
+ pyname._name = _ffi.gc(copy, _lib.X509_NAME_free)
result.append(pyname)
return result
@@ -1198,7 +1202,7 @@ class Connection(object):
:return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
"""
- return _api.SSL_get_shutdown(self._ssl)
+ return _lib.SSL_get_shutdown(self._ssl)
def set_shutdown(self, state):
@@ -1211,7 +1215,7 @@ class Connection(object):
if not isinstance(state, int):
raise TypeError("state must be an integer")
- _api.SSL_set_shutdown(self._ssl, state)
+ _lib.SSL_set_shutdown(self._ssl, state)
def state_string(self):
@@ -1227,11 +1231,11 @@ class Connection(object):
:return: A string representing the state
"""
- if self._ssl.session == _api.NULL:
+ if self._ssl.session == _ffi.NULL:
return None
- return _api.buffer(
+ return _ffi.buffer(
self._ssl.s3.server_random,
- _api.SSL3_RANDOM_SIZE)[:]
+ _lib.SSL3_RANDOM_SIZE)[:]
def client_random(self):
@@ -1240,11 +1244,11 @@ class Connection(object):
:return: A string representing the state
"""
- if self._ssl.session == _api.NULL:
+ if self._ssl.session == _ffi.NULL:
return None
- return _api.buffer(
+ return _ffi.buffer(
self._ssl.s3.client_random,
- _api.SSL3_RANDOM_SIZE)[:]
+ _lib.SSL3_RANDOM_SIZE)[:]
def master_key(self):
@@ -1253,9 +1257,9 @@ class Connection(object):
:return: A string representing the state
"""
- if self._ssl.session == _api.NULL:
+ if self._ssl.session == _ffi.NULL:
return None
- return _api.buffer(
+ return _ffi.buffer(
self._ssl.session.master_key,
self._ssl.session.master_key_length)[:]
@@ -1275,10 +1279,10 @@ class Connection(object):
:return: The peer's certificate
"""
- cert = _api.SSL_get_peer_certificate(self._ssl)
- if cert != _api.NULL:
+ cert = _lib.SSL_get_peer_certificate(self._ssl)
+ if cert != _ffi.NULL:
pycert = X509.__new__(X509)
- pycert._x509 = _api.ffi.gc(cert, _api.X509_free)
+ pycert._x509 = _ffi.gc(cert, _lib.X509_free)
return pycert
return None
@@ -1290,16 +1294,16 @@ class Connection(object):
:return: A list of X509 instances giving the peer's certificate chain,
or None if it does not have one.
"""
- cert_stack = _api.SSL_get_peer_cert_chain(self._ssl)
- if cert_stack == _api.NULL:
+ cert_stack = _lib.SSL_get_peer_cert_chain(self._ssl)
+ if cert_stack == _ffi.NULL:
return None
result = []
- for i in range(_api.sk_X509_num(cert_stack)):
+ for i in range(_lib.sk_X509_num(cert_stack)):
# TODO could incref instead of dup here
- cert = _api.X509_dup(_api.sk_X509_value(cert_stack, i))
+ cert = _lib.X509_dup(_lib.sk_X509_value(cert_stack, i))
pycert = X509.__new__(X509)
- pycert._x509 = _api.ffi.gc(cert, _api.X509_free)
+ pycert._x509 = _ffi.gc(cert, _lib.X509_free)
result.append(pycert)
return result
@@ -1311,7 +1315,7 @@ class Connection(object):
:return: True iff more data has to be read
"""
- return _api.SSL_want_read(self._ssl)
+ return _lib.SSL_want_read(self._ssl)
def want_write(self):
@@ -1321,7 +1325,7 @@ class Connection(object):
:return: True iff there is data to write
"""
- return _api.SSL_want_write(self._ssl)
+ return _lib.SSL_want_write(self._ssl)
def set_accept_state(self):
@@ -1331,7 +1335,7 @@ class Connection(object):
:return: None
"""
- _api.SSL_set_accept_state(self._ssl)
+ _lib.SSL_set_accept_state(self._ssl)
def set_connect_state(self):
@@ -1341,7 +1345,7 @@ class Connection(object):
:return: None
"""
- _api.SSL_set_connect_state(self._ssl)
+ _lib.SSL_set_connect_state(self._ssl)
def get_session(self):
@@ -1351,12 +1355,12 @@ class Connection(object):
@return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
no session exists.
"""
- session = _api.SSL_get1_session(self._ssl)
- if session == _api.NULL:
+ session = _lib.SSL_get1_session(self._ssl)
+ if session == _ffi.NULL:
return None
pysession = Session.__new__(Session)
- pysession._session = _api.ffi.gc(session, _api.SSL_SESSION_free)
+ pysession._session = _ffi.gc(session, _lib.SSL_SESSION_free)
return pysession
@@ -1370,7 +1374,7 @@ class Connection(object):
if not isinstance(session, Session):
raise TypeError("session must be a Session instance")
- result = _api.SSL_set_session(self._ssl, session._session)
+ result = _lib.SSL_set_session(self._ssl, session._session)
if not result:
_raise_current_error(Error)
diff --git a/OpenSSL/__init__.py b/OpenSSL/__init__.py
index c9ea33b..ae47528 100644
--- a/OpenSSL/__init__.py
+++ b/OpenSSL/__init__.py
@@ -33,13 +33,13 @@ else:
del DLFCN
sys.setdlopenflags(flags)
- from OpenSSL import crypto
+ # from OpenSSL import crypto
sys.setdlopenflags(orig)
del orig, flags
del sys
-from OpenSSL import rand, SSL
-from OpenSSL.version import __version__
+# from OpenSSL import rand, SSL
+# from OpenSSL.version import __version__
__all__ = [
'rand', 'crypto', 'SSL', 'tsafe', '__version__']
diff --git a/OpenSSL/crypto.py b/OpenSSL/crypto.py
index da2b08a..1a4db38 100644
--- a/OpenSSL/crypto.py
+++ b/OpenSSL/crypto.py
@@ -1,42 +1,44 @@
from time import time
-from tls.c import api as _api
+from cryptography.hazmat.backends.openssl import backend
+_ffi = backend.ffi
+_lib = backend.lib
-FILETYPE_PEM = _api.SSL_FILETYPE_PEM
-FILETYPE_ASN1 = _api.SSL_FILETYPE_ASN1
+FILETYPE_PEM = _lib.SSL_FILETYPE_PEM
+FILETYPE_ASN1 = _lib.SSL_FILETYPE_ASN1
# TODO This was an API mistake. OpenSSL has no such constant.
FILETYPE_TEXT = 2 ** 16 - 1
-TYPE_RSA = _api.EVP_PKEY_RSA
-TYPE_DSA = _api.EVP_PKEY_DSA
+TYPE_RSA = _lib.EVP_PKEY_RSA
+TYPE_DSA = _lib.EVP_PKEY_DSA
def _bio_to_string(bio):
"""
Copy the contents of an OpenSSL BIO object into a Python byte string.
"""
- result_buffer = _api.new('char**')
- buffer_length = _api.BIO_get_mem_data(bio, result_buffer)
- return _api.buffer(result_buffer[0], buffer_length)[:]
+ result_buffer = _ffi.new('char**')
+ buffer_length = _lib.BIO_get_mem_data(bio, result_buffer)
+ return _ffi.buffer(result_buffer[0], buffer_length)[:]
def _new_mem_buf(buffer=None):
if buffer is None:
- bio = _api.BIO_new(_api.BIO_s_mem())
- free = _api.BIO_free
+ bio = _lib.BIO_new(_lib.BIO_s_mem())
+ free = _lib.BIO_free
else:
- data = _api.ffi.new("char[]", buffer)
- bio = _api.BIO_new_mem_buf(data, len(buffer))
+ data = _ffi.new("char[]", buffer)
+ bio = _lib.BIO_new_mem_buf(data, len(buffer))
# Keep the memory alive as long as the bio is alive!
def free(bio, ref=data):
- return _api.BIO_free(bio)
+ return _lib.BIO_free(bio)
- if bio == _api.NULL:
+ if bio == _ffi.NULL:
1/0
- bio = _api.ffi.gc(bio, free)
+ bio = _ffi.gc(bio, free)
return bio
@@ -45,13 +47,13 @@ def _set_asn1_time(boundary, when):
if not isinstance(when, bytes):
raise TypeError("when must be a byte string")
- set_result = _api.ASN1_GENERALIZEDTIME_set_string(
- _api.cast('ASN1_GENERALIZEDTIME*', boundary), when)
+ set_result = _lib.ASN1_GENERALIZEDTIME_set_string(
+ _ffi.cast('ASN1_GENERALIZEDTIME*', boundary), when)
if set_result == 0:
- dummy = _api.ffi.gc(_api.ASN1_STRING_new(), _api.ASN1_STRING_free)
- _api.ASN1_STRING_set(dummy, when, len(when))
- check_result = _api.ASN1_GENERALIZEDTIME_check(
- _api.cast('ASN1_GENERALIZEDTIME*', dummy))
+ dummy = _ffi.gc(_lib.ASN1_STRING_new(), _lib.ASN1_STRING_free)
+ _lib.ASN1_STRING_set(dummy, when, len(when))
+ check_result = _lib.ASN1_GENERALIZEDTIME_check(
+ _ffi.cast('ASN1_GENERALIZEDTIME*', dummy))
if not check_result:
raise ValueError("Invalid string")
else:
@@ -61,22 +63,22 @@ def _set_asn1_time(boundary, when):
def _get_asn1_time(timestamp):
- string_timestamp = _api.cast('ASN1_STRING*', timestamp)
- if _api.ASN1_STRING_length(string_timestamp) == 0:
+ string_timestamp = _ffi.cast('ASN1_STRING*', timestamp)
+ if _lib.ASN1_STRING_length(string_timestamp) == 0:
return None
- elif _api.ASN1_STRING_type(string_timestamp) == _api.V_ASN1_GENERALIZEDTIME:
- return _api.string(_api.ASN1_STRING_data(string_timestamp))
+ elif _lib.ASN1_STRING_type(string_timestamp) == _lib.V_ASN1_GENERALIZEDTIME:
+ return _ffi.string(_lib.ASN1_STRING_data(string_timestamp))
else:
- generalized_timestamp = _api.new("ASN1_GENERALIZEDTIME**")
- _api.ASN1_TIME_to_generalizedtime(timestamp, generalized_timestamp)
- if generalized_timestamp[0] == _api.NULL:
+ generalized_timestamp = _ffi.new("ASN1_GENERALIZEDTIME**")
+ _lib.ASN1_TIME_to_generalizedtime(timestamp, generalized_timestamp)
+ if generalized_timestamp[0] == _ffi.NULL:
1/0
else:
- string_timestamp = _api.cast(
+ string_timestamp = _ffi.cast(
"ASN1_STRING*", generalized_timestamp[0])
- string_data = _api.ASN1_STRING_data(string_timestamp)
- string_result = _api.string(string_data)
- _api.ASN1_GENERALIZEDTIME_free(generalized_timestamp[0])
+ string_data = _lib.ASN1_STRING_data(string_timestamp)
+ string_result = _ffi.string(string_data)
+ _lib.ASN1_GENERALIZEDTIME_free(generalized_timestamp[0])
return string_result
@@ -89,13 +91,13 @@ class Error(Exception):
def _raise_current_error(exceptionType=Error):
errors = []
while True:
- error = _api.ERR_get_error()
+ error = _lib.ERR_get_error()
if error == 0:
break
errors.append((
- _api.string(_api.ERR_lib_error_string(error)),
- _api.string(_api.ERR_func_error_string(error)),
- _api.string(_api.ERR_reason_error_string(error))))
+ _ffi.string(_lib.ERR_lib_error_string(error)),
+ _ffi.string(_lib.ERR_func_error_string(error)),
+ _ffi.string(_lib.ERR_reason_error_string(error))))
raise exceptionType(errors)
@@ -108,8 +110,8 @@ class PKey(object):
_initialized = True
def __init__(self):
- pkey = _api.EVP_PKEY_new()
- self._pkey = _api.ffi.gc(pkey, _api.EVP_PKEY_free)
+ pkey = _lib.EVP_PKEY_new()
+ self._pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free)
self._initialized = False
@@ -129,32 +131,32 @@ class PKey(object):
raise TypeError("bits must be an integer")
# TODO Check error return
- exponent = _api.BN_new()
- exponent = _api.ffi.gc(exponent, _api.BN_free)
- _api.BN_set_word(exponent, _api.RSA_F4)
+ exponent = _lib.BN_new()
+ exponent = _ffi.gc(exponent, _lib.BN_free)
+ _lib.BN_set_word(exponent, _lib.RSA_F4)
if type == TYPE_RSA:
if bits <= 0:
raise ValueError("Invalid number of bits")
- rsa = _api.RSA_new()
+ rsa = _lib.RSA_new()
- result = _api.RSA_generate_key_ex(rsa, bits, exponent, _api.NULL)
+ result = _lib.RSA_generate_key_ex(rsa, bits, exponent, _ffi.NULL)
if result == -1:
1/0
- result = _api.EVP_PKEY_assign_RSA(self._pkey, rsa)
+ result = _lib.EVP_PKEY_assign_RSA(self._pkey, rsa)
if not result:
1/0
elif type == TYPE_DSA:
- dsa = _api.DSA_generate_parameters(
- bits, _api.NULL, 0, _api.NULL, _api.NULL, _api.NULL, _api.NULL)
- if dsa == _api.NULL:
+ dsa = _lib.DSA_generate_parameters(
+ bits, _ffi.NULL, 0, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL)
+ if dsa == _ffi.NULL:
1/0
- if not _api.DSA_generate_key(dsa):
+ if not _lib.DSA_generate_key(dsa):
1/0
- if not _api.EVP_PKEY_assign_DSA(self._pkey, dsa):
+ if not _lib.EVP_PKEY_assign_DSA(self._pkey, dsa):
1/0
else:
raise Error("No such key type")
@@ -174,12 +176,12 @@ class PKey(object):
if self._only_public:
raise TypeError("public key only")
- if _api.EVP_PKEY_type(self._pkey.type) != _api.EVP_PKEY_RSA:
+ if _lib.EVP_PKEY_type(self._pkey.type) != _lib.EVP_PKEY_RSA:
raise TypeError("key type unsupported")
- rsa = _api.EVP_PKEY_get1_RSA(self._pkey)
- rsa = _api.ffi.gc(rsa, _api.RSA_free)
- result = _api.RSA_check_key(rsa)
+ rsa = _lib.EVP_PKEY_get1_RSA(self._pkey)
+ rsa = _ffi.gc(rsa, _lib.RSA_free)
+ result = _lib.RSA_check_key(rsa)
if result:
return True
_raise_current_error()
@@ -200,7 +202,7 @@ class PKey(object):
:return: The number of bits of the key.
"""
- return _api.EVP_PKEY_bits(self._pkey)
+ return _lib.EVP_PKEY_bits(self._pkey)
PKeyType = PKey
@@ -212,8 +214,8 @@ class X509Name(object):
:param name: An X509Name object to copy
"""
- name = _api.X509_NAME_dup(name._name)
- self._name = _api.ffi.gc(name, _api.X509_NAME_free)
+ name = _lib.X509_NAME_dup(name._name)
+ self._name = _ffi.gc(name, _lib.X509_NAME_free)
def __setattr__(self, name, value):
@@ -226,8 +228,8 @@ class X509Name(object):
raise TypeError("attribute name must be string, not '%.200s'" % (
type(value).__name__,))
- nid = _api.OBJ_txt2nid(name)
- if nid == _api.NID_undef:
+ nid = _lib.OBJ_txt2nid(name)
+ if nid == _lib.NID_undef:
try:
_raise_current_error()
except Error:
@@ -235,20 +237,20 @@ class X509Name(object):
raise AttributeError("No such attribute")
# If there's an old entry for this NID, remove it
- for i in range(_api.X509_NAME_entry_count(self._name)):
- ent = _api.X509_NAME_get_entry(self._name, i)
- ent_obj = _api.X509_NAME_ENTRY_get_object(ent)
- ent_nid = _api.OBJ_obj2nid(ent_obj)
+ for i in range(_lib.X509_NAME_entry_count(self._name)):
+ ent = _lib.X509_NAME_get_entry(self._name, i)
+ ent_obj = _lib.X509_NAME_ENTRY_get_object(ent)
+ ent_nid = _lib.OBJ_obj2nid(ent_obj)
if nid == ent_nid:
- ent = _api.X509_NAME_delete_entry(self._name, i)
- _api.X509_NAME_ENTRY_free(ent)
+ ent = _lib.X509_NAME_delete_entry(self._name, i)
+ _lib.X509_NAME_ENTRY_free(ent)
break
if isinstance(value, unicode):
value = value.encode('utf-8')
- add_result = _api.X509_NAME_add_entry_by_NID(
- self._name, nid, _api.MBSTRING_UTF8, value, -1, -1, 0)
+ add_result = _lib.X509_NAME_add_entry_by_NID(
+ self._name, nid, _lib.MBSTRING_UTF8, value, -1, -1, 0)
if not add_result:
# TODO Untested
1/0
@@ -261,8 +263,8 @@ class X509Name(object):
organization (alias O), organizationalUnit (alias OU), commonName (alias
CN) and more...
"""
- nid = _api.OBJ_txt2nid(name)
- if nid == _api.NID_undef:
+ nid = _lib.OBJ_txt2nid(name)
+ if nid == _lib.NID_undef:
# This is a bit weird. OBJ_txt2nid indicated failure, but it seems
# a lower level function, a2d_ASN1_OBJECT, also feels the need to
# push something onto the error queue. If we don't clean that up
@@ -274,23 +276,23 @@ class X509Name(object):
pass
return super(X509Name, self).__getattr__(name)
- entry_index = _api.X509_NAME_get_index_by_NID(self._name, nid, -1)
+ entry_index = _lib.X509_NAME_get_index_by_NID(self._name, nid, -1)
if entry_index == -1:
return None
- entry = _api.X509_NAME_get_entry(self._name, entry_index)
- data = _api.X509_NAME_ENTRY_get_data(entry)
+ entry = _lib.X509_NAME_get_entry(self._name, entry_index)
+ data = _lib.X509_NAME_ENTRY_get_data(entry)
- result_buffer = _api.new("unsigned char**")
- data_length = _api.ASN1_STRING_to_UTF8(result_buffer, data)
+ result_buffer = _ffi.new("unsigned char**")
+ data_length = _lib.ASN1_STRING_to_UTF8(result_buffer, data)
if data_length < 0:
1/0
try:
- result = _api.buffer(result_buffer[0], data_length)[:].decode('utf-8')
+ result = _ffi.buffer(result_buffer[0], data_length)[:].decode('utf-8')
finally:
# XXX untested
- _api.OPENSSL_free(result_buffer[0])
+ _lib.OPENSSL_free(result_buffer[0])
return result
@@ -298,7 +300,7 @@ class X509Name(object):
if not isinstance(other, X509Name):
return NotImplemented
- result = _api.X509_NAME_cmp(self._name, other._name)
+ result = _lib.X509_NAME_cmp(self._name, other._name)
# TODO result == -2 is an error case that maybe should be checked for
return result
@@ -307,14 +309,14 @@ class X509Name(object):
"""
String representation of an X509Name
"""
- result_buffer = _api.new("char[]", 512);
- format_result = _api.X509_NAME_oneline(
+ result_buffer = _ffi.new("char[]", 512);
+ format_result = _lib.X509_NAME_oneline(
self._name, result_buffer, len(result_buffer))
- if format_result == _api.NULL:
+ if format_result == _ffi.NULL:
1/0
- return "<X509Name object '%s'>" % (_api.string(result_buffer),)
+ return "<X509Name object '%s'>" % (_ffi.string(result_buffer),)
def hash(self):
@@ -323,7 +325,7 @@ class X509Name(object):
:return: None
"""
- return _api.X509_NAME_hash(self._name)
+ return _lib.X509_NAME_hash(self._name)
def der(self):
@@ -333,13 +335,13 @@ class X509Name(object):
:return: A :py:class:`bytes` instance giving the DER encoded form of
this name.
"""
- result_buffer = _api.new('unsigned char**')
- encode_result = _api.i2d_X509_NAME(self._name, result_buffer)
+ result_buffer = _ffi.new('unsigned char**')
+ encode_result = _lib.i2d_X509_NAME(self._name, result_buffer)
if encode_result < 0:
1/0
- string_result = _api.buffer(result_buffer[0], encode_result)[:]
- _api.OPENSSL_free(result_buffer[0])
+ string_result = _ffi.buffer(result_buffer[0], encode_result)[:]
+ _lib.OPENSSL_free(result_buffer[0])
return string_result
@@ -350,20 +352,20 @@ class X509Name(object):
:return: List of tuples (name, value).
"""
result = []
- for i in range(_api.X509_NAME_entry_count(self._name)):
- ent = _api.X509_NAME_get_entry(self._name, i)
+ for i in range(_lib.X509_NAME_entry_count(self._name)):
+ ent = _lib.X509_NAME_get_entry(self._name, i)
- fname = _api.X509_NAME_ENTRY_get_object(ent)
- fval = _api.X509_NAME_ENTRY_get_data(ent)
+ fname = _lib.X509_NAME_ENTRY_get_object(ent)
+ fval = _lib.X509_NAME_ENTRY_get_data(ent)
- nid = _api.OBJ_obj2nid(fname)
- name = _api.OBJ_nid2sn(nid)
+ nid = _lib.OBJ_obj2nid(fname)
+ name = _lib.OBJ_nid2sn(nid)
result.append((
- _api.string(name),
- _api.string(
- _api.ASN1_STRING_data(fval),
- _api.ASN1_STRING_length(fval))))
+ _ffi.string(name),
+ _ffi.string(
+ _lib.ASN1_STRING_data(fval),
+ _lib.ASN1_STRING_length(fval))))
return result
X509NameType = X509Name
@@ -388,16 +390,16 @@ class X509Extension(object):
:return: The X509Extension object
"""
- ctx = _api.new("X509V3_CTX*")
+ ctx = _ffi.new("X509V3_CTX*")
# A context is necessary for any extension which uses the r2i conversion
# method. That is, X509V3_EXT_nconf may segfault if passed a NULL ctx.
# Start off by initializing most of the fields to NULL.
- _api.X509V3_set_ctx(ctx, _api.NULL, _api.NULL, _api.NULL, _api.NULL, 0)
+ _lib.X509V3_set_ctx(ctx, _ffi.NULL, _ffi.NULL, _ffi.NULL, _ffi.NULL, 0)
# We have no configuration database - but perhaps we should (some
# extensions may require it).
- _api.X509V3_set_ctx_nodb(ctx)
+ _lib.X509V3_set_ctx_nodb(ctx)
# Initialize the subject and issuer, if appropriate. ctx is a local,
# and as far as I can tell none of the X509V3_* APIs invoked here steal
@@ -421,54 +423,52 @@ class X509Extension(object):
# ext_struc it desires for its last parameter, though.)
value = "critical," + value
- extension = _api.X509V3_EXT_nconf(_api.NULL, ctx, type_name, value)
- if extension == _api.NULL:
+ extension = _lib.X509V3_EXT_nconf(_ffi.NULL, ctx, type_name, value)
+ if extension == _ffi.NULL:
_raise_current_error()
- self._extension = _api.ffi.gc(extension, _api.X509_EXTENSION_free)
+ self._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free)
@property
def _nid(self):
- return _api.OBJ_obj2nid(self._extension.object)
+ return _lib.OBJ_obj2nid(self._extension.object)
_prefixes = {
- _api.GEN_EMAIL: b"email",
- _api.GEN_DNS: b"DNS",
- _api.GEN_URI: b"URI",
+ _lib.GEN_EMAIL: b"email",
+ _lib.GEN_DNS: b"DNS",
+ _lib.GEN_URI: b"URI",
}
def _subjectAltNameString(self):
- method = _api.X509V3_EXT_get(self._extension)
- if method == _api.NULL:
+ method = _lib.X509V3_EXT_get(self._extension)
+ if method == _ffi.NULL:
1/0
payload = self._extension.value.data
length = self._extension.value.length
- payloadptr = _api.new("unsigned char**")
+ payloadptr = _ffi.new("unsigned char**")
payloadptr[0] = payload
- if method.it != _api.NULL:
- names = _api.cast(
- "GENERAL_NAMES*",
- _api.ASN1_item_d2i(
- _api.NULL, payloadptr, length,
- _api.ASN1_ITEM_ptr(method.it)))
+ if method.it != _ffi.NULL:
+ ptr = _lib.ASN1_ITEM_ptr(method.it)
+ data = _lib.ASN1_item_d2i(_ffi.NULL, payloadptr, length, ptr)
+ names = _ffi.cast("GENERAL_NAMES*", data)
else:
- names = _api.cast(
+ names = _ffi.cast(
"GENERAL_NAMES*",
- method.d2i(_api.NULL, payloadptr, length))
+ method.d2i(_ffi.NULL, payloadptr, length))
parts = []
- for i in range(_api.sk_GENERAL_NAME_num(names)):
- name = _api.sk_GENERAL_NAME_value(names, i)
+ for i in range(_lib.sk_GENERAL_NAME_num(names)):
+ name = _lib.sk_GENERAL_NAME_value(names, i)
try:
label = self._prefixes[name.type]
except KeyError:
bio = _new_mem_buf()
- _api.GENERAL_NAME_print(bio, name)
+ _lib.GENERAL_NAME_print(bio, name)
parts.append(_bio_to_string(bio))
else:
- value = _api.buffer(name.d.ia5.data, name.d.ia5.length)[:]
+ value = _ffi.buffer(name.d.ia5.data, name.d.ia5.length)[:]
parts.append(label + b":" + value)
return b", ".join(parts)
@@ -477,11 +477,11 @@ class X509Extension(object):
"""
:return: a nice text representation of the extension
"""
- if _api.NID_subject_alt_name == self._nid:
+ if _lib.NID_subject_alt_name == self._nid:
return self._subjectAltNameString()
bio = _new_mem_buf()
- print_result = _api.X509V3_EXT_print(bio, self._extension, 0, 0)
+ print_result = _lib.X509V3_EXT_print(bio, self._extension, 0, 0)
if not print_result:
1/0
@@ -494,7 +494,7 @@ class X509Extension(object):
:return: The critical field.
"""
- return _api.X509_EXTENSION_get_critical(self._extension)
+ return _lib.X509_EXTENSION_get_critical(self._extension)
def get_short_name(self):
@@ -503,9 +503,9 @@ class X509Extension(object):
:return: The short type name.
"""
- obj = _api.X509_EXTENSION_get_object(self._extension)
- nid = _api.OBJ_obj2nid(obj)
- return _api.string(_api.OBJ_nid2sn(nid))
+ obj = _lib.X509_EXTENSION_get_object(self._extension)
+ nid = _lib.OBJ_obj2nid(obj)
+ return _ffi.string(_lib.OBJ_nid2sn(nid))
def get_data(self):
@@ -514,19 +514,19 @@ class X509Extension(object):
:return: A :py:data:`str` giving the X509Extension's ASN.1 encoded data.
"""
- octet_result = _api.X509_EXTENSION_get_data(self._extension)
- string_result = _api.cast('ASN1_STRING*', octet_result)
- char_result = _api.ASN1_STRING_data(string_result)
- result_length = _api.ASN1_STRING_length(string_result)
- return _api.buffer(char_result, result_length)[:]
+ octet_result = _lib.X509_EXTENSION_get_data(self._extension)
+ string_result = _ffi.cast('ASN1_STRING*', octet_result)
+ char_result = _lib.ASN1_STRING_data(string_result)
+ result_length = _lib.ASN1_STRING_length(string_result)
+ return _ffi.buffer(char_result, result_length)[:]
X509ExtensionType = X509Extension
class X509Req(object):
def __init__(self):
- req = _api.X509_REQ_new()
- self._req = _api.ffi.gc(req, _api.X509_REQ_free)
+ req = _lib.X509_REQ_new()
+ self._req = _ffi.gc(req, _lib.X509_REQ_free)
def set_pubkey(self, pkey):
@@ -536,7 +536,7 @@ class X509Req(object):
:param pkey: The public key to use
:return: None
"""
- set_result = _api.X509_REQ_set_pubkey(self._req, pkey._pkey)
+ set_result = _lib.X509_REQ_set_pubkey(self._req, pkey._pkey)
if not set_result:
1/0
@@ -548,10 +548,10 @@ class X509Req(object):
:return: The public key
"""
pkey = PKey.__new__(PKey)
- pkey._pkey = _api.X509_REQ_get_pubkey(self._req)
- if pkey._pkey == _api.NULL:
+ pkey._pkey = _lib.X509_REQ_get_pubkey(self._req)
+ if pkey._pkey == _ffi.NULL:
1/0
- pkey._pkey = _api.ffi.gc(pkey._pkey, _api.EVP_PKEY_free)
+ pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
pkey._only_public = True
return pkey
@@ -564,7 +564,7 @@ class X509Req(object):
:param version: The version number
:return: None
"""
- set_result = _api.X509_REQ_set_version(self._req, version)
+ set_result = _lib.X509_REQ_set_version(self._req, version)
if not set_result:
_raise_current_error()
@@ -576,7 +576,7 @@ class X509Req(object):
:return: an integer giving the value of the version subfield
"""
- return _api.X509_REQ_get_version(self._req)
+ return _lib.X509_REQ_get_version(self._req)
def get_subject(self):
@@ -586,8 +586,8 @@ class X509Req(object):
:return: An X509Name object
"""
name = X509Name.__new__(X509Name)
- name._name = _api.X509_REQ_get_subject_name(self._req)
- if name._name == _api.NULL:
+ name._name = _lib.X509_REQ_get_subject_name(self._req)
+ if name._name == _ffi.NULL:
1/0
# The name is owned by the X509Req structure. As long as the X509Name
@@ -604,20 +604,20 @@ class X509Req(object):
:param extensions: a sequence of X509Extension objects
:return: None
"""
- stack = _api.sk_X509_EXTENSION_new_null()
- if stack == _api.NULL:
+ stack = _lib.sk_X509_EXTENSION_new_null()
+ if stack == _ffi.NULL:
1/0
- stack = _api.ffi.gc(stack, _api.sk_X509_EXTENSION_free)
+ stack = _ffi.gc(stack, _lib.sk_X509_EXTENSION_free)
for ext in extensions:
if not isinstance(ext, X509Extension):
raise ValueError("One of the elements is not an X509Extension")
# TODO push can fail (here and elsewhere)
- _api.sk_X509_EXTENSION_push(stack, ext._extension)
+ _lib.sk_X509_EXTENSION_push(stack, ext._extension)
- add_result = _api.X509_REQ_add_extensions(self._req, stack)
+ add_result = _lib.X509_REQ_add_extensions(self._req, stack)
if not add_result:
1/0
@@ -636,11 +636,11 @@ class X509Req(object):
if not pkey._initialized:
raise ValueError("Key is uninitialized")
- digest_obj = _api.EVP_get_digestbyname(digest)
- if digest_obj == _api.NULL:
+ digest_obj = _lib.EVP_get_digestbyname(digest)
+ if digest_obj == _ffi.NULL:
raise ValueError("No such digest method")
- sign_result = _api.X509_REQ_sign(self._req, pkey._pkey, digest_obj)
+ sign_result = _lib.X509_REQ_sign(self._req, pkey._pkey, digest_obj)
if not sign_result:
1/0
@@ -658,7 +658,7 @@ class X509Req(object):
if not isinstance(pkey, PKey):
raise TypeError("pkey must be a PKey instance")
- result = _api.X509_REQ_verify(self._req, pkey._pkey)
+ result = _lib.X509_REQ_verify(self._req, pkey._pkey)
if result <= 0:
_raise_current_error(Error)
@@ -672,8 +672,8 @@ X509ReqType = X509Req
class X509(object):
def __init__(self):
# TODO Allocation failure? And why not __new__ instead of __init__?
- x509 = _api.X509_new()
- self._x509 = _api.ffi.gc(x509, _api.X509_free)
+ x509 = _lib.X509_new()
+ self._x509 = _ffi.gc(x509, _lib.X509_free)
def set_version(self, version):
@@ -688,7 +688,7 @@ class X509(object):
if not isinstance(version, int):
raise TypeError("version must be an integer")
- _api.X509_set_version(self._x509, version)
+ _lib.X509_set_version(self._x509, version)
def get_version(self):
@@ -697,7 +697,7 @@ class X509(object):
:return: Version number as a Python integer
"""
- return _api.X509_get_version(self._x509)
+ return _lib.X509_get_version(self._x509)
def get_pubkey(self):
@@ -707,10 +707,10 @@ class X509(object):
:return: The public key
"""
pkey = PKey.__new__(PKey)
- pkey._pkey = _api.X509_get_pubkey(self._x509)
- if pkey._pkey == _api.NULL:
+ pkey._pkey = _lib.X509_get_pubkey(self._x509)
+ if pkey._pkey == _ffi.NULL:
_raise_current_error()
- pkey._pkey = _api.ffi.gc(pkey._pkey, _api.EVP_PKEY_free)
+ pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
pkey._only_public = True
return pkey
@@ -726,7 +726,7 @@ class X509(object):
if not isinstance(pkey, PKey):
raise TypeError("pkey must be a PKey instance")
- set_result = _api.X509_set_pubkey(self._x509, pkey._pkey)
+ set_result = _lib.X509_set_pubkey(self._x509, pkey._pkey)
if not set_result:
_raise_current_error()
@@ -748,11 +748,11 @@ class X509(object):
if not pkey._initialized:
raise ValueError("Key is uninitialized")
- evp_md = _api.EVP_get_digestbyname(digest)
- if evp_md == _api.NULL:
+ evp_md = _lib.EVP_get_digestbyname(digest)
+ if evp_md == _ffi.NULL:
raise ValueError("No such digest method")
- sign_result = _api.X509_sign(self._x509, pkey._pkey, evp_md)
+ sign_result = _lib.X509_sign(self._x509, pkey._pkey, evp_md)
if not sign_result:
_raise_current_error()
@@ -766,10 +766,10 @@ class X509(object):
:raise ValueError: If the signature algorithm is undefined.
"""
alg = self._x509.cert_info.signature.algorithm
- nid = _api.OBJ_obj2nid(alg)
- if nid == _api.NID_undef:
+ nid = _lib.OBJ_obj2nid(alg)
+ if nid == _lib.NID_undef:
raise ValueError("Undefined signature algorithm")
- return _api.string(_api.OBJ_nid2ln(nid))
+ return _ffi.string(_lib.OBJ_nid2ln(nid))
def digest(self, digest_name):
@@ -781,15 +781,15 @@ class X509(object):
:return: The digest of the object
"""
- digest = _api.EVP_get_digestbyname(digest_name)
- if digest == _api.NULL:
+ digest = _lib.EVP_get_digestbyname(digest_name)
+ if digest == _ffi.NULL:
raise ValueError("No such digest method")
- result_buffer = _api.new("char[]", _api.EVP_MAX_MD_SIZE)
- result_length = _api.new("unsigned int[]", 1)
+ result_buffer = _ffi.new("char[]", _lib.EVP_MAX_MD_SIZE)
+ result_length = _ffi.new("unsigned int[]", 1)
result_length[0] = len(result_buffer)
- digest_result = _api.X509_digest(
+ digest_result = _lib.X509_digest(
self._x509, digest, result_buffer, result_length)
if not digest_result:
@@ -797,7 +797,7 @@ class X509(object):
return ':'.join([
ch.encode('hex').upper() for ch
- in _api.buffer(result_buffer, result_length[0])])
+ in _ffi.buffer(result_buffer, result_length[0])])
def subject_name_hash(self):
@@ -806,7 +806,7 @@ class X509(object):
:return: The hash of the subject.
"""
- return _api.X509_subject_name_hash(self._x509)
+ return _lib.X509_subject_name_hash(self._x509)
def set_serial_number(self, serial):
@@ -825,27 +825,27 @@ class X509(object):
if not isinstance(hex_serial, bytes):
hex_serial = hex_serial.encode('ascii')
- bignum_serial = _api.new("BIGNUM**")
+ bignum_serial = _ffi.new("BIGNUM**")
# BN_hex2bn stores the result in &bignum. Unless it doesn't feel like
# it. If bignum is still NULL after this call, then the return value is
# actually the result. I hope. -exarkun
- small_serial = _api.BN_hex2bn(bignum_serial, hex_serial)
+ small_serial = _lib.BN_hex2bn(bignum_serial, hex_serial)
- if bignum_serial[0] == _api.NULL:
- set_result = ASN1_INTEGER_set(
- _api.X509_get_serialNumber(self._x509), small_serial)
+ if bignum_serial[0] == _ffi.NULL:
+ set_result = _lib.ASN1_INTEGER_set(
+ _lib.X509_get_serialNumber(self._x509), small_serial)
if set_result:
# TODO Not tested
_raise_current_error()
else:
- asn1_serial = _api.BN_to_ASN1_INTEGER(bignum_serial[0], _api.NULL)
- _api.BN_free(bignum_serial[0])
- if asn1_serial == _api.NULL:
+ asn1_serial = _lib.BN_to_ASN1_INTEGER(bignum_serial[0], _ffi.NULL)
+ _lib.BN_free(bignum_serial[0])
+ if asn1_serial == _ffi.NULL:
# TODO Not tested
_raise_current_error()
- asn1_serial = _api.ffi.gc(asn1_serial, _api.ASN1_INTEGER_free)
- set_result = _api.X509_set_serialNumber(self._x509, asn1_serial)
+ asn1_serial = _ffi.gc(asn1_serial, _lib.ASN1_INTEGER_free)
+ set_result = _lib.X509_set_serialNumber(self._x509, asn1_serial)
if not set_result:
# TODO Not tested
_raise_current_error()
@@ -857,18 +857,18 @@ class X509(object):
:return: Serial number as a Python integer
"""
- asn1_serial = _api.X509_get_serialNumber(self._x509)
- bignum_serial = _api.ASN1_INTEGER_to_BN(asn1_serial, _api.NULL)
+ asn1_serial = _lib.X509_get_serialNumber(self._x509)
+ bignum_serial = _lib.ASN1_INTEGER_to_BN(asn1_serial, _ffi.NULL)
try:
- hex_serial = _api.BN_bn2hex(bignum_serial)
+ hex_serial = _lib.BN_bn2hex(bignum_serial)
try:
- hexstring_serial = _api.string(hex_serial)
+ hexstring_serial = _ffi.string(hex_serial)
serial = int(hexstring_serial, 16)
return serial
finally:
- _api.OPENSSL_free(hex_serial)
+ _lib.OPENSSL_free(hex_serial)
finally:
- _api.BN_free(bignum_serial)
+ _lib.BN_free(bignum_serial)
def gmtime_adj_notAfter(self, amount):
@@ -884,8 +884,8 @@ class X509(object):
if not isinstance(amount, int):
raise TypeError("amount must be an integer")
- notAfter = _api.X509_get_notAfter(self._x509)
- _api.X509_gmtime_adj(notAfter, amount)
+ notAfter = _lib.X509_get_notAfter(self._x509)
+ _lib.X509_gmtime_adj(notAfter, amount)
def gmtime_adj_notBefore(self, amount):
@@ -900,8 +900,8 @@ class X509(object):
if not isinstance(amount, int):
raise TypeError("amount must be an integer")
- notBefore = _api.X509_get_notBefore(self._x509)
- _api.X509_gmtime_adj(notBefore, amount)
+ notBefore = _lib.X509_get_notBefore(self._x509)
+ _lib.X509_gmtime_adj(notBefore, amount)
def has_expired(self):
@@ -911,9 +911,9 @@ class X509(object):
:return: True if the certificate has expired, false otherwise
"""
now = int(time())
- notAfter = _api.X509_get_notAfter(self._x509)
- return _api.ASN1_UTCTIME_cmp_time_t(
- _api.cast('ASN1_UTCTIME*', notAfter), now) < 0
+ notAfter = _lib.X509_get_notAfter(self._x509)
+ return _lib.ASN1_UTCTIME_cmp_time_t(
+ _ffi.cast('ASN1_UTCTIME*', notAfter), now) < 0
def _get_boundary_time(self, which):
@@ -932,7 +932,7 @@ class X509(object):
or None if there is no value set.
"""
- return self._get_boundary_time(_api.X509_get_notBefore)
+ return self._get_boundary_time(_lib.X509_get_notBefore)
def _set_boundary_time(self, which, when):
@@ -952,7 +952,7 @@ class X509(object):
:return: None
"""
- return self._set_boundary_time(_api.X509_get_notBefore, when)
+ return self._set_boundary_time(_lib.X509_get_notBefore, when)
def get_notAfter(self):
@@ -967,7 +967,7 @@ class X509(object):
or None if there is no value set.
"""
- return self._get_boundary_time(_api.X509_get_notAfter)
+ return self._get_boundary_time(_lib.X509_get_notAfter)
def set_notAfter(self, when):
@@ -983,13 +983,13 @@ class X509(object):
:return: None
"""
- return self._set_boundary_time(_api.X509_get_notAfter, when)
+ return self._set_boundary_time(_lib.X509_get_notAfter, when)
def _get_name(self, which):
name = X509Name.__new__(X509Name)
name._name = which(self._x509)
- if name._name == _api.NULL:
+ if name._name == _ffi.NULL:
1/0
# The name is owned by the X509 structure. As long as the X509Name
@@ -1013,7 +1013,7 @@ class X509(object):
:return: An X509Name object
"""
- return self._get_name(_api.X509_get_issuer_name)
+ return self._get_name(_lib.X509_get_issuer_name)
def set_issuer(self, issuer):
@@ -1025,7 +1025,7 @@ class X509(object):
:return: None
"""
- return self._set_name(_api.X509_set_issuer_name, issuer)
+ return self._set_name(_lib.X509_set_issuer_name, issuer)
def get_subject(self):
@@ -1034,7 +1034,7 @@ class X509(object):
:return: An X509Name object
"""
- return self._get_name(_api.X509_get_subject_name)
+ return self._get_name(_lib.X509_get_subject_name)
def set_subject(self, subject):
@@ -1045,7 +1045,7 @@ class X509(object):
:type subject: :py:class:`X509Name`
:return: None
"""
- return self._set_name(_api.X509_set_subject_name, subject)
+ return self._set_name(_lib.X509_set_subject_name, subject)
def get_extension_count(self):
@@ -1054,7 +1054,7 @@ class X509(object):
:return: The number of extensions as an integer.
"""
- return _api.X509_get_ext_count(self._x509)
+ return _lib.X509_get_ext_count(self._x509)
def add_extensions(self, extensions):
@@ -1068,7 +1068,7 @@ class X509(object):
if not isinstance(ext, X509Extension):
raise ValueError("One of the elements is not an X509Extension")
- add_result = _api.X509_add_ext(self._x509, ext._extension, -1)
+ add_result = _lib.X509_add_ext(self._x509, ext._extension, -1)
if not add_result:
_raise_current_error()
@@ -1081,12 +1081,12 @@ class X509(object):
:return: The X509Extension object at the specified index.
"""
ext = X509Extension.__new__(X509Extension)
- ext._extension = _api.X509_get_ext(self._x509, index)
- if ext._extension == _api.NULL:
+ ext._extension = _lib.X509_get_ext(self._x509, index)
+ if ext._extension == _ffi.NULL:
raise IndexError("extension index out of bounds")
- extension = _api.X509_EXTENSION_dup(ext._extension)
- ext._extension = _api.ffi.gc(extension, _api.X509_EXTENSION_free)
+ extension = _lib.X509_EXTENSION_dup(ext._extension)
+ ext._extension = _ffi.gc(extension, _lib.X509_EXTENSION_free)
return ext
X509Type = X509
@@ -1095,15 +1095,15 @@ X509Type = X509
class X509Store(object):
def __init__(self):
- store = _api.X509_STORE_new()
- self._store = _api.ffi.gc(store, _api.X509_STORE_free)
+ store = _lib.X509_STORE_new()
+ self._store = _ffi.gc(store, _lib.X509_STORE_free)
def add_cert(self, cert):
if not isinstance(cert, X509):
raise TypeError()
- result = _api.X509_STORE_add_cert(self._store, cert._x509)
+ result = _lib.X509_STORE_add_cert(self._store, cert._x509)
if not result:
_raise_current_error(Error)
@@ -1126,18 +1126,18 @@ def load_certificate(type, buffer):
bio = _new_mem_buf(buffer)
if type == FILETYPE_PEM:
- x509 = _api.PEM_read_bio_X509(bio, _api.NULL, _api.NULL, _api.NULL)
+ x509 = _lib.PEM_read_bio_X509(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
elif type == FILETYPE_ASN1:
- x509 = _api.d2i_X509_bio(bio, _api.NULL);
+ x509 = _lib.d2i_X509_bio(bio, _ffi.NULL);
else:
raise ValueError(
"type argument must be FILETYPE_PEM or FILETYPE_ASN1")
- if x509 == _api.NULL:
+ if x509 == _ffi.NULL:
_raise_current_error()
cert = X509.__new__(X509)
- cert._x509 = _api.ffi.gc(x509, _api.X509_free)
+ cert._x509 = _ffi.gc(x509, _lib.X509_free)
return cert
@@ -1153,11 +1153,11 @@ def dump_certificate(type, cert):
bio = _new_mem_buf()
if type == FILETYPE_PEM:
- result_code = _api.PEM_write_bio_X509(bio, cert._x509)
+ result_code = _lib.PEM_write_bio_X509(bio, cert._x509)
elif type == FILETYPE_ASN1:
- result_code = _api.i2d_X509_bio(bio, cert._x509)
+ result_code = _lib.i2d_X509_bio(bio, cert._x509)
elif type == FILETYPE_TEXT:
- result_code = _api.X509_print_ex(bio, cert._x509, 0, 0)
+ result_code = _lib.X509_print_ex(bio, cert._x509, 0, 0)
else:
raise ValueError(
"type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
@@ -1185,23 +1185,23 @@ def dump_privatekey(type, pkey, cipher=None, passphrase=None):
bio = _new_mem_buf()
if cipher is not None:
- cipher_obj = _api.EVP_get_cipherbyname(cipher)
- if cipher_obj == _api.NULL:
+ cipher_obj = _lib.EVP_get_cipherbyname(cipher)
+ if cipher_obj == _ffi.NULL:
raise ValueError("Invalid cipher name")
else:
- cipher_obj = _api.NULL
+ cipher_obj = _ffi.NULL
helper = _PassphraseHelper(type, passphrase)
if type == FILETYPE_PEM:
- result_code = _api.PEM_write_bio_PrivateKey(
- bio, pkey._pkey, cipher_obj, _api.NULL, 0,
+ result_code = _lib.PEM_write_bio_PrivateKey(
+ bio, pkey._pkey, cipher_obj, _ffi.NULL, 0,
helper.callback, helper.callback_args)
helper.raise_if_problem()
elif type == FILETYPE_ASN1:
- result_code = _api.i2d_PrivateKey_bio(bio, pkey._pkey)
+ result_code = _lib.i2d_PrivateKey_bio(bio, pkey._pkey)
elif type == FILETYPE_TEXT:
- rsa = _api.EVP_PKEY_get1_RSA(pkey._pkey)
- result_code = _api.RSA_print(bio, rsa, 0)
+ rsa = _lib.EVP_PKEY_get1_RSA(pkey._pkey)
+ result_code = _lib.RSA_print(bio, rsa, 0)
# TODO RSA_free(rsa)?
else:
raise ValueError(
@@ -1216,22 +1216,22 @@ def dump_privatekey(type, pkey, cipher=None, passphrase=None):
def _X509_REVOKED_dup(original):
- copy = _api.X509_REVOKED_new()
- if copy == _api.NULL:
+ copy = _lib.X509_REVOKED_new()
+ if copy == _ffi.NULL:
1/0
- if original.serialNumber != _api.NULL:
- copy.serialNumber = _api.ASN1_INTEGER_dup(original.serialNumber)
+ if original.serialNumber != _ffi.NULL:
+ copy.serialNumber = _lib.ASN1_INTEGER_dup(original.serialNumber)
- if original.revocationDate != _api.NULL:
- copy.revocationDate = _api.M_ASN1_TIME_dup(original.revocationDate)
+ if original.revocationDate != _ffi.NULL:
+ copy.revocationDate = _lib.M_ASN1_TIME_dup(original.revocationDate)
- if original.extensions != _api.NULL:
- extension_stack = _api.sk_X509_EXTENSION_new_null()
- for i in range(_api.sk_X509_EXTENSION_num(original.extensions)):
- original_ext = _api.sk_X509_EXTENSION_value(original.extensions, i)
- copy_ext = _api.X509_EXTENSION_dup(original_ext)
- _api.sk_X509_EXTENSION_push(extension_stack, copy_ext)
+ if original.extensions != _ffi.NULL:
+ extension_stack = _lib.sk_X509_EXTENSION_new_null()
+ for i in range(_lib.sk_X509_EXTENSION_num(original.extensions)):
+ original_ext = _lib.sk_X509_EXTENSION_value(original.extensions, i)
+ copy_ext = _lib.X509_EXTENSION_dup(original_ext)
+ _lib.sk_X509_EXTENSION_push(extension_stack, copy_ext)
copy.extensions = extension_stack
copy.sequence = original.sequence
@@ -1256,8 +1256,8 @@ class Revoked(object):
]
def __init__(self):
- revoked = _api.X509_REVOKED_new()
- self._revoked = _api.ffi.gc(revoked, _api.X509_REVOKED_free)
+ revoked = _lib.X509_REVOKED_new()
+ self._revoked = _ffi.gc(revoked, _lib.X509_REVOKED_free)
def set_serial(self, hex_str):
@@ -1268,17 +1268,17 @@ class Revoked(object):
:type hex_str: :py:data:`str`
:return: None
"""
- bignum_serial = _api.ffi.gc(_api.BN_new(), _api.BN_free)
- bignum_ptr = _api.new("BIGNUM**")
+ bignum_serial = _ffi.gc(_lib.BN_new(), _lib.BN_free)
+ bignum_ptr = _ffi.new("BIGNUM**")
bignum_ptr[0] = bignum_serial
- bn_result = _api.BN_hex2bn(bignum_ptr, hex_str)
+ bn_result = _lib.BN_hex2bn(bignum_ptr, hex_str)
if not bn_result:
raise ValueError("bad hex string")
- asn1_serial = _api.ffi.gc(
- _api.BN_to_ASN1_INTEGER(bignum_serial, _api.NULL),
- _api.ASN1_INTEGER_free)
- _api.X509_REVOKED_set_serialNumber(self._revoked, asn1_serial)
+ asn1_serial = _ffi.gc(
+ _lib.BN_to_ASN1_INTEGER(bignum_serial, _ffi.NULL),
+ _lib.ASN1_INTEGER_free)
+ _lib.X509_REVOKED_set_serialNumber(self._revoked, asn1_serial)
def get_serial(self):
@@ -1289,7 +1289,7 @@ class Revoked(object):
"""
bio = _new_mem_buf()
- result = _api.i2a_ASN1_INTEGER(bio, self._revoked.serialNumber)
+ result = _lib.i2a_ASN1_INTEGER(bio, self._revoked.serialNumber)
if result < 0:
1/0
@@ -1298,11 +1298,11 @@ class Revoked(object):
def _delete_reason(self):
stack = self._revoked.extensions
- for i in range(_api.sk_X509_EXTENSION_num(stack)):
- ext = _api.sk_X509_EXTENSION_value(stack, i)
- if _api.OBJ_obj2nid(ext.object) == _api.NID_crl_reason:
- _api.X509_EXTENSION_free(ext)
- _api.sk_X509_EXTENSION_delete(stack, i)
+ for i in range(_lib.sk_X509_EXTENSION_num(stack)):
+ ext = _lib.sk_X509_EXTENSION_value(stack, i)
+ if _lib.OBJ_obj2nid(ext.object) == _lib.NID_crl_reason:
+ _lib.X509_EXTENSION_free(ext)
+ _lib.sk_X509_EXTENSION_delete(stack, i)
break
@@ -1324,18 +1324,18 @@ class Revoked(object):
reason = reason.lower().replace(' ', '')
reason_code = [r.lower() for r in self._crl_reasons].index(reason)
- new_reason_ext = _api.ASN1_ENUMERATED_new()
- if new_reason_ext == _api.NULL:
+ new_reason_ext = _lib.ASN1_ENUMERATED_new()
+ if new_reason_ext == _ffi.NULL:
1/0
- new_reason_ext = _api.ffi.gc(new_reason_ext, _api.ASN1_ENUMERATED_free)
+ new_reason_ext = _ffi.gc(new_reason_ext, _lib.ASN1_ENUMERATED_free)
- set_result = _api.ASN1_ENUMERATED_set(new_reason_ext, reason_code)
- if set_result == _api.NULL:
+ set_result = _lib.ASN1_ENUMERATED_set(new_reason_ext, reason_code)
+ if set_result == _ffi.NULL:
1/0
self._delete_reason()
- add_result = _api.X509_REVOKED_add1_ext_i2d(
- self._revoked, _api.NID_crl_reason, new_reason_ext, 0, 0)
+ add_result = _lib.X509_REVOKED_add1_ext_i2d(
+ self._revoked, _lib.NID_crl_reason, new_reason_ext, 0, 0)
if not add_result:
1/0
@@ -1348,14 +1348,14 @@ class Revoked(object):
:return: The reason as a string
"""
extensions = self._revoked.extensions
- for i in range(_api.sk_X509_EXTENSION_num(extensions)):
- ext = _api.sk_X509_EXTENSION_value(extensions, i)
- if _api.OBJ_obj2nid(ext.object) == _api.NID_crl_reason:
+ for i in range(_lib.sk_X509_EXTENSION_num(extensions)):
+ ext = _lib.sk_X509_EXTENSION_value(extensions, i)
+ if _lib.OBJ_obj2nid(ext.object) == _lib.NID_crl_reason:
bio = _new_mem_buf()
- print_result = _api.X509V3_EXT_print(bio, ext, 0, 0)
+ print_result = _lib.X509V3_EXT_print(bio, ext, 0, 0)
if not print_result:
- print_result = _api.M_ASN1_OCTET_STRING_print(bio, ext.value)
+ print_result = _lib.M_ASN1_OCTET_STRING_print(bio, ext.value)
if print_result == 0:
1/0
@@ -1405,8 +1405,8 @@ class CRL(object):
"""
Create a new empty CRL object.
"""
- crl = _api.X509_CRL_new()
- self._crl = _api.ffi.gc(crl, _api.X509_CRL_free)
+ crl = _lib.X509_CRL_new()
+ self._crl = _ffi.gc(crl, _lib.X509_CRL_free)
def get_revoked(self):
@@ -1417,11 +1417,11 @@ class CRL(object):
"""
results = []
revoked_stack = self._crl.crl.revoked
- for i in range(_api.sk_X509_REVOKED_num(revoked_stack)):
- revoked = _api.sk_X509_REVOKED_value(revoked_stack, i)
+ for i in range(_lib.sk_X509_REVOKED_num(revoked_stack)):
+ revoked = _lib.sk_X509_REVOKED_value(revoked_stack, i)
revoked_copy = _X509_REVOKED_dup(revoked)
pyrev = Revoked.__new__(Revoked)
- pyrev._revoked = _api.ffi.gc(revoked_copy, _api.X509_REVOKED_free)
+ pyrev._revoked = _ffi.gc(revoked_copy, _lib.X509_REVOKED_free)
results.append(pyrev)
if results:
return tuple(results)
@@ -1437,10 +1437,10 @@ class CRL(object):
:return: None
"""
copy = _X509_REVOKED_dup(revoked._revoked)
- if copy == _api.NULL:
+ if copy == _ffi.NULL:
1/0
- add_result = _api.X509_CRL_add0_revoked(self._crl, copy)
+ add_result = _lib.X509_CRL_add0_revoked(self._crl, copy)
# TODO what check on add_result?
@@ -1468,33 +1468,33 @@ class CRL(object):
if not isinstance(type, int):
raise TypeError("type must be an integer")
- bio = _api.BIO_new(_api.BIO_s_mem())
- if bio == _api.NULL:
+ bio = _lib.BIO_new(_lib.BIO_s_mem())
+ if bio == _ffi.NULL:
1/0
# A scratch time object to give different values to different CRL fields
- sometime = _api.ASN1_TIME_new()
- if sometime == _api.NULL:
+ sometime = _lib.ASN1_TIME_new()
+ if sometime == _ffi.NULL:
1/0
- _api.X509_gmtime_adj(sometime, 0)
- _api.X509_CRL_set_lastUpdate(self._crl, sometime)
+ _lib.X509_gmtime_adj(sometime, 0)
+ _lib.X509_CRL_set_lastUpdate(self._crl, sometime)
- _api.X509_gmtime_adj(sometime, days * 24 * 60 * 60)
- _api.X509_CRL_set_nextUpdate(self._crl, sometime)
+ _lib.X509_gmtime_adj(sometime, days * 24 * 60 * 60)
+ _lib.X509_CRL_set_nextUpdate(self._crl, sometime)
- _api.X509_CRL_set_issuer_name(self._crl, _api.X509_get_subject_name(cert._x509))
+ _lib.X509_CRL_set_issuer_name(self._crl, _lib.X509_get_subject_name(cert._x509))
- sign_result = _api.X509_CRL_sign(self._crl, key._pkey, _api.EVP_md5())
+ sign_result = _lib.X509_CRL_sign(self._crl, key._pkey, _lib.EVP_md5())
if not sign_result:
_raise_current_error()
if type == FILETYPE_PEM:
- ret = _api.PEM_write_bio_X509_CRL(bio, self._crl)
+ ret = _lib.PEM_write_bio_X509_CRL(bio, self._crl)
elif type == FILETYPE_ASN1:
- ret = _api.i2d_X509_CRL_bio(bio, self._crl)
+ ret = _lib.i2d_X509_CRL_bio(bio, self._crl)
elif type == FILETYPE_TEXT:
- ret = _api.X509_CRL_print(bio, self._crl)
+ ret = _lib.X509_CRL_print(bio, self._crl)
else:
raise ValueError(
"type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT")
@@ -1514,7 +1514,7 @@ class PKCS7(object):
:return: True if the PKCS7 is of type signed
"""
- if _api.PKCS7_type_is_signed(self._pkcs7):
+ if _lib.PKCS7_type_is_signed(self._pkcs7):
return True
return False
@@ -1525,7 +1525,7 @@ class PKCS7(object):
:returns: True if the PKCS7 is of type enveloped
"""
- if _api.PKCS7_type_is_enveloped(self._pkcs7):
+ if _lib.PKCS7_type_is_enveloped(self._pkcs7):
return True
return False
@@ -1536,7 +1536,7 @@ class PKCS7(object):
:returns: True if the PKCS7 is of type signedAndEnveloped
"""
- if _api.PKCS7_type_is_signedAndEnveloped(self._pkcs7):
+ if _lib.PKCS7_type_is_signedAndEnveloped(self._pkcs7):
return True
return False
@@ -1547,7 +1547,7 @@ class PKCS7(object):
:return: True if the PKCS7 is of type data
"""
- if _api.PKCS7_type_is_data(self._pkcs7):
+ if _lib.PKCS7_type_is_data(self._pkcs7):
return True
return False
@@ -1558,9 +1558,9 @@ class PKCS7(object):
:return: A string with the typename
"""
- nid = _api.OBJ_obj2nid(self._pkcs7.type)
- string_type = _api.OBJ_nid2sn(nid)
- return _api.string(string_type)
+ nid = _lib.OBJ_obj2nid(self._pkcs7.type)
+ string_type = _lib.OBJ_nid2sn(nid)
+ return _ffi.string(string_type)
PKCS7Type = PKCS7
@@ -1687,41 +1687,41 @@ class PKCS12(object):
:return: The string containing the PKCS12
"""
if self._cacerts is None:
- cacerts = _api.NULL
+ cacerts = _ffi.NULL
else:
- cacerts = _api.sk_X509_new_null()
- cacerts = _api.ffi.gc(cacerts, _api.sk_X509_free)
+ cacerts = _lib.sk_X509_new_null()
+ cacerts = _ffi.gc(cacerts, _lib.sk_X509_free)
for cert in self._cacerts:
- _api.sk_X509_push(cacerts, cert._x509)
+ _lib.sk_X509_push(cacerts, cert._x509)
if passphrase is None:
- passphrase = _api.NULL
+ passphrase = _ffi.NULL
friendlyname = self._friendlyname
if friendlyname is None:
- friendlyname = _api.NULL
+ friendlyname = _ffi.NULL
if self._pkey is None:
- pkey = _api.NULL
+ pkey = _ffi.NULL
else:
pkey = self._pkey._pkey
if self._cert is None:
- cert = _api.NULL
+ cert = _ffi.NULL
else:
cert = self._cert._x509
- pkcs12 = _api.PKCS12_create(
+ pkcs12 = _lib.PKCS12_create(
passphrase, friendlyname, pkey, cert, cacerts,
- _api.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
- _api.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+ _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+ _lib.NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
iter, maciter, 0)
- if pkcs12 == _api.NULL:
+ if pkcs12 == _ffi.NULL:
_raise_current_error()
- pkcs12 = _api.ffi.gc(pkcs12, _api.PKCS12_free)
+ pkcs12 = _ffi.gc(pkcs12, _lib.PKCS12_free)
bio = _new_mem_buf()
- _api.i2d_PKCS12_bio(bio, pkcs12)
+ _lib.i2d_PKCS12_bio(bio, pkcs12)
return _bio_to_string(bio)
PKCS12Type = PKCS12
@@ -1730,8 +1730,8 @@ PKCS12Type = PKCS12
class NetscapeSPKI(object):
def __init__(self):
- spki = _api.NETSCAPE_SPKI_new()
- self._spki = _api.ffi.gc(spki, _api.NETSCAPE_SPKI_free)
+ spki = _lib.NETSCAPE_SPKI_new()
+ self._spki = _ffi.gc(spki, _lib.NETSCAPE_SPKI_free)
def sign(self, pkey, digest):
@@ -1748,11 +1748,11 @@ class NetscapeSPKI(object):
if not pkey._initialized:
raise ValueError("Key is uninitialized")
- digest_obj = _api.EVP_get_digestbyname(digest)
- if digest_obj == _api.NULL:
+ digest_obj = _lib.EVP_get_digestbyname(digest)
+ if digest_obj == _ffi.NULL:
raise ValueError("No such digest method")
- sign_result = _api.NETSCAPE_SPKI_sign(self._spki, pkey._pkey, digest_obj)
+ sign_result = _lib.NETSCAPE_SPKI_sign(self._spki, pkey._pkey, digest_obj)
if not sign_result:
1/0
@@ -1766,7 +1766,7 @@ class NetscapeSPKI(object):
:raise OpenSSL.crypto.Error: If the signature is invalid or there is a
problem verifying the signature.
"""
- answer = _api.NETSCAPE_SPKI_verify(self._spki, key._pkey)
+ answer = _lib.NETSCAPE_SPKI_verify(self._spki, key._pkey)
if answer <= 0:
_raise_current_error()
return True
@@ -1778,9 +1778,9 @@ class NetscapeSPKI(object):
:return: The base64 encoded string
"""
- encoded = _api.NETSCAPE_SPKI_b64_encode(self._spki)
- result = _api.string(encoded)
- _api.CRYPTO_free(encoded)
+ encoded = _lib.NETSCAPE_SPKI_b64_encode(self._spki)
+ result = _ffi.string(encoded)
+ _lib.CRYPTO_free(encoded)
return result
@@ -1791,10 +1791,10 @@ class NetscapeSPKI(object):
:return: The public key
"""
pkey = PKey.__new__(PKey)
- pkey._pkey = _api.NETSCAPE_SPKI_get_pubkey(self._spki)
- if pkey._pkey == _api.NULL:
+ pkey._pkey = _lib.NETSCAPE_SPKI_get_pubkey(self._spki)
+ if pkey._pkey == _ffi.NULL:
1/0
- pkey._pkey = _api.ffi.gc(pkey._pkey, _api.EVP_PKEY_free)
+ pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
pkey._only_public = True
return pkey
@@ -1806,7 +1806,7 @@ class NetscapeSPKI(object):
:param pkey: The public key
:return: None
"""
- set_result = _api.NETSCAPE_SPKI_set_pubkey(self._spki, pkey._pkey)
+ set_result = _lib.NETSCAPE_SPKI_set_pubkey(self._spki, pkey._pkey)
if not set_result:
1/0
NetscapeSPKIType = NetscapeSPKI
@@ -1825,11 +1825,11 @@ class _PassphraseHelper(object):
@property
def callback(self):
if self._passphrase is None:
- return _api.NULL
+ return _ffi.NULL
elif isinstance(self._passphrase, bytes):
- return _api.NULL
+ return _ffi.NULL
elif callable(self._passphrase):
- return _api.callback("pem_password_cb", self._read_passphrase)
+ return _ffi.callback("pem_password_cb", self._read_passphrase)
else:
raise TypeError("Last argument must be string or callable")
@@ -1837,11 +1837,11 @@ class _PassphraseHelper(object):
@property
def callback_args(self):
if self._passphrase is None:
- return _api.NULL
+ return _ffi.NULL
elif isinstance(self._passphrase, bytes):
return self._passphrase
elif callable(self._passphrase):
- return _api.NULL
+ return _ffi.NULL
else:
raise TypeError("Last argument must be string or callable")
@@ -1894,19 +1894,19 @@ def load_privatekey(type, buffer, passphrase=None):
helper = _PassphraseHelper(type, passphrase)
if type == FILETYPE_PEM:
- evp_pkey = _api.PEM_read_bio_PrivateKey(
- bio, _api.NULL, helper.callback, helper.callback_args)
+ evp_pkey = _lib.PEM_read_bio_PrivateKey(
+ bio, _ffi.NULL, helper.callback, helper.callback_args)
helper.raise_if_problem()
elif type == FILETYPE_ASN1:
- evp_pkey = _api.d2i_PrivateKey_bio(bio, _api.NULL)
+ evp_pkey = _lib.d2i_PrivateKey_bio(bio, _ffi.NULL)
else:
raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")
- if evp_pkey == _api.NULL:
+ if evp_pkey == _ffi.NULL:
_raise_current_error()
pkey = PKey.__new__(PKey)
- pkey._pkey = _api.ffi.gc(evp_pkey, _api.EVP_PKEY_free)
+ pkey._pkey = _ffi.gc(evp_pkey, _lib.EVP_PKEY_free)
return pkey
@@ -1922,11 +1922,11 @@ def dump_certificate_request(type, req):
bio = _new_mem_buf()
if type == FILETYPE_PEM:
- result_code = _api.PEM_write_bio_X509_REQ(bio, req._req)
+ result_code = _lib.PEM_write_bio_X509_REQ(bio, req._req)
elif type == FILETYPE_ASN1:
- result_code = _api.i2d_X509_REQ_bio(bio, req._req)
+ result_code = _lib.i2d_X509_REQ_bio(bio, req._req)
elif type == FILETYPE_TEXT:
- result_code = _api.X509_REQ_print_ex(bio, req._req, 0, 0)
+ result_code = _lib.X509_REQ_print_ex(bio, req._req, 0, 0)
else:
raise ValueError("type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT")
@@ -1948,17 +1948,17 @@ def load_certificate_request(type, buffer):
bio = _new_mem_buf(buffer)
if type == FILETYPE_PEM:
- req = _api.PEM_read_bio_X509_REQ(bio, _api.NULL, _api.NULL, _api.NULL)
+ req = _lib.PEM_read_bio_X509_REQ(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
elif type == FILETYPE_ASN1:
- req = _api.d2i_X509_REQ_bio(bio, _api.NULL)
+ req = _lib.d2i_X509_REQ_bio(bio, _ffi.NULL)
else:
1/0
- if req == _api.NULL:
+ if req == _ffi.NULL:
1/0
x509req = X509Req.__new__(X509Req)
- x509req._req = _api.ffi.gc(req, _api.X509_REQ_free)
+ x509req._req = _ffi.gc(req, _lib.X509_REQ_free)
return x509req
@@ -1972,26 +1972,26 @@ def sign(pkey, data, digest):
:param digest: message digest to use
:return: signature
"""
- digest_obj = _api.EVP_get_digestbyname(digest)
- if digest_obj == _api.NULL:
+ digest_obj = _lib.EVP_get_digestbyname(digest)
+ if digest_obj == _ffi.NULL:
raise ValueError("No such digest method")
- md_ctx = _api.new("EVP_MD_CTX*")
- md_ctx = _api.ffi.gc(md_ctx, _api.EVP_MD_CTX_cleanup)
+ md_ctx = _ffi.new("EVP_MD_CTX*")
+ md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup)
- _api.EVP_SignInit(md_ctx, digest_obj)
- _api.EVP_SignUpdate(md_ctx, data, len(data))
+ _lib.EVP_SignInit(md_ctx, digest_obj)
+ _lib.EVP_SignUpdate(md_ctx, data, len(data))
- signature_buffer = _api.new("unsigned char[]", 512)
- signature_length = _api.new("unsigned int*")
+ signature_buffer = _ffi.new("unsigned char[]", 512)
+ signature_length = _ffi.new("unsigned int*")
signature_length[0] = len(signature_buffer)
- final_result = _api.EVP_SignFinal(
+ final_result = _lib.EVP_SignFinal(
md_ctx, signature_buffer, signature_length, pkey._pkey)
if final_result != 1:
1/0
- return _api.buffer(signature_buffer, signature_length[0])[:]
+ return _ffi.buffer(signature_buffer, signature_length[0])[:]
@@ -2005,21 +2005,21 @@ def verify(cert, signature, data, digest):
:param digest: message digest to use
:return: None if the signature is correct, raise exception otherwise
"""
- digest_obj = _api.EVP_get_digestbyname(digest)
- if digest_obj == _api.NULL:
+ digest_obj = _lib.EVP_get_digestbyname(digest)
+ if digest_obj == _ffi.NULL:
raise ValueError("No such digest method")
- pkey = _api.X509_get_pubkey(cert._x509)
- if pkey == _api.NULL:
+ pkey = _lib.X509_get_pubkey(cert._x509)
+ if pkey == _ffi.NULL:
1/0
- pkey = _api.ffi.gc(pkey, _api.EVP_PKEY_free)
+ pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free)
- md_ctx = _api.new("EVP_MD_CTX*")
- md_ctx = _api.ffi.gc(md_ctx, _api.EVP_MD_CTX_cleanup)
+ md_ctx = _ffi.new("EVP_MD_CTX*")
+ md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup)
- _api.EVP_VerifyInit(md_ctx, digest_obj)
- _api.EVP_VerifyUpdate(md_ctx, data, len(data))
- verify_result = _api.EVP_VerifyFinal(md_ctx, signature, len(signature), pkey)
+ _lib.EVP_VerifyInit(md_ctx, digest_obj)
+ _lib.EVP_VerifyUpdate(md_ctx, data, len(data))
+ verify_result = _lib.EVP_VerifyFinal(md_ctx, signature, len(signature), pkey)
if verify_result != 1:
_raise_current_error()
@@ -2038,13 +2038,13 @@ def load_crl(type, buffer):
bio = _new_mem_buf(buffer)
if type == FILETYPE_PEM:
- crl = _api.PEM_read_bio_X509_CRL(bio, _api.NULL, _api.NULL, _api.NULL)
+ crl = _lib.PEM_read_bio_X509_CRL(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
elif type == FILETYPE_ASN1:
- crl = _api.d2i_X509_CRL_bio(bio, _api.NULL)
+ crl = _lib.d2i_X509_CRL_bio(bio, _ffi.NULL)
else:
raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")
- if crl == _api.NULL:
+ if crl == _ffi.NULL:
_raise_current_error()
result = CRL.__new__(CRL)
@@ -2064,18 +2064,18 @@ def load_pkcs7_data(type, buffer):
bio = _new_mem_buf(buffer)
if type == FILETYPE_PEM:
- pkcs7 = _api.PEM_read_bio_PKCS7(bio, _api.NULL, _api.NULL, _api.NULL)
+ pkcs7 = _lib.PEM_read_bio_PKCS7(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
elif type == FILETYPE_ASN1:
pass
else:
1/0
raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")
- if pkcs7 == _api.NULL:
+ if pkcs7 == _ffi.NULL:
_raise_current_error()
pypkcs7 = PKCS7.__new__(PKCS7)
- pypkcs7._pkcs7 = _api.ffi.gc(pkcs7, _api.PKCS7_free)
+ pypkcs7._pkcs7 = _ffi.gc(pkcs7, _lib.PKCS7_free)
return pypkcs7
@@ -2090,20 +2090,20 @@ def load_pkcs12(buffer, passphrase):
"""
bio = _new_mem_buf(buffer)
- p12 = _api.d2i_PKCS12_bio(bio, _api.NULL)
- if p12 == _api.NULL:
+ p12 = _lib.d2i_PKCS12_bio(bio, _ffi.NULL)
+ if p12 == _ffi.NULL:
_raise_current_error()
- p12 = _api.ffi.gc(p12, _api.PKCS12_free)
+ p12 = _ffi.gc(p12, _lib.PKCS12_free)
- pkey = _api.new("EVP_PKEY**")
- cert = _api.new("X509**")
- cacerts = _api.new("struct stack_st_X509**")
+ pkey = _ffi.new("EVP_PKEY**")
+ cert = _ffi.new("X509**")
+ cacerts = _ffi.new("Cryptography_STACK_OF_X509**")
- parse_result = _api.PKCS12_parse(p12, passphrase, pkey, cert, cacerts)
+ parse_result = _lib.PKCS12_parse(p12, passphrase, pkey, cert, cacerts)
if not parse_result:
_raise_current_error()
- cacerts = _api.ffi.gc(cacerts[0], _api.sk_X509_free)
+ cacerts = _ffi.gc(cacerts[0], _lib.sk_X509_free)
# openssl 1.0.0 sometimes leaves an X509_check_private_key error in the
# queue for no particular reason. This error isn't interesting to anyone
@@ -2113,29 +2113,29 @@ def load_pkcs12(buffer, passphrase):
except Error:
pass
- if pkey[0] == _api.NULL:
+ if pkey[0] == _ffi.NULL:
pykey = None
else:
pykey = PKey.__new__(PKey)
- pykey._pkey = _api.ffi.gc(pkey[0], _api.EVP_PKEY_free)
+ pykey._pkey = _ffi.gc(pkey[0], _lib.EVP_PKEY_free)
- if cert[0] == _api.NULL:
+ if cert[0] == _ffi.NULL:
pycert = None
friendlyname = None
else:
pycert = X509.__new__(X509)
- pycert._x509 = _api.ffi.gc(cert[0], _api.X509_free)
+ pycert._x509 = _ffi.gc(cert[0], _lib.X509_free)
- friendlyname_length = _api.new("int*")
- friendlyname_buffer = _api.X509_alias_get0(cert[0], friendlyname_length)
- friendlyname = _api.buffer(friendlyname_buffer, friendlyname_length[0])[:]
- if friendlyname_buffer == _api.NULL:
+ friendlyname_length = _ffi.new("int*")
+ friendlyname_buffer = _lib.X509_alias_get0(cert[0], friendlyname_length)
+ friendlyname = _ffi.buffer(friendlyname_buffer, friendlyname_length[0])[:]
+ if friendlyname_buffer == _ffi.NULL:
friendlyname = None
pycacerts = []
- for i in range(_api.sk_X509_num(cacerts)):
+ for i in range(_lib.sk_X509_num(cacerts)):
pycacert = X509.__new__(X509)
- pycacert._x509 = _api.sk_X509_value(cacerts, i)
+ pycacert._x509 = _lib.sk_X509_value(cacerts, i)
pycacerts.append(pycacert)
if not pycacerts:
pycacerts = None
diff --git a/OpenSSL/rand.py b/OpenSSL/rand.py
index efdbd4b..8295854 100644
--- a/OpenSSL/rand.py
+++ b/OpenSSL/rand.py
@@ -6,7 +6,9 @@ See the file RATIONALE for a short explanation of why this module was written.
import __builtin__
-from tls.c import api as _api
+from cryptography.hazmat.backends.openssl import backend
+_lib = backend.lib
+_ffi = backend.ffi
# TODO Nothing tests the existence or use of this
class Error(Exception):
@@ -28,11 +30,11 @@ def bytes(num_bytes):
if num_bytes < 0:
raise ValueError("num_bytes must not be negative")
- result_buffer = _api.new("char[]", num_bytes)
- result_code = _api.RAND_bytes(result_buffer, num_bytes)
+ result_buffer = _ffi.new("char[]", num_bytes)
+ result_code = _lib.RAND_bytes(result_buffer, num_bytes)
if result_code == -1:
raise Exception("zoops") # TODO
- return _api.buffer(result_buffer)[:]
+ return _ffi.buffer(result_buffer)[:]
@@ -51,7 +53,7 @@ def add(buffer, entropy):
raise TypeError("entropy must be an integer")
# TODO Nothing tests this call actually being made, or made properly.
- _api.RAND_add(buffer, len(buffer), entropy)
+ _lib.RAND_add(buffer, len(buffer), entropy)
@@ -66,7 +68,7 @@ def seed(buffer):
raise TypeError("buffer must be a byte string")
# TODO Nothing tests this call actually being made, or made properly.
- _api.RAND_seed(buffer, len(buffer))
+ _lib.RAND_seed(buffer, len(buffer))
@@ -76,7 +78,7 @@ def status():
:return: True if the PRNG is seeded enough, false otherwise
"""
- return _api.RAND_status()
+ return _lib.RAND_status()
@@ -99,7 +101,7 @@ def egd(path, bytes=_unspecified):
elif not isinstance(bytes, int):
raise TypeError("bytes must be an integer")
- return _api.RAND_egd_bytes(path, bytes)
+ return _lib.RAND_egd_bytes(path, bytes)
@@ -110,7 +112,7 @@ def cleanup():
:return: None
"""
# TODO Nothing tests this call actually being made, or made properly.
- _api.RAND_cleanup()
+ _lib.RAND_cleanup()
@@ -131,7 +133,7 @@ def load_file(filename, maxbytes=_unspecified):
elif not isinstance(maxbytes, int):
raise TypeError("maxbytes must be an integer")
- return _api.RAND_load_file(filename, maxbytes)
+ return _lib.RAND_load_file(filename, maxbytes)
@@ -145,7 +147,7 @@ def write_file(filename):
if not isinstance(filename, str):
raise TypeError("filename must be a string")
- return _api.RAND_write_file(filename)
+ return _lib.RAND_write_file(filename)
# TODO There are no tests for screen at all
@@ -156,12 +158,12 @@ def screen():
:return: None
"""
- _api.RAND_screen()
+ _lib.RAND_screen()
-if getattr(_api, 'RAND_screen', None) is None:
+if getattr(_lib, 'RAND_screen', None) is None:
del screen
# TODO There are no tests for the RAND strings being loaded, whatever that
# means.
-_api.ERR_load_RAND_strings()
+_lib.ERR_load_RAND_strings()