Re: When to get peer certificate?
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?
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?
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?
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?
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]