aboutsummaryrefslogtreecommitdiffstats
path: root/eap_example
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2008-02-28 01:34:43 (GMT)
committerJouni Malinen <jm@jm.kir.nu>2008-02-28 01:34:43 (GMT)
commit6fc6879bd55a394f807cbbe927df736c190cb8ab (patch)
treecdf50da0c58f21510a808d53502a060d911ff243 /eap_example
downloadhostap-6fc6879bd55a394f807cbbe927df736c190cb8ab.zip
hostap-6fc6879bd55a394f807cbbe927df736c190cb8ab.tar.gz
hostap-6fc6879bd55a394f807cbbe927df736c190cb8ab.tar.bz2
Re-initialize hostapd/wpa_supplicant git repository based on 0.6.3 release
Diffstat (limited to 'eap_example')
-rw-r--r--eap_example/.gitignore3
-rw-r--r--eap_example/Makefile179
-rw-r--r--eap_example/README46
-rw-r--r--eap_example/ca.pem19
-rw-r--r--eap_example/eap_example.c55
-rw-r--r--eap_example/eap_example_peer.c270
-rw-r--r--eap_example/eap_example_server.c192
-rw-r--r--eap_example/server.keybin0 -> 608 bytes
-rw-r--r--eap_example/server.pem18
9 files changed, 782 insertions, 0 deletions
diff --git a/eap_example/.gitignore b/eap_example/.gitignore
new file mode 100644
index 0000000..82a12a5
--- /dev/null
+++ b/eap_example/.gitignore
@@ -0,0 +1,3 @@
+*.d
+eap_example
+libeap.so
diff --git a/eap_example/Makefile b/eap_example/Makefile
new file mode 100644
index 0000000..0a7ca78
--- /dev/null
+++ b/eap_example/Makefile
@@ -0,0 +1,179 @@
+ALL=eap_example
+
+all: $(ALL)
+
+ifndef CC
+CC=gcc
+endif
+
+ifndef CFLAGS
+CFLAGS = -MMD -O2 -Wall -g
+endif
+
+CONFIG_TLS=openssl
+#CONFIG_TLS=internal
+#CONFIG_INTERNAL_LIBTOMMATH=y
+
+
+CFLAGS += -I.
+CFLAGS += -I../src
+CFLAGS += -I../src/crypto
+CFLAGS += -I../src/utils
+CFLAGS += -I../src/common
+
+# at least for now, need to include config_ssid.h and config_blob.h from
+# wpa_supplicant directory
+CFLAGS += -I../wpa_supplicant
+
+
+OBJS_both += ../src/utils/common.o
+OBJS_both += ../src/utils/os_unix.o
+OBJS_both += ../src/utils/wpa_debug.o
+OBJS_both += ../src/utils/base64.o
+OBJS_both += ../src/utils/wpabuf.o
+OBJS_both += ../src/crypto/md5.o
+OBJS_both += ../src/crypto/rc4.o
+OBJS_both += ../src/crypto/md4.o
+OBJS_both += ../src/crypto/sha1.o
+OBJS_both += ../src/crypto/des.o
+OBJS_both += ../src/crypto/aes_wrap.o
+OBJS_both += ../src/crypto/aes.o
+OBJS_both += ../src/crypto/ms_funcs.o
+OBJS_both += ../src/crypto/sha256.o
+
+
+OBJS_both += ../src/eap_common/eap_psk_common.o
+OBJS_both += ../src/eap_common/eap_pax_common.o
+OBJS_both += ../src/eap_common/eap_sake_common.o
+OBJS_both += ../src/eap_common/eap_gpsk_common.o
+OBJS_both += ../src/eap_common/chap.o
+
+OBJS_peer += ../src/eap_peer/eap_tls.o
+OBJS_peer += ../src/eap_peer/eap_peap.o
+OBJS_peer += ../src/eap_peer/eap_ttls.o
+OBJS_peer += ../src/eap_peer/eap_md5.o
+OBJS_peer += ../src/eap_peer/eap_mschapv2.o
+OBJS_peer += ../src/eap_peer/mschapv2.o
+OBJS_peer += ../src/eap_peer/eap_otp.o
+OBJS_peer += ../src/eap_peer/eap_gtc.o
+OBJS_peer += ../src/eap_peer/eap_leap.o
+OBJS_peer += ../src/eap_peer/eap_psk.o
+OBJS_peer += ../src/eap_peer/eap_tlv.o
+OBJS_peer += ../src/eap_peer/eap_pax.o
+OBJS_peer += ../src/eap_peer/eap_sake.o
+OBJS_peer += ../src/eap_peer/eap_gpsk.o
+OBJS_peer += ../src/eap_peer/eap.o
+OBJS_peer += ../src/eap_common/eap_common.o
+OBJS_peer += ../src/eap_peer/eap_methods.o
+OBJS_peer += ../src/eap_peer/eap_tls_common.o
+
+CFLAGS += -DEAP_TLS
+CFLAGS += -DEAP_PEAP
+CFLAGS += -DEAP_TTLS
+CFLAGS += -DEAP_MD5
+CFLAGS += -DEAP_MSCHAPv2
+CFLAGS += -DEAP_GTC
+CFLAGS += -DEAP_OTP
+CFLAGS += -DEAP_LEAP
+CFLAGS += -DEAP_PSK
+CFLAGS += -DEAP_TLV
+CFLAGS += -DEAP_PAX
+CFLAGS += -DEAP_SAKE
+CFLAGS += -DEAP_GPSK -DEAP_GPSK_SHA256
+CFLAGS += -DEAP_TLS_FUNCS
+
+CFLAGS += -DIEEE8021X_EAPOL
+
+ifeq ($(CONFIG_TLS), openssl)
+CFLAGS += -DEAP_TLS_OPENSSL
+OBJS_both += ../src/crypto/tls_openssl.o
+OBJS_both += ../src/crypto/crypto_openssl.o
+LIBS += -lssl -lcrypto
+CFLAGS += -DINTERNAL_SHA256
+endif
+
+ifeq ($(CONFIG_TLS), internal)
+OBJS_both += ../src/crypto/tls_internal.o
+OBJS_both += ../src/tls/tlsv1_common.o ../src/tls/tlsv1_record.o
+OBJS_both += ../src/tls/tlsv1_cred.o
+OBJS_both += ../src/tls/asn1.o ../src/tls/x509v3.o
+OBJS_both += ../src/crypto/crypto_internal.o ../src/tls/rsa.o ../src/tls/bignum.o
+
+OBJS_peer += ../src/tls/tlsv1_client.o
+OBJS_peer += ../src/tls/tlsv1_client_write.o ../src/tls/tlsv1_client_read.o
+CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
+
+OBJS_server += ../src/tls/tlsv1_server.o
+OBJS_server += ../src/tls/tlsv1_server_write.o ../src/tls/tlsv1_server_read.o
+CFLAGS += -DCONFIG_TLS_INTERNAL_SERVER
+
+CFLAGS += -DCONFIG_TLS_INTERNAL
+CFLAGS += -DCONFIG_CRYPTO_INTERNAL
+CFLAGS += -DCONFIG_INTERNAL_X509
+CFLAGS += -DINTERNAL_AES
+CFLAGS += -DINTERNAL_SHA1
+CFLAGS += -DINTERNAL_SHA256
+CFLAGS += -DINTERNAL_MD5
+CFLAGS += -DINTERNAL_MD4
+CFLAGS += -DINTERNAL_DES
+ifdef CONFIG_INTERNAL_LIBTOMMATH
+CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
+else
+LIBS += -ltommath
+endif
+endif
+
+
+
+# Optional components to add EAP server support
+OBJS_server += ../src/eap_server/eap_tls.o
+OBJS_server += ../src/eap_server/eap_peap.o
+OBJS_server += ../src/eap_server/eap_ttls.o
+OBJS_server += ../src/eap_server/eap_md5.o
+OBJS_server += ../src/eap_server/eap_mschapv2.o
+OBJS_server += ../src/eap_server/eap_gtc.o
+OBJS_server += ../src/eap_server/eap_psk.o
+OBJS_server += ../src/eap_server/eap_tlv.o
+OBJS_server += ../src/eap_server/eap_pax.o
+OBJS_server += ../src/eap_server/eap_sake.o
+OBJS_server += ../src/eap_server/eap_gpsk.o
+OBJS_server += ../src/eap_server/eap.o
+OBJS_server += ../src/eap_server/eap_identity.o
+OBJS_server += ../src/eap_server/eap_methods.o
+OBJS_server += ../src/eap_server/eap_tls_common.o
+CFLAGS += -DEAP_SERVER
+
+
+ifndef LDO
+LDO=$(CC)
+endif
+
+
+OBJS_lib=$(OBJS_both) $(OBJS_peer) $(OBJS_server)
+
+OBJS_ex = eap_example.o eap_example_peer.o eap_example_server.o
+
+ifneq ($(CONFIG_SOLIB), yes)
+LIBEAP = libeap.a
+libeap.a: $(OBJS_lib)
+ ar rc libeap.a $(OBJS_lib)
+ ranlib libeap.a
+
+else
+CFLAGS += -fPIC -DPIC
+LDFLAGS += -shared
+
+LIBEAP = libeap.so
+libeap.so: $(OBJS_lib)
+ $(LDO) $(LDFLAGS) $(OBJS_lib) -o $(LIBEAP)
+
+endif
+
+eap_example: $(OBJS_ex) $(LIBEAP)
+ $(LDO) $(LDFLAGS) -o eap_example $(OBJS_ex) -L. -leap $(LIBS)
+
+clean:
+ $(MAKE) -C ../src clean
+ rm -f core *~ *.o *.d libeap.a libeap.so $(ALL)
+
+-include $(OBJS:%.o=%.d)
diff --git a/eap_example/README b/eap_example/README
new file mode 100644
index 0000000..b897ab5
--- /dev/null
+++ b/eap_example/README
@@ -0,0 +1,46 @@
+EAP peer/server library and example program
+Copyright (c) 2007, Jouni Malinen <j@w1.fi>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+Alternatively, this software may be distributed under the terms of BSD
+license.
+
+
+The interfaces of the EAP server/peer implementation are based on RFC
+4137 (EAP State Machines). This RFC is coordinated with the state
+machines defined in IEEE 802.1X-2004. hostapd and wpa_supplicant
+include implementation of the IEEE 802.1X EAPOL state machines and the
+interface between them and EAP. However, the EAP implementation can be
+used with other protocols, too, by providing a compatible interface
+which maps the EAPOL<->EAP variables to another protocol.
+
+This directory contains an example showing how EAP peer and server
+code from wpa_supplicant and hostapd can be used as a library. The
+example program initializes both an EAP server and an EAP peer
+entities and then runs through an EAP-PEAP/MSCHAPv2 authentication.
+
+eap_example_peer.c shows the initialization and glue code needed to
+control the EAP peer implementation. eap_example_server.c does the
+same for EAP server. eap_example.c is an example that ties in both the
+EAP server and client parts to allow an EAP authentication to be
+shown.
+
+In this example, the EAP messages are passed between the server and
+the peer are passed by direct function calls within the same process.
+In practice, server and peer functionalities would likely reside in
+separate devices and the EAP messages would be transmitted between the
+devices based on an external protocol. For example, in IEEE 802.11
+uses IEEE 802.1X EAPOL state machines to control the transmission of
+EAP messages and WiMax supports optional PMK EAP authentication
+mechanism that transmits EAP messages as defined in IEEE 802.16e.
+
+
+The EAP library links in number of helper functions from src/utils and
+src/crypto directories. Most of these are suitable as-is, but it may
+be desirable to replace the debug output code in src/utils/wpa_debug.c
+by dropping this file from the library and re-implementing the
+functions there in a way that better fits in with the main
+application.
diff --git a/eap_example/ca.pem b/eap_example/ca.pem
new file mode 100644
index 0000000..bfae1cc
--- /dev/null
+++ b/eap_example/ca.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDBzCCAnCgAwIBAgIJAIb4NS4TdLXUMA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQ4wDAYDVQQKEwV3MS5maTEQMA4G
+A1UEAxMHVGVzdCBDQTEbMBkGCSqGSIb3DQEJARYMdGVzdGNhQHcxLmZpMB4XDTA3
+MTIwOTAzMTQzN1oXDTE3MTIwNjAzMTQzN1owYTELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCkNhbGlmb3JuaWExDjAMBgNVBAoTBXcxLmZpMRAwDgYDVQQDEwdUZXN0IENB
+MRswGQYJKoZIhvcNAQkBFgx0ZXN0Y2FAdzEuZmkwgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBAO6GoecRclnILh9FTvqnY/yUZmeJDgC+3/PQiicpMDhAzCkWAmi+
+a1LSnqakNN/GdCy3q053TFLFEzhEHkhhRwY/zzj2vZIcFZESoUhr67CzCpcPmTGa
+AfOzsGPjaH6xYcaOR4RZMfXd/EKfAauHxj3LuCusLL5hK/FwxWhQJNJrAgMBAAGj
+gcYwgcMwHQYDVR0OBBYEFKhJuSLJ6JhcB/dRgB8j0h9mOlpKMIGTBgNVHSMEgYsw
+gYiAFKhJuSLJ6JhcB/dRgB8j0h9mOlpKoWWkYzBhMQswCQYDVQQGEwJVUzETMBEG
+A1UECBMKQ2FsaWZvcm5pYTEOMAwGA1UEChMFdzEuZmkxEDAOBgNVBAMTB1Rlc3Qg
+Q0ExGzAZBgkqhkiG9w0BCQEWDHRlc3RjYUB3MS5maYIJAIb4NS4TdLXUMAwGA1Ud
+EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAuU+5Uerq+n8WgiIsiANT3wUoGe2Y
+cnoQi2nVjUHrivgMDufH0tgh1AVfc3wVNNREdGC136qr1KBNqalQx2rKZ76xeNqW
+sQa2LIC2wE7Q7LJsltUcUjPyZHGUhBqWjKsCvlonfNB6JHkEayTEvVvyupgzTsxW
+QuuRdZ0sNv/S8VI=
+-----END CERTIFICATE-----
diff --git a/eap_example/eap_example.c b/eap_example/eap_example.c
new file mode 100644
index 0000000..b8917c8
--- /dev/null
+++ b/eap_example/eap_example.c
@@ -0,0 +1,55 @@
+/*
+ * Example application showing how EAP peer and server code from
+ * wpa_supplicant/hostapd can be used as a library. This example program
+ * initializes both an EAP server and an EAP peer entities and then runs
+ * through an EAP-PEAP/MSCHAPv2 authentication.
+ * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+
+
+int eap_example_peer_init(void);
+void eap_example_peer_deinit(void);
+int eap_example_peer_step(void);
+
+int eap_example_server_init(void);
+void eap_example_server_deinit(void);
+int eap_example_server_step(void);
+
+
+extern int wpa_debug_level;
+
+int main(int argc, char *argv[])
+{
+ int res_s, res_p;
+
+ wpa_debug_level = 0;
+
+ if (eap_example_peer_init() < 0 ||
+ eap_example_server_init() < 0)
+ return -1;
+
+ do {
+ printf("---[ server ]--------------------------------\n");
+ res_s = eap_example_server_step();
+ printf("---[ peer ]----------------------------------\n");
+ res_p = eap_example_peer_step();
+ } while (res_s || res_p);
+
+ eap_example_peer_deinit();
+ eap_example_server_deinit();
+
+ return 0;
+}
diff --git a/eap_example/eap_example_peer.c b/eap_example/eap_example_peer.c
new file mode 100644
index 0000000..c8b8415
--- /dev/null
+++ b/eap_example/eap_example_peer.c
@@ -0,0 +1,270 @@
+/*
+ * Example application showing how EAP peer code from wpa_supplicant can be
+ * used as a library.
+ * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eap_peer/eap.h"
+#include "eap_peer/eap_config.h"
+#include "wpabuf.h"
+
+void eap_example_server_rx(const u8 *data, size_t data_len);
+
+
+struct eap_peer_ctx {
+ Boolean eapSuccess;
+ Boolean eapRestart;
+ Boolean eapFail;
+ Boolean eapResp;
+ Boolean eapNoResp;
+ Boolean eapReq;
+ Boolean portEnabled;
+ Boolean altAccept; /* for EAP */
+ Boolean altReject; /* for EAP */
+
+ struct wpabuf *eapReqData; /* for EAP */
+
+ unsigned int idleWhile; /* for EAP state machine */
+
+ struct eap_peer_config eap_config;
+ struct eap_sm *eap;
+};
+
+
+static struct eap_peer_ctx eap_ctx;
+
+
+static struct eap_peer_config * peer_get_config(void *ctx)
+{
+ struct eap_peer_ctx *peer = ctx;
+ return &peer->eap_config;
+}
+
+
+static Boolean peer_get_bool(void *ctx, enum eapol_bool_var variable)
+{
+ struct eap_peer_ctx *peer = ctx;
+ if (peer == NULL)
+ return FALSE;
+ switch (variable) {
+ case EAPOL_eapSuccess:
+ return peer->eapSuccess;
+ case EAPOL_eapRestart:
+ return peer->eapRestart;
+ case EAPOL_eapFail:
+ return peer->eapFail;
+ case EAPOL_eapResp:
+ return peer->eapResp;
+ case EAPOL_eapNoResp:
+ return peer->eapNoResp;
+ case EAPOL_eapReq:
+ return peer->eapReq;
+ case EAPOL_portEnabled:
+ return peer->portEnabled;
+ case EAPOL_altAccept:
+ return peer->altAccept;
+ case EAPOL_altReject:
+ return peer->altReject;
+ }
+ return FALSE;
+}
+
+
+static void peer_set_bool(void *ctx, enum eapol_bool_var variable,
+ Boolean value)
+{
+ struct eap_peer_ctx *peer = ctx;
+ if (peer == NULL)
+ return;
+ switch (variable) {
+ case EAPOL_eapSuccess:
+ peer->eapSuccess = value;
+ break;
+ case EAPOL_eapRestart:
+ peer->eapRestart = value;
+ break;
+ case EAPOL_eapFail:
+ peer->eapFail = value;
+ break;
+ case EAPOL_eapResp:
+ peer->eapResp = value;
+ break;
+ case EAPOL_eapNoResp:
+ peer->eapNoResp = value;
+ break;
+ case EAPOL_eapReq:
+ peer->eapReq = value;
+ break;
+ case EAPOL_portEnabled:
+ peer->portEnabled = value;
+ break;
+ case EAPOL_altAccept:
+ peer->altAccept = value;
+ break;
+ case EAPOL_altReject:
+ peer->altReject = value;
+ break;
+ }
+}
+
+
+static unsigned int peer_get_int(void *ctx, enum eapol_int_var variable)
+{
+ struct eap_peer_ctx *peer = ctx;
+ if (peer == NULL)
+ return 0;
+ switch (variable) {
+ case EAPOL_idleWhile:
+ return peer->idleWhile;
+ }
+ return 0;
+}
+
+
+static void peer_set_int(void *ctx, enum eapol_int_var variable,
+ unsigned int value)
+{
+ struct eap_peer_ctx *peer = ctx;
+ if (peer == NULL)
+ return;
+ switch (variable) {
+ case EAPOL_idleWhile:
+ peer->idleWhile = value;
+ break;
+ }
+}
+
+
+static struct wpabuf * peer_get_eapReqData(void *ctx)
+{
+ struct eap_peer_ctx *peer = ctx;
+ if (peer == NULL || peer->eapReqData == NULL)
+ return NULL;
+
+ return peer->eapReqData;
+}
+
+
+static void peer_set_config_blob(void *ctx, struct wpa_config_blob *blob)
+{
+ printf("TODO: %s\n", __func__);
+}
+
+
+static const struct wpa_config_blob *
+peer_get_config_blob(void *ctx, const char *name)
+{
+ printf("TODO: %s\n", __func__);
+ return NULL;
+}
+
+
+static void peer_notify_pending(void *ctx)
+{
+ printf("TODO: %s\n", __func__);
+}
+
+
+static struct eapol_callbacks eap_cb;
+static struct eap_config eap_conf;
+
+int eap_example_peer_init(void)
+{
+ if (eap_peer_register_methods() < 0)
+ return -1;
+
+ os_memset(&eap_ctx, 0, sizeof(eap_ctx));
+
+ eap_ctx.eap_config.identity = (u8 *) os_strdup("user");
+ eap_ctx.eap_config.identity_len = 4;
+ eap_ctx.eap_config.password = (u8 *) os_strdup("password");
+ eap_ctx.eap_config.password_len = 8;
+ eap_ctx.eap_config.ca_cert = (u8 *) os_strdup("ca.pem");
+ eap_ctx.eap_config.fragment_size = 1398;
+
+ os_memset(&eap_cb, 0, sizeof(eap_cb));
+ eap_cb.get_config = peer_get_config;
+ eap_cb.get_bool = peer_get_bool;
+ eap_cb.set_bool = peer_set_bool;
+ eap_cb.get_int = peer_get_int;
+ eap_cb.set_int = peer_set_int;
+ eap_cb.get_eapReqData = peer_get_eapReqData;
+ eap_cb.set_config_blob = peer_set_config_blob;
+ eap_cb.get_config_blob = peer_get_config_blob;
+ eap_cb.notify_pending = peer_notify_pending;
+
+ os_memset(&eap_conf, 0, sizeof(eap_conf));
+ eap_ctx.eap = eap_peer_sm_init(&eap_ctx, &eap_cb, &eap_ctx, &eap_conf);
+ if (eap_ctx.eap == NULL)
+ return -1;
+
+ /* Enable "port" to allow authentication */
+ eap_ctx.portEnabled = TRUE;
+
+ return 0;
+}
+
+
+void eap_example_peer_deinit(void)
+{
+ eap_peer_sm_deinit(eap_ctx.eap);
+ eap_peer_unregister_methods();
+ wpabuf_free(eap_ctx.eapReqData);
+ os_free(eap_ctx.eap_config.identity);
+ os_free(eap_ctx.eap_config.password);
+ os_free(eap_ctx.eap_config.ca_cert);
+}
+
+
+int eap_example_peer_step(void)
+{
+ int res;
+ res = eap_peer_sm_step(eap_ctx.eap);
+
+ if (eap_ctx.eapResp) {
+ struct wpabuf *resp;
+ printf("==> Response\n");
+ eap_ctx.eapResp = FALSE;
+ resp = eap_get_eapRespData(eap_ctx.eap);
+ if (resp) {
+ /* Send EAP response to the server */
+ eap_example_server_rx(wpabuf_head(resp),
+ wpabuf_len(resp));
+ wpabuf_free(resp);
+ }
+ }
+
+ if (eap_ctx.eapSuccess) {
+ res = 0;
+ if (eap_key_available(eap_ctx.eap)) {
+ const u8 *key;
+ size_t key_len;
+ key = eap_get_eapKeyData(eap_ctx.eap, &key_len);
+ wpa_hexdump(MSG_DEBUG, "EAP keying material",
+ key, key_len);
+ }
+ }
+
+ return res;
+}
+
+
+void eap_example_peer_rx(const u8 *data, size_t data_len)
+{
+ /* Make received EAP message available to the EAP library */
+ eap_ctx.eapReq = TRUE;
+ wpabuf_free(eap_ctx.eapReqData);
+ eap_ctx.eapReqData = wpabuf_alloc_copy(data, data_len);
+}
diff --git a/eap_example/eap_example_server.c b/eap_example/eap_example_server.c
new file mode 100644
index 0000000..897aa26
--- /dev/null
+++ b/eap_example/eap_example_server.c
@@ -0,0 +1,192 @@
+/*
+ * Example application showing how EAP server code from hostapd can be used as
+ * a library.
+ * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eap_server/eap.h"
+#include "tls.h"
+#include "wpabuf.h"
+
+void eap_example_peer_rx(const u8 *data, size_t data_len);
+
+
+struct eap_server_ctx {
+ struct eap_eapol_interface *eap_if;
+ struct eap_sm *eap;
+ void *tls_ctx;
+};
+
+static struct eap_server_ctx eap_ctx;
+
+
+static int server_get_eap_user(void *ctx, const u8 *identity,
+ size_t identity_len, int phase2,
+ struct eap_user *user)
+{
+ os_memset(user, 0, sizeof(*user));
+
+ if (!phase2) {
+ /* Only allow EAP-PEAP as the Phase 1 method */
+ user->methods[0].vendor = EAP_VENDOR_IETF;
+ user->methods[0].method = EAP_TYPE_PEAP;
+ return 0;
+ }
+
+ if (identity_len != 4 || identity == NULL ||
+ os_memcmp(identity, "user", 4) != 0) {
+ printf("Unknown user\n");
+ return -1;
+ }
+
+ /* Only allow EAP-MSCHAPv2 as the Phase 2 method */
+ user->methods[0].vendor = EAP_VENDOR_IETF;
+ user->methods[0].method = EAP_TYPE_MSCHAPV2;
+ user->password = (u8 *) os_strdup("password");
+ user->password_len = 8;
+
+ return 0;
+}
+
+
+static const char * server_get_eap_req_id_text(void *ctx, size_t *len)
+{
+ *len = 0;
+ return NULL;
+}
+
+
+static struct eapol_callbacks eap_cb;
+static struct eap_config eap_conf;
+
+static int eap_example_server_init_tls(void)
+{
+ struct tls_config tconf;
+ struct tls_connection_params tparams;
+
+ os_memset(&tconf, 0, sizeof(tconf));
+ eap_ctx.tls_ctx = tls_init(&tconf);
+ if (eap_ctx.tls_ctx == NULL)
+ return -1;
+
+ os_memset(&tparams, 0, sizeof(tparams));
+ tparams.ca_cert = "ca.pem";
+ tparams.client_cert = "server.pem";
+ tparams.private_key = "server.key";
+ tparams.private_key_passwd = "whatever";
+
+ if (tls_global_set_params(eap_ctx.tls_ctx, &tparams)) {
+ printf("Failed to set TLS parameters\n");
+ return -1;
+ }
+
+ if (tls_global_set_verify(eap_ctx.tls_ctx, 0)) {
+ printf("Failed to set check_crl\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int eap_example_server_init(void)
+{
+ if (eap_server_register_methods() < 0)
+ return -1;
+
+ os_memset(&eap_ctx, 0, sizeof(eap_ctx));
+
+ if (eap_example_server_init_tls() < 0)
+ return -1;
+
+ os_memset(&eap_cb, 0, sizeof(eap_cb));
+ eap_cb.get_eap_user = server_get_eap_user;
+ eap_cb.get_eap_req_id_text = server_get_eap_req_id_text;
+
+ os_memset(&eap_conf, 0, sizeof(eap_conf));
+ eap_conf.eap_server = 1;
+ eap_conf.ssl_ctx = eap_ctx.tls_ctx;
+
+ eap_ctx.eap = eap_server_sm_init(&eap_ctx, &eap_cb, &eap_conf);
+ if (eap_ctx.eap == NULL)
+ return -1;
+
+ eap_ctx.eap_if = eap_get_interface(eap_ctx.eap);
+
+ /* Enable "port" and request EAP to start authentication. */
+ eap_ctx.eap_if->portEnabled = TRUE;
+ eap_ctx.eap_if->eapRestart = TRUE;
+
+ return 0;
+}
+
+
+void eap_example_server_deinit(void)
+{
+ eap_server_sm_deinit(eap_ctx.eap);
+ eap_server_unregister_methods();
+ tls_deinit(eap_ctx.tls_ctx);
+}
+
+
+int eap_example_server_step(void)
+{
+ int res, process = 0;
+
+ res = eap_server_sm_step(eap_ctx.eap);
+
+ if (eap_ctx.eap_if->eapReq) {
+ printf("==> Request\n");
+ process = 1;
+ eap_ctx.eap_if->eapReq = 0;
+ }
+
+ if (eap_ctx.eap_if->eapSuccess) {
+ printf("==> Success\n");
+ process = 1;
+ res = 0;
+ eap_ctx.eap_if->eapSuccess = 0;
+
+ if (eap_ctx.eap_if->eapKeyAvailable) {
+ wpa_hexdump(MSG_DEBUG, "EAP keying material",
+ eap_ctx.eap_if->eapKeyData,
+ eap_ctx.eap_if->eapKeyDataLen);
+ }
+ }
+
+ if (eap_ctx.eap_if->eapFail) {
+ printf("==> Fail\n");
+ process = 1;
+ eap_ctx.eap_if->eapFail = 0;
+ }
+
+ if (process && eap_ctx.eap_if->eapReqData) {
+ /* Send EAP response to the server */
+ eap_example_peer_rx(wpabuf_head(eap_ctx.eap_if->eapReqData),
+ wpabuf_len(eap_ctx.eap_if->eapReqData));
+ }
+
+ return res;
+}
+
+
+void eap_example_server_rx(const u8 *data, size_t data_len)
+{
+ /* Make received EAP message available to the EAP library */
+ wpabuf_free(eap_ctx.eap_if->eapRespData);
+ eap_ctx.eap_if->eapRespData = wpabuf_alloc_copy(data, data_len);
+ if (eap_ctx.eap_if->eapRespData)
+ eap_ctx.eap_if->eapResp = TRUE;
+}
diff --git a/eap_example/server.key b/eap_example/server.key
new file mode 100644
index 0000000..4f32591
--- /dev/null
+++ b/eap_example/server.key
Binary files differ
diff --git a/eap_example/server.pem b/eap_example/server.pem
new file mode 100644
index 0000000..02f6e7b
--- /dev/null
+++ b/eap_example/server.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC0zCCAjygAwIBAgIJAIb4NS4TdLXVMA0GCSqGSIb3DQEBBQUAMGExCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMQ4wDAYDVQQKEwV3MS5maTEQMA4G
+A1UEAxMHVGVzdCBDQTEbMBkGCSqGSIb3DQEJARYMdGVzdGNhQHcxLmZpMB4XDTA3
+MTIwOTAzMTUwOFoXDTE3MTIwNjAzMTUwOFoweTELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xDjAMBgNVBAoT
+BXcxLmZpMRAwDgYDVQQDEwdUZXN0IEFTMRswGQYJKoZIhvcNAQkBFgx0ZXN0YXNA
+dzEuZmkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOhi4M+aMRa778CPRFV
+ZNJvTuxfp0CQ+etNpSNkAbkCGNGolbPMPnSQWZUqL5HsaBLm2UbMtS2iR3CO5JQC
+bPy0xfAjCZV5LQeW4UNVKL3hdtVFzMT6fKgOKCDVEbLLWZze3lEbzhu81q2r3w5x
+4lqDieCHwvwjiTWpMtEyXIEnAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4
+QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRb
+xGTC3mPimgyGb5vYLLV5wyc9ITAfBgNVHSMEGDAWgBSoSbkiyeiYXAf3UYAfI9If
+ZjpaSjANBgkqhkiG9w0BAQUFAAOBgQA9wVGtroz/rsx1EeALJejW01SAr4kpTxoS
+WP6zuWFb+J/lJd7DeVM6/QBYAwZb0fB6nwSpJJCj6XDRZtN/yLeaTd/rCZrfom4Z
+8gbkWMTXDn2Cea2VnCe5W0gK+4dIj5DD5CpPvgt4lYqlwN0WAih6twd7Q4x/tiiJ
+ejNQzlTHOg==
+-----END CERTIFICATE-----