summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--INSTALL6
-rw-r--r--README1
-rw-r--r--configure.ac23
-rw-r--r--contrib/.gitignore1
-rw-r--r--contrib/Makefile.am1
m---------contrib/gana0
-rwxr-xr-xcontrib/gen-ts.sh26
-rw-r--r--contrib/pp/.gitignore3
-rw-r--r--contrib/pp/pp.rst64
-rw-r--r--contrib/redux.countries.json11
-rw-r--r--contrib/redux.es.json50
-rw-r--r--contrib/remote-reducer/README.md20
-rw-r--r--contrib/remote-reducer/remote_reducer.py53
-rw-r--r--contrib/tos/.gitignore3
-rw-r--r--debian/changelog6
-rw-r--r--debian/control4
-rw-r--r--doc/sphinx/_exts/__pycache__/typescriptdomain.cpython-39.pycbin15399 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-37.pycbin514 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-38.pycbin518 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-39.pycbin520 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-37.pycbin24431 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-38.pycbin24436 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-39.pycbin24344 -> 0 bytes
-rw-r--r--doc/sphinx/_exts/taler_sphinx_theme/__pycache__/__init__.cpython-39.pycbin6548 -> 0 bytes
-rw-r--r--doc/sphinx/cryptography.rst28
-rw-r--r--doc/sphinx/reducer.rst477
-rw-r--r--doc/sphinx/rest.rst75
-rw-r--r--doc/system-documentation/design.tex8
-rw-r--r--doc/system-documentation/thesis.bbl148
-rw-r--r--doc/system-documentation/thesis.pdfbin859824 -> 858783 bytes
-rw-r--r--doc/texinfo.tex418
-rw-r--r--src/authorization/Makefile.am24
-rw-r--r--src/authorization/anastasis_authorization_plugin.c2
-rw-r--r--src/authorization/anastasis_authorization_plugin_email.c22
-rw-r--r--src/authorization/anastasis_authorization_plugin_file.c6
-rw-r--r--src/authorization/anastasis_authorization_plugin_iban.c2
-rw-r--r--src/authorization/anastasis_authorization_plugin_post.c23
-rw-r--r--src/authorization/anastasis_authorization_plugin_sms.c19
-rw-r--r--src/authorization/anastasis_authorization_plugin_totp.c401
-rw-r--r--src/authorization/iban.h2
-rw-r--r--src/backend/anastasis-httpd.c12
-rw-r--r--src/backend/anastasis-httpd_config.c2
-rw-r--r--src/backend/anastasis-httpd_policy_upload.c7
-rw-r--r--src/backend/anastasis-httpd_terms.c23
-rw-r--r--src/backend/anastasis-httpd_terms.h2
-rw-r--r--src/backend/anastasis-httpd_truth.c376
-rw-r--r--src/backend/anastasis-httpd_truth_upload.c12
-rw-r--r--src/backend/anastasis.conf4
-rw-r--r--src/cli/anastasis-cli-redux.c3
-rwxr-xr-xsrc/cli/test_anastasis_reducer_enter_secret.sh20
-rwxr-xr-xsrc/cli/test_iban.sh15
-rw-r--r--src/include/anastasis.h12
-rw-r--r--src/include/anastasis_authorization_lib.h2
-rw-r--r--src/include/anastasis_authorization_plugin.h10
-rw-r--r--src/include/anastasis_crypto_lib.h121
-rw-r--r--src/include/anastasis_database_lib.h2
-rw-r--r--src/include/anastasis_database_plugin.h4
-rw-r--r--src/include/anastasis_redux.h6
-rw-r--r--src/include/anastasis_service.h6
-rw-r--r--src/include/anastasis_testing_lib.h449
-rw-r--r--src/include/anastasis_util_lib.h6
-rw-r--r--src/lib/anastasis_backup.c37
-rw-r--r--src/lib/anastasis_recovery.c58
-rw-r--r--src/reducer/Makefile.am1
-rw-r--r--src/reducer/anastasis_api_backup_redux.c265
-rw-r--r--src/reducer/anastasis_api_recovery_redux.c219
-rw-r--r--src/reducer/anastasis_api_redux.c356
-rw-r--r--src/reducer/anastasis_api_redux.h18
-rw-r--r--src/reducer/validation_CH_AHV.c6
-rw-r--r--src/reducer/validation_CZ_BN.c6
-rw-r--r--src/reducer/validation_DE_SVN.c6
-rw-r--r--src/reducer/validation_DE_TIN.c6
-rw-r--r--src/reducer/validation_ES_DNI.c184
-rw-r--r--src/reducer/validation_IN_AADHAR.c6
-rw-r--r--src/reducer/validation_IT_CF.c6
-rw-r--r--src/reducer/validation_XX_SQUARE.c6
-rw-r--r--src/reducer/validation_XY_PRIME.c6
-rw-r--r--src/restclient/anastasis_api_config.c6
-rw-r--r--src/restclient/anastasis_api_curl_defaults.c6
-rw-r--r--src/restclient/anastasis_api_curl_defaults.h6
-rw-r--r--src/restclient/anastasis_api_keyshare_lookup.c8
-rw-r--r--src/restclient/anastasis_api_policy_lookup.c6
-rw-r--r--src/restclient/anastasis_api_policy_store.c11
-rw-r--r--src/restclient/anastasis_api_truth_store.c8
-rw-r--r--src/stasis/anastasis_db_plugin.c2
-rw-r--r--src/stasis/plugin_anastasis_postgres.c50
-rw-r--r--src/stasis/stasis-0001.sql2
-rw-r--r--src/stasis/test_anastasis_db.c2
-rw-r--r--src/testing/Makefile.am16
-rw-r--r--src/testing/test_anastasis.c6
-rw-r--r--src/testing/test_anastasis_api.c6
-rw-r--r--src/testing/testing_api_cmd_config.c10
-rw-r--r--src/testing/testing_api_cmd_keyshare_lookup.c62
-rw-r--r--src/testing/testing_api_cmd_policy_lookup.c8
-rw-r--r--src/testing/testing_api_cmd_policy_store.c28
-rw-r--r--src/testing/testing_api_cmd_truth_store.c30
-rw-r--r--src/testing/testing_api_helpers.c6
-rw-r--r--src/testing/testing_api_trait_account_priv.c58
-rw-r--r--src/testing/testing_api_trait_account_pub.c58
-rw-r--r--src/testing/testing_api_trait_code.c59
-rw-r--r--src/testing/testing_api_trait_eks.c58
-rw-r--r--src/testing/testing_api_trait_hash.c57
-rw-r--r--src/testing/testing_api_trait_payment_secret.c59
-rw-r--r--src/testing/testing_api_trait_salt.c60
-rw-r--r--src/testing/testing_api_trait_truth_key.c58
-rw-r--r--src/testing/testing_api_trait_truth_uuid.c61
-rw-r--r--src/testing/testing_api_traits.c36
-rw-r--r--src/testing/testing_cmd_challenge_answer.c56
-rw-r--r--src/testing/testing_cmd_policy_create.c17
-rw-r--r--src/testing/testing_cmd_recover_secret.c22
-rw-r--r--src/testing/testing_cmd_secret_share.c29
-rw-r--r--src/testing/testing_cmd_truth_upload.c14
-rw-r--r--src/testing/testing_trait_challenge.c57
-rw-r--r--src/testing/testing_trait_core_secret.c59
-rw-r--r--src/testing/testing_trait_policy.c58
-rw-r--r--src/testing/testing_trait_truth.c58
-rw-r--r--src/util/.gitignore1
-rw-r--r--src/util/Makefile.am15
-rw-r--r--src/util/anastasis-config.c6
-rw-r--r--src/util/anastasis-crypto-tvg.c619
-rw-r--r--src/util/anastasis_crypto.c426
-rw-r--r--src/util/os_installation.c4
-rw-r--r--src/util/test_anastasis_crypto.c31
124 files changed, 3714 insertions, 2812 deletions
diff --git a/.gitignore b/.gitignore
index dd37851..0d5dbc1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -126,3 +126,7 @@ src/include/anastasis_error_codes.h
src/lib/test_anastasis_api_home/
doc/anastasis.info
src/cli/test_reducer.err
+.vscode
+vgcore*
+__pycache__
+tags
diff --git a/INSTALL b/INSTALL
index 8865734..e82fd21 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,8 +1,8 @@
Installation Instructions
*************************
- Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
-Foundation, Inc.
+ Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free
+Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
@@ -225,7 +225,7 @@ order to use an ANSI C compiler:
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
- HP-UX 'make' updates targets which have the same time stamps as their
+ HP-UX 'make' updates targets which have the same timestamps as their
prerequisites, which makes it generally unusable when shipped generated
files such as 'configure' are involved. Use GNU 'make' instead.
diff --git a/README b/README
index 14cb067..db5dcf0 100644
--- a/README
+++ b/README
@@ -25,6 +25,7 @@ Dependencies
libjansson : MIT License
libgcrypt : LGPL
+libsodium : ISC License
postgresql : PostgreSQL License
libgnunet* : GPLv3+,
libtaler* : GPLv3+
diff --git a/configure.ac b/configure.ac
index 6d51fb9..70778fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
# This configure file is in the public domain
AC_PREREQ([2.69])
-AC_INIT([anastasis], [0.1.0], [taler-bug@gnu.org])
+AC_INIT([anastasis], [0.2.0], [taler-bug@gnu.org])
AC_CONFIG_SRCDIR([src/backend/anastasis-httpd.c])
AC_CONFIG_HEADERS([anastasis_config.h])
# support for non-recursive builds
@@ -160,7 +160,15 @@ AX_LIB_POSTGRESQL([9.3])
AS_IF([test "x$found_postgresql" = "xyes"],[postgres=true])
AM_CONDITIONAL(HAVE_POSTGRESQL, test x$postgres = xtrue)
+libsodium=0
+# test for libsodium >=1.018 (introduction of
+# crypto_scalarmult_ed25519_base_noclamp API)
+AC_CHECK_HEADER([sodium.h],
+ [AC_CHECK_LIB([sodium], [crypto_core_ed25519_scalar_mul],
+ [libsodium=1])])
+AS_IF([test x$libsodium = x0],
+ [AC_MSG_ERROR([Anastasis requires libsodium >= 1.0.18.])])
# Check for Taler's libtalerutil
@@ -180,6 +188,12 @@ AS_CASE([$with_exchange],
CPPFLAGS="$CPPFLAGS $POSTGRESQL_CPPFLAGS"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
+# Require minimum libgcrypt version
+need_libgcrypt_version=1.6.1
+AC_DEFINE_UNQUOTED([NEED_LIBGCRYPT_VERSION], ["$need_libgcrypt_version"],
+ [minimum version of libgcrypt required])
+AM_PATH_LIBGCRYPT([$need_libgcrypt_version])
+
AC_CHECK_HEADERS([taler/taler_util.h],
[AC_CHECK_LIB([talerutil],
[TALER_b2s],
@@ -243,13 +257,6 @@ PKG_CHECK_MODULES([JANSSON], [jansson >= 2.3],
*** You need libjansson to build this program.
***]])])
-
-# Require minimum libgcrypt version
-need_libgcrypt_version=1.6.1
-AC_DEFINE_UNQUOTED([NEED_LIBGCRYPT_VERSION], ["$need_libgcrypt_version"],
- [minimum version of libgcrypt required])
-AM_PATH_LIBGCRYPT([$need_libgcrypt_version])
-
# logging
extra_logging=0
AC_ARG_ENABLE([logging],
diff --git a/contrib/.gitignore b/contrib/.gitignore
new file mode 100644
index 0000000..93559bd
--- /dev/null
+++ b/contrib/.gitignore
@@ -0,0 +1 @@
+anastasis-data.ts
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index a360ab5..a2bdf27 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -55,6 +55,7 @@ pkgdata_DATA = \
redux.cz.json \
redux.de.json \
redux.dk.json \
+ redux.es.json \
redux.in.json \
redux.it.json \
redux.jp.json \
diff --git a/contrib/gana b/contrib/gana
-Subproject 323cb8276408e2c02b59bbe6e10da904538a149
+Subproject f126ffd32255c68f4fbef5e9ef849ef04855b0a
diff --git a/contrib/gen-ts.sh b/contrib/gen-ts.sh
new file mode 100755
index 0000000..bc204d1
--- /dev/null
+++ b/contrib/gen-ts.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# Generate a single TS file from the JSON data files in contrib/.
+# Requires prettier to be installed.
+
+gen_ts() {
+ echo "// This file is auto-generated, do not modify."
+ echo "// Generated from $(git describe --tags) on $(date -R)"
+ echo "// To re-generate, run contrib/gen-ts.sh from the main anastasis code base."
+ echo
+ echo "export const anastasisData = {"
+ echo "providersList: $(cat provider-list.json),"
+ echo "countriesList: $(cat redux.countries.json),"
+ echo "countryDetails: {"
+ for f in redux.??.json; do
+ cc=$(echo $f | awk -F "." '{ print $2 }')
+ echo "$cc: $(cat $f),"
+ done
+ echo "}," # country details
+ echo "}" # anastasis data
+
+}
+
+gen_ts > anastasis-data.ts
+# Auto-format
+prettier -w anastasis-data.ts
diff --git a/contrib/pp/.gitignore b/contrib/pp/.gitignore
new file mode 100644
index 0000000..fb83616
--- /dev/null
+++ b/contrib/pp/.gitignore
@@ -0,0 +1,3 @@
+sphinx.err
+sphinx.log
+_build/
diff --git a/contrib/pp/pp.rst b/contrib/pp/pp.rst
index a8ff838..8972028 100644
--- a/contrib/pp/pp.rst
+++ b/contrib/pp/pp.rst
@@ -1,7 +1,7 @@
Privacy Policy
==============
-Last Updated: 07.09.2021
+Last Updated: 22.09.2021
This Privacy Policy describes the policies and procedures of Anastasis
SARL (“we,” “our,” or “us”) pertaining to the collection, use, and
@@ -45,30 +45,32 @@ information (i.e., information that cannot be used to identify who you are)
will tell you how we might collect and use each type.
We do our best to not collect any Personal Information from Anastasis
-users. The detailed Personal Information Anastasis asks from you during
-the regular backup and recovery process at the beginning is never shared
-with us and only used to create a cryptographic account identifier which
-does not allow us to recover any of your details.
+users. The detailed Personal Information Anastasis asks from you
+during the regular backup and recovery process at the beginning is
+never shared with us and only used to create a cryptographic account
+identifier which does not allow us to recover any of your
+details. This data will always remain on your own device without the
+possibility of access from our side.
That being said, when using our Services to recover key material, we may
inherently receive the following information (depending on your choice of
authentication method):
- * Bank account details necessary when receiving funds from you to authenticate via a SEPA transfer. We will store these as part of our business records for accounting, and our bank will also be legally obliged to store the details for many years.
+ * Bank account details necessary when receiving funds from you to authenticate via a SEPA transfer. We will store these as part of our business records for accounting, and our bank will also be legally obliged to store the details for many years according to legal retention periods.
- * Your phone number when using SMS authentication. We rely on third party providers (such as your mobile network operator) to deliver the SMS to you. These third parties will see the SMS message sent to you and could thus learn that you are using Anastasis. SMS is inherently insecure, and you should expect many governments and private parties to be able to observe these messages. However, we do not store your SMS number on our systems, except maybe in short-term logs to diagnose errors.
+ * Your phone number when using SMS authentication. We rely on third party providers (such as your mobile network operator) to deliver the SMS to you. These third parties will see the SMS message sent to you and could thus learn that you are using Anastasis. SMS is inherently insecure, and you should expect many governments and private parties to be able to observe these messages. However, we do not store your phone number for SMS communication on our systems, except maybe in short-term logs to diagnose errors.
* Your e-mail address when using E-mail authentication. We rely on the Internet and your E-mail provider to deliver the E-mail to you. Internet service providers will see the E-mail message sent to you and could thus learn that you are using Anastasis. E-mail is inherently insecure, and you should expect many governments and private parties to be able to observe these messages. However, we do not store your E-mail address on our systems, except maybe in short-term logs to diagnose errors.
* Your physical address when using postal mail authentication. We rely on external providers for printing and sending the letter to you. These providers will need to learn your address and could learn that you are using Anastasis. Physical mail has strict privacy protections by law, but governments are known to break postal secrecy. We do not store your physical address on our systems, except maybe in short-term logs to diagnose errors.
- * When you contact us. We may collect certain information if you choose to contact us, for example to report a bug or other error with the Taler Wallet. This may include contact information such as your name, email address or phone number depending on the method you choose to contact us.
+ * When you contact us. We may collect certain information if you choose to contact us, for example to report a bug or other error with the Taler Wallet. This may include contact information such as your name, email address or phone number depending on the method you choose to contact us. We strictly only use the information provided by you in these instances to answer your request or to deliver the services requested by you.
-How we collect and process information
+How we collect and process personal data
--------------------------------------
-We may process your information for the following reasons:
+We may process your personal data for the following reasons:
* to authenticate you during secret recovery
* to support you using Anastasis when you contact us
@@ -96,8 +98,7 @@ Agents or third party partners
We may provide your Personal Information to our employees, contractors,
agents, service providers, and designees (“Agents”) to enable them to perform
certain services for us exclusively, including: improvement and maintenance of
-our software and Services. By accepting this Privacy Policy, as outlined
-above, you consent to any such transfer.
+our software and Services.
Protection of us and others
@@ -124,6 +125,43 @@ needed for purposes specified in the “How We Use the Information We
Gather” section will be deleted after ninety (90) days.
+What are your data protection rights?
+-------------------------------------
+
+Anastasis would like to make sure you are fully aware of all of your
+data protection rights. Every user is entitled to the following:
+
+**The right to access**: You have the right to request Anastasis for
+ copies of your personal data. We may charge you a small fee for this
+ service.
+
+**The right to rectification**: You have the right to request that
+Anastasis correct any information you believe is inaccurate. You also
+have the right to request Anastasis to complete information you
+believe is incomplete. The right to erasure - You have the right to
+request that Anastasis erase your personal data, under certain
+conditions.
+
+**The right to restrict processing**: You have the right to request
+ that Anastasis restrict the processing of your personal data, under
+ certain conditions.
+
+**The right to object to processing**: You have the right to object to
+ Anastasis's processing of your personal data, under certain
+ conditions.
+
+**The right to data portability**: You have the right to request that
+ Anastasis transfer the data that we have collected to another
+ organization, or directly to you, under certain conditions.
+
+If you make a request, we have one month to respond to you. If you
+would like to exercise any of these rights, please contact us at our
+email: privacy@anastasis.lu
+
+You can always contact your local data protection authority to enforce
+your rights.
+
+
Data retention
--------------
@@ -170,7 +208,7 @@ International users and visitors
--------------------------------
Our Services are (currently) hosted in Germany. If you are a user
-accessing the Services from the Switzerland, Asia, US, or any other
+accessing the Services from Switzerland, Asia, US, or any other
region with laws or regulations governing personal data collection,
use, and disclosure that differ from the laws of Germany, please be
advised that through your continued use of the Services, which is
diff --git a/contrib/redux.countries.json b/contrib/redux.countries.json
index aaaf134..8fb2e99 100644
--- a/contrib/redux.countries.json
+++ b/contrib/redux.countries.json
@@ -73,6 +73,17 @@
"call_code" : "+45"
},
{
+ "code" : "es",
+ "name" : "Spain",
+ "continent" : "Europe",
+ "continent_i18n" : { "es_ES" : "Europa" },
+ "name_i18n" : {
+ "es_ES": "España"
+ },
+ "currency": "EUR",
+ "call_code" : "+44"
+ },
+ {
"code" : "in",
"name" : "India",
"continent" : "India",
diff --git a/contrib/redux.es.json b/contrib/redux.es.json
new file mode 100644
index 0000000..5926b6d
--- /dev/null
+++ b/contrib/redux.es.json
@@ -0,0 +1,50 @@
+{
+ "license": "GPLv3+",
+ "SPDX-License-Identifier": "GPL3.0-or-later",
+ "required_attributes": [
+ {
+ "type": "string",
+ "name": "full_name",
+ "label": "Full name",
+ "widget": "anastasis_gtk_ia_full_name",
+ "uuid" : "9e8f463f-575f-42cb-85f3-759559997331"
+ },
+ {
+ "type": "date",
+ "name": "birthdate",
+ "label": "Birthdate",
+ "widget": "anastasis_gtk_ia_birthdate",
+ "uuid" : "83d655c7-bdb6-484d-904e-80c1058c8854"
+ },
+ {
+ "type": "string",
+ "name": "birthplace",
+ "label": "Birthplace",
+ "widget": "anastasis_gtk_ia_birthplace",
+ "uuid" : "4c822e8e-89c6-11eb-95c4-8b077ad8489f"
+ },
+ {
+ "type": "string",
+ "name": "tax_number",
+ "label": "Tax number",
+ "label_i18n":{
+ "es_ES":"Número de Identificación Fiscal (DNI, NIE)",
+ },
+ "widget": "anastasis_gtk_ia_es_dni",
+ "uuid" : "ac8bd865-6be8-445c-b650-6a18eef16a49",
+ "validation-regex": "^[0-9MXYZ][0-9]{7}[TRWAGMYFPDXBNJZSQVHLCKE]$",
+ "validation-logic": "ES_DNI_check"
+ },
+ {
+ "type": "string",
+ "name": "ssn_number",
+ "label": "Social security number",
+ "label_i18n":{
+ "es_ES":"Número de Seguridad Social",
+ },
+ "widget": "anastasis_gtk_ia_es_ssn",
+ "uuid" : "22396a19-f3bb-497e-b63a-961fd639140e",
+ "validation-regex": "^[0-9]{11}$"
+ }
+ ]
+}
diff --git a/contrib/remote-reducer/README.md b/contrib/remote-reducer/README.md
new file mode 100644
index 0000000..74adc66
--- /dev/null
+++ b/contrib/remote-reducer/README.md
@@ -0,0 +1,20 @@
+# Anastasis Remote Reducer
+
+The remote reducer is a simple HTTP service that proxies requests to
+``anastasis-reducer``. It is not meant to be used in production.
+
+## Dependencies
+
+The remote reducer needs python3 and flask. Flask can be installed via pip:
+
+```
+pip3 install flask
+```
+
+## Running the remote reducer
+
+```
+cd $ANASTASIS_GIT/contrib/remote-reducer
+export FLASK_APP=remote_reducer
+flask run -p 5000
+```
diff --git a/contrib/remote-reducer/remote_reducer.py b/contrib/remote-reducer/remote_reducer.py
new file mode 100644
index 0000000..aef6d6d
--- /dev/null
+++ b/contrib/remote-reducer/remote_reducer.py
@@ -0,0 +1,53 @@
+import flask
+from flask import Flask, request
+import subprocess
+import json
+import sys
+import os
+
+if sys.version_info.major < 3:
+ print("Python>=3 required")
+ os.exit(1)
+
+app = Flask(__name__)
+
+
+@app.route("/")
+def hello_world():
+ return "<p>Hello, World!</p>"
+
+
+@app.route("/start-recovery")
+def start_recovery():
+ res = subprocess.run(["anastasis-reducer", "-r"], capture_output=True)
+ resp = flask.Response(res.stdout)
+ resp.headers['Access-Control-Allow-Origin'] = '*'
+ return resp
+
+
+@app.route("/start-backup")
+def start_backup():
+ res = subprocess.run(["anastasis-reducer", "-b"], capture_output=True)
+ resp = flask.Response(res.stdout)
+ resp.headers['Access-Control-Allow-Origin'] = '*'
+ return resp
+
+
+@app.route("/action", methods=["POST", "OPTIONS"])
+def reduce_action():
+ if request.method == "OPTIONS":
+ resp = flask.Response()
+ resp.headers['Access-Control-Allow-Origin'] = '*'
+ resp.headers['Access-Control-Allow-Headers'] = '*'
+ resp.headers['Access-Control-Allow-Method'] = '*'
+ return resp
+
+ b = request.get_json()
+ res = subprocess.run(
+ ["anastasis-reducer", "-a", json.dumps(b["arguments"]), b["action"]],
+ capture_output=True,
+ input=json.dumps(b["state"]).encode("utf-8"),
+ )
+ resp = flask.Response(res.stdout)
+ resp.headers['Access-Control-Allow-Origin'] = '*'
+ return resp
diff --git a/contrib/tos/.gitignore b/contrib/tos/.gitignore
new file mode 100644
index 0000000..fb83616
--- /dev/null
+++ b/contrib/tos/.gitignore
@@ -0,0 +1,3 @@
+sphinx.err
+sphinx.log
+_build/
diff --git a/debian/changelog b/debian/changelog
index d972a47..374d9ac 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+anastasis (0.2.0) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Christian Grothoff <grothoff@gnu.org> Thu, 30 Sep 2021 14:02:10 +0100
+
anastasis (0.1.0-5) unstable; urgency=low
* Fix amount check for payments (upstream fix).
diff --git a/debian/control b/debian/control
index 5097893..0252c0d 100644
--- a/debian/control
+++ b/debian/control
@@ -42,7 +42,7 @@ Architecture: any
Pre-Depends:
${misc:Pre-Depends}
Depends:
- libtalerexchange (>= 0.8.4),
+ libtalerexchange (>= 0.8.5),
libgnutls30 (>= 3.7.1),
adduser,
lsb-base,
@@ -69,7 +69,7 @@ Section: libdevel
Architecture: any
Depends:
libtalermerchant-dev (>= 0.8.3),
- libtalerexchange-dev (>= 0.8.4),
+ libtalerexchange-dev (>= 0.8.5),
libgnunet-dev (>=0.15.3),
${misc:Depends},
${shlibs:Depends}
diff --git a/doc/sphinx/_exts/__pycache__/typescriptdomain.cpython-39.pyc b/doc/sphinx/_exts/__pycache__/typescriptdomain.cpython-39.pyc
deleted file mode 100644
index 077f3c9..0000000
--- a/doc/sphinx/_exts/__pycache__/typescriptdomain.cpython-39.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-37.pyc b/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-37.pyc
deleted file mode 100644
index 6f0c344..0000000
--- a/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-38.pyc b/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-38.pyc
deleted file mode 100644
index 2b7f52b..0000000
--- a/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-38.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-39.pyc b/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-39.pyc
deleted file mode 100644
index 0323e4b..0000000
--- a/doc/sphinx/_exts/httpdomain/__pycache__/__init__.cpython-39.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-37.pyc b/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-37.pyc
deleted file mode 100644
index 031c4ed..0000000
--- a/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-37.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-38.pyc b/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-38.pyc
deleted file mode 100644
index 062d289..0000000
--- a/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-38.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-39.pyc b/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-39.pyc
deleted file mode 100644
index 32e2273..0000000
--- a/doc/sphinx/_exts/httpdomain/__pycache__/httpdomain.cpython-39.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/_exts/taler_sphinx_theme/__pycache__/__init__.cpython-39.pyc b/doc/sphinx/_exts/taler_sphinx_theme/__pycache__/__init__.cpython-39.pyc
deleted file mode 100644
index 7f4021b..0000000
--- a/doc/sphinx/_exts/taler_sphinx_theme/__pycache__/__init__.cpython-39.pyc
+++ /dev/null
Binary files differ
diff --git a/doc/sphinx/cryptography.rst b/doc/sphinx/cryptography.rst
index 406732a..a38f6e7 100644
--- a/doc/sphinx/cryptography.rst
+++ b/doc/sphinx/cryptography.rst
@@ -116,7 +116,7 @@ HKDF to ensure that the result differs from other cases where we hash
.. code-block:: none
ver_secret := HKDF(kdf_id, "ver", keysize)
- eddsa_priv := eddsa_d_to_a(ver_secret)
+ eddsa_priv := ver_secret
eddsa_pub := get_EdDSA_Pub(eddsa_priv)
@@ -128,13 +128,6 @@ HKDF to ensure that the result differs from other cases where we hash
**ver_secret**: Derived key from the ``kdf_id``, serves as intermediate step for the generation of the private key.
-**eddsa_d_to_a()**: Function which converts the ver_key to a valid EdDSA private key. Specifically, assuming the value ``eddsa_priv`` is in a 32-byte array "digest", the function clears and sets certain bits as follows:
-
-.. code-block:: c
-
- digest[0] = (digest[0] & 0x7f) | 0x40;
- digest[31] &= 0xf8;
-
**eddsa_priv**: The generated EdDSA private key.
**eddsa_pub**: The generated EdDSA public key.
@@ -240,7 +233,9 @@ 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
+server. This signature ensures that an adversary that observes the upload is not
+able to upload a new version of the policy without knowing the user's identity attributes.
+The signature is made over a hash of the request body. The following
algorithm is equivalent for **Anastasis-Policy-Signature**.
.. code-block:: none
@@ -255,21 +250,6 @@ algorithm is equivalent for **Anastasis-Policy-Signature**.
**ver_res**: A boolean value. True: Signature verification passed, False: Signature verification failed.
-When requesting policy downloads, the client must also provide a signature:
-
-.. code-block:: none
-
- (anastasis-account-signature) := eddsa_sign(version, eddsa_priv)
- ver_res := eddsa_verifiy(version, anastasis-account-signature, eddsa_pub)
-
-**anastasis-account-signature**: Signature over the SHA-512 hash of the body using the purpose code ``TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD`` (1401) (see GNUnet EdDSA signature API for the use of purpose).
-
-**version**: The version requested as a 64-bit integer, 2^64-1 for the "latest version".
-
-**ver_res**: A boolean value. True: Signature verification passed, False: Signature verification failed.
-
-
-
Availability Considerations
^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/sphinx/reducer.rst b/doc/sphinx/reducer.rst
index 320db48..b091c1d 100644
--- a/doc/sphinx/reducer.rst
+++ b/doc/sphinx/reducer.rst
@@ -89,13 +89,23 @@ above would look like following for the transition action_ ``select_continent``:
]
}
+An action may also result into an *error response* instead of a new state.
+Clients should then render this error response to the user and allow the user
+to continue from the old state. An error response looks like this:
+
+.. code-block:: json
+
+ {
+ "code": 123,
+ "hint": "something went wrong",
+ "details": "parameter foo failed to frobnify"
+ }
+
States
^^^^^^
Overall, the reducer knows the following states:
- - **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.
- **CONTINENT_SELECTING**: The user should specify the continent where they are living,
so that we can show a list of countries to choose from.
- **COUNTRY_SELECTING**: The user should specify the country where they are living,
@@ -358,7 +368,7 @@ providers that accept payments in the selected currency:
},
{
"type": "string",
- "name": "tax_number",
+ "name": "tax_number",
"label": "Taxpayer identification number",
"label_i18n":{
"de_DE": "Steuerliche Identifikationsnummer",
@@ -366,7 +376,7 @@ providers that accept payments in the selected currency:
"en": "German taxpayer identification number"
},
"widget": "anastasis_gtk_ia_tax_de",
- "uuid": "dae48f85-e3ff-47a4-a4a3-ed981ed8c3c6",
+ "uuid": "dae48f85-e3ff-47a4-a4a3-ed981ed8c3c6",
"validation-regex": "^[0-9]{11}$",
"validation-logic": "DE_TIN_check"
},
@@ -381,8 +391,8 @@ providers that accept payments in the selected currency:
"en": "Social security number"
},
"widget": "anastasis_gtk_ia_ssn",
- "validation-regex": "^[0-9]{8}[[:upper:]][0-9]{3}$",
- "validation-logic": "DE_SVN_check"
+ "validation-regex": "^[0-9]{8}[[:upper:]][0-9]{3}$",
+ "validation-logic": "DE_SVN_check"
"optional" : true
}
],
@@ -494,22 +504,23 @@ 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:
+Here, the client must provide an object with the base URLs of the
+providers to add or disable. The object maps the
+URLs to status information about the provider to
+use. For example:
.. code-block:: json
{
- "urls": [
- "http://localhost:8888/",
- "http://localhost:8089/"
- ]
+ "http://localhost:8088/" : { "disabled" : false },
+ "http://localhost:8089/" : { "disabled" : false }
+ "http://localhost:8090/" : { "disabled" : true },
}
-Note that existing providers will remain in the state. The following is an
+Note that existing providers will remain in the state they were in. 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:
+unreachable, the services on port 8088 and 8888 were previously known, and service on
+port 8088 was now added, and on 8090 is disabled:
.. code-block:: json
@@ -517,10 +528,15 @@ port 8888 was now added:
"backup_state": "USER_ATTRIBUTES_COLLECTING",
"authentication_providers": {
"http://localhost:8089/": {
+ "disabled": false,
"error_code": 11,
"http_status": 0
},
+ "http://localhost:8090/": {
+ "disabled": true
+ },
"http://localhost:8088/": {
+ "disabled": false,
"http_status": 200,
"methods": [
{ "type" : "question",
@@ -601,16 +617,18 @@ to it:
}
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:
+expression, or fail the custom validation logic, the reducer SHOULD return an
+error response indicating that the transition has failed and what is wrong about
+the input and not transition to a new state. 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:
.. code-block:: json
{
- "backup_state": "ERROR",
"code": 8404,
"hint": "An input did not match the regular expression.",
"detail": "social_security_number"
@@ -703,8 +721,8 @@ response:
]
}
-If the index is invalid, the reducer will instead
-transition into an ``ERROR`` state.
+If the index is invalid, the reducer will return an error
+response instead of making a transition.
**next** (from ``AUTHENTICATIONS_EDITING``):
@@ -779,8 +797,8 @@ policy. The ``methods`` array specifies the index of the
``authentication_method`` in the ``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
-``ERROR`` state instead of suggesting policies.
+If no authentication method was provided, the reducer will
+return an error response instead of making a transition.
**add_policy**:
@@ -867,7 +885,7 @@ the "policies" array, returning an updated state:
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 ``ERROR`` state instead of
+authentication, the reducer return an error response instead of
adding the new policy.
@@ -898,7 +916,7 @@ An example for a possible argument would thus be:
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 ``ERROR`` state instead of
+authentication, the reducer will return an error response instead of
modifying the policy.
@@ -961,7 +979,7 @@ be:
]
}
-If the index given is invalid, the reducer will transition into an ``ERROR`` state
+If the index given is invalid, the reducer will return an error response
instead of deleting a policy.
@@ -1022,7 +1040,7 @@ be:
]
}
-If the index given is invalid, the reducer will transition into an ``ERROR`` state
+If the index given is invalid, the reducer will return an error response
instead of deleting a challenge.
@@ -1037,7 +1055,7 @@ The reducer will simply transition to the ``SECRET_EDITING`` state:
{
"backup_state": "SECRET_EDITING",
- "upload_fees" : [ "KUDOS:42" ],
+ "upload_fees" : [ { "fee": "KUDOS:42" } ],
"expiration" : { "t_ms" : 1245362362 }
}
@@ -1046,8 +1064,8 @@ 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 ``policies`` is currently empty, the reducer will transition
-into an ``ERROR`` state instead of allowing the user to continue.
+If the array of ``policies`` is currently empty, the reducer will
+return an error response instead of allowing the user to continue.
**enter_secret:**
@@ -1083,7 +1101,7 @@ be updated.
"mime" : "text/plain"
},
"expiration" : { "t_ms" : 1245362362 },
- "upload_fees" : [ "KUDOS:42" ]
+ "upload_fees" : [ { "fee": "KUDOS:42" } ]
}
@@ -1152,8 +1170,8 @@ 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
-``ERROR`` state instead of allowing the user to continue.
+If the secret is currently empty, the reducer will return an
+error response 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
@@ -1230,14 +1248,13 @@ 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
``BACKUP_FINISHED`` state (if all payments have been completed and the backup
-finished), or into an ``ERROR`` state in case there was an irrecoverable error,
+finished), or return an error response in case there was an irrecoverable error,
indicating the specific provider and how it failed. An example for this
final error state would be:
.. code-block:: json
{
- "backup_state": "ERROR",
"http_status" : 500,
"upload_status" : 52,
"provider_url" : "https://bad.example.com/",
@@ -1290,12 +1307,14 @@ a state where the user can choose which challenges to satisfy:
"challenges": [
{
"uuid": "MW2R3RCBZPHNC78AW8AKWRCHF9KV3Y82EN62T831ZP54S3K5599G",
+ "uuid-display": "MW2R3RC",
"cost": "TESTKUDOS:0",
"type": "question",
"instructions": "q1"
},
{
"uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "uuid-display": "TXYKGE",
"cost": "TESTKUDOS:0",
"type": "email",
"instructions": "e-mail address m?il@f*.bar"
@@ -1330,8 +1349,9 @@ obtained and its ``version`` are also provided. Each challenge comes with
four mandatory fields:
- **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
+ UUIDs in the policies array refer to.
+ - **uuid-display**: Shortened idenfier which is included in messages
+ send to the user. Allows the user to
distinguish different PIN/TANs should say the same phone number be
used for SMS-authentication with different providers.
- **cost**: This is the amount the Anastasis provider will charge
@@ -1353,7 +1373,6 @@ message together with a transition failure:
.. code-block:: json
{
- "recovery_state": "ERROR",
"error_message": "account unknown to Anastasis server",
"error_code": 9,
}
@@ -1442,236 +1461,236 @@ information about attempted challenges, with the final state being ``solved``:
Challenges feedback for a challenge can have many different ``state`` values
that applications must all handle. States other than ``solved`` are:
- - **payment**: Here, the user must pay for a challenge. An example would be:
+- **payment**: Here, the user must pay for a challenge. An example would be:
- .. code-block:: json
+ .. code-block:: json
- {
- "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"
- }
- }
- }
+ {
+ "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"
+ }
+ }
+ }
- - **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.
+- **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.
- .. code-block:: json
+ .. code-block:: json
- {
- "recovery_state": "CHALLENGE_SOLVING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "body",
- "body": "CROCKFORDBASE32ENCODEDBODY",
- "http_status": 403,
- "mime_type" : "anything/possible"
- }
- }
- }
+ {
+ "recovery_state": "CHALLENGE_SOLVING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "body",
+ "body": "CROCKFORDBASE32ENCODEDBODY",
+ "http_status": 403,
+ "mime_type" : "anything/possible"
+ }
+ }
+ }
- - **hint**: Here, the server provided human-readable hint for
- how to solve the challenge. Note that the ``hint`` provided this
- time is from the Anastasis provider and may differ from the ``instructions``
- for the challenge under ``recovery_information``:
+- **hint**: Here, the server provided human-readable hint for
+ how to solve the challenge. Note that the ``hint`` provided this
+ time is from the Anastasis provider and may differ from the ``instructions``
+ for the challenge under ``recovery_information``:
- .. code-block:: json
+ .. code-block:: json
- {
- "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
- }
- }
+ {
+ "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
+ }
+ }
+ }
+
+- **details**: Here, the server provided a detailed JSON status response
+ related to solving the challenge:
+
+ .. code-block:: json
+
+ {
+ "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
}
+ }
+ }
- - **details**: Here, the server provided a detailed JSON status response
- related to solving the challenge:
+- **redirect**: To solve the challenge, the user must visit the indicated
+ Web site at ``redirect_url``, for example to perform video authentication:
- .. code-block:: json
+ .. code-block:: json
- {
- "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
- }
+ {
+ "recovery_state": "CHALLENGE_SOLVING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "redirect",
+ "redirect_url": "https://videoconf.example.com/",
+ "http_status": 303
}
}
+ }
- - **redirect**: To solve the challenge, the user must visit the indicated
- Web site at ``redirect_url``, for example to perform video authentication:
+- **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.
- .. code-block:: json
+ .. code-block:: json
- {
- "recovery_state": "CHALLENGE_SOLVING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "redirect",
- "redirect_url": "https://videoconf.example.com/",
- "http_status": 303
- }
- }
+ {
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "server-failure",
+ "http_status": "500",
+ "error_code": 52
}
+ }
+ }
- - **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.
+- **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.
- .. code-block:: json
+ .. code-block:: json
- {
- "recovery_state": "CHALLENGE_SELECTING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "server-failure",
- "http_status": "500",
- "error_code": 52
- }
+ {
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "truth-unknown",
+ "error_code": 8108
}
}
+ }
- - **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.
+- **rate-limit-exceeded**: This indicates that the user has made too many invalid attempts in too short an amount of time.
- .. code-block:: json
+ .. code-block:: json
- {
- "recovery_state": "CHALLENGE_SELECTING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "truth-unknown",
- "error_code": 8108
- }
- }
- }
+ {
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "rate-limit-exceeded",
+ "error_code": 8121
+ }
+ }
+ }
- - **rate-limit-exceeded**: This indicates that the user has made too many invalid attempts in too short an amount of time.
+- **authentication-timeout**: This indicates that the challenge is awaiting for some external authentication process to complete. The application should ``poll`` for it to complete, or proceed with selecting other challenges.
- .. code-block:: json
+ .. code-block:: json
- {
- "recovery_state": "CHALLENGE_SELECTING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "rate-limit-exceeded",
- "error_code": 8121
- }
- }
+ {
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "authentication-timeout",
+ "error_code": 8122
}
+ }
+ }
- - **authentication-timeout**: This indicates that the challenge is awaiting for some external authentication process to complete. The application should ``poll`` for it to complete, or proceed with selecting other challenges.
+- **external-instructions**: This indicates that the challenge requires the user to perform some authentication method-specific actions. Details about what the user should do are provided.
- .. code-block:: json
+ .. code-block:: json
- {
- "recovery_state": "CHALLENGE_SELECTING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "authentication-timeout",
- "error_code": 8122
- }
+ {
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": {
+ "...": "..."
+ }
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": {
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
+ "state": "external-instructions",
+ "method": "iban",
+ "async": true, // optional
+ "answer_code": 987654321, // optional
+ "details": {
+ "...": "..."
}
}
+ }
+ }
- - **authentication-instructions**: This indicates that the challenge requires the user to perform some authentication method-specific actions. Details about what the user should do are provided.
-
- .. code-block:: json
-
- {
- "recovery_state": "CHALLENGE_SELECTING",
- "recovery_information": {
- "...": "..."
- }
- "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
- "challenge_feedback": {
- "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": {
- "state": "external-instructions",
- "method": "iban",
- "async": true, // optional
- "answer_code": 987654321, // optional
- "details": {
- "...": "..."
- }
- }
- }
- }
+ If "async" is "true", then the client should
+ poll for the challenge being satisfied using
+ the "answer_code" that has been provided.
- If "async" is "true", then the client should
- poll for the challenge being satisfied using
- the "answer_code" that has been provided.
+ The specific instructions on how to satisfy
+ the challenge depend on the ``method``.
+ They include:
- The specific instructions on how to satisfy
- the challenge depend on the ``method``.
- They include:
+ - **iban**: The user must perform a wire transfer from their account to the Anastasis provider.
- - **iban**: The user must perform a wire transfer from their account to the Anastasis provider.
+ .. code-block:: json
- .. code-block:: json
+ {
+ "challenge_amount": "EUR:1",
+ "credit_iban": "DE12345789000",
+ "business_name": "Data Loss Incorporated",
+ "wire_transfer_subject": "Anastasis 987654321"
+ }
- {
- "challenge_amount": "EUR:1",
- "credit_iban": "DE12345789000",
- "business_name": "Data Loss Incorporated",
- "wire_transfer_subject": "Anastasis 987654321"
- }
-
- Note that the actual wire transfer subject must contain both
- the numeric ``answer_code`` as well as
- the string ``Anastasis``.
+ Note that the actual wire transfer subject must contain both
+ the numeric ``answer_code`` as well as
+ the string ``Anastasis``.
**poll:**
diff --git a/doc/sphinx/rest.rst b/doc/sphinx/rest.rst
index 0a081c4..a1c5810 100644
--- a/doc/sphinx/rest.rst
+++ b/doc/sphinx/rest.rst
@@ -28,8 +28,9 @@ REST API
.. _config:
+-----------------------
Receiving Configuration
-^^^^^^^^^^^^^^^^^^^^^^^
+-----------------------
.. http:get:: /config
@@ -97,8 +98,9 @@ Receiving Configuration
.. _terms:
+--------------------------
Receiving Terms of Service
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+--------------------------
.. http:get:: /terms
@@ -122,8 +124,9 @@ Receiving Terms of Service
.. _manage-policy:
-Manage policy
-^^^^^^^^^^^^^
+---------------
+Managing 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
@@ -184,7 +187,6 @@ In the following, UUID is always defined and used according to `RFC 4122`_.
*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.
- *Anastasis-Account-Signature*: The client must provide Base-32 encoded EdDSA signature over hash of body with ``$ACCOUNT_PRIV``, affirming desire to download the requested encrypted recovery document. The purpose used MUST be ``TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD`` (1401).
.. http:post:: /policy/$ACCOUNT_PUB
@@ -230,8 +232,10 @@ In the following, UUID is always defined and used according to `RFC 4122`_.
**Response**:
:http:statuscode:`204 No content`:
- The encrypted recovery document was accepted and stored. ``Anastasis-Version`` and ``Anastasis-UUID`` headers
- indicate what version and UUID was assigned to this encrypted recovery document upload by the server.
+ The encrypted recovery document was accepted and stored. ``Anastasis-Version``
+ indicates what version was assigned to this encrypted recovery document upload by the server.
+ ``Anastasis-Policy-Expiration`` indicates the time until the server promises to store the policy,
+ in seconds since epoch.
:http:statuscode:`304 Not modified`:
The same encrypted recovery document was previously accepted and stored. ``Anastasis-Version`` header
indicates what version was previously assigned to this encrypted recovery document.
@@ -272,18 +276,17 @@ In the following, UUID is always defined and used according to `RFC 4122`_.
.. ts:def:: RecoveryDocument
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
+ // Human-readable name of the secret
+ secret_name?: string;
+
+ // Encrypted core secret.
+ encrypted_core_secret: string; // bytearray of undefined length
// List of escrow providers and selected authentication method.
- methods: EscrowMethod[];
+ escrow_methods: EscrowMethod[];
// List of possible decryption policies.
- policy: DecryptionPolicy[];
+ policies: DecryptionPolicy[];
}
@@ -292,7 +295,7 @@ In the following, UUID is always defined and used according to `RFC 4122`_.
interface EscrowMethod {
// URL of the escrow provider (including possibly this Anastasis server).
- provider_url : string;
+ url : string;
// Type of the escrow method (e.g. security question, SMS etc.).
escrow_type: string;
@@ -302,21 +305,23 @@ In the following, UUID is always defined and used according to `RFC 4122`_.
// Key used to encrypt the `Truth` this `EscrowMethod` is related to.
// Client has to provide this key to the server when using ``/truth/``.
- truth_encryption_key: [32]; //bytearray
+ truth_key: [32]; //bytearray
- // Salt used to encrypt the truth on the Anastasis server.
+ // Salt used to hash the security answer if appliccable.
truth_salt: [32]; //bytearray
- // The challenge to give to the user (i.e. the security question
+ // Salt from the provider to derive the user ID
+ // at this provider.
+ provider_salt: [32]; //bytearray
+
+ // The instructions 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
+ instructions: string;
}
@@ -326,22 +331,23 @@ In the following, UUID is always defined and used according to `RFC 4122`_.
interface DecryptionPolicy {
// Salt included to encrypt master key share when
// using this decryption policy.
- policy_salt: [32]; //bytearray
+ 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
+ master_key: [32]; //bytearray
// List of escrow methods identified by their UUID.
- uuid: string[];
+ uuids: string[];
}
.. _Truth:
+--------------
Managing truth
-^^^^^^^^^^^^^^
+--------------
Truth always consists of an encrypted key share and encrypted
authentication data. The key share and the authentication data
@@ -479,7 +485,7 @@ charge per truth operation using GNU Taler.
:http:statuscode:`503 Service Unavailable`:
Server is out of Service.
- *Truth-Decryption-Key*: Key used to encrypt the **truth** (see encrypted_truth within `TruthUploadRequest`_) and which has to provided by the user. The key is stored with
+ *Anastasis-Truth-Decryption-Key*: Key used to encrypt the **truth** (see encrypted_truth within `TruthUploadRequest`_) and which has to provided by the user. The key is stored with
the according `EscrowMethod`_. The server needs this key to get the info out of `TruthUploadRequest`_ needed to verify the ``$RESPONSE``.
**Details:**
@@ -509,17 +515,10 @@ charge per truth operation using GNU Taler.
}
- .. _KeyShare:
- .. ts:def:: KeyShare
interface KeyShare {
- // Key material to concatenate with policy_salt and KDF to derive
- // the key to decrypt the master key.
+ // Key material to derive the key to decrypt the master key.
key_share: [32]; //bytearray
-
- // Signature over method, UUID, and ``key_share``.
- account_sig: EddsaSignature;
-
}
@@ -538,15 +537,15 @@ charge per truth operation using GNU Taler.
amount: Amount;
// What is the target IBAN?
- credit_iban: String;
+ credit_iban: string;
// What is the receiver name?
- business_name: String;
+ business_name: string;
// What is the expected wire transfer subject?
wire_transfer_subject: Integer;
// Hint about the origin account that must be used.
- debit_account_hint: String;
+ debit_account_hint: string;
}
diff --git a/doc/system-documentation/design.tex b/doc/system-documentation/design.tex
index 650beb1..1fe9134 100644
--- a/doc/system-documentation/design.tex
+++ b/doc/system-documentation/design.tex
@@ -357,7 +357,7 @@ that the result differs from other cases where we hash {\em kdf id}:
eddsa_keys_create (kdf_id, salt, keysize)
{
ver_secret = HKDF(kdf_id, salt, keysize)
- eddsa_priv = eddsa_d_to_a(ver_secret)
+ eddsa_priv = ver_secret
eddsa_pub = get_eddsa_pub(eddsa_priv)
return eddsa_priv, eddsa_pub
}
@@ -369,14 +369,8 @@ eddsa_keys_create (kdf_id, salt, keysize)
\item[salt] {Is used that different keys are generated, the salt here is "ver".}
\item[key\_size] {Size of the output, here 32 bytes.}
\item[ver\_secret] {Derived key from the kdf\_id, serves as intermediate step for the generation of the private key.}
- \item[eddsa\_d\_to\_a()] {Function which converts the ver\_key to a valid EdDSA private key. Specifically, assuming the value eddsa\_priv is in a 32-byte array “digest”, the function clears and sets certain bits as follows:}
\end{description}
-\begin{lstlisting}
-digest[0] = (digest[0] & 0x7f) | 0x40;
-digest[31] &= 0xf8;
-\end{lstlisting}
-
\begin{description}
\item[eddsa\_priv] {The generated EdDSA private key.}
\item[eddsa\_pub] {The generated EdDSA public key.}
diff --git a/doc/system-documentation/thesis.bbl b/doc/system-documentation/thesis.bbl
index efd9b6e..b30324b 100644
--- a/doc/system-documentation/thesis.bbl
+++ b/doc/system-documentation/thesis.bbl
@@ -22,7 +22,7 @@
\entry{jerome2015}{article}{}
\name{author}{4}{}{%
{{hash=e042fd1cbe6bde0a3c8d7e8074ded97f}{%
- family={J{é}r{ô}me},
+ family={Jérôme},
familyi={J\bibinitperiod},
given={Brugger},
giveni={B\bibinitperiod}}}%
@@ -52,10 +52,10 @@
\strng{authornamehash}{7c1cd3857fa434fc3f5603bf8f77898f}
\strng{authorfullhash}{2a4edbd7fe20c9aeda5b1dfcb9ebb082}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
- \field{title}{AHV-Nummer als einheitlicher, organisations{ü}bergreifender Personenidentifikator}
+ \field{title}{AHV-Nummer als einheitlicher, organisationsübergreifender Personenidentifikator}
\field{year}{2015}
\endentry
\entry{garfinkel1995}{book}{}
@@ -76,7 +76,7 @@
\strng{authornamehash}{f7ae1c1e91c1c29835e2ff7e98908fa7}
\strng{authorfullhash}{f7ae1c1e91c1c29835e2ff7e98908fa7}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{PGP: pretty good privacy}
@@ -87,7 +87,7 @@
{pEp Security SA}%
}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labeltitlesource}{title}
\field{title}{Welcome to p≡p Documentation!}
\field{urlday}{6}
@@ -120,7 +120,7 @@
\strng{authornamehash}{881bf2fe8d7563c67a7bf0dca669ec1e}
\strng{authorfullhash}{881bf2fe8d7563c67a7bf0dca669ec1e}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{Proceedings IEEE 9th International Workshops on Enabling Technologies: Infrastructure for Collaborative Enterprises (WET ICE 2000)}
@@ -177,7 +177,7 @@
\strng{authornamehash}{10c7b94477775db573510e04e477a77b}
\strng{authorfullhash}{40a5ec0e4490a4063bf48a5924ef1c0f}
\field{sortinit}{5}
- \field{sortinithash}{5dd416adbafacc8226114bc0202d5fdd}
+ \field{sortinithash}{20e9b4b0b173788c5dace24730f47d8c}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{2017 11th IEEE International Conference on Anti-counterfeiting, Security, and Identification (ASID)}
@@ -204,7 +204,7 @@
\strng{authornamehash}{3648296958ad2ea0461fac7a13e12981}
\strng{authorfullhash}{3648296958ad2ea0461fac7a13e12981}
\field{sortinit}{6}
- \field{sortinithash}{7851c86048328b027313775d8fbd2131}
+ \field{sortinithash}{b33bc299efb3c36abec520a4c896a66d}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Bitcoin: Millions of dollars of cryptocurrency 'lost' after man dies with only password}
@@ -225,7 +225,7 @@
{Bitcoin}%
}
\field{sortinit}{7}
- \field{sortinithash}{f615fb9c6fba11c6f962fb3fd599810e}
+ \field{sortinithash}{108d0be1b1bee9773a1173443802c0a3}
\field{labeltitlesource}{title}
\field{title}{BIP 32 - Hierarchical Deterministic Wallets}
\field{urlday}{6}
@@ -255,7 +255,7 @@
\strng{authornamehash}{b5c45c4b8deb48651c65650f0409e671}
\strng{authorfullhash}{b5c45c4b8deb48651c65650f0409e671}
\field{sortinit}{9}
- \field{sortinithash}{54047ffb55bdefa0694bbd554c1b11a0}
+ \field{sortinithash}{0a5ebc79d83c96b6579069544c73c7d4}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Mobile Platforms Group Intel Corporation}
@@ -285,10 +285,10 @@
\strng{authornamehash}{abb7f98446293f740b141f01ff61554d}
\strng{authorfullhash}{abb7f98446293f740b141f01ff61554d}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
- \field{journaltitle}{Foundations and Trends® in Theoretical Computer Science}
+ \field{journaltitle}{Foundations and Trends{®} in Theoretical Computer Science}
\field{number}{1--3}
\field{title}{Pseudorandomness}
\field{volume}{7}
@@ -314,7 +314,7 @@
\strng{authornamehash}{6535189281ff6a1012638e384823f5cf}
\strng{authorfullhash}{6535189281ff6a1012638e384823f5cf}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{Annual International Cryptology Conference}
@@ -354,7 +354,7 @@
\strng{authornamehash}{39e304099b960365cdb56b83f4c70df6}
\strng{authorfullhash}{39e304099b960365cdb56b83f4c70df6}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{issn}{0004-5411}
@@ -407,7 +407,7 @@
\strng{editornamehash}{14f9bdb855aa40873ff3dce506ed6fff}
\strng{editorfullhash}{14f9bdb855aa40873ff3dce506ed6fff}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{abstract}{This paper describes the state of the art for cryptographic hash functions. Different definitions are compared, and the few theoretical results on hash functions are discussed. A brief overview is presented of the most important constructions, and some open problems are presented.}
@@ -450,7 +450,7 @@
\strng{authornamehash}{4d5e3f9d17e0c0b2294603b963e91c33}
\strng{authorfullhash}{4d5e3f9d17e0c0b2294603b963e91c33}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{International Journal of Computer Science Issues (IJCSI)}
@@ -481,7 +481,7 @@
\strng{authornamehash}{79ea2c47cb704d13b6d9bcf7c199fc51}
\strng{authorfullhash}{79ea2c47cb704d13b6d9bcf7c199fc51}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{IJCSNS International Journal of Computer Science and Network Security}
@@ -520,7 +520,7 @@
\strng{authornamehash}{4b253103893adba3aada17995ac73ec0}
\strng{authorfullhash}{4b253103893adba3aada17995ac73ec0}
\field{sortinit}{1}
- \field{sortinithash}{50c6687d7fc80f50136d75228e3c59ba}
+ \field{sortinithash}{4f6aaa89bab872aa0999fec09ff8e98a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{2011 Eighth International Conference on Information Technology: New Generations}
@@ -554,7 +554,7 @@
\strng{authornamehash}{2527ef0685da3bdb01959cd066adc238}
\strng{authorfullhash}{2527ef0685da3bdb01959cd066adc238}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{RSA Laboratories’ CryptoBytes}
@@ -583,7 +583,7 @@
\strng{authornamehash}{088445b3855bedf4bcc9d25651eb98b2}
\strng{authorfullhash}{088445b3855bedf4bcc9d25651eb98b2}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{Annual Cryptology Conference}
@@ -610,7 +610,7 @@
\strng{authornamehash}{0afd18d7b25d23c61db1fe942ec1c236}
\strng{authorfullhash}{0afd18d7b25d23c61db1fe942ec1c236}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Field-programmable gate array technology}
@@ -634,7 +634,7 @@
\strng{authornamehash}{093f14ec763e8df6227fd18ac8958011}
\strng{authorfullhash}{093f14ec763e8df6227fd18ac8958011}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{month}{6}
@@ -670,7 +670,7 @@
\strng{authornamehash}{037d5c3d4e3ef2dcef34dc59a05beed9}
\strng{authorfullhash}{037d5c3d4e3ef2dcef34dc59a05beed9}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{2016 IEEE European Symposium on Security and Privacy (EuroS\&P)}
@@ -694,7 +694,7 @@
\strng{authornamehash}{799c6648cb97b6ffb4e9da11a6e277ac}
\strng{authorfullhash}{799c6648cb97b6ffb4e9da11a6e277ac}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{San Jose State University, Department of Computer Science}
@@ -719,7 +719,7 @@
\strng{authornamehash}{71b77dd8ab33fe646ef25cded49e9881}
\strng{authorfullhash}{71b77dd8ab33fe646ef25cded49e9881}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Communications of the ACM}
@@ -749,7 +749,7 @@
\strng{authorfullhash}{ee278eaf10727ef21f15ba59cdfcb51b}
\field{extraname}{1}
\field{sortinit}{2}
- \field{sortinithash}{ed39bb39cf854d5250e95b1c1f94f4ed}
+ \field{sortinithash}{8b555b3791beccb63322c22f3320aa9a}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{Annual international cryptology conference}
@@ -777,7 +777,7 @@
\strng{authornamehash}{618e5892290641345f357d52e5ef3c12}
\strng{authorfullhash}{618e5892290641345f357d52e5ef3c12}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{28th Annual Symposium on Foundations of Computer Science (sfcs 1987)}
@@ -805,7 +805,7 @@
\strng{authorfullhash}{ee278eaf10727ef21f15ba59cdfcb51b}
\field{extraname}{2}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{Annual international cryptology conference}
@@ -858,7 +858,7 @@
\strng{authornamehash}{45cd1a76e0cdd8946f91bead3b664768}
\strng{authorfullhash}{c1db872bc8ef36ee51e0526f23769166}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Cryptography}
@@ -899,7 +899,7 @@
\strng{authornamehash}{ce7e837cc1dbca8dddef9896de46176c}
\strng{authorfullhash}{c7f2c123e1ed3b1e1ad986ca25e522b3}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Australian Journal of Basic and Applied Sciences}
@@ -934,7 +934,7 @@
\strng{authornamehash}{daa648a2c605762c09bfaab94d0f2168}
\strng{authorfullhash}{daa648a2c605762c09bfaab94d0f2168}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{IEEE Security \& Privacy}
@@ -978,7 +978,7 @@
\strng{authornamehash}{adce78e3f1e04476f35b2b5fcb6c6262}
\strng{authorfullhash}{85e8ef541ae3f71805b7382856006c85}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{International Conference on Detection of Intrusions and Malware, and Vulnerability Assessment}
@@ -1015,7 +1015,7 @@
\strng{authornamehash}{5646590031d49807385b96f9f6caae4a}
\strng{authorfullhash}{5646590031d49807385b96f9f6caae4a}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Detection of Intrusions and Malware, and Vulnerability Assessment: 10th International Conference, DIMVA 2013, Berlin, Germany, July 18-19, 2013. Proceedings}
@@ -1027,7 +1027,7 @@
{OWASP Foundation}%
}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labeltitlesource}{title}
\field{title}{Forgot Password Cheat Sheet}
\field{urlday}{5}
@@ -1072,10 +1072,10 @@
\strng{authornamehash}{46fedf156ec86b72f1439a7e282b9fee}
\strng{authorfullhash}{7c1027a04280b6542245beeb85db1408}
\field{sortinit}{3}
- \field{sortinithash}{a37a8ef248a93c322189792c34fc68c9}
+ \field{sortinithash}{ad6fe7482ffbd7b9f99c9e8b5dccd3d7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
- \field{title}{Wenn der Softbot menschliche Identit{ä}t best{ä}tigt. Videoident-Verfahren II: Die Technik}
+ \field{title}{Wenn der Softbot menschliche Identität bestätigt. Videoident-Verfahren II: Die Technik}
\field{year}{2017}
\endentry
\entry{biometric_auth}{article}{}
@@ -1101,7 +1101,7 @@
\strng{authornamehash}{db53816ca2458e8344846c9aa5b3bce3}
\strng{authorfullhash}{db53816ca2458e8344846c9aa5b3bce3}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Security and Communication Networks}
@@ -1127,7 +1127,7 @@
\strng{authornamehash}{b7a2e18f77259e34d5b676fd04412bb3}
\strng{authorfullhash}{b7a2e18f77259e34d5b676fd04412bb3}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{CCC-Tüftler hackt Merkels Iris und von der Leyens Fingerabdruck}
@@ -1148,7 +1148,7 @@
{Coinbase}%
}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labeltitlesource}{title}
\field{title}{Backup your encrypted private keys on Google Drive and iCloud with Coinbase Wallet}
\field{urlday}{6}
@@ -1186,7 +1186,7 @@
\strng{authornamehash}{e366017de179e8187fd5bb233ad210d8}
\strng{authorfullhash}{e366017de179e8187fd5bb233ad210d8}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Applied Approach to Privacy and Security for the Internet of Things}
@@ -1207,7 +1207,7 @@
\strng{authornamehash}{9dfd0bf532dd1b08969afefcdd7188b5}
\strng{authorfullhash}{9dfd0bf532dd1b08969afefcdd7188b5}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Black Hat USA}
@@ -1235,7 +1235,7 @@
\strng{authornamehash}{b3b08047d44ad47ea9a90d61cc647064}
\strng{authorfullhash}{b3b08047d44ad47ea9a90d61cc647064}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{booktitle}{Internet Research Task Force, Crypto Forum Research Group, RFC}
@@ -1261,7 +1261,7 @@
\strng{authornamehash}{f2ca7c0188bc149bef92a85d32759b7b}
\strng{authorfullhash}{f2ca7c0188bc149bef92a85d32759b7b}
\field{sortinit}{4}
- \field{sortinithash}{e071e0bcb44634fab398d68ad04e69f4}
+ \field{sortinithash}{9381316451d1b9788675a07e972a12a7}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{journaltitle}{Network Security}
@@ -1277,7 +1277,7 @@
{Taler Systems SA}%
}
\field{sortinit}{5}
- \field{sortinithash}{5dd416adbafacc8226114bc0202d5fdd}
+ \field{sortinithash}{20e9b4b0b173788c5dace24730f47d8c}
\field{labeltitlesource}{title}
\field{title}{GNU Taler: Features}
\field{urlday}{2}
@@ -1297,7 +1297,7 @@
{The PostgreSQL Global Development Group}%
}
\field{sortinit}{5}
- \field{sortinithash}{5dd416adbafacc8226114bc0202d5fdd}
+ \field{sortinithash}{20e9b4b0b173788c5dace24730f47d8c}
\field{labeltitlesource}{title}
\field{title}{PostgreSQL: The World's Most Advanced Open Source Relational Database}
\field{urlday}{2}
@@ -1317,7 +1317,7 @@
{Curl}%
}
\field{sortinit}{5}
- \field{sortinithash}{5dd416adbafacc8226114bc0202d5fdd}
+ \field{sortinithash}{20e9b4b0b173788c5dace24730f47d8c}
\field{labeltitlesource}{title}
\field{title}{libcurl - the multiprotocol file transfer library}
\field{urlday}{2}
@@ -1337,7 +1337,7 @@
{GNU project}%
}
\field{sortinit}{5}
- \field{sortinithash}{5dd416adbafacc8226114bc0202d5fdd}
+ \field{sortinithash}{20e9b4b0b173788c5dace24730f47d8c}
\field{labeltitlesource}{title}
\field{title}{GNU Libmicrohttpd}
\field{urlday}{2}
@@ -1352,60 +1352,6 @@
\verb https://www.gnu.org/software/libmicrohttpd/?
\endverb
\endentry
- \entry{global_data_index}{online}{}
- \list{organization}{1}{%
- {Dell EMC.}%
- }
- \field{sortinit}{5}
- \field{sortinithash}{5dd416adbafacc8226114bc0202d5fdd}
- \field{labeltitlesource}{title}
- \field{title}{Global Data Protection Index 2018 – Key Findings}
- \field{urlday}{7}
- \field{urlmonth}{3}
- \field{urlyear}{2020}
- \field{year}{2018}
- \field{urldateera}{ce}
- \verb{urlraw}
- \verb https://www.delltechnologies.com/content/dam/uwaem/production-design-assets/en/gdpi/assets/infographics/dell-gdpi-vb-key-findings-deck.pdf)
- \endverb
- \verb{url}
- \verb https://www.delltechnologies.com/content/dam/uwaem/production-design-assets/en/gdpi/assets/infographics/dell-gdpi-vb-key-findings-deck.pdf)
- \endverb
- \endentry
- \entry{forgot_my_pin}{online}{}
- \name{author}{1}{}{%
- {{hash=3690e6a925d190517dbba666878a6978}{%
- family={Frauenfelder},
- familyi={F\bibinitperiod},
- given={Mark},
- giveni={M\bibinitperiod}}}%
- }
- \list{organization}{1}{%
- {WIRED}%
- }
- \strng{namehash}{3690e6a925d190517dbba666878a6978}
- \strng{fullhash}{3690e6a925d190517dbba666878a6978}
- \strng{bibnamehash}{3690e6a925d190517dbba666878a6978}
- \strng{authorbibnamehash}{3690e6a925d190517dbba666878a6978}
- \strng{authornamehash}{3690e6a925d190517dbba666878a6978}
- \strng{authorfullhash}{3690e6a925d190517dbba666878a6978}
- \field{sortinit}{6}
- \field{sortinithash}{7851c86048328b027313775d8fbd2131}
- \field{labelnamesource}{author}
- \field{labeltitlesource}{title}
- \field{title}{I Forgot My PIN’: An Epic Tale of Losing \$30,000 in Bitcoin}
- \field{urlday}{7}
- \field{urlmonth}{3}
- \field{urlyear}{2020}
- \field{year}{2017}
- \field{urldateera}{ce}
- \verb{urlraw}
- \verb https://www.wired.com/story/i-forgot-my-pin-an-epic-tale-of-losing-dollar30000-in-bitcoin/
- \endverb
- \verb{url}
- \verb https://www.wired.com/story/i-forgot-my-pin-an-epic-tale-of-losing-dollar30000-in-bitcoin/
- \endverb
- \endentry
\enddatalist
\endrefsection
\endinput
diff --git a/doc/system-documentation/thesis.pdf b/doc/system-documentation/thesis.pdf
index 4d03f5b..44f154f 100644
--- a/doc/system-documentation/thesis.pdf
+++ b/doc/system-documentation/thesis.pdf
Binary files differ
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
index 3c7051d..e48383d 100644
--- a/doc/texinfo.tex
+++ b/doc/texinfo.tex
@@ -3,9 +3,9 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2020-10-24.12}
+\def\texinfoversion{2021-04-25.21}
%
-% Copyright 1985, 1986, 1988, 1990-2020 Free Software Foundation, Inc.
+% Copyright 1985, 1986, 1988, 1990-2021 Free Software Foundation, Inc.
%
% This texinfo.tex file is free software: you can redistribute it and/or
% modify it under the terms of the GNU General Public License as
@@ -572,9 +572,8 @@
\fi
}
-% @end foo executes the definition of \Efoo.
-% But first, it executes a specialized version of \checkenv
-%
+
+% @end foo calls \checkenv and executes the definition of \Efoo.
\parseargdef\end{%
\if 1\csname iscond.#1\endcsname
\else
@@ -1003,6 +1002,14 @@ where each line of input produces a line of output.}
\global\everypar = {}%
}
+% leave vertical mode without cancelling any first paragraph indent
+\gdef\imageindent{%
+ \toks0=\everypar
+ \everypar={}%
+ \ptexnoindent
+ \global\everypar=\toks0
+}
+
% @refill is a no-op.
\let\refill=\relax
@@ -1863,19 +1870,23 @@ output) for that.)}
\closein 1
\endgroup
%
- \def\xetexpdfext{pdf}%
- \ifx\xeteximgext\xetexpdfext
- \XeTeXpdffile "#1".\xeteximgext ""
- \else
- \def\xetexpdfext{PDF}%
+ % Putting an \hbox around the image can prevent an over-long line
+ % after the image.
+ \hbox\bgroup
+ \def\xetexpdfext{pdf}%
\ifx\xeteximgext\xetexpdfext
\XeTeXpdffile "#1".\xeteximgext ""
\else
- \XeTeXpicfile "#1".\xeteximgext ""
+ \def\xetexpdfext{PDF}%
+ \ifx\xeteximgext\xetexpdfext
+ \XeTeXpdffile "#1".\xeteximgext ""
+ \else
+ \XeTeXpicfile "#1".\xeteximgext ""
+ \fi
\fi
- \fi
- \ifdim \wd0 >0pt width \xeteximagewidth \fi
- \ifdim \wd2 >0pt height \xeteximageheight \fi \relax
+ \ifdim \wd0 >0pt width \xeteximagewidth \fi
+ \ifdim \wd2 >0pt height \xeteximageheight \fi \relax
+ \egroup
}
\fi
@@ -2673,8 +2684,6 @@ end
\definetextfontsizexi
-\message{markup,}
-
% Check if we are currently using a typewriter font. Since all the
% Computer Modern typewriter fonts have zero interword stretch (and
% shrink), and it is reasonable to expect all typewriter fonts to have
@@ -2682,68 +2691,14 @@ end
%
\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
-% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will
-% define and register \INITMACRO to be called on markup style changes.
-% \INITMACRO can check \currentmarkupstyle for the innermost
-% style.
-
-\let\currentmarkupstyle\empty
-
-\def\setupmarkupstyle#1{%
- \def\currentmarkupstyle{#1}%
- \markupstylesetup
-}
-
-\let\markupstylesetup\empty
-
-\def\defmarkupstylesetup#1{%
- \expandafter\def\expandafter\markupstylesetup
- \expandafter{\markupstylesetup #1}%
- \def#1%
-}
-
-% Markup style setup for left and right quotes.
-\defmarkupstylesetup\markupsetuplq{%
- \expandafter\let\expandafter \temp
- \csname markupsetuplq\currentmarkupstyle\endcsname
- \ifx\temp\relax \markupsetuplqdefault \else \temp \fi
-}
-
-\defmarkupstylesetup\markupsetuprq{%
- \expandafter\let\expandafter \temp
- \csname markupsetuprq\currentmarkupstyle\endcsname
- \ifx\temp\relax \markupsetuprqdefault \else \temp \fi
-}
-
{
\catcode`\'=\active
\catcode`\`=\active
-\gdef\markupsetuplqdefault{\let`\lq}
-\gdef\markupsetuprqdefault{\let'\rq}
-
-\gdef\markupsetcodequoteleft{\let`\codequoteleft}
-\gdef\markupsetcodequoteright{\let'\codequoteright}
+\gdef\setcodequotes{\let`\codequoteleft \let'\codequoteright}
+\gdef\setregularquotes{\let`\lq \let'\rq}
}
-\let\markupsetuplqcode \markupsetcodequoteleft
-\let\markupsetuprqcode \markupsetcodequoteright
-%
-\let\markupsetuplqexample \markupsetcodequoteleft
-\let\markupsetuprqexample \markupsetcodequoteright
-%
-\let\markupsetuplqkbd \markupsetcodequoteleft
-\let\markupsetuprqkbd \markupsetcodequoteright
-%
-\let\markupsetuplqsamp \markupsetcodequoteleft
-\let\markupsetuprqsamp \markupsetcodequoteright
-%
-\let\markupsetuplqverb \markupsetcodequoteleft
-\let\markupsetuprqverb \markupsetcodequoteright
-%
-\let\markupsetuplqverbatim \markupsetcodequoteleft
-\let\markupsetuprqverbatim \markupsetcodequoteright
-
% Allow an option to not use regular directed right quote/apostrophe
% (char 0x27), but instead the undirected quote from cmtt (char 0x0d).
% The undirected quote is ugly, so don't make it the default, but it
@@ -2906,7 +2861,7 @@ end
}
% @samp.
-\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
+\def\samp#1{{\setcodequotes\lq\tclose{#1}\rq\null}}
% @indicateurl is \samp, that is, with quotes.
\let\indicateurl=\samp
@@ -2949,8 +2904,7 @@ end
\global\let'=\rq \global\let`=\lq % default definitions
%
\global\def\code{\begingroup
- \setupmarkupstyle{code}%
- % The following should really be moved into \setupmarkupstyle handlers.
+ \setcodequotes
\catcode\dashChar=\active \catcode\underChar=\active
\ifallowcodebreaks
\let-\codedash
@@ -3104,7 +3058,7 @@ end
\urefcatcodes
%
\global\def\urefcode{\begingroup
- \setupmarkupstyle{code}%
+ \setcodequotes
\urefcatcodes
\let&\urefcodeamp
\let.\urefcodedot
@@ -3225,8 +3179,8 @@ end
\def\kbdsub#1#2#3\par{%
\def\one{#1}\def\three{#3}\def\threex{??}%
\ifx\one\xkey\ifx\threex\three \key{#2}%
- \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
- \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
+ \else{\tclose{\kbdfont\setcodequotes\look}}\fi
+ \else{\tclose{\kbdfont\setcodequotes\look}}\fi
}
% definition of @key that produces a lozenge. Doesn't adjust to text size.
@@ -3243,7 +3197,7 @@ end
% monospace, don't change it; that way, we respect @kbdinputstyle. But
% if it isn't monospace, then use \tt.
%
-\def\key#1{{\setupmarkupstyle{key}%
+\def\key#1{{\setregularquotes
\nohyphenation
\ifmonospace\else\tt\fi
#1}\null}
@@ -3373,16 +3327,20 @@ end
{\obeylines
\globaldefs=1
\envdef\displaymath{%
-\tex
+\tex%
\def\thisenv{\displaymath}%
+\begingroup\let\end\displaymathend%
$$%
}
-\def\Edisplaymath{$$
+\def\displaymathend{$$\endgroup\end}%
+
+\def\Edisplaymath{%
\def\thisenv{\tex}%
\end tex
}}
+
% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
% Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
% except specified as a normal braced arg, so no newlines to worry about.
@@ -4343,82 +4301,8 @@ $$%
\doitemize{#1.}\flushcr
}
-% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
-% to @enumerate.
-%
-\def\alphaenumerate{\enumerate{a}}
-\def\capsenumerate{\enumerate{A}}
-\def\Ealphaenumerate{\Eenumerate}
-\def\Ecapsenumerate{\Eenumerate}
-
% @multitable macros
-% Amy Hendrickson, 8/18/94, 3/6/96
-%
-% @multitable ... @end multitable will make as many columns as desired.
-% Contents of each column will wrap at width given in preamble. Width
-% can be specified either with sample text given in a template line,
-% or in percent of \hsize, the current width of text on page.
-
-% Table can continue over pages but will only break between lines.
-
-% To make preamble:
-%
-% Either define widths of columns in terms of percent of \hsize:
-% @multitable @columnfractions .25 .3 .45
-% @item ...
-%
-% Numbers following @columnfractions are the percent of the total
-% current hsize to be used for each column. You may use as many
-% columns as desired.
-
-
-% Or use a template:
-% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
-% @item ...
-% using the widest term desired in each column.
-
-% Each new table line starts with @item, each subsequent new column
-% starts with @tab. Empty columns may be produced by supplying @tab's
-% with nothing between them for as many times as empty columns are needed,
-% ie, @tab@tab@tab will produce two empty columns.
-
-% @item, @tab do not need to be on their own lines, but it will not hurt
-% if they are.
-
-% Sample multitable:
-
-% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
-% @item first col stuff @tab second col stuff @tab third col
-% @item
-% first col stuff
-% @tab
-% second col stuff
-% @tab
-% third col
-% @item first col stuff @tab second col stuff
-% @tab Many paragraphs of text may be used in any column.
-%
-% They will wrap at the width determined by the template.
-% @item@tab@tab This will be in third column.
-% @end multitable
-
-% Default dimensions may be reset by user.
-% @multitableparskip is vertical space between paragraphs in table.
-% @multitableparindent is paragraph indent in table.
-% @multitablecolmargin is horizontal space to be left between columns.
-% @multitablelinespace is space to leave between table items, baseline
-% to baseline.
-% 0pt means it depends on current normal line spacing.
-%
-\newskip\multitableparskip
-\newskip\multitableparindent
-\newdimen\multitablecolspace
-\newskip\multitablelinespace
-\multitableparskip=0pt
-\multitableparindent=6pt
-\multitablecolspace=12pt
-\multitablelinespace=0pt
% Macros used to set up halign preamble:
%
@@ -4466,8 +4350,6 @@ $$%
\go
}
-% multitable-only commands.
-%
% @headitem starts a heading row, which we typeset in bold. Assignments
% have to be global since we are inside the implicit group of an
% alignment entry. \everycr below resets \everytab so we don't have to
@@ -4484,14 +4366,8 @@ $$%
% default for tables with no headings.
\let\headitemcrhook=\relax
%
-% A \tab used to include \hskip1sp. But then the space in a template
-% line is not enough. That is bad. So let's go back to just `&' until
-% we again encounter the problem the 1sp was intended to solve.
-% --karl, nathan@acm.org, 20apr99.
\def\tab{\checkenv\multitable &\the\everytab}%
-% @multitable ... @end multitable definitions:
-%
\newtoks\everytab % insert after every tab.
%
\envdef\multitable{%
@@ -4506,9 +4382,8 @@ $$%
%
\tolerance=9500
\hbadness=9500
- \setmultitablespacing
- \parskip=\multitableparskip
- \parindent=\multitableparindent
+ \parskip=0pt
+ \parindent=6pt
\overfullrule=0pt
\global\colcount=0
%
@@ -4538,47 +4413,24 @@ $$%
% continue for many paragraphs if desired.
\halign\bgroup &%
\global\advance\colcount by 1
- \multistrut
+ \strut
\vtop{%
- % Use the current \colcount to find the correct column width:
+ \advance\hsize by -1\leftskip
+ % Find the correct column width
\hsize=\expandafter\csname col\the\colcount\endcsname
%
- % In order to keep entries from bumping into each other
- % we will add a \leftskip of \multitablecolspace to all columns after
- % the first one.
- %
- % If a template has been used, we will add \multitablecolspace
- % to the width of each template entry.
- %
- % If the user has set preamble in terms of percent of \hsize we will
- % use that dimension as the width of the column, and the \leftskip
- % will keep entries from bumping into each other. Table will start at
- % left margin and final column will justify at right margin.
- %
- % Make sure we don't inherit \rightskip from the outer environment.
\rightskip=0pt
\ifnum\colcount=1
- % The first column will be indented with the surrounding text.
- \advance\hsize by\leftskip
+ \advance\hsize by\leftskip % Add indent of surrounding text
\else
- \ifsetpercent \else
- % If user has not set preamble in terms of percent of \hsize
- % we will advance \hsize by \multitablecolspace.
- \advance\hsize by \multitablecolspace
- \fi
- % In either case we will make \leftskip=\multitablecolspace:
- \leftskip=\multitablecolspace
+ % In order to keep entries from bumping into each other.
+ \leftskip=12pt
+ \ifsetpercent \else
+ % If a template has been used
+ \advance\hsize by \leftskip
+ \fi
\fi
- % Ignoring space at the beginning and end avoids an occasional spurious
- % blank line, when TeX decides to break the line at the space before the
- % box from the multistrut, so the strut ends up on a line by itself.
- % For example:
- % @multitable @columnfractions .11 .89
- % @item @code{#}
- % @tab Legal holiday which is valid in major parts of the whole country.
- % Is automatically provided with highlighting sequences respectively
- % marking characters.
- \noindent\ignorespaces##\unskip\multistrut
+ \noindent\ignorespaces##\unskip\strut
}\cr
}
\def\Emultitable{%
@@ -4587,31 +4439,6 @@ $$%
\global\setpercentfalse
}
-\def\setmultitablespacing{%
- \def\multistrut{\strut}% just use the standard line spacing
- %
- % Compute \multitablelinespace (if not defined by user) for use in
- % \multitableparskip calculation. We used define \multistrut based on
- % this, but (ironically) that caused the spacing to be off.
- % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
-\ifdim\multitablelinespace=0pt
-\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
-\global\advance\multitablelinespace by-\ht0
-\fi
-% Test to see if parskip is larger than space between lines of
-% table. If not, do nothing.
-% If so, set to same dimension as multitablelinespace.
-\ifdim\multitableparskip>\multitablelinespace
-\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
- % than skip between lines in the table.
-\fi%
-\ifdim\multitableparskip=0pt
-\global\multitableparskip=\multitablelinespace
-\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller
- % than skip between lines in the table.
-\fi}
-
\message{conditionals,}
@@ -5225,30 +5052,29 @@ $$%
\let\lbracechar\{%
\let\rbracechar\}%
%
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\DH{DZZ}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\TH{TH}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\dh{dzz}%
+ \def\exclamdown{!}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ \def\o{o}%
+ \def\questiondown{?}%
+ \def\ss{ss}%
+ \def\th{th}%
%
\let\do\indexnofontsdef
%
- % Non-English letters.
- \do\AA{AA}%
- \do\AE{AE}%
- \do\DH{DZZ}%
- \do\L{L}%
- \do\OE{OE}%
- \do\O{O}%
- \do\TH{TH}%
- \do\aa{aa}%
- \do\ae{ae}%
- \do\dh{dzz}%
- \do\exclamdown{!}%
- \do\l{l}%
- \do\oe{oe}%
- \do\ordf{a}%
- \do\ordm{o}%
- \do\o{o}%
- \do\questiondown{?}%
- \do\ss{ss}%
- \do\th{th}%
- %
\do\LaTeX{LaTeX}%
\do\TeX{TeX}%
%
@@ -7144,7 +6970,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% But \@ or @@ will get a plain @ character.
\envdef\tex{%
- \setupmarkupstyle{tex}%
+ \setregularquotes
\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
\catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
@@ -7370,7 +7196,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% If you want all examples etc. small: @set dispenvsize small.
% If you want even small examples the full size: @set dispenvsize nosmall.
% This affects the following displayed environments:
-% @example, @display, @format, @lisp
+% @example, @display, @format, @lisp, @verbatim
%
\def\smallword{small}
\def\nosmallword{nosmall}
@@ -7416,9 +7242,9 @@ might help (with 'rm \jobname.?? \jobname.??s')%
%
\maketwodispenvdef{lisp}{example}{%
\nonfillstart
- \tt\setupmarkupstyle{example}%
+ \tt\setcodequotes
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
- \gobble % eat return
+ \parsearg\gobble
}
% @display/@smalldisplay: same as @lisp except keep current font.
%
@@ -7576,7 +7402,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\setupverb{%
\tt % easiest (and conventionally used) font for verbatim
\def\par{\leavevmode\endgraf}%
- \setupmarkupstyle{verb}%
+ \setcodequotes
\tabeightspaces
% Respect line breaks,
% print special symbols as themselves, and
@@ -7617,7 +7443,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\tt % easiest (and conventionally used) font for verbatim
\def\par{\egroup\leavevmode\box\verbbox\endgraf\starttabbox}%
\tabexpand
- \setupmarkupstyle{verbatim}%
+ \setcodequotes
% Respect line breaks,
% print special symbols as themselves, and
% make each space count.
@@ -8036,7 +7862,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% leave the code in, but it's strange for @var to lead to typewriter.
% Nowadays we recommend @code, since the difference between a ttsl hyphen
% and a tt hyphen is pretty tiny. @code also disables ?` !`.
- \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}%
+ \def\var##1{{\setregularquotes\ttslanted{##1}}}%
#1%
\sl\hyphenchar\font=45
}
@@ -8145,11 +7971,18 @@ might help (with 'rm \jobname.?? \jobname.??s')%
}
\fi
+\let\E=\expandafter
+
% Used at the time of macro expansion.
% Argument is macro body with arguments substituted
\def\scanmacro#1{%
\newlinechar`\^^M
- \def\xeatspaces{\eatspaces}%
+ % expand the expansion of \eatleadingcr twice to maybe remove a leading
+ % newline (and \else and \fi tokens), then call \eatspaces on the result.
+ \def\xeatspaces##1{%
+ \E\E\E\E\E\E\E\eatspaces\E\E\E\E\E\E\E{\eatleadingcr##1%
+ }}%
+ \def\xempty##1{}%
%
% Process the macro body under the current catcode regime.
\scantokens{#1@comment}%
@@ -8202,6 +8035,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\unbrace{\gdef\trim@@@ #1 } #2@{#1}
}
+{\catcode`\^^M=\other%
+\gdef\eatleadingcr#1{\if\noexpand#1\noexpand^^M\else\E#1\fi}}%
+% Warning: this won't work for a delimited argument
+% or for an empty argument
+
% Trim a single trailing ^^M off a string.
{\catcode`\^^M=\other \catcode`\Q=3%
\gdef\eatcr #1{\eatcra #1Q^^MQ}%
@@ -8368,6 +8206,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\let\hash\relax
% \hash is redefined to `#' later to get it into definitions
\let\xeatspaces\relax
+ \let\xempty\relax
\parsemargdefxxx#1,;,%
\ifnum\paramno<10\relax\else
\paramno0\relax
@@ -8379,9 +8218,11 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else \let\next=\parsemargdefxxx
\advance\paramno by 1
\expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
- {\xeatspaces{\hash\the\paramno}}%
+ {\xeatspaces{\hash\the\paramno\noexpand\xempty{}}}%
\edef\paramlist{\paramlist\hash\the\paramno,}%
\fi\next}
+% the \xempty{} is to give \eatleadingcr an argument in the case of an
+% empty macro argument.
% \parsemacbody, \parsermacbody
%
@@ -8970,7 +8811,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else
\ifhavexrefs
% We (should) know the real title if we have the xref values.
- \def\printedrefname{\refx{#1-title}{}}%
+ \def\printedrefname{\refx{#1-title}}%
\else
% Otherwise just copy the Info node name.
\def\printedrefname{\ignorespaces #1}%
@@ -9064,7 +8905,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% If the user specified the print name (third arg) to the ref,
% print it instead of our usual "Figure 1.2".
\ifdim\wd\printedrefnamebox = 0pt
- \refx{#1-snt}{}%
+ \refx{#1-snt}%
\else
\printedrefname
\fi
@@ -9099,28 +8940,30 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\else
% Reference within this manual.
%
- % Only output a following space if the -snt ref is nonempty; for
- % @unnumbered and @anchor, it won't be.
- \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ % Only output a following space if the -snt ref is nonempty, as the ref
+ % will be empty for @unnumbered and @anchor.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}}%
\ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
%
% output the `[mynode]' via the macro below so it can be overridden.
\xrefprintnodename\printedrefname
%
- % But we always want a comma and a space:
- ,\space
- %
- % output the `page 3'.
- \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
- % Add a , if xref followed by a space
- \if\space\noexpand\tokenafterxref ,%
- \else\ifx\ \tokenafterxref ,% @TAB
- \else\ifx\*\tokenafterxref ,% @*
- \else\ifx\ \tokenafterxref ,% @SPACE
- \else\ifx\
- \tokenafterxref ,% @NL
- \else\ifx\tie\tokenafterxref ,% @tie
- \fi\fi\fi\fi\fi\fi
+ \expandafter\ifx\csname SETtxiomitxrefpg\endcsname\relax
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}%
+ % Add a , if xref followed by a space
+ \if\space\noexpand\tokenafterxref ,%
+ \else\ifx\ \tokenafterxref ,% @TAB
+ \else\ifx\*\tokenafterxref ,% @*
+ \else\ifx\ \tokenafterxref ,% @SPACE
+ \else\ifx\
+ \tokenafterxref ,% @NL
+ \else\ifx\tie\tokenafterxref ,% @tie
+ \fi\fi\fi\fi\fi\fi
+ \fi
\fi\fi
\fi
\endlink
@@ -9187,9 +9030,8 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\fi\fi\fi
}
-% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX
-% is output afterwards if non-empty.
-\def\refx#1#2{%
+% \refx{NAME} - reference a cross-reference string named NAME.
+\def\refx#1{%
\requireauxfile
{%
\indexnofonts
@@ -9216,7 +9058,6 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% It's defined, so just use it.
\thisrefX
\fi
- #2% Output the suffix in any case.
}
% This is the macro invoked by entries in the aux file. Define a control
@@ -9326,10 +9167,10 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\catcode`\[=\other
\catcode`\]=\other
\catcode`\"=\other
- \catcode`\_=\other
- \catcode`\|=\other
- \catcode`\<=\other
- \catcode`\>=\other
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
\catcode`\$=\other
\catcode`\#=\other
\catcode`\&=\other
@@ -9550,7 +9391,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
\catcode`\^^M = 5 % in case we're inside an example
\normalturnoffactive % allow _ et al. in names
- \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro
+ \makevalueexpandable
% If the image is by itself, center it.
\ifvmode
\imagevmodetrue
@@ -9576,7 +9417,7 @@ might help (with 'rm \jobname.?? \jobname.??s')%
% On the other hand, if we are in the case of @center @image, we don't
% want to start a paragraph, which will create a hsize-width box and
% eradicate the centering.
- \ifx\centersub\centerV\else \noindent \fi
+ \ifx\centersub\centerV \else \imageindent \fi
%
% Output the image.
\ifpdf
@@ -11603,7 +11444,7 @@ directory should work if nowhere else does.}
\let> = \activegtr
\let~ = \activetilde
\let^ = \activehat
- \markupsetuplqdefault \markupsetuprqdefault
+ \setregularquotes
\let\b = \strong
\let\i = \smartitalic
% in principle, all other definitions in \tex have to be undone too.
@@ -11662,8 +11503,7 @@ directory should work if nowhere else does.}
@let|=@normalverticalbar
@let~=@normaltilde
@let\=@ttbackslash
- @markupsetuplqdefault
- @markupsetuprqdefault
+ @setregularquotes
@unsepspaces
}
}
@@ -11756,8 +11596,7 @@ directory should work if nowhere else does.}
@c Do this last of all since we use ` in the previous @catcode assignments.
@catcode`@'=@active
@catcode`@`=@active
-@markupsetuplqdefault
-@markupsetuprqdefault
+@setregularquotes
@c Local variables:
@c eval: (add-hook 'before-save-hook 'time-stamp)
@@ -11770,3 +11609,4 @@ directory should work if nowhere else does.}
@c vim:sw=2:
@enablebackslashhack
+
diff --git a/src/authorization/Makefile.am b/src/authorization/Makefile.am
index cfcd89e..ec9ae5a 100644
--- a/src/authorization/Makefile.am
+++ b/src/authorization/Makefile.am
@@ -21,6 +21,8 @@ pkgdata_DATA = \
EXTRA_DIST = \
$(pkgdata_DATA) \
+ $(cfg_DATA) \
+ $(bin_SCRIPTS) \
iban.h iban.c
@@ -69,7 +71,8 @@ plugin_LTLIBRARIES = \
libanastasis_plugin_authorization_file.la \
libanastasis_plugin_authorization_iban.la \
libanastasis_plugin_authorization_post.la \
- libanastasis_plugin_authorization_sms.la
+ libanastasis_plugin_authorization_sms.la \
+ libanastasis_plugin_authorization_totp.la
libanastasis_plugin_authorization_file_la_SOURCES = \
@@ -151,3 +154,22 @@ libanastasis_plugin_authorization_sms_la_LDFLAGS = \
-ljansson \
-lmicrohttpd \
$(XLIB)
+
+
+libanastasis_plugin_authorization_totp_la_SOURCES = \
+ anastasis_authorization_plugin_totp.c
+libanastasis_plugin_authorization_totp_la_LIBADD = \
+ $(LTLIBINTL)
+libanastasis_plugin_authorization_totp_la_LDFLAGS = \
+ $(ANASTASIS_PLUGIN_LDFLAGS) \
+ $(top_builddir)/src/stasis/libanastasisdb.la \
+ $(top_builddir)/src/util/libanastasisutil.la \
+ -ltalerjson \
+ -ltalermhd \
+ -ltalerutil \
+ -lgnunetjson \
+ -lgnunetutil \
+ -ljansson \
+ -lmicrohttpd \
+ -lgcrypt \
+ $(XLIB)
diff --git a/src/authorization/anastasis_authorization_plugin.c b/src/authorization/anastasis_authorization_plugin.c
index c557aa3..7e25c03 100644
--- a/src/authorization/anastasis_authorization_plugin.c
+++ b/src/authorization/anastasis_authorization_plugin.c
@@ -3,7 +3,7 @@
Copyright (C) 2015, 2016, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/authorization/anastasis_authorization_plugin_email.c b/src/authorization/anastasis_authorization_plugin_email.c
index 0eefcc5..d968252 100644
--- a/src/authorization/anastasis_authorization_plugin_email.c
+++ b/src/authorization/anastasis_authorization_plugin_email.c
@@ -3,7 +3,7 @@
Copyright (C) 2019-2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -374,20 +374,12 @@ email_process (struct ANASTASIS_AUTHORIZATION_State *as,
GNUNET_DISK_PIPE_END_WRITE);
GNUNET_assert (NULL != pipe_stdin);
GNUNET_DISK_pipe_close (p);
- {
- char *tpk;
-
- tpk = GNUNET_STRINGS_data_to_string_alloc (
- &as->truth_uuid,
- sizeof (as->truth_uuid));
- GNUNET_asprintf (&as->msg,
- get_message (as->ctx->messages,
- connection,
- "body"),
- (unsigned long long) as->code,
- tpk);
- GNUNET_free (tpk);
- }
+ GNUNET_asprintf (&as->msg,
+ get_message (as->ctx->messages,
+ connection,
+ "body"),
+ (unsigned long long) as->code,
+ ANASTASIS_CRYPTO_uuid2s (&as->truth_uuid));
{
const char *off = as->msg;
diff --git a/src/authorization/anastasis_authorization_plugin_file.c b/src/authorization/anastasis_authorization_plugin_file.c
index 66dbbe1..863db11 100644
--- a/src/authorization/anastasis_authorization_plugin_file.c
+++ b/src/authorization/anastasis_authorization_plugin_file.c
@@ -3,7 +3,7 @@
Copyright (C) 2019 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -86,7 +86,7 @@ file_validate (void *cls,
(void) cls;
if (NULL == data)
- return GNUNET_NO;
+ return GNUNET_SYSERR;
filename = GNUNET_STRINGS_data_to_string_alloc (data,
data_length);
flag = false;
@@ -100,7 +100,7 @@ file_validate (void *cls,
}
}
if (flag)
- return GNUNET_NO;
+ return GNUNET_SYSERR;
GNUNET_free (filename);
return GNUNET_OK;
}
diff --git a/src/authorization/anastasis_authorization_plugin_iban.c b/src/authorization/anastasis_authorization_plugin_iban.c
index 7717770..58a63a6 100644
--- a/src/authorization/anastasis_authorization_plugin_iban.c
+++ b/src/authorization/anastasis_authorization_plugin_iban.c
@@ -3,7 +3,7 @@
Copyright (C) 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/authorization/anastasis_authorization_plugin_post.c b/src/authorization/anastasis_authorization_plugin_post.c
index 4adeffd..4692317 100644
--- a/src/authorization/anastasis_authorization_plugin_post.c
+++ b/src/authorization/anastasis_authorization_plugin_post.c
@@ -3,7 +3,7 @@
Copyright (C) 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -448,21 +448,12 @@ post_process (struct ANASTASIS_AUTHORIZATION_State *as,
GNUNET_DISK_PIPE_END_WRITE);
GNUNET_assert (NULL != pipe_stdin);
GNUNET_DISK_pipe_close (p);
- {
- char *tpk;
-
- tpk = GNUNET_STRINGS_data_to_string_alloc (
- &as->truth_uuid,
- sizeof (as->truth_uuid));
- GNUNET_asprintf (&as->msg,
- get_message (as->ctx->messages,
- connection,
- "body"),
- (unsigned long long) as->code,
- tpk);
- GNUNET_free (tpk);
- }
-
+ GNUNET_asprintf (&as->msg,
+ get_message (as->ctx->messages,
+ connection,
+ "body"),
+ (unsigned long long) as->code,
+ ANASTASIS_CRYPTO_uuid2s (&as->truth_uuid));
{
const char *off = as->msg;
size_t left = strlen (off);
diff --git a/src/authorization/anastasis_authorization_plugin_sms.c b/src/authorization/anastasis_authorization_plugin_sms.c
index 94b2c0d..2fed576 100644
--- a/src/authorization/anastasis_authorization_plugin_sms.c
+++ b/src/authorization/anastasis_authorization_plugin_sms.c
@@ -3,7 +3,7 @@
Copyright (C) 2019, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -373,19 +373,10 @@ sms_process (struct ANASTASIS_AUTHORIZATION_State *as,
GNUNET_DISK_PIPE_END_WRITE);
GNUNET_assert (NULL != pipe_stdin);
GNUNET_DISK_pipe_close (p);
- {
- char *tpk;
-
- tpk = GNUNET_STRINGS_data_to_string_alloc (
- &as->truth_uuid,
- sizeof (as->truth_uuid));
- GNUNET_asprintf (&as->msg,
- "A-%llu\nAnastasis\n%s",
- (unsigned long long) as->code,
- tpk);
- GNUNET_free (tpk);
- }
-
+ GNUNET_asprintf (&as->msg,
+ "A-%llu\nAnastasis\n: %s",
+ (unsigned long long) as->code,
+ ANASTASIS_CRYPTO_uuid2s (&as->truth_uuid));
{
const char *off = as->msg;
size_t left = strlen (off);
diff --git a/src/authorization/anastasis_authorization_plugin_totp.c b/src/authorization/anastasis_authorization_plugin_totp.c
new file mode 100644
index 0000000..b3d5bc0
--- /dev/null
+++ b/src/authorization/anastasis_authorization_plugin_totp.c
@@ -0,0 +1,401 @@
+/*
+ This totp is part of Anastasis
+ Copyright (C) 2021 Anastasis SARL
+
+ Anastasis is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ Anastasis; see the totp COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @totp anastasis_authorization_plugin_totp.c
+ * @brief authorization plugin using totp
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "anastasis_authorization_plugin.h"
+#include <taler/taler_mhd_lib.h>
+#include <gnunet/gnunet_db_lib.h>
+#include "anastasis_database_lib.h"
+#include <gcrypt.h>
+
+
+/**
+ * How many retries do we allow per code?
+ */
+#define INITIAL_RETRY_COUNTER 3
+
+/**
+ * How long is a TOTP code valid?
+ */
+#define TOTP_VALIDITY_PERIOD GNUNET_TIME_relative_multiply ( \
+ GNUNET_TIME_UNIT_SECONDS, 30)
+
+/**
+ * Range of time we allow (plus-minus).
+ */
+#define TIME_INTERVAL_RANGE 2
+
+/**
+ * How long is the shared secret in bytes?
+ */
+#define SECRET_LEN 32
+
+
+/**
+ * Saves the state of a authorization process
+ */
+struct ANASTASIS_AUTHORIZATION_State
+{
+ /**
+ * UUID of the challenge which is authorised
+ */
+ struct ANASTASIS_CRYPTO_TruthUUIDP truth_uuid;
+
+ /**
+ * Was the challenge satisfied?
+ */
+ struct GNUNET_HashCode valid_replies[TIME_INTERVAL_RANGE * 2 + 1];
+
+ /**
+ * Our context.
+ */
+ const struct ANASTASIS_AuthorizationContext *ac;
+
+};
+
+
+/**
+ * Validate @a data is a well-formed input into the challenge method,
+ * i.e. @a data is a well-formed phone number for sending an SMS, or
+ * a well-formed e-mail address for sending an e-mail. Not expected to
+ * check that the phone number or e-mail account actually exists.
+ *
+ * To be possibly used before issuing a 402 payment required to the client.
+ *
+ * @param cls closure with a `const struct ANASTASIS_AuthorizationContext *`
+ * @param connection HTTP client request (for queuing response)
+ * @param truth_mime mime type of @e data
+ * @param data input to validate (i.e. is it a valid phone number, etc.)
+ * @param data_length number of bytes in @a data
+ * @return #GNUNET_OK if @a data is valid,
+ * #GNUNET_NO if @a data is invalid and a reply was successfully queued on @a connection
+ * #GNUNET_SYSERR if @a data invalid but we failed to queue a reply on @a connection
+ */
+static enum GNUNET_GenericReturnValue
+totp_validate (void *cls,
+ struct MHD_Connection *connection,
+ const char *truth_mime,
+ const char *data,
+ size_t data_length)
+{
+ (void) cls;
+ (void) truth_mime;
+ (void) connection;
+ if (NULL == data)
+ {
+ GNUNET_break_op (0);
+ if (MHD_NO ==
+ TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_EXPECTATION_FAILED,
+ TALER_EC_ANASTASIS_TOTP_KEY_MISSING,
+ NULL))
+ return GNUNET_SYSERR;
+ return GNUNET_NO;
+ }
+ if (SECRET_LEN != data_length)
+ {
+ GNUNET_break_op (0);
+ if (MHD_NO ==
+ TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_EXPECTATION_FAILED,
+ TALER_EC_ANASTASIS_TOTP_KEY_INVALID,
+ NULL))
+ return GNUNET_SYSERR;
+ return GNUNET_NO;
+ }
+ return GNUNET_OK;
+}
+
+
+/**
+ * Compute TOTP code at current time with offset
+ * @a time_off for the @a key.
+ *
+ * @param time_off offset to apply when computing the code
+ * @param key input key material
+ * @param key_size number of bytes in @a key
+ * @return TOTP code at this time
+ */
+static uint64_t
+compute_totp (int time_off,
+ const void *key,
+ size_t key_size)
+{
+ struct GNUNET_TIME_Absolute now;
+ time_t t;
+ uint64_t ctr;
+ uint8_t hmac[20]; /* SHA1: 20 bytes */
+
+ now = GNUNET_TIME_absolute_get ();
+ (void) GNUNET_TIME_round_abs (&now);
+ while (time_off < 0)
+ {
+ now = GNUNET_TIME_absolute_subtract (now,
+ TOTP_VALIDITY_PERIOD);
+ time_off++;
+ }
+ while (time_off > 0)
+ {
+ now = GNUNET_TIME_absolute_add (now,
+ TOTP_VALIDITY_PERIOD);
+ time_off--;
+ }
+ t = now.abs_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
+ ctr = GNUNET_htonll (t / 30LLU);
+
+ {
+ gcry_md_hd_t md;
+ const unsigned char *mc;
+
+ GNUNET_assert (GPG_ERR_NO_ERROR ==
+ gcry_md_open (&md,
+ GCRY_MD_SHA1,
+ GCRY_MD_FLAG_HMAC));
+ gcry_md_setkey (md,
+ key,
+ key_size);
+ gcry_md_write (md,
+ &ctr,
+ sizeof (ctr));
+ mc = gcry_md_read (md,
+ GCRY_MD_SHA1);
+ GNUNET_assert (NULL != mc);
+ memcpy (hmac,
+ mc,
+ sizeof (hmac));
+ gcry_md_close (md);
+ }
+
+ {
+ uint32_t code = 0;
+ int offset;
+
+ offset = hmac[sizeof (hmac) - 1] & 0x0f;
+ for (int count = 0; count < 4; count++)
+ code |= hmac[offset + 3 - count] << (8 * count);
+ code &= 0x7fffffff;
+ /* always use 8 digits (maximum) */
+ code = code % 100000000;
+ return code;
+ }
+}
+
+
+/**
+ * Begin issuing authentication challenge to user based on @a data.
+ *
+ * @param cls closure
+ * @param trigger function to call when we made progress
+ * @param trigger_cls closure for @a trigger
+ * @param truth_uuid Identifier of the challenge, to be (if possible) included in the
+ * interaction with the user
+ * @param code always 0 (direct validation, backend does
+ * not generate a code in this mode)
+ * @param data truth for input to validate (i.e. the shared secret)
+ * @param data_length number of bytes in @a data
+ * @return state to track progress on the authorization operation, NULL on failure
+ */
+static struct ANASTASIS_AUTHORIZATION_State *
+totp_start (void *cls,
+ GNUNET_SCHEDULER_TaskCallback trigger,
+ void *trigger_cls,
+ const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid,
+ uint64_t code,
+ const void *data,
+ size_t data_length)
+{
+ const struct ANASTASIS_AuthorizationContext *ac = cls;
+ struct ANASTASIS_AUTHORIZATION_State *as;
+ uint64_t want;
+ unsigned int off = 0;
+
+ GNUNET_assert (0 == code);
+ as = GNUNET_new (struct ANASTASIS_AUTHORIZATION_State);
+ as->ac = ac;
+ as->truth_uuid = *truth_uuid;
+ for (int i = -TIME_INTERVAL_RANGE;
+ i <= TIME_INTERVAL_RANGE;
+ i++)
+ {
+ want = compute_totp (i,
+ data,
+ data_length);
+ ANASTASIS_hash_answer (want,
+ &as->valid_replies[off++]);
+ }
+ return as;
+}
+
+
+/**
+ * Begin issuing authentication challenge to user based on @a data.
+ *
+ * @param as authorization state
+ * @param timeout how long do we have to produce a reply
+ * @param connection HTTP client request (for queuing response, such as redirection to video portal)
+ * @return state of the request
+ */
+static enum ANASTASIS_AUTHORIZATION_Result
+totp_process (struct ANASTASIS_AUTHORIZATION_State *as,
+ struct GNUNET_TIME_Absolute timeout,
+ struct MHD_Connection *connection)
+{
+ MHD_RESULT mres;
+ const char *mime;
+ const char *lang;
+ const char *challenge_response_s;
+ struct GNUNET_HashCode challenge_response;
+
+ challenge_response_s = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "response");
+ if ( (NULL == challenge_response_s) ||
+ (GNUNET_OK !=
+ GNUNET_CRYPTO_hash_from_string (challenge_response_s,
+ &challenge_response)) )
+ {
+ GNUNET_break_op (0);
+ mres = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ "response");
+ if (MHD_YES != mres)
+ return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED;
+ return ANASTASIS_AUTHORIZATION_RES_FAILED;
+
+ }
+ for (unsigned int i = 0; i<=TIME_INTERVAL_RANGE * 2; i++)
+ if (0 ==
+ GNUNET_memcmp (&challenge_response,
+ &as->valid_replies[i]))
+ return ANASTASIS_AUTHORIZATION_RES_FINISHED;
+ mime = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT);
+ if (NULL == mime)
+ mime = "text/plain";
+ lang = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ACCEPT_LANGUAGE);
+ if (NULL == lang)
+ lang = "en";
+
+ /* Build HTTP response */
+ {
+ struct MHD_Response *resp;
+ struct GNUNET_TIME_Absolute now;
+
+ now = GNUNET_TIME_absolute_get ();
+ (void) GNUNET_TIME_round_abs (&now);
+ if (TALER_MHD_xmime_matches (mime,
+ "application/json"))
+ {
+ resp = TALER_MHD_MAKE_JSON_PACK (
+ GNUNET_JSON_pack_uint64 ("code",
+ TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED),
+ GNUNET_JSON_pack_string ("hint",
+ TALER_ErrorCode_get_hint (
+ TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED)),
+ GNUNET_JSON_pack_time_abs ("server_time",
+ now));
+ }
+ else
+ {
+ size_t response_size;
+ char *response;
+
+ // FIXME: i18n of the message based on 'lang' ...
+ response_size
+ = GNUNET_asprintf (&response,
+ "Server time: %s",
+ GNUNET_STRINGS_absolute_time_to_string (now));
+ resp = MHD_create_response_from_buffer (response_size,
+ response,
+ MHD_RESPMEM_MUST_COPY);
+ TALER_MHD_add_global_headers (resp);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ MHD_HTTP_HEADER_CONTENT_TYPE,
+ "text/plain"));
+ }
+ mres = MHD_queue_response (connection,
+ MHD_HTTP_FORBIDDEN,
+ resp);
+ MHD_destroy_response (resp);
+ }
+ if (MHD_YES != mres)
+ return ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED;
+ return ANASTASIS_AUTHORIZATION_RES_FAILED;
+}
+
+
+/**
+ * Free internal state associated with @a as.
+ *
+ * @param as state to clean up
+ */
+static void
+totp_cleanup (struct ANASTASIS_AUTHORIZATION_State *as)
+{
+ GNUNET_free (as);
+}
+
+
+/**
+ * Initialize Totp based authorization plugin
+ *
+ * @param cls a configuration instance
+ * @return NULL on error, otherwise a `struct ANASTASIS_AuthorizationPlugin`
+ */
+void *
+libanastasis_plugin_authorization_totp_init (void *cls)
+{
+ const struct ANASTASIS_AuthorizationContext *ac = cls;
+ struct ANASTASIS_AuthorizationPlugin *plugin;
+
+ plugin = GNUNET_new (struct ANASTASIS_AuthorizationPlugin);
+ plugin->cls = (void *) ac;
+ plugin->user_provided_code = true;
+ plugin->retry_counter = INITIAL_RETRY_COUNTER;
+ plugin->code_validity_period = TOTP_VALIDITY_PERIOD;
+ plugin->code_rotation_period = plugin->code_validity_period;
+ plugin->code_retransmission_frequency = plugin->code_validity_period;
+ plugin->validate = &totp_validate;
+ plugin->start = &totp_start;
+ plugin->process = &totp_process;
+ plugin->cleanup = &totp_cleanup;
+ return plugin;
+}
+
+
+/**
+ * Unload authorization plugin
+ *
+ * @param cls a `struct ANASTASIS_AuthorizationPlugin`
+ * @return NULL (always)
+ */
+void *
+libanastasis_plugin_authorization_totp_done (void *cls)
+{
+ struct ANASTASIS_AuthorizationPlugin *plugin = cls;
+
+ GNUNET_free (plugin);
+ return NULL;
+}
diff --git a/src/authorization/iban.h b/src/authorization/iban.h
index 70db7ea..17836f4 100644
--- a/src/authorization/iban.h
+++ b/src/authorization/iban.h
@@ -3,7 +3,7 @@
Copyright (C) 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/backend/anastasis-httpd.c b/src/backend/anastasis-httpd.c
index 9f5c87b..ba5417b 100644
--- a/src/backend/anastasis-httpd.c
+++ b/src/backend/anastasis-httpd.c
@@ -295,7 +295,7 @@ url_handler (void *cls,
&TMH_MHD_handler_agpl_redirect, MHD_HTTP_FOUND },
{ "/terms", MHD_HTTP_METHOD_GET, NULL,
NULL, 0,
- &AH_handler_terms, MHD_HTTP_OK },
+ &AH_handler_privacy, MHD_HTTP_OK },
{ "/privacy", MHD_HTTP_METHOD_GET, NULL,
NULL, 0,
&AH_handler_terms, MHD_HTTP_OK },
@@ -389,6 +389,11 @@ url_handler (void *cls,
upload_data,
upload_data_size);
}
+ if (0 == strcmp (method,
+ MHD_HTTP_METHOD_OPTIONS))
+ {
+ return TALER_MHD_reply_cors_preflight (connection);
+ }
return TMH_MHD_handler_static_response (&h405,
connection);
}
@@ -429,6 +434,11 @@ url_handler (void *cls,
upload_data,
upload_data_size);
}
+ if (0 == strcmp (method,
+ MHD_HTTP_METHOD_OPTIONS))
+ {
+ return TALER_MHD_reply_cors_preflight (connection);
+ }
return TMH_MHD_handler_static_response (&h405,
connection);
}
diff --git a/src/backend/anastasis-httpd_config.c b/src/backend/anastasis-httpd_config.c
index d96d57e..19c1e7b 100644
--- a/src/backend/anastasis-httpd_config.c
+++ b/src/backend/anastasis-httpd_config.c
@@ -3,7 +3,7 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/backend/anastasis-httpd_policy_upload.c b/src/backend/anastasis-httpd_policy_upload.c
index c36cc17..0f9d8d6 100644
--- a/src/backend/anastasis-httpd_policy_upload.c
+++ b/src/backend/anastasis-httpd_policy_upload.c
@@ -323,11 +323,10 @@ proposal_cb (void *cls,
AH_trigger_daemon (NULL);
if (MHD_HTTP_OK != por->hr.http_status)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Backend returned status %u/%d\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Backend returned status %u/%d when trying to setup order\n",
por->hr.http_status,
(int) por->hr.ec);
- GNUNET_break (0);
puc->resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_uint64 ("code",
TALER_EC_SYNC_PAYMENT_CREATE_BACKEND_ERROR),
@@ -340,7 +339,7 @@ proposal_cb (void *cls,
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_object_incref ("backend-reply",
(json_t *) por->hr.reply)));
- puc->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ puc->response_code = MHD_HTTP_BAD_GATEWAY;
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
diff --git a/src/backend/anastasis-httpd_terms.c b/src/backend/anastasis-httpd_terms.c
index b4debe7..94a6380 100644
--- a/src/backend/anastasis-httpd_terms.c
+++ b/src/backend/anastasis-httpd_terms.c
@@ -3,7 +3,7 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -36,13 +36,6 @@ static struct TALER_MHD_Legal *tos;
static struct TALER_MHD_Legal *pp;
-/**
- * Manages a /terms call.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @return MHD result code
- */
MHD_RESULT
AH_handler_terms (struct AH_RequestHandler *rh,
struct MHD_Connection *connection)
@@ -53,15 +46,8 @@ AH_handler_terms (struct AH_RequestHandler *rh,
}
-/**
- * Handle a "/privacy" request.
- *
- * @param rh context of the handler
- * @param connection the MHD connection to handle
- * @return MHD result code
- */
MHD_RESULT
-AH_handler_privacy (const struct AH_RequestHandler *rh,
+AH_handler_privacy (struct AH_RequestHandler *rh,
struct MHD_Connection *connection)
{
(void) rh;
@@ -70,11 +56,6 @@ AH_handler_privacy (const struct AH_RequestHandler *rh,
}
-/**
- * Load our terms of service as per configuration.
- *
- * @param cfg configuration to process
- */
void
AH_load_terms (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
diff --git a/src/backend/anastasis-httpd_terms.h b/src/backend/anastasis-httpd_terms.h
index e34c86e..5043c57 100644
--- a/src/backend/anastasis-httpd_terms.h
+++ b/src/backend/anastasis-httpd_terms.h
@@ -45,7 +45,7 @@ AH_handler_terms (struct AH_RequestHandler *rh,
* @return MHD result code
*/
MHD_RESULT
-AH_handler_privacy (const struct AH_RequestHandler *rh,
+AH_handler_privacy (struct AH_RequestHandler *rh,
struct MHD_Connection *connection);
/**
diff --git a/src/backend/anastasis-httpd_truth.c b/src/backend/anastasis-httpd_truth.c
index 4dd3ddc..52d5dab 100644
--- a/src/backend/anastasis-httpd_truth.c
+++ b/src/backend/anastasis-httpd_truth.c
@@ -349,7 +349,7 @@ refund_cb (
void *cls,
const struct TALER_MERCHANT_HttpResponse *hr,
const char *taler_refund_uri,
- const struct GNUNET_HashCode *h_contract)
+ const struct TALER_PrivateContractHash *h_contract)
{
struct RefundEntry *re = cls;
@@ -882,6 +882,38 @@ return_key_share (
/**
+ * Mark @a gc as suspended and update the respective
+ * data structures and jobs.
+ *
+ * @param[in,out] gc context of the suspended operation
+ */
+static void
+gc_suspended (struct GetContext *gc)
+{
+ gc->suspended = true;
+ if (NULL == AH_to_heap)
+ AH_to_heap = GNUNET_CONTAINER_heap_create (
+ GNUNET_CONTAINER_HEAP_ORDER_MIN);
+ gc->hn = GNUNET_CONTAINER_heap_insert (AH_to_heap,
+ gc,
+ gc->timeout.abs_value_us);
+ if (NULL != to_task)
+ {
+ GNUNET_SCHEDULER_cancel (to_task);
+ to_task = NULL;
+ }
+ {
+ struct GetContext *rn;
+
+ rn = GNUNET_CONTAINER_heap_peek (AH_to_heap);
+ to_task = GNUNET_SCHEDULER_add_at (rn->timeout,
+ &do_timeout,
+ NULL);
+ }
+}
+
+
+/**
* Run the authorization method-specific 'process' function and continue
* based on its result with generating an HTTP response.
*
@@ -923,26 +955,7 @@ run_authorization_process (struct MHD_Connection *connection,
return MHD_YES;
case ANASTASIS_AUTHORIZATION_RES_SUSPENDED:
/* connection was suspended */
- gc->suspended = true;
- if (NULL == AH_to_heap)
- AH_to_heap = GNUNET_CONTAINER_heap_create (
- GNUNET_CONTAINER_HEAP_ORDER_MIN);
- gc->hn = GNUNET_CONTAINER_heap_insert (AH_to_heap,
- gc,
- gc->timeout.abs_value_us);
- if (NULL != to_task)
- {
- GNUNET_SCHEDULER_cancel (to_task);
- to_task = NULL;
- }
- {
- struct GetContext *rn;
-
- rn = GNUNET_CONTAINER_heap_peek (AH_to_heap);
- to_task = GNUNET_SCHEDULER_add_at (rn->timeout,
- &do_timeout,
- NULL);
- }
+ gc_suspended (gc);
return MHD_YES;
case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED:
/* Challenge sent successfully */
@@ -978,6 +991,212 @@ run_authorization_process (struct MHD_Connection *connection,
}
+/**
+ * Use the database to rate-limit queries to the
+ * authentication procedure, but without actually
+ * storing 'real' challenge codes.
+ *
+ * @param[in,out] gc context to rate limit requests for
+ * @return #GNUNET_OK if rate-limiting passes,
+ * #GNUNET_NO if a reply was sent (rate limited)
+ * #GNUNET_SYSERR if we failed and no reply
+ * was queued
+ */
+static enum GNUNET_GenericReturnValue
+rate_limit (struct GetContext *gc)
+{
+ enum GNUNET_DB_QueryStatus qs;
+ struct GNUNET_TIME_Absolute rt;
+ uint64_t code;
+ enum ANASTASIS_DB_CodeStatus cs;
+ struct GNUNET_HashCode hc;
+ bool satisfied;
+ uint64_t dummy;
+
+ rt = GNUNET_TIME_UNIT_FOREVER_ABS;
+ qs = db->create_challenge_code (db->cls,
+ &gc->truth_uuid,
+ MAX_QUESTION_FREQ,
+ GNUNET_TIME_UNIT_HOURS,
+ INITIAL_RETRY_COUNTER,
+ &rt,
+ &code);
+ if (0 > qs)
+ {
+ GNUNET_break (0 < qs);
+ return (MHD_YES ==
+ TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "create_challenge_code (for rate limiting)"))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ return (MHD_YES ==
+ TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_TOO_MANY_REQUESTS,
+ TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED,
+ NULL))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
+ }
+ /* decrement trial counter */
+ ANASTASIS_hash_answer (code + 1, /* always use wrong answer */
+ &hc);
+ cs = db->verify_challenge_code (db->cls,
+ &gc->truth_uuid,
+ &hc,
+ &dummy,
+ &satisfied);
+ switch (cs)
+ {
+ case ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH:
+ /* good, what we wanted */
+ return GNUNET_OK;
+ case ANASTASIS_DB_CODE_STATUS_HARD_ERROR:
+ case ANASTASIS_DB_CODE_STATUS_SOFT_ERROR:
+ GNUNET_break (0);
+ return (MHD_YES ==
+ TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ "verify_challenge_code"))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
+ case ANASTASIS_DB_CODE_STATUS_NO_RESULTS:
+ return (MHD_YES ==
+ TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_TOO_MANY_REQUESTS,
+ TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED,
+ NULL))
+ ? GNUNET_NO
+ : GNUNET_SYSERR;
+ case ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED:
+ /* this should be impossible, we used code+1 */
+ GNUNET_assert (0);
+ }
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Handle special case of a security question where we do not
+ * generate a code. Rate limits answers against brute forcing.
+ *
+ * @param[in,out] gc request to handle
+ * @param decrypted_truth hash to check against
+ * @param decrypted_truth_size number of bytes in @a decrypted_truth
+ * @return MHD status code
+ */
+static MHD_RESULT
+handle_security_question (struct GetContext *gc,
+ const void *decrypted_truth,
+ size_t decrypted_truth_size)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Handling security question challenge\n");
+ if (! gc->have_response)
+ {
+ return TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED,
+ NULL);
+ }
+ /* rate limit */
+ {
+ enum GNUNET_GenericReturnValue ret;
+
+ ret = rate_limit (gc);
+ if (GNUNET_OK != ret)
+ return (GNUNET_NO == ret) ? MHD_YES : MHD_NO;
+ }
+ /* check reply matches truth */
+ if ( (decrypted_truth_size != sizeof (struct GNUNET_HashCode)) ||
+ (0 != memcmp (&gc->challenge_response,
+ decrypted_truth,
+ decrypted_truth_size)) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Wrong answer provided to secure question had %u bytes, wanted %u\n",
+ (unsigned int) decrypted_truth_size,
+ (unsigned int) sizeof (struct GNUNET_HashCode));
+ return TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED,
+ NULL);
+ }
+ /* good, return the key share */
+ return return_key_share (&gc->truth_uuid,
+ gc->connection);
+}
+
+
+/**
+ * Handle special case of an answer being directly checked by the
+ * plugin and not by our database. Rate limits answers against brute
+ * forcing.
+ *
+ * @param[in,out] gc request to handle
+ * @param decrypted_truth hash to check against
+ * @param decrypted_truth_size number of bytes in @a decrypted_truth
+ * @return MHD status code
+ */
+static MHD_RESULT
+direct_validation (struct GetContext *gc,
+ const void *decrypted_truth,
+ size_t decrypted_truth_size)
+{
+ /* Non-random code, call plugin directly! */
+ enum ANASTASIS_AUTHORIZATION_Result aar;
+ enum GNUNET_GenericReturnValue res;
+
+ res = rate_limit (gc);
+ if (GNUNET_OK != res)
+ return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+ gc->as = gc->authorization->start (gc->authorization->cls,
+ &AH_trigger_daemon,
+ NULL,
+ &gc->truth_uuid,
+ 0LLU,
+ decrypted_truth,
+ decrypted_truth_size);
+ if (NULL == gc->as)
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (gc->connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_ANASTASIS_TRUTH_AUTHORIZATION_START_FAILED,
+ NULL);
+ }
+ aar = gc->authorization->process (gc->as,
+ GNUNET_TIME_UNIT_ZERO_ABS,
+ gc->connection);
+ switch (aar)
+ {
+ case ANASTASIS_AUTHORIZATION_RES_SUCCESS:
+ GNUNET_break (0);
+ return MHD_YES;
+ case ANASTASIS_AUTHORIZATION_RES_FAILED:
+ return MHD_YES;
+ case ANASTASIS_AUTHORIZATION_RES_SUSPENDED:
+ gc_suspended (gc);
+ return MHD_YES;
+ case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED:
+ GNUNET_break (0);
+ return MHD_NO;
+ case ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED:
+ return MHD_NO;
+ case ANASTASIS_AUTHORIZATION_RES_FINISHED:
+ return return_key_share (&gc->truth_uuid,
+ gc->connection);
+ }
+ GNUNET_break (0);
+ return MHD_NO;
+}
+
+
MHD_RESULT
AH_handler_truth_get (
struct MHD_Connection *connection,
@@ -1113,7 +1332,6 @@ AH_handler_truth_get (
GNUNET_TIME_UNIT_SECONDS);
}
}
-
} /* end of first-time initialization (if NULL == gc) */
else
{
@@ -1291,104 +1509,14 @@ AH_handler_truth_get (
but check that the hash matches */
if (is_question)
{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Handling security question challenge\n");
- if (! gc->have_response)
- {
- GNUNET_free (decrypted_truth);
- GNUNET_free (truth_mime);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_ANASTASIS_TRUTH_CHALLENGE_RESPONSE_REQUIRED,
- NULL);
- }
+ MHD_RESULT ret;
- {
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Absolute rt;
- uint64_t code;
- enum ANASTASIS_DB_CodeStatus cs;
- struct GNUNET_HashCode hc;
- bool satisfied;
- uint64_t dummy;
-
- rt = GNUNET_TIME_UNIT_FOREVER_ABS;
- qs = db->create_challenge_code (db->cls,
- &gc->truth_uuid,
- MAX_QUESTION_FREQ,
- GNUNET_TIME_UNIT_HOURS,
- INITIAL_RETRY_COUNTER,
- &rt,
- &code);
- if (0 > qs)
- {
- GNUNET_break (0 < qs);
- GNUNET_free (decrypted_truth);
- GNUNET_free (truth_mime);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "create_challenge_code (for rate limiting)");
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- GNUNET_free (decrypted_truth);
- GNUNET_free (truth_mime);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_TOO_MANY_REQUESTS,
- TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED,
- NULL);
- }
- /* decrement trial counter */
- ANASTASIS_hash_answer (code + 1, /* always use wrong answer */
- &hc);
- cs = db->verify_challenge_code (db->cls,
- &gc->truth_uuid,
- &hc,
- &dummy,
- &satisfied);
- switch (cs)
- {
- case ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH:
- /* good, what we wanted */
- break;
- case ANASTASIS_DB_CODE_STATUS_HARD_ERROR:
- case ANASTASIS_DB_CODE_STATUS_SOFT_ERROR:
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (gc->connection,
- MHD_HTTP_INTERNAL_SERVER_ERROR,
- TALER_EC_GENERIC_DB_FETCH_FAILED,
- "verify_challenge_code");
- case ANASTASIS_DB_CODE_STATUS_NO_RESULTS:
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_TOO_MANY_REQUESTS,
- TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED,
- NULL);
- case ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED:
- /* this should be impossible, we used code+1 */
- GNUNET_assert (0);
- }
- }
- if ( (decrypted_truth_size != sizeof (struct GNUNET_HashCode)) ||
- (0 != memcmp (&gc->challenge_response,
- decrypted_truth,
- decrypted_truth_size)) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Wrong answer provided to secure question had %u bytes, wanted %u\n",
- (unsigned int) decrypted_truth_size,
- (unsigned int) sizeof (struct GNUNET_HashCode));
- GNUNET_free (decrypted_truth);
- GNUNET_free (truth_mime);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_FORBIDDEN,
- TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED,
- NULL);
- }
- GNUNET_free (decrypted_truth);
+ ret = handle_security_question (gc,
+ decrypted_truth,
+ decrypted_truth_size);
GNUNET_free (truth_mime);
- return return_key_share (&gc->truth_uuid,
- connection);
+ GNUNET_free (decrypted_truth);
+ return ret;
}
/* Not security question, check for answer in DB */
@@ -1399,6 +1527,18 @@ AH_handler_truth_get (
uint64_t code;
GNUNET_free (truth_mime);
+ if (gc->authorization->user_provided_code)
+ {
+ MHD_RESULT res;
+
+ res = direct_validation (gc,
+ decrypted_truth,
+ decrypted_truth_size);
+ GNUNET_free (decrypted_truth);
+ return res;
+ }
+
+ /* random code, check against database */
cs = db->verify_challenge_code (db->cls,
&gc->truth_uuid,
&gc->challenge_response,
diff --git a/src/backend/anastasis-httpd_truth_upload.c b/src/backend/anastasis-httpd_truth_upload.c
index d9e63c3..e4bce9c 100644
--- a/src/backend/anastasis-httpd_truth_upload.c
+++ b/src/backend/anastasis-httpd_truth_upload.c
@@ -519,7 +519,7 @@ AH_handler_truth_post (
struct TruthUploadContext *tuc = hc->ctx;
MHD_RESULT ret;
int res;
- struct ANASTASIS_CRYPTO_EncryptedKeyShareP keyshare_data;
+ struct ANASTASIS_CRYPTO_EncryptedKeyShareP key_share_data;
void *encrypted_truth;
size_t encrypted_truth_size;
const char *truth_mime = NULL;
@@ -528,8 +528,8 @@ AH_handler_truth_post (
uint32_t storage_years;
struct GNUNET_TIME_Absolute paid_until;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("keyshare_data",
- &keyshare_data),
+ GNUNET_JSON_spec_fixed_auto ("key_share_data",
+ &key_share_data),
GNUNET_JSON_spec_string ("type",
&type),
GNUNET_JSON_spec_varsize ("encrypted_truth",
@@ -776,7 +776,7 @@ AH_handler_truth_post (
GNUNET_STRINGS_absolute_time_to_string (paid_until));
qs = db->store_truth (db->cls,
truth_uuid,
- &keyshare_data,
+ &key_share_data,
(NULL == truth_mime)
? ""
: truth_mime,
@@ -813,8 +813,8 @@ AH_handler_truth_post (
ok = ( (xtruth_size == encrypted_truth_size) &&
(0 == strcmp (xmethod,
type)) &&
- (0 == strcmp (truth_mime,
- xtruth_mime)) &&
+ (0 == strcmp (((NULL == truth_mime) ? "" : truth_mime),
+ ((NULL == xtruth_mime) ? "" : xtruth_mime))) &&
(0 == memcmp (xtruth,
encrypted_truth,
xtruth_size)) );
diff --git a/src/backend/anastasis.conf b/src/backend/anastasis.conf
index 8d2f0f6..ad85be2 100644
--- a/src/backend/anastasis.conf
+++ b/src/backend/anastasis.conf
@@ -53,14 +53,14 @@ FULFILLMENT_URL = taler://fulfillment-success
# Directory with our terms of service.
-TERMS_DIR = $DATADIR/tos/
+TERMS_DIR = ${DATADIR}tos/
# Etag / filename for the terms of service.
TERMS_ETAG = 0
# Directory with our privacy policy.
-PRIVACY_DIR = $DATADIR/pp/
+PRIVACY_DIR = ${DATADIR}pp/
# Etag / filename for the privacy policy.
PRIVACY_ETAG = 0
diff --git a/src/cli/anastasis-cli-redux.c b/src/cli/anastasis-cli-redux.c
index dc9c7ab..0e6e54b 100644
--- a/src/cli/anastasis-cli-redux.c
+++ b/src/cli/anastasis-cli-redux.c
@@ -146,6 +146,9 @@ action_cb (void *cls,
"Redux failed with error %d: %s\n",
error_code,
TALER_ErrorCode_get_hint (error_code));
+ json_dumpf (result_state,
+ stderr,
+ JSON_INDENT (2));
}
GNUNET_SCHEDULER_shutdown ();
global_ret = (TALER_EC_NONE != error_code) ? 1 : 0;
diff --git a/src/cli/test_anastasis_reducer_enter_secret.sh b/src/cli/test_anastasis_reducer_enter_secret.sh
index 8005f08..8fb8b60 100755
--- a/src/cli/test_anastasis_reducer_enter_secret.sh
+++ b/src/cli/test_anastasis_reducer_enter_secret.sh
@@ -8,6 +8,7 @@ BOLD="$(tput bold)"
NORM="$(tput sgr0)"
set -eu
+set -x
# Exit, with status code "skip" (no 'real' failure)
function exit_skip() {
@@ -309,7 +310,7 @@ FEES=`jq -r -e '.upload_fees[0].fee' < $UFILE`
# 4x 4.99 for annual fees, plus 4x0.01 for truth uploads
if test "$FEES" != "TESTKUDOS:20"
then
- jq -e . $TFILE
+ jq -e . $UFILE
exit_fail "Expected upload fees to be 'TESTKUDOS:20', got '$FEES'"
fi
@@ -326,13 +327,18 @@ then
exit_fail "Expected new state to be 'TRUTHS_PAYING', got '$STATE'"
fi
-TMETHOD=`jq -r -e '.policies[0].methods[0].truth.type' < $TFILE`
-if test $TMETHOD != "question"
-then
- exit_fail "Expected method to be >='question', got $TMETHOD"
-fi
+# FIXME: this test is specific to how the
+# C reducer stores state (redundantly!), should converge eventually!
+
+#TMETHOD=`jq -r -e '.policies[0].methods[0].truth.type' < $TFILE`
+#if test $TMETHOD != "question"
+#then
+# exit_fail "Expected method to be >='question', got $TMETHOD"
+#fi
+#
+#echo " OK"
+
-echo " OK"
#Pay
echo -en $COLOR$BOLD"Withdrawing amount to wallet ..."$NORM$NOCOLOR
diff --git a/src/cli/test_iban.sh b/src/cli/test_iban.sh
index cb31f6a..923256b 100755
--- a/src/cli/test_iban.sh
+++ b/src/cli/test_iban.sh
@@ -1,6 +1,7 @@
#!/bin/bash
set -eu
+set -x
# Exit, with status code "skip" (no 'real' failure)
function exit_skip() {
@@ -46,8 +47,7 @@ function prepare_sandbox_account() {
--account-name=$4 \
--ebics-user-id=$1 \
--ebics-host-id=$EBICS_HOST \
- --ebics-partner-id=$2 \
- --currency=$CURRENCY
+ --ebics-partner-id=$2
echo " OK"
}
@@ -160,7 +160,7 @@ fi
echo " OK"
echo -n "Starting Sandbox ..."
-libeufin-sandbox serve &> sandbox.log &
+libeufin-sandbox serve --no-auth &> sandbox.log &
sandbox_pid=$!
if ! curl -s --retry 5 --retry-connrefused $SANDBOX_URL > /dev/null; then
exit_skip "Could not launch Sandbox"
@@ -207,15 +207,6 @@ echo " OK"
export LIBEUFIN_NEXUS_USERNAME=$DEBIT_USERNAME
export LIBEUFIN_NEXUS_PASSWORD=$DEBIT_PASSWORD
-# FIXME: this command below likely not needed. Please
-# remove, run the test, and commit+push if it still works!
-prepare_nexus_account \
- ebicsuserDebit \
- ebicspartnerDebit \
- bankconnection-debit \
- nexus-bankaccount-debit \
- sandbox-account-debit
-
# Make credit user, will be Anastasis client.
CREDIT_USERNAME=anastasis-credit-user
CREDIT_PASSWORD=anastasis-credit-password
diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index a950172..c7ab630 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -291,7 +291,7 @@ typedef void
* @param af_cls closure for @a af
* @return #GNUNET_OK if the challenge was successfully started
*/
-int
+enum GNUNET_GenericReturnValue
ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
const struct ANASTASIS_PaymentSecretP *psp,
struct GNUNET_TIME_Relative timeout,
@@ -314,7 +314,7 @@ ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
* @param af_cls closure for @a af
* @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
ANASTASIS_challenge_answer (struct ANASTASIS_Challenge *c,
const struct ANASTASIS_PaymentSecretP *psp,
struct GNUNET_TIME_Relative timeout,
@@ -337,7 +337,7 @@ ANASTASIS_challenge_answer (struct ANASTASIS_Challenge *c,
* @param af_cls closure for @a af
* @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
ANASTASIS_challenge_answer2 (struct ANASTASIS_Challenge *c,
const struct ANASTASIS_PaymentSecretP *psp,
struct GNUNET_TIME_Relative timeout,
diff --git a/src/include/anastasis_authorization_lib.h b/src/include/anastasis_authorization_lib.h
index 975dd5f..bcbd2e6 100644
--- a/src/include/anastasis_authorization_lib.h
+++ b/src/include/anastasis_authorization_lib.h
@@ -3,7 +3,7 @@
Copyright (C) 2019, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/include/anastasis_authorization_plugin.h b/src/include/anastasis_authorization_plugin.h
index 91a88f8..10b99f3 100644
--- a/src/include/anastasis_authorization_plugin.h
+++ b/src/include/anastasis_authorization_plugin.h
@@ -3,7 +3,7 @@
Copyright (C) 2019 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -127,6 +127,14 @@ struct ANASTASIS_AuthorizationPlugin
bool payment_plugin_managed;
/**
+ * The plugin expects the "code" in the "start" function to be
+ * provided by the user and not generated by the Anastasis
+ * backend. The plugin will then validate the code using its own
+ * means. Used by TOTP.
+ */
+ bool user_provided_code;
+
+ /**
* How often are retries allowed for challenges created
* by this plugin?
*/
diff --git a/src/include/anastasis_crypto_lib.h b/src/include/anastasis_crypto_lib.h
index 6377baf..780fb34 100644
--- a/src/include/anastasis_crypto_lib.h
+++ b/src/include/anastasis_crypto_lib.h
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -133,34 +133,25 @@ struct ANASTASIS_CRYPTO_PolicyKeyP
/**
- * Specifies an encrypted master key, the key is used to encrypt the core secret from the user
- */
-struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
-{
- struct GNUNET_HashCode key GNUNET_PACKED;
-};
-
-
-/**
- * Specifies a Nonce used for the AES encryption, here defined as 32Byte large.
+ * Nonce used for encryption, 24 bytes.
*/
struct ANASTASIS_CRYPTO_NonceP
{
- uint32_t nonce[8];
+ uint8_t nonce[crypto_secretbox_NONCEBYTES];
};
/**
- * Specifies an IV used for the AES encryption, here defined as 16Byte large.
+ * Header that is prepended to a ciphertext, consisting of nonce and MAC.
*/
-struct ANASTASIS_CRYPTO_IvP
+struct ANASTASIS_CRYPTO_CiphertextHeaderP
{
- uint32_t iv[4];
+ uint8_t header[crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES];
};
/**
- * Specifies an symmetric key used for the AES encryption, here defined as 32Byte large.
+ * Specifies a key used for symmetric encryption, 32 bytes.
*/
struct ANASTASIS_CRYPTO_SymKeyP
{
@@ -169,15 +160,6 @@ struct ANASTASIS_CRYPTO_SymKeyP
/**
- * Specifies an AES Tag used for the AES authentication, here defined as 16 Byte large.
- */
-struct ANASTASIS_CRYPTO_AesTagP
-{
- uint32_t aes_tag[4];
-};
-
-
-/**
* Specifies a Key Share from an escrow provider, the combined
* keyshares generate the EscrowMasterKey which is used to decrypt the
* Secret from the user.
@@ -194,17 +176,12 @@ struct ANASTASIS_CRYPTO_KeyShareP
struct ANASTASIS_CRYPTO_EncryptedKeyShareP
{
/**
- * Nonce used for the symmetric encryption.
- */
- struct ANASTASIS_CRYPTO_NonceP nonce;
-
- /**
- * GCM tag to check authenticity.
+ * Ciphertext.
*/
- struct ANASTASIS_CRYPTO_AesTagP tag;
+ struct ANASTASIS_CRYPTO_CiphertextHeaderP header;
/**
- * The actual key share.
+ * The actual key share, encrypted.
*/
struct ANASTASIS_CRYPTO_KeyShareP keyshare;
};
@@ -271,6 +248,33 @@ struct ANASTASIS_AccountSignatureP
GNUNET_NETWORK_STRUCT_END
+/**
+ * Result of encrypting the core secret.
+ */
+struct ANASTASIS_CoreSecretEncryptionResult
+{
+ /**
+ * Encrypted core secret.
+ */
+ void *enc_core_secret;
+
+ /**
+ * Size of the encrypted core secret.
+ */
+ size_t enc_core_secret_size;
+
+ /**
+ * Array of encrypted master keys. Each key is encrypted
+ * to a different policy key.
+ */
+ void **enc_master_keys;
+
+ /**
+ * Sizes of the encrypted master keys.
+ */
+ size_t *enc_master_key_sizes;
+};
+
/**
* Hash a numerical answer to compute the hash value to be submitted
@@ -344,7 +348,7 @@ ANASTASIS_CRYPTO_secure_answer_hash (
/**
- * Encrypt and signs the recovery document with AES256, the recovery
+ * Encrypt and signs the recovery document, the recovery
* document is encrypted with a derivation from the user identifier
* and the salt "erd".
*
@@ -365,7 +369,7 @@ ANASTASIS_CRYPTO_recovery_document_encrypt (
/**
- * Decrypts the recovery document with AES256, the decryption key is generated with
+ * Decrypts the recovery document, the decryption key is generated with
* the user identifier provided by the user and the salt "erd". The nonce and IV used for the encryption
* are the first 48 bytes of the data.
*
@@ -419,7 +423,7 @@ ANASTASIS_CRYPTO_keyshare_decrypt (
/**
* Encrypts the truth data which contains the hashed answer or the
- * phone number. It is encrypted with AES256, the key is generated
+ * phone number. It is encrypted with xsalsa20-poly1305, the key is generated
* with the user identification as entropy source and the salt "ect".
*
* @param nonce value to use for the nonce
@@ -442,7 +446,7 @@ ANASTASIS_CRYPTO_truth_encrypt (
/**
* Decrypts the truth data which contains the hashed answer or the phone number..
- * It is decrypted with AES256, the key is generated with the user identification as
+ * It is decrypted with xsalsa20-poly1305, the key is generated with the user identification as
* entropy source and the salt "ect".
*
* @param truth_enc_key master key used for encryption of the truth (see interface EscrowMethod)
@@ -492,24 +496,30 @@ ANASTASIS_CRYPTO_policy_key_derive (
* The core secret is the user provided secret which will be saved with Anastasis.
* The secret will be encrypted with the master key, the master key is a random key which will
* be generated. The master key afterwards will be encrypted with the different policy keys.
- * Encryption is performed with AES256
+ * Encryption is performed with xsalsa20-poly1305.
*
* @param policy_keys an array of policy keys which are used to encrypt the master key
* @param policy_keys_length defines the amount of policy keys and also the amount of encrypted master keys
* @param core_secret the user provided core secret which is secured by anastasis
* @param core_secret_size the size of the core secret
- * @param[out] enc_core_secret the core secret is encrypted with the generated master key
- * @param[out] encrypted_master_keys array of encrypted master keys which will be safed inside the policies one encrypted
- * master key is created for each policy key
+ * @returns result of the encryption, must be freed with #ANASTASIS_CRYPTO_destroy_encrypted_core_secret
*/
-void
+struct ANASTASIS_CoreSecretEncryptionResult *
ANASTASIS_CRYPTO_core_secret_encrypt (
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys,
unsigned int policy_keys_length,
const void *core_secret,
- size_t core_secret_size,
- void **enc_core_secret,
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_keys);
+ size_t core_secret_size);
+
+
+/**
+ * Destroy a core secret encryption result.
+ *
+ * @param cser the result to destroy
+ */
+void
+ANASTASIS_CRYPTO_destroy_encrypted_core_secret (
+ struct ANASTASIS_CoreSecretEncryptionResult *cser);
/**
@@ -517,6 +527,7 @@ ANASTASIS_CRYPTO_core_secret_encrypt (
* Afterwards the core secret is encrypted with the master key. The core secret is returned.
*
* @param encrypted_master_key master key for decrypting the core secret, is itself encrypted by the policy key
+ * @param encrypted_master_key_size size of the encrypted master key
* @param policy_key built policy key which will decrypt the master key
* @param encrypted_core_secret the encrypted core secret from the user, will be encrypted with the policy key
* @param encrypted_core_secret_size size of the encrypted core secret
@@ -525,9 +536,23 @@ ANASTASIS_CRYPTO_core_secret_encrypt (
*/
void
ANASTASIS_CRYPTO_core_secret_recover (
- const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key,
+ const void *encrypted_master_key,
+ size_t encrypted_master_key_size,
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key,
const void *encrypted_core_secret,
size_t encrypted_core_secret_size,
void **core_secret,
size_t *core_secret_size);
+
+
+/**
+ * Convert a @a uuid to a shortened, human-readable string
+ * useful to show to users to identify the truth.
+ * Note that the return value is in a global variable and
+ * only valid until the next invocation of this function.
+ *
+ * @param uuid UUID to convert
+ * @return string representation
+ */
+const char *
+ANASTASIS_CRYPTO_uuid2s (const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid);
diff --git a/src/include/anastasis_database_lib.h b/src/include/anastasis_database_lib.h
index 7de1612..896b039 100644
--- a/src/include/anastasis_database_lib.h
+++ b/src/include/anastasis_database_lib.h
@@ -3,7 +3,7 @@
Copyright (C) 2019 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/include/anastasis_database_plugin.h b/src/include/anastasis_database_plugin.h
index 7bf91a2..b698103 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -3,7 +3,7 @@
Copyright (C) 2019-2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -633,7 +633,7 @@ struct ANASTASIS_DatabasePlugin
(*mark_challenge_code_satisfied)(
void *cls,
const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid,
- const uint64_t code);
+ uint64_t code);
/**
diff --git a/src/include/anastasis_redux.h b/src/include/anastasis_redux.h
index dd28174..39ed021 100644
--- a/src/include/anastasis_redux.h
+++ b/src/include/anastasis_redux.h
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index bec89d1..d6d7d4c 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -3,14 +3,14 @@
Copyright (C) 2019-2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.LIB. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/include/anastasis_testing_lib.h b/src/include/anastasis_testing_lib.h
index a6c1fba..ba1b8a3 100644
--- a/src/include/anastasis_testing_lib.h
+++ b/src/include/anastasis_testing_lib.h
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -32,231 +32,125 @@
#define ANASTASIS_FAIL() \
do {GNUNET_break (0); return NULL; } while (0)
-/**
- * Index used in #ANASTASIS_TESTING_get_trait_hash() for the current hash.
- */
-#define ANASTASIS_TESTING_TRAIT_HASH_CURRENT 0
-
-/**
- * Obtain a hash from @a cmd.
- *
- * @param cmd command to extract the number from.
- * @param index the number's index number, use #ANASTASIS_TESTING_TRAIT_HASH_CURRENT
- * @param[out] h set to the hash coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_hash (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct GNUNET_HashCode **h);
-
-
-/**
- * Offer a hash.
- *
- * @param index the number's index number.
- * @param h the hash to offer.
- * @return trait on success.
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_hash (unsigned int index,
- const struct GNUNET_HashCode *h);
-
-
-/**
- * Obtain a truth decryption key from @a cmd.
- *
- * @param cmd command to extract the public key from.
- * @param index usually 0
- * @param[out] key set to the account public key used in @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_truth_key (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthKeyP **key);
-
-
-/**
- * Offer an truth decryption key.
- *
- * @param index usually zero
- * @param h the account_pub to offer.
- * @return trait on success.
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_truth_key (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthKeyP *h);
-
-
-/**
- * Obtain an account public key from @a cmd.
- *
- * @param cmd command to extract the public key from.
- * @param index usually 0
- * @param[out] pub set to the account public key used in @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_account_pub (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPublicKeyP **pub);
-
-
-/**
- * Offer an account public key.
- *
- * @param index usually zero
- * @param h the account_pub to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_account_pub (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPublicKeyP *h);
-
-
-/**
- * Obtain an account private key from @a cmd.
- *
- * @param cmd command to extract the number from.
- * @param index must be 0
- * @param[out] priv set to the account private key used in @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_account_priv (
- const struct
- TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPrivateKeyP **priv);
-
-
-/**
- * Offer an account private key.
- *
- * @param index usually zero
- * @param priv the account_priv to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_account_priv (
- unsigned int index,
- const struct
- ANASTASIS_CRYPTO_AccountPrivateKeyP *priv);
-
-/**
- * Obtain an account public key from @a cmd.
- *
- * @param cmd command to extract the payment identifier from.
- * @param index the payment identifier's index number.
- * @param[out] payment_secret set to the payment secret coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_payment_secret (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_PaymentSecretP **payment_secret);
-
-
-/**
- * Offer a payment secret.
- *
- * @param index usually zero
- * @param h the payment secret to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_payment_secret (
- unsigned int index,
- const struct ANASTASIS_PaymentSecretP *h);
-
-
-/**
- * Obtain an truth UUID from @a cmd.
- *
- * @param cmd command to extract the number from.
- * @param index the number's index number.
- * @param[out] tpk set to the number coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_truth_uuid (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthUUIDP **tpk);
-
/**
- * Offer a truth UUID.
- *
- * @param index the number's index number.
- * @param tpk the UUID to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_truth_uuid (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthUUIDP *tpk);
-
-
-/**
- * Obtain an encrypted key share from @a cmd.
- *
- * @param cmd command to extract the number from.
- * @param index the number's index number.
- * @param[out] eks set to the key share coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_eks (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_EncryptedKeyShareP **eks);
+ * Create headers for a trait with name @a name for
+ * statically allocated data of type @a type.
+ */
+#define ANASTASIS_TESTING_MAKE_DECL_SIMPLE_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ ANASTASIS_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ type **ret); \
+ struct TALER_TESTING_Trait \
+ ANASTASIS_TESTING_make_trait_ ## name ( \
+ type * value);
+
+
+/**
+ * Create C implementation for a trait with name @a name for statically
+ * allocated data of type @a type.
+ */
+#define ANASTASIS_TESTING_MAKE_IMPL_SIMPLE_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ ANASTASIS_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ type **ret) \
+ { \
+ if (NULL == cmd->traits) return GNUNET_SYSERR; \
+ return cmd->traits (cmd->cls, \
+ (const void **) ret, \
+ TALER_S (name), \
+ 0); \
+ } \
+ struct TALER_TESTING_Trait \
+ ANASTASIS_TESTING_make_trait_ ## name ( \
+ type * value) \
+ { \
+ struct TALER_TESTING_Trait ret = { \
+ .trait_name = TALER_S (name), \
+ .ptr = (const void *) value \
+ }; \
+ return ret; \
+ }
/**
- * Offer an encrypted key share.
- *
- * @param index the number's index number.
- * @param eks the encrypted key share to offer.
- * @return trait on success
+ * Create headers for a trait with name @a name for
+ * statically allocated data of type @a type.
*/
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_eks (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *eks);
+#define ANASTASIS_TESTING_MAKE_DECL_INDEXED_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ ANASTASIS_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ unsigned int index, \
+ type **ret); \
+ struct TALER_TESTING_Trait \
+ ANASTASIS_TESTING_make_trait_ ## name ( \
+ unsigned int index, \
+ type * value);
/**
- * Obtain a code from @a cmd.
- *
- * @param cmd command to extract the number from.
- * @param index the number's index number.
- * @param[out] code set to the number coming from @a cmd.
- * @return #GNUNET_OK on success.
+ * Create C implementation for a trait with name @a name for statically
+ * allocated data of type @a type.
*/
-int
-ANASTASIS_TESTING_get_trait_code (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const char **code);
+#define ANASTASIS_TESTING_MAKE_IMPL_INDEXED_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ ANASTASIS_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ unsigned int index, \
+ type **ret) \
+ { \
+ if (NULL == cmd->traits) return GNUNET_SYSERR; \
+ return cmd->traits (cmd->cls, \
+ (const void **) ret, \
+ TALER_S (name), \
+ index); \
+ } \
+ struct TALER_TESTING_Trait \
+ ANASTASIS_TESTING_make_trait_ ## name ( \
+ unsigned int index, \
+ type * value) \
+ { \
+ struct TALER_TESTING_Trait ret = { \
+ .index = index, \
+ .trait_name = TALER_S (name), \
+ .ptr = (const void *) value \
+ }; \
+ return ret; \
+ }
/**
- * Offer an authentication code.
- *
- * @param index the number's index number.
- * @param code the code to offer.
- * @return trait on success
+ * Call #op on all simple traits.
*/
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_code (unsigned int index,
- const char *code);
+#define ANASTASIS_TESTING_SIMPLE_TRAITS(op) \
+ op (hash, const struct GNUNET_HashCode) \
+ op (truth, const struct ANASTASIS_Truth *) \
+ op (policy, const struct ANASTASIS_Policy *) \
+ op (salt, const struct ANASTASIS_CRYPTO_ProviderSaltP) \
+ op (core_secret, const void *) \
+ op (truth_key, const struct ANASTASIS_CRYPTO_TruthKeyP) \
+ op (account_pub, const struct ANASTASIS_CRYPTO_AccountPublicKeyP) \
+ op (account_priv, const struct ANASTASIS_CRYPTO_AccountPrivateKeyP) \
+ op (payment_secret, const struct ANASTASIS_PaymentSecretP) \
+ op (truth_uuid, const struct ANASTASIS_CRYPTO_TruthUUIDP) \
+ op (eks, const struct ANASTASIS_CRYPTO_EncryptedKeyShareP) \
+ op (code, const char *) \
+ op (filename, const char *)
+
+
+/**
+ * Call #op on all indexed traits.
+ */
+#define ANASTASIS_TESTING_INDEXED_TRAITS(op) \
+ op (challenges, const struct ANASTASIS_Challenge *)
+
+
+ANASTASIS_TESTING_SIMPLE_TRAITS (ANASTASIS_TESTING_MAKE_DECL_SIMPLE_TRAIT)
+
+ANASTASIS_TESTING_INDEXED_TRAITS (ANASTASIS_TESTING_MAKE_DECL_INDEXED_TRAIT)
/**
@@ -505,34 +399,6 @@ ANASTASIS_TESTING_cmd_keyshare_lookup (
/**
- * Obtain a salt from @a cmd.
- *
- * @param cmd command to extract the salt from.
- * @param index the salt's index number.
- * @param[out] s set to the salt coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_salt (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_ProviderSaltP **s);
-
-
-/**
- * Offer an salt.
- *
- * @param index the salt's index number.
- * @param s the salt to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_salt (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_ProviderSaltP *s);
-
-
-/**
* Make the "/config" command.
*
* @param label command label
@@ -549,31 +415,6 @@ ANASTASIS_TESTING_cmd_config (const char *label,
/* ********************* test truth upload ********************* */
/**
- * Obtain a truth from @a cmd.
- *
- * @param cmd command to extract the truth from.
- * @param index the index of the truth
- * @param[out] t set to the truth coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_truth (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_Truth **t);
-
-
-/**
- * Offer a truth.
- *
- * @param index the truth's index number.
- * @param t the truth to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_truth (unsigned int index,
- const struct ANASTASIS_Truth *t);
-
-/**
* Creates a sample of id_data.
*
* @param id_data some sample data (e.g. AHV, name, surname, ...)
@@ -642,31 +483,6 @@ ANASTASIS_TESTING_cmd_truth_upload_question (
/* ********************* test policy create ********************* */
-/**
- * Obtain a policy from @a cmd.
- *
- * @param cmd command to extract the policy from.
- * @param index the index of the policy
- * @param[out] p set to the policy coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_policy (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_Policy **p);
-
-
-/**
- * Offer a policy.
- *
- * @param index the policy's index number.
- * @param p the policy to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_policy (unsigned int index,
- const struct ANASTASIS_Policy *p);
-
/**
* Make the "policy create" command.
@@ -682,31 +498,6 @@ ANASTASIS_TESTING_cmd_policy_create (const char *label,
/* ********************* test secret share ********************* */
-/**
- * Obtain the core secret from @a cmd.
- *
- * @param cmd command to extract the core secret from.
- * @param index the index of the core secret (usually 0)
- * @param[out] s set to the core secret coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_core_secret (const struct
- TALER_TESTING_Command *cmd,
- unsigned int index,
- const void **s);
-
-
-/**
- * Offer the core secret.
- *
- * @param index the core secret's index number (usually 0).
- * @param s the core secret to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_core_secret (unsigned int index,
- const void *s);
/**
* Types of options for performing the secret sharing. Used as a bitmask.
@@ -824,30 +615,6 @@ ANASTASIS_TESTING_cmd_recover_secret_finish (
/* ********************* test challenge answer ********************* */
-/**
- * Obtain a challenge from @a cmd.
- *
- * @param cmd command to extract the challenge from.
- * @param index the index of the challenge
- * @param[out] c set to the challenge coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-ANASTASIS_TESTING_get_trait_challenge (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_Challenge **c);
-
-/**
- * Offer a challenge.
- *
- * @param index the challenge index number.
- * @param r the challenge to offer.
- * @return trait on success
- */
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_challenge (unsigned int index,
- const struct ANASTASIS_Challenge *r);
-
/**
* Create a "challenge start" command. Suitable for the "file"
diff --git a/src/include/anastasis_util_lib.h b/src/include/anastasis_util_lib.h
index e780d82..07b021b 100644
--- a/src/include/anastasis_util_lib.h
+++ b/src/include/anastasis_util_lib.h
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/lib/anastasis_backup.c b/src/lib/anastasis_backup.c
index 6747d73..c9273d0 100644
--- a/src/lib/anastasis_backup.c
+++ b/src/lib/anastasis_backup.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -651,7 +651,7 @@ policy_store_cb (void *cls,
.ss = ANASTASIS_SHARE_STATUS_PROVIDER_FAILED,
.details.provider_failure.provider_url = pss->anastasis_url,
.details.provider_failure.http_status = ud->http_status,
- .details.provider_failure.ec = us,
+ .details.provider_failure.ec = ud->ec,
};
ss->src (ss->src_cls,
@@ -729,9 +729,7 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
size_t core_secret_size)
{
struct ANASTASIS_SecretShare *ss;
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
- encrypted_master_keys[GNUNET_NZL (policies_len)];
- void *encrypted_core_secret;
+ struct ANASTASIS_CoreSecretEncryptionResult *cser;
json_t *dec_policies;
json_t *esc_methods;
size_t recovery_document_size;
@@ -755,12 +753,10 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
for (unsigned int i = 0; i < policies_len; i++)
policy_keys[i] = policies[i]->policy_key;
- ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
- policies_len,
- core_secret,
- core_secret_size,
- &encrypted_core_secret,
- encrypted_master_keys);
+ cser = ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
+ policies_len,
+ core_secret,
+ core_secret_size);
}
dec_policies = json_array ();
GNUNET_assert (NULL != dec_policies);
@@ -780,8 +776,10 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
json_array_append_new (
dec_policies,
GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("master_key",
- &encrypted_master_keys[k]),
+ GNUNET_JSON_pack_data_varsize ("master_key",
+ cser->enc_master_keys[k],
+ cser->enc_master_key_sizes
+ [k]),
GNUNET_JSON_pack_array_steal ("uuids",
uuids),
GNUNET_JSON_pack_data_auto ("salt",
@@ -828,7 +826,7 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
pt->instructions),
GNUNET_JSON_pack_data_auto ("truth_key",
&pt->truth_key),
- GNUNET_JSON_pack_data_auto ("salt",
+ GNUNET_JSON_pack_data_auto ("truth_salt",
&pt->salt),
GNUNET_JSON_pack_data_auto ("provider_salt",
&pt->provider_salt),
@@ -855,10 +853,11 @@ ANASTASIS_secret_share (struct GNUNET_CURL_Context *ctx,
GNUNET_JSON_pack_array_steal ("escrow_methods",
esc_methods),
GNUNET_JSON_pack_data_varsize ("encrypted_core_secret",
- encrypted_core_secret,
- core_secret_size));
+ cser->enc_core_secret,
+ cser->enc_core_secret_size));
GNUNET_assert (NULL != recovery_document);
- GNUNET_free (encrypted_core_secret);
+ ANASTASIS_CRYPTO_destroy_encrypted_core_secret (cser);
+ cser = NULL;
rd_str = json_dumps (recovery_document,
JSON_COMPACT | JSON_SORT_KEYS);
diff --git a/src/lib/anastasis_recovery.c b/src/lib/anastasis_recovery.c
index ac10418..528bbd1 100644
--- a/src/lib/anastasis_recovery.c
+++ b/src/lib/anastasis_recovery.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -118,9 +118,14 @@ struct DecryptionPolicy
struct ANASTASIS_DecryptionPolicy pub_details;
/**
- * Encrypted masterkey (encrypted with the policy key).
+ * Encrypted master key (encrypted with the policy key).
*/
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP emk;
+ void *emk;
+
+ /**
+ * Size of the encrypted master key.
+ */
+ size_t emk_size;
/**
* Salt used to decrypt master key.
@@ -439,7 +444,10 @@ keyshare_lookup_cb (void *cls,
rdps->pub_details.challenges_length,
&rdps->salt,
&policy_key);
- ANASTASIS_CRYPTO_core_secret_recover (&rdps->emk,
+ GNUNET_assert (NULL != rdps->emk);
+ GNUNET_assert (rdps->emk_size > 0);
+ ANASTASIS_CRYPTO_core_secret_recover (rdps->emk,
+ rdps->emk_size,
&policy_key,
recovery->enc_core_secret,
recovery->enc_core_secret_size,
@@ -462,7 +470,7 @@ ANASTASIS_challenge_get_details (struct ANASTASIS_Challenge *challenge)
}
-int
+enum GNUNET_GenericReturnValue
ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
const struct ANASTASIS_PaymentSecretP *psp,
struct GNUNET_TIME_Relative timeout,
@@ -500,7 +508,7 @@ ANASTASIS_challenge_start (struct ANASTASIS_Challenge *c,
}
-int
+enum GNUNET_GenericReturnValue
ANASTASIS_challenge_answer (
struct ANASTASIS_Challenge *c,
const struct ANASTASIS_PaymentSecretP *psp,
@@ -526,7 +534,7 @@ ANASTASIS_challenge_answer (
}
-int
+enum GNUNET_GenericReturnValue
ANASTASIS_challenge_answer2 (struct ANASTASIS_Challenge *c,
const struct ANASTASIS_PaymentSecretP *psp,
struct GNUNET_TIME_Relative timeout,
@@ -783,7 +791,7 @@ policy_lookup_cb (void *cls,
&instructions),
GNUNET_JSON_spec_fixed_auto ("truth_key",
&cs->truth_key),
- GNUNET_JSON_spec_fixed_auto ("salt",
+ GNUNET_JSON_spec_fixed_auto ("truth_salt",
&cs->salt),
GNUNET_JSON_spec_fixed_auto ("provider_salt",
&cs->provider_salt),
@@ -822,12 +830,14 @@ policy_lookup_cb (void *cls,
for (unsigned int j = 0; j < r->ri.dps_len; j++)
{
struct DecryptionPolicy *dp = &r->dps[j];
+
json_t *uuids = NULL;
json_t *uuid;
size_t n_index;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("master_key",
- &dp->emk),
+ GNUNET_JSON_spec_varsize ("master_key",
+ &dp->emk,
+ &dp->emk_size),
GNUNET_JSON_spec_fixed_auto ("salt",
&dp->salt),
GNUNET_JSON_spec_json ("uuids",
@@ -854,6 +864,9 @@ policy_lookup_cb (void *cls,
return;
}
+ GNUNET_assert (NULL != dp->emk);
+ GNUNET_assert (dp->emk_size > 0);
+
dp->pub_details.challenges_length = json_array_size (uuids);
dp->pub_details.challenges
= GNUNET_new_array (dp->pub_details.challenges_length,
@@ -997,9 +1010,11 @@ ANASTASIS_recovery_serialize (const struct ANASTASIS_Recovery *r)
json_array_append_new (c_arr,
cs));
}
+ GNUNET_assert (NULL != dp->emk);
dps = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("emk",
- &dp->emk),
+ GNUNET_JSON_pack_data_varsize ("emk",
+ dp->emk,
+ dp->emk_size),
GNUNET_JSON_pack_data_auto ("salt",
&dp->salt),
GNUNET_JSON_pack_array_steal ("challenges",
@@ -1187,8 +1202,9 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
struct DecryptionPolicy *dp = &r->dps[n_index];
json_t *challenges;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("emk",
- &dp->emk),
+ GNUNET_JSON_spec_varsize ("emk",
+ &dp->emk,
+ &dp->emk_size),
GNUNET_JSON_spec_fixed_auto ("salt",
&dp->salt),
GNUNET_JSON_spec_json ("challenges",
@@ -1213,6 +1229,8 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
JSON_INDENT (2));
return GNUNET_SYSERR;
}
+ GNUNET_assert (NULL != dp->emk);
+ GNUNET_assert (dp->emk_size > 0);
if (! json_is_array (challenges))
{
GNUNET_break_op (0);
@@ -1263,7 +1281,8 @@ parse_dps_array (struct ANASTASIS_Recovery *r,
}
}
}
- GNUNET_JSON_parse_free (spec);
+ /* We don't free the spec, since we're still using dp->ems. */
+ json_decref (challenges);
}
return GNUNET_OK;
}
@@ -1428,11 +1447,14 @@ ANASTASIS_recovery_abort (struct ANASTASIS_Recovery *r)
}
GNUNET_free (r->solved_challenges);
for (unsigned int j = 0; j < r->ri.dps_len; j++)
+ {
GNUNET_free (r->dps[j].pub_details.challenges);
+ GNUNET_free (r->dps[j].emk);
+ }
GNUNET_free (r->ri.dps);
for (unsigned int i = 0; i < r->ri.cs_len; i++)
{
- struct ANASTASIS_Challenge *cs = r->ri.cs[i];
+ struct ANASTASIS_Challenge *cs = &r->cs[i];
if (NULL != cs->kslo)
{
diff --git a/src/reducer/Makefile.am b/src/reducer/Makefile.am
index 5cbe6f7..3b7edb6 100644
--- a/src/reducer/Makefile.am
+++ b/src/reducer/Makefile.am
@@ -22,6 +22,7 @@ libanastasisredux_la_SOURCES = \
validation_CZ_BN.c \
validation_DE_SVN.c \
validation_DE_TIN.c \
+ validation_ES_DNI.c \
validation_IN_AADHAR.c \
validation_IT_CF.c \
validation_XX_SQUARE.c \
diff --git a/src/reducer/anastasis_api_backup_redux.c b/src/reducer/anastasis_api_backup_redux.c
index cfef852..fab5230 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -131,7 +131,7 @@ ANASTASIS_backup_state_from_string_ (const char *state_string)
if (0 == strcmp (state_string,
backup_strings[i]))
return i;
- return ANASTASIS_BACKUP_STATE_ERROR;
+ return ANASTASIS_BACKUP_STATE_INVALID;
}
@@ -177,6 +177,68 @@ json_t *
ANASTASIS_backup_start (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
json_t *initial_state;
+ const char *external_reducer = ANASTASIS_REDUX_probe_external_reducer ();
+
+ if (NULL != external_reducer)
+ {
+ int pipefd_stdout[2];
+ pid_t pid = 0;
+ int status;
+ FILE *reducer_stdout;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Using external reducer '%s' for backup start status\n",
+ external_reducer);
+
+ GNUNET_assert (0 == pipe (pipefd_stdout));
+ pid = fork ();
+ if (pid == 0)
+ {
+ close (pipefd_stdout[0]);
+ dup2 (pipefd_stdout[1], STDOUT_FILENO);
+ execlp (external_reducer,
+ external_reducer,
+ "-b",
+ NULL);
+ GNUNET_assert (0);
+ }
+
+ close (pipefd_stdout[1]);
+ reducer_stdout = fdopen (pipefd_stdout[0],
+ "r");
+ {
+ json_error_t err;
+
+ initial_state = json_loadf (reducer_stdout,
+ 0,
+ &err);
+
+ if (NULL == initial_state)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "External reducer did not output valid JSON: %s:%d:%d %s\n",
+ err.source,
+ err.line,
+ err.column,
+ err.text);
+ GNUNET_assert (0 == fclose (reducer_stdout));
+ waitpid (pid, &status, 0);
+ return NULL;
+ }
+ }
+
+ GNUNET_assert (NULL != initial_state);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Waiting for external reducer to terminate.\n");
+ GNUNET_assert (0 == fclose (reducer_stdout));
+ reducer_stdout = NULL;
+ waitpid (pid, &status, 0);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "External reducer finished with exit status '%d'\n",
+ status);
+ return initial_state;
+ }
(void) cfg;
initial_state = ANASTASIS_REDUX_load_continents_ ();
@@ -286,22 +348,28 @@ add_authentication (json_t *state,
json_object_foreach (auth_providers, url, details)
{
- json_t *methods;
+ json_t *methods = NULL;
json_t *method;
size_t index;
- uint32_t size_limit_in_mb;
+ uint32_t size_limit_in_mb = 0;
+ bool disabled = false;
+ uint32_t http_status = 0;
struct GNUNET_JSON_Specification ispec[] = {
- GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes",
- &size_limit_in_mb),
- GNUNET_JSON_spec_json ("methods",
- &methods),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes",
+ &size_limit_in_mb)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_json ("methods",
+ &methods)),
GNUNET_JSON_spec_end ()
};
- if (MHD_HTTP_OK !=
- json_integer_value (json_object_get (details,
- "http_status")))
- continue; /* skip providers that are down */
if (GNUNET_OK !=
GNUNET_JSON_parse (details,
ispec,
@@ -310,6 +378,16 @@ add_authentication (json_t *state,
GNUNET_break (0);
continue;
}
+ if (disabled)
+ continue;
+ if (MHD_HTTP_OK != http_status)
+ continue; /* skip providers that are down */
+ if ( (NULL == methods) ||
+ (0 == size_limit_in_mb) )
+ {
+ GNUNET_break (0);
+ continue;
+ }
json_array_foreach (methods, index, method)
{
const char *type;
@@ -1082,6 +1160,33 @@ provider_candidate (struct PolicyBuilder *pb,
json_object_foreach (pb->providers, url, pconfig)
{
+ bool disabled = false;
+ uint32_t http_status = 0;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (pconfig,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ continue;
+ }
+ if ( (MHD_HTTP_OK != http_status) ||
+ disabled)
+ {
+ GNUNET_JSON_parse_free (spec);
+ continue;
+ }
+ GNUNET_JSON_parse_free (spec);
prov_sel[i] = url;
if (i == pb->req_methods - 1)
{
@@ -1178,16 +1283,25 @@ method_candidate (struct PolicyBuilder *pb,
* @param[out] salt value to extract
* @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
lookup_salt (const json_t *state,
const char *provider_url,
struct ANASTASIS_CRYPTO_ProviderSaltP *salt)
{
const json_t *aps;
const json_t *cfg;
+ uint32_t http_status = 0;
+ bool disabled = false;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("salt",
- salt),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("salt",
+ salt)),
GNUNET_JSON_spec_end ()
};
@@ -1205,10 +1319,6 @@ lookup_salt (const json_t *state,
GNUNET_break (0);
return GNUNET_SYSERR;
}
- if (MHD_HTTP_OK !=
- json_integer_value (json_object_get (cfg,
- "http_status")))
- return GNUNET_NO; /* skip providers that are down */
if (GNUNET_OK !=
GNUNET_JSON_parse (cfg,
spec,
@@ -1218,6 +1328,12 @@ lookup_salt (const json_t *state,
GNUNET_break_op (0);
return GNUNET_NO;
}
+ if (disabled)
+ return GNUNET_NO;
+ if (NULL ==
+ json_object_get (cfg,
+ "salt"))
+ return GNUNET_NO;
return GNUNET_OK;
}
@@ -1622,6 +1738,11 @@ done_authentication (json_t *state,
"'authentication_methods' must not be empty");
return NULL;
case 1:
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "Two factor authentication (2-FA) is required");
+ return NULL;
case 2:
pb.req_methods = pb.num_methods;
break;
@@ -1904,7 +2025,15 @@ add_policy (json_t *state,
{
const json_t *prov_cfg;
uint32_t limit;
+ bool disabled = false;
+ uint32_t http_status = 0;
struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes",
&limit),
GNUNET_JSON_spec_json ("methods",
@@ -1924,10 +2053,6 @@ add_policy (json_t *state,
"provider URL unknown");
return NULL;
}
- if (MHD_HTTP_OK !=
- json_integer_value (json_object_get (prov_cfg,
- "http_status")))
- continue;
if (GNUNET_OK !=
GNUNET_JSON_parse (prov_cfg,
spec,
@@ -1937,6 +2062,13 @@ add_policy (json_t *state,
json_decref (methods);
continue;
}
+ if ( (MHD_HTTP_OK != http_status) ||
+ disabled)
+ {
+ /* skip provider, disabled or down */
+ json_decref (methods);
+ continue;
+ }
if (! json_is_array (prov_methods))
{
GNUNET_break (0);
@@ -2373,17 +2505,21 @@ update_expiration_cost (json_t *state,
json_object_foreach (providers, url, provider)
{
struct TALER_Amount annual_fee;
+ bool disabled = false;
+ uint32_t http_status = 0;
struct GNUNET_JSON_Specification pspec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
TALER_JSON_spec_amount_any ("annual_fee",
&annual_fee),
GNUNET_JSON_spec_end ()
};
struct TALER_Amount fee;
- if (MHD_HTTP_OK !=
- json_integer_value (json_object_get (provider,
- "http_status")))
- continue; /* skip providers that are down */
if (GNUNET_OK !=
GNUNET_JSON_parse (provider,
pspec,
@@ -2393,6 +2529,9 @@ update_expiration_cost (json_t *state,
GNUNET_break_op (0);
continue;
}
+ if ( (MHD_HTTP_OK != http_status) ||
+ disabled)
+ continue; /* skip providers that are down or disabled */
if (0 >
TALER_amount_multiply (&fee,
&annual_fee,
@@ -2473,7 +2612,15 @@ update_expiration_cost (json_t *state,
off++;
{
struct TALER_Amount upload_cost;
+ bool disabled = false;
+ uint32_t http_status = 0;
struct GNUNET_JSON_Specification pspec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
TALER_JSON_spec_amount_any ("truth_upload_fee",
&upload_cost),
GNUNET_JSON_spec_end ()
@@ -2491,6 +2638,12 @@ update_expiration_cost (json_t *state,
GNUNET_break (0);
return GNUNET_SYSERR;
}
+ if ( (MHD_HTTP_OK != http_status) ||
+ disabled)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
if (0 >
TALER_amount_multiply (&fee,
&upload_cost,
@@ -2994,8 +3147,6 @@ secret_share_result_cb (void *cls,
json_t *details;
details = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("backup_state",
- "ERROR"),
GNUNET_JSON_pack_uint64 ("http_status",
sr->details.provider_failure.http_status),
GNUNET_JSON_pack_uint64 ("upload_status",
@@ -3074,7 +3225,7 @@ share_secret (struct UploadContext *uc)
};
args = json_object_get (uc->state,
- "pay-arguments");
+ "pay_arguments");
if ( (NULL != args) &&
(GNUNET_OK !=
GNUNET_JSON_parse (args,
@@ -3900,7 +4051,7 @@ upload (json_t *state,
};
args = json_object_get (uc->state,
- "pay-arguments");
+ "pay_arguments");
if ( (NULL != args) &&
(GNUNET_OK !=
GNUNET_JSON_parse (args,
@@ -4111,17 +4262,22 @@ check_upload_size_limit (json_t *state,
see #6760. */
json_object_foreach (aps, url, ap)
{
- uint32_t limit;
+ uint32_t limit = 0;
+ bool disabled = false;
+ uint32_t http_status = 0;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes",
- &limit),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("http_status",
+ &http_status)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("storage_limit_in_megabytes",
+ &limit)),
GNUNET_JSON_spec_end ()
};
- if (MHD_HTTP_OK !=
- json_integer_value (json_object_get (ap,
- "http_status")))
- continue; /* skip providers that are down */
if (GNUNET_OK !=
GNUNET_JSON_parse (ap,
spec,
@@ -4131,6 +4287,9 @@ check_upload_size_limit (json_t *state,
GNUNET_break_op (0);
continue;
}
+ if ( (MHD_HTTP_OK != http_status) ||
+ disabled)
+ continue;
if (0 == limit)
return GNUNET_SYSERR;
min_limit = GNUNET_MIN (min_limit,
@@ -4483,7 +4642,7 @@ pay_truths_backup (json_t *state,
if (NULL != arguments)
GNUNET_assert (0 ==
json_object_set (state,
- "pay-arguments",
+ "pay_arguments",
(json_t *) arguments));
return upload (state,
cb,
@@ -4513,7 +4672,7 @@ pay_policies_backup (json_t *state,
if (NULL != arguments)
GNUNET_assert (0 ==
json_object_set (state,
- "pay-arguments",
+ "pay_arguments",
(json_t *) arguments));
return upload (state,
cb,
@@ -4674,7 +4833,7 @@ ANASTASIS_backup_action_ (json_t *state,
"back",
&back_finished
},
- { ANASTASIS_BACKUP_STATE_ERROR, NULL, NULL }
+ { ANASTASIS_BACKUP_STATE_INVALID, NULL, NULL }
};
const char *s = json_string_value (json_object_get (state,
"backup_state"));
@@ -4682,7 +4841,7 @@ ANASTASIS_backup_action_ (json_t *state,
GNUNET_assert (NULL != s); /* holds as per invariant of caller */
bs = ANASTASIS_backup_state_from_string_ (s);
- if (ANASTASIS_BACKUP_STATE_ERROR == bs)
+ if (ANASTASIS_BACKUP_STATE_INVALID == bs)
{
ANASTASIS_redux_fail_ (cb,
cb_cls,
@@ -4935,7 +5094,25 @@ ANASTASIS_REDUX_backup_begin_ (json_t *state,
json_object_foreach (provider_list, url, prov) {
struct BackupStartStateProviderEntry *pe;
json_t *istate;
+ bool disabled = false;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_end ()
+ };
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (prov,
+ spec,
+ NULL, NULL))
+ {
+ /* skip malformed provider entry */
+ GNUNET_break_op (0);
+ continue;
+ }
+ if (disabled)
+ continue;
pe = GNUNET_new (struct BackupStartStateProviderEntry);
pe->bss = bss;
istate = json_object ();
diff --git a/src/reducer/anastasis_api_recovery_redux.c b/src/reducer/anastasis_api_recovery_redux.c
index 897a6dd..050a5b1 100644
--- a/src/reducer/anastasis_api_recovery_redux.c
+++ b/src/reducer/anastasis_api_recovery_redux.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -44,7 +44,7 @@ ANASTASIS_recovery_state_from_string_ (const char *state_string)
if (0 == strcmp (state_string,
recovery_strings[i]))
return i;
- return ANASTASIS_RECOVERY_STATE_ERROR;
+ return ANASTASIS_RECOVERY_STATE_INVALID;
}
@@ -83,6 +83,68 @@ json_t *
ANASTASIS_recovery_start (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
json_t *initial_state;
+ const char *external_reducer = ANASTASIS_REDUX_probe_external_reducer ();
+
+ if (NULL != external_reducer)
+ {
+ int pipefd_stdout[2];
+ pid_t pid = 0;
+ int status;
+ FILE *reducer_stdout;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Using external reducer '%s' for recovery start status\n",
+ external_reducer);
+
+ GNUNET_assert (0 == pipe (pipefd_stdout));
+ pid = fork ();
+ if (pid == 0)
+ {
+ close (pipefd_stdout[0]);
+ dup2 (pipefd_stdout[1], STDOUT_FILENO);
+ execlp (external_reducer,
+ external_reducer,
+ "-r",
+ NULL);
+ GNUNET_assert (0);
+ }
+
+ close (pipefd_stdout[1]);
+ reducer_stdout = fdopen (pipefd_stdout[0],
+ "r");
+ {
+ json_error_t err;
+
+ initial_state = json_loadf (reducer_stdout,
+ 0,
+ &err);
+
+ if (NULL == initial_state)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "External reducer did not output valid JSON: %s:%d:%d %s\n",
+ err.source,
+ err.line,
+ err.column,
+ err.text);
+ GNUNET_assert (0 == fclose (reducer_stdout));
+ waitpid (pid, &status, 0);
+ return NULL;
+ }
+ }
+
+ GNUNET_assert (NULL != initial_state);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Waiting for external reducer to terminate.\n");
+ GNUNET_assert (0 == fclose (reducer_stdout));
+ reducer_stdout = NULL;
+ waitpid (pid, &status, 0);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "External reducer finished with exit status '%d'\n",
+ status);
+ return initial_state;
+ }
(void) cfg;
initial_state = ANASTASIS_REDUX_load_continents_ ();
@@ -188,15 +250,16 @@ sctx_free (void *cls)
/**
- * Update @a state to reflect the error provided in @a rc.
+ * Call the action callback with an error result
*
- * @param[in,out] state state to update
+ * @param cb action callback to call
+ * @param cb_cls closure for @a cb
* @param rc error code to translate to JSON
- * @return error code to use
*/
-static enum TALER_ErrorCode
-update_state_by_error (json_t *state,
- enum ANASTASIS_RecoveryStatus rc)
+void
+fail_by_error (ANASTASIS_ActionCallback cb,
+ void *cb_cls,
+ enum ANASTASIS_RecoveryStatus rc)
{
const char *msg = NULL;
enum TALER_ErrorCode ec = TALER_EC_INVALID;
@@ -249,17 +312,10 @@ update_state_by_error (json_t *state,
ec = TALER_EC_ANASTASIS_REDUCER_POLICY_LOOKUP_FAILED;
break;
}
- GNUNET_assert (0 ==
- json_object_set_new (state,
- "error_message",
- json_string (msg)));
- GNUNET_assert (0 ==
- json_object_set_new (state,
- "error_code",
- json_integer (rc)));
- set_state (state,
- ANASTASIS_RECOVERY_STATE_ERROR);
- return ec;
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ ec,
+ msg);
}
@@ -279,7 +335,6 @@ core_secret_cb (void *cls,
size_t secret_size)
{
struct SelectChallengeContext *sctx = cls;
- enum TALER_ErrorCode ec;
sctx->r = NULL;
if (ANASTASIS_RS_SUCCESS == rc)
@@ -311,11 +366,9 @@ core_secret_cb (void *cls,
sctx_free (sctx);
return;
}
- ec = update_state_by_error (sctx->state,
- rc);
- sctx->cb (sctx->cb_cls,
- ec,
- sctx->state);
+ fail_by_error (sctx->cb,
+ sctx->cb_cls,
+ rc);
sctx_free (sctx);
}
@@ -488,11 +541,10 @@ answer_feedback_cb (
if (NULL == rd)
{
GNUNET_break (0);
- set_state (sctx->state,
- ANASTASIS_RECOVERY_STATE_ERROR);
- sctx->cb (sctx->cb_cls,
- TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- sctx->state);
+ ANASTASIS_redux_fail_ (sctx->cb,
+ sctx->cb_cls,
+ TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+ "unable to serialize recovery state");
sctx_free (sctx);
return;
}
@@ -801,11 +853,10 @@ answer_feedback_cb (
if (NULL == c)
{
GNUNET_break (0);
- set_state (sctx->state,
- ANASTASIS_RECOVERY_STATE_ERROR);
- sctx->cb (sctx->cb_cls,
- TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- sctx->state);
+ ANASTASIS_redux_fail_ (sctx->cb,
+ sctx->cb_cls,
+ TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+ NULL);
sctx_free (sctx);
return;
}
@@ -1684,10 +1735,13 @@ select_challenge_cb (void *cls,
json_object_set_new (sctx->state,
"selected_challenge_uuid",
GNUNET_JSON_from_data_auto (&cd->uuid)));
- if (0 == strcmp ("question",
- cd->type))
+ if ( (0 == strcmp ("question",
+ cd->type)) ||
+ (0 == strcmp ("totp",
+ cd->type)) )
{
- /* security question, immediately request user to answer it */
+ /* security question or TOTP:
+ immediately request user to answer it */
set_state (sctx->state,
ANASTASIS_RECOVERY_STATE_CHALLENGE_SOLVING);
sctx->cb (sctx->cb_cls,
@@ -2049,7 +2103,7 @@ ANASTASIS_recovery_action_ (json_t *state,
"back",
&back_challenge_solving
},
- { ANASTASIS_RECOVERY_STATE_ERROR, NULL, NULL }
+ { ANASTASIS_RECOVERY_STATE_INVALID, NULL, NULL }
};
const char *s = json_string_value (json_object_get (state,
"recovery_state"));
@@ -2057,7 +2111,7 @@ ANASTASIS_recovery_action_ (json_t *state,
GNUNET_assert (NULL != s);
rs = ANASTASIS_recovery_state_from_string_ (s);
- if (ANASTASIS_RECOVERY_STATE_ERROR == rs)
+ if (ANASTASIS_RECOVERY_STATE_INVALID == rs)
{
ANASTASIS_redux_fail_ (cb,
cb_cls,
@@ -2303,7 +2357,6 @@ core_early_secret_cb (void *cls,
{
struct PolicyDownloadEntry *pd = cls;
struct RecoverSecretState *rss = pd->rss;
- enum TALER_ErrorCode ec;
pd->recovery = NULL;
GNUNET_assert (NULL == secret);
@@ -2316,11 +2369,9 @@ core_early_secret_cb (void *cls,
return; /* wait for another one */
/* all failed! report failure! */
GNUNET_assert (ANASTASIS_RS_SUCCESS != rc);
- ec = update_state_by_error (rss->state,
- rc);
- rss->cb (rss->cb_cls,
- ec,
- rss->state);
+ fail_by_error (rss->cb,
+ rss->cb_cls,
+ rc);
rss->cb = NULL;
free_rss (rss);
}
@@ -2412,31 +2463,30 @@ static void
return_no_policy (struct RecoverSecretState *rss,
bool offline)
{
- json_t *msg;
+ json_t *estate;
+ const char *detail;
+ enum TALER_ErrorCode ec;
+ ec = TALER_EC_ANASTASIS_REDUCER_NETWORK_FAILED;
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"No provider online, need user to manually specify providers!\n");
- msg = GNUNET_JSON_PACK (
+
+ if (offline)
+ detail = "could not contact provider (offline)";
+ else
+ detail = "provider does not know you";
+
+ estate = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("detail",
+ detail)),
+ GNUNET_JSON_pack_uint64 ("code",
+ ec),
GNUNET_JSON_pack_string ("hint",
- offline
- ? "could not contact provider"
- : "provider does not know you"),
- GNUNET_JSON_pack_bool ("offline",
- offline));
- GNUNET_assert (0 ==
- json_object_set_new (rss->state,
- "recovery_error",
- msg));
- /* In case there are old ones, remove them! */
- (void) json_object_del (rss->state,
- "recovery_document");
- (void) json_object_del (rss->state,
- "recovery_information");
- set_state (rss->state,
- ANASTASIS_RECOVERY_STATE_SECRET_SELECTING);
+ TALER_ErrorCode_get_hint (ec)));
rss->cb (rss->cb_cls,
- TALER_EC_NONE,
- rss->state);
+ ec,
+ estate);
free_rss (rss);
}
@@ -2526,8 +2576,6 @@ policy_lookup_cb (void *cls,
{
json_decref (challenges);
json_decref (policies);
- set_state (rss->state,
- ANASTASIS_RECOVERY_STATE_ERROR);
ANASTASIS_redux_fail_ (rss->cb,
rss->cb_cls,
TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
@@ -2545,6 +2593,8 @@ policy_lookup_cb (void *cls,
: &cost),
GNUNET_JSON_pack_string ("type",
cd->type),
+ GNUNET_JSON_pack_string ("uuid-display",
+ ANASTASIS_CRYPTO_uuid2s (&cd->uuid)),
GNUNET_JSON_pack_string ("instructions",
cd->instructions));
GNUNET_assert (0 ==
@@ -2574,11 +2624,10 @@ policy_lookup_cb (void *cls,
if (NULL == rd)
{
GNUNET_break (0);
- set_state (rss->state,
- ANASTASIS_RECOVERY_STATE_ERROR);
- rss->cb (rss->cb_cls,
- TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
- rss->state);
+ ANASTASIS_redux_fail_ (rss->cb,
+ rss->cb_cls,
+ TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
+ "unable to serialize recovery state");
free_rss (rss);
return;
}
@@ -2587,9 +2636,6 @@ policy_lookup_cb (void *cls,
"recovery_document",
rd));
}
- /* In case there is an old error remove it! */
- (void) json_object_del (rss->state,
- "recovery_error");
set_state (rss->state,
ANASTASIS_RECOVERY_STATE_SECRET_SELECTING);
rss->cb (rss->cb_cls,
@@ -2864,6 +2910,23 @@ ANASTASIS_REDUX_recovery_challenge_begin_ (json_t *state,
const char *url;
json_object_foreach (providers, url, prov) {
+ bool disabled = false;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("disabled",
+ &disabled)),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (prov,
+ spec,
+ NULL, NULL))
+ {
+ /* skip malformed provider entry */
+ GNUNET_break_op (0);
+ continue;
+ }
begin_query_provider (rss,
url);
}
diff --git a/src/reducer/anastasis_api_redux.c b/src/reducer/anastasis_api_redux.c
index f55eece..11dc678 100644
--- a/src/reducer/anastasis_api_redux.c
+++ b/src/reducer/anastasis_api_redux.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -234,6 +234,26 @@ static json_t *redux_countries;
*/
static json_t *provider_list;
+/**
+ * External reducer binary or NULL
+ * to use internal reducer.
+ */
+static char *external_reducer_binary;
+
+
+const char *
+ANASTASIS_REDUX_probe_external_reducer (void)
+{
+ if (NULL != external_reducer_binary)
+ return external_reducer_binary;
+ external_reducer_binary = getenv ("ANASTASIS_EXTERNAL_REDUCER");
+ if (NULL != external_reducer_binary)
+ unsetenv ("ANASTASIS_EXTERNAL_REDUCER");
+
+ return external_reducer_binary;
+
+}
+
/**
* Extract the mode of a state from json
@@ -262,7 +282,7 @@ ANASTASIS_generic_state_from_string_ (const char *state_string)
if (0 == strcmp (state_string,
generic_strings[i]))
return i;
- return ANASTASIS_GENERIC_STATE_ERROR;
+ return ANASTASIS_GENERIC_STATE_INVALID;
}
@@ -1378,9 +1398,16 @@ ANASTASIS_add_provider_ (json_t *state,
ANASTASIS_ActionCallback cb,
void *cb_cls)
{
- json_t *urls;
json_t *tlist;
+ if (NULL == arguments)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "arguments missing");
+ return true; /* cb was invoked */
+ }
tlist = json_object_get (state,
"authentication_providers");
if (NULL == tlist)
@@ -1392,47 +1419,19 @@ ANASTASIS_add_provider_ (json_t *state,
"authentication_providers",
tlist));
}
- if (NULL == arguments)
{
- ANASTASIS_redux_fail_ (cb,
- cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "arguments missing");
- return true;
- }
- urls = json_object_get (arguments,
- "urls");
- if (NULL == urls)
- {
- ANASTASIS_redux_fail_ (cb,
- cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "'urls' missing");
- return true;
- }
- {
- size_t index;
- json_t *url;
+ json_t *params;
+ const char *url;
- json_array_foreach (urls, index, url)
+ json_object_foreach (((json_t *) arguments), url, params)
{
- const char *url_str = json_string_value (url);
-
- if (NULL == url_str)
- {
- ANASTASIS_redux_fail_ (cb,
- cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "'urls' must be strings");
- return true;
- }
GNUNET_assert (0 ==
- json_object_set_new (tlist,
- url_str,
- json_object ()));
+ json_object_set (tlist,
+ url,
+ params));
}
}
- return false;
+ return false; /* cb not invoked */
}
@@ -1502,6 +1501,256 @@ typedef struct ANASTASIS_ReduxAction *
void *cb_cls);
+/**
+ * Closure for read operations on the external reducer.
+ */
+struct ExternalReducerCls
+{
+ struct GNUNET_Buffer read_buffer;
+ struct GNUNET_SCHEDULER_Task *read_task;
+ struct GNUNET_DISK_PipeHandle *reducer_stdin;
+ struct GNUNET_DISK_PipeHandle *reducer_stdout;
+ struct GNUNET_OS_Process *reducer_process;
+ ANASTASIS_ActionCallback action_cb;
+ void *action_cb_cls;
+};
+
+/**
+ * Clean up and destroy the external reducer state.
+ *
+ * @param cls closure, a 'struct ExternalReducerCls *'
+ */
+static void
+cleanup_external_reducer (void *cls)
+{
+ struct ExternalReducerCls *red_cls = cls;
+
+ if (NULL != red_cls->read_task)
+ {
+ GNUNET_SCHEDULER_cancel (red_cls->read_task);
+ red_cls->read_task = NULL;
+ }
+
+ GNUNET_buffer_clear (&red_cls->read_buffer);
+ if (NULL != red_cls->reducer_stdin)
+ {
+ GNUNET_DISK_pipe_close (red_cls->reducer_stdin);
+ red_cls->reducer_stdin = NULL;
+ }
+ if (NULL != red_cls->reducer_stdout)
+ {
+ GNUNET_DISK_pipe_close (red_cls->reducer_stdout);
+ red_cls->reducer_stdout = NULL;
+ }
+
+ if (NULL != red_cls->reducer_process)
+ {
+ enum GNUNET_OS_ProcessStatusType type;
+ unsigned long code;
+ enum GNUNET_GenericReturnValue pwret;
+
+ pwret = GNUNET_OS_process_wait_status (red_cls->reducer_process,
+ &type,
+ &code);
+
+ GNUNET_assert (GNUNET_SYSERR != pwret);
+ if (GNUNET_NO == pwret)
+ {
+ GNUNET_OS_process_kill (red_cls->reducer_process,
+ SIGTERM);
+ GNUNET_assert (GNUNET_SYSERR != GNUNET_OS_process_wait (
+ red_cls->reducer_process));
+ }
+
+ GNUNET_OS_process_destroy (red_cls->reducer_process);
+ red_cls->reducer_process = NULL;
+ }
+
+ GNUNET_free (red_cls);
+}
+
+
+/**
+ * Task called when
+ *
+ * @param cls closure, a 'struct ExternalReducerCls *'
+ */
+static void
+external_reducer_read_cb (void *cls)
+{
+ struct ExternalReducerCls *red_cls = cls;
+ ssize_t sret;
+ char buf[256];
+
+ red_cls->read_task = NULL;
+
+ sret = GNUNET_DISK_file_read (GNUNET_DISK_pipe_handle (
+ red_cls->reducer_stdout,
+ GNUNET_DISK_PIPE_END_READ),
+ buf,
+ 256);
+ if (sret < 0)
+ {
+ GNUNET_break (0);
+ red_cls->action_cb (red_cls->action_cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INTERNAL_ERROR,
+ NULL);
+ cleanup_external_reducer (red_cls);
+ return;
+ }
+ else if (0 == sret)
+ {
+ char *str = GNUNET_buffer_reap_str (&red_cls->read_buffer);
+ json_t *json;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got external reducer response: '%s'\n",
+ str);
+
+ json = json_loads (str, 0, NULL);
+
+ if (NULL == json)
+ {
+ GNUNET_break (0);
+ red_cls->action_cb (red_cls->action_cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INTERNAL_ERROR,
+ NULL);
+ cleanup_external_reducer (red_cls);
+ return;
+ }
+
+ {
+ enum TALER_ErrorCode ec;
+ ec = json_integer_value (json_object_get (json, "code"));
+
+ red_cls->action_cb (red_cls->action_cb_cls,
+ ec,
+ json);
+ }
+ cleanup_external_reducer (red_cls);
+ return;
+ }
+ else
+ {
+ GNUNET_buffer_write (&red_cls->read_buffer,
+ buf,
+ sret);
+
+ red_cls->read_task = GNUNET_SCHEDULER_add_read_file (
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_DISK_pipe_handle (
+ red_cls->reducer_stdout,
+ GNUNET_DISK_PIPE_END_READ),
+ external_reducer_read_cb,
+ red_cls);
+ }
+}
+
+
+/**
+ * Handle an action using an external reducer, i.e.
+ * by shelling out to another process.
+ */
+static struct ANASTASIS_ReduxAction *
+redux_action_external (const char *ext_reducer,
+ const json_t *state,
+ const char *action,
+ const json_t *arguments,
+ ANASTASIS_ActionCallback cb,
+ void *cb_cls)
+{
+ char *arg_str;
+ char *state_str = json_dumps (state, JSON_COMPACT);
+ ssize_t sret;
+ struct ExternalReducerCls *red_cls = GNUNET_new (struct ExternalReducerCls);
+
+ if (NULL == arguments)
+ arg_str = GNUNET_strdup ("{}");
+ else
+ arg_str = json_dumps (arguments, JSON_COMPACT);
+
+ red_cls->action_cb = cb;
+ red_cls->action_cb_cls = cb_cls;
+
+ GNUNET_assert (NULL != (red_cls->reducer_stdin = GNUNET_DISK_pipe (
+ GNUNET_DISK_PF_NONE)));
+ GNUNET_assert (NULL != (red_cls->reducer_stdout = GNUNET_DISK_pipe (
+ GNUNET_DISK_PF_NONE)));
+
+ /* By the time we're here, this variable should be unset, because
+ otherwise using anastasis-reducer as the external reducer
+ will lead to infinite recursion. */
+ GNUNET_assert (NULL == getenv ("ANASTASIS_EXTERNAL_REDUCER"));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Starting external reducer with action '%s' and argument '%s'\n",
+ action,
+ arg_str);
+
+ red_cls->reducer_process = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ERR,
+ red_cls->reducer_stdin,
+ red_cls->reducer_stdout,
+ NULL,
+ ext_reducer,
+ ext_reducer,
+ "-a",
+ arg_str,
+ action,
+ NULL);
+
+ GNUNET_free (arg_str);
+
+ if (NULL == red_cls->reducer_process)
+ {
+ GNUNET_break (0);
+ GNUNET_free (state_str);
+ cleanup_external_reducer (red_cls);
+ return NULL;
+ }
+
+ /* Close pipe ends we don't use. */
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_pipe_close_end (red_cls->reducer_stdin,
+ GNUNET_DISK_PIPE_END_READ));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_pipe_close_end (red_cls->reducer_stdout,
+ GNUNET_DISK_PIPE_END_WRITE));
+
+ sret = GNUNET_DISK_file_write_blocking (GNUNET_DISK_pipe_handle (
+ red_cls->reducer_stdin,
+ GNUNET_DISK_PIPE_END_WRITE),
+ state_str,
+ strlen (state_str));
+ GNUNET_free (state_str);
+ if (sret <= 0)
+ {
+ GNUNET_break (0);
+ cleanup_external_reducer (red_cls);
+ return NULL;
+ }
+
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_pipe_close_end (red_cls->reducer_stdin,
+ GNUNET_DISK_PIPE_END_WRITE));
+
+ red_cls->read_task = GNUNET_SCHEDULER_add_read_file (
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_DISK_pipe_handle (
+ red_cls->reducer_stdout,
+ GNUNET_DISK_PIPE_END_READ),
+ external_reducer_read_cb,
+ red_cls);
+
+ {
+ struct ANASTASIS_ReduxAction *ra = GNUNET_new (struct
+ ANASTASIS_ReduxAction);
+ ra->cleanup_cls = red_cls;
+ ra->cleanup = cleanup_external_reducer;
+ return ra;
+ }
+}
+
+
struct ANASTASIS_ReduxAction *
ANASTASIS_redux_action (const json_t *state,
const char *action,
@@ -1520,6 +1769,7 @@ ANASTASIS_redux_action (const json_t *state,
"select_continent",
&select_continent
},
+ /* Deprecated alias for "back" from that state, should be removed eventually. */
{
ANASTASIS_GENERIC_STATE_COUNTRY_SELECTING,
"unselect_continent",
@@ -1527,6 +1777,11 @@ ANASTASIS_redux_action (const json_t *state,
},
{
ANASTASIS_GENERIC_STATE_COUNTRY_SELECTING,
+ "back",
+ &unselect_continent
+ },
+ {
+ ANASTASIS_GENERIC_STATE_COUNTRY_SELECTING,
"select_country",
&select_country
},
@@ -1536,11 +1791,6 @@ ANASTASIS_redux_action (const json_t *state,
&select_continent
},
{
- ANASTASIS_GENERIC_STATE_COUNTRY_SELECTING,
- "unselect_continent",
- &unselect_continent
- },
- {
ANASTASIS_GENERIC_STATE_USER_ATTRIBUTES_COLLECTING,
"enter_user_attributes",
&enter_user_attributes
@@ -1555,13 +1805,25 @@ ANASTASIS_redux_action (const json_t *state,
"back",
&ANASTASIS_back_generic_decrement_
},
- { ANASTASIS_GENERIC_STATE_ERROR, NULL, NULL }
+ { ANASTASIS_GENERIC_STATE_INVALID, NULL, NULL }
};
bool recovery_mode = false;
const char *s = json_string_value (json_object_get (state,
"backup_state"));
enum ANASTASIS_GenericState gs;
+ /* If requested, handle action with external reducer, used for testing. */
+ {
+ const char *ext_reducer = ANASTASIS_REDUX_probe_external_reducer ();
+ if (NULL != ext_reducer)
+ return redux_action_external (ext_reducer,
+ state,
+ action,
+ arguments,
+ cb,
+ cb_cls);
+ }
+
if (NULL == s)
{
s = json_string_value (json_object_get (state,
@@ -1583,7 +1845,7 @@ ANASTASIS_redux_action (const json_t *state,
new_state = json_deep_copy (state);
GNUNET_assert (NULL != new_state);
- if (gs != ANASTASIS_GENERIC_STATE_ERROR)
+ if (gs != ANASTASIS_GENERIC_STATE_INVALID)
{
for (unsigned int i = 0; NULL != dispatchers[i].fun; i++)
{
diff --git a/src/reducer/anastasis_api_redux.h b/src/reducer/anastasis_api_redux.h
index 4d62d5e..f161d61 100644
--- a/src/reducer/anastasis_api_redux.h
+++ b/src/reducer/anastasis_api_redux.h
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -25,7 +25,7 @@
#define ANASTASIS_GENERIC_STATES(REDUX_STATE) \
- REDUX_STATE (ERROR) \
+ REDUX_STATE (INVALID) \
REDUX_STATE (CONTINENT_SELECTING) \
REDUX_STATE (COUNTRY_SELECTING) \
REDUX_STATE (USER_ATTRIBUTES_COLLECTING)
@@ -328,6 +328,16 @@ ANASTASIS_backup_action_ (json_t *state,
/**
+ * Check if an external reducer binary is requested.
+ * Cache the result and unset the corresponding environment
+ * variable.
+ *
+ * @returns name of the external reducer or NULL to user internal reducer
+ */
+const char *
+ANASTASIS_REDUX_probe_external_reducer (void);
+
+/**
* Generic container for an action with asynchronous activities.
*/
struct ANASTASIS_ReduxAction
diff --git a/src/reducer/validation_CH_AHV.c b/src/reducer/validation_CH_AHV.c
index 6beded1..4ea973c 100644
--- a/src/reducer/validation_CH_AHV.c
+++ b/src/reducer/validation_CH_AHV.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_CZ_BN.c b/src/reducer/validation_CZ_BN.c
index 85dea4a..b570841 100644
--- a/src/reducer/validation_CZ_BN.c
+++ b/src/reducer/validation_CZ_BN.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_DE_SVN.c b/src/reducer/validation_DE_SVN.c
index 7096708..e753f0c 100644
--- a/src/reducer/validation_DE_SVN.c
+++ b/src/reducer/validation_DE_SVN.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_DE_TIN.c b/src/reducer/validation_DE_TIN.c
index 0412f87..5678579 100644
--- a/src/reducer/validation_DE_TIN.c
+++ b/src/reducer/validation_DE_TIN.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_ES_DNI.c b/src/reducer/validation_ES_DNI.c
new file mode 100644
index 0000000..5fb3885
--- /dev/null
+++ b/src/reducer/validation_ES_DNI.c
@@ -0,0 +1,184 @@
+/*
+ This file is part of Anastasis
+ Copyright (C) 2021 Anastasis SARL
+
+ Anastasis is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file reducer/validation_ES_DNI.c
+ * @brief validation logic for Spanish Documento Nacional de Identidad numbers, and Número de Identificación de Extranjeros
+ * @author Christian Grothoff
+ *
+ * Examples:
+ * 12345678Z, 39740191D, 14741806W, X8095495R
+ */
+#include <string.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+/**
+ * Function to validate a Spanish CIF number.
+ *
+ * @param civ number to validate
+ * @return true if validation passed, else false
+ */
+static bool
+validate_cif (const char *cif)
+{
+ size_t slen = strlen (cif);
+ char letter = cif[0];
+ const char *number = &cif[1];
+ char control = cif[slen - 1];
+ unsigned int sum = 0;
+
+ if (9 != slen)
+ return false;
+
+ for (unsigned int i = 0; i < slen - 2; i++)
+ {
+ unsigned int n = number[i] - '0';
+
+ if (n >= 10)
+ return false;
+ if (0 == (i % 2))
+ {
+ n *= 2;
+ sum += n < 10 ? n : n - 9;
+ }
+ else
+ {
+ sum += n;
+ }
+ }
+ sum %= 10;
+ if (0 != sum)
+ sum = 10 - sum;
+ {
+ char control_digit = "0123456789"[sum];
+ char control_letter = "JABCDEFGHI"[sum];
+
+ switch (letter)
+ {
+ case 'A':
+ case 'B':
+ case 'E':
+ case 'H':
+ return control == control_digit;
+ case 'N':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'W':
+ return control == control_letter;
+ default:
+ return (control == control_letter) ||
+ (control == control_digit);
+ }
+ }
+}
+
+
+/**
+ * Function to validate a Spanish DNI number.
+ *
+ * See https://www.ordenacionjuego.es/en/calculo-digito-control
+ *
+ * @param dni_number number to validate (input)
+ * @return true if validation passed, else false
+ */
+bool
+ES_DNI_check (const char *dni_number)
+{
+ const char map[] = "TRWAGMYFPDXBNJZSQVHLCKE";
+ unsigned int num;
+ char chksum;
+ unsigned int fact;
+ char dummy;
+
+ if (strlen (dni_number) < 8)
+ return false;
+ switch (dni_number[0])
+ {
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'H':
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'N':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'U':
+ case 'V':
+ case 'W':
+ /* CIF: [A-W]\d{7}[0-9A-J] */
+ /* CIF is for companies, we only take those
+ of individuals here! */
+ return false; /* CIV is not allowed! */
+ case 'M':
+ /* special NIE, with CIF validation (?),
+ but for individuals, see
+ https://www.strongabogados.com/tax-id-spain.php */
+ return validate_cif (dni_number);
+ case 'X':
+ case 'Y':
+ case 'Z':
+ /* NIE */
+ fact = dni_number[0] - 'X';
+ /* 7 or 8 digits */
+ if (2 == sscanf (&dni_number[1],
+ "%8u%c%c",
+ &num,
+ &chksum,
+ &dummy))
+ {
+ num += fact * 100000000;
+ }
+ else if (2 == sscanf (&dni_number[1],
+ "%7u%c%c",
+ &num,
+ &chksum,
+ &dummy))
+ {
+ num += fact * 10000000;
+ }
+ else
+ {
+ return false;
+ }
+ break;
+ default:
+ fact = 0;
+ /* DNI */
+ if (2 != sscanf (dni_number,
+ "%8u%c%c",
+ &num,
+ &chksum,
+ &dummy))
+ return false;
+ break;
+ }
+ if (map[num % 23] != chksum)
+ return false;
+ return true;
+}
diff --git a/src/reducer/validation_IN_AADHAR.c b/src/reducer/validation_IN_AADHAR.c
index 4c4901a..d53b655 100644
--- a/src/reducer/validation_IN_AADHAR.c
+++ b/src/reducer/validation_IN_AADHAR.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_IT_CF.c b/src/reducer/validation_IT_CF.c
index ca66a11..6e9c6c6 100644
--- a/src/reducer/validation_IT_CF.c
+++ b/src/reducer/validation_IT_CF.c
@@ -3,14 +3,14 @@
Copyright (C) 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_XX_SQUARE.c b/src/reducer/validation_XX_SQUARE.c
index 88cf890..1f43400 100644
--- a/src/reducer/validation_XX_SQUARE.c
+++ b/src/reducer/validation_XX_SQUARE.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/reducer/validation_XY_PRIME.c b/src/reducer/validation_XY_PRIME.c
index 32bdce0..56aa724 100644
--- a/src/reducer/validation_XY_PRIME.c
+++ b/src/reducer/validation_XY_PRIME.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/restclient/anastasis_api_config.c b/src/restclient/anastasis_api_config.c
index acb0967..9cf25c9 100644
--- a/src/restclient/anastasis_api_config.c
+++ b/src/restclient/anastasis_api_config.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/restclient/anastasis_api_curl_defaults.c b/src/restclient/anastasis_api_curl_defaults.c
index b777bae..e052517 100644
--- a/src/restclient/anastasis_api_curl_defaults.c
+++ b/src/restclient/anastasis_api_curl_defaults.c
@@ -3,14 +3,14 @@
Copyright (C) 2014-2019 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
diff --git a/src/restclient/anastasis_api_curl_defaults.h b/src/restclient/anastasis_api_curl_defaults.h
index 4d990af..948b931 100644
--- a/src/restclient/anastasis_api_curl_defaults.h
+++ b/src/restclient/anastasis_api_curl_defaults.h
@@ -3,14 +3,14 @@
Copyright (C) 2014-2019 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
diff --git a/src/restclient/anastasis_api_keyshare_lookup.c b/src/restclient/anastasis_api_keyshare_lookup.c
index 50e0d67..13390c9 100644
--- a/src/restclient/anastasis_api_keyshare_lookup.c
+++ b/src/restclient/anastasis_api_keyshare_lookup.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -411,7 +411,7 @@ ANASTASIS_keyshare_lookup (
char *val;
char *hdr;
- /* Set Truth-Decryption-Key header */
+ /* Set Anastasis-Truth-Decryption-Key header */
val = GNUNET_STRINGS_data_to_string_alloc (truth_key,
sizeof (*truth_key));
GNUNET_asprintf (&hdr,
diff --git a/src/restclient/anastasis_api_policy_lookup.c b/src/restclient/anastasis_api_policy_lookup.c
index e21ed58..42db90d 100644
--- a/src/restclient/anastasis_api_policy_lookup.c
+++ b/src/restclient/anastasis_api_policy_lookup.c
@@ -3,16 +3,16 @@
Copyright (C) 2014-2019 Anastasis SARL
ANASTASIS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as
+ it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2.1,
or (at your option) any later version.
ANASTASIS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
+ You should have received a copy of the GNU General Public
License along with ANASTASIS; see the file COPYING.LGPL. If not,
see <http://www.gnu.org/licenses/>
*/
diff --git a/src/restclient/anastasis_api_policy_store.c b/src/restclient/anastasis_api_policy_store.c
index 5d44094..22d6330 100644
--- a/src/restclient/anastasis_api_policy_store.c
+++ b/src/restclient/anastasis_api_policy_store.c
@@ -3,16 +3,16 @@
Copyright (C) 2014-2021 Anastasis SARL
ANASTASIS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as
+ it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2.1,
or (at your option) any later version.
ANASTASIS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
+ You should have received a copy of the GNU General Public
License along with ANASTASIS; see the file COPYING.LGPL. If not,
see <http://www.gnu.org/licenses/>
*/
@@ -227,6 +227,11 @@ handle_policy_store_finished (void *cls,
data_size);
ud.us = ANASTASIS_US_SERVER_ERROR;
break;
+ case MHD_HTTP_BAD_GATEWAY:
+ ud.ec = TALER_JSON_get_error_code2 (data,
+ data_size);
+ ud.us = ANASTASIS_US_SERVER_ERROR;
+ break;
default:
ud.ec = TALER_JSON_get_error_code2 (data,
data_size);
diff --git a/src/restclient/anastasis_api_truth_store.c b/src/restclient/anastasis_api_truth_store.c
index 74b9238..c1cf634 100644
--- a/src/restclient/anastasis_api_truth_store.c
+++ b/src/restclient/anastasis_api_truth_store.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -296,7 +296,7 @@ ANASTASIS_truth_store (
json_t *truth_data;
truth_data = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("keyshare_data",
+ GNUNET_JSON_pack_data_auto ("key_share_data",
encrypted_keyshare),
GNUNET_JSON_pack_string ("type",
type),
diff --git a/src/stasis/anastasis_db_plugin.c b/src/stasis/anastasis_db_plugin.c
index 7edca5f..a7e55b9 100644
--- a/src/stasis/anastasis_db_plugin.c
+++ b/src/stasis/anastasis_db_plugin.c
@@ -3,7 +3,7 @@
Copyright (C) 2015, 2016 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/stasis/plugin_anastasis_postgres.c b/src/stasis/plugin_anastasis_postgres.c
index b1be081..bdbdc04 100644
--- a/src/stasis/plugin_anastasis_postgres.c
+++ b/src/stasis/plugin_anastasis_postgres.c
@@ -3,7 +3,7 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -134,7 +134,7 @@ postgres_create_tables (void *cls)
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
static enum GNUNET_GenericReturnValue
-postgres_connect (void *cls)
+prepare_statements (void *cls)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_PreparedStatement ps[] = {
@@ -502,14 +502,16 @@ postgres_connect (void *cls)
GNUNET_PQ_PREPARED_STATEMENT_END
};
- pg->conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "stasis-postgres",
- NULL,
- NULL,
- ps);
- if (NULL == pg->conn)
- return GNUNET_SYSERR;
- return GNUNET_OK;
+ {
+ enum GNUNET_GenericReturnValue ret;
+
+ ret = GNUNET_PQ_prepare_statements (pg->conn,
+ ps);
+ if (GNUNET_OK != ret)
+ return ret;
+ pg->init = true;
+ return GNUNET_OK;
+ }
}
@@ -562,7 +564,7 @@ internal_setup (struct PostgresClosure *pg,
struct GNUNET_PQ_Context *db_conn;
db_conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
+ "stasis-postgres",
NULL,
es,
NULL);
@@ -576,7 +578,7 @@ internal_setup (struct PostgresClosure *pg,
return GNUNET_OK;
if (skip_prepare)
return GNUNET_OK;
- return postgres_connect (pg);
+ return prepare_statements (pg);
}
@@ -646,7 +648,8 @@ begin_transaction (void *cls,
};
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
pg->transaction_name = name;
if (GNUNET_OK !=
GNUNET_PQ_exec_statements (pg->conn,
@@ -802,7 +805,8 @@ postgres_gc (void *cls,
enum GNUNET_DB_QueryStatus qs;
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
"gc_accounts",
params);
@@ -843,7 +847,8 @@ postgres_store_recovery_document (
enum GNUNET_DB_QueryStatus qs;
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
for (unsigned int retry = 0; retry<MAX_RETRIES; retry++)
{
if (GNUNET_OK !=
@@ -1407,7 +1412,8 @@ postgres_record_recdoc_payment (
enum GNUNET_DB_QueryStatus qs;
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
/* because of constraint at user_id, first we have to verify
if user exists, and if not, create one */
@@ -2057,7 +2063,8 @@ postgres_lookup_account (
enum GNUNET_DB_QueryStatus qs;
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
{
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_absolute_time ("expiration_date",
@@ -2165,7 +2172,8 @@ postgres_get_latest_recovery_document (
};
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"latest_recoverydocument_select",
params,
@@ -2740,7 +2748,8 @@ postgres_challenge_gc (void *cls)
};
check_connection (pg);
- postgres_preflight (pg);
+ GNUNET_break (GNUNET_OK ==
+ postgres_preflight (pg));
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"gc_challengecodes",
params);
@@ -2777,7 +2786,8 @@ libanastasis_plugin_db_postgres_init (void *cls)
}
plugin = GNUNET_new (struct ANASTASIS_DatabasePlugin);
plugin->cls = pg;
- plugin->connect = &postgres_connect;
+ /* FIXME: Should this be the same? */
+ plugin->connect = &postgres_preflight;
plugin->create_tables = &postgres_create_tables;
plugin->drop_tables = &postgres_drop_tables;
plugin->gc = &postgres_gc;
diff --git a/src/stasis/stasis-0001.sql b/src/stasis/stasis-0001.sql
index e0ebfa6..de2762a 100644
--- a/src/stasis/stasis-0001.sql
+++ b/src/stasis/stasis-0001.sql
@@ -40,7 +40,7 @@ COMMENT ON COLUMN anastasis_truth_payment.expiration
CREATE TABLE IF NOT EXISTS anastasis_truth
(truth_uuid BYTEA PRIMARY KEY CHECK(LENGTH(truth_uuid)=32),
- key_share_data BYTEA CHECK(LENGTH(key_share_data)=80) NOT NULL,
+ key_share_data BYTEA CHECK(LENGTH(key_share_data)=72) NOT NULL,
method_name VARCHAR NOT NULL,
encrypted_truth BYTEA NOT NULL,
truth_mime VARCHAR NOT NULL,
diff --git a/src/stasis/test_anastasis_db.c b/src/stasis/test_anastasis_db.c
index 1ec9770..0b696a4 100644
--- a/src/stasis/test_anastasis_db.c
+++ b/src/stasis/test_anastasis_db.c
@@ -3,7 +3,7 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU Affero General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 8fc710b..9a98530 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -19,24 +19,12 @@ libanastasistesting_la_SOURCES = \
testing_api_cmd_keyshare_lookup.c \
testing_api_cmd_config.c \
testing_api_helpers.c \
- testing_api_trait_account_pub.c \
- testing_api_trait_account_priv.c \
- testing_api_trait_eks.c \
- testing_api_trait_payment_secret.c \
- testing_api_trait_truth_key.c \
- testing_api_trait_truth_uuid.c \
- testing_api_trait_hash.c \
- testing_api_trait_salt.c \
- testing_api_trait_code.c \
+ testing_api_traits.c \
testing_cmd_truth_upload.c \
testing_cmd_policy_create.c \
testing_cmd_secret_share.c \
testing_cmd_recover_secret.c \
- testing_cmd_challenge_answer.c \
- testing_trait_truth.c \
- testing_trait_policy.c \
- testing_trait_core_secret.c \
- testing_trait_challenge.c
+ testing_cmd_challenge_answer.c
libanastasistesting_la_LIBADD = \
$(top_builddir)/src/restclient/libanastasisrest.la \
$(top_builddir)/src/lib/libanastasis.la \
diff --git a/src/testing/test_anastasis.c b/src/testing/test_anastasis.c
index f821f20..87d98b0 100644
--- a/src/testing/test_anastasis.c
+++ b/src/testing/test_anastasis.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/testing/test_anastasis_api.c b/src/testing/test_anastasis_api.c
index 2767264..d8064f8 100644
--- a/src/testing/test_anastasis_api.c
+++ b/src/testing/test_anastasis_api.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
diff --git a/src/testing/testing_api_cmd_config.c b/src/testing/testing_api_cmd_config.c
index 58a58dc..b4cf6e0 100644
--- a/src/testing/testing_api_cmd_config.c
+++ b/src/testing/testing_api_cmd_config.c
@@ -3,14 +3,14 @@
Copyright (C) 2019, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -167,10 +167,8 @@ config_traits (void *cls,
unsigned int index)
{
struct ConfigState *ss = cls;
-
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_salt (0,
- &ss->salt),
+ ANASTASIS_TESTING_make_trait_salt (&ss->salt),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_api_cmd_keyshare_lookup.c b/src/testing/testing_api_cmd_keyshare_lookup.c
index 04ecf43..8b06a67 100644
--- a/src/testing/testing_api_cmd_keyshare_lookup.c
+++ b/src/testing/testing_api_cmd_keyshare_lookup.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -222,7 +222,7 @@ keyshare_lookup_run (void *cls,
const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key;
const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid;
const struct ANASTASIS_PaymentSecretP *payment_secret;
- const char *answer;
+ const char **answerp;
ksls->is = is;
if (NULL == ksls->upload_reference)
@@ -244,23 +244,21 @@ keyshare_lookup_run (void *cls,
return;
}
{
- const char *fn;
+ const char **fn;
if (GNUNET_OK !=
- TALER_TESTING_get_trait_string (upload_cmd,
- 0,
- &fn))
+ ANASTASIS_TESTING_get_trait_filename (upload_cmd,
+ &fn))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (ksls->is);
return;
}
- if (NULL != fn)
- ksls->filename = GNUNET_strdup (fn);
+ if (NULL != *fn)
+ ksls->filename = GNUNET_strdup (*fn);
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_truth_uuid (upload_cmd,
- 0,
&truth_uuid))
{
GNUNET_break (0);
@@ -275,7 +273,6 @@ keyshare_lookup_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_truth_key (upload_cmd,
- 0,
&truth_key))
{
GNUNET_break (0);
@@ -304,14 +301,13 @@ keyshare_lookup_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_code (download_cmd,
- 0,
- &answer))
+ &answerp))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (ksls->is);
return;
}
- if (NULL == answer)
+ if (NULL == *answerp)
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (ksls->is);
@@ -321,19 +317,18 @@ keyshare_lookup_run (void *cls,
else
{
/* answer is the answer */
- answer = ksls->answer;
+ answerp = &ksls->answer;
}
if (NULL != ksls->payment_reference)
{
const struct TALER_TESTING_Command *payment_cmd;
- payment_cmd = TALER_TESTING_interpreter_lookup_command
- (is,
- ksls->payment_reference);
+ payment_cmd = TALER_TESTING_interpreter_lookup_command (
+ is,
+ ksls->payment_reference);
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_payment_secret (payment_cmd,
- 0,
&payment_secret))
{
GNUNET_break (0);
@@ -349,9 +344,9 @@ keyshare_lookup_run (void *cls,
{
struct GNUNET_HashCode h_answer;
- if (NULL != answer)
- GNUNET_CRYPTO_hash (answer,
- strlen (answer),
+ if (NULL != *answerp)
+ GNUNET_CRYPTO_hash (*answerp,
+ strlen (*answerp),
&h_answer);
ksls->kslo = ANASTASIS_keyshare_lookup (is->ctx,
ksls->anastasis_url,
@@ -359,7 +354,7 @@ keyshare_lookup_run (void *cls,
truth_key,
payment_secret,
GNUNET_TIME_UNIT_ZERO,
- (NULL != answer)
+ (NULL != *answerp)
? &h_answer
: NULL,
&keyshare_lookup_cb,
@@ -391,6 +386,7 @@ keyshare_lookup_cleanup (void *cls,
GNUNET_free (ksls->pay_uri);
GNUNET_free (ksls->order_id);
GNUNET_free (ksls->code);
+ GNUNET_free (ksls->filename);
GNUNET_free (ksls->instructions);
GNUNET_free (ksls->redirect_uri);
GNUNET_free (ksls);
@@ -406,7 +402,7 @@ keyshare_lookup_cleanup (void *cls,
* @param index index number of the object to extract.
* @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
keyshare_lookup_traits (void *cls,
const void **ret,
const char *trait,
@@ -414,14 +410,14 @@ keyshare_lookup_traits (void *cls,
{
struct KeyShareLookupState *ksls = cls;
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_payment_secret (0,
- &ksls->payment_secret_response),
- TALER_TESTING_make_trait_url (TALER_TESTING_UT_TALER_URL,
- ksls->pay_uri),
- TALER_TESTING_make_trait_order_id (0,
- ksls->order_id),
- ANASTASIS_TESTING_make_trait_code (0,
- ksls->code),
+ ANASTASIS_TESTING_make_trait_payment_secret (
+ &ksls->payment_secret_response),
+ TALER_TESTING_make_trait_payto_uri (
+ (const char **) ksls->pay_uri),
+ TALER_TESTING_make_trait_order_id (
+ (const char **) &ksls->order_id),
+ ANASTASIS_TESTING_make_trait_code (
+ (const char **) &ksls->code),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_api_cmd_policy_lookup.c b/src/testing/testing_api_cmd_policy_lookup.c
index eaff0f2..1f59b12 100644
--- a/src/testing/testing_api_cmd_policy_lookup.c
+++ b/src/testing/testing_api_cmd_policy_lookup.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -140,7 +140,6 @@ policy_lookup_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_hash (upload_cmd,
- ANASTASIS_TESTING_TRAIT_HASH_CURRENT,
&pls->upload_hash))
{
GNUNET_break (0);
@@ -149,7 +148,6 @@ policy_lookup_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_account_pub (upload_cmd,
- 0,
&anastasis_pub))
{
GNUNET_break (0);
diff --git a/src/testing/testing_api_cmd_policy_store.c b/src/testing/testing_api_cmd_policy_store.c
index 4b96472..d1ee3c0 100644
--- a/src/testing/testing_api_cmd_policy_store.c
+++ b/src/testing/testing_api_cmd_policy_store.c
@@ -3,16 +3,16 @@
Copyright (C) 2014-2019 Anastasis SARL
ANASTASIS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
+ it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or
(at your option) any later version.
ANASTASIS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+ GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public
+ You should have received a copy of the GNU General Public
License along with ANASTASIS; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
@@ -229,7 +229,6 @@ policy_store_run (void *cls,
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_account_priv (ref,
- 0,
&priv))
{
GNUNET_break (0);
@@ -243,7 +242,6 @@ policy_store_run (void *cls,
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_account_pub (ref,
- 0,
&pub))
{
GNUNET_break (0);
@@ -257,7 +255,6 @@ policy_store_run (void *cls,
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_payment_secret (ref,
- 0,
&ps))
{
GNUNET_break (0);
@@ -341,18 +338,13 @@ policy_store_traits (void *cls,
{
struct PolicyStoreState *pss = cls;
struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_claim_token (0,
- &pss->claim_token),
- TALER_TESTING_make_trait_order_id (0,
- pss->order_id),
- ANASTASIS_TESTING_make_trait_hash (0,
- &pss->curr_hash),
- ANASTASIS_TESTING_make_trait_account_pub (0,
- &pss->anastasis_pub),
- ANASTASIS_TESTING_make_trait_account_priv (0,
- &pss->anastasis_priv),
- ANASTASIS_TESTING_make_trait_payment_secret (0,
- &pss->payment_secret_response),
+ TALER_TESTING_make_trait_claim_token (&pss->claim_token),
+ TALER_TESTING_make_trait_order_id (
+ (const char **) &pss->order_id),
+ ANASTASIS_TESTING_make_trait_hash (&pss->curr_hash),
+ ANASTASIS_TESTING_make_trait_account_pub (&pss->anastasis_pub),
+ ANASTASIS_TESTING_make_trait_account_priv (&pss->anastasis_priv),
+ ANASTASIS_TESTING_make_trait_payment_secret (&pss->payment_secret_response),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_api_cmd_truth_store.c b/src/testing/testing_api_cmd_truth_store.c
index 141ef20..0972210 100644
--- a/src/testing/testing_api_cmd_truth_store.c
+++ b/src/testing/testing_api_cmd_truth_store.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -205,7 +205,6 @@ truth_store_run (void *cls,
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_truth_uuid (ref,
- 0,
&uuid))
{
GNUNET_break (0);
@@ -215,7 +214,6 @@ truth_store_run (void *cls,
tss->uuid = *uuid;
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_eks (ref,
- 0,
&eks))
{
GNUNET_break (0);
@@ -335,7 +333,7 @@ truth_store_cleanup (void *cls,
* @param index index number of the object to extract.
* @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
truth_store_traits (void *cls,
const void **ret,
const char *trait,
@@ -343,18 +341,14 @@ truth_store_traits (void *cls,
{
struct TruthStoreState *tss = cls;
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_truth_uuid (0,
- &tss->uuid),
- ANASTASIS_TESTING_make_trait_truth_key (0,
- &tss->key),
- ANASTASIS_TESTING_make_trait_eks (0,
- &tss->encrypted_keyshare),
- ANASTASIS_TESTING_make_trait_payment_secret (0,
- &tss->payment_secret_response),
- TALER_TESTING_make_trait_url (TALER_TESTING_UT_TALER_URL,
- tss->pay_uri),
- TALER_TESTING_make_trait_string (0,
- tss->filename),
+ ANASTASIS_TESTING_make_trait_truth_uuid (&tss->uuid),
+ ANASTASIS_TESTING_make_trait_truth_key (&tss->key),
+ ANASTASIS_TESTING_make_trait_eks (&tss->encrypted_keyshare),
+ ANASTASIS_TESTING_make_trait_payment_secret (&tss->payment_secret_response),
+ TALER_TESTING_make_trait_payto_uri (
+ (const char **) &tss->pay_uri),
+ ANASTASIS_TESTING_make_trait_filename (
+ (const char **) &tss->filename),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_api_helpers.c b/src/testing/testing_api_helpers.c
index 15fa136..f131d00 100644
--- a/src/testing/testing_api_helpers.c
+++ b/src/testing/testing_api_helpers.c
@@ -3,16 +3,16 @@
Copyright (C) 2014-2021 Anastasis SARL
ANASTASIS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
+ it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or
(at your option) any later version.
ANASTASIS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
ANASTASISABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+ GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public
+ You should have received a copy of the GNU General Public
License along with ANASTASIS; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
diff --git a/src/testing/testing_api_trait_account_priv.c b/src/testing/testing_api_trait_account_priv.c
deleted file mode 100644
index aa8addd..0000000
--- a/src/testing/testing_api_trait_account_priv.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2019 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Privlic License for more details.
-
- You should have received a copy of the GNU Affero General Privlic
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_account_priv.c
- * @brief traits to offer a account_priv
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_ACCOUNT_PRIV "anastasis-account_priv"
-
-
-int
-ANASTASIS_TESTING_get_trait_account_priv (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPrivateKeyP **priv)
-{
- return cmd->traits (cmd->cls,
- (const void **) priv,
- ANASTASIS_TESTING_TRAIT_ACCOUNT_PRIV,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_account_priv (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPrivateKeyP *priv)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_ACCOUNT_PRIV,
- .ptr = (const void *) priv
- };
-
- return ret;
-}
-
-
-/* end of testing_api_trait_account_priv.c */
diff --git a/src/testing/testing_api_trait_account_pub.c b/src/testing/testing_api_trait_account_pub.c
deleted file mode 100644
index b4bc6f5..0000000
--- a/src/testing/testing_api_trait_account_pub.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2019 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_account_pub.c
- * @brief traits to offer a account_pub
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_ACCOUNT_PUB "anastasis-account_pub"
-
-
-int
-ANASTASIS_TESTING_get_trait_account_pub (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPublicKeyP **pub)
-{
- return cmd->traits (cmd->cls,
- (const void **) pub,
- ANASTASIS_TESTING_TRAIT_ACCOUNT_PUB,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_account_pub (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_AccountPublicKeyP *h)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_ACCOUNT_PUB,
- .ptr = (const void *) h
- };
-
- return ret;
-}
-
-
-/* end of testing_api_trait_account_pub.c */
diff --git a/src/testing/testing_api_trait_code.c b/src/testing/testing_api_trait_code.c
deleted file mode 100644
index bdc289b..0000000
--- a/src/testing/testing_api_trait_code.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2019 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_code.c
- * @brief traits to offers a code for a challenge
- * @author Dominik Meister
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_CODE "anastasis-code"
-
-
-int
-ANASTASIS_TESTING_get_trait_code (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const char **code)
-{
- return cmd->traits (cmd->cls,
- (const void **) code,
- ANASTASIS_TESTING_TRAIT_CODE,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_code (
- unsigned int index,
- const char *code)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_CODE,
- .ptr = (const void *) code
- };
-
- return ret;
-}
-
-
-/* end of testing_api_trait_code.c */
diff --git a/src/testing/testing_api_trait_eks.c b/src/testing/testing_api_trait_eks.c
deleted file mode 100644
index d148456..0000000
--- a/src/testing/testing_api_trait_eks.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2021 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_eks.c
- * @brief traits to offer a payment identifier
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_EKS \
- "anastasis-eks"
-
-
-int
-ANASTASIS_TESTING_get_trait_eks (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_EncryptedKeyShareP **eks)
-{
- return cmd->traits (cmd->cls,
- (const void **) eks,
- ANASTASIS_TESTING_TRAIT_EKS,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_eks (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_EncryptedKeyShareP *eks)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_EKS,
- .ptr = (const void *) eks
- };
- return ret;
-}
-
-
-/* end of testing_api_trait_eks.c */
diff --git a/src/testing/testing_api_trait_hash.c b/src/testing/testing_api_trait_hash.c
deleted file mode 100644
index 9f9d554..0000000
--- a/src/testing/testing_api_trait_hash.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2019 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file anastasis/src/testing/testing_api_trait_hash.c
- * @brief traits to offer a hash
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_HASH "anastasis-hash"
-
-
-int
-ANASTASIS_TESTING_get_trait_hash (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct GNUNET_HashCode **h)
-{
- return cmd->traits (cmd->cls,
- (const void **) h,
- ANASTASIS_TESTING_TRAIT_HASH,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_hash (
- unsigned int index,
- const struct GNUNET_HashCode *h)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_HASH,
- .ptr = (const void *) h
- };
- return ret;
-}
-
-
-/* end of testing_api_trait_hash.c */
diff --git a/src/testing/testing_api_trait_payment_secret.c b/src/testing/testing_api_trait_payment_secret.c
deleted file mode 100644
index aa580da..0000000
--- a/src/testing/testing_api_trait_payment_secret.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2019 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_payment_secret.c
- * @brief traits to offer a payment identifier
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_PAYMENT_SECRET \
- "anastasis-payment_secret"
-
-
-int
-ANASTASIS_TESTING_get_trait_payment_secret (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_PaymentSecretP **payment_secret)
-{
- return cmd->traits (cmd->cls,
- (const void **) payment_secret,
- ANASTASIS_TESTING_TRAIT_PAYMENT_SECRET,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_payment_secret (
- unsigned int index,
- const struct ANASTASIS_PaymentSecretP *h)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_PAYMENT_SECRET,
- .ptr = (const void *) h
- };
-
- return ret;
-}
-
-
-/* end of testing_api_trait_payment_secret.c */
diff --git a/src/testing/testing_api_trait_salt.c b/src/testing/testing_api_trait_salt.c
deleted file mode 100644
index 178b092..0000000
--- a/src/testing/testing_api_trait_salt.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2020 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_salt.c
- * @brief traits to offer a hash
- * @author Christian Grothoff
- * @author Dominik Meister
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_SALT "anastasis-provider-salt"
-
-
-int
-ANASTASIS_TESTING_get_trait_salt (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_ProviderSaltP **s)
-{
- return cmd->traits (cmd->cls,
- (const void **) s,
- ANASTASIS_TESTING_TRAIT_SALT,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_salt (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_ProviderSaltP *s)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_SALT,
- .ptr = (const void *) s
- };
-
- return ret;
-}
-
-
-/* end of testing_api_trait_salt.c */
diff --git a/src/testing/testing_api_trait_truth_key.c b/src/testing/testing_api_trait_truth_key.c
deleted file mode 100644
index 5de8860..0000000
--- a/src/testing/testing_api_trait_truth_key.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2019, 2021 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_truth_key.c
- * @brief traits to offer a payment identifier
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_TRUTH_KEY \
- "anastasis-truth_key"
-
-
-int
-ANASTASIS_TESTING_get_trait_truth_key
- (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthKeyP **truth_key)
-{
- return cmd->traits (cmd->cls,
- (const void **) truth_key,
- ANASTASIS_TESTING_TRAIT_TRUTH_KEY,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_truth_key
- (unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthKeyP *h)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_TRUTH_KEY,
- .ptr = (const void *) h
- };
- return ret;
-}
-
-
-/* end of testing_api_trait_truth_key.c */
diff --git a/src/testing/testing_api_trait_truth_uuid.c b/src/testing/testing_api_trait_truth_uuid.c
deleted file mode 100644
index 7eba4b0..0000000
--- a/src/testing/testing_api_trait_truth_uuid.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2020 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_api_trait_truth_uuid.c
- * @brief traits to offer a UUID for some truth
- * @author Christian Grothoff
- * @author Dominik Meister
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-
-#define ANASTASIS_TESTING_TRAIT_TRUTH_UUID "anastasis-truth-uuid"
-
-
-int
-ANASTASIS_TESTING_get_trait_truth_uuid (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthUUIDP **tpk)
-{
- return cmd->traits (cmd->cls,
- (const void **) tpk,
- ANASTASIS_TESTING_TRAIT_TRUTH_UUID,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_truth_uuid (
- unsigned int index,
- const struct ANASTASIS_CRYPTO_TruthUUIDP *tpk)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_TRUTH_UUID,
- .ptr = (const void *) tpk
- };
-
- return ret;
-}
-
-
-/* end of testing_api_trait_truth_uuid.c */
diff --git a/src/testing/testing_api_traits.c b/src/testing/testing_api_traits.c
new file mode 100644
index 0000000..79b78a5
--- /dev/null
+++ b/src/testing/testing_api_traits.c
@@ -0,0 +1,36 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2018, 2021 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3, or
+ (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file testing/testing_api_traits.c
+ * @brief loop for trait resolution
+ * @author Christian Grothoff
+ * @author Marcello Stanisci
+ */
+#include "platform.h"
+#include "anastasis_testing_lib.h"
+#include <taler/taler_json_lib.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include <taler/taler_testing_lib.h>
+
+
+ANASTASIS_TESTING_SIMPLE_TRAITS (ANASTASIS_TESTING_MAKE_IMPL_SIMPLE_TRAIT)
+
+ANASTASIS_TESTING_INDEXED_TRAITS (ANASTASIS_TESTING_MAKE_IMPL_INDEXED_TRAIT)
+
+/* end of testing_api_traits.c */
diff --git a/src/testing/testing_cmd_challenge_answer.c b/src/testing/testing_cmd_challenge_answer.c
index ff897f3..78f7404 100644
--- a/src/testing/testing_cmd_challenge_answer.c
+++ b/src/testing/testing_cmd_challenge_answer.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -91,7 +91,7 @@ struct ChallengeState
/**
* code we read in the file generated by the plugin
*/
- char code[22];
+ char *code;
};
@@ -166,6 +166,7 @@ challenge_answer_cb (void *af_cls,
TALER_TESTING_interpreter_fail (cs->is);
return;
}
+ cs->code = GNUNET_malloc (22);
if (0 == fscanf (file,
"%21s",
cs->code))
@@ -259,7 +260,7 @@ challenge_answer_run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
struct ChallengeState *cs = cls;
- const struct ANASTASIS_Challenge *c;
+ const struct ANASTASIS_Challenge **c;
const struct ANASTASIS_PaymentSecretP *ps;
cs->is = is;
@@ -277,14 +278,15 @@ challenge_answer_run (void *cls,
return;
}
if (GNUNET_OK !=
- ANASTASIS_TESTING_get_trait_challenge (ref,
- cs->challenge_index,
- &c))
+ ANASTASIS_TESTING_get_trait_challenges (ref,
+ cs->challenge_index,
+ &c))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (cs->is);
return;
}
+ cs->c = (struct ANASTASIS_Challenge *) *c;
}
if (NULL != cs->payment_ref)
@@ -301,7 +303,6 @@ challenge_answer_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_payment_secret (ref,
- 0,
&ps))
{
GNUNET_break (0);
@@ -314,12 +315,10 @@ challenge_answer_run (void *cls,
ps = NULL;
}
- cs->c = (struct ANASTASIS_Challenge *) c;
-
if (1 == cs->mode)
{
const struct TALER_TESTING_Command *ref;
- const char *answer;
+ const char **answer;
unsigned long long code;
char dummy;
@@ -333,7 +332,6 @@ challenge_answer_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_code (ref,
- 0,
&answer))
{
GNUNET_break (0);
@@ -341,7 +339,7 @@ challenge_answer_run (void *cls,
return;
}
if (1 !=
- sscanf (answer,
+ sscanf (*answer,
"%llu%c",
&code,
&dummy))
@@ -397,7 +395,7 @@ challenge_start_run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
struct ChallengeState *cs = cls;
- const struct ANASTASIS_Challenge *c;
+ const struct ANASTASIS_Challenge **c;
const struct TALER_TESTING_Command *ref;
const struct ANASTASIS_PaymentSecretP *ps;
@@ -412,9 +410,9 @@ challenge_start_run (void *cls,
return;
}
if (GNUNET_OK !=
- ANASTASIS_TESTING_get_trait_challenge (ref,
- cs->challenge_index,
- &c))
+ ANASTASIS_TESTING_get_trait_challenges (ref,
+ cs->challenge_index,
+ &c))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (cs->is);
@@ -434,7 +432,6 @@ challenge_start_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_payment_secret (ref,
- 0,
&ps))
{
GNUNET_break (0);
@@ -447,7 +444,7 @@ challenge_start_run (void *cls,
ps = NULL;
}
if (GNUNET_OK !=
- ANASTASIS_challenge_start ((struct ANASTASIS_Challenge *) c,
+ ANASTASIS_challenge_start ((struct ANASTASIS_Challenge *) *c,
ps,
GNUNET_TIME_UNIT_ZERO,
NULL,
@@ -484,6 +481,7 @@ challenge_cleanup (void *cls,
}
GNUNET_free (cs->payment_uri);
GNUNET_free (cs->order_id);
+ GNUNET_free (cs->code);
GNUNET_free (cs);
}
@@ -497,7 +495,7 @@ challenge_cleanup (void *cls,
* @param index index number of the object to extract.
* @return #GNUNET_OK on success
*/
-static int
+static enum GNUNET_GenericReturnValue
challenge_create_traits (void *cls,
const void **ret,
const char *trait,
@@ -505,14 +503,14 @@ challenge_create_traits (void *cls,
{
struct ChallengeState *cs = cls;
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_code (0,
- cs->code),
- ANASTASIS_TESTING_make_trait_payment_secret (0,
- &cs->payment_order_req),
- TALER_TESTING_make_trait_url (TALER_TESTING_UT_TALER_URL,
- cs->payment_uri),
- TALER_TESTING_make_trait_order_id (0,
- cs->order_id),
+ ANASTASIS_TESTING_make_trait_code (
+ (const char **) &cs->code),
+ ANASTASIS_TESTING_make_trait_payment_secret (
+ &cs->payment_order_req),
+ TALER_TESTING_make_trait_payto_uri (
+ (const char **) cs->payment_uri),
+ TALER_TESTING_make_trait_order_id (
+ (const char **) &cs->order_id),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_cmd_policy_create.c b/src/testing/testing_cmd_policy_create.c
index 62ad71f..64f7060 100644
--- a/src/testing/testing_cmd_policy_create.c
+++ b/src/testing/testing_cmd_policy_create.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -82,7 +82,7 @@ policy_create_run (void *cls,
for (unsigned int i = 0; i < pcs->cmd_label_array_length; i++)
{
const struct TALER_TESTING_Command *ref;
- const struct ANASTASIS_Truth *truth;
+ const struct ANASTASIS_Truth **truth;
ref = TALER_TESTING_interpreter_lookup_command (is,
pcs->cmd_label_array[i]);
@@ -94,15 +94,14 @@ policy_create_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_truth (ref,
- 0,
&truth))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (pcs->is);
return;
}
- GNUNET_assert (NULL != truth);
- truths[i] = truth;
+ GNUNET_assert (NULL != *truth);
+ truths[i] = *truth;
}
}
@@ -159,8 +158,8 @@ policy_create_traits (void *cls,
{
struct PolicyCreateState *pcs = cls;
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_policy (0,
- pcs->policy),
+ ANASTASIS_TESTING_make_trait_policy (
+ (const struct ANASTASIS_Policy **) &pcs->policy),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_cmd_recover_secret.c b/src/testing/testing_cmd_recover_secret.c
index 55c0168..153143d 100644
--- a/src/testing/testing_cmd_recover_secret.c
+++ b/src/testing/testing_cmd_recover_secret.c
@@ -3,14 +3,14 @@
Copyright (C) 2020, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -79,7 +79,7 @@ struct RecoverSecretState
/**
* Coresecret to check if decryption worked
*/
- const void *core_secret;
+ const void **core_secret;
/**
* Task scheduled to wait for recovery to complete.
@@ -151,7 +151,7 @@ core_secret_cb (void *cls,
return;
}
if (0 != memcmp (secret,
- rss->core_secret,
+ *rss->core_secret,
secret_size))
{
GNUNET_break (0);
@@ -204,7 +204,6 @@ recover_secret_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_salt (ref,
- 0,
&salt))
{
GNUNET_break (0);
@@ -224,9 +223,9 @@ recover_secret_run (void *cls,
return;
}
if (GNUNET_OK !=
- ANASTASIS_TESTING_get_trait_core_secret (ref,
- 0,
- &rss->core_secret))
+ ANASTASIS_TESTING_get_trait_core_secret (
+ ref,
+ (const void ***) &rss->core_secret))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (rss->is);
@@ -327,8 +326,9 @@ recover_secret_traits (void *cls,
}
{
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_challenge (index,
- rss->ri->cs[index]),
+ ANASTASIS_TESTING_make_trait_challenges (
+ index,
+ (const struct ANASTASIS_Challenge **) &rss->ri->cs[index]),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_cmd_secret_share.c b/src/testing/testing_cmd_secret_share.c
index d9122e8..7a9dbc0 100644
--- a/src/testing/testing_cmd_secret_share.c
+++ b/src/testing/testing_cmd_secret_share.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -199,7 +199,7 @@ secret_share_run (void *cls,
for (unsigned int i = 0; i < sss->cmd_label_array_length; i++)
{
const struct TALER_TESTING_Command *ref;
- const struct ANASTASIS_Policy *policy;
+ const struct ANASTASIS_Policy **policy;
ref = TALER_TESTING_interpreter_lookup_command (is,
sss->cmd_label_array[i]);
@@ -211,22 +211,21 @@ secret_share_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_policy (ref,
- 0,
&policy))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (sss->is);
return;
}
- GNUNET_assert (NULL != policy);
- policies[i] = policy;
+ GNUNET_assert (NULL != *policy);
+ policies[i] = *policy;
}
}
if (NULL != sss->prev_secret_share)
{
const struct TALER_TESTING_Command *ref;
- const char *order_id;
+ const char **order_id;
ref = TALER_TESTING_interpreter_lookup_command (is,
sss->prev_secret_share);
@@ -238,14 +237,13 @@ secret_share_run (void *cls,
}
if (GNUNET_OK !=
TALER_TESTING_get_trait_order_id (ref,
- 0,
&order_id))
{
GNUNET_break (0);
TALER_TESTING_interpreter_fail (sss->is);
return;
}
- sss->payment_order_id = (char *) order_id;
+ sss->payment_order_id = (char *) *order_id;
if (NULL == sss->payment_order_id)
{
@@ -289,7 +287,6 @@ secret_share_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_salt (ref,
- 0,
&salt))
{
GNUNET_break (0);
@@ -368,12 +365,10 @@ secret_share_traits (void *cls,
{
struct SecretShareState *sss = cls;
struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_claim_token (0,
- &sss->token),
- ANASTASIS_TESTING_make_trait_core_secret (0,
- sss->core_secret),
- TALER_TESTING_make_trait_order_id (0,
- sss->payment_order_id),
+ TALER_TESTING_make_trait_claim_token (&sss->token),
+ ANASTASIS_TESTING_make_trait_core_secret (&sss->core_secret),
+ TALER_TESTING_make_trait_order_id (
+ (const char **) &sss->payment_order_id),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_cmd_truth_upload.c b/src/testing/testing_cmd_truth_upload.c
index 19692c8..99c2879 100644
--- a/src/testing/testing_cmd_truth_upload.c
+++ b/src/testing/testing_cmd_truth_upload.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -198,7 +198,6 @@ truth_upload_run (void *cls,
}
if (GNUNET_OK !=
ANASTASIS_TESTING_get_trait_salt (ref,
- 0,
&salt))
{
GNUNET_break (0);
@@ -285,10 +284,9 @@ truth_upload_traits (void *cls,
{
struct TruthUploadState *tus = cls;
struct TALER_TESTING_Trait traits[] = {
- ANASTASIS_TESTING_make_trait_truth (0,
- tus->truth),
- ANASTASIS_TESTING_make_trait_payment_secret (0,
- &tus->payment_secret_response),
+ ANASTASIS_TESTING_make_trait_truth (
+ (const struct ANASTASIS_Truth **) &tus->truth),
+ ANASTASIS_TESTING_make_trait_payment_secret (&tus->payment_secret_response),
TALER_TESTING_trait_end ()
};
diff --git a/src/testing/testing_trait_challenge.c b/src/testing/testing_trait_challenge.c
deleted file mode 100644
index f0485a1..0000000
--- a/src/testing/testing_trait_challenge.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2020 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_trait_challenge.c
- * @brief traits to offer a challenge
- * @author Christian Grothoff
- * @author Dominik Meister
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_CHALLENGE "anastasis-challenge"
-
-
-int
-ANASTASIS_TESTING_get_trait_challenge (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_Challenge **c)
-{
- return cmd->traits (cmd->cls,
- (const void **) c,
- ANASTASIS_TESTING_TRAIT_CHALLENGE,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_challenge (unsigned int index,
- const struct ANASTASIS_Challenge *c)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_CHALLENGE,
- .ptr = (const void *) c
- };
- return ret;
-}
-
-
-/* end of testing_trait_challenge.c */
diff --git a/src/testing/testing_trait_core_secret.c b/src/testing/testing_trait_core_secret.c
deleted file mode 100644
index e6aee0f..0000000
--- a/src/testing/testing_trait_core_secret.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2020 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_trait_core_secret.c
- * @brief traits to offer the core secret
- * @author Christian Grothoff
- * @author Dominik Meister
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_CORE_SECRET "anastasis-core-secret"
-
-
-int
-ANASTASIS_TESTING_get_trait_core_secret (const struct
- TALER_TESTING_Command *cmd,
- unsigned int index,
- const void **s)
-{
- return cmd->traits (cmd->cls,
- s,
- ANASTASIS_TESTING_TRAIT_CORE_SECRET,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_core_secret (unsigned int index,
- const void *s)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_CORE_SECRET,
- .ptr = s
- };
-
- return ret;
-}
-
-
-/* end of testing_trait_core_secret.c */
diff --git a/src/testing/testing_trait_policy.c b/src/testing/testing_trait_policy.c
deleted file mode 100644
index 0944088..0000000
--- a/src/testing/testing_trait_policy.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2020 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_trait_policy.c
- * @brief traits to offer a policy
- * @author Christian Grothoff
- * @author Dominik Meister
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_POLICY "anastasis-policy"
-
-
-int
-ANASTASIS_TESTING_get_trait_policy (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_Policy **p)
-{
- return cmd->traits (cmd->cls,
- (const void **) p,
- ANASTASIS_TESTING_TRAIT_POLICY,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_policy (unsigned int index,
- const struct ANASTASIS_Policy *p)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_POLICY,
- .ptr = (const void *) p
- };
-
- return ret;
-}
-
-
-/* end of testing_trait_policy.c */
diff --git a/src/testing/testing_trait_truth.c b/src/testing/testing_trait_truth.c
deleted file mode 100644
index 559fd9e..0000000
--- a/src/testing/testing_trait_truth.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- This file is part of Anastasis
- Copyright (C) 2020 Anastasis SARL
-
- Anastasis is free software; you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- Anastasis is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public
- License along with Anastasis; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file testing/testing_trait_truth.c
- * @brief traits to offer a truth
- * @author Christian Grothoff
- * @author Dominik Meister
- * @author Dennis Neufeld
- */
-#include "platform.h"
-#include "anastasis_testing_lib.h"
-
-#define ANASTASIS_TESTING_TRAIT_TRUTH "anastasis-truth"
-
-
-int
-ANASTASIS_TESTING_get_trait_truth (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct ANASTASIS_Truth **t)
-{
- return cmd->traits (cmd->cls,
- (const void **) t,
- ANASTASIS_TESTING_TRAIT_TRUTH,
- index);
-}
-
-
-struct TALER_TESTING_Trait
-ANASTASIS_TESTING_make_trait_truth (unsigned int index,
- const struct ANASTASIS_Truth *t)
-{
- struct TALER_TESTING_Trait ret = {
- .index = index,
- .trait_name = ANASTASIS_TESTING_TRAIT_TRUTH,
- .ptr = (const void *) t
- };
-
- return ret;
-}
-
-
-/* end of testing_trait_truth.c */
diff --git a/src/util/.gitignore b/src/util/.gitignore
new file mode 100644
index 0000000..80af6f7
--- /dev/null
+++ b/src/util/.gitignore
@@ -0,0 +1 @@
+anastasis-crypto-tvg
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 657ec0c..22c7a1c 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -6,6 +6,9 @@ if USE_COVERAGE
XLIB = -lgcov
endif
+bin_PROGRAMS = \
+ anastasis-crypto-tvg
+
pkgcfgdir = $(prefix)/share/anastasis/config.d/
pkgcfg_DATA = \
@@ -35,6 +38,7 @@ libanastasisutil_la_SOURCES = \
libanastasisutil_la_LIBADD = \
-lgnunetutil \
$(LIBGCRYPT_LIBS) \
+ -lsodium \
-ljansson \
-ltalerutil \
$(XLIB)
@@ -51,7 +55,18 @@ TESTS = \
test_anastasis_crypto_SOURCES = \
test_anastasis_crypto.c
test_anastasis_crypto_LDADD = \
+ $(top_builddir)/src/util/libanastasisutil.la \
-lgnunetutil \
-ltalerutil \
+ $(XLIB)
+
+anastasis_crypto_tvg_SOURCES = \
+ anastasis-crypto-tvg.c
+anastasis_crypto_tvg_LDADD = \
libanastasisutil.la \
+ -ltalerjson \
+ -ltalerutil \
+ -lgnunetjson \
+ -lgnunetutil \
+ -ljansson \
$(XLIB)
diff --git a/src/util/anastasis-config.c b/src/util/anastasis-config.c
index 0c2cb29..34574d1 100644
--- a/src/util/anastasis-config.c
+++ b/src/util/anastasis-config.c
@@ -3,16 +3,16 @@
Copyright (C) 2012-2021 Anastasis Systems SA
Anastasis is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
+ under the terms of the GNU General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
+ General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL3.0-or-later
diff --git a/src/util/anastasis-crypto-tvg.c b/src/util/anastasis-crypto-tvg.c
new file mode 100644
index 0000000..a606e85
--- /dev/null
+++ b/src/util/anastasis-crypto-tvg.c
@@ -0,0 +1,619 @@
+/*
+ This file is part of Anastasis
+ Copyright (C) 2020,2021 Anastasis SARL
+
+ Anastasis is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
+*/
+
+
+/**
+ * @file util/anastasis-crypto-tgv.c
+ * @brief Generate test vectors for cryptographic operations.
+ * @author Florian Dold
+ *
+ *
+ * Test vectors have the following format (TypeScript pseudo code):
+ *
+ * interface TestVectorFile {
+ * encoding: "base32crockford";
+ * producer?: string;
+ * vectors: TestVector[];
+ * }
+ *
+ * enum Operation {
+ * Hash("hash"),
+ * ...
+ * }
+ *
+ * interface TestVector {
+ * operation: Operation;
+ * // Inputs for the operation
+ * [ k: string]: string | number;
+ * };
+ *
+ *
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_signatures.h>
+#include <gnunet/gnunet_testing_lib.h>
+#include <jansson.h>
+#include <gcrypt.h>
+#include "anastasis_crypto_lib.h"
+
+
+/**
+ * Should we verify or output test vectors?
+ */
+static int verify_flag = GNUNET_NO;
+
+
+/**
+ * Global exit code.
+ */
+static int global_ret = 0;
+
+
+/**
+ * Create a fresh test vector for a given operation label.
+ *
+ * @param vecs array of vectors to append the new vector to
+ * @param vecname label for the operation of the vector
+ * @returns the fresh test vector
+ */
+static json_t *
+vec_for (json_t *vecs, const char *vecname)
+{
+ json_t *t = json_object ();
+
+ json_object_set_new (t,
+ "operation",
+ json_string (vecname));
+ json_array_append_new (vecs, t);
+ return t;
+}
+
+
+/**
+ * Add a base32crockford encoded value
+ * to a test vector.
+ *
+ * @param vec test vector to add to
+ * @param label label for the value
+ * @param data data to add
+ * @param size size of data
+ */
+static void
+d2j (json_t *vec,
+ const char *label,
+ const void *data,
+ size_t size)
+{
+ char *buf;
+ json_t *json;
+
+ buf = GNUNET_STRINGS_data_to_string_alloc (data, size);
+ json = json_string (buf);
+ GNUNET_free (buf);
+ GNUNET_break (NULL != json);
+
+ json_object_set_new (vec, label, json);
+}
+
+
+static void
+d2j_append (json_t *arr,
+ const void *data,
+ size_t size)
+{
+ char *buf;
+ json_t *json;
+
+ buf = GNUNET_STRINGS_data_to_string_alloc (data, size);
+ json = json_string (buf);
+ GNUNET_free (buf);
+ GNUNET_break (NULL != json);
+
+ json_array_append_new (arr,
+ json);
+}
+
+
+#define d2j_auto(vec, label, d) d2j (vec, label, d, sizeof (*d))
+#define d2j_append_auto(arr, d) d2j_append (arr, d, sizeof (*d))
+#define random_auto(d) GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, \
+ d, \
+ sizeof (*d));
+
+/**
+ * Add a number to a test vector.
+ *
+ * @param vec test vector to add to
+ * @param label label for the value
+ * @param data data to add
+ * @param size size of data
+ */
+static void
+uint2j (json_t *vec,
+ const char *label,
+ unsigned int num)
+{
+ json_t *json = json_integer (num);
+
+ json_object_set_new (vec, label, json);
+}
+
+
+static int
+expect_data_fixed (json_t *vec,
+ const char *name,
+ void *data,
+ size_t expect_len)
+{
+ const char *s = json_string_value (json_object_get (vec, name));
+
+ if (NULL == s)
+ return GNUNET_NO;
+
+ if (GNUNET_OK != GNUNET_STRINGS_string_to_data (s,
+ strlen (s),
+ data,
+ expect_len))
+ return GNUNET_NO;
+ return GNUNET_OK;
+}
+
+
+static int
+expect_data_dynamic (json_t *vec,
+ const char *name,
+ void **data,
+ size_t *ret_len)
+{
+ const char *s = json_string_value (json_object_get (vec, name));
+ char *tmp;
+ size_t len;
+
+ if (NULL == s)
+ return GNUNET_NO;
+
+ len = (strlen (s) * 5) / 8;
+ if (NULL != ret_len)
+ *ret_len = len;
+ tmp = GNUNET_malloc (len);
+
+ if (GNUNET_OK != GNUNET_STRINGS_string_to_data (s, strlen (s), tmp, len))
+ {
+ GNUNET_free (tmp);
+ return GNUNET_NO;
+ }
+ *data = tmp;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Check a single vector.
+ *
+ * @param operation operator of the vector
+ * @param vec the vector, a JSON object.
+ *
+ * @returns GNUNET_OK if the vector is okay
+ */
+static int
+checkvec (const char *operation,
+ json_t *vec)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "checking %s\n", operation);
+
+ if (0 == strcmp (operation, "hash"))
+ {
+ void *data;
+ size_t data_len;
+ struct GNUNET_HashCode hash_out;
+ struct GNUNET_HashCode hc;
+
+ if (GNUNET_OK != expect_data_dynamic (vec,
+ "input",
+ &data,
+ &data_len))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK != expect_data_fixed (vec,
+ "output",
+ &hash_out,
+ sizeof (hash_out)))
+ {
+ GNUNET_free (data);
+ GNUNET_break (0);
+ return GNUNET_NO;
+ }
+
+ GNUNET_CRYPTO_hash (data, data_len, &hc);
+
+ if (0 != GNUNET_memcmp (&hc, &hash_out))
+ {
+ GNUNET_free (data);
+ GNUNET_break (0);
+ return GNUNET_NO;
+ }
+ GNUNET_free (data);
+ }
+
+ return GNUNET_OK;
+}
+
+
+/**
+ * Check test vectors from stdin.
+ *
+ * @returns global exit code
+ */
+static int
+check_vectors ()
+{
+ json_error_t err;
+ json_t *vecfile = json_loadf (stdin, 0, &err);
+ const char *encoding;
+ json_t *vectors;
+
+ if (NULL == vecfile)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "unable to parse JSON\n");
+ return 1;
+ }
+ encoding = json_string_value (json_object_get (vecfile,
+ "encoding"));
+ if ( (NULL == encoding) || (0 != strcmp (encoding, "base32crockford")) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "unsupported or missing encoding\n");
+ json_decref (vecfile);
+ return 1;
+ }
+ vectors = json_object_get (vecfile, "vectors");
+ if (! json_is_array (vectors))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bad vectors\n");
+ json_decref (vecfile);
+ return 1;
+ }
+ {
+ /* array is a JSON array */
+ size_t index;
+ json_t *value;
+ int ret;
+
+ json_array_foreach (vectors, index, value) {
+ const char *op = json_string_value (json_object_get (value,
+ "operation"));
+
+ if (NULL == op)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "missing operation\n");
+ ret = GNUNET_SYSERR;
+ break;
+ }
+ ret = checkvec (op, value);
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "bad vector %u\n",
+ (unsigned int) index);
+ break;
+ }
+ }
+ return (ret == GNUNET_OK) ? 0 : 1;
+ }
+}
+
+
+/**
+ * Output test vectors.
+ *
+ * @returns global exit code
+ */
+static int
+output_vectors ()
+{
+ json_t *vecfile = json_object ();
+ json_t *vecs = json_array ();
+
+ json_object_set_new (vecfile,
+ "encoding",
+ json_string ("base32crockford"));
+ json_object_set_new (vecfile,
+ "producer",
+ json_string (
+ "GNU Anastasis (C implementation) " PACKAGE_VERSION " "
+ VCS_VERSION));
+ json_object_set_new (vecfile,
+ "vectors",
+ vecs);
+
+ {
+ json_t *vec = vec_for (vecs, "hash");
+ struct GNUNET_HashCode hc;
+ char *str = "Hello, GNUnet";
+
+ GNUNET_CRYPTO_hash (str, strlen (str), &hc);
+
+ d2j (vec, "input", str, strlen (str));
+ d2j (vec, "output", &hc, sizeof (struct GNUNET_HashCode));
+ }
+
+ {
+ json_t *vec = vec_for (vecs, "user_identifier_derive");
+ struct ANASTASIS_CRYPTO_ProviderSaltP server_salt;
+ struct ANASTASIS_CRYPTO_UserIdentifierP id;
+ json_t *id_data = json_pack ("{s:s, s:s}",
+ "name",
+ "Fleabag",
+ "ssn",
+ "AB123");
+ GNUNET_assert (NULL != id_data);
+ random_auto (&server_salt);
+
+ ANASTASIS_CRYPTO_user_identifier_derive (id_data,
+ &server_salt,
+ &id);
+ json_object_set_new (vec, "input_id_data", id_data);
+ d2j_auto (vec, "input_server_salt", &server_salt);
+ d2j_auto (vec, "output_id", &id);
+ }
+
+ {
+ json_t *vec = vec_for (vecs, "account_keypair_derive");
+ struct ANASTASIS_CRYPTO_UserIdentifierP id;
+ struct ANASTASIS_CRYPTO_AccountPrivateKeyP priv_key;
+ struct ANASTASIS_CRYPTO_AccountPublicKeyP pub_key;
+
+ random_auto (&id);
+ ANASTASIS_CRYPTO_account_public_key_derive (&id, &pub_key);
+ ANASTASIS_CRYPTO_account_private_key_derive (&id, &priv_key);
+
+ d2j_auto (vec, "input_id", &id);
+ d2j_auto (vec, "output_priv_key", &priv_key);
+ d2j_auto (vec, "output_pub_key", &pub_key);
+
+ }
+
+ {
+ json_t *vec = vec_for (vecs, "secure_answer_hash");
+ const char *answer = "Blah";
+ struct ANASTASIS_CRYPTO_TruthUUIDP uuid;
+ struct ANASTASIS_CRYPTO_QuestionSaltP salt;
+ struct GNUNET_HashCode result;
+
+ random_auto (&uuid);
+ random_auto (&salt);
+ ANASTASIS_CRYPTO_secure_answer_hash (answer, &uuid, &salt, &result);
+ json_object_set_new (vec, "input_answer", json_string (answer));
+ d2j_auto (vec, "input_uuid", &uuid);
+ d2j_auto (vec, "input_salt", &salt);
+ d2j_auto (vec, "output_hash", &result);
+ }
+
+ {
+ json_t *vec = vec_for (vecs, "recovery_document_encryption");
+ struct ANASTASIS_CRYPTO_UserIdentifierP id;
+ void *rec_doc = "my recovery doc";
+ size_t rd_size = strlen (rec_doc) + 1;
+ void *enc_rec_doc;
+ size_t erd_size;
+
+ random_auto (&id);
+
+ ANASTASIS_CRYPTO_recovery_document_encrypt (&id,
+ rec_doc,
+ rd_size,
+ &enc_rec_doc,
+ &erd_size);
+ d2j_auto (vec, "input_user_id", &id);
+ d2j (vec, "input_recovery_document", rec_doc, rd_size);
+ d2j (vec, "output_encrypted_recovery_document", &enc_rec_doc, erd_size);
+ }
+
+ {
+ /* With extra salt */
+ json_t *vec = vec_for (vecs, "keyshare_encryption");
+ struct ANASTASIS_CRYPTO_KeyShareP key_share;
+ struct ANASTASIS_CRYPTO_UserIdentifierP id;
+ char *xsalt = "myanswer";
+ struct ANASTASIS_CRYPTO_EncryptedKeyShareP enc_key_share;
+
+ random_auto (&key_share);
+ random_auto (&id);
+
+ ANASTASIS_CRYPTO_keyshare_encrypt (&key_share,
+ &id,
+ xsalt,
+ &enc_key_share);
+ d2j_auto (vec, "input_key_share", &key_share);
+ d2j_auto (vec, "input_user_id", &id);
+ json_object_set_new (vec, "input_xsalt", json_string (xsalt));
+ d2j_auto (vec, "output_enc_key_share", &enc_key_share);
+ }
+
+ {
+ /* Without extra salt */
+ json_t *vec = vec_for (vecs, "keyshare_encryption");
+ struct ANASTASIS_CRYPTO_KeyShareP key_share;
+ struct ANASTASIS_CRYPTO_UserIdentifierP id;
+ char *xsalt = NULL;
+ struct ANASTASIS_CRYPTO_EncryptedKeyShareP enc_key_share;
+
+ random_auto (&key_share);
+ random_auto (&id);
+
+ ANASTASIS_CRYPTO_keyshare_encrypt (&key_share,
+ &id,
+ xsalt,
+ &enc_key_share);
+ d2j_auto (vec, "input_key_share", &key_share);
+ d2j_auto (vec, "input_user_id", &id);
+ json_object_set_new (vec, "input_xsalt", json_null ());
+ d2j_auto (vec, "output_enc_key_share", &enc_key_share);
+ }
+
+ {
+ json_t *vec = vec_for (vecs, "truth_encryption");
+
+ struct ANASTASIS_CRYPTO_NonceP nonce;
+ struct ANASTASIS_CRYPTO_TruthKeyP truth_enc_key;
+ char truth[256];
+ size_t truth_size = 256;
+ void *enc_truth;
+ size_t ect_size;
+
+ random_auto (&nonce);
+ random_auto (&truth);
+ random_auto (&truth_enc_key);
+
+ ANASTASIS_CRYPTO_truth_encrypt (&nonce,
+ &truth_enc_key,
+ truth,
+ truth_size,
+ &enc_truth,
+ &ect_size);
+
+ d2j_auto (vec, "input_nonce", &nonce);
+ d2j_auto (vec, "input_truth_enc_key", &truth_enc_key);
+ d2j (vec, "input_truth", &truth, truth_size);
+ d2j (vec, "output_encrypted_truth", enc_truth, ect_size);
+ }
+
+ {
+ json_t *vec = vec_for (vecs, "policy_key_derive");
+
+ struct ANASTASIS_CRYPTO_KeyShareP key_shares[2];
+ unsigned int keyshare_length = 2;
+ struct ANASTASIS_CRYPTO_MasterSaltP salt;
+ struct ANASTASIS_CRYPTO_PolicyKeyP policy_key;
+ json_t *key_shares_json = json_array ();
+
+ random_auto (&key_shares[0]);
+ random_auto (&key_shares[1]);
+ random_auto (&salt);
+
+ ANASTASIS_CRYPTO_policy_key_derive (key_shares,
+ keyshare_length,
+ &salt,
+ &policy_key);
+
+ d2j_append_auto (key_shares_json, &key_shares[0]);
+ d2j_append_auto (key_shares_json, &key_shares[1]);
+ json_object_set_new (vec, "input_key_shares", key_shares_json);
+ d2j_auto (vec, "input_salt", &salt);
+ d2j_auto (vec, "output_policy_key", &policy_key);
+ }
+
+ {
+ // json_t *vec = vec_for (vecs, "core_secret_encryption");
+ // struct ANASTASIS_CRYPTO_PolicyKeyP policy_keys[2];
+ // unsigned int policy_keys_length = 2;
+ // char core_secret[256];
+ // size_t core_secret_size = 256;
+ // void *enc_core_secret;
+ // struct ANASTASIS_CRYPTO_EncryptedMasterKeyP encrypted_master_keys[2];
+ // json_t *policy_keys_json = json_array ();
+ // json_t *encrypted_master_keys_json = json_array ();
+
+ // random_auto (&policy_keys[0]);
+ // random_auto (&policy_keys[1]);
+ // random_auto (&core_secret);
+
+ // ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys, policy_keys_length,
+ // core_secret, core_secret_size,
+ // &enc_core_secret,
+ // encrypted_master_keys);
+
+ // d2j_append_auto (policy_keys_json, &policy_keys_json[0]);
+ // d2j_append_auto (policy_keys_json, &policy_keys_json[1]);
+ // d2j_append_auto (encrypted_master_keys_json, &encrypted_master_keys[0]);
+ // d2j_append_auto (encrypted_master_keys_json, &encrypted_master_keys[1]);
+
+ // d2j_auto (vec, "input_core_secret", &core_secret);
+ // json_object_set_new (vec, "input_policy_keys", policy_keys_json);
+ // json_object_set_new (vec, "output_encrypted_core_secret", encrypted_master_keys_json);
+ // json_object_set_new (vec, "output_encrypted_master_keys", encrypted_master_keys_json);
+ }
+
+
+ json_dumpf (vecfile, stdout, JSON_INDENT (2));
+ json_decref (vecfile);
+ printf ("\n");
+
+ return 0;
+}
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be NULL!)
+ * @param cfg configuration
+ */
+static void
+run (void *cls,
+ char *const *args,
+ const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ if (GNUNET_YES == verify_flag)
+ global_ret = check_vectors ();
+ else
+ global_ret = output_vectors ();
+}
+
+
+/**
+ * The main function of the test vector generation tool.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+ char *const *argv)
+{
+ const struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_option_flag ('V',
+ "verify",
+ gettext_noop (
+ "verify a test vector from stdin"),
+ &verify_flag),
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_log_setup ("anastasis-crypto-tvg",
+ "INFO",
+ NULL));
+ if (GNUNET_OK !=
+ GNUNET_PROGRAM_run (argc, argv,
+ "anastasis-crypto-tvg",
+ "Generate test vectors for cryptographic operations",
+ options,
+ &run, NULL))
+ return 1;
+ return global_ret;
+}
+
+
+/* end of anastasis-crypto-tvg.c */
diff --git a/src/util/anastasis_crypto.c b/src/util/anastasis_crypto.c
index bed0a94..f9ae657 100644
--- a/src/util/anastasis_crypto.c
+++ b/src/util/anastasis_crypto.c
@@ -3,14 +3,14 @@
Copyright (C) 2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License as published by the Free Software
+ terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
+ You should have received a copy of the GNU General Public License along with
Anastasis; see the file COPYING.GPL. If not, see <http://www.gnu.org/licenses/>
*/
/**
@@ -61,61 +61,58 @@ ANASTASIS_CRYPTO_secure_answer_hash (
GNUNET_CRYPTO_kdf (
result,
sizeof (*result),
- "Anastasis-secure-question-uuid-salting",
- strlen ("Anastasis-secure-question-uuid-salting"),
- &pow,
- sizeof (pow),
+ /* salt / XTS */
uuid,
sizeof (*uuid),
+ /* skm */
+ &pow,
+ sizeof (pow),
+ /* info chunks */
+ "anastasis-secure-question-hashing",
+ strlen ("anastasis-secure-question-hashing"),
NULL,
0));
}
/**
- * Compute @a key and @a iv.
+ * Compute @a key.
*
* @param key_material key for calculation
* @param key_m_len length of key
* @param nonce nonce for calculation
* @param salt salt value for calculation
* @param[out] key where to write the en-/description key
- * @param[out] iv where to write the IV
*/
static void
-get_iv_key (const void *key_material,
+derive_key (const void *key_material,
size_t key_m_len,
const struct ANASTASIS_CRYPTO_NonceP *nonce,
const char *salt,
- const struct ANASTASIS_CRYPTO_SymKeyP *key,
- struct ANASTASIS_CRYPTO_IvP *iv)
+ struct ANASTASIS_CRYPTO_SymKeyP *key)
{
- char res[sizeof (struct ANASTASIS_CRYPTO_SymKeyP)
- + sizeof (struct ANASTASIS_CRYPTO_IvP)];
-
if (GNUNET_YES !=
- GNUNET_CRYPTO_hkdf (res,
- sizeof (res),
- GCRY_MD_SHA512,
- GCRY_MD_SHA256,
- key_material,
- key_m_len,
- nonce,
- sizeof (struct ANASTASIS_CRYPTO_NonceP),
- salt,
- strlen (salt),
- NULL,
- 0))
+ GNUNET_CRYPTO_kdf (key,
+ sizeof (struct ANASTASIS_CRYPTO_SymKeyP),
+ /* salt / XTS */
+ nonce,
+ sizeof (struct ANASTASIS_CRYPTO_NonceP),
+ /* ikm */
+ key_material,
+ key_m_len,
+ /* info chunks */
+ /* The "salt" passed here is actually not something random,
+ but a protocol-specific identifier string. Thus
+ we pass it as a context info to the HKDF */
+ salt,
+ strlen (salt),
+ NULL,
+ 0))
{
+ // FIXME: Huh?! Why would we continue here?
GNUNET_break (0);
return;
}
- memcpy ((void *) key,
- res,
- sizeof (*key));
- memcpy (iv,
- &res[sizeof (*key)],
- sizeof (*iv));
}
@@ -141,67 +138,25 @@ anastasis_encrypt (const struct ANASTASIS_CRYPTO_NonceP *nonce,
void **res,
size_t *res_size)
{
- struct ANASTASIS_CRYPTO_NonceP *nonceptr;
- gcry_cipher_hd_t cipher;
- struct ANASTASIS_CRYPTO_SymKeyP sym_key;
- struct ANASTASIS_CRYPTO_IvP iv;
- int rc;
- struct ANASTASIS_CRYPTO_AesTagP *tag;
- char *ciphertext;
-
- *res_size = data_size
- + sizeof (struct ANASTASIS_CRYPTO_NonceP)
- + sizeof (struct ANASTASIS_CRYPTO_AesTagP);
- if (*res_size <= data_size)
- {
- GNUNET_break (0);
- return;
- }
- *res = GNUNET_malloc (*res_size);
- if (*res_size != data_size
- + sizeof (struct ANASTASIS_CRYPTO_NonceP)
- + sizeof (struct ANASTASIS_CRYPTO_AesTagP))
- {
- GNUNET_break (0);
- return;
- }
- nonceptr = (struct ANASTASIS_CRYPTO_NonceP *) *res;
- tag = (struct ANASTASIS_CRYPTO_AesTagP *) &nonceptr[1];
- ciphertext = (char *) &tag[1];
- memcpy (nonceptr,
- nonce,
- sizeof (*nonce));
- get_iv_key (key,
+ size_t ciphertext_size;
+ struct ANASTASIS_CRYPTO_SymKeyP skey;
+
+ derive_key (key,
key_len,
nonce,
salt,
- &sym_key,
- &iv);
+ &skey);
+ ciphertext_size = crypto_secretbox_NONCEBYTES
+ + crypto_secretbox_MACBYTES + data_size;
+ *res_size = ciphertext_size;
+ *res = GNUNET_malloc (ciphertext_size);
+ memcpy (*res, nonce, crypto_secretbox_NONCEBYTES);
GNUNET_assert (0 ==
- gcry_cipher_open (&cipher,
- GCRY_CIPHER_AES256,
- GCRY_CIPHER_MODE_GCM,
- 0));
- rc = gcry_cipher_setkey (cipher,
- &sym_key,
- sizeof (sym_key));
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
- rc = gcry_cipher_setiv (cipher,
- &iv,
- sizeof (iv));
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
-
- GNUNET_assert (0 ==
- gcry_cipher_encrypt (cipher,
- ciphertext,
- data_size,
- data,
- data_size));
- GNUNET_assert (0 ==
- gcry_cipher_gettag (cipher,
- tag,
- sizeof (struct ANASTASIS_CRYPTO_AesTagP)));
- gcry_cipher_close (cipher);
+ crypto_secretbox_easy (*res + crypto_secretbox_NONCEBYTES,
+ data,
+ data_size,
+ (void *) nonce,
+ (void *) &skey));
}
@@ -226,70 +181,30 @@ anastasis_decrypt (const void *key,
size_t *res_size)
{
const struct ANASTASIS_CRYPTO_NonceP *nonce;
- gcry_cipher_hd_t cipher;
- const struct ANASTASIS_CRYPTO_SymKeyP sym_key;
- struct ANASTASIS_CRYPTO_IvP iv;
- int rc;
- const struct ANASTASIS_CRYPTO_AesTagP *tag;
- const char *ciphertext;
-
- *res_size = data_size
- - sizeof (struct ANASTASIS_CRYPTO_NonceP)
- - sizeof (struct ANASTASIS_CRYPTO_AesTagP);
- if (*res_size >= data_size)
- {
- GNUNET_break (0);
- return;
- }
- *res = GNUNET_malloc (*res_size);
- if (*res_size != data_size
- - sizeof (struct ANASTASIS_CRYPTO_NonceP)
- - sizeof (struct ANASTASIS_CRYPTO_AesTagP))
- {
- GNUNET_break (0);
- GNUNET_free (*res);
- return;
- }
+ struct ANASTASIS_CRYPTO_SymKeyP skey;
+ size_t plaintext_size;
- nonce = (const struct ANASTASIS_CRYPTO_NonceP *) data;
- tag = (struct ANASTASIS_CRYPTO_AesTagP *) &nonce[1];
- ciphertext = (const char *) &tag[1];
- get_iv_key (key,
+ GNUNET_assert (data_size >= crypto_secretbox_NONCEBYTES
+ + crypto_secretbox_MACBYTES);
+ nonce = data;
+ derive_key (key,
key_len,
nonce,
salt,
- &sym_key,
- &iv);
- GNUNET_assert (0 ==
- gcry_cipher_open (&cipher,
- GCRY_CIPHER_AES256,
- GCRY_CIPHER_MODE_GCM,
- 0));
- rc = gcry_cipher_setkey (cipher,
- &sym_key,
- sizeof (sym_key));
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
-
- rc = gcry_cipher_setiv (cipher,
- &iv,
- sizeof (iv));
- GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY));
-
- GNUNET_assert (0 == gcry_cipher_decrypt (cipher,
- *res,
- *res_size,
- ciphertext,
- *res_size));
- if (0 !=
- gcry_cipher_checktag (cipher,
- tag,
- sizeof (struct ANASTASIS_CRYPTO_AesTagP)))
+ &skey);
+ plaintext_size = data_size - (crypto_secretbox_NONCEBYTES
+ + crypto_secretbox_MACBYTES);
+ *res = GNUNET_malloc (plaintext_size);
+ *res_size = plaintext_size;
+ if (0 != crypto_secretbox_open_easy (*res,
+ data + crypto_secretbox_NONCEBYTES,
+ data_size - crypto_secretbox_NONCEBYTES,
+ (void *) nonce,
+ (void *) &skey))
{
GNUNET_break (0);
GNUNET_free (*res);
- return;
}
- gcry_cipher_close (cipher);
}
@@ -321,23 +236,23 @@ ANASTASIS_CRYPTO_account_private_key_derive (
{
/* priv_key = ver_secret */
if (GNUNET_YES !=
- GNUNET_CRYPTO_hkdf (&priv_key->priv,
- sizeof (priv_key->priv),
- GCRY_MD_SHA512,
- GCRY_MD_SHA256,
- id,
- sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP),
- "ver",
- strlen ("ver"),
- NULL,
- 0))
+ GNUNET_CRYPTO_kdf (&priv_key->priv,
+ sizeof (priv_key->priv),
+ /* salt / XTS */
+ NULL,
+ 0,
+ /* ikm */
+ id,
+ sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP),
+ /* context chunks */
+ "ver",
+ strlen ("ver"),
+ NULL,
+ 0))
{
GNUNET_break (0);
return;
}
- /* go from ver_secret to proper private key (eddsa_d_to_a() in spec) */
- priv_key->priv.d[0] = (priv_key->priv.d[0] & 0x7f) | 0x40;
- priv_key->priv.d[31] &= 0xf8;
}
@@ -518,105 +433,125 @@ ANASTASIS_CRYPTO_policy_key_derive (
const struct ANASTASIS_CRYPTO_MasterSaltP *salt,
struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key)
{
- GNUNET_CRYPTO_hkdf (policy_key,
- sizeof (*policy_key),
- GCRY_MD_SHA512,
- GCRY_MD_SHA256,
- key_shares,
- keyshare_length * sizeof (*key_shares),
- salt,
- sizeof (*salt),
- NULL, 0);
+ GNUNET_CRYPTO_kdf (policy_key,
+ sizeof (*policy_key),
+ /* salt / XTS */
+ salt,
+ sizeof (*salt),
+ /* ikm */
+ key_shares,
+ keyshare_length * sizeof (*key_shares),
+ /* info chunks */
+ "anastasis-policy-key-derive",
+ strlen ("anastasis-policy-key-derive"),
+ NULL, 0);
}
-void
+struct ANASTASIS_CoreSecretEncryptionResult *
ANASTASIS_CRYPTO_core_secret_encrypt (
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_keys,
unsigned int policy_keys_length,
const void *core_secret,
- size_t core_secret_size,
- void **enc_core_secret,
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_keys)
+ size_t core_secret_size)
{
- struct GNUNET_CRYPTO_SymmetricSessionKey sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
struct GNUNET_HashCode master_key;
+ struct ANASTASIS_CoreSecretEncryptionResult *cser;
+ struct ANASTASIS_CRYPTO_NonceP nonce;
+
+ cser = GNUNET_new (struct ANASTASIS_CoreSecretEncryptionResult);
- *enc_core_secret = GNUNET_malloc (core_secret_size);
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
&master_key,
sizeof (struct GNUNET_HashCode));
- GNUNET_CRYPTO_hash_to_aes_key (&master_key,
- &sk,
- &iv);
- GNUNET_assert (GNUNET_SYSERR !=
- GNUNET_CRYPTO_symmetric_encrypt (core_secret,
- core_secret_size,
- &sk,
- &iv,
- *enc_core_secret));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &nonce,
+ sizeof (struct ANASTASIS_CRYPTO_NonceP));
+
+ anastasis_encrypt (&nonce,
+ &master_key,
+ sizeof (struct GNUNET_HashCode),
+ core_secret,
+ core_secret_size,
+ "cse",
+ &cser->enc_core_secret,
+ &cser->enc_core_secret_size);
+
+ /* Allocate result arrays with NULL-termination so we don't
+ need to store the length to free */
+ cser->enc_master_key_sizes = GNUNET_new_array (policy_keys_length + 1,
+ size_t);
+ cser->enc_master_keys = GNUNET_new_array (policy_keys_length + 1,
+ void *);
+
for (unsigned int i = 0; i < policy_keys_length; i++)
{
- struct GNUNET_CRYPTO_SymmetricSessionKey i_sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector i_iv;
- struct GNUNET_HashCode key = policy_keys[i].key;
-
- GNUNET_CRYPTO_hash_to_aes_key (&key,
- &i_sk,
- &i_iv);
- GNUNET_assert (
- GNUNET_SYSERR !=
- GNUNET_CRYPTO_symmetric_encrypt (&master_key,
- sizeof (struct GNUNET_HashCode),
- &i_sk,
- &i_iv,
- &encrypted_master_keys[i]));
+ struct ANASTASIS_CRYPTO_NonceP nonce_i;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG,
+ &nonce_i,
+ sizeof (struct ANASTASIS_CRYPTO_NonceP));
+
+ anastasis_encrypt (&nonce_i,
+ &policy_keys[i].key,
+ sizeof (struct GNUNET_HashCode),
+ &master_key,
+ sizeof (struct GNUNET_HashCode),
+ "emk",
+ &cser->enc_master_keys[i],
+ &cser->enc_master_key_sizes[i]);
}
+ return cser;
}
+/**
+ * Decrypts the core secret with the master key. First the master key is decrypted with the provided policy key.
+ * Afterwards the core secret is encrypted with the master key. The core secret is returned.
+ *
+ * @param encrypted_master_key master key for decrypting the core secret, is itself encrypted by the policy key
+ * @param encrypted_master_key_size size of the encrypted master key
+ * @param policy_key built policy key which will decrypt the master key
+ * @param encrypted_core_secret the encrypted core secret from the user, will be encrypted with the policy key
+ * @param encrypted_core_secret_size size of the encrypted core secret
+ * @param[out] core_secret decrypted core secret will be returned
+ * @param[out] core_secret_size size of core secret
+ */
void
ANASTASIS_CRYPTO_core_secret_recover (
- const struct ANASTASIS_CRYPTO_EncryptedMasterKeyP *encrypted_master_key,
+ const void *encrypted_master_key,
+ size_t encrypted_master_key_size,
const struct ANASTASIS_CRYPTO_PolicyKeyP *policy_key,
const void *encrypted_core_secret,
size_t encrypted_core_secret_size,
void **core_secret,
size_t *core_secret_size)
{
- struct GNUNET_CRYPTO_SymmetricSessionKey mk_sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector mk_iv;
- struct GNUNET_CRYPTO_SymmetricSessionKey core_sk;
- struct GNUNET_CRYPTO_SymmetricInitializationVector core_iv;
- struct GNUNET_HashCode master_key;
- struct GNUNET_HashCode key = policy_key->key;
+ void *master_key;
+ size_t master_key_size;
*core_secret = GNUNET_malloc (encrypted_core_secret_size);
- GNUNET_CRYPTO_hash_to_aes_key (&key,
- &mk_sk,
- &mk_iv);
- GNUNET_assert (
- GNUNET_SYSERR !=
- GNUNET_CRYPTO_symmetric_decrypt (
- encrypted_master_key,
- sizeof (struct ANASTASIS_CRYPTO_EncryptedMasterKeyP),
- &mk_sk,
- &mk_iv,
- &master_key));
- GNUNET_CRYPTO_hash_to_aes_key (&master_key,
- &core_sk,
- &core_iv);
+ anastasis_decrypt (&policy_key->key,
+ sizeof (struct GNUNET_HashCode),
+ encrypted_master_key,
+ encrypted_master_key_size,
+ "emk",
+ &master_key,
+ &master_key_size);
+ GNUNET_break (NULL != master_key);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"At %s:%d encrypted core secret is %s-%llu b\n", __FILE__,
__LINE__,
TALER_b2s (encrypted_core_secret, encrypted_core_secret_size),
(unsigned long long) encrypted_core_secret_size);
- *core_secret_size = GNUNET_CRYPTO_symmetric_decrypt (encrypted_core_secret,
- encrypted_core_secret_size,
- &core_sk,
- &core_iv,
- *core_secret);
+ anastasis_decrypt (master_key,
+ master_key_size,
+ encrypted_core_secret,
+ encrypted_core_secret_size,
+ "cse",
+ core_secret,
+ core_secret_size);
+ GNUNET_break (NULL != *core_secret);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"At %s:%d decrypted core secret is %s-%llu b\n", __FILE__,
__LINE__,
@@ -626,4 +561,47 @@ ANASTASIS_CRYPTO_core_secret_recover (
}
+/**
+ * Destroy a core secret encryption result.
+ *
+ * @param cser the result to destroy
+ */
+void
+ANASTASIS_CRYPTO_destroy_encrypted_core_secret (
+ struct ANASTASIS_CoreSecretEncryptionResult *cser)
+{
+ for (unsigned int i = 0; NULL != cser->enc_master_keys[i]; i++)
+ GNUNET_free (cser->enc_master_keys[i]);
+ GNUNET_free (cser->enc_master_keys);
+ GNUNET_free (cser->enc_master_key_sizes);
+ GNUNET_free (cser->enc_core_secret);
+ GNUNET_free (cser);
+}
+
+
+/**
+ * Convert a @a uuid to a shortened, human-readable string
+ * useful to show to users to identify the truth.
+ * Note that the return value is in a global variable and
+ * only valid until the next invocation of this function.
+ *
+ * @param uuid UUID to convert
+ * @return string representation
+ */
+const char *
+ANASTASIS_CRYPTO_uuid2s (const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid)
+{
+ static char uuids[7];
+ char *tpk;
+
+ tpk = GNUNET_STRINGS_data_to_string_alloc (uuid,
+ sizeof (*uuid));
+ memcpy (uuids,
+ tpk,
+ sizeof (uuids) - 1);
+ GNUNET_free (tpk);
+ return uuids;
+}
+
+
/* end of anastasis_crypto.c */
diff --git a/src/util/os_installation.c b/src/util/os_installation.c
index a23182e..cfcf3c3 100644
--- a/src/util/os_installation.c
+++ b/src/util/os_installation.c
@@ -3,7 +3,7 @@
Copyright (C) 2019, 2021 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
+ it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
@@ -12,7 +12,7 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
+ You should have received a copy of the GNU General Public License
along with Anastasis; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
diff --git a/src/util/test_anastasis_crypto.c b/src/util/test_anastasis_crypto.c
index b435bea..6b292a0 100644
--- a/src/util/test_anastasis_crypto.c
+++ b/src/util/test_anastasis_crypto.c
@@ -3,16 +3,16 @@
Copyright (C) 2014-2020 Anastasis SARL
Anastasis is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
+ it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3, or
(at your option) any later version.
Anastasis is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
+ GNU General Public License for more details.
- You should have received a copy of the GNU Affero General Public
+ You should have received a copy of the GNU General Public
License along with Anastasis; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
*/
@@ -216,11 +216,9 @@ test_core_secret (void)
{
const char *test = "TEST_CORE_SECRET";
const char *test_wrong = "TEST_CORE_WRONG";
- void *enc_core_secret;
unsigned int policy_keys_length = 5;
struct ANASTASIS_CRYPTO_MasterSaltP salt;
- struct ANASTASIS_CRYPTO_EncryptedMasterKeyP
- encrypted_master_keys[policy_keys_length];
+ struct ANASTASIS_CoreSecretEncryptionResult *cser;
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
&salt,
@@ -258,14 +256,10 @@ test_core_secret (void)
TALER_b2s (test, strlen (test)));
// test encryption of core_secret
- ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
- policy_keys_length,
- test,
- strlen (test),
- &enc_core_secret,
- (struct
- ANASTASIS_CRYPTO_EncryptedMasterKeyP *)
- &encrypted_master_keys);
+ cser = ANASTASIS_CRYPTO_core_secret_encrypt (policy_keys,
+ policy_keys_length,
+ test,
+ strlen (test));
// test recover of core secret
for (unsigned int k = 0; k < policy_keys_length; k++)
@@ -273,10 +267,11 @@ test_core_secret (void)
void *dec_core_secret;
size_t core_secret_size;
- ANASTASIS_CRYPTO_core_secret_recover (&encrypted_master_keys[k],
+ ANASTASIS_CRYPTO_core_secret_recover (cser->enc_master_keys[k],
+ cser->enc_master_key_sizes[k],
&policy_keys[k],
- enc_core_secret,
- strlen (test),
+ cser->enc_core_secret,
+ cser->enc_core_secret_size,
&dec_core_secret,
&core_secret_size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -291,7 +286,7 @@ test_core_secret (void)
test)));
GNUNET_free (dec_core_secret);
}
- GNUNET_free (enc_core_secret);
+ ANASTASIS_CRYPTO_destroy_encrypted_core_secret (cser);
return 0;
}