Re: When to get peer certificate?

2001-01-10 Thread Lutz Jaenicke

On Mon, Jan 08, 2001 at 04:59:28PM +, Dr S N Henson wrote:
 Lutz Jaenicke wrote:
  I just had a look into it. Maybe I will undertand it tomorrow.
  Once I understood it I will consider writing a manual page and update
  the example for the verify_callback...
  
 
 There is a manual page describing the ex_data functions in the
 RSA_get_ex_new_index(1), other than the fact that the data is stored in
 X509_STORE_CTX and the different function names the usage is identical.

Thanks, I finally understood how it works. I was first confused by the
specially crafted SSL_get_ex_data_X509_STORE_CTX_idx() function but
I managed to use it now :-)

Ok, now directed to the original poster of this thread: I have just
enhanced/changed Postfix/TLS to use the just discovered functionality
and can share my experiences with you. (The full change will be released
as Postfix/TLS 0.6.33 after I have re-checked every change and added
appropriate comments.)

First, for your information I have all necessary informations about
a SSL connection in a special structur anyway, so I have just enhanced
it to contain the enforce_CN and enforce_verify_errors flags, which
I had as global variables before (please just ignore the other fields
which are filled in as appropriate during the run):

typedef struct {
  SSL *con;
  BIO *internal_bio;/* postfix/TLS side of pair */
  BIO *network_bio; /* netsork side of pair */
  char peer_subject[CCERT_BUFSIZ];
  char peer_issuer[CCERT_BUFSIZ];
  char peer_CN[CCERT_BUFSIZ];
  char issuer_CN[CCERT_BUFSIZ];
  unsigned char md[EVP_MAX_MD_SIZE];
  char fingerprint[EVP_MAX_MD_SIZE * 3];
  char peername_save[129];
  int enforce_verify_errors;
  int enforce_CN;
} TLScontext_t;

Now you need one global variable that however has the same value for all
SSL structures and is therefore no problem:

static int TLScontext_index;

You need to initialize this index once in the program to identify the type
of information to be retrieved! (The SSL internals don't have an idea what
an TLScontext is, so the pointer to it is handled based on the index-number.)

TLScontext_index = SSL_get_ex_new_index(0, "TLScontext ex_data index",
NULL, NULL, NULL);

The informations here NULL'ed are needed for copying the structure etc,
The TLScontext is just one entity the pointer to which is enough, so
I don't need these functionality. Check out the manual page for
RSA_get_ex_new_index(3) (as suggested by Steve) to learn more about it.

Ok, now when establishing a new SSL connection, I create a new TLScontext
and a new SSL, and then store the pointer to TLScontext into the SSL:
TLScontext-con = SSL_new();
SSL_set_ex_data(TLScontext-con, TLScontext_index, TLScontext);
(setting of other parameters...)

Now later in the verify_callback I can do:
int verify_callback(int ok, X509_STORE_CTX * ctx)
{
  SSL *con;
  TLScontext_t *TLScontext;

  con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  TLScontext = SSL_get_ex_data(con, TLScontext_index);

  /* Now happily use all informations about this connection. */
}

SSL_get_ex_data_X509_STORE_CTX_idx() is a fixed functionality that will always
point you to the (pointer to SSL) always stored inside (ctx).
If you are happy to just now the (pointer to SSL) you wouldn't even need the
other things around, but then you would have to search your database of
active SSLs to find which one you are currently investigating.

Of course, you don't need to use a general structure, you can also store more
then one information with an index each.

Hmm. It will probably take some days before I find the time to do it, but
I will integrate this one way or the other to the verify_callback()
manual page already available and SSL_set_ex_data() and friends
yet-to-be-written manual page...

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]



When to get peer certificate?

2001-01-05 Thread Ari Pirinen

When can I safely call SSL_get_peer_certificate?
I am reading socket in non-blocking mode, and would like to
know when I've read enough so that I can obtain the peer certificate. The
reason is, as I've understood, I must check that CN matches the host name I
requested to prevent MITM attacks. And no, I can't use the verify function
(for this purpose) because it don't have context to my request (several
requests can be going on at the same time).

Also, I think I must close the connection if they dont match.
Is there a special procedure to follow so that the other side
knows I didn't approve of the certificate or do I just close?

Thanks,
Ari Pirinen
[EMAIL PROTECTED]


__
FREE Personalized Email at Mail.com
Sign up at http://www.mail.com/?sr=signup
__
OpenSSL Project http://www.openssl.org
User Support Mailing List[EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: When to get peer certificate?

2001-01-05 Thread Lutz Jaenicke

On Fri, Jan 05, 2001 at 07:45:00AM -0500, Ari Pirinen wrote:
 When can I safely call SSL_get_peer_certificate?
 I am reading socket in non-blocking mode, and would like to
 know when I've read enough so that I can obtain the peer certificate. The
 reason is, as I've understood, I must check that CN matches the host name I
 requested to prevent MITM attacks. And no, I can't use the verify function
 (for this purpose) because it don't have context to my request (several
 requests can be going on at the same time).

Wait until the handshake is completly finished. Then call
SSL_get_peer_certificate() to obtain the certificate and check the CN.
Please understand, that the peer-certificate obtained this way is just
the certificate presented, you must additionally check whether it passed
the verification against the trusted CAs with SSL_get_verify_result().

 Also, I think I must close the connection if they dont match.
 Is there a special procedure to follow so that the other side
 knows I didn't approve of the certificate or do I just close?
There are two ways of thinking:
- Call SSL_shutdown() to allow for a clean shutdown of the SSL connection,
  then close() the socket. (This send a close-alert to the peer.)
- Call close() on the socket only to immediatly cancel the connection. This
  way you save bandwidth. In the logfiles, a "probably somebody pressed the
  STOP button" message might appear, depending on the type of server.
  Maybe nobody will take care of this message :-)
If you use session caching, you should make sure to delete the session from
cache, as we should not re-use a questionable session. (With OpenSSL you
have to write your own client side cache support, it is not available by
default.)

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]



Re: When to get peer certificate?

2001-01-05 Thread Ari Pirinen

On Fri, Jan 05, 2001 at 07:45:00AM -0500, Ari Pirinen wrote:
 When can I safely call SSL_get_peer_certificate?
 I am reading socket in non-blocking mode, and would like to
 know when I've read enough so that I can obtain the peer certificate. The
 reason is, as I've understood, I must check that CN matches the host name
I
 requested to prevent MITM attacks. And no, I can't use the verify
function
 (for this purpose) because it don't have context to my request (several
 requests can be going on at the same time).

 Wait until the handshake is completly finished. Then call
SSL_get_peer_certificate() to obtain the certificate and check the CN.

Thank you for the prompt reply. This was actually my question,
how do I know when the handshake is completely finished?
I found some functions from headers that seem to have something
to do with this:
#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
#define SSL_in_init(a)  (SSL_state(a)SSL_ST_INIT)
#define SSL_in_before(a)(SSL_state(a)SSL_ST_BEFORE)
#define SSL_in_connect_init(a)  (SSL_state(a)SSL_ST_CONNECT)
#define SSL_in_accept_init(a)   (SSL_state(a)SSL_ST_ACCEPT)

Is handshake completely finished when SSL_is_init_finished
returns true, or can it be finished before that?

Please understand, that the peer-certificate obtained this way is just
the certificate presented, you must additionally check whether it passed
the verification against the trusted CAs with SSL_get_verify_result().

Yes, I understand this. I probably will add my own verify
callback there... I assume that the verify callback gets called
immediately when the initialisation if finished, that is,
essentially meaning the verify callback is called before I
will check the CN ?

 Also, I think I must close the connection if they dont match.
 Is there a special procedure to follow so that the other side
 knows I didn't approve of the certificate or do I just close?
There are two ways of thinking:
- Call SSL_shutdown() to allow for a clean shutdown of the SSL connection,
  then close() the socket. (This send a close-alert to the peer.)

Thank you.

Regards,
Ari Pirinen
[EMAIL PROTECTED]


__
FREE Personalized Email at Mail.com
Sign up at http://www.mail.com/?sr=signup
__
OpenSSL Project http://www.openssl.org
User Support Mailing List[EMAIL PROTECTED]
Automated List Manager   [EMAIL PROTECTED]



Re: When to get peer certificate?

2001-01-05 Thread Lutz Jaenicke

On Fri, Jan 05, 2001 at 08:31:23AM -0500, Ari Pirinen wrote:
 Thank you for the prompt reply. This was actually my question,
 how do I know when the handshake is completely finished?

That is a good question :-) I would call SSL_connect() to establish
the connection. Once SSL_connect() returns with '1', the connection is
established and the handshake is finished :-)

 I found some functions from headers that seem to have something
 to do with this:
 #define SSL_is_init_finished(a)   (SSL_state(a) == SSL_ST_OK)
 #define SSL_in_init(a)(SSL_state(a)SSL_ST_INIT)
 #define SSL_in_before(a)  (SSL_state(a)SSL_ST_BEFORE)
 #define SSL_in_connect_init(a)(SSL_state(a)SSL_ST_CONNECT)
 #define SSL_in_accept_init(a) (SSL_state(a)SSL_ST_ACCEPT)
 
 Is handshake completely finished when SSL_is_init_finished
 returns true, or can it be finished before that?

I did read some of the source but I am not sure on how to use these functions.

 Please understand, that the peer-certificate obtained this way is just
 the certificate presented, you must additionally check whether it passed
 the verification against the trusted CAs with SSL_get_verify_result().
 
 Yes, I understand this. I probably will add my own verify
 callback there... I assume that the verify callback gets called
 immediately when the initialisation if finished, that is,
 essentially meaning the verify callback is called before I
 will check the CN ?
Once the callback is called, the handshake is not finished, but you already
have the certificate needed from the peer. You could immediatly check
the CN once you are checking at depth "0", since this is your peers
certificate! This way you would not even have to wait until the handshake
is completed.
If you set up the verify options with SSL_VERIFY_PEER and have the callback
return "0" on non-matching CN, OpenSSL will make the handshake fail,
so you only have to close() the socket afterwards.
(As a side effect, no session will be cached on either side.)

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]