summaryrefslogtreecommitdiff
path: root/SWIG/_bio.i
diff options
context:
space:
mode:
authoryan11.meng <yan11.meng@samsung.com>2020-02-26 12:47:07 +0900
committeryan11.meng <yan11.meng@samsung.com>2020-02-26 12:47:07 +0900
commit13ec6f74c73b377d6233de42cc942846e976541b (patch)
tree894efb8d5e53dd68dd463f7b222406439f4f494d /SWIG/_bio.i
parent5015799de7fb1dc08b584c0044d8393e4062ff34 (diff)
downloadpython-M2Crypto-13ec6f74c73b377d6233de42cc942846e976541b.tar.gz
python-M2Crypto-13ec6f74c73b377d6233de42cc942846e976541b.tar.bz2
python-M2Crypto-13ec6f74c73b377d6233de42cc942846e976541b.zip
Imported Upstream version 0.35.1
Change-Id: Id4a444b8c1d11fee1026b433a47ca5aabcf11622
Diffstat (limited to 'SWIG/_bio.i')
-rw-r--r--SWIG/_bio.i366
1 files changed, 342 insertions, 24 deletions
diff --git a/SWIG/_bio.i b/SWIG/_bio.i
index 441ba06..e85a275 100644
--- a/SWIG/_bio.i
+++ b/SWIG/_bio.i
@@ -4,8 +4,9 @@
* Portions created by Open Source Applications Foundation (OSAF) are
* Copyright (C) 2004-2005 OSAF. All Rights Reserved.
* Author: Heikki Toivonen
-*/
-/* $Id: _bio.i 695 2009-07-24 06:37:01Z heikki $ */
+ *
+ * Copyright 2018 Daniel Wozniak. All Rights Reserved.*/
+/* $Id$ */
%{
#include <openssl/bio.h>
@@ -31,15 +32,8 @@ extern BIO_METHOD *BIO_f_cipher(void);
extern BIO *BIO_new(BIO_METHOD *);
%rename(bio_new_socket) BIO_new_socket;
extern BIO *BIO_new_socket(int, int);
-%rename(bio_new_fd) BIO_new_fd;
-extern BIO *BIO_new_fd(int, int);
-%rename(bio_new_fp) BIO_new_fp;
-extern BIO *BIO_new_fp(FILE *, int);
-%rename(bio_new_file) BIO_new_file;
-extern BIO *BIO_new_file(const char *, const char *);
-%rename(bio_free) BIO_free;
-%threadallow BIO_free;
-extern int BIO_free(BIO *);
+%rename(bio_new_fd) BIO_new_pyfd;
+%rename(bio_new_pyfd) BIO_new_pyfd;
%rename(bio_free_all) BIO_free_all;
%threadallow BIO_free_all;
extern void BIO_free_all(BIO *);
@@ -51,6 +45,9 @@ extern BIO *BIO_push(BIO *, BIO *);
%rename(bio_pop) BIO_pop;
extern BIO *BIO_pop(BIO *);
+%rename(bio_eof) BIO_eof;
+extern int BIO_eof(BIO *);
+
%constant int bio_noclose = BIO_NOCLOSE;
%constant int bio_close = BIO_CLOSE;
%constant int BIO_FLAGS_READ = 0x01;
@@ -60,12 +57,71 @@ extern BIO *BIO_pop(BIO *);
%constant int BIO_FLAGS_SHOULD_RETRY = 0x08;
%constant int BIO_FLAGS_MEM_RDONLY = 0x200;
+%warnfilter(454) _bio_err;
%inline %{
static PyObject *_bio_err;
+
+void pyfd_init(void);
+
void bio_init(PyObject *bio_err) {
Py_INCREF(bio_err);
_bio_err = bio_err;
+ pyfd_init();
+}
+
+int bio_free(BIO *bio) {
+ int ret;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_free(bio);
+ Py_END_ALLOW_THREADS
+ if (ret == 0) {
+ m2_PyErr_Msg(_bio_err);
+ }
+ return ret;
+}
+
+BIO * bio_new_file(const char *filename, const char *mode) {
+ BIO *ret;
+
+ Py_BEGIN_ALLOW_THREADS
+ ret = BIO_new_file(filename, mode);
+ Py_END_ALLOW_THREADS
+
+ if (ret == NULL) {
+ m2_PyErr_Msg(_bio_err);
+ }
+
+ return ret;
+}
+
+BIO *bio_new_pyfile(PyObject *pyfile, int bio_close) {
+ FILE *fp = NULL;
+ BIO *bio = NULL;
+
+ fp = PyFile_AsFile(pyfile);
+
+ bio = BIO_new_fp(fp, bio_close);
+
+ /* returns NULL if error occurred */
+ if (bio == NULL) {
+ /* Find out the name of the file so we can have good error
+ * message. */
+ PyObject *pyname = m2_PyFile_Name(pyfile);
+ char *name = PyBytes_AsString(pyname);
+
+ if (name == NULL) {
+ PyErr_Format(_bio_err,
+ "Opening of the new BIO on file failed!");
+ }
+ else {
+ PyErr_Format(_bio_err,
+ "Opening of the new BIO on file %s failed!", name);
+ }
+ Py_DECREF(pyname);
+ }
+ return bio;
}
PyObject *bio_read(BIO *bio, int num) {
@@ -83,13 +139,14 @@ PyObject *bio_read(BIO *bio, int num) {
if (r < 0) {
PyMem_Free(buf);
if (ERR_peek_error()) {
- PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_bio_err);
return NULL;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
- blob = PyString_FromStringAndSize(buf, r);
+
+ blob = PyBytes_FromStringAndSize(buf, r);
+
PyMem_Free(buf);
return blob;
}
@@ -106,23 +163,24 @@ PyObject *bio_gets(BIO *bio, int num) {
Py_BEGIN_ALLOW_THREADS
r = BIO_gets(bio, buf, num);
Py_END_ALLOW_THREADS
- if (r < 0) {
+ if (r < 1) {
PyMem_Free(buf);
if (ERR_peek_error()) {
- PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_bio_err);
return NULL;
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
- blob = PyString_FromStringAndSize(buf, r);
+
+ blob = PyBytes_FromStringAndSize(buf, r);
+
PyMem_Free(buf);
return blob;
}
int bio_write(BIO *bio, PyObject *from) {
const void *fbuf;
- int flen, ret;
+ int flen = 0, ret;
if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
return -1;
@@ -132,7 +190,8 @@ int bio_write(BIO *bio, PyObject *from) {
Py_END_ALLOW_THREADS
if (ret < 0) {
if (ERR_peek_error()) {
- PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
+ m2_PyErr_Msg(_bio_err);
+ return -1;
}
}
return ret;
@@ -166,6 +225,10 @@ int bio_seek(BIO *bio, int offset) {
return (int)BIO_seek(bio, offset);
}
+int bio_tell(BIO* bio) {
+ return BIO_tell(bio);
+}
+
void bio_set_flags(BIO *bio, int flags) {
BIO_set_flags(bio, flags);
}
@@ -174,6 +237,11 @@ int bio_get_flags(BIO *bio) {
return BIO_get_flags(bio);
}
+/*
+ * sets the cipher of BIO @param b to c using key @param key and IV @iv.
+ * @param enc should be set to 1 for encryption and zero to decryption.
+ *
+ */
PyObject *bio_set_cipher(BIO *b, EVP_CIPHER *c, PyObject *key, PyObject *iv, int op) {
const void *kbuf, *ibuf;
Py_ssize_t klen, ilen;
@@ -184,8 +252,7 @@ PyObject *bio_set_cipher(BIO *b, EVP_CIPHER *c, PyObject *key, PyObject *iv, int
BIO_set_cipher(b, (const EVP_CIPHER *)c,
(unsigned char *)kbuf, (unsigned char *)ibuf, op);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
int bio_set_mem_eof_return(BIO *b, int v) {
@@ -197,6 +264,7 @@ int bio_get_fd(BIO *bio) {
}
%}
+%warnfilter(454) methods_fdp;
%threadallow bio_do_handshake;
%inline %{
int bio_do_handshake(BIO *bio) {
@@ -223,5 +291,255 @@ int bio_should_read(BIO* a) {
int bio_should_write(BIO* a) {
return BIO_should_write(a);
}
+
+/* Macros for things not defined before 1.1.0 */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static BIO_METHOD *
+BIO_meth_new( int type, const char *name )
+{
+ BIO_METHOD *method = malloc( sizeof(BIO_METHOD) );
+ memset( method, 0, sizeof(BIO_METHOD) );
+
+ method->type = type;
+ method->name = name;
+
+ return method;
+}
+
+static void
+BIO_meth_free( BIO_METHOD *meth )
+{
+ if ( meth == NULL ) {
+ return;
+ }
+
+ free(meth);
+}
+#define BIO_meth_set_write(m, f) (m)->bwrite = (f)
+#define BIO_meth_set_read(m, f) (m)->bread = (f)
+#define BIO_meth_set_puts(m, f) (m)->bputs = (f)
+#define BIO_meth_set_gets(m, f) (m)->bgets = (f)
+#define BIO_meth_set_ctrl(m, f) (m)->ctrl = (f)
+#define BIO_meth_set_create(m, f) (m)->create = (f)
+#define BIO_meth_set_destroy(m, f) (m)->destroy = (f)
+#define BIO_set_shutdown(b, x) (b)->shutdown = x
+#define BIO_get_shutdown(b) (b)->shutdown
+#define BIO_set_init(b, x) b->init = x
+#define BIO_get_init(b) (b)->init
+#define BIO_set_data(b, x) b->ptr = x
+#define BIO_clear_flags(b, x) b->flags &= ~(x)
+#define BIO_get_data(b) b->ptr
+#endif
+
+/* implment custom BIO_s_pyfd */
+
+#ifdef _WIN32
+# define clear_sys_error() SetLastError(0)
+/* Linux doesn't use underscored calls yet */
+# define open(p, f, m) _open(p, f, m)
+# define read(f, b, n) _read(f, b, n)
+# define write(f, b, n) _write(f, b, n)
+# define close(f) _close(f)
+# define lseek(fd, o, w) _lseek(fd, o, w)
+#else
+# define clear_sys_error() errno=0
+#endif
+
+typedef struct pyfd_struct {
+ int fd;
+} BIO_PYFD_CTX;
+
+/* Setting up methods_fdp */
+static BIO_METHOD *methods_fdp;
+
+static int pyfd_write(BIO *b, const char *in, int inl) {
+ int ret, fd;
+
+ if (BIO_get_fd(b, &fd) == -1) {
+ PyErr_SetString(_bio_err, "BIO has not been initialized.");
+ return -1;
+ }
+ clear_sys_error();
+ ret = write(fd, in, inl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_write(b);
+ }
+ return ret;
+}
+
+static int pyfd_read(BIO *b, char *out, int outl) {
+ int ret = 0, fd;
+
+ if (BIO_get_fd(b, &fd) == -1) {
+ PyErr_SetString(_bio_err, "BIO has not been initialized.");
+ return -1;
+ }
+ if (out != NULL) {
+ clear_sys_error();
+ ret = read(fd, out, outl);
+ BIO_clear_retry_flags(b);
+ if (ret <= 0) {
+ if (BIO_fd_should_retry(ret))
+ BIO_set_retry_read(b);
+ }
+ }
+ return ret;
+}
+
+static int pyfd_puts(BIO *bp, const char *str) {
+ int n, ret;
+
+ n = strlen(str);
+ ret = pyfd_write(bp, str, n);
+ return ret;
+}
+
+static int pyfd_gets(BIO *bp, char *buf, int size) {
+ int ret = 0;
+ char *ptr = buf;
+ char *end = buf + size - 1;
+
+ /* See
+ https://github.com/openssl/openssl/pull/3442
+ We were here just repeating a bug from OpenSSL
+ */
+ while (ptr < end && pyfd_read(bp, ptr, 1) > 0) {
+ if (*ptr++ == '\n')
+ break;
+ }
+
+ ptr[0] = '\0';
+
+ if (buf[0] != '\0')
+ ret = strlen(buf);
+ return ret;
+}
+
+static int pyfd_new(BIO* b) {
+ BIO_PYFD_CTX* ctx;
+
+ ctx = OPENSSL_zalloc(sizeof(*ctx));
+ if (ctx == NULL)
+ return 0;
+
+ ctx->fd = -1;
+
+ BIO_set_data(b, ctx);
+ BIO_set_shutdown(b, 0);
+ BIO_set_init(b, 1);
+
+ return 1;
+ }
+
+static int pyfd_free(BIO* b) {
+ BIO_PYFD_CTX* ctx;
+
+ if (b == 0)
+ return 0;
+
+ ctx = BIO_get_data(b);
+ if (ctx == NULL)
+ return 0;
+
+ if (BIO_get_shutdown(b) && BIO_get_init(b))
+ close(ctx->fd);
+
+ BIO_set_data(b, NULL);
+ BIO_set_shutdown(b, 0);
+ BIO_set_init(b, 0);
+
+ OPENSSL_free(ctx);
+
+ return 1;
+}
+
+static long pyfd_ctrl(BIO *b, int cmd, long num, void *ptr) {
+ BIO_PYFD_CTX* ctx;
+ int *ip;
+ long ret = 1;
+
+ ctx = BIO_get_data(b);
+ if (ctx == NULL)
+ return 0;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ num = 0;
+ case BIO_C_FILE_SEEK:
+ ret = (long)lseek(ctx->fd, num, 0);
+ break;
+ case BIO_C_FILE_TELL:
+ case BIO_CTRL_INFO:
+ ret = (long)lseek(ctx->fd, 0, 1);
+ break;
+ case BIO_C_SET_FD:
+ pyfd_free(b);
+ if (*((int *)ptr) > -1) {
+ if (!pyfd_new(b) || !(ctx = BIO_get_data(b)))
+ return 0;
+ ctx->fd = *((int *)ptr);
+ BIO_set_shutdown(b, (int)num);
+ BIO_set_init(b, 1);
+ }
+ break;
+ case BIO_C_GET_FD:
+ if (BIO_get_init(b)) {
+ ip = (int *)ptr;
+ if (ip != NULL)
+ *ip = ctx->fd;
+ ret = ctx->fd;
+ } else
+ ret = -1;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = BIO_get_shutdown(b);
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ BIO_set_shutdown(b, (int)num);
+ break;
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_WPENDING:
+ ret = 0;
+ break;
+ case BIO_CTRL_DUP:
+ case BIO_CTRL_FLUSH:
+ ret = 1;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+void pyfd_init(void) {
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ methods_fdp = BIO_meth_new(
+ BIO_get_new_index()|BIO_TYPE_DESCRIPTOR|BIO_TYPE_SOURCE_SINK,
+ "python file descriptor");
+#else
+ methods_fdp = BIO_meth_new(
+ 100 |BIO_TYPE_DESCRIPTOR|BIO_TYPE_SOURCE_SINK,
+ "python file descriptor");
+#endif
+
+ BIO_meth_set_write(methods_fdp, pyfd_write);
+ BIO_meth_set_read(methods_fdp, pyfd_read);
+ BIO_meth_set_puts(methods_fdp, pyfd_puts);
+ BIO_meth_set_gets(methods_fdp, pyfd_gets);
+ BIO_meth_set_ctrl(methods_fdp, pyfd_ctrl);
+ BIO_meth_set_create(methods_fdp, pyfd_new);
+ BIO_meth_set_destroy(methods_fdp, pyfd_free);
+}
+
+BIO* BIO_new_pyfd(int fd, int close_flag) {
+ BIO *ret;
+
+ ret = BIO_new(methods_fdp);
+ BIO_set_fd(ret, fd, close_flag);
+ return ret;
+ }
%}