@ -28,34 +28,6 @@ static int hostapd_dpp_auth_init_next(struct hostapd_data *hapd);
static const u8 broadcast [ ETH_ALEN ] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff } ;
static struct dpp_configurator *
hostapd_dpp_configurator_get_id ( struct hostapd_data * hapd , unsigned int id )
{
struct dpp_configurator * conf ;
dl_list_for_each ( conf , & hapd - > iface - > interfaces - > dpp_configurator ,
struct dpp_configurator , list ) {
if ( conf - > id = = id )
return conf ;
}
return NULL ;
}
static unsigned int hapd_dpp_next_id ( struct hostapd_data * hapd )
{
struct dpp_bootstrap_info * bi ;
unsigned int max_id = 0 ;
dl_list_for_each ( bi , & hapd - > iface - > interfaces - > dpp_bootstrap ,
struct dpp_bootstrap_info , list ) {
if ( bi - > id > max_id )
max_id = bi - > id ;
}
return max_id + 1 ;
}
/**
* hostapd_dpp_qr_code - Parse and add DPP bootstrapping info from a QR Code
* @ hapd : Pointer to hostapd_data
@ -67,13 +39,10 @@ int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
struct dpp_bootstrap_info * bi ;
struct dpp_authentication * auth = hapd - > dpp_auth ;
bi = dpp_ parse_qr_code( cmd ) ;
bi = dpp_ add_qr_code( hapd - > iface - > interfaces - > dpp , cmd ) ;
if ( ! bi )
return - 1 ;
bi - > id = hapd_dpp_next_id ( hapd ) ;
dl_list_add ( & hapd - > iface - > interfaces - > dpp_bootstrap , & bi - > list ) ;
if ( auth & & auth - > response_pending & &
dpp_notify_new_qr_code ( auth , bi ) = = 1 ) {
wpa_printf ( MSG_DEBUG ,
@ -92,195 +61,6 @@ int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
}
static char * get_param ( const char * cmd , const char * param )
{
const char * pos , * end ;
char * val ;
size_t len ;
pos = os_strstr ( cmd , param ) ;
if ( ! pos )
return NULL ;
pos + = os_strlen ( param ) ;
end = os_strchr ( pos , ' ' ) ;
if ( end )
len = end - pos ;
else
len = os_strlen ( pos ) ;
val = os_malloc ( len + 1 ) ;
if ( ! val )
return NULL ;
os_memcpy ( val , pos , len ) ;
val [ len ] = ' \0 ' ;
return val ;
}
int hostapd_dpp_bootstrap_gen ( struct hostapd_data * hapd , const char * cmd )
{
char * chan = NULL , * mac = NULL , * info = NULL , * pk = NULL , * curve = NULL ;
char * key = NULL ;
u8 * privkey = NULL ;
size_t privkey_len = 0 ;
size_t len ;
int ret = - 1 ;
struct dpp_bootstrap_info * bi ;
bi = os_zalloc ( sizeof ( * bi ) ) ;
if ( ! bi )
goto fail ;
if ( os_strstr ( cmd , " type=qrcode " ) )
bi - > type = DPP_BOOTSTRAP_QR_CODE ;
else if ( os_strstr ( cmd , " type=pkex " ) )
bi - > type = DPP_BOOTSTRAP_PKEX ;
else
goto fail ;
chan = get_param ( cmd , " chan= " ) ;
mac = get_param ( cmd , " mac= " ) ;
info = get_param ( cmd , " info= " ) ;
curve = get_param ( cmd , " curve= " ) ;
key = get_param ( cmd , " key= " ) ;
if ( key ) {
privkey_len = os_strlen ( key ) / 2 ;
privkey = os_malloc ( privkey_len ) ;
if ( ! privkey | |
hexstr2bin ( key , privkey , privkey_len ) < 0 )
goto fail ;
}
pk = dpp_keygen ( bi , curve , privkey , privkey_len ) ;
if ( ! pk )
goto fail ;
len = 4 ; /* "DPP:" */
if ( chan ) {
if ( dpp_parse_uri_chan_list ( bi , chan ) < 0 )
goto fail ;
len + = 3 + os_strlen ( chan ) ; /* C:...; */
}
if ( mac ) {
if ( dpp_parse_uri_mac ( bi , mac ) < 0 )
goto fail ;
len + = 3 + os_strlen ( mac ) ; /* M:...; */
}
if ( info ) {
if ( dpp_parse_uri_info ( bi , info ) < 0 )
goto fail ;
len + = 3 + os_strlen ( info ) ; /* I:...; */
}
len + = 4 + os_strlen ( pk ) ;
bi - > uri = os_malloc ( len + 1 ) ;
if ( ! bi - > uri )
goto fail ;
os_snprintf ( bi - > uri , len + 1 , " DPP:%s%s%s%s%s%s%s%s%sK:%s;; " ,
chan ? " C: " : " " , chan ? chan : " " , chan ? " ; " : " " ,
mac ? " M: " : " " , mac ? mac : " " , mac ? " ; " : " " ,
info ? " I: " : " " , info ? info : " " , info ? " ; " : " " ,
pk ) ;
bi - > id = hapd_dpp_next_id ( hapd ) ;
dl_list_add ( & hapd - > iface - > interfaces - > dpp_bootstrap , & bi - > list ) ;
ret = bi - > id ;
bi = NULL ;
fail :
os_free ( curve ) ;
os_free ( pk ) ;
os_free ( chan ) ;
os_free ( mac ) ;
os_free ( info ) ;
str_clear_free ( key ) ;
bin_clear_free ( privkey , privkey_len ) ;
dpp_bootstrap_info_free ( bi ) ;
return ret ;
}
static struct dpp_bootstrap_info *
dpp_bootstrap_get_id ( struct hostapd_data * hapd , unsigned int id )
{
struct dpp_bootstrap_info * bi ;
dl_list_for_each ( bi , & hapd - > iface - > interfaces - > dpp_bootstrap ,
struct dpp_bootstrap_info , list ) {
if ( bi - > id = = id )
return bi ;
}
return NULL ;
}
static int dpp_bootstrap_del ( struct hapd_interfaces * ifaces , unsigned int id )
{
struct dpp_bootstrap_info * bi , * tmp ;
int found = 0 ;
dl_list_for_each_safe ( bi , tmp , & ifaces - > dpp_bootstrap ,
struct dpp_bootstrap_info , list ) {
if ( id & & bi - > id ! = id )
continue ;
found = 1 ;
dl_list_del ( & bi - > list ) ;
dpp_bootstrap_info_free ( bi ) ;
}
if ( id = = 0 )
return 0 ; /* flush succeeds regardless of entries found */
return found ? 0 : - 1 ;
}
int hostapd_dpp_bootstrap_remove ( struct hostapd_data * hapd , const char * id )
{
unsigned int id_val ;
if ( os_strcmp ( id , " * " ) = = 0 ) {
id_val = 0 ;
} else {
id_val = atoi ( id ) ;
if ( id_val = = 0 )
return - 1 ;
}
return dpp_bootstrap_del ( hapd - > iface - > interfaces , id_val ) ;
}
const char * hostapd_dpp_bootstrap_get_uri ( struct hostapd_data * hapd ,
unsigned int id )
{
struct dpp_bootstrap_info * bi ;
bi = dpp_bootstrap_get_id ( hapd , id ) ;
if ( ! bi )
return NULL ;
return bi - > uri ;
}
int hostapd_dpp_bootstrap_info ( struct hostapd_data * hapd , int id ,
char * reply , int reply_size )
{
struct dpp_bootstrap_info * bi ;
bi = dpp_bootstrap_get_id ( hapd , id ) ;
if ( ! bi )
return - 1 ;
return os_snprintf ( reply , reply_size , " type=%s \n "
" mac_addr= " MACSTR " \n "
" info=%s \n "
" num_freq=%u \n "
" curve=%s \n " ,
dpp_bootstrap_type_txt ( bi - > type ) ,
MAC2STR ( bi - > mac_addr ) ,
bi - > info ? bi - > info : " " ,
bi - > num_freq ,
bi - > curve - > name ) ;
}
static void hostapd_dpp_auth_resp_retry_timeout ( void * eloop_ctx ,
void * timeout_ctx )
{
@ -515,38 +295,6 @@ static void hostapd_dpp_set_testing_options(struct hostapd_data *hapd,
}
static int hostapd_dpp_set_configurator ( struct hostapd_data * hapd ,
struct dpp_authentication * auth ,
const char * cmd )
{
const char * pos ;
if ( ! cmd )
return 0 ;
wpa_printf ( MSG_DEBUG , " DPP: Set configurator parameters: %s " , cmd ) ;
pos = os_strstr ( cmd , " configurator= " ) ;
if ( pos ) {
auth - > configurator = 1 ;
pos + = 14 ;
auth - > conf = hostapd_dpp_configurator_get_id ( hapd , atoi ( pos ) ) ;
if ( ! auth - > conf ) {
wpa_printf ( MSG_INFO ,
" DPP: Could not find the specified configurator " ) ;
return - 1 ;
}
}
if ( dpp_configuration_parse ( auth , cmd ) < 0 ) {
wpa_msg ( hapd - > msg_ctx , MSG_INFO ,
" DPP: Failed to set configurator parameters " ) ;
return - 1 ;
}
return 0 ;
}
static void hostapd_dpp_init_timeout ( void * eloop_ctx , void * timeout_ctx )
{
struct hostapd_data * hapd = eloop_ctx ;
@ -656,7 +404,7 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
if ( ! pos )
return - 1 ;
pos + = 6 ;
peer_bi = dpp_bootstrap_get_id ( hapd , atoi ( pos ) ) ;
peer_bi = dpp_bootstrap_get_id ( hapd - > iface - > interfaces - > dpp , atoi ( pos ) ) ;
if ( ! peer_bi ) {
wpa_printf ( MSG_INFO ,
" DPP: Could not find bootstrapping info for the identified peer " ) ;
@ -666,7 +414,8 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
pos = os_strstr ( cmd , " own= " ) ;
if ( pos ) {
pos + = 5 ;
own_bi = dpp_bootstrap_get_id ( hapd , atoi ( pos ) ) ;
own_bi = dpp_bootstrap_get_id ( hapd - > iface - > interfaces - > dpp ,
atoi ( pos ) ) ;
if ( ! own_bi ) {
wpa_printf ( MSG_INFO ,
" DPP: Could not find bootstrapping info for the identified local entry " ) ;
@ -716,7 +465,8 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
if ( ! hapd - > dpp_auth )
goto fail ;
hostapd_dpp_set_testing_options ( hapd , hapd - > dpp_auth ) ;
if ( hostapd_dpp_set_configurator ( hapd , hapd - > dpp_auth , cmd ) < 0 ) {
if ( dpp_set_configurator ( hapd - > iface - > interfaces - > dpp , hapd - > msg_ctx ,
hapd - > dpp_auth , cmd ) < 0 ) {
dpp_auth_deinit ( hapd - > dpp_auth ) ;
hapd - > dpp_auth = NULL ;
goto fail ;
@ -775,7 +525,10 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
{
const u8 * r_bootstrap , * i_bootstrap ;
u16 r_bootstrap_len , i_bootstrap_len ;
struct dpp_bootstrap_info * bi , * own_bi = NULL , * peer_bi = NULL ;
struct dpp_bootstrap_info * own_bi = NULL , * peer_bi = NULL ;
if ( ! hapd - > iface - > interfaces - > dpp )
return ;
wpa_printf ( MSG_DEBUG , " DPP: Authentication Request from " MACSTR ,
MAC2STR ( src ) ) ;
@ -802,28 +555,8 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
/* Try to find own and peer bootstrapping key matches based on the
* received hash values */
dl_list_for_each ( bi , & hapd - > iface - > interfaces - > dpp_bootstrap ,
struct dpp_bootstrap_info , list ) {
if ( ! own_bi & & bi - > own & &
os_memcmp ( bi - > pubkey_hash , r_bootstrap ,
SHA256_MAC_LEN ) = = 0 ) {
wpa_printf ( MSG_DEBUG ,
" DPP: Found matching own bootstrapping information " ) ;
own_bi = bi ;
}
if ( ! peer_bi & & ! bi - > own & &
os_memcmp ( bi - > pubkey_hash , i_bootstrap ,
SHA256_MAC_LEN ) = = 0 ) {
wpa_printf ( MSG_DEBUG ,
" DPP: Found matching peer bootstrapping information " ) ;
peer_bi = bi ;
}
if ( own_bi & & peer_bi )
break ;
}
dpp_bootstrap_find_pair ( hapd - > iface - > interfaces - > dpp , i_bootstrap ,
r_bootstrap , & own_bi , & peer_bi ) ;
if ( ! own_bi ) {
wpa_msg ( hapd - > msg_ctx , MSG_INFO , DPP_EVENT_FAIL
" No matching own bootstrapping key found - ignore message " ) ;
@ -845,8 +578,9 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
return ;
}
hostapd_dpp_set_testing_options ( hapd , hapd - > dpp_auth ) ;
if ( hostapd_dpp_set_configurator ( hapd , hapd - > dpp_auth ,
hapd - > dpp_configurator_params ) < 0 ) {
if ( dpp_set_configurator ( hapd - > iface - > interfaces - > dpp , hapd - > msg_ctx ,
hapd - > dpp_auth ,
hapd - > dpp_configurator_params ) < 0 ) {
dpp_auth_deinit ( hapd - > dpp_auth ) ;
hapd - > dpp_auth = NULL ;
return ;
@ -1553,24 +1287,10 @@ hostapd_dpp_rx_pkex_commit_reveal_req(struct hostapd_data *hapd, const u8 *src,
wpabuf_head ( msg ) , wpabuf_len ( msg ) ) ;
wpabuf_free ( msg ) ;
bi = os_zalloc( sizeof ( * bi ) ) ;
bi = dpp_pkex_finish( hapd - > iface - > interfaces - > dpp , pkex , src , freq ) ;
if ( ! bi )
return ;
bi - > id = hapd_dpp_next_id ( hapd ) ;
bi - > type = DPP_BOOTSTRAP_PKEX ;
os_memcpy ( bi - > mac_addr , src , ETH_ALEN ) ;
bi - > num_freq = 1 ;
bi - > freq [ 0 ] = freq ;
bi - > curve = pkex - > own_bi - > curve ;
bi - > pubkey = pkex - > peer_bootstrap_key ;
pkex - > peer_bootstrap_key = NULL ;
dpp_pkex_free ( pkex ) ;
hapd - > dpp_pkex = NULL ;
if ( dpp_bootstrap_key_hash ( bi ) < 0 ) {
dpp_bootstrap_info_free ( bi ) ;
return ;
}
dl_list_add ( & hapd - > iface - > interfaces - > dpp_bootstrap , & bi - > list ) ;
}
@ -1580,7 +1300,7 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
unsigned int freq )
{
int res ;
struct dpp_bootstrap_info * bi , * own_bi ;
struct dpp_bootstrap_info * bi ;
struct dpp_pkex * pkex = hapd - > dpp_pkex ;
char cmd [ 500 ] ;
@ -1598,26 +1318,10 @@ hostapd_dpp_rx_pkex_commit_reveal_resp(struct hostapd_data *hapd, const u8 *src,
return ;
}
own_bi = pkex - > own_bi ;
bi = os_zalloc ( sizeof ( * bi ) ) ;
bi = dpp_pkex_finish ( hapd - > iface - > interfaces - > dpp , pkex , src , freq ) ;
if ( ! bi )
return ;
bi - > id = hapd_dpp_next_id ( hapd ) ;
bi - > type = DPP_BOOTSTRAP_PKEX ;
os_memcpy ( bi - > mac_addr , src , ETH_ALEN ) ;
bi - > num_freq = 1 ;
bi - > freq [ 0 ] = freq ;
bi - > curve = own_bi - > curve ;
bi - > pubkey = pkex - > peer_bootstrap_key ;
pkex - > peer_bootstrap_key = NULL ;
dpp_pkex_free ( pkex ) ;
hapd - > dpp_pkex = NULL ;
if ( dpp_bootstrap_key_hash ( bi ) < 0 ) {
dpp_bootstrap_info_free ( bi ) ;
return ;
}
dl_list_add ( & hapd - > iface - > interfaces - > dpp_bootstrap , & bi - > list ) ;
os_snprintf ( cmd , sizeof ( cmd ) , " peer=%u %s " ,
bi - > id ,
@ -1785,93 +1489,6 @@ void hostapd_dpp_gas_status_handler(struct hostapd_data *hapd, int ok)
}
static unsigned int hostapd_dpp_next_configurator_id ( struct hostapd_data * hapd )
{
struct dpp_configurator * conf ;
unsigned int max_id = 0 ;
dl_list_for_each ( conf , & hapd - > iface - > interfaces - > dpp_configurator ,
struct dpp_configurator , list ) {
if ( conf - > id > max_id )
max_id = conf - > id ;
}
return max_id + 1 ;
}
int hostapd_dpp_configurator_add ( struct hostapd_data * hapd , const char * cmd )
{
char * curve = NULL ;
char * key = NULL ;
u8 * privkey = NULL ;
size_t privkey_len = 0 ;
int ret = - 1 ;
struct dpp_configurator * conf = NULL ;
curve = get_param ( cmd , " curve= " ) ;
key = get_param ( cmd , " key= " ) ;
if ( key ) {
privkey_len = os_strlen ( key ) / 2 ;
privkey = os_malloc ( privkey_len ) ;
if ( ! privkey | |
hexstr2bin ( key , privkey , privkey_len ) < 0 )
goto fail ;
}
conf = dpp_keygen_configurator ( curve , privkey , privkey_len ) ;
if ( ! conf )
goto fail ;
conf - > id = hostapd_dpp_next_configurator_id ( hapd ) ;
dl_list_add ( & hapd - > iface - > interfaces - > dpp_configurator , & conf - > list ) ;
ret = conf - > id ;
conf = NULL ;
fail :
os_free ( curve ) ;
str_clear_free ( key ) ;
bin_clear_free ( privkey , privkey_len ) ;
dpp_configurator_free ( conf ) ;
return ret ;
}
static int dpp_configurator_del ( struct hapd_interfaces * ifaces , unsigned int id )
{
struct dpp_configurator * conf , * tmp ;
int found = 0 ;
dl_list_for_each_safe ( conf , tmp , & ifaces - > dpp_configurator ,
struct dpp_configurator , list ) {
if ( id & & conf - > id ! = id )
continue ;
found = 1 ;
dl_list_del ( & conf - > list ) ;
dpp_configurator_free ( conf ) ;
}
if ( id = = 0 )
return 0 ; /* flush succeeds regardless of entries found */
return found ? 0 : - 1 ;
}
int hostapd_dpp_configurator_remove ( struct hostapd_data * hapd , const char * id )
{
unsigned int id_val ;
if ( os_strcmp ( id , " * " ) = = 0 ) {
id_val = 0 ;
} else {
id_val = atoi ( id ) ;
if ( id_val = = 0 )
return - 1 ;
}
return dpp_configurator_del ( hapd - > iface - > interfaces , id_val ) ;
}
int hostapd_dpp_configurator_sign ( struct hostapd_data * hapd , const char * cmd )
{
struct dpp_authentication * auth ;
@ -1884,7 +1501,8 @@ int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
curve = get_param ( cmd , " curve= " ) ;
hostapd_dpp_set_testing_options ( hapd , auth ) ;
if ( hostapd_dpp_set_configurator ( hapd , auth , cmd ) = = 0 & &
if ( dpp_set_configurator ( hapd - > iface - > interfaces - > dpp , hapd - > msg_ctx ,
auth , cmd ) = = 0 & &
dpp_configurator_own_config ( auth , curve , 1 ) = = 0 ) {
hostapd_dpp_handle_config_obj ( hapd , auth ) ;
ret = 0 ;
@ -1897,19 +1515,6 @@ int hostapd_dpp_configurator_sign(struct hostapd_data *hapd, const char *cmd)
}
int hostapd_dpp_configurator_get_key ( struct hostapd_data * hapd , unsigned int id ,
char * buf , size_t buflen )
{
struct dpp_configurator * conf ;
conf = hostapd_dpp_configurator_get_id ( hapd , id ) ;
if ( ! conf )
return - 1 ;
return dpp_configurator_get_key ( conf , buf , buflen ) ;
}
int hostapd_dpp_pkex_add ( struct hostapd_data * hapd , const char * cmd )
{
struct dpp_bootstrap_info * own_bi ;
@ -1919,7 +1524,7 @@ int hostapd_dpp_pkex_add(struct hostapd_data *hapd, const char *cmd)
if ( ! pos )
return - 1 ;
pos + = 5 ;
own_bi = dpp_bootstrap_get_id ( hapd , atoi ( pos ) ) ;
own_bi = dpp_bootstrap_get_id ( hapd - > iface - > interfaces - > dpp , atoi ( pos ) ) ;
if ( ! own_bi ) {
wpa_printf ( MSG_DEBUG ,
" DPP: Identified bootstrap info not found " ) ;
@ -2060,20 +1665,3 @@ void hostapd_dpp_deinit(struct hostapd_data *hapd)
os_free ( hapd - > dpp_configurator_params ) ;
hapd - > dpp_configurator_params = NULL ;
}
void hostapd_dpp_init_global ( struct hapd_interfaces * ifaces )
{
dl_list_init ( & ifaces - > dpp_bootstrap ) ;
dl_list_init ( & ifaces - > dpp_configurator ) ;
ifaces - > dpp_init_done = 1 ;
}
void hostapd_dpp_deinit_global ( struct hapd_interfaces * ifaces )
{
if ( ! ifaces - > dpp_init_done )
return ;
dpp_bootstrap_del ( ifaces , 0 ) ;
dpp_configurator_del ( ifaces , 0 ) ;
}