00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/tls.h"
00019 #include "eap_i.h"
00020 #include "eap_tls_common.h"
00021 #include "eap_config.h"
00022
00023
00024 static void eap_tls_deinit(struct eap_sm *sm, void *priv);
00025
00026
00027 struct eap_tls_data {
00028 struct eap_ssl_data ssl;
00029 u8 *key_data;
00030 };
00031
00032
00033 static void * eap_tls_init(struct eap_sm *sm)
00034 {
00035 struct eap_tls_data *data;
00036 struct eap_peer_config *config = eap_get_config(sm);
00037 if (config == NULL ||
00038 ((sm->init_phase2 ? config->private_key2 : config->private_key)
00039 == NULL &&
00040 (sm->init_phase2 ? config->engine2 : config->engine) == 0)) {
00041 wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured");
00042 return NULL;
00043 }
00044
00045 data = os_zalloc(sizeof(*data));
00046 if (data == NULL)
00047 return NULL;
00048
00049 if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
00050 wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
00051 eap_tls_deinit(sm, data);
00052 if (config->engine) {
00053 wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard "
00054 "PIN");
00055 eap_sm_request_pin(sm);
00056 sm->ignore = TRUE;
00057 } else if (config->private_key && !config->private_key_passwd)
00058 {
00059 wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private "
00060 "key passphrase");
00061 eap_sm_request_passphrase(sm);
00062 sm->ignore = TRUE;
00063 }
00064 return NULL;
00065 }
00066
00067 return data;
00068 }
00069
00070
00071 static void eap_tls_deinit(struct eap_sm *sm, void *priv)
00072 {
00073 struct eap_tls_data *data = priv;
00074 if (data == NULL)
00075 return;
00076 eap_peer_tls_ssl_deinit(sm, &data->ssl);
00077 os_free(data->key_data);
00078 os_free(data);
00079 }
00080
00081
00082 static struct wpabuf * eap_tls_failure(struct eap_sm *sm,
00083 struct eap_tls_data *data,
00084 struct eap_method_ret *ret, int res,
00085 struct wpabuf *resp, u8 id)
00086 {
00087 wpa_printf(MSG_DEBUG, "EAP-TLS: TLS processing failed");
00088
00089 ret->methodState = METHOD_DONE;
00090 ret->decision = DECISION_FAIL;
00091
00092 if (res == -1) {
00093 struct eap_peer_config *config = eap_get_config(sm);
00094 if (config) {
00095
00096
00097
00098
00099
00100
00101 os_free(config->pin);
00102 config->pin = NULL;
00103 }
00104 }
00105
00106 if (resp) {
00107
00108
00109
00110
00111 return resp;
00112 }
00113
00114 return eap_peer_tls_build_ack(id, EAP_TYPE_TLS, 0);
00115 }
00116
00117
00118 static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data,
00119 struct eap_method_ret *ret)
00120 {
00121 wpa_printf(MSG_DEBUG, "EAP-TLS: Done");
00122
00123 ret->methodState = METHOD_DONE;
00124 ret->decision = DECISION_UNCOND_SUCC;
00125
00126 os_free(data->key_data);
00127 data->key_data = eap_peer_tls_derive_key(sm, &data->ssl,
00128 "client EAP encryption",
00129 EAP_TLS_KEY_LEN +
00130 EAP_EMSK_LEN);
00131 if (data->key_data) {
00132 wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived key",
00133 data->key_data, EAP_TLS_KEY_LEN);
00134 wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived EMSK",
00135 data->key_data + EAP_TLS_KEY_LEN,
00136 EAP_EMSK_LEN);
00137 } else {
00138 wpa_printf(MSG_INFO, "EAP-TLS: Failed to derive key");
00139 }
00140 }
00141
00142
00143 static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
00144 struct eap_method_ret *ret,
00145 const struct wpabuf *reqData)
00146 {
00147 size_t left;
00148 int res;
00149 struct wpabuf *resp;
00150 u8 flags, id;
00151 const u8 *pos;
00152 struct eap_tls_data *data = priv;
00153
00154 pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TLS, ret,
00155 reqData, &left, &flags);
00156 if (pos == NULL)
00157 return NULL;
00158 id = eap_get_id(reqData);
00159
00160 if (flags & EAP_TLS_FLAGS_START) {
00161 wpa_printf(MSG_DEBUG, "EAP-TLS: Start");
00162 left = 0;
00163
00164 }
00165
00166 resp = NULL;
00167 res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TLS, 0, id,
00168 pos, left, &resp);
00169
00170 if (res < 0) {
00171 return eap_tls_failure(sm, data, ret, res, resp, id);
00172 }
00173
00174 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn))
00175 eap_tls_success(sm, data, ret);
00176
00177 if (res == 1) {
00178 wpabuf_free(resp);
00179 return eap_peer_tls_build_ack(id, EAP_TYPE_TLS, 0);
00180 }
00181
00182 return resp;
00183 }
00184
00185
00186 static Boolean eap_tls_has_reauth_data(struct eap_sm *sm, void *priv)
00187 {
00188 struct eap_tls_data *data = priv;
00189 return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
00190 }
00191
00192
00193 static void eap_tls_deinit_for_reauth(struct eap_sm *sm, void *priv)
00194 {
00195 }
00196
00197
00198 static void * eap_tls_init_for_reauth(struct eap_sm *sm, void *priv)
00199 {
00200 struct eap_tls_data *data = priv;
00201 os_free(data->key_data);
00202 data->key_data = NULL;
00203 if (eap_peer_tls_reauth_init(sm, &data->ssl)) {
00204 os_free(data);
00205 return NULL;
00206 }
00207 return priv;
00208 }
00209
00210
00211 static int eap_tls_get_status(struct eap_sm *sm, void *priv, char *buf,
00212 size_t buflen, int verbose)
00213 {
00214 struct eap_tls_data *data = priv;
00215 return eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose);
00216 }
00217
00218
00219 static Boolean eap_tls_isKeyAvailable(struct eap_sm *sm, void *priv)
00220 {
00221 struct eap_tls_data *data = priv;
00222 return data->key_data != NULL;
00223 }
00224
00225
00226 static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len)
00227 {
00228 struct eap_tls_data *data = priv;
00229 u8 *key;
00230
00231 if (data->key_data == NULL)
00232 return NULL;
00233
00234 key = os_malloc(EAP_TLS_KEY_LEN);
00235 if (key == NULL)
00236 return NULL;
00237
00238 *len = EAP_TLS_KEY_LEN;
00239 os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
00240
00241 return key;
00242 }
00243
00244
00245 static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
00246 {
00247 struct eap_tls_data *data = priv;
00248 u8 *key;
00249
00250 if (data->key_data == NULL)
00251 return NULL;
00252
00253 key = os_malloc(EAP_EMSK_LEN);
00254 if (key == NULL)
00255 return NULL;
00256
00257 *len = EAP_EMSK_LEN;
00258 os_memcpy(key, data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN);
00259
00260 return key;
00261 }
00262
00263
00264 int eap_peer_tls_register(void)
00265 {
00266 struct eap_method *eap;
00267 int ret;
00268
00269 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
00270 EAP_VENDOR_IETF, EAP_TYPE_TLS, "TLS");
00271 if (eap == NULL)
00272 return -1;
00273
00274 eap->init = eap_tls_init;
00275 eap->deinit = eap_tls_deinit;
00276 eap->process = eap_tls_process;
00277 eap->isKeyAvailable = eap_tls_isKeyAvailable;
00278 eap->getKey = eap_tls_getKey;
00279 eap->get_status = eap_tls_get_status;
00280 eap->has_reauth_data = eap_tls_has_reauth_data;
00281 eap->deinit_for_reauth = eap_tls_deinit_for_reauth;
00282 eap->init_for_reauth = eap_tls_init_for_reauth;
00283 eap->get_emsk = eap_tls_get_emsk;
00284
00285 ret = eap_peer_method_register(eap);
00286 if (ret)
00287 eap_peer_method_free(eap);
00288 return ret;
00289 }