diff mbox series

RFC: PKEX support for DPP

Message ID 20231005123034.15802-1-prestwoj@gmail.com (mailing list archive)
State New
Headers show
Series RFC: PKEX support for DPP | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-alpine-ci-fetch success Fetch PR
prestwoj/iwd-ci-gitlint success GitLint
prestwoj/iwd-ci-fetch success Fetch PR
prestwoj/iwd-alpine-ci-makedistcheck fail Make Distcheck Make FAIL: make[2]: *** No rule to make target 'ell/sysctl.h', needed by 'distdir-am'. Stop. make[1]: *** [Makefile:3218: distdir] Error 2 make: *** [Makefile:3298: dist] Error 2
prestwoj/iwd-alpine-ci-incremental_build success Incremental build not run PASS
prestwoj/iwd-alpine-ci-build success Build - Configure
prestwoj/iwd-alpine-ci-makecheckvalgrind fail Make FAIL: make[1]: *** No rule to make target 'ell/sysctl.c', needed by 'ell/sysctl.lo'. Stop. make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:1710: all] Error 2
prestwoj/iwd-alpine-ci-makecheck pending makecheck SKIP
prestwoj/iwd-ci-incremental_build success Incremental build not run PASS
prestwoj/iwd-ci-build success Build - Configure
prestwoj/iwd-ci-makecheckvalgrind fail Make FAIL: make[1]: *** No rule to make target 'ell/sysctl.c', needed by 'ell/sysctl.lo'. Stop. make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:1709: all] Error 2
prestwoj/iwd-ci-makecheck pending makecheck SKIP
prestwoj/iwd-ci-clang fail Clang IWD - make FAIL: make[1]: *** No rule to make target 'ell/sysctl.c', needed by 'ell/sysctl.lo'. Stop. make[1]: *** Waiting for unfinished jobs.... make: *** [Makefile:1709: all] Error 2
prestwoj/iwd-ci-makedistcheck fail Make Distcheck Make FAIL: make[2]: *** No rule to make target 'ell/sysctl.h', needed by 'distdir-am'. Stop. make[1]: *** [Makefile:3217: distdir] Error 2 make: *** [Makefile:3297: dist] Error 2
prestwoj/iwd-ci-testrunner pending testrunner SKIP

Commit Message

James Prestwood Oct. 5, 2023, 12:30 p.m. UTC
PKEX is part of the WFA EasyConnect specification and is
an additional boostrapping method (like QR codes) for
exchanging public keys between a configurator and enrollee.

PKEX operates over wifi and requires a key/code be exchanged
prior to the protocol. The key is used to encrypt the exchange
of the boostrapping information, then DPP authentication is
started immediately aftewards.

This can be useful for devices which don't have the ability to
scan a QR code, or even as a more convenient way to share
wireless credentials if the PSK is very secure (i.e. not a
human readable string).

This only documents the DBus API for now to get an idea of how
and where this module would live. The current plan is to keep
it in dpp.c. This module is getting rather large but all the
infrastructure exists for offchannel/frame callbacks and
state so it makes sense to keep it there. The plan is to add
some additional states to dpp for PKEX which would happen
prior to AUTHENTICATION and allow the PRESENCE state to be
skipped.

PKEX would be used via the two DBus APIs. PkexConfigure would
start listening and wait for an Enrollee to send a PKEX
exchange request. The enrollee would be started with PkexEnroll
and initiate the exchange. PKEX would proceed and once done
DPP Authentication would start using the boostrapping keys
exchanged.

For convenience/security the PKEX key could be specified in the
IWD provisioning file (part of the Security group). This would
allow IWD to encrypt it and avoid the need for some other entity
to store the key in order to call PkexConfigure (e.g. if not
initiated by a human entering the key).
---
 doc/device-provisioning-api.txt | 44 +++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

Comments

Denis Kenzior Oct. 6, 2023, 2:55 p.m. UTC | #1
Hi James,

On 10/5/23 07:30, James Prestwood wrote:
> PKEX is part of the WFA EasyConnect specification and is
> an additional boostrapping method (like QR codes) for
> exchanging public keys between a configurator and enrollee.
> 
> PKEX operates over wifi and requires a key/code be exchanged
> prior to the protocol. The key is used to encrypt the exchange
> of the boostrapping information, then DPP authentication is
> started immediately aftewards.
> 
> This can be useful for devices which don't have the ability to
> scan a QR code, or even as a more convenient way to share
> wireless credentials if the PSK is very secure (i.e. not a
> human readable string).
> 
> This only documents the DBus API for now to get an idea of how
> and where this module would live. The current plan is to keep
> it in dpp.c. This module is getting rather large but all the
> infrastructure exists for offchannel/frame callbacks and
> state so it makes sense to keep it there. The plan is to add
> some additional states to dpp for PKEX which would happen
> prior to AUTHENTICATION and allow the PRESENCE state to be
> skipped.
> 

Sounds good.

> PKEX would be used via the two DBus APIs. PkexConfigure would
> start listening and wait for an Enrollee to send a PKEX
> exchange request. The enrollee would be started with PkexEnroll
> and initiate the exchange. PKEX would proceed and once done
> DPP Authentication would start using the boostrapping keys
> exchanged.

I would really like to avoid camel case abbreviations in APIs.  Also, we like to 
use more easily understood terminology in our APIs whenever possible.  For 
example, SignalStrength not RSSI, SimpleConfiguration not WSC, etc.  Also, this 
is very different in feel compared to the rest of DeviceProvisioning Methods.

Perhaps this should be moved to its own interface, something like 
SharedCodeDeviceProvisioning.

> 
> For convenience/security the PKEX key could be specified in the
> IWD provisioning file (part of the Security group). This would

Why don't you just make this the default and drop the dictionary parameters.

> allow IWD to encrypt it and avoid the need for some other entity
> to store the key in order to call PkexConfigure (e.g. if not
> initiated by a human entering the key).
> ---
>   doc/device-provisioning-api.txt | 44 +++++++++++++++++++++++++++++++++
>   1 file changed, 44 insertions(+)
> 
> diff --git a/doc/device-provisioning-api.txt b/doc/device-provisioning-api.txt
> index ac204f46..c8b2e4a5 100644
> --- a/doc/device-provisioning-api.txt
> +++ b/doc/device-provisioning-api.txt
> @@ -57,6 +57,50 @@ Methods		string StartEnrollee()
>   						net.connman.iwd.NotSupported
>   						net.connman.iwd.Busy
>   
> +		PkexConfigure(dict args)
> +			The 'args' dictionary (a{sv}) contains parameters for
> +			the PKEX configurer. This can be empty or contain the
> +			following dictionary members:
> +
> +			string Key - The PKEX key. This is required if not
> +			specified in the network profile already.
> +
> +			string Identifier - The PKEX key identifier. This is
> +			optional, but if used both the Configurer and enrollee
> +			must use the same value. Can also be specified in the
> +			network profile.
> +
> +			uint32_t Timeout - A timeout (in seconds) for
> +			configuration. This is optional, but suggested to
> +			prevent a device from indefinitely configuring
> +			enrollees (if Stop() was never called).

I would pick something reasonable (or read it from the provisioning file) and 
drop this from the API entirely.

> +
> +			Possible errors:	net.connman.iwd.Busy
> +						net.connman.iwd.NotConnected
> +						net.connman.iwd.InvalidArguments
> +						net.connman.iwd.NotConfigured
> +
> +		PkexEnroll(dict args)
> +			The 'args' dictionary (a{sv}) contains parameters for
> +			the PKEX enrollee.
> +
> +			string Key - The PKEX key. This is required and must
> +			match the configurer's key.
> +
> +			string Identifier - The PKEX key identifier. This is
> +			optional, but if used both the Configurer and enrollee

"configurator"

> +			must use the same value.
> +
> +			array(y) Address - The address of the PKEX listener. If
> +			not specified a broadcast address is used.

array(y)?  Nack :)

> +
> +			array(u) Frequencies - A list of frequencies to
> +			discover on. If not specified channel 2, 44, and 149
> +			are used per the DPP spec.

Same here.

I would drop Address and Frequencies from this API.  No human is going to be 
entering these via a UI.

> +
> +			Possible errors:	net.connman.iwd.Busy
> +						net.connman.iwd.InvalidArguments
> +
>   Properties	boolean Started [readonly]
>   
>   			True if DPP is currently active.

Regards,
-Denis
James Prestwood Oct. 6, 2023, 4:14 p.m. UTC | #2
On 10/6/23 7:55 AM, Denis Kenzior wrote:
> Hi James,
> 
> On 10/5/23 07:30, James Prestwood wrote:
>> PKEX is part of the WFA EasyConnect specification and is
>> an additional boostrapping method (like QR codes) for
>> exchanging public keys between a configurator and enrollee.
>>
>> PKEX operates over wifi and requires a key/code be exchanged
>> prior to the protocol. The key is used to encrypt the exchange
>> of the boostrapping information, then DPP authentication is
>> started immediately aftewards.
>>
>> This can be useful for devices which don't have the ability to
>> scan a QR code, or even as a more convenient way to share
>> wireless credentials if the PSK is very secure (i.e. not a
>> human readable string).
>>
>> This only documents the DBus API for now to get an idea of how
>> and where this module would live. The current plan is to keep
>> it in dpp.c. This module is getting rather large but all the
>> infrastructure exists for offchannel/frame callbacks and
>> state so it makes sense to keep it there. The plan is to add
>> some additional states to dpp for PKEX which would happen
>> prior to AUTHENTICATION and allow the PRESENCE state to be
>> skipped.
>>
> 
> Sounds good.
> 
>> PKEX would be used via the two DBus APIs. PkexConfigure would
>> start listening and wait for an Enrollee to send a PKEX
>> exchange request. The enrollee would be started with PkexEnroll
>> and initiate the exchange. PKEX would proceed and once done
>> DPP Authentication would start using the boostrapping keys
>> exchanged.
> 
> I would really like to avoid camel case abbreviations in APIs.  Also, we 
> like to use more easily understood terminology in our APIs whenever 
> possible.  For example, SignalStrength not RSSI, SimpleConfiguration not 
> WSC, etc.  Also, this is very different in feel compared to the rest of 
> DeviceProvisioning Methods.
> 
> Perhaps this should be moved to its own interface, something like 
> SharedCodeDeviceProvisioning.

Sounds good.

> 
>>
>> For convenience/security the PKEX key could be specified in the
>> IWD provisioning file (part of the Security group). This would
> 
> Why don't you just make this the default and drop the dictionary 
> parameters.
> 
>> allow IWD to encrypt it and avoid the need for some other entity
>> to store the key in order to call PkexConfigure (e.g. if not
>> initiated by a human entering the key).
>> ---
>>   doc/device-provisioning-api.txt | 44 +++++++++++++++++++++++++++++++++
>>   1 file changed, 44 insertions(+)
>>
>> diff --git a/doc/device-provisioning-api.txt 
>> b/doc/device-provisioning-api.txt
>> index ac204f46..c8b2e4a5 100644
>> --- a/doc/device-provisioning-api.txt
>> +++ b/doc/device-provisioning-api.txt
>> @@ -57,6 +57,50 @@ Methods        string StartEnrollee()
>>                           net.connman.iwd.NotSupported
>>                           net.connman.iwd.Busy
>> +        PkexConfigure(dict args)
>> +            The 'args' dictionary (a{sv}) contains parameters for
>> +            the PKEX configurer. This can be empty or contain the
>> +            following dictionary members:
>> +
>> +            string Key - The PKEX key. This is required if not
>> +            specified in the network profile already.
>> +
>> +            string Identifier - The PKEX key identifier. This is
>> +            optional, but if used both the Configurer and enrollee
>> +            must use the same value. Can also be specified in the
>> +            network profile.
>> +
>> +            uint32_t Timeout - A timeout (in seconds) for
>> +            configuration. This is optional, but suggested to
>> +            prevent a device from indefinitely configuring
>> +            enrollees (if Stop() was never called).
> 
> I would pick something reasonable (or read it from the provisioning 
> file) and drop this from the API entirely.
> 
>> +
>> +            Possible errors:    net.connman.iwd.Busy
>> +                        net.connman.iwd.NotConnected
>> +                        net.connman.iwd.InvalidArguments
>> +                        net.connman.iwd.NotConfigured
>> +
>> +        PkexEnroll(dict args)
>> +            The 'args' dictionary (a{sv}) contains parameters for
>> +            the PKEX enrollee.
>> +
>> +            string Key - The PKEX key. This is required and must
>> +            match the configurer's key.
>> +
>> +            string Identifier - The PKEX key identifier. This is
>> +            optional, but if used both the Configurer and enrollee
> 
> "configurator"
> 
>> +            must use the same value.
>> +
>> +            array(y) Address - The address of the PKEX listener. If
>> +            not specified a broadcast address is used.
> 
> array(y)?  Nack :)
> 
>> +
>> +            array(u) Frequencies - A list of frequencies to
>> +            discover on. If not specified channel 2, 44, and 149
>> +            are used per the DPP spec.
> 
> Same here.
> 
> I would drop Address and Frequencies from this API.  No human is going 
> to be entering these via a UI.

The issue I foresee is trying to find configurators since they stay on 
the current operating channel which likely isn't 2, 44, or 149 (I 
suppose we could have them go offchannel, but I wanted to avoid that). 
But I agree, its not something a human would know or want to type in.

Enrollees could instead iterate all supported channels, but that would 
take a while (200ms per channel per the spec, and actually the spec 
wants 5 retries per channel but I wasn't planning on doing that). But 
maybe this is the only way to do it in an automatic way.

One idea I had was to have the enrollee scan first, iterate channels 
from nearby APs, if nothing is found repeat. That would likely reduce 
the number of frequencies significantly.

> 
>> +
>> +            Possible errors:    net.connman.iwd.Busy
>> +                        net.connman.iwd.InvalidArguments
>> +
>>   Properties    boolean Started [readonly]
>>               True if DPP is currently active.
> 
> Regards,
> -Denis
diff mbox series

Patch

diff --git a/doc/device-provisioning-api.txt b/doc/device-provisioning-api.txt
index ac204f46..c8b2e4a5 100644
--- a/doc/device-provisioning-api.txt
+++ b/doc/device-provisioning-api.txt
@@ -57,6 +57,50 @@  Methods		string StartEnrollee()
 						net.connman.iwd.NotSupported
 						net.connman.iwd.Busy
 
+		PkexConfigure(dict args)
+			The 'args' dictionary (a{sv}) contains parameters for
+			the PKEX configurer. This can be empty or contain the
+			following dictionary members:
+
+			string Key - The PKEX key. This is required if not
+			specified in the network profile already.
+
+			string Identifier - The PKEX key identifier. This is
+			optional, but if used both the Configurer and enrollee
+			must use the same value. Can also be specified in the
+			network profile.
+
+			uint32_t Timeout - A timeout (in seconds) for
+			configuration. This is optional, but suggested to
+			prevent a device from indefinitely configuring
+			enrollees (if Stop() was never called).
+
+			Possible errors:	net.connman.iwd.Busy
+						net.connman.iwd.NotConnected
+						net.connman.iwd.InvalidArguments
+						net.connman.iwd.NotConfigured
+
+		PkexEnroll(dict args)
+			The 'args' dictionary (a{sv}) contains parameters for
+			the PKEX enrollee.
+
+			string Key - The PKEX key. This is required and must
+			match the configurer's key.
+
+			string Identifier - The PKEX key identifier. This is
+			optional, but if used both the Configurer and enrollee
+			must use the same value.
+
+			array(y) Address - The address of the PKEX listener. If
+			not specified a broadcast address is used.
+
+			array(u) Frequencies - A list of frequencies to
+			discover on. If not specified channel 2, 44, and 149
+			are used per the DPP spec.
+
+			Possible errors:	net.connman.iwd.Busy
+						net.connman.iwd.InvalidArguments
+
 Properties	boolean Started [readonly]
 
 			True if DPP is currently active.