From 1b414f59fc46b8c88e606de122debf69e8b5faa8 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 17 Sep 2011 22:42:54 +0300 Subject: [PATCH] eapol_test: Add option for writing server certificate chain to a file eapol_test command line argument -o can now be used to request the received server certificate chain to be written to the specified file. The certificates will be written in PEM format. [Bug 391] --- src/crypto/tls.h | 1 + src/crypto/tls_openssl.c | 4 ++- src/eap_peer/eap.c | 1 + src/eap_peer/eap.h | 5 ++++ src/eapol_supp/eapol_supp_sm.c | 1 + src/eapol_supp/eapol_supp_sm.h | 5 ++++ wpa_supplicant/eapol_test.c | 52 ++++++++++++++++++++++++++++------ 7 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/crypto/tls.h b/src/crypto/tls.h index 0928b5ba4..b5cac1cfb 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -72,6 +72,7 @@ struct tls_config { const char *pkcs11_engine_path; const char *pkcs11_module_path; int fips_mode; + int cert_in_cb; void (*event_cb)(void *ctx, enum tls_event ev, union tls_event_data *data); diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 14ff87e26..a8df6aa07 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -59,6 +59,7 @@ struct tls_global { void (*event_cb)(void *ctx, enum tls_event ev, union tls_event_data *data); void *cb_ctx; + int cert_in_cb; }; static struct tls_global *tls_global = NULL; @@ -694,6 +695,7 @@ void * tls_init(const struct tls_config *conf) if (conf) { tls_global->event_cb = conf->event_cb; tls_global->cb_ctx = conf->cb_ctx; + tls_global->cert_in_cb = conf->cert_in_cb; } #ifdef CONFIG_FIPS @@ -1144,7 +1146,7 @@ static void openssl_tls_cert_event(struct tls_connection *conn, return; os_memset(&ev, 0, sizeof(ev)); - if (conn->cert_probe) { + if (conn->cert_probe || tls_global->cert_in_cb) { cert = get_x509_cert(err_cert); ev.peer_cert.cert = cert; } diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index ecfaf3096..39513d6a7 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -1242,6 +1242,7 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx, #endif /* CONFIG_FIPS */ tlsconf.event_cb = eap_peer_sm_tls_event; tlsconf.cb_ctx = sm; + tlsconf.cert_in_cb = conf->cert_in_cb; sm->ssl_ctx = tls_init(&tlsconf); if (sm->ssl_ctx == NULL) { wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS " diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h index 2a80d4e74..15e451e8a 100644 --- a/src/eap_peer/eap.h +++ b/src/eap_peer/eap.h @@ -262,6 +262,11 @@ struct eap_config { * This is only used by EAP-WSC and can be left %NULL if not available. */ struct wps_context *wps; + + /** + * cert_in_cb - Include server certificates in callback + */ + int cert_in_cb; }; struct eap_sm * eap_peer_sm_init(void *eapol_ctx, diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c index bb6cff604..c4a0d8a3d 100644 --- a/src/eapol_supp/eapol_supp_sm.c +++ b/src/eapol_supp/eapol_supp_sm.c @@ -1883,6 +1883,7 @@ struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) conf.pkcs11_engine_path = ctx->pkcs11_engine_path; conf.pkcs11_module_path = ctx->pkcs11_module_path; conf.wps = ctx->wps; + conf.cert_in_cb = ctx->cert_in_cb; sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf); if (sm->eap == NULL) { diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h index 3ea7e7993..48813a994 100644 --- a/src/eapol_supp/eapol_supp_sm.h +++ b/src/eapol_supp/eapol_supp_sm.h @@ -231,6 +231,11 @@ struct eapol_ctx { */ void (*cert_cb)(void *ctx, int depth, const char *subject, const char *cert_hash, const struct wpabuf *cert); + + /** + * cert_in_cb - Include server certificates in callback + */ + int cert_in_cb; }; diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c index 332a044ae..76f7527c5 100644 --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c @@ -24,6 +24,7 @@ #include "eap_peer/eap.h" #include "eap_server/eap_methods.h" #include "eloop.h" +#include "utils/base64.h" #include "rsn_supp/wpa.h" #include "eap_peer/eap_i.h" #include "wpa_supplicant_i.h" @@ -76,6 +77,8 @@ struct eapol_test_data { char *connect_info; u8 own_addr[ETH_ALEN]; struct extra_radius_attr *extra_attrs; + + FILE *server_cert_file; }; static struct eapol_test_data eapol_test; @@ -292,7 +295,6 @@ static void ieee802_1x_encapsulate_radius(struct eapol_test_data *e, static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, size_t len) { - /* struct wpa_supplicant *wpa_s = ctx; */ printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n", type, (unsigned long) len); if (type == IEEE802_1X_TYPE_EAP_PACKET) { @@ -306,16 +308,16 @@ static int eapol_test_eapol_send(void *ctx, int type, const u8 *buf, static void eapol_test_set_config_blob(void *ctx, struct wpa_config_blob *blob) { - struct wpa_supplicant *wpa_s = ctx; - wpa_config_set_blob(wpa_s->conf, blob); + struct eapol_test_data *e = ctx; + wpa_config_set_blob(e->wpa_s->conf, blob); } static const struct wpa_config_blob * eapol_test_get_config_blob(void *ctx, const char *name) { - struct wpa_supplicant *wpa_s = ctx; - return wpa_config_get_blob(wpa_s->conf, name); + struct eapol_test_data *e = ctx; + return wpa_config_get_blob(e->wpa_s->conf, name); } @@ -384,6 +386,20 @@ static void eapol_sm_cb(struct eapol_sm *eapol, int success, void *ctx) } +static void eapol_test_write_cert(FILE *f, const char *subject, + const struct wpabuf *cert) +{ + unsigned char *encoded; + + encoded = base64_encode(wpabuf_head(cert), wpabuf_len(cert), NULL); + if (encoded == NULL) + return; + fprintf(f, "%s\n-----BEGIN CERTIFICATE-----\n%s" + "-----END CERTIFICATE-----\n\n", subject, encoded); + os_free(encoded); +} + + static void eapol_test_cert_cb(void *ctx, int depth, const char *subject, const char *cert_hash, const struct wpabuf *cert) @@ -409,6 +425,10 @@ static void eapol_test_cert_cb(void *ctx, int depth, const char *subject, depth, subject, cert_hex); os_free(cert_hex); } + + if (e->server_cert_file) + eapol_test_write_cert(e->server_cert_file, + subject, cert); } } @@ -424,7 +444,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, printf("Failed to allocate EAPOL context.\n"); return -1; } - ctx->ctx = wpa_s; + ctx->ctx = e; ctx->msg_ctx = wpa_s; ctx->scard_ctx = wpa_s->scard; ctx->cb = eapol_sm_cb; @@ -439,6 +459,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; ctx->cert_cb = eapol_test_cert_cb; + ctx->cert_in_cb = 1; wpa_s->eapol = eapol_sm_init(ctx); if (wpa_s->eapol == NULL) { @@ -995,7 +1016,7 @@ static void usage(void) "eapol_test [-nWS] -c [-a] [-p] " "[-s]\\\n" " [-r] [-t] [-C] \\\n" - " [-M] \\\n" + " [-M] [-o] \\\n" " [-A]\n" "eapol_test scard\n" @@ -1021,6 +1042,8 @@ static void usage(void) " -M = Set own MAC address " "(Calling-Station-Id,\n" " default: 02:00:00:00:00:01)\n" + " -o = Write received server certificate\n" + " chain to the specified file\n" " -N = send arbitrary attribute specified by:\n" " attr_id:syntax:value or attr_id\n" " attr_id - number id of the attribute\n" @@ -1062,7 +1085,7 @@ int main(int argc, char *argv[]) wpa_debug_show_keys = 1; for (;;) { - c = getopt(argc, argv, "a:A:c:C:M:nN:p:r:s:St:W"); + c = getopt(argc, argv, "a:A:c:C:M:nN:o:p:r:s:St:W"); if (c < 0) break; switch (c) { @@ -1087,6 +1110,16 @@ int main(int argc, char *argv[]) case 'n': eapol_test.no_mppe_keys++; break; + case 'o': + if (eapol_test.server_cert_file) + fclose(eapol_test.server_cert_file); + eapol_test.server_cert_file = fopen(optarg, "w"); + if (eapol_test.server_cert_file == NULL) { + printf("Could not open '%s' for writing\n", + optarg); + return -1; + } + break; case 'p': as_port = atoi(optarg); break; @@ -1229,6 +1262,9 @@ int main(int argc, char *argv[]) eloop_destroy(); + if (eapol_test.server_cert_file) + fclose(eapol_test.server_cert_file); + printf("MPPE keys OK: %d mismatch: %d\n", eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); if (eapol_test.num_mppe_mismatch)