summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/.gitignore1
-rw-r--r--src/util/Makefile.am21
-rw-r--r--src/util/anastasis-config.c6
-rw-r--r--src/util/anastasis-config.in5
-rw-r--r--src/util/anastasis-crypto-tvg.c601
-rw-r--r--src/util/anastasis_crypto.c470
-rw-r--r--src/util/os_installation.c4
-rw-r--r--src/util/pin.c84
-rw-r--r--src/util/test_anastasis_crypto.c53
9 files changed, 974 insertions, 271 deletions
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..29d2b13 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 = \
@@ -23,6 +26,9 @@ anastasis-config: anastasis-config.in
chmod a-w+x $@.tmp && \
mv $@.tmp $@
+CLEANFILES = \
+ anastasis-config
+
bin_SCRIPTS = \
anastasis-config
@@ -31,10 +37,12 @@ lib_LTLIBRARIES = \
libanastasisutil_la_SOURCES = \
anastasis_crypto.c \
- os_installation.c
+ os_installation.c \
+ pin.c
libanastasisutil_la_LIBADD = \
-lgnunetutil \
$(LIBGCRYPT_LIBS) \
+ -lsodium \
-ljansson \
-ltalerutil \
$(XLIB)
@@ -51,7 +59,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-config.in b/src/util/anastasis-config.in
index 0e94921..6657540 100644
--- a/src/util/anastasis-config.in
+++ b/src/util/anastasis-config.in
@@ -7,6 +7,7 @@ if ! type gnunet-config >/dev/null; then
exit 1
fi
-GC=`which gnunet-config`
-export LD_PRELOAD=${LD_PRELOAD:-}:%libdir%/libanastasisutil.so
+GC=$(which gnunet-config)
+SO=$(ls %libdir%/libanastasisutil.so.* | sort -n | tail -n1)
+export LD_PRELOAD=${LD_PRELOAD:-}:${SO}
exec gnunet-config "$@"
diff --git a/src/util/anastasis-crypto-tvg.c b/src/util/anastasis-crypto-tvg.c
new file mode 100644
index 0000000..d5fc4c1
--- /dev/null
+++ b/src/util/anastasis-crypto-tvg.c
@@ -0,0 +1,601 @@
+/*
+ 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));
+
+
+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 provider_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 (&provider_salt);
+
+ ANASTASIS_CRYPTO_user_identifier_derive (id_data,
+ &provider_salt,
+ &id);
+ json_object_set_new (vec, "input_id_data", id_data);
+ d2j_auto (vec, "input_provider_salt", &provider_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..579f097 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/>
*/
/**
@@ -41,6 +41,10 @@ ANASTASIS_hash_answer (uint64_t code,
GNUNET_CRYPTO_hash (cbuf,
strlen (cbuf),
hashed_code);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Hashed answer %llu to %s\n",
+ (unsigned long long) code,
+ GNUNET_h2s (hashed_code));
}
@@ -61,61 +65,53 @@ 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_break (0);
- return;
- }
- memcpy ((void *) key,
- res,
- sizeof (*key));
- memcpy (iv,
- &res[sizeof (*key)],
- sizeof (*iv));
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CRYPTO_kdf (key,
+ sizeof (*key),
+ /* salt / XTS */
+ nonce,
+ sizeof (*nonce),
+ /* 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));
}
@@ -141,67 +137,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);
- 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));
-
+ &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_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));
}
@@ -215,8 +169,9 @@ anastasis_encrypt (const struct ANASTASIS_CRYPTO_NonceP *nonce,
* @param salt salt value which is used for key derivation
* @param[out] res plaintext output
* @param[out] res_size size of the plaintext
+ * @return #GNUNET_OK on success
*/
-static void
+static enum GNUNET_GenericReturnValue
anastasis_decrypt (const void *key,
size_t key_len,
const void *data,
@@ -226,77 +181,42 @@ 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))
+ struct ANASTASIS_CRYPTO_SymKeyP skey;
+ size_t plaintext_size;
+
+ if (data_size < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES)
{
GNUNET_break (0);
- GNUNET_free (*res);
- return;
+ return GNUNET_SYSERR;
}
-
- nonce = (const struct ANASTASIS_CRYPTO_NonceP *) data;
- tag = (struct ANASTASIS_CRYPTO_AesTagP *) &nonce[1];
- ciphertext = (const char *) &tag[1];
- get_iv_key (key,
+ 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;
+ return GNUNET_SYSERR;
}
- gcry_cipher_close (cipher);
+ return GNUNET_OK;
}
void
ANASTASIS_CRYPTO_user_identifier_derive (
const json_t *id_data,
- const struct ANASTASIS_CRYPTO_ProviderSaltP *server_salt,
+ const struct ANASTASIS_CRYPTO_ProviderSaltP *provider_salt,
struct ANASTASIS_CRYPTO_UserIdentifierP *id)
{
char *json_enc;
@@ -305,7 +225,7 @@ ANASTASIS_CRYPTO_user_identifier_derive (
json_enc = json_dumps (id_data,
JSON_COMPACT | JSON_SORT_KEYS);
GNUNET_assert (NULL != json_enc);
- GNUNET_CRYPTO_pow_hash (&server_salt->salt,
+ GNUNET_CRYPTO_pow_hash (&provider_salt->salt,
json_enc,
strlen (json_enc),
&hash);
@@ -321,23 +241,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;
}
@@ -417,9 +337,9 @@ ANASTASIS_CRYPTO_keyshare_encrypt (
sizeof (nonce));
anastasis_encrypt (&nonce,
id,
- sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP),
+ sizeof (*id),
key_share,
- sizeof (struct ANASTASIS_CRYPTO_KeyShareP),
+ sizeof (*key_share),
(NULL == xsalt) ? salt : xsalt,
&eks,
&eks_size);
@@ -444,9 +364,9 @@ ANASTASIS_CRYPTO_keyshare_decrypt (
void *ks = NULL;
anastasis_decrypt (id,
- sizeof (struct ANASTASIS_CRYPTO_UserIdentifierP),
+ sizeof (*id),
enc_key_share,
- sizeof (struct ANASTASIS_CRYPTO_EncryptedKeyShareP),
+ sizeof (*enc_key_share),
(NULL == xsalt) ? salt : xsalt,
&ks,
&ks_size);
@@ -518,105 +438,113 @@ 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;
}
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 +554,78 @@ ANASTASIS_CRYPTO_core_secret_recover (
}
+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);
+}
+
+
+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;
+}
+
+
+void
+ANASTASIS_CRYPTO_recovery_metadata_encrypt (
+ const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
+ const void *meta_data,
+ size_t meta_data_size,
+ void **enc_meta_data,
+ size_t *enc_meta_data_size)
+{
+ const char *salt = "rmd";
+ struct ANASTASIS_CRYPTO_NonceP nonce;
+
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
+ &nonce,
+ sizeof (nonce));
+ anastasis_encrypt (&nonce,
+ id,
+ sizeof (*id),
+ meta_data,
+ meta_data_size,
+ salt,
+ enc_meta_data,
+ enc_meta_data_size);
+}
+
+
+enum GNUNET_GenericReturnValue
+ANASTASIS_CRYPTO_recovery_metadata_decrypt (
+ const struct ANASTASIS_CRYPTO_UserIdentifierP *id,
+ const void *enc_meta_data,
+ size_t enc_meta_data_size,
+ void **meta_data,
+ size_t *meta_data_size)
+{
+ const char *salt = "rmd";
+
+ return anastasis_decrypt (id,
+ sizeof (*id),
+ enc_meta_data,
+ enc_meta_data_size,
+ salt,
+ meta_data,
+ meta_data_size);
+}
+
+
/* 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/pin.c b/src/util/pin.c
new file mode 100644
index 0000000..0285bb0
--- /dev/null
+++ b/src/util/pin.c
@@ -0,0 +1,84 @@
+/*
+ This file is part of GNU 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. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file anastasis/src/util/pin.c
+ * @brief pin conversion functions
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "anastasis_util_lib.h"
+
+
+bool
+ANASTASIS_scan_pin (const char *as,
+ unsigned long long *pin)
+{
+ char dummy;
+ char s[16];
+
+ if ( (NULL != as) &&
+ (0 == strncasecmp ("A-", as, 2)) )
+ as += 2; /* skip "A-" prefix if present */
+ if (strlen (as) != 18)
+ return false;
+ if ( ('-' != as[5]) ||
+ ('-' != as[9]) ||
+ ('-' != as[14]) )
+ return false;
+ GNUNET_snprintf (s,
+ sizeof (s),
+ "%.5s%.3s%.4s%.3s",
+ as,
+ &as[6],
+ &as[10],
+ &as[15]);
+ if (1 != sscanf (s,
+ "%llu%c",
+ pin,
+ &dummy))
+ {
+ GNUNET_break (0);
+ return false;
+ }
+ return true;
+}
+
+
+const char *
+ANASTASIS_pin2s (uint64_t pin)
+{
+ static char buf[22];
+ char tmp[16];
+
+ GNUNET_assert (pin < ANASTASIS_PIN_MAX_VALUE);
+ GNUNET_snprintf (tmp,
+ sizeof (tmp),
+ "%015llu",
+ (unsigned long long) pin);
+ GNUNET_snprintf (buf,
+ sizeof (buf),
+ "A-%.5s-%.3s-%.4s-%.3s",
+ tmp,
+ &tmp[5],
+ &tmp[8],
+ &tmp[12]);
+ return buf;
+}
diff --git a/src/util/test_anastasis_crypto.c b/src/util/test_anastasis_crypto.c
index b435bea..6132e35 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/>
*/
@@ -41,11 +41,11 @@ test_user_identifier_derive (void)
struct ANASTASIS_CRYPTO_UserIdentifierP id_1;
struct ANASTASIS_CRYPTO_UserIdentifierP id_2;
struct ANASTASIS_CRYPTO_UserIdentifierP id_3;
- struct ANASTASIS_CRYPTO_ProviderSaltP server_salt;
+ struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt;
char *salt_str = "Server-Salt-Test";
- GNUNET_memcpy (&server_salt,
+ GNUNET_memcpy (&provider_salt,
salt_str,
strlen (salt_str));
// sample data 1
@@ -59,13 +59,13 @@ test_user_identifier_derive (void)
json_object_set_new (id_data_3, "arg1", json_string ("Hallo2"));
ANASTASIS_CRYPTO_user_identifier_derive (id_data_1,
- &server_salt,
+ &provider_salt,
&id_1);
ANASTASIS_CRYPTO_user_identifier_derive (id_data_2,
- &server_salt,
+ &provider_salt,
&id_2);
ANASTASIS_CRYPTO_user_identifier_derive (id_data_3,
- &server_salt,
+ &provider_salt,
&id_3);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"UserIdentifier_1: %s\n",
@@ -97,19 +97,19 @@ test_recovery_document (void)
void *plaintext;
size_t size_plaintext;
struct ANASTASIS_CRYPTO_UserIdentifierP id;
- struct ANASTASIS_CRYPTO_ProviderSaltP server_salt;
+ struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt;
int ret;
json_t *id_data = json_object ();
const char *test = "TEST_ERD";
char *salt_str = "Server-Salt-Test";
- GNUNET_memcpy (&server_salt,
+ GNUNET_memcpy (&provider_salt,
salt_str,
strlen (salt_str));
json_object_set_new (id_data, "arg1", json_string ("ID_DATA"));
ANASTASIS_CRYPTO_user_identifier_derive (id_data,
- &server_salt,
+ &provider_salt,
&id);
ANASTASIS_CRYPTO_recovery_document_encrypt (&id,
test,
@@ -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;
}
@@ -301,17 +296,17 @@ test_public_key_derive (void)
{
struct ANASTASIS_CRYPTO_UserIdentifierP id;
struct ANASTASIS_CRYPTO_AccountPublicKeyP pub_key;
- struct ANASTASIS_CRYPTO_ProviderSaltP server_salt;
+ struct ANASTASIS_CRYPTO_ProviderSaltP provider_salt;
json_t *id_data = json_object ();
const char *salt_str = "Server-Salt-Test";
- GNUNET_memcpy (&server_salt,
+ GNUNET_memcpy (&provider_salt,
salt_str,
strlen (salt_str));
json_object_set_new (id_data, "arg1", json_string ("ID_DATA"));
ANASTASIS_CRYPTO_user_identifier_derive (id_data,
- &server_salt,
+ &provider_salt,
&id);
ANASTASIS_CRYPTO_account_public_key_derive (&id,