Yes you can implement your own BIO. I've done it but I don't recommend it.

I had started writing something similar to osslsigncode but that could verify 
Microsoft Authenticode. When hashing the file certain fields must be excluded. 
PKCS7_verify() will not take a hash for comparison, only the content to be 
hashed, so I couldn't use my own hash function and skip the fields to be 
excluded. PKCS7_verify() accepts a BIO for detached content so instead what I 
did is a custom BIO that reads in the data but will skip any excluded field. So 
when OpenSSL goes to hash the file it calls my custom BIO's read which skips 
the excluded fields.

There are a few things you should remember such that BIOs are an abstraction 
layer and can have more than one instance so stay away from static variables 
(think cpp classes). Instead what I did was use bio->ptr (pointer) to an 
internal structure that contains my variables

struct class_variables
{
int fd;
uint64_t filesize;
}
etc
then on construct (ie create function) do something like
assert( ( bio->ptr = malloc( sizeof( struct class_variables ) ) ) );
then on destruct (ie destroy function) free it
so then in your BIO read/whatever function you can do something like this
struct class_variables *variables = (struct class_variables *)bio->ptr;
then variables->whatever

In the case of bytes read BIOs actually have a specific member that openssl's 
functions can use internally:
unsigned long num_read; (i.e. bio->num_read)
but the problem with that might be that it's only 32bit. with what i was doing 
it was ok to ignore this issue

If that's not enough for you you'll have to watch out for things like where 
OpenSSL internal functions copy the pointer to bio data but not the struct. 
There's an example of this in PKCS7_verify() where if you pass a memory BIO it 
creates a secondary memory BIO and then copies over only the memory pointer and 
len from the first BIO, and nothing else, and uses that secondary BIO for some 
work. The problem being say you have a callback on the first BIO to monitor for 
a read well forget it ever being called.

Probably other stuff I'm not thinking of, but yes it's possible. Can you share 
with us what you are trying to do?

--- On Mon, 4/12/10, Phillip Hellewell <[email protected]> wrote:

From: Phillip Hellewell <[email protected]>
Subject: Re: Custom user-defined BIO
To: "Howard Chu" <[email protected]>
Cc: [email protected]
Date: Monday, April 12, 2010, 12:27 PM

Thanks for the example.  Yeah, my best idea so far was to look at existing 
examples, such as bss_mem.c.  One question I still have is which of the 
BIO_CTRL_* commands does my ctrl function need to handle?  bss_mem.c handles 
about a dozen of them, but the example you gave me only handles BIO_CTRL_FLUSH, 
so is that the only one I'm required to handle?



Phillip

On Mon, Apr 12, 2010 at 10:15 AM, Howard Chu <[email protected]> wrote:


Phillip Hellewell wrote:


Hi all,



How do I implement my own BIO?  Do I just create a function that returns a

BIO_METHOD* with pointers to my custom functions?  Is there any documentation

on how to do this?



I searched the mailing list and found that this question has been asked before

but no one ever responds.  The lack of documentation and responses leads me to

believe that the BIO interface is not really meant to be used for user-defined

I/O.



1999: http://marc.info/?l=ssl-users&m=91639275613495&w=2

<http://marc.info/?l=ssl-users&m=91639275613495&w=2>

2005: http://marc.info/?l=openssl-users&m=110624296809686&w=2

<http://marc.info/?l=openssl-users&m=110624296809686&w=2>

2008: http://marc.info/?l=openssl-dev&m=122959672906832&w=2

<http://marc.info/?l=openssl-dev&m=122959672906832&w=2>



Please, at least will someone respond with one of the following:

1. "No, don't even try to do it.  You're not supposed to."

2. "Yes, you can do it but no one is going to help you.  Just look at some of

the files in crypto/bio/ and see if you can figure it out."




Some things are probably too easy to justify the time it takes to respond. In 
this case, define a BIO_METHOD struct with your handlers and just use it.



One example is in OpenLDAP's libldap/tls_o.c.



http://www.openldap.org/devel/cvsweb.cgi/~checkout~/libraries/libldap/tls_o.c?rev=1.16



-- 

  -- Howard Chu

  CTO, Symas Corp.           http://www.symas.com

  Director, Highland Sun     http://highlandsun.com/hyc/

  Chief Architect, OpenLDAP  http://www.openldap.org/project/






      

Reply via email to