Claus Assmann <[EMAIL PROTECTED]>:
>>> Question: is there some simple way to find out whether the client
>>> has been authenticated? I registered a callback with SSL_CTX_set_verify,
>>> but I don't completely understand it...
>> Do you have to use a callback? You can use SSL_get_verify_result
>> and SSL_get_peer_certificate. If the former returns X509_V_OK and
>> the latter returns non-NULL, then you have an authenticated
>> certificate.
> Thanks for your help! I've tried this, and run into a new problem:
> how do I correctly set the verify_mode? Reading the code,
> SSL_VERIFY_CLIENT_ONCE and SSL_VERIFY_PEER seem to be useful for
> my purpose (try to verify the client, but don't fail). However,
> setting ctx->verify_mode to SSL_VERIFY_CLIENT_ONCE doesn't seem to
> work: the server doesn't ask for a certificate then. If also
> SSL_VERIFY_PEER is set, the connection fails if the client doesn't
> provide a certificate (although I assumed this only happens if
> SSL_VERIFY_FAIL_IF_NO_PEER_CERT is set). So it seems I have to
> install a callback (that always returns 1).
SSL_VERIFY_FAIL_IF_NO_PEER_CERT should not be set for your
application, obviously. Verification will still fail and the protocol
be aborted if the client presents a certificate and OpenSSL does not
like it. To change this behaviour, you don't have to provide an X.509
verification callback with SSL_CTX_set_verify (as s_client, s_server
and ssltest do); you can use SSL_CTX_set_cert_verify_callback, which
sets a higher level callback (app_verify_callback). All this is still
quite confusing in the library source code -- the naming is not alway
consistent, and various members of the structures are never used. The
relevant code for this is the following in ssl_verify_cert_chain
(ssl/ssl_cert.c; this extract is simplified by hand-processing the
#ifndef):
if (s->ctx->app_verify_callback != NULL)
i=s->ctx->app_verify_callback(&ctx);
else
i=X509_verify_cert(&ctx);
s->verify_result=ctx.error;
SSL_CTX_set_cert_verify_callback takes two arguments, the second of
which is never used. Obviously the idea was the second one would be
passed to the callback -- this will likely be done so in OpenSSL
0.9.5. All your callback has to do is call X509_verify_cert and
return 1 if that function returned 0. X509_verify_cert sets
ctx.error, so that the application can see that something went wrong.
Example code:
static int
verify_dont_fail_cb(X509_STORE_CTX *c)
{
int i;
i = X509_verify_cert(c); /* sets c->error */
if (i == 0)
return 1;
else
return i;
}
SSL_CTX *
tls_create_ctx(..., int fail_unless_verified_p, ...)
{
.....
SSL_CTX_set_verify(ret, SSL_VERIFY_PEER | (fail_unless_verified_p ?
SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0), 0);
if (!fail_unless_verified_p)
SSL_CTX_set_cert_verify_callback(ret, verify_dont_fail_cb, NULL);
.....
}
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]