Index: SWIG/_evp.i
===================================================================
--- SWIG/_evp.i	(revision 739)
+++ SWIG/_evp.i	(working copy)
@@ -169,22 +169,23 @@
                                  int iter,
                                  int keylen) {
     unsigned char key[EVP_MAX_KEY_LENGTH];
-    unsigned char *saltbuf;
-    char *passbuf;
     PyObject *ret;
-    int passlen, saltlen;
+    Py_buffer passbuf, saltbuf;
 
-    if (m2_PyObject_AsReadBufferInt(pass, (const void **)&passbuf,
-                                    &passlen) == -1)
+    if (m2_PyObject_GetBufferInt(pass, &passbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
+    if (m2_PyObject_GetBufferInt(salt, &saltbuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(pass, &passbuf);
         return NULL;
-    if (m2_PyObject_AsReadBufferInt(salt, (const void **)&saltbuf,
-                                    &saltlen) == -1)
-        return NULL;
+    }
 
-    PKCS5_PBKDF2_HMAC_SHA1(passbuf, passlen, saltbuf, saltlen, iter,
-                           keylen, key);
+    PKCS5_PBKDF2_HMAC_SHA1((char *) passbuf.buf, passbuf.len,
+                           (unsigned char *) saltbuf.buf, saltbuf.len,
+                           iter, keylen, key);
     ret = PyString_FromStringAndSize((char*)key, keylen);
     OPENSSL_cleanse(key, keylen);
+    m2_PyBuffer_Release(pass, &passbuf);
+    m2_PyBuffer_Release(salt, &saltbuf);
     return ret;
 }
 
@@ -202,13 +203,15 @@
 }
 
 int digest_update(EVP_MD_CTX *ctx, PyObject *blob) {
-    const void *buf;
-    Py_ssize_t len;
+    Py_buffer buf;
+    int ret;
 
-    if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
-        return -1;
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
+      return -1;
 
-    return EVP_DigestUpdate(ctx, buf, len);
+    ret = EVP_DigestUpdate(ctx, buf.buf, buf.len);
+    m2_PyBuffer_Release(blob, &buf);
+    return ret;
 }
 
 PyObject *digest_final(EVP_MD_CTX *ctx) {
@@ -247,25 +250,25 @@
 }
 
 PyObject *hmac_init(HMAC_CTX *ctx, PyObject *key, const EVP_MD *md) {
-    const void *kbuf;
-    int klen;
+    Py_buffer kbuf;
 
-    if (m2_PyObject_AsReadBufferInt(key, &kbuf, &klen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(key, &kbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    HMAC_Init(ctx, kbuf, klen, md);
+    HMAC_Init(ctx, kbuf.buf, kbuf.len, md);
+    m2_PyBuffer_Release(key, &kbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *hmac_update(HMAC_CTX *ctx, PyObject *blob) {
-    const void *buf;
-    Py_ssize_t len;
+    Py_buffer buf;
 
-    if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    HMAC_Update(ctx, buf, len);
+    HMAC_Update(ctx, buf.buf, buf.len);
+    m2_PyBuffer_Release(blob, &buf);
     Py_INCREF(Py_None);
     return Py_None;
 }
@@ -286,25 +289,30 @@
 }
 
 PyObject *hmac(PyObject *key, PyObject *data, const EVP_MD *md) {
-    const void *kbuf, *dbuf;
     void *blob;
-    int klen;
     unsigned int blen;
-    Py_ssize_t dlen;
     PyObject *ret;
+    Py_buffer kbuf, dbuf;
 
-    if ((m2_PyObject_AsReadBufferInt(key, &kbuf, &klen) == -1)
-        || (PyObject_AsReadBuffer(data, &dbuf, &dlen) == -1))
+    if (m2_PyObject_GetBufferInt(key, &kbuf, PyBUF_SIMPLE) == -1)
         return NULL;
+    if (m2_PyObject_GetBuffer(data, &dbuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(key, &kbuf);
+        return NULL;
+    }
 
     if (!(blob = PyMem_Malloc(EVP_MAX_MD_SIZE))) {
         PyErr_SetString(PyExc_MemoryError, "hmac");
+        m2_PyBuffer_Release(key, &kbuf);
+        m2_PyBuffer_Release(data, &dbuf);
         return NULL;
     }
-    HMAC(md, kbuf, klen, dbuf, dlen, blob, &blen);
+    HMAC(md, kbuf.buf, kbuf.len, dbuf.buf, dbuf.len, blob, &blen);
     blob = PyMem_Realloc(blob, blen);
     ret = PyString_FromStringAndSize(blob, blen);
     PyMem_Free(blob);
+    m2_PyBuffer_Release(key, &kbuf);
+    m2_PyBuffer_Release(data, &dbuf);
     return ret;
 }
 
@@ -329,61 +337,74 @@
                         PyObject *iv, /* Not used */
                         int iter) {
     unsigned char key[EVP_MAX_KEY_LENGTH];
-    const void *dbuf, *sbuf;
-    int dlen, klen;
-    Py_ssize_t slen;
+    int klen;
     PyObject *ret;
+    Py_buffer dbuf, sbuf;
 
-    if ((m2_PyObject_AsReadBufferInt(data, &dbuf, &dlen) == -1)
-        || (PyObject_AsReadBuffer(salt, &sbuf, &slen) == -1))
+    if (m2_PyObject_GetBufferInt(data, &dbuf, PyBUF_SIMPLE) == -1)
         return NULL;
+    if (m2_PyObject_GetBuffer(salt, &sbuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(data, &dbuf);
+        return NULL;
+    }
 
-    assert((slen == 8) || (slen == 0));
-    klen = EVP_BytesToKey(cipher, md, (unsigned char *)sbuf, 
-        (unsigned char *)dbuf, dlen, iter, 
+    assert((sbuf.len == 8) || (sbuf.len == 0));
+    klen = EVP_BytesToKey(cipher, md, (unsigned char *)sbuf.buf,
+        (unsigned char *)dbuf.buf, dbuf.len, iter,
         key, NULL); /* Since we are not returning IV no need to derive it */
     ret = PyString_FromStringAndSize((char*)key, klen);
+    m2_PyBuffer_Release(data, &dbuf);
+    m2_PyBuffer_Release(salt, &sbuf);
     return ret;
 }
 
 PyObject *cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, 
                         PyObject *key, PyObject *iv, int mode) {
-    const void *kbuf, *ibuf;
-    Py_ssize_t klen, ilen;
+    Py_buffer kbuf, ibuf;
 
-    if ((PyObject_AsReadBuffer(key, &kbuf, &klen) == -1)
-        || (PyObject_AsReadBuffer(iv, &ibuf, &ilen) == -1))
+    if (m2_PyObject_GetBuffer(key, &kbuf, PyBUF_SIMPLE) == -1)
         return NULL;
+    if (m2_PyObject_GetBuffer(iv, &ibuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(key, &kbuf);
+        return NULL;
+    }
 
-    if (!EVP_CipherInit(ctx, cipher, (unsigned char *)kbuf,
-                        (unsigned char *)ibuf, mode)) {
+    if (!EVP_CipherInit(ctx, cipher, (unsigned char *)kbuf.buf,
+                        (unsigned char *)ibuf.buf, mode)) {
         PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(key, &kbuf);
+        m2_PyBuffer_Release(iv, &ibuf);
         return NULL;
     }
     Py_INCREF(Py_None);
+    m2_PyBuffer_Release(key, &kbuf);
+    m2_PyBuffer_Release(iv, &ibuf);
     return Py_None;
 }
 
 PyObject *cipher_update(EVP_CIPHER_CTX *ctx, PyObject *blob) {
-    const void *buf;
-    int len, olen;
+    int olen;
     void *obuf;
     PyObject *ret;
+    Py_buffer buf;
 
-    if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1)
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    if (!(obuf = PyMem_Malloc(len + EVP_CIPHER_CTX_block_size(ctx) - 1))) {
+    if (!(obuf = PyMem_Malloc(buf.len + EVP_CIPHER_CTX_block_size(ctx) - 1))) {
         PyErr_SetString(PyExc_MemoryError, "cipher_update");
+        m2_PyBuffer_Release(blob, &buf);
         return NULL;
     }
-    if (!EVP_CipherUpdate(ctx, obuf, &olen, (unsigned char *)buf, len)) {
+    if (!EVP_CipherUpdate(ctx, obuf, &olen, (unsigned char *)buf.buf, buf.len)) {
         PyMem_Free(obuf);
         PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(blob, &buf);
         return NULL;
     }
     ret = PyString_FromStringAndSize(obuf, olen);
     PyMem_Free(obuf);
+    m2_PyBuffer_Release(blob, &buf);
     return ret;
 }
 
@@ -407,17 +428,18 @@
 }
 
 PyObject *sign_update(EVP_MD_CTX *ctx, PyObject *blob) {
-    const void *buf;
-    Py_ssize_t len;
+    Py_buffer buf;
 
-    if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    if (!EVP_SignUpdate(ctx, buf, len)) {
+    if (!EVP_SignUpdate(ctx, buf.buf, buf.len)) {
         PyErr_SetString(_evp_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(blob, &buf);
         return NULL;
     }
     Py_INCREF(Py_None);
+    m2_PyBuffer_Release(blob, &buf);
     return Py_None;
 }
 
@@ -445,24 +467,27 @@
 }
 
 int verify_update(EVP_MD_CTX *ctx, PyObject *blob) {
-    const void *buf;
-    Py_ssize_t len;
+    Py_buffer buf;
+    int ret;
 
-    if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
         return -1;
-
-    return EVP_VerifyUpdate(ctx, buf, len);
+    ret = EVP_VerifyUpdate(ctx, buf.buf, buf.len);
+    m2_PyBuffer_Release(blob, &buf);
+    return ret;
 }
 
 
 int verify_final(EVP_MD_CTX *ctx, PyObject *blob, EVP_PKEY *pkey) {
-    unsigned char *kbuf; 
-    int len;
+    Py_buffer kbuf;
+    int ret;
 
-    if (m2_PyObject_AsReadBufferInt(blob, (const void **)&kbuf, &len) == -1)
+    if (m2_PyObject_GetBufferInt(blob, &kbuf, PyBUF_SIMPLE) == -1)
         return -1;
 
-    return EVP_VerifyFinal(ctx, kbuf, len, pkey);
+    ret = EVP_VerifyFinal(ctx, (unsigned char *) kbuf.buf, kbuf.len, pkey);
+    m2_PyBuffer_Release(blob, &kbuf);
+    return ret;
 }
 %}
 
Index: SWIG/_dh.i
===================================================================
--- SWIG/_dh.i	(revision 739)
+++ SWIG/_dh.i	(working copy)
@@ -83,33 +83,37 @@
 }
 
 PyObject *dh_compute_key(DH *dh, PyObject *pubkey) {
-    const void *pkbuf;
-    int pklen, klen;
+    Py_buffer pkbuf;
+    int klen;
     void *key;
     BIGNUM *pk;
     PyObject *ret;
 
-    if (m2_PyObject_AsReadBufferInt(pubkey, &pkbuf, &pklen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(pubkey, &pkbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(pk = BN_mpi2bn((unsigned char *)pkbuf, pklen, NULL))) {
+    if (!(pk = BN_mpi2bn((unsigned char *)pkbuf.buf, pkbuf.len, NULL))) {
         PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(pubkey, &pkbuf);
         return NULL;
     }
     if (!(key = PyMem_Malloc(DH_size(dh)))) {
         BN_free(pk);
         PyErr_SetString(PyExc_MemoryError, "dh_compute_key");
+        m2_PyBuffer_Release(pubkey, &pkbuf);
         return NULL;
     }
     if ((klen = DH_compute_key((unsigned char *)key, pk, dh)) == -1) {
         BN_free(pk);
         PyMem_Free(key);
         PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(pubkey, &pkbuf);
         return NULL;
     }
     ret = PyString_FromStringAndSize((const char *)key, klen);
     BN_free(pk);
     PyMem_Free(key);
+    m2_PyBuffer_Release(pubkey, &pkbuf);
     return ret;
 }
         
@@ -147,39 +151,41 @@
 
 PyObject *dh_set_p(DH *dh, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)vbuf.buf, vbuf.len, NULL))) {
         PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (dh->p)
         BN_free(dh->p);
     dh->p = bn;
+    m2_PyBuffer_Release(value, &vbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *dh_set_g(DH *dh, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)vbuf.buf, vbuf.len, NULL))) {
         PyErr_SetString(_dh_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (dh->g)
         BN_free(dh->g);
     dh->g = bn;
     Py_INCREF(Py_None);
+    m2_PyBuffer_Release(value, &vbuf);
     return Py_None;
 }
 %}
Index: SWIG/_ssl.i
===================================================================
--- SWIG/_ssl.i	(revision 739)
+++ SWIG/_ssl.i	(working copy)
@@ -315,13 +315,14 @@
 }
 
 int ssl_ctx_set_session_id_context(SSL_CTX *ctx, PyObject *sid_ctx) {
-    const void *buf;
-    int len;
+    Py_buffer buf;
+    int ret;
 
-    if (m2_PyObject_AsReadBufferInt(sid_ctx, &buf, &len) == -1)
-        return -1;
-
-    return SSL_CTX_set_session_id_context(ctx, buf, len);
+    if (m2_PyObject_GetBufferInt(sid_ctx, &buf, PyBUF_SIMPLE) == -1)
+      return -1;
+    ret = SSL_CTX_set_session_id_context(ctx, buf.buf, buf.len);
+    m2_PyBuffer_Release(sid_ctx, &buf);
+    return ret;
 }
 
 void ssl_ctx_set_info_callback(SSL_CTX *ctx, PyObject *pyfunc) {
@@ -384,13 +385,15 @@
 }
 
 int ssl_set_session_id_context(SSL *ssl, PyObject *sid_ctx) {
-    const void *buf;
-    int len;
+    Py_buffer buf;
+    int ret;
 
-    if (m2_PyObject_AsReadBufferInt(sid_ctx, &buf, &len) == -1)
-        return -1;
+    if (m2_PyObject_GetBufferInt(sid_ctx, &buf, PyBUF_SIMPLE) == -1)
+      return -1;
 
-    return SSL_set_session_id_context(ssl, buf, len);
+    ret = SSL_set_session_id_context(ssl, buf.buf, buf.len);
+    m2_PyBuffer_Release(sid_ctx, &buf);
+    return ret;
 }
 
 int ssl_set_fd(SSL *ssl, int fd) {
@@ -583,17 +586,14 @@
 }
 
 int ssl_write(SSL *ssl, PyObject *blob) {
-    const void *buf;
-    int len, r, err, ret;
+    int r, err, ret;
+    Py_buffer buf;
 
-
-    if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1) {
+    if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_SIMPLE) == -1)
         return -1;
-    }
 
-    
     Py_BEGIN_ALLOW_THREADS
-    r = SSL_write(ssl, buf, len);
+    r = SSL_write(ssl, buf.buf, buf.len);
     Py_END_ALLOW_THREADS
 
 
@@ -623,22 +623,19 @@
             ret = -1;
     }
     
-    
+    m2_PyBuffer_Release(blob, &buf);
     return ret;
 }
 
 int ssl_write_nbio(SSL *ssl, PyObject *blob) {
-    const void *buf;
-    int len, r, err, ret;
+    int r, err, ret;
+    Py_buffer buf;
 
-
-    if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1) {
+    if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_SIMPLE) == -1)
         return -1;
-    }
-
     
     Py_BEGIN_ALLOW_THREADS
-    r = SSL_write(ssl, buf, len);
+    r = SSL_write(ssl, buf.buf, buf.len);
     Py_END_ALLOW_THREADS
     
     
@@ -667,7 +664,7 @@
             ret = -1;
     }
     
-    
+    m2_PyBuffer_Release(blob, &buf);
     return ret;
 }
 
Index: SWIG/_lib.h
===================================================================
--- SWIG/_lib.h	(revision 739)
+++ SWIG/_lib.h	(working copy)
@@ -1,6 +1,15 @@
 /* Copyright (c) 1999 Ng Pheng Siong. All rights reserved. */
 /* $Id$ */
 
+#if PY_VERSION_HEX < 0x02060000
+typedef struct { /* Only a subset */
+  void *buf;
+  Py_ssize_t len;
+} Py_buffer;
+
+#define PyBUF_SIMPLE 0
+#endif /* PY_VERSION_HEX < 0x02060000 */
+
 #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
 typedef int Py_ssize_t;
 #define PY_SSIZE_T_MAX INT_MAX
@@ -8,14 +17,19 @@
 #endif
 
 typedef struct _blob {
-	unsigned char *data;
-	int len;
+  unsigned char *data;
+  int len;
 } Blob;
 
 Blob *blob_new(int len, const char *errmsg);
 Blob *blob_copy(Blob *from, const char *errmsg);
 void blob_free(Blob *blob);
 
+/* Always use these together, to correctly handle non-memoryview objects. */
+static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags);
+static int m2_PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+static void m2_PyBuffer_Release(PyObject *obj, Py_buffer *view);
+
 static int m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
                                        int *buffer_len);
 static int m2_PyString_AsStringAndSizeInt(PyObject *obj, char **s, int *len);
@@ -24,4 +38,3 @@
 int passphrase_callback(char *buf, int num, int v, void *userdata);
 
 void lib_init(void);
-
Index: SWIG/_lib.i
===================================================================
--- SWIG/_lib.i	(revision 739)
+++ SWIG/_lib.i	(working copy)
@@ -47,9 +47,73 @@
 /* Python helpers. */
 
 %}
+%ignore PyBuffer_Release;
+%ignore PyObject_CheckBuffer;
+%ignore PyObject_GetBuffer;
+%ignore m2_PyBuffer_Release;
+%ignore m2_PyObject_GetBuffer;
+%ignore m2_PyObject_GetBufferInt;
 %ignore m2_PyObject_AsReadBufferInt;
 %ignore m2_PyString_AsStringAndSizeInt;
 %{
+
+
+#if PY_VERSION_HEX < 0x02060000
+static int PyObject_CheckBuffer(PyObject *obj) {
+    (void)obj;
+    return 0;
+}
+
+static int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+    (void)obj;
+    (void)view;
+    (void)flags;
+    return -1;
+}
+
+static void PyBuffer_Release(Py_buffer *view) {
+    (void)view;
+}
+#endif /* PY_VERSION_HEX < 0x02060000 */
+
+
+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_PyObject_GetBuffer(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;
+  }
+  return ret;
+}
+
+
+static int m2_PyObject_GetBufferInt(PyObject *obj, Py_buffer *view, int flags) {
+  int ret;
+
+  ret = m2_PyObject_GetBuffer(obj, view, flags);
+  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 int
 m2_PyObject_AsReadBufferInt(PyObject *obj, const void **buffer,
                 int *buffer_len)
@@ -73,7 +137,6 @@
 {
     int ret;
     Py_ssize_t len2;
-
     ret = PyString_AsStringAndSize(obj, s, &len2);
     if (ret)
        return ret;
@@ -318,13 +381,15 @@
 }
 
 BIGNUM *mpi_to_bn(PyObject *value) {
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
+    BIGNUM *ret;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    return BN_mpi2bn(vbuf, vlen, NULL);
+    ret = BN_mpi2bn(vbuf.buf, vbuf.len, NULL);
+    m2_PyBuffer_Release(value, &vbuf);
+    return ret;
 }
 
 PyObject *bn_to_bin(BIGNUM *bn) {
@@ -344,13 +409,15 @@
 }
 
 BIGNUM *bin_to_bn(PyObject *value) {
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
+    BIGNUM *ret;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    return BN_bin2bn(vbuf, vlen, NULL);
+    ret = BN_bin2bn(vbuf.buf, vbuf.len, NULL);
+    m2_PyBuffer_Release(value, &vbuf);
+    return ret;
 }
 
 PyObject *bn_to_hex(BIGNUM *bn) {
@@ -372,44 +439,48 @@
 }
 
 BIGNUM *hex_to_bn(PyObject *value) {
-    const void *vbuf;
-    Py_ssize_t vlen;
+    Py_buffer vbuf;
     BIGNUM *bn;
 
-    if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
     if ((bn=BN_new())==NULL) {
         PyErr_SetString(PyExc_MemoryError, "hex_to_bn");
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
-    if (BN_hex2bn(&bn, (const char *)vbuf) <= 0) {
+    if (BN_hex2bn(&bn, (const char *)vbuf.buf) <= 0) {
         PyErr_SetString(PyExc_RuntimeError, 
               ERR_error_string(ERR_get_error(), NULL));
         BN_free(bn);
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
+    m2_PyBuffer_Release(value, &vbuf);
     return bn;
 }
 
 BIGNUM *dec_to_bn(PyObject *value) {
-    const void *vbuf;
-    Py_ssize_t vlen;
+    Py_buffer vbuf;
     BIGNUM *bn;
 
-    if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
     if ((bn=BN_new())==NULL) {
       PyErr_SetString(PyExc_MemoryError, "dec_to_bn");
+      m2_PyBuffer_Release(value, &vbuf);
       return NULL;
     }
-    if ((BN_dec2bn(&bn, (const char *)vbuf) <= 0)) {
+    if ((BN_dec2bn(&bn, (const char *)vbuf.buf) <= 0)) {
       PyErr_SetString(PyExc_RuntimeError, 
             ERR_error_string(ERR_get_error(), NULL));
       BN_free(bn);
+      m2_PyBuffer_Release(value, &vbuf);
       return NULL;
     }
+    m2_PyBuffer_Release(value, &vbuf);
     return bn;
 }
 %}
Index: SWIG/_dsa.i
===================================================================
--- SWIG/_dsa.i	(revision 739)
+++ SWIG/_dsa.i	(working copy)
@@ -99,57 +99,60 @@
 
 PyObject *dsa_set_p(DSA *dsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)vbuf.buf, vbuf.len, NULL))) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (dsa->p)
         BN_free(dsa->p);
     dsa->p = bn;
+    m2_PyBuffer_Release(value, &vbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *dsa_set_q(DSA *dsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)vbuf.buf, vbuf.len, NULL))) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (dsa->q)
         BN_free(dsa->q);
     dsa->q = bn;
+    m2_PyBuffer_Release(value, &vbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *dsa_set_g(DSA *dsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)vbuf.buf, vbuf.len, NULL))) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (dsa->g)
         BN_free(dsa->g);
     dsa->g = bn;
+    m2_PyBuffer_Release(value, &vbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
@@ -236,97 +239,124 @@
 }
 
 PyObject *dsa_sign(DSA *dsa, PyObject *value) {
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
     PyObject *tuple;
     DSA_SIG *sig; 
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    if (!(sig = DSA_do_sign(vbuf, vlen, dsa))) {
+    if (!(sig = DSA_do_sign(vbuf.buf, vbuf.len, dsa))) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (!(tuple = PyTuple_New(2))) {
         DSA_SIG_free(sig);
         PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     PyTuple_SET_ITEM(tuple, 0, dsa_sig_get_r(sig));
     PyTuple_SET_ITEM(tuple, 1, dsa_sig_get_s(sig));
     DSA_SIG_free(sig);
+    m2_PyBuffer_Release(value, &vbuf);
     return tuple;
 }
 
 int dsa_verify(DSA *dsa, PyObject *value, PyObject *r, PyObject *s) {
-    const void *vbuf, *rbuf, *sbuf;
-    int vlen, rlen, slen;
+    Py_buffer vbuf, rbuf, sbuf;
     DSA_SIG *sig;
     int ret;
 
-    if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        || (m2_PyObject_AsReadBufferInt(r, &rbuf, &rlen) == -1)
-        || (m2_PyObject_AsReadBufferInt(s, &sbuf, &slen) == -1))
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
         return -1;
+    if (m2_PyObject_GetBufferInt(r, &rbuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(value, &vbuf);
+        return -1;
+    }
+    if (m2_PyObject_GetBufferInt(s, &sbuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        return -1;
+    }
 
     if (!(sig = DSA_SIG_new())) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        m2_PyBuffer_Release(s, &sbuf);
         return -1;
     }
-    if (!(sig->r = BN_mpi2bn((unsigned char *)rbuf, rlen, NULL))) {
+    if (!(sig->r = BN_mpi2bn((unsigned char *)rbuf.buf, rbuf.len, NULL))) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
         DSA_SIG_free(sig);
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        m2_PyBuffer_Release(s, &sbuf);
         return -1;
     }
-    if (!(sig->s = BN_mpi2bn((unsigned char *)sbuf, slen, NULL))) {
+    if (!(sig->s = BN_mpi2bn((unsigned char *)sbuf.buf, sbuf.len, NULL))) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
         DSA_SIG_free(sig);
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        m2_PyBuffer_Release(s, &sbuf);
         return -1;
     }
-    ret = DSA_do_verify(vbuf, vlen, sig, dsa);
+    ret = DSA_do_verify(vbuf.buf, vbuf.len, sig, dsa);
     DSA_SIG_free(sig);
     if (ret == -1)
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+    m2_PyBuffer_Release(value, &vbuf);
+    m2_PyBuffer_Release(r, &rbuf);
+    m2_PyBuffer_Release(s, &sbuf);
     return ret;
 }
 
 PyObject *dsa_sign_asn1(DSA *dsa, PyObject *value) {
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
     void *sigbuf;
     unsigned int siglen;
     PyObject *ret;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
     if (!(sigbuf = PyMem_Malloc(DSA_size(dsa)))) {
         PyErr_SetString(PyExc_MemoryError, "dsa_sign_asn1");
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
-    if (!DSA_sign(0, vbuf, vlen, (unsigned char *)sigbuf, &siglen, dsa)) {
+    if (!DSA_sign(0, vbuf.buf, vbuf.len,
+                  (unsigned char *)sigbuf, &siglen, dsa)) {
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
         PyMem_Free(sigbuf);
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     ret = PyString_FromStringAndSize(sigbuf, siglen);
     PyMem_Free(sigbuf);
+    m2_PyBuffer_Release(value, &vbuf);
     return ret;
 }
 
 int dsa_verify_asn1(DSA *dsa, PyObject *value, PyObject *sig) {
-    const void *vbuf; 
-    void *sbuf;
-    int vlen, slen, ret;
+    int ret;
+    Py_buffer vbuf, sbuf;
 
-    if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        || (m2_PyObject_AsReadBufferInt(sig, (const void **)&sbuf, &slen)
-        == -1))
-        return -1;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return -1;
+    if (m2_PyObject_GetBufferInt(sig, &sbuf, PyBUF_SIMPLE) == -1) {
+      m2_PyBuffer_Release(value, &vbuf);
+      return -1;
+    }
 
-    if ((ret = DSA_verify(0, vbuf, vlen, sbuf, slen, dsa)) == -1)
+    if ((ret = DSA_verify(0, (const void *) vbuf.buf, vbuf.len,
+                          (void *) sbuf.buf, sbuf.len, dsa)) == -1)
         PyErr_SetString(_dsa_err, ERR_reason_error_string(ERR_get_error()));
+    m2_PyBuffer_Release(value, &vbuf);
+    m2_PyBuffer_Release(sig, &sbuf);
     return ret;
 }
 
Index: SWIG/_aes.i
===================================================================
--- SWIG/_aes.i	(revision 739)
+++ SWIG/_aes.i	(working copy)
@@ -42,16 +42,16 @@
 // otherwise: encrypt (Python code will supply the value 1.)
 */
 PyObject *AES_set_key(AES_KEY *key, PyObject *value, int bits, int op) { 
-    const void *vbuf; 
-    Py_ssize_t vlen;
+    Py_buffer vbuf;
 
-    if (PyObject_AsReadBuffer(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
     if (op == 0) 
-        AES_set_encrypt_key(vbuf, bits, key);
+        AES_set_encrypt_key(vbuf.buf, bits, key);
     else
-        AES_set_decrypt_key(vbuf, bits, key);
+        AES_set_decrypt_key(vbuf.buf, bits, key);
+    m2_PyBuffer_Release(value, &vbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
@@ -61,21 +61,23 @@
 // otherwise: encrypt (Python code will supply the value 1.)
 */
 PyObject *AES_crypt(const AES_KEY *key, PyObject *in, int outlen, int op) {
-    const void *buf;
-    Py_ssize_t len;
     unsigned char *out;
+    Py_buffer buf;
 
-    if (PyObject_AsReadBuffer(in, &buf, &len) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(in, &buf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
     if (!(out=(unsigned char *)PyMem_Malloc(outlen))) {
         PyErr_SetString(PyExc_MemoryError, "AES_crypt");
+        m2_PyBuffer_Release(in, &buf);
         return NULL;
     }
+
     if (op == 0)
-        AES_encrypt((const unsigned char *)in, out, key);
+        AES_encrypt((const unsigned char *)buf.buf, out, key);
     else
-        AES_decrypt((const unsigned char *)in, out, key);
+        AES_decrypt((const unsigned char *)buf.buf, out, key);
+    m2_PyBuffer_Release(in, &buf);
     return PyString_FromStringAndSize((char*)out, outlen);
 }
 
Index: SWIG/_bio.i
===================================================================
--- SWIG/_bio.i	(revision 739)
+++ SWIG/_bio.i	(working copy)
@@ -121,20 +121,21 @@
 }
 
 int bio_write(BIO *bio, PyObject *from) {
-    const void *fbuf;
-    int flen, ret;
+    Py_buffer fbuf;
+    int ret;
 
-    if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
-        return -1;
+    if (m2_PyObject_GetBufferInt(from, &fbuf, PyBUF_SIMPLE) == -1)
+      return -1;
 
     Py_BEGIN_ALLOW_THREADS
-    ret = BIO_write(bio, fbuf, flen);
+    ret = BIO_write(bio, fbuf.buf, fbuf.len);
     Py_END_ALLOW_THREADS
     if (ret < 0) {
         if (ERR_peek_error()) {
             PyErr_SetString(_bio_err, ERR_reason_error_string(ERR_get_error()));
         }
     }
+    m2_PyBuffer_Release(from, &fbuf);
     return ret;
 }
 
@@ -175,15 +176,20 @@
 }
 
 PyObject *bio_set_cipher(BIO *b, EVP_CIPHER *c, PyObject *key, PyObject *iv, int op) {
-    const void *kbuf, *ibuf;
-    Py_ssize_t klen, ilen;
+    Py_buffer kbuf, ibuf;
 
-    if ((PyObject_AsReadBuffer(key, &kbuf, &klen) == -1)
-        || (PyObject_AsReadBuffer(iv, &ibuf, &ilen) == -1))
-        return NULL;
+    if (m2_PyObject_GetBuffer(key, &kbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
+    if (m2_PyObject_GetBuffer(iv, &ibuf, PyBUF_SIMPLE) == -1) {
+      m2_PyBuffer_Release(key, &kbuf);
+      return NULL;
+    }
+
     BIO_set_cipher(b, (const EVP_CIPHER *)c, 
-        (unsigned char *)kbuf, (unsigned char *)ibuf, op);
+        (unsigned char *)kbuf.buf, (unsigned char *)ibuf.buf, op);
+    m2_PyBuffer_Release(iv, &ibuf);
+    m2_PyBuffer_Release(key, &kbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
Index: SWIG/_util.i
===================================================================
--- SWIG/_util.i	(revision 739)
+++ SWIG/_util.i	(working copy)
@@ -17,41 +17,43 @@
     
 PyObject *util_hex_to_string(PyObject *blob) {
     PyObject *obj;
-    const void *buf;
     char *ret;
-    Py_ssize_t len;
+    Py_buffer buf;
 
-    if (PyObject_AsReadBuffer(blob, &buf, &len) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    ret = hex_to_string((unsigned char *)buf, len);
+    ret = hex_to_string((unsigned char *)buf.buf, buf.len);
     if (!ret) {
         PyErr_SetString(_util_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(blob, &buf);
         return NULL;
     }
     obj = PyString_FromString(ret);
     OPENSSL_free(ret);
+    m2_PyBuffer_Release(blob, &buf);
     return obj;
 }
 
 PyObject *util_string_to_hex(PyObject *blob) {
     PyObject *obj;
-    const void *buf;
     unsigned char *ret;
-    Py_ssize_t len0;
     long len;
+    Py_buffer buf;
 
-    if (PyObject_AsReadBuffer(blob, &buf, &len0) == -1)
-        return NULL;
+    if (m2_PyObject_GetBuffer(blob, &buf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    len = len0;
-    ret = string_to_hex((char *)buf, &len);
+    len = buf.len;
+    ret = string_to_hex((char *)buf.buf, &len);
     if (ret == NULL) {
         PyErr_SetString(_util_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(blob, &buf);
         return NULL;
     }
     obj = PyString_FromStringAndSize((char*)ret, len);
     OPENSSL_free(ret);
+    m2_PyBuffer_Release(blob, &buf);
     return obj;
 }
 %}
Index: SWIG/_rand.i
===================================================================
--- SWIG/_rand.i	(revision 739)
+++ SWIG/_rand.i	(working copy)
@@ -26,25 +26,25 @@
 }
 
 PyObject *rand_seed(PyObject *seed) {
-    const void *buf;
-    int len;
+    Py_buffer buf;
 
-    if (m2_PyObject_AsReadBufferInt(seed, &buf, &len) == -1)
+    if (m2_PyObject_GetBufferInt(seed, &buf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    RAND_seed(buf, len);
+    RAND_seed(buf.buf, buf.len);
+    m2_PyBuffer_Release(seed, &buf);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *rand_add(PyObject *blob, double entropy) {
-    const void *buf;
-    int len;
+    Py_buffer buf;
 
-    if (m2_PyObject_AsReadBufferInt(blob, &buf, &len) == -1)
+    if (m2_PyObject_GetBufferInt(blob, &buf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    RAND_add(buf, len, entropy);
+    RAND_add(buf.buf, buf.len, entropy);
+    m2_PyBuffer_Release(blob, &buf);
     Py_INCREF(Py_None);
     return Py_None;
 }
Index: SWIG/_rsa.i
===================================================================
--- SWIG/_rsa.i	(revision 739)
+++ SWIG/_rsa.i	(working copy)
@@ -120,18 +120,19 @@
 
 PyObject *rsa_set_e(RSA *rsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &pybuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)pybuf.buf, pybuf.len, NULL))) {
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &pybuf);
         return NULL;
     }
     if (rsa->e)
         BN_free(rsa->e);
+    m2_PyBuffer_Release(value, &pybuf);
     rsa->e = bn;
     Py_INCREF(Py_None);
     return Py_None;
@@ -139,18 +140,19 @@
 
 PyObject *rsa_set_n(RSA *rsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &pybuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_mpi2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_mpi2bn((unsigned char *)pybuf.buf, pybuf.len, NULL))) {
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &pybuf);
         return NULL;
     }
     if (rsa->n)
         BN_free(rsa->n);
+    m2_PyBuffer_Release(value, &pybuf);
     rsa->n = bn;
     Py_INCREF(Py_None);
     return Py_None;
@@ -158,18 +160,19 @@
 
 PyObject *rsa_set_e_bin(RSA *rsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &pybuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_bin2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_bin2bn((unsigned char *)pybuf.buf, pybuf.len, NULL))) {
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &pybuf);
         return NULL;
     }
     if (rsa->e)
         BN_free(rsa->e);
+    m2_PyBuffer_Release(value, &pybuf);
     rsa->e = bn;
     Py_INCREF(Py_None);
     return Py_None;
@@ -177,178 +180,196 @@
 
 PyObject *rsa_set_n_bin(RSA *rsa, PyObject *value) {
     BIGNUM *bn;
-    const void *vbuf;
-    int vlen;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &pybuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(bn = BN_bin2bn((unsigned char *)vbuf, vlen, NULL))) {
+    if (!(bn = BN_bin2bn((unsigned char *)pybuf.buf, pybuf.len, NULL))) {
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &pybuf);
         return NULL;
     }
     if (rsa->n)
         BN_free(rsa->n);
+    m2_PyBuffer_Release(value, &pybuf);
     rsa->n = bn;
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *rsa_private_encrypt(RSA *rsa, PyObject *from, int padding) {
-    const void *fbuf;
     void *tbuf;
-    int flen, tlen;
+    int tlen;
     PyObject *ret;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(from, &pybuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
     if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
         PyErr_SetString(PyExc_MemoryError, "rsa_private_encrypt");
+        m2_PyBuffer_Release(from, &pybuf);
         return NULL;
     }
-    tlen = RSA_private_encrypt(flen, (unsigned char *)fbuf, 
-        (unsigned char *)tbuf, rsa, padding);
+    tlen = RSA_private_encrypt(pybuf.len, (unsigned char *)pybuf.buf,
+                               (unsigned char *)tbuf, rsa, padding);
     if (tlen == -1) {
         PyMem_Free(tbuf);
+        m2_PyBuffer_Release(from, &pybuf);
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
         return NULL;
     }
     ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
     PyMem_Free(tbuf);
+    m2_PyBuffer_Release(from, &pybuf);
     return ret;
 }
 
 PyObject *rsa_public_decrypt(RSA *rsa, PyObject *from, int padding) {
-    const void *fbuf;
     void *tbuf;
-    int flen, tlen;
+    int tlen;
     PyObject *ret;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+    if (m2_PyObject_GetBufferInt(from, &pybuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
     if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
         PyErr_SetString(PyExc_MemoryError, "rsa_public_decrypt");
+        m2_PyBuffer_Release(from, &pybuf);
         return NULL;
     }
-    tlen = RSA_public_decrypt(flen, (unsigned char *)fbuf, 
-        (unsigned char *)tbuf, rsa, padding);
+    tlen = RSA_public_decrypt(pybuf.len, (unsigned char *)pybuf.buf,
+                              (unsigned char *)tbuf, rsa, padding);
     if (tlen == -1) {
         PyMem_Free(tbuf);
+        m2_PyBuffer_Release(from, &pybuf);
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
         return NULL;
     }
     ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
     PyMem_Free(tbuf);
+    m2_PyBuffer_Release(from, &pybuf);
     return ret;
 }
 
 PyObject *rsa_public_encrypt(RSA *rsa, PyObject *from, int padding) {
-    const void *fbuf;
     void *tbuf;
-    int flen, tlen;
+    int tlen;
     PyObject *ret;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+    if (m2_PyObject_GetBufferInt(from, &pybuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
     if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
         PyErr_SetString(PyExc_MemoryError, "rsa_public_encrypt");
+        m2_PyBuffer_Release(from, &pybuf);
         return NULL;
     }
-    tlen = RSA_public_encrypt(flen, (unsigned char *)fbuf, 
+    tlen = RSA_public_encrypt(pybuf.len, (unsigned char *)pybuf.buf, 
         (unsigned char *)tbuf, rsa, padding);
     if (tlen == -1) {
         PyMem_Free(tbuf);
+        m2_PyBuffer_Release(from, &pybuf);
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
         return NULL;
     }
     ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
     PyMem_Free(tbuf);
+    m2_PyBuffer_Release(from, &pybuf);
     return ret;
 }
 
 PyObject *rsa_private_decrypt(RSA *rsa, PyObject *from, int padding) {
-    const void *fbuf;
     void *tbuf;
-    int flen, tlen;
+    int tlen;
     PyObject *ret;
+    Py_buffer pybuf;
 
-    if (m2_PyObject_AsReadBufferInt(from, &fbuf, &flen) == -1)
+    if (m2_PyObject_GetBufferInt(from, &pybuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
     if (!(tbuf = PyMem_Malloc(BN_num_bytes(rsa->n)))) {
         PyErr_SetString(PyExc_MemoryError, "rsa_private_decrypt");
+        m2_PyBuffer_Release(from, &pybuf);
         return NULL;
     }
-    tlen = RSA_private_decrypt(flen, (unsigned char *)fbuf, 
-        (unsigned char *)tbuf, rsa, padding);
+    tlen = RSA_private_decrypt(pybuf.len, (unsigned char *)pybuf.buf, 
+                               (unsigned char *)tbuf, rsa, padding);
+
     if (tlen == -1) {
         PyMem_Free(tbuf);
+        m2_PyBuffer_Release(from, &pybuf);
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
         return NULL;
     }
     ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
     PyMem_Free(tbuf);
+    m2_PyBuffer_Release(from, &pybuf);
     return ret;
 }
 
 #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
 PyObject *rsa_padding_add_pkcs1_pss(RSA *rsa, PyObject *digest, EVP_MD *hash, int salt_length) {
-    const void *dbuf;
     unsigned char *tbuf;
-    int dlen, result, tlen;
+    int result, tlen;
     PyObject *ret;
+    Py_buffer dbuf;
 
-    if (m2_PyObject_AsReadBufferInt(digest, &dbuf, &dlen) == -1)
+    if (m2_PyObject_GetBufferInt(digest, &dbuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
     tlen = RSA_size(rsa); 
 
     if (!(tbuf = OPENSSL_malloc(tlen))) {
         PyErr_SetString(PyExc_MemoryError, "rsa_padding_add_pkcs1_pss");
+        m2_PyBuffer_Release(digest, &dbuf);
         return NULL;
     }
     result = RSA_padding_add_PKCS1_PSS(
         rsa,
         tbuf,
-        (unsigned char *)dbuf,
+        (unsigned char *)dbuf.buf,
         hash,
         salt_length);
 
     if (result == -1) {
         OPENSSL_cleanse(tbuf, tlen);
         OPENSSL_free(tbuf);
+        m2_PyBuffer_Release(digest, &dbuf);
         PyErr_SetString(_rsa_err, ERR_reason_error_string(ERR_get_error()));
         return NULL;
     }
     ret = PyString_FromStringAndSize((const char *)tbuf, tlen);
     OPENSSL_cleanse(tbuf, tlen);
     OPENSSL_free(tbuf);
+    m2_PyBuffer_Release(digest, &dbuf);
     return ret;
 }
 
 int rsa_verify_pkcs1_pss(RSA *rsa, PyObject *digest, PyObject *signature, EVP_MD *hash, int salt_length) {
-    const void *dbuf;
-    const void *sbuf;
-    int dlen, slen, ret;
+    int ret;
+    Py_buffer dbuf, sbuf;
 
-    if (m2_PyObject_AsReadBufferInt(digest, &dbuf, &dlen) == -1) {
+    if (m2_PyObject_GetBufferInt(digest, &dbuf, PyBUF_SIMPLE) == -1) {
         return 0;
     }
-
-    if (m2_PyObject_AsReadBufferInt(signature, &sbuf, &slen) == -1) {
+    if (m2_PyObject_GetBufferInt(signature, &sbuf, PyBUF_SIMPLE) == -1) {
+        m2_PyBuffer_Release(digest, &dbuf);
         return 0;
     }
 
     ret = RSA_verify_PKCS1_PSS(
         rsa,
-        (unsigned char *)dbuf,
+        (unsigned char *)dbuf.buf,
         hash,
-        (unsigned char *)sbuf,
+        (unsigned char *)sbuf.buf,
         salt_length);
 
+    m2_PyBuffer_Release(digest, &dbuf);
+    m2_PyBuffer_Release(signature, &sbuf);
     return ret;
 }
 #endif
Index: SWIG/_ec.i
===================================================================
--- SWIG/_ec.i	(revision 739)
+++ SWIG/_ec.i	(working copy)
@@ -255,56 +255,76 @@
 }
 
 PyObject *ecdsa_sign(EC_KEY *key, PyObject *value) {
-    const void *vbuf;
-    int vlen;
     PyObject *tuple;
     ECDSA_SIG *sig; 
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        return NULL;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return NULL;
 
-    if (!(sig = ECDSA_do_sign(vbuf, vlen, key))) {
+    if (!(sig = ECDSA_do_sign(vbuf.buf, vbuf.len, key))) {
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     if (!(tuple = PyTuple_New(2))) {
         ECDSA_SIG_free(sig);
         PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     PyTuple_SET_ITEM(tuple, 0, ecdsa_sig_get_r(sig));
     PyTuple_SET_ITEM(tuple, 1, ecdsa_sig_get_s(sig));
     ECDSA_SIG_free(sig);
+    m2_PyBuffer_Release(value, &vbuf);
     return tuple;
 }
 
 int ecdsa_verify(EC_KEY *key, PyObject *value, PyObject *r, PyObject *s) {
-    const void *vbuf, *rbuf, *sbuf;
-    int vlen, rlen, slen;
+    Py_buffer vbuf, rbuf, sbuf;
     ECDSA_SIG *sig;
     int ret;
 
-    if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        || (m2_PyObject_AsReadBufferInt(r, &rbuf, &rlen) == -1)
-        || (m2_PyObject_AsReadBufferInt(s, &sbuf, &slen) == -1))
-        return -1;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return -1;
+    if (m2_PyObject_GetBufferInt(r, &rbuf, PyBUF_SIMPLE) == -1) {
+      m2_PyBuffer_Release(value, &vbuf);
+      return -1;
+    }
+    if (m2_PyObject_GetBufferInt(s, &sbuf, PyBUF_SIMPLE) == -1) {
+      m2_PyBuffer_Release(value, &vbuf);
+      m2_PyBuffer_Release(r, &rbuf);
+      return -1;
+    }
 
     if (!(sig = ECDSA_SIG_new())) {
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        m2_PyBuffer_Release(s, &sbuf);
         return -1;
     }
-    if (!BN_mpi2bn((unsigned char *)rbuf, rlen, sig->r)) {
+    if (!BN_mpi2bn((unsigned char *)rbuf.buf, rbuf.len, sig->r)) {
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
         ECDSA_SIG_free(sig);
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        m2_PyBuffer_Release(s, &sbuf);
         return -1;
     }
-    if (!BN_mpi2bn((unsigned char *)sbuf, slen, sig->s)) {
+    if (!BN_mpi2bn((unsigned char *)sbuf.buf, sbuf.len, sig->s)) {
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
         ECDSA_SIG_free(sig);
+        m2_PyBuffer_Release(value, &vbuf);
+        m2_PyBuffer_Release(r, &rbuf);
+        m2_PyBuffer_Release(s, &sbuf);
         return -1;
     }
-    ret = ECDSA_do_verify(vbuf, vlen, sig, key);
+    ret = ECDSA_do_verify(vbuf.buf, vbuf.len, sig, key);
     ECDSA_SIG_free(sig);
+    m2_PyBuffer_Release(value, &vbuf);
+    m2_PyBuffer_Release(r, &rbuf);
+    m2_PyBuffer_Release(s, &sbuf);
     if (ret == -1)
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
     return ret;
@@ -312,42 +332,49 @@
 
 
 PyObject *ecdsa_sign_asn1(EC_KEY *key, PyObject *value) {
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
     void *sigbuf;
     unsigned int siglen;
     PyObject *ret;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
     if (!(sigbuf = PyMem_Malloc(ECDSA_size(key)))) {
         PyErr_SetString(PyExc_MemoryError, "ecdsa_sign_asn1");
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
-    if (!ECDSA_sign(0, vbuf, vlen, (unsigned char *)sigbuf, &siglen, key)) {
+    if (!ECDSA_sign(0, vbuf.buf, vbuf.len,
+                    (unsigned char *)sigbuf, &siglen, key)) {
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
         PyMem_Free(sigbuf);
+        m2_PyBuffer_Release(value, &vbuf);
         return NULL;
     }
     ret = PyString_FromStringAndSize(sigbuf, siglen);
     PyMem_Free(sigbuf);
+    m2_PyBuffer_Release(value, &vbuf);
     return ret;
 }
 
 
 int ecdsa_verify_asn1(EC_KEY *key, PyObject *value, PyObject *sig) {
-    const void *vbuf; 
-    void *sbuf;
-    int vlen, slen, ret;
+    Py_buffer vbuf, sbuf;
+    int ret;
 
-    if ((m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
-        || (m2_PyObject_AsReadBufferInt(sig, (const void **)&sbuf, &slen)
-        == -1))
-        return -1;
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
+      return -1;
+    if (m2_PyObject_GetBufferInt(sig, &sbuf, PyBUF_SIMPLE) == -1) {
+      m2_PyBuffer_Release(value, &vbuf);
+      return -1;
+    }
 
-    if ((ret = ECDSA_verify(0, vbuf, vlen, sbuf, slen, key)) == -1)
+    if ((ret = ECDSA_verify(0, (const void *) vbuf.buf, vbuf.len,
+                            sbuf.buf, sbuf.len, key)) == -1)
         PyErr_SetString(_ec_err, ERR_reason_error_string(ERR_get_error()));
+    m2_PyBuffer_Release(value, &vbuf);
+    m2_PyBuffer_Release(sig, &sbuf);
     return ret;
 }
 
@@ -391,9 +418,7 @@
     EC_KEY *keypair;
 
     if (PyObject_AsReadBuffer(pubkey, &keypairbuf, &keypairbuflen) == -1)
-    {
-        return NULL;
-    }
+      return NULL;
 
     tempBuf = (const unsigned char *)keypairbuf;
     if ((keypair = d2i_EC_PUBKEY( NULL, &tempBuf, keypairbuflen)) == 0)
Index: SWIG/_rc4.i
===================================================================
--- SWIG/_rc4.i	(revision 739)
+++ SWIG/_rc4.i	(working copy)
@@ -22,33 +22,34 @@
 }
 
 PyObject *rc4_set_key(RC4_KEY *key, PyObject *value) {
-    const void *vbuf;
-    int vlen;
+    Py_buffer vbuf;
 
-    if (m2_PyObject_AsReadBufferInt(value, &vbuf, &vlen) == -1)
+    if (m2_PyObject_GetBufferInt(value, &vbuf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    RC4_set_key(key, vlen, vbuf);
+    RC4_set_key(key, vbuf.len, vbuf.buf);
+    m2_PyBuffer_Release(value, &vbuf);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 PyObject *rc4_update(RC4_KEY *key, PyObject *in) {
     PyObject *ret;
-    const void *buf;
-    Py_ssize_t len;
     void *out;
+    Py_buffer buf;
 
-    if (PyObject_AsReadBuffer(in, &buf, &len) == -1)
+    if (m2_PyObject_GetBuffer(in, &buf, PyBUF_SIMPLE) == -1)
         return NULL;
 
-    if (!(out = PyMem_Malloc(len))) {
+    if (!(out = PyMem_Malloc(buf.len))) {
         PyErr_SetString(PyExc_MemoryError, "expected a string object");
+        m2_PyBuffer_Release(in, &buf);
         return NULL;
     }
-    RC4(key, len, buf, out);
-    ret = PyString_FromStringAndSize(out, len);
+    RC4(key, buf.len, buf.buf, out);
+    ret = PyString_FromStringAndSize(out, buf.len);
     PyMem_Free(out);
+    m2_PyBuffer_Release(in, &buf);
     return ret;
 }
 
