diff mbox series

[v3,6/9] doc: PKEX support for DPP

Message ID 20231031184750.722404-7-prestwoj@gmail.com (mailing list archive)
State New
Headers show
Series DPP PKEX Changes | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
prestwoj/iwd-ci-gitlint success GitLint

Commit Message

James Prestwood Oct. 31, 2023, 6:47 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).

PKEX would be used via the three DBus APIs on a new interface
SharedCodeDeviceProvisioning.

ConfigureEnrollee(a{sv}) will start a configurator with a
static shared code (optionally identifier) passed in as the
argument to this method.

StartEnrollee(a{sv}) will start a PKEX enrollee using a static
shared code (optionally identifier) passed as the argument to
the method.

StartConfigurator() will start a PKEX configurator (should be
already registered) which will query an agent for an enrollees
shared code. Enrollees are distinguished by the identifier.

After the PKEX protocol is finished, DPP bootstrapping keys have
been exchanged and DPP Authentication will start, followed by
configuration.
---
 doc/device-provisioning-api.txt | 149 ++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)

Comments

Denis Kenzior Nov. 3, 2023, 2:07 a.m. UTC | #1
Hi James,

On 10/31/23 13:47, 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).
> 
> PKEX would be used via the three DBus APIs on a new interface
> SharedCodeDeviceProvisioning.
> 
> ConfigureEnrollee(a{sv}) will start a configurator with a
> static shared code (optionally identifier) passed in as the
> argument to this method.
> 
> StartEnrollee(a{sv}) will start a PKEX enrollee using a static
> shared code (optionally identifier) passed as the argument to
> the method.
> 
> StartConfigurator() will start a PKEX configurator (should be
> already registered) which will query an agent for an enrollees
> shared code. Enrollees are distinguished by the identifier.
> 
> After the PKEX protocol is finished, DPP bootstrapping keys have
> been exchanged and DPP Authentication will start, followed by
> configuration.
> ---
>   doc/device-provisioning-api.txt | 149 ++++++++++++++++++++++++++++++++
>   1 file changed, 149 insertions(+)
> 
> diff --git a/doc/device-provisioning-api.txt b/doc/device-provisioning-api.txt
> index ac204f46..3c6fc74e 100644
> --- a/doc/device-provisioning-api.txt
> +++ b/doc/device-provisioning-api.txt
> @@ -71,3 +71,152 @@ Properties	boolean Started [readonly]
>   
>   			Indicates the DPP URI. This property is only available
>   			when Started is true.
> +
> +
> +Interface	net.connman.iwd.SharedCodeDeviceProvisioning [Experimental]
> +Object path	/net/connman/iwd/{phy0,phy1,...}/{1,2,...}
> +
> +		ConfigureEnrollee(a{sv})
> +
> +			Starts a DPP configurator using a shared code (and
> +			optionally identifier) set in the dictionary argument.
> +			Valid dictionary keys are:
> +
> +			string Code
> +				The shared code to use. The code used by both
> +				parties (configurator and enrollee) must match.
> +
> +			string Identifier
> +				An optional identifier. The identifier used by
> +				both parties must match. Per the DPP spec the
> +				identifier "shall be a UTF-8 string not greater
> +				than eighty (80) octets"
> +
> +			As with the DeviceProvisioning interface, configurators
> +			must be connected to the network they wish to configure
> +			in order to start.
> +
> +			Once started a configurator (acting as a responder) will
> +			listen on the currently connected channel for an
> +			enrollee's initial exchange request which will kick off
> +			the shared code bootstrapping protocol (PKEX). Once
> +			completed DPP will start automatically. Only one
> +			enrollee can be configured per call to
> +			ConfigureEnrollee, i.e. once PKEX/DPP is has finished

"is has finished"?

> +			(including failure) the configurator will stop.
> +
> +			The SharedCode methods have an eventual timeout and will
> +			stop automatically after 2 minutes.
> +
> +			Possible errors:	net.connman.iwd.Busy
> +						net.connman.iwd.NotConnected
> +						net.connman.InvalidArguments
> +
> +		StartEnrollee(a{sv})
> +
> +			Starts a DPP enrollee using a shared code (and
> +			optionally identifier) set in the dictionary argument
> +			(described above in ConfigureEnrollee).
> +
> +			As with the device provisioning interface, enrollees
> +			must be disconnected in order to start.
> +
> +			Once started an enrollee (acting as an initiator) will
> +			iterate channels sending out broadcast exchange requests
> +			waiting for a response from a configurator. A response
> +			will kick off the shared code bootstrapping protocol
> +			(PKEX), followed by DPP if successful. Once the
> +			protocols have completed, or failed, the enrollee will
> +			stop. If failed, StartEnrollee will need to be called
> +			again to retry.
> +
> +			Possible errors:	net.connman.iwd.Busy
> +						net.connman.iwd.InvalidArguments
> +
> +		StartConfigurator()

You are missing return parameters for all of these methods.  Also seems like 
Stop() method isn't documented.

> +
> +			Start a shared code configurator using an agent to
> +			obtain the shared code. This method is meant for an
> +			automated use case where a configurator is capable of
> +			configuring multiple enrollees, and distinguishing
> +			between them by their identifier.
> +
> +			Prior to calling, a SharedCodeAgent must be registered
> +			using RegisterSharedCodeAgent. Only a single agent can
> +			be registered per SharedCodeInterface.

So the one thing to watch out for is that DPP interface can come and go, unlike 
the Manager interface.  Since StartConfigurator() has to be called for each 
protocol attempt, providing the agent as an argument might be be a nicer 
shortcut?  The API is marked experimental, so we can always change this.  You 
will probably know more once you try to implement the API.

Also, it seems to me that StartConfigurator implies that the agent is active. 
If the agent goes away, StartConfigurator() should be aborted, no?

> +
> +			This method behaves nearly the same as ConfigureEnrollee
> +			except upon receiving an enrollees first exchange
> +			request the registered agent will be asked for the
> +			shared code using the RequestSharedCode method.
> +
> +			Though the agent can provide shared codes for multiple
> +			enrollees, this method will only configure a single
> +			enrollee at a time. Once completed it will need to be
> +			called again to configure additional enrollees.
> +
> +			Possible errors:	net.connman.iwd.Busy
> +						net.connman.iwd.NotConnected
> +						net.connman.iwd.NoAgent
> +
> +		void RegisterSharedCodeAgent(object path)
> +
> +			Register the agent object for servicing shared code
> +			requests on the net.connman.iwd.SharedCodeAgent
> +			interface. There may only be one agent registered at a
> +			time per SharedCodeDeviceProvisioning interface.
> +
> +			Possible Errors:	[service].Error.InvalidArguments
> +						[service].Error.AlreadyExists
> +
> +		void UnregisterSharedCodeAgent()
> +
> +			Unregister an existing agent.
> +
> +			Possible Errors:	[service].Error.NotFound
> +
> +Properties	boolean Started [readonly]
> +
> +			True if shared code device provisioning is currently
> +			active. (configurator or enrollee is started)
> +
> +		string Role [readonly, optional]
> +
> +			Indicates the DPP role. Possible values are "enrollee"
> +			or "configurator". This property is only available when
> +			Started is true.
> +
> +SharedCodeAgent hierarchy
> +=========================
> +
> +Service		unique name
> +Interface	net.connman.iwd.SharedCodeAgent [Experimental]
> +Object path	freely definable
> +
> +Methods		void Release() [noreply]
> +
> +			This method gets called when the service daemon
> +			unregisters the agent.

You don't actually call this method.

> +
> +		string RequestSharedCode(object network, string identifier)
> +
> +			This method gets called when a shared code is requested
> +			for a particular enrollee, distingushed by the
> +			identifier. The shared code agent should lookup the
> +			identifier and return the shared code, or return an
> +			error if not found.

Looks like you don't actually call the agent with the network object?

> +
> +			Possible Errors:	[service].Error.Canceled
> +						[service].Error.NotFound
> +
> +		void Cancel(string reason) [noreply]
> +
> +			This method gets called to indicate that the agent
> +			request failed before a reply was returned. The
> +			argument will indicate why the request is being
> +			cancelled and may be "user-canceled", "timed-out" or
> +			"shutdown".

You don't call this method either.
> +
> +Examples	Requesting a shared code for an enrollee identified by "foo"
> +
> +			RequestSharedCode("foo") ==> "super_secret_code"

This signature incorrect as well?

Regards,
-Denis
James Prestwood Nov. 3, 2023, 11:24 a.m. UTC | #2
Hi Denis,

On 11/2/23 7:07 PM, Denis Kenzior wrote:
> Hi James,
> 
> On 10/31/23 13:47, 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).
>>
>> PKEX would be used via the three DBus APIs on a new interface
>> SharedCodeDeviceProvisioning.
>>
>> ConfigureEnrollee(a{sv}) will start a configurator with a
>> static shared code (optionally identifier) passed in as the
>> argument to this method.
>>
>> StartEnrollee(a{sv}) will start a PKEX enrollee using a static
>> shared code (optionally identifier) passed as the argument to
>> the method.
>>
>> StartConfigurator() will start a PKEX configurator (should be
>> already registered) which will query an agent for an enrollees
>> shared code. Enrollees are distinguished by the identifier.
>>
>> After the PKEX protocol is finished, DPP bootstrapping keys have
>> been exchanged and DPP Authentication will start, followed by
>> configuration.
>> ---
>>   doc/device-provisioning-api.txt | 149 ++++++++++++++++++++++++++++++++
>>   1 file changed, 149 insertions(+)
>>
>> diff --git a/doc/device-provisioning-api.txt 
>> b/doc/device-provisioning-api.txt
>> index ac204f46..3c6fc74e 100644
>> --- a/doc/device-provisioning-api.txt
>> +++ b/doc/device-provisioning-api.txt
>> @@ -71,3 +71,152 @@ Properties    boolean Started [readonly]
>>               Indicates the DPP URI. This property is only available
>>               when Started is true.
>> +
>> +
>> +Interface    net.connman.iwd.SharedCodeDeviceProvisioning [Experimental]
>> +Object path    /net/connman/iwd/{phy0,phy1,...}/{1,2,...}
>> +
>> +        ConfigureEnrollee(a{sv})
>> +
>> +            Starts a DPP configurator using a shared code (and
>> +            optionally identifier) set in the dictionary argument.
>> +            Valid dictionary keys are:
>> +
>> +            string Code
>> +                The shared code to use. The code used by both
>> +                parties (configurator and enrollee) must match.
>> +
>> +            string Identifier
>> +                An optional identifier. The identifier used by
>> +                both parties must match. Per the DPP spec the
>> +                identifier "shall be a UTF-8 string not greater
>> +                than eighty (80) octets"
>> +
>> +            As with the DeviceProvisioning interface, configurators
>> +            must be connected to the network they wish to configure
>> +            in order to start.
>> +
>> +            Once started a configurator (acting as a responder) will
>> +            listen on the currently connected channel for an
>> +            enrollee's initial exchange request which will kick off
>> +            the shared code bootstrapping protocol (PKEX). Once
>> +            completed DPP will start automatically. Only one
>> +            enrollee can be configured per call to
>> +            ConfigureEnrollee, i.e. once PKEX/DPP is has finished
> 
> "is has finished"?
> 
>> +            (including failure) the configurator will stop.
>> +
>> +            The SharedCode methods have an eventual timeout and will
>> +            stop automatically after 2 minutes.
>> +
>> +            Possible errors:    net.connman.iwd.Busy
>> +                        net.connman.iwd.NotConnected
>> +                        net.connman.InvalidArguments
>> +
>> +        StartEnrollee(a{sv})
>> +
>> +            Starts a DPP enrollee using a shared code (and
>> +            optionally identifier) set in the dictionary argument
>> +            (described above in ConfigureEnrollee).
>> +
>> +            As with the device provisioning interface, enrollees
>> +            must be disconnected in order to start.
>> +
>> +            Once started an enrollee (acting as an initiator) will
>> +            iterate channels sending out broadcast exchange requests
>> +            waiting for a response from a configurator. A response
>> +            will kick off the shared code bootstrapping protocol
>> +            (PKEX), followed by DPP if successful. Once the
>> +            protocols have completed, or failed, the enrollee will
>> +            stop. If failed, StartEnrollee will need to be called
>> +            again to retry.
>> +
>> +            Possible errors:    net.connman.iwd.Busy
>> +                        net.connman.iwd.InvalidArguments
>> +
>> +        StartConfigurator()
> 
> You are missing return parameters for all of these methods.  Also seems 
> like Stop() method isn't documented.
> 
>> +
>> +            Start a shared code configurator using an agent to
>> +            obtain the shared code. This method is meant for an
>> +            automated use case where a configurator is capable of
>> +            configuring multiple enrollees, and distinguishing
>> +            between them by their identifier.
>> +
>> +            Prior to calling, a SharedCodeAgent must be registered
>> +            using RegisterSharedCodeAgent. Only a single agent can
>> +            be registered per SharedCodeInterface.
> 
> So the one thing to watch out for is that DPP interface can come and go, 
> unlike the Manager interface.  Since StartConfigurator() has to be 
> called for each protocol attempt, providing the agent as an argument 
> might be be a nicer shortcut?  The API is marked experimental, so we can 
> always change this.  You will probably know more once you try to 
> implement the API.

I had that thought too but was just keeping things consistent. But I'm 
fine removing the register APIs and just passing the path here.

> 
> Also, it seems to me that StartConfigurator implies that the agent is 
> active. If the agent goes away, StartConfigurator() should be aborted, no?

Yes, probably not a bad idea.

> 
>> +
>> +            This method behaves nearly the same as ConfigureEnrollee
>> +            except upon receiving an enrollees first exchange
>> +            request the registered agent will be asked for the
>> +            shared code using the RequestSharedCode method.
>> +
>> +            Though the agent can provide shared codes for multiple
>> +            enrollees, this method will only configure a single
>> +            enrollee at a time. Once completed it will need to be
>> +            called again to configure additional enrollees.
>> +
>> +            Possible errors:    net.connman.iwd.Busy
>> +                        net.connman.iwd.NotConnected
>> +                        net.connman.iwd.NoAgent
>> +
>> +        void RegisterSharedCodeAgent(object path)
>> +
>> +            Register the agent object for servicing shared code
>> +            requests on the net.connman.iwd.SharedCodeAgent
>> +            interface. There may only be one agent registered at a
>> +            time per SharedCodeDeviceProvisioning interface.
>> +
>> +            Possible Errors:    [service].Error.InvalidArguments
>> +                        [service].Error.AlreadyExists
>> +
>> +        void UnregisterSharedCodeAgent()
>> +
>> +            Unregister an existing agent.
>> +
>> +            Possible Errors:    [service].Error.NotFound
>> +
>> +Properties    boolean Started [readonly]
>> +
>> +            True if shared code device provisioning is currently
>> +            active. (configurator or enrollee is started)
>> +
>> +        string Role [readonly, optional]
>> +
>> +            Indicates the DPP role. Possible values are "enrollee"
>> +            or "configurator". This property is only available when
>> +            Started is true.
>> +
>> +SharedCodeAgent hierarchy
>> +=========================
>> +
>> +Service        unique name
>> +Interface    net.connman.iwd.SharedCodeAgent [Experimental]
>> +Object path    freely definable
>> +
>> +Methods        void Release() [noreply]
>> +
>> +            This method gets called when the service daemon
>> +            unregisters the agent.
> 
> You don't actually call this method.
> 
>> +
>> +        string RequestSharedCode(object network, string identifier)
>> +
>> +            This method gets called when a shared code is requested
>> +            for a particular enrollee, distingushed by the
>> +            identifier. The shared code agent should lookup the
>> +            identifier and return the shared code, or return an
>> +            error if not found.
> 
> Looks like you don't actually call the agent with the network object?

Yeah, this was a mistake, there should just be the one string argument.

> 
>> +
>> +            Possible Errors:    [service].Error.Canceled
>> +                        [service].Error.NotFound
>> +
>> +        void Cancel(string reason) [noreply]
>> +
>> +            This method gets called to indicate that the agent
>> +            request failed before a reply was returned. The
>> +            argument will indicate why the request is being
>> +            cancelled and may be "user-canceled", "timed-out" or
>> +            "shutdown".
> 
> You don't call this method either.
>> +
>> +Examples    Requesting a shared code for an enrollee identified by "foo"
>> +
>> +            RequestSharedCode("foo") ==> "super_secret_code"
> 
> This signature incorrect as well?
> 
> Regards,
> -Denis
diff mbox series

Patch

diff --git a/doc/device-provisioning-api.txt b/doc/device-provisioning-api.txt
index ac204f46..3c6fc74e 100644
--- a/doc/device-provisioning-api.txt
+++ b/doc/device-provisioning-api.txt
@@ -71,3 +71,152 @@  Properties	boolean Started [readonly]
 
 			Indicates the DPP URI. This property is only available
 			when Started is true.
+
+
+Interface	net.connman.iwd.SharedCodeDeviceProvisioning [Experimental]
+Object path	/net/connman/iwd/{phy0,phy1,...}/{1,2,...}
+
+		ConfigureEnrollee(a{sv})
+
+			Starts a DPP configurator using a shared code (and
+			optionally identifier) set in the dictionary argument.
+			Valid dictionary keys are:
+
+			string Code
+				The shared code to use. The code used by both
+				parties (configurator and enrollee) must match.
+
+			string Identifier
+				An optional identifier. The identifier used by
+				both parties must match. Per the DPP spec the
+				identifier "shall be a UTF-8 string not greater
+				than eighty (80) octets"
+
+			As with the DeviceProvisioning interface, configurators
+			must be connected to the network they wish to configure
+			in order to start.
+
+			Once started a configurator (acting as a responder) will
+			listen on the currently connected channel for an
+			enrollee's initial exchange request which will kick off
+			the shared code bootstrapping protocol (PKEX). Once
+			completed DPP will start automatically. Only one
+			enrollee can be configured per call to
+			ConfigureEnrollee, i.e. once PKEX/DPP is has finished
+			(including failure) the configurator will stop.
+
+			The SharedCode methods have an eventual timeout and will
+			stop automatically after 2 minutes.
+
+			Possible errors:	net.connman.iwd.Busy
+						net.connman.iwd.NotConnected
+						net.connman.InvalidArguments
+
+		StartEnrollee(a{sv})
+
+			Starts a DPP enrollee using a shared code (and
+			optionally identifier) set in the dictionary argument
+			(described above in ConfigureEnrollee).
+
+			As with the device provisioning interface, enrollees
+			must be disconnected in order to start.
+
+			Once started an enrollee (acting as an initiator) will
+			iterate channels sending out broadcast exchange requests
+			waiting for a response from a configurator. A response
+			will kick off the shared code bootstrapping protocol
+			(PKEX), followed by DPP if successful. Once the
+			protocols have completed, or failed, the enrollee will
+			stop. If failed, StartEnrollee will need to be called
+			again to retry.
+
+			Possible errors:	net.connman.iwd.Busy
+						net.connman.iwd.InvalidArguments
+
+		StartConfigurator()
+
+			Start a shared code configurator using an agent to
+			obtain the shared code. This method is meant for an
+			automated use case where a configurator is capable of
+			configuring multiple enrollees, and distinguishing
+			between them by their identifier.
+
+			Prior to calling, a SharedCodeAgent must be registered
+			using RegisterSharedCodeAgent. Only a single agent can
+			be registered per SharedCodeInterface.
+
+			This method behaves nearly the same as ConfigureEnrollee
+			except upon receiving an enrollees first exchange
+			request the registered agent will be asked for the
+			shared code using the RequestSharedCode method.
+
+			Though the agent can provide shared codes for multiple
+			enrollees, this method will only configure a single
+			enrollee at a time. Once completed it will need to be
+			called again to configure additional enrollees.
+
+			Possible errors:	net.connman.iwd.Busy
+						net.connman.iwd.NotConnected
+						net.connman.iwd.NoAgent
+
+		void RegisterSharedCodeAgent(object path)
+
+			Register the agent object for servicing shared code
+			requests on the net.connman.iwd.SharedCodeAgent
+			interface. There may only be one agent registered at a
+			time per SharedCodeDeviceProvisioning interface.
+
+			Possible Errors:	[service].Error.InvalidArguments
+						[service].Error.AlreadyExists
+
+		void UnregisterSharedCodeAgent()
+
+			Unregister an existing agent.
+
+			Possible Errors:	[service].Error.NotFound
+
+Properties	boolean Started [readonly]
+
+			True if shared code device provisioning is currently
+			active. (configurator or enrollee is started)
+
+		string Role [readonly, optional]
+
+			Indicates the DPP role. Possible values are "enrollee"
+			or "configurator". This property is only available when
+			Started is true.
+
+SharedCodeAgent hierarchy
+=========================
+
+Service		unique name
+Interface	net.connman.iwd.SharedCodeAgent [Experimental]
+Object path	freely definable
+
+Methods		void Release() [noreply]
+
+			This method gets called when the service daemon
+			unregisters the agent.
+
+		string RequestSharedCode(object network, string identifier)
+
+			This method gets called when a shared code is requested
+			for a particular enrollee, distingushed by the
+			identifier. The shared code agent should lookup the
+			identifier and return the shared code, or return an
+			error if not found.
+
+			Possible Errors:	[service].Error.Canceled
+						[service].Error.NotFound
+
+		void Cancel(string reason) [noreply]
+
+			This method gets called to indicate that the agent
+			request failed before a reply was returned. The
+			argument will indicate why the request is being
+			cancelled and may be "user-canceled", "timed-out" or
+			"shutdown".
+
+Examples	Requesting a shared code for an enrollee identified by "foo"
+
+			RequestSharedCode("foo") ==> "super_secret_code"