170 lines
5.7 KiB
ReStructuredText
170 lines
5.7 KiB
ReStructuredText
.. _sec-api-apps:
|
|
|
|
****
|
|
Apps
|
|
****
|
|
|
|
.. contents::
|
|
|
|
.. _sec-api-apps-sessionkey:
|
|
|
|
Session Keys
|
|
============
|
|
|
|
OctoPrint offers a special API key type for apps to use, the so called App Session Key. These keys have a time based
|
|
validity and are generated by OctoPrint for requesting apps.
|
|
|
|
Obtaining those keys is based on a handshake procedure backed by cryptographic signatures using RSA. OctoPrint needs to
|
|
be aware of apps and their associated public keys (this can be achieved either via entries in ``config.yaml`` or by
|
|
installing app specific plugins which implement the ``AppPlugin`` type).
|
|
|
|
Apps can be registered within OctoPrint via ``config.yaml`` by adding them to the ``api`` > ``apps`` section, using the
|
|
application's id concatenated with its version as key, with the public key provided as item ``pubkey`` (stripped of the
|
|
``BEGIN RSA PUBLIC KEY`` and ``END RSA PUBLIC KEY`` separators and also newlines) and optionally also whether the app is
|
|
enabled or not (defaults to enabled, so can be left out if it's not to be set to disabled explicitly).
|
|
|
|
Example:
|
|
|
|
.. sourcecode:: yaml
|
|
|
|
api:
|
|
apps:
|
|
"com.example.my_octoprint_app:0.9":
|
|
pubkey: MEgCQQDYkr5Fv/YXK5ZL1uwRN4A61IagZaYLGqJ5JJGFo8wDrmpAMRqE9kK4+5hIDblC5DzfEr5oP7OA3tRO48Rf5yInAgMBAAE=
|
|
enabled: false
|
|
"com.example.my_octoprint_app:1.0":
|
|
pubkey: MEgCQQCIWfi7Nc8bcnfZJJtA6a4RyMC+sKBlMOb25OVNNB4L2v0TiGO72jVKR4osvb4oztlbRW5GkdiY0T2LJcfDYvkJAgMBAAE=
|
|
|
|
In the example, the app ``com.example.my_octoprint_app`` in version 0.9 has been disabled (e.g. due to the key having
|
|
leaked) whereas version 1.0 is fully registered with OctoPrint and may verify app session keys.
|
|
|
|
|
|
.. _sec-api-apps-sessionkey-workflow:
|
|
|
|
Workflow
|
|
--------
|
|
|
|
Apps perform the handshake by first requesting a temporary key with very limited validity,
|
|
then sending a message back to OctoPrint containing their id, version, the temporary key and a signature created with their
|
|
private key over these three pieces of data. OctoPrint then tries to verify the signature and if successful unlocks the
|
|
key to be used as a fully recognized API key.
|
|
|
|
For performing the handshake a special API exists within OctoPrint for which no API key is needed which is described below.
|
|
|
|
.. _sec-api-apps-sessionkey-get:
|
|
|
|
Obtaining a temporary session key
|
|
---------------------------------
|
|
|
|
.. http:get:: /apps/auth
|
|
|
|
Retrieve a temporary session key with a minimum validity. It can only be used as a proper API key after having been
|
|
:ref:`verified <sec-api-apps-sessionkey-verify>`.
|
|
|
|
Returns the temporary session key and the timestamp until it's valid.
|
|
|
|
**Example**:
|
|
|
|
.. sourcecode:: http
|
|
|
|
GET /apps/auth HTTP/1.1
|
|
Host: example.com
|
|
|
|
.. sourcecode:: http
|
|
|
|
HTTP/1.1 200 OK
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"unverifiedKey": "F43A844750F74AD080FE9F438D47B33C",
|
|
"validUntil": 1416220357.011
|
|
}
|
|
|
|
:statuscode 200: No error
|
|
|
|
.. _sec-api-apps-sessionkey-verify:
|
|
|
|
Verifying a temporary session key
|
|
---------------------------------
|
|
|
|
.. http:post:: /apps/auth
|
|
|
|
Verify a formerly :ref:`retrieved <sec-api-apps-sessionkey-get>` temporary session key by providing credentials and a
|
|
cryptographic signature over these credentials and the temporary key.
|
|
|
|
Returns the now verified session key and the new validity.
|
|
|
|
**Example**:
|
|
|
|
.. sourcecode:: http
|
|
|
|
POST /apps/auth HTTP/1.1
|
|
Host: example.com
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"appid": "com.example.my_octoprint_app",
|
|
"appversion": "1.0",
|
|
"key": "F43A844750F74AD080FE9F438D47B33C",
|
|
"_sig": "LGVCiolQWDc4AVn1DOcWljY0cFQxWF4pldVveUjjmL9JhiL0LnCKBbGwZ/CwKBWswFAxPaxQ0kDusVdOmCUa/w=="
|
|
}
|
|
|
|
.. sourcecode:: http
|
|
|
|
HTTP/1.1 200 OK
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"key": "F43A844750F74AD080FE9F438D47B33C",
|
|
"validUntil": 1416227497.011
|
|
}
|
|
|
|
.. _sec-api-apps-sessionkey-signature:
|
|
|
|
Creating the signature
|
|
----------------------
|
|
|
|
The signature is created by concatenating the ``appid``, ``appversion`` and ``key`` fields, separated by a ``:`` (colon),
|
|
signing the result with the app's private key using SHA-1 and then BASE64-encoding the result, stripping newlines.
|
|
|
|
Example for signature generation using Python and the `Python RSA library <https://pypi.python.org/pypi/rsa>`_:
|
|
|
|
.. sourcecode:: python
|
|
|
|
import base64
|
|
import rsa
|
|
|
|
appid = "com.example.my_octoprint_app"
|
|
version = "1.0"
|
|
unverified_key = "F43A844750F74AD080FE9F438D47B33C"
|
|
message_to_sign = appid + ":" + version + ":" + unverified_key
|
|
// => "com.example.my_octoprint_app:1.0:F43A844750F74AD080FE9F438D47B33C"
|
|
|
|
private_key = rsa.PrivateKey.load_pkcs1("...")
|
|
signature = base64.encodestring(rsa.sign(message_to_sign, private_key, "SHA-1")).replace("\n", "")
|
|
// => "LGVCiolQWDc4AVn1DOcWljY0cFQxWF4pldVveUjjmL9JhiL0LnCKBbGwZ/CwKBWswFAxPaxQ0kDusVdOmCUa/w=="
|
|
|
|
|
|
.. _sec-api-apps-sessionkey-testing:
|
|
|
|
Testing your implementation
|
|
---------------------------
|
|
|
|
If you want to use app session keys, here is the key pair with which the above examples were created, in order for you
|
|
to verify your signature implementation::
|
|
|
|
-----BEGIN RSA PRIVATE KEY-----
|
|
MIIBPQIBAAJBAIhZ+Ls1zxtyd9kkm0DprhHIwL6woGUw5vbk5U00Hgva/ROIY7va
|
|
NUpHiiy9vijO2VtFbkaR2JjRPYslx8Ni+QkCAwEAAQJARK4lFo+FEcs3yR2iQjEy
|
|
p+yaAbNQJ4hZXlVvltLAYICzOM3kyKx53/eKU59NjskLz9q6QxfleymYPWAgl4NW
|
|
fQIjAJVH8MjwNcaAquTM9z2OiFi3OC8WgaKOi5W/T+r2+B70wG8CHwDp08dqOZ/u
|
|
xcBiy4Wzpcme9bckqoVuS3gWMm+YqgcCIwCMFU07kkY0NyumtzxPdIA4F/7OGSWf
|
|
IHqWFEfvasAddHlbAh8A5UgkB3Zf7Bt+7aFSBnlvve6FWm/XDPL12xYztYgrAiIa
|
|
W3miN6FjIm+8TDowrk+nyYXG2GZefeY7QXOjYr6tlDn0
|
|
-----END RSA PRIVATE KEY-----
|
|
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
MEgCQQCIWfi7Nc8bcnfZJJtA6a4RyMC+sKBlMOb25OVNNB4L2v0TiGO72jVKR4os
|
|
vb4oztlbRW5GkdiY0T2LJcfDYvkJAgMBAAE=
|
|
-----END RSA PUBLIC KEY-----
|
|
|