00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
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
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
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
00175
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
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();};
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
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
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
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
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
00297 SSL_set_accept_state(this->tls);
00298 return this;
00299 }
00300 };
00301
00302 #endif
00303