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 "eap_server/eap_i.h"
00019 #include "eap_common/eap_gpsk_common.h"
00020
00021
00022 struct eap_gpsk_data {
00023 enum { GPSK_1, GPSK_3, SUCCESS, FAILURE } state;
00024 u8 rand_server[EAP_GPSK_RAND_LEN];
00025 u8 rand_peer[EAP_GPSK_RAND_LEN];
00026 u8 msk[EAP_MSK_LEN];
00027 u8 emsk[EAP_EMSK_LEN];
00028 u8 sk[EAP_GPSK_MAX_SK_LEN];
00029 size_t sk_len;
00030 u8 pk[EAP_GPSK_MAX_PK_LEN];
00031 size_t pk_len;
00032 u8 *id_peer;
00033 size_t id_peer_len;
00034 u8 *id_server;
00035 size_t id_server_len;
00036 #define MAX_NUM_CSUITES 2
00037 struct eap_gpsk_csuite csuite_list[MAX_NUM_CSUITES];
00038 size_t csuite_count;
00039 int vendor;
00040 int specifier;
00041 };
00042
00043
00044 static const char * eap_gpsk_state_txt(int state)
00045 {
00046 switch (state) {
00047 case GPSK_1:
00048 return "GPSK-1";
00049 case GPSK_3:
00050 return "GPSK-3";
00051 case SUCCESS:
00052 return "SUCCESS";
00053 case FAILURE:
00054 return "FAILURE";
00055 default:
00056 return "?";
00057 }
00058 }
00059
00060
00061 static void eap_gpsk_state(struct eap_gpsk_data *data, int state)
00062 {
00063 wpa_printf(MSG_DEBUG, "EAP-GPSK: %s -> %s",
00064 eap_gpsk_state_txt(data->state),
00065 eap_gpsk_state_txt(state));
00066 data->state = state;
00067 }
00068
00069
00070 static void * eap_gpsk_init(struct eap_sm *sm)
00071 {
00072 struct eap_gpsk_data *data;
00073
00074 data = os_zalloc(sizeof(*data));
00075 if (data == NULL)
00076 return NULL;
00077 data->state = GPSK_1;
00078
00079
00080 data->id_server = (u8 *) os_strdup("hostapd");
00081 if (data->id_server)
00082 data->id_server_len = os_strlen((char *) data->id_server);
00083
00084 data->csuite_count = 0;
00085 if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
00086 EAP_GPSK_CIPHER_AES)) {
00087 WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
00088 EAP_GPSK_VENDOR_IETF);
00089 WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
00090 EAP_GPSK_CIPHER_AES);
00091 data->csuite_count++;
00092 }
00093 if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
00094 EAP_GPSK_CIPHER_SHA256)) {
00095 WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
00096 EAP_GPSK_VENDOR_IETF);
00097 WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
00098 EAP_GPSK_CIPHER_SHA256);
00099 data->csuite_count++;
00100 }
00101
00102 return data;
00103 }
00104
00105
00106 static void eap_gpsk_reset(struct eap_sm *sm, void *priv)
00107 {
00108 struct eap_gpsk_data *data = priv;
00109 os_free(data->id_server);
00110 os_free(data->id_peer);
00111 os_free(data);
00112 }
00113
00114
00115 static struct wpabuf * eap_gpsk_build_gpsk_1(struct eap_sm *sm,
00116 struct eap_gpsk_data *data, u8 id)
00117 {
00118 size_t len;
00119 struct wpabuf *req;
00120
00121 wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-1");
00122
00123 if (os_get_random(data->rand_server, EAP_GPSK_RAND_LEN)) {
00124 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to get random data");
00125 eap_gpsk_state(data, FAILURE);
00126 return NULL;
00127 }
00128 wpa_hexdump(MSG_MSGDUMP, "EAP-GPSK: RAND_Server",
00129 data->rand_server, EAP_GPSK_RAND_LEN);
00130
00131 len = 1 + 2 + data->id_server_len + EAP_GPSK_RAND_LEN + 2 +
00132 data->csuite_count * sizeof(struct eap_gpsk_csuite);
00133 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
00134 EAP_CODE_REQUEST, id);
00135 if (req == NULL) {
00136 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
00137 "for request/GPSK-1");
00138 eap_gpsk_state(data, FAILURE);
00139 return NULL;
00140 }
00141
00142 wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_1);
00143 wpabuf_put_be16(req, data->id_server_len);
00144 wpabuf_put_data(req, data->id_server, data->id_server_len);
00145 wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
00146 wpabuf_put_be16(req,
00147 data->csuite_count * sizeof(struct eap_gpsk_csuite));
00148 wpabuf_put_data(req, data->csuite_list,
00149 data->csuite_count * sizeof(struct eap_gpsk_csuite));
00150
00151 return req;
00152 }
00153
00154
00155 static struct wpabuf * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
00156 struct eap_gpsk_data *data, u8 id)
00157 {
00158 u8 *pos, *start;
00159 size_t len, miclen;
00160 struct eap_gpsk_csuite *csuite;
00161 struct wpabuf *req;
00162
00163 wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-3");
00164
00165 miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
00166 len = 1 + 2 * EAP_GPSK_RAND_LEN + 2 + data->id_server_len +
00167 sizeof(struct eap_gpsk_csuite) + 2 + miclen;
00168 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
00169 EAP_CODE_REQUEST, id);
00170 if (req == NULL) {
00171 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
00172 "for request/GPSK-3");
00173 eap_gpsk_state(data, FAILURE);
00174 return NULL;
00175 }
00176
00177 wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_3);
00178 start = wpabuf_put(req, 0);
00179
00180 wpabuf_put_data(req, data->rand_peer, EAP_GPSK_RAND_LEN);
00181 wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
00182 wpabuf_put_be16(req, data->id_server_len);
00183 wpabuf_put_data(req, data->id_server, data->id_server_len);
00184 csuite = wpabuf_put(req, sizeof(*csuite));
00185 WPA_PUT_BE32(csuite->vendor, data->vendor);
00186 WPA_PUT_BE16(csuite->specifier, data->specifier);
00187
00188
00189 wpabuf_put_be16(req, 0);
00190
00191 pos = wpabuf_put(req, miclen);
00192 if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
00193 data->specifier, start, pos - start, pos) < 0)
00194 {
00195 os_free(req);
00196 eap_gpsk_state(data, FAILURE);
00197 return NULL;
00198 }
00199
00200 return req;
00201 }
00202
00203
00204 static struct wpabuf * eap_gpsk_buildReq(struct eap_sm *sm, void *priv, u8 id)
00205 {
00206 struct eap_gpsk_data *data = priv;
00207
00208 switch (data->state) {
00209 case GPSK_1:
00210 return eap_gpsk_build_gpsk_1(sm, data, id);
00211 case GPSK_3:
00212 return eap_gpsk_build_gpsk_3(sm, data, id);
00213 default:
00214 wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown state %d in buildReq",
00215 data->state);
00216 break;
00217 }
00218 return NULL;
00219 }
00220
00221
00222 static Boolean eap_gpsk_check(struct eap_sm *sm, void *priv,
00223 struct wpabuf *respData)
00224 {
00225 struct eap_gpsk_data *data = priv;
00226 const u8 *pos;
00227 size_t len;
00228
00229 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
00230 if (pos == NULL || len < 1) {
00231 wpa_printf(MSG_INFO, "EAP-GPSK: Invalid frame");
00232 return TRUE;
00233 }
00234
00235 wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode=%d", *pos);
00236
00237 if (data->state == GPSK_1 && *pos == EAP_GPSK_OPCODE_GPSK_2)
00238 return FALSE;
00239
00240 if (data->state == GPSK_3 && *pos == EAP_GPSK_OPCODE_GPSK_4)
00241 return FALSE;
00242
00243 wpa_printf(MSG_INFO, "EAP-GPSK: Unexpected opcode=%d in state=%d",
00244 *pos, data->state);
00245
00246 return TRUE;
00247 }
00248
00249
00250 static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
00251 struct eap_gpsk_data *data,
00252 const u8 *payload, size_t payloadlen)
00253 {
00254 const u8 *pos, *end;
00255 u16 alen;
00256 const struct eap_gpsk_csuite *csuite;
00257 size_t i, miclen;
00258 u8 mic[EAP_GPSK_MAX_MIC_LEN];
00259
00260 if (data->state != GPSK_1)
00261 return;
00262
00263 wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Response/GPSK-2");
00264
00265 pos = payload;
00266 end = payload + payloadlen;
00267
00268 if (end - pos < 2) {
00269 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00270 "ID_Peer length");
00271 eap_gpsk_state(data, FAILURE);
00272 return;
00273 }
00274 alen = WPA_GET_BE16(pos);
00275 pos += 2;
00276 if (end - pos < alen) {
00277 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00278 "ID_Peer");
00279 eap_gpsk_state(data, FAILURE);
00280 return;
00281 }
00282 os_free(data->id_peer);
00283 data->id_peer = os_malloc(alen);
00284 if (data->id_peer == NULL) {
00285 wpa_printf(MSG_DEBUG, "EAP-GPSK: Not enough memory to store "
00286 "%d-octet ID_Peer", alen);
00287 return;
00288 }
00289 os_memcpy(data->id_peer, pos, alen);
00290 data->id_peer_len = alen;
00291 wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
00292 data->id_peer, data->id_peer_len);
00293 pos += alen;
00294
00295 if (end - pos < 2) {
00296 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00297 "ID_Server length");
00298 eap_gpsk_state(data, FAILURE);
00299 return;
00300 }
00301 alen = WPA_GET_BE16(pos);
00302 pos += 2;
00303 if (end - pos < alen) {
00304 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00305 "ID_Server");
00306 eap_gpsk_state(data, FAILURE);
00307 return;
00308 }
00309 if (alen != data->id_server_len ||
00310 os_memcmp(pos, data->id_server, alen) != 0) {
00311 wpa_printf(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1 and "
00312 "GPSK-2 did not match");
00313 eap_gpsk_state(data, FAILURE);
00314 return;
00315 }
00316 pos += alen;
00317
00318 if (end - pos < EAP_GPSK_RAND_LEN) {
00319 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00320 "RAND_Peer");
00321 eap_gpsk_state(data, FAILURE);
00322 return;
00323 }
00324 os_memcpy(data->rand_peer, pos, EAP_GPSK_RAND_LEN);
00325 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
00326 data->rand_peer, EAP_GPSK_RAND_LEN);
00327 pos += EAP_GPSK_RAND_LEN;
00328
00329 if (end - pos < EAP_GPSK_RAND_LEN) {
00330 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00331 "RAND_Server");
00332 eap_gpsk_state(data, FAILURE);
00333 return;
00334 }
00335 if (os_memcmp(data->rand_server, pos, EAP_GPSK_RAND_LEN) != 0) {
00336 wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1 and "
00337 "GPSK-2 did not match");
00338 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1",
00339 data->rand_server, EAP_GPSK_RAND_LEN);
00340 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-2",
00341 pos, EAP_GPSK_RAND_LEN);
00342 eap_gpsk_state(data, FAILURE);
00343 return;
00344 }
00345 pos += EAP_GPSK_RAND_LEN;
00346
00347 if (end - pos < 2) {
00348 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00349 "CSuite_List length");
00350 eap_gpsk_state(data, FAILURE);
00351 return;
00352 }
00353 alen = WPA_GET_BE16(pos);
00354 pos += 2;
00355 if (end - pos < alen) {
00356 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00357 "CSuite_List");
00358 eap_gpsk_state(data, FAILURE);
00359 return;
00360 }
00361 if (alen != data->csuite_count * sizeof(struct eap_gpsk_csuite) ||
00362 os_memcmp(pos, data->csuite_list, alen) != 0) {
00363 wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List in GPSK-1 and "
00364 "GPSK-2 did not match");
00365 eap_gpsk_state(data, FAILURE);
00366 return;
00367 }
00368 pos += alen;
00369
00370 if (end - pos < (int) sizeof(*csuite)) {
00371 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00372 "CSuite_Sel");
00373 eap_gpsk_state(data, FAILURE);
00374 return;
00375 }
00376 csuite = (const struct eap_gpsk_csuite *) pos;
00377 for (i = 0; i < data->csuite_count; i++) {
00378 if (os_memcmp(csuite, &data->csuite_list[i], sizeof(*csuite))
00379 == 0)
00380 break;
00381 }
00382 if (i == data->csuite_count) {
00383 wpa_printf(MSG_DEBUG, "EAP-GPSK: Peer selected unsupported "
00384 "ciphersuite %d:%d",
00385 WPA_GET_BE32(csuite->vendor),
00386 WPA_GET_BE16(csuite->specifier));
00387 eap_gpsk_state(data, FAILURE);
00388 return;
00389 }
00390 data->vendor = WPA_GET_BE32(csuite->vendor);
00391 data->specifier = WPA_GET_BE16(csuite->specifier);
00392 wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel %d:%d",
00393 data->vendor, data->specifier);
00394 pos += sizeof(*csuite);
00395
00396 if (end - pos < 2) {
00397 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00398 "PD_Payload_1 length");
00399 eap_gpsk_state(data, FAILURE);
00400 return;
00401 }
00402 alen = WPA_GET_BE16(pos);
00403 pos += 2;
00404 if (end - pos < alen) {
00405 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00406 "PD_Payload_1");
00407 eap_gpsk_state(data, FAILURE);
00408 return;
00409 }
00410 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_1", pos, alen);
00411 pos += alen;
00412
00413 if (sm->user == NULL || sm->user->password == NULL) {
00414 wpa_printf(MSG_INFO, "EAP-GPSK: No PSK/password configured "
00415 "for the user");
00416 eap_gpsk_state(data, FAILURE);
00417 return;
00418 }
00419
00420 if (eap_gpsk_derive_keys(sm->user->password, sm->user->password_len,
00421 data->vendor, data->specifier,
00422 data->rand_peer, data->rand_server,
00423 data->id_peer, data->id_peer_len,
00424 data->id_server, data->id_server_len,
00425 data->msk, data->emsk,
00426 data->sk, &data->sk_len,
00427 data->pk, &data->pk_len) < 0) {
00428 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive keys");
00429 eap_gpsk_state(data, FAILURE);
00430 return;
00431 }
00432
00433 miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
00434 if (end - pos < (int) miclen) {
00435 wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
00436 "(left=%lu miclen=%lu)",
00437 (unsigned long) (end - pos),
00438 (unsigned long) miclen);
00439 eap_gpsk_state(data, FAILURE);
00440 return;
00441 }
00442 if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
00443 data->specifier, payload, pos - payload, mic)
00444 < 0) {
00445 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
00446 eap_gpsk_state(data, FAILURE);
00447 return;
00448 }
00449 if (os_memcmp(mic, pos, miclen) != 0) {
00450 wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-2");
00451 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
00452 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
00453 eap_gpsk_state(data, FAILURE);
00454 return;
00455 }
00456 pos += miclen;
00457
00458 if (pos != end) {
00459 wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
00460 "data in the end of GPSK-2",
00461 (unsigned long) (end - pos));
00462 }
00463
00464 eap_gpsk_state(data, GPSK_3);
00465 }
00466
00467
00468 static void eap_gpsk_process_gpsk_4(struct eap_sm *sm,
00469 struct eap_gpsk_data *data,
00470 const u8 *payload, size_t payloadlen)
00471 {
00472 const u8 *pos, *end;
00473 u16 alen;
00474 size_t miclen;
00475 u8 mic[EAP_GPSK_MAX_MIC_LEN];
00476
00477 if (data->state != GPSK_3)
00478 return;
00479
00480 wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Response/GPSK-4");
00481
00482 pos = payload;
00483 end = payload + payloadlen;
00484
00485 if (end - pos < 2) {
00486 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00487 "PD_Payload_1 length");
00488 eap_gpsk_state(data, FAILURE);
00489 return;
00490 }
00491 alen = WPA_GET_BE16(pos);
00492 pos += 2;
00493 if (end - pos < alen) {
00494 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00495 "PD_Payload_1");
00496 eap_gpsk_state(data, FAILURE);
00497 return;
00498 }
00499 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_1", pos, alen);
00500 pos += alen;
00501
00502 miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
00503 if (end - pos < (int) miclen) {
00504 wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
00505 "(left=%lu miclen=%lu)",
00506 (unsigned long) (end - pos),
00507 (unsigned long) miclen);
00508 eap_gpsk_state(data, FAILURE);
00509 return;
00510 }
00511 if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
00512 data->specifier, payload, pos - payload, mic)
00513 < 0) {
00514 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
00515 eap_gpsk_state(data, FAILURE);
00516 return;
00517 }
00518 if (os_memcmp(mic, pos, miclen) != 0) {
00519 wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-4");
00520 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
00521 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
00522 eap_gpsk_state(data, FAILURE);
00523 return;
00524 }
00525 pos += miclen;
00526
00527 if (pos != end) {
00528 wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
00529 "data in the end of GPSK-4",
00530 (unsigned long) (end - pos));
00531 }
00532
00533 eap_gpsk_state(data, SUCCESS);
00534 }
00535
00536
00537 static void eap_gpsk_process(struct eap_sm *sm, void *priv,
00538 struct wpabuf *respData)
00539 {
00540 struct eap_gpsk_data *data = priv;
00541 const u8 *pos;
00542 size_t len;
00543
00544 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
00545 if (pos == NULL || len < 1)
00546 return;
00547
00548 switch (*pos) {
00549 case EAP_GPSK_OPCODE_GPSK_2:
00550 eap_gpsk_process_gpsk_2(sm, data, pos + 1, len - 1);
00551 break;
00552 case EAP_GPSK_OPCODE_GPSK_4:
00553 eap_gpsk_process_gpsk_4(sm, data, pos + 1, len - 1);
00554 break;
00555 }
00556 }
00557
00558
00559 static Boolean eap_gpsk_isDone(struct eap_sm *sm, void *priv)
00560 {
00561 struct eap_gpsk_data *data = priv;
00562 return data->state == SUCCESS || data->state == FAILURE;
00563 }
00564
00565
00566 static u8 * eap_gpsk_getKey(struct eap_sm *sm, void *priv, size_t *len)
00567 {
00568 struct eap_gpsk_data *data = priv;
00569 u8 *key;
00570
00571 if (data->state != SUCCESS)
00572 return NULL;
00573
00574 key = os_malloc(EAP_MSK_LEN);
00575 if (key == NULL)
00576 return NULL;
00577 os_memcpy(key, data->msk, EAP_MSK_LEN);
00578 *len = EAP_MSK_LEN;
00579
00580 return key;
00581 }
00582
00583
00584 static u8 * eap_gpsk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
00585 {
00586 struct eap_gpsk_data *data = priv;
00587 u8 *key;
00588
00589 if (data->state != SUCCESS)
00590 return NULL;
00591
00592 key = os_malloc(EAP_EMSK_LEN);
00593 if (key == NULL)
00594 return NULL;
00595 os_memcpy(key, data->emsk, EAP_EMSK_LEN);
00596 *len = EAP_EMSK_LEN;
00597
00598 return key;
00599 }
00600
00601
00602 static Boolean eap_gpsk_isSuccess(struct eap_sm *sm, void *priv)
00603 {
00604 struct eap_gpsk_data *data = priv;
00605 return data->state == SUCCESS;
00606 }
00607
00608
00609 int eap_server_gpsk_register(void)
00610 {
00611 struct eap_method *eap;
00612 int ret;
00613
00614 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
00615 EAP_VENDOR_IETF, EAP_TYPE_GPSK, "GPSK");
00616 if (eap == NULL)
00617 return -1;
00618
00619 eap->init = eap_gpsk_init;
00620 eap->reset = eap_gpsk_reset;
00621 eap->buildReq = eap_gpsk_buildReq;
00622 eap->check = eap_gpsk_check;
00623 eap->process = eap_gpsk_process;
00624 eap->isDone = eap_gpsk_isDone;
00625 eap->getKey = eap_gpsk_getKey;
00626 eap->isSuccess = eap_gpsk_isSuccess;
00627 eap->get_emsk = eap_gpsk_get_emsk;
00628
00629 ret = eap_server_method_register(eap);
00630 if (ret)
00631 eap_server_method_free(eap);
00632 return ret;
00633 }