Skip to content

Commit ace63e9

Browse files
authored
Merge pull request #22 from haydenroche5/compatibility-layer
Add an OpenSSL compatibility layer.
2 parents e25f244 + 7db065d commit ace63e9

File tree

6 files changed

+541
-81
lines changed

6 files changed

+541
-81
lines changed

README.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ We provide Python wheels (prebuilt binaries) for OSX 64 bits and Linux 64 bits:
2121

2222
.. code-block:: bash
2323
24+
$ pip install wheel
2425
$ pip install wolfssl
2526
2627
To build wolfssl-py from source:
@@ -56,6 +57,10 @@ one of the following commands:
5657
$ pytest
5758
$ py.test tests
5859
60+
Note: If you used USE_LOCAL_WOLFSSL in the installation step or otherwise have
61+
wolfSSL installed in a non-standard location, you'll need to prepend `pytest`
62+
with `USE_LOCAL_WOLFSSL=<path/to/wolfssl>`.
63+
5964
Support
6065
=======
6166

src/wolfssl/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
# When bumping the C library version, reset the POST count to 0
2828

29-
__wolfssl_version__ = "v4.1.0-stable"
29+
__wolfssl_version__ = "v4.8.1-stable"
3030

3131
# We're using implicit post releases [PEP 440] to bump package version
3232
# while maintaining the C library version intact for better reference.

src/wolfssl/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ def do_handshake(self, block=False): # pylint: disable=unused-argument
698698
eStr = _ffi.string(_lib.wolfSSL_ERR_error_string(err,
699699
eBuf)).decode("ascii")
700700

701-
if 'ASN no signer error to confirm' in eStr or err is -188:
701+
if 'ASN no signer error to confirm' in eStr or err == -188:
702702
# Some Python ssl consumers explicitly check error message
703703
# for 'certificate verify failed'
704704
raise SSLError("do_handshake failed with error %d, "

src/wolfssl/_build_ffi.py

Lines changed: 204 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -25,47 +25,107 @@
2525
from distutils.util import get_platform
2626
from cffi import FFI
2727
from wolfssl._build_wolfssl import wolfssl_inc_path, wolfssl_lib_path
28+
import wolfssl._openssl as openssl
29+
import subprocess
30+
import shlex
31+
import os
32+
from ctypes import cdll
33+
from collections import namedtuple
34+
35+
def make_optional_func_list(libwolfssl_path, funcs):
36+
if libwolfssl_path.endswith(".so"):
37+
libwolfssl = cdll.LoadLibrary(libwolfssl_path)
38+
defined = []
39+
for func in funcs:
40+
try:
41+
getattr(libwolfssl, func.name)
42+
defined.append(func)
43+
except AttributeError as _:
44+
pass
45+
# Can't discover functions in a static library with ctypes. Need to fall
46+
# back to running nm as a subprocess.
47+
else:
48+
nm_cmd = "nm --defined-only {}".format(libwolfssl_path)
49+
result = subprocess.run(shlex.split(nm_cmd), capture_output=True)
50+
nm_stdout = result.stdout.decode()
51+
defined = [func for func in funcs if func.name in nm_stdout]
52+
53+
return defined
54+
55+
libwolfssl_path = os.path.join(wolfssl_lib_path(), "libwolfssl.a")
56+
if not os.path.exists(libwolfssl_path):
57+
libwolfssl_path = os.path.join(wolfssl_lib_path(), "libwolfssl.so")
58+
if not os.path.exists(libwolfssl_path):
59+
err = "Couldn't find libwolfssl under {}.".format(wolfssl_lib_path())
60+
raise Exception(err)
61+
62+
WolfFunction = namedtuple("WolfFunction", ["name", "native_sig", "ossl_sig"])
63+
# Depending on how wolfSSL was configured, the functions below may or may not be
64+
# defined.
65+
optional_funcs = [
66+
WolfFunction("wolfSSL_ERR_func_error_string",
67+
"const char* wolfSSL_ERR_func_error_string(unsigned long)",
68+
"const char* ERR_func_error_string(unsigned long)"),
69+
WolfFunction("wolfSSL_ERR_lib_error_string",
70+
"const char* wolfSSL_ERR_lib_error_string(unsigned long)",
71+
"const char* ERR_lib_error_string(unsigned long)"),
72+
WolfFunction("wolfSSL_X509_EXTENSION_dup",
73+
"WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_dup(WOLFSSL_X509_EXTENSION*)",
74+
"X509_EXTENSION* X509_EXTENSION_dup(X509_EXTENSION*)")
75+
]
76+
optional_funcs = make_optional_func_list(libwolfssl_path, optional_funcs)
77+
78+
source = """
79+
#include <wolfssl/options.h>
80+
#include <wolfssl/ssl.h>
81+
"""
82+
ffi_source = source + openssl.source
2883

2984
ffi = FFI()
3085

3186
ffi.set_source(
3287
"wolfssl._ffi",
33-
"""
34-
#include <wolfssl/options.h>
35-
#include <wolfssl/ssl.h>
36-
""",
88+
ffi_source,
3789
include_dirs=[wolfssl_inc_path()],
3890
library_dirs=[wolfssl_lib_path()],
3991
libraries=["wolfssl"],
4092
)
4193

42-
ffi.cdef(
43-
"""
44-
94+
cdef = """
4595
/**
46-
* Structs
96+
* Constants
4797
*/
48-
typedef struct WOLFSSL_ALERT {
49-
int code;
50-
int level;
51-
} WOLFSSL_ALERT;
52-
53-
typedef struct WOLFSSL_ALERT_HISTORY {
54-
WOLFSSL_ALERT last_rx;
55-
WOLFSSL_ALERT last_tx;
56-
} WOLFSSL_ALERT_HISTORY;
98+
static const long SOCKET_PEER_CLOSED_E;
5799
58100
/**
59101
* Types
60102
*/
61103
typedef unsigned char byte;
62104
typedef unsigned int word32;
105+
106+
typedef ... WOLFSSL_CTX;
107+
typedef ... WOLFSSL;
108+
typedef ... WOLFSSL_X509;
109+
typedef ... WOLFSSL_X509_EXTENSION;
110+
typedef ... WOLFSSL_X509_STORE_CTX;
111+
typedef ... WOLFSSL_X509_NAME;
112+
typedef ... WOLFSSL_X509_NAME_ENTRY;
113+
typedef ... WOLFSSL_ALERT_HISTORY;
114+
typedef ... WOLFSSL_METHOD;
115+
typedef ... WOLFSSL_ASN1_TIME;
116+
typedef ... WOLFSSL_ASN1_GENERALIZEDTIME;
117+
typedef ... WOLFSSL_ASN1_STRING;
118+
typedef ... WOLFSSL_ASN1_OBJECT;
119+
120+
typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*);
121+
typedef int pem_password_cb(char*, int, int, void*);
122+
typedef int (*CallbackSniRecv)(WOLFSSL*, int*, void*);
63123
64-
typedef int pem_password_cb(char* passwd, int sz, int rw, void* userdata);
65124
/**
66-
* Memory free function
125+
* Memory
67126
*/
68127
void wolfSSL_Free(void*);
128+
void wolfSSL_OPENSSL_free(void*);
69129
70130
/**
71131
* Debugging
@@ -76,63 +136,145 @@
76136
/**
77137
* SSL/TLS Method functions
78138
*/
79-
void* wolfTLSv1_1_server_method(void);
80-
void* wolfTLSv1_1_client_method(void);
139+
WOLFSSL_METHOD* wolfTLSv1_1_server_method(void);
140+
WOLFSSL_METHOD* wolfTLSv1_1_client_method(void);
81141
82-
void* wolfTLSv1_2_server_method(void);
83-
void* wolfTLSv1_2_client_method(void);
142+
WOLFSSL_METHOD* wolfTLSv1_2_server_method(void);
143+
WOLFSSL_METHOD* wolfTLSv1_2_client_method(void);
84144
85-
void* wolfSSLv23_server_method(void);
86-
void* wolfSSLv23_client_method(void);
145+
WOLFSSL_METHOD* wolfSSLv23_server_method(void);
146+
WOLFSSL_METHOD* wolfSSLv23_client_method(void);
147+
148+
WOLFSSL_METHOD* wolfSSLv23_method(void);
149+
WOLFSSL_METHOD* wolfTLSv1_1_method(void);
150+
WOLFSSL_METHOD* wolfTLSv1_2_method(void);
87151
88152
/**
89153
* SSL/TLS Context functions
90154
*/
91-
void* wolfSSL_CTX_new(void*);
92-
void wolfSSL_CTX_free(void*);
93-
94-
void wolfSSL_CTX_set_verify(void*, int, void*);
95-
int wolfSSL_CTX_set_cipher_list(void*, const char*);
96-
int wolfSSL_CTX_use_PrivateKey_file(void*, const char*, int);
97-
int wolfSSL_CTX_load_verify_locations(void*, const char*, const char*);
98-
int wolfSSL_CTX_load_verify_buffer(void*, const unsigned char*, long,int);
99-
int wolfSSL_CTX_use_certificate_chain_file(void*, const char *);
100-
int wolfSSL_CTX_UseSNI(void*, unsigned char, const void*, unsigned short);
101-
long wolfSSL_CTX_get_options(void*);
102-
long wolfSSL_CTX_set_options(void*, long);
103-
void wolfSSL_CTX_set_default_passwd_cb(void*, pem_password_cb*);
155+
WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD*);
156+
void wolfSSL_CTX_free(WOLFSSL_CTX*);
157+
158+
void wolfSSL_CTX_set_verify(WOLFSSL_CTX*, int, VerifyCallback);
159+
int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX*, const char*);
160+
int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX*, const char*, int);
161+
int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX*, const char*,
162+
const char*);
163+
int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX*, const unsigned char*,
164+
long,int);
165+
int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX*, const char *);
166+
int wolfSSL_CTX_UseSNI(WOLFSSL_CTX*, unsigned char, const void*,
167+
unsigned short);
168+
long wolfSSL_CTX_get_options(WOLFSSL_CTX*);
169+
long wolfSSL_CTX_set_options(WOLFSSL_CTX*, long);
170+
void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX*, pem_password_cb*);
171+
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX*,
172+
CallbackSniRecv);
173+
long wolfSSL_CTX_set_mode(WOLFSSL_CTX*, long);
104174
105175
/**
106176
* SSL/TLS Session functions
107177
*/
108-
void* wolfSSL_new(void*);
109-
void wolfSSL_free(void*);
110-
111-
int wolfSSL_set_fd(void*, int);
112-
int wolfSSL_get_error(void*, int);
113-
char* wolfSSL_ERR_error_string(int, char*);
114-
int wolfSSL_negotiate(void*);
115-
int wolfSSL_connect(void*);
116-
int wolfSSL_accept(void*);
117-
int wolfSSL_write(void*, const void*, int);
118-
int wolfSSL_read(void*, void*, int);
119-
int wolfSSL_pending(void*);
120-
int wolfSSL_shutdown(void*);
121-
void* wolfSSL_get_peer_certificate(void*);
122-
int wolfSSL_UseSNI(void*, unsigned char, const void*, unsigned short);
123-
int wolfSSL_check_domain_name(void*, const char*);
124-
int wolfSSL_get_alert_history(void*, WOLFSSL_ALERT_HISTORY*);
125-
const char* wolfSSL_alert_type_string_long(int);
126-
const char* wolfSSL_alert_desc_string_long(int);
178+
WOLFSSL* wolfSSL_new(WOLFSSL_CTX*);
179+
void wolfSSL_free(WOLFSSL*);
180+
181+
int wolfSSL_set_fd(WOLFSSL*, int);
182+
int wolfSSL_get_error(WOLFSSL*, int);
183+
char* wolfSSL_ERR_error_string(int, char*);
184+
int wolfSSL_negotiate(WOLFSSL*);
185+
int wolfSSL_connect(WOLFSSL*);
186+
int wolfSSL_accept(WOLFSSL*);
187+
int wolfSSL_write(WOLFSSL*, const void*, int);
188+
int wolfSSL_read(WOLFSSL*, void*, int);
189+
int wolfSSL_pending(WOLFSSL*);
190+
int wolfSSL_shutdown(WOLFSSL*);
191+
WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL*);
192+
int wolfSSL_UseSNI(WOLFSSL*, unsigned char, const void*,
193+
unsigned short);
194+
int wolfSSL_check_domain_name(WOLFSSL*, const char*);
195+
int wolfSSL_get_alert_history(WOLFSSL*, WOLFSSL_ALERT_HISTORY*);
196+
const char* wolfSSL_get_servername(WOLFSSL*, unsigned char);
197+
int wolfSSL_set_tlsext_host_name(WOLFSSL*, const char*);
198+
long wolfSSL_ctrl(WOLFSSL*, int, long, void*);
199+
void wolfSSL_set_connect_state(WOLFSSL*);
127200
128201
/**
129202
* WOLFSSL_X509 functions
130203
*/
131-
char* wolfSSL_X509_get_subjectCN(void*);
132-
char* wolfSSL_X509_get_next_altname(void*);
133-
const unsigned char* wolfSSL_X509_get_der(void*, int*);
134-
"""
135-
)
204+
char* wolfSSL_X509_get_subjectCN(void*);
205+
char* wolfSSL_X509_get_next_altname(void*);
206+
const unsigned char* wolfSSL_X509_get_der(void*, int*);
207+
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
208+
WOLFSSL_X509_STORE_CTX*);
209+
int wolfSSL_X509_up_ref(WOLFSSL_X509*);
210+
void wolfSSL_X509_free(WOLFSSL_X509*);
211+
int wolfSSL_X509_STORE_CTX_get_error(
212+
WOLFSSL_X509_STORE_CTX*);
213+
int wolfSSL_X509_STORE_CTX_get_error_depth(
214+
WOLFSSL_X509_STORE_CTX*);
215+
int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void);
216+
void* wolfSSL_X509_STORE_CTX_get_ex_data(
217+
WOLFSSL_X509_STORE_CTX*, int);
218+
void wolfSSL_X509_STORE_CTX_set_error(
219+
WOLFSSL_X509_STORE_CTX*, int);
220+
WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509*);
221+
char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*,
222+
char*, int);
223+
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notBefore(const WOLFSSL_X509*);
224+
WOLFSSL_ASN1_TIME* wolfSSL_X509_get_notAfter(const WOLFSSL_X509*);
225+
int wolfSSL_X509_NAME_entry_count(WOLFSSL_X509_NAME*);
226+
WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME*, int);
227+
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
228+
WOLFSSL_X509_NAME_ENTRY*);
229+
WOLFSSL_ASN1_STRING* wolfSSL_X509_NAME_ENTRY_get_data(WOLFSSL_X509_NAME_ENTRY*);
230+
int wolfSSL_X509_NAME_get_index_by_NID(WOLFSSL_X509_NAME*, int,
231+
int);
232+
int wolfSSL_X509_NAME_cmp(const WOLFSSL_X509_NAME*,
233+
const WOLFSSL_X509_NAME*);
234+
int wolfSSL_X509_get_ext_count(const WOLFSSL_X509*);
235+
WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509*, int);
236+
void wolfSSL_X509_EXTENSION_free(
237+
WOLFSSL_X509_EXTENSION*);
238+
WOLFSSL_ASN1_OBJECT* wolfSSL_X509_EXTENSION_get_object(
239+
WOLFSSL_X509_EXTENSION*);
240+
WOLFSSL_ASN1_STRING* wolfSSL_X509_EXTENSION_get_data(
241+
WOLFSSL_X509_EXTENSION*);
242+
WOLFSSL_X509* wolfSSL_X509_dup(WOLFSSL_X509*);
243+
244+
/**
245+
* ASN.1
246+
*/
247+
int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING*);
248+
int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING*);
249+
unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING*);
250+
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME*,
251+
WOLFSSL_ASN1_TIME**);
252+
void wolfSSL_ASN1_GENERALIZEDTIME_free(
253+
WOLFSSL_ASN1_GENERALIZEDTIME*);
254+
void wolfSSL_ASN1_TIME_free(WOLFSSL_ASN1_TIME*);
255+
int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME*);
256+
unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME*);
257+
int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **,
258+
WOLFSSL_ASN1_STRING*);
259+
260+
/**
261+
* Misc.
262+
*/
263+
int wolfSSL_library_init(void);
264+
const char* wolfSSL_alert_type_string_long(int);
265+
const char* wolfSSL_alert_desc_string_long(int);
266+
unsigned long wolfSSL_ERR_get_error(void);
267+
const char* wolfSSL_ERR_reason_error_string(unsigned long);
268+
int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT*);
269+
const char* wolfSSL_OBJ_nid2sn(int n);
270+
int wolfSSL_OBJ_txt2nid(const char*);
271+
"""
272+
273+
for func in optional_funcs:
274+
cdef += "{};".format(func.native_sig)
275+
276+
ffi_cdef = cdef + openssl.construct_cdef(optional_funcs)
277+
ffi.cdef(ffi_cdef)
136278

137279
if __name__ == "__main__":
138280
ffi.compile(verbose=True)

0 commit comments

Comments
 (0)