aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Schwieren <tristan.schwieren@tum.de>2022-08-11 16:45:12 +0200
committerTristan Schwieren <tristan.schwieren@tum.de>2022-08-26 17:49:06 +0200
commit3eab839a585eb5db577a276bad7840f8c4f7c51f (patch)
tree26e1a01f14d3f18fc60a9b6f3c65b6c104d69371
parent0c577c77d84029093d676aa22c8cc662b7f3b124 (diff)
downloadgnunet-3eab839a585eb5db577a276bad7840f8c4f7c51f.tar.gz
gnunet-3eab839a585eb5db577a276bad7840f8c4f7c51f.zip
- siop for reclaim; A rest endpoint that signs stuff
-rw-r--r--src/identity/plugin_rest_identity.c119
-rw-r--r--src/include/gnunet_crypto_lib.h15
-rw-r--r--src/util/Makefile.am6
-rw-r--r--src/util/crypto_ecc.c64
-rw-r--r--src/util/test_crypto_ecc.c57
5 files changed, 261 insertions, 0 deletions
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index d7cd0e826..ba0aa82f1 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -28,6 +28,8 @@
28#include "gnunet_rest_plugin.h" 28#include "gnunet_rest_plugin.h"
29#include "gnunet_identity_service.h" 29#include "gnunet_identity_service.h"
30#include "gnunet_rest_lib.h" 30#include "gnunet_rest_lib.h"
31#include "identity.h"
32#include "gnunet_crypto_lib.h"
31#include "microhttpd.h" 33#include "microhttpd.h"
32#include <jansson.h> 34#include <jansson.h>
33 35
@@ -52,6 +54,11 @@
52#define GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM "/identity/subsystem" 54#define GNUNET_REST_API_NS_IDENTITY_SUBSYSTEM "/identity/subsystem"
53 55
54/** 56/**
57 * Identity Namespace with sign specifier
58 */
59#define GNUNET_REST_API_NS_SIGN "/sign"
60
61/**
55 * Parameter public key 62 * Parameter public key
56 */ 63 */
57#define GNUNET_REST_IDENTITY_PARAM_PUBKEY "pubkey" 64#define GNUNET_REST_IDENTITY_PARAM_PUBKEY "pubkey"
@@ -1185,6 +1192,117 @@ ego_delete_name (struct GNUNET_REST_RequestHandle *con_handle,
1185 handle); 1192 handle);
1186} 1193}
1187 1194
1195struct ego_sign_data_cls
1196{
1197 void *data;
1198 struct RequestHandle *handle;
1199};
1200
1201void
1202ego_sign_data_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
1203{
1204 struct RequestHandle *handle = ((struct ego_sign_data_cls *) cls)->handle;
1205 char *data = (char *) ((struct ego_sign_data_cls *) cls)->data; // data is url decoded
1206 struct MHD_Response *resp;
1207 struct GNUNET_CRYPTO_EcdsaSignature sig;
1208 struct GNUNET_IDENTITY_Signature sig_ident;
1209 void *sig_buf;
1210 char *sig_str;
1211 char *result;
1212
1213 if (ego == NULL)
1214 {
1215 handle->response_code = MHD_HTTP_BAD_REQUEST;
1216 handle->emsg = GNUNET_strdup ("Ego not found");
1217 GNUNET_SCHEDULER_add_now (&do_error, handle);
1218 return;
1219 }
1220
1221 if ( GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign_raw (&(ego->pk.ecdsa_key),
1222 (void *) data,
1223 strlen (data),
1224 &sig))
1225 {
1226 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1227 handle->emsg = GNUNET_strdup ("Signature creation failed");
1228 GNUNET_SCHEDULER_add_now (&do_error, handle);
1229 return;
1230 }
1231
1232 // TODO: Encode the signature
1233
1234 GNUNET_asprintf (&result,
1235 "{\"data\": \"%s\", \"signature\": \"%s\"}",
1236 data,
1237 sig_str);
1238
1239 resp = GNUNET_REST_create_response (result);
1240 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1241
1242 free (data);
1243 free (result);
1244 free (cls);
1245 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
1246}
1247
1248/**
1249 *
1250 * @param con_handle the connection handle
1251 * @param url the url
1252 * @param cls the RequestHandle
1253 */
1254void
1255ego_sign_data (struct GNUNET_REST_RequestHandle *con_handle,
1256 const char *url,
1257 void *cls)
1258{
1259 // TODO: replace with precompiler #define
1260 const char *username_key = "user";
1261 const char *data_key = "data";
1262
1263 struct RequestHandle *handle = cls;
1264 struct MHD_Response *resp;
1265 struct GNUNET_HashCode cache_key_username;
1266 struct GNUNET_HashCode cache_key_data;
1267 char *username;
1268 char *data;
1269 char *result;
1270
1271 struct ego_sign_data_cls *cls2;
1272
1273 GNUNET_CRYPTO_hash (username_key, strlen (username_key), &cache_key_username);
1274 GNUNET_CRYPTO_hash (data_key, strlen (data_key), &cache_key_data);
1275
1276 if ((GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (
1277 handle->rest_handle->url_param_map,
1278 &cache_key_username)) ||
1279 (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (
1280 handle->rest_handle->url_param_map,
1281 &cache_key_data)))
1282 {
1283 handle->response_code = MHD_HTTP_BAD_REQUEST;
1284 handle->emsg = GNUNET_strdup ("URL parameter missing");
1285 GNUNET_SCHEDULER_add_now (&do_error, handle);
1286 return;
1287 }
1288
1289 username = (char *) GNUNET_CONTAINER_multihashmap_get (
1290 handle->rest_handle->url_param_map,
1291 &cache_key_username);
1292
1293 data = (char *) GNUNET_CONTAINER_multihashmap_get (
1294 handle->rest_handle->url_param_map,
1295 &cache_key_data);
1296
1297 cls2 = malloc (sizeof(struct ego_sign_data_cls));
1298 cls2->data = (void *) GNUNET_strdup (data);
1299 cls2->handle = handle;
1300
1301 GNUNET_IDENTITY_ego_lookup (cfg,
1302 username,
1303 ego_sign_data_cb,
1304 cls2);
1305}
1188 1306
1189/** 1307/**
1190 * Respond to OPTIONS request 1308 * Respond to OPTIONS request
@@ -1335,6 +1453,7 @@ rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1335 GNUNET_REST_API_NS_IDENTITY_NAME, 1453 GNUNET_REST_API_NS_IDENTITY_NAME,
1336 &ego_delete_name }, 1454 &ego_delete_name },
1337 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, 1455 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
1456 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_SIGN, &ego_sign_data},
1338 GNUNET_REST_HANDLER_END }; 1457 GNUNET_REST_HANDLER_END };
1339 1458
1340 1459
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 2737ee0e9..69ecf8432 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1945,6 +1945,21 @@ GNUNET_CRYPTO_ecdsa_sign_ (
1945 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, 1945 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
1946 struct GNUNET_CRYPTO_EcdsaSignature *sig); 1946 struct GNUNET_CRYPTO_EcdsaSignature *sig);
1947 1947
1948/**
1949 * @brief
1950 *
1951 * @param priv
1952 * @param data
1953 * @param len
1954 * @param sig
1955 * @return enum GNUNET_GenericReturnValue
1956 */
1957enum GNUNET_GenericReturnValue
1958GNUNET_CRYPTO_ecdsa_sign_raw (
1959 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1960 void *data,
1961 size_t len,
1962 struct GNUNET_CRYPTO_EcdsaSignature *sig);
1948 1963
1949/** 1964/**
1950 * @ingroup crypto 1965 * @ingroup crypto
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 9cb7da15b..b86fa0f12 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -292,6 +292,7 @@ check_PROGRAMS = \
292 test_container_heap \ 292 test_container_heap \
293 test_crypto_symmetric \ 293 test_crypto_symmetric \
294 test_crypto_crc \ 294 test_crypto_crc \
295 test_crypto_ecc \
295 test_crypto_cs \ 296 test_crypto_cs \
296 test_crypto_ecdsa \ 297 test_crypto_ecdsa \
297 test_crypto_eddsa \ 298 test_crypto_eddsa \
@@ -460,6 +461,11 @@ test_crypto_cs_LDADD = \
460 libgnunetutil.la \ 461 libgnunetutil.la \
461 -lsodium 462 -lsodium
462 463
464test_crypto_ecc_SOURCES = \
465 test_crypto_ecc.c
466test_crypto_ecc_LDADD = \
467 libgnunetutil.la
468
463test_crypto_ecdsa_SOURCES = \ 469test_crypto_ecdsa_SOURCES = \
464 test_crypto_ecdsa.c 470 test_crypto_ecdsa.c
465test_crypto_ecdsa_LDADD = \ 471test_crypto_ecdsa_LDADD = \
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 5b1b579ec..11e882de1 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -594,6 +594,70 @@ GNUNET_CRYPTO_ecdsa_sign_ (
594 return GNUNET_OK; 594 return GNUNET_OK;
595} 595}
596 596
597// TODO: Code reuse with GNUNET_CRYPTO_ecdsa_sign_
598// Refactor above as a wrapper around raw
599enum GNUNET_GenericReturnValue
600GNUNET_CRYPTO_ecdsa_sign_raw (
601 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
602 void *data,
603 size_t len,
604 struct GNUNET_CRYPTO_EcdsaSignature *sig)
605{
606 struct GNUNET_HashCode hash_code;
607 gcry_sexp_t skey_sexp;
608 gcry_sexp_t sig_sexp;
609 gcry_sexp_t data_sexp;
610 gcry_error_t error;
611 gcry_mpi_t rs[2];
612
613 // Decode private key
614 skey_sexp = decode_private_ecdsa_key (priv);
615
616 // Hash data
617 GNUNET_CRYPTO_hash (data, len, &hash_code);
618 if (0 != (error = gcry_sexp_build (&data_sexp,
619 NULL,
620 "(data(flags rfc6979)(hash %s %b))",
621 "sha512",
622 (int) sizeof(hash_code),
623 &hash_code)))
624 {
625 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", error);
626 return GNUNET_SYSERR;
627 }
628
629 // Sign Hash
630 if (0 != (error = gcry_pk_sign (&sig_sexp, data_sexp, skey_sexp)))
631 {
632 LOG (GNUNET_ERROR_TYPE_WARNING,
633 _ ("ECC signing failed at %s:%d: %s\n"),
634 __FILE__,
635 __LINE__,
636 gcry_strerror (error));
637 gcry_sexp_release (data_sexp);
638 gcry_sexp_release (skey_sexp);
639 return GNUNET_SYSERR;
640 }
641 gcry_sexp_release (skey_sexp);
642 gcry_sexp_release (data_sexp);
643
644 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
645 'signature' */
646 if (0 != (error = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
647 {
648 GNUNET_break (0);
649 gcry_sexp_release (sig_sexp);
650 return GNUNET_SYSERR;
651 }
652 gcry_sexp_release (sig_sexp);
653 GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
654 GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
655 gcry_mpi_release (rs[0]);
656 gcry_mpi_release (rs[1]);
657
658 return GNUNET_OK;
659}
660
597 661
598enum GNUNET_GenericReturnValue 662enum GNUNET_GenericReturnValue
599GNUNET_CRYPTO_eddsa_sign_ ( 663GNUNET_CRYPTO_eddsa_sign_ (
diff --git a/src/util/test_crypto_ecc.c b/src/util/test_crypto_ecc.c
new file mode 100644
index 000000000..ebfa04c45
--- /dev/null
+++ b/src/util/test_crypto_ecc.c
@@ -0,0 +1,57 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2002-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19
20 */
21/**
22 * @file util/test_crypto_ecc.c
23 * @brief test case for crypto_ecc.c GNUNET_CRYPTO_ecdsa_sign_raw() function
24 * @author Tristan Schwieren
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28
29static int
30test_GNUNET_CRYPTO_ecdsa_sign_raw ()
31{
32 struct GNUNET_CRYPTO_EcdsaPrivateKey skey;
33 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
34 struct GNUNET_CRYPTO_EcdsaSignature sig;
35 const char *test_data = "Hello World!";
36
37 /* Generate keys */
38 GNUNET_CRYPTO_ecdsa_key_create (&skey);
39 GNUNET_CRYPTO_ecdsa_key_get_public (&skey, &pkey);
40
41 GNUNET_assert (GNUNET_OK ==
42 GNUNET_CRYPTO_ecdsa_sign_raw (&skey,
43 test_data,
44 strlen (test_data),
45 &sig));
46
47 return 0;
48}
49
50int
51main (int argc, char *argv[])
52{
53 return test_GNUNET_CRYPTO_ecdsa_sign_raw ();
54}
55
56
57/* end of test_crypto_ecc.c */