I'm writing some new Python bindings for OpenSSL which attempt to mirror
the OpenSSL API as closely as is sensible, other than some
rearchitecting for OO-ness.

The wrapper source can be downloaded here:
http://www.brontes3d.com/opensource/straightssl.html

I've hit the need to manipulate the reference count of BIO structures.
For example:

ctx = straightSSL.Context()
ssl = straightSSL.SSL(ctx)
rbio = straightSSL.MemoryBio()
wbio = straightSSL.MemoryBio()
ssl.set_bio(rbio, wbio)
#
# At this point, rbio and wbio have a reference count of 1.
#
del ssl

The SSL object destructor now calls SSL_free() which then decreases the
BIO reference count of rbio and wbio to 0, freeing them. However the
overlying python rbio and wbio objects are still in scope on the Python
level, and using them will cause a segfault.

To get around this, I need a way to increment the reference count of the
BIO's before I call SSL_free, so that SSL_free doesn't ever free the
BIO. (instead, I do freeing in the Python-level Bio destructor, which is
designed to only happen when the BIO-level refcount is 1 and dropping to
0).

I realise that the BIO structure is currently exported through the
headers and that the crypto functions to manipulate the reference count
are as well. However, I'm worried that they are subject to change as
they are only internal implementation details.

Would there be any objection to something like the attached patch, to
ensure that a stable refcounting API is always available for these
objects?

If necessary I would be happy to write a manpage for these new calls, as
well as providing equivalent functions for other object abstractions
that have reference counts -- just say.

Thanks.
-- 
Daniel Drake
Brontes Technologies, A 3M Company
http://www.brontes3d.com/opensource
Index: openssl-0.9.8e/crypto/bio/bio.h
===================================================================
--- openssl-0.9.8e.orig/crypto/bio/bio.h
+++ openssl-0.9.8e/crypto/bio/bio.h
@@ -223,6 +223,10 @@ void BIO_clear_flags(BIO *b, int flags);
 #define BIO_retry_type(a)		BIO_test_flags(a, BIO_FLAGS_RWS)
 #define BIO_should_retry(a)		BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
 
+/* These are for low-level users who need to control reference counting. */
+#define BIO_incref(a)		CRYPTO_add(&a->references,1,CRYPTO_LOCK_BIO);
+#define BIO_decref(a)		CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
+
 /* The next three are used in conjunction with the
  * BIO_should_io_special() condition.  After this returns true,
  * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 

Reply via email to