From 7e669bcf6b6336ec429da949bcb4aa456971dba2 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 30 Jul 2021 10:38:27 +0200 Subject: folding history in preparation of GNU Anastasis v0.0.0 release --- doc/anastasis.texi | 6093 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6093 insertions(+) create mode 100644 doc/anastasis.texi (limited to 'doc/anastasis.texi') diff --git a/doc/anastasis.texi b/doc/anastasis.texi new file mode 100644 index 0000000..a5d8b11 --- /dev/null +++ b/doc/anastasis.texi @@ -0,0 +1,6093 @@ +\input texinfo @c -*-texinfo-*- +@c %**start of header +@setfilename anastasis.info +@documentencoding UTF-8 +@ifinfo +@*Generated by Sphinx 3.4.3.@* +@end ifinfo +@settitle Anastasis Manual +@defindex ge +@paragraphindent 0 +@exampleindent 4 +@finalout +@dircategory CATEGORY +@direntry +* MENU ENTRY: (anastasis.info). DESCRIPTION +@end direntry + +@definfoenclose strong,`,' +@definfoenclose emph,`,' +@c %**end of header + +@copying +@quotation +GNU Anastasis 0.0.0, Jul 30, 2021 + +Anastasis SARL + +Copyright @copyright{} 2020-2021 Anastasis SARL (AGPLv3+ or GFDL 1.3+) +@end quotation + +@end copying + +@titlepage +@title Anastasis Manual +@insertcopying +@end titlepage +@contents + +@c %** start of user preamble + +@c %** end of user preamble + +@ifnottex +@node Top +@top Anastasis Manual +@insertcopying +@end ifnottex + +@c %**start of body +@anchor{index doc}@anchor{0} +@c This file is part of GNU Anastasis. +@c Copyright (C) 2020-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff + +GNU Anastasis is Free Software protocol and implementation that allows +users to securely deposit @strong{core secrets} with an open set of escrow +providers and to recover these secrets if their original copies are +lost. + +Anastasis is intended for users that want to make backups of key +material, such as OpenPGP encryption keys, hard disk encryption keys +or master keys of electronic wallets. Anastasis is NOT intended to +store large amounts of secret data, it is only designed to safeguard +key material. + +Anastasis solves the issue of keeping key material both available +to the authorized user(s), and confidential from anyone else. + +With Anastasis, the @strong{core secrets} are protected from the Anastasis +escrow providers by encrypting each with a @strong{master key}. The +@strong{master key} can be split and distributed across the escrow +providers to ensure that no single escrow provider can recover the +@strong{master key} on its own. Which subset(s) of Anastasis providers +must be contacted to recover a @strong{master key} is freely configurable. + +With Anastasis, users can reliably recover their @strong{core secret}, +while Anastasis makes this difficult for everyone else. This is even +true if the user is unable to reliably remember any secret with +sufficiently high entropy: Anastasis does not simply reduce the +problem to encrypting the @strong{core secret} using some other key +material in possession of the user. + +@menu +* Documentation Overview:: + +@detailmenu + --- The Detailed Node Listing --- + +Documentation Overview + +* Introduction:: +* Installation:: +* Configuration:: +* Cryptography:: +* REST API:: +* Reducer API:: +* Authentication Methods:: +* DB Schema:: +* Design Documents:: +* Anastasis licensing information:: +* Man Pages:: +* Complete Index:: +* GNU Free Documentation License:: + +Introduction + +* User Identifiers:: +* Adversary models:: +* The recovery document:: + +Installation + +* Installing from source:: +* Installing Anastasis binary packages on Debian:: +* Installing Anastasis binary packages on Ubuntu:: + +Installing from source + +* Installing GNUnet:: +* Installing the Taler Exchange:: +* Installing the Taler Merchant:: +* Installing Anastasis:: +* Installing GNUnet-gtk:: +* Installing Anastasis-gtk:: + +Installing Anastasis binary packages on Debian + +* Installing the graphical front-end:: +* Installing the backend:: + +Installing Anastasis binary packages on Ubuntu + +* Installing the graphical front-end: Installing the graphical front-end<2>. +* Installing the backend: Installing the backend<2>. + +Configuration + +* Configuration format:: +* Using anastasis-config:: + +Cryptography + +* Key derivations:: +* Key Usage:: +* Availability Considerations:: + +Key derivations + +* Verification:: +* Encryption:: + +Key Usage + +* Encryption: Encryption<2>. +* Signatures:: + +REST API + +* HTTP Request and Response:: +* Protocol Version Ranges:: +* Common encodings:: + +Common encodings + +* Binary Data:: +* Hash codes:: +* Large numbers:: +* Timestamps:: +* Integers:: +* Objects:: +* Keys:: +* Signatures: Signatures<2>. +* Amounts:: +* Time:: +* Cryptographic primitives:: +* Signatures: Signatures<3>. +* Receiving Configuration:: +* Receiving Terms of Service:: +* Manage policy:: +* Managing truth:: + +Reducer API + +* States:: +* Backup Reducer:: +* Recovery Reducer:: +* Reducer transitions:: + +Reducer transitions + +* Initial state:: +* Common transitions:: +* Backup transitions:: +* Recovery transitions:: + +Authentication Methods + +* SMS (sms): SMS sms. +* Email verification (email): Email verification email. +* Video identification (vid): Video identification vid. +* Security question (qa): Security question qa. +* Snail mail verification (post): Snail mail verification post. + +Design Documents + +* Design Doc 001; Anastasis User Experience: Design Doc 001 Anastasis User Experience. +* Template:: + +Design Doc 001: Anastasis User Experience + +* Summary:: +* Motivation:: +* Setup Steps:: +* Show Service Status After Setup:: +* Recovery Steps:: + +Setup Steps + +* Entry point; Settings: Entry point Settings. +* Providing Identification:: +* Add Authentication Methods:: +* Confirm/Change Service Providers:: +* Defining Recovery Options:: +* Pay for Setup:: + +Recovery Steps + +* Entry point; Settings: Entry point Settings<2>. +* Providing Identification: Providing Identification<2>. +* Select Authentication Challenge:: +* Payment:: +* Enter Challenge Response:: +* Success:: + +Template + +* Summary: Summary<2>. +* Motivation: Motivation<2>. +* Requirements:: +* Proposed Solution:: +* Alternatives:: +* Drawbacks:: +* Discussion / Q&A:: + +Anastasis licensing information + +* Anastasis (git;//git.taler.net/anastasis): Anastasis git //git taler net/anastasis. +* Anastasis-gtk (git;//git.taler.net/anastasis-gtk): Anastasis-gtk git //git taler net/anastasis-gtk. +* Documentation:: + +Anastasis (git://git.taler.net/anastasis) + +* Runtime dependencies:: + +Anastasis-gtk (git://git.taler.net/anastasis-gtk) + +* Runtime dependencies: Runtime dependencies<2>. + +Man Pages + +* anastasis-config(1): anastasis-config 1. +* anastasis-gtk(1): anastasis-gtk 1. +* anastasis-httpd(1): anastasis-httpd 1. +* anastasis-reducer(1): anastasis-reducer 1. +* anastasis.conf(5): anastasis conf 5. + +anastasis-config(1) + +* Synopsis:: +* Description:: +* See Also:: +* Bugs:: + +anastasis-gtk(1) + +* Synopsis: Synopsis<2>. +* Description: Description<2>. +* See Also: See Also<2>. +* Bugs: Bugs<2>. + +anastasis-httpd(1) + +* Synopsis: Synopsis<3>. +* Description: Description<3>. +* Signals:: +* See also:: +* Bugs: Bugs<3>. + +anastasis-reducer(1) + +* Synopsis: Synopsis<4>. +* Description: Description<4>. +* See Also: See Also<3>. +* Bugs: Bugs<4>. + +anastasis.conf(5) + +* Description: Description<5>. +* SEE ALSO:: +* BUGS:: + +Description + +* GLOBAL OPTIONS:: +* Authorization options:: +* Postgres database configuration:: + +GNU Free Documentation License + +* 0. PREAMBLE: 0 PREAMBLE. +* 1. APPLICABILITY AND DEFINITIONS: 1 APPLICABILITY AND DEFINITIONS. +* 2. VERBATIM COPYING: 2 VERBATIM COPYING. +* 3. COPYING IN QUANTITY: 3 COPYING IN QUANTITY. +* 4. MODIFICATIONS: 4 MODIFICATIONS. +* 5. COMBINING DOCUMENTS: 5 COMBINING DOCUMENTS. +* 6. COLLECTIONS OF DOCUMENTS: 6 COLLECTIONS OF DOCUMENTS. +* 7. AGGREGATION WITH INDEPENDENT WORKS: 7 AGGREGATION WITH INDEPENDENT WORKS. +* 8. TRANSLATION: 8 TRANSLATION. +* 9. TERMINATION: 9 TERMINATION. +* 10. FUTURE REVISIONS OF THIS LICENSE: 10 FUTURE REVISIONS OF THIS LICENSE. +* 11. RELICENSING: 11 RELICENSING. +* ADDENDUM; How to use this License for your documents: ADDENDUM How to use this License for your documents. + +@end detailmenu +@end menu + +@node Documentation Overview,,Top,Top +@anchor{index anastasis-documentation}@anchor{1}@anchor{index documentation-overview}@anchor{2} +@chapter Documentation Overview + + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@menu +* Introduction:: +* Installation:: +* Configuration:: +* Cryptography:: +* REST API:: +* Reducer API:: +* Authentication Methods:: +* DB Schema:: +* Design Documents:: +* Anastasis licensing information:: +* Man Pages:: +* Complete Index:: +* GNU Free Documentation License:: + +@end menu + +@node Introduction,Installation,,Documentation Overview +@anchor{introduction doc}@anchor{3}@anchor{introduction introduction}@anchor{4} +@section Introduction + + +To understand how Anastasis works, you need to understand three key +concepts: user identifiers, our adversary model and the role of the +recovery document. + +@menu +* User Identifiers:: +* Adversary models:: +* The recovery document:: + +@end menu + +@node User Identifiers,Adversary models,,Introduction +@anchor{introduction user-identifiers}@anchor{5} +@subsection User Identifiers + + +To uniquely identify users, an “unforgettable” @strong{identifier} is used. This +identifier should be difficult to guess for anybody but the user. However, the +@strong{identifier} is not expected to have sufficient entropy or secrecy to be +cryptographically secure. Examples for such identifier would be a +concatenation of the full name of the user and their social security or +passport number(s). For Swiss citizens, the AHV number could also be used. + +@node Adversary models,The recovery document,User Identifiers,Introduction +@anchor{introduction adversary-models}@anchor{6} +@subsection Adversary models + + +The adversary model of Anastasis has two types of adversaries: weak +adversaries which do not know the user’s @strong{identifier}, and strong +adversaries which somehow do know a user’s @strong{identifier}. For weak +adversaries the system guarantees full confidentiality. For strong +adversaries, breaking confidentiality additionally requires that Anastasis +escrow providers must have colluded. The user is able to specify a set of +@strong{policies} which determine which Anastasis escrow providers would need to +collude to break confidentiality. These policies also set the bar for the user +to recover their core secret. + +@node The recovery document,,Adversary models,Introduction +@anchor{introduction the-recovery-document}@anchor{7} +@subsection The recovery document + + +A @strong{recovery document} includes all of the information a user needs to +recover access to their core secret. It specifies a set of @strong{escrow +methods}, which specify how the user should convince the Anastasis server +that they are “real”. Escrow methods can for example include SMS-based +verification, video identification or a security question. For each escrow +method, the Anastasis server is provided with @strong{truth}, that is data the +Anastasis operator may learn during the recovery process to authenticate the +user. Examples for truth would be a phone number (for SMS), a picture of the +user (for video identification), or the (hash of) a security answer. A strong +adversary is assumed to be able to learn the truth, while weak adversaries +must not. In addition to a set of escrow methods and associated Anastasis +server operators, the @strong{recovery document} also specifies @strong{policies}, which +describe the combination(s) of the escrow methods that suffice to obtain +access to the core secret. For example, a @strong{policy} could say that the +escrow methods (A and B) suffice, and a second policy may permit (A and C). A +different user may choose to use the policy that (A and B and C) are all +required. Anastasis imposes no limit on the number of policies in a +@strong{recovery document}, or the set of providers or escrow methods involved in +guarding a user’s secret. Weak adversaries must not be able to deduce +information about a user’s @strong{recovery document} (except for its length, which +may be exposed to an adversary which monitors the user’s network traffic). + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node Installation,Configuration,Introduction,Documentation Overview +@anchor{installation doc}@anchor{8}@anchor{installation installation}@anchor{9} +@section Installation + + +Please install the following packages before proceeding with the +exchange compilation. + + +@itemize - + +@item +libsqlite3 >= 3.16.2 + +@item +GNU libunistring >= 0.9.3 + +@item +libcurl >= 7.26 (or libgnurl >= 7.26) + +@item +libqrencode >= 4.0.0 + +@item +GNU libgcrypt >= 1.6 + +@item +libsodium >= 1.0 + +@item +libargon2 >= 20171227 + +@item +libjansson >= 2.7 + +@item +Postgres >= 9.6, including libpq + +@item +GNU libmicrohttpd >= 0.9.71 + +@item +GNUnet >= 0.14.0 (from source tarball@footnote{http://ftpmirror.gnu.org/gnunet/}) + +@item +GNU Taler exchange + +@item +GNU Taler merchant backend +@end itemize + +Except for the last two, these are available in most GNU/Linux distributions +and should just be installed using the respective package manager. + +@menu +* Installing from source:: +* Installing Anastasis binary packages on Debian:: +* Installing Anastasis binary packages on Ubuntu:: + +@end menu + +@node Installing from source,Installing Anastasis binary packages on Debian,,Installation +@anchor{installation installing-from-source}@anchor{a} +@subsection Installing from source + + +The following instructions will show how to install libgnunetutil and +the GNU Taler exchange from source. + +@menu +* Installing GNUnet:: +* Installing the Taler Exchange:: +* Installing the Taler Merchant:: +* Installing Anastasis:: +* Installing GNUnet-gtk:: +* Installing Anastasis-gtk:: + +@end menu + +@node Installing GNUnet,Installing the Taler Exchange,,Installing from source +@anchor{installation installing-gnunet}@anchor{b} +@subsubsection Installing GNUnet + + +Before you install GNUnet, you must download and install the dependencies +mentioned in the previous section, otherwise the build may succeed, but could +fail to export some of the tooling required by GNU Taler. + +To install GNUnet, unpack the tarball and change +into the resulting directory, then proceed as follows: + +@example +$ ./configure [--prefix=GNUNETPFX] +$ # Each dependency can be fetched from non standard locations via +$ # the '--with-' option. See './configure --help'. +$ make +# make install +# ldconfig +@end example + +If you did not specify a prefix, GNUnet will install to @code{/usr/local}, +which requires you to run the last step as @code{root}. +The @code{ldconfig} command (also run as @code{root}) makes the +shared object libraries (@code{.so} files) +visible to the various installed programs. + +@node Installing the Taler Exchange,Installing the Taler Merchant,Installing GNUnet,Installing from source +@anchor{installation installing-the-taler-exchange}@anchor{c} +@subsubsection Installing the Taler Exchange + + +After installing GNUnet, unpack the GNU Taler exchange tarball, +change into the resulting directory, and proceed as follows: + +@example +$ ./configure [--prefix=EXCHANGEPFX] \ + [--with-gnunet=GNUNETPFX] +$ # Each dependency can be fetched from non standard locations via +$ # the '--with-' option. See './configure --help'. +$ make +# make install +@end example + +If you did not specify a prefix, the exchange will install to @code{/usr/local}, +which requires you to run the last step as @code{root}. You have to specify +@code{--with-gnunet=/usr/local} if you installed GNUnet to @code{/usr/local} in the +previous step. + +@node Installing the Taler Merchant,Installing Anastasis,Installing the Taler Exchange,Installing from source +@anchor{installation installing-the-taler-merchant}@anchor{d} +@subsubsection Installing the Taler Merchant + + +GNU Taler merchant has these additional dependencies: + + +@itemize - + +@item +libqrencode >= 4.0.0 +@end itemize + +The following steps assume all dependencies are installed. + +First, unpack the GNU Taler merchant tarball and change into +the resulting directory. +Then, use the following commands to build and install the merchant backend: + +@example +$ ./configure [--prefix=PFX] \ + [--with-gnunet=GNUNETPFX] \ + [--with-exchange=EXCHANGEPFX] +$ # Each dependency can be fetched from non standard locations via +$ # the '--with-' option. See './configure --help'. +$ make +# make install +@end example + +If you did not specify a prefix, the exchange will install to +@code{/usr/local}, which requires you to run the last step as @code{root}. + +You have to specify @code{--with-exchange=/usr/local} and/or +@code{--with-gnunet=/usr/local} if you installed the exchange and/or +GNUnet to @code{/usr/local} in the previous steps. + +Depending on the prefixes you specified for the installation and the +distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding +lines for @code{GNUNETPFX/lib/} and @code{EXCHANGEPFX/lib/} and @code{PFX/lib/} +(replace the prefixes with the actual paths you used). Afterwards, you should +run @code{ldconfig}. Without this step, it is possible that the linker may not +find the installed libraries and launching the Taler merchant backend would +then fail. + +@node Installing Anastasis,Installing GNUnet-gtk,Installing the Taler Merchant,Installing from source +@anchor{installation installing-anastasis}@anchor{e} +@subsubsection Installing Anastasis + + +The following steps assume all dependencies are installed. + +First, unpack the Anastasis tarball and change into +the resulting directory. +Then, use the following commands to build and install Anastasis: + +@example +$ ./configure [--prefix=PFX] \ + [--with-gnunet=GNUNETPFX] \ + [--with-exchange=EXCHANGEPFX] +$ # Each dependency can be fetched from non standard locations via +$ # the '--with-' option. See './configure --help'. +$ make +# make install +@end example + +If you did not specify a prefix, Anastasis will be installed to +@code{/usr/local}, which requires you to run the last step as @code{root}. + +You have to specify @code{--with-exchange=/usr/local} and/or +@code{--with-gnunet=/usr/local} if you installed the exchange and/or +GNUnet to @code{/usr/local} in the previous steps. + +Depending on the prefixes you specified for the installation and the +distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding +lines for @code{GNUNETPFX/lib/} and @code{EXCHANGEPFX/lib/} and @code{PFX/lib/} +(replace the prefixes with the actual paths you used). Afterwards, you should +run @code{ldconfig}. Without this step, it is possible that the linker may not +find the installed libraries and launching the Anastasis backend would +then fail. + +@node Installing GNUnet-gtk,Installing Anastasis-gtk,Installing Anastasis,Installing from source +@anchor{installation installing-gnunet-gtk}@anchor{f} +@subsubsection Installing GNUnet-gtk + + +The following steps assume at least the GNUnet and Gtk+ dependencies are installed. + +First, unpack the gnunet-gtk tarball and change into the resulting directory. +Then, use the following commands to build and install gnunet-gtk: + +@example +$ ./configure [--prefix=$PFX] \ + [--with-gnunet=$GNUNETPFX] +$ # Each dependency can be fetched from non standard locations via +$ # the '--with-' option. See './configure --help'. +$ make +# make install +@end example + +It is highly recommended to use the same prefix ($PFX) for gnunet-gtk that was +used for GNUnet ($GNUNETPFX). If you did not specify a prefix, gnunet-gtk +will be installed to @code{/usr/local}, which requires you to run the last step +as @code{root}. + +You have to specify @code{--with-gnunet=/usr/local} if you installed +GNUnet to @code{/usr/local} in the previous steps. + +Depending on the prefixes you specified for the installation and the +distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding +lines for @code{$GNUNETPFX/lib/} and @code{$PFX/lib/} (replace the prefixes with the +actual paths you used). Afterwards, you should run @code{ldconfig}. Without this +step, it is possible that the linker may not find the installed libraries and +launching gnunet-gtk would then fail. + +@node Installing Anastasis-gtk,,Installing GNUnet-gtk,Installing from source +@anchor{installation installing-anastasis-gtk}@anchor{10} +@subsubsection Installing Anastasis-gtk + + +The following steps assume at least the GNUnet, gnunet-gtk and Anastasis +dependencies are installed. + +First, unpack the anastasis-gtk tarball and change into the resulting +directory. Then, use the following commands to build and install +anastasis-gtk: + +@example +$ ./configure [--prefix=PFX] \ + [--with-gnunet=GNUNETPFX] \ + [--with-exchange=EXCHANGEPFX] \ + [--with-anastasis=ANASTASISPFX] +$ # Each dependency can be fetched from non standard locations via +$ # the '--with-' option. See './configure --help'. +$ make +# make install +@end example + +If you did not specify a prefix, anastasis-gtk will be installed to +@code{/usr/local}, which requires you to run the last step as @code{root}. + +You have to specify @code{-with-anastasis=/usr/local}, @code{--with-exchange=/usr/local} and/or +@code{--with-gnunet=/usr/local} if you installed the exchange and/or +GNUnet to @code{/usr/local} in the previous steps. + +Depending on the prefixes you specified for the installation and the +distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding +lines for @code{GNUNETPFX/lib/} and @code{EXCHANGEPFX/lib/} and @code{PFX/lib/} +(replace the prefixes with the actual paths you used). Afterwards, you should +run @code{ldconfig}. Without this step, it is possible that the linker may not +find the installed libraries and launching anastasis-gtk would then fail. + +@node Installing Anastasis binary packages on Debian,Installing Anastasis binary packages on Ubuntu,Installing from source,Installation +@anchor{installation installing-anastasis-binary-packages-on-debian}@anchor{11} +@subsection Installing Anastasis binary packages on Debian + + +To install the GNU Taler Debian packages, first ensure that you have +the right Debian distribution. At this time, the packages are built for +Sid, which means you should use a system which at least includes +unstable packages in its source list. We recommend using APT pinning +to limit unstable packages to those explicitly requested. To do this, +set your @code{/etc/apt/preferences} as follows: + +@example +Package: * +Pin: release a=stable +Pin-Priority: 700 + +Package: * +Pin: release a=testing +Pin-Priority: 650 + +Package: * +Pin: release a=unstable +Pin-Priority: 600 + +Package: * +Pin: release l=Debian-Security +Pin-Priority: 1000 +@end example + +A typical @code{/etc/apt/sources.list} file for this setup +which combines Debian stable with more recent packages +from testing and unstable would look like this: + +@example +deb http://ftp.ch.debian.org/debian/ buster main +deb http://security.debian.org/debian-security buster/updates main +deb http://ftp.ch.debian.org/debian/ testing main +deb http://ftp.ch.debian.org/debian/ unstable main +@end example + +Naturally, you may want to use different mirrors depending on your region. +Additionally, you must add a file to import the GNU Taler packages. Typically, +this is done by adding a file @code{/etc/apt/sources.list.d/taler.list} that +looks like this: + +@example +deb https://deb.taler.net/apt/debian sid main +@end example + +Next, you must import the Taler Systems SA public package signing key +into your keyring and update the package lists: + +@example +# wget -O - https://taler.net/taler-systems.gpg.key | apt-key add - +# apt update +@end example + +@cartouche +@quotation Note +You may want to verify the correctness of the Taler Systems key out-of-band. +@end quotation +@end cartouche + +Now your system is ready to install the official GNU Taler binary packages +using apt. + +@menu +* Installing the graphical front-end:: +* Installing the backend:: + +@end menu + +@node Installing the graphical front-end,Installing the backend,,Installing Anastasis binary packages on Debian +@anchor{installation installing-the-graphical-front-end}@anchor{12} +@subsubsection Installing the graphical front-end + + +To install the Anastasis Gtk+ frontend, you can simply run: + +@example +# apt install anastasis-gtk +@end example + +To use @code{anastasis-gtk}, you can simply run: + +@example +$ anastasis-gtk +@end example + +@node Installing the backend,,Installing the graphical front-end,Installing Anastasis binary packages on Debian +@anchor{installation installing-the-backend}@anchor{13} +@subsubsection Installing the backend + + +If you want to install the Anastasis backend-end (which normal users do not +need), you should run: + +@example +# apt install -t sid anastasis-httpd +@end example + +Note that the latter package does not perform all of the configuration work. +It does setup the user users and the systemd service scripts, but you still +must configure the database backup, HTTP reverse proxy (typically with TLS +certificates), Taler merchant backend for payments, authentication services, +prices and the terms of service. + +Sample configuration files for the HTTP reverse proxy can be found in +@code{/etc/anastasis.conf}. + +Note that the package does not complete the integration of the backend +with the HTTP reverse proxy (typically with TLS certificates). A +configuration fragment for Nginx or Apache will be placed in +@code{/etc/@{apache,nginx@}/conf-available/anastasis.conf}. + +To operate an Anastasis backend with payments, you additionally +need to install a Taler merchant backend via: + +@example +# apt install -t sid taler-merchant-httpd +@end example + +@node Installing Anastasis binary packages on Ubuntu,,Installing Anastasis binary packages on Debian,Installation +@anchor{installation installing-anastasis-binary-packages-on-ubuntu}@anchor{14} +@subsection Installing Anastasis binary packages on Ubuntu + + +To install the GNU Taler Ubuntu packages, first ensure that you have +the right Ubuntu distribution. At this time, the packages are built for +Ubuntu 20.04 LTS (Focal Fossa). + +A typical @code{/etc/apt/sources.list.d/taler.list} file for this setup +would look like this: + +@example +deb https://deb.taler.net/apt/ubuntu/ focal-fossa main +@end example + +The last line is crucial, as it adds the GNU Taler packages. + +Next, you must import the Taler Systems SA public package signing key +into your keyring and update the package lists: + +@example +# wget -O - https://taler.net/taler-systems.gpg.key | apt-key add - +# apt update +@end example + +@cartouche +@quotation Note +You may want to verify the correctness of the Taler Systems key out-of-band. +@end quotation +@end cartouche + +Now your system is ready to install the official GNU Taler binary packages +using apt. + +@menu +* Installing the graphical front-end: Installing the graphical front-end<2>. +* Installing the backend: Installing the backend<2>. + +@end menu + +@node Installing the graphical front-end<2>,Installing the backend<2>,,Installing Anastasis binary packages on Ubuntu +@anchor{installation id1}@anchor{15} +@subsubsection Installing the graphical front-end + + +To install the Anastasis front-end, you can now simply run: + +@example +# apt install -t focal-fossa anastasis-gtk +@end example + +To use @code{anastasis-gtk}, you can simply run: + +@example +$ anastasis-gtk +@end example + +@node Installing the backend<2>,,Installing the graphical front-end<2>,Installing Anastasis binary packages on Ubuntu +@anchor{installation id2}@anchor{16} +@subsubsection Installing the backend + + +If you want to install the Anastasis backend-end (which normal users do not +need), you should run: + +@example +# apt install -t focal-fossa anastasis-httpd +@end example + +Note that the latter package does not perform all of the configuration work. +It does setup the user users and the systemd service scripts, but you still +must configure the database backup, HTTP reverse proxy (typically with TLS +certificates), Taler merchant backend for payments, authentication services, +prices and the terms of service. + +Sample configuration files for the HTTP reverse proxy can be found in +@code{/etc/anastasis.conf}. + +To operate an Anastasis backend with payments, you additionally +need to install a Taler merchant backend via: + +@example +# apt install -t sid taler-merchant-httpd +@end example + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node Configuration,Cryptography,Installation,Documentation Overview +@anchor{configuration doc}@anchor{17}@anchor{configuration configuration}@anchor{18} +@section Configuration + + +Details about the contents of the configuration file are describe in +the @code{anastasis.conf(5)} chapter. This chapter only describes the +configuration format. + +@menu +* Configuration format:: +* Using anastasis-config:: + +@end menu + +@node Configuration format,Using anastasis-config,,Configuration +@anchor{configuration configuration-format}@anchor{19} +@subsection Configuration format + + +In Taler realm, any component obeys to the same pattern to get +configuration values. According to this pattern, once the component has +been installed, the installation deploys default values in +$@{prefix@}/share/taler/config.d/, in .conf files. In order to override +these defaults, the user can write a custom .conf file and either pass +it to the component at execution time, or name it taler.conf and place +it under $HOME/.config/. + +A config file is a text file containing sections, and each section +contains its values. The right format follows: + +@example +[section1] +value1 = string +value2 = 23 + +[section2] +value21 = string +value22 = /path22 +@end example + +Throughout any configuration file, it is possible to use @code{$}-prefixed +variables, like @code{$VAR}, especially when they represent filesystem +paths. It is also possible to provide defaults values for those +variables that are unset, by using the following syntax: +@code{$@{VAR:-default@}}. However, there are two ways a user can set +@code{$}-prefixable variables: + +by defining them under a @code{[paths]} section, see example below, + +@example +[paths] +TALER_DEPLOYMENT_SHARED = $@{HOME@}/shared-data +.. +[section-x] +path-x = $@{TALER_DEPLOYMENT_SHARED@}/x +@end example + +or by setting them in the environment: + +@example +$ export VAR=/x +@end example + +The configuration loader will give precedence to variables set under +@code{[path]}, though. + +The utility @code{taler-config}, which gets installed along with the +exchange, serves to get and set configuration values without directly +editing the .conf. The option @code{-f} is particularly useful to resolve +pathnames, when they use several levels of @code{$}-expanded variables. See +@code{taler-config --help}. + +Note that, in this stage of development, the file +@code{$HOME/.config/taler.conf} can contain sections for @emph{all} the +component. For example, both an exchange and a bank can read values from +it. + +The repository @code{git://taler.net/deployment} contains examples of +configuration file used in our demos. See under @code{deployment/config}. + +@quotation + +@strong{Note} + +Expectably, some components will not work just by using default +values, as their work is often interdependent. For example, a +merchant needs to know an exchange URL, or a database name. +@end quotation + +@node Using anastasis-config,,Configuration format,Configuration +@anchor{configuration using-anastasis-config}@anchor{1a} +@subsection Using anastasis-config + + +The tool @code{anastasis-config} can be used to extract or manipulate +configuration values; however, the configuration use the well-known INI +file format and can also be edited by hand. + +Run + +@example +$ anastasis-config -s $SECTION +@end example + +to list all of the configuration values in section @code{$SECTION}. + +Run + +@example +$ anastasis-config -s $section -o $option +@end example + +to extract the respective configuration value for option @code{$option} in +section @code{$section}. + +Finally, to change a setting, run + +@example +$ anastasis-config -s $section -o $option -V $value +@end example + +to set the respective configuration value to @code{$value}. Note that you +have to manually restart the Taler backend after you change the +configuration to make the new configuration go into effect. + +Some default options will use $-variables, such as @code{$DATADIR} within +their value. To expand the @code{$DATADIR} or other $-variables in the +configuration, pass the @code{-f} option to @code{anastasis-config}. For example, +compare: + +@example +$ anastasis-config -s ACCOUNT-bank \ + -o WIRE_RESPONSE +$ anastasis-config -f -s ACCOUNT-bank \ + -o WIRE_RESPONSE +@end example + +While the configuration file is typically located at +@code{$HOME/.config/taler.conf}, an alternative location can be specified +to @code{taler-merchant-httpd} and @code{anastasis-config} using the @code{-c} +option. + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node Cryptography,REST API,Configuration,Documentation Overview +@anchor{cryptography doc}@anchor{1b}@anchor{cryptography cryptography}@anchor{1c} +@section Cryptography + + +When a user needs to interact with Anastasis, the system first derives some key +material, but not the master secret, from the user’s @strong{identifier} using +different HKDFs. These HKDFs are salted using the respective escrow +provider’s @strong{server salt}, which ensures that the accounts for the same user +cannot be easily correlated across the various Anastasis servers. + +Each Anastasis server uses an EdDSA @strong{account key} to identify the account of +the user. The account private key is derived from the user’s @strong{identifier} using +a computationally expensive cryptographic hash function. Using an +expensive hash algorithm is assumed to make it infeasible for a weak adversary to +determine account keys by brute force (without knowing the user’s identifier). +However, it is assumed that a strong adversary performing a targeted attack can +compute the account key pair. + +The public account key is Crockford base32-encoded in the URI to identify the +account, and used to sign requests. These signatures are also provided in +base32-encoding and transmitted using the HTTP header +@code{Anastasis-Account-Signature}. + +When confidential data is uploaded to an Anastasis server, the respective +payload is encrypted using AES-GCM with a symmetric key and initialization +vector derived from the @strong{identifier} and a high-entropy @strong{nonce}. The +nonce and the GCM tag are prepended to the ciphertext before being uploaded to +the Anastasis server. This is done whenever confidential data is stored with +the server. + +The @strong{core secret} of the user is (AES) encrypted using a symmetric @strong{master +key}. Recovering this master key requires the user to satisfy a particular +@strong{policy}. Policies specify a set of @strong{escrow methods}, each of which leads +the user to a @strong{key share}. Combining those key shares (by hashing) allows +the user to obtain a @strong{policy key}, which can be used to decrypt the @strong{master +key}. There can be many policies, satisfying any of these will allow the +user to recover the master key. A @strong{recovery document} contains the +encrypted @strong{core secret}, a set of escrow methods and a set of policies. + +@menu +* Key derivations:: +* Key Usage:: +* Availability Considerations:: + +@end menu + +@node Key derivations,Key Usage,,Cryptography +@anchor{cryptography key-derivations}@anchor{1d} +@subsection Key derivations + + +EdDSA and ECDHE public keys are always points on Curve25519 and represented +using the standard 256 bit Ed25519 compact format. The binary representation +is converted to Crockford Base32 when transmitted inside JSON or as part of +URLs. + +To start, a user provides their private, unique and unforgettable +@strong{identifier} as a seed to identify their account. For example, this could +be a social security number together with their full name. Specifics may +depend on the cultural context, in this document we will simply refer to this +information as the @strong{identifier}. + +This identifier will be first hashed with Argon2, to provide a @strong{kdf_id} +which will be used to derive other keys later. The Hash must also include the +respective @strong{server_salt}. This also ensures that the @strong{kdf_id} is different +on each server. The use of Argon2 and the respective @strong{server_salt} is intended +to make it difficult to brute-force @strong{kdf_id} values and help protect the user’s +privacy. Also this ensures that the @strong{kdf_id}s on every server differs. However, +we do not assume that the @strong{identifier} or the @strong{kdf_id} cannot be +determined by an adversary performing a targeted attack, as a user’s +@strong{identifier} is likely to always be known to state actors and may +likely also be available to other actors. + +@example +kdf_id := Argon2( identifier, server_salt, keysize ) +@end example + +@strong{identifier}: The secret defined from the user beforehand. + +@strong{server_salt}: The salt from the Server. + +@strong{keysize}: The desired output size of the KDF, here 32 bytes. + +@menu +* Verification:: +* Encryption:: + +@end menu + +@node Verification,Encryption,,Key derivations +@anchor{cryptography verification}@anchor{1e} +@subsubsection Verification + + +For users to authorize “policy” operations we need an EdDSA key pair. As we +cannot assure that the corresponding private key is truly secret, such policy +operations must never be destructive: Should an adversary learn the private +key, they could access (and with the @strong{kdf_id}, decrypt) the user’s policy (but +not the core secret), or upload a new version of the +@strong{encrypted recovery document} (but not delete an existing version). + +For the generation of the private key we use the @strong{kdf_id} as the entropy source, +hash it to derive a base secret which will then be processed to fit the +requirements for EdDSA private keys. From the private key we can then +generate the corresponding public key. Here, “ver” is used as a salt for the +HKDF to ensure that the result differs from other cases where we hash +@strong{kdf_id}. + +@example +ver_secret := HKDF(kdf_id, "ver", keysize) +eddsa_priv := eddsa_d_to_a(ver_secret) +eddsa_pub := get_EdDSA_Pub(eddsa_priv) +@end example + +@strong{HKDF()}: The HKDF-function uses two phases: First we use HMAC-SHA512 for the extraction phase, then HMAC-SHA256 is used for expansion phase. + +@strong{kdf_id}: Hashed identifier. + +@strong{key_size}: Size of the output, here 32 bytes. + +@strong{ver_secret}: Derived key from the @code{kdf_id}, serves as intermediate step for the generation of the private key. + +@strong{eddsa_d_to_a()}: Function which converts the ver_key to a valid EdDSA private key. Specifically, assuming the value @code{eddsa_priv} is in a 32-byte array “digest”, the function clears and sets certain bits as follows: + +@example +digest[0] = (digest[0] & 0x7f) | 0x40; +digest[31] &= 0xf8; +@end example + +@strong{eddsa_priv}: The generated EdDSA private key. + +@strong{eddsa_pub}: The generated EdDSA public key. + +@node Encryption,,Verification,Key derivations +@anchor{cryptography encryption}@anchor{1f} +@subsubsection Encryption + + +For symmetric encryption of data we use AES256-GCM. For this we need a +symmetric key and an initialization vector (IV). To ensure that the +symmetric key changes for each encryption operation, we compute the +key material using an HKDF over a @code{nonce} and the @code{kdf_id}. + +@example +(iv,key) := HKDF(kdf_id, nonce, keysize + ivsize) +@end example + +@strong{HKDF()}: The HKDF-function uses two phases: First we use HMAC-SHA512 for the extraction phase, then HMAC-SHA256 is used for expansion phase. + +@strong{kdf_id}: Hashed identifier. + +@strong{keysize}: Size of the AES symmetric key, here 32 bytes. + +@strong{ivsize}: Size of the AES GCM IV, here 12 bytes. + +@strong{prekey}: Original key material. + +@strong{nonce}: 32-byte nonce, must never match “ver” (which it cannot as the length is different). Of course, we must +avoid key reuse. So, we have to use different nonces to get different keys and IVs (see below). + +@strong{key}: Symmetric key which is later used to encrypt the documents with AES256-GCM. + +@strong{iv}: IV which will be used for AES-GCM. + +@node Key Usage,Availability Considerations,Key derivations,Cryptography +@anchor{cryptography key-usage}@anchor{20} +@subsection Key Usage + + +The keys we have generated are then used to encrypt the @strong{recovery document} and +the @strong{key_share} of the user. + +@menu +* Encryption: Encryption<2>. +* Signatures:: + +@end menu + +@node Encryption<2>,Signatures,,Key Usage +@anchor{cryptography id1}@anchor{21} +@subsubsection Encryption + + +Before every encryption a 32-byte nonce is generated. +From this the symmetric key is computed as described above. +We use AES256-GCM for the encryption of the @strong{recovery document} and +the @strong{key_share}. To ensure that the key derivation for the encryption +of the @strong{recovery document} differs fundamentally from that of an +individual @strong{key share}, we use different salts (“erd” and “eks”, respectively). + +@example +(iv0, key0) := HKDF(key_id, nonce0, "erd", keysize + ivsize) +(encrypted_recovery_document, aes_gcm_tag) := AES256_GCM(recovery_document, key0, iv0) +(iv_i, key_i) := HKDF(key_id, nonce_i, "eks", [optional data], keysize + ivsize) +(encrypted_key_share_i, aes_gcm_tag_i) := AES256_GCM(key_share_i, key_i, iv_i) +@end example + +@strong{encrypted_recovery_document}: The encrypted @strong{recovery document} which contains the escrow methods, policies +and the encrypted @strong{core secret}. + +@strong{nonce0}: Nonce which is used to generate @emph{key0} and @emph{iv0} which are used for the encryption of the @emph{recovery document}. +Nonce must contain the string “ERD”. + +@strong{optional data}: Key material that optionally is contributed from the authentication method to further obfuscate the key share from the escrow provider. + +@strong{encrypted_key_share_i}: The encrypted @strong{key_share} which the escrow provider must release upon successful authentication. +Here, @strong{i} must be a positive number used to iterate over the various @strong{key shares} used for the various @strong{escrow methods} +at the various providers. + +@strong{nonce_i}: Nonce which is used to generate @emph{key_i} and @emph{iv_i} which are used for the encryption of the @strong{key share}. @strong{i} must be +the same number as specified above for @emph{encrypted_key_share_i}. Nonce must contain the string “EKS” plus the according @emph{i}. + +As a special rule, when a @strong{security question} is used to authorize access to an +@strong{encrypted_key_share_i}, then the salt “eks” is replaced with an (expensive) hash +of the answer to the security question as an additional way to make the key share +inaccessible to those who do not have the answer: + +@example +powh := POW_HASH (qsalt, answer) +ekss := HKDF("Anastasis-secure-question-uuid-salting", + powh, + uuid); +(iv_i, key_i) := HKDF(key_id, nonce_i, ekss, [optional data], keysize + ivsize) +@end example + +@strong{qsalt}: Salt value used to hash answer to satisfy the challenge to prevent the provider from determining the answer via guessing. + +@strong{answer}: Answer to the security question, in UTF-8, as entered by the user. + +@strong{powh}: Result of the (expensive, proof-of-work) hash algorithm. + +@strong{uuid}: UUID of the challenge associated with the security question and the encrypted key share. + +@strong{ekss}: Replacement salt to be used instead of “eks” when deriving the key to encrypt/decrypt the key share. + +@node Signatures,,Encryption<2>,Key Usage +@anchor{cryptography signatures}@anchor{22} +@subsubsection Signatures + + +The EdDSA keys are used to sign the data sent from the client to the +server. Everything the client sends to server is signed. The following +algorithm is equivalent for @strong{Anastasis-Policy-Signature}. + +@example +(anastasis-account-signature) := eddsa_sign(h_body, eddsa_priv) +ver_res := eddsa_verifiy(h_body, anastasis-account-signature, eddsa_pub) +@end example + +@strong{anastasis-account-signature}: Signature over the SHA-512 hash of the body using the purpose code @code{TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD} (1400) (see GNUnet EdDSA signature API for the use of purpose). + +@strong{h_body}: The hashed body. + +@strong{ver_res}: A boolean value. True: Signature verification passed, False: Signature verification failed. + +When requesting policy downloads, the client must also provide a signature: + +@example +(anastasis-account-signature) := eddsa_sign(version, eddsa_priv) +ver_res := eddsa_verifiy(version, anastasis-account-signature, eddsa_pub) +@end example + +@strong{anastasis-account-signature}: Signature over the SHA-512 hash of the body using the purpose code @code{TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD} (1401) (see GNUnet EdDSA signature API for the use of purpose). + +@strong{version}: The version requested as a 64-bit integer, 2^64-1 for the “latest version”. + +@strong{ver_res}: A boolean value. True: Signature verification passed, False: Signature verification failed. + +@node Availability Considerations,,Key Usage,Cryptography +@anchor{cryptography availability-considerations}@anchor{23} +@subsection Availability Considerations + + +Anastasis considers two main threats against availability. First, the +Anastasis server operators must be protected against denial-of-service attacks +where an adversary attempts to exhaust the operator’s resources. The API protects +against these attacks by allowing operators to set fees for all +operations. Furthermore, all data stored comes with an expiration logic, so an +attacker cannot force servers to store data indefinitely. + +A second availability issue arises from strong adversaries that may be able to +compute the account keys of some user. While we assume that such an adversary +cannot successfully authenticate against the truth, the account key does +inherently enable these adversaries to upload a new policy for the account. +This cannot be prevented, as the legitimate user must be able to set or change +a policy using only the account key. To ensure that an adversary cannot +exploit this, policy uploads first of all never delete existing policies, but +merely create another version. This way, even if an adversary uploads a +malicious policy, a user can still retrieve an older version of the policy to +recover access to their data. This append-only storage for policies still +leaves a strong adversary with the option of uploading many policies to +exhaust the Anastasis server’s capacity. We limit this attack by requiring a +policy upload to include a reference to a @strong{payment identifier} from a payment +made by the user. Thus, a policy upload requires both knowledge of the +@strong{identity} and making a payment. This effectively prevents an adversary +from using the append-only policy storage from exhausting Anastasis server +capacity. + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node REST API,Reducer API,Cryptography,Documentation Overview +@anchor{rest doc}@anchor{24}@anchor{rest rest-api}@anchor{25} +@section REST API + + +@c This file is part of Anastasis +@c +@c Copyright (C) 2014-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff + +@menu +* HTTP Request and Response:: +* Protocol Version Ranges:: +* Common encodings:: + +@end menu + +@node HTTP Request and Response,Protocol Version Ranges,,REST API +@anchor{rest http-common}@anchor{26}@anchor{rest http-request-and-response}@anchor{27} +@subsection HTTP Request and Response + + +Certain response formats are common for all requests. They are documented here +instead of with each individual request. Furthermore, we note that clients may +theoretically fail to receive any response. In this case, the client should +verify that the Internet connection is working properly, and then proceed to +handle the error as if an internal error (500) had been returned. + +@anchor{rest any--*}@anchor{28} +@deffn {HTTP Any} ANY /* + +@strong{Request:} + +Unless specified otherwise, HTTP requests that carry a message body must +have the content type @code{application/json}. + +@*Request Headers: + +@itemize * + +@item +Content-Type@footnote{https://tools.ietf.org/html/rfc7231#section-3.1.1.5} – application/json +@end itemize + + +@strong{Response:} + +@*Response Headers: + +@itemize * + +@item +Content-Type@footnote{https://tools.ietf.org/html/rfc7231#section-3.1.1.5} – application/json +@end itemize + + + +@table @asis + +@item 200 Ok@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}: + +The request was successful. + +@item 400 Bad request@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}: + +One of the arguments to the request is missing or malformed. + +@item 500 Internal server error@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1}: + +This always indicates some serious internal operational error of the Anastasis +provider, such as a program bug, database problems, etc., and must not be used for +client-side problems. When facing an internal server error, clients should +retry their request after some delay. We recommended initially trying after +1s, twice more at randomized times within 1 minute, then the user should be +informed and another three retries should be scheduled within the next 24h. +If the error persists, a report should ultimately be made to the auditor, +although the auditor API for this is not yet specified. However, as internal +server errors are always reported to the exchange operator, a good operator +should naturally be able to address them in a timely fashion, especially +within 24h. +@end table + +Unless specified otherwise, all error status codes (4xx and 5xx) have a message +body with an @ref{29,,ErrorDetail} JSON object. + +@strong{Details:} + +@example +interface ErrorDetail @{ + + // Numeric error code unique to the condition, see `@w{`}gnu-taler-error-codes`@w{`} in GANA. + // The other arguments are specific to the error value reported here. + code: number; + + // Human-readable description of the error, i.e. "missing parameter", "commitment violation", ... + // Should give a human-readable hint about the error's nature. Optional, may change without notice! + hint?: string; + +@} +@end example +@end deffn + +@node Protocol Version Ranges,Common encodings,HTTP Request and Response,REST API +@anchor{rest protocol-version-ranges}@anchor{2a} +@subsection Protocol Version Ranges + + +Anastasis services expose the range of API versions they support. Clients in +turn have an API version range they support. These version ranges are written +down in the libtool version format@footnote{https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html}. + +A protocol version is a positive, non-zero integer. A protocol version range consists of three components: + + +@enumerate + +@item +The @code{current} version. This is the latest version of the protocol supported by the client or service. + +@item +The @code{revision} number. This value should usually not be interpreted by the client/server, but serves +purely as a comment. Each time a service/client for a protocol is updated while supporting the same +set of protocol versions, the revision should be increased. +In rare cases, the revision number can be used to work around unintended breakage in deployed +versions of a service. This is discouraged and should only be used in exceptional situations. + +@item +The @code{age} number. This non-zero integer identifies with how many previous protocol versions this +implementation is compatible. An @code{age} of 0 implies that the implementation only supports +the @code{current} protocol version. The @code{age} must be less or equal than the @code{current} protocol version. +@end enumerate + +To avoid confusion with semantic versions, the protocol version range is written down in the following format: + +@example +current[:revision[:age]] +@end example + +The angle brackets mark optional components. If either @code{revision} or @code{age} are omitted, they default to 0. + +Examples: + + +@itemize * + +@item +“1” and “1” are compatible + +@item +“1” and “2” are @strong{incompatible} + +@item +“2:0:1” and “1:0:0” are compatible + +@item +“2:5:1” and “1:10:0” are compatible + +@item +“4:0:1” and “2:0:0” are @strong{incompatible} + +@item +“4:0:1” and “3:0:0” are compatible +@end itemize + +@cartouche +@quotation Note +Semantic versions@footnote{https://semver.org/} are not a good tool for this job, as we concisely want to express +that the client/server supports the last @code{n} versions of the protocol. +Semantic versions don’t support this, and semantic version ranges are too complex for this. +@end quotation +@end cartouche + +@cartouche +@quotation Warning +A client doesn’t have one single protocol version range. Instead, it has +a protocol version range for each type of service it talks to. +@end quotation +@end cartouche + +@cartouche +@quotation Warning +For privacy reasons, the protocol version range of a client should not be +sent to the service. Instead, the client should just use the two version ranges +to decide whether it will talk to the service. +@end quotation +@end cartouche + +@node Common encodings,,Protocol Version Ranges,REST API +@anchor{rest common-encodings}@anchor{2b}@anchor{rest encodings-ref}@anchor{2c} +@subsection Common encodings + + +This section describes how certain types of values are represented throughout the API. + +@menu +* Binary Data:: +* Hash codes:: +* Large numbers:: +* Timestamps:: +* Integers:: +* Objects:: +* Keys:: +* Signatures: Signatures<2>. +* Amounts:: +* Time:: +* Cryptographic primitives:: +* Signatures: Signatures<3>. +* Receiving Configuration:: +* Receiving Terms of Service:: +* Manage policy:: +* Managing truth:: + +@end menu + +@node Binary Data,Hash codes,,Common encodings +@anchor{rest base32}@anchor{2d}@anchor{rest binary-data}@anchor{2e} +@subsubsection Binary Data + + +@example +type Base32 = string; +@end example + +Binary data is generally encoded using Crockford’s variant of Base32 +(@indicateurl{http://www.crockford.com/wrmg/base32.html}), except that “U” is not excluded +but also decodes to “V” to make OCR easy. We will still simply use the JSON +type “base32” and the term “Crockford Base32” in the text to refer to the +resulting encoding. + +@node Hash codes,Large numbers,Binary Data,Common encodings +@anchor{rest hash-codes}@anchor{2f} +@subsubsection Hash codes + + +Hash codes are strings representing base32 encoding of the respective +hashed data. See @ref{2d,,base32}. + +@example +// 64-byte hash code. +type HashCode = string; +@end example + +@example +// 32-byte hash code. +type ShortHashCode = string; +@end example + +@node Large numbers,Timestamps,Hash codes,Common encodings +@anchor{rest large-numbers}@anchor{30} +@subsubsection Large numbers + + +Large numbers such as 256 bit keys, are transmitted as other binary data in +Crockford Base32 encoding. + +@node Timestamps,Integers,Large numbers,Common encodings +@anchor{rest timestamps}@anchor{31} +@subsubsection Timestamps + + +Timestamps are represented by the following structure: + +@example +interface Timestamp @{ + // Milliseconds since epoch, or the special + // value "never" to represent an event that will + // never happen. + t_ms: number | "never"; +@} +@end example + +@example +interface Duration @{ + // Duration in milliseconds or "forever" + // to represent an infinite duration. + d_ms: number | "forever"; +@} +@end example + +@node Integers,Objects,Timestamps,Common encodings +@anchor{rest integers}@anchor{32}@anchor{rest publickey}@anchor{33} +@subsubsection Integers + + +@example +// JavaScript numbers restricted to integers. +type Integer = number; +@end example + +@node Objects,Keys,Integers,Common encodings +@anchor{rest objects}@anchor{34} +@subsubsection Objects + + +@example +// JavaScript objects, no further restrictions. +type Object = object; +@end example + +@node Keys,Signatures<2>,Objects,Common encodings +@anchor{rest keys}@anchor{35} +@subsubsection Keys + + +@example +// EdDSA and ECDHE public keys always point on Curve25519 +// and represented using the standard 256 bits Ed25519 compact format, +// converted to Crockford `Base32`. +type EddsaPublicKey = string; +@end example + +@example +// EdDSA and ECDHE public keys always point on Curve25519 +// and represented using the standard 256 bits Ed25519 compact format, +// converted to Crockford `Base32`. +type EddsaPrivateKey = string; +@end example + +@node Signatures<2>,Amounts,Keys,Common encodings +@anchor{rest signature}@anchor{36}@anchor{rest signatures}@anchor{37} +@subsubsection Signatures + + +@example +// EdDSA signatures are transmitted as 64-bytes `base32` +// binary-encoded objects with just the R and S values (base32_ binary-only). +type EddsaSignature = string; +@end example + +@node Amounts,Time,Signatures<2>,Common encodings +@anchor{rest amount}@anchor{38}@anchor{rest amounts}@anchor{39} +@subsubsection Amounts + + +@example +type Amount = string; +@end example + +Amounts of currency are serialized as a string of the format +@code{:}. Taler treats monetary amounts as +fixed-precision numbers, with 8 decimal places. Unlike floating point numbers, +this allows accurate representation of monetary amounts. + +The following constrains apply for a valid amount: + + +@enumerate + +@item +The @code{} part must be at most 11 characters long and may only consist +of ASCII letters (@code{a-zA-Z}). + +@item +The integer part of @code{} may be at most 2^52. + +@item +The fractional part of @code{} may contain at most 8 decimal digits. +@end enumerate + +@cartouche +@quotation Note +“EUR:1.50” and “EUR:10” are valid amounts. These are all invalid amounts: “A:B:1.5”, “EUR:4503599627370501.0”, “EUR:1.”, “EUR:.1”. +@end quotation +@end cartouche + +An amount that is prefixed with a @code{+} or @code{-} character is also used in certain contexts. +When no sign is present, the amount is assumed to be positive. + +@node Time,Cryptographic primitives,Amounts,Common encodings +@anchor{rest time}@anchor{3a} +@subsubsection Time + + +In signed messages, time is represented using 64-bit big-endian values, +denoting microseconds since the UNIX Epoch. @code{UINT64_MAX} represents “never”. + +@example +struct GNUNET_TIME_Absolute @{ + uint64_t timestamp_us; +@}; +struct GNUNET_TIME_AbsoluteNBO @{ + uint64_t abs_value_us__; // in network byte order +@}; +@end example + +@node Cryptographic primitives,Signatures<3>,Time,Common encodings +@anchor{rest cryptographic-primitives}@anchor{3b} +@subsubsection Cryptographic primitives + + +All elliptic curve operations are on Curve25519. Public and private keys are +thus 32 bytes, and signatures 64 bytes. For hashing, including HKDFs, Taler +uses 512-bit hash codes (64 bytes). + +@example +struct GNUNET_HashCode @{ + uint8_t hash[64]; // usually SHA-512 +@}; +@end example +@anchor{rest taler-ecdhephemeralpublickeyp}@anchor{3c} +@example +struct TALER_EcdhEphemeralPublicKeyP @{ + uint8_t ecdh_pub[32]; +@}; +@end example + +@example +struct UUID @{ + uint32_t value[4]; +@}; +@end example + +@node Signatures<3>,Receiving Configuration,Cryptographic primitives,Common encodings +@anchor{rest id1}@anchor{3d}@anchor{rest id2}@anchor{3e} +@subsubsection Signatures + + +Any piece of signed data, complies to the abstract data structure given below. + +@example +struct Data @{ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + type1_t payload1; + type2_t payload2; + ... +@}; + +/*From gnunet_crypto_lib.h*/ +struct GNUNET_CRYPTO_EccSignaturePurpose @{ + /** + + The following constraints apply for a valid amount: + + * This field is used to express the context in + * which the signature is made, ensuring that a + * signature cannot be lifted from one part of the protocol + * to another. See `src/include/taler_signatures.h` within the + * exchange's codebase (git://taler.net/exchange). + */ + uint32_t purpose; + /** + * This field equals the number of bytes being signed, + * namely 'sizeof (struct Data)'. + */ + uint32_t size; +@}; +@end example +@anchor{rest salt}@anchor{3f} +@node Receiving Configuration,Receiving Terms of Service,Signatures<3>,Common encodings +@anchor{rest config}@anchor{40}@anchor{rest receiving-configuration}@anchor{41} +@subsubsection Receiving Configuration + + +@anchor{rest get--config}@anchor{42} +@deffn {HTTP Get} GET /config + +Obtain the configuration details of the escrow provider. + +@strong{Response:} + +Returns an @ref{43,,EscrowConfigurationResponse}. +@anchor{rest escrowconfigurationresponse}@anchor{43} +@example +interface EscrowConfigurationResponse @{ + + // Protocol identifier, clarifies that this is an Anastasis provider. + name: "anastasis"; + + // libtool-style representation of the Exchange protocol version, see + // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning + // The format is "current:revision:age". + version: string; + + // Currency in which this provider processes payments. + currency: string; + + // Supported authorization methods. + methods: AuthorizationMethodConfig[]; + + // Maximum policy upload size supported. + storage_limit_in_megabytes: number; + + // Payment required to maintain an account to store policy documents for a year. + // Users can pay more, in which case the storage time will go up proportionally. + annual_fee: Amount; + + // Payment required to upload truth. To be paid per upload. + truth_upload_fee: Amount; + + // Limit on the liability that the provider is offering with + // respect to the services provided. + liability_limit: Amount; + + // Salt value with 128 bits of entropy. + // Different providers + // will use different high-entropy salt values. The resulting + // **provider salt** is then used in various operations to ensure + // cryptographic operations differ by provider. A provider must + // never change its salt value. + server_salt: string; + +@} +@end example +@anchor{rest authorizationmethodconfig}@anchor{44} +@example +interface AuthorizationMethodConfig @{ + // Name of the authorization method. + type: string; + + // Fee for accessing key share using this method. + cost: Amount; + +@} +@end example +@end deffn + +@node Receiving Terms of Service,Manage policy,Receiving Configuration,Common encodings +@anchor{rest receiving-terms-of-service}@anchor{45}@anchor{rest terms}@anchor{46} +@subsubsection Receiving Terms of Service + + +@anchor{rest get--terms}@anchor{47} +@deffn {HTTP Get} GET /terms + +Obtain the terms of service provided by the escrow provider. + +@strong{Response:} + +Returns the terms of service of the provider, in the best language +and format available based on the client’s request. +@end deffn + +@anchor{rest get--privacy}@anchor{48} +@deffn {HTTP Get} GET /privacy + +Obtain the privacy policy of the service provided by the escrow provider. + +@strong{Response:} + +Returns the privacy policy of the provider, in the best language +and format available based on the client’s request. +@end deffn + +@node Manage policy,Managing truth,Receiving Terms of Service,Common encodings +@anchor{rest id3}@anchor{49}@anchor{rest manage-policy}@anchor{4a} +@subsubsection Manage policy + + +This API is used by the Anastasis client to deposit or request encrypted +recovery documents with the escrow provider. Generally, a client will deposit +the same encrypted recovery document with each escrow provider, but provide +a different truth to each escrow provider. + +Operations by the client are identified and authorized by @code{$ACCOUNT_PUB}, which +should be kept secret from third parties. @code{$ACCOUNT_PUB} should be an account +public key using the Crockford base32-encoding. + +In the following, UUID is always defined and used according to RFC 4122@footnote{https://tools.ietf.org/html/rfc4122}. + +@anchor{rest get--policy-$ACCOUNT_PUB[?version=$NUMBER]}@anchor{4b} +@deffn {HTTP Get} GET /policy/$ACCOUNT_PUB[?version=$NUMBER] + +Get the customer’s encrypted recovery document. If @code{version} +is not specified, the server returns the latest available version. If +@code{version} is specified, returns the policy with the respective +@code{version}. The response must begin with the nonce and +an AES-GCM tag and continue with the ciphertext. Once decrypted, the +plaintext is expected to contain: + + +@itemize * + +@item +the escrow policy + +@item +the separately encrypted master public key +@end itemize + +Note that the key shares required to decrypt the master public key are +not included, as for this the client needs to obtain authorization. +The policy does provide sufficient information for the client to determine +how to authorize requests for @strong{truth}. + +The client MAY provide an @code{If-None-Match} header with an Etag. +In that case, the server MUST additionally respond with an @code{304} status +code in case the resource matches the provided Etag. + +@strong{Response}: + + +@table @asis + +@item 200 OK@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}: + +The escrow provider responds with an @ref{4c,,EncryptedRecoveryDocument} object. + +@item 304 Not modified@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}: + +The client requested the same resource it already knows. + +@item 400 Bad request@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}: + +The @code{$ACCOUNT_PUB} is not an EdDSA public key. + +@item 402 Payment Required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}: + +The account’s balance is too low for the specified operation. +See the Taler payment protocol specification for how to pay. + +@item 403 Forbidden@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}: + +The required account signature was invalid. + +@item 404 Not found@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5}: + +The requested resource was not found. +@end table + +@emph{Anastasis-Version}: $NUMBER — The server must return actual version of the encrypted recovery document via this header. +If the client specified a version number in the header of the request, the server must return that version. If the client +did not specify a version in the request, the server returns latest version of the @ref{4c,,EncryptedRecoveryDocument}. + +@emph{Etag}: Set by the server to the Base32-encoded SHA512 hash of the body. Used for caching and to prevent redundancies. The server MUST send the Etag if the status code is @code{200 OK}. + +@emph{If-None-Match}: If this is not the very first request of the client, this contains the Etag-value which the client has received before from the server. +The client SHOULD send this header with every request (except for the first request) to avoid unnecessary downloads. + +@emph{Anastasis-Account-Signature}: The client must provide Base-32 encoded EdDSA signature over hash of body with @code{$ACCOUNT_PRIV}, affirming desire to download the requested encrypted recovery document. The purpose used MUST be @code{TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD} (1401). +@end deffn + +@anchor{rest post--policy-$ACCOUNT_PUB}@anchor{4d} +@deffn {HTTP Post} POST /policy/$ACCOUNT_PUB + +Upload a new version of the customer’s encrypted recovery document. +While the document’s structure is described in JSON below, the upload +should just be the bytestream of the raw data (i.e. 32-byte nonce followed +by 16-byte tag followed by the encrypted document). +If the request has been seen before, the server should do nothing, and otherwise store the new version. +The body must begin with a nonce, an AES-GCM tag and continue with the ciphertext. The format +is the same as specified for the response of the GET method. The +Anastasis server cannot fully validate the format, but MAY impose +minimum and maximum size limits. + +@strong{Request}: + +@*Query Parameters: + +@itemize * + +@item +@code{storage_duration=YEARS} – For how many years from now would the client like us to +store the recovery document? Defaults to 0 (that is, do +not extend / prolong existing storage contract). +The server will respond with a @code{402 Payment required}, but only +if the rest of the request is well-formed (account +signature must match). Clients that do not actually +intend to make a new upload but that only want to pay +may attempt to upload the latest backup again, as this +option will be checked before the @code{304 Not modified} +case. + +@item +@code{timeout_ms=NUMBER} – @emph{Optional.} If specified, the Anastasis server will +wait up to @code{timeout_ms} milliseconds for completion of the payment before +sending the HTTP response. A client must never rely on this behavior, as the +backend may return a response immediately. +@end itemize + + +@emph{If-None-Match}: This header MUST be present and set to the SHA512 hash (Etag) of the body by the client. +The client SHOULD also set the @code{Expect: 100-Continue} header and wait for @code{100 continue} +before uploading the body. The server MUST +use the Etag to check whether it already knows the encrypted recovery document that is about to be uploaded. +The server MUST refuse the upload with a @code{304} status code if the Etag matches +the latest version already known to the server. + +@emph{Anastasis-Policy-Signature}: The client must provide Base-32 encoded EdDSA signature over hash of body with @code{$ACCOUNT_PRIV}, affirming desire to upload an encrypted recovery document. + +@emph{Payment-Identifier}: Base-32 encoded 32-byte payment identifier that was included in a previous payment (see @code{402} status code). Used to allow the server to check that the client paid for the upload (to protect the server against DoS attacks) and that the client knows a real secret of financial value (as the @strong{kdf_id} might be known to an attacker). If this header is missing in the client’s request (or the associated payment has exceeded the upload limit), the server must return a @code{402} response. When making payments, the server must include a fresh, randomly-generated payment-identifier in the payment request. + +@strong{Response}: + + +@table @asis + +@item 204 No content@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5}: + +The encrypted recovery document was accepted and stored. @code{Anastasis-Version} and @code{Anastasis-UUID} headers +indicate what version and UUID was assigned to this encrypted recovery document upload by the server. + +@item 304 Not modified@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}: + +The same encrypted recovery document was previously accepted and stored. @code{Anastasis-Version} header +indicates what version was previously assigned to this encrypted recovery document. + +@item 400 Bad request@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}: + +The @code{$ACCOUNT_PUB} is not an EdDSA public key or mandatory headers are missing. +The response body MUST elaborate on the error using a Taler error code in the typical JSON encoding. + +@item 402 Payment required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}: + +The account’s balance is too low for the specified operation. +See the Taler payment protocol specification for how to pay. +The response body MAY provide alternative means for payment. + +@item 403 Forbidden@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}: + +The required account signature was invalid. The response body may elaborate on the error. + +@item 413 Request entity too large@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14}: + +The upload is too large @emph{or} too small. The response body may elaborate on the error. +@end table + +@strong{Details:} +@anchor{rest encryptedrecoverydocument}@anchor{4c} +@example +interface EncryptedRecoveryDocument @{ + // Nonce used to compute the (iv,key) pair for encryption of the + // encrypted_compressed_recovery_document. + nonce: [32]; //bytearray + + // Authentication tag. + aes_gcm_tag: [16]; //bytearray + + // Variable-size encrypted recovery document. After decryption, + // this contains a gzip compressed JSON-encoded `RecoveryDocument`. + // The nonce of the HKDF for this encryption must include the + // string "ERD". + encrypted_compressed_recovery_document: []; //bytearray of undefined length + +@} +@end example +@anchor{rest recoverydocument}@anchor{4e} +@example +interface RecoveryDocument @{ + // Account identifier at backup provider, AES-encrypted with + // the (symmetric) master_key, i.e. an URL + // https://sync.taler.net/$BACKUP_ID and + // a private key to decrypt the backup. Anastasis is oblivious + // to the details of how this is ultimately encoded. + backup_account: []; //bytearray of undefined length + + // List of escrow providers and selected authentication method. + methods: EscrowMethod[]; + + // List of possible decryption policies. + policy: DecryptionPolicy[]; + +@} +@end example +@anchor{rest escrowmethod}@anchor{4f} +@example +interface EscrowMethod @{ + // URL of the escrow provider (including possibly this Anastasis server). + provider_url : string; + + // Type of the escrow method (e.g. security question, SMS etc.). + escrow_type: string; + + // UUID of the escrow method (see /truth/ API below). + uuid: string; + + // Key used to encrypt the `Truth` this `EscrowMethod` is related to. + // Client has to provide this key to the server when using `@w{`}/truth/`@w{`}. + truth_encryption_key: [32]; //bytearray + + // Salt used to encrypt the truth on the Anastasis server. + truth_salt: [32]; //bytearray + + // The challenge to give to the user (i.e. the security question + // if this is challenge-response). + // (Q: as string in base32 encoding?) + // (Q: what is the mime-type of this value?) + // + // For some methods, this value may be absent. + // + // The plaintext challenge is not revealed to the + // Anastasis server. + challenge: []; //bytearray of undefined length + +@} +@end example +@anchor{rest decryptionpolicy}@anchor{50} +@example +interface DecryptionPolicy @{ + // Salt included to encrypt master key share when + // using this decryption policy. + policy_salt: [32]; //bytearray + + // Master key, AES-encrypted with key derived from + // salt and keyshares revealed by the following list of + // escrow methods identified by UUID. + encrypted_master_key: [32]; //bytearray + + // List of escrow methods identified by their UUID. + uuid: string[]; + +@} +@end example +@end deffn + +@node Managing truth,,Manage policy,Common encodings +@anchor{rest managing-truth}@anchor{51}@anchor{rest truth}@anchor{52} +@subsubsection Managing truth + + +This API is used by the Anastasis client to deposit @strong{truth} or request a (encrypted) @strong{key share} with +the escrow provider. + +An @strong{escrow method} specifies an Anastasis provider and how the user should +authorize themself. The @strong{truth} API allows the user to provide the +(encrypted) key share to the respective escrow provider, as well as auxiliary +data required for such a respective escrow method. + +An Anastasis-server may store truth for free for a certain time period, or +charge per truth operation using GNU Taler. + +@anchor{rest post--truth-$UUID}@anchor{53} +@deffn {HTTP Post} POST /truth/$UUID + +Upload a @ref{54,,TruthUploadRequest}-Object according to the policy the client created before (see @ref{4e,,RecoveryDocument}). +If request has been seen before, the server should do nothing, and otherwise store the new object. + +@strong{Request:} + +@*Query Parameters: + +@itemize * + +@item +@code{timeout_ms=NUMBER} – @emph{Optional.} If specified, the Anastasis server will +wait up to @code{timeout_ms} milliseconds for completion of the payment before +sending the HTTP response. A client must never rely on this behavior, as the +backend may return a response immediately. +@end itemize + + +@strong{Response:} + + +@table @asis + +@item 204 No content@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5}: + +Truth stored successfully. + +@item 304 Not modified@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}: + +The same truth was previously accepted and stored under this UUID. The +Anastasis server must still update the expiration time for the truth when returning +this response code. + +@item 402 Payment required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}: + +This server requires payment to store truth per item. +See the Taler payment protocol specification for how to pay. +The response body MAY provide alternative means for payment. + +@item 409 Conflict@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10}: + +The server already has some truth stored under this UUID. The client should check that it +is generating UUIDs with enough entropy. + +@item 412 Precondition failed@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13}: + +The selected authentication method is not supported on this provider. +@end table + +@strong{Details:} +@anchor{rest truthuploadrequest}@anchor{54} +@example +interface TruthUploadRequest @{ + // Contains the information of an interface `EncryptedKeyShare`, but simply + // as one binary block (in Crockford Base32 encoding for JSON). + key_share_data: []; //bytearray + + // Key share method, i.e. "security question", "SMS", "e-mail", ... + type: string; + + // Nonce used to compute the (iv,key) pair for encryption of the + // encrypted_truth. + nonce: [32]; //bytearray + + // Authentication tag of `@w{`}encrypted_truth`@w{`}. + aes_gcm_tag: [16]; //bytearray + + // Variable-size truth. After decryption, + // this contains the ground truth, i.e. H(challenge answer), + // phone number, e-mail address, picture, fingerprint, ... + // **base32 encoded**. + // + // The nonce of the HKDF for this encryption must include the + // string "ECT". + encrypted_truth: [80]; //bytearray + + // MIME type of truth, i.e. text/ascii, image/jpeg, etc. + truth_mime: string; + + // For how many years from now would the client like us to + // store the truth? + storage_duration_years: Integer; + +@} +@end example +@end deffn + +@anchor{rest get--truth-$UUID[?response=$H_RESPONSE]}@anchor{55} +@deffn {HTTP Get} GET /truth/$UUID[?response=$H_RESPONSE] + +Get the stored encrypted key share. If @code{$H_RESPONSE} is specified by the client, the server checks +if @code{$H_RESPONSE} matches the expected response specified before within the @ref{54,,TruthUploadRequest} (see @code{encrypted_truth}). +Also, the user has to provide the correct @emph{truth_encryption_key} with every get request (see below). +When @code{$H_RESPONSE} is correct, the server responds with the encrypted key share. +The encrypted key share is returned simply as a byte array and not in JSON format. + +@strong{Response}: + + +@table @asis + +@item 200 OK@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}: + +@ref{56,,EncryptedKeyShare} is returned in body (in binary). + +@item 202 Accepted@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3}: + +The escrow provider will respond out-of-band (i.e. SMS). +The body may contain human-readable instructions on next steps. + +@item >>208 Already Reported<<: + +An authentication challenge was recently send, client should +simply respond to the pending challenge. + +@item 303 See other@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4}: + +The provider redirects for authentication (i.e. video identification/WebRTC). +If the client is not a browser, it should launch a browser at the URL +given in the @code{Location} header and allow the user to re-try the operation +after successful authorization. + +@item 402 Payment required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}: + +The service requires payment for access to truth. +See the Taler payment protocol specification for how to pay. +The response body MAY provide alternative means for payment. + +@item 403 Forbidden@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}: + +The server requires a valid “response” to the challenge associated with the UUID. + +@item 404 Not found@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5}: + +The server does not know any truth under the given UUID. + +@item 410 Gone@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11}: + +The server has not (recently) issued a challenge under the given UUID, +but a reply was provided. (This does not apply for secure question.) + +@item 417 Expectation Failed@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18}: + +The decrypted @code{truth} does not match the expectations of the authentication +backend, i.e. a phone number for sending an SMS is not a number, or +an e-mail address for sending an E-mail is not a valid e-mail address. + +@item 503 Service Unavailable@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4}: + +Server is out of Service. +@end table + +@emph{Truth-Decryption-Key}: Key used to encrypt the @strong{truth} (see encrypted_truth within @ref{54,,TruthUploadRequest}) and which has to provided by the user. The key is stored with +the according @ref{4f,,EscrowMethod}. The server needs this key to get the info out of @ref{54,,TruthUploadRequest} needed to verify the @code{$RESPONSE}. + +@strong{Details:} +@anchor{rest encryptedkeyshare}@anchor{56} +@example +interface EncryptedKeyShare @{ + // Nonce used to compute the decryption (iv,key) pair. + nonce_i: [32]; //bytearray + + // Authentication tag. + aes_gcm_tag_i: [16]; //bytearray + + // Encrypted key-share in base32 encoding. + // After decryption, this yields a `KeyShare`. Note that + // the `KeyShare` MUST be encoded as a fixed-size binary + // block (instead of in JSON encoding). + // + // HKDF for the key generation must include the + // string "eks" as salt. + // Depending on the method, + // the HKDF may additionally include + // bits from the response (i.e. some hash over the + // answer to the security question). + encrypted_key_share_i: [32]; //bytearray + +@} +@end example +@anchor{rest keyshare}@anchor{57} +@example +interface KeyShare @{ + // Key material to concatenate with policy_salt and KDF to derive + // the key to decrypt the master key. + key_share: [32]; //bytearray + + // Signature over method, UUID, and `@w{`}key_share`@w{`}. + account_sig: EddsaSignature; + +@} +@end example +@end deffn + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node Reducer API,Authentication Methods,REST API,Documentation Overview +@anchor{reducer doc}@anchor{58}@anchor{reducer reducer-api}@anchor{59} +@section Reducer API + + +This section describes the Anastasis Reducer API which is used by client applications +to store or load the different states the client application can have. +The reducer takes a @ref{5a,,state} in JSON syntax and returns the new state in JSON syntax. + +For example a @strong{state} may take the following structure: + +@example +@{ + "backup_state": "CONTINENT_SELECTING", + "continents": [ + "Europe", + "North_America" + ] +@} +@end example + +The new state depends on the previous one and on the transition @ref{5b,,action} with its +arguments given to the reducer. A @strong{transition argument} also is a statement in JSON syntax: + +@example +@{ + "continent": "Europe" +@} +@end example + +The new state returned by the reducer with the state and transition argument defined +above would look like following for the transition @ref{5b,,action} @code{select_continent}: + +@example +@{ + "backup_state": "COUNTRY_SELECTING", + "continents": [ + "Europe", + "North_America" + ], + "selected_continent": "Europe", + "countries": [ + @{ + "code": "ch", + "name": "Switzerland", + "continent": "Europe", + "name_i18n": @{ + "de_DE": "Schweiz", + "de_CH": "Schwiiz", + "fr": "Suisse", + "en": "Swiss" + @}, + "currency": "CHF" + @}, + @{ + "code": "de", + "name": "Germany", + "continent": "Europe", + "continent_i18n": @{ + "de": "Europa" + @}, + "name_i18n": @{ + "de_DE": "Deutschland", + "de_CH": "Deutschland", + "fr": "Allemagne", + "en": "Germany" + @}, + "currency": "EUR" + @} + ] +@} +@end example + +@menu +* States:: +* Backup Reducer:: +* Recovery Reducer:: +* Reducer transitions:: + +@end menu + +@node States,Backup Reducer,,Reducer API +@anchor{reducer states}@anchor{5c} +@subsection States + + +Overall, the reducer knows the following states: + +@quotation + + +@itemize - + +@item + +@table @asis + +@item @strong{ERROR}: The transition led to an error. No further transitions are possible from + +this state, but the client may want to continue from a previous state. +@end table + +@item + +@table @asis + +@item @strong{CONTINENT_SELECTING}: The user should specify the continent where they are living, + +so that we can show a list of countries to choose from. +@end table + +@item + +@table @asis + +@item @strong{COUNTRY_SELECTING}: The user should specify the country where they are living, + +so that we can determine appropriate attributes, currencies and Anastasis +providers. +@end table + +@item + +@table @asis + +@item @strong{USER_ATTRIBUTES_COLLECTING}: The user should provide the country-specific personal + +attributes. +@end table + +@item + +@table @asis + +@item @strong{AUTHENTICATIONS_EDITING}: The user should add authentication methods to be used + +during recovery. +@end table + +@item +@strong{POLICIES_REVIEWING}: The user should review the recovery policies. + +@item +@strong{SECRET_EDITING}: The user should edit the secret to be backed up. + +@item + +@table @asis + +@item @strong{TRUTHS_PAYING}: The user needs to pay for one or more uploads of data associated + +with an authentication method. +@end table + +@item +@strong{POLICIES_PAYING}: The user needs to pay for storing the recovery policy document. + +@item +@strong{BACKUP_FINISHED}: A backup has been successfully generated. + +@item + +@table @asis + +@item @strong{SECRET_SELECTING}: The user needs to select a recovery policy document with + +the secret that is to be recovered. +@end table + +@item + +@table @asis + +@item @strong{CHALLENGE_SELECTING}: The user needs to select an authorization challenge to + +proceed with recovery. +@end table + +@item +@strong{CHALLENGE_PAYING}: The user needs to pay to proceed with the authorization challenge. + +@item +@strong{CHALLENGE_SOLVING}: The user needs to solve the authorization challenge. + +@item +@strong{RECOVERY_FINISHED}: The secret of the user has been recovered. +@end itemize +@end quotation + +State names: + +@quotation + + +@itemize - + +@item +In SELECTING-states, the user has to choose one value out of a predefined set of values (for example a continent out of a set of continents). + +@item +In COLLECTING-states, the user has to give certain values. + +@item +In EDITING-states, the user is free to choose which values he wants to give. + +@item +In REVEIWING-states, the user may make a few choices, but primarily is expected to affirm something. + +@item +in PAYING-states, the user must make a payment. + +@item +in FINISHED-states, the operation has definitively concluded. +@end itemize +@end quotation + +@node Backup Reducer,Recovery Reducer,States,Reducer API +@anchor{reducer backup-reducer}@anchor{5d} +@subsection Backup Reducer + +@anchor{reducer state}@anchor{5a}@anchor{reducer action}@anchor{5b} + +@float Figure + +@image{anastasis-figures/anastasis_reducer_backup,,,fig-anastasis_reducer_backup,png} + +@caption{Backup states and their transitions.} + +@end float + + +The illustration above shows the different states the reducer can have during a backup +process. + +@node Recovery Reducer,Reducer transitions,Backup Reducer,Reducer API +@anchor{reducer recovery-reducer}@anchor{5e} +@subsection Recovery Reducer + + + +@float Figure + +@image{anastasis-figures/anastasis_reducer_recovery,,,fig-anastasis_reducer_recovery,png} + +@caption{Recovery states and their transitions.} + +@end float + + +The illustration above shows the different states the reducer can have during a recovery +process. + +@node Reducer transitions,,Recovery Reducer,Reducer API +@anchor{reducer reducer-transitions}@anchor{5f} +@subsection Reducer transitions + + +In the following, the individual transitions will be specified in more detail. +Note that we only show fields added by the reducer, typically the previous +state is preserved to enable “back” transitions to function smoothly. + +@menu +* Initial state:: +* Common transitions:: +* Backup transitions:: +* Recovery transitions:: + +@end menu + +@node Initial state,Common transitions,,Reducer transitions +@anchor{reducer initial-state}@anchor{60} +@subsubsection Initial state + + +The initial states for backup and recovery processes are: + +@strong{Initial backup state:} + +@example +@{ + "backup_state": "CONTINENT_SELECTING", + "continents": [ + "Europe", + "North America" + ] +@} +@end example + +@strong{Initial recovery state:} + +@example +@{ + "recovery_state": "CONTINENT_SELECTING", + "continents": [ + "Europe", + "North America" + ] +@} +@end example + +Here, “continents” is an array of English strings with the names of the +continents which contain countries for which Anastasis could function (based +on having providers that are known to operate and rules being provided for +user attributes from those countries). + +For internationalization, another field @code{continents_i18n} may be present. +This field would be a map of language names to arrays of translated +continent names: + +@example +@{ + "recovery_state": "CONTINENT_SELECTING", + "continents": [ + "Europe", + "North America" + ] + "continents_i18n": + @{ + "de_DE" : [ + "Europa", + "Nordamerika" + ], + "de_CH" : [ + "Europa", + "Nordamerika" + ] + @} +@} +@end example + +Translations must be given in the same order as the main English array. + +@node Common transitions,Backup transitions,Initial state,Reducer transitions +@anchor{reducer common-transitions}@anchor{61} +@subsubsection Common transitions + + +@strong{select_continent:} + +Here the user specifies the continent they live on. Arguments (example): + +@example +@{ + "continent": "Europe" +@} +@end example + +The continent must be given using the English name from the @code{continents} array. +Using a translated continent name is invalid and may result in failure. + +The reducer returns an updated state with a list of countries to choose from, +for example: + +@example +@{ + "backup_state": "COUNTRY_SELECTING", + "selected_continent": "Europe", + "countries": [ + @{ + "code": "ch", + "name": "Switzerland", + "continent": "Europe", + "name_i18n": @{ + "de_DE": "Schweiz", + "de_CH": "Schwiiz", + "fr": "Suisse", + "en": "Swiss" + @}, + "currency": "CHF" + @}, + @{ + "code": "de", + "name": "Germany", + "continent": "Europe", + "continent_i18n": @{ + "de": "Europa" + @}, + "name_i18n": @{ + "de_DE": "Deutschland", + "de_CH": "Deutschland", + "fr": "Allemagne", + "en": "Germany" + @}, + "currency": "EUR" + @} + ] +@} +@end example + +Here @code{countries} is an array of countries on the @code{selected_continent}. For +each country, the @code{code} is the ISO 3166-1 alpha-2 country code. The +@code{continent} is only present because some countries span continents, the +information is redundant and will always match @code{selected_continent}. The +@code{name} is the name of the country in English, internationalizations of the +name may be provided in @code{name_i18n}. The @code{currency} is @strong{an} official +currency of the country, if a country has multiple currencies, it may appear +multiple times in the list. In this case, the user should select the entry +with the currency they intend to pay with. It is also possible for users +to select a currency that does not match their country, but user interfaces +should by default try to use currencies that match the user’s residence. + +@strong{select_country:} + +Selects the country (via the country code) and specifies the currency. +The latter is needed as some countries have more than one currency, +and some use-cases may also involve users insisting on paying with +foreign currency. + +Arguments (example): + +@example +@{ + "country_code": "de", + "currency": "EUR" +@} +@end example + +The @code{country_code} must be an ISO 3166-1 alpha-2 country code from +the array of @code{countries} of the reducer’s state. The @code{currency} +field must be a valid currency accepted by the Taler payment system. + +The reducer returns a new state with the list of attributes the +user is expected to provide, as well as possible authentication +providers that accept payments in the selected currency: + +@example +@{ + "backup_state": "USER_ATTRIBUTES_COLLECTING", + "selected_country": "de", + "currency": "EUR", + "required_attributes": [ + @{ + "type": "string", + "name": "full_name", + "label": "Full name", + "label_i18n": @{ + "de_DE": "Vollstaendiger Name", + "de_CH": "Vollstaendiger. Name", + "fr": "Nom complet", + "en": "Full name" + @}, + "widget": "anastasis_gtk_ia_full_name", + "uuid" : "9e8f463f-575f-42cb-85f3-759559997331" + @}, + @{ + "type": "date", + "name": "birthdate", + "label": "Birthdate", + "label_i18n": @{ + "de_DE": "Geburtsdatum", + "de_CH": "Geburtsdatum", + "fr": "Date de naissance", + "en": "Birthdate" + @}, + "uuid" : "83d655c7-bdb6-484d-904e-80c1058c8854" + "widget": "anastasis_gtk_ia_birthdate" + @}, + @{ + "type": "string", + "name": "tax_number", + "label": "Taxpayer identification number", + "label_i18n":@{ + "de_DE": "Steuerliche Identifikationsnummer", + "de_CH": "Steuerliche Identifikationsnummer", + "en": "German taxpayer identification number" + @}, + "widget": "anastasis_gtk_ia_tax_de", + "uuid": "dae48f85-e3ff-47a4-a4a3-ed981ed8c3c6", + "validation-regex": "^[0-9]@{11@}$", + "validation-logic": "DE_TIN_check" + @}, + @{ + "type": "string", + "name": "social_security_number", + "label": "Social security number", + "label_i18n": @{ + "de_DE": "Sozialversicherungsnummer", + "de_CH": "Sozialversicherungsnummer", + "fr": "Numéro de sécurité sociale", + "en": "Social security number" + @}, + "widget": "anastasis_gtk_ia_ssn", + "validation-regex": "^[0-9]@{8@}[[:upper:]][0-9]@{3@}$", + "validation-logic": "DE_SVN_check" + "optional" : true + @} + ], + "authentication_providers": @{ + "http://localhost:8089/": @{ + "http_status": 200, + "methods": [ + @{ "type" : "question", + "usage_fee" : "EUR:0.0" @}, + @{ "type" : "sms", + "usage_fee" : "EUR:0.5" @} + ], + "annual_fee": "EUR:4.99", + "truth_upload_fee": "EUR:4.99", + "liability_limit": "EUR:1", + "currency": "EUR", + "truth_lifetime": @{ "d_ms" : 50000000 @}, + "storage_limit_in_megabytes": 1, + "provider_name": "Anastasis 4", + "salt": "CXAPCKSH9D3MYJTS9536RHJHCW" + @}, + "http://localhost:8088/": @{ + "http_status": 200, + "methods": [ + @{ "type" : "question", + "usage_fee" : "EUR:0.01" @}, + @{ "type" : "sms", + "usage_fee" : "EUR:0.55" @} + ], + "annual_fee": "EUR:0.99", + "truth_upload_fee": "EUR:3.99", + "liability_limit": "EUR:1", + "currency": "EUR", + "truth_lifetime": @{ "d_ms" : 50000000 @}, + "storage_limit_in_megabytes": 1, + "provider_name": "Anastasis 4", + "salt": "CXAPCKSH9D3MYJTS9536RHJHCW" + @} + @} +@} +@end example + +The array of @code{required_attributes} contains attributes about the user +that must be provided includes: + +@quotation + + +@itemize - + +@item +@strong{type}: The type of the attribute, for now only @code{string} and @code{date} are +supported. + +@item +@strong{name}: The name of the attribute, this is the key under which the +attribute value must be provided later. The name must be unique per response. + +@item +@strong{label}: A human-readable description of the attribute in English. +Translated descriptions may be provided under @strong{label_i18n}. + +@item +@strong{uuid}: A UUID that uniquely identifies identical attributes across +different countries. Useful to preserve values should the user enter +some attributes, and then switch to another country. Note that +attributes must not be preserved if they merely have the same @strong{name}, +only the @strong{uuid} will be identical if the semantics is identical. + +@item +@strong{widget}: An optional name of a widget that is known to nicely render +the attribute entry in user interfaces where named widgets are +supported. + +@item +@strong{validation-regex}: An optional extended POSIX regular expression +that is to be used to validate (string) inputs to ensure they are +well-formed. + +@item +@strong{validation-logic}: Optional name of a function that should be called +to validate the input. If the function is not known to the particular +client, the respective validation can be skipped (at the expense of +typos by users not being detected, possibly rendering secrets +irrecoverable). + +@item +@strong{optional}: Optional boolean field that, if @code{true}, indicates that +this attribute is not actually required but optional and users MAY leave +it blank in case they do not have the requested information. Used for +common fields that apply to some large part of the population but are +not sufficiently universal to be actually required. +@end itemize +@end quotation + +The authentication providers are listed under a key that is the +base URL of the service. For each provider, the following +information is provided if the provider was successfully contacted: + +@quotation + + +@itemize - + +@item +@strong{http_status}: HTTP status code, always @code{200} on success. + +@item +@strong{methods}: Array of authentication methods supported by this +provider. Includes the @strong{type} of the authentication method +and the @strong{usage_fee} (how much the user must pay for authorization +using this method during recovery). + +@item +@strong{annual_fee}: Fee the provider charges to store the recovery +policy for one year. + +@item +@strong{truth_upload_fee}: Fee the provider charges to store a key share. + +@item +@strong{liability_limit}: Amount the provider can be held liable for in +case a key share or recovery document cannot be recovered due to +provider failures. + +@item +@strong{currency}: Currency in which the provider wants to be paid, +will match all of the fees. + +@item +@strong{storage_limit_in_megabytes}: Maximum size of an upload (for +both recovery document and truth data) in megabytes. + +@item +@strong{provider_name}: Human-readable name of the provider’s business. + +@item +@strong{salt}: Salt value used by the provider, used to derive the +user’s identity at this provider. Should be unique per provider, +and must never change for a given provider. The salt is +base32 encoded. +@end itemize +@end quotation + +If contacting the provider failed, the information returned is: + +@quotation + + +@itemize - + +@item +@strong{http_status}: HTTP status code (if available, possibly 0 if +we did not even obtain an HTTP response). + +@item +@strong{error_code}: Taler error code, never 0. +@end itemize +@end quotation + +@strong{add_provider}: + +This operation can be performed in state @code{USER_ATTRIBUTES_COLLECTING}. It +adds one or more Anastasis providers to the list of providers the reducer +should henceforth consider. Note that removing providers is not possible at +this time. + +Here, the client must provide an array with the base URLs of the +providers to add, for example: + +@example +@{ + "urls": [ + "http://localhost:8888/", + "http://localhost:8089/" + ] +@} +@end example + +Note that existing providers will remain in the state. The following is an +example for an expected new state where the service on port 8089 is +unreachable, the service on port 8088 was previously known, and service on +port 8888 was now added: + +@example +@{ + "backup_state": "USER_ATTRIBUTES_COLLECTING", + "authentication_providers": @{ + "http://localhost:8089/": @{ + "error_code": 11, + "http_status": 0 + @}, + "http://localhost:8088/": @{ + "http_status": 200, + "methods": [ + @{ "type" : "question", + "usage_fee" : "EUR:0.01" @}, + @{ "type" : "sms", + "usage_fee" : "EUR:0.55" @} + ], + "annual_fee": "EUR:0.99", + "truth_upload_fee": "EUR:3.99", + "liability_limit": "EUR:1", + "currency": "EUR", + "truth_lifetime": @{ "d_ms" : 50000000 @}, + "storage_limit_in_megabytes": 1, + "provider_name": "Anastasis 4", + "salt": "CXAPCKSH9D3MYJTS9536RHJHCW" + @} + "http://localhost:8888/": @{ + "methods": [ + @{ "type" : "question", + "usage_fee" : "EUR:0.01" @}, + @{ "type" : "sms", + "usage_fee" : "EUR:0.55" @} + ], + "annual_fee": "EUR:0.99", + "truth_upload_fee": "EUR:3.99", + "liability_limit": "EUR:1", + "currency": "EUR", + "truth_lifetime": @{ "d_ms" : 50000000 @}, + "storage_limit_in_megabytes": 1, + "provider_name": "Anastasis 42", + "salt": "BXAPCKSH9D3MYJTS9536RHJHCX" + @} + @} +@} +@end example + +@node Backup transitions,Recovery transitions,Common transitions,Reducer transitions +@anchor{reducer backup-transitions}@anchor{62} +@subsubsection Backup transitions + + +@strong{enter_user_attributes:} + +This transition provides the user’s personal attributes. The specific set of +attributes required depends on the country of residence of the user. Some +attributes may be optional, in which case they should be omitted entirely +(that is, not simply be set to @code{null} or an empty string). Example +arguments would be: + +@example +@{ + "identity_attributes": @{ + "full_name": "Max Musterman", + "social_security_number": "123456789", + "birthdate": "2000-01-01", + "birthplace": "Earth" + @} +@} +@end example + +Note that at this stage, the state machines between backup and +recovery diverge and the @code{recovery_state} will begin to look +very different from the @code{backup_state}. + +For backups, if all required attributes are present, the reducer will +transition to an @code{AUTHENTICATIONS_EDITING} state with the attributes added +to it: + +@example +@{ + "backup_state": "AUTHENTICATIONS_EDITING", + "identity_attributes": @{ + "full_name": "Max Musterman", + "social_security_number": "123456789", + "birthdate": "2000-01-01", + "birthplace": "Earth" + @} +@} +@end example + +If required attributes are missing, do not match the required regular +expression, or fail the custom validation logic, the reducer SHOULD transition +to an error state indicating what was wrong about the input. A reducer that +does not support some specific validation logic MAY accept the invalid input +and proceed anyway. The error state will include a Taler error code that +is specific to the failure, and optional details. Example: + +@example +@{ + "backup_state": "ERROR", + "code": 8404, + "hint": "An input did not match the regular expression.", + "detail": "social_security_number" +@} +@end example + +Clients may safely repeat this transition to validate the user’s inputs +until they satisfy all of the constraints. This way, the user interface +does not have to perform the input validation directly. + +@strong{add_authentication}: + +This transition adds an authentication method. The method must be supported +by one or more providers that are included in the current state. Adding an +authentication method requires specifying the @code{type} and @code{instructions} to +be given to the user. The @code{challenge} is encrypted and stored at the +Anastasis provider. The specific semantics of the value depend on the +@code{type}. Typical challenges values are a phone number (to send an SMS to), +an e-mail address (to send a PIN code to) or the answer to a security +question. Note that these challenge values will still be encrypted (and +possibly hashed) before being given to the Anastasis providers. + +Note that the @code{challenge} must be given in Crockford Base32 encoding, as it +MAY include binary data (such as a photograph of the user). In the latter +case, the optional @code{mime_type} field must be provided to give the MIME type +of the value encoded in @code{challenge}. + +@example +@{ + "authentication_method": + @{ + "type": "question", + "mime_type" : "text/plain", + "instructions" : "What is your favorite GNU package?", + "challenge" : "E1QPPS8A", + @} +@} +@end example + +If the information provided is valid, the reducer will add the new +authentication method to the array of authentication methods: + +@example +@{ + "backup_state": "AUTHENTICATIONS_EDITING", + "authentication_methods": [ + @{ + "type": "question", + "mime_type" : "text/plain", + "instructions" : "What is your favorite GNU package?", + "challenge" : "E1QPPS8A", + @}, + @{ + "type": "email", + "instructions" : "E-mail to user@@*le.com", + "challenge": "ENSPAWJ0CNW62VBGDHJJWRVFDM50" + @} + ] +@} +@end example + +@strong{delete_authentication}: + +This transition can be used to remove an authentication method from the +array of authentication methods. It simply requires the index of the +authentication method to remove. Note that the array is 0-indexed: + +@example +@{ + "authentication_method": 1 +@} +@end example + +Assuming we begin with the state from the example above, this would +remove the @code{email} authentication method, resulting in the following +response: + +@example +@{ + "backup_state": "AUTHENTICATIONS_EDITING", + "authentication_methods": [ + @{ + "type": "question", + "mime_type" : "text/plain", + "instructions" : "What is your favorite GNU package?", + "challenge" : "gdb", + @} + ] +@} +@end example + +If the index is invalid, the reducer will instead +transition into an @code{ERROR} state. + +@strong{next} (from @code{AUTHENTICATIONS_EDITING}): + +This transition confirms that the user has finished adding (or removing) +authentication methods, and that the system should now automatically compute +a set of reasonable recovery policies. + +This transition does not take any mandatory arguments. Optional arguments can +be provided to upload the recovery document only to a specific subset of the +providers: + +@example +@{ + "providers": [ + "http://localhost:8088/", + "http://localhost:8089/" + ] +@} +@end example + +The resulting state provides the suggested recovery policies in a way suitable +for presentation to the user: + +@example +@{ + "backup_state": "POLICIES_REVIEWING", + "policy_providers" : [ + @{ "provider_url" : "http://localhost:8088/" @}, + @{ "provider_url" : "http://localhost:8089/" @} + ], + "policies": [ + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8088/" + @}, + @{ + "authentication_method": 1, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 2, + "provider": "http://localhost:8087/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8088/" + @}, + @{ + "authentication_method": 1, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 3, + "provider": "http://localhost:8089/" + @} + ] + @} + ] +@} +@end example + +For each recovery policy, the state includes the specific details of which +authentication @code{methods} must be solved to recovery the secret using this +policy. The @code{methods} array specifies the index of the +@code{authentication_method} in the @code{authentication_methods} array, as well as +the provider that was selected to supervise this authentication. + +If no authentication method was provided, the reducer will transition into an +@code{ERROR} state instead of suggesting policies. + +@strong{add_policy}: + +Using this transition, the user can add an additional recovery policy to the +state. The argument format is the same that is used in the existing state. +An example for a possible argument would thus be: + +@example +@{ + "policy": [ + @{ + "authentication_method": 1, + "provider": "http://localhost:8088/" + @}, + @{ + "authentication_method": 3, + "provider": "http://localhost:8089/" + @} + ] +@} +@end example + +Note that the specified providers must already be in the +@code{authentication_providers} of the state. You cannot add new providers at +this stage. The reducer will simply attempt to append the suggested policy to +the “policies” array, returning an updated state: + +@example +@{ + "backup_state": "POLICIES_REVIEWING", + "policies": [ + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 1, + "provider": "http://localhost:8088/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 2, + "provider": "http://localhost:8088/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 1, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 2, + "provider": "http://localhost:8088/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 1, + "provider": "http://localhost:8088/" + @}, + @{ + "authentication_method": 3, + "provider": "http://localhost:8089/" + @} + ] + @} + ] +@} +@end example + +If the new policy is invalid, for example because it adds an unknown +authentication method, or the selected provider does not support the type of +authentication, the reducer will transition into an @code{ERROR} state instead of +adding the new policy. + +@strong{update_policy}: + +Using this transition, the user can modify an existing recovery policy +in the state. +The argument format is the same that is used in @strong{add_policy}, +except there is an additional key @code{policy_index} which +identifies the policy to modify. +An example for a possible argument would thus be: + +@example +@{ + "policy_index" : 1, + "policy": [ + @{ + "authentication_method": 1, + "provider": "http://localhost:8088/" + @}, + @{ + "authentication_method": 3, + "provider": "http://localhost:8089/" + @} + ] +@} +@end example + +If the new policy is invalid, for example because it adds an unknown +authentication method, or the selected provider does not support the type of +authentication, the reducer will transition into an @code{ERROR} state instead of +modifying the policy. + +@strong{delete_policy:} + +This transition allows the deletion of a recovery policy. The argument +simply specifies the index of the policy to delete, for example: + +@example +@{ + "policy_index": 3 +@} +@end example + +Given as input the state from the example above, the expected new state would +be: + +@example +@{ + "backup_state": "POLICIES_REVIEWING", + "policies": [ + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 1, + "provider": "http://localhost:8088/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 2, + "provider": "http://localhost:8088/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 1, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 2, + "provider": "http://localhost:8088/" + @} + ] + @} + ] +@} +@end example + +If the index given is invalid, the reducer will transition into an @code{ERROR} state +instead of deleting a policy. + +@strong{delete_challenge:} + +This transition allows the deletion of an individual +challenge from a recovery policy. The argument +simply specifies the index of the policy and challenge +to delete, for example: + +@example +@{ + "policy_index": 1, + "challenge_index" : 1 +@} +@end example + +Given as input the state from the example above, the expected new state would +be: + +@example +@{ + "backup_state": "POLICIES_REVIEWING", + "policies": [ + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 1, + "provider": "http://localhost:8088/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 0, + "provider": "http://localhost:8089/" + @} + ] + @}, + @{ + "methods": [ + @{ + "authentication_method": 1, + "provider": "http://localhost:8089/" + @}, + @{ + "authentication_method": 2, + "provider": "http://localhost:8088/" + @} + ] + @} + ] +@} +@end example + +If the index given is invalid, the reducer will transition into an @code{ERROR} state +instead of deleting a challenge. + +@strong{next} (from @code{POLICIES_REVIEWING}): + +Using this transition, the user confirms that the policies in the current +state are acceptable. The transition does not take any arguments. + +The reducer will simply transition to the @code{SECRET_EDITING} state: + +@example +@{ + "backup_state": "SECRET_EDITING", + "upload_fees" : [ "KUDOS:42" ], + "expiration" : @{ "t_ms" : 1245362362 @} +@} +@end example + +Here, @code{upload_fees} is an array of applicable upload fees for the +given policy expiration time. This is an array because fees could +be in different currencies. The final cost may be lower if the +user already paid for some of the time. + +If the array of @code{policies} is currently empty, the reducer will transition +into an @code{ERROR} state instead of allowing the user to continue. + +@strong{enter_secret:} + +This transition provides the reducer with the actual core @code{secret} of the user +that Anastasis is supposed to backup (and possibly recover). The argument is +simply the Crockford-Base32 encoded @code{value} together with its @code{mime} type, or a @code{text} field with a human-readable secret text. +For example: + +@example +@{ + "secret": @{ + "value": "EDJP6WK5EG50", + "mime" : "text/plain" + @}, + "expiration" : @{ "t_ms" : 1245362362 @} +@} +@end example + +If the application is unaware of the format, it set the @code{mime} field to @code{null}. +The @code{expiration} field is optional. + +The reducer remains in the @code{SECRET_EDITING} state, but now the secret and +updated expiration time are part of the state and the cost calculations will +be updated. + +@example +@{ + "backup_state": "SECRET_EDITING", + "core_secret" : @{ + "value": "EDJP6WK5EG50", + "mime" : "text/plain" + @}, + "expiration" : @{ "t_ms" : 1245362362 @}, + "upload_fees" : [ "KUDOS:42" ] +@} +@end example + +@strong{clear_secret:} + +This transition removes the core secret from the state. It is simply a +convenience function to undo @code{enter_secret} without providing a new value +immediately. The transition takes no arguments. The resuting state will no +longer have the @code{core_secret} field, and be otherwise unchanged. Calling +@strong{clear_secret} on a state without a @code{core_secret} will result in an error. + +@strong{enter_secret_name:} + +This transition provides the reducer with a name for the core @code{secret} of the user. This name will be given to the user as a hint when seleting a recovery policy document during recovery, prior to satisfying any of the challenges. The argument simply contains the name for the secret. +Applications that have built-in support for Anastasis MUST prefix the +secret name with an underscore and an application-specific identifier +registered in GANA so that they can use recognize their own backups. +An example argument would be: + +@example +@{ + "name": "_TALERWALLET_MyPinePhone", +@} +@end example + +Here, @code{MyPinePhone} might be chosen by the user to identify the +device that was being backed up. + +The reducer remains in the @code{SECRET_EDITING} state, but now the +secret name is updated: + +@example +@{ + "secret_name" : "_TALERWALLET_MyPinePhone" +@} +@end example + +@strong{update_expiration:} + +This transition asks the reducer to change the desired expiration time +and to update the associated cost. For example: + +@example +@{ + "expiration" : @{ "t_ms" : 1245362362 @} +@} +@end example + +The reducer remains in the @code{SECRET_EDITING} state, but the +expiration time and cost calculation will be updated. + +@example +@{ + "backup_state": "SECRET_EDITING", + "expiration" : @{ "t_ms" : 1245362362 @}, + "upload_fees" : [ @{ "fee": "KUDOS:43" @} ] +@} +@end example + +@strong{next} (from @code{SECRET_EDITING}): + +Using this transition, the user confirms that the secret and expiration +settings in the current state are acceptable. The transition does not take any +arguments. + +If the secret is currently empty, the reducer will transition into an +@code{ERROR} state instead of allowing the user to continue. + +After adding a secret, the reducer may transition into different states +depending on whether payment(s) are necessary. If payments are needed, the +@code{secret} will be stored in the state under @code{core_secret}. Applications +should be careful when persisting the resulting state, as the @code{core_secret} +is not protected in the @code{PAYING} states. The @code{PAYING} states only differ +in terms of what the payments are for (key shares or the recovery document), +in all cases the state simply includes an array of Taler URIs that refer to +payments that need to be made with the Taler wallet. + +If all payments are complete, the reducer will transition into the +@code{BACKUP_FINISHED} state and (if applicable) delete the @code{core_secret} as an +additional safety measure. + +Example results are thus: + +@example +@{ + "backup_state": "TRUTHS_PAYING", + "secret_name" : "$NAME", + "core_secret" : @{ "$anything":"$anything" @}, + "payments": [ + "taler://pay/...", + "taler://pay/..." + ] +@} +@end example + +@example +@{ + "backup_state": "POLICIES_PAYING", + "secret_name" : "$NAME", + "core_secret" : @{ "$anything":"$anything" @}, + "payments": [ + "taler://pay/...", + "taler://pay/..." + ] +@} +@end example + +@example +@{ + "backup_state": "BACKUP_FINISHED", +@} +@end example + +@strong{pay:} + +This transition suggests to the reducer that a payment may have been made or +is immanent, and that the reducer should check with the Anastasis service +provider to see if the operation is now possible. The operation takes one +optional argument, which is a @code{timeout} value that specifies how long the +reducer may wait (in long polling) for the payment to complete: + +@example +@{ + "timeout": @{ "d_ms" : 5000 @}, +@} +@end example + +The specified timeout is passed on to the Anastasis service provider(s), which +will wait this long before giving up. If no timeout is given, the check is +done as quickly as possible without additional delays. The reducer will continue +to either an updated state with the remaining payment requests, to the +@code{BACKUP_FINISHED} state (if all payments have been completed and the backup +finished), or into an @code{ERROR} state in case there was an irrecoverable error, +indicating the specific provider and how it failed. An example for this +final error state would be: + +@example +@{ + "backup_state": "ERROR", + "http_status" : 500, + "upload_status" : 52, + "provider_url" : "https://bad.example.com/", +@} +@end example + +Here, the fields have the following meaning: + +@quotation + + +@itemize - + +@item +@strong{http_status} is the HTTP status returned by the Anastasis provider. + +@item +@strong{upload_status} is the Taler error code return by the provider. + +@item +@strong{provider_url} is the base URL of the failing provider. +@end itemize +@end quotation + +In the above example, 52 would thus imply that the Anastasis provider failed to +store information into its database. + +@node Recovery transitions,,Backup transitions,Reducer transitions +@anchor{reducer recovery-transitions}@anchor{63} +@subsubsection Recovery transitions + + +@strong{enter_user_attributes:} + +This transition provides the user’s personal attributes. The specific set of +attributes required depends on the country of residence of the user. Some +attributes may be optional, in which case they should be omitted entirely +(that is, not simply be set to @code{null} or an empty string). The +arguments are identical to the @strong{enter_user_attributes} transition from +the backup process. Example arguments would thus be: + +@example +@{ + "identity_attributes": @{ + "full_name": "Max Musterman", + "social_security_number": "123456789", + "birthdate": "2000-01-01", + "birthplace": "Earth" + @} +@} +@end example + +However, in contrast to the backup process, the reducer will attempt to +retrieve the latest recovery document from all known providers for the +selected currency given the above inputs. If a recovery document was found +by any provider, the reducer will attempt to load it and transition to +a state where the user can choose which challenges to satisfy: + +@example +@{ + "recovery_state": "CHALLENGE_SELECTING", + "recovery_information": @{ + "challenges": [ + @{ + "uuid": "MW2R3RCBZPHNC78AW8AKWRCHF9KV3Y82EN62T831ZP54S3K5599G", + "cost": "TESTKUDOS:0", + "type": "question", + "instructions": "q1" + @}, + @{ + "uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "cost": "TESTKUDOS:0", + "type": "email", + "instructions": "e-mail address m?il@@f*.bar" + @}, + ], + "policies": [ + [ + @{ + "uuid": "MW2R3RCBZPHNC78AW8AKWRCHF9KV3Y82EN62T831ZP54S3K5599G" + @}, + @{ + "uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0" + @}, + ], + ], + "provider_url": "http://localhost:8088/", + "version": 1, + @}, + "recovery_document": @{ + "...": "..." + @} +@} +@end example + +The @code{recovery_document} is an internal representation of the recovery +information and of no concern to the user interface. The pertinent information +is in the @code{recovery_information}. Here, the @code{challenges} array is a list +of possible challenges the user could attempt to solve next, while @code{policies} +is an array of policies, with each policy being an array of challenges. +Satisfying all of the challenges of one of the policies will enable the secret +to be recovered. The @code{provider_url} from where the recovery document was +obtained and its @code{version} are also provided. Each challenge comes with +four mandatory fields: + +@quotation + + +@itemize - + +@item +@strong{uuid}: A unique identifier of the challenge; this is what the +UUIDs in the policies array refer to, but also this UUID may be +included in messages sent to the user. They allow the user to +distinguish different PIN/TANs should say the same phone number be +used for SMS-authentication with different providers. + +@item +@strong{cost}: This is the amount the Anastasis provider will charge +to allow the user to pass the challenge. + +@item +@strong{type}: This is the type of the challenge, as a string. + +@item +@strong{instructions}: Contains additional important hints for the user +to allow the user to satisfy the challenge. It typically includes +an abbreviated form of the contact information or the security +question. Details depend on @code{type}. +@end itemize +@end quotation + +If a recovery document was not found, either the user never performed +a backup, entered incorrect attributes, or used a provider not yet in +the list of Anastasis providers. Hence, the user must now either +select a different provider, or go @code{back} and update the identity +attributes. In the case a recovery document was not found, the +transition fails, returning the error code and a human-readable error +message together with a transition failure: + +@example +@{ + "recovery_state": "ERROR", + "error_message": "account unknown to Anastasis server", + "error_code": 9, +@} +@end example + +Here, the @code{error_code} is from the @code{enum ANASTASIS_RecoveryStatus} +and describes precisely what failed about the download, while the +@code{error_message} is a human-readable (English) explanation of the code. +Applications may want to translate the message using GNU gettext; +translations should be available in the @code{anastasis} text domain. +However, in general it should be sufficient to display the slightly +more generic Taler error code that is returned with the new state. + +@strong{change_version:} + +Even if a recovery document was found, it is possible that the user +intended to recover a different version, or recover a backup where +the recovery document is stored at a different provider. Thus, the +reducer allows the user to explicitly switch to a different provider +or recovery document version using the @code{change_version} transition, +which takes a provider URL and policy version as arguments: + +@example +@{ + "provider_url": "https://localhost:8080/", + "version": 2 +@} +@end example + +Note that using a version of 0 implies fetching “the latest version”. The +resulting states are the same as those of the @code{enter_user_attributes} +transition, except that the recovery document version is not necessarily the +latest available version at the provider. + +@strong{select_challenge:} + +Selecting a challenge takes different, depending on the state of the payment. +A comprehensive example for @code{select_challenge} would be: + +@example +@{ + "uuid": "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30" + "timeout" : @{ "d_ms" : 5000 @}, + "payment_secret": "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG" +@} +@end example + +The @code{uuid} field is mandatory and specifies the selected challenge. +The other fields are optional, and are needed in case the user has +previously been requested to pay for the challenge. In this case, +the @code{payment_secret} identifies the previous payment request, and +@code{timeout} says how long the Anastasis service should wait for the +payment to be completed before giving up (long polling). + +Depending on the type of the challenge and the need for payment, the +reducer may transition into @code{CHALLENGE_SOLVING} or @code{CHALLENGE_PAYING} +states. In @code{CHALLENGE_SOLVING}, the new state will primarily specify +the selected challenge: + +@example +@{ + "backup_state": "CHALLENGE_SOLVING", + "selected_challenge_uuid": "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30" +@} +@end example + +In @code{CHALLENGE_PAYING}, the new state will include instructions for payment +in the @code{challenge_feedback}. In general, @code{challenge_feedback} includes +information about attempted challenges, with the final state being @code{solved}: + +@example +@{ + "recovery_state": "CHALLENGE_SELECTING", + "recovery_information": @{ + "...": "..." + @} + "challenge_feedback": @{ + "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30" : @{ + "state" : "solved" + @} + @} +@} +@end example + +Challenges feedback for a challenge can have many different @code{state} values +that applications must all handle. States other than @code{solved} are: + +@quotation + + +@itemize - + +@item +@strong{payment}: Here, the user must pay for a challenge. An example would be: + +@example +@{ + "backup_state": "CHALLENGE_PAYING", + "selected_challenge_uuid": "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30", + "challenge_feedback": @{ + "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30" : @{ + "state" : "payment", + "taler_pay_uri" : "taler://pay/...", + "provider" : "https://localhost:8080/", + "payment_secret" : "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG" + @} + @} +@} +@end example +@end itemize + +@quotation + + +@itemize - + +@item +@strong{body}: Here, the server provided an HTTP reply for +how to solve the challenge, but the reducer could not parse +them into a known format. A mime-type may be provided and may +help parse the details. + +@example +@{ + "recovery_state": "CHALLENGE_SOLVING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "body", + "body": "CROCKFORDBASE32ENCODEDBODY", + "http_status": 403, + "mime_type" : "anything/possible" + @} + @} +@} +@end example + +@item +@strong{hint}: Here, the server provided human-readable hint for +how to solve the challenge. Note that the @code{hint} provided this +time is from the Anastasis provider and may differ from the @code{instructions} +for the challenge under @code{recovery_information}: + +@example +@{ + "recovery_state": "CHALLENGE_SOLVING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "hint", + "hint": "Recovery TAN send to email mail@@DOMAIN", + "http_status": 403 + @} + @} +@} +@end example + +@item +@strong{details}: Here, the server provided a detailed JSON status response +related to solving the challenge: + +@example +@{ + "recovery_state": "CHALLENGE_SOLVING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "details", + "details": @{ + "code": 8111, + "hint": "The client's response to the challenge was invalid.", + "detail" : null + @}, + "http_status": 403 + @} + @} +@} +@end example +@end itemize + +@quotation + + +@itemize - + +@item +@strong{redirect}: To solve the challenge, the user must visit the indicated +Web site at @code{redirect_url}, for example to perform video authentication: +@end itemize + +@quotation + +@example +@{ + "recovery_state": "CHALLENGE_SOLVING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "redirect", + "redirect_url": "https://videoconf.example.com/", + "http_status": 303 + @} + @} +@} +@end example + + +@itemize - + +@item +@strong{server-failure}: This indicates that the Anastasis provider encountered +a failure and recovery using this challenge cannot proceed at this time. +Examples for failures might be that the provider is unable to send SMS +messages at this time due to an outage. The body includes details about +the failure. The user may try again later or continue with other challenges. +@end itemize + +@example +@{ + "recovery_state": "CHALLENGE_SELECTING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "server-failure", + "http_status": "500", + "error_code": 52 + @} + @} +@} +@end example + + +@itemize - + +@item +@strong{truth-unknown}: This indicates that the Anastasis provider is unaware of +the specified challenge. This is typically a permanent failure, and user +interfaces should not allow users to re-try this challenge. +@end itemize + +@example +@{ + "recovery_state": "CHALLENGE_SELECTING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "truth-unknown", + "error_code": 8108 + @} + @} +@} +@end example + + +@itemize - + +@item +@strong{rate-limit-exceeded}: +@end itemize + +@example +@{ + "recovery_state": "CHALLENGE_SELECTING", + "recovery_information": @{ + "...": "..." + @} + "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0", + "challenge_feedback": @{ + "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{ + "state": "rate-limit-exceeded", + "error_code": 8121 + @} + @} +@} +@end example +@end quotation +@end quotation +@end quotation +@end quotation + +@strong{pay:} + +With a @code{pay} transition, the application indicates to the reducer that +a payment may have been made. Here, it is again possible to specify an +optional @code{timeout} argument for long-polling, for example: + +@example +@{ + "payment_secret": "ABCDADF242525AABASD52525235ABABFDABABANALASDAAKASDAS" + "timeout" : @{ "d_ms" : 5000 @}, +@} +@end example + +Depending on the type of the challenge and the result of the operation, the +new state may be @code{CHALLENGE_SOLVING} (if say the SMS was now sent to the +user), @code{CHALLENGE_SELECTING} (if the answer to the security question was +correct), @code{RECOVERY_FINISHED} (if this was the last challenge that needed to +be solved) or still @code{CHALLENGE_PAYING} (if the challenge was not actually +paid for). For sample messages, see the different types of +@code{challenge_feedback} in the section about @code{select_challenge}. + +@strong{solve_challenge:} + +Solving a challenge takes various formats, depending on the type of the +challenge and what is known about the answer. The different supported +formats are: + +@example +@{ + "answer": "answer to security question" +@} +@end example + +@example +@{ + "pin": 1234 +@} +@end example + +@example +@{ + "hash": "SOMEBASE32ENCODEDHASHVALUE" +@} +@end example + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node Authentication Methods,DB Schema,Reducer API,Documentation Overview +@anchor{authentication doc}@anchor{64}@anchor{authentication anastasis-auth-methods}@anchor{65}@anchor{authentication authentication-methods}@anchor{66} +@section Authentication Methods + + +This section describes the supported authentication methods in detail. We +note that the server implements rate limiting for all authentication methods +to ensure that malicious strong attackers cannot guess the values by +brute-force. Typically, a user is given three attempts per hour to enter the +correct code from 2^63 possible values. Transmitted codes also come with an +expiration date. If the user re-requests a challenge to be sent, the same +challenge may be transmitted (with the three attempts counter not increasing!) +for a limited period of time (depending on the authentication method) before +the service eventually rotates to a fresh random code with a fresh retry +counter. Given the default value range and time intervals (which providers are +at liberty to adjust), brute-force attacks against this are expected to +succeed with a 50% probability after about 200000 years of attempts at the +maximum permissible frequency. + +@menu +* SMS (sms): SMS sms. +* Email verification (email): Email verification email. +* Video identification (vid): Video identification vid. +* Security question (qa): Security question qa. +* Snail mail verification (post): Snail mail verification post. + +@end menu + +@node SMS sms,Email verification email,,Authentication Methods +@anchor{authentication sms-sms}@anchor{67} +@subsection SMS (sms) + + +Sends an SMS with a code (prefixed with @code{A-}) to the user’s phone, including +a UUID which identifies the challenge the code is for. The user must send +this code back with his request (see @code{$RESPONSE} under @ref{52,,Managing truth}). +If the transmitted code is correct, the server responses with the requested +encrypted key share. + +@node Email verification email,Video identification vid,SMS sms,Authentication Methods +@anchor{authentication email-verification-email}@anchor{68} +@subsection Email verification (email) + + +Sends an email with a code (prefixed with @code{A-}) to the user’s mail address, +including a UUID which identifies the challenge the code is for. The user +must send this code back with his request (see @code{$RESPONSE} under @ref{52,,Managing truth}). +If the transmitted code is correct, the server responses with the +requested encrypted key share. + +@node Video identification vid,Security question qa,Email verification email,Authentication Methods +@anchor{authentication video-identification-vid}@anchor{69} +@subsection Video identification (vid) + + +Requires the user to identify via video-call. In the video-call, the +user is told the code (prefixed with @code{A-}) needed to authenticate. + +The user is expected to delete all metadata revealing personal information +from the images before uploading them. Since the respective images must be +passed on to the video identification service in the event of password +recovery, it should be ensured that no further information about the user can +be derived from them. + +Video identification will typically result in the Anastasis provider +requesting the user to be redirected to a Web site (or other URL) for the +video-call. + +@node Security question qa,Snail mail verification post,Video identification vid,Authentication Methods +@anchor{authentication security-question-qa}@anchor{6a} +@subsection Security question (qa) + + +Asks the user a security question. The user sends back a @strong{salted} +hash over the answer. The @strong{question-salt} is stored encrypted as +part of the recovery document and never revealed to the providers. This +ensures that providers cannot derive the answer from the hash value. +Furthermore, the security question itself is also only in the recovery +document and never given to the Anastasis provider. A moderately expensive +hash function is used to further limit strong attackers that have obtained +the recovery document from brute-forcing the answer. + +If the hash value matches with the one the server is expecting, the server +answers with the requested encrypted key share. However, unlike other +encrypted key shares, the encrypted key share of a security question uses a +special variation of the Anastasis encryption: Here, a different hash function +over the security answer is used to provide an additional @strong{key-salt} for the +decryption of the (encrypted) @strong{key share}. This ensures that the key share +remains irrecoverable without the answer even if the Anastasis provider +storing the security question is malicious. + +@node Snail mail verification post,,Security question qa,Authentication Methods +@anchor{authentication snail-mail-verification-post}@anchor{6b} +@subsection Snail mail verification (post) + + +Sends physical mail (snail mail) with a code (prefixed with @code{A-}) to the +user’s mail address, including a UUID which identifies the challenge the code +is for. The user must send this code back with their request (see +@code{$RESPONSE} under @ref{52,,Managing truth}). If the transmitted code is correct, +the server responds with the requested encrypted key share. + +@c This file is part of Anastasis +@c Copyright (C) 2019-2021 Anastasis SARL +@c +@c Anastasis is free software; you can redistribute it and/or modify it under the +@c terms of the GNU Affero General Public License as published by the Free Software +@c Foundation; either version 2.1, or (at your option) any later version. +@c +@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY +@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +@c +@c You should have received a copy of the GNU Affero General Public License along with +@c Anastasis; see the file COPYING. If not, see +@c +@c @author Christian Grothoff +@c @author Dominik Meister +@c @author Dennis Neufeld + +@node DB Schema,Design Documents,Authentication Methods,Documentation Overview +@anchor{db doc}@anchor{6c}@anchor{db db-schema}@anchor{6d} +@section DB Schema + + +@image{anastasis-figures/anastasis-db,,,,png} + +@image{anastasis-figures/anastasis_challengecode,,,,png} + +@image{anastasis-figures/anastasis_challenge_payment,,,,png} + +@image{anastasis-figures/anastasis_truth,,,,png} + +@image{anastasis-figures/anastasis_truth_payment,,,,png} + +@node Design Documents,Anastasis licensing information,DB Schema,Documentation Overview +@anchor{design-documents/index doc}@anchor{6e}@anchor{design-documents/index design-documents}@anchor{6f} +@section Design Documents + + +This is a collection of design documents related to Anastasis. +The goal of these documents is to discuss facilitate discussion around +new features while keeping track of the evolution of the whole system +and protocol. + +@menu +* Design Doc 001; Anastasis User Experience: Design Doc 001 Anastasis User Experience. +* Template:: + +@end menu + +@node Design Doc 001 Anastasis User Experience,Template,,Design Documents +@anchor{design-documents/001-anastasis-ux doc}@anchor{70}@anchor{design-documents/001-anastasis-ux design-doc-001-anastasis-user-experience}@anchor{71} +@subsection Design Doc 001: Anastasis User Experience + + +@menu +* Summary:: +* Motivation:: +* Setup Steps:: +* Show Service Status After Setup:: +* Recovery Steps:: + +@end menu + +@node Summary,Motivation,,Design Doc 001 Anastasis User Experience +@anchor{design-documents/001-anastasis-ux summary}@anchor{72} +@subsubsection Summary + + +This document describes the recommended way of implementing the user experience +of setting up and making use of @ref{3,,Introduction} account recovery. + +@node Motivation,Setup Steps,Summary,Design Doc 001 Anastasis User Experience +@anchor{design-documents/001-anastasis-ux motivation}@anchor{73} +@subsubsection Motivation + + +Wallet state consisting of digital cash, transaction history etc. should not be lost. +Taler provides a backup mechanism to prevent that. +As an additional protection measure Anastasis can be used to provide access to the backup, +even if all devices and offline secrets have been lost. + +Access to the backup key is shared with escrow providers that can be chosen by the user. + +@node Setup Steps,Show Service Status After Setup,Motivation,Design Doc 001 Anastasis User Experience +@anchor{design-documents/001-anastasis-ux setup-steps}@anchor{74} +@subsubsection Setup Steps + +@image{graphviz-2d8d83202d2b7835498d2a5c18fa9e3cc05c4b6a,,,[graphviz],png} + +@menu +* Entry point; Settings: Entry point Settings. +* Providing Identification:: +* Add Authentication Methods:: +* Confirm/Change Service Providers:: +* Defining Recovery Options:: +* Pay for Setup:: + +@end menu + +@node Entry point Settings,Providing Identification,,Setup Steps +@anchor{design-documents/001-anastasis-ux entry-point-settings}@anchor{75} +@subsubsection Entry point: Settings + + +The app settings should have a section for Anastasis using a different more +universally understood name like Wallet Recovery. + +The section should have an option to setup Anastasis initially. This option +should be disabled as long as no backup has been set up. The section could +maybe be integrated into the backup settings. + +@image{anastasis-figures/menu,,,,png} + +@image{anastasis-figures/settings,,,,png} + +@image{anastasis-figures/backupsettings,,,,png} + +@node Providing Identification,Add Authentication Methods,Entry point Settings,Setup Steps +@anchor{design-documents/001-anastasis-ux providing-identification}@anchor{76} +@subsubsection Providing Identification + + +Instead of a forgettable freely chosen user name, Anastasis collects various +static information from the user to generate a unique user identifier from +that. Examples for such identifier would be a concatenation of the full name +of the user and their social security or passport number(s). + +The information that can reasonably used here various from cultural context +and jurisdiction. Therefore, one idea is to start by asking for continent and +then the country of primary legal residence, and then continue from there with +country-specific attributes (and also offer a stateless person option). + +Special care should be taken to avoid that information can later be provided +ambiguously thus changing the user identifier and not being able to restore +the user’s data. This can be typographic issues like someone providing +“Seestr.” and later “Seestrasse” or “Seestraße” or “seestrasse”. But it can +also be simple typos that we can only prevent in some instances like when +checking checksums in passport numbers. + +The user should be made aware that this data will not leave the app and that +it is only used to compute a unique identifier that can not be forgotten. + +If possible, we should guide the user in the country selection by accessing +permission-less information such as the currently set language/locale and the +country of the SIM card. But nothing invasive like the actual GPS location. + +@image{anastasis-figures/userid,,,,png} + +@node Add Authentication Methods,Confirm/Change Service Providers,Providing Identification,Setup Steps +@anchor{design-documents/001-anastasis-ux add-authentication-methods}@anchor{77} +@subsubsection Add Authentication Methods + + +After creating a unique identifier, the user can chose one or more +@ref{65,,Authentication Methods} supported by Anastasis. + +When selecting a method, the user is already asked to provide the information +required for the recovery with that method. For example, a photo of +themselves, their phone number or mailing address. + +The user interface validates that the inputs are well-formed, and refuses +inputs that are clearly invalid. Where possible, it pre-fills the fields with +sane values (phone number, e-mail addresses, country of residence). + +@image{anastasis-figures/truth,,,,png} + +@image{anastasis-figures/addtruth,,,,png} + +@image{anastasis-figures/addtruthmail,,,,png} + +@node Confirm/Change Service Providers,Defining Recovery Options,Add Authentication Methods,Setup Steps +@anchor{design-documents/001-anastasis-ux confirm-change-service-providers}@anchor{78} +@subsubsection Confirm/Change Service Providers + + +From the dialog where the user is adding authentication methods, the user can +optionally jump to a side-action with list of available providers (and their +status) and possibly add additional providers that are not included in the +default list provided by the wallet. + +@image{anastasis-figures/policy,,,,png} + +@image{anastasis-figures/addpolicy,,,,png} + +@image{anastasis-figures/addpolicymethod,,,,png} + +@node Defining Recovery Options,Pay for Setup,Confirm/Change Service Providers,Setup Steps +@anchor{design-documents/001-anastasis-ux defining-recovery-options}@anchor{79} +@subsubsection Defining Recovery Options + + +After mapping authentication methods to providers, the user needs select which +combinations are sufficient to recover the secret. Here, the system +pre-computes a reasonably sane allocation, for small @code{n} the default could +be @code{n-1} out of @code{n}. + +We should propose a mapping of authentication methods to providers by +minimizing cost (tricky: sign-up vs. recovery costs, different currencies) and +distributing the selected authentication methods across as many providers as +possible. + +The user should be able to change the proposed default selection +and add more than one provider to each chosen method. + +Using Anastatis providers usually is not free. From here on, the UI should +show estimated recurring costs (yearly) and the cost of recovery. These costs +should get updated with each user action affecting those costs such as +when the user reconfigures the policies. + +@node Pay for Setup,,Defining Recovery Options,Setup Steps +@anchor{design-documents/001-anastasis-ux pay-for-setup}@anchor{7a} +@subsubsection Pay for Setup + + +As the last step when all information has been properly provided, the user is +asked to pay for the service with the regular wallet payment confirmation +screen. + +@node Show Service Status After Setup,Recovery Steps,Setup Steps,Design Doc 001 Anastasis User Experience +@anchor{design-documents/001-anastasis-ux show-service-status-after-setup}@anchor{7b} +@subsubsection Show Service Status After Setup + + +TODO + +@node Recovery Steps,,Show Service Status After Setup,Design Doc 001 Anastasis User Experience +@anchor{design-documents/001-anastasis-ux recovery-steps}@anchor{7c} +@subsubsection Recovery Steps + +@image{graphviz-834e5a93329dec2ccdefd2a21bdfb5a02bad1c84,,,[graphviz],png} + +@menu +* Entry point; Settings: Entry point Settings<2>. +* Providing Identification: Providing Identification<2>. +* Select Authentication Challenge:: +* Payment:: +* Enter Challenge Response:: +* Success:: + +@end menu + +@node Entry point Settings<2>,Providing Identification<2>,,Recovery Steps +@anchor{design-documents/001-anastasis-ux id1}@anchor{7d} +@subsubsection Entry point: Settings + + +Like the backup, the recovery option should be available via +the App settings. + +The section should have an option to recover from backup. If a previous +recovery was not completed, the interaction should resume from that previous +checkpoint instead of from the beginning. + +@image{anastasis-figures/menu,,,,png} + +@image{anastasis-figures/settings,,,,png} + +@image{anastasis-figures/backupsettings,,,,png} + +@node Providing Identification<2>,Select Authentication Challenge,Entry point Settings<2>,Recovery Steps +@anchor{design-documents/001-anastasis-ux id2}@anchor{7e} +@subsubsection Providing Identification + + +The first dialog(s) during recovery should be identical to the first dialog +during backup: the user is asked to select a continent, country of residence +and then to provide country-specific inputs for identification. + +@image{anastasis-figures/userid,,,,png} + +@node Select Authentication Challenge,Payment,Providing Identification<2>,Recovery Steps +@anchor{design-documents/001-anastasis-ux select-authentication-challenge}@anchor{7f} +@subsubsection Select Authentication Challenge + + +If Anastasis could recover the recovery document via any provider, it should +show a dialog allowing the user to select one of the open challenges, and +highlight which challenges still need to be satisfied for the various policies. + +Additionally, the specific provider and recovery document version should be shown. +The user should be able to change the provider or recovery document version, +resulting in a switch of the recovery document and policies. If the user has +already satisfied some challenges of the current recovery document, switching to a +different recovery document should only be done after a confirmation pop-up dialog +warning the user that the existing progress will be lost. + +When selecting a challenge, the user may be asked to confirm making a payment +for this challenge if the provider requires payment. + +@node Payment,Enter Challenge Response,Select Authentication Challenge,Recovery Steps +@anchor{design-documents/001-anastasis-ux payment}@anchor{80} +@subsubsection Payment + + +Typcially, this would be the canonical wallet payment confirmation dialog. + +However, in the case of a security question, the payment confirmation should +be combined with the dialog where the user enters the security answer (so +instead of an @code{Ok} button, text showing the amount due and @code{Pay} should be +used – except of course if the security question challenge is free of +charge). + +@node Enter Challenge Response,Success,Payment,Recovery Steps +@anchor{design-documents/001-anastasis-ux enter-challenge-response}@anchor{81} +@subsubsection Enter Challenge Response + + +If the challenge was not a security question, the dialog to enter the security +code (PIN/TAN) should open after payment. The security code field should have +a prefix @code{A-}. However, the user should be able to enter both only the +numeric code, or the full code with the @code{A-} prefix (or ideally, the user +cannot delete the pre-filled @code{A-} text). + +@node Success,,Enter Challenge Response,Recovery Steps +@anchor{design-documents/001-anastasis-ux success}@anchor{82} +@subsubsection Success + + +The user is informed about the successful recovery. We may want to do this +as part of a separate screen, or simply with a notification bar in the +main wallet screen. + +@node Template,,Design Doc 001 Anastasis User Experience,Design Documents +@anchor{design-documents/999-template doc}@anchor{83}@anchor{design-documents/999-template template}@anchor{84} +@subsection Template + + +@menu +* Summary: Summary<2>. +* Motivation: Motivation<2>. +* Requirements:: +* Proposed Solution:: +* Alternatives:: +* Drawbacks:: +* Discussion / Q&A:: + +@end menu + +@node Summary<2>,Motivation<2>,,Template +@anchor{design-documents/999-template summary}@anchor{85} +@subsubsection Summary + + +@node Motivation<2>,Requirements,Summary<2>,Template +@anchor{design-documents/999-template motivation}@anchor{86} +@subsubsection Motivation + + +@node Requirements,Proposed Solution,Motivation<2>,Template +@anchor{design-documents/999-template requirements}@anchor{87} +@subsubsection Requirements + + +@node Proposed Solution,Alternatives,Requirements,Template +@anchor{design-documents/999-template proposed-solution}@anchor{88} +@subsubsection Proposed Solution + + +@node Alternatives,Drawbacks,Proposed Solution,Template +@anchor{design-documents/999-template alternatives}@anchor{89} +@subsubsection Alternatives + + +@node Drawbacks,Discussion / Q&A,Alternatives,Template +@anchor{design-documents/999-template drawbacks}@anchor{8a} +@subsubsection Drawbacks + + +@node Discussion / Q&A,,Drawbacks,Template +@anchor{design-documents/999-template discussion-q-a}@anchor{8b} +@subsubsection Discussion / Q&A + + +(This should be filled in with results from discussions on mailing lists / personal communication.) + +@node Anastasis licensing information,Man Pages,Design Documents,Documentation Overview +@anchor{global-licensing doc}@anchor{8c}@anchor{global-licensing anastasis-licensing-information}@anchor{8d} +@section Anastasis licensing information + + +This file gives an overview of all Anastasis component’s licensing and +of runtime dependencies thereof. For “component” here is meant a set +of source files which can be retrieved from a single repository. If +components consist of sources under different licensing regimes, i.e. +because we want to enable third party developments to easily integrate +with Taler, those are described as well. + +All Anastasis components are generally released under the Affero +GPL. + +@menu +* Anastasis (git;//git.taler.net/anastasis): Anastasis git //git taler net/anastasis. +* Anastasis-gtk (git;//git.taler.net/anastasis-gtk): Anastasis-gtk git //git taler net/anastasis-gtk. +* Documentation:: + +@end menu + +@node Anastasis git //git taler net/anastasis,Anastasis-gtk git //git taler net/anastasis-gtk,,Anastasis licensing information +@anchor{global-licensing anastasis-git-git-taler-net-anastasis}@anchor{8e}@anchor{global-licensing exchange-repo}@anchor{8f} +@subsection Anastasis (git://git.taler.net/anastasis) + + +Anastasis core logic is under AGPL. + +@menu +* Runtime dependencies:: + +@end menu + +@node Runtime dependencies,,,Anastasis git //git taler net/anastasis +@anchor{global-licensing runtime-dependencies}@anchor{90} +@subsubsection Runtime dependencies + + +The following list encompasses all the runtime dependencies for this +project, and gives the copyright holder for each of them: + + +@itemize * + +@item +libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen and other individuals + +@item +libgcrypt: LGPL, owned by Free Software Foundation + +@item +postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The PostgreSQL Global Development Group + +@item +libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V. + +@item +libgnunetjson: GPLv3+, GNUnet e.V. + +@item +GNU Taler: LGPLv3+ / GPLv3+ / AGPLv3+: owned by Taler Systems SA +@end itemize + +@node Anastasis-gtk git //git taler net/anastasis-gtk,Documentation,Anastasis git //git taler net/anastasis,Anastasis licensing information +@anchor{global-licensing anastasis-gtk-git-git-taler-net-anastasis-gtk}@anchor{91} +@subsection Anastasis-gtk (git://git.taler.net/anastasis-gtk) + + +Anastasis-gtk is under AGPL. + +@menu +* Runtime dependencies: Runtime dependencies<2>. + +@end menu + +@node Runtime dependencies<2>,,,Anastasis-gtk git //git taler net/anastasis-gtk +@anchor{global-licensing id1}@anchor{92} +@subsubsection Runtime dependencies + + +The following list encompasses all the runtime dependencies for this +project, and gives the copyright holder for each of them: + + +@itemize * + +@item +libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen and other individuals + +@item +libgcrypt: LGPL, owned by Free Software Foundation + +@item +postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The PostgreSQL Global Development Group + +@item +libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V. + +@item +libgnunetjson: GPLv3+, GNUnet e.V. + +@item +libgnunetgtk: GPLv3+, GNUnet e.V. + +@item +GNU Taler: LGPLv3+ / GPLv3+ / AGPLv3+: owned by Taler Systems SA +@end itemize + +@node Documentation,,Anastasis-gtk git //git taler net/anastasis-gtk,Anastasis licensing information +@anchor{global-licensing documentation}@anchor{93} +@subsection Documentation + + +The documentation is licensed under the GNU Free Documentation License Version 1.3 or later. + +@node Man Pages,Complete Index,Anastasis licensing information,Documentation Overview +@anchor{manindex doc}@anchor{94}@anchor{manindex man-pages}@anchor{95} +@section Man Pages + + +@menu +* anastasis-config(1): anastasis-config 1. +* anastasis-gtk(1): anastasis-gtk 1. +* anastasis-httpd(1): anastasis-httpd 1. +* anastasis-reducer(1): anastasis-reducer 1. +* anastasis.conf(5): anastasis conf 5. + +@end menu + +@node anastasis-config 1,anastasis-gtk 1,,Man Pages +@anchor{manpages/anastasis-config 1 doc}@anchor{96}@anchor{manpages/anastasis-config 1 anastasis-config-1}@anchor{97} +@subsection anastasis-config(1) + + + +@menu +* Synopsis:: +* Description:: +* See Also:: +* Bugs:: + +@end menu + +@node Synopsis,Description,,anastasis-config 1 +@anchor{manpages/anastasis-config 1 synopsis}@anchor{98} +@subsubsection Synopsis + + +@strong{anastasis-config} +[@strong{-b} @emph{backend} | @strong{––supported-backend=}@emph{backend}] +[@strong{-c} @emph{filename} | @strong{––config=}@emph{filename}] +[@strong{-f} | @strong{––filename}] +[@strong{-F} | @strong{––full}] +[@strong{-h} | @strong{––help}] +[@strong{-L} @emph{loglevel} | @strong{––loglevel=}@emph{loglevel}] +[@strong{-l} @emph{filename} | @strong{––logfile=}‌@emph{filename}] +[@strong{-o} @emph{option} | @strong{––option=}@emph{option}] +[@strong{-r} | @strong{––rewrite}] +[@strong{-S} | @strong{––list-sections}] +[@strong{-s} @emph{section} | @strong{––section=}@emph{section}] +[@strong{-V} @emph{value} | @strong{––value=}@emph{value}] +[@strong{-v} | @strong{––version}] + +@node Description,See Also,Synopsis,anastasis-config 1 +@anchor{manpages/anastasis-config 1 description}@anchor{99} +@subsubsection Description + + +@strong{anastasis-config} can be used to read or modify Anastasis configuration files. + + +@table @asis + +@item @strong{-b} @emph{BACKEND} | @strong{––supported-backend=}@emph{BACKEND} + +Tests whether the specified @emph{BACKEND} is supported by the current installation. +The backend must match the name of a plugin, i.e. “namestore_postgres” for +the Postgres database backend of the “NAMESTORE” service. If @emph{BACKEND} is +supported, anastasis-config will return a status code of 0 (success), otherwise +77 (unsupported). When this option is specified, no other options may be +specified. Specifying this option together with other options will cause +anastasis-config to return a status code of 1 (error). + +@item @strong{-c} @emph{FILENAME} | @strong{––config=}@emph{FILENAME} + +Use the configuration file @emph{FILENAME}. + +@item @strong{-f} | @strong{––filename} + +Try to perform expansions as if the option values represent filenames (will +also be applied even if the option is not really a filename). + +@item @strong{-F} | @strong{––full} + +Write the full configuration file, not just the differences to the defaults. + +@item @strong{-h} | @strong{––help} + +Print short help on options. + +@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}@emph{LOGLEVEL} + +Use @emph{LOGLEVEL} for logging. +Valid values are @code{DEBUG}, @code{INFO}, @code{WARNING}, and @code{ERROR}. + +@item @strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME} + +Send logging output to @emph{FILENAME}. + +@item @strong{-o} @emph{OPTION} | @strong{––option=}@emph{OPTION} + +Which configuration option should be accessed or edited. Required to set a +value. If not given, all values of a given section will be printed in the +format “OPTION = VALUE”. + +@item @strong{-r} | @strong{––rewrite} + +Write the configuration file even if nothing changed. Will remove all comments! + +@item @strong{-S} | @strong{––list-sections} + +List available configuration sections for use with @code{--section}. + +@item @strong{-s} @emph{SECTION} | @strong{––section=}@emph{SECTION} + +Which configuration section should be accessed or edited. +Required option. + +@item @strong{-V} @emph{VALUE} | @strong{––value=}@emph{VALUE} + +Configuration value to store in the given section under the given option. +Must only be given together with @code{-s} and @code{-o} options. + + +@table @asis + +@item Note: + +Changing the configuration file with @code{-V} will remove comments +and may reorder sections and remove @code{@@INLINE@@} directives. +@end table + +@item @strong{-v} | @strong{––version} + +Print Anastasis version number. +@end table + +@node See Also,Bugs,Description,anastasis-config 1 +@anchor{manpages/anastasis-config 1 see-also}@anchor{9a} +@subsubsection See Also + + +anastasis.conf(5) + +@node Bugs,,See Also,anastasis-config 1 +@anchor{manpages/anastasis-config 1 bugs}@anchor{9b} +@subsubsection Bugs + + +Report bugs by using @indicateurl{https://bugs.anastasis.lu} or by sending electronic +mail to <@email{contact@@anastasis.lu}>. + +@node anastasis-gtk 1,anastasis-httpd 1,anastasis-config 1,Man Pages +@anchor{manpages/anastasis-gtk 1 doc}@anchor{9c}@anchor{manpages/anastasis-gtk 1 anastasis-gtk-1}@anchor{9d} +@subsection anastasis-gtk(1) + + + +@menu +* Synopsis: Synopsis<2>. +* Description: Description<2>. +* See Also: See Also<2>. +* Bugs: Bugs<2>. + +@end menu + +@node Synopsis<2>,Description<2>,,anastasis-gtk 1 +@anchor{manpages/anastasis-gtk 1 synopsis}@anchor{9e} +@subsubsection Synopsis + + +@strong{anastasis-gtk} +[@strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}] +[@strong{-h} | @strong{––help}] +[@strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}] +[@strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}] +[@strong{-v} | @strong{––version}] + +@node Description<2>,See Also<2>,Synopsis<2>,anastasis-gtk 1 +@anchor{manpages/anastasis-gtk 1 description}@anchor{9f} +@subsubsection Description + + +@strong{anastasis-gtk} is a graphical tool to run Anastasis +key recover and backup operations. + + +@table @asis + +@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME} + +Use the configuration from @emph{FILENAME}. + +@item @strong{-h} | @strong{––help} + +Print short help on options. + +@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL} + +Specifies the log level to use. Accepted values are: @code{DEBUG}, @code{INFO}, +@code{WARNING}, @code{ERROR}. + +@item @strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME} + +Send logging output to @emph{FILENAME}. + +@item @strong{-v} | @strong{––version} + +Print version information. +@end table + +@node See Also<2>,Bugs<2>,Description<2>,anastasis-gtk 1 +@anchor{manpages/anastasis-gtk 1 see-also}@anchor{a0} +@subsubsection See Also + + +anastasis-reducer(1), anastasis-httpd(1), anastasis.conf(5). + +@node Bugs<2>,,See Also<2>,anastasis-gtk 1 +@anchor{manpages/anastasis-gtk 1 bugs}@anchor{a1} +@subsubsection Bugs + + +Report bugs by using @indicateurl{https://bugs.anastasis.lu/} or by sending electronic +mail to <@email{contact@@anastasis.lu}>. + +@node anastasis-httpd 1,anastasis-reducer 1,anastasis-gtk 1,Man Pages +@anchor{manpages/anastasis-httpd 1 doc}@anchor{a2}@anchor{manpages/anastasis-httpd 1 anastasis-httpd-1}@anchor{a3} +@subsection anastasis-httpd(1) + + + +@menu +* Synopsis: Synopsis<3>. +* Description: Description<3>. +* Signals:: +* See also:: +* Bugs: Bugs<3>. + +@end menu + +@node Synopsis<3>,Description<3>,,anastasis-httpd 1 +@anchor{manpages/anastasis-httpd 1 synopsis}@anchor{a4} +@subsubsection Synopsis + + +@strong{anastasis-httpd} + +@node Description<3>,Signals,Synopsis<3>,anastasis-httpd 1 +@anchor{manpages/anastasis-httpd 1 description}@anchor{a5} +@subsubsection Description + + +Banastasis-httpd is a command line tool to run the Anastasis (HTTP +backend). The required configuration and database must exist before +running this command. + +Its options are as follows: + + +@table @asis + +@item @strong{-C} | @strong{–connection-close} + +Force each HTTP connection to be closed after each request. + +@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME} + +Use the configuration and other resources for the merchant to operate +from FILENAME. + +@item @strong{-h} | @strong{––help} + +Print short help on options. + +@item @strong{-v} | @strong{––version} + +Print version information. +@end table + +@node Signals,See also,Description<3>,anastasis-httpd 1 +@anchor{manpages/anastasis-httpd 1 signals}@anchor{a6} +@subsubsection Signals + + +@strong{anastasis-httpd} responds to the following signals: + + +@table @asis + +@item @code{SIGTERM} + +Sending a SIGTERM to the process will cause it to shutdown cleanly. +@end table + +@node See also,Bugs<3>,Signals,anastasis-httpd 1 +@anchor{manpages/anastasis-httpd 1 see-also}@anchor{a7} +@subsubsection See also + + +anastasis-dbinit(1), anastasis-config(1), anastasis-gtk(1), anastasis-reducer(1) + +@node Bugs<3>,,See also,anastasis-httpd 1 +@anchor{manpages/anastasis-httpd 1 bugs}@anchor{a8} +@subsubsection Bugs + + +Report bugs by using @indicateurl{https://bugs.anastasis.lu} or by sending +electronic mail to <@email{contact@@anastasis.lu}>. + +@node anastasis-reducer 1,anastasis conf 5,anastasis-httpd 1,Man Pages +@anchor{manpages/anastasis-reducer 1 doc}@anchor{a9}@anchor{manpages/anastasis-reducer 1 anastasis-reducer-1}@anchor{aa} +@subsection anastasis-reducer(1) + + + +@menu +* Synopsis: Synopsis<4>. +* Description: Description<4>. +* See Also: See Also<3>. +* Bugs: Bugs<4>. + +@end menu + +@node Synopsis<4>,Description<4>,,anastasis-reducer 1 +@anchor{manpages/anastasis-reducer 1 synopsis}@anchor{ab} +@subsubsection Synopsis + + +@strong{anastasis-reducer} +[@strong{-a**_*JSON*_|_}–arguments=@emph{JSON}] +[@strong{-b**_|_}–backup] +[@strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}] +[@strong{-h} | @strong{––help}] +[@strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}] +[@strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}] +[@strong{-r**_|_}–restore] +[@strong{-v} | @strong{––version}] COMMAND + +@node Description<4>,See Also<3>,Synopsis<4>,anastasis-reducer 1 +@anchor{manpages/anastasis-reducer 1 description}@anchor{ac} +@subsubsection Description + + +@strong{anastasis-reducer} is a command-line tool to run Anastasis +key recover and backup operations using a reducer-style interface. +The reducer will read the current state from standard input and +write the resulting state to standard output. A COMMAND must +be given on the command line. The arguments (if any) are to +be given in JSON format to the @strong{-a} option. A list of +commands can be found in the @ref{58,,Reducer API} +chapter. + + +@table @asis + +@item @strong{-a} @emph{JSON} | @strong{––arguments=}@emph{JSON} + +Provide JSON inputs for the given command. + +@item @strong{-b} | @strong{–backup} + +Begin fresh reducer operation for a back up operation. + +@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME} + +Use the configuration from @emph{FILENAME}. + +@item @strong{-h} | @strong{––help} + +Print short help on options. + +@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL} + +Specifies the log level to use. Accepted values are: @code{DEBUG}, @code{INFO}, +@code{WARNING}, @code{ERROR}. + +@item @strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME} + +Send logging output to @emph{FILENAME}. + +@item @strong{-r} | @strong{–restore} + +Begin fresh reducer operation for a restore operation. + +@item @strong{-v} | @strong{––version} + +Print version information. +@end table + +@node See Also<3>,Bugs<4>,Description<4>,anastasis-reducer 1 +@anchor{manpages/anastasis-reducer 1 see-also}@anchor{ad} +@subsubsection See Also + + +anastasis-gtk(1), anastasis-httpd(1), anastasis.conf(5). + +@node Bugs<4>,,See Also<3>,anastasis-reducer 1 +@anchor{manpages/anastasis-reducer 1 bugs}@anchor{ae} +@subsubsection Bugs + + +Report bugs by using @indicateurl{https://bugs.anastasis.lu/} or by sending electronic +mail to <@email{contact@@anastasis.lu}>. + +@node anastasis conf 5,,anastasis-reducer 1,Man Pages +@anchor{manpages/anastasis conf 5 doc}@anchor{af}@anchor{manpages/anastasis conf 5 anastasis-conf-5}@anchor{b0} +@subsection anastasis.conf(5) + + + +@menu +* Description: Description<5>. +* SEE ALSO:: +* BUGS:: + +@end menu + +@node Description<5>,SEE ALSO,,anastasis conf 5 +@anchor{manpages/anastasis conf 5 description}@anchor{b1} +@subsubsection Description + + +The configuration file is line-oriented. +Blank lines and whitespace at the beginning and end of a line are ignored. +Comments start with @code{#} or @code{%} in the first column +(after any beginning-of-line whitespace) and go to the end of the line. + +The file is split into sections. +Every section begins with “[SECTIONNAME]” and +contains a number of options of the form “OPTION=VALUE”. +There may be whitespace around the @code{=} (equal sign). +Section names and options are @emph{case-insensitive}. + +The values, however, are @emph{case-sensitive}. +In particular, boolean values are one of @code{YES} or @code{NO}. +Values can include whitespace by surrounding +the entire value with @code{"} (double quote). +Note, however, that there are no escape characters in such strings; +all characters between the double quotes (including other double quotes) +are taken verbatim. + +Values that represent filenames can begin with a @code{/bin/sh}-like +variable reference. +This can be simple, such as @code{$TMPDIR/foo}, or complex, +such as @code{$@{TMPDIR:-$@{TMP:-/tmp@}@}/foo}. +See @code{[PATHS]} (below). + +Values that represent a time duration are represented as a series of one or +more @code{NUMBER UNIT} pairs, e.g. @code{60 s}, @code{4 weeks 1 day}, @code{5 years 2 minutes}. + +Values that represent an amount are in the usual amount syntax: +@code{CURRENCY:VALUE.FRACTION}, e.g. @code{EUR:1.50}. +The @code{FRACTION} portion may extend up to 8 places. + +Files containing default values for many of the options described below +are installed under @code{$ANASTASIS_PREFIX/share/taler/config.d/}. +The configuration file given with @strong{-c} to Anastasis binaries +overrides these defaults. + +A configuration file may include another, by using the @code{@@INLINE@@} directive, +for example, in @code{main.conf}, you could write @code{@@INLINE@@ sub.conf} to +include the entirety of @code{sub.conf} at that point in @code{main.conf}. +.. TODO: Document ‘anastasis-config -V’ in light of ‘@@INLINE@@’ in taler-config(1). + +@menu +* GLOBAL OPTIONS:: +* Authorization options:: +* Postgres database configuration:: + +@end menu + +@node GLOBAL OPTIONS,Authorization options,,Description<5> +@anchor{manpages/anastasis conf 5 global-options}@anchor{b2} +@subsubsection GLOBAL OPTIONS + + +The following options are from the @code{[anastasis]} section and used by +the @strong{anastasis-httpd} service. + + +@table @asis + +@item PAYMENT_BACKEND_URL + +Base-URL of the Taler merchant backend instance to use for payments. +FIXME: How do we pass the access token? + +@item ANNUAL_FEE + +Annual fee to be paid for policy uploads, i.e. “EUR:1.5”. + +@item TRUTH_UPLOAD_FEE + +Annual fee to be paid for truth uploads, i.e. “EUR:1.5”. + +@item DB + +Database backend to use, only @code{postgres} is supported right now. + +@item UPLOAD_LIMIT_MB + +Maximum upload size for policy uploads in megabytes. Default is 1. + +@item ANNUAL_POLICY_UPLOAD_LIMIT + +Maximum number of policies uploaded per year of service. Default is 42. + +@item BUSINESS_NAME + +Name of the business. + +@item SERVER_SALT + +Must be set to a high-entropy random server salt that the provider must never +change after the initial configuration. + +@item PORT + +TCP port on which the HTTP service should listen on. +@end table + +@node Authorization options,Postgres database configuration,GLOBAL OPTIONS,Description<5> +@anchor{manpages/anastasis conf 5 authorization-options}@anchor{b3} +@subsubsection Authorization options + + +For each active authorization plugin, options must be configured in +a section called @code{[authorization-$PLUGIN]} where @code{$PLUGIN} is +the name of the authorization plugin. + + +@table @asis + +@item COST + +Fee the user has to pay to obtain a challenge from this +authorization plugin during recovery. + +@item ENABLED + +@code{yes} to enable this plugin, @code{no} to disable. + +@item COMMAND + +Helper command to run (only relevant for some plugins). +@end table + +@node Postgres database configuration,,Authorization options,Description<5> +@anchor{manpages/anastasis conf 5 postgres-database-configuration}@anchor{b4} +@subsubsection Postgres database configuration + + +The following options must be in the section @code{[statis-postgres]} if +@code{postgres} was used for the database under @code{DB} in the +@code{[anastasis]} section. + + +@table @asis + +@item CONFIG + +Path under which the Postgres database is that the service +should use, i.e. @code{postgres://anastasis}. +@end table + +@node SEE ALSO,BUGS,Description<5>,anastasis conf 5 +@anchor{manpages/anastasis conf 5 see-also}@anchor{b5} +@subsubsection SEE ALSO + + +anastasis-httpd(1), anastasis-config(1) + +@node BUGS,,SEE ALSO,anastasis conf 5 +@anchor{manpages/anastasis conf 5 bugs}@anchor{b6} +@subsubsection BUGS + + +Report bugs by using @indicateurl{https://bugs.anastasis.lu/} or by sending electronic +mail to <@email{contact@@anastasis.lu}>. + +@node Complete Index,GNU Free Documentation License,Man Pages,Documentation Overview +@anchor{genindex doc}@anchor{b7}@anchor{genindex complete-index}@anchor{b8} +@section Complete Index + + +@node GNU Free Documentation License,,Complete Index,Documentation Overview +@anchor{fdl-1 3 doc}@anchor{b9}@anchor{fdl-1 3 gnu-fdl-1-3}@anchor{ba}@anchor{fdl-1 3 gnu-free-documentation-license}@anchor{bb} +@section GNU Free Documentation License + + +Version 1.3, 3 November 2008 + +Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, +Inc. @indicateurl{https://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +@menu +* 0. PREAMBLE: 0 PREAMBLE. +* 1. APPLICABILITY AND DEFINITIONS: 1 APPLICABILITY AND DEFINITIONS. +* 2. VERBATIM COPYING: 2 VERBATIM COPYING. +* 3. COPYING IN QUANTITY: 3 COPYING IN QUANTITY. +* 4. MODIFICATIONS: 4 MODIFICATIONS. +* 5. COMBINING DOCUMENTS: 5 COMBINING DOCUMENTS. +* 6. COLLECTIONS OF DOCUMENTS: 6 COLLECTIONS OF DOCUMENTS. +* 7. AGGREGATION WITH INDEPENDENT WORKS: 7 AGGREGATION WITH INDEPENDENT WORKS. +* 8. TRANSLATION: 8 TRANSLATION. +* 9. TERMINATION: 9 TERMINATION. +* 10. FUTURE REVISIONS OF THIS LICENSE: 10 FUTURE REVISIONS OF THIS LICENSE. +* 11. RELICENSING: 11 RELICENSING. +* ADDENDUM; How to use this License for your documents: ADDENDUM How to use this License for your documents. + +@end menu + +@node 0 PREAMBLE,1 APPLICABILITY AND DEFINITIONS,,GNU Free Documentation License +@anchor{fdl-1 3 preamble}@anchor{bc} +@subsection 0. PREAMBLE + + +The purpose of this License is to make a manual, textbook, or other +functional and useful document “free” in the sense of freedom: to assure +everyone the effective freedom to copy and redistribute it, with or +without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of “copyleft”, which means that derivative works +of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft license +designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free program +should come with manuals providing the same freedoms that the software +does. But this License is not limited to software manuals; it can be +used for any textual work, regardless of subject matter or whether it is +published as a printed book. We recommend this License principally for +works whose purpose is instruction or reference. + +@node 1 APPLICABILITY AND DEFINITIONS,2 VERBATIM COPYING,0 PREAMBLE,GNU Free Documentation License +@anchor{fdl-1 3 applicability-and-definitions}@anchor{bd} +@subsection 1. APPLICABILITY AND DEFINITIONS + + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The “Document”, below, refers +to any such manual or work. Any member of the public is a licensee, and +is addressed as “you”. You accept the license if you copy, modify or +distribute the work in a way requiring permission under copyright law. + +A “Modified Version” of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A “Secondary Section” is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document’s overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (Thus, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding them. + +The “Invariant Sections” are certain Secondary Sections whose titles are +designated, as being those of Invariant Sections, in the notice that +says that the Document is released under this License. If a section does +not fit the above definition of Secondary then it is not allowed to be +designated as Invariant. The Document may contain zero Invariant +Sections. If the Document does not identify any Invariant Sections then +there are none. + +The “Cover Texts” are certain short passages of text that are listed, as +Front-Cover Texts or Back-Cover Texts, in the notice that says that the +Document is released under this License. A Front-Cover Text may be at +most 5 words, and a Back-Cover Text may be at most 25 words. + +A “Transparent” copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the general +public, that is suitable for revising the document straightforwardly +with generic text editors or (for images composed of pixels) generic +paint programs or (for drawings) some widely available drawing editor, +and that is suitable for input to text formatters or for automatic +translation to a variety of formats suitable for input to text +formatters. A copy made in an otherwise Transparent file format whose +markup, or absence of markup, has been arranged to thwart or discourage +subsequent modification by readers is not Transparent. An image format +is not Transparent if used for any substantial amount of text. A copy +that is not “Transparent” is called “Opaque”. + +Examples of suitable formats for Transparent copies include plain ASCII +without markup, Texinfo input format, LaTeX input format, SGML or XML +using a publicly available DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the machine-generated +HTML, PostScript or PDF produced by some word processors for output +purposes only. + +The “Title Page” means, for a printed book, the title page itself, plus +such following pages as are needed to hold, legibly, the material this +License requires to appear in the title page. For works in formats which +do not have any title page as such, “Title Page” means the text near the +most prominent appearance of the work’s title, preceding the beginning +of the body of the text. + +The “publisher” means any person or entity that distributes copies of +the Document to the public. + +A section “Entitled XYZ” means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as “Acknowledgements”, +“Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of +such a section when you modify the Document means that it remains a +section “Entitled XYZ” according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this License, +but only as regards disclaiming warranties: any other implication that +these Warranty Disclaimers may have is void and has no effect on the +meaning of this License. + +@node 2 VERBATIM COPYING,3 COPYING IN QUANTITY,1 APPLICABILITY AND DEFINITIONS,GNU Free Documentation License +@anchor{fdl-1 3 verbatim-copying}@anchor{be} +@subsection 2. VERBATIM COPYING + + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies to +the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further copying +of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@node 3 COPYING IN QUANTITY,4 MODIFICATIONS,2 VERBATIM COPYING,GNU Free Documentation License +@anchor{fdl-1 3 copying-in-quantity}@anchor{bf} +@subsection 3. COPYING IN QUANTITY + + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document’s license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover Texts: +Front-Cover Texts on the front cover, and Back-Cover Texts on the back +cover. Both covers must also clearly and legibly identify you as the +publisher of these copies. The front cover must present the full title +with all words of the title equally prominent and visible. You may add +other material on the covers in addition. Copying with changes limited +to the covers, as long as they preserve the title of the Document and +satisfy these conditions, can be treated as verbatim copying in other +respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy a +computer-network location from which the general network-using public +has access to download using public-standard network protocols a +complete Transparent copy of the Document, free of added material. If +you use the latter option, you must take reasonably prudent steps, when +you begin distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@node 4 MODIFICATIONS,5 COMBINING DOCUMENTS,3 COPYING IN QUANTITY,GNU Free Documentation License +@anchor{fdl-1 3 modifications}@anchor{c0} +@subsection 4. MODIFICATIONS + + +You may copy and distribute a Modified Version of the Document under the +conditions of sections 2 and 3 above, provided that you release the +Modified Version under precisely this License, with the Modified Version +filling the role of the Document, thus licensing distribution and +modification of the Modified Version to whoever possesses a copy of it. +In addition, you must do these things in the Modified Version: + + +@itemize - + +@item +A. Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions (which +should, if there were any, be listed in the History section of the +Document). You may use the same title as a previous version if the +original publisher of that version gives permission. + +@item +B. List on the Title Page, as authors, one or more persons or +entities responsible for authorship of the modifications in the +Modified Version, together with at least five of the principal +authors of the Document (all of its principal authors, if it has +fewer than five), unless they release you from this requirement. + +@item +C. State on the Title page the name of the publisher of the Modified +Version, as the publisher. + +@item + +@enumerate 4 + +@item +Preserve all the copyright notices of the Document. +@end enumerate + +@item +E. Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +F. Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +G. Preserve in that license notice the full lists of Invariant +Sections and required Cover Texts given in the Document’s license +notice. + +@item + +@enumerate 8 + +@item +Include an unaltered copy of this License. +@end enumerate + +@item +I. Preserve the section Entitled “History”, Preserve its Title, and +add to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled “History” in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +J. Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise the +network locations given in the Document for previous versions it was +based on. These may be placed in the “History” section. You may omit +a network location for a work that was published at least four years +before the Document itself, or if the original publisher of the +version it refers to gives permission. + +@item +K. For any section Entitled “Acknowledgements” or “Dedications”, +Preserve the Title of the section, and preserve in the section all +the substance and tone of each of the contributor acknowledgements +and/or dedications given therein. + +@item +L. Preserve all the Invariant Sections of the Document, unaltered in +their text and in their titles. Section numbers or the equivalent are +not considered part of the section titles. + +@item +M. Delete any section Entitled “Endorsements”. Such a section may not +be included in the Modified Version. + +@item +N. Do not retitle any existing section to be Entitled “Endorsements” +or to conflict in title with any Invariant Section. + +@item + +@enumerate 15 + +@item +Preserve any Warranty Disclaimers. +@end enumerate +@end itemize + +If the Modified Version includes new front-matter sections or appendices +that qualify as Secondary Sections and contain no material copied from +the Document, you may at your option designate some or all of these +sections as invariant. To do this, add their titles to the list of +Invariant Sections in the Modified Version’s license notice. These +titles must be distinct from any other section titles. + +You may add a section Entitled “Endorsements”, provided it contains +nothing but endorsements of your Modified Version by various +parties—for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of Front-Cover +Text and one of Back-Cover Text may be added by (or through arrangements +made by) any one entity. If the Document already includes a cover text +for the same cover, previously added by you or by arrangement made by +the same entity you are acting on behalf of, you may not add another; +but you may replace the old one, on explicit permission from the +previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@node 5 COMBINING DOCUMENTS,6 COLLECTIONS OF DOCUMENTS,4 MODIFICATIONS,GNU Free Documentation License +@anchor{fdl-1 3 combining-documents}@anchor{c1} +@subsection 5. COMBINING DOCUMENTS + + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its license +notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by adding +at the end of it, in parentheses, the name of the original author or +publisher of that section if known, or else a unique number. Make the +same adjustment to the section titles in the list of Invariant Sections +in the license notice of the combined work. + +In the combination, you must combine any sections Entitled “History” in +the various original documents, forming one section Entitled “History”; +likewise combine any sections Entitled “Acknowledgements”, and any +sections Entitled “Dedications”. You must delete all sections Entitled +“Endorsements”. + +@node 6 COLLECTIONS OF DOCUMENTS,7 AGGREGATION WITH INDEPENDENT WORKS,5 COMBINING DOCUMENTS,GNU Free Documentation License +@anchor{fdl-1 3 collections-of-documents}@anchor{c2} +@subsection 6. COLLECTIONS OF DOCUMENTS + + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@node 7 AGGREGATION WITH INDEPENDENT WORKS,8 TRANSLATION,6 COLLECTIONS OF DOCUMENTS,GNU Free Documentation License +@anchor{fdl-1 3 aggregation-with-independent-works}@anchor{c3} +@subsection 7. AGGREGATION WITH INDEPENDENT WORKS + + +A compilation of the Document or its derivatives with other separate and +independent documents or works, in or on a volume of a storage or +distribution medium, is called an “aggregate” if the copyright resulting +from the compilation is not used to limit the legal rights of the +compilation’s users beyond what the individual works permit. When the +Document is included in an aggregate, this License does not apply to the +other works in the aggregate which are not themselves derivative works +of the Document. + +If the Cover Text requirement of section 3 is applicable to these copies +of the Document, then if the Document is less than one half of the +entire aggregate, the Document’s Cover Texts may be placed on covers +that bracket the Document within the aggregate, or the electronic +equivalent of covers if the Document is in electronic form. Otherwise +they must appear on printed covers that bracket the whole aggregate. + +@node 8 TRANSLATION,9 TERMINATION,7 AGGREGATION WITH INDEPENDENT WORKS,GNU Free Documentation License +@anchor{fdl-1 3 translation}@anchor{c4} +@subsection 8. TRANSLATION + + +Translation is considered a kind of modification, so you may distribute +translations of the Document under the terms of section 4. Replacing +Invariant Sections with translations requires special permission from +their copyright holders, but you may include translations of some or all +Invariant Sections in addition to the original versions of these +Invariant Sections. You may include a translation of this License, and +all the license notices in the Document, and any Warranty Disclaimers, +provided that you also include the original English version of this +License and the original versions of those notices and disclaimers. In +case of a disagreement between the translation and the original version +of this License or a notice or disclaimer, the original version will +prevail. + +If a section in the Document is Entitled “Acknowledgements”, +“Dedications”, or “History”, the requirement (section 4) to Preserve its +Title (section 1) will typically require changing the actual title. + +@node 9 TERMINATION,10 FUTURE REVISIONS OF THIS LICENSE,8 TRANSLATION,GNU Free Documentation License +@anchor{fdl-1 3 termination}@anchor{c5} +@subsection 9. TERMINATION + + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided under this License. Any attempt otherwise to copy, +modify, sublicense, or distribute it is void, and will automatically +terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally terminates +your license, and (b) permanently, if the copyright holder fails to +notify you of the violation by some reasonable means prior to 60 days +after the cessation. + +Moreover, your license from a particular copyright holder is reinstated +permanently if the copyright holder notifies you of the violation by +some reasonable means, this is the first time you have received notice +of violation of this License (for any work) from that copyright holder, +and you cure the violation prior to 30 days after your receipt of the +notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@node 10 FUTURE REVISIONS OF THIS LICENSE,11 RELICENSING,9 TERMINATION,GNU Free Documentation License +@anchor{fdl-1 3 future-revisions-of-this-license}@anchor{c6} +@subsection 10. FUTURE REVISIONS OF THIS LICENSE + + +The Free Software Foundation may publish new, revised versions of the +GNU Free Documentation License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. See @indicateurl{https://www.gnu.org/licenses/}. + +Each version of the License is given a distinguishing version number. If +the Document specifies that a particular numbered version of this +License “or any later version” applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document specifies +that a proxy can decide which future versions of this License can be +used, that proxy’s public statement of acceptance of a version +permanently authorizes you to choose that version for the Document. + +@node 11 RELICENSING,ADDENDUM How to use this License for your documents,10 FUTURE REVISIONS OF THIS LICENSE,GNU Free Documentation License +@anchor{fdl-1 3 relicensing}@anchor{c7} +@subsection 11. RELICENSING + + +“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World +Wide Web server that publishes copyrightable works and also provides +prominent facilities for anybody to edit those works. A public wiki that +anybody can edit is an example of such a server. A “Massive Multiauthor +Collaboration” (or “MMC”) contained in the site means any set of +copyrightable works thus published on the MMC site. + +“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +“Incorporate” means to publish or republish a Document, in whole or in +part, as part of another Document. + +An MMC is “eligible for relicensing” if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole or +in part into the MMC, (1) had no cover texts or invariant sections, and +(2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@node ADDENDUM How to use this License for your documents,,11 RELICENSING,GNU Free Documentation License +@anchor{fdl-1 3 addendum-how-to-use-this-license-for-your-documents}@anchor{c8} +@subsection ADDENDUM: How to use this License for your documents + + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and license +notices just after the title page: + +@example +Copyright (C) YEAR YOUR NAME. +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 +or any later version published by the Free Software Foundation; +with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the section entitled "GNU +Free Documentation License". +@end example + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the “with … Texts.” line with this: + +@example +with the Invariant Sections being LIST THEIR TITLES, with the +Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. +@end example + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of free +software license, such as the GNU General Public License, to permit +their use in free software. +@anchor{29}@w{ } +@anchor{rest tsref-type-ErrorDetail}@w{ } + +@c %**end of body +@bye -- cgit v1.2.3