Theft deterrence protocol: Difference between revisions
(→Antitheft server response: Add hints map example.) |
DanielDrake (talk | contribs) |
||
(17 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
{{draft}} |
{{draft}} |
||
This is a basic |
This is a basic theft deterrence client/server protocol for FRS. It is expected that this protocol is temporary to a degree: we expect to have a more featureful management system at some point in the future. The primary goal of this protocol is to deploy something "good enough for now" that will allow us to upgrade to a revised featureful protocol at a later date, with the benefit of some experience with the upgrade/theft deterrence system. At various points in the discussion below, we will flag features which are expected to be deprecated, replaced, or fleshed out later. |
||
== |
==Theft-deterrence client request== |
||
The |
The theft-deterrence client (OATC) will periodically send requests to the canonical theft-deterrence server. It is recommended that OATC send a request if (activation lease expiration time + time of last request) / 2 is earlier than the current time. This guarantees an server outage must last longer than (lease time / 2) in order to affect clients. |
||
The client requests and responses are [http://www.w3.org/Protocols/rfc2616/rfc2616.html standard HTTP/1.1] in order to allow them to pass unmolested through the greatest |
The client requests and responses are [http://www.w3.org/Protocols/rfc2616/rfc2616.html standard HTTP/1.1] in order to allow them to pass unmolested through the greatest variety of (stateful) firewalls, NATs, and proxies. |
||
The client request is: |
The client request is: |
||
POST /antitheft/1 HTTP/1.1 |
POST /antitheft/1/ HTTP/1.1 |
||
Host: antitheft.laptop.org |
Host: antitheft.laptop.org |
||
Authorization: OLPC-hashcash <hashcash> |
Authorization: OLPC-hashcash hc="<hashcash>" |
||
Content-Type: application/x-www-form-urlencoded |
Content-Type: application/x-www-form-urlencoded |
||
<form contents> |
<form contents> |
||
As should be obvious from the request, it is made to the URL http://antitheft.laptop.org/antitheft/1. The number at the end of the URL is a version string; later versions of this protocol will use a different suffix. The 'Authorization' line is optional, but may trigger a [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 401 response] if omitted. The response will have the following form. |
As should be obvious from the request, it is made to the URL http://antitheft.laptop.org/antitheft/1/. The number at the end of the URL is a version string; later versions of this protocol will use a different suffix. The 'Authorization' line is optional, but may trigger a [http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 401 response] if omitted. The response will have the following form. |
||
HTTP/1.1 401 Hashcash required. |
HTTP/1.1 401 Hashcash required. |
||
WWW-Authenticate: <oatc-bits> <oatc-nonce> |
WWW-Authenticate: OLPC-hashcash bits="<oatc-bits>", nonce="<oatc-nonce>" |
||
The authorization line mitigates DoS attacks. The '<hashcash>' element should be a [http://www.hashcash.org/docs/hashcash.html#stamp_format__version_1_ version 1 hashcash stamp] with the resource string equal to <oatc-nonce> and the bits field greater than or equal to <oatc-bits>. |
The authorization line mitigates DoS attacks. The '<hashcash>' element should be a [http://www.hashcash.org/docs/hashcash.html#stamp_format__version_1_ version 1 hashcash stamp] with the resource string equal to <oatc-nonce> and the bits field greater than or equal to <oatc-bits>. |
||
Line 25: | Line 25: | ||
If required, the hashcash should be checked before the form contents are accepted. A limited-size buffer may be used for the first recv on the stream to enforce this, so extra headers (or re-ordered headers) should be avoided. |
If required, the hashcash should be checked before the form contents are accepted. A limited-size buffer may be used for the first recv on the stream to enforce this, so extra headers (or re-ordered headers) should be avoided. |
||
The form contents are [http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1 encoded |
The form contents are [http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1 encoded as application/x-www-form-urlencoded]. The fields are: |
||
; serialnum : the serial number of the laptop |
; serialnum : the serial number of the laptop |
||
; version : the |
; version : the hash identifying the currently-running version on the laptop |
||
; stream : an opaque string identifying the "upgrade stream" to which the user has subscribed themself. Note that future upgrade servers may ignore this field in favor of central management |
; stream : an opaque string identifying the "upgrade stream" to which the user has subscribed themself. Note that future upgrade servers may ignore this field in favor of central management |
||
; freespace : the number of kilobytes free in [[Early Boot|/versions/pristine]] (so the upgrade server can chose an appropriate build or defer the update when space is limited). |
|||
; nonce : an opaque string randomly generated by the client so as to be highly likely unique |
; nonce : an opaque string randomly generated by the client so as to be highly likely unique |
||
; delegated : an optional hint -- see the delegation response for more information |
; delegated : an optional hint -- see the delegation response for more information |
||
== |
==Theft-deterrent server response== |
||
The response status code should be 200 if the response is accepted or 401 if the hashcash authentication failed. |
The response status code should be 200 if the response is accepted or 401 if the hashcash authentication failed. |
||
Line 43: | Line 44: | ||
The reponse body is a [[Canonical JSON]] [[Manifest Specification#Envelopes|envelope]] with type 'oatc-signed-resp' and version 1. The body is a tuple: |
The reponse body is a [[Canonical JSON]] [[Manifest Specification#Envelopes|envelope]] with type 'oatc-signed-resp' and version 1. The body is a tuple: |
||
(data, credential) |
(data, credential) |
||
where the signature field is a [[Manifest Specification#Credentials|credential]] on the data field, signed with the " |
where the signature field is a [[Manifest Specification#Credentials|credential]] on the data field, signed with the "theft-deterrence server" key. This key validates this response as coming from a trusted theft-deterrence server; it is not the same as the activation lease key, upgrade signing key, or kernel signing key. |
||
The 'data' field in the 'oatc-signed-resp' object is another [[Canonical JSON]] [[Manifest Specification#Envelopes|envelope]] with type 'oatc-resp' and version 1. The body is a map with the following keys and data: |
The 'data' field in the 'oatc-signed-resp' object is another [[Canonical JSON]] [[Manifest Specification#Envelopes|envelope]] with type 'oatc-resp' and version 1. The body is a map with the following keys and data: |
||
; nonce: value nonce-data |
; nonce: value nonce-data |
||
: the nonce-data must match the nonce provided in the request exactly. |
: the nonce-data must match the nonce provided in the request exactly. |
||
; time: value timestamp |
|||
: the timestamp is 16-character [http://en.wikipedia.org/wiki/ISO_8601 ISO 8601] UTC time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z") It gives the time on the server when the reply was made; the theft-deterrence client uses it as a check on its local time. |
|||
; stolen: hash |
; stolen: hash |
||
: the stolen field, if present, contains a ascii hexadecimal-encoded sha256 hash. The hash is either of the string "<uuid>:<nonce>" or of "<uuid>:<nonce>:STOLEN". |
: the stolen field, if present, contains a ascii hexadecimal-encoded sha256 hash. The hash is either of the string "<uuid>:<nonce>" or of "<uuid>:<nonce>:STOLEN". |
||
; |
; update : value (hash, frequency, priority, hint) |
||
: the hash identifies the new version to which we should upgrade |
: the hash identifies the new version to which we should upgrade |
||
: the frequency is a positive integer; it specifies how many times per month the laptop should poll for new updates. |
|||
: the priority is a string. |
: the priority is a string. If it has the contents "urgent" we should reboot immediately after receiving this upgrade, because it has critical security implications. If it has the contents "low", the update will be applied only if manually requested; no automatic upgrade will occur. Other contents are ignored, but the string "normal" is typically used for upgrades which are not "urgent" or "low" priority. |
||
: the hint is |
: the hint is an ordered list of string pairs. The first element of each pair identifies an upgrade mechanism, and the second element gives a hint as to where that upgrade mechanism can find the upgrade identified by the hash. The order gives a suggested prioritization of the upgrade mechanisms. For example: |
||
⚫ | |||
[ ( 'xo', 'teachers-xo.br.laptop.org:' ), |
|||
' |
( 'schoolserver-rsync', 'rsync://schoolserver/build-589' ), |
||
⚫ | |||
( 'fallback-tarball', 'http://olpc.download.redhat.org/.../build-589/devel_jffs/') ] |
|||
: the hints map thus implicitly provides a mapping from version hashes to human-readable build strings, allows us to centrally control the sources of the update (disabling certain upgrade mechanisms, using local mirrors, etc), and is extensible to provide guidance to future download mechanisms. |
: the hints map thus implicitly provides a mapping from version hashes to human-readable build strings, allows us to centrally control the sources of the update (disabling certain upgrade mechanisms, using local mirrors, etc), and is extensible to provide guidance to future download mechanisms. |
||
; delegate : value (url, key_or_fingerprint) |
; delegate : value (url, key_or_fingerprint) |
||
: the url identifies another |
: the url identifies another theft-deterrence server at which we should repeat our request. |
||
: if the 'delegated' field in the response was present, the key_or_fingerprint field will be a short opaque fingerprint corresponding to a key which the client is already expected to have. |
: if the 'delegated' field in the response was present, the key_or_fingerprint field will be a short opaque fingerprint corresponding to a key which the client is already expected to have. |
||
: if the 'delegated' field in the response was absent, the key_or_fingerprint field will be a [[Manifest Specification#Keys|key object]] identifying the public key with which the delegated server is expected to sign its responses. |
: if the 'delegated' field in the response was absent, the key_or_fingerprint field will be a [[Manifest Specification#Keys|key object]] identifying the public key with which the delegated server is expected to sign its responses. |
||
Line 66: | Line 71: | ||
: the lease-data is an activation lease in the [[Firmware Key and Signature Formats#Antitheft.2FActivation_Lease|firmware activation lease format]]. |
: the lease-data is an activation lease in the [[Firmware Key and Signature Formats#Antitheft.2FActivation_Lease|firmware activation lease format]]. |
||
The only mandatory |
The only mandatory fields in the response are 'nonce', which prevents replay attacks, and 'time', which detects clock-reset attacks. If the 'lease' field is absent, then the server does not have a newer activation lease to give to the client. If the 'delegate' field is absent, then the response of this server is authoritative. If the 'upgrade' field is absent, the server judges the client's software version adequate for the time being. The options are not exclusive -- for example, the response might have both 'lease' and 'delegate' set if it wanted to delegate upgrade management to another server, or 'upgrade' and 'delegate' set if it wanted to delegate lease management. |
||
It is recommended that any server which returns some entries with the 'stolen' field return *all* entries with the 'stolen' field, to prevent network filtering of messages with 'stolen' set. The fixed size hash used as the payload is intended to prevent filtering from being able to distinguish between normal responses and responses indicating a stolen laptop. Care should be taken to ensure that these cases can not be easily distinguished by the presence or contents of other fields in the message. For a stateless upgrade server, the 'stolen' field can be safely omitted. |
It is recommended that any server which returns some entries with the 'stolen' field return *all* entries with the 'stolen' field, to prevent network filtering of messages with 'stolen' set. The fixed size hash used as the payload is intended to prevent filtering from being able to distinguish between normal responses and responses indicating a stolen laptop. Care should be taken to ensure that these cases can not be easily distinguished by the presence or contents of other fields in the message. For a stateless upgrade server, the 'stolen' field can be safely omitted. |
||
If the 'lease' field may be present when 'stolen' is present, then the 'lease' field of a stolen machine should contain a correctly-formatted lease which is difficult to distinguish from a valid lease. For example, the UUID may be randomly chosen not to match the correct UUID for the machine, and a valid lease generated for this bogus SN/UUID pair. A proxy cannot distinguish this from a valid lease without knowing the UUID for every SN, since the UUID is not exposed in the lease format. (Note that you must not use a fixed 'bogus UUID', since it is easy to check whether a suspect lease is actually for a particular SN/<bogus UUID> pair.) The expiration time, disposition, and key id must also match that expected for a valid lease. For efficiency, randomly-generated signature data may be generated if one is careful to match the expected format of a RSA PKCS #1, version 2.1, section 8.1.1/8.2.1 signature; in particular the integer signature representative must be between 0 and n-1 and the encoded signature must be k octets long, where k is the length in octets of the RSA modulus n for the appropriate public key. |
|||
==OATC/Rainbow protocol== |
==OATC/Rainbow protocol== |
||
There are two files in /security which rainbow/userland uses to communicate with the |
There are two files in /security which rainbow/userland uses to communicate with the theft-deterrent client (oatc): |
||
/security/update-stream |
/security/update-stream |
||
/security/update-version |
/security/update-version |
||
The 'update-stream' file contains the string which is to be included in the 'stream' field of the |
The 'update-stream' file contains the string which is to be included in the 'stream' field of the theft-deterrence request. The 'update-version' file contains the string which is to be included in the 'version' field of the theft-deterrence request. |
||
There is an additional unix datagram socket in |
There is an additional unix datagram socket in |
||
/security/events |
/security/events |
||
which is used to communicate between rainbow and oatc. A datagram is sent from oatc to rainbow with the json-encoded 'oatc-resp' object whenever an |
which is used to communicate between rainbow and oatc. A datagram is sent from oatc to rainbow with the json-encoded 'oatc-resp' object whenever an theft-deterrence response is received. A short timeout on the send prevents userland from hanging oatc. The contents are parsed and used to trigger upgrades. |
||
Userland may also send blackbox data via this socket to oatc; this is left unspecified (and unimplemented) at the present. |
Userland may also send blackbox data via this socket to oatc; this is left unspecified (and unimplemented) at the present. |
||
==Server implementations== |
|||
* [http://dev.laptop.org/git/users/cscott/act-server OLPC's act-server]: a complex django-based platform for creating developer keys, activation leases, also inclusive of a partial theft deterrence protocol implementation for distributing lease updates and update advisories |
|||
* [http://dev.laptop.org/git/users/dsd/oatslite oatslite]: a small Python implementation of this protocol, supporting lease distribution and update advisories |
|||
* [http://dev.laptop.org/git/users/martin/xs-activation.git xs-activation]: the XS school server as of v0.6 includes a mod_python theft deterrence protocol implementation for distribution of act02 delegated leases and active-kill antitheft |
|||
==Client implementations== |
|||
olpc-update-query (from the olpc-update package) implements this protocol. It supports lease updates, stolen message handling, and correction of wildly-wrong system clocks, and will call into olpc-update if a software update is specified in the server's response. |
|||
[[Category:Security, activation and deployability]] |
Latest revision as of 20:13, 1 June 2012
NOTE: The contents of this page are not set in stone, and are subject to change! This page is a draft in active flux ... |
This is a basic theft deterrence client/server protocol for FRS. It is expected that this protocol is temporary to a degree: we expect to have a more featureful management system at some point in the future. The primary goal of this protocol is to deploy something "good enough for now" that will allow us to upgrade to a revised featureful protocol at a later date, with the benefit of some experience with the upgrade/theft deterrence system. At various points in the discussion below, we will flag features which are expected to be deprecated, replaced, or fleshed out later.
Theft-deterrence client request
The theft-deterrence client (OATC) will periodically send requests to the canonical theft-deterrence server. It is recommended that OATC send a request if (activation lease expiration time + time of last request) / 2 is earlier than the current time. This guarantees an server outage must last longer than (lease time / 2) in order to affect clients.
The client requests and responses are standard HTTP/1.1 in order to allow them to pass unmolested through the greatest variety of (stateful) firewalls, NATs, and proxies.
The client request is:
POST /antitheft/1/ HTTP/1.1 Host: antitheft.laptop.org Authorization: OLPC-hashcash hc="<hashcash>" Content-Type: application/x-www-form-urlencoded <form contents>
As should be obvious from the request, it is made to the URL http://antitheft.laptop.org/antitheft/1/. The number at the end of the URL is a version string; later versions of this protocol will use a different suffix. The 'Authorization' line is optional, but may trigger a 401 response if omitted. The response will have the following form.
HTTP/1.1 401 Hashcash required. WWW-Authenticate: OLPC-hashcash bits="<oatc-bits>", nonce="<oatc-nonce>"
The authorization line mitigates DoS attacks. The '<hashcash>' element should be a version 1 hashcash stamp with the resource string equal to <oatc-nonce> and the bits field greater than or equal to <oatc-bits>.
If required, the hashcash should be checked before the form contents are accepted. A limited-size buffer may be used for the first recv on the stream to enforce this, so extra headers (or re-ordered headers) should be avoided.
The form contents are encoded as application/x-www-form-urlencoded. The fields are:
- serialnum
- the serial number of the laptop
- version
- the hash identifying the currently-running version on the laptop
- stream
- an opaque string identifying the "upgrade stream" to which the user has subscribed themself. Note that future upgrade servers may ignore this field in favor of central management
- freespace
- the number of kilobytes free in /versions/pristine (so the upgrade server can chose an appropriate build or defer the update when space is limited).
- nonce
- an opaque string randomly generated by the client so as to be highly likely unique
- delegated
- an optional hint -- see the delegation response for more information
Theft-deterrent server response
The response status code should be 200 if the response is accepted or 401 if the hashcash authentication failed.
Response format:
HTTP/1.1 200 OK Content-Type: text/x-json <reponse body>
The reponse body is a Canonical JSON envelope with type 'oatc-signed-resp' and version 1. The body is a tuple:
(data, credential)
where the signature field is a credential on the data field, signed with the "theft-deterrence server" key. This key validates this response as coming from a trusted theft-deterrence server; it is not the same as the activation lease key, upgrade signing key, or kernel signing key.
The 'data' field in the 'oatc-signed-resp' object is another Canonical JSON envelope with type 'oatc-resp' and version 1. The body is a map with the following keys and data:
- nonce
- value nonce-data
- the nonce-data must match the nonce provided in the request exactly.
- time
- value timestamp
- the timestamp is 16-character ISO 8601 UTC time in basic format (no dashes or colons) and no fractional seconds. (eg: "20070816T173500Z") It gives the time on the server when the reply was made; the theft-deterrence client uses it as a check on its local time.
- stolen
- hash
- the stolen field, if present, contains a ascii hexadecimal-encoded sha256 hash. The hash is either of the string "<uuid>:<nonce>" or of "<uuid>:<nonce>:STOLEN".
- update
- value (hash, frequency, priority, hint)
- the hash identifies the new version to which we should upgrade
- the frequency is a positive integer; it specifies how many times per month the laptop should poll for new updates.
- the priority is a string. If it has the contents "urgent" we should reboot immediately after receiving this upgrade, because it has critical security implications. If it has the contents "low", the update will be applied only if manually requested; no automatic upgrade will occur. Other contents are ignored, but the string "normal" is typically used for upgrades which are not "urgent" or "low" priority.
- the hint is an ordered list of string pairs. The first element of each pair identifies an upgrade mechanism, and the second element gives a hint as to where that upgrade mechanism can find the upgrade identified by the hash. The order gives a suggested prioritization of the upgrade mechanisms. For example:
[ ( 'xo', 'teachers-xo.br.laptop.org:' ), ( 'schoolserver-rsync', 'rsync://schoolserver/build-589' ), ( 'fallback-rsync', 'rsync://updates.laptop.org/build-589'), ( 'fallback-tarball', 'http://olpc.download.redhat.org/.../build-589/devel_jffs/') ]
- the hints map thus implicitly provides a mapping from version hashes to human-readable build strings, allows us to centrally control the sources of the update (disabling certain upgrade mechanisms, using local mirrors, etc), and is extensible to provide guidance to future download mechanisms.
- delegate
- value (url, key_or_fingerprint)
- the url identifies another theft-deterrence server at which we should repeat our request.
- if the 'delegated' field in the response was present, the key_or_fingerprint field will be a short opaque fingerprint corresponding to a key which the client is already expected to have.
- if the 'delegated' field in the response was absent, the key_or_fingerprint field will be a key object identifying the public key with which the delegated server is expected to sign its responses.
- public keys are large objects; the 'delegated' hint tries to avoid sending them when unnecessary. If the delegation key changes and the client finds that it doesn't in fact have a key matching the sent fingerprint, it must retry the request to the original server with the 'delegated' hint absent.
- lease
- value lease-data
- the lease-data is an activation lease in the firmware activation lease format.
The only mandatory fields in the response are 'nonce', which prevents replay attacks, and 'time', which detects clock-reset attacks. If the 'lease' field is absent, then the server does not have a newer activation lease to give to the client. If the 'delegate' field is absent, then the response of this server is authoritative. If the 'upgrade' field is absent, the server judges the client's software version adequate for the time being. The options are not exclusive -- for example, the response might have both 'lease' and 'delegate' set if it wanted to delegate upgrade management to another server, or 'upgrade' and 'delegate' set if it wanted to delegate lease management.
It is recommended that any server which returns some entries with the 'stolen' field return *all* entries with the 'stolen' field, to prevent network filtering of messages with 'stolen' set. The fixed size hash used as the payload is intended to prevent filtering from being able to distinguish between normal responses and responses indicating a stolen laptop. Care should be taken to ensure that these cases can not be easily distinguished by the presence or contents of other fields in the message. For a stateless upgrade server, the 'stolen' field can be safely omitted.
If the 'lease' field may be present when 'stolen' is present, then the 'lease' field of a stolen machine should contain a correctly-formatted lease which is difficult to distinguish from a valid lease. For example, the UUID may be randomly chosen not to match the correct UUID for the machine, and a valid lease generated for this bogus SN/UUID pair. A proxy cannot distinguish this from a valid lease without knowing the UUID for every SN, since the UUID is not exposed in the lease format. (Note that you must not use a fixed 'bogus UUID', since it is easy to check whether a suspect lease is actually for a particular SN/<bogus UUID> pair.) The expiration time, disposition, and key id must also match that expected for a valid lease. For efficiency, randomly-generated signature data may be generated if one is careful to match the expected format of a RSA PKCS #1, version 2.1, section 8.1.1/8.2.1 signature; in particular the integer signature representative must be between 0 and n-1 and the encoded signature must be k octets long, where k is the length in octets of the RSA modulus n for the appropriate public key.
OATC/Rainbow protocol
There are two files in /security which rainbow/userland uses to communicate with the theft-deterrent client (oatc):
/security/update-stream /security/update-version
The 'update-stream' file contains the string which is to be included in the 'stream' field of the theft-deterrence request. The 'update-version' file contains the string which is to be included in the 'version' field of the theft-deterrence request.
There is an additional unix datagram socket in
/security/events
which is used to communicate between rainbow and oatc. A datagram is sent from oatc to rainbow with the json-encoded 'oatc-resp' object whenever an theft-deterrence response is received. A short timeout on the send prevents userland from hanging oatc. The contents are parsed and used to trigger upgrades.
Userland may also send blackbox data via this socket to oatc; this is left unspecified (and unimplemented) at the present.
Server implementations
- OLPC's act-server: a complex django-based platform for creating developer keys, activation leases, also inclusive of a partial theft deterrence protocol implementation for distributing lease updates and update advisories
- oatslite: a small Python implementation of this protocol, supporting lease distribution and update advisories
- xs-activation: the XS school server as of v0.6 includes a mod_python theft deterrence protocol implementation for distribution of act02 delegated leases and active-kill antitheft
Client implementations
olpc-update-query (from the olpc-update package) implements this protocol. It supports lease updates, stolen message handling, and correction of wildly-wrong system clocks, and will call into olpc-update if a software update is specified in the server's response.