summaryrefslogtreecommitdiff
path: root/SWIG/_lib.i
diff options
context:
space:
mode:
Diffstat (limited to 'SWIG/_lib.i')
-rw-r--r--SWIG/_lib.i360
1 files changed, 289 insertions, 71 deletions
diff --git a/SWIG/_lib.i b/SWIG/_lib.i
index 42dc180..c84b800 100644
--- a/SWIG/_lib.i
+++ b/SWIG/_lib.i
@@ -1,19 +1,85 @@
/* Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved. */
-/* $Id: _lib.i 695 2009-07-24 06:37:01Z heikki $ */
+/* $Id$ */
%{
+#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
#include <ceval.h>
+%}
+
+/* OpenSSL 1.1 compatibility shim */
+%include _lib11_compat.i
+
+/* Python 3 compatibility shim */
+%include _py3k_compat.i
+
+%{
+/* OpenSSL 1.0.2 copmatbility shim */
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+typedef void (*OPENSSL_sk_freefunc)(void *);
+typedef void *(*OPENSSL_sk_copyfunc)(const void *);
+typedef struct stack_st OPENSSL_STACK;
+
+# define MIN_NODES 4
+# define sk_deep_copy OPENSSL_sk_deep_copy
+
+void OPENSSL_sk_free(OPENSSL_STACK *st)
+{
+ if (st == NULL)
+ return;
+ OPENSSL_free(st->data);
+ OPENSSL_free(st);
+}
+
+OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
+ OPENSSL_sk_copyfunc copy_func,
+ OPENSSL_sk_freefunc free_func)
+{
+ OPENSSL_STACK *ret;
+ int i;
+
+ if (sk->num < 0)
+ return NULL;
+
+ if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+ return NULL;
+
+ /* direct structure assignment */
+ *ret = *sk;
+
+ ret->num_alloc = sk->num > MIN_NODES ? (size_t)sk->num : MIN_NODES;
+ ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
+ if (ret->data == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ for (i = 0; i < ret->num; ++i) {
+ if (sk->data[i] == NULL)
+ continue;
+ if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
+ while (--i >= 0)
+ if (ret->data[i] != NULL)
+ free_func((void *)ret->data[i]);
+ OPENSSL_sk_free(ret);
+ return NULL;
+ }
+ }
+ return ret;
+}
+#endif /* OpenSSL 1.0.2 copmatbility shim */
+
/* Blob interface. Deprecated. */
Blob *blob_new(int len, const char *errmsg) {
-
+
Blob *blob;
if (!(blob=(Blob *)PyMem_Malloc(sizeof(Blob)))){
PyErr_SetString(PyExc_MemoryError, errmsg);
@@ -47,9 +113,15 @@ void blob_free(Blob *blob) {
/* Python helpers. */
%}
+%ignore PyObject_CheckBuffer;
+%ignore PyObject_GetBuffer;
+%ignore PyBuffer_Release;
%ignore m2_PyObject_AsReadBufferInt;
+%ignore m2_PyObject_GetBufferInt;
+%ignore m2_PyBuffer_Release;
%ignore m2_PyString_AsStringAndSizeInt;
%{
+
static int
m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
int *buffer_len)
@@ -68,13 +140,63 @@ m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
return 0;
}
+static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags)
+{
+ int ret;
+
+ if (PyObject_CheckBuffer(obj))
+ ret = PyObject_GetBuffer(obj, view, flags);
+ else {
+ const void *buf;
+
+ ret = PyObject_AsReadBuffer(obj, &buf, &view->len);
+ if (ret == 0)
+ view->buf = (void *)buf;
+ }
+ if (ret)
+ return ret;
+ if (view->len > INT_MAX) {
+ PyErr_SetString(PyExc_ValueError, "object too large");
+ m2_PyBuffer_Release(obj, view);
+ return -1;
+ }
+
+ return 0;
+}
+
+static BIGNUM*
+m2_PyObject_AsBIGNUM(PyObject* value, PyObject* _py_exc)
+{
+ BIGNUM* bn;
+ const void* vbuf;
+ int vlen = 0;
+
+ if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+ return NULL;
+
+ if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+ PyErr_SetString(_py_exc, ERR_reason_error_string(ERR_get_error()));
+ return NULL;
+ }
+
+ return bn;
+}
+
+static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view)
+{
+ if (PyObject_CheckBuffer(obj))
+ PyBuffer_Release(view);
+ /* else do nothing, view->buf comes from PyObject_AsReadBuffer */
+}
+
static int
m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len)
{
int ret;
Py_ssize_t len2;
- ret = PyString_AsStringAndSize(obj, s, &len2);
+ ret = PyBytes_AsStringAndSize(obj, s, &len2);
+
if (ret)
return ret;
if (len2 > INT_MAX) {
@@ -85,8 +207,46 @@ m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len)
return 0;
}
+/* Works as PyFile_Name, but always returns a new object. */
+PyObject *m2_PyFile_Name(PyObject *pyfile) {
+ PyObject *out = NULL;
+#if PY_MAJOR_VERSION >= 3
+ out = PyObject_GetAttrString(pyfile, "name");
+#else
+ out = PyFile_Name(pyfile);
+ Py_XINCREF(out);
+#endif
+ return out;
+}
+
+/* Yes, __FUNCTION__ is a non-standard symbol, but it is supported by
+ * both gcc and MSVC. */
+#define m2_PyErr_Msg(type) m2_PyErr_Msg_Caller(type, (const char*) __FUNCTION__)
+
+static void m2_PyErr_Msg_Caller(PyObject *err_type, const char* caller) {
+ const char *err_reason;
+ const char *data;
+ int flags;
+ /* This max size of a (longer than ours) OpenSSL error string is hardcoded
+ * in OpenSSL's crypto/err/err_prn.c:ERR_print_errors_cb() */
+ char err_msg[4096];
+ unsigned long err_code = ERR_get_error_line_data(NULL, NULL, &data, &flags);
+
+ if (err_code != 0) {
+ err_reason = ERR_reason_error_string(err_code);
+ if (data && (flags & ERR_TXT_STRING))
+ snprintf(err_msg, sizeof(err_msg), "%s (%s)", err_reason, data);
+ else
+ snprintf(err_msg, sizeof(err_msg), "%s", err_reason);
+
+ PyErr_SetString(err_type, err_msg);
+ } else {
+ PyErr_Format(err_type, "Unknown error in function %s.", caller);
+ }
+}
+
-/* C callbacks invoked by OpenSSL; these in turn call back into
+/* C callbacks invoked by OpenSSL; these in turn call back into
Python. */
int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
@@ -100,6 +260,7 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
int cret;
int new_style_callback = 0, warning_raised_exception=0;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
@@ -117,7 +278,7 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
PyCodeObject *code = (PyCodeObject *) PyFunction_GetCode(ssl_verify_cb_func);
if (code && code->co_argcount == 2) { /* XXX Python internals */
new_style_callback = 1;
- }
+ }
} else {
/* XXX There are lots of other callable types, but we will assume
* XXX that any other type of callable uses the new style callback,
@@ -125,30 +286,34 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
*/
new_style_callback = 1;
}
-
+
if (new_style_callback) {
- PyObject *x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
+ PyObject *x509mod;
+
+ x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
_klass = PyObject_GetAttrString(x509mod, "X509_Store_Context");
-
+
_x509_store_ctx_swigptr = SWIG_NewPointerObj((void *)ctx, SWIGTYPE_p_X509_STORE_CTX, 0);
_x509_store_ctx_obj = Py_BuildValue("(Oi)", _x509_store_ctx_swigptr, 0);
- _x509_store_ctx_inst = PyInstance_New(_klass, _x509_store_ctx_obj, NULL);
+
+ _x509_store_ctx_inst = PyObject_CallObject(_klass, _x509_store_ctx_obj);
+
argv = Py_BuildValue("(iO)", ok, _x509_store_ctx_inst);
} else {
if (PyErr_Warn(PyExc_DeprecationWarning, "Old style callback, use cb_func(ok, store) instead")) {
warning_raised_exception = 1;
}
-
+
x509 = X509_STORE_CTX_get_current_cert(ctx);
errnum = X509_STORE_CTX_get_error(ctx);
errdepth = X509_STORE_CTX_get_error_depth(ctx);
-
- ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
+
+ ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
ssl_ctx = SSL_get_SSL_CTX(ssl);
-
+
_x509 = SWIG_NewPointerObj((void *)x509, SWIGTYPE_p_X509, 0);
_ssl_ctx = SWIG_NewPointerObj((void *)ssl_ctx, SWIGTYPE_p_SSL_CTX, 0);
- argv = Py_BuildValue("(OOiii)", _ssl_ctx, _x509, errnum, errdepth, ok);
+ argv = Py_BuildValue("(OOiii)", _ssl_ctx, _x509, errnum, errdepth, ok);
}
if (!warning_raised_exception) {
@@ -161,9 +326,10 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
/* Got an exception in PyEval_CallObject(), let's fail verification
* to be safe.
*/
- cret = 0;
+ cret = 0;
} else {
- cret = (int)PyInt_AsLong(ret);
+ /* FIXME This is possibly problematic if ret > MAXINT */
+ cret = (int)PyLong_AsLong(ret);
}
Py_XDECREF(ret);
Py_XDECREF(argv);
@@ -182,15 +348,59 @@ int ssl_verify_callback(int ok, X509_STORE_CTX *ctx) {
return cret;
}
+int x509_store_verify_callback(int ok, X509_STORE_CTX *ctx) {
+ PyGILState_STATE gilstate;
+ PyObject *argv, *ret;
+ PyObject *_x509_store_ctx_swigptr=0, *_x509_store_ctx_obj=0, *_x509_store_ctx_inst=0, *_klass=0;
+ int cret;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
+ PyObject *x509mod;
+
+
+ gilstate = PyGILState_Ensure();
+
+ /* Below, handle only what is called 'new style callback' in ssl_verify_callback().
+ TODO: does 'old style callback' exist any more? */
+ x509mod = PyDict_GetItemString(PyImport_GetModuleDict(), "M2Crypto.X509");
+ _klass = PyObject_GetAttrString(x509mod, "X509_Store_Context");
+ _x509_store_ctx_swigptr = SWIG_NewPointerObj((void *)ctx, SWIGTYPE_p_X509_STORE_CTX, 0);
+ _x509_store_ctx_obj = Py_BuildValue("(Oi)", _x509_store_ctx_swigptr, 0);
+
+ _x509_store_ctx_inst = PyObject_CallObject(_klass, _x509_store_ctx_obj);
+
+ argv = Py_BuildValue("(iO)", ok, _x509_store_ctx_inst);
+
+ ret = PyEval_CallObject(x509_store_verify_cb_func, argv);
+ if (!ret) {
+ /* Got an exception in PyEval_CallObject(), let's fail verification
+ * to be safe.
+ */
+ cret = 0;
+ } else {
+ cret = (int)PyInt_AsLong(ret);
+ }
+
+ Py_XDECREF(ret);
+ Py_XDECREF(argv);
+ Py_XDECREF(_x509_store_ctx_inst);
+ Py_XDECREF(_x509_store_ctx_obj);
+ Py_XDECREF(_x509_store_ctx_swigptr);
+ Py_XDECREF(_klass);
+
+ PyGILState_Release(gilstate);
+ return cret;
+}
+
void ssl_info_callback(const SSL *s, int where, int ret) {
PyObject *argv, *retval, *_SSL;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
gilstate = PyGILState_Ensure();
_SSL = SWIG_NewPointerObj((void *)s, SWIGTYPE_p_SSL, 0);
argv = Py_BuildValue("(iiO)", where, ret, _SSL);
-
+
retval = PyEval_CallObject(ssl_info_cb_func, argv);
Py_XDECREF(retval);
@@ -204,6 +414,7 @@ DH *ssl_set_tmp_dh_callback(SSL *ssl, int is_export, int keylength) {
PyObject *argv, *ret, *_ssl;
DH *dh;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
gilstate = PyGILState_Ensure();
@@ -227,6 +438,7 @@ RSA *ssl_set_tmp_rsa_callback(SSL *ssl, int is_export, int keylength) {
PyObject *argv, *ret, *_ssl;
RSA *rsa;
PyGILState_STATE gilstate;
+ PyObject *self = NULL; /* bug in SWIG_NewPointerObj as of 3.0.5 */
gilstate = PyGILState_Ensure();
@@ -246,17 +458,18 @@ RSA *ssl_set_tmp_rsa_callback(SSL *ssl, int is_export, int keylength) {
return rsa;
}
-void gen_callback(int p, int n, void *arg) {
+/* Universal callback for dh_generate_parameters,
+ * dsa_generate_parametersm, and rsa_generate_key */
+int bn_gencb_callback(int p, int n, BN_GENCB *gencb) {
PyObject *argv, *ret, *cbfunc;
-
- PyGILState_STATE gilstate;
- gilstate = PyGILState_Ensure();
- cbfunc = (PyObject *)arg;
+
+ cbfunc = (PyObject *)BN_GENCB_get_arg(gencb);
argv = Py_BuildValue("(ii)", p, n);
ret = PyEval_CallObject(cbfunc, argv);
+ PyErr_Clear();
Py_DECREF(argv);
Py_XDECREF(ret);
- PyGILState_Release(gilstate);
+ return 1;
}
int passphrase_callback(char *buf, int num, int v, void *arg) {
@@ -269,20 +482,25 @@ int passphrase_callback(char *buf, int num, int v, void *arg) {
gilstate = PyGILState_Ensure();
cbfunc = (PyObject *)arg;
argv = Py_BuildValue("(i)", v);
+ /* PyEval_CallObject sets exception, if needed. */
ret = PyEval_CallObject(cbfunc, argv);
Py_DECREF(argv);
if (ret == NULL) {
PyGILState_Release(gilstate);
return -1;
}
- if (!PyString_Check(ret)) {
+
+ if (!PyBytes_Check(ret)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Result of callback is not bytes().");
Py_DECREF(ret);
PyGILState_Release(gilstate);
return -1;
}
- if ((len = PyString_Size(ret)) > num)
+ if ((len = PyBytes_Size(ret)) > num)
len = num;
- str = PyString_AsString(ret);
+ str = PyBytes_AsString(ret);
+
for (i = 0; i < len; i++)
buf[i] = str[i];
Py_DECREF(ret);
@@ -292,34 +510,38 @@ int passphrase_callback(char *buf, int num, int v, void *arg) {
%}
%inline %{
+
void lib_init() {
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSLeay_add_all_algorithms();
ERR_load_ERR_strings();
+#endif
}
-/* Bignum routines that aren't not numerous enough to
+/* Bignum routines that aren't not numerous enough to
warrant a separate file. */
-PyObject *bn_to_mpi(BIGNUM *bn) {
- int len;
+PyObject *bn_to_mpi(const BIGNUM *bn) {
+ int len = 0;
unsigned char *mpi;
- PyObject *pyo;
+ PyObject *pyo;
len = BN_bn2mpi(bn, NULL);
if (!(mpi=(unsigned char *)PyMem_Malloc(len))) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_MemoryError);
return NULL;
}
len=BN_bn2mpi(bn, mpi);
- pyo=PyString_FromStringAndSize((const char *)mpi, len);
+
+ pyo=PyBytes_FromStringAndSize((const char *)mpi, len);
+
PyMem_Free(mpi);
return pyo;
}
-BIGNUM *mpi_to_bn(PyObject *value) {
+const BIGNUM *mpi_to_bn(PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
@@ -328,9 +550,9 @@ BIGNUM *mpi_to_bn(PyObject *value) {
}
PyObject *bn_to_bin(BIGNUM *bn) {
- int len;
+ int len = 0;
unsigned char *bin;
- PyObject *pyo;
+ PyObject *pyo;
len = BN_num_bytes(bn);
if (!(bin=(unsigned char *)PyMem_Malloc(len))) {
@@ -338,14 +560,16 @@ PyObject *bn_to_bin(BIGNUM *bn) {
return NULL;
}
BN_bn2bin(bn, bin);
- pyo=PyString_FromStringAndSize((const char *)bin, len);
+
+ pyo=PyBytes_FromStringAndSize((const char *)bin, len);
+
PyMem_Free(bin);
return pyo;
}
-BIGNUM *bin_to_bn(PyObject *value) {
+const BIGNUM *bin_to_bn(PyObject *value) {
const void *vbuf;
- int vlen;
+ int vlen = 0;
if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
return NULL;
@@ -355,25 +579,26 @@ BIGNUM *bin_to_bn(PyObject *value) {
PyObject *bn_to_hex(BIGNUM *bn) {
char *hex;
- PyObject *pyo;
- Py_ssize_t len;
+ PyObject *pyo;
+ Py_ssize_t len = 0;
hex = BN_bn2hex(bn);
if (!hex) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_RuntimeError);
OPENSSL_free(hex);
- return NULL;
+ return NULL;
}
len = strlen(hex);
- pyo=PyString_FromStringAndSize(hex, len);
+
+ pyo=PyBytes_FromStringAndSize(hex, len);
+
OPENSSL_free(hex);
return pyo;
}
BIGNUM *hex_to_bn(PyObject *value) {
const void *vbuf;
- Py_ssize_t vlen;
+ Py_ssize_t vlen = 0;
BIGNUM *bn;
if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
@@ -384,8 +609,7 @@ BIGNUM *hex_to_bn(PyObject *value) {
return NULL;
}
if (BN_hex2bn(&bn, (const char *)vbuf) <= 0) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_RuntimeError);
BN_free(bn);
return NULL;
}
@@ -394,7 +618,7 @@ BIGNUM *hex_to_bn(PyObject *value) {
BIGNUM *dec_to_bn(PyObject *value) {
const void *vbuf;
- Py_ssize_t vlen;
+ Py_ssize_t vlen = 0;
BIGNUM *bn;
if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
@@ -405,8 +629,7 @@ BIGNUM *dec_to_bn(PyObject *value) {
return NULL;
}
if ((BN_dec2bn(&bn, (const char *)vbuf) <= 0)) {
- PyErr_SetString(PyExc_RuntimeError,
- ERR_error_string(ERR_get_error(), NULL));
+ m2_PyErr_Msg(PyExc_RuntimeError);
BN_free(bn);
return NULL;
}
@@ -418,23 +641,26 @@ BIGNUM *dec_to_bn(PyObject *value) {
/* Various useful typemaps. */
%typemap(in) Blob * {
- Py_ssize_t len;
+ Py_ssize_t len = 0;
- if (!PyString_Check($input)) {
+ if (!PyBytes_Check($input)) {
PyErr_SetString(PyExc_TypeError, "expected PyString");
return NULL;
}
- len=PyString_Size($input);
+ len=PyBytes_Size($input);
+
if (len > INT_MAX) {
PyErr_SetString(PyExc_ValueError, "object too large");
- return -1;
+ return NULL;
}
$1=(Blob *)PyMem_Malloc(sizeof(Blob));
if (!$1) {
PyErr_SetString(PyExc_MemoryError, "malloc Blob");
return NULL;
}
- $1->data=(unsigned char *)PyString_AsString($input);
+
+ $1->data=(unsigned char *)PyBytes_AsString($input);
+
$1->len=len;
}
@@ -443,20 +669,14 @@ BIGNUM *dec_to_bn(PyObject *value) {
Py_INCREF(Py_None);
$result=Py_None;
} else {
- $result=PyString_FromStringAndSize((const char *)$1->data, $1->len);
+
+ $result=PyBytes_FromStringAndSize((const char *)$1->data, $1->len);
+
PyMem_Free($1->data);
PyMem_Free($1);
}
}
-%typemap(in) FILE * {
- if (!PyFile_Check($input)) {
- PyErr_SetString(PyExc_TypeError, "expected PyFile");
- return NULL;
- }
- $1=PyFile_AsFile($input);
-}
-
%typemap(in) PyObject *pyfunc {
if (!PyCallable_Check($input)) {
PyErr_SetString(PyExc_TypeError, "expected PyCallable");
@@ -466,7 +686,8 @@ BIGNUM *dec_to_bn(PyObject *value) {
}
%typemap(in) PyObject *pyblob {
- if (!PyString_Check($input)) {
+ if (!PyBytes_Check($input)) {
+
PyErr_SetString(PyExc_TypeError, "expected PyString");
return NULL;
}
@@ -482,7 +703,7 @@ BIGNUM *dec_to_bn(PyObject *value) {
}
%typemap(out) int {
- $result=PyInt_FromLong($1);
+ $result=PyLong_FromLong($1);
if (PyErr_Occurred()) SWIG_fail;
}
@@ -493,9 +714,6 @@ BIGNUM *dec_to_bn(PyObject *value) {
/* A bunch of "straight-thru" functions. */
-%rename(err_print_errors_fp) ERR_print_errors_fp;
-%threadallow ERR_print_errors_fp;
-extern void ERR_print_errors_fp(FILE *);
%rename(err_print_errors) ERR_print_errors;
%threadallow ERR_print_errors;
extern void ERR_print_errors(BIO *);