On Wed, Nov 01, 2000 at 09:28:55PM +0100, Thomas Geller wrote:
> First of all thank you Lutz for your help.
>
> > The result at depth 0 says, that the certificate at level 0 is
> consistently
> > signed from its CA. The CA itself (at level 1) however failed verification
> > for several reasons.
> > The preverify_ok state only indicates whether the certificate at the
> > actual depth passed or not. It does not say anything about other levels.
> > As you have already seen, the overall result of the verification is
> > CERT_UNTRUSTED, as at least one error occured.
>
> I see, the preverify_ok value at depth 0 is 1. That means the peer cert was
> passed. But the CA cert on level 1 wasn't passed because the preverify_ok
> value at this depth is 0.
> But what are the several reasons of the error at depth 0?
Level 1! At level 0 the peer certificate itself passed. At level 1,
there were several reasons listed.
> Confusing for me is the fact, that X509_STOR_CTX_GET_CURRENT_CERT at depth 1
> is returning a cert though then preverify_ok value at this depth is 0
> (wasn't passed).
That is still consistent. We have a CURRENT_CERT, failure is flagged,
so now we can use the verify_callback to get the certificate currently
being checked, the preverify_ok value (the certificate did no pass) and
can access the reason for the verification failure. The verify_callback
can now evaluate the verification failure and perform further action.
> How can I achieve the goal to proof without doubt that the server I'm
> connected with is the one I've expected?
There are several possibilities:
- Use verify_result=SSL_get_verify_result(ssl). If the verify_result is
X509_V_OK, then the certificate passed all verifications at all depths.
Now, you can get the peers certificate (it is trusted as it passed
verification) and evaluate its contents. Typically you will check the
CommonName. It must match the name of the server you wanted to connect
to.
- You can also use the following construct:
int overall_result = passed;
verify_callback(preverify_ok,...)
{
if (!preverify_ok)
overall_result = failed;
}
...
if (peer_certificate_presented && (overall_result==passed))
check_out_CommonName_against_expected_server;
Using the second technique, you have full control yourself. The first
technique is however sufficient and secure. However (applies for both
techniques) don't forget that "passed" is the default state and only
makes sense when a peer certificate was presented (this should however
be no problem, as a server will always present a certificate (except for
ADH ciphers)).
Again, the complete authentication has two steps:
1. Check certificate's integrity and signature (SSL_get_verify_result() etc)
2. Check certificate's contents to find out, whether this is the server
you actually wanted to connect to.
I use these techniques in my Postfix/TLS patchkit. The verify_callback()
etc can be studied in src/global/pfixtls.c, the server's identity check is
performed in src/smtp/smtp_proto.c.
The code there is probably shorter than this email :-)
(Available from my homepage, see my .signature :-)
Best regards,
Lutz
--
Lutz Jaenicke [EMAIL PROTECTED]
BTU Cottbus http://www.aet.TU-Cottbus.DE/personen/jaenicke/
Lehrstuhl Allgemeine Elektrotechnik Tel. +49 355 69-4129
Universitaetsplatz 3-4, D-03044 Cottbus Fax. +49 355 69-4153
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]