Access Protocol: Difference between revisions

Jump to navigation Jump to search
1,185 bytes added ,  08:45, 9 April 2019
no edit summary
No edit summary
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 4: Line 4:
== Catalyst App ==
== Catalyst App ==
* [https://github.com/Hive13/HiveWeb GitHub link]
* [https://github.com/Hive13/HiveWeb GitHub link]
* Actually do something with the temperatures presented to it.
* Add in OpenID Support
* Add in OpenID Support
** Facebook/Foursquare Checkins to the hive on entry
** Facebook/Foursquare Checkins to the hive on entry
Line 17: Line 16:
* Screen to display information
* Screen to display information
* Current measurement to measure how long a tool is on.
* Current measurement to measure how long a tool is on.
* Log temperature readings for any number of devices
* Log soda sold out information
* Log general stuff
* Log general stuff


Line 41: Line 38:
* Each device has a key pre-shared with the server to mutually authenticate w/o SSL, which some of our MCUs have no hope of doing.
* Each device has a key pre-shared with the server to mutually authenticate w/o SSL, which some of our MCUs have no hope of doing.
* The body object contains a <code>device</code> key with the name of the device requesting access - if the server doesn't know about this device, it'll fail.
* The body object contains a <code>device</code> key with the name of the device requesting access - if the server doesn't know about this device, it'll fail.
* The data object also contains an operation - if not, <code>access</code> is assumed.  Other options are <code>vend</code> and <code>log</code>. Currently, <code>log</code> does nothing but return a success.
* The body object contains a <code>data</code> object with the body of the request.  It can have several fields in it.
* Finally, for <code>vend</code> or <code>access</code>, the data object contains a <code>badge</code> key, containing the presented badge number as an integer.
** <code>version</code> - integer - 1 is assumed if not specified.  Version of the API to use.
** <code>operation</code> - string - <code>access</code> is assumed if not specified.  Other options are <code>vend</code> and <code>log</code>.
** <code>badge</code> - integer - for <code>vend</code> or <code>access</code>.  Contains the presented badge number.
** <code>random</code> - array of integers - this is random per-packet data to stop replay attacks
** <code>random_response</code> - array of integers - this must be copied from the request to the response if present; this solves a different subset of replay attacks.
* The checksum is computed like this: ([https://github.com/Hive13/HiveWeb/blob/master/lib/HiveWeb/View/ChecksummedJSON.pm Here's where it's done on the server.])
* The checksum is computed like this: ([https://github.com/Hive13/HiveWeb/blob/master/lib/HiveWeb/View/ChecksummedJSON.pm Here's where it's done on the server.])
*# Sort all of the keys recursively on the data object.
*# Sort all of the keys recursively on the data object.
Line 49: Line 50:
*# Take the SHA-512 checksum of that string - encode as a hex string - it's case-insensitive everywhere, but I use uppercase.
*# Take the SHA-512 checksum of that string - encode as a hex string - it's case-insensitive everywhere, but I use uppercase.
*# Create an object with keys of <code>data</code>, <code>device</code>, and <code>checksum</code> - that object is the body of the request or response.
*# Create an object with keys of <code>data</code>, <code>device</code>, and <code>checksum</code> - that object is the body of the request or response.
* Each data object has a <code>random</code> field - this is random per-packet data to stop replay attacks
 
* Each request should contain a <code>random_response</code> field - this must be copied from the request to the response if present; this solves a different subset of replay attacks.
=== Changes in Version 2 ===
* Version 2 of the API stops replay attacks from the client to the server.  The server has a 16-byte nonce it expects the client to send with the packet or else it'll fail.
* A <code>get_nonce</code> operation has been added to the operations.  It'll silently succeed on version 1 packets, but will return the expected nonce for the next packet otherwise.
* The nonce must be submitted in the data object as <code>nonce</code>.
* Instead of a <code>response</code> Boolean and an <code>error</code> text to indicate error condition, there are several Booleans added for each part of the verification process.
** The order in which they are generated - and in which they should be checked - is <code>checksum_valid</code>, <code>version_valid</code>, <code>nonce_valid</code>, and <code>operation_valid</code>.  Subsequent fields may not be present in a response if a field is set to false.  The <code>error</code> and <code>response</code> fields are now used by the individual operations to indicate success and provide operation-specific errors.


== General-purpose logging ==
== General-purpose logging ==
* JSON body with data, device, and checksum as described above - TBD what to do about an unknown device.
* JSON body with data, device, and checksum as described above - TBD what to do about an unknown device.
* Data field has key <code>option</code> set to <code>log</code>
* Data field has key <code>option</code> set to <code>log</code>
* An optional keys is <code>current_timestamp</code> in milliseconds, to batch several logs and let the server figure out the timesamps - <code>millis()</code> in Arduino-land works here.
* An optional key is <code>current_timestamp</code> in milliseconds, to batch several logs and let the server figure out the timesamps - <code>millis()</code> in Arduino-land works here.
* Key <code>messages</code> is an array of message objects, containing keys as below:
* Key <code>messages</code> is an array of message objects, containing keys as below:
** <code>absolute_timestamp</code> has the server compare it to <code>current_timestamp</code> to figure out when the message was generated. Optional.
** <code>absolute_timestamp</code> has the server compare it to <code>current_timestamp</code> to figure out when the message was generated. Optional.
** <code>relative_timestamp</code> is how long ago (this number is only positive) the message was generated. Optional.
** <code>relative_timestamp</code> is how long ago (this number is only positive) the message was generated. Optional.
** If neither are specified, the server will timestamp the message with when it hit the DB.
** If neither are specified, the server will timestamp the message with when it hit the DB.  If both are specified, prepare for [http://catb.org/jargon/html/N/nasal-demons.html nasal demons].
** <code>data</code> is the message text.  No reasonable length limit.  Required; the array member will be silently discarded without it.
** <code>data</code> is the message text.  No reasonable length limit.  Required; the array member will be silently discarded without it.
** <code>severity</code> is the 0-7 standard syslog values (panic, alert, crit, error, warn, notice, info, debug).  Optional; defaults to info.
** <code>severity</code> is the 0-7 standard syslog values (panic, alert, crit, error, warn, notice, info, debug).  Optional; defaults to info.
* Key <code>temperatures</code> is an array of temperature reading objects to log, containing keys as below:
* Key <code>temperatures</code> is an array of temperature reading objects to log, containing keys as below:
** <code>absolute_timestamp</code> and <code>relative_timestamp</code> function as in <code>messages</code>.
** <code>absolute_timestamp</code> and <code>relative_timestamp</code> function as in <code>messages</code>.  Missing means use the timestamp for the packet as a whole.
** <code>temperature</code> is the reading, in '''''tenths''''' of a degree Fahrenheit.  This is done to remove the need for floating-point libraries on microcontrollers, as they are large.  Required.
** <code>temperature</code> is the reading, in '''''tenths''''' of a degree Fahrenheit.  This is done to remove the need for floating-point libraries on microcontrollers, as they are large.  Required.
** <code>item</code> is which item the temperature is measuring.  Note that a device must have permission to that item to log temperatures for it.  Required; the array member will be silently discarded if missing or unauthorized.
** <code>item</code> is which item the temperature is measuring.  Note that a device must have permission to that item to log temperatures for it.  Required; the array member will be silently discarded if missing or unauthorized.


== Current protocol weaknesses and notes ==
== Current protocol weaknesses and notes ==
* You can capture a packet going to the server and replay it again and again and the server will accept it and process it.
* You can capture a Version 1 packet going to the server and replay it again and again and the server will accept it and process it.
** This could add junk log entries to the access log.
** This could add junk log entries to the access log.
** This could also drain someone's soda credits.
** This could also drain someone's soda credits.
** Solution is the server tells the client what nonce it expects back in the next packet, and stores that in the DB.  We'd also need an operation to get that nonce if the MCU lost it, and a "wrong nonce" error.
** This has been fixed in the version 2 API.  There are also two fields in the DB stating the minimum and maximum version each device can use.
* You CANNOT replay the response to a successful badge swipe and open the door, because
* You CANNOT replay the response to a successful badge swipe and open the door, because
*# The MCU only listens after a badge is presented (or a temperature is logged, but it won't call door_open() from that function).
*# The MCU only listens after a badge is presented (or a temperature is logged, but it won't call door_open() from that function).
Line 87: Line 93:
** Catalyst convention is to use Pascal case for table names.
** Catalyst convention is to use Pascal case for table names.
** Postgres convention is to use Snake case for table names.
** Postgres convention is to use Snake case for table names.
** Use <code>TIMESTMAP WITH TIME ZONE</code> for all timestamp columns.
* <code>members</code> stores member information.
* <code>members</code> stores member information.
** It needs renamed to <code>member</code> for consistency, though the app calls it <code>Member</code> with a name override.
** It needs renamed to <code>member</code> for consistency, though the app calls it <code>Member</code> with a name override.
Line 96: Line 103:
* <code>item</code> stores information about items that can be accessed - doors, tools, and so on.
* <code>item</code> stores information about items that can be accessed - doors, tools, and so on.
* <code>device_item</code> is a many-to-many showing which devices can service which items.
* <code>device_item</code> is a many-to-many showing which devices can service which items.
* <code>item_mgroup"</code> is a many-to-many granting access to an item to a group.
* <code>item_mgroup</code> is a many-to-many granting access to an item to a group.


[[Category:RFID]]
[[Category:RFID]]
973

edits

Navigation menu