Hi,

I'll make an undevelopped response, embedded in your email below,
before going to bed, because in my timezone, that's 5h AM passed. And
I'll send more details in a few days because tomorrow afternoon, I
must travel for a few days. So I'll get back a computer and Internet
only on Sunday afternoon.

2011/3/17 Samuel Mimram <[email protected]>:
> Hi,
>
> Yes, you found the right place where ocaml-ssl in maintained. Actually, I
> wrote this binding a long time ago, and haven't used it for a long time, so
> it's not really a high priority for me. However, I am willing to make
> necessary modifications if someone (like you) needs more features, or
> better: integrate provided patches ;)
>
> 1. I thing that you are using the "get_verify_result" function. A better
> alternative is to use the "verify" function which returns unit but raise an
> exception of type "verify_error" which is pretty informative. Is it what you
> were looking for?

I think I must have missed this "verify" function (I don't know how
with the place taken by the verify_error type!). :-)
That's better indeed but this is still missing information. If I were
the maintainer ;-), I would have adequate contextual parameters on the
error type. Like this:
type verify_error =
| Error_v_cert_has_expired of string (* the date of the expiration. It
could also be a int, which could indicate the number of day it has
expired since. That's maybe better for internationalization. Anyway
anything usable... :-) *)
| Error_v_subject_issuer_mismatch of string * string (* the subject
and issuer which mismatch
[...]

Stuffs like this. My examples may be badly chosen (I did not think
them through) but that's the idea. By the way, you might want to
review the "unused" description on some of these. That does not seem
up to date with http://www.openssl.org/docs/apps/verify.html
On my distribution too, the man is not up to date... But I guess
upstream has better information. :-)

By the way, when using a context with Ssl.Verify_peer, even though it
is supposed to close the TLS negotiation cleanly, apparently it
didn't. I could not get back to non-encrypted dialog with the server
afterwards (I remind: I use TLS with STARTTLS, I don't open directly
an encrypted socket), so that's annoying because I would have to close
the connection and reopen a new one.
I would like to be able to get back to my previous non-TLS connection
when the TLS negotiation fails. Maybe I am the one who failed doing
something for this, I don't know.
Anyway after catching the exception, it means this method ends up with
a failed TLS connection which does not work as such anymore, and an
unusable non-TLS connection as well: that's unusable.

The only way I found was to have a context with an empty mode list, so
it always succeeds, but I check the certificate with get_verify_result
afterwards and provide my software from doing anything on the
connection if it has certificate error, waiting for the user to decide
what he wants to do. This is why I can't use Ssl.Verify_peer. Note
that this method still forces me to close the whole connection as well
if the user refuses, but at least I can continue if he accepts!

Also I think I found a bug, but I'll need to make further test to
point you where it comes from (from looking at your C code, I have an
idea, but I need to confirm by testing).

> 2. This should be easy. Please provide me with the exact list of things that
> you would like to see, and ideally with how you would do this in C (I only
> added issuer and and subject because these are the only provided examples in
> man SSL_CTX_set_verify...).

That's indeed pretty strange. There is not even a man for the
functions you use X509_get_subject_name and X509_get_issuer_name. They
seem to be used only in examples of other mans.
And searching the web, it seems only these 2 functions exist as
"simple" field interface. For the rest (all other fields of a cert), I
think generic functions must be used. For instance, this maybe:
«
X509_NAME_ENTRY_get_data() retrieves the field value of ne in and
ASN1_STRING structure.
»
Or maybe this:
«
X509_NAME *d2i_X509_NAME(X509_NAME **a, unsigned char **pp, long length);
These functions decode and encode an X509_NAME structure which is the
the same as the Name type defined in RFC2459 (and elsewhere) and used
for example in
       certificate subject and issuer names.
»
I guess that needs to be tested.
I may make C test later (next week?) unless you do them before. :-)

> 3. The verify_callback is really a hack, where you can only use the provided
> client_verify_callback: this it why it should change in the future, in order
> to allow caml functions. Actually, the problem is that SSL_CTX_set_verify is
> waiting for a C function and there is no custom data which is passed in
> which I could pass a pointer to the caml function to call (ideally I should
> be able to put the pointer to the caml function insinde X509_STORE_CTX which
> is passed to the callback but this does not seem to be possible). Maybe do
> you have an idea of how I could design the bindings?

I don't think that's difficult thanks to OCaml closure facilities. You
just need to wrap the user-provided closure into a single function.
Then you make a callback of this single function in C, and you always
call only this same function, which is actually an "empty"
implementation calling the user-provided one.

Example:

let user_callback = ref (fun _ -> ());;

let unique_callback n =
    !user_callback n
;;

Callback.register "verify callback" unique_callback;;

Then in C:
void verify_callback(int arg)
{
    caml_callback(*caml_named_value("verify callback"), Val_int(arg));
}

This way, in the C code, you will always use the C function
"verify_callback" as a callback. It will hence always call the actual
OCaml function "unique_callback", which one will actually calls a
function provided by the user which you can modify as easily as you
want (because it is a reference). You can even change it dynamically,
which the C logics cannot really do!

That's an example with a callback with an int parameter, because I
didn't not check what is the actual parameter of the verify callback.
:-) But that's easy to change.
( cf. http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html#toc142 )

I can implement this if you want, but with the hint in the email, I
think you got it.

Finally note that even though you could implement it this way, I think
a nicer API could be possible, further from the C API. I actually like
the way I workarounded the current issues I encountered and maybe I
could come up with a nicer design than simply mimicking the C
interface, inspired by my code. But it is getting late, and I want to
sleep. I'll explain it in a few days when I am back.

Ah also, a last feature I forgot in my previous email:
you have a function to get a cert from a file, but none to write a
cert into a file. That would be good to be able to save certs received
through a connection (for various reasons, the "typical" one is that
you want to save a cert the user has accepted not to ask him each
time; maybe also for security, to compare certs between connections,
and any other reason a developer might think of!).

Thanks!

Jehan

> ++
>
> Sam.
>
>
> 2011/3/16 Jehan Pagès <[email protected]>
>>
>> Hi,
>>
>> I am using ocaml-ssl for a project. Though it is not a lot advertized
>> on your main website, I got it from your Sourceforge files section, so
>> I guess you are the maintainers (note that I also doubted because the
>> Caml Hump, first link in a Google search for "ocaml-ssl", list a now
>> dead link for the ocaml-ssl project. You might want to update this!
>> :-).
>>
>> Anyway I was wondering if you were planning to make significant
>> improvement on this binding or this is too low a priority (I can see
>> you have quite a huge list of modules to maintain indeed!).
>>
>> Limitations are found in particular on the certificate validation part
>> which is not very flexible.
>> For instance when it is not validated automatically by the library, I
>> want to provide useful data to the user in order to allow him to
>> manually validate or refuse a certificate. But the current binding
>> simply has not all this part:
>> 1/ the error is returned in an unprocessed integer form (I had to map
>> values with "man 1 verify". Without this, you cannot do much).
>> 2/ The only 2 fields I can get on the cert through ocaml-ssl are the
>> issuer and the subject. I would like to have the expiration date, the
>> start date or other fields (because as a user, when a cert is expired
>> from just today, but is good otherwise, I would say that for a
>> non-highly sensible website, I would say ok, but not a cert expired
>> for 3 years for instance!)...
>> 3/ Also the verify_callback with the following warning: "Warning: this
>> might change in the future."... I would actually like for it to
>> change, because in its current form, I don't really see what we can do
>> with it! It is a private type with no construction function. We are
>> stuck with the only one defined callback (or there is something I
>> didn't get in how to use this).
>>
>> So here I am... just wondering if you have plans for ocaml-ssl, which
>> otherwise works nice. I had a few workarounds so I have been able to
>> bypass some of the current limitations of the current API to give
>> users the possibility to accept a problematic cert, but some data like
>> dates would be really nice too (being able to get all the fields
>> without restriction would be even better). :-)
>>
>> Thanks.
>>
>> Jehan
>>
>>
>> ------------------------------------------------------------------------------
>> Colocation vs. Managed Hosting
>> A question and answer guide to determining the best fit
>> for your organization - today and in the future.
>> http://p.sf.net/sfu/internap-sfd2d
>> _______________________________________________
>> Savonet-devl mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/savonet-devl
>
>

------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Savonet-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-devl

Répondre à