diff options
Diffstat (limited to 'src/cli/util')
-rw-r--r-- | src/cli/util/.gitignore | 10 | ||||
-rw-r--r-- | src/cli/util/Makefile.am | 108 | ||||
-rw-r--r-- | src/cli/util/crypto-test-vectors.json | 56 | ||||
-rw-r--r-- | src/cli/util/gnunet-base32.c | 155 | ||||
-rw-r--r-- | src/cli/util/gnunet-config-diff.c | 24 | ||||
-rw-r--r-- | src/cli/util/gnunet-config.c | 206 | ||||
-rw-r--r-- | src/cli/util/gnunet-crypto-tvg.c | 1608 | ||||
-rw-r--r-- | src/cli/util/gnunet-ecc.c | 510 | ||||
-rw-r--r-- | src/cli/util/gnunet-qr.c | 597 | ||||
-rw-r--r-- | src/cli/util/gnunet-resolver.c | 191 | ||||
-rw-r--r-- | src/cli/util/gnunet-scrypt.c | 325 | ||||
-rw-r--r-- | src/cli/util/gnunet-timeout.c | 119 | ||||
-rw-r--r-- | src/cli/util/gnunet-uri.c | 192 | ||||
-rw-r--r-- | src/cli/util/meson.build | 62 | ||||
-rwxr-xr-x | src/cli/util/test_crypto_vectors.sh | 3 |
15 files changed, 4166 insertions, 0 deletions
diff --git a/src/cli/util/.gitignore b/src/cli/util/.gitignore new file mode 100644 index 000000000..9e045f16f --- /dev/null +++ b/src/cli/util/.gitignore | |||
@@ -0,0 +1,10 @@ | |||
1 | gnunet-config | ||
2 | gnunet-config-diff | ||
3 | gnunet-crypto-tvg | ||
4 | gnunet-ecc | ||
5 | gnunet-qr | ||
6 | gnunet-resolver | ||
7 | gnunet-scrypt | ||
8 | gnunet-uri | ||
9 | gnunet-base32 | ||
10 | gnunet-timeout | ||
diff --git a/src/cli/util/Makefile.am b/src/cli/util/Makefile.am new file mode 100644 index 000000000..cac477e13 --- /dev/null +++ b/src/cli/util/Makefile.am | |||
@@ -0,0 +1,108 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | plugindir = $(libdir)/gnunet | ||
5 | |||
6 | libexecdir= $(pkglibdir)/libexec/ | ||
7 | |||
8 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
9 | |||
10 | if USE_COVERAGE | ||
11 | AM_CFLAGS = --coverage -O0 | ||
12 | XLIB = -lgcov | ||
13 | endif | ||
14 | |||
15 | gnunet_config_diff_SOURCES = \ | ||
16 | gnunet-config-diff.c | ||
17 | gnunet_config_diff_LDADD = \ | ||
18 | $(top_builddir)/src/lib/util/libgnunetutil.la | ||
19 | |||
20 | GNUNET_ECC = gnunet-ecc | ||
21 | GNUNET_SCRYPT = gnunet-scrypt | ||
22 | |||
23 | libexec_PROGRAMS = \ | ||
24 | gnunet-timeout | ||
25 | |||
26 | bin_PROGRAMS = \ | ||
27 | gnunet-base32 \ | ||
28 | gnunet-config \ | ||
29 | gnunet-resolver \ | ||
30 | $(GNUNET_ECC) \ | ||
31 | $(GNUNET_SCRYPT) \ | ||
32 | gnunet-uri | ||
33 | if HAVE_ZBAR | ||
34 | bin_PROGRAMS += gnunet-qr | ||
35 | endif | ||
36 | |||
37 | noinst_PROGRAMS = \ | ||
38 | gnunet-config-diff \ | ||
39 | gnunet-crypto-tvg | ||
40 | |||
41 | if ENABLE_TEST_RUN | ||
42 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
43 | TESTS = $(check_PROGRAMS) $(check_SCRIPTS) | ||
44 | endif | ||
45 | |||
46 | gnunet_timeout_SOURCES = \ | ||
47 | gnunet-timeout.c | ||
48 | |||
49 | gnunet_resolver_SOURCES = \ | ||
50 | gnunet-resolver.c | ||
51 | gnunet_resolver_LDADD = \ | ||
52 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
53 | $(GN_LIBINTL) | ||
54 | |||
55 | gnunet_crypto_tvg_SOURCES = \ | ||
56 | gnunet-crypto-tvg.c | ||
57 | gnunet_crypto_tvg_LDADD = \ | ||
58 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
59 | $(GN_LIBINTL) -lgcrypt -ljansson | ||
60 | |||
61 | gnunet_ecc_SOURCES = \ | ||
62 | gnunet-ecc.c | ||
63 | gnunet_ecc_LDADD = \ | ||
64 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
65 | $(GN_LIBINTL) -lgcrypt | ||
66 | |||
67 | gnunet_base32_SOURCES = \ | ||
68 | gnunet-base32.c | ||
69 | gnunet_base32_LDADD = \ | ||
70 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
71 | $(GN_LIBINTL) | ||
72 | |||
73 | gnunet_scrypt_SOURCES = \ | ||
74 | gnunet-scrypt.c | ||
75 | gnunet_scrypt_LDADD = \ | ||
76 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
77 | $(GN_LIBINTL) -lgcrypt | ||
78 | |||
79 | |||
80 | gnunet_config_SOURCES = \ | ||
81 | gnunet-config.c | ||
82 | gnunet_config_LDADD = \ | ||
83 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
84 | $(GN_LIBINTL) | ||
85 | |||
86 | gnunet_uri_SOURCES = \ | ||
87 | gnunet-uri.c | ||
88 | gnunet_uri_LDADD = \ | ||
89 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
90 | $(GN_LIBINTL) | ||
91 | |||
92 | |||
93 | gnunet_qr_SOURCES = \ | ||
94 | gnunet-qr.c | ||
95 | gnunet_qr_LDADD = \ | ||
96 | $(top_builddir)/src/lib/util/libgnunetutil.la \ | ||
97 | $(GN_LIBINTL) | ||
98 | gnunet_qr_LDFLAGS= -lzbar | ||
99 | if HAVE_PNG | ||
100 | gnunet_qr_LDFLAGS += -lpng | ||
101 | endif | ||
102 | |||
103 | check_SCRIPTS = \ | ||
104 | test_crypto_vectors.sh | ||
105 | |||
106 | EXTRA_DIST = \ | ||
107 | test_crypto_vectors.sh \ | ||
108 | crypto-test-vectors.json | ||
diff --git a/src/cli/util/crypto-test-vectors.json b/src/cli/util/crypto-test-vectors.json new file mode 100644 index 000000000..972b62c3e --- /dev/null +++ b/src/cli/util/crypto-test-vectors.json | |||
@@ -0,0 +1,56 @@ | |||
1 | { | ||
2 | "encoding": "base32crockford", | ||
3 | "producer": "GNUnet 0.14.0 git-64ad3b0a1", | ||
4 | "vectors": [ | ||
5 | { | ||
6 | "operation": "hash", | ||
7 | "input": "91JPRV3F5GG4EKJNDSJQ8", | ||
8 | "output": "D0R24RZ1TPASVQ2NY56CT8AJDYZE9ZGDB0GVZ05E9D4YGZQW2RC5YFPQ0Q86EPW836DY7VYQTNFFJT3ZR2K508F4JVS5JNJKYN2MMFR" | ||
9 | }, | ||
10 | { | ||
11 | "operation": "ecc_ecdh", | ||
12 | "priv1": "TFA439C75RT2JK9V6GTRRXH3QR3QC4SVJ1KBQ4MNY3S338GT6T50", | ||
13 | "pub1": "E19WJDA83485BC8EC8RV7FTAK86BESJG1YNYRENEC0JV7XEZ7M80", | ||
14 | "priv2": "2DT3B0TMY6VVP56YZKG5ASRSQAEV0GB4QMT9N6CTPDARNJ905APG", | ||
15 | "skm": "GY63DCHR6BGV2AKDM44V7A4H4DA0WJC7D5C2R7DXTWC9D83H7XM0PEQKKZ1K2HWMWBSBNPDWXDN7PA1R1WJKVQ2RDTNF1PBXCFHM9QR" | ||
16 | }, | ||
17 | { | ||
18 | "operation": "eddsa_key_derivation", | ||
19 | "priv": "8QC2VNF8443S5KPNKMB4XMV58BTHWAKZ7SVW5WG3KRB37567XS90", | ||
20 | "pub": "3M9KK1WSNM1RTY5P72HKFA264V4B7MVHVJ08Y90CV06DYHV8XPP0" | ||
21 | }, | ||
22 | { | ||
23 | "operation": "eddsa_signing", | ||
24 | "priv": "5077XJR9AMH4T97ACKFBVBJD0KFENHPV66B2Y1JBSKXBJKNZJ4E0", | ||
25 | "pub": "6E2F03JJ8AEDANTTZZ4SBZDFEEZSF8A9DVGTS6VFBCVZQYQ46RRG", | ||
26 | "data": "00000300000000000000", | ||
27 | "sig": "XCNJGJ96WPDH60YVMH6C74NGQSGJE3BC1TYMGX6BHY5DMZZZKTB373QTXJ507K5EBSG9YS2EYKHCX3ATRQ6P5MY9MXC4ZB1XSZ2X23G" | ||
28 | }, | ||
29 | { | ||
30 | "operation": "kdf", | ||
31 | "salt": "94KPT83PCNS7J83KC5P78Y8", | ||
32 | "ikm": "94KPT83MD1JJ0WV5CDS6AX10D5Q70XBM41NPAY90DNGQ8SBJD5GPR", | ||
33 | "ctx": "94KPT83141HPYVKMCNW78833D1TPWTSC41GPRWVF41NPWVVQDRG62WS04XMPWSKF4WG6JVH0EHM6A82J8S1G", | ||
34 | "out_len %u\n": 64, | ||
35 | "out": "GTMR4QT05Z9WF5HKVG0WK9RPXGHSMHJNW377G9GJXCA8B0FEKPF4D27RJMSJZYWSQNTBJ5EYVV7ZW18B48Z0JVJJ80RHB706Y96Q358" | ||
36 | }, | ||
37 | { | ||
38 | "operation": "eddsa_ecdh", | ||
39 | "priv_ecdhe": "5FBRFZY942H2PD96NFNYWZKYXCRFY11JWQ59V7G9B4M8EX1KE100", | ||
40 | "pub_ecdhe": "GDX7FC01AZYMG0BY0AMHR6E7KCGX9F6SWES16WZ1QWZ2VSYXKH00", | ||
41 | "priv_eddsa": "3HYHM9DZQ3D61APDQNBCSKJE452YEP6JK01DWR1J3VZAASFEA570", | ||
42 | "pub_eddsa": "87N7PFAHBX97HRE8XYW8KYN64YZDF4FCBR2BZ5SZN3QE3D2BF0R0", | ||
43 | "key_material": "QH0RAXXC9RYDEAXKNTAWM0WXJS25RS67H5T252EGA22RA6JTYRFDAEK8CJY85QSYWGYHQXK5Y1SWSRB3P0NXNXYP237EXMXQ3P2WE00" | ||
44 | }, | ||
45 | { | ||
46 | "operation": "rsa_blind_signing", | ||
47 | "message_hash": "XKQMJ4CNTXBFE1V2WR6JS063J7PZQE4XMB5JH3RS5X0THQ1JQSQ69Y7KDBC9TYRJEZH48MEPY2SF4QHQ4VHXC0YQX5935MQEGP0AX6R", | ||
48 | "rsa_public_key": "040000YRN1NVJ68RS6RJF52PGRCQG19ZKWQPSTJX2G7ZDCKSZFE2VW3HHA81YF5C639JHJF5TX8YTEE2FW2WQCG1PTKNBSPPJEJGA032CN3E8QZ27VWY0K6JFT8ZSYWRH2SKDMXW56A4QKY46JJBWJ6T0ZRVBW6S1HTHXVE2RW8MXRW5T801077MDY13N5F8Z1JZVKBJ06TK3S0YPEDBXK0VEHRHEQJ5X5XYKR4KQTFAZNBMKXY8836VCHBXTK4YNX6AJ1CK29SMJH3Z3QRM16A2TNQGFR0HSMV446BF7FMT2E379ZAT5ST4G3BM2NWZYW545S2SW5MG5S6M88XZZ7SKFD48YVXNZ205GGSEYJPVBMR76WG4ZG30WBCPC1N54XE12RMAG81D8C09WG22PKGGDHYXX68N04002", | ||
49 | "rsa_private_key": "50W3MTV5F4PP8RBMC4520A1H60X70XB2DHMP6BBBCNWGM81050SKMWKKC452081050RKMVHJ6MVKM06RN1NVJ68RS6RJF52PGRCQG19ZKWQPSTJX2G7ZDCKSZFE2VW3HHA81YF5C639JHJF5TX8YTEE2FW2WQCG1PTKNBSPPJEJGA032CN3E8QZ27VWY0K6JFT8ZSYWRH2SKDMXW56A4QKY46JJBWJ6T0ZRVBW6S1HTHXVE2RW8MXRW5T801077MDY13N5F8Z1JZVKBJ06TK3S0YPEDBXK0VEHRHEQJ5X5XYKR4KQTFAZNBMKXY8836VCHBXTK4YNX6AJ1CK29SMJH3Z3QRM16A2TNQGFR0HSMV446BF7FMT2E379ZAT5ST4G3BM2NWZYW545S2SW5MG5S6M88XZZ7SKFD48YVXNZ205GGSEYJPVBMR76WG4ZG30WBCPC1N54XE12RMAG81D8C09WG22PKGGDHYXX68N5452081050RKMS9K780G009918G2081918G20A8A40M32C9TE1S6JXK1EHJJTTV5F45208186CX74WV118G2081864X6WCHN6WX01P58DEWHJ669P4KS8NM635W0AFWZ5XPEMQ8M1ZVB4YFVVGPZ0WCAJ0FKSB1GTCMCKSEQA7PKKGKZ0Q5V40DPMXAYDNMKMM2G0RK58VJ5ZRHYZ7G4SMKYJ7YFQ648PCVD7F19JH5WZH1MMJZ4HPG7Y6TZ1P8CEMFEVGP7257E71EJ0081SX3FG8X9BT7RCQYWTWG1PMRY87NKKAZCR6VME4BNWHF9FFMY14XYKTQXAX4ZFJ20SPV4AZEMS7NF9JMGB4RJED4M8ZRXY509JGPNDW3Y04ED6S11JVSVX6GKGSTFTPHEEH40TX0NF7ZQ191E8PF1D41E9N227FZSYCVV927PZDFRG1C46BQMNPTX61SQ417W0R72V5K0D997BG8P52M20BA302F40GNMW43CFQF9J59918G2081864X6ACST04002A8A40G20A1H79J34D9P78SBPDS45EQZVX2D6R1GZ6FHKHDG4ABYZ6FCPSMMGZ29ZY5NS8B304D0QBD800A5SM3D8S92WKS3KFWFXE8X597TNJBR94BGNCFHY8TV63KQZ0RFMRTPHFA2XNFX2V4KECZNTHGKZNJTWH8051XP6FJJ6700A5KWMH24CK1KF9XVH2ATQJ4F1ZJZQM00A00ESTVKM5N58K5FN5TW34B1H1Q1CWRZXJ9QMBG0QKHXHZMFYZSN9ERV59935716NGSX9GBB3R9BY32TBTAJ7K0N391ATSE5263X5NKVDH7XCF1PF0WRTTJYBAJBQWVGJ8P7RGVWB27Q3S4AJJ55FS2T9K341EHATHJZQQTR0JWP5E4NQHR4GN60QMK2SY0VJM56N0NHJXRGAGJW3S9ABJ7M4TAV6YRJJ2H040G2GC9TE0RK4E9T03CET00DAJDXJ1NF511J69JMDDSVARPSFSS6AJTRMVXD10NVA4Z162ER74WNH0J6H2RTA9C9MZM4TEBP8P7AF0NANBH4XZJCNDZV7BEAMJ6R363GHZKGBR0HH1SATGWNJWGW2961MRFPX7S0RJK7CWYE7EX1XQ2683TENRPDKV29D1F1RNDD6P04MZTKSH5YMEZPKGEDRJZXXM9918G2081864X72C9J74X01ZXF256C681JDWRRG7T4AC9JRHP54YM65X9AT17YGC3G4569ZKBQEZ219Y7JG4V10F4AW7Q1XKGPTW3Y3X0WCTB06HM249Q094VHEYD4BTEQ2DF334W8G3VEB7N1CHCMPZEVVTR0XWQSNV6MBJRF5MBY6Z148YA36YA61EXA28PHE3KSN1M4HVF7B06JD736TSK9GC9CAG8F0MMGM81040M32EKN64S3JEG0YCC3PHPNBZAGQ2WE8HJHM28B049N2MQ94G8VPXNHG43C6ADB44DE1DK8ASMYTSXZWMAYKN1SS2GVFTVH8Q4N3TTJ3BKA61Y93QE17XNRF3S0CSSQTY3SVVAFHDA9APFFSMRYD67N4DXQ1X42NA270VF6H0MCRQ87JKVBQAB0CH2WH7RHYMCQ4KN50M2NEFE1YA6F2N2DG7Z9JA8A40G20A8A40G2J2H054500", | ||
50 | "blinding_key_secret": "3SWF49XZPHQMENTSBZQR7Z0B8ZSZ2JRARE79Q4VXZMQ7W6QABXMG", | ||
51 | "blinded_message": "3KHKZJZ30ABB4E56MA2V0EQWGCWH0QQG9P2ZHYHR186C5HZXJMM4N9WXAQTKS94QSV9Y17GGNXN5MB1PZZFG7Q0FY88QPKKRG4MYCPSMTZK5W59R0MJVNJ4P4AQM96TDG5W7RV8GSNR1QQZ1GNHW3CX6D6ZRTMXB2NKB5SSYTDJS79F5ZFBRZ4HVED9JBBPWSR79KVV5QQ4APBGHBCKGMF9NJJS53A1BVYHDEVYAGFYF2SNEP827ZP50FKJ5GKGV8NQ15ESEZ69AT7GJG0T3TZVENY2YN9CVR98W3BKEZ53J7VTANARG8SJS8AMJQ7S23P5HRJ7XE9KTNRNXKH49MXV9JHHYE5535N7AGWEKR47SBCGNF44Z7XJ9RV5BQV12ZRJKN4HBZQHDNCMH3QKX9Z6G64", | ||
52 | "blinded_sig": "ND1V807BK0G73SDXN582BP3Q21MWF4A76EGWD0KA3XGJAWPSVHNHKA44931ZRB9M76SYAFD8ZPTG3A7FH5G2CWGX76VXTCDX5XNRW7EEBNMPDAQ0ZEKF6AHP872SKCGRH89SK4NGC57M8BRA3ZRPDDT9XCBG3XY02VQH4Z0F39DPBS48K0EBMK7B9S3X6QDNR5ND5MV0G7G7T3VPKZRW94MQBKPY1T6K53MQGG4PV81D9YEWNRM3WE04NNQREYDA5ETVDWQ5ZCYV9HF4ZCMWVVGWDBDH732JA3NKZ2B8QK0E6XS0Y4GGGQJS6HFQ4PATGK3TS5GHJEPDF3A6XAFNJQV99CSJW7V1NC504NTQ5NJ8KAVC1758MBBV3SS2BND4YHF0Y4NWJNVH3STV166YWFKR8W", | ||
53 | "sig": "EC5MVSPGQMM96N2VT4R2G5104E61V8RY4PR6AK9F614TVVEN7D152T0DP97CDTRDDSQGBV4GZWXQPM90SW30R2RAKKHNDCXHQFAMRSW1XCBEKVKBGC6FP0AQY9S37NVR01VJ2WVX8PN29H2ZFFQBQ9JK96GTJZ3B7DD583S8Y93GH5KWEM41CZJ73QCRT1A2AGVXX5ACFR0T448MC81QB4EGCKP5Z96VCX6RPDD5S9A4295M0E9PPQJCN5G5JKWKG17HWEDF4A26ZMD8YW27EQBZ69GSEZX4PWEV7AXFGG5X0RPKCQEPCX7XDY6NXJ1E2FZBX259RDRCFNDAZS80T0DHD9NVE73QDDESZYEZTM1TM669GHPN8AF4QV8DNW7SFZZKJ67FWR8CZC0PWTEN4ZPTRM" | ||
54 | } | ||
55 | ] | ||
56 | } | ||
diff --git a/src/cli/util/gnunet-base32.c b/src/cli/util/gnunet-base32.c new file mode 100644 index 000000000..209741740 --- /dev/null +++ b/src/cli/util/gnunet-base32.c | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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/gnunet-base32.c | ||
23 | * @brief tool to encode/decode from/to the Crockford Base32 encoding GNUnet uses | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * The main function of gnunet-base32 | ||
33 | * | ||
34 | * @param argc number of arguments from the command line | ||
35 | * @param argv command line arguments | ||
36 | * @return 0 ok, 1 on error | ||
37 | */ | ||
38 | int | ||
39 | main (int argc, | ||
40 | char *const *argv) | ||
41 | { | ||
42 | int decode = 0; | ||
43 | const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
44 | GNUNET_GETOPT_option_flag ('d', | ||
45 | "decode", | ||
46 | gettext_noop ( | ||
47 | "run decoder modus, otherwise runs as encoder"), | ||
48 | &decode), | ||
49 | GNUNET_GETOPT_option_help ("Crockford base32 encoder/decoder"), | ||
50 | GNUNET_GETOPT_option_version (PACKAGE_VERSION), | ||
51 | GNUNET_GETOPT_OPTION_END | ||
52 | }; | ||
53 | int ret; | ||
54 | char *in; | ||
55 | unsigned int in_size; | ||
56 | ssize_t iret; | ||
57 | char *out; | ||
58 | size_t out_size; | ||
59 | |||
60 | if (GNUNET_OK != | ||
61 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
62 | &argc, &argv)) | ||
63 | return 2; | ||
64 | ret = GNUNET_GETOPT_run ("gnunet-base32", | ||
65 | options, | ||
66 | argc, | ||
67 | argv); | ||
68 | if (ret < 0) | ||
69 | return 1; | ||
70 | if (0 == ret) | ||
71 | return 0; | ||
72 | in_size = 0; | ||
73 | in = NULL; | ||
74 | iret = 1; | ||
75 | while (iret > 0) | ||
76 | { | ||
77 | /* read in blocks of 4k */ | ||
78 | char buf[4092]; | ||
79 | |||
80 | iret = read (0, | ||
81 | buf, | ||
82 | sizeof (buf)); | ||
83 | if (iret < 0) | ||
84 | { | ||
85 | GNUNET_free (in); | ||
86 | return 2; | ||
87 | } | ||
88 | if (iret > 0) | ||
89 | { | ||
90 | if (iret + in_size < in_size) | ||
91 | { | ||
92 | GNUNET_break (0); | ||
93 | GNUNET_free (in); | ||
94 | return 1; | ||
95 | } | ||
96 | GNUNET_array_grow (in, | ||
97 | in_size, | ||
98 | in_size + iret); | ||
99 | memcpy (&in[in_size - iret], | ||
100 | buf, | ||
101 | iret); | ||
102 | } | ||
103 | } | ||
104 | if (decode) | ||
105 | { | ||
106 | /* This formula can overestimate by 1 byte, so we try both | ||
107 | out_size and out_size-1 below */ | ||
108 | out_size = in_size * 5 / 8; | ||
109 | out = GNUNET_malloc (out_size); | ||
110 | if ( (GNUNET_OK != | ||
111 | GNUNET_STRINGS_string_to_data (in, | ||
112 | in_size, | ||
113 | out, | ||
114 | out_size)) && | ||
115 | (out_size > 0) ) | ||
116 | { | ||
117 | out_size--; | ||
118 | if (GNUNET_OK != | ||
119 | GNUNET_STRINGS_string_to_data (in, | ||
120 | in_size, | ||
121 | out, | ||
122 | out_size)) | ||
123 | { | ||
124 | GNUNET_free (out); | ||
125 | GNUNET_free (in); | ||
126 | return 3; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | else | ||
131 | { | ||
132 | out = GNUNET_STRINGS_data_to_string_alloc (in, | ||
133 | in_size); | ||
134 | out_size = strlen (out); | ||
135 | } | ||
136 | { | ||
137 | size_t pos = 0; | ||
138 | |||
139 | while (pos < out_size) | ||
140 | { | ||
141 | iret = write (1, | ||
142 | &out[pos], | ||
143 | out_size - pos); | ||
144 | if (iret <= 0) | ||
145 | return 4; | ||
146 | pos += iret; | ||
147 | } | ||
148 | } | ||
149 | GNUNET_free (out); | ||
150 | GNUNET_free_nz ((void *) argv); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | |||
155 | /* end of gnunet-uri.c */ | ||
diff --git a/src/cli/util/gnunet-config-diff.c b/src/cli/util/gnunet-config-diff.c new file mode 100644 index 000000000..e1e3ffd5d --- /dev/null +++ b/src/cli/util/gnunet-config-diff.c | |||
@@ -0,0 +1,24 @@ | |||
1 | |||
2 | #include "platform.h" | ||
3 | #include <gnunet_util_lib.h> | ||
4 | |||
5 | int | ||
6 | main (int argc, char **argv) | ||
7 | { | ||
8 | struct GNUNET_CONFIGURATION_Handle *i1; | ||
9 | struct GNUNET_CONFIGURATION_Handle *i2; | ||
10 | |||
11 | if (argc != 3) | ||
12 | { | ||
13 | fprintf (stderr, "Invoke using `%s DEFAULTS-IN DIFFS'\n", argv[0]); | ||
14 | return 1; | ||
15 | } | ||
16 | i1 = GNUNET_CONFIGURATION_create (); | ||
17 | i2 = GNUNET_CONFIGURATION_create (); | ||
18 | if ((GNUNET_OK != GNUNET_CONFIGURATION_load (i1, argv[1])) || | ||
19 | (GNUNET_OK != GNUNET_CONFIGURATION_load (i2, argv[2]))) | ||
20 | return 1; | ||
21 | if (GNUNET_OK != GNUNET_CONFIGURATION_write_diffs (i1, i2, argv[2])) | ||
22 | return 2; | ||
23 | return 0; | ||
24 | } | ||
diff --git a/src/cli/util/gnunet-config.c b/src/cli/util/gnunet-config.c new file mode 100644 index 000000000..714c683dd --- /dev/null +++ b/src/cli/util/gnunet-config.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2021 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/gnunet-config.c | ||
23 | * @brief tool to access and manipulate GNUnet configuration files | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Backend to check if the respective plugin is | ||
33 | * loadable. NULL if no check is to be performed. | ||
34 | * The value is the "basename" of the plugin to load. | ||
35 | */ | ||
36 | static char *backend_check; | ||
37 | |||
38 | |||
39 | /** | ||
40 | * If printing the value of CFLAGS has been requested. | ||
41 | */ | ||
42 | static int cflags; | ||
43 | |||
44 | /** | ||
45 | * Check if this is an experimental build | ||
46 | */ | ||
47 | static int is_experimental; | ||
48 | |||
49 | |||
50 | /** | ||
51 | * If printing the value of LIBS has been requested. | ||
52 | */ | ||
53 | static int libs; | ||
54 | |||
55 | |||
56 | /** | ||
57 | * If printing the value of PREFIX has been requested. | ||
58 | */ | ||
59 | static int prefix; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Print each option in a given section. | ||
64 | * Main task to run to perform operations typical for | ||
65 | * gnunet-config as per the configuration settings | ||
66 | * given in @a cls. | ||
67 | * | ||
68 | * @param cls closure with the `struct GNUNET_CONFIGURATION_ConfigSettings` | ||
69 | * @param args remaining command-line arguments | ||
70 | * @param cfgfile name of the configuration file used (for saving, | ||
71 | * can be NULL!) | ||
72 | * @param cfg configuration | ||
73 | */ | ||
74 | static void | ||
75 | run (void *cls, | ||
76 | char *const *args, | ||
77 | const char *cfgfile, | ||
78 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
79 | { | ||
80 | struct GNUNET_CONFIGURATION_ConfigSettings *cs = cls; | ||
81 | |||
82 | if (1 == is_experimental) | ||
83 | { | ||
84 | #ifdef GNUNET_EXPERIMENTAL | ||
85 | cs->global_ret = 0; | ||
86 | #else | ||
87 | cs->global_ret = 1; | ||
88 | #endif | ||
89 | return; | ||
90 | } | ||
91 | if (1 == cflags || 1 == libs || 1 == prefix) | ||
92 | { | ||
93 | char *prefixdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_PREFIX); | ||
94 | char *libdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); | ||
95 | |||
96 | if (1 == cflags) | ||
97 | { | ||
98 | fprintf (stdout, "-I%sinclude\n", prefixdir); | ||
99 | } | ||
100 | if (1 == libs) | ||
101 | { | ||
102 | fprintf (stdout, "-L%s -lgnunetutil\n", libdir); | ||
103 | } | ||
104 | if (1 == prefix) | ||
105 | { | ||
106 | fprintf (stdout, "%s\n", prefixdir); | ||
107 | } | ||
108 | cs->global_ret = 0; | ||
109 | GNUNET_free (prefixdir); | ||
110 | GNUNET_free (libdir); | ||
111 | return; | ||
112 | } | ||
113 | if (NULL != backend_check) | ||
114 | { | ||
115 | char *name; | ||
116 | |||
117 | GNUNET_asprintf (&name, | ||
118 | "libgnunet_plugin_%s", | ||
119 | backend_check); | ||
120 | cs->global_ret = (GNUNET_OK == | ||
121 | GNUNET_PLUGIN_test (name)) ? 0 : 77; | ||
122 | GNUNET_free (name); | ||
123 | return; | ||
124 | } | ||
125 | GNUNET_CONFIGURATION_config_tool_run (cs, | ||
126 | args, | ||
127 | cfgfile, | ||
128 | cfg); | ||
129 | } | ||
130 | |||
131 | |||
132 | /** | ||
133 | * Program to manipulate configuration files. | ||
134 | * | ||
135 | * @param argc number of arguments from the command line | ||
136 | * @param argv command line arguments | ||
137 | * @return 0 ok, 1 on error | ||
138 | */ | ||
139 | int | ||
140 | main (int argc, | ||
141 | char *const *argv) | ||
142 | { | ||
143 | struct GNUNET_CONFIGURATION_ConfigSettings cs = { | ||
144 | .api_version = GNUNET_UTIL_VERSION, | ||
145 | .global_ret = EXIT_SUCCESS | ||
146 | }; | ||
147 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
148 | GNUNET_GETOPT_option_exclusive ( | ||
149 | GNUNET_GETOPT_option_string ( | ||
150 | 'b', | ||
151 | "supported-backend", | ||
152 | "BACKEND", | ||
153 | gettext_noop ( | ||
154 | "test if the current installation supports the specified BACKEND"), | ||
155 | &backend_check)), | ||
156 | GNUNET_GETOPT_option_flag ( | ||
157 | 'C', | ||
158 | "cflags", | ||
159 | gettext_noop ( | ||
160 | "Provide an appropriate value for CFLAGS to applications building on top of GNUnet"), | ||
161 | &cflags), | ||
162 | GNUNET_GETOPT_option_flag ( | ||
163 | 'E', | ||
164 | "is-experimental", | ||
165 | gettext_noop ("Is this an experimental build of GNUnet"), | ||
166 | &is_experimental), | ||
167 | GNUNET_GETOPT_option_flag ( | ||
168 | 'j', | ||
169 | "libs", | ||
170 | gettext_noop ( | ||
171 | "Provide an appropriate value for LIBS to applications building on top of GNUnet"), | ||
172 | &libs), | ||
173 | GNUNET_GETOPT_option_flag ( | ||
174 | 'p', | ||
175 | "prefix", | ||
176 | gettext_noop ( | ||
177 | "Provide the path under which GNUnet was installed"), | ||
178 | &prefix), | ||
179 | GNUNET_CONFIGURATION_CONFIG_OPTIONS (&cs), | ||
180 | GNUNET_GETOPT_OPTION_END | ||
181 | }; | ||
182 | enum GNUNET_GenericReturnValue ret; | ||
183 | |||
184 | if (GNUNET_OK != | ||
185 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
186 | &argc, &argv)) | ||
187 | return EXIT_FAILURE; | ||
188 | ret = | ||
189 | GNUNET_PROGRAM_run (argc, | ||
190 | argv, | ||
191 | "gnunet-config [OPTIONS]", | ||
192 | gettext_noop ("Manipulate GNUnet configuration files"), | ||
193 | options, | ||
194 | &run, | ||
195 | &cs); | ||
196 | GNUNET_free_nz ((void *) argv); | ||
197 | GNUNET_CONFIGURATION_config_settings_free (&cs); | ||
198 | if (GNUNET_NO == ret) | ||
199 | return 0; | ||
200 | if (GNUNET_SYSERR == ret) | ||
201 | return EXIT_INVALIDARGUMENT; | ||
202 | return cs.global_ret; | ||
203 | } | ||
204 | |||
205 | |||
206 | /* end of gnunet-config.c */ | ||
diff --git a/src/cli/util/gnunet-crypto-tvg.c b/src/cli/util/gnunet-crypto-tvg.c new file mode 100644 index 000000000..721177eda --- /dev/null +++ b/src/cli/util/gnunet-crypto-tvg.c | |||
@@ -0,0 +1,1608 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020 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/gnunet-crypto-tgv.c | ||
23 | * @brief Generate test vectors for cryptographic operations. | ||
24 | * @author Florian Dold | ||
25 | * | ||
26 | * Note that this program shouldn't depend on code in src/json/, | ||
27 | * so we're using raw jansson and no GNUnet JSON helpers. | ||
28 | * | ||
29 | * Test vectors have the following format (TypeScript pseudo code): | ||
30 | * | ||
31 | * interface TestVectorFile { | ||
32 | * encoding: "base32crockford"; | ||
33 | * producer?: string; | ||
34 | * vectors: TestVector[]; | ||
35 | * } | ||
36 | * | ||
37 | * enum Operation { | ||
38 | * Hash("hash"), | ||
39 | * ... | ||
40 | * } | ||
41 | * | ||
42 | * interface TestVector { | ||
43 | * operation: Operation; | ||
44 | * // Inputs for the operation | ||
45 | * [ k: string]: string | number; | ||
46 | * }; | ||
47 | * | ||
48 | * | ||
49 | */ | ||
50 | |||
51 | #include "platform.h" | ||
52 | #include "gnunet_util_lib.h" | ||
53 | #include "gnunet_signatures.h" | ||
54 | #include "gnunet_testing_lib.h" | ||
55 | #include <jansson.h> | ||
56 | #include <gcrypt.h> | ||
57 | |||
58 | GNUNET_NETWORK_STRUCT_BEGIN | ||
59 | |||
60 | /** | ||
61 | * Sample signature struct. | ||
62 | * | ||
63 | * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST | ||
64 | */ | ||
65 | struct TestSignatureDataPS | ||
66 | { | ||
67 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
68 | uint32_t testval; | ||
69 | }; | ||
70 | |||
71 | GNUNET_NETWORK_STRUCT_END | ||
72 | |||
73 | |||
74 | /** | ||
75 | * Should we verify or output test vectors? | ||
76 | */ | ||
77 | static int verify_flag = GNUNET_NO; | ||
78 | |||
79 | |||
80 | /** | ||
81 | * Global exit code. | ||
82 | */ | ||
83 | static int global_ret = 0; | ||
84 | |||
85 | |||
86 | /** | ||
87 | * Create a fresh test vector for a given operation label. | ||
88 | * | ||
89 | * @param vecs array of vectors to append the new vector to | ||
90 | * @param vecname label for the operation of the vector | ||
91 | * @returns the fresh test vector | ||
92 | */ | ||
93 | static json_t * | ||
94 | vec_for (json_t *vecs, const char *vecname) | ||
95 | { | ||
96 | json_t *t = json_object (); | ||
97 | |||
98 | json_object_set_new (t, | ||
99 | "operation", | ||
100 | json_string (vecname)); | ||
101 | json_array_append_new (vecs, t); | ||
102 | return t; | ||
103 | } | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Add a base32crockford encoded value | ||
108 | * to a test vector. | ||
109 | * | ||
110 | * @param vec test vector to add to | ||
111 | * @param label label for the value | ||
112 | * @param data data to add | ||
113 | * @param size size of data | ||
114 | */ | ||
115 | static void | ||
116 | d2j (json_t *vec, | ||
117 | const char *label, | ||
118 | const void *data, | ||
119 | size_t size) | ||
120 | { | ||
121 | char *buf; | ||
122 | json_t *json; | ||
123 | |||
124 | buf = GNUNET_STRINGS_data_to_string_alloc (data, size); | ||
125 | json = json_string (buf); | ||
126 | GNUNET_free (buf); | ||
127 | GNUNET_break (NULL != json); | ||
128 | |||
129 | json_object_set_new (vec, label, json); | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Add a number to a test vector. | ||
135 | * | ||
136 | * @param vec test vector to add to | ||
137 | * @param label label for the value | ||
138 | * @param data data to add | ||
139 | * @param size size of data | ||
140 | */ | ||
141 | static void | ||
142 | uint2j (json_t *vec, | ||
143 | const char *label, | ||
144 | unsigned int num) | ||
145 | { | ||
146 | json_t *json = json_integer (num); | ||
147 | |||
148 | json_object_set_new (vec, label, json); | ||
149 | } | ||
150 | |||
151 | |||
152 | static int | ||
153 | expect_data_fixed (json_t *vec, | ||
154 | const char *name, | ||
155 | void *data, | ||
156 | size_t expect_len) | ||
157 | { | ||
158 | const char *s = json_string_value (json_object_get (vec, name)); | ||
159 | |||
160 | if (NULL == s) | ||
161 | return GNUNET_NO; | ||
162 | |||
163 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (s, | ||
164 | strlen (s), | ||
165 | data, | ||
166 | expect_len)) | ||
167 | return GNUNET_NO; | ||
168 | return GNUNET_OK; | ||
169 | } | ||
170 | |||
171 | |||
172 | static int | ||
173 | expect_data_dynamic (json_t *vec, | ||
174 | const char *name, | ||
175 | void **data, | ||
176 | size_t *ret_len) | ||
177 | { | ||
178 | const char *s = json_string_value (json_object_get (vec, name)); | ||
179 | char *tmp; | ||
180 | size_t len; | ||
181 | |||
182 | if (NULL == s) | ||
183 | return GNUNET_NO; | ||
184 | |||
185 | len = (strlen (s) * 5) / 8; | ||
186 | if (NULL != ret_len) | ||
187 | *ret_len = len; | ||
188 | tmp = GNUNET_malloc (len); | ||
189 | |||
190 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (s, strlen (s), tmp, len)) | ||
191 | { | ||
192 | GNUNET_free (tmp); | ||
193 | return GNUNET_NO; | ||
194 | } | ||
195 | *data = tmp; | ||
196 | return GNUNET_OK; | ||
197 | } | ||
198 | |||
199 | |||
200 | /** | ||
201 | * Check a single vector. | ||
202 | * | ||
203 | * @param operation operator of the vector | ||
204 | * @param vec the vector, a JSON object. | ||
205 | * | ||
206 | * @returns GNUNET_OK if the vector is okay | ||
207 | */ | ||
208 | static int | ||
209 | checkvec (const char *operation, | ||
210 | json_t *vec) | ||
211 | { | ||
212 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
213 | "checking %s\n", operation); | ||
214 | |||
215 | if (0 == strcmp (operation, "hash")) | ||
216 | { | ||
217 | void *data; | ||
218 | size_t data_len; | ||
219 | struct GNUNET_HashCode hash_out; | ||
220 | struct GNUNET_HashCode hc; | ||
221 | |||
222 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
223 | "input", | ||
224 | &data, | ||
225 | &data_len)) | ||
226 | { | ||
227 | GNUNET_break (0); | ||
228 | return GNUNET_SYSERR; | ||
229 | } | ||
230 | if (GNUNET_OK != expect_data_fixed (vec, | ||
231 | "output", | ||
232 | &hash_out, | ||
233 | sizeof (hash_out))) | ||
234 | { | ||
235 | GNUNET_free (data); | ||
236 | GNUNET_break (0); | ||
237 | return GNUNET_NO; | ||
238 | } | ||
239 | |||
240 | GNUNET_CRYPTO_hash (data, data_len, &hc); | ||
241 | |||
242 | if (0 != GNUNET_memcmp (&hc, &hash_out)) | ||
243 | { | ||
244 | GNUNET_free (data); | ||
245 | GNUNET_break (0); | ||
246 | return GNUNET_NO; | ||
247 | } | ||
248 | GNUNET_free (data); | ||
249 | } | ||
250 | else if (0 == strcmp (operation, "ecc_ecdh")) | ||
251 | { | ||
252 | struct GNUNET_CRYPTO_EcdhePrivateKey priv1; | ||
253 | struct GNUNET_CRYPTO_EcdhePublicKey pub1; | ||
254 | struct GNUNET_CRYPTO_EcdhePrivateKey priv2; | ||
255 | struct GNUNET_HashCode skm; | ||
256 | struct GNUNET_HashCode skm_comp; | ||
257 | |||
258 | if (GNUNET_OK != expect_data_fixed (vec, | ||
259 | "priv1", | ||
260 | &priv1, | ||
261 | sizeof (priv1))) | ||
262 | { | ||
263 | GNUNET_break (0); | ||
264 | return GNUNET_NO; | ||
265 | } | ||
266 | if (GNUNET_OK != expect_data_fixed (vec, | ||
267 | "priv2", | ||
268 | &priv2, | ||
269 | sizeof (priv2))) | ||
270 | { | ||
271 | GNUNET_break (0); | ||
272 | return GNUNET_NO; | ||
273 | } | ||
274 | if (GNUNET_OK != expect_data_fixed (vec, | ||
275 | "pub1", | ||
276 | &pub1, | ||
277 | sizeof (pub1))) | ||
278 | { | ||
279 | GNUNET_break (0); | ||
280 | return GNUNET_NO; | ||
281 | } | ||
282 | if (GNUNET_OK != expect_data_fixed (vec, | ||
283 | "skm", | ||
284 | &skm, | ||
285 | sizeof (skm))) | ||
286 | { | ||
287 | GNUNET_break (0); | ||
288 | return GNUNET_NO; | ||
289 | } | ||
290 | GNUNET_assert (GNUNET_OK == | ||
291 | GNUNET_CRYPTO_ecc_ecdh (&priv2, | ||
292 | &pub1, | ||
293 | &skm_comp)); | ||
294 | if (0 != GNUNET_memcmp (&skm, &skm_comp)) | ||
295 | { | ||
296 | GNUNET_break (0); | ||
297 | return GNUNET_NO; | ||
298 | } | ||
299 | } | ||
300 | else if (0 == strcmp (operation, "eddsa_key_derivation")) | ||
301 | { | ||
302 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
303 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
304 | struct GNUNET_CRYPTO_EddsaPublicKey pub_comp; | ||
305 | |||
306 | if (GNUNET_OK != expect_data_fixed (vec, | ||
307 | "priv", | ||
308 | &priv, | ||
309 | sizeof (priv))) | ||
310 | { | ||
311 | GNUNET_break (0); | ||
312 | return GNUNET_NO; | ||
313 | } | ||
314 | |||
315 | if (GNUNET_OK != expect_data_fixed (vec, | ||
316 | "pub", | ||
317 | &pub, | ||
318 | sizeof (pub))) | ||
319 | { | ||
320 | GNUNET_break (0); | ||
321 | return GNUNET_NO; | ||
322 | } | ||
323 | |||
324 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | ||
325 | &pub_comp); | ||
326 | if (0 != GNUNET_memcmp (&pub, &pub_comp)) | ||
327 | { | ||
328 | GNUNET_break (0); | ||
329 | return GNUNET_NO; | ||
330 | } | ||
331 | |||
332 | } | ||
333 | else if (0 == strcmp (operation, "eddsa_signing")) | ||
334 | { | ||
335 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
336 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
337 | struct TestSignatureDataPS data = { 0 }; | ||
338 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
339 | struct GNUNET_CRYPTO_EddsaSignature sig_comp; | ||
340 | |||
341 | if (GNUNET_OK != expect_data_fixed (vec, | ||
342 | "priv", | ||
343 | &priv, | ||
344 | sizeof (priv))) | ||
345 | { | ||
346 | GNUNET_break (0); | ||
347 | return GNUNET_NO; | ||
348 | } | ||
349 | |||
350 | if (GNUNET_OK != expect_data_fixed (vec, | ||
351 | "pub", | ||
352 | &pub, | ||
353 | sizeof (pub))) | ||
354 | { | ||
355 | GNUNET_break (0); | ||
356 | return GNUNET_NO; | ||
357 | } | ||
358 | |||
359 | if (GNUNET_OK != expect_data_fixed (vec, | ||
360 | "data", | ||
361 | &data, | ||
362 | sizeof (data))) | ||
363 | { | ||
364 | GNUNET_break (0); | ||
365 | return GNUNET_NO; | ||
366 | } | ||
367 | |||
368 | if (GNUNET_OK != expect_data_fixed (vec, | ||
369 | "sig", | ||
370 | &sig, | ||
371 | sizeof (sig))) | ||
372 | { | ||
373 | GNUNET_break (0); | ||
374 | return GNUNET_NO; | ||
375 | } | ||
376 | |||
377 | GNUNET_CRYPTO_eddsa_sign (&priv, | ||
378 | &data, | ||
379 | &sig_comp); | ||
380 | GNUNET_assert (GNUNET_OK == | ||
381 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, | ||
382 | &data, | ||
383 | &sig, | ||
384 | &pub)); | ||
385 | if (0 != GNUNET_memcmp (&sig, &sig_comp)) | ||
386 | { | ||
387 | GNUNET_break (0); | ||
388 | return GNUNET_NO; | ||
389 | } | ||
390 | } | ||
391 | else if (0 == strcmp (operation, "kdf")) | ||
392 | { | ||
393 | size_t out_len; | ||
394 | void *out; | ||
395 | size_t out_len_comp; | ||
396 | void *out_comp; | ||
397 | void *ikm; | ||
398 | size_t ikm_len; | ||
399 | void *salt; | ||
400 | size_t salt_len; | ||
401 | void *ctx; | ||
402 | size_t ctx_len; | ||
403 | |||
404 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
405 | "out", | ||
406 | &out, | ||
407 | &out_len)) | ||
408 | { | ||
409 | GNUNET_break (0); | ||
410 | return GNUNET_SYSERR; | ||
411 | } | ||
412 | |||
413 | out_len_comp = out_len; | ||
414 | out_comp = GNUNET_malloc (out_len_comp); | ||
415 | |||
416 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
417 | "ikm", | ||
418 | &ikm, | ||
419 | &ikm_len)) | ||
420 | { | ||
421 | GNUNET_free (out); | ||
422 | GNUNET_free (out_comp); | ||
423 | GNUNET_break (0); | ||
424 | return GNUNET_SYSERR; | ||
425 | } | ||
426 | |||
427 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
428 | "salt", | ||
429 | &salt, | ||
430 | &salt_len)) | ||
431 | { | ||
432 | GNUNET_free (out); | ||
433 | GNUNET_free (out_comp); | ||
434 | GNUNET_free (ikm); | ||
435 | GNUNET_break (0); | ||
436 | return GNUNET_SYSERR; | ||
437 | } | ||
438 | |||
439 | if (GNUNET_OK != expect_data_dynamic (vec, | ||
440 | "ctx", | ||
441 | &ctx, | ||
442 | &ctx_len)) | ||
443 | { | ||
444 | GNUNET_free (out); | ||
445 | GNUNET_free (out_comp); | ||
446 | GNUNET_free (ikm); | ||
447 | GNUNET_free (salt); | ||
448 | GNUNET_break (0); | ||
449 | return GNUNET_SYSERR; | ||
450 | } | ||
451 | |||
452 | GNUNET_assert (GNUNET_OK == | ||
453 | GNUNET_CRYPTO_kdf (out_comp, | ||
454 | out_len_comp, | ||
455 | salt, | ||
456 | salt_len, | ||
457 | ikm, | ||
458 | ikm_len, | ||
459 | ctx, | ||
460 | ctx_len, | ||
461 | NULL)); | ||
462 | |||
463 | if (0 != memcmp (out, out_comp, out_len)) | ||
464 | { | ||
465 | GNUNET_free (out); | ||
466 | GNUNET_free (out_comp); | ||
467 | GNUNET_free (ikm); | ||
468 | GNUNET_free (salt); | ||
469 | GNUNET_free (ctx); | ||
470 | GNUNET_break (0); | ||
471 | return GNUNET_NO; | ||
472 | } | ||
473 | GNUNET_free (out); | ||
474 | GNUNET_free (out_comp); | ||
475 | GNUNET_free (ikm); | ||
476 | GNUNET_free (salt); | ||
477 | GNUNET_free (ctx); | ||
478 | } | ||
479 | else if (0 == strcmp (operation, "eddsa_ecdh")) | ||
480 | { | ||
481 | struct GNUNET_CRYPTO_EcdhePrivateKey priv_ecdhe; | ||
482 | struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe; | ||
483 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_eddsa; | ||
484 | struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa; | ||
485 | struct GNUNET_HashCode key_material; | ||
486 | struct GNUNET_HashCode key_material_comp; | ||
487 | |||
488 | if (GNUNET_OK != expect_data_fixed (vec, | ||
489 | "priv_ecdhe", | ||
490 | &priv_ecdhe, | ||
491 | sizeof (priv_ecdhe))) | ||
492 | { | ||
493 | GNUNET_break (0); | ||
494 | return GNUNET_NO; | ||
495 | } | ||
496 | |||
497 | if (GNUNET_OK != expect_data_fixed (vec, | ||
498 | "pub_ecdhe", | ||
499 | &pub_ecdhe, | ||
500 | sizeof (pub_ecdhe))) | ||
501 | { | ||
502 | GNUNET_break (0); | ||
503 | return GNUNET_NO; | ||
504 | } | ||
505 | |||
506 | if (GNUNET_OK != expect_data_fixed (vec, | ||
507 | "priv_eddsa", | ||
508 | &priv_eddsa, | ||
509 | sizeof (priv_eddsa))) | ||
510 | { | ||
511 | GNUNET_break (0); | ||
512 | return GNUNET_NO; | ||
513 | } | ||
514 | |||
515 | if (GNUNET_OK != expect_data_fixed (vec, | ||
516 | "pub_eddsa", | ||
517 | &pub_eddsa, | ||
518 | sizeof (pub_eddsa))) | ||
519 | { | ||
520 | GNUNET_break (0); | ||
521 | return GNUNET_NO; | ||
522 | } | ||
523 | |||
524 | if (GNUNET_OK != expect_data_fixed (vec, | ||
525 | "key_material", | ||
526 | &key_material, | ||
527 | sizeof (key_material))) | ||
528 | { | ||
529 | GNUNET_break (0); | ||
530 | return GNUNET_NO; | ||
531 | } | ||
532 | |||
533 | GNUNET_CRYPTO_ecdh_eddsa (&priv_ecdhe, | ||
534 | &pub_eddsa, | ||
535 | &key_material_comp); | ||
536 | |||
537 | if (0 != GNUNET_memcmp (&key_material, | ||
538 | &key_material_comp)) | ||
539 | { | ||
540 | GNUNET_break (0); | ||
541 | return GNUNET_NO; | ||
542 | } | ||
543 | } | ||
544 | else if (0 == strcmp (operation, "rsa_blind_signing")) | ||
545 | { | ||
546 | struct GNUNET_CRYPTO_RsaPrivateKey *skey; | ||
547 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; | ||
548 | struct GNUNET_HashCode message_hash; | ||
549 | struct GNUNET_CRYPTO_RsaBlindingKeySecret bks; | ||
550 | struct GNUNET_CRYPTO_RsaSignature *blinded_sig; | ||
551 | struct GNUNET_CRYPTO_RsaSignature *sig; | ||
552 | struct GNUNET_CRYPTO_RsaBlindedMessage bm; | ||
553 | struct GNUNET_CRYPTO_RsaBlindedMessage bm_comp; | ||
554 | void *public_enc_data; | ||
555 | size_t public_enc_len; | ||
556 | void *secret_enc_data; | ||
557 | size_t secret_enc_len; | ||
558 | void *sig_enc_data; | ||
559 | size_t sig_enc_length; | ||
560 | void *sig_enc_data_comp; | ||
561 | size_t sig_enc_length_comp; | ||
562 | |||
563 | if (GNUNET_OK != | ||
564 | expect_data_fixed (vec, | ||
565 | "message_hash", | ||
566 | &message_hash, | ||
567 | sizeof (message_hash))) | ||
568 | { | ||
569 | GNUNET_break (0); | ||
570 | return GNUNET_SYSERR; | ||
571 | } | ||
572 | |||
573 | if (GNUNET_OK != | ||
574 | expect_data_fixed (vec, | ||
575 | "blinding_key_secret", | ||
576 | &bks, | ||
577 | sizeof (bks))) | ||
578 | { | ||
579 | GNUNET_break (0); | ||
580 | return GNUNET_SYSERR; | ||
581 | } | ||
582 | |||
583 | if (GNUNET_OK != | ||
584 | expect_data_dynamic (vec, | ||
585 | "blinded_message", | ||
586 | &bm.blinded_msg, | ||
587 | &bm.blinded_msg_size)) | ||
588 | { | ||
589 | GNUNET_break (0); | ||
590 | return GNUNET_SYSERR; | ||
591 | } | ||
592 | if (GNUNET_OK != | ||
593 | expect_data_dynamic (vec, | ||
594 | "rsa_public_key", | ||
595 | &public_enc_data, | ||
596 | &public_enc_len)) | ||
597 | { | ||
598 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
599 | GNUNET_break (0); | ||
600 | return GNUNET_SYSERR; | ||
601 | } | ||
602 | if (GNUNET_OK != | ||
603 | expect_data_dynamic (vec, | ||
604 | "rsa_private_key", | ||
605 | &secret_enc_data, | ||
606 | &secret_enc_len)) | ||
607 | { | ||
608 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
609 | GNUNET_free (public_enc_data); | ||
610 | GNUNET_break (0); | ||
611 | return GNUNET_SYSERR; | ||
612 | } | ||
613 | if (GNUNET_OK != | ||
614 | expect_data_dynamic (vec, | ||
615 | "sig", | ||
616 | &sig_enc_data, | ||
617 | &sig_enc_length)) | ||
618 | { | ||
619 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
620 | GNUNET_free (public_enc_data); | ||
621 | GNUNET_free (secret_enc_data); | ||
622 | GNUNET_break (0); | ||
623 | return GNUNET_SYSERR; | ||
624 | } | ||
625 | |||
626 | pkey = GNUNET_CRYPTO_rsa_public_key_decode (public_enc_data, | ||
627 | public_enc_len); | ||
628 | GNUNET_assert (NULL != pkey); | ||
629 | skey = GNUNET_CRYPTO_rsa_private_key_decode (secret_enc_data, | ||
630 | secret_enc_len); | ||
631 | GNUNET_assert (NULL != skey); | ||
632 | |||
633 | GNUNET_assert (GNUNET_YES == | ||
634 | GNUNET_CRYPTO_rsa_blind (&message_hash, | ||
635 | sizeof (message_hash), | ||
636 | &bks, | ||
637 | pkey, | ||
638 | &bm_comp)); | ||
639 | if ( (bm.blinded_msg_size != | ||
640 | bm_comp.blinded_msg_size) || | ||
641 | (0 != memcmp (bm.blinded_msg, | ||
642 | bm_comp.blinded_msg, | ||
643 | bm.blinded_msg_size)) ) | ||
644 | { | ||
645 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
646 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm_comp); | ||
647 | GNUNET_free (public_enc_data); | ||
648 | GNUNET_free (secret_enc_data); | ||
649 | GNUNET_free (sig_enc_data); | ||
650 | GNUNET_CRYPTO_rsa_private_key_free (skey); | ||
651 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | ||
652 | GNUNET_break (0); | ||
653 | return GNUNET_NO; | ||
654 | } | ||
655 | blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, | ||
656 | &bm); | ||
657 | sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, | ||
658 | &bks, | ||
659 | pkey); | ||
660 | GNUNET_assert (GNUNET_YES == | ||
661 | GNUNET_CRYPTO_rsa_verify (&message_hash, | ||
662 | sizeof (message_hash), | ||
663 | sig, | ||
664 | pkey)); | ||
665 | GNUNET_free (public_enc_data); | ||
666 | public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, | ||
667 | &public_enc_data); | ||
668 | sig_enc_length_comp = GNUNET_CRYPTO_rsa_signature_encode (sig, | ||
669 | &sig_enc_data_comp); | ||
670 | |||
671 | if ( (sig_enc_length != sig_enc_length_comp) || | ||
672 | (0 != memcmp (sig_enc_data, sig_enc_data_comp, sig_enc_length) )) | ||
673 | { | ||
674 | GNUNET_CRYPTO_rsa_signature_free (blinded_sig); | ||
675 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
676 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm_comp); | ||
677 | GNUNET_free (public_enc_data); | ||
678 | GNUNET_free (secret_enc_data); | ||
679 | GNUNET_free (sig_enc_data); | ||
680 | GNUNET_free (sig_enc_data_comp); | ||
681 | GNUNET_CRYPTO_rsa_private_key_free (skey); | ||
682 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
683 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | ||
684 | GNUNET_break (0); | ||
685 | return GNUNET_NO; | ||
686 | } | ||
687 | GNUNET_CRYPTO_rsa_signature_free (blinded_sig); | ||
688 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
689 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm_comp); | ||
690 | GNUNET_free (public_enc_data); | ||
691 | GNUNET_free (secret_enc_data); | ||
692 | GNUNET_free (sig_enc_data); | ||
693 | GNUNET_free (sig_enc_data_comp); | ||
694 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
695 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | ||
696 | GNUNET_CRYPTO_rsa_private_key_free (skey); | ||
697 | } | ||
698 | else if (0 == strcmp (operation, "cs_blind_signing")) | ||
699 | { | ||
700 | struct GNUNET_CRYPTO_CsPrivateKey priv; | ||
701 | struct GNUNET_CRYPTO_CsPublicKey pub; | ||
702 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]; | ||
703 | struct GNUNET_CRYPTO_CsRSecret r_priv[2]; | ||
704 | struct GNUNET_CRYPTO_CsRPublic r_pub[2]; | ||
705 | struct GNUNET_CRYPTO_CSPublicRPairP r_pub_blind; | ||
706 | struct GNUNET_CRYPTO_CsC c[2]; | ||
707 | struct GNUNET_CRYPTO_CsS signature_scalar; | ||
708 | struct GNUNET_CRYPTO_CsBlindS blinded_s; | ||
709 | struct GNUNET_CRYPTO_CsSignature sig; | ||
710 | struct GNUNET_CRYPTO_CsSessionNonce snonce; | ||
711 | struct GNUNET_CRYPTO_CsBlindingNonce bnonce; | ||
712 | struct GNUNET_HashCode message_hash; | ||
713 | unsigned int b; | ||
714 | |||
715 | if (GNUNET_OK != expect_data_fixed (vec, | ||
716 | "message_hash", | ||
717 | &message_hash, | ||
718 | sizeof (message_hash))) | ||
719 | { | ||
720 | GNUNET_break (0); | ||
721 | return GNUNET_SYSERR; | ||
722 | } | ||
723 | if (GNUNET_OK != expect_data_fixed (vec, | ||
724 | "cs_public_key", | ||
725 | &pub, | ||
726 | sizeof (pub))) | ||
727 | { | ||
728 | GNUNET_break (0); | ||
729 | return GNUNET_SYSERR; | ||
730 | } | ||
731 | |||
732 | if (GNUNET_OK != | ||
733 | expect_data_fixed (vec, | ||
734 | "cs_private_key", | ||
735 | &priv, | ||
736 | sizeof (priv))) | ||
737 | { | ||
738 | GNUNET_break (0); | ||
739 | return GNUNET_SYSERR; | ||
740 | } | ||
741 | if (GNUNET_OK != | ||
742 | expect_data_fixed (vec, | ||
743 | "cs_nonce", | ||
744 | &snonce, | ||
745 | sizeof (snonce))) | ||
746 | { | ||
747 | GNUNET_break (0); | ||
748 | return GNUNET_SYSERR; | ||
749 | } | ||
750 | /* historically, the tvg used the same nonce for | ||
751 | both, which is HORRIBLE for production, but | ||
752 | maybe OK for TVG... */ | ||
753 | memcpy (&bnonce, | ||
754 | &snonce, | ||
755 | sizeof (snonce)); | ||
756 | if (GNUNET_OK != | ||
757 | expect_data_fixed (vec, | ||
758 | "cs_r_priv_0", | ||
759 | &r_priv[0], | ||
760 | sizeof (r_priv[0]))) | ||
761 | { | ||
762 | GNUNET_break (0); | ||
763 | return GNUNET_SYSERR; | ||
764 | } | ||
765 | if (GNUNET_OK != expect_data_fixed (vec, | ||
766 | "cs_r_priv_1", | ||
767 | &r_priv[1], | ||
768 | sizeof (r_priv[1]))) | ||
769 | { | ||
770 | GNUNET_break (0); | ||
771 | return GNUNET_SYSERR; | ||
772 | } | ||
773 | if (GNUNET_OK != expect_data_fixed (vec, | ||
774 | "cs_r_pub_0", | ||
775 | &r_pub[0], | ||
776 | sizeof (r_pub[0]))) | ||
777 | { | ||
778 | GNUNET_break (0); | ||
779 | return GNUNET_SYSERR; | ||
780 | } | ||
781 | if (GNUNET_OK != expect_data_fixed (vec, | ||
782 | "cs_r_pub_1", | ||
783 | &r_pub[1], | ||
784 | sizeof (r_pub[1]))) | ||
785 | { | ||
786 | GNUNET_break (0); | ||
787 | return GNUNET_SYSERR; | ||
788 | } | ||
789 | |||
790 | if (GNUNET_OK != expect_data_fixed (vec, | ||
791 | "cs_bs_alpha_0", | ||
792 | &bs[0].alpha, | ||
793 | sizeof (bs[0].alpha))) | ||
794 | { | ||
795 | GNUNET_break (0); | ||
796 | return GNUNET_SYSERR; | ||
797 | } | ||
798 | if (GNUNET_OK != expect_data_fixed (vec, | ||
799 | "cs_bs_alpha_1", | ||
800 | &bs[1].alpha, | ||
801 | sizeof (bs[1].alpha))) | ||
802 | { | ||
803 | GNUNET_break (0); | ||
804 | return GNUNET_SYSERR; | ||
805 | } | ||
806 | if (GNUNET_OK != expect_data_fixed (vec, | ||
807 | "cs_bs_beta_0", | ||
808 | &bs[0].beta, | ||
809 | sizeof (bs[0].beta))) | ||
810 | { | ||
811 | GNUNET_break (0); | ||
812 | return GNUNET_SYSERR; | ||
813 | } | ||
814 | if (GNUNET_OK != | ||
815 | expect_data_fixed (vec, | ||
816 | "cs_bs_beta_1", | ||
817 | &bs[1].beta, | ||
818 | sizeof (bs[1].beta))) | ||
819 | { | ||
820 | GNUNET_break (0); | ||
821 | return GNUNET_SYSERR; | ||
822 | } | ||
823 | if (GNUNET_OK != | ||
824 | expect_data_fixed (vec, | ||
825 | "cs_r_pub_blind_0", | ||
826 | &r_pub_blind.r_pub[0], | ||
827 | sizeof (r_pub_blind.r_pub[0]))) | ||
828 | { | ||
829 | GNUNET_break (0); | ||
830 | return GNUNET_SYSERR; | ||
831 | } | ||
832 | if (GNUNET_OK != | ||
833 | expect_data_fixed (vec, | ||
834 | "cs_r_pub_blind_1", | ||
835 | &r_pub_blind.r_pub[1], | ||
836 | sizeof (r_pub_blind.r_pub[1]))) | ||
837 | { | ||
838 | GNUNET_break (0); | ||
839 | return GNUNET_SYSERR; | ||
840 | } | ||
841 | if (GNUNET_OK != | ||
842 | expect_data_fixed (vec, | ||
843 | "cs_c_0", | ||
844 | &c[0], | ||
845 | sizeof (c[0]))) | ||
846 | { | ||
847 | GNUNET_break (0); | ||
848 | return GNUNET_SYSERR; | ||
849 | } | ||
850 | if (GNUNET_OK != expect_data_fixed (vec, | ||
851 | "cs_c_1", | ||
852 | &c[1], | ||
853 | sizeof (c[1]))) | ||
854 | { | ||
855 | GNUNET_break (0); | ||
856 | return GNUNET_SYSERR; | ||
857 | } | ||
858 | if (GNUNET_OK != expect_data_fixed (vec, | ||
859 | "cs_blind_s", | ||
860 | &blinded_s, | ||
861 | sizeof (blinded_s))) | ||
862 | { | ||
863 | GNUNET_break (0); | ||
864 | return GNUNET_SYSERR; | ||
865 | } | ||
866 | if (GNUNET_OK != expect_data_fixed (vec, | ||
867 | "cs_b", | ||
868 | &b, | ||
869 | sizeof (b))) | ||
870 | { | ||
871 | GNUNET_break (0); | ||
872 | return GNUNET_SYSERR; | ||
873 | } | ||
874 | if (GNUNET_OK != expect_data_fixed (vec, | ||
875 | "cs_sig_s", | ||
876 | &signature_scalar, | ||
877 | sizeof (signature_scalar))) | ||
878 | { | ||
879 | GNUNET_break (0); | ||
880 | return GNUNET_SYSERR; | ||
881 | } | ||
882 | sig.s_scalar = signature_scalar; | ||
883 | if (GNUNET_OK != expect_data_fixed (vec, | ||
884 | "cs_sig_R", | ||
885 | &sig.r_point, | ||
886 | sizeof (sig.r_point))) | ||
887 | { | ||
888 | GNUNET_break (0); | ||
889 | return GNUNET_SYSERR; | ||
890 | } | ||
891 | |||
892 | if ((b != 1) && (b != 0)) | ||
893 | { | ||
894 | GNUNET_break (0); | ||
895 | return GNUNET_SYSERR; | ||
896 | } | ||
897 | |||
898 | struct GNUNET_CRYPTO_CsRSecret r_priv_comp[2]; | ||
899 | struct GNUNET_CRYPTO_CsRPublic r_pub_comp[2]; | ||
900 | struct GNUNET_CRYPTO_CsBlindingSecret bs_comp[2]; | ||
901 | struct GNUNET_CRYPTO_CsC c_comp[2]; | ||
902 | struct GNUNET_CRYPTO_CSPublicRPairP r_pub_blind_comp; | ||
903 | struct GNUNET_CRYPTO_CsBlindSignature blinded_s_comp; | ||
904 | struct GNUNET_CRYPTO_CsS signature_scalar_comp; | ||
905 | struct GNUNET_CRYPTO_CsSignature sig_comp; | ||
906 | |||
907 | GNUNET_CRYPTO_cs_r_derive (&snonce, | ||
908 | "rw", | ||
909 | &priv, | ||
910 | r_priv_comp); | ||
911 | GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[0], | ||
912 | &r_pub_comp[0]); | ||
913 | GNUNET_CRYPTO_cs_r_get_public (&r_priv_comp[1], | ||
914 | &r_pub_comp[1]); | ||
915 | GNUNET_assert (0 == memcmp (&r_priv_comp, | ||
916 | &r_priv, | ||
917 | sizeof(struct GNUNET_CRYPTO_CsRSecret) * 2)); | ||
918 | GNUNET_assert (0 == memcmp (&r_pub_comp, | ||
919 | &r_pub, | ||
920 | sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2)); | ||
921 | |||
922 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&bnonce, | ||
923 | bs_comp); | ||
924 | GNUNET_assert (0 == | ||
925 | memcmp (&bs_comp, | ||
926 | &bs, | ||
927 | sizeof(struct GNUNET_CRYPTO_CsBlindingSecret) | ||
928 | * 2)); | ||
929 | GNUNET_CRYPTO_cs_calc_blinded_c (bs_comp, | ||
930 | r_pub_comp, | ||
931 | &pub, | ||
932 | &message_hash, | ||
933 | sizeof(message_hash), | ||
934 | c_comp, | ||
935 | &r_pub_blind_comp); | ||
936 | GNUNET_assert (0 == | ||
937 | memcmp (&c_comp, | ||
938 | &c, | ||
939 | sizeof(struct GNUNET_CRYPTO_CsC) * 2)); | ||
940 | GNUNET_assert (0 == | ||
941 | GNUNET_memcmp (&r_pub_blind_comp, | ||
942 | &r_pub_blind)); | ||
943 | { | ||
944 | struct GNUNET_CRYPTO_CsBlindedMessage bm = { | ||
945 | .c[0] = c_comp[0], | ||
946 | .c[1] = c_comp[1], | ||
947 | .nonce = snonce | ||
948 | }; | ||
949 | |||
950 | GNUNET_CRYPTO_cs_sign_derive (&priv, | ||
951 | r_priv_comp, | ||
952 | &bm, | ||
953 | &blinded_s_comp); | ||
954 | } | ||
955 | GNUNET_assert (0 == | ||
956 | GNUNET_memcmp (&blinded_s_comp.s_scalar, | ||
957 | &blinded_s)); | ||
958 | GNUNET_assert (b == blinded_s_comp.b); | ||
959 | GNUNET_CRYPTO_cs_unblind (&blinded_s_comp.s_scalar, | ||
960 | &bs_comp[b], | ||
961 | &signature_scalar_comp); | ||
962 | GNUNET_assert (0 == | ||
963 | GNUNET_memcmp (&signature_scalar_comp, | ||
964 | &signature_scalar)); | ||
965 | sig_comp.r_point = r_pub_blind_comp.r_pub[b]; | ||
966 | sig_comp.s_scalar = signature_scalar_comp; | ||
967 | GNUNET_assert (0 == memcmp (&sig_comp, | ||
968 | &sig, | ||
969 | sizeof(sig_comp))); | ||
970 | if (GNUNET_OK != | ||
971 | GNUNET_CRYPTO_cs_verify (&sig_comp, | ||
972 | &pub, | ||
973 | &message_hash, | ||
974 | sizeof(message_hash))) | ||
975 | { | ||
976 | GNUNET_break (0); | ||
977 | return GNUNET_SYSERR; | ||
978 | } | ||
979 | } | ||
980 | else | ||
981 | { | ||
982 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
983 | "unsupported operation '%s'\n", operation); | ||
984 | } | ||
985 | |||
986 | return GNUNET_OK; | ||
987 | } | ||
988 | |||
989 | |||
990 | /** | ||
991 | * Check test vectors from stdin. | ||
992 | * | ||
993 | * @returns global exit code | ||
994 | */ | ||
995 | static int | ||
996 | check_vectors () | ||
997 | { | ||
998 | json_error_t err; | ||
999 | json_t *vecfile = json_loadf (stdin, 0, &err); | ||
1000 | const char *encoding; | ||
1001 | json_t *vectors; | ||
1002 | |||
1003 | if (NULL == vecfile) | ||
1004 | { | ||
1005 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "unable to parse JSON\n"); | ||
1006 | return 1; | ||
1007 | } | ||
1008 | encoding = json_string_value (json_object_get (vecfile, | ||
1009 | "encoding")); | ||
1010 | if ( (NULL == encoding) || (0 != strcmp (encoding, "base32crockford")) ) | ||
1011 | { | ||
1012 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "unsupported or missing encoding\n"); | ||
1013 | json_decref (vecfile); | ||
1014 | return 1; | ||
1015 | } | ||
1016 | vectors = json_object_get (vecfile, "vectors"); | ||
1017 | if (! json_is_array (vectors)) | ||
1018 | { | ||
1019 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bad vectors\n"); | ||
1020 | json_decref (vecfile); | ||
1021 | return 1; | ||
1022 | } | ||
1023 | { | ||
1024 | /* array is a JSON array */ | ||
1025 | size_t index; | ||
1026 | json_t *value; | ||
1027 | enum GNUNET_GenericReturnValue ret = GNUNET_OK; | ||
1028 | |||
1029 | json_array_foreach (vectors, index, value) { | ||
1030 | const char *op = json_string_value (json_object_get (value, | ||
1031 | "operation")); | ||
1032 | |||
1033 | if (NULL == op) | ||
1034 | { | ||
1035 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1036 | "missing operation\n"); | ||
1037 | ret = GNUNET_SYSERR; | ||
1038 | break; | ||
1039 | } | ||
1040 | ret = checkvec (op, value); | ||
1041 | if (GNUNET_OK != ret) | ||
1042 | { | ||
1043 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1044 | "bad vector %u\n", | ||
1045 | (unsigned int) index); | ||
1046 | break; | ||
1047 | } | ||
1048 | } | ||
1049 | json_decref (vecfile); | ||
1050 | return (ret == GNUNET_OK) ? 0 : 1; | ||
1051 | } | ||
1052 | } | ||
1053 | |||
1054 | |||
1055 | /** | ||
1056 | * Output test vectors. | ||
1057 | * | ||
1058 | * @returns global exit code | ||
1059 | */ | ||
1060 | static int | ||
1061 | output_vectors () | ||
1062 | { | ||
1063 | json_t *vecfile = json_object (); | ||
1064 | json_t *vecs = json_array (); | ||
1065 | |||
1066 | json_object_set_new (vecfile, | ||
1067 | "encoding", | ||
1068 | json_string ("base32crockford")); | ||
1069 | json_object_set_new (vecfile, | ||
1070 | "producer", | ||
1071 | json_string ("GNUnet " PACKAGE_VERSION " " VCS_VERSION)); | ||
1072 | json_object_set_new (vecfile, | ||
1073 | "vectors", | ||
1074 | vecs); | ||
1075 | |||
1076 | { | ||
1077 | json_t *vec = vec_for (vecs, "hash"); | ||
1078 | struct GNUNET_HashCode hc; | ||
1079 | char *str = "Hello, GNUnet"; | ||
1080 | |||
1081 | GNUNET_CRYPTO_hash (str, strlen (str), &hc); | ||
1082 | |||
1083 | d2j (vec, "input", str, strlen (str)); | ||
1084 | d2j (vec, "output", &hc, sizeof (struct GNUNET_HashCode)); | ||
1085 | } | ||
1086 | { | ||
1087 | json_t *vec = vec_for (vecs, "ecc_ecdh"); | ||
1088 | struct GNUNET_CRYPTO_EcdhePrivateKey priv1; | ||
1089 | struct GNUNET_CRYPTO_EcdhePublicKey pub1; | ||
1090 | struct GNUNET_CRYPTO_EcdhePrivateKey priv2; | ||
1091 | struct GNUNET_HashCode skm; | ||
1092 | |||
1093 | GNUNET_CRYPTO_ecdhe_key_create (&priv1); | ||
1094 | GNUNET_CRYPTO_ecdhe_key_create (&priv2); | ||
1095 | GNUNET_CRYPTO_ecdhe_key_get_public (&priv1, | ||
1096 | &pub1); | ||
1097 | GNUNET_assert (GNUNET_OK == | ||
1098 | GNUNET_CRYPTO_ecc_ecdh (&priv2, | ||
1099 | &pub1, | ||
1100 | &skm)); | ||
1101 | |||
1102 | d2j (vec, | ||
1103 | "priv1", | ||
1104 | &priv1, | ||
1105 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | ||
1106 | d2j (vec, | ||
1107 | "pub1", | ||
1108 | &pub1, | ||
1109 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
1110 | d2j (vec, | ||
1111 | "priv2", | ||
1112 | &priv2, | ||
1113 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | ||
1114 | d2j (vec, | ||
1115 | "skm", | ||
1116 | &skm, | ||
1117 | sizeof (struct GNUNET_HashCode)); | ||
1118 | } | ||
1119 | |||
1120 | { | ||
1121 | json_t *vec = vec_for (vecs, "eddsa_key_derivation"); | ||
1122 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
1123 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
1124 | |||
1125 | GNUNET_CRYPTO_eddsa_key_create (&priv); | ||
1126 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | ||
1127 | &pub); | ||
1128 | |||
1129 | d2j (vec, | ||
1130 | "priv", | ||
1131 | &priv, | ||
1132 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | ||
1133 | d2j (vec, | ||
1134 | "pub", | ||
1135 | &pub, | ||
1136 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | ||
1137 | } | ||
1138 | { | ||
1139 | json_t *vec = vec_for (vecs, "eddsa_signing"); | ||
1140 | struct GNUNET_CRYPTO_EddsaPrivateKey priv; | ||
1141 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
1142 | struct GNUNET_CRYPTO_EddsaSignature sig; | ||
1143 | struct TestSignatureDataPS data = { 0 }; | ||
1144 | |||
1145 | GNUNET_CRYPTO_eddsa_key_create (&priv); | ||
1146 | GNUNET_CRYPTO_eddsa_key_get_public (&priv, | ||
1147 | &pub); | ||
1148 | data.purpose.size = htonl (sizeof (data)); | ||
1149 | data.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); | ||
1150 | GNUNET_CRYPTO_eddsa_sign (&priv, | ||
1151 | &data, | ||
1152 | &sig); | ||
1153 | GNUNET_assert (GNUNET_OK == | ||
1154 | GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, | ||
1155 | &data, | ||
1156 | &sig, | ||
1157 | &pub)); | ||
1158 | |||
1159 | d2j (vec, | ||
1160 | "priv", | ||
1161 | &priv, | ||
1162 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | ||
1163 | d2j (vec, | ||
1164 | "pub", | ||
1165 | &pub, | ||
1166 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | ||
1167 | d2j (vec, | ||
1168 | "data", | ||
1169 | &data, | ||
1170 | sizeof (struct TestSignatureDataPS)); | ||
1171 | d2j (vec, | ||
1172 | "sig", | ||
1173 | &sig, | ||
1174 | sizeof (struct GNUNET_CRYPTO_EddsaSignature)); | ||
1175 | } | ||
1176 | |||
1177 | { | ||
1178 | json_t *vec = vec_for (vecs, "kdf"); | ||
1179 | size_t out_len = 64; | ||
1180 | char out[out_len]; | ||
1181 | char *ikm = "I'm the secret input key material"; | ||
1182 | char *salt = "I'm very salty"; | ||
1183 | char *ctx = "I'm a context chunk, also known as 'info' in the RFC"; | ||
1184 | |||
1185 | GNUNET_assert (GNUNET_OK == | ||
1186 | GNUNET_CRYPTO_kdf (&out, | ||
1187 | out_len, | ||
1188 | salt, | ||
1189 | strlen (salt), | ||
1190 | ikm, | ||
1191 | strlen (ikm), | ||
1192 | ctx, | ||
1193 | strlen (ctx), | ||
1194 | NULL)); | ||
1195 | |||
1196 | d2j (vec, | ||
1197 | "salt", | ||
1198 | salt, | ||
1199 | strlen (salt)); | ||
1200 | d2j (vec, | ||
1201 | "ikm", | ||
1202 | ikm, | ||
1203 | strlen (ikm)); | ||
1204 | d2j (vec, | ||
1205 | "ctx", | ||
1206 | ctx, | ||
1207 | strlen (ctx)); | ||
1208 | uint2j (vec, | ||
1209 | "out_len", | ||
1210 | (unsigned int) out_len); | ||
1211 | d2j (vec, | ||
1212 | "out", | ||
1213 | out, | ||
1214 | out_len); | ||
1215 | } | ||
1216 | { | ||
1217 | json_t *vec = vec_for (vecs, "eddsa_ecdh"); | ||
1218 | struct GNUNET_CRYPTO_EcdhePrivateKey priv_ecdhe; | ||
1219 | struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe; | ||
1220 | struct GNUNET_CRYPTO_EddsaPrivateKey priv_eddsa; | ||
1221 | struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa; | ||
1222 | struct GNUNET_HashCode key_material; | ||
1223 | |||
1224 | GNUNET_CRYPTO_ecdhe_key_create (&priv_ecdhe); | ||
1225 | GNUNET_CRYPTO_ecdhe_key_get_public (&priv_ecdhe, &pub_ecdhe); | ||
1226 | GNUNET_CRYPTO_eddsa_key_create (&priv_eddsa); | ||
1227 | GNUNET_CRYPTO_eddsa_key_get_public (&priv_eddsa, &pub_eddsa); | ||
1228 | GNUNET_CRYPTO_ecdh_eddsa (&priv_ecdhe, &pub_eddsa, &key_material); | ||
1229 | |||
1230 | d2j (vec, "priv_ecdhe", | ||
1231 | &priv_ecdhe, | ||
1232 | sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | ||
1233 | d2j (vec, "pub_ecdhe", | ||
1234 | &pub_ecdhe, | ||
1235 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
1236 | d2j (vec, "priv_eddsa", | ||
1237 | &priv_eddsa, | ||
1238 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); | ||
1239 | d2j (vec, "pub_eddsa", | ||
1240 | &pub_eddsa, | ||
1241 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); | ||
1242 | d2j (vec, "key_material", | ||
1243 | &key_material, | ||
1244 | sizeof (struct GNUNET_HashCode)); | ||
1245 | } | ||
1246 | |||
1247 | { | ||
1248 | json_t *vec = vec_for (vecs, "edx25519_derive"); | ||
1249 | struct GNUNET_CRYPTO_Edx25519PrivateKey priv1_edx; | ||
1250 | struct GNUNET_CRYPTO_Edx25519PublicKey pub1_edx; | ||
1251 | struct GNUNET_CRYPTO_Edx25519PrivateKey priv2_edx; | ||
1252 | struct GNUNET_CRYPTO_Edx25519PublicKey pub2_edx; | ||
1253 | struct GNUNET_HashCode seed; | ||
1254 | |||
1255 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1256 | &seed, | ||
1257 | sizeof (struct GNUNET_HashCode)); | ||
1258 | GNUNET_CRYPTO_edx25519_key_create (&priv1_edx); | ||
1259 | GNUNET_CRYPTO_edx25519_key_get_public (&priv1_edx, &pub1_edx); | ||
1260 | GNUNET_CRYPTO_edx25519_private_key_derive (&priv1_edx, | ||
1261 | &seed, | ||
1262 | sizeof (seed), | ||
1263 | &priv2_edx); | ||
1264 | GNUNET_CRYPTO_edx25519_public_key_derive (&pub1_edx, | ||
1265 | &seed, | ||
1266 | sizeof (seed), | ||
1267 | &pub2_edx); | ||
1268 | |||
1269 | d2j (vec, "priv1_edx", | ||
1270 | &priv1_edx, | ||
1271 | sizeof (struct GNUNET_CRYPTO_Edx25519PrivateKey)); | ||
1272 | d2j (vec, "pub1_edx", | ||
1273 | &pub1_edx, | ||
1274 | sizeof (struct GNUNET_CRYPTO_Edx25519PublicKey)); | ||
1275 | d2j (vec, "seed", | ||
1276 | &seed, | ||
1277 | sizeof (struct GNUNET_HashCode)); | ||
1278 | d2j (vec, "priv2_edx", | ||
1279 | &priv2_edx, | ||
1280 | sizeof (struct GNUNET_CRYPTO_Edx25519PrivateKey)); | ||
1281 | d2j (vec, "pub2_edx", | ||
1282 | &pub2_edx, | ||
1283 | sizeof (struct GNUNET_CRYPTO_Edx25519PublicKey)); | ||
1284 | } | ||
1285 | |||
1286 | { | ||
1287 | json_t *vec = vec_for (vecs, "rsa_blind_signing"); | ||
1288 | |||
1289 | struct GNUNET_CRYPTO_RsaPrivateKey *skey; | ||
1290 | struct GNUNET_CRYPTO_RsaPublicKey *pkey; | ||
1291 | struct GNUNET_HashCode message_hash; | ||
1292 | struct GNUNET_CRYPTO_RsaBlindingKeySecret bks; | ||
1293 | struct GNUNET_CRYPTO_RsaSignature *blinded_sig; | ||
1294 | struct GNUNET_CRYPTO_RsaSignature *sig; | ||
1295 | struct GNUNET_CRYPTO_RsaBlindedMessage bm; | ||
1296 | void *public_enc_data; | ||
1297 | size_t public_enc_len; | ||
1298 | void *secret_enc_data; | ||
1299 | size_t secret_enc_len; | ||
1300 | void *blinded_sig_enc_data; | ||
1301 | size_t blinded_sig_enc_length; | ||
1302 | void *sig_enc_data; | ||
1303 | size_t sig_enc_length; | ||
1304 | |||
1305 | skey = GNUNET_CRYPTO_rsa_private_key_create (2048); | ||
1306 | pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey); | ||
1307 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1308 | &message_hash, | ||
1309 | sizeof (struct GNUNET_HashCode)); | ||
1310 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1311 | &bks, | ||
1312 | sizeof (struct | ||
1313 | GNUNET_CRYPTO_RsaBlindingKeySecret)); | ||
1314 | GNUNET_assert (GNUNET_YES == | ||
1315 | GNUNET_CRYPTO_rsa_blind (&message_hash, | ||
1316 | sizeof (message_hash), | ||
1317 | &bks, | ||
1318 | pkey, | ||
1319 | &bm)); | ||
1320 | blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, | ||
1321 | &bm); | ||
1322 | sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, | ||
1323 | &bks, | ||
1324 | pkey); | ||
1325 | GNUNET_assert (GNUNET_YES == | ||
1326 | GNUNET_CRYPTO_rsa_verify (&message_hash, | ||
1327 | sizeof (message_hash), | ||
1328 | sig, | ||
1329 | pkey)); | ||
1330 | public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, | ||
1331 | &public_enc_data); | ||
1332 | secret_enc_len = GNUNET_CRYPTO_rsa_private_key_encode (skey, | ||
1333 | &secret_enc_data); | ||
1334 | blinded_sig_enc_length | ||
1335 | = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig, | ||
1336 | &blinded_sig_enc_data); | ||
1337 | sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, | ||
1338 | &sig_enc_data); | ||
1339 | d2j (vec, | ||
1340 | "message_hash", | ||
1341 | &message_hash, | ||
1342 | sizeof (struct GNUNET_HashCode)); | ||
1343 | d2j (vec, | ||
1344 | "rsa_public_key", | ||
1345 | public_enc_data, | ||
1346 | public_enc_len); | ||
1347 | d2j (vec, | ||
1348 | "rsa_private_key", | ||
1349 | secret_enc_data, | ||
1350 | secret_enc_len); | ||
1351 | d2j (vec, | ||
1352 | "blinding_key_secret", | ||
1353 | &bks, | ||
1354 | sizeof (struct GNUNET_CRYPTO_RsaBlindingKeySecret)); | ||
1355 | d2j (vec, | ||
1356 | "blinded_message", | ||
1357 | bm.blinded_msg, | ||
1358 | bm.blinded_msg_size); | ||
1359 | d2j (vec, | ||
1360 | "blinded_sig", | ||
1361 | blinded_sig_enc_data, | ||
1362 | blinded_sig_enc_length); | ||
1363 | d2j (vec, | ||
1364 | "sig", | ||
1365 | sig_enc_data, | ||
1366 | sig_enc_length); | ||
1367 | GNUNET_CRYPTO_rsa_private_key_free (skey); | ||
1368 | GNUNET_CRYPTO_rsa_public_key_free (pkey); | ||
1369 | GNUNET_CRYPTO_rsa_signature_free (sig); | ||
1370 | GNUNET_CRYPTO_rsa_signature_free (blinded_sig); | ||
1371 | GNUNET_free (public_enc_data); | ||
1372 | GNUNET_CRYPTO_rsa_blinded_message_free (&bm); | ||
1373 | GNUNET_free (sig_enc_data); | ||
1374 | GNUNET_free (blinded_sig_enc_data); | ||
1375 | GNUNET_free (secret_enc_data); | ||
1376 | } | ||
1377 | |||
1378 | { | ||
1379 | json_t *vec = vec_for (vecs, "cs_blind_signing"); | ||
1380 | |||
1381 | struct GNUNET_CRYPTO_CsPrivateKey priv; | ||
1382 | struct GNUNET_CRYPTO_CsPublicKey pub; | ||
1383 | struct GNUNET_CRYPTO_CsBlindingSecret bs[2]; | ||
1384 | struct GNUNET_CRYPTO_CsRSecret r_priv[2]; | ||
1385 | struct GNUNET_CRYPTO_CsRPublic r_pub[2]; | ||
1386 | struct GNUNET_CRYPTO_CSPublicRPairP r_pub_blind; | ||
1387 | struct GNUNET_CRYPTO_CsC c[2]; | ||
1388 | struct GNUNET_CRYPTO_CsS signature_scalar; | ||
1389 | struct GNUNET_CRYPTO_CsBlindSignature blinded_s; | ||
1390 | struct GNUNET_CRYPTO_CsSignature sig; | ||
1391 | struct GNUNET_CRYPTO_CsSessionNonce snonce; | ||
1392 | struct GNUNET_CRYPTO_CsBlindingNonce bnonce; | ||
1393 | struct GNUNET_HashCode message_hash; | ||
1394 | |||
1395 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, | ||
1396 | &message_hash, | ||
1397 | sizeof (struct GNUNET_HashCode)); | ||
1398 | |||
1399 | GNUNET_CRYPTO_cs_private_key_generate (&priv); | ||
1400 | GNUNET_CRYPTO_cs_private_key_get_public (&priv, | ||
1401 | &pub); | ||
1402 | GNUNET_assert (GNUNET_YES == | ||
1403 | GNUNET_CRYPTO_hkdf (&snonce, | ||
1404 | sizeof(snonce), | ||
1405 | GCRY_MD_SHA512, | ||
1406 | GCRY_MD_SHA256, | ||
1407 | "nonce", | ||
1408 | strlen ("nonce"), | ||
1409 | "nonce_secret", | ||
1410 | strlen ("nonce_secret"), | ||
1411 | NULL, | ||
1412 | 0)); | ||
1413 | /* NOTE: historically, we made the bad choice of | ||
1414 | making both nonces the same. Maybe barely OK | ||
1415 | for the TGV, not good for production! */ | ||
1416 | memcpy (&bnonce, | ||
1417 | &snonce, | ||
1418 | sizeof (snonce)); | ||
1419 | GNUNET_CRYPTO_cs_r_derive (&snonce, | ||
1420 | "rw", | ||
1421 | &priv, | ||
1422 | r_priv); | ||
1423 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[0], | ||
1424 | &r_pub[0]); | ||
1425 | GNUNET_CRYPTO_cs_r_get_public (&r_priv[1], | ||
1426 | &r_pub[1]); | ||
1427 | GNUNET_CRYPTO_cs_blinding_secrets_derive (&bnonce, | ||
1428 | bs); | ||
1429 | GNUNET_CRYPTO_cs_calc_blinded_c (bs, | ||
1430 | r_pub, | ||
1431 | &pub, | ||
1432 | &message_hash, | ||
1433 | sizeof(message_hash), | ||
1434 | c, | ||
1435 | &r_pub_blind); | ||
1436 | { | ||
1437 | struct GNUNET_CRYPTO_CsBlindedMessage bm = { | ||
1438 | .c[0] = c[0], | ||
1439 | .c[1] = c[1], | ||
1440 | .nonce = snonce | ||
1441 | }; | ||
1442 | |||
1443 | GNUNET_CRYPTO_cs_sign_derive (&priv, | ||
1444 | r_priv, | ||
1445 | &bm, | ||
1446 | &blinded_s); | ||
1447 | } | ||
1448 | GNUNET_CRYPTO_cs_unblind (&blinded_s.s_scalar, | ||
1449 | &bs[blinded_s.b], | ||
1450 | &signature_scalar); | ||
1451 | sig.r_point = r_pub_blind.r_pub[blinded_s.b]; | ||
1452 | sig.s_scalar = signature_scalar; | ||
1453 | if (GNUNET_OK != | ||
1454 | GNUNET_CRYPTO_cs_verify (&sig, | ||
1455 | &pub, | ||
1456 | &message_hash, | ||
1457 | sizeof(message_hash))) | ||
1458 | { | ||
1459 | GNUNET_break (0); | ||
1460 | return GNUNET_SYSERR; | ||
1461 | } | ||
1462 | d2j (vec, | ||
1463 | "message_hash", | ||
1464 | &message_hash, | ||
1465 | sizeof (struct GNUNET_HashCode)); | ||
1466 | d2j (vec, | ||
1467 | "cs_public_key", | ||
1468 | &pub, | ||
1469 | sizeof(pub)); | ||
1470 | d2j (vec, | ||
1471 | "cs_private_key", | ||
1472 | &priv, | ||
1473 | sizeof(priv)); | ||
1474 | d2j (vec, | ||
1475 | "cs_nonce", | ||
1476 | &snonce, | ||
1477 | sizeof(snonce)); | ||
1478 | d2j (vec, | ||
1479 | "cs_r_priv_0", | ||
1480 | &r_priv[0], | ||
1481 | sizeof(r_priv[0])); | ||
1482 | d2j (vec, | ||
1483 | "cs_r_priv_1", | ||
1484 | &r_priv[1], | ||
1485 | sizeof(r_priv[1])); | ||
1486 | d2j (vec, | ||
1487 | "cs_r_pub_0", | ||
1488 | &r_pub[0], | ||
1489 | sizeof(r_pub[0])); | ||
1490 | d2j (vec, | ||
1491 | "cs_r_pub_1", | ||
1492 | &r_pub[1], | ||
1493 | sizeof(r_pub[1])); | ||
1494 | d2j (vec, | ||
1495 | "cs_bs_alpha_0", | ||
1496 | &bs[0].alpha, | ||
1497 | sizeof(bs[0].alpha)); | ||
1498 | d2j (vec, | ||
1499 | "cs_bs_alpha_1", | ||
1500 | &bs[1].alpha, | ||
1501 | sizeof(bs[1].alpha)); | ||
1502 | d2j (vec, | ||
1503 | "cs_bs_beta_0", | ||
1504 | &bs[0].beta, | ||
1505 | sizeof(bs[0].beta)); | ||
1506 | d2j (vec, | ||
1507 | "cs_bs_beta_1", | ||
1508 | &bs[1].beta, | ||
1509 | sizeof(bs[1].beta)); | ||
1510 | d2j (vec, | ||
1511 | "cs_r_pub_blind_0", | ||
1512 | &r_pub_blind.r_pub[0], | ||
1513 | sizeof(r_pub_blind.r_pub[0])); | ||
1514 | d2j (vec, | ||
1515 | "cs_r_pub_blind_1", | ||
1516 | &r_pub_blind.r_pub[1], | ||
1517 | sizeof(r_pub_blind.r_pub[1])); | ||
1518 | d2j (vec, | ||
1519 | "cs_c_0", | ||
1520 | &c[0], | ||
1521 | sizeof(c[0])); | ||
1522 | d2j (vec, | ||
1523 | "cs_c_1", | ||
1524 | &c[1], | ||
1525 | sizeof(c[1])); | ||
1526 | d2j (vec, | ||
1527 | "cs_blind_s", | ||
1528 | &blinded_s, | ||
1529 | sizeof(blinded_s)); | ||
1530 | d2j (vec, | ||
1531 | "cs_b", | ||
1532 | &blinded_s.b, | ||
1533 | sizeof(blinded_s.b)); | ||
1534 | d2j (vec, | ||
1535 | "cs_sig_s", | ||
1536 | &signature_scalar, | ||
1537 | sizeof(signature_scalar)); | ||
1538 | d2j (vec, | ||
1539 | "cs_sig_R", | ||
1540 | &r_pub_blind.r_pub[blinded_s.b], | ||
1541 | sizeof(r_pub_blind.r_pub[blinded_s.b])); | ||
1542 | } | ||
1543 | |||
1544 | json_dumpf (vecfile, stdout, JSON_INDENT (2)); | ||
1545 | json_decref (vecfile); | ||
1546 | printf ("\n"); | ||
1547 | |||
1548 | return 0; | ||
1549 | } | ||
1550 | |||
1551 | |||
1552 | /** | ||
1553 | * Main function that will be run. | ||
1554 | * | ||
1555 | * @param cls closure | ||
1556 | * @param args remaining command-line arguments | ||
1557 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
1558 | * @param cfg configuration | ||
1559 | */ | ||
1560 | static void | ||
1561 | run (void *cls, | ||
1562 | char *const *args, | ||
1563 | const char *cfgfile, | ||
1564 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
1565 | { | ||
1566 | if (GNUNET_YES == verify_flag) | ||
1567 | global_ret = check_vectors (); | ||
1568 | else | ||
1569 | global_ret = output_vectors (); | ||
1570 | } | ||
1571 | |||
1572 | |||
1573 | /** | ||
1574 | * The main function of the test vector generation tool. | ||
1575 | * | ||
1576 | * @param argc number of arguments from the command line | ||
1577 | * @param argv command line arguments | ||
1578 | * @return 0 ok, 1 on error | ||
1579 | */ | ||
1580 | int | ||
1581 | main (int argc, | ||
1582 | char *const *argv) | ||
1583 | { | ||
1584 | const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
1585 | GNUNET_GETOPT_option_flag ('V', | ||
1586 | "verify", | ||
1587 | gettext_noop ( | ||
1588 | "verify a test vector from stdin"), | ||
1589 | &verify_flag), | ||
1590 | GNUNET_GETOPT_OPTION_END | ||
1591 | }; | ||
1592 | |||
1593 | GNUNET_assert (GNUNET_OK == | ||
1594 | GNUNET_log_setup ("gnunet-crypto-tvg", | ||
1595 | "INFO", | ||
1596 | NULL)); | ||
1597 | if (GNUNET_OK != | ||
1598 | GNUNET_PROGRAM_run (argc, argv, | ||
1599 | "gnunet-crypto-tvg", | ||
1600 | "Generate test vectors for cryptographic operations", | ||
1601 | options, | ||
1602 | &run, NULL)) | ||
1603 | return 1; | ||
1604 | return global_ret; | ||
1605 | } | ||
1606 | |||
1607 | |||
1608 | /* end of gnunet-crypto-tvg.c */ | ||
diff --git a/src/cli/util/gnunet-ecc.c b/src/cli/util/gnunet-ecc.c new file mode 100644 index 000000000..812745085 --- /dev/null +++ b/src/cli/util/gnunet-ecc.c | |||
@@ -0,0 +1,510 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012, 2013 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/gnunet-ecc.c | ||
23 | * @brief tool to manipulate EDDSA key files | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_testing_lib.h" | ||
30 | #include <gcrypt.h> | ||
31 | |||
32 | /** | ||
33 | * Number of characters a Base32-encoded public key requires. | ||
34 | */ | ||
35 | #define KEY_STR_LEN sizeof(struct GNUNET_CRYPTO_EddsaPublicKey) * 8 / 5 + 1 | ||
36 | |||
37 | /** | ||
38 | * Flag for listing public key. | ||
39 | */ | ||
40 | static int list_keys; | ||
41 | |||
42 | /** | ||
43 | * Flag for listing public key. | ||
44 | */ | ||
45 | static unsigned int list_keys_count; | ||
46 | |||
47 | /** | ||
48 | * Flag for printing public key. | ||
49 | */ | ||
50 | static int print_public_key; | ||
51 | |||
52 | /** | ||
53 | * Flag for printing private key. | ||
54 | */ | ||
55 | static int print_private_key; | ||
56 | |||
57 | /** | ||
58 | * Flag for printing public key in hex. | ||
59 | */ | ||
60 | static int print_public_key_hex; | ||
61 | |||
62 | /** | ||
63 | * Flag for printing the output of random example operations. | ||
64 | */ | ||
65 | static int print_examples_flag; | ||
66 | |||
67 | /** | ||
68 | * Option set to create a bunch of keys at once. | ||
69 | */ | ||
70 | static unsigned int make_keys; | ||
71 | |||
72 | |||
73 | /** | ||
74 | * Create a flat file with a large number of key pairs for testing. | ||
75 | * | ||
76 | * @param fn File name to store the keys. | ||
77 | * @param prefix Desired prefix for the public keys, NULL if any key is OK. | ||
78 | */ | ||
79 | static void | ||
80 | create_keys (const char *fn, const char *prefix) | ||
81 | { | ||
82 | FILE *f; | ||
83 | struct GNUNET_CRYPTO_EddsaPrivateKey pk; | ||
84 | struct GNUNET_CRYPTO_EddsaPublicKey target_pub; | ||
85 | static char vanity[KEY_STR_LEN + 1]; | ||
86 | size_t len; | ||
87 | size_t n; | ||
88 | size_t rest; | ||
89 | unsigned char mask; | ||
90 | unsigned target_byte; | ||
91 | char *s; | ||
92 | |||
93 | if (NULL == (f = fopen (fn, "w+"))) | ||
94 | { | ||
95 | fprintf (stderr, _ ("Failed to open `%s': %s\n"), fn, strerror (errno)); | ||
96 | return; | ||
97 | } | ||
98 | if (NULL != prefix) | ||
99 | { | ||
100 | len = GNUNET_strlcpy (vanity, prefix, sizeof(vanity)); | ||
101 | n = len * 5 / 8; | ||
102 | rest = len * 5 % 8; | ||
103 | |||
104 | memset (&vanity[len], '0', KEY_STR_LEN - len); | ||
105 | vanity[KEY_STR_LEN] = '\0'; | ||
106 | GNUNET_assert (GNUNET_OK == | ||
107 | GNUNET_CRYPTO_eddsa_public_key_from_string (vanity, | ||
108 | KEY_STR_LEN, | ||
109 | &target_pub)); | ||
110 | if (0 != rest) | ||
111 | { | ||
112 | /** | ||
113 | * Documentation by example: | ||
114 | * vanity = "A" | ||
115 | * len = 1 | ||
116 | * n = 5/8 = 0 (bytes) | ||
117 | * rest = 5%8 = 5 (bits) | ||
118 | * mask = ~(2**(8 - 5) - 1) = ~(2**3 - 1) = ~(8 - 1) = ~b111 = b11111000 | ||
119 | */mask = ~((int) pow (2, 8 - rest) - 1); | ||
120 | target_byte = ((unsigned char *) &target_pub)[n] & mask; | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | /* Just so old (debian) versions of GCC calm down with the warnings. */ | ||
125 | mask = target_byte = 0; | ||
126 | } | ||
127 | s = GNUNET_CRYPTO_eddsa_public_key_to_string (&target_pub); | ||
128 | fprintf (stderr, | ||
129 | _ ("Generating %u keys like %s, please wait"), | ||
130 | make_keys, | ||
131 | s); | ||
132 | GNUNET_free (s); | ||
133 | fprintf (stderr, "\nattempt %s [%u, %X]\n", vanity, (unsigned int) n, mask); | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | fprintf (stderr, _ ("Generating %u keys, please wait"), make_keys); | ||
138 | /* Just so old (debian) versions of GCC calm down with the warnings. */ | ||
139 | n = rest = target_byte = mask = 0; | ||
140 | } | ||
141 | |||
142 | while (0 < make_keys--) | ||
143 | { | ||
144 | fprintf (stderr, "."); | ||
145 | GNUNET_CRYPTO_eddsa_key_create (&pk); | ||
146 | if (NULL != prefix) | ||
147 | { | ||
148 | struct GNUNET_CRYPTO_EddsaPublicKey newkey; | ||
149 | |||
150 | GNUNET_CRYPTO_eddsa_key_get_public (&pk, | ||
151 | &newkey); | ||
152 | if (0 != memcmp (&target_pub, | ||
153 | &newkey, | ||
154 | n)) | ||
155 | { | ||
156 | make_keys++; | ||
157 | continue; | ||
158 | } | ||
159 | if (0 != rest) | ||
160 | { | ||
161 | unsigned char new_byte; | ||
162 | |||
163 | new_byte = ((unsigned char *) &newkey)[n] & mask; | ||
164 | if (target_byte != new_byte) | ||
165 | { | ||
166 | make_keys++; | ||
167 | continue; | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | if (GNUNET_TESTING_HOSTKEYFILESIZE != | ||
172 | fwrite (&pk, | ||
173 | 1, | ||
174 | GNUNET_TESTING_HOSTKEYFILESIZE, | ||
175 | f)) | ||
176 | { | ||
177 | fprintf (stderr, | ||
178 | _ ("\nFailed to write to `%s': %s\n"), | ||
179 | fn, | ||
180 | strerror (errno)); | ||
181 | break; | ||
182 | } | ||
183 | } | ||
184 | if (UINT_MAX == make_keys) | ||
185 | fprintf (stderr, _ ("\nFinished!\n")); | ||
186 | else | ||
187 | fprintf (stderr, _ ("\nError, %u keys not generated\n"), make_keys); | ||
188 | fclose (f); | ||
189 | } | ||
190 | |||
191 | |||
192 | static void | ||
193 | print_hex (const char *msg, const void *buf, size_t size) | ||
194 | { | ||
195 | printf ("%s: ", msg); | ||
196 | for (size_t i = 0; i < size; i++) | ||
197 | { | ||
198 | printf ("%02hhx", ((const uint8_t *) buf)[i]); | ||
199 | } | ||
200 | printf ("\n"); | ||
201 | } | ||
202 | |||
203 | |||
204 | static void | ||
205 | print_examples_ecdh (void) | ||
206 | { | ||
207 | struct GNUNET_CRYPTO_EcdhePrivateKey dh_priv1; | ||
208 | struct GNUNET_CRYPTO_EcdhePublicKey dh_pub1; | ||
209 | struct GNUNET_CRYPTO_EcdhePrivateKey dh_priv2; | ||
210 | struct GNUNET_CRYPTO_EcdhePublicKey dh_pub2; | ||
211 | struct GNUNET_HashCode hash; | ||
212 | char buf[128]; | ||
213 | |||
214 | GNUNET_CRYPTO_ecdhe_key_create (&dh_priv1); | ||
215 | GNUNET_CRYPTO_ecdhe_key_create (&dh_priv2); | ||
216 | GNUNET_CRYPTO_ecdhe_key_get_public (&dh_priv1, | ||
217 | &dh_pub1); | ||
218 | GNUNET_CRYPTO_ecdhe_key_get_public (&dh_priv2, | ||
219 | &dh_pub2); | ||
220 | |||
221 | GNUNET_assert (NULL != | ||
222 | GNUNET_STRINGS_data_to_string (&dh_priv1, | ||
223 | sizeof (dh_priv1), | ||
224 | buf, | ||
225 | sizeof (buf))); | ||
226 | printf ("ECDHE key 1:\n"); | ||
227 | printf ("private: %s\n", | ||
228 | buf); | ||
229 | print_hex ("private(hex)", | ||
230 | &dh_priv1, sizeof (dh_priv1)); | ||
231 | GNUNET_assert (NULL != | ||
232 | GNUNET_STRINGS_data_to_string (&dh_pub1, | ||
233 | sizeof (dh_pub1), | ||
234 | buf, | ||
235 | sizeof (buf))); | ||
236 | printf ("public: %s\n", | ||
237 | buf); | ||
238 | print_hex ("public(hex)", | ||
239 | &dh_pub1, | ||
240 | sizeof (dh_pub1)); | ||
241 | |||
242 | GNUNET_assert (NULL != | ||
243 | GNUNET_STRINGS_data_to_string (&dh_priv2, | ||
244 | sizeof (dh_priv2), | ||
245 | buf, | ||
246 | sizeof (buf))); | ||
247 | printf ("ECDHE key 2:\n"); | ||
248 | printf ("private: %s\n", buf); | ||
249 | print_hex ("private(hex)", | ||
250 | &dh_priv2, | ||
251 | sizeof (dh_priv2)); | ||
252 | GNUNET_assert (NULL != | ||
253 | GNUNET_STRINGS_data_to_string (&dh_pub2, | ||
254 | sizeof (dh_pub2), | ||
255 | buf, | ||
256 | sizeof (buf))); | ||
257 | printf ("public: %s\n", buf); | ||
258 | print_hex ("public(hex)", | ||
259 | &dh_pub2, | ||
260 | sizeof (dh_pub2)); | ||
261 | |||
262 | GNUNET_assert (GNUNET_OK == | ||
263 | GNUNET_CRYPTO_ecc_ecdh (&dh_priv1, | ||
264 | &dh_pub2, | ||
265 | &hash)); | ||
266 | GNUNET_assert (NULL != | ||
267 | GNUNET_STRINGS_data_to_string (&hash, | ||
268 | sizeof (hash), | ||
269 | buf, | ||
270 | sizeof (buf))); | ||
271 | printf ("ECDH shared secret: %s\n", | ||
272 | buf); | ||
273 | |||
274 | } | ||
275 | |||
276 | |||
277 | /** | ||
278 | * Print some random example operations to stdout. | ||
279 | */ | ||
280 | static void | ||
281 | print_examples (void) | ||
282 | { | ||
283 | print_examples_ecdh (); | ||
284 | // print_examples_ecdsa (); | ||
285 | // print_examples_eddsa (); | ||
286 | } | ||
287 | |||
288 | |||
289 | static void | ||
290 | print_key (const char *filename) | ||
291 | { | ||
292 | struct GNUNET_DISK_FileHandle *fd; | ||
293 | struct GNUNET_CRYPTO_EddsaPrivateKey private_key; | ||
294 | struct GNUNET_CRYPTO_EddsaPublicKey public_key; | ||
295 | char *hostkeys_data; | ||
296 | char *hostkey_str; | ||
297 | uint64_t fs; | ||
298 | unsigned int total_hostkeys; | ||
299 | unsigned int c; | ||
300 | ssize_t sret; | ||
301 | |||
302 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
303 | { | ||
304 | fprintf (stderr, _ ("Hostkeys file `%s' not found\n"), filename); | ||
305 | return; | ||
306 | } | ||
307 | |||
308 | /* Check hostkey file size, read entire thing into memory */ | ||
309 | if (GNUNET_OK != | ||
310 | GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) | ||
311 | fs = 0; | ||
312 | if (0 == fs) | ||
313 | { | ||
314 | fprintf (stderr, _ ("Hostkeys file `%s' is empty\n"), filename); | ||
315 | return; /* File is empty */ | ||
316 | } | ||
317 | if (0 != (fs % GNUNET_TESTING_HOSTKEYFILESIZE)) | ||
318 | { | ||
319 | fprintf (stderr, _ ("Incorrect hostkey file format: %s\n"), filename); | ||
320 | return; | ||
321 | } | ||
322 | fd = GNUNET_DISK_file_open (filename, | ||
323 | GNUNET_DISK_OPEN_READ, | ||
324 | GNUNET_DISK_PERM_NONE); | ||
325 | if (NULL == fd) | ||
326 | { | ||
327 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename); | ||
328 | return; | ||
329 | } | ||
330 | hostkeys_data = GNUNET_malloc (fs); | ||
331 | sret = GNUNET_DISK_file_read (fd, hostkeys_data, fs); | ||
332 | if ((sret < 0) || (fs != (size_t) sret)) | ||
333 | { | ||
334 | fprintf (stderr, _ ("Could not read hostkey file: %s\n"), filename); | ||
335 | GNUNET_free (hostkeys_data); | ||
336 | GNUNET_DISK_file_close (fd); | ||
337 | return; | ||
338 | } | ||
339 | GNUNET_DISK_file_close (fd); | ||
340 | |||
341 | if (NULL == hostkeys_data) | ||
342 | return; | ||
343 | total_hostkeys = fs / GNUNET_TESTING_HOSTKEYFILESIZE; | ||
344 | for (c = 0; (c < total_hostkeys) && (c < list_keys_count); c++) | ||
345 | { | ||
346 | GNUNET_memcpy (&private_key, | ||
347 | hostkeys_data + (c * GNUNET_TESTING_HOSTKEYFILESIZE), | ||
348 | GNUNET_TESTING_HOSTKEYFILESIZE); | ||
349 | GNUNET_CRYPTO_eddsa_key_get_public (&private_key, &public_key); | ||
350 | hostkey_str = GNUNET_CRYPTO_eddsa_public_key_to_string (&public_key); | ||
351 | if (NULL != hostkey_str) | ||
352 | { | ||
353 | fprintf (stderr, "%4u: %s\n", c, hostkey_str); | ||
354 | GNUNET_free (hostkey_str); | ||
355 | } | ||
356 | else | ||
357 | fprintf (stderr, "%4u: %s\n", c, "invalid"); | ||
358 | } | ||
359 | GNUNET_free (hostkeys_data); | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Main function that will be run by the scheduler. | ||
365 | * | ||
366 | * @param cls closure, NULL | ||
367 | * @param args remaining command-line arguments | ||
368 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
369 | * @param cfg configuration | ||
370 | */ | ||
371 | static void | ||
372 | run (void *cls, | ||
373 | char *const *args, | ||
374 | const char *cfgfile, | ||
375 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
376 | { | ||
377 | (void) cls; | ||
378 | (void) cfgfile; | ||
379 | (void) cfg; | ||
380 | |||
381 | if (print_examples_flag) | ||
382 | { | ||
383 | print_examples (); | ||
384 | return; | ||
385 | } | ||
386 | if (NULL == args[0]) | ||
387 | { | ||
388 | fprintf (stderr, "%s", _ ("No hostkey file specified on command line\n")); | ||
389 | return; | ||
390 | } | ||
391 | if (list_keys) | ||
392 | { | ||
393 | print_key (args[0]); | ||
394 | return; | ||
395 | } | ||
396 | if (make_keys > 0) | ||
397 | { | ||
398 | create_keys (args[0], args[1]); | ||
399 | return; | ||
400 | } | ||
401 | if (print_public_key || print_public_key_hex || print_private_key) | ||
402 | { | ||
403 | char *str; | ||
404 | struct GNUNET_DISK_FileHandle *keyfile; | ||
405 | struct GNUNET_CRYPTO_EddsaPrivateKey pk; | ||
406 | struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
407 | |||
408 | keyfile = GNUNET_DISK_file_open (args[0], | ||
409 | GNUNET_DISK_OPEN_READ, | ||
410 | GNUNET_DISK_PERM_NONE); | ||
411 | if (NULL == keyfile) | ||
412 | return; | ||
413 | while (sizeof(pk) == GNUNET_DISK_file_read (keyfile, &pk, sizeof(pk))) | ||
414 | { | ||
415 | GNUNET_CRYPTO_eddsa_key_get_public (&pk, &pub); | ||
416 | if (print_public_key_hex) | ||
417 | { | ||
418 | print_hex ("HEX:", &pub, sizeof(pub)); | ||
419 | } | ||
420 | else if (print_public_key) | ||
421 | { | ||
422 | str = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); | ||
423 | fprintf (stdout, "%s\n", str); | ||
424 | GNUNET_free (str); | ||
425 | } | ||
426 | else if (print_private_key) | ||
427 | { | ||
428 | str = GNUNET_CRYPTO_eddsa_private_key_to_string (&pk); | ||
429 | fprintf (stdout, "%s\n", str); | ||
430 | GNUNET_free (str); | ||
431 | } | ||
432 | } | ||
433 | GNUNET_DISK_file_close (keyfile); | ||
434 | } | ||
435 | } | ||
436 | |||
437 | |||
438 | /** | ||
439 | * Program to manipulate ECC key files. | ||
440 | * | ||
441 | * @param argc number of arguments from the command line | ||
442 | * @param argv command line arguments | ||
443 | * @return 0 ok, 1 on error | ||
444 | */ | ||
445 | int | ||
446 | main (int argc, char *const *argv) | ||
447 | { | ||
448 | struct GNUNET_GETOPT_CommandLineOption options[] = | ||
449 | { GNUNET_GETOPT_option_flag ('i', | ||
450 | "iterate", | ||
451 | gettext_noop ( | ||
452 | "list keys included in a file (for testing)"), | ||
453 | &list_keys), | ||
454 | GNUNET_GETOPT_option_uint ( | ||
455 | 'e', | ||
456 | "end=", | ||
457 | "COUNT", | ||
458 | gettext_noop ("number of keys to list included in a file (for testing)"), | ||
459 | &list_keys_count), | ||
460 | GNUNET_GETOPT_option_uint ( | ||
461 | 'g', | ||
462 | "generate-keys", | ||
463 | "COUNT", | ||
464 | gettext_noop ("create COUNT public-private key pairs (for testing)"), | ||
465 | &make_keys), | ||
466 | GNUNET_GETOPT_option_flag ('p', | ||
467 | "print-public-key", | ||
468 | gettext_noop ( | ||
469 | "print the public key in ASCII format"), | ||
470 | &print_public_key), | ||
471 | GNUNET_GETOPT_option_flag ('P', | ||
472 | "print-private-key", | ||
473 | gettext_noop ( | ||
474 | "print the private key in ASCII format"), | ||
475 | &print_private_key), | ||
476 | GNUNET_GETOPT_option_flag ('x', | ||
477 | "print-hex", | ||
478 | gettext_noop ( | ||
479 | "print the public key in HEX format"), | ||
480 | &print_public_key_hex), | ||
481 | GNUNET_GETOPT_option_flag ( | ||
482 | 'E', | ||
483 | "examples", | ||
484 | gettext_noop ( | ||
485 | "print examples of ECC operations (used for compatibility testing)"), | ||
486 | &print_examples_flag), | ||
487 | GNUNET_GETOPT_OPTION_END }; | ||
488 | int ret; | ||
489 | |||
490 | list_keys_count = UINT32_MAX; | ||
491 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
492 | return 2; | ||
493 | |||
494 | ret = (GNUNET_OK == | ||
495 | GNUNET_PROGRAM_run (argc, | ||
496 | argv, | ||
497 | "gnunet-ecc [OPTIONS] keyfile [VANITY_PREFIX]", | ||
498 | gettext_noop ( | ||
499 | "Manipulate GNUnet private ECC key files"), | ||
500 | options, | ||
501 | &run, | ||
502 | NULL)) | ||
503 | ? 0 | ||
504 | : 1; | ||
505 | GNUNET_free_nz ((void *) argv); | ||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | |||
510 | /* end of gnunet-ecc.c */ | ||
diff --git a/src/cli/util/gnunet-qr.c b/src/cli/util/gnunet-qr.c new file mode 100644 index 000000000..d9b873c05 --- /dev/null +++ b/src/cli/util/gnunet-qr.c | |||
@@ -0,0 +1,597 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013-2019 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 | * @file util/gnunet-qr.c | ||
22 | * @author Hartmut Goebel (original implementation) | ||
23 | * @author Martin Schanzenbach (integrate gnunet-uri) | ||
24 | * @author Christian Grothoff (error handling) | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include <stdio.h> | ||
28 | #include <stdbool.h> | ||
29 | #include <signal.h> | ||
30 | #include <zbar.h> | ||
31 | |||
32 | |||
33 | #include "gnunet_util_lib.h" | ||
34 | |||
35 | #if HAVE_PNG | ||
36 | #include <png.h> | ||
37 | #endif | ||
38 | |||
39 | /** | ||
40 | * Global exit code. | ||
41 | * Set to non-zero if an error occurs after the scheduler has started. | ||
42 | */ | ||
43 | static int exit_code = 0; | ||
44 | |||
45 | /** | ||
46 | * Video device to capture from. | ||
47 | * Used by default if PNG support is disabled or no PNG file is specified. | ||
48 | * Defaults to /dev/video0. | ||
49 | */ | ||
50 | static char *device = NULL; | ||
51 | |||
52 | #if HAVE_PNG | ||
53 | /** | ||
54 | * Name of the file to read from. | ||
55 | * If the file is not a PNG-encoded image of a QR code, an error will be | ||
56 | * thrown. | ||
57 | */ | ||
58 | static char *pngfilename = NULL; | ||
59 | #endif | ||
60 | |||
61 | /** | ||
62 | * Requested verbosity. | ||
63 | */ | ||
64 | static unsigned int verbosity = 0; | ||
65 | |||
66 | /** | ||
67 | * Child process handle. | ||
68 | */ | ||
69 | struct GNUNET_OS_Process *childproc = NULL; | ||
70 | |||
71 | /** | ||
72 | * Child process handle for waiting. | ||
73 | */ | ||
74 | static struct GNUNET_ChildWaitHandle *waitchildproc = NULL; | ||
75 | |||
76 | /** | ||
77 | * Macro to handle verbosity when printing messages. | ||
78 | */ | ||
79 | #define LOG(fmt, ...) \ | ||
80 | do \ | ||
81 | { \ | ||
82 | if (0 < verbosity) \ | ||
83 | { \ | ||
84 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, fmt, ##__VA_ARGS__); \ | ||
85 | if (verbosity > 1) \ | ||
86 | { \ | ||
87 | fprintf (stdout, fmt, ##__VA_ARGS__); \ | ||
88 | } \ | ||
89 | } \ | ||
90 | } \ | ||
91 | while (0) | ||
92 | |||
93 | /** | ||
94 | * Executed when program is terminating. | ||
95 | */ | ||
96 | static void | ||
97 | shutdown_program (void *cls) | ||
98 | { | ||
99 | if (NULL != waitchildproc) | ||
100 | { | ||
101 | GNUNET_wait_child_cancel (waitchildproc); | ||
102 | } | ||
103 | if (NULL != childproc) | ||
104 | { | ||
105 | /* A bit brutal, but this process is terminating so we're out of time */ | ||
106 | GNUNET_OS_process_kill (childproc, SIGKILL); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * Callback executed when the child process terminates. | ||
112 | * | ||
113 | * @param cls closure | ||
114 | * @param type status of the child process | ||
115 | * @param code the exit code of the child process | ||
116 | */ | ||
117 | static void | ||
118 | wait_child (void *cls, | ||
119 | enum GNUNET_OS_ProcessStatusType type, | ||
120 | long unsigned int code) | ||
121 | { | ||
122 | GNUNET_OS_process_destroy (childproc); | ||
123 | childproc = NULL; | ||
124 | waitchildproc = NULL; | ||
125 | |||
126 | char *uri = cls; | ||
127 | |||
128 | if (0 != exit_code) | ||
129 | { | ||
130 | fprintf (stdout, _("Failed to add URI %s\n"), uri); | ||
131 | } | ||
132 | else | ||
133 | { | ||
134 | fprintf (stdout, _("Added URI %s\n"), uri); | ||
135 | } | ||
136 | |||
137 | GNUNET_free (uri); | ||
138 | |||
139 | GNUNET_SCHEDULER_shutdown (); | ||
140 | } | ||
141 | |||
142 | /** | ||
143 | * Dispatch URIs to the appropriate GNUnet helper process. | ||
144 | * | ||
145 | * @param cls closure | ||
146 | * @param uri URI to dispatch | ||
147 | * @param cfgfile name of the configuration file in use | ||
148 | * @param cfg the configuration in use | ||
149 | */ | ||
150 | static void | ||
151 | handle_uri (void *cls, | ||
152 | const char *uri, | ||
153 | const char *cfgfile, | ||
154 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
155 | { | ||
156 | const char *cursor = uri; | ||
157 | |||
158 | if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://"))) | ||
159 | { | ||
160 | fprintf (stderr, | ||
161 | _("Invalid URI: does not start with `gnunet://'\n")); | ||
162 | exit_code = 1; | ||
163 | return; | ||
164 | } | ||
165 | |||
166 | cursor += strlen ("gnunet://"); | ||
167 | |||
168 | const char *slash = strchr (cursor, '/'); | ||
169 | if (NULL == slash) | ||
170 | { | ||
171 | fprintf (stderr, _("Invalid URI: fails to specify a subsystem\n")); | ||
172 | exit_code = 1; | ||
173 | return; | ||
174 | } | ||
175 | |||
176 | char *subsystem = GNUNET_strndup (cursor, slash - cursor); | ||
177 | char *program = NULL; | ||
178 | |||
179 | if (GNUNET_OK != | ||
180 | GNUNET_CONFIGURATION_get_value_string (cfg, "uri", subsystem, &program)) | ||
181 | { | ||
182 | fprintf (stderr, _("No known handler for subsystem `%s'\n"), subsystem); | ||
183 | GNUNET_free (subsystem); | ||
184 | exit_code = 1; | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | GNUNET_free (subsystem); | ||
189 | |||
190 | char **childargv = NULL; | ||
191 | unsigned int childargc = 0; | ||
192 | |||
193 | for (const char *token=strtok (program, " "); | ||
194 | NULL!=token; | ||
195 | token=strtok(NULL, " ")) | ||
196 | { | ||
197 | GNUNET_array_append (childargv, childargc, GNUNET_strdup (token)); | ||
198 | } | ||
199 | GNUNET_array_append (childargv, childargc, GNUNET_strdup (uri)); | ||
200 | GNUNET_array_append (childargv, childargc, NULL); | ||
201 | |||
202 | childproc = GNUNET_OS_start_process_vap (GNUNET_OS_INHERIT_STD_ALL, | ||
203 | NULL, | ||
204 | NULL, | ||
205 | NULL, | ||
206 | childargv[0], | ||
207 | childargv); | ||
208 | for (size_t i=0; i<childargc-1; ++i) | ||
209 | { | ||
210 | GNUNET_free (childargv[i]); | ||
211 | } | ||
212 | |||
213 | GNUNET_array_grow (childargv, childargc, 0); | ||
214 | |||
215 | if (NULL == childproc) | ||
216 | { | ||
217 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
218 | _("Unable to start child process `%s'\n"), | ||
219 | program); | ||
220 | GNUNET_free (program); | ||
221 | exit_code = 1; | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | waitchildproc = GNUNET_wait_child (childproc, &wait_child, (void *)uri); | ||
226 | } | ||
227 | |||
228 | /** | ||
229 | * Obtain a QR code symbol from @a proc. | ||
230 | * | ||
231 | * @param proc the zbar processor to use | ||
232 | * @return NULL on error | ||
233 | */ | ||
234 | static const zbar_symbol_t * | ||
235 | get_symbol (zbar_processor_t *proc) | ||
236 | { | ||
237 | if (0 != zbar_processor_parse_config (proc, "enable")) | ||
238 | { | ||
239 | GNUNET_break (0); | ||
240 | return NULL; | ||
241 | } | ||
242 | |||
243 | int r = zbar_processor_init (proc, device, 1); | ||
244 | if (0 != r) | ||
245 | { | ||
246 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
247 | _("Failed to open device: `%s': %d\n"), | ||
248 | device, | ||
249 | r); | ||
250 | return NULL; | ||
251 | } | ||
252 | |||
253 | r = zbar_processor_set_visible (proc, 1); | ||
254 | r += zbar_processor_set_active (proc, 1); | ||
255 | if (0 != r) | ||
256 | { | ||
257 | GNUNET_break (0); | ||
258 | return NULL; | ||
259 | } | ||
260 | |||
261 | LOG (_("Capturing...\n")); | ||
262 | |||
263 | int n = zbar_process_one (proc, -1); | ||
264 | |||
265 | zbar_processor_set_active (proc, 0); | ||
266 | zbar_processor_set_visible (proc, 0); | ||
267 | |||
268 | if (-1 == n) | ||
269 | { | ||
270 | LOG (_("No captured images\n")); | ||
271 | return NULL; | ||
272 | } | ||
273 | |||
274 | LOG(_("Got %d images\n"), n); | ||
275 | |||
276 | const zbar_symbol_set_t *symbols = zbar_processor_get_results (proc); | ||
277 | if (NULL == symbols) | ||
278 | { | ||
279 | GNUNET_break (0); | ||
280 | return NULL; | ||
281 | } | ||
282 | |||
283 | return zbar_symbol_set_first_symbol (symbols); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * Run the zbar QR code parser. | ||
288 | * | ||
289 | * @return NULL on error | ||
290 | */ | ||
291 | static char * | ||
292 | run_zbar (void) | ||
293 | { | ||
294 | zbar_processor_t *proc = zbar_processor_create (1); | ||
295 | if (NULL == proc) | ||
296 | { | ||
297 | GNUNET_break (0); | ||
298 | return NULL; | ||
299 | } | ||
300 | |||
301 | if (NULL == device) | ||
302 | { | ||
303 | device = GNUNET_strdup ("/dev/video0"); | ||
304 | } | ||
305 | |||
306 | const zbar_symbol_t *symbol = get_symbol (proc); | ||
307 | if (NULL == symbol) | ||
308 | { | ||
309 | zbar_processor_destroy (proc); | ||
310 | return NULL; | ||
311 | } | ||
312 | |||
313 | const char *data = zbar_symbol_get_data (symbol); | ||
314 | if (NULL == data) | ||
315 | { | ||
316 | GNUNET_break (0); | ||
317 | zbar_processor_destroy (proc); | ||
318 | return NULL; | ||
319 | } | ||
320 | |||
321 | LOG (_("Found %s: \"%s\"\n"), | ||
322 | zbar_get_symbol_name (zbar_symbol_get_type (symbol)), | ||
323 | data); | ||
324 | |||
325 | char *copy = GNUNET_strdup (data); | ||
326 | |||
327 | zbar_processor_destroy (proc); | ||
328 | GNUNET_free (device); | ||
329 | |||
330 | return copy; | ||
331 | } | ||
332 | |||
333 | #if HAVE_PNG | ||
334 | /** | ||
335 | * Decode the PNG-encoded file to a raw byte buffer. | ||
336 | * | ||
337 | * @param width[out] where to store the image width | ||
338 | * @param height[out] where to store the image height | ||
339 | */ | ||
340 | static char * | ||
341 | png_parse (uint32_t *width, uint32_t *height) | ||
342 | { | ||
343 | if (NULL == width || NULL == height) | ||
344 | { | ||
345 | return NULL; | ||
346 | } | ||
347 | |||
348 | FILE *pngfile = fopen (pngfilename, "rb"); | ||
349 | if (NULL == pngfile) | ||
350 | { | ||
351 | return NULL; | ||
352 | } | ||
353 | |||
354 | unsigned char header[8]; | ||
355 | if (8 != fread (header, 1, 8, pngfile)) | ||
356 | { | ||
357 | fclose (pngfile); | ||
358 | return NULL; | ||
359 | } | ||
360 | |||
361 | if (png_sig_cmp (header, 0, 8)) | ||
362 | { | ||
363 | fclose (pngfile); | ||
364 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
365 | _("%s is not a PNG file\n"), | ||
366 | pngfilename); | ||
367 | fprintf (stderr, _("%s is not a PNG file\n"), pngfilename); | ||
368 | return NULL; | ||
369 | } | ||
370 | |||
371 | /* libpng's default error handling might or might not conflict with GNUnet's | ||
372 | scheduler and event loop. Beware of strange interactions. */ | ||
373 | png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, | ||
374 | NULL, | ||
375 | NULL, | ||
376 | NULL); | ||
377 | if (NULL == png) | ||
378 | { | ||
379 | GNUNET_break (0); | ||
380 | fclose (pngfile); | ||
381 | return NULL; | ||
382 | } | ||
383 | |||
384 | png_infop pnginfo = png_create_info_struct (png); | ||
385 | if (NULL == pnginfo) | ||
386 | { | ||
387 | GNUNET_break (0); | ||
388 | png_destroy_read_struct (&png, NULL, NULL); | ||
389 | fclose (pngfile); | ||
390 | return NULL; | ||
391 | } | ||
392 | |||
393 | if (setjmp (png_jmpbuf (png))) | ||
394 | { | ||
395 | GNUNET_break (0); | ||
396 | png_destroy_read_struct (&png, &pnginfo, NULL); | ||
397 | fclose (pngfile); | ||
398 | return NULL; | ||
399 | } | ||
400 | |||
401 | png_init_io (png, pngfile); | ||
402 | png_set_sig_bytes (png, 8); | ||
403 | |||
404 | png_read_info (png, pnginfo); | ||
405 | |||
406 | png_byte pngcolor = png_get_color_type (png, pnginfo); | ||
407 | png_byte pngdepth = png_get_bit_depth (png, pnginfo); | ||
408 | |||
409 | /* Normalize picture --- based on a zbar example */ | ||
410 | if (0 != (pngcolor & PNG_COLOR_TYPE_PALETTE)) | ||
411 | { | ||
412 | png_set_palette_to_rgb (png); | ||
413 | } | ||
414 | |||
415 | if (pngcolor == PNG_COLOR_TYPE_GRAY && pngdepth < 8) | ||
416 | { | ||
417 | png_set_expand_gray_1_2_4_to_8 (png); | ||
418 | } | ||
419 | |||
420 | if (16 == pngdepth) | ||
421 | { | ||
422 | png_set_strip_16 (png); | ||
423 | } | ||
424 | |||
425 | if (0 != (pngcolor & PNG_COLOR_MASK_ALPHA)) | ||
426 | { | ||
427 | png_set_strip_alpha (png); | ||
428 | } | ||
429 | |||
430 | if (0 != (pngcolor & PNG_COLOR_MASK_COLOR)) | ||
431 | { | ||
432 | png_set_rgb_to_gray_fixed (png, 1, -1, -1); | ||
433 | } | ||
434 | |||
435 | png_uint_32 pngwidth = png_get_image_width (png, pnginfo); | ||
436 | png_uint_32 pngheight = png_get_image_height (png, pnginfo); | ||
437 | |||
438 | char *buffer = GNUNET_new_array (pngwidth * pngheight, char); | ||
439 | png_bytepp rows = GNUNET_new_array (pngheight, png_bytep); | ||
440 | |||
441 | for (png_uint_32 i=0; i<pngheight; ++i) | ||
442 | { | ||
443 | rows[i] = (unsigned char *)buffer + (pngwidth * i); | ||
444 | } | ||
445 | |||
446 | png_read_image (png, rows); | ||
447 | |||
448 | GNUNET_free (rows); | ||
449 | fclose (pngfile); | ||
450 | |||
451 | *width = pngwidth; | ||
452 | *height = pngheight; | ||
453 | |||
454 | return buffer; | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * Parse a PNG-encoded file for a QR code. | ||
459 | * | ||
460 | * @return NULL on error | ||
461 | */ | ||
462 | static char * | ||
463 | run_png_reader (void) | ||
464 | { | ||
465 | uint32_t width = 0; | ||
466 | uint32_t height = 0; | ||
467 | char *buffer = png_parse (&width, &height); | ||
468 | if (NULL == buffer) | ||
469 | { | ||
470 | return NULL; | ||
471 | } | ||
472 | |||
473 | zbar_image_scanner_t *scanner = zbar_image_scanner_create (); | ||
474 | zbar_image_scanner_set_config (scanner,0, ZBAR_CFG_ENABLE, 1); | ||
475 | |||
476 | zbar_image_t *zimage = zbar_image_create (); | ||
477 | zbar_image_set_format (zimage, zbar_fourcc ('Y', '8', '0', '0')); | ||
478 | zbar_image_set_size (zimage, width, height); | ||
479 | zbar_image_set_data (zimage, buffer, width * height, &zbar_image_free_data); | ||
480 | |||
481 | int n = zbar_scan_image (scanner, zimage); | ||
482 | |||
483 | if (-1 == n) | ||
484 | { | ||
485 | LOG (_("No captured images\n")); | ||
486 | return NULL; | ||
487 | } | ||
488 | |||
489 | LOG(_("Got %d images\n"), n); | ||
490 | |||
491 | const zbar_symbol_t *symbol = zbar_image_first_symbol (zimage); | ||
492 | |||
493 | const char *data = zbar_symbol_get_data (symbol); | ||
494 | if (NULL == data) | ||
495 | { | ||
496 | GNUNET_break (0); | ||
497 | zbar_image_destroy (zimage); | ||
498 | zbar_image_scanner_destroy (scanner); | ||
499 | return NULL; | ||
500 | } | ||
501 | |||
502 | LOG (_("Found %s: \"%s\"\n"), | ||
503 | zbar_get_symbol_name (zbar_symbol_get_type (symbol)), | ||
504 | data); | ||
505 | |||
506 | char *copy = GNUNET_strdup (data); | ||
507 | |||
508 | zbar_image_destroy (zimage); | ||
509 | zbar_image_scanner_destroy (scanner); | ||
510 | |||
511 | return copy; | ||
512 | } | ||
513 | #endif | ||
514 | |||
515 | /** | ||
516 | * Main function executed by the scheduler. | ||
517 | * | ||
518 | * @param cls closure | ||
519 | * @param args remaining command line arguments | ||
520 | * @param cfgfile name of the configuration file being used | ||
521 | * @param cfg the used configuration | ||
522 | */ | ||
523 | static void | ||
524 | run (void *cls, | ||
525 | char *const *args, | ||
526 | const char *cfgfile, | ||
527 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
528 | { | ||
529 | char *data = NULL; | ||
530 | |||
531 | GNUNET_SCHEDULER_add_shutdown (&shutdown_program, NULL); | ||
532 | |||
533 | #if HAVE_PNG | ||
534 | if (NULL != pngfilename) | ||
535 | { | ||
536 | data = run_png_reader (); | ||
537 | } | ||
538 | else | ||
539 | #endif | ||
540 | { | ||
541 | data = run_zbar (); | ||
542 | } | ||
543 | |||
544 | if (NULL == data) | ||
545 | { | ||
546 | LOG (_("No data found\n")); | ||
547 | exit_code = 1; | ||
548 | GNUNET_SCHEDULER_shutdown (); | ||
549 | return; | ||
550 | } | ||
551 | |||
552 | handle_uri (cls, data, cfgfile, cfg); | ||
553 | |||
554 | if (0 != exit_code) | ||
555 | { | ||
556 | fprintf (stdout, _("Failed to add URI %s\n"), data); | ||
557 | GNUNET_free (data); | ||
558 | GNUNET_SCHEDULER_shutdown (); | ||
559 | return; | ||
560 | } | ||
561 | |||
562 | LOG (_("Dispatching the URI\n")); | ||
563 | } | ||
564 | |||
565 | int | ||
566 | main (int argc, char *const *argv) | ||
567 | { | ||
568 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
569 | GNUNET_GETOPT_option_string ( | ||
570 | 'd', | ||
571 | "device", | ||
572 | "DEVICE", | ||
573 | gettext_noop ("use the video device DEVICE (defaults to /dev/video0)"), | ||
574 | &device), | ||
575 | #if HAVE_PNG | ||
576 | GNUNET_GETOPT_option_string ( | ||
577 | 'f', | ||
578 | "file", | ||
579 | "FILE", | ||
580 | gettext_noop ("read from the PNG-encoded file FILE"), | ||
581 | &pngfilename), | ||
582 | #endif | ||
583 | GNUNET_GETOPT_option_verbose (&verbosity), | ||
584 | GNUNET_GETOPT_OPTION_END, | ||
585 | }; | ||
586 | |||
587 | enum GNUNET_GenericReturnValue ret = | ||
588 | GNUNET_PROGRAM_run (argc, | ||
589 | argv, | ||
590 | "gnunet-qr", | ||
591 | gettext_noop ("Scan a QR code and import the URI read"), | ||
592 | options, | ||
593 | &run, | ||
594 | NULL); | ||
595 | |||
596 | return ((GNUNET_OK == ret) && (0 == exit_code)) ? 0 : 1; | ||
597 | } | ||
diff --git a/src/cli/util/gnunet-resolver.c b/src/cli/util/gnunet-resolver.c new file mode 100644 index 000000000..a23aeb4aa --- /dev/null +++ b/src/cli/util/gnunet-resolver.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2010 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/gnunet-resolver.c | ||
23 | * @brief tool to test resolver | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_resolver_service.h" | ||
30 | |||
31 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
32 | |||
33 | /** | ||
34 | * Flag for reverse lookup. | ||
35 | */ | ||
36 | static int reverse; | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Prints each hostname obtained from DNS. | ||
41 | * | ||
42 | * @param cls closure (unused) | ||
43 | * @param hostname one of the names for the host, NULL | ||
44 | * on the last call to the callback | ||
45 | */ | ||
46 | static void | ||
47 | print_hostname (void *cls, | ||
48 | const char *hostname) | ||
49 | { | ||
50 | (void) cls; | ||
51 | if (NULL == hostname) | ||
52 | return; | ||
53 | fprintf (stdout, | ||
54 | "%s\n", | ||
55 | hostname); | ||
56 | } | ||
57 | |||
58 | |||
59 | /** | ||
60 | * Callback function to display address. | ||
61 | * | ||
62 | * @param cls closure (unused) | ||
63 | * @param addr one of the addresses of the host, NULL for the last address | ||
64 | * @param addrlen length of the address | ||
65 | */ | ||
66 | static void | ||
67 | print_sockaddr (void *cls, | ||
68 | const struct sockaddr *addr, | ||
69 | socklen_t addrlen) | ||
70 | { | ||
71 | (void) cls; | ||
72 | if (NULL == addr) | ||
73 | return; | ||
74 | fprintf (stdout, | ||
75 | "%s\n", | ||
76 | GNUNET_a2s (addr, | ||
77 | addrlen)); | ||
78 | } | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Main function that will be run by the scheduler. | ||
83 | * | ||
84 | * @param cls closure | ||
85 | * @param args remaining command-line arguments | ||
86 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
87 | * @param cfg configuration | ||
88 | */ | ||
89 | static void | ||
90 | run (void *cls, | ||
91 | char *const *args, | ||
92 | const char *cfgfile, | ||
93 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
94 | { | ||
95 | const struct sockaddr *sa; | ||
96 | socklen_t salen; | ||
97 | struct sockaddr_in v4; | ||
98 | struct sockaddr_in6 v6; | ||
99 | |||
100 | (void) cls; | ||
101 | (void) cfgfile; | ||
102 | (void) cfg; | ||
103 | if (NULL == args[0]) | ||
104 | return; | ||
105 | if (! reverse) | ||
106 | { | ||
107 | GNUNET_RESOLVER_ip_get (args[0], | ||
108 | AF_UNSPEC, | ||
109 | GET_TIMEOUT, | ||
110 | &print_sockaddr, | ||
111 | NULL); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | sa = NULL; | ||
116 | memset (&v4, 0, sizeof(v4)); | ||
117 | v4.sin_family = AF_INET; | ||
118 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
119 | v4.sin_len = sizeof(v4); | ||
120 | #endif | ||
121 | if (1 == inet_pton (AF_INET, | ||
122 | args[0], | ||
123 | &v4.sin_addr)) | ||
124 | { | ||
125 | sa = (struct sockaddr *) &v4; | ||
126 | salen = sizeof(v4); | ||
127 | } | ||
128 | memset (&v6, 0, sizeof(v6)); | ||
129 | v6.sin6_family = AF_INET6; | ||
130 | #if HAVE_SOCKADDR_IN_SIN_LEN | ||
131 | v6.sin6_len = sizeof(v6); | ||
132 | #endif | ||
133 | if (1 == inet_pton (AF_INET6, | ||
134 | args[0], | ||
135 | &v6.sin6_addr)) | ||
136 | { | ||
137 | sa = (struct sockaddr *) &v6; | ||
138 | salen = sizeof(v6); | ||
139 | } | ||
140 | if (NULL == sa) | ||
141 | { | ||
142 | fprintf (stderr, | ||
143 | "`%s' is not a valid IP: %s\n", | ||
144 | args[0], | ||
145 | strerror (errno)); | ||
146 | return; | ||
147 | } | ||
148 | GNUNET_RESOLVER_hostname_get (sa, salen, | ||
149 | GNUNET_YES, | ||
150 | GET_TIMEOUT, | ||
151 | &print_hostname, | ||
152 | NULL); | ||
153 | } | ||
154 | |||
155 | |||
156 | /** | ||
157 | * The main function to access GNUnet's DNS resolver. | ||
158 | * | ||
159 | * @param argc number of arguments from the command line | ||
160 | * @param argv command line arguments | ||
161 | * @return 0 ok, 1 on error | ||
162 | */ | ||
163 | int | ||
164 | main (int argc, char *const *argv) | ||
165 | { | ||
166 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
167 | GNUNET_GETOPT_option_flag ('r', | ||
168 | "reverse", | ||
169 | gettext_noop ("perform a reverse lookup"), | ||
170 | &reverse), | ||
171 | GNUNET_GETOPT_OPTION_END | ||
172 | }; | ||
173 | int ret; | ||
174 | |||
175 | if (GNUNET_OK != | ||
176 | GNUNET_STRINGS_get_utf8_args (argc, argv, | ||
177 | &argc, &argv)) | ||
178 | return 2; | ||
179 | |||
180 | ret = (GNUNET_OK == | ||
181 | GNUNET_PROGRAM_run (argc, argv, | ||
182 | "gnunet-resolver [hostname]", | ||
183 | gettext_noop ("Use built-in GNUnet stub resolver"), | ||
184 | options, | ||
185 | &run, NULL)) ? 0 : 1; | ||
186 | GNUNET_free_nz ((void *) argv); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | |||
191 | /* end of gnunet-resolver.c */ | ||
diff --git a/src/cli/util/gnunet-scrypt.c b/src/cli/util/gnunet-scrypt.c new file mode 100644 index 000000000..3d1b9c017 --- /dev/null +++ b/src/cli/util/gnunet-scrypt.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2014 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 | * @file util/gnunet-scrypt.c | ||
22 | * @brief tool to manipulate SCRYPT proofs of work. | ||
23 | * @author Bart Polot | ||
24 | */ | ||
25 | |||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include <gcrypt.h> | ||
29 | |||
30 | |||
31 | /** | ||
32 | * Salt for PoW calcualations. | ||
33 | */ | ||
34 | static struct GNUNET_CRYPTO_PowSalt salt = { "gnunet-nse-proof" }; | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Amount of work required (W-bit collisions) for NSE proofs, in collision-bits. | ||
39 | */ | ||
40 | static unsigned long long nse_work_required; | ||
41 | |||
42 | /** | ||
43 | * Interval between proof find runs. | ||
44 | */ | ||
45 | static struct GNUNET_TIME_Relative proof_find_delay; | ||
46 | |||
47 | static struct GNUNET_CRYPTO_EddsaPublicKey pub; | ||
48 | |||
49 | static uint64_t proof; | ||
50 | |||
51 | static struct GNUNET_SCHEDULER_Task *proof_task; | ||
52 | |||
53 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
54 | |||
55 | static char *pkfn; | ||
56 | |||
57 | static char *pwfn; | ||
58 | |||
59 | |||
60 | /** | ||
61 | * Write our current proof to disk. | ||
62 | * | ||
63 | * @param cls closure | ||
64 | */ | ||
65 | static void | ||
66 | shutdown_task (void *cls) | ||
67 | { | ||
68 | (void) cls; | ||
69 | if (GNUNET_OK != | ||
70 | GNUNET_DISK_fn_write (pwfn, | ||
71 | &proof, | ||
72 | sizeof(proof), | ||
73 | GNUNET_DISK_PERM_USER_READ | ||
74 | | GNUNET_DISK_PERM_USER_WRITE)) | ||
75 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
76 | "write", | ||
77 | pwfn); | ||
78 | } | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Find our proof of work. | ||
83 | * | ||
84 | * @param cls closure (unused) | ||
85 | */ | ||
86 | static void | ||
87 | find_proof (void *cls) | ||
88 | { | ||
89 | #define ROUND_SIZE 10 | ||
90 | uint64_t counter; | ||
91 | char buf[sizeof(struct GNUNET_CRYPTO_EddsaPublicKey) | ||
92 | + sizeof(uint64_t)] GNUNET_ALIGN; | ||
93 | struct GNUNET_HashCode result; | ||
94 | unsigned int i; | ||
95 | struct GNUNET_TIME_Absolute timestamp; | ||
96 | struct GNUNET_TIME_Relative elapsed; | ||
97 | |||
98 | (void) cls; | ||
99 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
100 | "Got Proof of Work %llu\n", | ||
101 | (unsigned long long) proof); | ||
102 | proof_task = NULL; | ||
103 | GNUNET_memcpy (&buf[sizeof(uint64_t)], | ||
104 | &pub, | ||
105 | sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)); | ||
106 | i = 0; | ||
107 | counter = proof; | ||
108 | timestamp = GNUNET_TIME_absolute_get (); | ||
109 | while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) | ||
110 | { | ||
111 | GNUNET_memcpy (buf, &counter, sizeof(uint64_t)); | ||
112 | GNUNET_CRYPTO_pow_hash (&salt, | ||
113 | buf, | ||
114 | sizeof(buf), | ||
115 | &result); | ||
116 | if (nse_work_required <= | ||
117 | GNUNET_CRYPTO_hash_count_leading_zeros (&result)) | ||
118 | { | ||
119 | proof = counter; | ||
120 | fprintf (stdout, | ||
121 | "Proof of work found: %llu!\n", | ||
122 | (unsigned long long) proof); | ||
123 | GNUNET_SCHEDULER_shutdown (); | ||
124 | return; | ||
125 | } | ||
126 | counter++; | ||
127 | i++; | ||
128 | } | ||
129 | elapsed = GNUNET_TIME_absolute_get_duration (timestamp); | ||
130 | elapsed = GNUNET_TIME_relative_divide (elapsed, ROUND_SIZE); | ||
131 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
132 | "Current: %llu [%s/proof]\n", | ||
133 | (unsigned long long) counter, | ||
134 | GNUNET_STRINGS_relative_time_to_string (elapsed, 0)); | ||
135 | if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) | ||
136 | { | ||
137 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
138 | "Testing proofs currently at %llu\n", | ||
139 | (unsigned long long) counter); | ||
140 | /* remember progress every 100 rounds */ | ||
141 | proof = counter; | ||
142 | shutdown_task (NULL); | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | proof = counter; | ||
147 | } | ||
148 | proof_task = | ||
149 | GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, | ||
150 | GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
151 | &find_proof, | ||
152 | NULL); | ||
153 | } | ||
154 | |||
155 | |||
156 | /** | ||
157 | * Main function that will be run by the scheduler. | ||
158 | * | ||
159 | * @param cls closure | ||
160 | * @param args remaining command-line arguments | ||
161 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
162 | * @param cfg configuration | ||
163 | */ | ||
164 | static void | ||
165 | run (void *cls, | ||
166 | char *const *args, | ||
167 | const char *cfgfile, | ||
168 | const struct GNUNET_CONFIGURATION_Handle *config) | ||
169 | { | ||
170 | struct GNUNET_CRYPTO_EddsaPrivateKey pk; | ||
171 | char *pids; | ||
172 | |||
173 | (void) cls; | ||
174 | (void) args; | ||
175 | (void) cfgfile; | ||
176 | cfg = config; | ||
177 | /* load proof of work */ | ||
178 | if (NULL == pwfn) | ||
179 | { | ||
180 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
181 | "NSE", | ||
182 | "PROOFFILE", | ||
183 | &pwfn)) | ||
184 | { | ||
185 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE"); | ||
186 | GNUNET_SCHEDULER_shutdown (); | ||
187 | return; | ||
188 | } | ||
189 | } | ||
190 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Proof of Work file: %s\n", pwfn); | ||
191 | if ((GNUNET_YES != GNUNET_DISK_file_test (pwfn)) || | ||
192 | (sizeof(proof) != GNUNET_DISK_fn_read (pwfn, &proof, sizeof(proof)))) | ||
193 | proof = 0; | ||
194 | |||
195 | /* load private key */ | ||
196 | if (NULL == pkfn) | ||
197 | { | ||
198 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
199 | "PEER", | ||
200 | "PRIVATE_KEY", | ||
201 | &pkfn)) | ||
202 | { | ||
203 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
204 | "PEER", | ||
205 | "PRIVATE_KEY"); | ||
206 | return; | ||
207 | } | ||
208 | } | ||
209 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn); | ||
210 | if (GNUNET_SYSERR == | ||
211 | GNUNET_CRYPTO_eddsa_key_from_file (pkfn, | ||
212 | GNUNET_YES, | ||
213 | &pk)) | ||
214 | { | ||
215 | fprintf (stderr, _ ("Loading hostkey from `%s' failed.\n"), pkfn); | ||
216 | GNUNET_free (pkfn); | ||
217 | return; | ||
218 | } | ||
219 | GNUNET_free (pkfn); | ||
220 | GNUNET_CRYPTO_eddsa_key_get_public (&pk, | ||
221 | &pub); | ||
222 | pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); | ||
223 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peer ID: %s\n", pids); | ||
224 | GNUNET_free (pids); | ||
225 | |||
226 | /* get target bit amount */ | ||
227 | if (0 == nse_work_required) | ||
228 | { | ||
229 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, | ||
230 | "NSE", | ||
231 | "WORKBITS", | ||
232 | &nse_work_required)) | ||
233 | { | ||
234 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS"); | ||
235 | GNUNET_SCHEDULER_shutdown (); | ||
236 | return; | ||
237 | } | ||
238 | if (nse_work_required >= sizeof(struct GNUNET_HashCode) * 8) | ||
239 | { | ||
240 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
241 | "NSE", | ||
242 | "WORKBITS", | ||
243 | _ ("Value is too large.\n")); | ||
244 | GNUNET_SCHEDULER_shutdown (); | ||
245 | return; | ||
246 | } | ||
247 | else if (0 == nse_work_required) | ||
248 | { | ||
249 | GNUNET_SCHEDULER_shutdown (); | ||
250 | return; | ||
251 | } | ||
252 | } | ||
253 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bits: %llu\n", nse_work_required); | ||
254 | |||
255 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
256 | "Delay between tries: %s\n", | ||
257 | GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1)); | ||
258 | proof_task = | ||
259 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
260 | &find_proof, | ||
261 | NULL); | ||
262 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | ||
263 | } | ||
264 | |||
265 | |||
266 | /** | ||
267 | * Program to manipulate ECC key files. | ||
268 | * | ||
269 | * @param argc number of arguments from the command line | ||
270 | * @param argv command line arguments | ||
271 | * @return 0 ok, 1 on error | ||
272 | */ | ||
273 | int | ||
274 | main (int argc, char *const *argv) | ||
275 | { | ||
276 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
277 | GNUNET_GETOPT_option_ulong ( | ||
278 | 'b', | ||
279 | "bits", | ||
280 | "BITS", | ||
281 | gettext_noop ("number of bits to require for the proof of work"), | ||
282 | &nse_work_required), | ||
283 | GNUNET_GETOPT_option_filename ( | ||
284 | 'k', | ||
285 | "keyfile", | ||
286 | "FILE", | ||
287 | gettext_noop ("file with private key, otherwise default is used"), | ||
288 | &pkfn), | ||
289 | GNUNET_GETOPT_option_filename ( | ||
290 | 'o', | ||
291 | "outfile", | ||
292 | "FILE", | ||
293 | gettext_noop ("file with proof of work, otherwise default is used"), | ||
294 | &pwfn), | ||
295 | GNUNET_GETOPT_option_relative_time ('t', | ||
296 | "timeout", | ||
297 | "TIME", | ||
298 | gettext_noop ( | ||
299 | "time to wait between calculations"), | ||
300 | &proof_find_delay), | ||
301 | GNUNET_GETOPT_OPTION_END | ||
302 | }; | ||
303 | int ret; | ||
304 | |||
305 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
306 | return 2; | ||
307 | |||
308 | ret = | ||
309 | (GNUNET_OK == | ||
310 | GNUNET_PROGRAM_run (argc, | ||
311 | argv, | ||
312 | "gnunet-scrypt [OPTIONS] prooffile", | ||
313 | gettext_noop ("Manipulate GNUnet proof of work files"), | ||
314 | options, | ||
315 | &run, | ||
316 | NULL)) | ||
317 | ? 0 | ||
318 | : 1; | ||
319 | GNUNET_free_nz ((void *) argv); | ||
320 | GNUNET_free (pwfn); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | |||
325 | /* end of gnunet-scrypt.c */ | ||
diff --git a/src/cli/util/gnunet-timeout.c b/src/cli/util/gnunet-timeout.c new file mode 100644 index 000000000..1d3002c08 --- /dev/null +++ b/src/cli/util/gnunet-timeout.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010 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, or | ||
8 | (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 src/util/gnunet-timeout.c | ||
23 | * @brief small tool starting a child process, waiting that it terminates or killing it after a given timeout period | ||
24 | * @author Matthias Wachs | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include <sys/types.h> | ||
29 | #include <sys/wait.h> | ||
30 | #include <signal.h> | ||
31 | #include <stdio.h> | ||
32 | #include <stdlib.h> | ||
33 | #include <unistd.h> | ||
34 | |||
35 | static pid_t child; | ||
36 | |||
37 | |||
38 | static void | ||
39 | sigchld_handler (int val) | ||
40 | { | ||
41 | int status = 0; | ||
42 | int ret = 0; | ||
43 | |||
44 | (void) val; | ||
45 | waitpid (child, &status, 0); | ||
46 | if (WIFEXITED (status) != 0) | ||
47 | { | ||
48 | ret = WEXITSTATUS (status); | ||
49 | _exit (ret); /* return same status code */ | ||
50 | } | ||
51 | if (WIFSIGNALED (status) != 0) | ||
52 | { | ||
53 | ret = WTERMSIG (status); | ||
54 | kill (getpid (), ret); /* kill self with the same signal */ | ||
55 | } | ||
56 | _exit (-1); | ||
57 | } | ||
58 | |||
59 | |||
60 | static void | ||
61 | sigint_handler (int val) | ||
62 | { | ||
63 | kill (0, val); | ||
64 | _exit (val); | ||
65 | } | ||
66 | |||
67 | |||
68 | int | ||
69 | main (int argc, char *argv[]) | ||
70 | { | ||
71 | int timeout = 0; | ||
72 | pid_t gpid = 0; | ||
73 | |||
74 | if (argc < 3) | ||
75 | { | ||
76 | fprintf (stderr, | ||
77 | "arg 1: timeout in sec., arg 2: executable, arg<n> arguments\n"); | ||
78 | exit (-1); | ||
79 | } | ||
80 | |||
81 | timeout = atoi (argv[1]); | ||
82 | |||
83 | if (timeout == 0) | ||
84 | timeout = 600; | ||
85 | |||
86 | /* with getpgid() it does not compile, but getpgrp is the BSD version and working */ | ||
87 | gpid = getpgrp (); | ||
88 | |||
89 | signal (SIGCHLD, sigchld_handler); | ||
90 | signal (SIGABRT, sigint_handler); | ||
91 | signal (SIGFPE, sigint_handler); | ||
92 | signal (SIGILL, sigint_handler); | ||
93 | signal (SIGINT, sigint_handler); | ||
94 | signal (SIGSEGV, sigint_handler); | ||
95 | signal (SIGTERM, sigint_handler); | ||
96 | |||
97 | child = fork (); | ||
98 | if (child == 0) | ||
99 | { | ||
100 | /* int setpgrp(pid_t pid, pid_t pgid); is not working on this machine */ | ||
101 | // setpgrp (0, pid_t gpid); | ||
102 | if (-1 != gpid) | ||
103 | setpgid (0, gpid); | ||
104 | execvp (argv[2], &argv[2]); | ||
105 | exit (-1); | ||
106 | } | ||
107 | if (child > 0) | ||
108 | { | ||
109 | sleep (timeout); | ||
110 | printf ("Child processes were killed after timeout of %u seconds\n", | ||
111 | timeout); | ||
112 | kill (0, SIGTERM); | ||
113 | exit (3); | ||
114 | } | ||
115 | exit (-1); | ||
116 | } | ||
117 | |||
118 | |||
119 | /* end of timeout_watchdog.c */ | ||
diff --git a/src/cli/util/gnunet-uri.c b/src/cli/util/gnunet-uri.c new file mode 100644 index 000000000..128167cc5 --- /dev/null +++ b/src/cli/util/gnunet-uri.c | |||
@@ -0,0 +1,192 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012 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/gnunet-uri.c | ||
23 | * @brief tool to dispatch URIs to the appropriate GNUnet helper process | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | |||
30 | /** | ||
31 | * Handler exit code | ||
32 | */ | ||
33 | static long unsigned int exit_code = 0; | ||
34 | |||
35 | /** | ||
36 | * Helper process we started. | ||
37 | */ | ||
38 | static struct GNUNET_OS_Process *p; | ||
39 | |||
40 | /** | ||
41 | * Pipe used to communicate shutdown via signal. | ||
42 | */ | ||
43 | static struct GNUNET_DISK_PipeHandle *sigpipe; | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Task triggered whenever we receive a SIGCHLD (child | ||
48 | * process died) or when user presses CTRL-C. | ||
49 | * | ||
50 | * @param cls closure, NULL | ||
51 | */ | ||
52 | static void | ||
53 | maint_child_death (void *cls) | ||
54 | { | ||
55 | enum GNUNET_OS_ProcessStatusType type; | ||
56 | |||
57 | (void) cls; | ||
58 | if ((GNUNET_OK != GNUNET_OS_process_status (p, &type, &exit_code)) || | ||
59 | (type != GNUNET_OS_PROCESS_EXITED)) | ||
60 | GNUNET_break (0 == GNUNET_OS_process_kill (p, GNUNET_TERM_SIG)); | ||
61 | GNUNET_OS_process_destroy (p); | ||
62 | } | ||
63 | |||
64 | |||
65 | /** | ||
66 | * Main function that will be run by the scheduler. | ||
67 | * | ||
68 | * @param cls closure | ||
69 | * @param args remaining command-line arguments | ||
70 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
71 | * @param cfg configuration | ||
72 | */ | ||
73 | static void | ||
74 | run (void *cls, | ||
75 | char *const *args, | ||
76 | const char *cfgfile, | ||
77 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
78 | { | ||
79 | const char *uri; | ||
80 | const char *slash; | ||
81 | char *subsystem; | ||
82 | char *program; | ||
83 | struct GNUNET_SCHEDULER_Task *rt; | ||
84 | |||
85 | (void) cls; | ||
86 | (void) cfgfile; | ||
87 | if (NULL == (uri = args[0])) | ||
88 | { | ||
89 | fprintf (stderr, _ ("No URI specified on command line\n")); | ||
90 | return; | ||
91 | } | ||
92 | if (0 != strncasecmp ("gnunet://", uri, strlen ("gnunet://"))) | ||
93 | { | ||
94 | fprintf (stderr, | ||
95 | _ ("Invalid URI: does not start with `%s'\n"), | ||
96 | "gnunet://"); | ||
97 | return; | ||
98 | } | ||
99 | uri += strlen ("gnunet://"); | ||
100 | if (NULL == (slash = strchr (uri, '/'))) | ||
101 | { | ||
102 | fprintf (stderr, _ ("Invalid URI: fails to specify subsystem\n")); | ||
103 | return; | ||
104 | } | ||
105 | subsystem = GNUNET_strndup (uri, slash - uri); | ||
106 | if (GNUNET_OK != | ||
107 | GNUNET_CONFIGURATION_get_value_string (cfg, "uri", subsystem, &program)) | ||
108 | { | ||
109 | fprintf (stderr, _ ("No handler known for subsystem `%s'\n"), subsystem); | ||
110 | GNUNET_free (subsystem); | ||
111 | return; | ||
112 | } | ||
113 | GNUNET_free (subsystem); | ||
114 | rt = GNUNET_SCHEDULER_add_read_file ( | ||
115 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
116 | GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), | ||
117 | &maint_child_death, | ||
118 | NULL); | ||
119 | p = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_NONE, | ||
120 | NULL, | ||
121 | NULL, | ||
122 | NULL, | ||
123 | program, | ||
124 | program, | ||
125 | args[0], | ||
126 | NULL); | ||
127 | GNUNET_free (program); | ||
128 | if (NULL == p) | ||
129 | GNUNET_SCHEDULER_cancel (rt); | ||
130 | } | ||
131 | |||
132 | |||
133 | /** | ||
134 | * Signal handler called for SIGCHLD. Triggers the | ||
135 | * respective handler by writing to the trigger pipe. | ||
136 | */ | ||
137 | static void | ||
138 | sighandler_child_death () | ||
139 | { | ||
140 | static char c; | ||
141 | int old_errno = errno; /* back-up errno */ | ||
142 | |||
143 | GNUNET_break ( | ||
144 | 1 == | ||
145 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, | ||
146 | GNUNET_DISK_PIPE_END_WRITE), | ||
147 | &c, | ||
148 | sizeof(c))); | ||
149 | errno = old_errno; /* restore errno */ | ||
150 | } | ||
151 | |||
152 | |||
153 | /** | ||
154 | * The main function to handle gnunet://-URIs. | ||
155 | * | ||
156 | * @param argc number of arguments from the command line | ||
157 | * @param argv command line arguments | ||
158 | * @return 0 ok, 1 on error | ||
159 | */ | ||
160 | int | ||
161 | main (int argc, char *const *argv) | ||
162 | { | ||
163 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
164 | GNUNET_GETOPT_OPTION_END | ||
165 | }; | ||
166 | struct GNUNET_SIGNAL_Context *shc_chld; | ||
167 | int ret; | ||
168 | |||
169 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
170 | return 2; | ||
171 | sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE); | ||
172 | GNUNET_assert (sigpipe != NULL); | ||
173 | shc_chld = | ||
174 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); | ||
175 | ret = GNUNET_PROGRAM_run (argc, | ||
176 | argv, | ||
177 | "gnunet-uri URI", | ||
178 | gettext_noop ( | ||
179 | "Perform default-actions for GNUnet URIs"), | ||
180 | options, | ||
181 | &run, | ||
182 | NULL); | ||
183 | GNUNET_SIGNAL_handler_uninstall (shc_chld); | ||
184 | shc_chld = NULL; | ||
185 | GNUNET_DISK_pipe_close (sigpipe); | ||
186 | sigpipe = NULL; | ||
187 | GNUNET_free_nz ((void *) argv); | ||
188 | return ((GNUNET_OK == ret) && (0 == exit_code)) ? 0 : 1; | ||
189 | } | ||
190 | |||
191 | |||
192 | /* end of gnunet-uri.c */ | ||
diff --git a/src/cli/util/meson.build b/src/cli/util/meson.build new file mode 100644 index 000000000..ed9c3105c --- /dev/null +++ b/src/cli/util/meson.build | |||
@@ -0,0 +1,62 @@ | |||
1 | executable ('gnunet-base32', | ||
2 | ['gnunet-base32.c'], | ||
3 | dependencies: [libgnunetutil_dep], | ||
4 | include_directories: [incdir, configuration_inc], | ||
5 | install: true, | ||
6 | install_dir: get_option('bindir')) | ||
7 | executable ('gnunet-config', | ||
8 | ['gnunet-config.c'], | ||
9 | dependencies: [libgnunetutil_dep], | ||
10 | include_directories: [incdir, configuration_inc], | ||
11 | install: true, | ||
12 | install_dir: get_option('bindir')) | ||
13 | executable ('gnunet-resolver', | ||
14 | ['gnunet-resolver.c'], | ||
15 | dependencies: [libgnunetutil_dep], | ||
16 | include_directories: [incdir, configuration_inc], | ||
17 | install: true, | ||
18 | install_dir: get_option('bindir')) | ||
19 | executable ('gnunet-ecc', | ||
20 | ['gnunet-ecc.c'], | ||
21 | dependencies: [libgnunetutil_dep, gcrypt_dep, m_dep], | ||
22 | include_directories: [incdir, configuration_inc], | ||
23 | install: true, | ||
24 | install_dir: get_option('bindir')) | ||
25 | executable ('gnunet-scrypt', | ||
26 | ['gnunet-scrypt.c'], | ||
27 | dependencies: [libgnunetutil_dep], | ||
28 | include_directories: [incdir, configuration_inc], | ||
29 | install: true, | ||
30 | install_dir: get_option('bindir')) | ||
31 | executable ('gnunet-uri', | ||
32 | ['gnunet-uri.c'], | ||
33 | dependencies: [libgnunetutil_dep], | ||
34 | include_directories: [incdir, configuration_inc], | ||
35 | install: true, | ||
36 | install_dir: get_option('bindir')) | ||
37 | if zbar_dep.found() | ||
38 | executable ('gnunet-qr', | ||
39 | ['gnunet-qr.c'], | ||
40 | dependencies: [zbar_dep, libgnunetutil_dep], | ||
41 | include_directories: [incdir, configuration_inc], | ||
42 | install: true, | ||
43 | install_dir: get_option('bindir')) | ||
44 | endif | ||
45 | executable ('gnunet-config-diff', | ||
46 | ['gnunet-config-diff.c'], | ||
47 | dependencies: [libgnunetutil_dep], | ||
48 | include_directories: [incdir, configuration_inc], | ||
49 | install: false) | ||
50 | |||
51 | executable ('gnunet-timeout', | ||
52 | ['gnunet-timeout.c'], | ||
53 | dependencies: [libgnunetutil_dep], | ||
54 | include_directories: [incdir, configuration_inc], | ||
55 | install: true, | ||
56 | install_dir: get_option('libdir') / 'gnunet' / 'libexec') | ||
57 | executable ('gnunet-crypto-tvg', | ||
58 | ['gnunet-crypto-tvg.c'], | ||
59 | dependencies: [libgnunetutil_dep, json_dep], | ||
60 | include_directories: [incdir, configuration_inc], | ||
61 | install: false) | ||
62 | |||
diff --git a/src/cli/util/test_crypto_vectors.sh b/src/cli/util/test_crypto_vectors.sh new file mode 100755 index 000000000..40700a324 --- /dev/null +++ b/src/cli/util/test_crypto_vectors.sh | |||
@@ -0,0 +1,3 @@ | |||
1 | #!/usr/bin/env bash | ||
2 | |||
3 | cat ./crypto-test-vectors.json | ./gnunet-crypto-tvg --verify | ||