Pass full struct to peer certificate callbacks

This makes it easier to add new information to the callbacks without
having to modify each callback function type in EAPOL and EAP code every
time.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2019-06-11 04:20:18 +03:00
parent 82b9de98c3
commit bc0634da4a
9 changed files with 64 additions and 77 deletions

View file

@ -48,6 +48,17 @@ enum tls_fail_reason {
#define TLS_MAX_ALT_SUBJECT 10 #define TLS_MAX_ALT_SUBJECT 10
struct tls_cert_data {
int depth;
const char *subject;
const struct wpabuf *cert;
const u8 *hash;
size_t hash_len;
const char *altsubject[TLS_MAX_ALT_SUBJECT];
int num_altsubject;
const char *serial_num;
};
union tls_event_data { union tls_event_data {
struct { struct {
int depth; int depth;
@ -57,16 +68,7 @@ union tls_event_data {
const struct wpabuf *cert; const struct wpabuf *cert;
} cert_fail; } cert_fail;
struct { struct tls_cert_data peer_cert;
int depth;
const char *subject;
const struct wpabuf *cert;
const u8 *hash;
size_t hash_len;
const char *altsubject[TLS_MAX_ALT_SUBJECT];
int num_altsubject;
const char *serial_num;
} peer_cert;
struct { struct {
int is_local; int is_local;

View file

@ -2097,12 +2097,8 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
} }
} }
sm->eapol_cb->notify_cert(sm->eapol_ctx, sm->eapol_cb->notify_cert(sm->eapol_ctx, &data->peer_cert,
data->peer_cert.depth, hash_hex);
data->peer_cert.subject,
data->peer_cert.altsubject,
data->peer_cert.num_altsubject,
hash_hex, data->peer_cert.cert);
break; break;
case TLS_ALERT: case TLS_ALERT:
if (data->alert.is_local) if (data->alert.is_local)

View file

@ -16,6 +16,7 @@
struct eap_sm; struct eap_sm;
struct wpa_config_blob; struct wpa_config_blob;
struct wpabuf; struct wpabuf;
struct tls_cert_data;
struct eap_method_type { struct eap_method_type {
int vendor; int vendor;
@ -226,16 +227,11 @@ struct eapol_callbacks {
/** /**
* notify_cert - Notification of a peer certificate * notify_cert - Notification of a peer certificate
* @ctx: eapol_ctx from eap_peer_sm_init() call * @ctx: eapol_ctx from eap_peer_sm_init() call
* @depth: Depth in certificate chain (0 = server) * @cert: Certificate information
* @subject: Subject of the peer certificate
* @altsubject: Select fields from AltSubject of the peer certificate
* @num_altsubject: Number of altsubject values
* @cert_hash: SHA-256 hash of the certificate * @cert_hash: SHA-256 hash of the certificate
* @cert: Peer certificate
*/ */
void (*notify_cert)(void *ctx, int depth, const char *subject, void (*notify_cert)(void *ctx, struct tls_cert_data *cert,
const char *altsubject[], int num_altsubject, const char *cert_hash);
const char *cert_hash, const struct wpabuf *cert);
/** /**
* notify_status - Notification of the current EAP state * notify_status - Notification of the current EAP state

View file

@ -1998,15 +1998,12 @@ static void eapol_sm_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field,
#define eapol_sm_eap_param_needed NULL #define eapol_sm_eap_param_needed NULL
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
static void eapol_sm_notify_cert(void *ctx, int depth, const char *subject, static void eapol_sm_notify_cert(void *ctx, struct tls_cert_data *cert,
const char *altsubject[], const char *cert_hash)
int num_altsubject, const char *cert_hash,
const struct wpabuf *cert)
{ {
struct eapol_sm *sm = ctx; struct eapol_sm *sm = ctx;
if (sm->ctx->cert_cb) if (sm->ctx->cert_cb)
sm->ctx->cert_cb(sm->ctx->ctx, depth, subject, altsubject, sm->ctx->cert_cb(sm->ctx->ctx, cert, cert_hash);
num_altsubject, cert_hash, cert);
} }

View file

@ -11,6 +11,8 @@
#include "common/defs.h" #include "common/defs.h"
struct tls_cert_data;
typedef enum { Unauthorized, Authorized } PortStatus; typedef enum { Unauthorized, Authorized } PortStatus;
typedef enum { Auto, ForceUnauthorized, ForceAuthorized } PortControl; typedef enum { Auto, ForceUnauthorized, ForceAuthorized } PortControl;
@ -246,16 +248,11 @@ struct eapol_ctx {
/** /**
* cert_cb - Notification of a peer certificate * cert_cb - Notification of a peer certificate
* @ctx: Callback context (ctx) * @ctx: Callback context (ctx)
* @depth: Depth in certificate chain (0 = server) * @cert: Certificate information
* @subject: Subject of the peer certificate
* @altsubject: Select fields from AltSubject of the peer certificate
* @num_altsubject: Number of altsubject values
* @cert_hash: SHA-256 hash of the certificate * @cert_hash: SHA-256 hash of the certificate
* @cert: Peer certificate
*/ */
void (*cert_cb)(void *ctx, int depth, const char *subject, void (*cert_cb)(void *ctx, struct tls_cert_data *cert,
const char *altsubject[], int num_altsubject, const char *cert_hash);
const char *cert_hash, const struct wpabuf *cert);
/** /**
* cert_in_cb - Include server certificates in callback * cert_in_cb - Include server certificates in callback

View file

@ -15,6 +15,7 @@
#include "common.h" #include "common.h"
#include "utils/ext_password.h" #include "utils/ext_password.h"
#include "common/version.h" #include "common/version.h"
#include "crypto/tls.h"
#include "config.h" #include "config.h"
#include "eapol_supp/eapol_supp_sm.h" #include "eapol_supp/eapol_supp_sm.h"
#include "eap_peer/eap.h" #include "eap_peer/eap.h"
@ -497,44 +498,43 @@ static void eapol_test_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field,
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
static void eapol_test_cert_cb(void *ctx, int depth, const char *subject, static void eapol_test_cert_cb(void *ctx, struct tls_cert_data *cert,
const char *altsubject[], int num_altsubject, const char *cert_hash)
const char *cert_hash,
const struct wpabuf *cert)
{ {
struct eapol_test_data *e = ctx; struct eapol_test_data *e = ctx;
wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
"depth=%d subject='%s'%s%s", "depth=%d subject='%s'%s%s",
depth, subject, cert->depth, cert->subject,
cert_hash ? " hash=" : "", cert_hash ? " hash=" : "",
cert_hash ? cert_hash : ""); cert_hash ? cert_hash : "");
if (cert) { if (cert->cert) {
char *cert_hex; char *cert_hex;
size_t len = wpabuf_len(cert) * 2 + 1; size_t len = wpabuf_len(cert->cert) * 2 + 1;
cert_hex = os_malloc(len); cert_hex = os_malloc(len);
if (cert_hex) { if (cert_hex) {
wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert->cert),
wpabuf_len(cert)); wpabuf_len(cert->cert));
wpa_msg_ctrl(e->wpa_s, MSG_INFO, wpa_msg_ctrl(e->wpa_s, MSG_INFO,
WPA_EVENT_EAP_PEER_CERT WPA_EVENT_EAP_PEER_CERT
"depth=%d subject='%s' cert=%s", "depth=%d subject='%s' cert=%s",
depth, subject, cert_hex); cert->depth, cert->subject, cert_hex);
os_free(cert_hex); os_free(cert_hex);
} }
if (e->server_cert_file) if (e->server_cert_file)
eapol_test_write_cert(e->server_cert_file, eapol_test_write_cert(e->server_cert_file,
subject, cert); cert->subject, cert->cert);
} }
if (altsubject) { if (cert->altsubject) {
int i; int i;
for (i = 0; i < num_altsubject; i++) for (i = 0; i < cert->num_altsubject; i++)
wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT wpa_msg(e->wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
"depth=%d %s", depth, altsubject[i]); "depth=%d %s", cert->depth,
cert->altsubject[i]);
} }
} }

View file

@ -18,6 +18,7 @@
#include "dbus/dbus_new.h" #include "dbus/dbus_new.h"
#include "rsn_supp/wpa.h" #include "rsn_supp/wpa.h"
#include "fst/fst.h" #include "fst/fst.h"
#include "crypto/tls.h"
#include "driver_i.h" #include "driver_i.h"
#include "scan.h" #include "scan.h"
#include "p2p_supplicant.h" #include "p2p_supplicant.h"
@ -786,42 +787,43 @@ void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
} }
void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth, void wpas_notify_certification(struct wpa_supplicant *wpa_s,
const char *subject, const char *altsubject[], struct tls_cert_data *cert,
int num_altsubject, const char *cert_hash, const char *cert_hash)
const struct wpabuf *cert)
{ {
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_CERT
"depth=%d subject='%s'%s%s", "depth=%d subject='%s'%s%s",
depth, subject, cert_hash ? " hash=" : "", cert->depth, cert->subject, cert_hash ? " hash=" : "",
cert_hash ? cert_hash : ""); cert_hash ? cert_hash : "");
if (cert) { if (cert->cert) {
char *cert_hex; char *cert_hex;
size_t len = wpabuf_len(cert) * 2 + 1; size_t len = wpabuf_len(cert->cert) * 2 + 1;
cert_hex = os_malloc(len); cert_hex = os_malloc(len);
if (cert_hex) { if (cert_hex) {
wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert), wpa_snprintf_hex(cert_hex, len, wpabuf_head(cert->cert),
wpabuf_len(cert)); wpabuf_len(cert->cert));
wpa_msg_ctrl(wpa_s, MSG_INFO, wpa_msg_ctrl(wpa_s, MSG_INFO,
WPA_EVENT_EAP_PEER_CERT WPA_EVENT_EAP_PEER_CERT
"depth=%d subject='%s' cert=%s", "depth=%d subject='%s' cert=%s",
depth, subject, cert_hex); cert->depth, cert->subject, cert_hex);
os_free(cert_hex); os_free(cert_hex);
} }
} }
if (altsubject) { if (cert->altsubject) {
int i; int i;
for (i = 0; i < num_altsubject; i++) for (i = 0; i < cert->num_altsubject; i++)
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
"depth=%d %s", depth, altsubject[i]); "depth=%d %s", cert->depth,
cert->altsubject[i]);
} }
/* notify the new DBus API */ /* notify the new DBus API */
wpas_dbus_signal_certification(wpa_s, depth, subject, altsubject, wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
num_altsubject, cert_hash, cert); cert->altsubject, cert->num_altsubject,
cert_hash, cert->cert);
} }

View file

@ -14,6 +14,7 @@
struct wps_credential; struct wps_credential;
struct wps_event_m2d; struct wps_event_m2d;
struct wps_event_fail; struct wps_event_fail;
struct tls_cert_data;
int wpas_notify_supplicant_initialized(struct wpa_global *global); int wpas_notify_supplicant_initialized(struct wpa_global *global);
void wpas_notify_supplicant_deinitialized(struct wpa_global *global); void wpas_notify_supplicant_deinitialized(struct wpa_global *global);
@ -130,10 +131,9 @@ void wpas_notify_persistent_group_removed(struct wpa_supplicant *wpa_s,
void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s, void wpas_notify_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail); struct wps_event_fail *fail);
void wpas_notify_certification(struct wpa_supplicant *wpa_s, int depth, void wpas_notify_certification(struct wpa_supplicant *wpa_s,
const char *subject, const char *altsubject[], struct tls_cert_data *cert,
int num_altsubject, const char *cert_hash, const char *cert_hash);
const struct wpabuf *cert);
void wpas_notify_preq(struct wpa_supplicant *wpa_s, void wpas_notify_preq(struct wpa_supplicant *wpa_s,
const u8 *addr, const u8 *dst, const u8 *bssid, const u8 *addr, const u8 *dst, const u8 *bssid,
const u8 *ie, size_t ie_len, u32 ssi_signal); const u8 *ie, size_t ie_len, u32 ssi_signal);

View file

@ -1017,15 +1017,12 @@ static void wpa_supplicant_port_cb(void *ctx, int authorized)
} }
static void wpa_supplicant_cert_cb(void *ctx, int depth, const char *subject, static void wpa_supplicant_cert_cb(void *ctx, struct tls_cert_data *cert,
const char *altsubject[], int num_altsubject, const char *cert_hash)
const char *cert_hash,
const struct wpabuf *cert)
{ {
struct wpa_supplicant *wpa_s = ctx; struct wpa_supplicant *wpa_s = ctx;
wpas_notify_certification(wpa_s, depth, subject, altsubject, wpas_notify_certification(wpa_s, cert, cert_hash);
num_altsubject, cert_hash, cert);
} }