On Sat, Jan 31, 2009 at 6:49 AM, t...@terralogic.net wrote:
I've not looked at the OpenSSL code for a few years now. Last time I looked
the only way to do things was via a BIO and the BIO functions did the
crypto.
This is totally inappropriate for many server designs.
Interesting! Can you give me a few examples maybe? Haven't run into
this issue myself yet and I like to come prepared when it happens.
I would like to ask if the crypto/bio functions have been factored apart so
they are orthoganal.
Not entirely. crypto is entirely separate from BIO stuff, though both
still sit in the 'crypto' lib, but that's easily remedied.
SSL uses / expects BIOs though for the protocol execution. Crypto is
encapsulated in the EVP layer. Then there's a set of extra BIOs which
attach EVP to the data streams going through the BIO chains, in effect
thus forming the glue between crypto algorithms and SSL protocol.
To my way of thinking we should have a way to basically do this:
1) define a single structure which will carry all data for a connection.
This can be referenced from say an fd which is returned by fopen().
2) define a single function which might for instance use a state flag and
plug it into a case statement in order to call the appropriate step in the
crypto pipeline. Thus the interface might work something like this: A
packet comes in via say fread(). This packet is then passed into OpenSSL as
follows: ierr=OpenSSL(control_code, fd, p_fd-OpenSSL_connection_data,
packet_in, packet_out); In this case the control_code might be a constant
which might have values like initialize, release, abort,
establish_connection (many steps), encrypt, decrypt and whatever else is
appropriate.
Sounds to me like you're in favor of an approach similar to ioctl() et
al, given the OpenSSL(ctl_cmd, ...) interface you're looking for.
Who's the target audience for this interface? (skill level,
background, that sort of thing)
3) with something like this the bio() functions I looked at before are easy
to implement... but if the application needs to do the I/O then it can.
I don't entirely follow. Currently OpenSSL allows you to do a lot of
comm I/O on your own; all you need to do it stick it in a BIO once you
enter the SSL zone. On the other hand, one can take the BIO
abstraction (which was engineered for this purpose) and extend it by
writing a custom BIO or two. I've done so myself over the years,
including BIO's which source/sink 2D barcodes, mobile phone comms,
etc. (BIO filters and BIO source/sinks)
4) another thing that should be done if it is not already done is that all
malloc()ing should be controlled such that malloc() takes place a page at a
time and the needed space is allocated from the pages in a pool indexed by
the fd number. If this is done then the memory for a connection can be
released easily adn memory leaks cannot occur. The point here is that if a
connection is lost we simply blow away all the data held in
OpenSSL_connection_data and blow away all pages associated with the page pool
holding allocated memory and we are done. The crypto functions don't even
need to know it happened.
malloc() is abstracted out so you can provide your own pool-based [or
other] system (been there, done that) but doing it on a per-connection
basis so that total cleanup happens at the level of blowing away the
[connection-related] pool and call it a day isn't available yet; given
the stateful communication layers[*] which you'll have interfacing
with the SSL layer, one may ponder if that is really feasible. If
you're looking at one-chunk-per-conn, it's the SSL struct, which is
derived from the SSL_CTX template (= one SSL_CTX can spawn multiple
connections)
If you don't need SSL but just want the crypto or the BIO, you can do
that too. (Done that myself as well, including such stuff as custom
work for sneakerNet based secured communications.)
[*] such as IP stacks et al, which manage their connection handles
themselves: when you don't include means to cleanup those handles and
anything related to those, you've a different kind of leak going on.
OpenSSL doesn't need nor assume socket-based I/O, so you can use the
same code in utterly different environs (memory-mapped I/O, etc.).
Still, there's always third-party cleanup to do when you close/destroy
an SSL transfer line.
I'm curious: are you looking for a reduced SSL API footprint solution, maybe?
--
Met vriendelijke groeten / Best regards,
Ger Hobbelt
--
web:http://www.hobbelt.com/
http://www.hebbut.net/
mail: g...@hobbelt.com
mobile: +31-6-11 120 978
--
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager