Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

eap_tls_session.hxx

00001 /* BEGIN_COPYRIGHT                                                        */
00002 /*                                                                        */
00003 /* Open Diameter: Open-source software for the Diameter and               */
00004 /*                Diameter related protocols                              */
00005 /*                                                                        */
00006 /* Copyright (C) 2002-2004 Open Diameter Project                          */
00007 /*                                                                        */
00008 /* This program is free software; you can redistribute it and/or modify   */
00009 /* it under the terms of the GNU General Public License as published by   */
00010 /* the Free Software Foundation; either version 2 of the License, or      */
00011 /* (at your option) any later version.                                    */
00012 /*                                                                        */          
00013 /* This program is distributed in the hope that it will be useful,        */
00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of         */
00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
00016 /* GNU General Public License for more details.                           */
00017 /*                                                                        */
00018 /* You should have received a copy of the GNU General Public License      */
00019 /* along with this program; if not, write to the Free Software            */
00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307    */
00021 /* USA.                                                                   */
00022 /*                                                                        */
00023 /* In addition, when you copy and redistribute some or the entire part of */
00024 /* the source code of this software with or without modification, you     */
00025 /* MUST include this copyright notice in each copy.                       */
00026 /*                                                                        */
00027 /* If you make any changes that are appeared to be useful, please send    */
00028 /* sources that include the changed part to                               */
00029 /* diameter-developers@lists.sourceforge.net so that we can reflect your  */
00030 /* changes to one unified version of this software.                       */
00031 /*                                                                        */
00032 /* END_COPYRIGHT                                                          */
00033 /***************************************************************************
00034                           eap_tls_session.hxx  -  description
00035                              -------------------
00036     begin                : mar abr 6 2004
00037     copyright            : (C) 2004 by 
00038     email                : 
00039  ***************************************************************************/
00040 
00041 /***************************************************************************
00042  *                                                                         *
00043  *   This program is free software; you can redistribute it and/or modify  *
00044  *   it under the terms of the GNU General Public License as published by  *
00045  *   the Free Software Foundation; either version 2 of the License, or     *
00046  *   (at your option) any later version.                                   *
00047  *                                                                         *
00048  ***************************************************************************/
00049 
00050 #ifndef  __EAP_TLS_SESSION_H__
00051 #define  __EAP_TLS_SESSION_H__
00052 
00053 #include "eap_tls.hxx"
00054 
00055 #include <openssl/hmac.h>
00056 #define EAPTLS_PRF_LABEL        "client EAP encryption"
00057 #define EAPTLS_MPPE_KEY_LEN     32
00058 
00059 typedef X509_STORE_CTX  X509_store_certificate;
00060 typedef X509 X509_certificate;
00061 typedef RSA RSA_key;
00062 typedef EVP_MD Hash;
00063 
00064 class EAPTLSCrypto_callbacks
00065 {
00066   public:
00067     EAPTLSCrypto_callbacks(){};
00068     virtual ~EAPTLSCrypto_callbacks(){};
00069     static void cbtls_info(const TLS_data *s, ACE_INT32 where, ACE_INT32 ret);
00070     static ACE_INT32 cbtls_verify(ACE_INT32 ok, X509_store_certificate *ctx);
00071     static void cbtls_msg(ACE_INT32 write_p, ACE_INT32 msg_version, ACE_INT32 content_type, const void *buf, ACE_UINT32 len, TLS_data *ssl, void *arg);
00072     static ACE_INT32 cbtls_password(char *buf, ACE_INT32 num, ACE_INT32 rwflag, void *userdata);
00073     static RSA_key *cbtls_rsa(TLS_data *s, ACE_INT32 is_export, ACE_INT32 keylength);
00074     static void P_hash(const Hash *evp_md,
00075                                   const ACE_Byte *secret, ACE_UINT32 secret_len,
00076                                   const ACE_Byte *seed,   ACE_UINT32 seed_len,
00077                                   ACE_Byte *out, ACE_UINT32 out_len);
00078     static void PRF(const ACE_Byte *secret, ACE_UINT32 secret_len,
00079     const ACE_Byte *seed,   ACE_UINT32 seed_len,
00080                 ACE_Byte *out, ACE_Byte *buf, ACE_UINT32 out_len);
00081 
00082     static AAAMessageBlock *eaptls_gen_mppe_keys(AAAMessageBlock *mk,
00083                                                                                     AAAMessageBlock *client_random,
00084                                                                                     AAAMessageBlock *server_random);
00085 };
00086 
00087 class EAPTLS_session_t
00088 {
00089   public:
00090    
00091   EAPTLS_session_t()
00092   {
00093     // this->session_init(false);
00094       this->cb = new EAPTLSCrypto_callbacks();
00095      info=new EAPTLS_info_t();
00096      this->clean_in = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00097      this->clean_out = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00098      this->dirty_in = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00099      this->dirty_out = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00100      this->master_key = NULL;
00101      this->client_random = AAAMessageBlock::Acquire(SSL3_RANDOM_SIZE);
00102      this->server_random = AAAMessageBlock::Acquire(SSL3_RANDOM_SIZE);
00103   };
00104 
00105   EAPTLS_session_t(EAPTLS_tls_t *eaptls)
00106   {
00107      this->eaptls=eaptls;
00108      this->cb = new EAPTLSCrypto_callbacks();
00109      //this->session_init(false);
00110      info=new EAPTLS_info_t();
00111      this->clean_in = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00112      this->clean_out = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00113      this->dirty_in = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00114      this->dirty_out = AAAMessageBlock::Acquire(MAX_RECORD_SIZE);
00115      this->master_key = NULL;
00116      this->client_random = AAAMessageBlock::Acquire(SSL3_RANDOM_SIZE);
00117      this->server_random = AAAMessageBlock::Acquire(SSL3_RANDOM_SIZE);
00118   };
00119 
00120  virtual ~EAPTLS_session_t()
00121  {
00122      if (info != NULL) delete info;
00123      if (cb != NULL)  delete cb;
00124      clean_in->Release();
00125      clean_out->Release();
00126      dirty_in->Release();
00127      dirty_out->Release();
00128      client_random->Release();
00129      server_random->Release();
00130      if (master_key != NULL) master_key->Release();   
00131  };
00132 
00133  virtual EAPTLS_session_t *session_init(bool resume)
00134   {
00135 
00136       this->first_fragment=(this->eaptls->get_config()->get_fragment_size() != 0);
00137       this->tls_msg_length=0;
00138      
00139       if ((this->tls = SSL_new(eaptls->get_tls_context())) == NULL) {
00140          EAP_LOG(LM_ERROR, "rlm_eap_tls: Error creating new SSL");
00141          ERR_print_errors_fp(stderr);
00142          return NULL;
00143       }
00144 
00145       SSL_set_app_data(this->tls, NULL);
00146 
00147       this->tls_in=BIO_new(BIO_s_mem());
00148       this->tls_out=BIO_new(BIO_s_mem());
00149       SSL_set_bio(this->tls, tls_in, tls_out);
00150 
00151       SSL_set_msg_callback(this->tls, cb->cbtls_msg);
00152       SSL_set_msg_callback_arg(this->tls, this);
00153       SSL_set_info_callback(this->tls, cb->cbtls_info);
00154 
00155       return this;
00156   };
00157   virtual void session_close()
00158   {
00159     if(this->tls)
00160     {
00161       this->sess=SSL_get1_session(this->tls);
00162       if (this->master_key != NULL) master_key->Release();
00163       this->master_key = AAAMessageBlock::Acquire(this->sess->master_key_length);
00164       
00165       this->master_key->copy((const char *)this->sess->master_key,this->sess->master_key_length);
00166       this->server_random->copy((const char *)(this->tls->s3->server_random),SSL3_RANDOM_SIZE);
00167       this->client_random->copy((const char *)(this->tls->s3->client_random),SSL3_RANDOM_SIZE);
00168 
00169       SSL_shutdown(this->tls);
00170       SSL_free(this->tls);
00171     }
00172     #if 0
00173     /*
00174      * WARNING: SSL_free seems to decrement the reference counts already,
00175      *  so doing this might crash the application.
00176      */
00177          if(tls_in)
00178     {
00179      BIO_free(tls_in);
00180     }
00181 
00182          if(tls_out)
00183     {
00184                 BIO_free(tls_out);
00185     }
00186     #endif
00187     clean_in->reset();
00188     clean_out->reset();
00189     dirty_in->reset();
00190     dirty_out->reset();
00191   } ;
00192 
00193 
00194   void set_tls_data(TLS_data *tls) { this->tls = tls;};
00195   void set_info(EAPTLS_info_t *info) { this->info = info;};
00196   void set_bufferTLS_in(BufferTLS *tls_in) { this->tls_in = tls_in;};
00197   void set_bufferTLS_out(BufferTLS *tls_out){ this->tls_out = tls_out;};
00198   void set_clean_in(EAPTLS_record_t *record){ this->clean_in->reset(); this->clean_in->copy(record->rd_ptr(),record->length());};
00199   void set_clean_out(EAPTLS_record_t *record){ this->clean_out->reset(); this->clean_out->copy(record->rd_ptr(),record->length());};
00200   void append_dirty_in(EAPTLS_record_t *record)
00201   {
00202     if (record != NULL) this->dirty_in->copy(record->rd_ptr(),record->length());
00203   };
00204   void set_dirty_in(EAPTLS_record_t *record)
00205   {
00206     this->dirty_in->reset();
00207     append_dirty_in(record);
00208   };
00209   void set_dirty_out(EAPTLS_record_t *record){this->dirty_out->reset(); this->dirty_out->copy(record->rd_ptr(),record->length());};
00210   void set_first_fragment(bool first_fragment) {this->first_fragment = first_fragment;};
00211   void set_tls_msg_length(ACE_UINT32 tls_msg_length) {this->tls_msg_length = tls_msg_length;};
00212   void set_length_to_send(ACE_UINT32 length_to_send) {this->length_to_send = length_to_send;};
00213   void set_flags_to_send(ACE_Byte flags_to_send) {this->flags_to_send = flags_to_send;};
00214   void set_fragments(AAAMessageBlock *fragments) {this->fragments=fragments;};
00215 
00216   TLS_data *get_tls_data() { return tls;};
00217   //Information to derive new session keys
00218   AAAMessageBlock *get_master_key() {return this->master_key;};
00219   AAAMessageBlock *get_client_random() {return this->client_random;};             
00220   AAAMessageBlock *get_server_random(){return this->server_random;};
00221   //-------------------------------------------------                   
00222   EAPTLS_info_t *get_info() { return info;};
00223   BufferTLS *get_bufferTLS_in() {return tls_in;};
00224   BufferTLS *get_bufferTLS_out() { return tls_out;};
00225   EAPTLS_record_t  *get_clean_in() {return clean_in;};
00226   EAPTLS_record_t  *get_clean_out() {return this->clean_out;};
00227   EAPTLS_record_t  *get_dirty_in() {return this->dirty_in;};
00228   EAPTLS_record_t  *get_dirty_out() {return this->dirty_out;};
00229   ACE_UINT32 get_tls_msg_length() {return tls_msg_length;};
00230   ACE_UINT32 get_length_to_send() {return length_to_send;};
00231   AAAMessageBlock *restore_fragments(){return fragments;};
00232   ACE_Byte get_flags_to_send() {return flags_to_send;};
00233   bool if_first_fragment() {return first_fragment;};
00234   ACE_UINT32 get_fragment_size() {return eaptls->get_config()->get_fragment_size();}; //return FRAGMENT size
00235   bool if_length_included() {return eaptls->get_config()->get_include_length();};
00236 
00237   protected:
00238     EAPTLS_tls_t *eaptls;
00239     TLS_data *tls;
00240     EAPTLS_info_t *info;
00241     BufferTLS *tls_in;
00242     BufferTLS *tls_out;
00243     EAPTLS_record_t *clean_in;
00244     EAPTLS_record_t *clean_out;
00245     EAPTLS_record_t *dirty_in;
00246     EAPTLS_record_t *dirty_out;
00247     EAPTLSCrypto_callbacks *cb;
00248     //Used for fragmentation
00249     ACE_UINT32 tls_msg_length;
00250     ACE_UINT32 length_to_send;
00251     ACE_Byte flags_to_send;
00252     bool first_fragment;
00253     AAAMessageBlock *master_key;
00254     AAAMessageBlock *client_random;
00255     AAAMessageBlock *server_random;
00256     AAAMessageBlock *fragments;
00257     SSL_SESSION *sess;
00258    
00259 };
00260 
00261 class EAPTLS_session_t_peer : public EAPTLS_session_t
00262 {
00263      public:
00264         EAPTLS_session_t_peer():EAPTLS_session_t(){this->sess=NULL;};
00265         EAPTLS_session_t_peer(EAPTLS_tls_t *eaptls):EAPTLS_session_t(eaptls){this->sess=NULL;};
00266         virtual EAPTLS_session_t_peer *session_init(bool resume)
00267         {
00268              ACE_INT32 verify_mode = 0;
00269              EAPTLS_session_t::session_init(resume);
00270              /* Always verify the peer certificate */
00271                   verify_mode |= SSL_VERIFY_PEER;
00272                  verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00273                  SSL_set_verify(this->tls, verify_mode, cb->cbtls_verify);
00274                 /* In Client mode we only connect.  */
00275                   SSL_set_connect_state(this->tls);
00276              if (resume && (this->sess !=NULL)) SSL_set_session(this->tls,this->sess);
00277              return this;
00278         }
00279 };
00280 
00281 class EAPTLS_session_t_auth : public EAPTLS_session_t
00282 {
00283     public:
00284         EAPTLS_session_t_auth():EAPTLS_session_t(){this->sess=NULL;};
00285         EAPTLS_session_t_auth(EAPTLS_tls_t *eaptls):EAPTLS_session_t(eaptls){this->sess=NULL;};
00286 
00287         virtual EAPTLS_session_t_auth *session_init(bool resume)
00288         {
00289              ACE_INT32 verify_mode = 0;
00290              EAPTLS_session_t::session_init(resume);
00291              /* Always verify the peer certificate */
00292                   verify_mode |= SSL_VERIFY_PEER;
00293                  verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00294                   verify_mode |= SSL_VERIFY_CLIENT_ONCE;
00295                   SSL_set_verify(this->tls, verify_mode, cb->cbtls_verify);
00296                   /* In Server mode we only accept.  */
00297             SSL_set_accept_state(this->tls);
00298             return this;
00299         }
00300 };
00301 
00302 #endif
00303 

Generated on Fri Jun 25 19:16:16 2004 for EAP State Machine by doxygen 1.3.5