diff options
78 files changed, 14264 insertions, 3795 deletions
@@ -15,8 +15,11 @@ GNU package (http://www.gnu.org/). | |||
15 | This is an ALPHA release. There are known and significant bugs as | 15 | This is an ALPHA release. There are known and significant bugs as |
16 | well as many missing features in this release. | 16 | well as many missing features in this release. |
17 | 17 | ||
18 | GNUnet is free software released under the GNU General Public License | ||
19 | (v3 or later). For details see the COPYING file in this directory. | ||
20 | |||
18 | Additional documentation about GNUnet can be found at | 21 | Additional documentation about GNUnet can be found at |
19 | https://gnunet.org/. | 22 | https://gnunet.org/ and in the doc/ folder. |
20 | 23 | ||
21 | 24 | ||
22 | Dependencies: | 25 | Dependencies: |
@@ -63,6 +66,8 @@ How to install? | |||
63 | The fastest way is to use a binary package if it is available for your | 66 | The fastest way is to use a binary package if it is available for your |
64 | system. For a more detailed description, read the installation | 67 | system. For a more detailed description, read the installation |
65 | instructions on the webpage at https://gnunet.org/installation. | 68 | instructions on the webpage at https://gnunet.org/installation. |
69 | Generic installation instructions are in the INSTALL file in this | ||
70 | directory. | ||
66 | 71 | ||
67 | Note that some functions of GNUnet require "root" access. GNUnet will | 72 | Note that some functions of GNUnet require "root" access. GNUnet will |
68 | install (tiny) SUID binaries for those functions is you run "make | 73 | install (tiny) SUID binaries for those functions is you run "make |
@@ -300,7 +305,7 @@ Stay tuned | |||
300 | 305 | ||
301 | * https://gnunet.org/ | 306 | * https://gnunet.org/ |
302 | * https://gnunet.org/bugs/ | 307 | * https://gnunet.org/bugs/ |
303 | * https://gnunet.org/svn/ | 308 | * https://gnunet.org/git/ |
304 | * http://www.gnu.org/software/gnunet/ | 309 | * http://www.gnu.org/software/gnunet/ |
305 | * http://mail.gnu.org/mailman/listinfo/gnunet-developers | 310 | * http://mail.gnu.org/mailman/listinfo/gnunet-developers |
306 | * http://mail.gnu.org/mailman/listinfo/help-gnunet | 311 | * http://mail.gnu.org/mailman/listinfo/help-gnunet |
diff --git a/configure.ac b/configure.ac index eae03b01b..017b4836c 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -446,6 +446,27 @@ AC_CHECK_LIB(ogg, ogg_stream_flush_fill, | |||
446 | ogg=0) | 446 | ogg=0) |
447 | 447 | ||
448 | 448 | ||
449 | PKG_CHECK_MODULES([GLIB], [glib-2.0]) | ||
450 | # check for pbc library | ||
451 | pbc=0 | ||
452 | AC_CHECK_HEADER([pbc/pbc.h],pbc=1) | ||
453 | AC_CHECK_HEADER([gabe.h],abe=1) | ||
454 | AM_CONDITIONAL(HAVE_PBC, [test "$pbc" = 1]) | ||
455 | AM_CONDITIONAL(HAVE_ABE, [test "$abe" = 1]) | ||
456 | if test "x$pbc" = x1 | ||
457 | then | ||
458 | AC_DEFINE([HAVE_PBC],[1],[Have pbc library]) | ||
459 | else | ||
460 | AC_DEFINE([HAVE_PBC],[0],[Lacking pbc library]) | ||
461 | fi | ||
462 | if test "x$abe" = x1 | ||
463 | then | ||
464 | AC_DEFINE([HAVE_ABE],[1],[Have ABE library]) | ||
465 | else | ||
466 | AC_DEFINE([HAVE_ABE],[0],[Lacking ABE library]) | ||
467 | fi | ||
468 | |||
469 | |||
449 | 470 | ||
450 | gst=0 | 471 | gst=0 |
451 | PKG_CHECK_MODULES( | 472 | PKG_CHECK_MODULES( |
@@ -1570,6 +1591,8 @@ src/gnsrecord/Makefile | |||
1570 | src/hello/Makefile | 1591 | src/hello/Makefile |
1571 | src/identity/Makefile | 1592 | src/identity/Makefile |
1572 | src/identity/identity.conf | 1593 | src/identity/identity.conf |
1594 | src/credential/Makefile | ||
1595 | src/credential/credential.conf | ||
1573 | src/include/Makefile | 1596 | src/include/Makefile |
1574 | src/integration-tests/Makefile | 1597 | src/integration-tests/Makefile |
1575 | src/json/Makefile | 1598 | src/json/Makefile |
@@ -1635,6 +1658,8 @@ src/vpn/vpn.conf | |||
1635 | src/zonemaster/Makefile | 1658 | src/zonemaster/Makefile |
1636 | src/zonemaster/zonemaster.conf | 1659 | src/zonemaster/zonemaster.conf |
1637 | src/rest/Makefile | 1660 | src/rest/Makefile |
1661 | src/abe/Makefile | ||
1662 | src/identity-attribute/Makefile | ||
1638 | src/identity-provider/Makefile | 1663 | src/identity-provider/Makefile |
1639 | pkgconfig/Makefile | 1664 | pkgconfig/Makefile |
1640 | pkgconfig/gnunetarm.pc | 1665 | pkgconfig/gnunetarm.pc |
diff --git a/contrib/Dockerfile b/contrib/Dockerfile new file mode 100644 index 000000000..5a193a46d --- /dev/null +++ b/contrib/Dockerfile | |||
@@ -0,0 +1,63 @@ | |||
1 | from fedora:26 | ||
2 | |||
3 | # Install the required build tools | ||
4 | RUN dnf -y update && dnf -y install which git automake texinfo gettext-devel autoconf libtool libtool-ltdl-devel libidn-devel libunistring-devel glpk libextractor-devel libmicrohttpd-devel gnutls libgcrypt-devel jansson-devel sqlite-devel npm | ||
5 | |||
6 | WORKDIR /usr/src | ||
7 | |||
8 | # Install gnurl from source at version gnurl-7.54.0 | ||
9 | RUN git clone https://git.taler.net/gnurl.git --branch gnurl-7.54.0 | ||
10 | WORKDIR /usr/src/gnurl | ||
11 | RUN autoreconf -i | ||
12 | RUN ./configure --enable-ipv6 --with-gnutls --without-libssh2 \ | ||
13 | --without-libmetalink --without-winidn --without-librtmp \ | ||
14 | --without-nghttp2 --without-nss --without-cyassl \ | ||
15 | --without-polarssl --without-ssl --without-winssl \ | ||
16 | --without-darwinssl --disable-sspi --disable-ntlm-wb --disable-ldap \ | ||
17 | --disable-rtsp --disable-dict --disable-telnet --disable-tftp \ | ||
18 | --disable-pop3 --disable-imap --disable-smtp --disable-gopher \ | ||
19 | --disable-file --disable-ftp --disable-smb | ||
20 | RUN make install | ||
21 | WORKDIR /usr/src | ||
22 | |||
23 | RUN dnf -y install wget flex bison | ||
24 | |||
25 | # Install libpbc | ||
26 | RUN wget https://crypto.stanford.edu/pbc/files/pbc-0.5.14.tar.gz | ||
27 | RUN tar xvzpf pbc-0.5.14.tar.gz | ||
28 | WORKDIR /usr/src/pbc-0.5.14 | ||
29 | RUN ./configure --prefix=/usr | ||
30 | RUN make install | ||
31 | WORKDIR /usr/src | ||
32 | |||
33 | RUN dnf -y install glib2-devel | ||
34 | |||
35 | # Install libbswabe | ||
36 | RUN git clone https://github.com/schanzen/libgabe.git | ||
37 | WORKDIR /usr/src/libgabe | ||
38 | RUN ./configure --prefix=/usr | ||
39 | RUN make install | ||
40 | |||
41 | # Install WebUI | ||
42 | WORKDIR /usr/src/ | ||
43 | RUN git clone https://github.com/schanzen/gnunet-webui.git | ||
44 | WORKDIR /usr/src/gnunet-webui | ||
45 | RUN git checkout gnuidentity | ||
46 | |||
47 | RUN mkdir /usr/src/gnunet | ||
48 | WORKDIR /usr/src/gnunet | ||
49 | ADD . . | ||
50 | ARG NUM_JOBS | ||
51 | RUN ./bootstrap | ||
52 | RUN ./configure --prefix=/usr/local | ||
53 | RUN make -j$NUM_JOBS | ||
54 | RUN make install | ||
55 | |||
56 | RUN groupadd gnunetdns | ||
57 | RUN adduser --system -m --home-dir /var/lib/gnunet gnunet | ||
58 | RUN chown gnunet:gnunet /var/lib/gnunet | ||
59 | RUN echo '[arm]\nSYSTEM_ONLY = YES\nUSER_ONLY = NO\n' > /etc/gnunet.conf | ||
60 | |||
61 | ADD docker-entrypoint.sh . | ||
62 | |||
63 | CMD ["sh", "docker-entrypoint.sh"] | ||
diff --git a/contrib/docker-entrypoint.sh b/contrib/docker-entrypoint.sh new file mode 100644 index 000000000..807d86d6f --- /dev/null +++ b/contrib/docker-entrypoint.sh | |||
@@ -0,0 +1,3 @@ | |||
1 | #!/bin/bash | ||
2 | gnunet-arm -s > $HOME/gnunet.log 2>&1 | ||
3 | exec bash \ No newline at end of file | ||
diff --git a/po/POTFILES.in b/po/POTFILES.in index 4a4cfbd96..2fcb74c09 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in | |||
@@ -1,15 +1,24 @@ | |||
1 | src/abe/abe.c | ||
1 | src/arm/arm_api.c | 2 | src/arm/arm_api.c |
2 | src/arm/arm_monitor_api.c | 3 | src/arm/arm_monitor_api.c |
3 | src/arm/gnunet-arm.c | 4 | src/arm/gnunet-arm.c |
4 | src/arm/gnunet-service-arm.c | 5 | src/arm/gnunet-service-arm.c |
5 | src/arm/mockup-service.c | 6 | src/arm/mockup-service.c |
7 | src/ats-tests/ats-testing-experiment.c | ||
8 | src/ats-tests/ats-testing-log.c | ||
9 | src/ats-tests/ats-testing-preferences.c | ||
10 | src/ats-tests/ats-testing-traffic.c | ||
11 | src/ats-tests/ats-testing.c | ||
12 | src/ats-tests/gnunet-ats-sim.c | ||
13 | src/ats-tests/gnunet-solver-eval.c | ||
14 | src/ats-tool/gnunet-ats.c | ||
6 | src/ats/ats_api_connectivity.c | 15 | src/ats/ats_api_connectivity.c |
7 | src/ats/ats_api_performance.c | 16 | src/ats/ats_api_performance.c |
8 | src/ats/ats_api_scanner.c | 17 | src/ats/ats_api_scanner.c |
9 | src/ats/ats_api_scheduling.c | 18 | src/ats/ats_api_scheduling.c |
10 | src/ats/gnunet-ats-solver-eval.c | 19 | src/ats/gnunet-ats-solver-eval.c |
11 | src/ats/gnunet-service-ats_addresses.c | ||
12 | src/ats/gnunet-service-ats.c | 20 | src/ats/gnunet-service-ats.c |
21 | src/ats/gnunet-service-ats_addresses.c | ||
13 | src/ats/gnunet-service-ats_connectivity.c | 22 | src/ats/gnunet-service-ats_connectivity.c |
14 | src/ats/gnunet-service-ats_normalization.c | 23 | src/ats/gnunet-service-ats_normalization.c |
15 | src/ats/gnunet-service-ats_performance.c | 24 | src/ats/gnunet-service-ats_performance.c |
@@ -20,14 +29,6 @@ src/ats/gnunet-service-ats_scheduling.c | |||
20 | src/ats/plugin_ats_mlp.c | 29 | src/ats/plugin_ats_mlp.c |
21 | src/ats/plugin_ats_proportional.c | 30 | src/ats/plugin_ats_proportional.c |
22 | src/ats/plugin_ats_ril.c | 31 | src/ats/plugin_ats_ril.c |
23 | src/ats-tests/ats-testing.c | ||
24 | src/ats-tests/ats-testing-experiment.c | ||
25 | src/ats-tests/ats-testing-log.c | ||
26 | src/ats-tests/ats-testing-preferences.c | ||
27 | src/ats-tests/ats-testing-traffic.c | ||
28 | src/ats-tests/gnunet-ats-sim.c | ||
29 | src/ats-tests/gnunet-solver-eval.c | ||
30 | src/ats-tool/gnunet-ats.c | ||
31 | src/auction/gnunet-auction-create.c | 32 | src/auction/gnunet-auction-create.c |
32 | src/auction/gnunet-auction-info.c | 33 | src/auction/gnunet-auction-info.c |
33 | src/auction/gnunet-auction-join.c | 34 | src/auction/gnunet-auction-join.c |
@@ -39,8 +40,8 @@ src/block/plugin_block_test.c | |||
39 | src/cadet/cadet_api.c | 40 | src/cadet/cadet_api.c |
40 | src/cadet/cadet_test_lib.c | 41 | src/cadet/cadet_test_lib.c |
41 | src/cadet/desirability_table.c | 42 | src/cadet/desirability_table.c |
42 | src/cadet/gnunet-cadet.c | ||
43 | src/cadet/gnunet-cadet-profiler.c | 43 | src/cadet/gnunet-cadet-profiler.c |
44 | src/cadet/gnunet-cadet.c | ||
44 | src/cadet/gnunet-service-cadet.c | 45 | src/cadet/gnunet-service-cadet.c |
45 | src/cadet/gnunet-service-cadet_channel.c | 46 | src/cadet/gnunet-service-cadet_channel.c |
46 | src/cadet/gnunet-service-cadet_connection.c | 47 | src/cadet/gnunet-service-cadet_connection.c |
@@ -56,15 +57,15 @@ src/consensus/gnunet-service-consensus.c | |||
56 | src/consensus/plugin_block_consensus.c | 57 | src/consensus/plugin_block_consensus.c |
57 | src/conversation/conversation_api.c | 58 | src/conversation/conversation_api.c |
58 | src/conversation/conversation_api_call.c | 59 | src/conversation/conversation_api_call.c |
59 | src/conversation/gnunet-conversation.c | ||
60 | src/conversation/gnunet-conversation-test.c | 60 | src/conversation/gnunet-conversation-test.c |
61 | src/conversation/gnunet_gst.c | 61 | src/conversation/gnunet-conversation.c |
62 | src/conversation/gnunet_gst_test.c | ||
63 | src/conversation/gnunet-helper-audio-playback.c | ||
64 | src/conversation/gnunet-helper-audio-playback-gst.c | 62 | src/conversation/gnunet-helper-audio-playback-gst.c |
65 | src/conversation/gnunet-helper-audio-record.c | 63 | src/conversation/gnunet-helper-audio-playback.c |
66 | src/conversation/gnunet-helper-audio-record-gst.c | 64 | src/conversation/gnunet-helper-audio-record-gst.c |
65 | src/conversation/gnunet-helper-audio-record.c | ||
67 | src/conversation/gnunet-service-conversation.c | 66 | src/conversation/gnunet-service-conversation.c |
67 | src/conversation/gnunet_gst.c | ||
68 | src/conversation/gnunet_gst_test.c | ||
68 | src/conversation/microphone.c | 69 | src/conversation/microphone.c |
69 | src/conversation/plugin_gnsrecord_conversation.c | 70 | src/conversation/plugin_gnsrecord_conversation.c |
70 | src/conversation/speaker.c | 71 | src/conversation/speaker.c |
@@ -75,6 +76,13 @@ src/core/gnunet-service-core.c | |||
75 | src/core/gnunet-service-core_kx.c | 76 | src/core/gnunet-service-core_kx.c |
76 | src/core/gnunet-service-core_sessions.c | 77 | src/core/gnunet-service-core_sessions.c |
77 | src/core/gnunet-service-core_typemap.c | 78 | src/core/gnunet-service-core_typemap.c |
79 | src/credential/credential_api.c | ||
80 | src/credential/credential_misc.c | ||
81 | src/credential/credential_serialization.c | ||
82 | src/credential/gnunet-credential.c | ||
83 | src/credential/gnunet-service-credential.c | ||
84 | src/credential/plugin_gnsrecord_credential.c | ||
85 | src/credential/plugin_rest_credential.c | ||
78 | src/curl/curl.c | 86 | src/curl/curl.c |
79 | src/curl/curl_reschedule.c | 87 | src/curl/curl_reschedule.c |
80 | src/datacache/datacache.c | 88 | src/datacache/datacache.c |
@@ -94,7 +102,6 @@ src/dht/dht_api.c | |||
94 | src/dht/dht_test_lib.c | 102 | src/dht/dht_test_lib.c |
95 | src/dht/gnunet-dht-get.c | 103 | src/dht/gnunet-dht-get.c |
96 | src/dht/gnunet-dht-monitor.c | 104 | src/dht/gnunet-dht-monitor.c |
97 | src/dht/gnunet_dht_profiler.c | ||
98 | src/dht/gnunet-dht-put.c | 105 | src/dht/gnunet-dht-put.c |
99 | src/dht/gnunet-service-dht.c | 106 | src/dht/gnunet-service-dht.c |
100 | src/dht/gnunet-service-dht_clients.c | 107 | src/dht/gnunet-service-dht_clients.c |
@@ -103,6 +110,7 @@ src/dht/gnunet-service-dht_hello.c | |||
103 | src/dht/gnunet-service-dht_neighbours.c | 110 | src/dht/gnunet-service-dht_neighbours.c |
104 | src/dht/gnunet-service-dht_nse.c | 111 | src/dht/gnunet-service-dht_nse.c |
105 | src/dht/gnunet-service-dht_routing.c | 112 | src/dht/gnunet-service-dht_routing.c |
113 | src/dht/gnunet_dht_profiler.c | ||
106 | src/dht/plugin_block_dht.c | 114 | src/dht/plugin_block_dht.c |
107 | src/dns/dns_api.c | 115 | src/dns/dns_api.c |
108 | src/dns/dnsparser.c | 116 | src/dns/dnsparser.c |
@@ -117,8 +125,8 @@ src/dv/gnunet-dv.c | |||
117 | src/dv/gnunet-service-dv.c | 125 | src/dv/gnunet-service-dv.c |
118 | src/dv/plugin_transport_dv.c | 126 | src/dv/plugin_transport_dv.c |
119 | src/exit/gnunet-daemon-exit.c | 127 | src/exit/gnunet-daemon-exit.c |
120 | src/exit/gnunet-helper-exit.c | ||
121 | src/exit/gnunet-helper-exit-windows.c | 128 | src/exit/gnunet-helper-exit-windows.c |
129 | src/exit/gnunet-helper-exit.c | ||
122 | src/fragmentation/defragmentation.c | 130 | src/fragmentation/defragmentation.c |
123 | src/fragmentation/fragmentation.c | 131 | src/fragmentation/fragmentation.c |
124 | src/fs/fs_api.c | 132 | src/fs/fs_api.c |
@@ -143,8 +151,8 @@ src/fs/gnunet-auto-share.c | |||
143 | src/fs/gnunet-daemon-fsprofiler.c | 151 | src/fs/gnunet-daemon-fsprofiler.c |
144 | src/fs/gnunet-directory.c | 152 | src/fs/gnunet-directory.c |
145 | src/fs/gnunet-download.c | 153 | src/fs/gnunet-download.c |
146 | src/fs/gnunet-fs.c | ||
147 | src/fs/gnunet-fs-profiler.c | 154 | src/fs/gnunet-fs-profiler.c |
155 | src/fs/gnunet-fs.c | ||
148 | src/fs/gnunet-helper-fs-publish.c | 156 | src/fs/gnunet-helper-fs-publish.c |
149 | src/fs/gnunet-publish.c | 157 | src/fs/gnunet-publish.c |
150 | src/fs/gnunet-search.c | 158 | src/fs/gnunet-search.c |
@@ -162,10 +170,10 @@ src/fs/plugin_block_fs.c | |||
162 | src/gns/gns_api.c | 170 | src/gns/gns_api.c |
163 | src/gns/gnunet-bcd.c | 171 | src/gns/gnunet-bcd.c |
164 | src/gns/gnunet-dns2gns.c | 172 | src/gns/gnunet-dns2gns.c |
165 | src/gns/gnunet-gns.c | ||
166 | src/gns/gnunet-gns-helper-service-w32.c | 173 | src/gns/gnunet-gns-helper-service-w32.c |
167 | src/gns/gnunet-gns-import.c | 174 | src/gns/gnunet-gns-import.c |
168 | src/gns/gnunet-gns-proxy.c | 175 | src/gns/gnunet-gns-proxy.c |
176 | src/gns/gnunet-gns.c | ||
169 | src/gns/gnunet-service-gns.c | 177 | src/gns/gnunet-service-gns.c |
170 | src/gns/gnunet-service-gns_interceptor.c | 178 | src/gns/gnunet-service-gns_interceptor.c |
171 | src/gns/gnunet-service-gns_resolver.c | 179 | src/gns/gnunet-service-gns_resolver.c |
@@ -174,41 +182,44 @@ src/gns/nss/nss_gns_query.c | |||
174 | src/gns/plugin_block_gns.c | 182 | src/gns/plugin_block_gns.c |
175 | src/gns/plugin_gnsrecord_gns.c | 183 | src/gns/plugin_gnsrecord_gns.c |
176 | src/gns/plugin_rest_gns.c | 184 | src/gns/plugin_rest_gns.c |
185 | src/gns/w32nsp-install.c | ||
186 | src/gns/w32nsp-resolve.c | ||
187 | src/gns/w32nsp-uninstall.c | ||
188 | src/gns/w32nsp.c | ||
177 | src/gnsrecord/gnsrecord.c | 189 | src/gnsrecord/gnsrecord.c |
178 | src/gnsrecord/gnsrecord_crypto.c | 190 | src/gnsrecord/gnsrecord_crypto.c |
179 | src/gnsrecord/gnsrecord_misc.c | 191 | src/gnsrecord/gnsrecord_misc.c |
180 | src/gnsrecord/gnsrecord_serialization.c | 192 | src/gnsrecord/gnsrecord_serialization.c |
181 | src/gnsrecord/plugin_gnsrecord_dns.c | 193 | src/gnsrecord/plugin_gnsrecord_dns.c |
182 | src/gns/w32nsp.c | ||
183 | src/gns/w32nsp-install.c | ||
184 | src/gns/w32nsp-resolve.c | ||
185 | src/gns/w32nsp-uninstall.c | ||
186 | src/hello/address.c | 194 | src/hello/address.c |
187 | src/hello/gnunet-hello.c | 195 | src/hello/gnunet-hello.c |
188 | src/hello/hello.c | 196 | src/hello/hello.c |
189 | src/hostlist/gnunet-daemon-hostlist.c | 197 | src/hostlist/gnunet-daemon-hostlist.c |
190 | src/hostlist/gnunet-daemon-hostlist_client.c | 198 | src/hostlist/gnunet-daemon-hostlist_client.c |
191 | src/hostlist/gnunet-daemon-hostlist_server.c | 199 | src/hostlist/gnunet-daemon-hostlist_server.c |
200 | src/identity-attribute/identity_attribute.c | ||
201 | src/identity-attribute/plugin_identity_attribute_gnuid.c | ||
202 | src/identity-provider/gnunet-idp.c | ||
203 | src/identity-provider/gnunet-service-identity-provider.c | ||
204 | src/identity-provider/identity_provider_api.c | ||
205 | src/identity-provider/jwt.c | ||
206 | src/identity-provider/plugin_gnsrecord_identity_provider.c | ||
207 | src/identity-provider/plugin_identity_provider_sqlite.c | ||
208 | src/identity-provider/plugin_rest_identity_provider.c | ||
192 | src/identity/gnunet-identity.c | 209 | src/identity/gnunet-identity.c |
193 | src/identity/gnunet-service-identity.c | 210 | src/identity/gnunet-service-identity.c |
194 | src/identity/identity_api.c | 211 | src/identity/identity_api.c |
195 | src/identity/identity_api_lookup.c | 212 | src/identity/identity_api_lookup.c |
196 | src/identity/plugin_gnsrecord_identity.c | ||
197 | src/identity/plugin_rest_identity.c | 213 | src/identity/plugin_rest_identity.c |
198 | src/identity-provider/gnunet-identity-token.c | 214 | src/json/json.c |
199 | src/identity-provider/gnunet-service-identity-provider.c | 215 | src/json/json_generator.c |
200 | src/identity-provider/identity_provider_api.c | 216 | src/json/json_helper.c |
201 | src/identity-provider/identity_token.c | 217 | src/json/json_mhd.c |
202 | src/identity-provider/plugin_rest_identity_provider.c | ||
203 | src/jsonapi/jsonapi.c | 218 | src/jsonapi/jsonapi.c |
204 | src/jsonapi/jsonapi_document.c | 219 | src/jsonapi/jsonapi_document.c |
205 | src/jsonapi/jsonapi_error.c | 220 | src/jsonapi/jsonapi_error.c |
206 | src/jsonapi/jsonapi_relationship.c | 221 | src/jsonapi/jsonapi_relationship.c |
207 | src/jsonapi/jsonapi_resource.c | 222 | src/jsonapi/jsonapi_resource.c |
208 | src/json/json.c | ||
209 | src/json/json_generator.c | ||
210 | src/json/json_helper.c | ||
211 | src/json/json_mhd.c | ||
212 | src/multicast/gnunet-multicast.c | 223 | src/multicast/gnunet-multicast.c |
213 | src/multicast/gnunet-service-multicast.c | 224 | src/multicast/gnunet-service-multicast.c |
214 | src/multicast/multicast_api.c | 225 | src/multicast/multicast_api.c |
@@ -222,8 +233,8 @@ src/namecache/namecache_api.c | |||
222 | src/namecache/plugin_namecache_flat.c | 233 | src/namecache/plugin_namecache_flat.c |
223 | src/namecache/plugin_namecache_postgres.c | 234 | src/namecache/plugin_namecache_postgres.c |
224 | src/namecache/plugin_namecache_sqlite.c | 235 | src/namecache/plugin_namecache_sqlite.c |
225 | src/namestore/gnunet-namestore.c | ||
226 | src/namestore/gnunet-namestore-fcfsd.c | 236 | src/namestore/gnunet-namestore-fcfsd.c |
237 | src/namestore/gnunet-namestore.c | ||
227 | src/namestore/gnunet-service-namestore.c | 238 | src/namestore/gnunet-service-namestore.c |
228 | src/namestore/namestore_api.c | 239 | src/namestore/namestore_api.c |
229 | src/namestore/namestore_api_monitor.c | 240 | src/namestore/namestore_api_monitor.c |
@@ -238,10 +249,10 @@ src/nat-auto/gnunet-service-nat-auto.c | |||
238 | src/nat-auto/gnunet-service-nat-auto_legacy.c | 249 | src/nat-auto/gnunet-service-nat-auto_legacy.c |
239 | src/nat-auto/nat_auto_api.c | 250 | src/nat-auto/nat_auto_api.c |
240 | src/nat-auto/nat_auto_api_test.c | 251 | src/nat-auto/nat_auto_api_test.c |
241 | src/nat/gnunet-helper-nat-client.c | ||
242 | src/nat/gnunet-helper-nat-client-windows.c | 252 | src/nat/gnunet-helper-nat-client-windows.c |
243 | src/nat/gnunet-helper-nat-server.c | 253 | src/nat/gnunet-helper-nat-client.c |
244 | src/nat/gnunet-helper-nat-server-windows.c | 254 | src/nat/gnunet-helper-nat-server-windows.c |
255 | src/nat/gnunet-helper-nat-server.c | ||
245 | src/nat/gnunet-nat.c | 256 | src/nat/gnunet-nat.c |
246 | src/nat/gnunet-service-nat.c | 257 | src/nat/gnunet-service-nat.c |
247 | src/nat/gnunet-service-nat_externalip.c | 258 | src/nat/gnunet-service-nat_externalip.c |
@@ -250,15 +261,15 @@ src/nat/gnunet-service-nat_mini.c | |||
250 | src/nat/gnunet-service-nat_stun.c | 261 | src/nat/gnunet-service-nat_stun.c |
251 | src/nat/nat_api.c | 262 | src/nat/nat_api.c |
252 | src/nat/nat_api_stun.c | 263 | src/nat/nat_api_stun.c |
253 | src/nse/gnunet-nse.c | ||
254 | src/nse/gnunet-nse-profiler.c | 264 | src/nse/gnunet-nse-profiler.c |
265 | src/nse/gnunet-nse.c | ||
255 | src/nse/gnunet-service-nse.c | 266 | src/nse/gnunet-service-nse.c |
256 | src/nse/nse_api.c | 267 | src/nse/nse_api.c |
268 | src/peerinfo-tool/gnunet-peerinfo.c | ||
269 | src/peerinfo-tool/gnunet-peerinfo_plugins.c | ||
257 | src/peerinfo/gnunet-service-peerinfo.c | 270 | src/peerinfo/gnunet-service-peerinfo.c |
258 | src/peerinfo/peerinfo_api.c | 271 | src/peerinfo/peerinfo_api.c |
259 | src/peerinfo/peerinfo_api_notify.c | 272 | src/peerinfo/peerinfo_api_notify.c |
260 | src/peerinfo-tool/gnunet-peerinfo.c | ||
261 | src/peerinfo-tool/gnunet-peerinfo_plugins.c | ||
262 | src/peerstore/gnunet-peerstore.c | 273 | src/peerstore/gnunet-peerstore.c |
263 | src/peerstore/gnunet-service-peerstore.c | 274 | src/peerstore/gnunet-service-peerstore.c |
264 | src/peerstore/peerstore_api.c | 275 | src/peerstore/peerstore_api.c |
@@ -309,13 +320,13 @@ src/rps/gnunet-service-rps_custommap.c | |||
309 | src/rps/gnunet-service-rps_sampler.c | 320 | src/rps/gnunet-service-rps_sampler.c |
310 | src/rps/gnunet-service-rps_sampler_elem.c | 321 | src/rps/gnunet-service-rps_sampler_elem.c |
311 | src/rps/gnunet-service-rps_view.c | 322 | src/rps/gnunet-service-rps_view.c |
312 | src/rps/rps_api.c | ||
313 | src/rps/rps-test_util.c | 323 | src/rps/rps-test_util.c |
324 | src/rps/rps_api.c | ||
314 | src/scalarproduct/gnunet-scalarproduct.c | 325 | src/scalarproduct/gnunet-scalarproduct.c |
315 | src/scalarproduct/gnunet-service-scalarproduct_alice.c | ||
316 | src/scalarproduct/gnunet-service-scalarproduct_bob.c | ||
317 | src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | 326 | src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c |
318 | src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | 327 | src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c |
328 | src/scalarproduct/gnunet-service-scalarproduct_alice.c | ||
329 | src/scalarproduct/gnunet-service-scalarproduct_bob.c | ||
319 | src/scalarproduct/scalarproduct_api.c | 330 | src/scalarproduct/scalarproduct_api.c |
320 | src/secretsharing/gnunet-secretsharing-profiler.c | 331 | src/secretsharing/gnunet-secretsharing-profiler.c |
321 | src/secretsharing/gnunet-service-secretsharing.c | 332 | src/secretsharing/gnunet-service-secretsharing.c |
@@ -342,15 +353,16 @@ src/statistics/gnunet-statistics.c | |||
342 | src/statistics/statistics_api.c | 353 | src/statistics/statistics_api.c |
343 | src/template/gnunet-service-template.c | 354 | src/template/gnunet-service-template.c |
344 | src/template/gnunet-template.c | 355 | src/template/gnunet-template.c |
356 | src/testbed-logger/gnunet-service-testbed-logger.c | ||
357 | src/testbed-logger/testbed_logger_api.c | ||
345 | src/testbed/generate-underlay-topology.c | 358 | src/testbed/generate-underlay-topology.c |
346 | src/testbed/gnunet-daemon-latency-logger.c | 359 | src/testbed/gnunet-daemon-latency-logger.c |
347 | src/testbed/gnunet-daemon-testbed-blacklist.c | 360 | src/testbed/gnunet-daemon-testbed-blacklist.c |
348 | src/testbed/gnunet-daemon-testbed-underlay.c | 361 | src/testbed/gnunet-daemon-testbed-underlay.c |
349 | src/testbed/gnunet-helper-testbed.c | 362 | src/testbed/gnunet-helper-testbed.c |
350 | src/testbed/gnunet_mpi_test.c | ||
351 | src/testbed/gnunet-service-test-barriers.c | 363 | src/testbed/gnunet-service-test-barriers.c |
352 | src/testbed/gnunet-service-testbed_barriers.c | ||
353 | src/testbed/gnunet-service-testbed.c | 364 | src/testbed/gnunet-service-testbed.c |
365 | src/testbed/gnunet-service-testbed_barriers.c | ||
354 | src/testbed/gnunet-service-testbed_cache.c | 366 | src/testbed/gnunet-service-testbed_cache.c |
355 | src/testbed/gnunet-service-testbed_connectionpool.c | 367 | src/testbed/gnunet-service-testbed_connectionpool.c |
356 | src/testbed/gnunet-service-testbed_cpustatus.c | 368 | src/testbed/gnunet-service-testbed_cpustatus.c |
@@ -358,20 +370,19 @@ src/testbed/gnunet-service-testbed_links.c | |||
358 | src/testbed/gnunet-service-testbed_meminfo.c | 370 | src/testbed/gnunet-service-testbed_meminfo.c |
359 | src/testbed/gnunet-service-testbed_oc.c | 371 | src/testbed/gnunet-service-testbed_oc.c |
360 | src/testbed/gnunet-service-testbed_peers.c | 372 | src/testbed/gnunet-service-testbed_peers.c |
361 | src/testbed/gnunet_testbed_mpi_spawn.c | ||
362 | src/testbed/gnunet-testbed-profiler.c | 373 | src/testbed/gnunet-testbed-profiler.c |
363 | src/testbed-logger/gnunet-service-testbed-logger.c | 374 | src/testbed/gnunet_mpi_test.c |
364 | src/testbed-logger/testbed_logger_api.c | 375 | src/testbed/gnunet_testbed_mpi_spawn.c |
365 | src/testbed/testbed_api_barriers.c | ||
366 | src/testbed/testbed_api.c | 376 | src/testbed/testbed_api.c |
377 | src/testbed/testbed_api_barriers.c | ||
367 | src/testbed/testbed_api_hosts.c | 378 | src/testbed/testbed_api_hosts.c |
368 | src/testbed/testbed_api_operations.c | 379 | src/testbed/testbed_api_operations.c |
369 | src/testbed/testbed_api_peers.c | 380 | src/testbed/testbed_api_peers.c |
370 | src/testbed/testbed_api_sd.c | 381 | src/testbed/testbed_api_sd.c |
371 | src/testbed/testbed_api_services.c | 382 | src/testbed/testbed_api_services.c |
372 | src/testbed/testbed_api_statistics.c | 383 | src/testbed/testbed_api_statistics.c |
373 | src/testbed/testbed_api_testbed.c | ||
374 | src/testbed/testbed_api_test.c | 384 | src/testbed/testbed_api_test.c |
385 | src/testbed/testbed_api_testbed.c | ||
375 | src/testbed/testbed_api_topology.c | 386 | src/testbed/testbed_api_topology.c |
376 | src/testbed/testbed_api_underlay.c | 387 | src/testbed/testbed_api_underlay.c |
377 | src/testing/gnunet-testing.c | 388 | src/testing/gnunet-testing.c |
@@ -380,34 +391,39 @@ src/testing/testing.c | |||
380 | src/topology/friends.c | 391 | src/topology/friends.c |
381 | src/topology/gnunet-daemon-topology.c | 392 | src/topology/gnunet-daemon-topology.c |
382 | src/transport/gnunet-helper-transport-bluetooth.c | 393 | src/transport/gnunet-helper-transport-bluetooth.c |
383 | src/transport/gnunet-helper-transport-wlan.c | ||
384 | src/transport/gnunet-helper-transport-wlan-dummy.c | 394 | src/transport/gnunet-helper-transport-wlan-dummy.c |
385 | src/transport/gnunet-service-transport_ats.c | 395 | src/transport/gnunet-helper-transport-wlan.c |
386 | src/transport/gnunet-service-transport.c | 396 | src/transport/gnunet-service-transport.c |
397 | src/transport/gnunet-service-transport_ats.c | ||
387 | src/transport/gnunet-service-transport_hello.c | 398 | src/transport/gnunet-service-transport_hello.c |
388 | src/transport/gnunet-service-transport_manipulation.c | 399 | src/transport/gnunet-service-transport_manipulation.c |
389 | src/transport/gnunet-service-transport_neighbours.c | 400 | src/transport/gnunet-service-transport_neighbours.c |
390 | src/transport/gnunet-service-transport_plugins.c | 401 | src/transport/gnunet-service-transport_plugins.c |
391 | src/transport/gnunet-service-transport_validation.c | 402 | src/transport/gnunet-service-transport_validation.c |
392 | src/transport/gnunet-transport.c | ||
393 | src/transport/gnunet-transport-certificate-creation.c | 403 | src/transport/gnunet-transport-certificate-creation.c |
394 | src/transport/gnunet-transport-profiler.c | 404 | src/transport/gnunet-transport-profiler.c |
395 | src/transport/gnunet-transport-wlan-receiver.c | 405 | src/transport/gnunet-transport-wlan-receiver.c |
396 | src/transport/gnunet-transport-wlan-sender.c | 406 | src/transport/gnunet-transport-wlan-sender.c |
407 | src/transport/gnunet-transport.c | ||
397 | src/transport/plugin_transport_http_client.c | 408 | src/transport/plugin_transport_http_client.c |
398 | src/transport/plugin_transport_http_common.c | 409 | src/transport/plugin_transport_http_common.c |
399 | src/transport/plugin_transport_http_server.c | 410 | src/transport/plugin_transport_http_server.c |
400 | src/transport/plugin_transport_smtp.c | 411 | src/transport/plugin_transport_smtp.c |
401 | src/transport/plugin_transport_tcp.c | 412 | src/transport/plugin_transport_tcp.c |
402 | src/transport/plugin_transport_template.c | 413 | src/transport/plugin_transport_template.c |
403 | src/transport/plugin_transport_udp_broadcasting.c | ||
404 | src/transport/plugin_transport_udp.c | 414 | src/transport/plugin_transport_udp.c |
415 | src/transport/plugin_transport_udp_broadcasting.c | ||
405 | src/transport/plugin_transport_unix.c | 416 | src/transport/plugin_transport_unix.c |
406 | src/transport/plugin_transport_wlan.c | 417 | src/transport/plugin_transport_wlan.c |
407 | src/transport/tcp_connection_legacy.c | 418 | src/transport/tcp_connection_legacy.c |
408 | src/transport/tcp_server_legacy.c | 419 | src/transport/tcp_server_legacy.c |
409 | src/transport/tcp_server_mst_legacy.c | 420 | src/transport/tcp_server_mst_legacy.c |
410 | src/transport/tcp_service_legacy.c | 421 | src/transport/tcp_service_legacy.c |
422 | src/transport/transport-testing-filenames.c | ||
423 | src/transport/transport-testing-loggers.c | ||
424 | src/transport/transport-testing-main.c | ||
425 | src/transport/transport-testing-send.c | ||
426 | src/transport/transport-testing.c | ||
411 | src/transport/transport_api_address_to_string.c | 427 | src/transport/transport_api_address_to_string.c |
412 | src/transport/transport_api_blacklist.c | 428 | src/transport/transport_api_blacklist.c |
413 | src/transport/transport_api_core.c | 429 | src/transport/transport_api_core.c |
@@ -416,11 +432,6 @@ src/transport/transport_api_manipulation.c | |||
416 | src/transport/transport_api_monitor_peers.c | 432 | src/transport/transport_api_monitor_peers.c |
417 | src/transport/transport_api_monitor_plugins.c | 433 | src/transport/transport_api_monitor_plugins.c |
418 | src/transport/transport_api_offer_hello.c | 434 | src/transport/transport_api_offer_hello.c |
419 | src/transport/transport-testing.c | ||
420 | src/transport/transport-testing-filenames.c | ||
421 | src/transport/transport-testing-loggers.c | ||
422 | src/transport/transport-testing-main.c | ||
423 | src/transport/transport-testing-send.c | ||
424 | src/tun/regex.c | 435 | src/tun/regex.c |
425 | src/tun/tun.c | 436 | src/tun/tun.c |
426 | src/util/bandwidth.c | 437 | src/util/bandwidth.c |
@@ -434,10 +445,11 @@ src/util/configuration_loader.c | |||
434 | src/util/container_bloomfilter.c | 445 | src/util/container_bloomfilter.c |
435 | src/util/container_heap.c | 446 | src/util/container_heap.c |
436 | src/util/container_meta_data.c | 447 | src/util/container_meta_data.c |
437 | src/util/container_multihashmap32.c | ||
438 | src/util/container_multihashmap.c | 448 | src/util/container_multihashmap.c |
449 | src/util/container_multihashmap32.c | ||
439 | src/util/container_multipeermap.c | 450 | src/util/container_multipeermap.c |
440 | src/util/container_multishortmap.c | 451 | src/util/container_multishortmap.c |
452 | src/util/crypto_abe.c | ||
441 | src/util/crypto_crc.c | 453 | src/util/crypto_crc.c |
442 | src/util/crypto_ecc.c | 454 | src/util/crypto_ecc.c |
443 | src/util/crypto_ecc_dlog.c | 455 | src/util/crypto_ecc_dlog.c |
@@ -454,8 +466,8 @@ src/util/crypto_symmetric.c | |||
454 | src/util/disk.c | 466 | src/util/disk.c |
455 | src/util/getopt.c | 467 | src/util/getopt.c |
456 | src/util/getopt_helpers.c | 468 | src/util/getopt_helpers.c |
457 | src/util/gnunet-config.c | ||
458 | src/util/gnunet-config-diff.c | 469 | src/util/gnunet-config-diff.c |
470 | src/util/gnunet-config.c | ||
459 | src/util/gnunet-ecc.c | 471 | src/util/gnunet-ecc.c |
460 | src/util/gnunet-helper-w32-console.c | 472 | src/util/gnunet-helper-w32-console.c |
461 | src/util/gnunet-resolver.c | 473 | src/util/gnunet-resolver.c |
@@ -486,8 +498,8 @@ src/util/time.c | |||
486 | src/util/w32cat.c | 498 | src/util/w32cat.c |
487 | src/util/win.c | 499 | src/util/win.c |
488 | src/util/winproc.c | 500 | src/util/winproc.c |
489 | src/vpn/gnunet-helper-vpn.c | ||
490 | src/vpn/gnunet-helper-vpn-windows.c | 501 | src/vpn/gnunet-helper-vpn-windows.c |
502 | src/vpn/gnunet-helper-vpn.c | ||
491 | src/vpn/gnunet-service-vpn.c | 503 | src/vpn/gnunet-service-vpn.c |
492 | src/vpn/gnunet-vpn.c | 504 | src/vpn/gnunet-vpn.c |
493 | src/vpn/vpn_api.c | 505 | src/vpn/vpn_api.c |
diff --git a/src/Makefile.am b/src/Makefile.am index 7f1a00177..6d0284157 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -12,11 +12,12 @@ endif | |||
12 | if HAVE_EXPERIMENTAL | 12 | if HAVE_EXPERIMENTAL |
13 | EXP_DIR = \ | 13 | EXP_DIR = \ |
14 | rps | 14 | rps |
15 | endif | 15 | # dv (FTBFS) |
16 | 16 | if HAVE_ABE | |
17 | if HAVE_JSON | 17 | EXP_DIR += abe \ |
18 | if HAVE_MHD | 18 | credential \ |
19 | PROVIDER_DIR = identity-provider | 19 | identity-attribute \ |
20 | identity-provider | ||
20 | endif | 21 | endif |
21 | endif | 22 | endif |
22 | 23 | ||
@@ -128,7 +129,6 @@ SUBDIRS = \ | |||
128 | psyc \ | 129 | psyc \ |
129 | social \ | 130 | social \ |
130 | $(AUCTION_DIR) \ | 131 | $(AUCTION_DIR) \ |
131 | $(EXP_DIR) \ | 132 | $(EXP_DIR) |
132 | $(PROVIDER_DIR) | ||
133 | 133 | ||
134 | endif | 134 | endif |
diff --git a/src/abe/Makefile.am b/src/abe/Makefile.am new file mode 100644 index 000000000..308e6c67c --- /dev/null +++ b/src/abe/Makefile.am | |||
@@ -0,0 +1,50 @@ | |||
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 | dist_pkgcfg_DATA = \ | ||
11 | abe.conf | ||
12 | |||
13 | if USE_COVERAGE | ||
14 | AM_CFLAGS = --coverage -O0 | ||
15 | XLIB = -lgcov | ||
16 | endif | ||
17 | |||
18 | libgnunetabe_la_SOURCES = abe.c | ||
19 | |||
20 | libgnunetabe_la_LIBADD = \ | ||
21 | $(GCLIBADD)\ | ||
22 | $(LIBGCRYPT_LIBS) \ | ||
23 | $(LTLIBICONV) \ | ||
24 | $(LTLIBINTL) \ | ||
25 | $(ABE_LIBADD) \ | ||
26 | -lgabe \ | ||
27 | -lpbc \ | ||
28 | -lglib-2.0 \ | ||
29 | -lltdl $(Z_LIBS) -lunistring $(XLIB) | ||
30 | |||
31 | libgnunetabe_la_LDFLAGS = \ | ||
32 | $(GN_LIB_LDFLAGS) \ | ||
33 | -version-info 1:0:0 | ||
34 | |||
35 | lib_LTLIBRARIES = libgnunetabe.la | ||
36 | |||
37 | if ENABLE_TEST_RUN | ||
38 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
39 | TESTS = $(check_PROGRAMS) | ||
40 | endif | ||
41 | |||
42 | check_PROGRAMS = test_cpabe | ||
43 | |||
44 | test_cpabe_SOURCES = \ | ||
45 | test_cpabe.c | ||
46 | test_cpabe_LDADD = \ | ||
47 | libgnunetabe.la \ | ||
48 | $(top_builddir)/src/util/libgnunetutil.la | ||
49 | check_PROGRAMS += \ | ||
50 | test_cpabe | ||
diff --git a/src/abe/abe.c b/src/abe/abe.c new file mode 100644 index 000000000..3f1f6dc5b --- /dev/null +++ b/src/abe/abe.c | |||
@@ -0,0 +1,499 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. Copyright (C) 2001-2018 Christian Grothoff | ||
3 | (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | |||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @file abe/abe.c | ||
24 | * @brief functions for Attribute-Based Encryption | ||
25 | * @author Martin Schanzenbach | ||
26 | */ | ||
27 | |||
28 | |||
29 | #include "platform.h" | ||
30 | #include <pbc/pbc.h> | ||
31 | #include <gabe.h> | ||
32 | |||
33 | #include "gnunet_crypto_lib.h" | ||
34 | #include "gnunet_abe_lib.h" | ||
35 | |||
36 | struct GNUNET_ABE_AbeMasterKey | ||
37 | { | ||
38 | gabe_pub_t* pub; | ||
39 | gabe_msk_t* msk; | ||
40 | }; | ||
41 | |||
42 | struct GNUNET_ABE_AbeKey | ||
43 | { | ||
44 | gabe_pub_t* pub; | ||
45 | gabe_prv_t* prv; | ||
46 | }; | ||
47 | |||
48 | static int | ||
49 | init_aes( element_t k, int enc, | ||
50 | gcry_cipher_hd_t* handle, | ||
51 | struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
52 | unsigned char* iv) | ||
53 | { | ||
54 | int rc; | ||
55 | int key_len; | ||
56 | unsigned char* key_buf; | ||
57 | |||
58 | key_len = element_length_in_bytes(k) < 33 ? 3 : element_length_in_bytes(k); | ||
59 | key_buf = (unsigned char*) malloc(key_len); | ||
60 | element_to_bytes(key_buf, k); | ||
61 | |||
62 | memcpy (key->aes_key, key_buf, GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
63 | GNUNET_assert (0 == | ||
64 | gcry_cipher_open (handle, GCRY_CIPHER_AES256, | ||
65 | GCRY_CIPHER_MODE_CFB, 0)); | ||
66 | rc = gcry_cipher_setkey (*handle, | ||
67 | key->aes_key, | ||
68 | sizeof (key->aes_key)); | ||
69 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
70 | memset (iv, 0, 16); //TODO make reasonable | ||
71 | rc = gcry_cipher_setiv (*handle, | ||
72 | iv, | ||
73 | 16); | ||
74 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
75 | |||
76 | free(key_buf); | ||
77 | return rc; | ||
78 | } | ||
79 | |||
80 | static int | ||
81 | aes_128_cbc_encrypt( char* pt, | ||
82 | int size, | ||
83 | element_t k, | ||
84 | char **ct ) | ||
85 | { | ||
86 | gcry_cipher_hd_t handle; | ||
87 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
88 | unsigned char iv[16]; | ||
89 | char* buf; | ||
90 | int padding; | ||
91 | int buf_size; | ||
92 | uint8_t len[4]; | ||
93 | init_aes(k, 1, &handle, &skey, iv); | ||
94 | |||
95 | /* TODO make less crufty */ | ||
96 | |||
97 | /* stuff in real length (big endian) before padding */ | ||
98 | len[0] = (size & 0xff000000)>>24; | ||
99 | len[1] = (size & 0xff0000)>>16; | ||
100 | len[2] = (size & 0xff00)>>8; | ||
101 | len[3] = (size & 0xff)>>0; | ||
102 | padding = 16 - ((4+size) % 16); | ||
103 | buf_size = 4 + size + padding; | ||
104 | buf = GNUNET_malloc (buf_size); | ||
105 | GNUNET_memcpy (buf, len, 4); | ||
106 | GNUNET_memcpy (buf+4, pt, size); | ||
107 | *ct = GNUNET_malloc (buf_size); | ||
108 | |||
109 | GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf, buf_size)); | ||
110 | gcry_cipher_close (handle); | ||
111 | //AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT); | ||
112 | GNUNET_free (buf); | ||
113 | return buf_size; | ||
114 | } | ||
115 | |||
116 | static int | ||
117 | aes_128_cbc_decrypt( char* ct, | ||
118 | int size, | ||
119 | element_t k, | ||
120 | char **pt ) | ||
121 | { | ||
122 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
123 | gcry_cipher_hd_t handle; | ||
124 | unsigned char iv[16]; | ||
125 | char* tmp; | ||
126 | uint32_t len; | ||
127 | |||
128 | init_aes(k, 1, &handle, &skey, iv); | ||
129 | |||
130 | tmp = GNUNET_malloc (size); | ||
131 | |||
132 | //AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT); | ||
133 | GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, ct, size)); | ||
134 | gcry_cipher_close (handle); | ||
135 | /* TODO make less crufty */ | ||
136 | |||
137 | /* get real length */ | ||
138 | len = 0; | ||
139 | len = len | ||
140 | | ((tmp[0])<<24) | ((tmp[1])<<16) | ||
141 | | ((tmp[2])<<8) | ((tmp[3])<<0); | ||
142 | /* truncate any garbage from the padding */ | ||
143 | *pt = GNUNET_malloc (len); | ||
144 | GNUNET_memcpy (*pt, tmp+4, len); | ||
145 | GNUNET_free (tmp); | ||
146 | return len; | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * @ingroup abe | ||
151 | * Create a new CP-ABE master key. Caller must free return value. | ||
152 | * | ||
153 | * @return fresh private key; free using #GNUNET_ABE_cpabe_delete_master_key | ||
154 | */ | ||
155 | struct GNUNET_ABE_AbeMasterKey* | ||
156 | GNUNET_ABE_cpabe_create_master_key (void) | ||
157 | { | ||
158 | struct GNUNET_ABE_AbeMasterKey* key; | ||
159 | key = GNUNET_new (struct GNUNET_ABE_AbeMasterKey); | ||
160 | gabe_setup(&key->pub, &key->msk); | ||
161 | GNUNET_assert (NULL != key->pub); | ||
162 | GNUNET_assert (NULL != key->msk); | ||
163 | return key; | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * @ingroup abe | ||
168 | * Delete a CP-ABE master key. | ||
169 | * | ||
170 | * @param key the master key | ||
171 | * @return fresh private key; free using #GNUNET_free | ||
172 | */ | ||
173 | void | ||
174 | GNUNET_ABE_cpabe_delete_master_key (struct GNUNET_ABE_AbeMasterKey *key) | ||
175 | { | ||
176 | gabe_msk_free (key->msk); | ||
177 | gabe_pub_free (key->pub); | ||
178 | //GNUNET_free (key->msk); | ||
179 | //gabe_msk_free (key->msk); //For some reason free of pub implicit? | ||
180 | GNUNET_free (key); | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * @ingroup abe | ||
185 | * Create a new CP-ABE key. Caller must free return value. | ||
186 | * | ||
187 | * @param key the master key | ||
188 | * @param attrs the attributes to append to the key | ||
189 | * @return fresh private key; free using #GNUNET_ABE_cpabe_delete_key | ||
190 | */ | ||
191 | struct GNUNET_ABE_AbeKey* | ||
192 | GNUNET_ABE_cpabe_create_key (struct GNUNET_ABE_AbeMasterKey *key, | ||
193 | char **attrs) | ||
194 | { | ||
195 | struct GNUNET_ABE_AbeKey *prv_key; | ||
196 | int size; | ||
197 | char *tmp; | ||
198 | |||
199 | prv_key = GNUNET_new (struct GNUNET_ABE_AbeKey); | ||
200 | prv_key->prv = gabe_keygen(key->pub, key->msk, attrs); | ||
201 | size = gabe_pub_serialize(key->pub, &tmp); | ||
202 | prv_key->pub = gabe_pub_unserialize(tmp, size); | ||
203 | GNUNET_free (tmp); | ||
204 | GNUNET_assert (NULL != prv_key->prv); | ||
205 | return prv_key; | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * @ingroup abe | ||
210 | * Delete a CP-ABE key. | ||
211 | * | ||
212 | * @param key the key to delete | ||
213 | * @param delete_pub GNUNE_YES if the public key should also be freed (bug in gabe) | ||
214 | * @return fresh private key; free using #GNUNET_free | ||
215 | */ | ||
216 | void | ||
217 | GNUNET_ABE_cpabe_delete_key (struct GNUNET_ABE_AbeKey *key, | ||
218 | int delete_pub) | ||
219 | { | ||
220 | //Memory management in gabe is buggy | ||
221 | gabe_prv_free (key->prv); | ||
222 | if (GNUNET_YES == delete_pub) | ||
223 | gabe_pub_free (key->pub); | ||
224 | GNUNET_free (key); | ||
225 | } | ||
226 | |||
227 | static ssize_t | ||
228 | write_cpabe (void **result, | ||
229 | uint32_t file_len, | ||
230 | char* cph_buf, | ||
231 | int cph_buf_len, | ||
232 | char* aes_buf, | ||
233 | int aes_buf_len) | ||
234 | { | ||
235 | char *ptr; | ||
236 | uint32_t *len; | ||
237 | |||
238 | *result = GNUNET_malloc (12 + cph_buf_len + aes_buf_len); | ||
239 | ptr = *result; | ||
240 | len = (uint32_t*) ptr; | ||
241 | *len = htonl (file_len); | ||
242 | ptr += 4; | ||
243 | len = (uint32_t*) ptr; | ||
244 | *len = htonl (aes_buf_len); | ||
245 | ptr += 4; | ||
246 | memcpy (ptr, aes_buf, aes_buf_len); | ||
247 | ptr += aes_buf_len; | ||
248 | len = (uint32_t*) ptr; | ||
249 | *len = htonl (cph_buf_len); | ||
250 | ptr += 4; | ||
251 | memcpy (ptr, cph_buf, cph_buf_len); | ||
252 | return 12 + cph_buf_len + aes_buf_len; | ||
253 | } | ||
254 | |||
255 | static ssize_t | ||
256 | read_cpabe (const void *data, | ||
257 | char** cph_buf, | ||
258 | int *cph_buf_len, | ||
259 | char** aes_buf, | ||
260 | int *aes_buf_len) | ||
261 | { | ||
262 | int buf_len; | ||
263 | char *ptr; | ||
264 | uint32_t *len; | ||
265 | |||
266 | ptr = (char*)data; | ||
267 | len = (uint32_t*)ptr; | ||
268 | buf_len = ntohl (*len); | ||
269 | ptr += 4; | ||
270 | len = (uint32_t*)ptr; | ||
271 | *aes_buf_len = ntohl (*len); | ||
272 | ptr += 4; | ||
273 | *aes_buf = GNUNET_malloc (*aes_buf_len); | ||
274 | memcpy(*aes_buf, ptr, *aes_buf_len); | ||
275 | ptr += *aes_buf_len; | ||
276 | len = (uint32_t*)ptr; | ||
277 | *cph_buf_len = ntohl (*len); | ||
278 | ptr += 4; | ||
279 | *cph_buf = GNUNET_malloc (*cph_buf_len); | ||
280 | memcpy(*cph_buf, ptr, *cph_buf_len); | ||
281 | |||
282 | return buf_len; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * @ingroup abe | ||
287 | * Encrypt a block using sessionkey. | ||
288 | * | ||
289 | * @param block the block to encrypt | ||
290 | * @param size the size of the @a block | ||
291 | * @param policy the ABE policy | ||
292 | * @param key the key used to encrypt | ||
293 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
294 | * @return the size of the encrypted block, -1 for errors | ||
295 | */ | ||
296 | ssize_t | ||
297 | GNUNET_ABE_cpabe_encrypt (const void *block, | ||
298 | size_t size, | ||
299 | const char *policy, | ||
300 | const struct GNUNET_ABE_AbeMasterKey *key, | ||
301 | void **result) | ||
302 | { | ||
303 | gabe_cph_t* cph; | ||
304 | char* plt; | ||
305 | char* cph_buf; | ||
306 | char* aes_buf; | ||
307 | element_t m; | ||
308 | int cph_buf_len; | ||
309 | int aes_buf_len; | ||
310 | ssize_t result_len; | ||
311 | |||
312 | if( !(cph = gabe_enc(key->pub, m, (char*)policy)) ) | ||
313 | return GNUNET_SYSERR; | ||
314 | cph_buf_len = gabe_cph_serialize(cph, | ||
315 | &cph_buf); | ||
316 | gabe_cph_free(cph); | ||
317 | GNUNET_free (cph); | ||
318 | plt = GNUNET_memdup (block, size); | ||
319 | aes_buf_len = aes_128_cbc_encrypt(plt, size, m, &aes_buf); | ||
320 | GNUNET_free (plt); | ||
321 | element_clear(m); | ||
322 | result_len = write_cpabe(result, size, cph_buf, cph_buf_len, aes_buf, aes_buf_len); | ||
323 | GNUNET_free(cph_buf); | ||
324 | GNUNET_free(aes_buf); | ||
325 | return result_len; | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * @ingroup abe | ||
330 | * Decrypt a block using the ABE key. | ||
331 | * | ||
332 | * @param block the block to encrypt | ||
333 | * @param size the size of the @a block | ||
334 | * @param key the key used to decrypt | ||
335 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
336 | * @return the size of the encrypted block, -1 for errors | ||
337 | */ | ||
338 | ssize_t | ||
339 | GNUNET_ABE_cpabe_decrypt (const void *block, | ||
340 | size_t size, | ||
341 | const struct GNUNET_ABE_AbeKey *key, | ||
342 | void **result) | ||
343 | { | ||
344 | char* aes_buf; | ||
345 | char* cph_buf; | ||
346 | gabe_cph_t* cph; | ||
347 | element_t m; | ||
348 | int cph_buf_size; | ||
349 | int aes_buf_size; | ||
350 | int plt_len; | ||
351 | |||
352 | read_cpabe(block, &cph_buf, &cph_buf_size, &aes_buf, &aes_buf_size); | ||
353 | cph = gabe_cph_unserialize(key->pub, cph_buf, cph_buf_size); | ||
354 | if( !gabe_dec(key->pub, key->prv, cph, m) ) { | ||
355 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
356 | "%s\n", gabe_error()); | ||
357 | GNUNET_free (aes_buf); | ||
358 | GNUNET_free (cph_buf); | ||
359 | gabe_cph_free(cph); | ||
360 | GNUNET_free (cph); | ||
361 | element_clear (m); | ||
362 | return GNUNET_SYSERR; | ||
363 | } | ||
364 | gabe_cph_free(cph); | ||
365 | GNUNET_free (cph); | ||
366 | plt_len = aes_128_cbc_decrypt(aes_buf, aes_buf_size, m, (char**)result); | ||
367 | GNUNET_free (cph_buf); | ||
368 | GNUNET_free (aes_buf); | ||
369 | element_clear (m); | ||
370 | //freeing is buggy in gabe | ||
371 | //gabe_prv_free (prv); | ||
372 | //gabe_pub_free (pub); | ||
373 | return plt_len; | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * @ingroup abe | ||
378 | * Serialize an ABE key. | ||
379 | * | ||
380 | * @param key the key to serialize | ||
381 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
382 | * @return the size of the encrypted block, -1 for errors | ||
383 | */ | ||
384 | ssize_t | ||
385 | GNUNET_ABE_cpabe_serialize_key (const struct GNUNET_ABE_AbeKey *key, | ||
386 | void **result) | ||
387 | { | ||
388 | ssize_t len; | ||
389 | char *pub; | ||
390 | char *prv; | ||
391 | int pub_len; | ||
392 | int prv_len; | ||
393 | |||
394 | pub_len = gabe_pub_serialize (key->pub, &pub); | ||
395 | prv_len = gabe_prv_serialize (key->prv, &prv); | ||
396 | |||
397 | len = pub_len + prv_len + 12; | ||
398 | write_cpabe (result, len, pub, pub_len, prv, prv_len); | ||
399 | |||
400 | GNUNET_free (pub); | ||
401 | GNUNET_free (prv); | ||
402 | |||
403 | return len; | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * @ingroup abe | ||
408 | * Deserialize a serialized ABE key. | ||
409 | * | ||
410 | * @param data the data to deserialize | ||
411 | * @param len the length of the data. | ||
412 | * @return the ABE key. NULL of unsuccessful | ||
413 | */ | ||
414 | struct GNUNET_ABE_AbeKey* | ||
415 | GNUNET_ABE_cpabe_deserialize_key (const void *data, | ||
416 | size_t len) | ||
417 | { | ||
418 | struct GNUNET_ABE_AbeKey *key; | ||
419 | char *pub; | ||
420 | char *prv; | ||
421 | int prv_len; | ||
422 | int pub_len; | ||
423 | |||
424 | key = GNUNET_new (struct GNUNET_ABE_AbeKey); | ||
425 | read_cpabe (data, | ||
426 | &pub, | ||
427 | &pub_len, | ||
428 | &prv, | ||
429 | &prv_len); | ||
430 | key->pub = gabe_pub_unserialize (pub, pub_len); | ||
431 | key->prv = gabe_prv_unserialize (key->pub, prv, prv_len); | ||
432 | |||
433 | GNUNET_free (pub); | ||
434 | GNUNET_free (prv); | ||
435 | return key; | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * @ingroup abe | ||
440 | * Serialize an ABE master key. | ||
441 | * | ||
442 | * @param key the key to serialize | ||
443 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
444 | * @return the size of the encrypted block, -1 for errors | ||
445 | */ | ||
446 | ssize_t | ||
447 | GNUNET_ABE_cpabe_serialize_master_key (const struct GNUNET_ABE_AbeMasterKey *key, | ||
448 | void **result) | ||
449 | { | ||
450 | ssize_t len; | ||
451 | char *pub; | ||
452 | char *msk; | ||
453 | int pub_len; | ||
454 | int msk_len; | ||
455 | |||
456 | pub_len = gabe_pub_serialize (key->pub, &pub); | ||
457 | msk_len = gabe_msk_serialize (key->msk, &msk); | ||
458 | |||
459 | len = pub_len + msk_len + 12; | ||
460 | write_cpabe (result, len, pub, pub_len, msk, msk_len); | ||
461 | |||
462 | GNUNET_free (pub); | ||
463 | GNUNET_free (msk); | ||
464 | |||
465 | return len; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * @ingroup abe | ||
470 | * Deserialize an ABE master key. | ||
471 | * | ||
472 | * @param data the data to deserialize | ||
473 | * @param len the length of the data. | ||
474 | * @return the ABE key. NULL of unsuccessful | ||
475 | */ | ||
476 | struct GNUNET_ABE_AbeMasterKey* | ||
477 | GNUNET_ABE_cpabe_deserialize_master_key (const void *data, | ||
478 | size_t len) | ||
479 | { | ||
480 | struct GNUNET_ABE_AbeMasterKey *key; | ||
481 | char *msk; | ||
482 | char *pub; | ||
483 | int msk_len; | ||
484 | int pub_len; | ||
485 | |||
486 | key = GNUNET_new (struct GNUNET_ABE_AbeMasterKey); | ||
487 | read_cpabe (data, | ||
488 | &pub, | ||
489 | &pub_len, | ||
490 | &msk, | ||
491 | &msk_len); | ||
492 | key->pub = gabe_pub_unserialize (pub, pub_len); | ||
493 | key->msk = gabe_msk_unserialize (key->pub, msk, msk_len); | ||
494 | |||
495 | GNUNET_free (pub); | ||
496 | GNUNET_free (msk); | ||
497 | |||
498 | return key; | ||
499 | } | ||
diff --git a/src/abe/test_cpabe.c b/src/abe/test_cpabe.c new file mode 100644 index 000000000..9b2062b23 --- /dev/null +++ b/src/abe/test_cpabe.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2002, 2003, 2004, 2006 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | |||
20 | */ | ||
21 | /** | ||
22 | * @author Martin Schanzenbach | ||
23 | * @file util/test_crypto_abe.c | ||
24 | * @brief test for ABE ciphers | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_abe_lib.h" | ||
29 | |||
30 | #define TESTSTRING "Hello World!" | ||
31 | |||
32 | static int | ||
33 | testAbecipher () | ||
34 | { | ||
35 | struct GNUNET_ABE_AbeMasterKey *msk; | ||
36 | struct GNUNET_ABE_AbeKey *key; | ||
37 | char *result; | ||
38 | char **attrs; | ||
39 | int size; | ||
40 | char *res; | ||
41 | msk = GNUNET_ABE_cpabe_create_master_key (); | ||
42 | size = GNUNET_ABE_cpabe_encrypt (TESTSTRING, strlen (TESTSTRING) + 1, | ||
43 | "testattr", //Policy | ||
44 | msk, | ||
45 | (void*)&result); | ||
46 | GNUNET_assert (-1 != size); | ||
47 | attrs = GNUNET_malloc (2 * sizeof (char*)); | ||
48 | attrs[0] = "testattr"; | ||
49 | attrs[1] = NULL; | ||
50 | key = GNUNET_ABE_cpabe_create_key (msk, | ||
51 | attrs); | ||
52 | |||
53 | size = GNUNET_ABE_cpabe_decrypt (result, size, | ||
54 | key, | ||
55 | (void*)&res); | ||
56 | if (strlen (TESTSTRING) + 1 != size) | ||
57 | { | ||
58 | printf ("abeciphertest failed: decryptBlock returned %d\n", size); | ||
59 | return 1; | ||
60 | } | ||
61 | if (0 != strcmp (res, TESTSTRING)) | ||
62 | { | ||
63 | printf ("abeciphertest failed: %s != %s\n", res, TESTSTRING); | ||
64 | return 1; | ||
65 | } | ||
66 | else | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | |||
71 | int | ||
72 | main (int argc, char *argv[]) | ||
73 | { | ||
74 | int failureCount = 0; | ||
75 | |||
76 | GNUNET_log_setup ("test-crypto-abe", "WARNING", NULL); | ||
77 | failureCount += testAbecipher (); | ||
78 | |||
79 | if (failureCount != 0) | ||
80 | { | ||
81 | printf ("%d TESTS FAILED!\n", failureCount); | ||
82 | return -1; | ||
83 | } | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* end of test_crypto_aes.c */ | ||
diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am new file mode 100644 index 000000000..ca11c5e4f --- /dev/null +++ b/src/credential/Makefile.am | |||
@@ -0,0 +1,112 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | EXTRA_DIST = \ | ||
5 | test_credential_defaults.conf \ | ||
6 | test_credential_lookup.conf | ||
7 | |||
8 | |||
9 | if USE_COVERAGE | ||
10 | AM_CFLAGS = --coverage -O0 | ||
11 | endif | ||
12 | |||
13 | pkgcfgdir = $(pkgdatadir)/config.d/ | ||
14 | |||
15 | libexecdir= $(pkglibdir)/libexec/ | ||
16 | |||
17 | plugindir = $(libdir)/gnunet | ||
18 | |||
19 | pkgcfg_DATA = \ | ||
20 | credential.conf | ||
21 | |||
22 | |||
23 | # /usr/lib - compiles a layer which can be used to be communicagte with the service | ||
24 | lib_LTLIBRARIES = \ | ||
25 | libgnunetcredential.la | ||
26 | |||
27 | # /usr/lib/gnunet/libexec - Business logic . Separate process | ||
28 | libexec_PROGRAMS = \ | ||
29 | gnunet-service-credential | ||
30 | |||
31 | bin_PROGRAMS = \ | ||
32 | gnunet-credential | ||
33 | |||
34 | plugin_LTLIBRARIES = \ | ||
35 | libgnunet_plugin_gnsrecord_credential.la | ||
36 | |||
37 | |||
38 | if HAVE_MHD | ||
39 | if HAVE_JSON | ||
40 | plugin_LTLIBRARIES += libgnunet_plugin_rest_credential.la | ||
41 | endif | ||
42 | endif | ||
43 | |||
44 | |||
45 | gnunet_credential_SOURCES = \ | ||
46 | gnunet-credential.c | ||
47 | gnunet_credential_LDADD = \ | ||
48 | libgnunetcredential.la \ | ||
49 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
50 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | ||
51 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
52 | $(GN_LIBINTL) | ||
53 | |||
54 | |||
55 | libgnunet_plugin_gnsrecord_credential_la_SOURCES = \ | ||
56 | plugin_gnsrecord_credential.c | ||
57 | libgnunet_plugin_gnsrecord_credential_la_LIBADD = \ | ||
58 | libgnunetcredential.la \ | ||
59 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
60 | $(LTLIBINTL) | ||
61 | libgnunet_plugin_gnsrecord_credential_la_LDFLAGS = \ | ||
62 | $(GN_PLUGIN_LDFLAGS) | ||
63 | |||
64 | |||
65 | |||
66 | gnunet_service_credential_SOURCES = \ | ||
67 | gnunet-service-credential.c | ||
68 | gnunet_service_credential_LDADD = \ | ||
69 | libgnunetcredential.la \ | ||
70 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
71 | $(top_builddir)/src/gns/libgnunetgns.la \ | ||
72 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | ||
73 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
74 | $(GN_LIBINTL) | ||
75 | |||
76 | |||
77 | libgnunetcredential_la_SOURCES = \ | ||
78 | credential_api.c \ | ||
79 | credential_serialization.c \ | ||
80 | credential_misc.c | ||
81 | libgnunetcredential_la_LIBADD = \ | ||
82 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) | ||
83 | libgnunetcredential_la_LDFLAGS = \ | ||
84 | $(GN_LIB_LDFLAGS) | ||
85 | |||
86 | |||
87 | libgnunet_plugin_rest_credential_la_SOURCES = \ | ||
88 | plugin_rest_credential.c | ||
89 | libgnunet_plugin_rest_credential_la_LIBADD = \ | ||
90 | libgnunetcredential.la \ | ||
91 | $(top_builddir)/src/rest/libgnunetrest.la \ | ||
92 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
93 | $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ | ||
94 | $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \ | ||
95 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ | ||
96 | $(LTLIBINTL) -ljansson -lmicrohttpd | ||
97 | libgnunet_plugin_rest_credential_la_LDFLAGS = \ | ||
98 | $(GN_PLUGIN_LDFLAGS) | ||
99 | |||
100 | |||
101 | check_SCRIPTS = \ | ||
102 | test_credential_issue.sh \ | ||
103 | test_credential_verify_simple.sh \ | ||
104 | test_credential_verify.sh \ | ||
105 | test_credential_verify_and.sh | ||
106 | |||
107 | if ENABLE_TEST_RUN | ||
108 | if HAVE_SQLITE | ||
109 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; | ||
110 | TESTS = $(check_SCRIPTS) | ||
111 | endif | ||
112 | endif | ||
diff --git a/src/credential/credential.conf.in b/src/credential/credential.conf.in new file mode 100644 index 000000000..71f3066ca --- /dev/null +++ b/src/credential/credential.conf.in | |||
@@ -0,0 +1,5 @@ | |||
1 | [credential] | ||
2 | BINARY = gnunet-service-credential | ||
3 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-credential.sock | ||
4 | USER_SERVICE = YES | ||
5 | OPTIONS = -L DEBUG \ No newline at end of file | ||
diff --git a/src/credential/credential.h b/src/credential/credential.h new file mode 100644 index 000000000..66a4636fc --- /dev/null +++ b/src/credential/credential.h | |||
@@ -0,0 +1,221 @@ | |||
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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file credential/credential.h | ||
22 | * @brief IPC messages between CREDENTIAL API and CREDENTIAL service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #ifndef CREDENTIAL_H | ||
26 | #define CREDENTIAL_H | ||
27 | |||
28 | #include "gnunet_credential_service.h" | ||
29 | |||
30 | GNUNET_NETWORK_STRUCT_BEGIN | ||
31 | |||
32 | /** | ||
33 | * Message from client to Credential service to collect credentials. | ||
34 | */ | ||
35 | struct CollectMessage | ||
36 | { | ||
37 | /** | ||
38 | * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY | ||
39 | */ | ||
40 | struct GNUNET_MessageHeader header; | ||
41 | |||
42 | /** | ||
43 | * Subject public key | ||
44 | */ | ||
45 | struct GNUNET_CRYPTO_EcdsaPrivateKey subject_key; | ||
46 | |||
47 | /** | ||
48 | * Trust anchor | ||
49 | */ | ||
50 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
51 | |||
52 | /** | ||
53 | * Length of the issuer attribute | ||
54 | */ | ||
55 | uint16_t issuer_attribute_len; | ||
56 | |||
57 | /** | ||
58 | * Unique identifier for this request (for key collisions). | ||
59 | */ | ||
60 | uint32_t id GNUNET_PACKED; | ||
61 | |||
62 | /* Followed by the zero-terminated attribute */ | ||
63 | |||
64 | }; | ||
65 | |||
66 | |||
67 | /** | ||
68 | * Message from client to Credential service to verify attributes. | ||
69 | */ | ||
70 | struct VerifyMessage | ||
71 | { | ||
72 | /** | ||
73 | * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY | ||
74 | */ | ||
75 | struct GNUNET_MessageHeader header; | ||
76 | |||
77 | /** | ||
78 | * Subject public key | ||
79 | */ | ||
80 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
81 | |||
82 | /** | ||
83 | * Trust anchor | ||
84 | */ | ||
85 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
86 | |||
87 | /** | ||
88 | * Number of credentials | ||
89 | */ | ||
90 | uint32_t c_count; | ||
91 | |||
92 | /** | ||
93 | * Length of the issuer attribute | ||
94 | */ | ||
95 | uint16_t issuer_attribute_len; | ||
96 | |||
97 | /** | ||
98 | * Unique identifier for this request (for key collisions). | ||
99 | */ | ||
100 | uint32_t id GNUNET_PACKED; | ||
101 | |||
102 | /* Followed by the zero-terminated attribute and credentials to look up */ | ||
103 | |||
104 | }; | ||
105 | |||
106 | |||
107 | /** | ||
108 | * Message from CREDENTIAL service to client: new results. | ||
109 | */ | ||
110 | struct DelegationChainResultMessage | ||
111 | { | ||
112 | /** | ||
113 | * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT | ||
114 | */ | ||
115 | struct GNUNET_MessageHeader header; | ||
116 | |||
117 | /** | ||
118 | * Unique identifier for this request (for key collisions). | ||
119 | */ | ||
120 | uint32_t id GNUNET_PACKED; | ||
121 | |||
122 | /** | ||
123 | * Indicates if credential has been found at all | ||
124 | */ | ||
125 | uint32_t cred_found GNUNET_PACKED; | ||
126 | |||
127 | /** | ||
128 | * The number of delegations in the response | ||
129 | */ | ||
130 | uint32_t d_count GNUNET_PACKED; | ||
131 | |||
132 | /** | ||
133 | * The number of credentials in the response | ||
134 | */ | ||
135 | uint32_t c_count GNUNET_PACKED; | ||
136 | |||
137 | /* followed by ad_count GNUNET_CREDENTIAL_RecordData structs*/ | ||
138 | |||
139 | }; | ||
140 | |||
141 | struct DelegationRecordData | ||
142 | { | ||
143 | /** | ||
144 | * Subject key | ||
145 | */ | ||
146 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
147 | |||
148 | /** | ||
149 | * Subject attributes | ||
150 | */ | ||
151 | uint32_t subject_attribute_len GNUNET_PACKED; | ||
152 | }; | ||
153 | |||
154 | |||
155 | struct ChainEntry | ||
156 | { | ||
157 | /** | ||
158 | * Issuer key | ||
159 | */ | ||
160 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
161 | |||
162 | /** | ||
163 | * Subject key | ||
164 | */ | ||
165 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
166 | |||
167 | /** | ||
168 | * Issuer attributes | ||
169 | */ | ||
170 | uint32_t issuer_attribute_len GNUNET_PACKED; | ||
171 | |||
172 | /** | ||
173 | * Subject attributes | ||
174 | */ | ||
175 | uint32_t subject_attribute_len GNUNET_PACKED; | ||
176 | }; | ||
177 | |||
178 | |||
179 | struct CredentialEntry | ||
180 | { | ||
181 | |||
182 | /** | ||
183 | * The signature for this credential by the issuer | ||
184 | */ | ||
185 | struct GNUNET_CRYPTO_EcdsaSignature signature; | ||
186 | |||
187 | /** | ||
188 | * Signature meta | ||
189 | */ | ||
190 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
191 | |||
192 | /** | ||
193 | * Public key of the issuer | ||
194 | */ | ||
195 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
196 | |||
197 | /** | ||
198 | * Public key of the subject this credential was issued to | ||
199 | */ | ||
200 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
201 | |||
202 | /** | ||
203 | * Expiration time of this credential | ||
204 | */ | ||
205 | uint64_t expiration GNUNET_PACKED; | ||
206 | |||
207 | /** | ||
208 | * Issuer attribute length | ||
209 | */ | ||
210 | uint32_t issuer_attribute_len; | ||
211 | |||
212 | /** | ||
213 | * Followed by the attribute string | ||
214 | */ | ||
215 | }; | ||
216 | |||
217 | |||
218 | GNUNET_NETWORK_STRUCT_END | ||
219 | |||
220 | #endif | ||
221 | |||
diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c new file mode 100644 index 000000000..677cb9ad4 --- /dev/null +++ b/src/credential/credential_api.c | |||
@@ -0,0 +1,511 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file credential/credential_api.c | ||
22 | * @brief library to access the CREDENTIAL service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_constants.h" | ||
28 | #include "gnunet_arm_service.h" | ||
29 | #include "gnunet_hello_lib.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | #include "gnunet_signatures.h" | ||
32 | #include "credential.h" | ||
33 | #include "credential_serialization.h" | ||
34 | #include "gnunet_credential_service.h" | ||
35 | #include "gnunet_identity_service.h" | ||
36 | |||
37 | |||
38 | #define LOG(kind,...) GNUNET_log_from (kind, "credential-api",__VA_ARGS__) | ||
39 | |||
40 | /** | ||
41 | * Handle to a verify request | ||
42 | */ | ||
43 | struct GNUNET_CREDENTIAL_Request | ||
44 | { | ||
45 | |||
46 | /** | ||
47 | * DLL | ||
48 | */ | ||
49 | struct GNUNET_CREDENTIAL_Request *next; | ||
50 | |||
51 | /** | ||
52 | * DLL | ||
53 | */ | ||
54 | struct GNUNET_CREDENTIAL_Request *prev; | ||
55 | |||
56 | /** | ||
57 | * handle to credential service | ||
58 | */ | ||
59 | struct GNUNET_CREDENTIAL_Handle *credential_handle; | ||
60 | |||
61 | /** | ||
62 | * processor to call on verify result | ||
63 | */ | ||
64 | GNUNET_CREDENTIAL_CredentialResultProcessor verify_proc; | ||
65 | |||
66 | /** | ||
67 | * @e verify_proc closure | ||
68 | */ | ||
69 | void *proc_cls; | ||
70 | |||
71 | /** | ||
72 | * Envelope with the message for this queue entry. | ||
73 | */ | ||
74 | struct GNUNET_MQ_Envelope *env; | ||
75 | |||
76 | /** | ||
77 | * request id | ||
78 | */ | ||
79 | uint32_t r_id; | ||
80 | |||
81 | }; | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Connection to the CREDENTIAL service. | ||
86 | */ | ||
87 | struct GNUNET_CREDENTIAL_Handle | ||
88 | { | ||
89 | |||
90 | /** | ||
91 | * Configuration to use. | ||
92 | */ | ||
93 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
94 | |||
95 | /** | ||
96 | * Connection to service (if available). | ||
97 | */ | ||
98 | struct GNUNET_MQ_Handle *mq; | ||
99 | |||
100 | /** | ||
101 | * Head of linked list of active verify requests. | ||
102 | */ | ||
103 | struct GNUNET_CREDENTIAL_Request *request_head; | ||
104 | |||
105 | /** | ||
106 | * Tail of linked list of active verify requests. | ||
107 | */ | ||
108 | struct GNUNET_CREDENTIAL_Request *request_tail; | ||
109 | |||
110 | /** | ||
111 | * Reconnect task | ||
112 | */ | ||
113 | struct GNUNET_SCHEDULER_Task *reconnect_task; | ||
114 | |||
115 | /** | ||
116 | * How long do we wait until we try to reconnect? | ||
117 | */ | ||
118 | struct GNUNET_TIME_Relative reconnect_backoff; | ||
119 | |||
120 | /** | ||
121 | * Request Id generator. Incremented by one for each request. | ||
122 | */ | ||
123 | uint32_t r_id_gen; | ||
124 | |||
125 | }; | ||
126 | |||
127 | |||
128 | /** | ||
129 | * Reconnect to CREDENTIAL service. | ||
130 | * | ||
131 | * @param handle the handle to the CREDENTIAL service | ||
132 | */ | ||
133 | static void | ||
134 | reconnect (struct GNUNET_CREDENTIAL_Handle *handle); | ||
135 | |||
136 | |||
137 | /** | ||
138 | * Reconnect to CREDENTIAL | ||
139 | * | ||
140 | * @param cls the handle | ||
141 | */ | ||
142 | static void | ||
143 | reconnect_task (void *cls) | ||
144 | { | ||
145 | struct GNUNET_CREDENTIAL_Handle *handle = cls; | ||
146 | |||
147 | handle->reconnect_task = NULL; | ||
148 | reconnect (handle); | ||
149 | } | ||
150 | |||
151 | |||
152 | /** | ||
153 | * Disconnect from service and then reconnect. | ||
154 | * | ||
155 | * @param handle our handle | ||
156 | */ | ||
157 | static void | ||
158 | force_reconnect (struct GNUNET_CREDENTIAL_Handle *handle) | ||
159 | { | ||
160 | GNUNET_MQ_destroy (handle->mq); | ||
161 | handle->mq = NULL; | ||
162 | handle->reconnect_backoff | ||
163 | = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); | ||
164 | handle->reconnect_task | ||
165 | = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, | ||
166 | &reconnect_task, | ||
167 | handle); | ||
168 | } | ||
169 | |||
170 | |||
171 | /** | ||
172 | * Generic error handler, called with the appropriate error code and | ||
173 | * the same closure specified at the creation of the message queue. | ||
174 | * Not every message queue implementation supports an error handler. | ||
175 | * | ||
176 | * @param cls closure with the `struct GNUNET_CREDENTIAL_Handle *` | ||
177 | * @param error error code | ||
178 | */ | ||
179 | static void | ||
180 | mq_error_handler (void *cls, | ||
181 | enum GNUNET_MQ_Error error) | ||
182 | { | ||
183 | struct GNUNET_CREDENTIAL_Handle *handle = cls; | ||
184 | |||
185 | force_reconnect (handle); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * Check validity of message received from the CREDENTIAL service | ||
190 | * | ||
191 | * @param cls the `struct GNUNET_CREDENTIAL_Handle *` | ||
192 | * @param vr_msg the incoming message | ||
193 | */ | ||
194 | static int | ||
195 | check_result (void *cls, | ||
196 | const struct DelegationChainResultMessage *vr_msg) | ||
197 | { | ||
198 | //TODO | ||
199 | return GNUNET_OK; | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
204 | * Handler for messages received from the CREDENTIAL service | ||
205 | * | ||
206 | * @param cls the `struct GNUNET_CREDENTIAL_Handle *` | ||
207 | * @param vr_msg the incoming message | ||
208 | */ | ||
209 | static void | ||
210 | handle_result (void *cls, | ||
211 | const struct DelegationChainResultMessage *vr_msg) | ||
212 | { | ||
213 | struct GNUNET_CREDENTIAL_Handle *handle = cls; | ||
214 | uint32_t r_id = ntohl (vr_msg->id); | ||
215 | struct GNUNET_CREDENTIAL_Request *vr; | ||
216 | size_t mlen = ntohs (vr_msg->header.size) - sizeof (*vr_msg); | ||
217 | uint32_t d_count = ntohl (vr_msg->d_count); | ||
218 | uint32_t c_count = ntohl (vr_msg->c_count); | ||
219 | struct GNUNET_CREDENTIAL_Delegation d_chain[d_count]; | ||
220 | struct GNUNET_CREDENTIAL_Credential creds[c_count]; | ||
221 | GNUNET_CREDENTIAL_CredentialResultProcessor proc; | ||
222 | void *proc_cls; | ||
223 | |||
224 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
225 | "Received verify reply from CREDENTIAL service\n"); | ||
226 | for (vr = handle->request_head; NULL != vr; vr = vr->next) | ||
227 | if (vr->r_id == r_id) | ||
228 | break; | ||
229 | if (NULL == vr) | ||
230 | return; | ||
231 | proc = vr->verify_proc; | ||
232 | proc_cls = vr->proc_cls; | ||
233 | GNUNET_CONTAINER_DLL_remove (handle->request_head, | ||
234 | handle->request_tail, | ||
235 | vr); | ||
236 | GNUNET_MQ_discard (vr->env); | ||
237 | GNUNET_free (vr); | ||
238 | GNUNET_assert (GNUNET_OK == | ||
239 | GNUNET_CREDENTIAL_delegation_chain_deserialize (mlen, | ||
240 | (const char*) &vr_msg[1], | ||
241 | d_count, | ||
242 | d_chain, | ||
243 | c_count, | ||
244 | creds)); | ||
245 | if (GNUNET_NO == ntohl (vr_msg->cred_found)) | ||
246 | { | ||
247 | proc (proc_cls, | ||
248 | 0, | ||
249 | NULL, | ||
250 | 0, | ||
251 | NULL); // TODO | ||
252 | } else { | ||
253 | proc (proc_cls, | ||
254 | d_count, | ||
255 | d_chain, | ||
256 | c_count, | ||
257 | creds); | ||
258 | } | ||
259 | } | ||
260 | |||
261 | |||
262 | /** | ||
263 | * Reconnect to CREDENTIAL service. | ||
264 | * | ||
265 | * @param handle the handle to the CREDENTIAL service | ||
266 | */ | ||
267 | static void | ||
268 | reconnect (struct GNUNET_CREDENTIAL_Handle *handle) | ||
269 | { | ||
270 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
271 | GNUNET_MQ_hd_var_size (result, | ||
272 | GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT, | ||
273 | struct DelegationChainResultMessage, | ||
274 | handle), | ||
275 | GNUNET_MQ_hd_var_size (result, | ||
276 | GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT_RESULT, | ||
277 | struct DelegationChainResultMessage, | ||
278 | handle), | ||
279 | GNUNET_MQ_handler_end () | ||
280 | }; | ||
281 | struct GNUNET_CREDENTIAL_Request *vr; | ||
282 | |||
283 | GNUNET_assert (NULL == handle->mq); | ||
284 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
285 | "Trying to connect to CREDENTIAL\n"); | ||
286 | handle->mq = GNUNET_CLIENT_connect (handle->cfg, | ||
287 | "credential", | ||
288 | handlers, | ||
289 | &mq_error_handler, | ||
290 | handle); | ||
291 | if (NULL == handle->mq) | ||
292 | return; | ||
293 | for (vr = handle->request_head; NULL != vr; vr = vr->next) | ||
294 | GNUNET_MQ_send_copy (handle->mq, | ||
295 | vr->env); | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | ||
300 | * Initialize the connection with the CREDENTIAL service. | ||
301 | * | ||
302 | * @param cfg configuration to use | ||
303 | * @return handle to the CREDENTIAL service, or NULL on error | ||
304 | */ | ||
305 | struct GNUNET_CREDENTIAL_Handle * | ||
306 | GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
307 | { | ||
308 | struct GNUNET_CREDENTIAL_Handle *handle; | ||
309 | |||
310 | handle = GNUNET_new (struct GNUNET_CREDENTIAL_Handle); | ||
311 | handle->cfg = cfg; | ||
312 | reconnect (handle); | ||
313 | if (NULL == handle->mq) | ||
314 | { | ||
315 | GNUNET_free (handle); | ||
316 | return NULL; | ||
317 | } | ||
318 | return handle; | ||
319 | } | ||
320 | |||
321 | |||
322 | /** | ||
323 | * Shutdown connection with the CREDENTIAL service. | ||
324 | * | ||
325 | * @param handle handle of the CREDENTIAL connection to stop | ||
326 | */ | ||
327 | void | ||
328 | GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle) | ||
329 | { | ||
330 | if (NULL != handle->mq) | ||
331 | { | ||
332 | GNUNET_MQ_destroy (handle->mq); | ||
333 | handle->mq = NULL; | ||
334 | } | ||
335 | if (NULL != handle->reconnect_task) | ||
336 | { | ||
337 | GNUNET_SCHEDULER_cancel (handle->reconnect_task); | ||
338 | handle->reconnect_task = NULL; | ||
339 | } | ||
340 | GNUNET_assert (NULL == handle->request_head); | ||
341 | GNUNET_free (handle); | ||
342 | } | ||
343 | |||
344 | |||
345 | /** | ||
346 | * Cancel pending verify request | ||
347 | * | ||
348 | * @param lr the verify request to cancel | ||
349 | */ | ||
350 | void | ||
351 | GNUNET_CREDENTIAL_request_cancel (struct GNUNET_CREDENTIAL_Request *lr) | ||
352 | { | ||
353 | struct GNUNET_CREDENTIAL_Handle *handle = lr->credential_handle; | ||
354 | |||
355 | GNUNET_CONTAINER_DLL_remove (handle->request_head, | ||
356 | handle->request_tail, | ||
357 | lr); | ||
358 | GNUNET_MQ_discard (lr->env); | ||
359 | GNUNET_free (lr); | ||
360 | } | ||
361 | |||
362 | |||
363 | /** | ||
364 | * Performs attribute collection. | ||
365 | * Collects all credentials of subject to fulfill the | ||
366 | * attribute, if possible | ||
367 | * | ||
368 | * @param handle handle to the Credential service | ||
369 | * @param issuer_key the issuer public key | ||
370 | * @param issuer_attribute the issuer attribute | ||
371 | * @param subject_key the subject public key | ||
372 | * @param proc function to call on result | ||
373 | * @param proc_cls closure for processor | ||
374 | * @return handle to the queued request | ||
375 | */ | ||
376 | struct GNUNET_CREDENTIAL_Request* | ||
377 | GNUNET_CREDENTIAL_collect (struct GNUNET_CREDENTIAL_Handle *handle, | ||
378 | const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, | ||
379 | const char *issuer_attribute, | ||
380 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, | ||
381 | GNUNET_CREDENTIAL_CredentialResultProcessor proc, | ||
382 | void *proc_cls) | ||
383 | { | ||
384 | /* IPC to shorten credential names, return shorten_handle */ | ||
385 | struct CollectMessage *c_msg; | ||
386 | struct GNUNET_CREDENTIAL_Request *vr; | ||
387 | size_t nlen; | ||
388 | |||
389 | if (NULL == issuer_attribute) | ||
390 | { | ||
391 | GNUNET_break (0); | ||
392 | return NULL; | ||
393 | } | ||
394 | |||
395 | //DEBUG LOG | ||
396 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
397 | "Trying to collect `%s' in CREDENTIAL\n", | ||
398 | issuer_attribute); | ||
399 | nlen = strlen (issuer_attribute) + 1; | ||
400 | if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr)) | ||
401 | { | ||
402 | GNUNET_break (0); | ||
403 | return NULL; | ||
404 | } | ||
405 | vr = GNUNET_new (struct GNUNET_CREDENTIAL_Request); | ||
406 | vr->credential_handle = handle; | ||
407 | vr->verify_proc = proc; | ||
408 | vr->proc_cls = proc_cls; | ||
409 | vr->r_id = handle->r_id_gen++; | ||
410 | vr->env = GNUNET_MQ_msg_extra (c_msg, | ||
411 | nlen, | ||
412 | GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT); | ||
413 | c_msg->id = htonl (vr->r_id); | ||
414 | c_msg->subject_key = *subject_key; | ||
415 | c_msg->issuer_key = *issuer_key; | ||
416 | c_msg->issuer_attribute_len = htons(strlen(issuer_attribute)); | ||
417 | GNUNET_memcpy (&c_msg[1], | ||
418 | issuer_attribute, | ||
419 | strlen (issuer_attribute)); | ||
420 | GNUNET_CONTAINER_DLL_insert (handle->request_head, | ||
421 | handle->request_tail, | ||
422 | vr); | ||
423 | if (NULL != handle->mq) | ||
424 | GNUNET_MQ_send_copy (handle->mq, | ||
425 | vr->env); | ||
426 | return vr; | ||
427 | } | ||
428 | /** | ||
429 | * Performs attribute verification. | ||
430 | * Checks if there is a delegation chain from | ||
431 | * attribute ``issuer_attribute'' issued by the issuer | ||
432 | * with public key ``issuer_key'' maps to the attribute | ||
433 | * ``subject_attribute'' claimed by the subject with key | ||
434 | * ``subject_key'' | ||
435 | * | ||
436 | * @param handle handle to the Credential service | ||
437 | * @param issuer_key the issuer public key | ||
438 | * @param issuer_attribute the issuer attribute | ||
439 | * @param subject_key the subject public key | ||
440 | * @param credential_count number of credentials provided | ||
441 | * @param credentials subject credentials | ||
442 | * @param proc function to call on result | ||
443 | * @param proc_cls closure for processor | ||
444 | * @return handle to the queued request | ||
445 | */ | ||
446 | struct GNUNET_CREDENTIAL_Request* | ||
447 | GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, | ||
448 | const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, | ||
449 | const char *issuer_attribute, | ||
450 | const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, | ||
451 | uint32_t credential_count, | ||
452 | const struct GNUNET_CREDENTIAL_Credential *credentials, | ||
453 | GNUNET_CREDENTIAL_CredentialResultProcessor proc, | ||
454 | void *proc_cls) | ||
455 | { | ||
456 | /* IPC to shorten credential names, return shorten_handle */ | ||
457 | struct VerifyMessage *v_msg; | ||
458 | struct GNUNET_CREDENTIAL_Request *vr; | ||
459 | size_t nlen; | ||
460 | size_t clen; | ||
461 | |||
462 | if (NULL == issuer_attribute || NULL == credentials) | ||
463 | { | ||
464 | GNUNET_break (0); | ||
465 | return NULL; | ||
466 | } | ||
467 | |||
468 | clen = GNUNET_CREDENTIAL_credentials_get_size (credential_count, | ||
469 | credentials); | ||
470 | |||
471 | //DEBUG LOG | ||
472 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
473 | "Trying to verify `%s' in CREDENTIAL\n", | ||
474 | issuer_attribute); | ||
475 | nlen = strlen (issuer_attribute) + 1 + clen; | ||
476 | if (nlen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (*vr)) | ||
477 | { | ||
478 | GNUNET_break (0); | ||
479 | return NULL; | ||
480 | } | ||
481 | vr = GNUNET_new (struct GNUNET_CREDENTIAL_Request); | ||
482 | vr->credential_handle = handle; | ||
483 | vr->verify_proc = proc; | ||
484 | vr->proc_cls = proc_cls; | ||
485 | vr->r_id = handle->r_id_gen++; | ||
486 | vr->env = GNUNET_MQ_msg_extra (v_msg, | ||
487 | nlen, | ||
488 | GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY); | ||
489 | v_msg->id = htonl (vr->r_id); | ||
490 | v_msg->subject_key = *subject_key; | ||
491 | v_msg->c_count = htonl(credential_count); | ||
492 | v_msg->issuer_key = *issuer_key; | ||
493 | v_msg->issuer_attribute_len = htons(strlen(issuer_attribute)); | ||
494 | GNUNET_memcpy (&v_msg[1], | ||
495 | issuer_attribute, | ||
496 | strlen (issuer_attribute)); | ||
497 | GNUNET_CREDENTIAL_credentials_serialize (credential_count, | ||
498 | credentials, | ||
499 | clen, | ||
500 | ((char*)&v_msg[1]) | ||
501 | + strlen (issuer_attribute) + 1); | ||
502 | GNUNET_CONTAINER_DLL_insert (handle->request_head, | ||
503 | handle->request_tail, | ||
504 | vr); | ||
505 | if (NULL != handle->mq) | ||
506 | GNUNET_MQ_send_copy (handle->mq, | ||
507 | vr->env); | ||
508 | return vr; | ||
509 | } | ||
510 | |||
511 | /* end of credential_api.c */ | ||
diff --git a/src/credential/credential_misc.c b/src/credential/credential_misc.c new file mode 100644 index 000000000..c94c33919 --- /dev/null +++ b/src/credential/credential_misc.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | |||
22 | /** | ||
23 | * @file credential/credential_misc.c | ||
24 | * @brief Misc API for credentials | ||
25 | * | ||
26 | * @author Martin Schanzenbach | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_constants.h" | ||
31 | #include "gnunet_credential_service.h" | ||
32 | #include "gnunet_signatures.h" | ||
33 | #include "credential.h" | ||
34 | #include <inttypes.h> | ||
35 | |||
36 | char* | ||
37 | GNUNET_CREDENTIAL_credential_to_string (const struct GNUNET_CREDENTIAL_Credential *cred) | ||
38 | { | ||
39 | char *cred_str; | ||
40 | char *subject_pkey; | ||
41 | char *issuer_pkey; | ||
42 | char *signature; | ||
43 | |||
44 | |||
45 | subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); | ||
46 | issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); | ||
47 | GNUNET_STRINGS_base64_encode ((char*)&cred->signature, | ||
48 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature), | ||
49 | &signature); | ||
50 | GNUNET_asprintf (&cred_str, | ||
51 | "%s.%s -> %s | %s | %"SCNu64, | ||
52 | issuer_pkey, | ||
53 | cred->issuer_attribute, | ||
54 | subject_pkey, | ||
55 | signature, | ||
56 | cred->expiration.abs_value_us); | ||
57 | GNUNET_free (subject_pkey); | ||
58 | GNUNET_free (issuer_pkey); | ||
59 | GNUNET_free (signature); | ||
60 | return cred_str; | ||
61 | } | ||
62 | |||
63 | struct GNUNET_CREDENTIAL_Credential* | ||
64 | GNUNET_CREDENTIAL_credential_from_string (const char* s) | ||
65 | { | ||
66 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
67 | size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | ||
68 | if (enclen % 5 > 0) | ||
69 | enclen += 5 - enclen % 5; | ||
70 | enclen /= 5; /* 260/5 = 52 */ | ||
71 | char subject_pkey[enclen + 1]; | ||
72 | char issuer_pkey[enclen + 1]; | ||
73 | char name[253 + 1]; | ||
74 | char signature[256]; //TODO max payload size | ||
75 | |||
76 | struct GNUNET_CRYPTO_EcdsaSignature *sig; | ||
77 | struct GNUNET_TIME_Absolute etime_abs; | ||
78 | |||
79 | if (5 != SSCANF (s, | ||
80 | "%52s.%253s -> %52s | %s | %"SCNu64, | ||
81 | issuer_pkey, | ||
82 | name, | ||
83 | subject_pkey, | ||
84 | signature, | ||
85 | &etime_abs.abs_value_us)) | ||
86 | { | ||
87 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
88 | _("Unable to parse CRED record string `%s'\n"), | ||
89 | s); | ||
90 | return NULL; | ||
91 | } | ||
92 | cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + strlen (name) + 1); | ||
93 | GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, | ||
94 | strlen (subject_pkey), | ||
95 | &cred->subject_key); | ||
96 | GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, | ||
97 | strlen (issuer_pkey), | ||
98 | &cred->issuer_key); | ||
99 | GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature, | ||
100 | strlen (signature), | ||
101 | (char**)&sig)); | ||
102 | cred->signature = *sig; | ||
103 | cred->expiration = etime_abs; | ||
104 | GNUNET_free (sig); | ||
105 | GNUNET_memcpy (&cred[1], | ||
106 | name, | ||
107 | strlen (name)+1); | ||
108 | cred->issuer_attribute_len = strlen ((char*)&cred[1]); | ||
109 | cred->issuer_attribute = (char*)&cred[1]; | ||
110 | return cred; | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Issue an attribute to a subject | ||
115 | * | ||
116 | * @param issuer the ego that should be used to issue the attribute | ||
117 | * @param subject the subject of the attribute | ||
118 | * @param attribute the name of the attribute | ||
119 | * @return handle to the queued request | ||
120 | */ | ||
121 | struct GNUNET_CREDENTIAL_Credential * | ||
122 | GNUNET_CREDENTIAL_credential_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | ||
123 | struct GNUNET_CRYPTO_EcdsaPublicKey *subject, | ||
124 | const char *attribute, | ||
125 | struct GNUNET_TIME_Absolute *expiration) | ||
126 | { | ||
127 | struct CredentialEntry *crd; | ||
128 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
129 | size_t size; | ||
130 | |||
131 | size = sizeof (struct CredentialEntry) + strlen (attribute) + 1; | ||
132 | crd = GNUNET_malloc (size); | ||
133 | cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + strlen (attribute) + 1); | ||
134 | crd->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | ||
135 | |||
136 | crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); | ||
137 | GNUNET_CRYPTO_ecdsa_key_get_public (issuer, | ||
138 | &crd->issuer_key); | ||
139 | crd->subject_key = *subject; | ||
140 | crd->expiration = GNUNET_htonll (expiration->abs_value_us); | ||
141 | crd->issuer_attribute_len = htonl (strlen (attribute)+1); | ||
142 | GNUNET_memcpy ((char*)&crd[1], | ||
143 | attribute, | ||
144 | strlen (attribute)+1); | ||
145 | if (GNUNET_OK != | ||
146 | GNUNET_CRYPTO_ecdsa_sign (issuer, | ||
147 | &crd->purpose, | ||
148 | &crd->signature)) | ||
149 | { | ||
150 | GNUNET_break (0); | ||
151 | GNUNET_free (crd); | ||
152 | return NULL; | ||
153 | } | ||
154 | cred->signature = crd->signature; | ||
155 | cred->expiration = *expiration; | ||
156 | GNUNET_CRYPTO_ecdsa_key_get_public (issuer, | ||
157 | &cred->issuer_key); | ||
158 | |||
159 | cred->subject_key = *subject; | ||
160 | GNUNET_memcpy (&cred[1], | ||
161 | attribute, | ||
162 | strlen (attribute)+1); | ||
163 | cred->issuer_attribute = (char*)&cred[1]; | ||
164 | GNUNET_free (crd); | ||
165 | return cred; | ||
166 | } | ||
167 | |||
168 | |||
diff --git a/src/credential/credential_misc.h b/src/credential/credential_misc.h new file mode 100644 index 000000000..c3aa8c214 --- /dev/null +++ b/src/credential/credential_misc.h | |||
@@ -0,0 +1,35 @@ | |||
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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file credential/credential_misc.h | ||
22 | * @brief Credential helper functions | ||
23 | */ | ||
24 | #ifndef CREDENTIAL_MISC_H | ||
25 | #define CREDENTIAL_MISC_H | ||
26 | |||
27 | |||
28 | |||
29 | char* | ||
30 | GNUNET_CREDENTIAL_credential_to_string (const struct GNUNET_CREDENTIAL_Credential *cred); | ||
31 | |||
32 | struct GNUNET_CREDENTIAL_Credential* | ||
33 | GNUNET_CREDENTIAL_credential_from_string (const char* str); | ||
34 | |||
35 | #endif | ||
diff --git a/src/credential/credential_serialization.c b/src/credential/credential_serialization.c new file mode 100644 index 000000000..1d23bb08c --- /dev/null +++ b/src/credential/credential_serialization.c | |||
@@ -0,0 +1,460 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | |||
22 | /** | ||
23 | * @file credential/credential_serialization.c | ||
24 | * @brief API to serialize and deserialize delegation chains | ||
25 | * and credentials | ||
26 | * @author Martin Schanzenbach | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_constants.h" | ||
31 | #include "gnunet_credential_service.h" | ||
32 | #include "gnunet_signatures.h" | ||
33 | #include "credential.h" | ||
34 | |||
35 | /** | ||
36 | * Calculate how many bytes we will need to serialize | ||
37 | * the given delegation chain | ||
38 | * | ||
39 | * @param ds_count number of delegation chain entries | ||
40 | * @param dsr array of #GNUNET_CREDENTIAL_DelegationSet | ||
41 | * @return the required size to serialize | ||
42 | */ | ||
43 | size_t | ||
44 | GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count, | ||
45 | const struct GNUNET_CREDENTIAL_DelegationSet *dsr) | ||
46 | { | ||
47 | unsigned int i; | ||
48 | size_t ret; | ||
49 | |||
50 | ret = sizeof (struct DelegationRecordData) * (ds_count); | ||
51 | |||
52 | for (i=0; i<ds_count;i++) | ||
53 | { | ||
54 | GNUNET_assert ((ret + dsr[i].subject_attribute_len) >= ret); | ||
55 | ret += dsr[i].subject_attribute_len; | ||
56 | } | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * Serizalize the given delegation chain entries and credential | ||
62 | * | ||
63 | * @param d_count number of delegation chain entries | ||
64 | * @param dsr array of #GNUNET_CREDENTIAL_DelegationSet | ||
65 | * @param dest_size size of the destination | ||
66 | * @param dest where to store the result | ||
67 | * @return the size of the data, -1 on failure | ||
68 | */ | ||
69 | ssize_t | ||
70 | GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count, | ||
71 | const struct GNUNET_CREDENTIAL_DelegationSet *dsr, | ||
72 | size_t dest_size, | ||
73 | char *dest) | ||
74 | { | ||
75 | struct DelegationRecordData rec; | ||
76 | unsigned int i; | ||
77 | size_t off; | ||
78 | |||
79 | off = 0; | ||
80 | for (i=0;i<d_count;i++) | ||
81 | { | ||
82 | rec.subject_attribute_len = htonl ((uint32_t) dsr[i].subject_attribute_len); | ||
83 | rec.subject_key = dsr[i].subject_key; | ||
84 | if (off + sizeof (rec) > dest_size) | ||
85 | return -1; | ||
86 | GNUNET_memcpy (&dest[off], | ||
87 | &rec, | ||
88 | sizeof (rec)); | ||
89 | off += sizeof (rec); | ||
90 | if (0 == dsr[i].subject_attribute_len) | ||
91 | continue; | ||
92 | if (off + dsr[i].subject_attribute_len > dest_size) | ||
93 | return -1; | ||
94 | GNUNET_memcpy (&dest[off], | ||
95 | dsr[i].subject_attribute, | ||
96 | dsr[i].subject_attribute_len); | ||
97 | off += dsr[i].subject_attribute_len; | ||
98 | } | ||
99 | return off; | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Deserialize the given destination | ||
105 | * | ||
106 | * @param len size of the serialized delegation chain and cred | ||
107 | * @param src the serialized data | ||
108 | * @param d_count the number of delegation chain entries | ||
109 | * @param dsr where to put the delegation chain entries | ||
110 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
111 | */ | ||
112 | int | ||
113 | GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len, | ||
114 | const char *src, | ||
115 | unsigned int d_count, | ||
116 | struct GNUNET_CREDENTIAL_DelegationSet *dsr) | ||
117 | { | ||
118 | struct DelegationRecordData rec; | ||
119 | unsigned int i; | ||
120 | size_t off; | ||
121 | |||
122 | off = 0; | ||
123 | for (i=0;i<d_count;i++) | ||
124 | { | ||
125 | if (off + sizeof (rec) > len) | ||
126 | return GNUNET_SYSERR; | ||
127 | GNUNET_memcpy (&rec, &src[off], sizeof (rec)); | ||
128 | dsr[i].subject_key = rec.subject_key; | ||
129 | off += sizeof (rec); | ||
130 | dsr[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len); | ||
131 | if (off + dsr[i].subject_attribute_len > len) | ||
132 | return GNUNET_SYSERR; | ||
133 | dsr[i].subject_attribute = (char*)&src[off]; | ||
134 | off += dsr[i].subject_attribute_len; | ||
135 | } | ||
136 | return GNUNET_OK; | ||
137 | } | ||
138 | |||
139 | |||
140 | /** | ||
141 | * Calculate how many bytes we will need to serialize | ||
142 | * the credentials | ||
143 | * | ||
144 | * @param c_count number of credential entries | ||
145 | * @param cd a #GNUNET_CREDENTIAL_Credential | ||
146 | * @return the required size to serialize | ||
147 | */ | ||
148 | size_t | ||
149 | GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count, | ||
150 | const struct GNUNET_CREDENTIAL_Credential *cd) | ||
151 | { | ||
152 | unsigned int i; | ||
153 | size_t ret; | ||
154 | |||
155 | ret = sizeof (struct CredentialEntry) * (c_count); | ||
156 | |||
157 | for (i=0; i<c_count;i++) | ||
158 | { | ||
159 | GNUNET_assert ((ret + cd[i].issuer_attribute_len) >= ret); | ||
160 | ret += cd[i].issuer_attribute_len; | ||
161 | } | ||
162 | return ret; | ||
163 | } | ||
164 | /** | ||
165 | * Serizalize the given credentials | ||
166 | * | ||
167 | * @param c_count number of credential entries | ||
168 | * @param cd a #GNUNET_CREDENTIAL_Credential | ||
169 | * @param dest_size size of the destination | ||
170 | * @param dest where to store the result | ||
171 | * @return the size of the data, -1 on failure | ||
172 | */ | ||
173 | ssize_t | ||
174 | GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count, | ||
175 | const struct GNUNET_CREDENTIAL_Credential *cd, | ||
176 | size_t dest_size, | ||
177 | char *dest) | ||
178 | { | ||
179 | struct CredentialEntry c_rec; | ||
180 | unsigned int i; | ||
181 | size_t off; | ||
182 | |||
183 | off = 0; | ||
184 | for (i=0;i<c_count;i++) | ||
185 | { | ||
186 | c_rec.issuer_attribute_len = htonl ((uint32_t) cd[i].issuer_attribute_len); | ||
187 | c_rec.issuer_key = cd[i].issuer_key; | ||
188 | c_rec.subject_key = cd[i].subject_key; | ||
189 | c_rec.signature = cd[i].signature; | ||
190 | c_rec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); | ||
191 | c_rec.purpose.size = htonl ((sizeof (struct CredentialEntry) + cd[i].issuer_attribute_len) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | ||
192 | c_rec.expiration = GNUNET_htonll (cd[i].expiration.abs_value_us); | ||
193 | if (off + sizeof (c_rec) > dest_size) | ||
194 | return -1; | ||
195 | GNUNET_memcpy (&dest[off], | ||
196 | &c_rec, | ||
197 | sizeof (c_rec)); | ||
198 | off += sizeof (c_rec); | ||
199 | if (off + cd[i].issuer_attribute_len > dest_size) | ||
200 | return -1; | ||
201 | GNUNET_memcpy (&dest[off], | ||
202 | cd[i].issuer_attribute, | ||
203 | cd[i].issuer_attribute_len); | ||
204 | off += cd[i].issuer_attribute_len; | ||
205 | } | ||
206 | |||
207 | return off; | ||
208 | } | ||
209 | |||
210 | |||
211 | |||
212 | /** | ||
213 | * Deserialize the given destination | ||
214 | * | ||
215 | * @param len size of the serialized creds | ||
216 | * @param src the serialized data | ||
217 | * @param c_count the number of credential entries | ||
218 | * @param cd where to put the credential data | ||
219 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
220 | */ | ||
221 | int | ||
222 | GNUNET_CREDENTIAL_credentials_deserialize (size_t len, | ||
223 | const char *src, | ||
224 | unsigned int c_count, | ||
225 | struct GNUNET_CREDENTIAL_Credential *cd) | ||
226 | { | ||
227 | struct CredentialEntry c_rec; | ||
228 | unsigned int i; | ||
229 | size_t off; | ||
230 | |||
231 | off = 0; | ||
232 | for (i=0;i<c_count;i++) | ||
233 | { | ||
234 | if (off + sizeof (c_rec) > len) | ||
235 | return GNUNET_SYSERR; | ||
236 | GNUNET_memcpy (&c_rec, &src[off], sizeof (c_rec)); | ||
237 | cd[i].issuer_attribute_len = ntohl ((uint32_t) c_rec.issuer_attribute_len); | ||
238 | cd[i].issuer_key = c_rec.issuer_key; | ||
239 | cd[i].subject_key = c_rec.subject_key; | ||
240 | cd[i].signature = c_rec.signature; | ||
241 | cd[i].expiration.abs_value_us = GNUNET_ntohll(c_rec.expiration); | ||
242 | off += sizeof (c_rec); | ||
243 | if (off + cd[i].issuer_attribute_len > len) | ||
244 | return GNUNET_SYSERR; | ||
245 | cd[i].issuer_attribute = &src[off]; | ||
246 | off += cd[i].issuer_attribute_len; | ||
247 | } | ||
248 | return GNUNET_OK; | ||
249 | } | ||
250 | |||
251 | |||
252 | |||
253 | /** | ||
254 | * Calculate how many bytes we will need to serialize | ||
255 | * the given delegation chain and credential | ||
256 | * | ||
257 | * @param d_count number of delegation chain entries | ||
258 | * @param dd array of #GNUNET_CREDENTIAL_Delegation | ||
259 | * @param c_count number of credential entries | ||
260 | * @param cd a #GNUNET_CREDENTIAL_Credential | ||
261 | * @return the required size to serialize | ||
262 | */ | ||
263 | size_t | ||
264 | GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count, | ||
265 | const struct GNUNET_CREDENTIAL_Delegation *dd, | ||
266 | unsigned int c_count, | ||
267 | const struct GNUNET_CREDENTIAL_Credential *cd) | ||
268 | { | ||
269 | unsigned int i; | ||
270 | size_t ret; | ||
271 | |||
272 | ret = sizeof (struct ChainEntry) * (d_count); | ||
273 | |||
274 | for (i=0; i<d_count;i++) | ||
275 | { | ||
276 | GNUNET_assert ((ret + | ||
277 | dd[i].issuer_attribute_len + | ||
278 | dd[i].subject_attribute_len) >= ret); | ||
279 | ret += dd[i].issuer_attribute_len + dd[i].subject_attribute_len; | ||
280 | } | ||
281 | return ret+GNUNET_CREDENTIAL_credentials_get_size(c_count, cd); | ||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * Serizalize the given delegation chain entries and credential | ||
287 | * | ||
288 | * @param d_count number of delegation chain entries | ||
289 | * @param dd array of #GNUNET_CREDENTIAL_Delegation | ||
290 | * @param c_count number of credential entries | ||
291 | * @param cd a #GNUNET_CREDENTIAL_Credential | ||
292 | * @param dest_size size of the destination | ||
293 | * @param dest where to store the result | ||
294 | * @return the size of the data, -1 on failure | ||
295 | */ | ||
296 | ssize_t | ||
297 | GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count, | ||
298 | const struct GNUNET_CREDENTIAL_Delegation *dd, | ||
299 | unsigned int c_count, | ||
300 | const struct GNUNET_CREDENTIAL_Credential *cd, | ||
301 | size_t dest_size, | ||
302 | char *dest) | ||
303 | { | ||
304 | struct ChainEntry rec; | ||
305 | unsigned int i; | ||
306 | size_t off; | ||
307 | |||
308 | off = 0; | ||
309 | for (i=0;i<d_count;i++) | ||
310 | { | ||
311 | rec.issuer_attribute_len = htonl ((uint32_t) dd[i].issuer_attribute_len); | ||
312 | rec.subject_attribute_len = htonl ((uint32_t) dd[i].subject_attribute_len); | ||
313 | rec.issuer_key = dd[i].issuer_key; | ||
314 | rec.subject_key = dd[i].subject_key; | ||
315 | if (off + sizeof (rec) > dest_size) | ||
316 | return -1; | ||
317 | GNUNET_memcpy (&dest[off], | ||
318 | &rec, | ||
319 | sizeof (rec)); | ||
320 | off += sizeof (rec); | ||
321 | if (off + dd[i].issuer_attribute_len > dest_size) | ||
322 | return -1; | ||
323 | GNUNET_memcpy (&dest[off], | ||
324 | dd[i].issuer_attribute, | ||
325 | dd[i].issuer_attribute_len); | ||
326 | off += dd[i].issuer_attribute_len; | ||
327 | if (0 == dd[i].subject_attribute_len) | ||
328 | continue; | ||
329 | if (off + dd[i].subject_attribute_len > dest_size) | ||
330 | return -1; | ||
331 | GNUNET_memcpy (&dest[off], | ||
332 | dd[i].subject_attribute, | ||
333 | dd[i].subject_attribute_len); | ||
334 | off += dd[i].subject_attribute_len; | ||
335 | } | ||
336 | return off+GNUNET_CREDENTIAL_credentials_serialize (c_count, | ||
337 | cd, | ||
338 | dest_size-off, | ||
339 | &dest[off]); | ||
340 | } | ||
341 | |||
342 | |||
343 | /** | ||
344 | * Deserialize the given destination | ||
345 | * | ||
346 | * @param len size of the serialized delegation chain and cred | ||
347 | * @param src the serialized data | ||
348 | * @param d_count the number of delegation chain entries | ||
349 | * @param dd where to put the delegation chain entries | ||
350 | * @param c_count the number of credential entries | ||
351 | * @param cd where to put the credential data | ||
352 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
353 | */ | ||
354 | int | ||
355 | GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len, | ||
356 | const char *src, | ||
357 | unsigned int d_count, | ||
358 | struct GNUNET_CREDENTIAL_Delegation *dd, | ||
359 | unsigned int c_count, | ||
360 | struct GNUNET_CREDENTIAL_Credential *cd) | ||
361 | { | ||
362 | struct ChainEntry rec; | ||
363 | unsigned int i; | ||
364 | size_t off; | ||
365 | |||
366 | off = 0; | ||
367 | for (i=0;i<d_count;i++) | ||
368 | { | ||
369 | if (off + sizeof (rec) > len) | ||
370 | return GNUNET_SYSERR; | ||
371 | GNUNET_memcpy (&rec, &src[off], sizeof (rec)); | ||
372 | dd[i].issuer_attribute_len = ntohl ((uint32_t) rec.issuer_attribute_len); | ||
373 | dd[i].issuer_key = rec.issuer_key; | ||
374 | dd[i].subject_key = rec.subject_key; | ||
375 | off += sizeof (rec); | ||
376 | if (off + dd[i].issuer_attribute_len > len) | ||
377 | return GNUNET_SYSERR; | ||
378 | dd[i].issuer_attribute = &src[off]; | ||
379 | off += dd[i].issuer_attribute_len; | ||
380 | dd[i].subject_attribute_len = ntohl ((uint32_t) rec.subject_attribute_len); | ||
381 | if (off + dd[i].subject_attribute_len > len) | ||
382 | return GNUNET_SYSERR; | ||
383 | dd[i].subject_attribute = &src[off]; | ||
384 | off += dd[i].subject_attribute_len; | ||
385 | } | ||
386 | return GNUNET_CREDENTIAL_credentials_deserialize (len-off, | ||
387 | &src[off], | ||
388 | c_count, | ||
389 | cd); | ||
390 | } | ||
391 | int | ||
392 | GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred, | ||
393 | char **data) | ||
394 | { | ||
395 | size_t size; | ||
396 | struct CredentialEntry *cdata; | ||
397 | |||
398 | size = sizeof (struct CredentialEntry) + strlen (cred->issuer_attribute) + 1; | ||
399 | *data = GNUNET_malloc (size); | ||
400 | cdata = (struct CredentialEntry*)*data; | ||
401 | cdata->subject_key = cred->subject_key; | ||
402 | cdata->issuer_key = cred->issuer_key; | ||
403 | cdata->expiration = GNUNET_htonll (cred->expiration.abs_value_us); | ||
404 | cdata->signature = cred->signature; | ||
405 | cdata->issuer_attribute_len = htonl (strlen (cred->issuer_attribute) + 1); | ||
406 | cdata->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); | ||
407 | cdata->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | ||
408 | GNUNET_memcpy (&cdata[1], | ||
409 | cred->issuer_attribute, | ||
410 | strlen (cred->issuer_attribute)); | ||
411 | |||
412 | if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, | ||
413 | &cdata->purpose, | ||
414 | &cdata->signature, | ||
415 | &cdata->issuer_key)) | ||
416 | { | ||
417 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
418 | "Invalid credential\n"); | ||
419 | //return NULL; | ||
420 | } | ||
421 | return size; | ||
422 | } | ||
423 | |||
424 | struct GNUNET_CREDENTIAL_Credential* | ||
425 | GNUNET_CREDENTIAL_credential_deserialize (const char* data, | ||
426 | size_t data_size) | ||
427 | { | ||
428 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
429 | struct CredentialEntry *cdata; | ||
430 | char *issuer_attribute; | ||
431 | |||
432 | if (data_size < sizeof (struct CredentialEntry)) | ||
433 | return NULL; | ||
434 | cdata = (struct CredentialEntry*)data; | ||
435 | if(GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL, | ||
436 | &cdata->purpose, | ||
437 | &cdata->signature, | ||
438 | &cdata->issuer_key)) | ||
439 | { | ||
440 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
441 | "Invalid credential\n"); | ||
442 | //return NULL; | ||
443 | } | ||
444 | issuer_attribute = (char*)&cdata[1]; | ||
445 | |||
446 | cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + ntohl(cdata->issuer_attribute_len)); | ||
447 | |||
448 | cred->issuer_key = cdata->issuer_key; | ||
449 | cred->subject_key = cdata->subject_key; | ||
450 | GNUNET_memcpy (&cred[1], | ||
451 | issuer_attribute, | ||
452 | ntohl (cdata->issuer_attribute_len)); | ||
453 | cred->signature = cdata->signature; | ||
454 | cred->issuer_attribute = (char*)&cred[1]; | ||
455 | cred->expiration.abs_value_us = GNUNET_ntohll (cdata->expiration); | ||
456 | return cred; | ||
457 | } | ||
458 | |||
459 | |||
460 | /* end of credential_serialization.c */ | ||
diff --git a/src/credential/credential_serialization.h b/src/credential/credential_serialization.h new file mode 100644 index 000000000..b870d47dc --- /dev/null +++ b/src/credential/credential_serialization.h | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | |||
22 | /** | ||
23 | * @file credential/credential_serialization.h | ||
24 | * @brief API to serialize and deserialize delegation chains | ||
25 | * and credentials | ||
26 | * @author Martin Schanzenbach | ||
27 | */ | ||
28 | #ifndef CREDENTIAL_SERIALIZATION_H | ||
29 | #define CREDENTIAL_SERIALIZATION_H | ||
30 | |||
31 | #include "platform.h" | ||
32 | #include "gnunet_util_lib.h" | ||
33 | #include "gnunet_constants.h" | ||
34 | #include "gnunet_credential_service.h" | ||
35 | |||
36 | /** | ||
37 | * Calculate how many bytes we will need to serialize | ||
38 | * the given delegation record | ||
39 | * | ||
40 | * @param ds_count number of delegation chain entries | ||
41 | * @param dsr array of #GNUNET_CREDENTIAL_Delegation | ||
42 | * @return the required size to serialize | ||
43 | */ | ||
44 | size_t | ||
45 | GNUNET_CREDENTIAL_delegation_set_get_size (unsigned int ds_count, | ||
46 | const struct GNUNET_CREDENTIAL_DelegationSet *dsr); | ||
47 | |||
48 | /** | ||
49 | * Serizalize the given delegation record entries | ||
50 | * | ||
51 | * @param d_count number of delegation chain entries | ||
52 | * @param dsr array of #GNUNET_CREDENTIAL_Delegation | ||
53 | * @param dest_size size of the destination | ||
54 | * @param dest where to store the result | ||
55 | * @return the size of the data, -1 on failure | ||
56 | */ | ||
57 | ssize_t | ||
58 | GNUNET_CREDENTIAL_delegation_set_serialize (unsigned int d_count, | ||
59 | const struct GNUNET_CREDENTIAL_DelegationSet *dsr, | ||
60 | size_t dest_size, | ||
61 | char *dest); | ||
62 | |||
63 | |||
64 | /** | ||
65 | * Deserialize the given destination | ||
66 | * | ||
67 | * @param len size of the serialized delegation recird | ||
68 | * @param src the serialized data | ||
69 | * @param d_count the number of delegation chain entries | ||
70 | * @param dsr where to put the delegation chain entries | ||
71 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
72 | */ | ||
73 | int | ||
74 | GNUNET_CREDENTIAL_delegation_set_deserialize (size_t len, | ||
75 | const char *src, | ||
76 | unsigned int d_count, | ||
77 | struct GNUNET_CREDENTIAL_DelegationSet *dsr); | ||
78 | |||
79 | /** | ||
80 | * Calculate how many bytes we will need to serialize | ||
81 | * the given delegation chain and credential | ||
82 | * | ||
83 | * @param d_count number of delegation chain entries | ||
84 | * @param dd array of #GNUNET_CREDENTIAL_Delegation | ||
85 | * @param c_count number of credential entries | ||
86 | * @param cd a #GNUNET_CREDENTIAL_Credential | ||
87 | * @return the required size to serialize | ||
88 | */ | ||
89 | size_t | ||
90 | GNUNET_CREDENTIAL_delegation_chain_get_size (unsigned int d_count, | ||
91 | const struct GNUNET_CREDENTIAL_Delegation *dd, | ||
92 | unsigned int c_count, | ||
93 | const struct GNUNET_CREDENTIAL_Credential *cd); | ||
94 | |||
95 | /** | ||
96 | * Serizalize the given delegation chain entries and credential | ||
97 | * | ||
98 | * @param d_count number of delegation chain entries | ||
99 | * @param dd array of #GNUNET_CREDENTIAL_Delegation | ||
100 | * @param c_count number of credential entries | ||
101 | * @param cd a #GNUNET_CREDENTIAL_Credential | ||
102 | * @param dest_size size of the destination | ||
103 | * @param dest where to store the result | ||
104 | * @return the size of the data, -1 on failure | ||
105 | */ | ||
106 | ssize_t | ||
107 | GNUNET_CREDENTIAL_delegation_chain_serialize (unsigned int d_count, | ||
108 | const struct GNUNET_CREDENTIAL_Delegation *dd, | ||
109 | unsigned int c_count, | ||
110 | const struct GNUNET_CREDENTIAL_Credential *cd, | ||
111 | size_t dest_size, | ||
112 | char *dest); | ||
113 | |||
114 | |||
115 | /** | ||
116 | * Deserialize the given destination | ||
117 | * | ||
118 | * @param len size of the serialized delegation chain and cred | ||
119 | * @param src the serialized data | ||
120 | * @param d_count the number of delegation chain entries | ||
121 | * @param dd where to put the delegation chain entries | ||
122 | * @param c_count number of credential entries | ||
123 | * @param cd where to put the credential data | ||
124 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
125 | */ | ||
126 | int | ||
127 | GNUNET_CREDENTIAL_delegation_chain_deserialize (size_t len, | ||
128 | const char *src, | ||
129 | unsigned int d_count, | ||
130 | struct GNUNET_CREDENTIAL_Delegation *dd, | ||
131 | unsigned int c_count, | ||
132 | struct GNUNET_CREDENTIAL_Credential *cd); | ||
133 | size_t | ||
134 | GNUNET_CREDENTIAL_credentials_get_size (unsigned int c_count, | ||
135 | const struct GNUNET_CREDENTIAL_Credential *cd); | ||
136 | |||
137 | ssize_t | ||
138 | GNUNET_CREDENTIAL_credentials_serialize (unsigned int c_count, | ||
139 | const struct GNUNET_CREDENTIAL_Credential *cd, | ||
140 | size_t dest_size, | ||
141 | char *dest); | ||
142 | |||
143 | |||
144 | int | ||
145 | GNUNET_CREDENTIAL_credentials_deserialize (size_t len, | ||
146 | const char *src, | ||
147 | unsigned int c_count, | ||
148 | struct GNUNET_CREDENTIAL_Credential *cd); | ||
149 | |||
150 | |||
151 | int | ||
152 | GNUNET_CREDENTIAL_credential_serialize (struct GNUNET_CREDENTIAL_Credential *cred, | ||
153 | char **data); | ||
154 | |||
155 | struct GNUNET_CREDENTIAL_Credential* | ||
156 | GNUNET_CREDENTIAL_credential_deserialize (const char* data, | ||
157 | size_t data_size); | ||
158 | #endif | ||
159 | /* end of credential_serialization.h */ | ||
diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c new file mode 100644 index 000000000..03f959b95 --- /dev/null +++ b/src/credential/gnunet-credential.c | |||
@@ -0,0 +1,588 @@ | |||
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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gnunet-credential.c | ||
22 | * @brief command line tool to access command line Credential service | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include <gnunet_util_lib.h> | ||
27 | #include <gnunet_credential_service.h> | ||
28 | #include <gnunet_gnsrecord_lib.h> | ||
29 | #include "credential_misc.h" | ||
30 | #include "credential_serialization.h" | ||
31 | |||
32 | /** | ||
33 | * Configuration we are using. | ||
34 | */ | ||
35 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
36 | |||
37 | /** | ||
38 | * EgoLookup | ||
39 | */ | ||
40 | static struct GNUNET_IDENTITY_EgoLookup *el; | ||
41 | |||
42 | /** | ||
43 | * Handle to Credential service. | ||
44 | */ | ||
45 | static struct GNUNET_CREDENTIAL_Handle *credential; | ||
46 | |||
47 | /** | ||
48 | * Desired timeout for the lookup (default is no timeout). | ||
49 | */ | ||
50 | static struct GNUNET_TIME_Relative timeout; | ||
51 | |||
52 | /** | ||
53 | * Handle to verify request | ||
54 | */ | ||
55 | static struct GNUNET_CREDENTIAL_Request *verify_request; | ||
56 | |||
57 | /** | ||
58 | * Handle to collect request | ||
59 | */ | ||
60 | static struct GNUNET_CREDENTIAL_Request *collect_request; | ||
61 | |||
62 | /** | ||
63 | * Task scheduled to handle timeout. | ||
64 | */ | ||
65 | static struct GNUNET_SCHEDULER_Task *tt; | ||
66 | |||
67 | /** | ||
68 | * Subject pubkey string | ||
69 | */ | ||
70 | static char *subject_key; | ||
71 | |||
72 | /** | ||
73 | * Subject credential string | ||
74 | */ | ||
75 | static char *subject_credential; | ||
76 | |||
77 | /** | ||
78 | * Credential TTL | ||
79 | */ | ||
80 | static char *expiration; | ||
81 | |||
82 | /** | ||
83 | * Subject key | ||
84 | */ | ||
85 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey; | ||
86 | |||
87 | /** | ||
88 | * Issuer key | ||
89 | */ | ||
90 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey; | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Issuer pubkey string | ||
95 | */ | ||
96 | static char *issuer_key; | ||
97 | |||
98 | /** | ||
99 | * ego | ||
100 | */ | ||
101 | static char *ego_name; | ||
102 | |||
103 | /** | ||
104 | * Issuer attribute | ||
105 | */ | ||
106 | static char *issuer_attr; | ||
107 | |||
108 | /** | ||
109 | * Verify mode | ||
110 | */ | ||
111 | static int verify; | ||
112 | |||
113 | /** | ||
114 | * Issue mode | ||
115 | */ | ||
116 | static int create_cred; | ||
117 | |||
118 | /** | ||
119 | * Collect mode | ||
120 | */ | ||
121 | static int collect; | ||
122 | |||
123 | /** | ||
124 | * Task run on shutdown. Cleans up everything. | ||
125 | * | ||
126 | * @param cls unused | ||
127 | */ | ||
128 | static void | ||
129 | do_shutdown (void *cls) | ||
130 | { | ||
131 | if (NULL != verify_request) | ||
132 | { | ||
133 | GNUNET_CREDENTIAL_request_cancel (verify_request); | ||
134 | verify_request = NULL; | ||
135 | } | ||
136 | if (NULL != credential) | ||
137 | { | ||
138 | GNUNET_CREDENTIAL_disconnect (credential); | ||
139 | credential = NULL; | ||
140 | } | ||
141 | if (NULL != tt) | ||
142 | { | ||
143 | GNUNET_SCHEDULER_cancel (tt); | ||
144 | tt = NULL; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
150 | * Task run on timeout. Triggers shutdown. | ||
151 | * | ||
152 | * @param cls unused | ||
153 | */ | ||
154 | static void | ||
155 | do_timeout (void *cls) | ||
156 | { | ||
157 | tt = NULL; | ||
158 | GNUNET_SCHEDULER_shutdown (); | ||
159 | } | ||
160 | |||
161 | static void | ||
162 | handle_collect_result (void *cls, | ||
163 | unsigned int d_count, | ||
164 | struct GNUNET_CREDENTIAL_Delegation *dc, | ||
165 | unsigned int c_count, | ||
166 | struct GNUNET_CREDENTIAL_Credential *cred) | ||
167 | { | ||
168 | int i; | ||
169 | char* line; | ||
170 | |||
171 | verify_request = NULL; | ||
172 | if (NULL != cred) | ||
173 | { | ||
174 | for (i=0;i<c_count;i++) | ||
175 | { | ||
176 | line = GNUNET_CREDENTIAL_credential_to_string (&cred[i]); | ||
177 | printf ("%s\n", | ||
178 | line); | ||
179 | GNUNET_free (line); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | |||
184 | GNUNET_SCHEDULER_shutdown (); | ||
185 | } | ||
186 | |||
187 | |||
188 | static void | ||
189 | handle_verify_result (void *cls, | ||
190 | unsigned int d_count, | ||
191 | struct GNUNET_CREDENTIAL_Delegation *dc, | ||
192 | unsigned int c_count, | ||
193 | struct GNUNET_CREDENTIAL_Credential *cred) | ||
194 | { | ||
195 | int i; | ||
196 | char* iss_key; | ||
197 | char* sub_key; | ||
198 | |||
199 | verify_request = NULL; | ||
200 | if (NULL == cred) | ||
201 | printf ("Failed.\n"); | ||
202 | else | ||
203 | { | ||
204 | printf("Delegation Chain:\n"); | ||
205 | for (i=0;i<d_count;i++) | ||
206 | { | ||
207 | iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].issuer_key); | ||
208 | sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&dc[i].subject_key); | ||
209 | if (0 != dc[i].subject_attribute_len) | ||
210 | { | ||
211 | printf ("(%d) %s.%s <- %s.%s\n", i, | ||
212 | iss_key, dc[i].issuer_attribute, | ||
213 | sub_key, dc[i].subject_attribute); | ||
214 | } else { | ||
215 | printf ("(%d) %s.%s <- %s\n", i, | ||
216 | iss_key, dc[i].issuer_attribute, | ||
217 | sub_key); | ||
218 | } | ||
219 | GNUNET_free (iss_key); | ||
220 | GNUNET_free (sub_key); | ||
221 | } | ||
222 | printf("\nCredentials:\n"); | ||
223 | for (i=0;i<c_count;i++) | ||
224 | { | ||
225 | iss_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred[i].issuer_key); | ||
226 | sub_key = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred[i].subject_key); | ||
227 | printf ("%s.%s <- %s\n", | ||
228 | iss_key, cred[i].issuer_attribute, | ||
229 | sub_key); | ||
230 | GNUNET_free (iss_key); | ||
231 | GNUNET_free (sub_key); | ||
232 | |||
233 | } | ||
234 | printf ("Successful.\n"); | ||
235 | } | ||
236 | |||
237 | |||
238 | GNUNET_SCHEDULER_shutdown (); | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * Callback invoked from identity service with ego information. | ||
243 | * An @a ego of NULL means the ego was not found. | ||
244 | * | ||
245 | * @param cls closure with the configuration | ||
246 | * @param ego an ego known to identity service, or NULL | ||
247 | */ | ||
248 | static void | ||
249 | identity_cb (void *cls, | ||
250 | const struct GNUNET_IDENTITY_Ego *ego) | ||
251 | { | ||
252 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; | ||
253 | struct GNUNET_CREDENTIAL_Credential *crd; | ||
254 | struct GNUNET_TIME_Absolute etime_abs; | ||
255 | struct GNUNET_TIME_Relative etime_rel; | ||
256 | char *res; | ||
257 | |||
258 | el = NULL; | ||
259 | if (NULL == ego) | ||
260 | { | ||
261 | if (NULL != ego_name) | ||
262 | { | ||
263 | fprintf (stderr, | ||
264 | _("Ego `%s' not known to identity service\n"), | ||
265 | ego_name); | ||
266 | } | ||
267 | GNUNET_SCHEDULER_shutdown (); | ||
268 | return; | ||
269 | } | ||
270 | |||
271 | if (GNUNET_YES == collect) | ||
272 | { | ||
273 | |||
274 | if (GNUNET_OK != | ||
275 | GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key, | ||
276 | strlen (issuer_key), | ||
277 | &issuer_pkey)) | ||
278 | { | ||
279 | fprintf (stderr, | ||
280 | _("Issuer public key `%s' is not well-formed\n"), | ||
281 | issuer_key); | ||
282 | GNUNET_SCHEDULER_shutdown (); | ||
283 | } | ||
284 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
285 | |||
286 | collect_request = GNUNET_CREDENTIAL_collect(credential, | ||
287 | &issuer_pkey, | ||
288 | issuer_attr, //TODO argument | ||
289 | privkey, | ||
290 | &handle_collect_result, | ||
291 | NULL); | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | //Else issue | ||
296 | |||
297 | if (NULL == expiration) | ||
298 | { | ||
299 | fprintf (stderr, | ||
300 | "Please specify a TTL\n"); | ||
301 | GNUNET_SCHEDULER_shutdown (); | ||
302 | return; | ||
303 | } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration, | ||
304 | &etime_rel)) | ||
305 | { | ||
306 | etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel); | ||
307 | } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration, | ||
308 | &etime_abs)) | ||
309 | { | ||
310 | fprintf (stderr, | ||
311 | "%s is not a valid ttl!\n", | ||
312 | expiration); | ||
313 | GNUNET_SCHEDULER_shutdown (); | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | |||
318 | privkey = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
319 | GNUNET_free_non_null (ego_name); | ||
320 | ego_name = NULL; | ||
321 | crd = GNUNET_CREDENTIAL_credential_issue (privkey, | ||
322 | &subject_pkey, | ||
323 | issuer_attr, | ||
324 | &etime_abs); | ||
325 | |||
326 | res = GNUNET_CREDENTIAL_credential_to_string (crd); | ||
327 | GNUNET_free (crd); | ||
328 | printf ("%s\n", res); | ||
329 | GNUNET_SCHEDULER_shutdown (); | ||
330 | } | ||
331 | |||
332 | |||
333 | |||
334 | |||
335 | /** | ||
336 | * Main function that will be run. | ||
337 | * | ||
338 | * @param cls closure | ||
339 | * @param args remaining command-line arguments | ||
340 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
341 | * @param c configuration | ||
342 | */ | ||
343 | static void | ||
344 | run (void *cls, | ||
345 | char *const *args, | ||
346 | const char *cfgfile, | ||
347 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
348 | { | ||
349 | |||
350 | cfg = c; | ||
351 | |||
352 | |||
353 | tt = GNUNET_SCHEDULER_add_delayed (timeout, | ||
354 | &do_timeout, NULL); | ||
355 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | ||
356 | |||
357 | if (GNUNET_YES == collect) { | ||
358 | if (NULL == issuer_key) | ||
359 | { | ||
360 | fprintf (stderr, | ||
361 | _("Issuer public key not well-formed\n")); | ||
362 | GNUNET_SCHEDULER_shutdown (); | ||
363 | return; | ||
364 | |||
365 | } | ||
366 | |||
367 | credential = GNUNET_CREDENTIAL_connect (cfg); | ||
368 | |||
369 | if (NULL == credential) | ||
370 | { | ||
371 | fprintf (stderr, | ||
372 | _("Failed to connect to CREDENTIAL\n")); | ||
373 | GNUNET_SCHEDULER_shutdown (); | ||
374 | } | ||
375 | if (NULL == issuer_attr) | ||
376 | { | ||
377 | fprintf (stderr, | ||
378 | _("You must provide issuer the attribute\n")); | ||
379 | GNUNET_SCHEDULER_shutdown (); | ||
380 | } | ||
381 | |||
382 | if (NULL == ego_name) | ||
383 | { | ||
384 | fprintf (stderr, | ||
385 | _("ego required\n")); | ||
386 | GNUNET_SCHEDULER_shutdown (); | ||
387 | return; | ||
388 | |||
389 | } | ||
390 | el = GNUNET_IDENTITY_ego_lookup (cfg, | ||
391 | ego_name, | ||
392 | &identity_cb, | ||
393 | (void *) cfg); | ||
394 | return; | ||
395 | |||
396 | } | ||
397 | |||
398 | if (NULL == subject_key) | ||
399 | { | ||
400 | fprintf (stderr, | ||
401 | _("Subject public key needed\n")); | ||
402 | GNUNET_SCHEDULER_shutdown (); | ||
403 | return; | ||
404 | |||
405 | } | ||
406 | if (GNUNET_OK != | ||
407 | GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, | ||
408 | strlen (subject_key), | ||
409 | &subject_pkey)) | ||
410 | { | ||
411 | fprintf (stderr, | ||
412 | _("Subject public key `%s' is not well-formed\n"), | ||
413 | subject_key); | ||
414 | GNUNET_SCHEDULER_shutdown (); | ||
415 | return; | ||
416 | } | ||
417 | if (GNUNET_YES == verify) { | ||
418 | if (NULL == issuer_key) | ||
419 | { | ||
420 | fprintf (stderr, | ||
421 | _("Issuer public key not well-formed\n")); | ||
422 | GNUNET_SCHEDULER_shutdown (); | ||
423 | return; | ||
424 | |||
425 | } | ||
426 | if (GNUNET_OK != | ||
427 | GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key, | ||
428 | strlen (issuer_key), | ||
429 | &issuer_pkey)) | ||
430 | { | ||
431 | fprintf (stderr, | ||
432 | _("Issuer public key `%s' is not well-formed\n"), | ||
433 | issuer_key); | ||
434 | GNUNET_SCHEDULER_shutdown (); | ||
435 | } | ||
436 | credential = GNUNET_CREDENTIAL_connect (cfg); | ||
437 | |||
438 | if (NULL == credential) | ||
439 | { | ||
440 | fprintf (stderr, | ||
441 | _("Failed to connect to CREDENTIAL\n")); | ||
442 | GNUNET_SCHEDULER_shutdown (); | ||
443 | } | ||
444 | if (NULL == issuer_attr || NULL == subject_credential) | ||
445 | { | ||
446 | fprintf (stderr, | ||
447 | _("You must provide issuer and subject attributes\n")); | ||
448 | GNUNET_SCHEDULER_shutdown (); | ||
449 | } | ||
450 | |||
451 | //Subject credentials are comma separated | ||
452 | char *tmp = GNUNET_strdup (subject_credential); | ||
453 | char *tok = strtok (tmp, ","); | ||
454 | if (NULL == tok) | ||
455 | { | ||
456 | fprintf (stderr, | ||
457 | "Invalid subject credentials\n"); | ||
458 | GNUNET_free (tmp); | ||
459 | GNUNET_SCHEDULER_shutdown (); | ||
460 | } | ||
461 | int count = 1; | ||
462 | int i; | ||
463 | while (NULL != (tok = strtok(NULL, ","))) | ||
464 | count++; | ||
465 | struct GNUNET_CREDENTIAL_Credential credentials[count]; | ||
466 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
467 | GNUNET_free (tmp); | ||
468 | tmp = GNUNET_strdup (subject_credential); | ||
469 | tok = strtok (tmp, ","); | ||
470 | for (i=0;i<count;i++) | ||
471 | { | ||
472 | cred = GNUNET_CREDENTIAL_credential_from_string (tok); | ||
473 | GNUNET_memcpy (&credentials[i], | ||
474 | cred, | ||
475 | sizeof (struct GNUNET_CREDENTIAL_Credential)); | ||
476 | credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute); | ||
477 | tok = strtok(NULL, ","); | ||
478 | GNUNET_free (cred); | ||
479 | } | ||
480 | |||
481 | verify_request = GNUNET_CREDENTIAL_verify(credential, | ||
482 | &issuer_pkey, | ||
483 | issuer_attr, //TODO argument | ||
484 | &subject_pkey, | ||
485 | count, | ||
486 | credentials, | ||
487 | &handle_verify_result, | ||
488 | NULL); | ||
489 | for (i=0;i<count;i++) | ||
490 | { | ||
491 | GNUNET_free ((char*)credentials[i].issuer_attribute); | ||
492 | } | ||
493 | } else if (GNUNET_YES == create_cred) { | ||
494 | if (NULL == ego_name) | ||
495 | { | ||
496 | fprintf (stderr, | ||
497 | _("Issuer ego required\n")); | ||
498 | GNUNET_SCHEDULER_shutdown (); | ||
499 | return; | ||
500 | |||
501 | } | ||
502 | el = GNUNET_IDENTITY_ego_lookup (cfg, | ||
503 | ego_name, | ||
504 | &identity_cb, | ||
505 | (void *) cfg); | ||
506 | return; | ||
507 | } else { | ||
508 | fprintf (stderr, | ||
509 | _("Please specify name to lookup, subject key and issuer key!\n")); | ||
510 | GNUNET_SCHEDULER_shutdown (); | ||
511 | } | ||
512 | return; | ||
513 | } | ||
514 | |||
515 | |||
516 | /** | ||
517 | * The main function for gnunet-gns. | ||
518 | * | ||
519 | * @param argc number of arguments from the command line | ||
520 | * @param argv command line arguments | ||
521 | * @return 0 ok, 1 on error | ||
522 | */ | ||
523 | int | ||
524 | main (int argc, char *const *argv) | ||
525 | { | ||
526 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
527 | GNUNET_GETOPT_option_flag ('I', | ||
528 | "issue", | ||
529 | gettext_noop ("create credential"), | ||
530 | &create_cred), | ||
531 | GNUNET_GETOPT_option_flag ('V', | ||
532 | "verify", | ||
533 | gettext_noop ("verify credential against attribute"), | ||
534 | &verify), | ||
535 | GNUNET_GETOPT_option_string ('s', | ||
536 | "subject", | ||
537 | "PKEY", | ||
538 | gettext_noop ("The public key of the subject to lookup the credential for"), | ||
539 | &subject_key), | ||
540 | GNUNET_GETOPT_option_string ('b', | ||
541 | "credential", | ||
542 | "CRED", | ||
543 | gettext_noop ("The name of the credential presented by the subject"), | ||
544 | &subject_credential), | ||
545 | GNUNET_GETOPT_option_string ('i', | ||
546 | "issuer", | ||
547 | "PKEY", | ||
548 | gettext_noop ("The public key of the authority to verify the credential against"), | ||
549 | &issuer_key), | ||
550 | GNUNET_GETOPT_option_string ('e', | ||
551 | "ego", | ||
552 | "EGO", | ||
553 | gettext_noop ("The ego to use"), | ||
554 | &ego_name), | ||
555 | GNUNET_GETOPT_option_string ('a', | ||
556 | "attribute", | ||
557 | "ATTR", | ||
558 | gettext_noop ("The issuer attribute to verify against or to issue"), | ||
559 | &issuer_attr), | ||
560 | GNUNET_GETOPT_option_string ('T', | ||
561 | "ttl", | ||
562 | "EXP", | ||
563 | gettext_noop ("The time to live for the credential"), | ||
564 | &expiration), | ||
565 | GNUNET_GETOPT_option_flag ('g', | ||
566 | "collect", | ||
567 | gettext_noop ("collect credentials"), | ||
568 | &collect), | ||
569 | GNUNET_GETOPT_OPTION_END | ||
570 | }; | ||
571 | int ret; | ||
572 | |||
573 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
574 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
575 | return 2; | ||
576 | |||
577 | GNUNET_log_setup ("gnunet-credential", "WARNING", NULL); | ||
578 | ret = | ||
579 | (GNUNET_OK == | ||
580 | GNUNET_PROGRAM_run (argc, argv, "gnunet-credential", | ||
581 | _("GNUnet credential resolver tool"), | ||
582 | options, | ||
583 | &run, NULL)) ? 0 : 1; | ||
584 | GNUNET_free ((void*) argv); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | /* end of gnunet-credential.c */ | ||
diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c new file mode 100644 index 000000000..be88839e9 --- /dev/null +++ b/src/credential/gnunet-service-credential.c | |||
@@ -0,0 +1,1160 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file credential/gnunet-service-credential.c | ||
22 | * @brief GNUnet Credential Service (main service) | ||
23 | * @author Martin Schanzenbach | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_credential_service.h" | ||
28 | #include "gnunet_statistics_service.h" | ||
29 | #include "credential.h" | ||
30 | #include "credential_serialization.h" | ||
31 | #include "gnunet_protocols.h" | ||
32 | #include "gnunet_signatures.h" | ||
33 | |||
34 | #include <gnunet_dnsparser_lib.h> | ||
35 | #include <gnunet_identity_service.h> | ||
36 | #include <gnunet_gnsrecord_lib.h> | ||
37 | #include <gnunet_namestore_service.h> | ||
38 | #include <gnunet_gns_service.h> | ||
39 | |||
40 | |||
41 | #define GNUNET_CREDENTIAL_MAX_LENGTH 255 | ||
42 | |||
43 | struct VerifyRequestHandle; | ||
44 | |||
45 | struct DelegationSetQueueEntry; | ||
46 | |||
47 | |||
48 | struct DelegationChainEntry | ||
49 | { | ||
50 | /** | ||
51 | * DLL | ||
52 | */ | ||
53 | struct DelegationChainEntry *next; | ||
54 | |||
55 | /** | ||
56 | * DLL | ||
57 | */ | ||
58 | struct DelegationChainEntry *prev; | ||
59 | |||
60 | /** | ||
61 | * The issuer | ||
62 | */ | ||
63 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
64 | |||
65 | /** | ||
66 | * The subject | ||
67 | */ | ||
68 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
69 | |||
70 | /** | ||
71 | * The issued attribute | ||
72 | */ | ||
73 | char *issuer_attribute; | ||
74 | |||
75 | /** | ||
76 | * The delegated attribute | ||
77 | */ | ||
78 | char *subject_attribute; | ||
79 | }; | ||
80 | |||
81 | /** | ||
82 | * DLL for record | ||
83 | */ | ||
84 | struct CredentialRecordEntry | ||
85 | { | ||
86 | /** | ||
87 | * DLL | ||
88 | */ | ||
89 | struct CredentialRecordEntry *next; | ||
90 | |||
91 | /** | ||
92 | * DLL | ||
93 | */ | ||
94 | struct CredentialRecordEntry *prev; | ||
95 | |||
96 | /** | ||
97 | * Number of references in delegation chains | ||
98 | */ | ||
99 | uint32_t refcount; | ||
100 | |||
101 | /** | ||
102 | * Payload | ||
103 | */ | ||
104 | struct GNUNET_CREDENTIAL_Credential *credential; | ||
105 | }; | ||
106 | |||
107 | /** | ||
108 | * DLL used for delegations | ||
109 | * Used for OR delegations | ||
110 | */ | ||
111 | struct DelegationQueueEntry | ||
112 | { | ||
113 | /** | ||
114 | * DLL | ||
115 | */ | ||
116 | struct DelegationQueueEntry *next; | ||
117 | |||
118 | /** | ||
119 | * DLL | ||
120 | */ | ||
121 | struct DelegationQueueEntry *prev; | ||
122 | |||
123 | /** | ||
124 | * Sets under this Queue | ||
125 | */ | ||
126 | struct DelegationSetQueueEntry *set_entries_head; | ||
127 | |||
128 | /** | ||
129 | * Sets under this Queue | ||
130 | */ | ||
131 | struct DelegationSetQueueEntry *set_entries_tail; | ||
132 | |||
133 | /** | ||
134 | * Parent set | ||
135 | */ | ||
136 | struct DelegationSetQueueEntry *parent_set; | ||
137 | |||
138 | /** | ||
139 | * Required solutions | ||
140 | */ | ||
141 | uint32_t required_solutions; | ||
142 | }; | ||
143 | |||
144 | /** | ||
145 | * DLL for delegation sets | ||
146 | * Used for AND delegation set | ||
147 | */ | ||
148 | struct DelegationSetQueueEntry | ||
149 | { | ||
150 | /** | ||
151 | * DLL | ||
152 | */ | ||
153 | struct DelegationSetQueueEntry *next; | ||
154 | |||
155 | /** | ||
156 | * DLL | ||
157 | */ | ||
158 | struct DelegationSetQueueEntry *prev; | ||
159 | |||
160 | /** | ||
161 | * GNS handle | ||
162 | */ | ||
163 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
164 | |||
165 | /** | ||
166 | * Verify handle | ||
167 | */ | ||
168 | struct VerifyRequestHandle *handle; | ||
169 | |||
170 | /** | ||
171 | * Parent attribute delegation | ||
172 | */ | ||
173 | struct DelegationQueueEntry *parent; | ||
174 | |||
175 | /** | ||
176 | * Issuer key | ||
177 | */ | ||
178 | struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key; | ||
179 | |||
180 | /** | ||
181 | * Queue entries of this set | ||
182 | */ | ||
183 | struct DelegationQueueEntry *queue_entries_head; | ||
184 | |||
185 | /** | ||
186 | * Queue entries of this set | ||
187 | */ | ||
188 | struct DelegationQueueEntry *queue_entries_tail; | ||
189 | |||
190 | /** | ||
191 | * Parent QueueEntry | ||
192 | */ | ||
193 | struct DelegationQueueEntry *parent_queue_entry; | ||
194 | |||
195 | /** | ||
196 | * Issuer attribute delegated to | ||
197 | */ | ||
198 | char *issuer_attribute; | ||
199 | |||
200 | /** | ||
201 | * The current attribute to look up | ||
202 | */ | ||
203 | char *lookup_attribute; | ||
204 | |||
205 | /** | ||
206 | * Trailing attribute context | ||
207 | */ | ||
208 | char *attr_trailer; | ||
209 | |||
210 | /** | ||
211 | * Still to resolve delegation as string | ||
212 | */ | ||
213 | char *unresolved_attribute_delegation; | ||
214 | |||
215 | /** | ||
216 | * The delegation chain entry | ||
217 | */ | ||
218 | struct DelegationChainEntry *delegation_chain_entry; | ||
219 | |||
220 | }; | ||
221 | |||
222 | |||
223 | /** | ||
224 | * Handle to a lookup operation from api | ||
225 | */ | ||
226 | struct VerifyRequestHandle | ||
227 | { | ||
228 | |||
229 | /** | ||
230 | * We keep these in a DLL. | ||
231 | */ | ||
232 | struct VerifyRequestHandle *next; | ||
233 | |||
234 | /** | ||
235 | * We keep these in a DLL. | ||
236 | */ | ||
237 | struct VerifyRequestHandle *prev; | ||
238 | |||
239 | /** | ||
240 | * Handle to the requesting client | ||
241 | */ | ||
242 | struct GNUNET_SERVICE_Client *client; | ||
243 | |||
244 | /** | ||
245 | * GNS handle | ||
246 | */ | ||
247 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
248 | |||
249 | /** | ||
250 | * Size of delegation tree | ||
251 | */ | ||
252 | uint32_t delegation_chain_size; | ||
253 | |||
254 | /** | ||
255 | * Children of this attribute | ||
256 | */ | ||
257 | struct DelegationChainEntry *delegation_chain_head; | ||
258 | |||
259 | /** | ||
260 | * Children of this attribute | ||
261 | */ | ||
262 | struct DelegationChainEntry *delegation_chain_tail; | ||
263 | |||
264 | /** | ||
265 | * Issuer public key | ||
266 | */ | ||
267 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
268 | |||
269 | /** | ||
270 | * Issuer attribute | ||
271 | */ | ||
272 | char *issuer_attribute; | ||
273 | |||
274 | /** | ||
275 | * Subject public key | ||
276 | */ | ||
277 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
278 | |||
279 | /** | ||
280 | * Credential DLL | ||
281 | */ | ||
282 | struct CredentialRecordEntry *cred_chain_head; | ||
283 | |||
284 | /** | ||
285 | * Credential DLL | ||
286 | */ | ||
287 | struct CredentialRecordEntry *cred_chain_tail; | ||
288 | |||
289 | /** | ||
290 | * Credential DLL size | ||
291 | */ | ||
292 | uint32_t cred_chain_size; | ||
293 | |||
294 | /** | ||
295 | * Root Delegation Set | ||
296 | */ | ||
297 | struct DelegationSetQueueEntry *root_set; | ||
298 | |||
299 | /** | ||
300 | * Current Delegation Pointer | ||
301 | */ | ||
302 | struct DelegationQueueEntry *current_delegation; | ||
303 | |||
304 | /** | ||
305 | * request id | ||
306 | */ | ||
307 | uint32_t request_id; | ||
308 | |||
309 | /** | ||
310 | * Pending lookups | ||
311 | */ | ||
312 | uint64_t pending_lookups; | ||
313 | |||
314 | /** | ||
315 | * Credential iterator | ||
316 | */ | ||
317 | struct GNUNET_NAMESTORE_ZoneIterator *cred_collection_iter; | ||
318 | |||
319 | /** | ||
320 | * Collect task | ||
321 | */ | ||
322 | struct GNUNET_SCHEDULER_Task *collect_next_task; | ||
323 | |||
324 | }; | ||
325 | |||
326 | |||
327 | /** | ||
328 | * Head of the DLL. | ||
329 | */ | ||
330 | static struct VerifyRequestHandle *vrh_head; | ||
331 | |||
332 | /** | ||
333 | * Tail of the DLL. | ||
334 | */ | ||
335 | static struct VerifyRequestHandle *vrh_tail; | ||
336 | |||
337 | /** | ||
338 | * Handle to the statistics service | ||
339 | */ | ||
340 | static struct GNUNET_STATISTICS_Handle *statistics; | ||
341 | |||
342 | /** | ||
343 | * Handle to GNS service. | ||
344 | */ | ||
345 | static struct GNUNET_GNS_Handle *gns; | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Handle to namestore service | ||
350 | */ | ||
351 | static struct GNUNET_NAMESTORE_Handle *namestore; | ||
352 | |||
353 | static void | ||
354 | cleanup_delegation_set (struct DelegationSetQueueEntry *ds_entry) | ||
355 | { | ||
356 | struct DelegationQueueEntry *dq_entry; | ||
357 | struct DelegationSetQueueEntry *child; | ||
358 | |||
359 | if (NULL == ds_entry) | ||
360 | return; | ||
361 | |||
362 | for (dq_entry = ds_entry->queue_entries_head; | ||
363 | NULL != dq_entry; | ||
364 | dq_entry = ds_entry->queue_entries_head) | ||
365 | { | ||
366 | GNUNET_CONTAINER_DLL_remove (ds_entry->queue_entries_head, | ||
367 | ds_entry->queue_entries_tail, | ||
368 | dq_entry); | ||
369 | for (child = dq_entry->set_entries_head; | ||
370 | NULL != child; | ||
371 | child = dq_entry->set_entries_head) | ||
372 | { | ||
373 | GNUNET_CONTAINER_DLL_remove (dq_entry->set_entries_head, | ||
374 | dq_entry->set_entries_tail, | ||
375 | child); | ||
376 | cleanup_delegation_set (child); | ||
377 | } | ||
378 | GNUNET_free (dq_entry); | ||
379 | } | ||
380 | GNUNET_free_non_null (ds_entry->issuer_key); | ||
381 | GNUNET_free_non_null (ds_entry->lookup_attribute); | ||
382 | GNUNET_free_non_null (ds_entry->issuer_attribute); | ||
383 | GNUNET_free_non_null (ds_entry->unresolved_attribute_delegation); | ||
384 | GNUNET_free_non_null (ds_entry->attr_trailer); | ||
385 | if (NULL != ds_entry->lookup_request) | ||
386 | { | ||
387 | GNUNET_GNS_lookup_cancel (ds_entry->lookup_request); | ||
388 | ds_entry->lookup_request = NULL; | ||
389 | } | ||
390 | if (NULL != ds_entry->delegation_chain_entry) | ||
391 | { | ||
392 | GNUNET_free_non_null (ds_entry->delegation_chain_entry->subject_attribute); | ||
393 | GNUNET_free_non_null (ds_entry->delegation_chain_entry->issuer_attribute); | ||
394 | GNUNET_free (ds_entry->delegation_chain_entry); | ||
395 | } | ||
396 | GNUNET_free (ds_entry); | ||
397 | } | ||
398 | |||
399 | static void | ||
400 | cleanup_handle (struct VerifyRequestHandle *vrh) | ||
401 | { | ||
402 | struct CredentialRecordEntry *cr_entry; | ||
403 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
404 | "Cleaning up...\n"); | ||
405 | if (NULL != vrh->lookup_request) | ||
406 | { | ||
407 | GNUNET_GNS_lookup_cancel (vrh->lookup_request); | ||
408 | vrh->lookup_request = NULL; | ||
409 | } | ||
410 | cleanup_delegation_set (vrh->root_set); | ||
411 | GNUNET_free_non_null (vrh->issuer_attribute); | ||
412 | for (cr_entry = vrh->cred_chain_head; | ||
413 | NULL != vrh->cred_chain_head; | ||
414 | cr_entry = vrh->cred_chain_head) | ||
415 | { | ||
416 | GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head, | ||
417 | vrh->cred_chain_tail, | ||
418 | cr_entry); | ||
419 | GNUNET_free_non_null (cr_entry->credential); | ||
420 | GNUNET_free (cr_entry); | ||
421 | } | ||
422 | GNUNET_free (vrh); | ||
423 | } | ||
424 | |||
425 | static void | ||
426 | shutdown_task (void *cls) | ||
427 | { | ||
428 | struct VerifyRequestHandle *vrh; | ||
429 | |||
430 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
431 | "Shutting down!\n"); | ||
432 | |||
433 | while (NULL != (vrh = vrh_head)) | ||
434 | { | ||
435 | //CREDENTIAL_resolver_lookup_cancel (clh->lookup); | ||
436 | GNUNET_CONTAINER_DLL_remove (vrh_head, | ||
437 | vrh_tail, | ||
438 | vrh); | ||
439 | cleanup_handle (vrh); | ||
440 | } | ||
441 | |||
442 | if (NULL != gns) | ||
443 | { | ||
444 | GNUNET_GNS_disconnect (gns); | ||
445 | gns = NULL; | ||
446 | } | ||
447 | if (NULL != namestore) | ||
448 | { | ||
449 | GNUNET_NAMESTORE_disconnect (namestore); | ||
450 | namestore = NULL; | ||
451 | } | ||
452 | if (NULL != statistics) | ||
453 | { | ||
454 | GNUNET_STATISTICS_destroy (statistics, | ||
455 | GNUNET_NO); | ||
456 | statistics = NULL; | ||
457 | } | ||
458 | |||
459 | } | ||
460 | |||
461 | |||
462 | |||
463 | static void | ||
464 | send_lookup_response (struct VerifyRequestHandle *vrh) | ||
465 | { | ||
466 | struct GNUNET_MQ_Envelope *env; | ||
467 | struct DelegationChainResultMessage *rmsg; | ||
468 | struct DelegationChainEntry *dce; | ||
469 | struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size]; | ||
470 | struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size]; | ||
471 | struct CredentialRecordEntry *cd; | ||
472 | struct CredentialRecordEntry *tmp; | ||
473 | size_t size; | ||
474 | |||
475 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
476 | "Sending response\n"); | ||
477 | dce = vrh->delegation_chain_head; | ||
478 | for (uint32_t i=0;i<vrh->delegation_chain_size;i++) | ||
479 | { | ||
480 | dd[i].issuer_key = dce->issuer_key; | ||
481 | dd[i].subject_key = dce->subject_key; | ||
482 | dd[i].issuer_attribute = dce->issuer_attribute; | ||
483 | dd[i].issuer_attribute_len = strlen (dce->issuer_attribute)+1; | ||
484 | dd[i].subject_attribute_len = 0; | ||
485 | dd[i].subject_attribute = NULL; | ||
486 | if (NULL != dce->subject_attribute) | ||
487 | { | ||
488 | dd[i].subject_attribute = dce->subject_attribute; | ||
489 | dd[i].subject_attribute_len = strlen(dce->subject_attribute)+1; | ||
490 | } | ||
491 | dce = dce->next; | ||
492 | } | ||
493 | |||
494 | /** | ||
495 | * Remove all credentials not needed | ||
496 | */ | ||
497 | for (cd = vrh->cred_chain_head; NULL != cd;) | ||
498 | { | ||
499 | if (cd->refcount > 0) | ||
500 | { | ||
501 | cd = cd->next; | ||
502 | continue; | ||
503 | } | ||
504 | tmp = cd; | ||
505 | cd = cd->next; | ||
506 | GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head, | ||
507 | vrh->cred_chain_tail, | ||
508 | tmp); | ||
509 | GNUNET_free (tmp->credential); | ||
510 | GNUNET_free (tmp); | ||
511 | vrh->cred_chain_size--; | ||
512 | } | ||
513 | |||
514 | /** | ||
515 | * Get serialized record data | ||
516 | * Append at the end of rmsg | ||
517 | */ | ||
518 | cd = vrh->cred_chain_head; | ||
519 | for (uint32_t i=0;i<vrh->cred_chain_size;i++) | ||
520 | { | ||
521 | cred[i].issuer_key = cd->credential->issuer_key; | ||
522 | cred[i].subject_key = cd->credential->subject_key; | ||
523 | cred[i].issuer_attribute_len = strlen(cd->credential->issuer_attribute)+1; | ||
524 | cred[i].issuer_attribute = cd->credential->issuer_attribute; | ||
525 | cred[i].expiration = cd->credential->expiration; | ||
526 | cred[i].signature = cd->credential->signature; | ||
527 | cd = cd->next; | ||
528 | } | ||
529 | size = GNUNET_CREDENTIAL_delegation_chain_get_size (vrh->delegation_chain_size, | ||
530 | dd, | ||
531 | vrh->cred_chain_size, | ||
532 | cred); | ||
533 | env = GNUNET_MQ_msg_extra (rmsg, | ||
534 | size, | ||
535 | GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT); | ||
536 | //Assign id so that client can find associated request | ||
537 | rmsg->id = vrh->request_id; | ||
538 | rmsg->d_count = htonl (vrh->delegation_chain_size); | ||
539 | rmsg->c_count = htonl (vrh->cred_chain_size); | ||
540 | |||
541 | if (0 < vrh->cred_chain_size) | ||
542 | rmsg->cred_found = htonl (GNUNET_YES); | ||
543 | else | ||
544 | rmsg->cred_found = htonl (GNUNET_NO); | ||
545 | |||
546 | GNUNET_assert (-1 != | ||
547 | GNUNET_CREDENTIAL_delegation_chain_serialize (vrh->delegation_chain_size, | ||
548 | dd, | ||
549 | vrh->cred_chain_size, | ||
550 | cred, | ||
551 | size, | ||
552 | (char*)&rmsg[1])); | ||
553 | |||
554 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(vrh->client), | ||
555 | env); | ||
556 | GNUNET_CONTAINER_DLL_remove (vrh_head, vrh_tail, vrh); | ||
557 | cleanup_handle(vrh); | ||
558 | |||
559 | GNUNET_STATISTICS_update (statistics, | ||
560 | "Completed verifications", 1, | ||
561 | GNUNET_NO); | ||
562 | } | ||
563 | |||
564 | |||
565 | static void | ||
566 | backward_resolution (void* cls, | ||
567 | uint32_t rd_count, | ||
568 | const struct GNUNET_GNSRECORD_Data *rd) | ||
569 | { | ||
570 | |||
571 | struct VerifyRequestHandle *vrh; | ||
572 | const struct GNUNET_CREDENTIAL_DelegationRecord *sets; | ||
573 | struct CredentialRecordEntry *cred_pointer; | ||
574 | struct DelegationSetQueueEntry *current_set; | ||
575 | struct DelegationSetQueueEntry *ds_entry; | ||
576 | struct DelegationSetQueueEntry *tmp_set; | ||
577 | struct DelegationQueueEntry *dq_entry; | ||
578 | char *expanded_attr; | ||
579 | char *lookup_attribute; | ||
580 | |||
581 | |||
582 | current_set = cls; | ||
583 | current_set->lookup_request = NULL; | ||
584 | vrh = current_set->handle; | ||
585 | vrh->pending_lookups--; | ||
586 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
587 | "Got %d attrs\n", rd_count); | ||
588 | |||
589 | // Each OR | ||
590 | for (uint32_t i=0; i < rd_count; i++) | ||
591 | { | ||
592 | if (GNUNET_GNSRECORD_TYPE_ATTRIBUTE != rd[i].record_type) | ||
593 | continue; | ||
594 | |||
595 | sets = rd[i].data; | ||
596 | struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets->set_count)]; | ||
597 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
598 | "Found new attribute delegation with %d sets. Creating new Job...\n", | ||
599 | ntohl (sets->set_count)); | ||
600 | |||
601 | if (GNUNET_OK !=GNUNET_CREDENTIAL_delegation_set_deserialize (GNUNET_ntohll(sets->data_size), | ||
602 | (const char*)&sets[1], | ||
603 | ntohl(sets->set_count), | ||
604 | set)) | ||
605 | { | ||
606 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
607 | "Failed to deserialize!\n"); | ||
608 | continue; | ||
609 | } | ||
610 | dq_entry = GNUNET_new (struct DelegationQueueEntry); | ||
611 | dq_entry->required_solutions = ntohl(sets->set_count); | ||
612 | dq_entry->parent_set = current_set; | ||
613 | GNUNET_CONTAINER_DLL_insert (current_set->queue_entries_head, | ||
614 | current_set->queue_entries_tail, | ||
615 | dq_entry); | ||
616 | // Each AND | ||
617 | for (uint32_t j=0; j<ntohl(sets->set_count); j++) | ||
618 | { | ||
619 | ds_entry = GNUNET_new (struct DelegationSetQueueEntry); | ||
620 | if (NULL != current_set->attr_trailer) | ||
621 | { | ||
622 | if (0 == set[j].subject_attribute_len) | ||
623 | { | ||
624 | GNUNET_asprintf (&expanded_attr, | ||
625 | "%s", | ||
626 | current_set->attr_trailer); | ||
627 | |||
628 | } else { | ||
629 | GNUNET_asprintf (&expanded_attr, | ||
630 | "%s.%s", | ||
631 | set[j].subject_attribute, | ||
632 | current_set->attr_trailer); | ||
633 | } | ||
634 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
635 | "Expanded to %s\n", expanded_attr); | ||
636 | ds_entry->unresolved_attribute_delegation = expanded_attr; | ||
637 | } else { | ||
638 | if (0 != set[j].subject_attribute_len) | ||
639 | { | ||
640 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
641 | "Not Expanding %s\n", set[j].subject_attribute); | ||
642 | ds_entry->unresolved_attribute_delegation = GNUNET_strdup (set[j].subject_attribute); | ||
643 | } | ||
644 | } | ||
645 | |||
646 | //Add a credential chain entry | ||
647 | ds_entry->delegation_chain_entry = GNUNET_new (struct DelegationChainEntry); | ||
648 | ds_entry->delegation_chain_entry->subject_key = set[j].subject_key; | ||
649 | ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
650 | GNUNET_memcpy (ds_entry->issuer_key, | ||
651 | &set[j].subject_key, | ||
652 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
653 | if (0 < set[j].subject_attribute_len) | ||
654 | ds_entry->delegation_chain_entry->subject_attribute = GNUNET_strdup (set[j].subject_attribute); | ||
655 | ds_entry->delegation_chain_entry->issuer_key = *current_set->issuer_key; | ||
656 | ds_entry->delegation_chain_entry->issuer_attribute = GNUNET_strdup (current_set->lookup_attribute); | ||
657 | |||
658 | ds_entry->parent_queue_entry = dq_entry; //current_delegation; | ||
659 | GNUNET_CONTAINER_DLL_insert (dq_entry->set_entries_head, | ||
660 | dq_entry->set_entries_tail, | ||
661 | ds_entry); | ||
662 | |||
663 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
664 | "Checking for cred match\n"); | ||
665 | /** | ||
666 | * Check if this delegation already matches one of our credentials | ||
667 | */ | ||
668 | for(cred_pointer = vrh->cred_chain_head; cred_pointer != NULL; | ||
669 | cred_pointer = cred_pointer->next) | ||
670 | { | ||
671 | if(0 != memcmp (&set->subject_key, | ||
672 | &cred_pointer->credential->issuer_key, | ||
673 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
674 | continue; | ||
675 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
676 | "Checking if %s matches %s\n", | ||
677 | ds_entry->unresolved_attribute_delegation, | ||
678 | cred_pointer->credential->issuer_attribute); | ||
679 | |||
680 | if (0 != strcmp (ds_entry->unresolved_attribute_delegation, | ||
681 | cred_pointer->credential->issuer_attribute)) | ||
682 | continue; | ||
683 | |||
684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
685 | "Found issuer\n"); | ||
686 | cred_pointer->refcount++; | ||
687 | //Backtrack | ||
688 | for (tmp_set = ds_entry; | ||
689 | NULL != tmp_set->parent_queue_entry; | ||
690 | tmp_set = tmp_set->parent_queue_entry->parent_set) | ||
691 | { | ||
692 | tmp_set->parent_queue_entry->required_solutions--; | ||
693 | if (NULL != tmp_set->delegation_chain_entry) | ||
694 | { | ||
695 | vrh->delegation_chain_size++; | ||
696 | GNUNET_CONTAINER_DLL_insert (vrh->delegation_chain_head, | ||
697 | vrh->delegation_chain_tail, | ||
698 | tmp_set->delegation_chain_entry); | ||
699 | } | ||
700 | if (0 < tmp_set->parent_queue_entry->required_solutions) | ||
701 | break; | ||
702 | } | ||
703 | |||
704 | if (NULL == tmp_set->parent_queue_entry) | ||
705 | { | ||
706 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
707 | "All solutions found\n"); | ||
708 | //Found match | ||
709 | send_lookup_response (vrh); | ||
710 | return; | ||
711 | } | ||
712 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
713 | "Not all solutions found yet.\n"); | ||
714 | continue; | ||
715 | |||
716 | } | ||
717 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
718 | "Building new lookup request from %s\n", | ||
719 | ds_entry->unresolved_attribute_delegation); | ||
720 | //Continue with backward resolution | ||
721 | char issuer_attribute_name[strlen (ds_entry->unresolved_attribute_delegation)+1]; | ||
722 | strcpy (issuer_attribute_name, | ||
723 | ds_entry->unresolved_attribute_delegation); | ||
724 | char *next_attr = strtok (issuer_attribute_name, "."); | ||
725 | GNUNET_asprintf (&lookup_attribute, | ||
726 | "%s.gnu", | ||
727 | next_attr); | ||
728 | GNUNET_asprintf (&ds_entry->lookup_attribute, | ||
729 | "%s", | ||
730 | next_attr); | ||
731 | if (strlen (next_attr) == strlen (ds_entry->unresolved_attribute_delegation)) | ||
732 | { | ||
733 | ds_entry->attr_trailer = NULL; | ||
734 | } else { | ||
735 | next_attr += strlen (next_attr) + 1; | ||
736 | ds_entry->attr_trailer = GNUNET_strdup (next_attr); | ||
737 | } | ||
738 | |||
739 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
740 | "Looking up %s\n", ds_entry->lookup_attribute); | ||
741 | if (NULL != ds_entry->attr_trailer) | ||
742 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
743 | "%s still to go...\n", ds_entry->attr_trailer); | ||
744 | |||
745 | vrh->pending_lookups++; | ||
746 | ds_entry->handle = vrh; | ||
747 | ds_entry->lookup_request = GNUNET_GNS_lookup (gns, | ||
748 | lookup_attribute, | ||
749 | ds_entry->issuer_key, //issuer_key, | ||
750 | GNUNET_GNSRECORD_TYPE_ATTRIBUTE, | ||
751 | GNUNET_GNS_LO_DEFAULT, | ||
752 | &backward_resolution, | ||
753 | ds_entry); | ||
754 | GNUNET_free (lookup_attribute); | ||
755 | } | ||
756 | } | ||
757 | |||
758 | if(0 == vrh->pending_lookups) | ||
759 | { | ||
760 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
761 | "We are all out of attributes...\n"); | ||
762 | send_lookup_response (vrh); | ||
763 | return; | ||
764 | |||
765 | } | ||
766 | } | ||
767 | |||
768 | |||
769 | /** | ||
770 | * Result from GNS lookup. | ||
771 | * | ||
772 | * @param cls the closure (our client lookup handle) | ||
773 | */ | ||
774 | static void | ||
775 | delegation_chain_resolution_start (void* cls) | ||
776 | { | ||
777 | struct VerifyRequestHandle *vrh = cls; | ||
778 | struct DelegationSetQueueEntry *ds_entry; | ||
779 | struct CredentialRecordEntry *cr_entry; | ||
780 | vrh->lookup_request = NULL; | ||
781 | |||
782 | if (0 == vrh->cred_chain_size) | ||
783 | { | ||
784 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
785 | "No credentials found\n"); | ||
786 | send_lookup_response (vrh); | ||
787 | return; | ||
788 | } | ||
789 | |||
790 | for (cr_entry = vrh->cred_chain_head; cr_entry != NULL; cr_entry = cr_entry->next) | ||
791 | { | ||
792 | if (0 != memcmp (&cr_entry->credential->issuer_key, | ||
793 | &vrh->issuer_key, | ||
794 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
795 | continue; | ||
796 | if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute)) | ||
797 | continue; | ||
798 | cr_entry->refcount++; | ||
799 | //Found match prematurely | ||
800 | send_lookup_response (vrh); | ||
801 | return; | ||
802 | |||
803 | } | ||
804 | |||
805 | /** | ||
806 | * Check for attributes from the issuer and follow the chain | ||
807 | * till you get the required subject's attributes | ||
808 | */ | ||
809 | char issuer_attribute_name[strlen (vrh->issuer_attribute)]; | ||
810 | strcpy (issuer_attribute_name, | ||
811 | vrh->issuer_attribute); | ||
812 | strcpy (issuer_attribute_name + strlen (vrh->issuer_attribute), | ||
813 | ".gnu"); | ||
814 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
815 | "Looking up %s\n", issuer_attribute_name); | ||
816 | ds_entry = GNUNET_new (struct DelegationSetQueueEntry); | ||
817 | ds_entry->issuer_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
818 | memcpy (ds_entry->issuer_key, | ||
819 | &vrh->issuer_key, | ||
820 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
821 | ds_entry->issuer_attribute = GNUNET_strdup (vrh->issuer_attribute); | ||
822 | ds_entry->handle = vrh; | ||
823 | ds_entry->lookup_attribute = GNUNET_strdup (vrh->issuer_attribute); | ||
824 | vrh->root_set = ds_entry; | ||
825 | vrh->pending_lookups = 1; | ||
826 | //Start with backward resolution | ||
827 | ds_entry->lookup_request = GNUNET_GNS_lookup (gns, | ||
828 | issuer_attribute_name, | ||
829 | &vrh->issuer_key, //issuer_key, | ||
830 | GNUNET_GNSRECORD_TYPE_ATTRIBUTE, | ||
831 | GNUNET_GNS_LO_DEFAULT, | ||
832 | &backward_resolution, | ||
833 | ds_entry); | ||
834 | } | ||
835 | |||
836 | static int | ||
837 | check_verify (void *cls, | ||
838 | const struct VerifyMessage *v_msg) | ||
839 | { | ||
840 | size_t msg_size; | ||
841 | const char* attr; | ||
842 | |||
843 | msg_size = ntohs (v_msg->header.size); | ||
844 | if (msg_size < sizeof (struct VerifyMessage)) | ||
845 | { | ||
846 | GNUNET_break (0); | ||
847 | return GNUNET_SYSERR; | ||
848 | } | ||
849 | if (ntohs (v_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) | ||
850 | { | ||
851 | GNUNET_break (0); | ||
852 | return GNUNET_SYSERR; | ||
853 | } | ||
854 | attr = (const char *) &v_msg[1]; | ||
855 | |||
856 | if ( strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) | ||
857 | { | ||
858 | GNUNET_break (0); | ||
859 | return GNUNET_SYSERR; | ||
860 | } | ||
861 | return GNUNET_OK; | ||
862 | } | ||
863 | |||
864 | static void | ||
865 | handle_verify (void *cls, | ||
866 | const struct VerifyMessage *v_msg) | ||
867 | { | ||
868 | struct VerifyRequestHandle *vrh; | ||
869 | struct GNUNET_SERVICE_Client *client = cls; | ||
870 | struct CredentialRecordEntry *cr_entry; | ||
871 | uint32_t credentials_count; | ||
872 | uint32_t credential_data_size; | ||
873 | char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; | ||
874 | char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; | ||
875 | char *attrptr = attr; | ||
876 | char *credential_data; | ||
877 | const char *utf_in; | ||
878 | |||
879 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
880 | "Received VERIFY message\n"); | ||
881 | utf_in = (const char *) &v_msg[1]; | ||
882 | GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); | ||
883 | GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len)); | ||
884 | issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0'; | ||
885 | vrh = GNUNET_new (struct VerifyRequestHandle); | ||
886 | GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh); | ||
887 | vrh->client = client; | ||
888 | vrh->request_id = v_msg->id; | ||
889 | vrh->issuer_key = v_msg->issuer_key; | ||
890 | vrh->subject_key = v_msg->subject_key; | ||
891 | vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); | ||
892 | if (NULL == issuer_attribute) | ||
893 | { | ||
894 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
895 | "No issuer attribute provided!\n"); | ||
896 | send_lookup_response (vrh); | ||
897 | return; | ||
898 | } | ||
899 | /** | ||
900 | * First, collect credentials | ||
901 | * TODO: cleanup! | ||
902 | */ | ||
903 | credentials_count = ntohl(v_msg->c_count); | ||
904 | credential_data_size = ntohs (v_msg->header.size) | ||
905 | - sizeof (struct VerifyMessage) | ||
906 | - ntohs (v_msg->issuer_attribute_len) | ||
907 | - 1; | ||
908 | struct GNUNET_CREDENTIAL_Credential credentials[credentials_count]; | ||
909 | credential_data = (char*)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1; | ||
910 | if (GNUNET_OK != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size, | ||
911 | credential_data, | ||
912 | credentials_count, | ||
913 | credentials)) | ||
914 | { | ||
915 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
916 | "Cannot deserialize credentials!\n"); | ||
917 | send_lookup_response (vrh); | ||
918 | return; | ||
919 | } | ||
920 | |||
921 | for (uint32_t i=0;i<credentials_count;i++) { | ||
922 | cr_entry = GNUNET_new (struct CredentialRecordEntry); | ||
923 | cr_entry->credential = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + | ||
924 | credentials[i].issuer_attribute_len); | ||
925 | GNUNET_memcpy (cr_entry->credential, | ||
926 | &credentials[i], | ||
927 | sizeof (struct GNUNET_CREDENTIAL_Credential)); | ||
928 | GNUNET_memcpy (&cr_entry->credential[1], | ||
929 | credentials[i].issuer_attribute, | ||
930 | credentials[i].issuer_attribute_len); | ||
931 | cr_entry->credential->issuer_attribute = (char*)&cr_entry->credential[1]; | ||
932 | GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, | ||
933 | vrh->cred_chain_tail, | ||
934 | cr_entry); | ||
935 | vrh->cred_chain_size++; | ||
936 | } | ||
937 | |||
938 | delegation_chain_resolution_start (vrh); | ||
939 | |||
940 | } | ||
941 | |||
942 | static void | ||
943 | handle_cred_collection_error_cb (void *cls) | ||
944 | { | ||
945 | struct VerifyRequestHandle *vrh = cls; | ||
946 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
947 | "Got disconnected from namestore database.\n"); | ||
948 | vrh->cred_collection_iter = NULL; | ||
949 | send_lookup_response (vrh); | ||
950 | } | ||
951 | |||
952 | static void | ||
953 | collect_next (void *cls) | ||
954 | { | ||
955 | struct VerifyRequestHandle *vrh = cls; | ||
956 | vrh->collect_next_task = NULL; | ||
957 | GNUNET_assert (NULL != vrh->cred_collection_iter); | ||
958 | GNUNET_NAMESTORE_zone_iterator_next (vrh->cred_collection_iter); | ||
959 | } | ||
960 | |||
961 | static void | ||
962 | handle_cred_collection_cb (void *cls, | ||
963 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, | ||
964 | const char *label, | ||
965 | unsigned int rd_count, | ||
966 | const struct GNUNET_GNSRECORD_Data *rd) | ||
967 | { | ||
968 | struct VerifyRequestHandle *vrh = cls; | ||
969 | struct GNUNET_CREDENTIAL_Credential *crd; | ||
970 | struct CredentialRecordEntry *cr_entry; | ||
971 | int cred_record_count; | ||
972 | |||
973 | cred_record_count = 0; | ||
974 | for (uint32_t i=0; i < rd_count; i++) | ||
975 | { | ||
976 | if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) | ||
977 | continue; | ||
978 | cred_record_count++; | ||
979 | crd = GNUNET_CREDENTIAL_credential_deserialize (rd[i].data, | ||
980 | rd[i].data_size); | ||
981 | if (NULL == crd) | ||
982 | { | ||
983 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
984 | "Invalid credential found\n"); | ||
985 | continue; | ||
986 | } | ||
987 | cr_entry = GNUNET_new (struct CredentialRecordEntry); | ||
988 | cr_entry->credential = crd; | ||
989 | GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head, | ||
990 | vrh->cred_chain_tail, | ||
991 | cr_entry); | ||
992 | vrh->cred_chain_size++; | ||
993 | } | ||
994 | vrh->collect_next_task = GNUNET_SCHEDULER_add_now (&collect_next, | ||
995 | vrh); | ||
996 | } | ||
997 | |||
998 | static void | ||
999 | handle_cred_collection_finished_cb (void *cls) | ||
1000 | { | ||
1001 | struct VerifyRequestHandle *vrh = cls; | ||
1002 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1003 | "Done collecting credentials.\n"); | ||
1004 | vrh->cred_collection_iter = NULL; | ||
1005 | delegation_chain_resolution_start (vrh); | ||
1006 | } | ||
1007 | |||
1008 | static void | ||
1009 | handle_collect (void *cls, | ||
1010 | const struct CollectMessage *c_msg) | ||
1011 | { | ||
1012 | char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; | ||
1013 | char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; | ||
1014 | struct VerifyRequestHandle *vrh; | ||
1015 | struct GNUNET_SERVICE_Client *client = cls; | ||
1016 | char *attrptr = attr; | ||
1017 | const char *utf_in; | ||
1018 | |||
1019 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1020 | "Received COLLECT message\n"); | ||
1021 | |||
1022 | utf_in = (const char *) &c_msg[1]; | ||
1023 | GNUNET_STRINGS_utf8_tolower (utf_in, attrptr); | ||
1024 | |||
1025 | GNUNET_memcpy (issuer_attribute, attr, ntohs (c_msg->issuer_attribute_len)); | ||
1026 | issuer_attribute[ntohs (c_msg->issuer_attribute_len)] = '\0'; | ||
1027 | vrh = GNUNET_new (struct VerifyRequestHandle); | ||
1028 | GNUNET_CONTAINER_DLL_insert (vrh_head, vrh_tail, vrh); | ||
1029 | vrh->client = client; | ||
1030 | vrh->request_id = c_msg->id; | ||
1031 | vrh->issuer_key = c_msg->issuer_key; | ||
1032 | GNUNET_CRYPTO_ecdsa_key_get_public (&c_msg->subject_key, | ||
1033 | &vrh->subject_key); | ||
1034 | vrh->issuer_attribute = GNUNET_strdup (issuer_attribute); | ||
1035 | |||
1036 | if (NULL == issuer_attribute) | ||
1037 | { | ||
1038 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1039 | "No issuer attribute provided!\n"); | ||
1040 | send_lookup_response (vrh); | ||
1041 | return; | ||
1042 | } | ||
1043 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1044 | "Getting credentials for subject\n"); | ||
1045 | /** | ||
1046 | * First, get attribute from subject | ||
1047 | */ | ||
1048 | vrh->cred_collection_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore, | ||
1049 | &c_msg->subject_key, | ||
1050 | &handle_cred_collection_error_cb, | ||
1051 | vrh, | ||
1052 | &handle_cred_collection_cb, | ||
1053 | vrh, | ||
1054 | &handle_cred_collection_finished_cb, | ||
1055 | vrh); | ||
1056 | } | ||
1057 | |||
1058 | |||
1059 | static int | ||
1060 | check_collect (void *cls, | ||
1061 | const struct CollectMessage *c_msg) | ||
1062 | { | ||
1063 | size_t msg_size; | ||
1064 | const char* attr; | ||
1065 | |||
1066 | msg_size = ntohs (c_msg->header.size); | ||
1067 | if (msg_size < sizeof (struct CollectMessage)) | ||
1068 | { | ||
1069 | GNUNET_break (0); | ||
1070 | return GNUNET_SYSERR; | ||
1071 | } | ||
1072 | if (ntohs (c_msg->issuer_attribute_len) > GNUNET_CREDENTIAL_MAX_LENGTH) | ||
1073 | { | ||
1074 | GNUNET_break (0); | ||
1075 | return GNUNET_SYSERR; | ||
1076 | } | ||
1077 | attr = (const char *) &c_msg[1]; | ||
1078 | |||
1079 | if ( ('\0' != attr[ntohs(c_msg->header.size) - sizeof (struct CollectMessage) - 1]) || | ||
1080 | (strlen (attr) > GNUNET_CREDENTIAL_MAX_LENGTH) ) | ||
1081 | { | ||
1082 | GNUNET_break (0); | ||
1083 | return GNUNET_SYSERR; | ||
1084 | } | ||
1085 | return GNUNET_OK; | ||
1086 | } | ||
1087 | |||
1088 | static void | ||
1089 | client_disconnect_cb (void *cls, | ||
1090 | struct GNUNET_SERVICE_Client *client, | ||
1091 | void *app_ctx) | ||
1092 | { | ||
1093 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1094 | "Client %p disconnected\n", | ||
1095 | client); | ||
1096 | } | ||
1097 | |||
1098 | static void * | ||
1099 | client_connect_cb (void *cls, | ||
1100 | struct GNUNET_SERVICE_Client *client, | ||
1101 | struct GNUNET_MQ_Handle *mq) | ||
1102 | { | ||
1103 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1104 | "Client %p connected\n", | ||
1105 | client); | ||
1106 | return client; | ||
1107 | } | ||
1108 | |||
1109 | /** | ||
1110 | * Process Credential requests. | ||
1111 | * | ||
1112 | * @param cls closure | ||
1113 | * @param c configuration to use | ||
1114 | * @param handle service handle | ||
1115 | */ | ||
1116 | static void | ||
1117 | run (void *cls, | ||
1118 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
1119 | struct GNUNET_SERVICE_Handle *handle) | ||
1120 | { | ||
1121 | |||
1122 | gns = GNUNET_GNS_connect (c); | ||
1123 | if (NULL == gns) | ||
1124 | { | ||
1125 | fprintf (stderr, | ||
1126 | _("Failed to connect to GNS\n")); | ||
1127 | } | ||
1128 | namestore = GNUNET_NAMESTORE_connect (c); | ||
1129 | if (NULL == namestore) | ||
1130 | { | ||
1131 | fprintf (stderr, | ||
1132 | _("Failed to connect to namestore\n")); | ||
1133 | } | ||
1134 | |||
1135 | statistics = GNUNET_STATISTICS_create ("credential", c); | ||
1136 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | ||
1137 | } | ||
1138 | |||
1139 | |||
1140 | /** | ||
1141 | * Define "main" method using service macro | ||
1142 | */ | ||
1143 | GNUNET_SERVICE_MAIN | ||
1144 | ("credential", | ||
1145 | GNUNET_SERVICE_OPTION_NONE, | ||
1146 | &run, | ||
1147 | &client_connect_cb, | ||
1148 | &client_disconnect_cb, | ||
1149 | NULL, | ||
1150 | GNUNET_MQ_hd_var_size (verify, | ||
1151 | GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY, | ||
1152 | struct VerifyMessage, | ||
1153 | NULL), | ||
1154 | GNUNET_MQ_hd_var_size (collect, | ||
1155 | GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT, | ||
1156 | struct CollectMessage, | ||
1157 | NULL), | ||
1158 | GNUNET_MQ_handler_end()); | ||
1159 | |||
1160 | /* end of gnunet-service-credential.c */ | ||
diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c new file mode 100644 index 000000000..342790b7a --- /dev/null +++ b/src/credential/plugin_gnsrecord_credential.c | |||
@@ -0,0 +1,353 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file credential/plugin_gnsrecord_credential.c | ||
23 | * @brief gnsrecord plugin to provide the API for CREDENTIAL records | ||
24 | * @author Martin Schanzenbach | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_gnsrecord_lib.h" | ||
30 | #include "gnunet_credential_service.h" | ||
31 | #include "gnunet_gnsrecord_plugin.h" | ||
32 | #include "gnunet_signatures.h" | ||
33 | #include "credential_serialization.h" | ||
34 | #include "credential_misc.h" | ||
35 | |||
36 | /** | ||
37 | * Convert the 'value' of a record to a string. | ||
38 | * | ||
39 | * @param cls closure, unused | ||
40 | * @param type type of the record | ||
41 | * @param data value in binary encoding | ||
42 | * @param data_size number of bytes in @a data | ||
43 | * @return NULL on error, otherwise human-readable representation of the value | ||
44 | */ | ||
45 | static char * | ||
46 | credential_value_to_string (void *cls, | ||
47 | uint32_t type, | ||
48 | const void *data, | ||
49 | size_t data_size) | ||
50 | { | ||
51 | |||
52 | const char *cdata; | ||
53 | |||
54 | switch (type) | ||
55 | { | ||
56 | case GNUNET_GNSRECORD_TYPE_ATTRIBUTE: | ||
57 | { | ||
58 | struct GNUNET_CREDENTIAL_DelegationRecord sets; | ||
59 | char *attr_str; | ||
60 | char *subject_pkey; | ||
61 | char *tmp_str; | ||
62 | int i; | ||
63 | if (data_size < sizeof (struct GNUNET_CREDENTIAL_DelegationRecord)) | ||
64 | return NULL; /* malformed */ | ||
65 | memcpy (&sets, | ||
66 | data, | ||
67 | sizeof (sets)); | ||
68 | cdata = data; | ||
69 | struct GNUNET_CREDENTIAL_DelegationSet set[ntohl(sets.set_count)]; | ||
70 | if (GNUNET_OK != GNUNET_CREDENTIAL_delegation_set_deserialize (GNUNET_ntohll (sets.data_size), | ||
71 | &cdata[sizeof (sets)], | ||
72 | ntohl (sets.set_count), | ||
73 | set)) | ||
74 | return NULL; | ||
75 | |||
76 | for (i=0;i<ntohl(sets.set_count);i++) | ||
77 | { | ||
78 | subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&set[i].subject_key); | ||
79 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
80 | "%d len attr\n", set[i].subject_attribute_len); | ||
81 | if (0 == set[i].subject_attribute_len) | ||
82 | { | ||
83 | if (0 == i) | ||
84 | { | ||
85 | GNUNET_asprintf (&attr_str, | ||
86 | "%s", | ||
87 | subject_pkey); | ||
88 | } else { | ||
89 | GNUNET_asprintf (&tmp_str, | ||
90 | "%s,%s", | ||
91 | attr_str, | ||
92 | subject_pkey); | ||
93 | GNUNET_free (attr_str); | ||
94 | attr_str = tmp_str; | ||
95 | } | ||
96 | } else { | ||
97 | if (0 == i) | ||
98 | { | ||
99 | GNUNET_asprintf (&attr_str, | ||
100 | "%s %s", | ||
101 | subject_pkey, | ||
102 | set[i].subject_attribute); | ||
103 | } else { | ||
104 | GNUNET_asprintf (&tmp_str, | ||
105 | "%s,%s %s", | ||
106 | attr_str, | ||
107 | subject_pkey, | ||
108 | set[i].subject_attribute); | ||
109 | GNUNET_free (attr_str); | ||
110 | attr_str = tmp_str; | ||
111 | } | ||
112 | } | ||
113 | GNUNET_free (subject_pkey); | ||
114 | } | ||
115 | return attr_str; | ||
116 | } | ||
117 | case GNUNET_GNSRECORD_TYPE_CREDENTIAL: | ||
118 | { | ||
119 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
120 | char *cred_str; | ||
121 | |||
122 | cred = GNUNET_CREDENTIAL_credential_deserialize (data, | ||
123 | data_size); | ||
124 | cred_str = GNUNET_CREDENTIAL_credential_to_string (cred); | ||
125 | GNUNET_free (cred); | ||
126 | return cred_str; | ||
127 | } | ||
128 | case GNUNET_GNSRECORD_TYPE_POLICY: | ||
129 | { | ||
130 | return GNUNET_strndup (data,data_size); | ||
131 | } | ||
132 | default: | ||
133 | return NULL; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Convert human-readable version of a 'value' of a record to the binary | ||
140 | * representation. | ||
141 | * | ||
142 | * @param cls closure, unused | ||
143 | * @param type type of the record | ||
144 | * @param s human-readable string | ||
145 | * @param data set to value in binary encoding (will be allocated) | ||
146 | * @param data_size set to number of bytes in @a data | ||
147 | * @return #GNUNET_OK on success | ||
148 | */ | ||
149 | static int | ||
150 | credential_string_to_value (void *cls, | ||
151 | uint32_t type, | ||
152 | const char *s, | ||
153 | void **data, | ||
154 | size_t *data_size) | ||
155 | { | ||
156 | if (NULL == s) | ||
157 | return GNUNET_SYSERR; | ||
158 | switch (type) | ||
159 | { | ||
160 | case GNUNET_GNSRECORD_TYPE_ATTRIBUTE: | ||
161 | { | ||
162 | struct GNUNET_CREDENTIAL_DelegationRecord *sets; | ||
163 | char attr_str[253 + 1]; | ||
164 | char subject_pkey[52 + 1]; | ||
165 | char *token; | ||
166 | char *tmp_str; | ||
167 | int matches = 0; | ||
168 | int entries; | ||
169 | size_t tmp_data_size; | ||
170 | int i; | ||
171 | |||
172 | tmp_str = GNUNET_strdup (s); | ||
173 | token = strtok (tmp_str, ","); | ||
174 | entries = 0; | ||
175 | tmp_data_size = 0; | ||
176 | *data_size = sizeof (struct GNUNET_CREDENTIAL_DelegationRecord); | ||
177 | while (NULL != token) | ||
178 | { | ||
179 | matches = SSCANF (token, | ||
180 | "%s %s", | ||
181 | subject_pkey, | ||
182 | attr_str); | ||
183 | if (0 == matches) | ||
184 | { | ||
185 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
186 | _("Unable to parse ATTR record string `%s'\n"), | ||
187 | s); | ||
188 | GNUNET_free (tmp_str); | ||
189 | return GNUNET_SYSERR; | ||
190 | } | ||
191 | if (1 == matches) { | ||
192 | tmp_data_size += sizeof (struct GNUNET_CREDENTIAL_DelegationRecordSet); | ||
193 | } else if (2 == matches) { | ||
194 | tmp_data_size += sizeof (struct GNUNET_CREDENTIAL_DelegationRecordSet) + strlen (attr_str) + 1; | ||
195 | } | ||
196 | entries++; | ||
197 | token = strtok (NULL, ","); | ||
198 | } | ||
199 | GNUNET_free (tmp_str); | ||
200 | tmp_str = GNUNET_strdup (s); | ||
201 | token = strtok (tmp_str, ","); | ||
202 | struct GNUNET_CREDENTIAL_DelegationSet set[entries]; | ||
203 | for (i=0;i<entries;i++) | ||
204 | { | ||
205 | matches = SSCANF (token, | ||
206 | "%s %s", | ||
207 | subject_pkey, | ||
208 | attr_str); | ||
209 | GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, | ||
210 | strlen (subject_pkey), | ||
211 | &set[i].subject_key); | ||
212 | if (2 == matches) { | ||
213 | set[i].subject_attribute_len = strlen (attr_str) + 1; | ||
214 | set[i].subject_attribute = GNUNET_strdup (attr_str); | ||
215 | } | ||
216 | token = strtok (NULL , ","); | ||
217 | } | ||
218 | tmp_data_size = GNUNET_CREDENTIAL_delegation_set_get_size (entries, | ||
219 | set); | ||
220 | |||
221 | if (-1 == tmp_data_size) | ||
222 | return GNUNET_SYSERR; | ||
223 | *data_size += tmp_data_size; | ||
224 | *data = sets = GNUNET_malloc (*data_size); | ||
225 | GNUNET_CREDENTIAL_delegation_set_serialize (entries, | ||
226 | set, | ||
227 | tmp_data_size, | ||
228 | (char*)&sets[1]); | ||
229 | for (i=0;i<entries;i++) | ||
230 | { | ||
231 | if (0 != set[i].subject_attribute_len) | ||
232 | GNUNET_free ((char*)set[i].subject_attribute); | ||
233 | } | ||
234 | sets->set_count = htonl (entries); | ||
235 | sets->data_size = GNUNET_htonll (tmp_data_size); | ||
236 | |||
237 | GNUNET_free (tmp_str); | ||
238 | return GNUNET_OK; | ||
239 | } | ||
240 | case GNUNET_GNSRECORD_TYPE_CREDENTIAL: | ||
241 | { | ||
242 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
243 | cred = GNUNET_CREDENTIAL_credential_from_string (s); | ||
244 | |||
245 | *data_size = GNUNET_CREDENTIAL_credential_serialize (cred, | ||
246 | (char**)data); | ||
247 | return GNUNET_OK; | ||
248 | } | ||
249 | case GNUNET_GNSRECORD_TYPE_POLICY: | ||
250 | { | ||
251 | *data_size = strlen (s); | ||
252 | *data = GNUNET_strdup (s); | ||
253 | return GNUNET_OK; | ||
254 | } | ||
255 | default: | ||
256 | return GNUNET_SYSERR; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | |||
261 | /** | ||
262 | * Mapping of record type numbers to human-readable | ||
263 | * record type names. | ||
264 | */ | ||
265 | static struct { | ||
266 | const char *name; | ||
267 | uint32_t number; | ||
268 | } name_map[] = { | ||
269 | { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL }, | ||
270 | { "ATTR", GNUNET_GNSRECORD_TYPE_ATTRIBUTE }, | ||
271 | { "POLICY", GNUNET_GNSRECORD_TYPE_POLICY }, | ||
272 | { NULL, UINT32_MAX } | ||
273 | }; | ||
274 | |||
275 | |||
276 | /** | ||
277 | * Convert a type name (i.e. "AAAA") to the corresponding number. | ||
278 | * | ||
279 | * @param cls closure, unused | ||
280 | * @param gns_typename name to convert | ||
281 | * @return corresponding number, UINT32_MAX on error | ||
282 | */ | ||
283 | static uint32_t | ||
284 | credential_typename_to_number (void *cls, | ||
285 | const char *gns_typename) | ||
286 | { | ||
287 | unsigned int i; | ||
288 | |||
289 | i=0; | ||
290 | while ( (name_map[i].name != NULL) && | ||
291 | (0 != strcasecmp (gns_typename, name_map[i].name)) ) | ||
292 | i++; | ||
293 | return name_map[i].number; | ||
294 | } | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A") | ||
299 | * | ||
300 | * @param cls closure, unused | ||
301 | * @param type number of a type to convert | ||
302 | * @return corresponding typestring, NULL on error | ||
303 | */ | ||
304 | static const char * | ||
305 | credential_number_to_typename (void *cls, | ||
306 | uint32_t type) | ||
307 | { | ||
308 | unsigned int i; | ||
309 | |||
310 | i=0; | ||
311 | while ( (name_map[i].name != NULL) && | ||
312 | (type != name_map[i].number) ) | ||
313 | i++; | ||
314 | return name_map[i].name; | ||
315 | } | ||
316 | |||
317 | |||
318 | /** | ||
319 | * Entry point for the plugin. | ||
320 | * | ||
321 | * @param cls NULL | ||
322 | * @return the exported block API | ||
323 | */ | ||
324 | void * | ||
325 | libgnunet_plugin_gnsrecord_credential_init (void *cls) | ||
326 | { | ||
327 | struct GNUNET_GNSRECORD_PluginFunctions *api; | ||
328 | |||
329 | api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions); | ||
330 | api->value_to_string = &credential_value_to_string; | ||
331 | api->string_to_value = &credential_string_to_value; | ||
332 | api->typename_to_number = &credential_typename_to_number; | ||
333 | api->number_to_typename = &credential_number_to_typename; | ||
334 | return api; | ||
335 | } | ||
336 | |||
337 | |||
338 | /** | ||
339 | * Exit point from the plugin. | ||
340 | * | ||
341 | * @param cls the return value from #libgnunet_plugin_block_test_init | ||
342 | * @return NULL | ||
343 | */ | ||
344 | void * | ||
345 | libgnunet_plugin_gnsrecord_credential_done (void *cls) | ||
346 | { | ||
347 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; | ||
348 | |||
349 | GNUNET_free (api); | ||
350 | return NULL; | ||
351 | } | ||
352 | |||
353 | /* end of plugin_gnsrecord_credential.c */ | ||
diff --git a/src/credential/plugin_rest_credential.c b/src/credential/plugin_rest_credential.c new file mode 100644 index 000000000..480658822 --- /dev/null +++ b/src/credential/plugin_rest_credential.c | |||
@@ -0,0 +1,1146 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @author Martin Schanzenbach | ||
22 | * @file credential/plugin_rest_credential.c | ||
23 | * @brief GNUnet CREDENTIAL REST plugin | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_rest_plugin.h" | ||
29 | #include <gnunet_identity_service.h> | ||
30 | #include <gnunet_gnsrecord_lib.h> | ||
31 | #include <gnunet_namestore_service.h> | ||
32 | #include <gnunet_credential_service.h> | ||
33 | #include <gnunet_rest_lib.h> | ||
34 | #include <gnunet_jsonapi_lib.h> | ||
35 | #include <gnunet_jsonapi_util.h> | ||
36 | #include <jansson.h> | ||
37 | |||
38 | #define GNUNET_REST_API_NS_CREDENTIAL "/credential" | ||
39 | |||
40 | #define GNUNET_REST_API_NS_CREDENTIAL_ISSUE "/credential/issue" | ||
41 | |||
42 | #define GNUNET_REST_API_NS_CREDENTIAL_VERIFY "/credential/verify" | ||
43 | |||
44 | #define GNUNET_REST_API_NS_CREDENTIAL_COLLECT "/credential/collect" | ||
45 | |||
46 | #define GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION "expiration" | ||
47 | |||
48 | #define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY "subject_key" | ||
49 | |||
50 | #define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO "subject" | ||
51 | |||
52 | #define GNUNET_REST_JSONAPI_CREDENTIAL "credential" | ||
53 | |||
54 | #define GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO "credential" | ||
55 | |||
56 | #define GNUNET_REST_JSONAPI_DELEGATIONS "delegations" | ||
57 | |||
58 | #define GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR "attribute" | ||
59 | |||
60 | #define GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_ATTR "credential" | ||
61 | |||
62 | /** | ||
63 | * @brief struct returned by the initialization function of the plugin | ||
64 | */ | ||
65 | struct Plugin | ||
66 | { | ||
67 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
68 | }; | ||
69 | |||
70 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
71 | |||
72 | struct RequestHandle | ||
73 | { | ||
74 | /** | ||
75 | * Handle to Credential service. | ||
76 | */ | ||
77 | struct GNUNET_CREDENTIAL_Handle *credential; | ||
78 | |||
79 | /** | ||
80 | * Handle to lookup request | ||
81 | */ | ||
82 | struct GNUNET_CREDENTIAL_Request *verify_request; | ||
83 | |||
84 | /** | ||
85 | * Handle to issue request | ||
86 | */ | ||
87 | struct GNUNET_CREDENTIAL_Request *issue_request; | ||
88 | |||
89 | /** | ||
90 | * Handle to identity | ||
91 | */ | ||
92 | struct GNUNET_IDENTITY_Handle *identity; | ||
93 | |||
94 | /** | ||
95 | * Handle to identity operation | ||
96 | */ | ||
97 | struct GNUNET_IDENTITY_Operation *id_op; | ||
98 | |||
99 | /** | ||
100 | * Handle to ego lookup | ||
101 | */ | ||
102 | struct GNUNET_IDENTITY_EgoLookup *ego_lookup; | ||
103 | |||
104 | /** | ||
105 | * Handle to rest request | ||
106 | */ | ||
107 | struct GNUNET_REST_RequestHandle *rest_handle; | ||
108 | |||
109 | /** | ||
110 | * ID of a task associated with the resolution process. | ||
111 | */ | ||
112 | struct GNUNET_SCHEDULER_Task * timeout_task; | ||
113 | |||
114 | /** | ||
115 | * The root of the received JSON or NULL | ||
116 | */ | ||
117 | json_t *json_root; | ||
118 | |||
119 | /** | ||
120 | * The plugin result processor | ||
121 | */ | ||
122 | GNUNET_REST_ResultProcessor proc; | ||
123 | |||
124 | /** | ||
125 | * The closure of the result processor | ||
126 | */ | ||
127 | void *proc_cls; | ||
128 | |||
129 | /** | ||
130 | * The issuer attribute to verify | ||
131 | */ | ||
132 | char *issuer_attr; | ||
133 | |||
134 | /** | ||
135 | * The subject attribute | ||
136 | */ | ||
137 | char *subject_attr; | ||
138 | |||
139 | /** | ||
140 | * The public key of the issuer | ||
141 | */ | ||
142 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
143 | |||
144 | /** | ||
145 | * The public key of the subject | ||
146 | */ | ||
147 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
148 | |||
149 | /** | ||
150 | * HTTP response code | ||
151 | */ | ||
152 | int response_code; | ||
153 | |||
154 | /** | ||
155 | * Timeout | ||
156 | */ | ||
157 | struct GNUNET_TIME_Relative timeout; | ||
158 | |||
159 | }; | ||
160 | |||
161 | |||
162 | /** | ||
163 | * Cleanup lookup handle. | ||
164 | * | ||
165 | * @param handle Handle to clean up | ||
166 | */ | ||
167 | static void | ||
168 | cleanup_handle (struct RequestHandle *handle) | ||
169 | { | ||
170 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
171 | "Cleaning up\n"); | ||
172 | if (NULL != handle->json_root) | ||
173 | json_decref (handle->json_root); | ||
174 | |||
175 | if (NULL != handle->issuer_attr) | ||
176 | GNUNET_free (handle->issuer_attr); | ||
177 | if (NULL != handle->subject_attr) | ||
178 | GNUNET_free (handle->subject_attr); | ||
179 | if (NULL != handle->verify_request) | ||
180 | GNUNET_CREDENTIAL_request_cancel (handle->verify_request); | ||
181 | if (NULL != handle->credential) | ||
182 | GNUNET_CREDENTIAL_disconnect (handle->credential); | ||
183 | if (NULL != handle->id_op) | ||
184 | GNUNET_IDENTITY_cancel (handle->id_op); | ||
185 | if (NULL != handle->ego_lookup) | ||
186 | GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup); | ||
187 | if (NULL != handle->identity) | ||
188 | GNUNET_IDENTITY_disconnect (handle->identity); | ||
189 | if (NULL != handle->timeout_task) | ||
190 | { | ||
191 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | ||
192 | } | ||
193 | GNUNET_free (handle); | ||
194 | } | ||
195 | |||
196 | |||
197 | static void | ||
198 | do_error (void *cls) | ||
199 | { | ||
200 | struct RequestHandle *handle = cls; | ||
201 | struct MHD_Response *resp; | ||
202 | |||
203 | resp = GNUNET_REST_create_response (NULL); | ||
204 | handle->proc (handle->proc_cls, resp, handle->response_code); | ||
205 | cleanup_handle (handle); | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * Attribute delegation to JSON | ||
210 | * | ||
211 | * @param delegation_chain_entry the DSE | ||
212 | * @return JSON, NULL if failed | ||
213 | */ | ||
214 | static json_t* | ||
215 | attribute_delegation_to_json (struct GNUNET_CREDENTIAL_Delegation *delegation_chain_entry) | ||
216 | { | ||
217 | char *subject; | ||
218 | char *issuer; | ||
219 | json_t *attr_obj; | ||
220 | |||
221 | issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->issuer_key); | ||
222 | if (NULL == issuer) | ||
223 | { | ||
224 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
225 | "Issuer in delegation malformed\n"); | ||
226 | return NULL; | ||
227 | } | ||
228 | subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&delegation_chain_entry->subject_key); | ||
229 | if (NULL == subject) | ||
230 | { | ||
231 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
232 | "Subject in credential malformed\n"); | ||
233 | GNUNET_free (issuer); | ||
234 | return NULL; | ||
235 | } | ||
236 | attr_obj = json_object (); | ||
237 | |||
238 | json_object_set_new (attr_obj, "issuer", json_string (issuer)); | ||
239 | json_object_set_new (attr_obj, "issuer_attribute", | ||
240 | json_string (delegation_chain_entry->issuer_attribute)); | ||
241 | |||
242 | json_object_set_new (attr_obj, "subject", json_string (subject)); | ||
243 | if (0 < delegation_chain_entry->subject_attribute_len) | ||
244 | { | ||
245 | json_object_set_new (attr_obj, "subject_attribute", | ||
246 | json_string (delegation_chain_entry->subject_attribute)); | ||
247 | } | ||
248 | GNUNET_free (issuer); | ||
249 | GNUNET_free (subject); | ||
250 | return attr_obj; | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * JSONAPI resource to Credential | ||
255 | * | ||
256 | * @param res the JSONAPI resource | ||
257 | * @return the resulting credential, NULL if failed | ||
258 | */ | ||
259 | static struct GNUNET_CREDENTIAL_Credential* | ||
260 | json_to_credential (json_t *res) | ||
261 | { | ||
262 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
263 | json_t *tmp; | ||
264 | const char *attribute; | ||
265 | const char *signature; | ||
266 | char *sig; | ||
267 | |||
268 | tmp = json_object_get (res, "attribute"); | ||
269 | if (0 == json_is_string (tmp)) | ||
270 | { | ||
271 | return NULL; | ||
272 | } | ||
273 | attribute = json_string_value (tmp); | ||
274 | cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) | ||
275 | + strlen (attribute)); | ||
276 | cred->issuer_attribute = attribute; | ||
277 | cred->issuer_attribute_len = strlen (attribute); | ||
278 | tmp = json_object_get (res, "issuer"); | ||
279 | if (0 == json_is_string (tmp)) | ||
280 | { | ||
281 | GNUNET_free (cred); | ||
282 | return NULL; | ||
283 | } | ||
284 | |||
285 | GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp), | ||
286 | strlen (json_string_value(tmp)), | ||
287 | &cred->issuer_key); | ||
288 | tmp = json_object_get (res, "subject"); | ||
289 | if (0 == json_is_string (tmp)) | ||
290 | { | ||
291 | GNUNET_free (cred); | ||
292 | return NULL; | ||
293 | } | ||
294 | GNUNET_CRYPTO_ecdsa_public_key_from_string (json_string_value(tmp), | ||
295 | strlen (json_string_value(tmp)), | ||
296 | &cred->subject_key); | ||
297 | |||
298 | tmp = json_object_get (res, "signature"); | ||
299 | if (0 == json_is_string (tmp)) | ||
300 | { | ||
301 | GNUNET_free (cred); | ||
302 | return NULL; | ||
303 | } | ||
304 | signature = json_string_value (tmp); | ||
305 | GNUNET_STRINGS_base64_decode (signature, | ||
306 | strlen (signature), | ||
307 | (char**)&sig); | ||
308 | GNUNET_memcpy (&cred->signature, | ||
309 | sig, | ||
310 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | ||
311 | GNUNET_free (sig); | ||
312 | |||
313 | tmp = json_object_get (res, "expiration"); | ||
314 | if (0 == json_is_integer (tmp)) | ||
315 | { | ||
316 | GNUNET_free (cred); | ||
317 | return NULL; | ||
318 | } | ||
319 | cred->expiration.abs_value_us = json_integer_value (tmp); | ||
320 | return cred; | ||
321 | } | ||
322 | |||
323 | |||
324 | /** | ||
325 | * Credential to JSON | ||
326 | * | ||
327 | * @param cred the credential | ||
328 | * @return the resulting json, NULL if failed | ||
329 | */ | ||
330 | static json_t* | ||
331 | credential_to_json (struct GNUNET_CREDENTIAL_Credential *cred) | ||
332 | { | ||
333 | char *issuer; | ||
334 | char *subject; | ||
335 | char *signature; | ||
336 | char attribute[cred->issuer_attribute_len + 1]; | ||
337 | json_t *cred_obj; | ||
338 | |||
339 | issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); | ||
340 | if (NULL == issuer) | ||
341 | { | ||
342 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
343 | "Issuer in credential malformed\n"); | ||
344 | return NULL; | ||
345 | } | ||
346 | subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); | ||
347 | if (NULL == subject) | ||
348 | { | ||
349 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
350 | "Subject in credential malformed\n"); | ||
351 | GNUNET_free (issuer); | ||
352 | return NULL; | ||
353 | } | ||
354 | GNUNET_STRINGS_base64_encode ((char*)&cred->signature, | ||
355 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature), | ||
356 | &signature); | ||
357 | memcpy (attribute, | ||
358 | cred->issuer_attribute, | ||
359 | cred->issuer_attribute_len); | ||
360 | attribute[cred->issuer_attribute_len] = '\0'; | ||
361 | cred_obj = json_object (); | ||
362 | json_object_set_new (cred_obj, "issuer", json_string (issuer)); | ||
363 | json_object_set_new (cred_obj, "subject", json_string (subject)); | ||
364 | json_object_set_new (cred_obj, "attribute", json_string (attribute)); | ||
365 | json_object_set_new (cred_obj, "signature", json_string (signature)); | ||
366 | json_object_set_new (cred_obj, "expiration", json_integer (cred->expiration.abs_value_us)); | ||
367 | GNUNET_free (issuer); | ||
368 | GNUNET_free (subject); | ||
369 | GNUNET_free (signature); | ||
370 | return cred_obj; | ||
371 | } | ||
372 | |||
373 | static void | ||
374 | handle_collect_response (void *cls, | ||
375 | unsigned int d_count, | ||
376 | struct GNUNET_CREDENTIAL_Delegation *delegation_chain, | ||
377 | unsigned int c_count, | ||
378 | struct GNUNET_CREDENTIAL_Credential *cred) | ||
379 | { | ||
380 | struct RequestHandle *handle = cls; | ||
381 | struct MHD_Response *resp; | ||
382 | struct GNUNET_JSONAPI_Document *json_document; | ||
383 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
384 | json_t *cred_obj; | ||
385 | json_t *cred_array; | ||
386 | char *result; | ||
387 | char *issuer; | ||
388 | char *id; | ||
389 | uint32_t i; | ||
390 | |||
391 | handle->verify_request = NULL; | ||
392 | if (NULL == cred) { | ||
393 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
394 | "Verify failed.\n"); | ||
395 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
396 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
397 | return; | ||
398 | } | ||
399 | issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key); | ||
400 | if (NULL == issuer) | ||
401 | { | ||
402 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
403 | "Issuer in delegation malformed\n"); | ||
404 | return; | ||
405 | } | ||
406 | GNUNET_asprintf (&id, | ||
407 | "%s.%s", | ||
408 | issuer, | ||
409 | handle->issuer_attr); | ||
410 | GNUNET_free (issuer); | ||
411 | json_document = GNUNET_JSONAPI_document_new (); | ||
412 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, | ||
413 | id); | ||
414 | GNUNET_free (id); | ||
415 | cred_array = json_array (); | ||
416 | for (i=0;i<c_count;i++) | ||
417 | { | ||
418 | cred_obj = credential_to_json (&cred[i]); | ||
419 | json_array_append_new (cred_array, cred_obj); | ||
420 | } | ||
421 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
422 | GNUNET_REST_JSONAPI_CREDENTIAL, | ||
423 | cred_array); | ||
424 | GNUNET_JSONAPI_document_resource_add (json_document, json_resource); | ||
425 | GNUNET_JSONAPI_document_serialize (json_document, &result); | ||
426 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
427 | "Result %s\n", | ||
428 | result); | ||
429 | json_decref (cred_array); | ||
430 | GNUNET_JSONAPI_document_delete (json_document); | ||
431 | resp = GNUNET_REST_create_response (result); | ||
432 | GNUNET_free(result); | ||
433 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
434 | cleanup_handle (handle); | ||
435 | } | ||
436 | |||
437 | static void | ||
438 | subject_ego_lookup (void *cls, | ||
439 | const struct GNUNET_IDENTITY_Ego *ego) | ||
440 | { | ||
441 | struct RequestHandle *handle = cls; | ||
442 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *sub_key; | ||
443 | handle->ego_lookup = NULL; | ||
444 | |||
445 | if (NULL == ego) | ||
446 | { | ||
447 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
448 | "Subject not found\n"); | ||
449 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
450 | return; | ||
451 | } | ||
452 | sub_key = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
453 | handle->verify_request = GNUNET_CREDENTIAL_collect (handle->credential, | ||
454 | &handle->issuer_key, | ||
455 | handle->issuer_attr, | ||
456 | sub_key, | ||
457 | &handle_collect_response, | ||
458 | handle); | ||
459 | } | ||
460 | |||
461 | |||
462 | |||
463 | static void | ||
464 | handle_verify_response (void *cls, | ||
465 | unsigned int d_count, | ||
466 | struct GNUNET_CREDENTIAL_Delegation *delegation_chain, | ||
467 | unsigned int c_count, | ||
468 | struct GNUNET_CREDENTIAL_Credential *cred) | ||
469 | { | ||
470 | |||
471 | struct RequestHandle *handle = cls; | ||
472 | struct MHD_Response *resp; | ||
473 | struct GNUNET_JSONAPI_Document *json_document; | ||
474 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
475 | json_t *cred_obj; | ||
476 | json_t *attr_obj; | ||
477 | json_t *cred_array; | ||
478 | json_t *attr_array; | ||
479 | char *result; | ||
480 | char *issuer; | ||
481 | char *id; | ||
482 | uint32_t i; | ||
483 | |||
484 | handle->verify_request = NULL; | ||
485 | if (NULL == cred) { | ||
486 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
487 | "Verify failed.\n"); | ||
488 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
489 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
490 | return; | ||
491 | } | ||
492 | issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&handle->issuer_key); | ||
493 | if (NULL == issuer) | ||
494 | { | ||
495 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
496 | "Issuer in delegation malformed\n"); | ||
497 | return; | ||
498 | } | ||
499 | GNUNET_asprintf (&id, | ||
500 | "%s.%s", | ||
501 | issuer, | ||
502 | handle->issuer_attr); | ||
503 | GNUNET_free (issuer); | ||
504 | json_document = GNUNET_JSONAPI_document_new (); | ||
505 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, | ||
506 | id); | ||
507 | GNUNET_free (id); | ||
508 | attr_array = json_array (); | ||
509 | for (i = 0; i < d_count; i++) | ||
510 | { | ||
511 | attr_obj = attribute_delegation_to_json (&delegation_chain[i]); | ||
512 | json_array_append_new (attr_array, attr_obj); | ||
513 | } | ||
514 | cred_array = json_array (); | ||
515 | for (i=0;i<c_count;i++) | ||
516 | { | ||
517 | cred_obj = credential_to_json (&cred[i]); | ||
518 | json_array_append_new (cred_array, cred_obj); | ||
519 | } | ||
520 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
521 | GNUNET_REST_JSONAPI_CREDENTIAL, | ||
522 | cred_array); | ||
523 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
524 | GNUNET_REST_JSONAPI_DELEGATIONS, | ||
525 | attr_array); | ||
526 | GNUNET_JSONAPI_document_resource_add (json_document, json_resource); | ||
527 | GNUNET_JSONAPI_document_serialize (json_document, &result); | ||
528 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
529 | "Result %s\n", | ||
530 | result); | ||
531 | json_decref (attr_array); | ||
532 | json_decref (cred_array); | ||
533 | GNUNET_JSONAPI_document_delete (json_document); | ||
534 | resp = GNUNET_REST_create_response (result); | ||
535 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
536 | GNUNET_free (result); | ||
537 | cleanup_handle (handle); | ||
538 | } | ||
539 | |||
540 | static void | ||
541 | collect_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, | ||
542 | const char* url, | ||
543 | void *cls) | ||
544 | { | ||
545 | struct RequestHandle *handle = cls; | ||
546 | struct GNUNET_HashCode key; | ||
547 | char *tmp; | ||
548 | char *entity_attr; | ||
549 | |||
550 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
551 | "Connecting...\n"); | ||
552 | handle->credential = GNUNET_CREDENTIAL_connect (cfg); | ||
553 | handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, | ||
554 | &do_error, handle); | ||
555 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
556 | "Connected\n"); | ||
557 | if (NULL == handle->credential) | ||
558 | { | ||
559 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
560 | "Connecting to CREDENTIAL failed\n"); | ||
561 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
562 | return; | ||
563 | } | ||
564 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, | ||
565 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), | ||
566 | &key); | ||
567 | if ( GNUNET_NO == | ||
568 | GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, | ||
569 | &key) ) | ||
570 | { | ||
571 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
572 | "Missing issuer attribute\n"); | ||
573 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
574 | return; | ||
575 | } | ||
576 | tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, | ||
577 | &key); | ||
578 | entity_attr = GNUNET_strdup (tmp); | ||
579 | tmp = strtok(entity_attr, "."); | ||
580 | if (NULL == tmp) | ||
581 | { | ||
582 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
583 | "Malformed issuer or attribute\n"); | ||
584 | GNUNET_free (entity_attr); | ||
585 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
586 | return; | ||
587 | } | ||
588 | if (GNUNET_OK != | ||
589 | GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, | ||
590 | strlen (tmp), | ||
591 | &handle->issuer_key)) | ||
592 | { | ||
593 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
594 | "Malformed issuer key\n"); | ||
595 | GNUNET_free (entity_attr); | ||
596 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
597 | return; | ||
598 | } | ||
599 | tmp = strtok (NULL, "."); //Issuer attribute | ||
600 | if (NULL == tmp) | ||
601 | { | ||
602 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
603 | "Malformed attribute\n"); | ||
604 | GNUNET_free (entity_attr); | ||
605 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
606 | return; | ||
607 | } | ||
608 | handle->issuer_attr = GNUNET_strdup (tmp); | ||
609 | GNUNET_free (entity_attr); | ||
610 | |||
611 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO, | ||
612 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_EGO), | ||
613 | &key); | ||
614 | if ( GNUNET_NO == | ||
615 | GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, | ||
616 | &key) ) | ||
617 | { | ||
618 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
619 | "Missing subject\n"); | ||
620 | GNUNET_free (entity_attr); | ||
621 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
622 | return; | ||
623 | } | ||
624 | tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, | ||
625 | &key); | ||
626 | if (NULL == tmp) | ||
627 | { | ||
628 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
629 | "Malformed subject\n"); | ||
630 | GNUNET_free (entity_attr); | ||
631 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
632 | return; | ||
633 | } | ||
634 | handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, | ||
635 | tmp, | ||
636 | &subject_ego_lookup, | ||
637 | handle); | ||
638 | } | ||
639 | |||
640 | |||
641 | |||
642 | static void | ||
643 | verify_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, | ||
644 | const char* url, | ||
645 | void *cls) | ||
646 | { | ||
647 | struct RequestHandle *handle = cls; | ||
648 | struct GNUNET_HashCode key; | ||
649 | struct GNUNET_JSONAPI_Document *json_obj; | ||
650 | struct GNUNET_JSONAPI_Resource *res; | ||
651 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
652 | char *tmp; | ||
653 | char *entity_attr; | ||
654 | int i; | ||
655 | uint32_t credential_count; | ||
656 | uint32_t resource_count; | ||
657 | json_t *cred_json; | ||
658 | json_t *data_js; | ||
659 | json_error_t err; | ||
660 | |||
661 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
662 | "Connecting...\n"); | ||
663 | handle->credential = GNUNET_CREDENTIAL_connect (cfg); | ||
664 | handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, | ||
665 | &do_error, handle); | ||
666 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
667 | "Connected\n"); | ||
668 | if (NULL == handle->credential) | ||
669 | { | ||
670 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
671 | "Connecting to CREDENTIAL failed\n"); | ||
672 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
673 | return; | ||
674 | } | ||
675 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, | ||
676 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), | ||
677 | &key); | ||
678 | if ( GNUNET_NO == | ||
679 | GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, | ||
680 | &key) ) | ||
681 | { | ||
682 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
683 | "Missing issuer attribute\n"); | ||
684 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
685 | return; | ||
686 | } | ||
687 | tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, | ||
688 | &key); | ||
689 | entity_attr = GNUNET_strdup (tmp); | ||
690 | tmp = strtok(entity_attr, "."); | ||
691 | if (NULL == tmp) | ||
692 | { | ||
693 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
694 | "Malformed issuer or attribute\n"); | ||
695 | GNUNET_free (entity_attr); | ||
696 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
697 | return; | ||
698 | } | ||
699 | if (GNUNET_OK != | ||
700 | GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, | ||
701 | strlen (tmp), | ||
702 | &handle->issuer_key)) | ||
703 | { | ||
704 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
705 | "Malformed issuer key\n"); | ||
706 | GNUNET_free (entity_attr); | ||
707 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
708 | return; | ||
709 | } | ||
710 | tmp = strtok (NULL, "."); //Issuer attribute | ||
711 | if (NULL == tmp) | ||
712 | { | ||
713 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
714 | "Malformed attribute\n"); | ||
715 | GNUNET_free (entity_attr); | ||
716 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
717 | return; | ||
718 | } | ||
719 | handle->issuer_attr = GNUNET_strdup (tmp); | ||
720 | GNUNET_free (entity_attr); | ||
721 | |||
722 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY, | ||
723 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY), | ||
724 | &key); | ||
725 | if ( GNUNET_NO == | ||
726 | GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map, | ||
727 | &key) ) | ||
728 | { | ||
729 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
730 | "Missing subject key\n"); | ||
731 | GNUNET_free (entity_attr); | ||
732 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
733 | return; | ||
734 | } | ||
735 | tmp = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, | ||
736 | &key); | ||
737 | if (NULL == tmp) | ||
738 | { | ||
739 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
740 | "Malformed subject\n"); | ||
741 | GNUNET_free (entity_attr); | ||
742 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
743 | return; | ||
744 | } | ||
745 | if (GNUNET_OK != | ||
746 | GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, | ||
747 | strlen (tmp), | ||
748 | &handle->subject_key)) { | ||
749 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
750 | "Malformed subject key\n"); | ||
751 | GNUNET_free (entity_attr); | ||
752 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
753 | return; | ||
754 | } | ||
755 | |||
756 | if (0 >= handle->rest_handle->data_size) | ||
757 | { | ||
758 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
759 | "Missing credentials\n"); | ||
760 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
761 | return; | ||
762 | } | ||
763 | |||
764 | struct GNUNET_JSON_Specification docspec[] = { | ||
765 | GNUNET_JSON_spec_jsonapi_document (&json_obj), | ||
766 | GNUNET_JSON_spec_end() | ||
767 | }; | ||
768 | char term_data[handle->rest_handle->data_size+1]; | ||
769 | term_data[handle->rest_handle->data_size] = '\0'; | ||
770 | credential_count = 0; | ||
771 | GNUNET_memcpy (term_data, | ||
772 | handle->rest_handle->data, | ||
773 | handle->rest_handle->data_size); | ||
774 | data_js = json_loads (term_data, | ||
775 | JSON_DECODE_ANY, | ||
776 | &err); | ||
777 | GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, docspec, | ||
778 | NULL, NULL)); | ||
779 | json_decref (data_js); | ||
780 | if (NULL == json_obj) | ||
781 | { | ||
782 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
783 | "Unable to parse JSONAPI Object from %s\n", | ||
784 | term_data); | ||
785 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
786 | return; | ||
787 | } | ||
788 | |||
789 | resource_count = GNUNET_JSONAPI_document_resource_count(json_obj); | ||
790 | GNUNET_assert (1 == resource_count); | ||
791 | res = (GNUNET_JSONAPI_document_get_resource(json_obj, 0)); | ||
792 | if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type(res, | ||
793 | GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO)) | ||
794 | { | ||
795 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
796 | "Resource not a credential!\n"); | ||
797 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
798 | "Unable to parse JSONAPI Object from %s\n", | ||
799 | term_data); | ||
800 | GNUNET_JSONAPI_document_delete (json_obj); | ||
801 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
802 | return; | ||
803 | } | ||
804 | cred_json = GNUNET_JSONAPI_resource_read_attr (res, | ||
805 | GNUNET_REST_JSONAPI_CREDENTIAL); | ||
806 | |||
807 | GNUNET_assert (json_is_array (cred_json)); | ||
808 | |||
809 | credential_count = json_array_size(cred_json); | ||
810 | |||
811 | struct GNUNET_CREDENTIAL_Credential credentials[credential_count]; | ||
812 | for (i=0;i<credential_count;i++) | ||
813 | { | ||
814 | cred = json_to_credential (json_array_get (cred_json, i)); | ||
815 | if (NULL == cred) | ||
816 | { | ||
817 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
818 | "Unable to parse credential!\n"); | ||
819 | continue; | ||
820 | } | ||
821 | GNUNET_memcpy (&credentials[i], | ||
822 | cred, | ||
823 | sizeof (struct GNUNET_CREDENTIAL_Credential)); | ||
824 | credentials[i].issuer_attribute = GNUNET_strdup (cred->issuer_attribute); | ||
825 | GNUNET_free (cred); | ||
826 | } | ||
827 | GNUNET_JSONAPI_document_delete(json_obj); | ||
828 | handle->verify_request = GNUNET_CREDENTIAL_verify (handle->credential, | ||
829 | &handle->issuer_key, | ||
830 | handle->issuer_attr, | ||
831 | &handle->subject_key, | ||
832 | credential_count, | ||
833 | credentials, | ||
834 | &handle_verify_response, | ||
835 | handle); | ||
836 | for (i=0;i<credential_count;i++) | ||
837 | GNUNET_free ((char*)credentials[i].issuer_attribute); | ||
838 | |||
839 | } | ||
840 | |||
841 | void | ||
842 | send_cred_response (struct RequestHandle *handle, | ||
843 | struct GNUNET_CREDENTIAL_Credential *cred) | ||
844 | { | ||
845 | struct MHD_Response *resp; | ||
846 | struct GNUNET_JSONAPI_Document *json_document; | ||
847 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
848 | json_t *cred_obj; | ||
849 | char *result; | ||
850 | char *issuer; | ||
851 | char *subject; | ||
852 | char *signature; | ||
853 | char *id; | ||
854 | |||
855 | GNUNET_assert (NULL != cred); | ||
856 | issuer = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key); | ||
857 | if (NULL == issuer) | ||
858 | { | ||
859 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
860 | "Subject malformed\n"); | ||
861 | return; | ||
862 | } | ||
863 | GNUNET_asprintf (&id, | ||
864 | "%s.%s", | ||
865 | issuer, | ||
866 | (char*)&cred[1]); | ||
867 | subject = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key); | ||
868 | if (NULL == subject) | ||
869 | { | ||
870 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
871 | "Subject malformed\n"); | ||
872 | return; | ||
873 | } | ||
874 | GNUNET_STRINGS_base64_encode ((char*)&cred->signature, | ||
875 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature), | ||
876 | &signature); | ||
877 | json_document = GNUNET_JSONAPI_document_new (); | ||
878 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_CREDENTIAL_TYPEINFO, | ||
879 | id); | ||
880 | GNUNET_free (id); | ||
881 | cred_obj = json_object(); | ||
882 | json_object_set_new (cred_obj, "issuer", json_string (issuer)); | ||
883 | json_object_set_new (cred_obj, "subject", json_string (subject)); | ||
884 | json_object_set_new (cred_obj, "expiration", json_integer( cred->expiration.abs_value_us)); | ||
885 | json_object_set_new (cred_obj, "signature", json_string (signature)); | ||
886 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
887 | GNUNET_REST_JSONAPI_CREDENTIAL, | ||
888 | cred_obj); | ||
889 | GNUNET_JSONAPI_document_resource_add (json_document, json_resource); | ||
890 | GNUNET_JSONAPI_document_serialize (json_document, &result); | ||
891 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
892 | "Result %s\n", | ||
893 | result); | ||
894 | json_decref (cred_obj); | ||
895 | GNUNET_JSONAPI_document_delete (json_document); | ||
896 | resp = GNUNET_REST_create_response (result); | ||
897 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
898 | GNUNET_free (result); | ||
899 | GNUNET_free (signature); | ||
900 | GNUNET_free (issuer); | ||
901 | GNUNET_free (subject); | ||
902 | cleanup_handle (handle); | ||
903 | } | ||
904 | |||
905 | void | ||
906 | get_cred_issuer_cb (void *cls, | ||
907 | struct GNUNET_IDENTITY_Ego *ego, | ||
908 | void **ctx, | ||
909 | const char *name) | ||
910 | { | ||
911 | struct RequestHandle *handle = cls; | ||
912 | struct GNUNET_TIME_Absolute etime_abs; | ||
913 | struct GNUNET_TIME_Relative etime_rel; | ||
914 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer_key; | ||
915 | struct GNUNET_HashCode key; | ||
916 | struct GNUNET_CREDENTIAL_Credential *cred; | ||
917 | char* expiration_str; | ||
918 | char* tmp; | ||
919 | |||
920 | handle->id_op = NULL; | ||
921 | |||
922 | if (NULL == name) | ||
923 | { | ||
924 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
925 | "Issuer not configured!\n"); | ||
926 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
927 | return; | ||
928 | } | ||
929 | |||
930 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
931 | "Connecting to credential service...\n"); | ||
932 | handle->credential = GNUNET_CREDENTIAL_connect (cfg); | ||
933 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
934 | "Connected\n"); | ||
935 | if (NULL == handle->credential) | ||
936 | { | ||
937 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
938 | "Connecting to CREDENTIAL failed\n"); | ||
939 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
940 | return; | ||
941 | } | ||
942 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION, | ||
943 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_EXPIRATION), | ||
944 | &key); | ||
945 | if ( GNUNET_NO == | ||
946 | GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | ||
947 | &key) ) | ||
948 | { | ||
949 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
950 | "Missing expiration\n"); | ||
951 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
952 | return; | ||
953 | } | ||
954 | expiration_str = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
955 | &key); | ||
956 | if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expiration_str, | ||
957 | &etime_rel)) | ||
958 | { | ||
959 | etime_abs = GNUNET_TIME_relative_to_absolute (etime_rel); | ||
960 | } else if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (expiration_str, | ||
961 | &etime_abs)) | ||
962 | { | ||
963 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
964 | "Malformed expiration: %s\n", expiration_str); | ||
965 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
966 | return; | ||
967 | } | ||
968 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR, | ||
969 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_ISSUER_ATTR), | ||
970 | &key); | ||
971 | if ( GNUNET_NO == | ||
972 | GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | ||
973 | &key) ) | ||
974 | { | ||
975 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
976 | "Missing issuer attribute\n"); | ||
977 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
978 | return; | ||
979 | } | ||
980 | handle->issuer_attr = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get | ||
981 | (handle->rest_handle->url_param_map, | ||
982 | &key)); | ||
983 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY, | ||
984 | strlen (GNUNET_REST_JSONAPI_CREDENTIAL_SUBJECT_KEY), | ||
985 | &key); | ||
986 | if ( GNUNET_NO == | ||
987 | GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | ||
988 | &key) ) | ||
989 | { | ||
990 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
991 | "Missing subject\n"); | ||
992 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
993 | return; | ||
994 | } | ||
995 | tmp = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
996 | &key); | ||
997 | if (NULL == tmp) | ||
998 | { | ||
999 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1000 | "Malformed subject\n"); | ||
1001 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1002 | return; | ||
1003 | } | ||
1004 | if (GNUNET_OK != | ||
1005 | GNUNET_CRYPTO_ecdsa_public_key_from_string (tmp, | ||
1006 | strlen (tmp), | ||
1007 | &handle->subject_key)) { | ||
1008 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1009 | "Malformed subject key\n"); | ||
1010 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1011 | return; | ||
1012 | } | ||
1013 | issuer_key = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1014 | cred = GNUNET_CREDENTIAL_credential_issue (issuer_key, | ||
1015 | &handle->subject_key, | ||
1016 | handle->issuer_attr, | ||
1017 | &etime_abs); | ||
1018 | if (NULL == cred) | ||
1019 | { | ||
1020 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1021 | "Failed to create credential\n"); | ||
1022 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1023 | return; | ||
1024 | } | ||
1025 | send_cred_response (handle, cred); | ||
1026 | } | ||
1027 | |||
1028 | |||
1029 | static void | ||
1030 | issue_cred_cont (struct GNUNET_REST_RequestHandle *conndata_handle, | ||
1031 | const char* url, | ||
1032 | void *cls) | ||
1033 | { | ||
1034 | struct RequestHandle *handle = cls; | ||
1035 | |||
1036 | handle->identity = GNUNET_IDENTITY_connect (cfg, | ||
1037 | NULL, | ||
1038 | NULL); | ||
1039 | handle->id_op = GNUNET_IDENTITY_get(handle->identity, | ||
1040 | "credential-issuer", | ||
1041 | &get_cred_issuer_cb, | ||
1042 | handle); | ||
1043 | handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, | ||
1044 | &do_error, | ||
1045 | handle); | ||
1046 | } | ||
1047 | |||
1048 | static void | ||
1049 | options_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
1050 | const char* url, | ||
1051 | void *cls) | ||
1052 | { | ||
1053 | struct MHD_Response *resp; | ||
1054 | struct RequestHandle *handle = cls; | ||
1055 | |||
1056 | //For GNS, independent of path return all options | ||
1057 | resp = GNUNET_REST_create_response (NULL); | ||
1058 | MHD_add_response_header (resp, | ||
1059 | "Access-Control-Allow-Methods", | ||
1060 | MHD_HTTP_METHOD_GET); | ||
1061 | handle->proc (handle->proc_cls, | ||
1062 | resp, | ||
1063 | MHD_HTTP_OK); | ||
1064 | cleanup_handle (handle); | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | static void | ||
1069 | rest_credential_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, | ||
1070 | GNUNET_REST_ResultProcessor proc, | ||
1071 | void *proc_cls) | ||
1072 | { | ||
1073 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | ||
1074 | struct GNUNET_REST_RequestHandlerError err; | ||
1075 | |||
1076 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
1077 | handle->proc_cls = proc_cls; | ||
1078 | handle->proc = proc; | ||
1079 | handle->rest_handle = conndata_handle; | ||
1080 | |||
1081 | static const struct GNUNET_REST_RequestHandler handlers[] = { | ||
1082 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_CREDENTIAL_VERIFY, &verify_cred_cont}, | ||
1083 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_COLLECT, &collect_cred_cont}, | ||
1084 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_CREDENTIAL_ISSUE, &issue_cred_cont}, | ||
1085 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_CREDENTIAL, &options_cont}, | ||
1086 | GNUNET_REST_HANDLER_END | ||
1087 | }; | ||
1088 | |||
1089 | if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle, | ||
1090 | handlers, | ||
1091 | &err, | ||
1092 | handle)) | ||
1093 | { | ||
1094 | handle->response_code = err.error_code; | ||
1095 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 | /** | ||
1101 | * Entry point for the plugin. | ||
1102 | * | ||
1103 | * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*" | ||
1104 | * @return NULL on error, otherwise the plugin context | ||
1105 | */ | ||
1106 | void * | ||
1107 | libgnunet_plugin_rest_credential_init (void *cls) | ||
1108 | { | ||
1109 | static struct Plugin plugin; | ||
1110 | cfg = cls; | ||
1111 | struct GNUNET_REST_Plugin *api; | ||
1112 | |||
1113 | if (NULL != plugin.cfg) | ||
1114 | return NULL; /* can only initialize once! */ | ||
1115 | memset (&plugin, 0, sizeof (struct Plugin)); | ||
1116 | plugin.cfg = cfg; | ||
1117 | api = GNUNET_new (struct GNUNET_REST_Plugin); | ||
1118 | api->cls = &plugin; | ||
1119 | api->name = GNUNET_REST_API_NS_CREDENTIAL; | ||
1120 | api->process_request = &rest_credential_process_request; | ||
1121 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1122 | _("GNS REST API initialized\n")); | ||
1123 | return api; | ||
1124 | } | ||
1125 | |||
1126 | |||
1127 | /** | ||
1128 | * Exit point from the plugin. | ||
1129 | * | ||
1130 | * @param cls the plugin context (as returned by "init") | ||
1131 | * @return always NULL | ||
1132 | */ | ||
1133 | void * | ||
1134 | libgnunet_plugin_rest_credential_done (void *cls) | ||
1135 | { | ||
1136 | struct GNUNET_REST_Plugin *api = cls; | ||
1137 | struct Plugin *plugin = api->cls; | ||
1138 | |||
1139 | plugin->cfg = NULL; | ||
1140 | GNUNET_free (api); | ||
1141 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1142 | "GNS REST plugin is finished\n"); | ||
1143 | return NULL; | ||
1144 | } | ||
1145 | |||
1146 | /* end of plugin_rest_gns.c */ | ||
diff --git a/src/credential/test_credential_collect.sh b/src/credential/test_credential_collect.sh new file mode 100755 index 000000000..6c713063f --- /dev/null +++ b/src/credential/test_credential_collect.sh | |||
@@ -0,0 +1,47 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | TEST_ATTR2="test2" | ||
27 | gnunet-arm -s -c test_credential_lookup.conf | ||
28 | gnunet-identity -C testissuer -c test_credential_lookup.conf | ||
29 | gnunet-identity -C testsubject -c test_credential_lookup.conf | ||
30 | SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}') | ||
31 | ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}') | ||
32 | #TODO1 Get credential and store it with subject (3) | ||
33 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
34 | $DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
35 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR2 --ttl=5m -c test_credential_lookup.conf` | ||
36 | $DO_TIMEOUT gnunet-namestore -a -z testsubject -n c2 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
37 | CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$ISSUER_KEY --attribute=$TEST_ATTR --ego=testsubject -c test_credential_lookup.conf | paste -d, -s` | ||
38 | echo $CREDS | ||
39 | RES=$? | ||
40 | gnunet-arm -e -c test_credential_lookup.conf | ||
41 | |||
42 | if test $? != 0 | ||
43 | then | ||
44 | echo "Error collecting..." | ||
45 | exit 1 | ||
46 | fi | ||
47 | |||
diff --git a/src/credential/test_credential_collect_rest.sh b/src/credential/test_credential_collect_rest.sh new file mode 100755 index 000000000..0b31f85bc --- /dev/null +++ b/src/credential/test_credential_collect_rest.sh | |||
@@ -0,0 +1,90 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) Service.user -> GNU.project.member | ||
19 | # (2) GNU.project -> GNUnet | ||
20 | # (3) GNUnet.member -> GNUnet.developer | ||
21 | # (4) GNUnet.member -> GNUnet.user | ||
22 | # (5) GNUnet.developer -> Alice | ||
23 | |||
24 | |||
25 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
26 | gnunet-arm -s -c test_credential_lookup.conf | ||
27 | gnunet-identity -C service -c test_credential_lookup.conf | ||
28 | gnunet-identity -C alice -c test_credential_lookup.conf | ||
29 | gnunet-identity -C gnu -c test_credential_lookup.conf | ||
30 | gnunet-identity -C gnunet -c test_credential_lookup.conf | ||
31 | |||
32 | GNU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}') | ||
33 | ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}') | ||
34 | GNUNET_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnunet | awk '{print $3}') | ||
35 | SERVICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep service | awk '{print $3}') | ||
36 | |||
37 | USER_ATTR="user" | ||
38 | GNU_PROJECT_ATTR="project" | ||
39 | MEMBER_ATTR="member" | ||
40 | DEVELOPER_ATTR="developer" | ||
41 | DEV_ATTR="developer" | ||
42 | TEST_CREDENTIAL="mygnunetcreds" | ||
43 | |||
44 | # (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU | ||
45 | gnunet-namestore -p -z service -a -n $USER_ATTR -t ATTR -V "$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" -e 5m -c test_credential_lookup.conf | ||
46 | |||
47 | # (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute | ||
48 | gnunet-namestore -p -z gnu -a -n $GNU_PROJECT_ATTR -t ATTR -V "$GNUNET_KEY" -e 5m -c test_credential_lookup.conf | ||
49 | |||
50 | # (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user" | ||
51 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $DEVELOPER_ATTR" -e 5m -c test_credential_lookup.conf | ||
52 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $USER_ATTR" -e 5m -c test_credential_lookup.conf | ||
53 | |||
54 | # (5) GNUnet issues Alice the credential "developer" | ||
55 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$DEV_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
56 | |||
57 | # Alice stores the credential under "mygnunetcreds" | ||
58 | gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
59 | |||
60 | # (5) GNUnet issues Alice the credential "developer" | ||
61 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$USER_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
62 | |||
63 | # Alice stores the credential under "mygnunetcreds" | ||
64 | gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
65 | |||
66 | #TODO2 Add -z swich like in gnunet-gns | ||
67 | #RES_CRED=`gnunet-credential --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY -c test_credential_lookup.conf` | ||
68 | |||
69 | gnunet-arm -i rest -c test_credential_lookup.conf | ||
70 | |||
71 | sleep 5 | ||
72 | |||
73 | curl -v "localhost:7776/credential/collect?attribute=$SERVICE_KEY.$USER_ATTR&subject=alice" | ||
74 | |||
75 | #TODO cleanup properly | ||
76 | gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf | ||
77 | gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_credential_lookup.conf | ||
78 | gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_credential_lookup.conf | ||
79 | gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_credential_lookup.conf | ||
80 | echo "Stopping arm..." | ||
81 | gnunet-arm -e -c test_credential_lookup.conf | ||
82 | echo "Done" | ||
83 | if [ "$RES_CRED" != "Failed." ] | ||
84 | then | ||
85 | echo -e "${RES_CRED}" | ||
86 | exit 0 | ||
87 | else | ||
88 | echo "FAIL: Failed to verify credential $RES_CRED." | ||
89 | exit 1 | ||
90 | fi | ||
diff --git a/src/credential/test_credential_defaults.conf b/src/credential/test_credential_defaults.conf new file mode 100644 index 000000000..d157ddd43 --- /dev/null +++ b/src/credential/test_credential_defaults.conf | |||
@@ -0,0 +1,24 @@ | |||
1 | @INLINE@ ../../contrib/no_forcestart.conf | ||
2 | |||
3 | [PATHS] | ||
4 | GNUNET_TEST_HOME = /tmp/test-gnunet-credential-testing/ | ||
5 | |||
6 | [namestore-sqlite] | ||
7 | FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db | ||
8 | |||
9 | [namecache-sqlite] | ||
10 | FILENAME=$GNUNET_TEST_HOME/namecache/namecache.db | ||
11 | |||
12 | [identity] | ||
13 | # Directory where we store information about our egos | ||
14 | EGODIR = $GNUNET_TEST_HOME/identity/egos/ | ||
15 | |||
16 | [dhtcache] | ||
17 | DATABASE = heap | ||
18 | |||
19 | [transport] | ||
20 | PLUGINS = tcp | ||
21 | |||
22 | [transport-tcp] | ||
23 | BINDTO = 127.0.0.1 | ||
24 | |||
diff --git a/src/credential/test_credential_issue.sh b/src/credential/test_credential_issue.sh new file mode 100755 index 000000000..158d91c5b --- /dev/null +++ b/src/credential/test_credential_issue.sh | |||
@@ -0,0 +1,44 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_credential_lookup.conf | ||
27 | gnunet-identity -C testissuer -c test_credential_lookup.conf | ||
28 | gnunet-identity -C testsubject -c test_credential_lookup.conf | ||
29 | SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}') | ||
30 | ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}') | ||
31 | #TODO1 Get credential and store it with subject (3) | ||
32 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
33 | STATUS=$? | ||
34 | |||
35 | if test $? != 0 | ||
36 | then | ||
37 | echo "Error issuing..." | ||
38 | exit 1 | ||
39 | fi | ||
40 | #Try import | ||
41 | $DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
42 | RES=$? | ||
43 | gnunet-arm -e -c test_credential_lookup.conf | ||
44 | exit $RES | ||
diff --git a/src/credential/test_credential_issue_rest.sh b/src/credential/test_credential_issue_rest.sh new file mode 100755 index 000000000..15cd55083 --- /dev/null +++ b/src/credential/test_credential_issue_rest.sh | |||
@@ -0,0 +1,53 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_credential_lookup.conf | ||
27 | gnunet-arm -i gns | ||
28 | gnunet-arm -i credential | ||
29 | gnunet-arm -i identity | ||
30 | gnunet-arm -i rest -c test_credential_lookup.conf | ||
31 | |||
32 | gnunet-arm -I -c test_credential_lookup.conf | ||
33 | gnunet-identity -C testissuer -c test_credential_lookup.conf | ||
34 | gnunet-identity -C testsubject -c test_credential_lookup.conf | ||
35 | gnunet-identity -s credential-issuer -e testissuer | ||
36 | SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}') | ||
37 | ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}') | ||
38 | #TODO1 Get credential and store it with subject (3) | ||
39 | sleep 5 | ||
40 | curl "localhost:7776/credential/issue?subject_key=$SUBJECT_KEY&attribute=$TEST_ATTR&expiration=1d" | ||
41 | #CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
42 | STATUS=$? | ||
43 | |||
44 | if test $? != 0 | ||
45 | then | ||
46 | echo "Error issuing..." | ||
47 | exit 1 | ||
48 | fi | ||
49 | #Try import | ||
50 | #$DO_TIMEOUT gnunet-namestore -a -z testsubject -n c1 -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
51 | RES=$? | ||
52 | gnunet-arm -e -c test_credential_lookup.conf | ||
53 | exit $RES | ||
diff --git a/src/credential/test_credential_lookup.conf b/src/credential/test_credential_lookup.conf new file mode 100644 index 000000000..3684063b1 --- /dev/null +++ b/src/credential/test_credential_lookup.conf | |||
@@ -0,0 +1,28 @@ | |||
1 | @INLINE@ test_credential_defaults.conf | ||
2 | |||
3 | [PATHS] | ||
4 | GNUNET_TEST_HOME = /tmp/test-gnunet-credential-peer-1/ | ||
5 | |||
6 | [dht] | ||
7 | AUTOSTART = YES | ||
8 | |||
9 | [transport] | ||
10 | PLUGINS = | ||
11 | |||
12 | [credential] | ||
13 | AUTOSTART = YES | ||
14 | PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/credlog | ||
15 | |||
16 | [rest] | ||
17 | PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/restlog | ||
18 | |||
19 | [gns] | ||
20 | #PREFIX = valgrind --leak-check=full --track-origins=yes | ||
21 | AUTOSTART = YES | ||
22 | AUTO_IMPORT_PKEY = YES | ||
23 | MAX_PARALLEL_BACKGROUND_QUERIES = 10 | ||
24 | DEFAULT_LOOKUP_TIMEOUT = 15 s | ||
25 | RECORD_PUT_INTERVAL = 1 h | ||
26 | ZONE_PUBLISH_TIME_WINDOW = 1 h | ||
27 | DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0 | ||
28 | |||
diff --git a/src/credential/test_credential_verify.sh b/src/credential/test_credential_verify.sh new file mode 100755 index 000000000..d042bcfe6 --- /dev/null +++ b/src/credential/test_credential_verify.sh | |||
@@ -0,0 +1,81 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) Service.user -> GNU.project.member | ||
19 | # (2) GNU.project -> GNUnet | ||
20 | # (3) GNUnet.member -> GNUnet.developer | ||
21 | # (4) GNUnet.member -> GNUnet.user | ||
22 | # (5) GNUnet.developer -> Alice | ||
23 | |||
24 | |||
25 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
26 | gnunet-arm -s -c test_credential_lookup.conf | ||
27 | gnunet-identity -C service -c test_credential_lookup.conf | ||
28 | gnunet-identity -C alice -c test_credential_lookup.conf | ||
29 | gnunet-identity -C gnu -c test_credential_lookup.conf | ||
30 | gnunet-identity -C gnunet -c test_credential_lookup.conf | ||
31 | |||
32 | GNU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}') | ||
33 | ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}') | ||
34 | GNUNET_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnunet | awk '{print $3}') | ||
35 | SERVICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep service | awk '{print $3}') | ||
36 | |||
37 | USER_ATTR="user" | ||
38 | GNU_PROJECT_ATTR="project" | ||
39 | MEMBER_ATTR="member" | ||
40 | DEVELOPER_ATTR="developer" | ||
41 | DEV_ATTR="developer" | ||
42 | TEST_CREDENTIAL="mygnunetcreds" | ||
43 | |||
44 | # (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU | ||
45 | gnunet-namestore -p -z service -a -n $USER_ATTR -t ATTR -V "$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" -e 5m -c test_credential_lookup.conf | ||
46 | |||
47 | # (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute | ||
48 | gnunet-namestore -p -z gnu -a -n $GNU_PROJECT_ATTR -t ATTR -V "$GNUNET_KEY" -e 5m -c test_credential_lookup.conf | ||
49 | |||
50 | # (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user" | ||
51 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $DEVELOPER_ATTR" -e 5m -c test_credential_lookup.conf | ||
52 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $USER_ATTR" -e 5m -c test_credential_lookup.conf | ||
53 | |||
54 | # (5) GNUnet issues Alice the credential "developer" | ||
55 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$DEV_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
56 | |||
57 | # Alice stores the credential under "mygnunetcreds" | ||
58 | gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
59 | |||
60 | CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --ego=alice -c test_credential_lookup.conf | paste -d, -s` | ||
61 | |||
62 | echo gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential=\'$CREDS\' -c test_credential_lookup.conf | ||
63 | #TODO2 Add -z swich like in gnunet-gns | ||
64 | gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential="$CREDS" -c test_credential_lookup.conf | ||
65 | |||
66 | |||
67 | #TODO cleanup properly | ||
68 | gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf | ||
69 | gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_credential_lookup.conf | ||
70 | gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_credential_lookup.conf | ||
71 | gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_credential_lookup.conf | ||
72 | gnunet-arm -e -c test_credential_lookup.conf | ||
73 | |||
74 | if [ "$RES_CRED" != "Failed." ] | ||
75 | then | ||
76 | echo -e "${RES_CRED}" | ||
77 | exit 0 | ||
78 | else | ||
79 | echo "FAIL: Failed to verify credential $RES_CRED." | ||
80 | exit 1 | ||
81 | fi | ||
diff --git a/src/credential/test_credential_verify_and.sh b/src/credential/test_credential_verify_and.sh new file mode 100755 index 000000000..9d5c1962e --- /dev/null +++ b/src/credential/test_credential_verify_and.sh | |||
@@ -0,0 +1,81 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) Service.user -> GNU.project.member | ||
19 | # (2) GNU.project -> GNUnet | ||
20 | # (3) GNUnet.member -> GNUnet.developer | ||
21 | # (4) GNUnet.member -> GNUnet.user | ||
22 | # (5) GNUnet.developer -> Alice | ||
23 | |||
24 | |||
25 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
26 | gnunet-arm -s -c test_credential_lookup.conf | ||
27 | gnunet-identity -C service -c test_credential_lookup.conf | ||
28 | gnunet-identity -C alice -c test_credential_lookup.conf | ||
29 | gnunet-identity -C gnu -c test_credential_lookup.conf | ||
30 | gnunet-identity -C gnunet -c test_credential_lookup.conf | ||
31 | |||
32 | GNU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}') | ||
33 | ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}') | ||
34 | GNUNET_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnunet | awk '{print $3}') | ||
35 | SERVICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep service | awk '{print $3}') | ||
36 | |||
37 | USER_ATTR="user" | ||
38 | GNU_PROJECT_ATTR="project" | ||
39 | MEMBER_ATTR="member" | ||
40 | DEVELOPER_ATTR="developer" | ||
41 | DEV_ATTR="developer" | ||
42 | TEST_CREDENTIAL="mygnunetcreds" | ||
43 | |||
44 | # (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU | ||
45 | gnunet-namestore -p -z service -a -n $USER_ATTR -t ATTR -V "$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" -e 5m -c test_credential_lookup.conf | ||
46 | |||
47 | # (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute | ||
48 | gnunet-namestore -p -z gnu -a -n $GNU_PROJECT_ATTR -t ATTR -V "$GNUNET_KEY" -e 5m -c test_credential_lookup.conf | ||
49 | |||
50 | # (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user" | ||
51 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $DEVELOPER_ATTR,$GNUNET_KEY $USER_ATTR" -e 5m -c test_credential_lookup.conf | ||
52 | |||
53 | # (5) GNUnet issues Alice the credential "developer" | ||
54 | CRED1=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$DEV_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
55 | # (5) GNUnet issues Alice the credential "user" | ||
56 | CRED2=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$USER_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
57 | # Alice stores the credential under "mygnunetcreds" | ||
58 | gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED1" -e 5m -c test_credential_lookup.conf | ||
59 | gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED2" -e 5m -c test_credential_lookup.conf | ||
60 | |||
61 | CREDS=`$DO_TIMEOUT gnunet-credential --collect --issuer=$SERVICE_KEY --attribute=$USER_ATTR --ego=alice -c test_credential_lookup.conf | paste -d, -s` | ||
62 | |||
63 | #TODO2 Add -z swich like in gnunet-gns | ||
64 | RES_CRED=`gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential="$CREDS" -c test_credential_lookup.conf` | ||
65 | |||
66 | |||
67 | #TODO cleanup properly | ||
68 | gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf | ||
69 | gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_credential_lookup.conf | ||
70 | gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_credential_lookup.conf | ||
71 | gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_credential_lookup.conf | ||
72 | gnunet-arm -e -c test_credential_lookup.conf | ||
73 | |||
74 | if [ "$RES_CRED" != "Failed." ] | ||
75 | then | ||
76 | echo -e "${RES_CRED}" | ||
77 | exit 0 | ||
78 | else | ||
79 | echo "FAIL: Failed to verify credential $RES_CRED." | ||
80 | exit 1 | ||
81 | fi | ||
diff --git a/src/credential/test_credential_verify_rest.sh b/src/credential/test_credential_verify_rest.sh new file mode 100755 index 000000000..6133ea25e --- /dev/null +++ b/src/credential/test_credential_verify_rest.sh | |||
@@ -0,0 +1,87 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) Service.user -> GNU.project.member | ||
19 | # (2) GNU.project -> GNUnet | ||
20 | # (3) GNUnet.member -> GNUnet.developer | ||
21 | # (4) GNUnet.member -> GNUnet.user | ||
22 | # (5) GNUnet.developer -> Alice | ||
23 | |||
24 | |||
25 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
26 | gnunet-arm -s -c test_credential_lookup.conf | ||
27 | gnunet-identity -C service -c test_credential_lookup.conf | ||
28 | gnunet-identity -C alice -c test_credential_lookup.conf | ||
29 | gnunet-identity -C gnu -c test_credential_lookup.conf | ||
30 | gnunet-identity -C gnunet -c test_credential_lookup.conf | ||
31 | |||
32 | GNU_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnu | grep -v gnunet | awk '{print $3}') | ||
33 | ALICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep alice | awk '{print $3}') | ||
34 | GNUNET_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep gnunet | awk '{print $3}') | ||
35 | SERVICE_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep service | awk '{print $3}') | ||
36 | |||
37 | USER_ATTR="user" | ||
38 | GNU_PROJECT_ATTR="project" | ||
39 | MEMBER_ATTR="member" | ||
40 | DEVELOPER_ATTR="developer" | ||
41 | DEV_ATTR="developer" | ||
42 | TEST_CREDENTIAL="mygnunetcreds" | ||
43 | |||
44 | # (1) A service assigns the attribute "user" to all entities that have been assigned "member" by entities that werde assigned "project" from GNU | ||
45 | gnunet-namestore -p -z service -a -n $USER_ATTR -t ATTR -V "$GNU_KEY $GNU_PROJECT_ATTR.$MEMBER_ATTR" -e 5m -c test_credential_lookup.conf | ||
46 | |||
47 | # (2) GNU recognized GNUnet as a GNU project and delegates the "project" attribute | ||
48 | gnunet-namestore -p -z gnu -a -n $GNU_PROJECT_ATTR -t ATTR -V "$GNUNET_KEY" -e 5m -c test_credential_lookup.conf | ||
49 | |||
50 | # (3+4) GNUnet assigns the attribute "member" to all entities gnunet has also assigned "developer" or "user" | ||
51 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $DEVELOPER_ATTR" -e 5m -c test_credential_lookup.conf | ||
52 | gnunet-namestore -p -z gnunet -a -n $MEMBER_ATTR -t ATTR -V "$GNUNET_KEY $USER_ATTR" -e 5m -c test_credential_lookup.conf | ||
53 | |||
54 | # (5) GNUnet issues Alice the credential "developer" | ||
55 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=gnunet --subject=$ALICE_KEY --attribute=$DEV_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
56 | |||
57 | # Alice stores the credential under "mygnunetcreds" | ||
58 | gnunet-namestore -p -z alice -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
59 | |||
60 | #TODO2 Add -z swich like in gnunet-gns | ||
61 | #RES_CRED=`gnunet-credential --verify --issuer=$SERVICE_KEY --attribute=$USER_ATTR --subject=$ALICE_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf` | ||
62 | |||
63 | gnunet-arm -i rest -c test_credential_lookup.conf | ||
64 | |||
65 | sleep 5 | ||
66 | |||
67 | CREDS=`curl "localhost:7776/credential/collect?attribute=$SERVICE_KEY.$USER_ATTR&subject=alice"` | ||
68 | |||
69 | echo $CREDS | ||
70 | |||
71 | curl -v "localhost:7776/credential/verify?attribute=$SERVICE_KEY.$USER_ATTR&subject_key=$ALICE_KEY" --data "$CREDS" | ||
72 | |||
73 | #TODO cleanup properly | ||
74 | gnunet-namestore -z alice -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf | ||
75 | gnunet-namestore -z gnu -d -n $GNU_PROJECT_ATTR -t ATTR -c test_credential_lookup.conf | ||
76 | gnunet-namestore -z gnunet -d -n $MEMBER_ATTR -t ATTR -c test_credential_lookup.conf | ||
77 | gnunet-namestore -z service -d -n $USER_ATTR -t ATTR -c test_credential_lookup.conf | ||
78 | gnunet-arm -e -c test_credential_lookup.conf | ||
79 | |||
80 | if [ "$RES_CRED" != "Failed." ] | ||
81 | then | ||
82 | echo -e "${RES_CRED}" | ||
83 | exit 0 | ||
84 | else | ||
85 | echo "FAIL: Failed to verify credential $RES_CRED." | ||
86 | exit 1 | ||
87 | fi | ||
diff --git a/src/credential/test_credential_verify_simple.sh b/src/credential/test_credential_verify_simple.sh new file mode 100755 index 000000000..c4fd8c7a3 --- /dev/null +++ b/src/credential/test_credential_verify_simple.sh | |||
@@ -0,0 +1,50 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (3) Isser.user -> Subject | ||
19 | |||
20 | |||
21 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
22 | gnunet-arm -s -c test_credential_lookup.conf | ||
23 | gnunet-identity -C testissuer -c test_credential_lookup.conf | ||
24 | gnunet-identity -C testsubject -c test_credential_lookup.conf | ||
25 | |||
26 | TEST_ATTR="user" | ||
27 | SUBJECT_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testsubject | awk '{print $3}') | ||
28 | ISSUER_KEY=$(gnunet-identity -d -c test_credential_lookup.conf | grep testissuer | awk '{print $3}') | ||
29 | CRED=`$DO_TIMEOUT gnunet-credential --issue --ego=testissuer --subject=$SUBJECT_KEY --attribute=$TEST_ATTR --ttl=5m -c test_credential_lookup.conf` | ||
30 | |||
31 | TEST_CREDENTIAL="t1" | ||
32 | gnunet-namestore -p -z testsubject -a -n $TEST_CREDENTIAL -t CRED -V "$CRED" -e 5m -c test_credential_lookup.conf | ||
33 | |||
34 | #TODO2 Add -z swich like in gnunet-gns | ||
35 | #RES_CRED=`$DO_TIMEOUT gnunet-credential --verify --issuer=$ISSUER_KEY --attribute="$TEST_ATTR" --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf` | ||
36 | RES_CRED=`gnunet-credential --verify --issuer=$ISSUER_KEY --attribute=$TEST_ATTR --subject=$SUBJECT_KEY --credential=$TEST_CREDENTIAL -c test_credential_lookup.conf` | ||
37 | |||
38 | #TODO cleanup properly | ||
39 | gnunet-namestore -z testsubject -d -n $TEST_CREDENTIAL -t CRED -e never -c test_credential_lookup.conf | ||
40 | gnunet-identity -D testsubject -c test_credential_lookup.conf | ||
41 | gnunet-arm -e -c test_credential_lookup.conf | ||
42 | echo $RES_CRED | ||
43 | #TODO3 proper test | ||
44 | if [ "$RES_CRED" == "Successful." ] | ||
45 | then | ||
46 | exit 0 | ||
47 | else | ||
48 | echo "FAIL: Failed to verify credential." | ||
49 | exit 1 | ||
50 | fi | ||
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index 7196a1844..d9a5dd684 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -3802,7 +3802,7 @@ run (void *cls, | |||
3802 | if (GNUNET_YES != | 3802 | if (GNUNET_YES != |
3803 | GNUNET_OS_check_helper_binary (binary, | 3803 | GNUNET_OS_check_helper_binary (binary, |
3804 | GNUNET_YES, | 3804 | GNUNET_YES, |
3805 | "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) //no nat, ipv4 only | 3805 | "gnunet-vpn - - - 169.1.3.7 255.255.255.0")) //no nat, ipv4 only |
3806 | { | 3806 | { |
3807 | GNUNET_free (binary); | 3807 | GNUNET_free (binary); |
3808 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 3808 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c index 26293f4df..84c4ae189 100644 --- a/src/gns/gns_api.c +++ b/src/gns/gns_api.c | |||
@@ -244,10 +244,7 @@ handle_result (void *cls, | |||
244 | return; | 244 | return; |
245 | proc = lr->lookup_proc; | 245 | proc = lr->lookup_proc; |
246 | proc_cls = lr->proc_cls; | 246 | proc_cls = lr->proc_cls; |
247 | GNUNET_CONTAINER_DLL_remove (handle->lookup_head, | 247 | |
248 | handle->lookup_tail, | ||
249 | lr); | ||
250 | GNUNET_free (lr); | ||
251 | GNUNET_assert (GNUNET_OK == | 248 | GNUNET_assert (GNUNET_OK == |
252 | GNUNET_GNSRECORD_records_deserialize (mlen, | 249 | GNUNET_GNSRECORD_records_deserialize (mlen, |
253 | (const char*) &lookup_msg[1], | 250 | (const char*) &lookup_msg[1], |
@@ -256,6 +253,12 @@ handle_result (void *cls, | |||
256 | proc (proc_cls, | 253 | proc (proc_cls, |
257 | rd_count, | 254 | rd_count, |
258 | rd); | 255 | rd); |
256 | GNUNET_CONTAINER_DLL_remove (handle->lookup_head, | ||
257 | handle->lookup_tail, | ||
258 | lr); | ||
259 | if (NULL != lr->env) | ||
260 | GNUNET_MQ_discard (lr->env); | ||
261 | GNUNET_free (lr); | ||
259 | } | 262 | } |
260 | 263 | ||
261 | 264 | ||
diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 5d611e19e..6adad0f34 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c | |||
@@ -140,30 +140,6 @@ gns_value_to_string (void *cls, | |||
140 | GNUNET_free (ival); | 140 | GNUNET_free (ival); |
141 | return box_str; | 141 | return box_str; |
142 | } | 142 | } |
143 | case GNUNET_GNSRECORD_TYPE_REVERSE: | ||
144 | { | ||
145 | struct GNUNET_GNSRECORD_ReverseRecord rev; | ||
146 | char *rev_str; | ||
147 | char *pkey_str; | ||
148 | |||
149 | if (data_size < sizeof (struct GNUNET_GNSRECORD_ReverseRecord)) | ||
150 | return NULL; /* malformed */ | ||
151 | |||
152 | memcpy (&rev, | ||
153 | data, | ||
154 | sizeof (rev)); | ||
155 | cdata = data; | ||
156 | pkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&rev.pkey); | ||
157 | |||
158 | GNUNET_asprintf (&rev_str, | ||
159 | "%s %s %"SCNu64, | ||
160 | &cdata[sizeof (rev)], | ||
161 | pkey_str, | ||
162 | rev.expiration.abs_value_us); | ||
163 | GNUNET_free (pkey_str); | ||
164 | return rev_str; | ||
165 | |||
166 | } | ||
167 | default: | 143 | default: |
168 | return NULL; | 144 | return NULL; |
169 | } | 145 | } |
@@ -335,48 +311,6 @@ gns_string_to_value (void *cls, | |||
335 | GNUNET_free (bval); | 311 | GNUNET_free (bval); |
336 | return GNUNET_OK; | 312 | return GNUNET_OK; |
337 | } | 313 | } |
338 | case GNUNET_GNSRECORD_TYPE_REVERSE: | ||
339 | { | ||
340 | struct GNUNET_GNSRECORD_ReverseRecord *rev; | ||
341 | char known_by[253 + 1]; | ||
342 | struct GNUNET_TIME_Absolute expiration; | ||
343 | |||
344 | /* TODO: From crypto_ecc.c | ||
345 | * Why is this not a constant??? | ||
346 | */ | ||
347 | size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | ||
348 | if (enclen % 5 > 0) | ||
349 | enclen += 5 - enclen % 5; | ||
350 | enclen /= 5; /* 260/5 = 52 */ | ||
351 | char pkey_str[enclen + 1]; | ||
352 | |||
353 | if (3 != SSCANF (s, | ||
354 | "%253s %52s %"SCNu64, | ||
355 | known_by, | ||
356 | pkey_str, | ||
357 | &expiration.abs_value_us)) | ||
358 | { | ||
359 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
360 | _("Unable to parse REVERSE record string `%s'\n"), | ||
361 | s); | ||
362 | return GNUNET_SYSERR; | ||
363 | } | ||
364 | *data_size = sizeof (struct GNUNET_GNSRECORD_ReverseRecord) + strlen (known_by) + 1; | ||
365 | *data = rev = GNUNET_malloc (*data_size); | ||
366 | if (GNUNET_OK != | ||
367 | GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey_str, | ||
368 | strlen (pkey_str), | ||
369 | &rev->pkey)) | ||
370 | { | ||
371 | GNUNET_free (rev); | ||
372 | return GNUNET_SYSERR; | ||
373 | } | ||
374 | rev->expiration = expiration; | ||
375 | GNUNET_memcpy (&rev[1], | ||
376 | known_by, | ||
377 | strlen (known_by)); | ||
378 | return GNUNET_OK; | ||
379 | } | ||
380 | default: | 314 | default: |
381 | return GNUNET_SYSERR; | 315 | return GNUNET_SYSERR; |
382 | } | 316 | } |
@@ -397,7 +331,6 @@ static struct { | |||
397 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, | 331 | { "VPN", GNUNET_GNSRECORD_TYPE_VPN }, |
398 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, | 332 | { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS }, |
399 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, | 333 | { "BOX", GNUNET_GNSRECORD_TYPE_BOX }, |
400 | { "REVERSE", GNUNET_GNSRECORD_TYPE_REVERSE }, | ||
401 | { NULL, UINT32_MAX } | 334 | { NULL, UINT32_MAX } |
402 | }; | 335 | }; |
403 | 336 | ||
diff --git a/src/identity-attribute/Makefile.am b/src/identity-attribute/Makefile.am new file mode 100644 index 000000000..2c73a443e --- /dev/null +++ b/src/identity-attribute/Makefile.am | |||
@@ -0,0 +1,44 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | plugindir = $(libdir)/gnunet | ||
5 | |||
6 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
7 | |||
8 | libexecdir= $(pkglibdir)/libexec/ | ||
9 | |||
10 | if MINGW | ||
11 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
12 | endif | ||
13 | |||
14 | if USE_COVERAGE | ||
15 | AM_CFLAGS = --coverage -O0 | ||
16 | XLIBS = -lgcov | ||
17 | endif | ||
18 | |||
19 | lib_LTLIBRARIES = \ | ||
20 | libgnunetidentityattribute.la | ||
21 | |||
22 | libgnunetidentityattribute_la_SOURCES = \ | ||
23 | identity_attribute.c | ||
24 | libgnunetidentityattribute_la_LIBADD = \ | ||
25 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
26 | $(GN_LIBINTL) | ||
27 | libgnunetidentityattribute_la_LDFLAGS = \ | ||
28 | $(GN_LIB_LDFLAGS) $(WINFLAGS) \ | ||
29 | -version-info 0:0:0 | ||
30 | |||
31 | |||
32 | plugin_LTLIBRARIES = \ | ||
33 | libgnunet_plugin_identity_attribute_gnuid.la | ||
34 | |||
35 | |||
36 | libgnunet_plugin_identity_attribute_gnuid_la_SOURCES = \ | ||
37 | plugin_identity_attribute_gnuid.c | ||
38 | libgnunet_plugin_identity_attribute_gnuid_la_LIBADD = \ | ||
39 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
40 | $(LTLIBINTL) | ||
41 | libgnunet_plugin_identity_attribute_gnuid_la_LDFLAGS = \ | ||
42 | $(GN_PLUGIN_LDFLAGS) | ||
43 | |||
44 | |||
diff --git a/src/identity-attribute/identity_attribute.c b/src/identity-attribute/identity_attribute.c new file mode 100644 index 000000000..cf50d058e --- /dev/null +++ b/src/identity-attribute/identity_attribute.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity-attribute/identity_attribute.c | ||
23 | * @brief helper library to manage identity attributes | ||
24 | * @author Martin Schanzenbach | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "identity_attribute.h" | ||
29 | #include "gnunet_identity_attribute_plugin.h" | ||
30 | |||
31 | /** | ||
32 | * Handle for a plugin | ||
33 | */ | ||
34 | struct Plugin | ||
35 | { | ||
36 | /** | ||
37 | * Name of the plugin | ||
38 | */ | ||
39 | char *library_name; | ||
40 | |||
41 | /** | ||
42 | * Plugin API | ||
43 | */ | ||
44 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api; | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * Plugins | ||
49 | */ | ||
50 | static struct Plugin **attr_plugins; | ||
51 | |||
52 | /** | ||
53 | * Number of plugins | ||
54 | */ | ||
55 | static unsigned int num_plugins; | ||
56 | |||
57 | /** | ||
58 | * Init canary | ||
59 | */ | ||
60 | static int initialized; | ||
61 | |||
62 | /** | ||
63 | * Add a plugin | ||
64 | */ | ||
65 | static void | ||
66 | add_plugin (void* cls, | ||
67 | const char *library_name, | ||
68 | void *lib_ret) | ||
69 | { | ||
70 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = lib_ret; | ||
71 | struct Plugin *plugin; | ||
72 | |||
73 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
74 | "Loading attribute plugin `%s'\n", | ||
75 | library_name); | ||
76 | plugin = GNUNET_new (struct Plugin); | ||
77 | plugin->api = api; | ||
78 | plugin->library_name = GNUNET_strdup (library_name); | ||
79 | GNUNET_array_append (attr_plugins, num_plugins, plugin); | ||
80 | } | ||
81 | |||
82 | /** | ||
83 | * Load plugins | ||
84 | */ | ||
85 | static void | ||
86 | init() | ||
87 | { | ||
88 | if (GNUNET_YES == initialized) | ||
89 | return; | ||
90 | initialized = GNUNET_YES; | ||
91 | GNUNET_PLUGIN_load_all ("libgnunet_plugin_identity_attribute_", NULL, | ||
92 | &add_plugin, NULL); | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * Convert a type name to the corresponding number | ||
97 | * | ||
98 | * @param typename name to convert | ||
99 | * @return corresponding number, UINT32_MAX on error | ||
100 | */ | ||
101 | uint32_t | ||
102 | GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename) | ||
103 | { | ||
104 | unsigned int i; | ||
105 | struct Plugin *plugin; | ||
106 | uint32_t ret; | ||
107 | |||
108 | init (); | ||
109 | for (i = 0; i < num_plugins; i++) | ||
110 | { | ||
111 | plugin = attr_plugins[i]; | ||
112 | if (UINT32_MAX != (ret = plugin->api->typename_to_number (plugin->api->cls, | ||
113 | typename))) | ||
114 | return ret; | ||
115 | } | ||
116 | return UINT32_MAX; | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Convert a type number to the corresponding type string | ||
121 | * | ||
122 | * @param type number of a type | ||
123 | * @return corresponding typestring, NULL on error | ||
124 | */ | ||
125 | const char* | ||
126 | GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type) | ||
127 | { | ||
128 | unsigned int i; | ||
129 | struct Plugin *plugin; | ||
130 | const char *ret; | ||
131 | |||
132 | init (); | ||
133 | for (i = 0; i < num_plugins; i++) | ||
134 | { | ||
135 | plugin = attr_plugins[i]; | ||
136 | if (NULL != (ret = plugin->api->number_to_typename (plugin->api->cls, | ||
137 | type))) | ||
138 | return ret; | ||
139 | } | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Convert human-readable version of a 'claim' of an attribute to the binary | ||
145 | * representation | ||
146 | * | ||
147 | * @param type type of the claim | ||
148 | * @param s human-readable string | ||
149 | * @param data set to value in binary encoding (will be allocated) | ||
150 | * @param data_size set to number of bytes in @a data | ||
151 | * @return #GNUNET_OK on success | ||
152 | */ | ||
153 | int | ||
154 | GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type, | ||
155 | const char *s, | ||
156 | void **data, | ||
157 | size_t *data_size) | ||
158 | { | ||
159 | unsigned int i; | ||
160 | struct Plugin *plugin; | ||
161 | |||
162 | init (); | ||
163 | for (i = 0; i < num_plugins; i++) | ||
164 | { | ||
165 | plugin = attr_plugins[i]; | ||
166 | if (GNUNET_OK == plugin->api->string_to_value (plugin->api->cls, | ||
167 | type, | ||
168 | s, | ||
169 | data, | ||
170 | data_size)) | ||
171 | return GNUNET_OK; | ||
172 | } | ||
173 | return GNUNET_SYSERR; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * Convert the 'claim' of an attribute to a string | ||
178 | * | ||
179 | * @param type the type of attribute | ||
180 | * @param data claim in binary encoding | ||
181 | * @param data_size number of bytes in @a data | ||
182 | * @return NULL on error, otherwise human-readable representation of the claim | ||
183 | */ | ||
184 | char * | ||
185 | GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type, | ||
186 | const void* data, | ||
187 | size_t data_size) | ||
188 | { | ||
189 | unsigned int i; | ||
190 | struct Plugin *plugin; | ||
191 | char *ret; | ||
192 | |||
193 | init(); | ||
194 | for (i = 0; i < num_plugins; i++) | ||
195 | { | ||
196 | plugin = attr_plugins[i]; | ||
197 | if (NULL != (ret = plugin->api->value_to_string (plugin->api->cls, | ||
198 | type, | ||
199 | data, | ||
200 | data_size))) | ||
201 | return ret; | ||
202 | } | ||
203 | return NULL; | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * Create a new attribute. | ||
208 | * | ||
209 | * @param attr_name the attribute name | ||
210 | * @param type the attribute type | ||
211 | * @param data the attribute value | ||
212 | * @param data_size the attribute value size | ||
213 | * @return the new attribute | ||
214 | */ | ||
215 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim * | ||
216 | GNUNET_IDENTITY_ATTRIBUTE_claim_new (const char* attr_name, | ||
217 | uint32_t type, | ||
218 | const void* data, | ||
219 | size_t data_size) | ||
220 | { | ||
221 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr; | ||
222 | char *write_ptr; | ||
223 | |||
224 | attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) + | ||
225 | strlen (attr_name) + 1 + | ||
226 | data_size); | ||
227 | attr->type = type; | ||
228 | attr->data_size = data_size; | ||
229 | attr->version = 0; | ||
230 | write_ptr = (char*)&attr[1]; | ||
231 | GNUNET_memcpy (write_ptr, | ||
232 | attr_name, | ||
233 | strlen (attr_name) + 1); | ||
234 | attr->name = write_ptr; | ||
235 | write_ptr += strlen (attr->name) + 1; | ||
236 | GNUNET_memcpy (write_ptr, | ||
237 | data, | ||
238 | data_size); | ||
239 | attr->data = write_ptr; | ||
240 | return attr; | ||
241 | } | ||
242 | |||
243 | size_t | ||
244 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
245 | { | ||
246 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
247 | size_t len = 0; | ||
248 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
249 | len += GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim); | ||
250 | return len; | ||
251 | } | ||
252 | |||
253 | size_t | ||
254 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
255 | char *result) | ||
256 | { | ||
257 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
258 | size_t len; | ||
259 | size_t total_len; | ||
260 | char* write_ptr; | ||
261 | |||
262 | write_ptr = result; | ||
263 | total_len = 0; | ||
264 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
265 | { | ||
266 | len = GNUNET_IDENTITY_ATTRIBUTE_serialize (le->claim, | ||
267 | write_ptr); | ||
268 | total_len += len; | ||
269 | write_ptr += len; | ||
270 | } | ||
271 | return total_len; | ||
272 | } | ||
273 | |||
274 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList * | ||
275 | GNUNET_IDENTITY_ATTRIBUTE_list_deserialize (const char* data, | ||
276 | size_t data_size) | ||
277 | { | ||
278 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; | ||
279 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
280 | size_t attr_len; | ||
281 | const char* read_ptr; | ||
282 | |||
283 | if (data_size < sizeof (struct Attribute)) | ||
284 | return NULL; | ||
285 | |||
286 | attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
287 | read_ptr = data; | ||
288 | while (((data + data_size) - read_ptr) >= sizeof (struct Attribute)) | ||
289 | { | ||
290 | |||
291 | le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry); | ||
292 | le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (read_ptr, | ||
293 | data_size - (read_ptr - data)); | ||
294 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
295 | "Deserialized attribute %s\n", le->claim->name); | ||
296 | GNUNET_CONTAINER_DLL_insert (attrs->list_head, | ||
297 | attrs->list_tail, | ||
298 | le); | ||
299 | attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (le->claim); | ||
300 | read_ptr += attr_len; | ||
301 | } | ||
302 | return attrs; | ||
303 | } | ||
304 | |||
305 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList* | ||
306 | GNUNET_IDENTITY_ATTRIBUTE_list_dup (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
307 | { | ||
308 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
309 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *result_le; | ||
310 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *result; | ||
311 | size_t len; | ||
312 | |||
313 | result = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
314 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
315 | { | ||
316 | result_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry); | ||
317 | len = sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) + le->claim->data_size; | ||
318 | result_le->claim = GNUNET_malloc (len); | ||
319 | GNUNET_memcpy (result_le->claim, | ||
320 | le->claim, | ||
321 | len); | ||
322 | result_le->claim->name = (const char*)&result_le->claim[1]; | ||
323 | GNUNET_CONTAINER_DLL_insert (result->list_head, | ||
324 | result->list_tail, | ||
325 | result_le); | ||
326 | } | ||
327 | return result; | ||
328 | } | ||
329 | |||
330 | |||
331 | void | ||
332 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
333 | { | ||
334 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
335 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *tmp_le; | ||
336 | |||
337 | for (le = attrs->list_head; NULL != le;) | ||
338 | { | ||
339 | GNUNET_free (le->claim); | ||
340 | tmp_le = le; | ||
341 | le = le->next; | ||
342 | GNUNET_free (tmp_le); | ||
343 | } | ||
344 | GNUNET_free (attrs); | ||
345 | |||
346 | } | ||
347 | |||
348 | size_t | ||
349 | GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) | ||
350 | { | ||
351 | return sizeof (struct Attribute) | ||
352 | + strlen (attr->name) | ||
353 | + attr->data_size; | ||
354 | } | ||
355 | |||
356 | size_t | ||
357 | GNUNET_IDENTITY_ATTRIBUTE_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr, | ||
358 | char *result) | ||
359 | { | ||
360 | size_t data_len_ser; | ||
361 | size_t name_len; | ||
362 | struct Attribute *attr_ser; | ||
363 | char* write_ptr; | ||
364 | |||
365 | attr_ser = (struct Attribute*)result; | ||
366 | attr_ser->attribute_type = htons (attr->type); | ||
367 | attr_ser->attribute_version = htonl (attr->version); | ||
368 | name_len = strlen (attr->name); | ||
369 | attr_ser->name_len = htons (name_len); | ||
370 | write_ptr = (char*)&attr_ser[1]; | ||
371 | GNUNET_memcpy (write_ptr, attr->name, name_len); | ||
372 | write_ptr += name_len; | ||
373 | //TODO plugin-ize | ||
374 | //data_len_ser = plugin->serialize_attribute_value (attr, | ||
375 | // &attr_ser[1]); | ||
376 | data_len_ser = attr->data_size; | ||
377 | GNUNET_memcpy (write_ptr, attr->data, attr->data_size); | ||
378 | attr_ser->data_size = htons (data_len_ser); | ||
379 | |||
380 | return sizeof (struct Attribute) + strlen (attr->name) + attr->data_size; | ||
381 | } | ||
382 | |||
383 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim * | ||
384 | GNUNET_IDENTITY_ATTRIBUTE_deserialize (const char* data, | ||
385 | size_t data_size) | ||
386 | { | ||
387 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr; | ||
388 | struct Attribute *attr_ser; | ||
389 | size_t data_len; | ||
390 | size_t name_len; | ||
391 | char* write_ptr; | ||
392 | |||
393 | if (data_size < sizeof (struct Attribute)) | ||
394 | return NULL; | ||
395 | |||
396 | attr_ser = (struct Attribute*)data; | ||
397 | data_len = ntohs (attr_ser->data_size); | ||
398 | name_len = ntohs (attr_ser->name_len); | ||
399 | attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_ATTRIBUTE_Claim) | ||
400 | + data_len + name_len + 1); | ||
401 | attr->type = ntohs (attr_ser->attribute_type); | ||
402 | attr->version = ntohl (attr_ser->attribute_version); | ||
403 | attr->data_size = ntohs (attr_ser->data_size); | ||
404 | |||
405 | write_ptr = (char*)&attr[1]; | ||
406 | GNUNET_memcpy (write_ptr, | ||
407 | &attr_ser[1], | ||
408 | name_len); | ||
409 | write_ptr[name_len] = '\0'; | ||
410 | attr->name = write_ptr; | ||
411 | |||
412 | write_ptr += name_len + 1; | ||
413 | GNUNET_memcpy (write_ptr, | ||
414 | (char*)&attr_ser[1] + name_len, | ||
415 | attr->data_size); | ||
416 | attr->data = write_ptr; | ||
417 | return attr; | ||
418 | |||
419 | } | ||
420 | |||
421 | /* end of identity_attribute.c */ | ||
diff --git a/src/identity-attribute/identity_attribute.h b/src/identity-attribute/identity_attribute.h new file mode 100644 index 000000000..8dfc17521 --- /dev/null +++ b/src/identity-attribute/identity_attribute.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @author Martin Schanzenbach | ||
22 | * @file identity-attribute/identity_attribute.h | ||
23 | * @brief GNUnet Identity attributes | ||
24 | * | ||
25 | */ | ||
26 | #ifndef IDENTITY_ATTRIBUTE_H | ||
27 | #define IDENTITY_ATTRIBUTE_H | ||
28 | |||
29 | #include "gnunet_identity_provider_service.h" | ||
30 | |||
31 | struct Attribute | ||
32 | { | ||
33 | /** | ||
34 | * Attribute type | ||
35 | */ | ||
36 | uint32_t attribute_type; | ||
37 | |||
38 | /** | ||
39 | * Attribute version | ||
40 | */ | ||
41 | uint32_t attribute_version; | ||
42 | |||
43 | /** | ||
44 | * Name length | ||
45 | */ | ||
46 | uint32_t name_len; | ||
47 | |||
48 | /** | ||
49 | * Data size | ||
50 | */ | ||
51 | uint32_t data_size; | ||
52 | |||
53 | //followed by data_size Attribute value data | ||
54 | }; | ||
55 | |||
56 | #endif | ||
diff --git a/src/identity-attribute/plugin_identity_attribute_gnuid.c b/src/identity-attribute/plugin_identity_attribute_gnuid.c new file mode 100644 index 000000000..006b45ea2 --- /dev/null +++ b/src/identity-attribute/plugin_identity_attribute_gnuid.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2013, 2014, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity-attribute/plugin_identity_attribute_gnuid.c | ||
23 | * @brief identity attribute plugin to provide the API for fundamental | ||
24 | * attribute types. | ||
25 | * | ||
26 | * @author Martin Schanzenbach | ||
27 | */ | ||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_identity_attribute_plugin.h" | ||
31 | #include <inttypes.h> | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Convert the 'value' of an attribute to a string. | ||
36 | * | ||
37 | * @param cls closure, unused | ||
38 | * @param type type of the attribute | ||
39 | * @param data value in binary encoding | ||
40 | * @param data_size number of bytes in @a data | ||
41 | * @return NULL on error, otherwise human-readable representation of the value | ||
42 | */ | ||
43 | static char * | ||
44 | gnuid_value_to_string (void *cls, | ||
45 | uint32_t type, | ||
46 | const void *data, | ||
47 | size_t data_size) | ||
48 | { | ||
49 | |||
50 | switch (type) | ||
51 | { | ||
52 | case GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING: | ||
53 | return GNUNET_strndup (data, data_size); | ||
54 | default: | ||
55 | return NULL; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | |||
60 | /** | ||
61 | * Convert human-readable version of a 'value' of an attribute to the binary | ||
62 | * representation. | ||
63 | * | ||
64 | * @param cls closure, unused | ||
65 | * @param type type of the attribute | ||
66 | * @param s human-readable string | ||
67 | * @param data set to value in binary encoding (will be allocated) | ||
68 | * @param data_size set to number of bytes in @a data | ||
69 | * @return #GNUNET_OK on success | ||
70 | */ | ||
71 | static int | ||
72 | gnuid_string_to_value (void *cls, | ||
73 | uint32_t type, | ||
74 | const char *s, | ||
75 | void **data, | ||
76 | size_t *data_size) | ||
77 | { | ||
78 | if (NULL == s) | ||
79 | return GNUNET_SYSERR; | ||
80 | switch (type) | ||
81 | { | ||
82 | |||
83 | case GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING: | ||
84 | *data = GNUNET_strdup (s); | ||
85 | *data_size = strlen (s); | ||
86 | return GNUNET_OK; | ||
87 | default: | ||
88 | return GNUNET_SYSERR; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Mapping of attribute type numbers to human-readable | ||
95 | * attribute type names. | ||
96 | */ | ||
97 | static struct { | ||
98 | const char *name; | ||
99 | uint32_t number; | ||
100 | } gnuid_name_map[] = { | ||
101 | { "STRING", GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING }, | ||
102 | { NULL, UINT32_MAX } | ||
103 | }; | ||
104 | |||
105 | |||
106 | /** | ||
107 | * Convert a type name to the corresponding number. | ||
108 | * | ||
109 | * @param cls closure, unused | ||
110 | * @param gnuid_typename name to convert | ||
111 | * @return corresponding number, UINT32_MAX on error | ||
112 | */ | ||
113 | static uint32_t | ||
114 | gnuid_typename_to_number (void *cls, | ||
115 | const char *gnuid_typename) | ||
116 | { | ||
117 | unsigned int i; | ||
118 | |||
119 | i=0; | ||
120 | while ( (NULL != gnuid_name_map[i].name) && | ||
121 | (0 != strcasecmp (gnuid_typename, | ||
122 | gnuid_name_map[i].name)) ) | ||
123 | i++; | ||
124 | return gnuid_name_map[i].number; | ||
125 | } | ||
126 | |||
127 | |||
128 | /** | ||
129 | * Convert a type number (i.e. 1) to the corresponding type string | ||
130 | * | ||
131 | * @param cls closure, unused | ||
132 | * @param type number of a type to convert | ||
133 | * @return corresponding typestring, NULL on error | ||
134 | */ | ||
135 | static const char * | ||
136 | gnuid_number_to_typename (void *cls, | ||
137 | uint32_t type) | ||
138 | { | ||
139 | unsigned int i; | ||
140 | |||
141 | i=0; | ||
142 | while ( (NULL != gnuid_name_map[i].name) && | ||
143 | (type != gnuid_name_map[i].number) ) | ||
144 | i++; | ||
145 | return gnuid_name_map[i].name; | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
150 | * Entry point for the plugin. | ||
151 | * | ||
152 | * @param cls NULL | ||
153 | * @return the exported block API | ||
154 | */ | ||
155 | void * | ||
156 | libgnunet_plugin_identity_attribute_gnuid_init (void *cls) | ||
157 | { | ||
158 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api; | ||
159 | |||
160 | api = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions); | ||
161 | api->value_to_string = &gnuid_value_to_string; | ||
162 | api->string_to_value = &gnuid_string_to_value; | ||
163 | api->typename_to_number = &gnuid_typename_to_number; | ||
164 | api->number_to_typename = &gnuid_number_to_typename; | ||
165 | return api; | ||
166 | } | ||
167 | |||
168 | |||
169 | /** | ||
170 | * Exit point from the plugin. | ||
171 | * | ||
172 | * @param cls the return value from #libgnunet_plugin_block_test_init() | ||
173 | * @return NULL | ||
174 | */ | ||
175 | void * | ||
176 | libgnunet_plugin_identity_attribute_gnuid_done (void *cls) | ||
177 | { | ||
178 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions *api = cls; | ||
179 | |||
180 | GNUNET_free (api); | ||
181 | return NULL; | ||
182 | } | ||
183 | |||
184 | /* end of plugin_identity_attribute_type_gnuid.c */ | ||
diff --git a/src/identity-provider/Makefile.am b/src/identity-provider/Makefile.am index 0d8752c4c..adf6af3b3 100644 --- a/src/identity-provider/Makefile.am +++ b/src/identity-provider/Makefile.am | |||
@@ -12,6 +12,15 @@ if USE_COVERAGE | |||
12 | XLIB = -lgcov | 12 | XLIB = -lgcov |
13 | endif | 13 | endif |
14 | 14 | ||
15 | if HAVE_SQLITE | ||
16 | SQLITE_PLUGIN = libgnunet_plugin_identity_provider_sqlite.la | ||
17 | endif | ||
18 | |||
19 | EXTRA_DIST = \ | ||
20 | test_idp_defaults.conf \ | ||
21 | test_idp.conf \ | ||
22 | $(check_SCRIPTS) | ||
23 | |||
15 | pkgcfgdir= $(pkgdatadir)/config.d/ | 24 | pkgcfgdir= $(pkgdatadir)/config.d/ |
16 | 25 | ||
17 | libexecdir= $(pkglibdir)/libexec/ | 26 | libexecdir= $(pkglibdir)/libexec/ |
@@ -22,29 +31,51 @@ pkgcfg_DATA = \ | |||
22 | lib_LTLIBRARIES = \ | 31 | lib_LTLIBRARIES = \ |
23 | libgnunetidentityprovider.la | 32 | libgnunetidentityprovider.la |
24 | plugin_LTLIBRARIES = \ | 33 | plugin_LTLIBRARIES = \ |
25 | libgnunet_plugin_rest_identity_provider.la | 34 | libgnunet_plugin_rest_identity_provider.la \ |
35 | libgnunet_plugin_gnsrecord_identity_provider.la \ | ||
36 | $(SQLITE_PLUGIN) | ||
26 | 37 | ||
27 | bin_PROGRAMS = \ | 38 | bin_PROGRAMS = \ |
28 | gnunet-identity-token | 39 | gnunet-idp |
29 | 40 | ||
30 | libexec_PROGRAMS = \ | 41 | libexec_PROGRAMS = \ |
31 | gnunet-service-identity-provider | 42 | gnunet-service-identity-provider |
32 | 43 | ||
33 | EXTRA_DIST = \ | 44 | libgnunet_plugin_gnsrecord_identity_provider_la_SOURCES = \ |
34 | $(pkgcfg_DATA) | 45 | plugin_gnsrecord_identity_provider.c |
46 | libgnunet_plugin_gnsrecord_identity_provider_la_LIBADD = \ | ||
47 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
48 | $(LTLIBINTL) | ||
49 | libgnunet_plugin_gnsrecord_identity_provider_la_LDFLAGS = \ | ||
50 | $(GN_PLUGIN_LDFLAGS) | ||
51 | |||
52 | libgnunet_plugin_identity_provider_sqlite_la_SOURCES = \ | ||
53 | plugin_identity_provider_sqlite.c | ||
54 | libgnunet_plugin_identity_provider_sqlite_la_LIBADD = \ | ||
55 | libgnunetidentityprovider.la \ | ||
56 | $(top_builddir)/src/sq/libgnunetsq.la \ | ||
57 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
58 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \ | ||
59 | $(LTLIBINTL) | ||
60 | libgnunet_plugin_identity_provider_sqlite_la_LDFLAGS = \ | ||
61 | $(GN_PLUGIN_LDFLAGS) | ||
62 | |||
63 | |||
35 | 64 | ||
36 | gnunet_service_identity_provider_SOURCES = \ | 65 | gnunet_service_identity_provider_SOURCES = \ |
37 | gnunet-service-identity-provider.c \ | 66 | gnunet-service-identity-provider.c |
38 | identity_token.c identity_token.h | ||
39 | gnunet_service_identity_provider_LDADD = \ | 67 | gnunet_service_identity_provider_LDADD = \ |
40 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ | 68 | $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ |
41 | $(top_builddir)/src/util/libgnunetutil.la \ | 69 | $(top_builddir)/src/util/libgnunetutil.la \ |
42 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 70 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
43 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 71 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
44 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 72 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
73 | $(top_builddir)/src/abe/libgnunetabe.la \ | ||
74 | $(top_builddir)/src/credential/libgnunetcredential.la \ | ||
75 | $(top_builddir)/src/identity-attribute/libgnunetidentityattribute.la \ | ||
76 | libgnunetidentityprovider.la \ | ||
45 | $(top_builddir)/src/gns/libgnunetgns.la \ | 77 | $(top_builddir)/src/gns/libgnunetgns.la \ |
46 | $(GN_LIBINTL) \ | 78 | $(GN_LIBINTL) |
47 | -ljansson | ||
48 | 79 | ||
49 | libgnunetidentityprovider_la_SOURCES = \ | 80 | libgnunetidentityprovider_la_SOURCES = \ |
50 | identity_provider_api.c \ | 81 | identity_provider_api.c \ |
@@ -57,22 +88,37 @@ libgnunetidentityprovider_la_LDFLAGS = \ | |||
57 | -version-info 0:0:0 | 88 | -version-info 0:0:0 |
58 | 89 | ||
59 | libgnunet_plugin_rest_identity_provider_la_SOURCES = \ | 90 | libgnunet_plugin_rest_identity_provider_la_SOURCES = \ |
60 | plugin_rest_identity_provider.c | 91 | plugin_rest_identity_provider.c \ |
92 | jwt.c | ||
61 | libgnunet_plugin_rest_identity_provider_la_LIBADD = \ | 93 | libgnunet_plugin_rest_identity_provider_la_LIBADD = \ |
62 | $(top_builddir)/src/identity/libgnunetidentity.la \ | 94 | $(top_builddir)/src/identity/libgnunetidentity.la \ |
63 | libgnunetidentityprovider.la \ | 95 | libgnunetidentityprovider.la \ |
64 | $(top_builddir)/src/rest/libgnunetrest.la \ | 96 | $(top_builddir)/src/rest/libgnunetrest.la \ |
65 | $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ | 97 | $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ |
98 | $(top_builddir)/src/identity-attribute/libgnunetidentityattribute.la \ | ||
66 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 99 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
67 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ | 100 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ |
68 | $(LTLIBINTL) -ljansson -lmicrohttpd | 101 | $(LTLIBINTL) -ljansson -lmicrohttpd |
69 | libgnunet_plugin_rest_identity_provider_la_LDFLAGS = \ | 102 | libgnunet_plugin_rest_identity_provider_la_LDFLAGS = \ |
70 | $(GN_PLUGIN_LDFLAGS) | 103 | $(GN_PLUGIN_LDFLAGS) |
71 | 104 | ||
72 | 105 | gnunet_idp_SOURCES = \ | |
73 | gnunet_identity_token_SOURCES = \ | 106 | gnunet-idp.c |
74 | gnunet-identity-token.c | 107 | gnunet_idp_LDADD = \ |
75 | gnunet_identity_token_LDADD = \ | ||
76 | $(top_builddir)/src/util/libgnunetutil.la \ | 108 | $(top_builddir)/src/util/libgnunetutil.la \ |
77 | -ljansson -lmicrohttpd \ | 109 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
110 | libgnunetidentityprovider.la \ | ||
111 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
112 | $(top_builddir)/src/identity-attribute/libgnunetidentityattribute.la \ | ||
78 | $(GN_LIBINTL) | 113 | $(GN_LIBINTL) |
114 | |||
115 | check_SCRIPTS = \ | ||
116 | test_idp_attribute.sh \ | ||
117 | test_idp_issue.sh \ | ||
118 | test_idp_consume.sh \ | ||
119 | test_idp_revoke.sh | ||
120 | |||
121 | if ENABLE_TEST_RUN | ||
122 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
123 | TESTS = $(check_SCRIPTS) | ||
124 | endif | ||
diff --git a/src/identity-provider/gnunet-identity-token.c b/src/identity-provider/gnunet-identity-token.c deleted file mode 100644 index 30b63bfc4..000000000 --- a/src/identity-provider/gnunet-identity-token.c +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @author Martin Schanzenbach | ||
22 | * @file src/identity-provider/gnunet-service-identity-provider.c | ||
23 | * @brief Identity Token Service | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include <jansson.h> | ||
30 | #include "gnunet_signatures.h" | ||
31 | |||
32 | /** | ||
33 | * The token | ||
34 | */ | ||
35 | static char* token; | ||
36 | |||
37 | /** | ||
38 | * Weather to print the token | ||
39 | */ | ||
40 | static int print_token; | ||
41 | |||
42 | static void | ||
43 | run (void *cls, | ||
44 | char *const *args, | ||
45 | const char *cfgfile, | ||
46 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
47 | { | ||
48 | char *payload; | ||
49 | char *header; | ||
50 | //Get token parts | ||
51 | const char *header_b64; | ||
52 | const char *payload_b64; | ||
53 | const char *signature_b32; | ||
54 | const char *keystring; | ||
55 | char *data; | ||
56 | json_t *payload_json; | ||
57 | json_t *keystring_json; | ||
58 | json_error_t error; | ||
59 | struct GNUNET_CRYPTO_EcdsaPublicKey key; | ||
60 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | ||
61 | struct GNUNET_CRYPTO_EcdsaSignature sig; | ||
62 | |||
63 | if (NULL == token) | ||
64 | { | ||
65 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
66 | _("Option `-t' is required\n")); | ||
67 | return; | ||
68 | } | ||
69 | header_b64 = strtok (token, "."); | ||
70 | payload_b64 = strtok (NULL, "."); | ||
71 | signature_b32 = strtok (NULL, "."); | ||
72 | if ( (NULL == header_b64) || | ||
73 | (NULL == payload_b64) || | ||
74 | (NULL == signature_b32) ) | ||
75 | { | ||
76 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
77 | _("Token `%s' is malformed\n"), | ||
78 | token); | ||
79 | GNUNET_free (token); | ||
80 | token = NULL; | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | //Decode payload | ||
85 | GNUNET_STRINGS_base64_decode (payload_b64, | ||
86 | strlen (payload_b64), | ||
87 | &payload); | ||
88 | //Decode header | ||
89 | GNUNET_STRINGS_base64_decode (header_b64, | ||
90 | strlen (header_b64), | ||
91 | &header); | ||
92 | |||
93 | |||
94 | GNUNET_asprintf(&data, | ||
95 | "%s,%s", | ||
96 | header_b64, | ||
97 | payload_b64); | ||
98 | char *val = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (data)); | ||
99 | purpose = (struct GNUNET_CRYPTO_EccSignaturePurpose*)val; | ||
100 | purpose->size = htonl(sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + strlen (data)); | ||
101 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); | ||
102 | GNUNET_memcpy (&purpose[1], data, strlen(data)); | ||
103 | GNUNET_free (data); | ||
104 | GNUNET_free (token); | ||
105 | token = NULL; | ||
106 | |||
107 | if (print_token) | ||
108 | printf ("Token:\nHeader:\t\t%s\nPayload:\t%s\n", | ||
109 | header, | ||
110 | payload); | ||
111 | GNUNET_free (header); | ||
112 | |||
113 | payload_json = json_loads (payload, 0, &error); | ||
114 | GNUNET_free (payload); | ||
115 | |||
116 | if ((NULL == payload_json) || (! json_is_object (payload_json)) ) | ||
117 | { | ||
118 | GNUNET_free (val); | ||
119 | return; | ||
120 | } | ||
121 | keystring_json = json_object_get (payload_json, "iss"); | ||
122 | if (! json_is_string (keystring_json)) | ||
123 | { | ||
124 | GNUNET_free (val); | ||
125 | return; | ||
126 | } | ||
127 | keystring = json_string_value (keystring_json); | ||
128 | if (GNUNET_OK != | ||
129 | GNUNET_CRYPTO_ecdsa_public_key_from_string (keystring, | ||
130 | strlen (keystring), | ||
131 | &key)) | ||
132 | { | ||
133 | GNUNET_free (val); | ||
134 | return; | ||
135 | } | ||
136 | GNUNET_STRINGS_string_to_data (signature_b32, | ||
137 | strlen (signature_b32), | ||
138 | &sig, | ||
139 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | ||
140 | |||
141 | if (print_token) | ||
142 | printf ("Signature:\t%s\n", | ||
143 | keystring); | ||
144 | |||
145 | if (GNUNET_OK != | ||
146 | GNUNET_CRYPTO_ecdsa_verify(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN, | ||
147 | purpose, | ||
148 | &sig, | ||
149 | &key)) | ||
150 | printf("Signature not OK!\n"); | ||
151 | else | ||
152 | printf("Signature OK!\n"); | ||
153 | GNUNET_free (val); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | |||
158 | int | ||
159 | main(int argc, char *const argv[]) | ||
160 | { | ||
161 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
162 | |||
163 | GNUNET_GETOPT_option_string ('t', | ||
164 | "token", | ||
165 | NULL, | ||
166 | gettext_noop ("GNUid token"), | ||
167 | &token), | ||
168 | |||
169 | GNUNET_GETOPT_option_flag ('p', | ||
170 | "print", | ||
171 | gettext_noop ("Print token contents"), | ||
172 | &print_token), | ||
173 | |||
174 | GNUNET_GETOPT_OPTION_END | ||
175 | }; | ||
176 | return GNUNET_PROGRAM_run (argc, argv, "ct", | ||
177 | "ct", options, | ||
178 | &run, NULL); | ||
179 | } | ||
diff --git a/src/identity-provider/gnunet-idp.c b/src/identity-provider/gnunet-idp.c new file mode 100644 index 000000000..62f07842b --- /dev/null +++ b/src/identity-provider/gnunet-idp.c | |||
@@ -0,0 +1,439 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @author Martin Schanzenbach | ||
22 | * @file src/identity-provider/gnunet-idp.c | ||
23 | * @brief Identity Provider utility | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_namestore_service.h" | ||
30 | #include "gnunet_identity_provider_service.h" | ||
31 | #include "gnunet_identity_service.h" | ||
32 | #include "gnunet_signatures.h" | ||
33 | |||
34 | /** | ||
35 | * return value | ||
36 | */ | ||
37 | static int ret; | ||
38 | |||
39 | /** | ||
40 | * List attribute flag | ||
41 | */ | ||
42 | static int list; | ||
43 | |||
44 | /** | ||
45 | * Relying party | ||
46 | */ | ||
47 | static char* rp; | ||
48 | |||
49 | /** | ||
50 | * The attribute | ||
51 | */ | ||
52 | static char* attr_name; | ||
53 | |||
54 | /** | ||
55 | * Attribute value | ||
56 | */ | ||
57 | static char* attr_value; | ||
58 | |||
59 | /** | ||
60 | * Attributes to issue | ||
61 | */ | ||
62 | static char* issue_attrs; | ||
63 | |||
64 | /** | ||
65 | * Ticket to consume | ||
66 | */ | ||
67 | static char* consume_ticket; | ||
68 | |||
69 | /** | ||
70 | * Attribute type | ||
71 | */ | ||
72 | static char* type_str; | ||
73 | |||
74 | /** | ||
75 | * Ticket to revoke | ||
76 | */ | ||
77 | static char* revoke_ticket; | ||
78 | |||
79 | /** | ||
80 | * Ego name | ||
81 | */ | ||
82 | static char* ego_name; | ||
83 | |||
84 | /** | ||
85 | * Identity handle | ||
86 | */ | ||
87 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
88 | |||
89 | /** | ||
90 | * IdP handle | ||
91 | */ | ||
92 | static struct GNUNET_IDENTITY_PROVIDER_Handle *idp_handle; | ||
93 | |||
94 | /** | ||
95 | * IdP operation | ||
96 | */ | ||
97 | static struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op; | ||
98 | |||
99 | /** | ||
100 | * Attribute iterator | ||
101 | */ | ||
102 | static struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_iterator; | ||
103 | |||
104 | /** | ||
105 | * Master ABE key | ||
106 | */ | ||
107 | static struct GNUNET_CRYPTO_AbeMasterKey *abe_key; | ||
108 | |||
109 | /** | ||
110 | * ego private key | ||
111 | */ | ||
112 | static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey; | ||
113 | |||
114 | /** | ||
115 | * rp public key | ||
116 | */ | ||
117 | static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key; | ||
118 | |||
119 | /** | ||
120 | * Ticket to consume | ||
121 | */ | ||
122 | static struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | ||
123 | |||
124 | /** | ||
125 | * Attribute list | ||
126 | */ | ||
127 | static struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attr_list; | ||
128 | |||
129 | static void | ||
130 | do_cleanup(void *cls) | ||
131 | { | ||
132 | if (NULL != attr_iterator) | ||
133 | GNUNET_IDENTITY_PROVIDER_get_attributes_stop (attr_iterator); | ||
134 | if (NULL != idp_handle) | ||
135 | GNUNET_IDENTITY_PROVIDER_disconnect (idp_handle); | ||
136 | if (NULL != identity_handle) | ||
137 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
138 | if (NULL != abe_key) | ||
139 | GNUNET_free (abe_key); | ||
140 | if (NULL != attr_list) | ||
141 | GNUNET_free (attr_list); | ||
142 | } | ||
143 | |||
144 | static void | ||
145 | ticket_issue_cb (void* cls, | ||
146 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) | ||
147 | { | ||
148 | char* ticket_str; | ||
149 | if (NULL != ticket) { | ||
150 | ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket, | ||
151 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); | ||
152 | printf("%s\n", | ||
153 | ticket_str); | ||
154 | GNUNET_free (ticket_str); | ||
155 | } | ||
156 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
157 | } | ||
158 | |||
159 | static void | ||
160 | store_attr_cont (void *cls, | ||
161 | int32_t success, | ||
162 | const char*emsg) | ||
163 | { | ||
164 | if (GNUNET_SYSERR == success) { | ||
165 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
166 | "%s\n", emsg); | ||
167 | } | ||
168 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
169 | } | ||
170 | |||
171 | static void | ||
172 | process_attrs (void *cls, | ||
173 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | ||
174 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) | ||
175 | { | ||
176 | char *value_str; | ||
177 | if (NULL == identity) | ||
178 | { | ||
179 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
180 | return; | ||
181 | } | ||
182 | if (NULL == attr) | ||
183 | { | ||
184 | ret = 1; | ||
185 | return; | ||
186 | } | ||
187 | value_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (attr->type, | ||
188 | attr->data, | ||
189 | attr->data_size); | ||
190 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
191 | "%s: %s\n", attr->name, value_str); | ||
192 | } | ||
193 | |||
194 | |||
195 | static void | ||
196 | iter_error (void *cls) | ||
197 | { | ||
198 | attr_iterator = NULL; | ||
199 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
200 | "Failed to iterate over attributes\n"); | ||
201 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
202 | } | ||
203 | |||
204 | static void | ||
205 | process_rvk (void *cls, int success, const char* msg) | ||
206 | { | ||
207 | if (GNUNET_OK != success) | ||
208 | { | ||
209 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
210 | "Revocation failed.\n"); | ||
211 | ret = 1; | ||
212 | } | ||
213 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
214 | } | ||
215 | |||
216 | static void | ||
217 | iter_finished (void *cls) | ||
218 | { | ||
219 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim; | ||
220 | char *data; | ||
221 | size_t data_size; | ||
222 | int type; | ||
223 | |||
224 | attr_iterator = NULL; | ||
225 | if (list) | ||
226 | { | ||
227 | GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | if (issue_attrs) | ||
232 | { | ||
233 | idp_op = GNUNET_IDENTITY_PROVIDER_ticket_issue (idp_handle, | ||
234 | pkey, | ||
235 | &rp_key, | ||
236 | attr_list, | ||
237 | &ticket_issue_cb, | ||
238 | NULL); | ||
239 | return; | ||
240 | } | ||
241 | if (consume_ticket) | ||
242 | { | ||
243 | idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume (idp_handle, | ||
244 | pkey, | ||
245 | &ticket, | ||
246 | &process_attrs, | ||
247 | NULL); | ||
248 | return; | ||
249 | } | ||
250 | if (revoke_ticket) | ||
251 | { | ||
252 | idp_op = GNUNET_IDENTITY_PROVIDER_ticket_revoke (idp_handle, | ||
253 | pkey, | ||
254 | &ticket, | ||
255 | &process_rvk, | ||
256 | NULL); | ||
257 | return; | ||
258 | } | ||
259 | if (NULL == type_str) | ||
260 | type = GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING; | ||
261 | else | ||
262 | type = GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (type_str); | ||
263 | |||
264 | GNUNET_assert (GNUNET_SYSERR != GNUNET_IDENTITY_ATTRIBUTE_string_to_value (type, | ||
265 | attr_value, | ||
266 | (void**)&data, | ||
267 | &data_size)); | ||
268 | claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name, | ||
269 | type, | ||
270 | data, | ||
271 | data_size); | ||
272 | idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle, | ||
273 | pkey, | ||
274 | claim, | ||
275 | &store_attr_cont, | ||
276 | NULL); | ||
277 | |||
278 | |||
279 | } | ||
280 | |||
281 | static void | ||
282 | iter_cb (void *cls, | ||
283 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | ||
284 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) | ||
285 | { | ||
286 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
287 | char *attrs_tmp; | ||
288 | char *attr_str; | ||
289 | |||
290 | if (issue_attrs) | ||
291 | { | ||
292 | attrs_tmp = GNUNET_strdup (issue_attrs); | ||
293 | attr_str = strtok (attrs_tmp, ","); | ||
294 | while (NULL != attr_str) { | ||
295 | if (0 != strcmp (attr_str, attr->name)) { | ||
296 | attr_str = strtok (NULL, ","); | ||
297 | continue; | ||
298 | } | ||
299 | le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry); | ||
300 | le->claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr->name, | ||
301 | attr->type, | ||
302 | attr->data, | ||
303 | attr->data_size); | ||
304 | GNUNET_CONTAINER_DLL_insert (attr_list->list_head, | ||
305 | attr_list->list_tail, | ||
306 | le); | ||
307 | break; | ||
308 | } | ||
309 | GNUNET_free (attrs_tmp); | ||
310 | } else if (list) { | ||
311 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
312 | "%s: %s\n", attr->name, (char*)attr->data); | ||
313 | } | ||
314 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator); | ||
315 | } | ||
316 | |||
317 | static void | ||
318 | ego_cb (void *cls, | ||
319 | struct GNUNET_IDENTITY_Ego *ego, | ||
320 | void **ctx, | ||
321 | const char *name) | ||
322 | { | ||
323 | if (NULL == name) | ||
324 | return; | ||
325 | if (0 != strcmp (name, ego_name)) | ||
326 | return; | ||
327 | pkey = GNUNET_IDENTITY_ego_get_private_key (ego); | ||
328 | |||
329 | if (NULL != rp) | ||
330 | GNUNET_CRYPTO_ecdsa_public_key_from_string (rp, | ||
331 | strlen (rp), | ||
332 | &rp_key); | ||
333 | if (NULL != consume_ticket) | ||
334 | GNUNET_STRINGS_string_to_data (consume_ticket, | ||
335 | strlen (consume_ticket), | ||
336 | &ticket, | ||
337 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); | ||
338 | if (NULL != revoke_ticket) | ||
339 | GNUNET_STRINGS_string_to_data (revoke_ticket, | ||
340 | strlen (revoke_ticket), | ||
341 | &ticket, | ||
342 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); | ||
343 | |||
344 | |||
345 | attr_list = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
346 | |||
347 | attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle, | ||
348 | pkey, | ||
349 | &iter_error, | ||
350 | NULL, | ||
351 | &iter_cb, | ||
352 | NULL, | ||
353 | &iter_finished, | ||
354 | NULL); | ||
355 | |||
356 | |||
357 | } | ||
358 | |||
359 | static void | ||
360 | run (void *cls, | ||
361 | char *const *args, | ||
362 | const char *cfgfile, | ||
363 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
364 | { | ||
365 | ret = 0; | ||
366 | if (NULL == ego_name) | ||
367 | { | ||
368 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
369 | _("Ego is required\n")); | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | idp_handle = GNUNET_IDENTITY_PROVIDER_connect (c); | ||
374 | //Get Ego | ||
375 | identity_handle = GNUNET_IDENTITY_connect (c, | ||
376 | &ego_cb, | ||
377 | NULL); | ||
378 | |||
379 | |||
380 | } | ||
381 | |||
382 | |||
383 | int | ||
384 | main(int argc, char *const argv[]) | ||
385 | { | ||
386 | struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
387 | |||
388 | GNUNET_GETOPT_option_string ('a', | ||
389 | "add", | ||
390 | NULL, | ||
391 | gettext_noop ("Add attribute"), | ||
392 | &attr_name), | ||
393 | |||
394 | GNUNET_GETOPT_option_string ('V', | ||
395 | "value", | ||
396 | NULL, | ||
397 | gettext_noop ("Attribute value"), | ||
398 | &attr_value), | ||
399 | GNUNET_GETOPT_option_string ('e', | ||
400 | "ego", | ||
401 | NULL, | ||
402 | gettext_noop ("Ego"), | ||
403 | &ego_name), | ||
404 | GNUNET_GETOPT_option_string ('r', | ||
405 | "rp", | ||
406 | NULL, | ||
407 | gettext_noop ("Audience (relying party)"), | ||
408 | &rp), | ||
409 | GNUNET_GETOPT_option_flag ('D', | ||
410 | "dump", | ||
411 | gettext_noop ("List attributes for Ego"), | ||
412 | &list), | ||
413 | GNUNET_GETOPT_option_string ('i', | ||
414 | "issue", | ||
415 | NULL, | ||
416 | gettext_noop ("Issue a ticket"), | ||
417 | &issue_attrs), | ||
418 | GNUNET_GETOPT_option_string ('C', | ||
419 | "consume", | ||
420 | NULL, | ||
421 | gettext_noop ("Consume a ticket"), | ||
422 | &consume_ticket), | ||
423 | GNUNET_GETOPT_option_string ('R', | ||
424 | "revoke", | ||
425 | NULL, | ||
426 | gettext_noop ("Revoke a ticket"), | ||
427 | &revoke_ticket), | ||
428 | GNUNET_GETOPT_option_string ('t', | ||
429 | "type", | ||
430 | NULL, | ||
431 | gettext_noop ("Type of attribute"), | ||
432 | &type_str), | ||
433 | GNUNET_GETOPT_OPTION_END | ||
434 | }; | ||
435 | GNUNET_PROGRAM_run (argc, argv, "ct", | ||
436 | "ct", options, | ||
437 | &run, NULL); | ||
438 | return ret; | ||
439 | } | ||
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 53fd02c9f..4e1de36cd 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c | |||
@@ -30,12 +30,14 @@ | |||
30 | #include "gnunet_identity_service.h" | 30 | #include "gnunet_identity_service.h" |
31 | #include "gnunet_gnsrecord_lib.h" | 31 | #include "gnunet_gnsrecord_lib.h" |
32 | #include "gnunet_namestore_service.h" | 32 | #include "gnunet_namestore_service.h" |
33 | #include "gnunet_abe_lib.h" | ||
34 | #include "gnunet_credential_service.h" | ||
33 | #include "gnunet_statistics_service.h" | 35 | #include "gnunet_statistics_service.h" |
34 | #include "gnunet_gns_service.h" | 36 | #include "gnunet_gns_service.h" |
37 | #include "gnunet_identity_provider_plugin.h" | ||
38 | #include "gnunet_identity_attribute_lib.h" | ||
35 | #include "gnunet_signatures.h" | 39 | #include "gnunet_signatures.h" |
36 | #include "identity_provider.h" | 40 | #include "identity_provider.h" |
37 | #include "identity_token.h" | ||
38 | #include <inttypes.h> | ||
39 | 41 | ||
40 | /** | 42 | /** |
41 | * First pass state | 43 | * First pass state |
@@ -58,24 +60,19 @@ | |||
58 | #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS | 60 | #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS |
59 | 61 | ||
60 | /** | 62 | /** |
61 | * Service state (to detect initial update pass) | 63 | * Identity handle |
62 | */ | ||
63 | static int state; | ||
64 | |||
65 | /** | ||
66 | * Head of ego entry DLL | ||
67 | */ | 64 | */ |
68 | static struct EgoEntry *ego_head; | 65 | static struct GNUNET_IDENTITY_Handle *identity_handle; |
69 | 66 | ||
70 | /** | 67 | /** |
71 | * Tail of ego entry DLL | 68 | * Database handle |
72 | */ | 69 | */ |
73 | static struct EgoEntry *ego_tail; | 70 | static struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *TKT_database; |
74 | 71 | ||
75 | /** | 72 | /** |
76 | * Identity handle | 73 | * Name of DB plugin |
77 | */ | 74 | */ |
78 | static struct GNUNET_IDENTITY_Handle *identity_handle; | 75 | static char *db_lib_name; |
79 | 76 | ||
80 | /** | 77 | /** |
81 | * Token expiration interval | 78 | * Token expiration interval |
@@ -93,6 +90,16 @@ static struct GNUNET_NAMESTORE_Handle *ns_handle; | |||
93 | static struct GNUNET_GNS_Handle *gns_handle; | 90 | static struct GNUNET_GNS_Handle *gns_handle; |
94 | 91 | ||
95 | /** | 92 | /** |
93 | * Credential handle | ||
94 | */ | ||
95 | static struct GNUNET_CREDENTIAL_Handle *credential_handle; | ||
96 | |||
97 | /** | ||
98 | * Stats handle | ||
99 | */ | ||
100 | static struct GNUNET_STATISTICS_Handle *stats_handle; | ||
101 | |||
102 | /** | ||
96 | * Namestore qe | 103 | * Namestore qe |
97 | */ | 104 | */ |
98 | static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | 105 | static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; |
@@ -112,11 +119,6 @@ static struct GNUNET_SCHEDULER_Task *timeout_task; | |||
112 | */ | 119 | */ |
113 | static struct GNUNET_SCHEDULER_Task *update_task; | 120 | static struct GNUNET_SCHEDULER_Task *update_task; |
114 | 121 | ||
115 | /** | ||
116 | * Timeout for next update pass | ||
117 | */ | ||
118 | static struct GNUNET_TIME_Relative min_rel_exp; | ||
119 | |||
120 | 122 | ||
121 | /** | 123 | /** |
122 | * Currently processed token | 124 | * Currently processed token |
@@ -134,43 +136,260 @@ static char* label; | |||
134 | static char* scopes; | 136 | static char* scopes; |
135 | 137 | ||
136 | /** | 138 | /** |
137 | * Expiration for processed token | 139 | * Handle to the statistics service. |
138 | */ | 140 | */ |
139 | static uint64_t rd_exp; | 141 | static struct GNUNET_STATISTICS_Handle *stats; |
140 | 142 | ||
141 | /** | 143 | /** |
142 | * ECDHE Privkey for processed token metadata | 144 | * Our configuration. |
143 | */ | 145 | */ |
144 | static struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_privkey; | 146 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
145 | 147 | ||
146 | /** | 148 | /** |
147 | * Handle to the statistics service. | 149 | * An idp client |
148 | */ | 150 | */ |
149 | static struct GNUNET_STATISTICS_Handle *stats; | 151 | struct IdpClient; |
150 | 152 | ||
151 | /** | 153 | /** |
152 | * Our configuration. | 154 | * A ticket iteration operation. |
153 | */ | 155 | */ |
154 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 156 | struct TicketIteration |
157 | { | ||
158 | /** | ||
159 | * DLL | ||
160 | */ | ||
161 | struct TicketIteration *next; | ||
162 | |||
163 | /** | ||
164 | * DLL | ||
165 | */ | ||
166 | struct TicketIteration *prev; | ||
167 | |||
168 | /** | ||
169 | * Client which intiated this zone iteration | ||
170 | */ | ||
171 | struct IdpClient *client; | ||
155 | 172 | ||
173 | /** | ||
174 | * Key of the identity we are iterating over. | ||
175 | */ | ||
176 | struct GNUNET_CRYPTO_EcdsaPublicKey identity; | ||
156 | 177 | ||
157 | struct ExchangeHandle | 178 | /** |
179 | * Identity is audience | ||
180 | */ | ||
181 | uint32_t is_audience; | ||
182 | |||
183 | /** | ||
184 | * The operation id fot the iteration in the response for the client | ||
185 | */ | ||
186 | uint32_t r_id; | ||
187 | |||
188 | /** | ||
189 | * Offset of the iteration used to address next result of the | ||
190 | * iteration in the store | ||
191 | * | ||
192 | * Initialy set to 0 in handle_iteration_start | ||
193 | * Incremented with by every call to handle_iteration_next | ||
194 | */ | ||
195 | uint32_t offset; | ||
196 | |||
197 | }; | ||
198 | |||
199 | |||
200 | |||
201 | /** | ||
202 | * Callback after an ABE bootstrap | ||
203 | * | ||
204 | * @param cls closure | ||
205 | * @param abe_key the ABE key that exists or was created | ||
206 | */ | ||
207 | typedef void | ||
208 | (*AbeBootstrapResult) (void *cls, | ||
209 | struct GNUNET_ABE_AbeMasterKey *abe_key); | ||
210 | |||
211 | |||
212 | struct AbeBootstrapHandle | ||
158 | { | 213 | { |
214 | /** | ||
215 | * Function to call when finished | ||
216 | */ | ||
217 | AbeBootstrapResult proc; | ||
159 | 218 | ||
160 | /** | 219 | /** |
161 | * Client connection | 220 | * Callback closure |
221 | */ | ||
222 | char *proc_cls; | ||
223 | |||
224 | /** | ||
225 | * Key of the zone we are iterating over. | ||
226 | */ | ||
227 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
228 | |||
229 | /** | ||
230 | * Namestore Queue Entry | ||
231 | */ | ||
232 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
233 | |||
234 | /** | ||
235 | * The issuer egos ABE master key | ||
236 | */ | ||
237 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
238 | }; | ||
239 | |||
240 | /** | ||
241 | * An attribute iteration operation. | ||
242 | */ | ||
243 | struct AttributeIterator | ||
244 | { | ||
245 | /** | ||
246 | * Next element in the DLL | ||
247 | */ | ||
248 | struct AttributeIterator *next; | ||
249 | |||
250 | /** | ||
251 | * Previous element in the DLL | ||
252 | */ | ||
253 | struct AttributeIterator *prev; | ||
254 | |||
255 | /** | ||
256 | * IDP client which intiated this zone iteration | ||
257 | */ | ||
258 | struct IdpClient *client; | ||
259 | |||
260 | /** | ||
261 | * Key of the zone we are iterating over. | ||
262 | */ | ||
263 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
264 | |||
265 | /** | ||
266 | * The issuer egos ABE master key | ||
267 | */ | ||
268 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
269 | |||
270 | /** | ||
271 | * Namestore iterator | ||
272 | */ | ||
273 | struct GNUNET_NAMESTORE_ZoneIterator *ns_it; | ||
274 | |||
275 | /** | ||
276 | * The operation id fot the zone iteration in the response for the client | ||
277 | */ | ||
278 | uint32_t request_id; | ||
279 | |||
280 | }; | ||
281 | |||
282 | |||
283 | |||
284 | /** | ||
285 | * An idp client | ||
286 | */ | ||
287 | struct IdpClient | ||
288 | { | ||
289 | |||
290 | /** | ||
291 | * The client | ||
162 | */ | 292 | */ |
163 | struct GNUNET_SERVICE_Client *client; | 293 | struct GNUNET_SERVICE_Client *client; |
164 | 294 | ||
165 | /** | 295 | /** |
166 | * Ticket | 296 | * Message queue for transmission to @e client |
297 | */ | ||
298 | struct GNUNET_MQ_Handle *mq; | ||
299 | |||
300 | /** | ||
301 | * Head of the DLL of | ||
302 | * Attribute iteration operations in | ||
303 | * progress initiated by this client | ||
304 | */ | ||
305 | struct AttributeIterator *op_head; | ||
306 | |||
307 | /** | ||
308 | * Tail of the DLL of | ||
309 | * Attribute iteration operations | ||
310 | * in progress initiated by this client | ||
311 | */ | ||
312 | struct AttributeIterator *op_tail; | ||
313 | |||
314 | /** | ||
315 | * Head of DLL of ticket iteration ops | ||
316 | */ | ||
317 | struct TicketIteration *ticket_iter_head; | ||
318 | |||
319 | /** | ||
320 | * Tail of DLL of ticket iteration ops | ||
321 | */ | ||
322 | struct TicketIteration *ticket_iter_tail; | ||
323 | |||
324 | |||
325 | /** | ||
326 | * Head of DLL of ticket revocation ops | ||
327 | */ | ||
328 | struct TicketRevocationHandle *revocation_list_head; | ||
329 | |||
330 | /** | ||
331 | * Tail of DLL of ticket revocation ops | ||
332 | */ | ||
333 | struct TicketRevocationHandle *revocation_list_tail; | ||
334 | }; | ||
335 | |||
336 | |||
337 | |||
338 | struct AttributeStoreHandle | ||
339 | { | ||
340 | |||
341 | /** | ||
342 | * Client connection | ||
343 | */ | ||
344 | struct IdpClient *client; | ||
345 | |||
346 | /** | ||
347 | * Identity | ||
348 | */ | ||
349 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
350 | |||
351 | /** | ||
352 | * Identity pubkey | ||
353 | */ | ||
354 | struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey; | ||
355 | |||
356 | /** | ||
357 | * The issuer egos ABE master key | ||
358 | */ | ||
359 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
360 | |||
361 | /** | ||
362 | * QueueEntry | ||
363 | */ | ||
364 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | ||
365 | |||
366 | /** | ||
367 | * The attribute to store | ||
368 | */ | ||
369 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim; | ||
370 | |||
371 | /** | ||
372 | * request id | ||
373 | */ | ||
374 | uint32_t r_id; | ||
375 | }; | ||
376 | |||
377 | |||
378 | /* Prototype */ | ||
379 | struct ParallelLookup; | ||
380 | |||
381 | struct ConsumeTicketHandle | ||
382 | { | ||
383 | |||
384 | /** | ||
385 | * Client connection | ||
167 | */ | 386 | */ |
168 | struct TokenTicket *ticket; | 387 | struct IdpClient *client; |
169 | 388 | ||
170 | /** | 389 | /** |
171 | * Token returned | 390 | * Ticket |
172 | */ | 391 | */ |
173 | struct IdentityToken *token; | 392 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; |
174 | 393 | ||
175 | /** | 394 | /** |
176 | * LookupRequest | 395 | * LookupRequest |
@@ -180,86 +399,173 @@ struct ExchangeHandle | |||
180 | /** | 399 | /** |
181 | * Audience Key | 400 | * Audience Key |
182 | */ | 401 | */ |
183 | struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey; | 402 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; |
184 | 403 | ||
185 | /** | 404 | /** |
186 | * Label to return | 405 | * Audience Key |
187 | */ | 406 | */ |
188 | char *label; | 407 | struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; |
189 | 408 | ||
190 | /** | 409 | /** |
410 | * Lookup DLL | ||
411 | */ | ||
412 | struct ParallelLookup *parallel_lookups_head; | ||
413 | |||
414 | /** | ||
415 | * Lookup DLL | ||
416 | */ | ||
417 | struct ParallelLookup *parallel_lookups_tail; | ||
418 | |||
419 | /** | ||
420 | * Kill task | ||
421 | */ | ||
422 | struct GNUNET_SCHEDULER_Task *kill_task; | ||
423 | |||
424 | /** | ||
425 | * The ABE key | ||
426 | */ | ||
427 | struct GNUNET_ABE_AbeKey *key; | ||
428 | |||
429 | /** | ||
430 | * Attributes | ||
431 | */ | ||
432 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; | ||
433 | |||
434 | /** | ||
435 | * Lookup time | ||
436 | */ | ||
437 | struct GNUNET_TIME_Absolute lookup_start_time; | ||
438 | |||
439 | /** | ||
191 | * request id | 440 | * request id |
192 | */ | 441 | */ |
193 | uint32_t r_id; | 442 | uint32_t r_id; |
194 | }; | 443 | }; |
195 | 444 | ||
196 | struct IssueHandle | 445 | /** |
446 | * Handle for a parallel GNS lookup job | ||
447 | */ | ||
448 | struct ParallelLookup | ||
197 | { | 449 | { |
450 | /* DLL */ | ||
451 | struct ParallelLookup *next; | ||
452 | |||
453 | /* DLL */ | ||
454 | struct ParallelLookup *prev; | ||
455 | |||
456 | /* The GNS request */ | ||
457 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
458 | |||
459 | /* The handle the return to */ | ||
460 | struct ConsumeTicketHandle *handle; | ||
461 | |||
462 | /** | ||
463 | * Lookup time | ||
464 | */ | ||
465 | struct GNUNET_TIME_Absolute lookup_start_time; | ||
466 | |||
467 | /* The label to look up */ | ||
468 | char *label; | ||
469 | }; | ||
470 | |||
471 | /** | ||
472 | * Ticket revocation request handle | ||
473 | */ | ||
474 | struct TicketRevocationHandle | ||
475 | { | ||
476 | /** | ||
477 | * DLL | ||
478 | */ | ||
479 | struct TicketRevocationHandle *next; | ||
480 | |||
481 | /** | ||
482 | * DLL | ||
483 | */ | ||
484 | struct TicketRevocationHandle *prev; | ||
198 | 485 | ||
199 | /** | 486 | /** |
200 | * Client connection | 487 | * Client connection |
201 | */ | 488 | */ |
202 | struct GNUNET_SERVICE_Client *client; | 489 | struct IdpClient *client; |
490 | |||
491 | /** | ||
492 | * Attributes to reissue | ||
493 | */ | ||
494 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; | ||
495 | |||
496 | /** | ||
497 | * Attributes to revoke | ||
498 | */ | ||
499 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *rvk_attrs; | ||
203 | 500 | ||
204 | /** | 501 | /** |
205 | * Issuer Key | 502 | * Issuer Key |
206 | */ | 503 | */ |
207 | struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key; | 504 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; |
208 | 505 | ||
209 | /** | 506 | /** |
210 | * Issue pubkey | 507 | * Ticket to issue |
211 | */ | 508 | */ |
212 | struct GNUNET_CRYPTO_EcdsaPublicKey iss_pkey; | 509 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; |
213 | 510 | ||
214 | /** | 511 | /** |
215 | * Audience Key | 512 | * QueueEntry |
216 | */ | 513 | */ |
217 | struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; | 514 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; |
218 | 515 | ||
219 | /** | 516 | /** |
220 | * Expiration | 517 | * Namestore iterator |
221 | */ | 518 | */ |
222 | struct GNUNET_TIME_Absolute expiration; | 519 | struct GNUNET_NAMESTORE_ZoneIterator *ns_it; |
223 | 520 | ||
224 | /** | 521 | /** |
225 | * Scopes | 522 | * The ABE master key |
226 | */ | 523 | */ |
227 | char *scopes; | 524 | struct GNUNET_ABE_AbeMasterKey *abe_key; |
228 | 525 | ||
229 | /** | 526 | /** |
230 | * nonce | 527 | * Offset |
231 | */ | 528 | */ |
232 | uint64_t nonce; | 529 | uint32_t offset; |
233 | 530 | ||
234 | /** | 531 | /** |
235 | * NS iterator | 532 | * request id |
236 | */ | 533 | */ |
237 | struct GNUNET_NAMESTORE_ZoneIterator *ns_it; | 534 | uint32_t r_id; |
535 | }; | ||
536 | |||
537 | |||
538 | |||
539 | /** | ||
540 | * Ticket issue request handle | ||
541 | */ | ||
542 | struct TicketIssueHandle | ||
543 | { | ||
238 | 544 | ||
239 | /** | 545 | /** |
240 | * Attribute map | 546 | * Client connection |
241 | */ | 547 | */ |
242 | struct GNUNET_CONTAINER_MultiHashMap *attr_map; | 548 | struct IdpClient *client; |
243 | 549 | ||
244 | /** | 550 | /** |
245 | * Token | 551 | * Attributes to issue |
246 | */ | 552 | */ |
247 | struct IdentityToken *token; | 553 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; |
248 | 554 | ||
249 | /** | 555 | /** |
250 | * Ticket | 556 | * Issuer Key |
251 | */ | 557 | */ |
252 | struct TokenTicket *ticket; | 558 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; |
253 | 559 | ||
254 | /** | 560 | /** |
255 | * QueueEntry | 561 | * Ticket to issue |
256 | */ | 562 | */ |
257 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | 563 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; |
258 | 564 | ||
259 | /** | 565 | /** |
260 | * The label the token is stored under | 566 | * QueueEntry |
261 | */ | 567 | */ |
262 | char *label; | 568 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; |
263 | 569 | ||
264 | /** | 570 | /** |
265 | * request id | 571 | * request id |
@@ -267,6 +573,7 @@ struct IssueHandle | |||
267 | uint32_t r_id; | 573 | uint32_t r_id; |
268 | }; | 574 | }; |
269 | 575 | ||
576 | |||
270 | /** | 577 | /** |
271 | * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format | 578 | * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t format |
272 | * | 579 | * |
@@ -293,1303 +600,1774 @@ struct EgoEntry | |||
293 | */ | 600 | */ |
294 | struct GNUNET_CONTAINER_MultiHashMap *attr_map; | 601 | struct GNUNET_CONTAINER_MultiHashMap *attr_map; |
295 | 602 | ||
296 | /** | ||
297 | * Attributes are old and should be updated if GNUNET_YES | ||
298 | */ | ||
299 | int attributes_dirty; | ||
300 | }; | 603 | }; |
301 | 604 | ||
302 | /** | 605 | /** |
303 | * Continuation for token store call | 606 | * Cleanup task |
607 | */ | ||
608 | static void | ||
609 | cleanup() | ||
610 | { | ||
611 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
612 | "Cleaning up\n"); | ||
613 | if (NULL != stats) | ||
614 | { | ||
615 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | ||
616 | stats = NULL; | ||
617 | } | ||
618 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, | ||
619 | TKT_database)); | ||
620 | GNUNET_free (db_lib_name); | ||
621 | db_lib_name = NULL; | ||
622 | if (NULL != timeout_task) | ||
623 | GNUNET_SCHEDULER_cancel (timeout_task); | ||
624 | if (NULL != update_task) | ||
625 | GNUNET_SCHEDULER_cancel (update_task); | ||
626 | if (NULL != identity_handle) | ||
627 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
628 | if (NULL != gns_handle) | ||
629 | GNUNET_GNS_disconnect (gns_handle); | ||
630 | if (NULL != credential_handle) | ||
631 | GNUNET_CREDENTIAL_disconnect (credential_handle); | ||
632 | if (NULL != ns_it) | ||
633 | GNUNET_NAMESTORE_zone_iteration_stop (ns_it); | ||
634 | if (NULL != ns_qe) | ||
635 | GNUNET_NAMESTORE_cancel (ns_qe); | ||
636 | if (NULL != ns_handle) | ||
637 | GNUNET_NAMESTORE_disconnect (ns_handle); | ||
638 | if (NULL != stats_handle) | ||
639 | GNUNET_STATISTICS_destroy (stats_handle, GNUNET_NO); | ||
640 | GNUNET_free_non_null (token); | ||
641 | GNUNET_free_non_null (label); | ||
642 | |||
643 | } | ||
644 | |||
645 | /** | ||
646 | * Shutdown task | ||
304 | * | 647 | * |
305 | * @param cls NULL | 648 | * @param cls NULL |
306 | * @param success error code | ||
307 | * @param emsg error message | ||
308 | */ | 649 | */ |
309 | static void | 650 | static void |
310 | store_token_cont (void *cls, | 651 | do_shutdown (void *cls) |
311 | int32_t success, | 652 | { |
312 | const char *emsg) | 653 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
654 | "Shutting down...\n"); | ||
655 | cleanup(); | ||
656 | } | ||
657 | |||
658 | /** | ||
659 | * Finished storing newly bootstrapped ABE key | ||
660 | */ | ||
661 | static void | ||
662 | bootstrap_store_cont (void *cls, | ||
663 | int32_t success, | ||
664 | const char *emsg) | ||
313 | { | 665 | { |
314 | ns_qe = NULL; | 666 | struct AbeBootstrapHandle *abh = cls; |
315 | if (GNUNET_SYSERR == success) | 667 | if (GNUNET_SYSERR == success) |
316 | { | 668 | { |
317 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 669 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
318 | "Failed to update token: %s\n", | 670 | "Failed to bootstrap ABE master %s\n", |
319 | emsg); | 671 | emsg); |
672 | abh->proc (abh->proc_cls, NULL); | ||
673 | GNUNET_free (abh->abe_key); | ||
674 | GNUNET_free (abh); | ||
320 | return; | 675 | return; |
321 | } | 676 | } |
322 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 677 | abh->proc (abh->proc_cls, abh->abe_key); |
678 | GNUNET_free (abh); | ||
323 | } | 679 | } |
324 | 680 | ||
325 | |||
326 | /** | 681 | /** |
327 | * This function updates the old token with new attributes, | 682 | * Generates and stores a new ABE key |
328 | * removes deleted attributes and expiration times. | ||
329 | * | ||
330 | * @param cls the ego entry | ||
331 | */ | 683 | */ |
332 | static void | 684 | static void |
333 | handle_token_update (void *cls) | 685 | bootstrap_store_task (void *cls) |
334 | { | 686 | { |
335 | char *token_metadata; | 687 | struct AbeBootstrapHandle *abh = cls; |
336 | char *write_ptr; | 688 | struct GNUNET_GNSRECORD_Data rd[1]; |
337 | char *enc_token_str; | 689 | char *key; |
338 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | 690 | |
339 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | 691 | rd[0].data_size = GNUNET_ABE_cpabe_serialize_master_key (abh->abe_key, |
340 | struct GNUNET_CRYPTO_EcdhePrivateKey *new_ecdhe_privkey; | 692 | (void**)&key); |
341 | struct EgoEntry *ego_entry = cls; | 693 | rd[0].data = key; |
342 | struct GNUNET_GNSRECORD_Data token_record[2]; | 694 | rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER; |
343 | struct GNUNET_HashCode key_hash; | 695 | rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE; |
344 | struct GNUNET_TIME_Relative token_rel_exp; | 696 | rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? |
345 | struct GNUNET_TIME_Relative token_ttl; | 697 | abh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, |
346 | struct GNUNET_TIME_Absolute token_exp; | 698 | &abh->identity, |
347 | struct GNUNET_TIME_Absolute token_nbf; | 699 | "+", |
348 | struct GNUNET_TIME_Absolute new_exp; | 700 | 1, |
349 | struct GNUNET_TIME_Absolute new_iat; | 701 | rd, |
350 | struct GNUNET_TIME_Absolute new_nbf; | 702 | &bootstrap_store_cont, |
351 | struct IdentityToken *new_token; | 703 | abh); |
352 | struct TokenAttr *cur_value; | 704 | GNUNET_free (key); |
353 | struct TokenAttr *attr; | 705 | } |
354 | size_t token_metadata_len; | ||
355 | |||
356 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
357 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, | ||
358 | &pub_key); | ||
359 | |||
360 | //Note: We need the token expiration time here. Not the record expiration | ||
361 | //time. | ||
362 | //There are two types of tokens: Token that expire on GNS level with | ||
363 | //an absolute expiration time. Those are basically tokens that will | ||
364 | //be automatically revoked on (record)expiration. | ||
365 | //Tokens stored with relative expiration times will expire on the token level (token expiration) | ||
366 | //but this service will reissue new tokens that can be retrieved from GNS | ||
367 | //automatically. | ||
368 | |||
369 | for (attr = token->attr_head; NULL != attr; attr = attr->next) | ||
370 | { | ||
371 | if (0 == strcmp (attr->name, "exp")) | ||
372 | { | ||
373 | GNUNET_assert (1 == sscanf (attr->val_head->value, | ||
374 | "%"SCNu64, | ||
375 | &token_exp.abs_value_us)); | ||
376 | } else if (0 == strcmp (attr->name, "nbf")) { | ||
377 | GNUNET_assert (1 == sscanf (attr->val_head->value, | ||
378 | "%"SCNu64, | ||
379 | &token_nbf.abs_value_us)); | ||
380 | } | ||
381 | } | ||
382 | token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp); | ||
383 | |||
384 | token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp); | ||
385 | if (0 != GNUNET_TIME_absolute_get_remaining (token_exp).rel_value_us) | ||
386 | { | ||
387 | //This token is not yet expired! Save and skip | ||
388 | if (min_rel_exp.rel_value_us > token_ttl.rel_value_us) | ||
389 | { | ||
390 | min_rel_exp = token_ttl; | ||
391 | } | ||
392 | GNUNET_free (token); | ||
393 | token = NULL; | ||
394 | GNUNET_free (label); | ||
395 | label = NULL; | ||
396 | GNUNET_free (scopes); | ||
397 | scopes = NULL; | ||
398 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | ||
399 | return; | ||
400 | } | ||
401 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
402 | "Token is expired. Create a new one\n"); | ||
403 | new_token = token_create (&pub_key, | ||
404 | &token->aud_key); | ||
405 | new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp); | ||
406 | new_nbf = GNUNET_TIME_absolute_get (); | ||
407 | new_iat = new_nbf; | ||
408 | for (attr = token->attr_head; NULL != attr; attr = attr->next) | ||
409 | { | ||
410 | if (0 == strcmp (attr->name, "exp")) | ||
411 | { | ||
412 | token_add_attr_int (new_token, attr->name, new_exp.abs_value_us); | ||
413 | } | ||
414 | else if (0 == strcmp (attr->name, "nbf")) | ||
415 | { | ||
416 | token_add_attr_int (new_token, attr->name, new_nbf.abs_value_us); | ||
417 | } | ||
418 | else if (0 == strcmp (attr->name, "iat")) | ||
419 | { | ||
420 | token_add_attr_int (new_token, attr->name, new_iat.abs_value_us); | ||
421 | } | ||
422 | else if ((0 == strcmp (attr->name, "iss")) | ||
423 | || (0 == strcmp (attr->name, "aud"))) | ||
424 | { | ||
425 | //Omit | ||
426 | } | ||
427 | else if (0 == strcmp (attr->name, "sub")) | ||
428 | { | ||
429 | token_add_attr (new_token, | ||
430 | attr->name, | ||
431 | attr->val_head->value); | ||
432 | } | ||
433 | else | ||
434 | { | ||
435 | GNUNET_CRYPTO_hash (attr->name, | ||
436 | strlen (attr->name), | ||
437 | &key_hash); | ||
438 | //Check if attr still exists. omit of not | ||
439 | if (GNUNET_NO != | ||
440 | GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map, | ||
441 | &key_hash)) | ||
442 | { | ||
443 | cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map, | ||
444 | &key_hash); | ||
445 | GNUNET_assert (NULL != cur_value); | ||
446 | GNUNET_CONTAINER_DLL_insert (new_token->attr_head, | ||
447 | new_token->attr_tail, | ||
448 | cur_value); | ||
449 | } | ||
450 | } | ||
451 | } | ||
452 | 706 | ||
453 | // reassemble and set | 707 | /** |
454 | GNUNET_assert (token_serialize (new_token, | 708 | * Error checking for ABE master |
455 | priv_key, | 709 | */ |
456 | &new_ecdhe_privkey, | 710 | static void |
457 | &enc_token_str)); | 711 | bootstrap_abe_error (void *cls) |
458 | 712 | { | |
459 | token_record[0].data = enc_token_str; | 713 | struct AbeBootstrapHandle *abh = cls; |
460 | token_record[0].data_size = strlen (enc_token_str) + 1; | 714 | GNUNET_free (abh); |
461 | token_record[0].expiration_time = rd_exp; //Old expiration time | 715 | abh->proc (abh->proc_cls, NULL); |
462 | token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; | 716 | GNUNET_free (abh); |
463 | token_record[0].flags = GNUNET_GNSRECORD_RF_NONE; | ||
464 | |||
465 | //Meta | ||
466 | token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey) | ||
467 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) | ||
468 | + strlen (scopes) + 1; //With 0-Terminator | ||
469 | token_metadata = GNUNET_malloc (token_metadata_len); | ||
470 | write_ptr = token_metadata; | ||
471 | GNUNET_memcpy (token_metadata, new_ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | ||
472 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey); | ||
473 | GNUNET_memcpy (write_ptr, &token->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
474 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | ||
475 | GNUNET_memcpy (write_ptr, scopes, strlen (scopes) + 1); //with 0-Terminator; | ||
476 | |||
477 | token_record[1].data = token_metadata; | ||
478 | token_record[1].data_size = token_metadata_len; | ||
479 | token_record[1].expiration_time = rd_exp; | ||
480 | token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA; | ||
481 | token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE; | ||
482 | |||
483 | ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
484 | priv_key, | ||
485 | label, | ||
486 | 2, | ||
487 | token_record, | ||
488 | &store_token_cont, | ||
489 | ego_entry); | ||
490 | token_destroy (new_token); | ||
491 | token_destroy (token); | ||
492 | GNUNET_free (new_ecdhe_privkey); | ||
493 | GNUNET_free (enc_token_str); | ||
494 | token = NULL; | ||
495 | GNUNET_free (label); | ||
496 | label = NULL; | ||
497 | GNUNET_free (scopes); | ||
498 | scopes = NULL; | ||
499 | } | 717 | } |
500 | 718 | ||
501 | 719 | ||
720 | /** | ||
721 | * Handle ABE lookup in namestore | ||
722 | */ | ||
502 | static void | 723 | static void |
503 | update_identities(void *cls); | 724 | bootstrap_abe_result (void *cls, |
725 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
726 | const char *label, | ||
727 | unsigned int rd_count, | ||
728 | const struct GNUNET_GNSRECORD_Data *rd) | ||
729 | { | ||
730 | struct AbeBootstrapHandle *abh = cls; | ||
731 | struct GNUNET_ABE_AbeMasterKey *abe_key; | ||
732 | |||
733 | for (uint32_t i=0;i<rd_count;i++) { | ||
734 | if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type) | ||
735 | continue; | ||
736 | abe_key = GNUNET_ABE_cpabe_deserialize_master_key (rd[i].data, | ||
737 | rd[i].data_size); | ||
738 | abh->proc (abh->proc_cls, abe_key); | ||
739 | GNUNET_free (abh); | ||
740 | return; | ||
741 | } | ||
504 | 742 | ||
743 | //No ABE master found, bootstrapping... | ||
744 | abh->abe_key = GNUNET_ABE_cpabe_create_master_key (); | ||
745 | GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh); | ||
746 | } | ||
505 | 747 | ||
506 | /** | 748 | /** |
507 | * | 749 | * Bootstrap ABE master if it does not yet exists. |
508 | * Cleanup attr_map | 750 | * Will call the AbeBootstrapResult processor when done. |
509 | * | 751 | * will always recreate the ABE key of GNUNET_YES == recreate |
510 | * @param cls NULL | ||
511 | * @param key the key | ||
512 | * @param value the json_t attribute value | ||
513 | * @return #GNUNET_YES | ||
514 | */ | 752 | */ |
515 | static int | 753 | static void |
516 | clear_ego_attrs (void *cls, | 754 | bootstrap_abe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, |
517 | const struct GNUNET_HashCode *key, | 755 | AbeBootstrapResult proc, |
518 | void *value) | 756 | void* cls, |
519 | { | 757 | int recreate) |
520 | struct TokenAttr *attr = value; | 758 | { |
521 | struct TokenAttrValue *val; | 759 | struct AbeBootstrapHandle *abh; |
522 | struct TokenAttrValue *tmp_val; | 760 | |
523 | for (val = attr->val_head; NULL != val;) | 761 | abh = GNUNET_new (struct AbeBootstrapHandle); |
762 | abh->proc = proc; | ||
763 | abh->proc_cls = cls; | ||
764 | abh->identity = *identity; | ||
765 | if (GNUNET_YES == recreate) | ||
524 | { | 766 | { |
525 | tmp_val = val->next; | 767 | abh->abe_key = GNUNET_ABE_cpabe_create_master_key (); |
526 | GNUNET_CONTAINER_DLL_remove (attr->val_head, | 768 | GNUNET_SCHEDULER_add_now (&bootstrap_store_task, abh); |
527 | attr->val_tail, | 769 | } else { |
528 | val); | 770 | abh->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle, |
529 | GNUNET_free (val->value); | 771 | identity, |
530 | GNUNET_free (val); | 772 | "+", |
531 | val = tmp_val; | 773 | &bootstrap_abe_error, |
774 | abh, | ||
775 | &bootstrap_abe_result, | ||
776 | abh); | ||
532 | } | 777 | } |
533 | GNUNET_free (attr->name); | ||
534 | GNUNET_free (attr); | ||
535 | |||
536 | return GNUNET_YES; | ||
537 | } | 778 | } |
538 | 779 | ||
539 | 780 | ||
540 | static void | ||
541 | token_collect_error_cb (void *cls) | ||
542 | { | ||
543 | struct EgoEntry *ego_entry = cls; | ||
544 | 781 | ||
545 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 782 | static int |
546 | ">>> Updating Ego failed!\n"); | 783 | create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, |
547 | //Clear attribute map for ego | 784 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, |
548 | GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map, | 785 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) |
549 | &clear_ego_attrs, | 786 | { |
550 | ego_entry); | 787 | struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; |
551 | GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map); | 788 | |
552 | update_task = GNUNET_SCHEDULER_add_now (&update_identities, | 789 | GNUNET_CRYPTO_hash_to_enc (new_key_hash, |
553 | ego_entry->next); | 790 | &new_key_hash_str); |
791 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); | ||
792 | static const char ctx_key[] = "gnuid-aes-ctx-key"; | ||
793 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
794 | new_key_hash, sizeof (struct GNUNET_HashCode), | ||
795 | ctx_key, strlen (ctx_key), | ||
796 | NULL, 0); | ||
797 | static const char ctx_iv[] = "gnuid-aes-ctx-iv"; | ||
798 | GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
799 | new_key_hash, sizeof (struct GNUNET_HashCode), | ||
800 | ctx_iv, strlen (ctx_iv), | ||
801 | NULL, 0); | ||
802 | return GNUNET_OK; | ||
803 | } | ||
554 | 804 | ||
805 | static void | ||
806 | cleanup_ticket_issue_handle (struct TicketIssueHandle *handle) | ||
807 | { | ||
808 | if (NULL != handle->attrs) | ||
809 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs); | ||
810 | if (NULL != handle->ns_qe) | ||
811 | GNUNET_NAMESTORE_cancel (handle->ns_qe); | ||
812 | GNUNET_free (handle); | ||
555 | } | 813 | } |
556 | 814 | ||
557 | 815 | ||
558 | static void | 816 | static void |
559 | token_collect_finished_cb (void *cls) | 817 | send_ticket_result (struct IdpClient *client, |
818 | uint32_t r_id, | ||
819 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
820 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
560 | { | 821 | { |
561 | struct EgoEntry *ego_entry = cls; | 822 | struct TicketResultMessage *irm; |
823 | struct GNUNET_MQ_Envelope *env; | ||
824 | struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket_buf; | ||
562 | 825 | ||
563 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 826 | /* store ticket in DB */ |
564 | ">>> Updating Ego finished\n"); | 827 | if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, |
565 | //Clear attribute map for ego | 828 | ticket, |
566 | GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map, | 829 | attrs)) |
567 | &clear_ego_attrs, | 830 | { |
568 | ego_entry); | 831 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
569 | GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map); | 832 | "Unable to store ticket after issue\n"); |
570 | update_task = GNUNET_SCHEDULER_add_now (&update_identities, | 833 | GNUNET_break (0); |
571 | ego_entry->next); | 834 | } |
572 | } | ||
573 | 835 | ||
836 | env = GNUNET_MQ_msg_extra (irm, | ||
837 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket), | ||
838 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT); | ||
839 | ticket_buf = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&irm[1]; | ||
840 | *ticket_buf = *ticket; | ||
841 | irm->id = htonl (r_id); | ||
842 | GNUNET_MQ_send (client->mq, | ||
843 | env); | ||
844 | } | ||
574 | 845 | ||
575 | /** | ||
576 | * | ||
577 | * Update all ID_TOKEN records for an identity and store them | ||
578 | * | ||
579 | * @param cls the identity entry | ||
580 | * @param zone the identity | ||
581 | * @param lbl the name of the record | ||
582 | * @param rd_count number of records | ||
583 | * @param rd record data | ||
584 | */ | ||
585 | static void | 846 | static void |
586 | token_collect (void *cls, | 847 | store_ticket_issue_cont (void *cls, |
587 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 848 | int32_t success, |
588 | const char *lbl, | 849 | const char *emsg) |
589 | unsigned int rd_count, | 850 | { |
590 | const struct GNUNET_GNSRECORD_Data *rd) | 851 | struct TicketIssueHandle *handle = cls; |
591 | { | 852 | |
592 | struct EgoEntry *ego_entry = cls; | 853 | handle->ns_qe = NULL; |
593 | const struct GNUNET_GNSRECORD_Data *token_record; | 854 | if (GNUNET_SYSERR == success) |
594 | const struct GNUNET_GNSRECORD_Data *token_metadata_record; | ||
595 | struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key; | ||
596 | struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key; | ||
597 | |||
598 | //There should be only a single record for a token under a label | ||
599 | if (2 != rd_count) | ||
600 | { | 855 | { |
601 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 856 | cleanup_ticket_issue_handle (handle); |
857 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | ||
858 | "Unknown Error\n"); | ||
859 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
602 | return; | 860 | return; |
603 | } | 861 | } |
862 | send_ticket_result (handle->client, | ||
863 | handle->r_id, | ||
864 | &handle->ticket, | ||
865 | handle->attrs); | ||
866 | cleanup_ticket_issue_handle (handle); | ||
867 | } | ||
604 | 868 | ||
605 | if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA) | 869 | |
606 | { | 870 | |
607 | token_metadata_record = &rd[0]; | 871 | int |
608 | token_record = &rd[1]; | 872 | serialize_abe_keyinfo2 (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, |
873 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
874 | const struct GNUNET_ABE_AbeKey *rp_key, | ||
875 | struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, | ||
876 | char **result) | ||
877 | { | ||
878 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; | ||
879 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
880 | char *enc_keyinfo; | ||
881 | char *serialized_key; | ||
882 | char *buf; | ||
883 | char *write_ptr; | ||
884 | char attrs_str_len; | ||
885 | ssize_t size; | ||
886 | |||
887 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
888 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
889 | struct GNUNET_HashCode new_key_hash; | ||
890 | ssize_t enc_size; | ||
891 | |||
892 | size = GNUNET_ABE_cpabe_serialize_key (rp_key, | ||
893 | (void**)&serialized_key); | ||
894 | attrs_str_len = 0; | ||
895 | for (le = attrs->list_head; NULL != le; le = le->next) { | ||
896 | attrs_str_len += strlen (le->claim->name) + 1; | ||
609 | } | 897 | } |
610 | else | 898 | buf = GNUNET_malloc (attrs_str_len + size); |
611 | { | 899 | write_ptr = buf; |
612 | token_record = &rd[0]; | 900 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
613 | token_metadata_record = &rd[1]; | 901 | "Writing attributes\n"); |
902 | for (le = attrs->list_head; NULL != le; le = le->next) { | ||
903 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
904 | "%s\n", le->claim->name); | ||
905 | |||
906 | |||
907 | GNUNET_memcpy (write_ptr, | ||
908 | le->claim->name, | ||
909 | strlen (le->claim->name)); | ||
910 | write_ptr[strlen (le->claim->name)] = ','; | ||
911 | write_ptr += strlen (le->claim->name) + 1; | ||
614 | } | 912 | } |
615 | if (token_metadata_record->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA) | 913 | write_ptr--; |
616 | { | 914 | write_ptr[0] = '\0'; //replace last , with a 0-terminator |
617 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 915 | write_ptr++; |
618 | return; | 916 | GNUNET_memcpy (write_ptr, |
917 | serialized_key, | ||
918 | size); | ||
919 | GNUNET_free (serialized_key); | ||
920 | // ECDH keypair E = eG | ||
921 | *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create(); | ||
922 | GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, | ||
923 | &ecdh_pubkey); | ||
924 | enc_keyinfo = GNUNET_malloc (size + attrs_str_len); | ||
925 | // Derived key K = H(eB) | ||
926 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, | ||
927 | &ticket->audience, | ||
928 | &new_key_hash)); | ||
929 | create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); | ||
930 | enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf, | ||
931 | size + attrs_str_len, | ||
932 | &skey, &iv, | ||
933 | enc_keyinfo); | ||
934 | *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+ | ||
935 | enc_size); | ||
936 | GNUNET_memcpy (*result, | ||
937 | &ecdh_pubkey, | ||
938 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
939 | GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
940 | enc_keyinfo, | ||
941 | enc_size); | ||
942 | GNUNET_free (enc_keyinfo); | ||
943 | GNUNET_free (buf); | ||
944 | return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size; | ||
945 | } | ||
946 | |||
947 | |||
948 | |||
949 | static void | ||
950 | issue_ticket_after_abe_bootstrap (void *cls, | ||
951 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
952 | { | ||
953 | struct TicketIssueHandle *ih = cls; | ||
954 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
955 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; | ||
956 | struct GNUNET_GNSRECORD_Data code_record[1]; | ||
957 | struct GNUNET_ABE_AbeKey *rp_key; | ||
958 | char *code_record_data; | ||
959 | char **attrs; | ||
960 | char *label; | ||
961 | char *policy; | ||
962 | int attrs_len; | ||
963 | uint32_t i; | ||
964 | size_t code_record_len; | ||
965 | |||
966 | //Create new ABE key for RP | ||
967 | attrs_len = 0; | ||
968 | for (le = ih->attrs->list_head; NULL != le; le = le->next) | ||
969 | attrs_len++; | ||
970 | attrs = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); | ||
971 | i = 0; | ||
972 | for (le = ih->attrs->list_head; NULL != le; le = le->next) { | ||
973 | GNUNET_asprintf (&policy, "%s_%lu", | ||
974 | le->claim->name, | ||
975 | le->claim->version); | ||
976 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
977 | "Adding attribute to key: %s\n", | ||
978 | policy); | ||
979 | attrs[i] = policy; | ||
980 | i++; | ||
619 | } | 981 | } |
620 | if (token_record->record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN) | 982 | attrs[i] = NULL; |
983 | rp_key = GNUNET_ABE_cpabe_create_key (abe_key, | ||
984 | attrs); | ||
985 | |||
986 | //TODO review this wireformat | ||
987 | code_record_len = serialize_abe_keyinfo2 (&ih->ticket, | ||
988 | ih->attrs, | ||
989 | rp_key, | ||
990 | &ecdhe_privkey, | ||
991 | &code_record_data); | ||
992 | code_record[0].data = code_record_data; | ||
993 | code_record[0].data_size = code_record_len; | ||
994 | code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; | ||
995 | code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY; | ||
996 | code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
997 | |||
998 | label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, | ||
999 | sizeof (uint64_t)); | ||
1000 | //Publish record | ||
1001 | ih->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1002 | &ih->identity, | ||
1003 | label, | ||
1004 | 1, | ||
1005 | code_record, | ||
1006 | &store_ticket_issue_cont, | ||
1007 | ih); | ||
1008 | //for (; i > 0; i--) | ||
1009 | // GNUNET_free (attrs[i-1]); | ||
1010 | GNUNET_free (ecdhe_privkey); | ||
1011 | GNUNET_free (label); | ||
1012 | GNUNET_free (attrs); | ||
1013 | GNUNET_free (code_record_data); | ||
1014 | GNUNET_ABE_cpabe_delete_key (rp_key, | ||
1015 | GNUNET_YES); | ||
1016 | GNUNET_ABE_cpabe_delete_master_key (abe_key); | ||
1017 | } | ||
1018 | |||
1019 | |||
1020 | static int | ||
1021 | check_issue_ticket_message(void *cls, | ||
1022 | const struct IssueTicketMessage *im) | ||
1023 | { | ||
1024 | uint16_t size; | ||
1025 | |||
1026 | size = ntohs (im->header.size); | ||
1027 | if (size <= sizeof (struct IssueTicketMessage)) | ||
621 | { | 1028 | { |
622 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 1029 | GNUNET_break (0); |
623 | return; | 1030 | return GNUNET_SYSERR; |
624 | } | 1031 | } |
1032 | return GNUNET_OK; | ||
1033 | } | ||
625 | 1034 | ||
626 | //Get metadata and decrypt token | ||
627 | priv_key = (struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data; | ||
628 | ecdhe_privkey = *priv_key; | ||
629 | aud_key = (struct GNUNET_CRYPTO_EcdsaPublicKey *)&priv_key[1]; | ||
630 | scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
631 | 1035 | ||
632 | token_parse2 (token_record->data, | 1036 | static void |
633 | &ecdhe_privkey, | 1037 | handle_issue_ticket_message (void *cls, |
634 | aud_key, | 1038 | const struct IssueTicketMessage *im) |
635 | &token); | 1039 | { |
1040 | struct TicketIssueHandle *ih; | ||
1041 | struct IdpClient *idp = cls; | ||
1042 | size_t attrs_len; | ||
1043 | |||
1044 | ih = GNUNET_new (struct TicketIssueHandle); | ||
1045 | attrs_len = ntohs (im->attr_len); | ||
1046 | ih->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&im[1], attrs_len); | ||
1047 | ih->r_id = ntohl (im->id); | ||
1048 | ih->client = idp; | ||
1049 | ih->identity = im->identity; | ||
1050 | GNUNET_CRYPTO_ecdsa_key_get_public (&ih->identity, | ||
1051 | &ih->ticket.identity); | ||
1052 | ih->ticket.audience = im->rp; | ||
1053 | ih->ticket.rnd = | ||
1054 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, | ||
1055 | UINT64_MAX); | ||
1056 | bootstrap_abe (&ih->identity, &issue_ticket_after_abe_bootstrap, ih, GNUNET_NO); | ||
1057 | GNUNET_SERVICE_client_continue (idp->client); | ||
636 | 1058 | ||
637 | label = GNUNET_strdup (lbl); | 1059 | } |
638 | rd_exp = token_record->expiration_time; | ||
639 | 1060 | ||
640 | GNUNET_SCHEDULER_add_now (&handle_token_update, | 1061 | /********************************************************** |
641 | ego_entry); | 1062 | * Revocation |
1063 | **********************************************************/ | ||
1064 | |||
1065 | /** | ||
1066 | * Cleanup revoke handle | ||
1067 | * | ||
1068 | * @param rh the ticket revocation handle | ||
1069 | */ | ||
1070 | static void | ||
1071 | cleanup_revoke_ticket_handle (struct TicketRevocationHandle *rh) | ||
1072 | { | ||
1073 | if (NULL != rh->attrs) | ||
1074 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->attrs); | ||
1075 | if (NULL != rh->rvk_attrs) | ||
1076 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (rh->rvk_attrs); | ||
1077 | if (NULL != rh->abe_key) | ||
1078 | GNUNET_ABE_cpabe_delete_master_key (rh->abe_key); | ||
1079 | if (NULL != rh->ns_qe) | ||
1080 | GNUNET_NAMESTORE_cancel (rh->ns_qe); | ||
1081 | if (NULL != rh->ns_it) | ||
1082 | GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it); | ||
1083 | GNUNET_free (rh); | ||
642 | } | 1084 | } |
643 | 1085 | ||
644 | 1086 | ||
1087 | /** | ||
1088 | * Send revocation result | ||
1089 | * | ||
1090 | * @param rh ticket revocation handle | ||
1091 | * @param success GNUNET_OK if successful result | ||
1092 | */ | ||
645 | static void | 1093 | static void |
646 | attribute_collect_error_cb (void *cls) | 1094 | send_revocation_finished (struct TicketRevocationHandle *rh, |
1095 | uint32_t success) | ||
647 | { | 1096 | { |
648 | struct EgoEntry *ego_entry = cls; | 1097 | struct GNUNET_MQ_Envelope *env; |
1098 | struct RevokeTicketResultMessage *trm; | ||
649 | 1099 | ||
650 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1100 | env = GNUNET_MQ_msg (trm, |
651 | ">>> Updating Attributes failed!\n"); | 1101 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT); |
652 | ego_entry->attributes_dirty = GNUNET_NO; | 1102 | trm->id = htonl (rh->r_id); |
653 | update_task = GNUNET_SCHEDULER_add_now (&update_identities, | 1103 | trm->success = htonl (success); |
654 | ego_entry); | 1104 | GNUNET_MQ_send (rh->client->mq, |
1105 | env); | ||
1106 | GNUNET_CONTAINER_DLL_remove (rh->client->revocation_list_head, | ||
1107 | rh->client->revocation_list_tail, | ||
1108 | rh); | ||
655 | } | 1109 | } |
656 | 1110 | ||
657 | 1111 | ||
1112 | /** | ||
1113 | * Process ticket from database | ||
1114 | * | ||
1115 | * @param cls struct TicketIterationProcResult | ||
1116 | * @param ticket the ticket | ||
1117 | * @param attrs the attributes | ||
1118 | */ | ||
1119 | static void | ||
1120 | ticket_reissue_proc (void *cls, | ||
1121 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
1122 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); | ||
1123 | |||
658 | static void | 1124 | static void |
659 | attribute_collect_finished_cb (void *cls) | 1125 | revocation_reissue_tickets (struct TicketRevocationHandle *rh); |
1126 | |||
1127 | |||
1128 | static void reissue_next (void *cls) | ||
660 | { | 1129 | { |
661 | struct EgoEntry *ego_entry = cls; | 1130 | struct TicketRevocationHandle *rh = cls; |
1131 | revocation_reissue_tickets (rh); | ||
1132 | } | ||
662 | 1133 | ||
663 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1134 | |
664 | ">>> Updating Attributes finished\n"); | 1135 | static void |
665 | ego_entry->attributes_dirty = GNUNET_NO; | 1136 | reissue_ticket_cont (void *cls, |
666 | update_task = GNUNET_SCHEDULER_add_now (&update_identities, | 1137 | int32_t success, |
667 | ego_entry); | 1138 | const char *emsg) |
1139 | { | ||
1140 | struct TicketRevocationHandle *rh = cls; | ||
1141 | |||
1142 | rh->ns_qe = NULL; | ||
1143 | if (GNUNET_SYSERR == success) | ||
1144 | { | ||
1145 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | ||
1146 | "Unknown Error\n"); | ||
1147 | send_revocation_finished (rh, GNUNET_SYSERR); | ||
1148 | cleanup_revoke_ticket_handle (rh); | ||
1149 | return; | ||
1150 | } | ||
1151 | rh->offset++; | ||
1152 | GNUNET_SCHEDULER_add_now (&reissue_next, rh); | ||
668 | } | 1153 | } |
669 | 1154 | ||
670 | 1155 | ||
671 | /** | 1156 | /** |
1157 | * Process ticket from database | ||
672 | * | 1158 | * |
673 | * Collect all ID_ATTR records for an identity and store them | 1159 | * @param cls struct TicketIterationProcResult |
674 | * | 1160 | * @param ticket the ticket |
675 | * @param cls the identity entry | 1161 | * @param attrs the attributes |
676 | * @param zone the identity | ||
677 | * @param lbl the name of the record | ||
678 | * @param rd_count number of records | ||
679 | * @param rd record data | ||
680 | * | ||
681 | */ | 1162 | */ |
682 | static void | 1163 | static void |
683 | attribute_collect (void *cls, | 1164 | ticket_reissue_proc (void *cls, |
684 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 1165 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, |
685 | const char *lbl, | 1166 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) |
686 | unsigned int rd_count, | 1167 | { |
687 | const struct GNUNET_GNSRECORD_Data *rd) | 1168 | struct TicketRevocationHandle *rh = cls; |
688 | { | 1169 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; |
689 | struct EgoEntry *ego_entry = cls; | 1170 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le_rollover; |
690 | struct GNUNET_HashCode key; | 1171 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; |
691 | struct TokenAttr *attr; | 1172 | struct GNUNET_GNSRECORD_Data code_record[1]; |
692 | struct TokenAttrValue *val; | 1173 | struct GNUNET_ABE_AbeKey *rp_key; |
693 | char *val_str; | 1174 | char *code_record_data; |
694 | int i; | 1175 | char **attr_arr; |
695 | 1176 | char *label; | |
696 | if (0 == rd_count) | 1177 | char *policy; |
1178 | int attrs_len; | ||
1179 | uint32_t i; | ||
1180 | int reissue_ticket; | ||
1181 | size_t code_record_len; | ||
1182 | |||
1183 | |||
1184 | if (NULL == ticket) | ||
697 | { | 1185 | { |
698 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 1186 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1187 | "Iteration done\n"); | ||
699 | return; | 1188 | return; |
700 | } | 1189 | } |
701 | GNUNET_CRYPTO_hash (lbl, | 1190 | |
702 | strlen (lbl), | 1191 | if (0 == memcmp (&ticket->audience, |
703 | &key); | 1192 | &rh->ticket.audience, |
704 | if (1 == rd_count) | 1193 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) |
705 | { | 1194 | { |
706 | if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) | 1195 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
707 | { | 1196 | "Do not reissue for this identity.!\n"); |
708 | val_str = GNUNET_GNSRECORD_value_to_string (rd->record_type, | ||
709 | rd->data, | ||
710 | rd->data_size); | ||
711 | attr = GNUNET_malloc (sizeof (struct TokenAttr)); | ||
712 | attr->name = GNUNET_strdup (lbl); | ||
713 | val = GNUNET_malloc (sizeof (struct TokenAttrValue)); | ||
714 | val->value = val_str; | ||
715 | GNUNET_CONTAINER_DLL_insert (attr->val_head, | ||
716 | attr->val_tail, | ||
717 | val); | ||
718 | GNUNET_assert (GNUNET_OK == | ||
719 | GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map, | ||
720 | &key, | ||
721 | attr, | ||
722 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
723 | } | ||
724 | 1197 | ||
725 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | 1198 | rh->offset++; |
1199 | GNUNET_SCHEDULER_add_now (&reissue_next, rh); | ||
726 | return; | 1200 | return; |
727 | } | 1201 | } |
728 | 1202 | ||
729 | attr = GNUNET_malloc (sizeof (struct TokenAttr)); | 1203 | /* |
730 | attr->name = GNUNET_strdup (lbl); | 1204 | * Check if any attribute of this ticket intersects with a rollover attribute |
731 | for (i = 0; i < rd_count; i++) | 1205 | */ |
1206 | reissue_ticket = GNUNET_NO; | ||
1207 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
732 | { | 1208 | { |
733 | if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) | 1209 | for (le_rollover = rh->rvk_attrs->list_head; |
1210 | NULL != le_rollover; | ||
1211 | le_rollover = le_rollover->next) | ||
734 | { | 1212 | { |
735 | val_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, | 1213 | if (0 == strcmp (le_rollover->claim->name, |
736 | rd[i].data, | 1214 | le->claim->name)) |
737 | rd[i].data_size); | 1215 | { |
738 | val = GNUNET_malloc (sizeof (struct TokenAttrValue)); | 1216 | reissue_ticket = GNUNET_YES; |
739 | val->value = val_str; | 1217 | le->claim->version = le_rollover->claim->version; |
740 | GNUNET_CONTAINER_DLL_insert (attr->val_head, | 1218 | } |
741 | attr->val_tail, | ||
742 | val); | ||
743 | } | 1219 | } |
744 | } | 1220 | } |
745 | GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map, | ||
746 | &key, | ||
747 | attr, | ||
748 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
749 | GNUNET_NAMESTORE_zone_iterator_next (ns_it); | ||
750 | } | ||
751 | |||
752 | /** | ||
753 | * | ||
754 | * Update identity information for ego. If attribute map is | ||
755 | * dirty, first update the attributes. | ||
756 | * | ||
757 | * @param cls the ego to update | ||
758 | */ | ||
759 | static void | ||
760 | update_identities(void *cls) | ||
761 | { | ||
762 | struct EgoEntry *next_ego = cls; | ||
763 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | ||
764 | 1221 | ||
765 | update_task = NULL; | 1222 | if (GNUNET_NO == reissue_ticket) |
766 | if (NULL == next_ego) | ||
767 | { | 1223 | { |
768 | if (min_rel_exp.rel_value_us < MIN_WAIT_TIME.rel_value_us) | ||
769 | min_rel_exp = MIN_WAIT_TIME; | ||
770 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
771 | ">>> Finished. Rescheduling in %"SCNu64"\n", | 1225 | "Skipping ticket.\n"); |
772 | min_rel_exp.rel_value_us); | 1226 | |
773 | ns_it = NULL; | 1227 | rh->offset++; |
774 | //finished -> reschedule | 1228 | GNUNET_SCHEDULER_add_now (&reissue_next, rh); |
775 | update_task = GNUNET_SCHEDULER_add_delayed (min_rel_exp, | 1229 | |
776 | &update_identities, | 1230 | |
777 | ego_head); | ||
778 | min_rel_exp.rel_value_us = 0; | ||
779 | return; | 1231 | return; |
780 | } | 1232 | } |
781 | priv_key = GNUNET_IDENTITY_ego_get_private_key (next_ego->ego); | ||
782 | if (GNUNET_YES == next_ego->attributes_dirty) | ||
783 | { | ||
784 | //Starting over. We must update the Attributes for they might have changed. | ||
785 | ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | ||
786 | priv_key, | ||
787 | &attribute_collect_error_cb, | ||
788 | next_ego, | ||
789 | &attribute_collect, | ||
790 | next_ego, | ||
791 | &attribute_collect_finished_cb, | ||
792 | next_ego); | ||
793 | 1233 | ||
1234 | //Create new ABE key for RP | ||
1235 | attrs_len = 0; | ||
1236 | |||
1237 | /* If this is the RP we want to revoke attributes of, the do so */ | ||
1238 | |||
1239 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
1240 | attrs_len++; | ||
1241 | attr_arr = GNUNET_malloc ((attrs_len + 1)*sizeof (char*)); | ||
1242 | i = 0; | ||
1243 | for (le = attrs->list_head; NULL != le; le = le->next) { | ||
1244 | GNUNET_asprintf (&policy, "%s_%lu", | ||
1245 | le->claim->name, | ||
1246 | le->claim->version); | ||
1247 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1248 | "Recreating key with %s\n", policy); | ||
1249 | attr_arr[i] = policy; | ||
1250 | i++; | ||
794 | } | 1251 | } |
795 | else | 1252 | attr_arr[i] = NULL; |
1253 | rp_key = GNUNET_ABE_cpabe_create_key (rh->abe_key, | ||
1254 | attr_arr); | ||
1255 | |||
1256 | //TODO review this wireformat | ||
1257 | code_record_len = serialize_abe_keyinfo2 (ticket, | ||
1258 | attrs, | ||
1259 | rp_key, | ||
1260 | &ecdhe_privkey, | ||
1261 | &code_record_data); | ||
1262 | code_record[0].data = code_record_data; | ||
1263 | code_record[0].data_size = code_record_len; | ||
1264 | code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us; | ||
1265 | code_record[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_KEY; | ||
1266 | code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1267 | |||
1268 | label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, | ||
1269 | sizeof (uint64_t)); | ||
1270 | //Publish record | ||
1271 | rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1272 | &rh->identity, | ||
1273 | label, | ||
1274 | 1, | ||
1275 | code_record, | ||
1276 | &reissue_ticket_cont, | ||
1277 | rh); | ||
1278 | //for (; i > 0; i--) | ||
1279 | // GNUNET_free (attr_arr[i-1]); | ||
1280 | GNUNET_free (ecdhe_privkey); | ||
1281 | GNUNET_free (label); | ||
1282 | GNUNET_free (attr_arr); | ||
1283 | GNUNET_free (code_record_data); | ||
1284 | GNUNET_ABE_cpabe_delete_key (rp_key, GNUNET_YES); | ||
1285 | } | ||
1286 | |||
1287 | |||
1288 | /* Prototype for below function */ | ||
1289 | static void | ||
1290 | attr_reenc_cont (void *cls, | ||
1291 | int32_t success, | ||
1292 | const char *emsg); | ||
1293 | |||
1294 | static void | ||
1295 | revocation_reissue_tickets (struct TicketRevocationHandle *rh) | ||
1296 | { | ||
1297 | int ret; | ||
1298 | /* Done, issue new keys */ | ||
1299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1300 | "Revocation Phase III: Reissuing Tickets\n"); | ||
1301 | if (GNUNET_SYSERR == (ret = TKT_database->iterate_tickets (TKT_database->cls, | ||
1302 | &rh->ticket.identity, | ||
1303 | GNUNET_NO, | ||
1304 | rh->offset, | ||
1305 | &ticket_reissue_proc, | ||
1306 | rh))) | ||
796 | { | 1307 | { |
797 | //Ego will be dirty next time | 1308 | GNUNET_break (0); |
798 | next_ego->attributes_dirty = GNUNET_YES; | 1309 | } |
799 | ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | 1310 | if (GNUNET_NO == ret) |
800 | priv_key, | 1311 | { |
801 | &token_collect_error_cb, | 1312 | send_revocation_finished (rh, GNUNET_OK); |
802 | next_ego, | 1313 | cleanup_revoke_ticket_handle (rh); |
803 | &token_collect, | 1314 | return; |
804 | next_ego, | ||
805 | &token_collect_finished_cb, | ||
806 | next_ego); | ||
807 | } | 1315 | } |
808 | } | 1316 | } |
809 | 1317 | ||
810 | |||
811 | /** | 1318 | /** |
812 | * Function called initially to start update task | 1319 | * Revoke next attribte by reencryption with |
1320 | * new ABE master | ||
813 | */ | 1321 | */ |
814 | static void | 1322 | static void |
815 | init_cont () | 1323 | reenc_next_attribute (struct TicketRevocationHandle *rh) |
816 | { | 1324 | { |
817 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, ">>> Starting Service\n"); | 1325 | struct GNUNET_GNSRECORD_Data rd[1]; |
818 | //Initially iterate all itenties and refresh all tokens | 1326 | char* buf; |
819 | update_task = GNUNET_SCHEDULER_add_now (&update_identities, | 1327 | char* enc_buf; |
820 | ego_head); | 1328 | size_t enc_size; |
1329 | char* rd_buf; | ||
1330 | size_t buf_size; | ||
1331 | char* policy; | ||
1332 | uint32_t attr_ver; | ||
1333 | |||
1334 | if (NULL == rh->attrs->list_head) | ||
1335 | { | ||
1336 | revocation_reissue_tickets (rh); | ||
1337 | return; | ||
1338 | } | ||
1339 | buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (rh->attrs->list_head->claim); | ||
1340 | buf = GNUNET_malloc (buf_size); | ||
1341 | GNUNET_IDENTITY_ATTRIBUTE_serialize (rh->attrs->list_head->claim, | ||
1342 | buf); | ||
1343 | rh->attrs->list_head->claim->version++; | ||
1344 | GNUNET_asprintf (&policy, "%s_%lu", | ||
1345 | rh->attrs->list_head->claim->name, | ||
1346 | rh->attrs->list_head->claim->version); | ||
1347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1348 | "Encrypting with policy %s\n", policy); | ||
1349 | /** | ||
1350 | * Encrypt the attribute value and store in namestore | ||
1351 | */ | ||
1352 | enc_size = GNUNET_ABE_cpabe_encrypt (buf, | ||
1353 | buf_size, | ||
1354 | policy, //Policy | ||
1355 | rh->abe_key, | ||
1356 | (void**)&enc_buf); | ||
1357 | GNUNET_free (buf); | ||
1358 | GNUNET_free (policy); | ||
1359 | rd[0].data_size = enc_size + sizeof (uint32_t); | ||
1360 | rd_buf = GNUNET_malloc (rd[0].data_size); | ||
1361 | attr_ver = htonl (rh->attrs->list_head->claim->version); | ||
1362 | GNUNET_memcpy (rd_buf, | ||
1363 | &attr_ver, | ||
1364 | sizeof (uint32_t)); | ||
1365 | GNUNET_memcpy (rd_buf+sizeof (uint32_t), | ||
1366 | enc_buf, | ||
1367 | enc_size); | ||
1368 | rd[0].data = rd_buf; | ||
1369 | rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; | ||
1370 | rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1371 | rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? | ||
1372 | rh->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1373 | &rh->identity, | ||
1374 | rh->attrs->list_head->claim->name, | ||
1375 | 1, | ||
1376 | rd, | ||
1377 | &attr_reenc_cont, | ||
1378 | rh); | ||
1379 | GNUNET_free (enc_buf); | ||
1380 | GNUNET_free (rd_buf); | ||
821 | } | 1381 | } |
822 | 1382 | ||
823 | |||
824 | /** | 1383 | /** |
825 | * Initial ego collection function. | 1384 | * Namestore callback after revoked attribute |
826 | * | 1385 | * is stored |
827 | * @param cls NULL | ||
828 | * @param ego ego | ||
829 | * @param ctx context | ||
830 | * @param identifier ego name | ||
831 | */ | 1386 | */ |
832 | static void | 1387 | static void |
833 | list_ego (void *cls, | 1388 | attr_reenc_cont (void *cls, |
834 | struct GNUNET_IDENTITY_Ego *ego, | 1389 | int32_t success, |
835 | void **ctx, | 1390 | const char *emsg) |
836 | const char *identifier) | ||
837 | { | 1391 | { |
838 | struct EgoEntry *new_entry; | 1392 | struct TicketRevocationHandle *rh = cls; |
839 | if ((NULL == ego) && (STATE_INIT == state)) | 1393 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; |
1394 | |||
1395 | if (GNUNET_SYSERR == success) | ||
840 | { | 1396 | { |
841 | state = STATE_POST_INIT; | 1397 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
842 | init_cont (); | 1398 | "Failed to reencrypt attribute %s\n", |
1399 | emsg); | ||
1400 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
843 | return; | 1401 | return; |
844 | } | 1402 | } |
845 | if (STATE_INIT == state) { | 1403 | if (NULL == rh->attrs->list_head) |
846 | new_entry = GNUNET_malloc (sizeof (struct EgoEntry)); | 1404 | { |
847 | new_entry->ego = ego; | 1405 | revocation_reissue_tickets (rh); |
848 | new_entry->attr_map = GNUNET_CONTAINER_multihashmap_create (5, | 1406 | return; |
849 | GNUNET_NO); | ||
850 | new_entry->attributes_dirty = GNUNET_YES; | ||
851 | GNUNET_CONTAINER_DLL_insert_tail(ego_head, ego_tail, new_entry); | ||
852 | } | 1407 | } |
1408 | le = rh->attrs->list_head; | ||
1409 | GNUNET_CONTAINER_DLL_remove (rh->attrs->list_head, | ||
1410 | rh->attrs->list_tail, | ||
1411 | le); | ||
1412 | GNUNET_assert (NULL != rh->rvk_attrs); | ||
1413 | GNUNET_CONTAINER_DLL_insert (rh->rvk_attrs->list_head, | ||
1414 | rh->rvk_attrs->list_tail, | ||
1415 | le); | ||
1416 | |||
1417 | |||
1418 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1419 | "Re-encrypting next attribute\n"); | ||
1420 | reenc_next_attribute (rh); | ||
853 | } | 1421 | } |
854 | 1422 | ||
855 | /** | 1423 | |
856 | * Cleanup task | ||
857 | */ | ||
858 | static void | 1424 | static void |
859 | cleanup() | 1425 | process_attributes_to_update (void *cls, |
1426 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
1427 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
860 | { | 1428 | { |
861 | struct EgoEntry *ego_entry; | 1429 | struct TicketRevocationHandle *rh = cls; |
862 | struct EgoEntry *ego_tmp; | ||
863 | 1430 | ||
1431 | rh->attrs = GNUNET_IDENTITY_ATTRIBUTE_list_dup (attrs); | ||
864 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1432 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
865 | "Cleaning up\n"); | 1433 | "Revocation Phase I: Collecting attributes\n"); |
866 | if (NULL != stats) | 1434 | /* Reencrypt all attributes with new key */ |
1435 | if (NULL == rh->attrs->list_head) | ||
867 | { | 1436 | { |
868 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 1437 | /* No attributes to reencrypt */ |
869 | stats = NULL; | 1438 | send_revocation_finished (rh, GNUNET_OK); |
1439 | cleanup_revoke_ticket_handle (rh); | ||
1440 | return; | ||
1441 | } else { | ||
1442 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1443 | "Revocation Phase II: Re-encrypting attributes\n"); | ||
1444 | reenc_next_attribute (rh); | ||
870 | } | 1445 | } |
871 | 1446 | ||
872 | if (NULL != timeout_task) | 1447 | } |
873 | GNUNET_SCHEDULER_cancel (timeout_task); | ||
874 | if (NULL != update_task) | ||
875 | GNUNET_SCHEDULER_cancel (update_task); | ||
876 | if (NULL != identity_handle) | ||
877 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
878 | if (NULL != gns_handle) | ||
879 | GNUNET_GNS_disconnect (gns_handle); | ||
880 | if (NULL != ns_it) | ||
881 | GNUNET_NAMESTORE_zone_iteration_stop (ns_it); | ||
882 | if (NULL != ns_qe) | ||
883 | GNUNET_NAMESTORE_cancel (ns_qe); | ||
884 | if (NULL != ns_handle) | ||
885 | GNUNET_NAMESTORE_disconnect (ns_handle); | ||
886 | if (NULL != token) | ||
887 | GNUNET_free (token); | ||
888 | if (NULL != label) | ||
889 | GNUNET_free (label); | ||
890 | 1448 | ||
891 | for (ego_entry = ego_head; | ||
892 | NULL != ego_entry;) | ||
893 | { | ||
894 | ego_tmp = ego_entry; | ||
895 | if (0 != GNUNET_CONTAINER_multihashmap_size (ego_tmp->attr_map)) | ||
896 | { | ||
897 | GNUNET_CONTAINER_multihashmap_iterate (ego_tmp->attr_map, | ||
898 | &clear_ego_attrs, | ||
899 | ego_tmp); | ||
900 | 1449 | ||
901 | } | 1450 | |
902 | GNUNET_CONTAINER_multihashmap_destroy (ego_tmp->attr_map); | 1451 | static void |
903 | ego_entry = ego_entry->next; | 1452 | get_ticket_after_abe_bootstrap (void *cls, |
904 | GNUNET_free (ego_tmp); | 1453 | struct GNUNET_ABE_AbeMasterKey *abe_key) |
1454 | { | ||
1455 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1456 | "Finished ABE bootstrap\n"); | ||
1457 | struct TicketRevocationHandle *rh = cls; | ||
1458 | rh->abe_key = abe_key; | ||
1459 | TKT_database->get_ticket_attributes (TKT_database->cls, | ||
1460 | &rh->ticket, | ||
1461 | &process_attributes_to_update, | ||
1462 | rh); | ||
1463 | } | ||
1464 | |||
1465 | static int | ||
1466 | check_revoke_ticket_message(void *cls, | ||
1467 | const struct RevokeTicketMessage *im) | ||
1468 | { | ||
1469 | uint16_t size; | ||
1470 | |||
1471 | size = ntohs (im->header.size); | ||
1472 | if (size <= sizeof (struct RevokeTicketMessage)) | ||
1473 | { | ||
1474 | GNUNET_break (0); | ||
1475 | return GNUNET_SYSERR; | ||
905 | } | 1476 | } |
1477 | return GNUNET_OK; | ||
906 | } | 1478 | } |
907 | 1479 | ||
908 | /** | ||
909 | * Shutdown task | ||
910 | * | ||
911 | * @param cls NULL | ||
912 | * @param tc task context | ||
913 | */ | ||
914 | static void | 1480 | static void |
915 | do_shutdown (void *cls) | 1481 | handle_revoke_ticket_message (void *cls, |
1482 | const struct RevokeTicketMessage *rm) | ||
916 | { | 1483 | { |
917 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1484 | struct TicketRevocationHandle *rh; |
918 | "Shutting down...\n"); | 1485 | struct IdpClient *idp = cls; |
919 | cleanup(); | 1486 | struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket; |
1487 | |||
1488 | rh = GNUNET_new (struct TicketRevocationHandle); | ||
1489 | ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket*)&rm[1]; | ||
1490 | rh->rvk_attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
1491 | rh->ticket = *ticket; | ||
1492 | rh->r_id = ntohl (rm->id); | ||
1493 | rh->client = idp; | ||
1494 | rh->identity = rm->identity; | ||
1495 | GNUNET_CRYPTO_ecdsa_key_get_public (&rh->identity, | ||
1496 | &rh->ticket.identity); | ||
1497 | GNUNET_CONTAINER_DLL_insert (idp->revocation_list_head, | ||
1498 | idp->revocation_list_tail, | ||
1499 | rh); | ||
1500 | bootstrap_abe (&rh->identity, &get_ticket_after_abe_bootstrap, rh, GNUNET_NO); | ||
1501 | GNUNET_SERVICE_client_continue (idp->client); | ||
1502 | |||
920 | } | 1503 | } |
921 | 1504 | ||
922 | 1505 | ||
923 | static struct GNUNET_MQ_Envelope* | 1506 | static void |
924 | create_exchange_result_message (const char* token, | 1507 | cleanup_consume_ticket_handle (struct ConsumeTicketHandle *handle) |
925 | const char* label, | ||
926 | uint64_t ticket_nonce, | ||
927 | uint64_t id) | ||
928 | { | 1508 | { |
929 | struct GNUNET_MQ_Envelope *env; | 1509 | if (NULL != handle->key) |
930 | struct ExchangeResultMessage *erm; | 1510 | GNUNET_ABE_cpabe_delete_key (handle->key, |
931 | uint16_t token_len = strlen (token) + 1; | 1511 | GNUNET_YES); |
932 | 1512 | if (NULL != handle->attrs) | |
933 | env = GNUNET_MQ_msg_extra (erm, | 1513 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (handle->attrs); |
934 | token_len, | 1514 | GNUNET_free (handle); |
935 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT); | ||
936 | erm->ticket_nonce = htonl (ticket_nonce); | ||
937 | erm->id = id; | ||
938 | GNUNET_memcpy (&erm[1], token, token_len); | ||
939 | return env; | ||
940 | } | 1515 | } |
941 | 1516 | ||
942 | 1517 | ||
943 | static struct GNUNET_MQ_Envelope* | 1518 | |
944 | create_issue_result_message (const char* label, | 1519 | static int |
945 | const char* ticket, | 1520 | check_consume_ticket_message(void *cls, |
946 | const char* token, | 1521 | const struct ConsumeTicketMessage *cm) |
947 | uint64_t id) | ||
948 | { | 1522 | { |
949 | struct GNUNET_MQ_Envelope *env; | 1523 | uint16_t size; |
950 | struct IssueResultMessage *irm; | ||
951 | char *tmp_str; | ||
952 | size_t len; | ||
953 | 1524 | ||
954 | GNUNET_asprintf (&tmp_str, "%s,%s,%s", label, ticket, token); | 1525 | size = ntohs (cm->header.size); |
955 | len = strlen (tmp_str) + 1; | 1526 | if (size <= sizeof (struct ConsumeTicketMessage)) |
956 | env = GNUNET_MQ_msg_extra (irm, | 1527 | { |
957 | len, | 1528 | GNUNET_break (0); |
958 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT); | 1529 | return GNUNET_SYSERR; |
959 | irm->id = id; | 1530 | } |
960 | GNUNET_memcpy (&irm[1], tmp_str, strlen (tmp_str) + 1); | 1531 | return GNUNET_OK; |
961 | GNUNET_free (tmp_str); | ||
962 | return env; | ||
963 | } | 1532 | } |
964 | 1533 | ||
965 | static void | 1534 | static void |
966 | cleanup_issue_handle (struct IssueHandle *handle) | 1535 | process_parallel_lookup2 (void *cls, uint32_t rd_count, |
967 | { | 1536 | const struct GNUNET_GNSRECORD_Data *rd) |
968 | if (NULL != handle->attr_map) | 1537 | { |
969 | GNUNET_CONTAINER_multihashmap_destroy (handle->attr_map); | 1538 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
970 | if (NULL != handle->scopes) | 1539 | "Parallel lookup finished (count=%u)\n", rd_count); |
971 | GNUNET_free (handle->scopes); | 1540 | struct ParallelLookup *parallel_lookup = cls; |
972 | if (NULL != handle->token) | 1541 | struct ConsumeTicketHandle *handle = parallel_lookup->handle; |
973 | token_destroy (handle->token); | 1542 | struct ConsumeTicketResultMessage *crm; |
974 | if (NULL != handle->ticket) | 1543 | struct GNUNET_MQ_Envelope *env; |
975 | ticket_destroy (handle->ticket); | 1544 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *attr_le; |
976 | if (NULL != handle->label) | 1545 | struct GNUNET_TIME_Absolute decrypt_duration; |
977 | GNUNET_free (handle->label); | 1546 | char *data; |
978 | GNUNET_free (handle); | 1547 | char *data_tmp; |
1548 | ssize_t attr_len; | ||
1549 | size_t attrs_len; | ||
1550 | |||
1551 | GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, | ||
1552 | handle->parallel_lookups_tail, | ||
1553 | parallel_lookup); | ||
1554 | GNUNET_free (parallel_lookup->label); | ||
1555 | |||
1556 | GNUNET_STATISTICS_update (stats_handle, | ||
1557 | "attribute_lookup_time_total", | ||
1558 | GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us, | ||
1559 | GNUNET_YES); | ||
1560 | GNUNET_STATISTICS_update (stats_handle, | ||
1561 | "attribute_lookups_count", | ||
1562 | 1, | ||
1563 | GNUNET_YES); | ||
1564 | |||
1565 | |||
1566 | GNUNET_free (parallel_lookup); | ||
1567 | if (1 != rd_count) | ||
1568 | GNUNET_break(0);//TODO | ||
1569 | if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) | ||
1570 | { | ||
1571 | decrypt_duration = GNUNET_TIME_absolute_get (); | ||
1572 | attr_len = GNUNET_ABE_cpabe_decrypt (rd->data + sizeof (uint32_t), | ||
1573 | rd->data_size - sizeof (uint32_t), | ||
1574 | handle->key, | ||
1575 | (void**)&data); | ||
1576 | if (GNUNET_SYSERR != attr_len) | ||
1577 | { | ||
1578 | GNUNET_STATISTICS_update (stats_handle, | ||
1579 | "abe_decrypt_time_total", | ||
1580 | GNUNET_TIME_absolute_get_duration (decrypt_duration).rel_value_us, | ||
1581 | GNUNET_YES); | ||
1582 | GNUNET_STATISTICS_update (stats_handle, | ||
1583 | "abe_decrypt_count", | ||
1584 | 1, | ||
1585 | GNUNET_YES); | ||
1586 | |||
1587 | attr_le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry); | ||
1588 | attr_le->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize (data, | ||
1589 | attr_len); | ||
1590 | attr_le->claim->version = ntohl(*(uint32_t*)rd->data); | ||
1591 | GNUNET_CONTAINER_DLL_insert (handle->attrs->list_head, | ||
1592 | handle->attrs->list_tail, | ||
1593 | attr_le); | ||
1594 | GNUNET_free (data); | ||
1595 | } | ||
1596 | } | ||
1597 | if (NULL != handle->parallel_lookups_head) | ||
1598 | return; //Wait for more | ||
1599 | /* Else we are done */ | ||
1600 | |||
1601 | /* Store ticket in DB */ | ||
1602 | if (GNUNET_OK != TKT_database->store_ticket (TKT_database->cls, | ||
1603 | &handle->ticket, | ||
1604 | handle->attrs)) | ||
1605 | { | ||
1606 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1607 | "Unable to store ticket after consume\n"); | ||
1608 | GNUNET_break (0); | ||
1609 | } | ||
1610 | |||
1611 | GNUNET_SCHEDULER_cancel (handle->kill_task); | ||
1612 | attrs_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (handle->attrs); | ||
1613 | env = GNUNET_MQ_msg_extra (crm, | ||
1614 | attrs_len, | ||
1615 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT); | ||
1616 | crm->id = htonl (handle->r_id); | ||
1617 | crm->attrs_len = htons (attrs_len); | ||
1618 | crm->identity = handle->ticket.identity; | ||
1619 | data_tmp = (char *) &crm[1]; | ||
1620 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize (handle->attrs, | ||
1621 | data_tmp); | ||
1622 | GNUNET_MQ_send (handle->client->mq, env); | ||
1623 | cleanup_consume_ticket_handle (handle); | ||
979 | } | 1624 | } |
980 | 1625 | ||
981 | static void | 1626 | void |
982 | store_token_issue_cont (void *cls, | 1627 | abort_parallel_lookups2 (void *cls) |
983 | int32_t success, | ||
984 | const char *emsg) | ||
985 | { | 1628 | { |
986 | struct IssueHandle *handle = cls; | 1629 | struct ConsumeTicketHandle *handle = cls; |
1630 | struct ParallelLookup *lu; | ||
1631 | struct ParallelLookup *tmp; | ||
1632 | struct AttributeResultMessage *arm; | ||
987 | struct GNUNET_MQ_Envelope *env; | 1633 | struct GNUNET_MQ_Envelope *env; |
988 | char *ticket_str; | ||
989 | char *token_str; | ||
990 | 1634 | ||
991 | handle->ns_qe = NULL; | 1635 | for (lu = handle->parallel_lookups_head; |
992 | if (GNUNET_SYSERR == success) | 1636 | NULL != lu;) { |
1637 | GNUNET_GNS_lookup_cancel (lu->lookup_request); | ||
1638 | GNUNET_free (lu->label); | ||
1639 | tmp = lu->next; | ||
1640 | GNUNET_CONTAINER_DLL_remove (handle->parallel_lookups_head, | ||
1641 | handle->parallel_lookups_tail, | ||
1642 | lu); | ||
1643 | GNUNET_free (lu); | ||
1644 | lu = tmp; | ||
1645 | } | ||
1646 | env = GNUNET_MQ_msg (arm, | ||
1647 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT); | ||
1648 | arm->id = htonl (handle->r_id); | ||
1649 | arm->attr_len = htons (0); | ||
1650 | GNUNET_MQ_send (handle->client->mq, env); | ||
1651 | |||
1652 | } | ||
1653 | |||
1654 | |||
1655 | static void | ||
1656 | process_consume_abe_key (void *cls, uint32_t rd_count, | ||
1657 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1658 | { | ||
1659 | struct ConsumeTicketHandle *handle = cls; | ||
1660 | struct GNUNET_HashCode new_key_hash; | ||
1661 | struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; | ||
1662 | struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; | ||
1663 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key; | ||
1664 | struct ParallelLookup *parallel_lookup; | ||
1665 | size_t size; | ||
1666 | char *buf; | ||
1667 | char *scope; | ||
1668 | char *lookup_query; | ||
1669 | |||
1670 | handle->lookup_request = NULL; | ||
1671 | if (1 != rd_count) | ||
993 | { | 1672 | { |
994 | cleanup_issue_handle (handle); | 1673 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
995 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | 1674 | "Number of keys %d != 1.", |
996 | "Unknown Error\n"); | 1675 | rd_count); |
1676 | cleanup_consume_ticket_handle (handle); | ||
997 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | 1677 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); |
998 | return; | 1678 | return; |
999 | } | 1679 | } |
1000 | if (GNUNET_OK != ticket_serialize (handle->ticket, | 1680 | |
1001 | &handle->iss_key, | 1681 | //Decrypt |
1002 | &ticket_str)) | 1682 | ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data; |
1683 | |||
1684 | buf = GNUNET_malloc (rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
1685 | |||
1686 | //Calculate symmetric key from ecdh parameters | ||
1687 | GNUNET_assert (GNUNET_OK == | ||
1688 | GNUNET_CRYPTO_ecdsa_ecdh (&handle->identity, | ||
1689 | ecdh_key, | ||
1690 | &new_key_hash)); | ||
1691 | create_sym_key_from_ecdh (&new_key_hash, | ||
1692 | &enc_key, | ||
1693 | &enc_iv); | ||
1694 | size = GNUNET_CRYPTO_symmetric_decrypt (rd->data + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
1695 | rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey), | ||
1696 | &enc_key, | ||
1697 | &enc_iv, | ||
1698 | buf); | ||
1699 | |||
1700 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1701 | "Decrypted bytes: %zd Expected bytes: %zd\n", | ||
1702 | size, rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
1703 | GNUNET_STATISTICS_update (stats_handle, | ||
1704 | "abe_key_lookup_time_total", | ||
1705 | GNUNET_TIME_absolute_get_duration (handle->lookup_start_time).rel_value_us, | ||
1706 | GNUNET_YES); | ||
1707 | GNUNET_STATISTICS_update (stats_handle, | ||
1708 | "abe_key_lookups_count", | ||
1709 | 1, | ||
1710 | GNUNET_YES); | ||
1711 | scopes = GNUNET_strdup (buf); | ||
1712 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1713 | "Scopes %s\n", scopes); | ||
1714 | handle->key = GNUNET_ABE_cpabe_deserialize_key ((void*)(buf + strlen (scopes) + 1), | ||
1715 | rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) | ||
1716 | - strlen (scopes) - 1); | ||
1717 | |||
1718 | for (scope = strtok (scopes, ","); NULL != scope; scope = strtok (NULL, ",")) | ||
1003 | { | 1719 | { |
1004 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | 1720 | GNUNET_asprintf (&lookup_query, |
1005 | "Error serializing ticket\n"); | 1721 | "%s.gnu", |
1006 | cleanup_issue_handle (handle); | 1722 | scope); |
1007 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | 1723 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1008 | return; | 1724 | "Looking up %s\n", lookup_query); |
1725 | parallel_lookup = GNUNET_new (struct ParallelLookup); | ||
1726 | parallel_lookup->handle = handle; | ||
1727 | parallel_lookup->label = GNUNET_strdup (scope); | ||
1728 | parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get(); | ||
1729 | parallel_lookup->lookup_request | ||
1730 | = GNUNET_GNS_lookup (gns_handle, | ||
1731 | lookup_query, | ||
1732 | &handle->ticket.identity, | ||
1733 | GNUNET_GNSRECORD_TYPE_ID_ATTR, | ||
1734 | GNUNET_GNS_LO_DEFAULT, | ||
1735 | &process_parallel_lookup2, | ||
1736 | parallel_lookup); | ||
1737 | GNUNET_CONTAINER_DLL_insert (handle->parallel_lookups_head, | ||
1738 | handle->parallel_lookups_tail, | ||
1739 | parallel_lookup); | ||
1740 | GNUNET_free (lookup_query); | ||
1009 | } | 1741 | } |
1010 | if (GNUNET_OK != token_to_string (handle->token, | 1742 | GNUNET_free (scopes); |
1011 | &handle->iss_key, | 1743 | GNUNET_free (buf); |
1012 | &token_str)) | 1744 | handle->kill_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3), |
1745 | &abort_parallel_lookups2, | ||
1746 | handle); | ||
1747 | } | ||
1748 | |||
1749 | |||
1750 | static void | ||
1751 | handle_consume_ticket_message (void *cls, | ||
1752 | const struct ConsumeTicketMessage *cm) | ||
1753 | { | ||
1754 | struct ConsumeTicketHandle *ch; | ||
1755 | struct IdpClient *idp = cls; | ||
1756 | char* lookup_query; | ||
1757 | char* rnd_label; | ||
1758 | |||
1759 | ch = GNUNET_new (struct ConsumeTicketHandle); | ||
1760 | ch->r_id = ntohl (cm->id); | ||
1761 | ch->client = idp; | ||
1762 | ch->identity = cm->identity; | ||
1763 | ch->attrs = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
1764 | GNUNET_CRYPTO_ecdsa_key_get_public (&ch->identity, | ||
1765 | &ch->identity_pub); | ||
1766 | ch->ticket = *((struct GNUNET_IDENTITY_PROVIDER_Ticket*)&cm[1]); | ||
1767 | rnd_label = GNUNET_STRINGS_data_to_string_alloc (&ch->ticket.rnd, | ||
1768 | sizeof (uint64_t)); | ||
1769 | GNUNET_asprintf (&lookup_query, | ||
1770 | "%s.gnu", | ||
1771 | rnd_label); | ||
1772 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1773 | "Looking for ABE key under %s\n", lookup_query); | ||
1774 | ch->lookup_start_time = GNUNET_TIME_absolute_get (); | ||
1775 | ch->lookup_request | ||
1776 | = GNUNET_GNS_lookup (gns_handle, | ||
1777 | lookup_query, | ||
1778 | &ch->ticket.identity, | ||
1779 | GNUNET_GNSRECORD_TYPE_ABE_KEY, | ||
1780 | GNUNET_GNS_LO_DEFAULT, | ||
1781 | &process_consume_abe_key, | ||
1782 | ch); | ||
1783 | GNUNET_free (rnd_label); | ||
1784 | GNUNET_free (lookup_query); | ||
1785 | GNUNET_SERVICE_client_continue (idp->client); | ||
1786 | } | ||
1787 | |||
1788 | static void | ||
1789 | cleanup_as_handle (struct AttributeStoreHandle *handle) | ||
1790 | { | ||
1791 | if (NULL != handle->claim) | ||
1792 | GNUNET_free (handle->claim); | ||
1793 | if (NULL != handle->abe_key) | ||
1794 | GNUNET_ABE_cpabe_delete_master_key (handle->abe_key); | ||
1795 | GNUNET_free (handle); | ||
1796 | } | ||
1797 | |||
1798 | static void | ||
1799 | attr_store_cont (void *cls, | ||
1800 | int32_t success, | ||
1801 | const char *emsg) | ||
1802 | { | ||
1803 | struct AttributeStoreHandle *as_handle = cls; | ||
1804 | struct GNUNET_MQ_Envelope *env; | ||
1805 | struct AttributeStoreResultMessage *acr_msg; | ||
1806 | |||
1807 | if (GNUNET_SYSERR == success) | ||
1013 | { | 1808 | { |
1014 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", | 1809 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1015 | "Error serializing token\n"); | 1810 | "Failed to store attribute %s\n", |
1016 | GNUNET_free (ticket_str); | 1811 | emsg); |
1017 | cleanup_issue_handle (handle); | 1812 | cleanup_as_handle (as_handle); |
1018 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | 1813 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); |
1019 | return; | 1814 | return; |
1020 | } | 1815 | } |
1021 | env = create_issue_result_message (handle->label, | 1816 | |
1022 | ticket_str, | 1817 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1023 | token_str, | 1818 | "Sending ATTRIBUTE_STORE_RESPONSE message\n"); |
1024 | handle->r_id); | 1819 | env = GNUNET_MQ_msg (acr_msg, |
1025 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(handle->client), | 1820 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE); |
1821 | acr_msg->id = htonl (as_handle->r_id); | ||
1822 | acr_msg->op_result = htonl (GNUNET_OK); | ||
1823 | GNUNET_MQ_send (as_handle->client->mq, | ||
1026 | env); | 1824 | env); |
1027 | cleanup_issue_handle (handle); | 1825 | cleanup_as_handle (as_handle); |
1028 | GNUNET_free (ticket_str); | ||
1029 | GNUNET_free (token_str); | ||
1030 | } | 1826 | } |
1031 | 1827 | ||
1032 | |||
1033 | /** | ||
1034 | * Build a token and store it | ||
1035 | * | ||
1036 | * @param cls the IssueHandle | ||
1037 | */ | ||
1038 | static void | 1828 | static void |
1039 | sign_and_return_token (void *cls) | 1829 | attr_store_task (void *cls) |
1040 | { | 1830 | { |
1041 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | 1831 | struct AttributeStoreHandle *as_handle = cls; |
1042 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; | 1832 | struct GNUNET_GNSRECORD_Data rd[1]; |
1043 | struct IssueHandle *handle = cls; | 1833 | char* buf; |
1044 | struct GNUNET_GNSRECORD_Data token_record[2]; | 1834 | char* policy; |
1045 | char *nonce_str; | 1835 | char* enc_buf; |
1046 | char *enc_token_str; | 1836 | char* rd_buf; |
1047 | char *token_metadata; | 1837 | size_t enc_size; |
1048 | char* write_ptr; | 1838 | size_t buf_size; |
1049 | uint64_t time; | 1839 | uint32_t attr_ver; |
1050 | uint64_t exp_time; | 1840 | |
1051 | size_t token_metadata_len; | 1841 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1052 | 1842 | "Storing attribute\n"); | |
1053 | //Remote nonce | 1843 | buf_size = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (as_handle->claim); |
1054 | nonce_str = NULL; | 1844 | buf = GNUNET_malloc (buf_size); |
1055 | GNUNET_asprintf (&nonce_str, "%lu", handle->nonce); | 1845 | |
1056 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Request nonce: %s\n", nonce_str); | 1846 | GNUNET_IDENTITY_ATTRIBUTE_serialize (as_handle->claim, |
1057 | 1847 | buf); | |
1058 | GNUNET_CRYPTO_ecdsa_key_get_public (&handle->iss_key, | 1848 | |
1059 | &pub_key); | 1849 | GNUNET_asprintf (&policy, |
1060 | handle->ticket = ticket_create (handle->nonce, | 1850 | "%s_%lu", |
1061 | &pub_key, | 1851 | as_handle->claim->name, |
1062 | handle->label, | 1852 | as_handle->claim->version); |
1063 | &handle->aud_key); | 1853 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1064 | 1854 | "Encrypting with policy %s\n", policy); | |
1065 | time = GNUNET_TIME_absolute_get().abs_value_us; | 1855 | /** |
1066 | exp_time = time + token_expiration_interval.rel_value_us; | 1856 | * Encrypt the attribute value and store in namestore |
1067 | 1857 | */ | |
1068 | token_add_attr_int (handle->token, "nbf", time); | 1858 | enc_size = GNUNET_ABE_cpabe_encrypt (buf, |
1069 | token_add_attr_int (handle->token, "iat", time); | 1859 | buf_size, |
1070 | token_add_attr_int (handle->token, "exp", exp_time); | 1860 | policy, //Policy |
1071 | token_add_attr (handle->token, "nonce", nonce_str); | 1861 | as_handle->abe_key, |
1072 | 1862 | (void**)&enc_buf); | |
1073 | //Token in a serialized encrypted format | 1863 | GNUNET_free (buf); |
1074 | GNUNET_assert (token_serialize (handle->token, | 1864 | GNUNET_free (policy); |
1075 | &handle->iss_key, | 1865 | rd[0].data_size = enc_size + sizeof (uint32_t); |
1076 | &ecdhe_privkey, | 1866 | rd_buf = GNUNET_malloc (rd[0].data_size); |
1077 | &enc_token_str)); | 1867 | attr_ver = htonl (as_handle->claim->version); |
1078 | 1868 | GNUNET_memcpy (rd_buf, | |
1079 | //Token record E,E_K (Token) | 1869 | &attr_ver, |
1080 | token_record[0].data = enc_token_str; | 1870 | sizeof (uint32_t)); |
1081 | token_record[0].data_size = strlen (enc_token_str) + 1; | 1871 | GNUNET_memcpy (rd_buf+sizeof (uint32_t), |
1082 | token_record[0].expiration_time = exp_time; | 1872 | enc_buf, |
1083 | token_record[0].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN; | 1873 | enc_size); |
1084 | token_record[0].flags = GNUNET_GNSRECORD_RF_NONE; | 1874 | rd[0].data = rd_buf; |
1085 | 1875 | rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR; | |
1086 | 1876 | rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | |
1087 | token_metadata_len = sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey) | 1877 | rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane? |
1088 | + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) | 1878 | as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, |
1089 | + strlen (handle->scopes) + 1; //With 0-Terminator | 1879 | &as_handle->identity, |
1090 | token_metadata = GNUNET_malloc (token_metadata_len); | 1880 | as_handle->claim->name, |
1091 | write_ptr = token_metadata; | 1881 | 1, |
1092 | GNUNET_memcpy (token_metadata, ecdhe_privkey, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); | 1882 | rd, |
1093 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey); | 1883 | &attr_store_cont, |
1094 | GNUNET_memcpy (write_ptr, &handle->aud_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | 1884 | as_handle); |
1095 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | 1885 | GNUNET_free (enc_buf); |
1096 | GNUNET_memcpy (write_ptr, handle->scopes, strlen (handle->scopes) + 1); //with 0-Terminator; | 1886 | GNUNET_free (rd_buf); |
1097 | |||
1098 | token_record[1].data = token_metadata; | ||
1099 | token_record[1].data_size = token_metadata_len; | ||
1100 | token_record[1].expiration_time = exp_time; | ||
1101 | token_record[1].record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA; | ||
1102 | token_record[1].flags = GNUNET_GNSRECORD_RF_PRIVATE; | ||
1103 | |||
1104 | //Persist token | ||
1105 | handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle, | ||
1106 | &handle->iss_key, | ||
1107 | handle->label, | ||
1108 | 2, | ||
1109 | token_record, | ||
1110 | &store_token_issue_cont, | ||
1111 | handle); | ||
1112 | GNUNET_free (ecdhe_privkey); | ||
1113 | GNUNET_free (nonce_str); | ||
1114 | GNUNET_free (enc_token_str); | ||
1115 | GNUNET_free (token_metadata); | ||
1116 | } | 1887 | } |
1117 | 1888 | ||
1118 | 1889 | ||
1119 | static void | 1890 | static void |
1120 | attr_collect_error (void *cls) | 1891 | store_after_abe_bootstrap (void *cls, |
1892 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
1121 | { | 1893 | { |
1122 | struct IssueHandle *handle = cls; | 1894 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1895 | "Finished ABE bootstrap\n"); | ||
1896 | struct AttributeStoreHandle *ash = cls; | ||
1897 | ash->abe_key = abe_key; | ||
1898 | GNUNET_SCHEDULER_add_now (&attr_store_task, ash); | ||
1899 | } | ||
1123 | 1900 | ||
1124 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute Error!\n"); | 1901 | static int |
1125 | handle->ns_it = NULL; | 1902 | check_attribute_store_message(void *cls, |
1126 | GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); | 1903 | const struct AttributeStoreMessage *sam) |
1904 | { | ||
1905 | uint16_t size; | ||
1906 | |||
1907 | size = ntohs (sam->header.size); | ||
1908 | if (size <= sizeof (struct AttributeStoreMessage)) | ||
1909 | { | ||
1910 | GNUNET_break (0); | ||
1911 | return GNUNET_SYSERR; | ||
1912 | } | ||
1913 | return GNUNET_OK; | ||
1127 | } | 1914 | } |
1128 | 1915 | ||
1129 | 1916 | ||
1130 | static void | 1917 | static void |
1131 | attr_collect_finished (void *cls) | 1918 | handle_attribute_store_message (void *cls, |
1919 | const struct AttributeStoreMessage *sam) | ||
1132 | { | 1920 | { |
1133 | struct IssueHandle *handle = cls; | 1921 | struct AttributeStoreHandle *as_handle; |
1922 | struct IdpClient *idp = cls; | ||
1923 | size_t data_len; | ||
1924 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1925 | "Received ATTRIBUTE_STORE message\n"); | ||
1926 | |||
1927 | data_len = ntohs (sam->attr_len); | ||
1928 | |||
1929 | as_handle = GNUNET_new (struct AttributeStoreHandle); | ||
1930 | as_handle->claim = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&sam[1], | ||
1931 | data_len); | ||
1932 | |||
1933 | as_handle->r_id = ntohl (sam->id); | ||
1934 | as_handle->identity = sam->identity; | ||
1935 | GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, | ||
1936 | &as_handle->identity_pkey); | ||
1134 | 1937 | ||
1135 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute END: \n"); | 1938 | GNUNET_SERVICE_client_continue (idp->client); |
1136 | handle->ns_it = NULL; | 1939 | as_handle->client = idp; |
1137 | GNUNET_SCHEDULER_add_now (&sign_and_return_token, handle); | 1940 | bootstrap_abe (&as_handle->identity, &store_after_abe_bootstrap, as_handle, GNUNET_NO); |
1138 | } | 1941 | } |
1139 | 1942 | ||
1943 | static void | ||
1944 | cleanup_iter_handle (struct AttributeIterator *ai) | ||
1945 | { | ||
1946 | if (NULL != ai->abe_key) | ||
1947 | GNUNET_ABE_cpabe_delete_master_key (ai->abe_key); | ||
1948 | GNUNET_CONTAINER_DLL_remove (ai->client->op_head, | ||
1949 | ai->client->op_tail, | ||
1950 | ai); | ||
1951 | GNUNET_free (ai); | ||
1952 | } | ||
1953 | |||
1954 | static void | ||
1955 | attr_iter_error (void *cls) | ||
1956 | { | ||
1957 | struct AttributeIterator *ai = cls; | ||
1958 | //TODO | ||
1959 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1960 | "Failed to iterate over attributes\n"); | ||
1961 | cleanup_iter_handle (ai); | ||
1962 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1963 | } | ||
1964 | |||
1965 | static void | ||
1966 | attr_iter_finished (void *cls) | ||
1967 | { | ||
1968 | struct AttributeIterator *ai = cls; | ||
1969 | struct GNUNET_MQ_Envelope *env; | ||
1970 | struct AttributeResultMessage *arm; | ||
1971 | |||
1972 | env = GNUNET_MQ_msg (arm, | ||
1973 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT); | ||
1974 | arm->id = htonl (ai->request_id); | ||
1975 | arm->attr_len = htons (0); | ||
1976 | GNUNET_MQ_send (ai->client->mq, env); | ||
1977 | cleanup_iter_handle (ai); | ||
1978 | } | ||
1140 | 1979 | ||
1141 | /** | ||
1142 | * Collect attributes for token | ||
1143 | */ | ||
1144 | static void | 1980 | static void |
1145 | attr_collect (void *cls, | 1981 | attr_iter_cb (void *cls, |
1146 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 1982 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, |
1147 | const char *label, | 1983 | const char *label, |
1148 | unsigned int rd_count, | 1984 | unsigned int rd_count, |
1149 | const struct GNUNET_GNSRECORD_Data *rd) | 1985 | const struct GNUNET_GNSRECORD_Data *rd) |
1150 | { | 1986 | { |
1151 | struct IssueHandle *handle = cls; | 1987 | struct AttributeIterator *ai = cls; |
1152 | int i; | 1988 | struct AttributeResultMessage *arm; |
1153 | char* data; | 1989 | struct GNUNET_ABE_AbeKey *key; |
1154 | struct GNUNET_HashCode key; | 1990 | struct GNUNET_MQ_Envelope *env; |
1155 | 1991 | ssize_t msg_extra_len; | |
1156 | GNUNET_CRYPTO_hash (label, | 1992 | char* attr_ser; |
1157 | strlen (label), | 1993 | char* attrs[2]; |
1158 | &key); | 1994 | char* data_tmp; |
1159 | 1995 | char* policy; | |
1160 | if (0 == rd_count || | 1996 | uint32_t attr_ver; |
1161 | ( (NULL != handle->attr_map) && | 1997 | |
1162 | (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map, | 1998 | if (rd_count != 1) |
1163 | &key)) | ||
1164 | ) | ||
1165 | ) | ||
1166 | { | 1999 | { |
1167 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | 2000 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it); |
1168 | return; | 2001 | return; |
1169 | } | 2002 | } |
1170 | 2003 | ||
1171 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", label); | 2004 | if (GNUNET_GNSRECORD_TYPE_ID_ATTR != rd->record_type) { |
1172 | 2005 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it); | |
1173 | if (1 == rd_count) | ||
1174 | { | ||
1175 | if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) | ||
1176 | { | ||
1177 | data = GNUNET_GNSRECORD_value_to_string (rd->record_type, | ||
1178 | rd->data, | ||
1179 | rd->data_size); | ||
1180 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data); | ||
1181 | token_add_attr (handle->token, | ||
1182 | label, | ||
1183 | data); | ||
1184 | GNUNET_free (data); | ||
1185 | } | ||
1186 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | ||
1187 | return; | 2006 | return; |
1188 | } | 2007 | } |
2008 | attr_ver = ntohl(*((uint32_t*)rd->data)); | ||
2009 | GNUNET_asprintf (&policy, "%s_%lu", | ||
2010 | label, attr_ver); | ||
2011 | attrs[0] = policy; | ||
2012 | attrs[1] = 0; | ||
2013 | key = GNUNET_ABE_cpabe_create_key (ai->abe_key, | ||
2014 | attrs); | ||
2015 | msg_extra_len = GNUNET_ABE_cpabe_decrypt (rd->data+sizeof (uint32_t), | ||
2016 | rd->data_size-sizeof (uint32_t), | ||
2017 | key, | ||
2018 | (void**)&attr_ser); | ||
2019 | |||
2020 | GNUNET_ABE_cpabe_delete_key (key, | ||
2021 | GNUNET_YES); | ||
2022 | //GNUNET_free (policy); | ||
2023 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2024 | "Found attribute: %s\n", label); | ||
2025 | env = GNUNET_MQ_msg_extra (arm, | ||
2026 | msg_extra_len, | ||
2027 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT); | ||
2028 | arm->id = htonl (ai->request_id); | ||
2029 | arm->attr_len = htons (msg_extra_len); | ||
2030 | GNUNET_CRYPTO_ecdsa_key_get_public (zone, | ||
2031 | &arm->identity); | ||
2032 | data_tmp = (char *) &arm[1]; | ||
2033 | GNUNET_memcpy (data_tmp, | ||
2034 | attr_ser, | ||
2035 | msg_extra_len); | ||
2036 | GNUNET_MQ_send (ai->client->mq, env); | ||
2037 | GNUNET_free (attr_ser); | ||
2038 | GNUNET_ABE_cpabe_delete_master_key (ai->abe_key); | ||
2039 | ai->abe_key = NULL; | ||
2040 | } | ||
1189 | 2041 | ||
1190 | i = 0; | ||
1191 | for (; i < rd_count; i++) | ||
1192 | { | ||
1193 | if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) | ||
1194 | { | ||
1195 | data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, | ||
1196 | rd[i].data, | ||
1197 | rd[i].data_size); | ||
1198 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding value: %s\n", data); | ||
1199 | token_add_attr (handle->token, label, data); | ||
1200 | GNUNET_free (data); | ||
1201 | } | ||
1202 | } | ||
1203 | 2042 | ||
1204 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | 2043 | void |
2044 | iterate_after_abe_bootstrap (void *cls, | ||
2045 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
2046 | { | ||
2047 | struct AttributeIterator *ai = cls; | ||
2048 | ai->abe_key = abe_key; | ||
2049 | ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | ||
2050 | &ai->identity, | ||
2051 | &attr_iter_error, | ||
2052 | ai, | ||
2053 | &attr_iter_cb, | ||
2054 | ai, | ||
2055 | &attr_iter_finished, | ||
2056 | ai); | ||
1205 | } | 2057 | } |
1206 | 2058 | ||
2059 | void | ||
2060 | iterate_next_after_abe_bootstrap (void *cls, | ||
2061 | struct GNUNET_ABE_AbeMasterKey *abe_key) | ||
2062 | { | ||
2063 | struct AttributeIterator *ai = cls; | ||
2064 | ai->abe_key = abe_key; | ||
2065 | GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it); | ||
2066 | } | ||
2067 | |||
2068 | |||
2069 | |||
1207 | static void | 2070 | static void |
1208 | cleanup_exchange_handle (struct ExchangeHandle *handle) | 2071 | handle_iteration_start (void *cls, |
2072 | const struct AttributeIterationStartMessage *ais_msg) | ||
1209 | { | 2073 | { |
1210 | if (NULL != handle->ticket) | 2074 | struct IdpClient *idp = cls; |
1211 | ticket_destroy (handle->ticket); | 2075 | struct AttributeIterator *ai; |
1212 | if (NULL != handle->token) | 2076 | |
1213 | token_destroy (handle->token); | 2077 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1214 | GNUNET_free (handle); | 2078 | "Received ATTRIBUTE_ITERATION_START message\n"); |
2079 | ai = GNUNET_new (struct AttributeIterator); | ||
2080 | ai->request_id = ntohl (ais_msg->id); | ||
2081 | ai->client = idp; | ||
2082 | ai->identity = ais_msg->identity; | ||
2083 | |||
2084 | GNUNET_CONTAINER_DLL_insert (idp->op_head, | ||
2085 | idp->op_tail, | ||
2086 | ai); | ||
2087 | bootstrap_abe (&ai->identity, &iterate_after_abe_bootstrap, ai, GNUNET_NO); | ||
2088 | GNUNET_SERVICE_client_continue (idp->client); | ||
1215 | } | 2089 | } |
1216 | 2090 | ||
2091 | |||
1217 | static void | 2092 | static void |
1218 | process_lookup_result (void *cls, uint32_t rd_count, | 2093 | handle_iteration_stop (void *cls, |
1219 | const struct GNUNET_GNSRECORD_Data *rd) | 2094 | const struct AttributeIterationStopMessage *ais_msg) |
1220 | { | 2095 | { |
1221 | struct ExchangeHandle *handle = cls; | 2096 | struct IdpClient *idp = cls; |
1222 | struct GNUNET_MQ_Envelope *env; | 2097 | struct AttributeIterator *ai; |
1223 | char* token_str; | 2098 | uint32_t rid; |
1224 | char* record_str; | ||
1225 | 2099 | ||
1226 | handle->lookup_request = NULL; | 2100 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1227 | if (2 != rd_count) | 2101 | "Received `%s' message\n", |
2102 | "ATTRIBUTE_ITERATION_STOP"); | ||
2103 | rid = ntohl (ais_msg->id); | ||
2104 | for (ai = idp->op_head; NULL != ai; ai = ai->next) | ||
2105 | if (ai->request_id == rid) | ||
2106 | break; | ||
2107 | if (NULL == ai) | ||
1228 | { | 2108 | { |
1229 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2109 | GNUNET_break (0); |
1230 | "Number of tokens %d != 2.", | 2110 | GNUNET_SERVICE_client_drop (idp->client); |
1231 | rd_count); | ||
1232 | cleanup_exchange_handle (handle); | ||
1233 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | ||
1234 | return; | 2111 | return; |
1235 | } | 2112 | } |
1236 | 2113 | GNUNET_CONTAINER_DLL_remove (idp->op_head, | |
1237 | record_str = | 2114 | idp->op_tail, |
1238 | GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN, | 2115 | ai); |
1239 | rd->data, | 2116 | GNUNET_free (ai); |
1240 | rd->data_size); | 2117 | GNUNET_SERVICE_client_continue (idp->client); |
1241 | |||
1242 | //Decrypt and parse | ||
1243 | GNUNET_assert (GNUNET_OK == token_parse (record_str, | ||
1244 | &handle->aud_privkey, | ||
1245 | &handle->token)); | ||
1246 | |||
1247 | //Readable | ||
1248 | GNUNET_assert (GNUNET_OK == token_to_string (handle->token, | ||
1249 | &handle->aud_privkey, | ||
1250 | &token_str)); | ||
1251 | |||
1252 | env = create_exchange_result_message (token_str, | ||
1253 | handle->label, | ||
1254 | handle->ticket->payload->nonce, | ||
1255 | handle->r_id); | ||
1256 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(handle->client), | ||
1257 | env); | ||
1258 | cleanup_exchange_handle (handle); | ||
1259 | GNUNET_free (record_str); | ||
1260 | GNUNET_free (token_str); | ||
1261 | } | 2118 | } |
1262 | 2119 | ||
1263 | /** | 2120 | |
1264 | * Checks a exchange message | 2121 | static void |
1265 | * | 2122 | handle_iteration_next (void *cls, |
1266 | * @param cls client sending the message | 2123 | const struct AttributeIterationNextMessage *ais_msg) |
1267 | * @param xm message of type `struct ExchangeMessage` | ||
1268 | * @return #GNUNET_OK if @a xm is well-formed | ||
1269 | */ | ||
1270 | static int | ||
1271 | check_exchange_message (void *cls, | ||
1272 | const struct ExchangeMessage *xm) | ||
1273 | { | 2124 | { |
1274 | uint16_t size; | 2125 | struct IdpClient *idp = cls; |
2126 | struct AttributeIterator *ai; | ||
2127 | uint32_t rid; | ||
1275 | 2128 | ||
1276 | size = ntohs (xm->header.size); | 2129 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1277 | if (size <= sizeof (struct ExchangeMessage)) | 2130 | "Received ATTRIBUTE_ITERATION_NEXT message\n"); |
2131 | rid = ntohl (ais_msg->id); | ||
2132 | for (ai = idp->op_head; NULL != ai; ai = ai->next) | ||
2133 | if (ai->request_id == rid) | ||
2134 | break; | ||
2135 | if (NULL == ai) | ||
1278 | { | 2136 | { |
1279 | GNUNET_break (0); | 2137 | GNUNET_break (0); |
1280 | return GNUNET_SYSERR; | 2138 | GNUNET_SERVICE_client_drop (idp->client); |
2139 | return; | ||
1281 | } | 2140 | } |
1282 | return GNUNET_OK; | 2141 | bootstrap_abe (&ai->identity, |
2142 | &iterate_next_after_abe_bootstrap, | ||
2143 | ai, | ||
2144 | GNUNET_NO); | ||
2145 | GNUNET_SERVICE_client_continue (idp->client); | ||
1283 | } | 2146 | } |
1284 | 2147 | ||
1285 | /** | 2148 | /** |
1286 | * | 2149 | * Ticket iteration processor result |
1287 | * Handler for exchange message | ||
1288 | * | ||
1289 | * @param cls unused | ||
1290 | * @param client who sent the message | ||
1291 | * @param message the message | ||
1292 | */ | 2150 | */ |
1293 | static void | 2151 | enum ZoneIterationResult |
1294 | handle_exchange_message (void *cls, | ||
1295 | const struct ExchangeMessage *xm) | ||
1296 | { | 2152 | { |
1297 | struct ExchangeHandle *xchange_handle; | 2153 | /** |
1298 | struct GNUNET_SERVICE_Client *client = cls; | 2154 | * Iteration start. |
1299 | const char *ticket; | 2155 | */ |
1300 | char *lookup_query; | 2156 | IT_START = 0, |
1301 | 2157 | ||
1302 | ticket = (const char *) &xm[1]; | 2158 | /** |
1303 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2159 | * Found tickets, |
1304 | "Received EXCHANGE of `%s' from client\n", | 2160 | * Continue to iterate with next iteration_next call |
1305 | ticket); | 2161 | */ |
1306 | xchange_handle = GNUNET_malloc (sizeof (struct ExchangeHandle)); | 2162 | IT_SUCCESS_MORE_AVAILABLE = 1, |
1307 | xchange_handle->aud_privkey = xm->aud_privkey; | ||
1308 | xchange_handle->r_id = xm->id; | ||
1309 | if (GNUNET_SYSERR == ticket_parse (ticket, | ||
1310 | &xchange_handle->aud_privkey, | ||
1311 | &xchange_handle->ticket)) | ||
1312 | { | ||
1313 | GNUNET_free (xchange_handle); | ||
1314 | GNUNET_SERVICE_client_drop (client); | ||
1315 | return; | ||
1316 | } | ||
1317 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for token under %s\n", | ||
1318 | xchange_handle->ticket->payload->label); | ||
1319 | GNUNET_asprintf (&lookup_query, | ||
1320 | "%s.gnu", | ||
1321 | xchange_handle->ticket->payload->label); | ||
1322 | GNUNET_SERVICE_client_continue (client); | ||
1323 | xchange_handle->client = client; | ||
1324 | xchange_handle->lookup_request | ||
1325 | = GNUNET_GNS_lookup (gns_handle, | ||
1326 | lookup_query, | ||
1327 | &xchange_handle->ticket->payload->identity_key, | ||
1328 | GNUNET_GNSRECORD_TYPE_ID_TOKEN, | ||
1329 | GNUNET_GNS_LO_LOCAL_MASTER, | ||
1330 | &process_lookup_result, | ||
1331 | xchange_handle); | ||
1332 | GNUNET_free (lookup_query); | ||
1333 | 2163 | ||
1334 | } | 2164 | /** |
2165 | * Iteration complete | ||
2166 | */ | ||
2167 | IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2 | ||
2168 | }; | ||
1335 | 2169 | ||
1336 | 2170 | ||
1337 | static void | 2171 | /** |
1338 | find_existing_token_error (void *cls) | 2172 | * Context for ticket iteration |
2173 | */ | ||
2174 | struct TicketIterationProcResult | ||
1339 | { | 2175 | { |
1340 | struct IssueHandle *handle = cls; | 2176 | /** |
1341 | cleanup_issue_handle (handle); | 2177 | * The ticket iteration handle |
1342 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error looking for existing token\n"); | 2178 | */ |
1343 | GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); | 2179 | struct TicketIteration *ti; |
1344 | } | ||
1345 | 2180 | ||
2181 | /** | ||
2182 | * Iteration result: iteration done? | ||
2183 | * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but | ||
2184 | * we got one for now and have sent it to the client | ||
2185 | * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results, | ||
2186 | * #IT_START: if we are still trying to find a result. | ||
2187 | */ | ||
2188 | int res_iteration_finished; | ||
2189 | |||
2190 | }; | ||
1346 | 2191 | ||
1347 | static void | 2192 | static void |
1348 | find_existing_token_finished (void *cls) | 2193 | cleanup_ticket_iter_handle (struct TicketIteration *ti) |
1349 | { | 2194 | { |
1350 | struct IssueHandle *handle = cls; | 2195 | GNUNET_free (ti); |
1351 | uint64_t rnd_key; | ||
1352 | |||
1353 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1354 | ">>> No existing token found\n"); | ||
1355 | rnd_key = | ||
1356 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, | ||
1357 | UINT64_MAX); | ||
1358 | GNUNET_STRINGS_base64_encode ((char*)&rnd_key, | ||
1359 | sizeof (uint64_t), | ||
1360 | &handle->label); | ||
1361 | handle->ns_it = NULL; | ||
1362 | handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | ||
1363 | &handle->iss_key, | ||
1364 | &attr_collect_error, | ||
1365 | handle, | ||
1366 | &attr_collect, | ||
1367 | handle, | ||
1368 | &attr_collect_finished, | ||
1369 | handle); | ||
1370 | } | 2196 | } |
1371 | 2197 | ||
1372 | |||
1373 | /** | 2198 | /** |
2199 | * Process ticket from database | ||
1374 | * | 2200 | * |
1375 | * Look for existing token | 2201 | * @param cls struct TicketIterationProcResult |
1376 | * | 2202 | * @param ticket the ticket |
1377 | * @param cls the identity entry | 2203 | * @param attrs the attributes |
1378 | * @param zone the identity | ||
1379 | * @param lbl the name of the record | ||
1380 | * @param rd_count number of records | ||
1381 | * @param rd record data | ||
1382 | * | ||
1383 | */ | 2204 | */ |
1384 | static void | 2205 | static void |
1385 | find_existing_token (void *cls, | 2206 | ticket_iterate_proc (void *cls, |
1386 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 2207 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, |
1387 | const char *lbl, | 2208 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) |
1388 | unsigned int rd_count, | 2209 | { |
1389 | const struct GNUNET_GNSRECORD_Data *rd) | 2210 | struct TicketIterationProcResult *proc = cls; |
1390 | { | ||
1391 | struct IssueHandle *handle = cls; | ||
1392 | const struct GNUNET_GNSRECORD_Data *token_metadata_record; | ||
1393 | struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key; | ||
1394 | struct GNUNET_HashCode key; | ||
1395 | int scope_count_token; | ||
1396 | char *scope; | ||
1397 | char *tmp_scopes; | ||
1398 | 2211 | ||
1399 | //There should be only a single record for a token under a label | 2212 | if (NULL == ticket) |
1400 | if (2 != rd_count) | ||
1401 | { | 2213 | { |
1402 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | 2214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2215 | "Iteration done\n"); | ||
2216 | proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE; | ||
1403 | return; | 2217 | return; |
1404 | } | 2218 | } |
2219 | proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE; | ||
2220 | send_ticket_result (proc->ti->client, | ||
2221 | proc->ti->r_id, | ||
2222 | ticket, | ||
2223 | attrs); | ||
1405 | 2224 | ||
1406 | if (rd[0].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA) | 2225 | } |
1407 | { | ||
1408 | token_metadata_record = &rd[0]; | ||
1409 | } | ||
1410 | else | ||
1411 | { | ||
1412 | token_metadata_record = &rd[1]; | ||
1413 | } | ||
1414 | if (token_metadata_record->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA) | ||
1415 | { | ||
1416 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | ||
1417 | return; | ||
1418 | } | ||
1419 | ecdhe_privkey = *((struct GNUNET_CRYPTO_EcdhePrivateKey *)token_metadata_record->data); | ||
1420 | aud_key = | ||
1421 | (struct GNUNET_CRYPTO_EcdsaPublicKey *)(token_metadata_record->data+sizeof(struct GNUNET_CRYPTO_EcdhePrivateKey)); | ||
1422 | tmp_scopes = GNUNET_strdup ((char*) aud_key+sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
1423 | 2226 | ||
1424 | if (0 != memcmp (aud_key, &handle->aud_key, | 2227 | /** |
1425 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | 2228 | * Perform ticket iteration step |
1426 | { | 2229 | * |
1427 | char *tmp2 = GNUNET_STRINGS_data_to_string_alloc (aud_key, | 2230 | * @param ti ticket iterator to process |
1428 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | 2231 | */ |
1429 | //Audience does not match! | 2232 | static void |
1430 | char *tmp = GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA, | 2233 | run_ticket_iteration_round (struct TicketIteration *ti) |
1431 | token_metadata_record->data, | 2234 | { |
1432 | token_metadata_record->data_size); | 2235 | struct TicketIterationProcResult proc; |
1433 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2236 | struct GNUNET_MQ_Envelope *env; |
1434 | "Token does not match audience %s vs %s. Moving on\n", | 2237 | struct TicketResultMessage *trm; |
1435 | tmp2, | 2238 | int ret; |
1436 | tmp); | ||
1437 | GNUNET_free (tmp_scopes); | ||
1438 | GNUNET_free (tmp2); | ||
1439 | GNUNET_free (tmp); | ||
1440 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | ||
1441 | return; | ||
1442 | } | ||
1443 | 2239 | ||
1444 | scope = strtok (tmp_scopes, ","); | 2240 | memset (&proc, 0, sizeof (proc)); |
1445 | scope_count_token = 0; | 2241 | proc.ti = ti; |
1446 | while (NULL != scope) | 2242 | proc.res_iteration_finished = IT_START; |
2243 | while (IT_START == proc.res_iteration_finished) | ||
1447 | { | 2244 | { |
1448 | GNUNET_CRYPTO_hash (scope, | 2245 | if (GNUNET_SYSERR == |
1449 | strlen (scope), | 2246 | (ret = TKT_database->iterate_tickets (TKT_database->cls, |
1450 | &key); | 2247 | &ti->identity, |
1451 | 2248 | ti->is_audience, | |
1452 | if ((NULL != handle->attr_map) && | 2249 | ti->offset, |
1453 | (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->attr_map, &key))) | 2250 | &ticket_iterate_proc, |
2251 | &proc))) | ||
1454 | { | 2252 | { |
1455 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2253 | GNUNET_break (0); |
1456 | "Issued token does not include `%s'. Moving on\n", scope); | 2254 | break; |
1457 | GNUNET_free (tmp_scopes); | ||
1458 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | ||
1459 | return; | ||
1460 | } | 2255 | } |
1461 | scope_count_token++; | 2256 | if (GNUNET_NO == ret) |
1462 | scope = strtok (NULL, ","); | 2257 | proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE; |
2258 | ti->offset++; | ||
1463 | } | 2259 | } |
1464 | GNUNET_free (tmp_scopes); | 2260 | if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished) |
1465 | //All scopes in token are also in request. Now | ||
1466 | //Check length | ||
1467 | if ((NULL != handle->attr_map) && | ||
1468 | (GNUNET_CONTAINER_multihashmap_size (handle->attr_map) == scope_count_token)) | ||
1469 | { | 2261 | { |
1470 | //We have an existing token | 2262 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1471 | handle->label = GNUNET_strdup (lbl); | 2263 | "More results available\n"); |
1472 | handle->ns_it = NULL; | 2264 | return; /* more later */ |
1473 | handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | ||
1474 | &handle->iss_key, | ||
1475 | &attr_collect_error, | ||
1476 | handle, | ||
1477 | &attr_collect, | ||
1478 | handle, | ||
1479 | &attr_collect_finished, | ||
1480 | handle); | ||
1481 | |||
1482 | return; | ||
1483 | } | 2265 | } |
1484 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 2266 | /* send empty response to indicate end of list */ |
1485 | "Nuber of attributes in token do not match request\n"); | 2267 | env = GNUNET_MQ_msg (trm, |
1486 | //No luck | 2268 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT); |
1487 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | 2269 | trm->id = htonl (ti->r_id); |
2270 | GNUNET_MQ_send (ti->client->mq, | ||
2271 | env); | ||
2272 | GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head, | ||
2273 | ti->client->ticket_iter_tail, | ||
2274 | ti); | ||
2275 | cleanup_ticket_iter_handle (ti); | ||
1488 | } | 2276 | } |
1489 | 2277 | ||
1490 | /** | 2278 | static void |
1491 | * Checks an issue message | 2279 | handle_ticket_iteration_start (void *cls, |
1492 | * | 2280 | const struct TicketIterationStartMessage *tis_msg) |
1493 | * @param cls client sending the message | ||
1494 | * @param im message of type `struct IssueMessage` | ||
1495 | * @return #GNUNET_OK if @a im is well-formed | ||
1496 | */ | ||
1497 | static int | ||
1498 | check_issue_message(void *cls, | ||
1499 | const struct IssueMessage *im) | ||
1500 | { | 2281 | { |
1501 | uint16_t size; | 2282 | struct IdpClient *client = cls; |
2283 | struct TicketIteration *ti; | ||
1502 | 2284 | ||
1503 | size = ntohs (im->header.size); | 2285 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1504 | if (size <= sizeof (struct IssueMessage)) | 2286 | "Received TICKET_ITERATION_START message\n"); |
1505 | { | 2287 | ti = GNUNET_new (struct TicketIteration); |
1506 | GNUNET_break (0); | 2288 | ti->r_id = ntohl (tis_msg->id); |
1507 | return GNUNET_SYSERR; | 2289 | ti->offset = 0; |
1508 | } | 2290 | ti->client = client; |
1509 | scopes = (char *) &im[1]; | 2291 | ti->identity = tis_msg->identity; |
1510 | if ('\0' != scopes[size - sizeof (struct IssueMessage) - 1]) | 2292 | ti->is_audience = ntohl (tis_msg->is_audience); |
2293 | |||
2294 | GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head, | ||
2295 | client->ticket_iter_tail, | ||
2296 | ti); | ||
2297 | run_ticket_iteration_round (ti); | ||
2298 | GNUNET_SERVICE_client_continue (client->client); | ||
2299 | } | ||
2300 | |||
2301 | |||
2302 | static void | ||
2303 | handle_ticket_iteration_stop (void *cls, | ||
2304 | const struct TicketIterationStopMessage *tis_msg) | ||
2305 | { | ||
2306 | struct IdpClient *client = cls; | ||
2307 | struct TicketIteration *ti; | ||
2308 | uint32_t rid; | ||
2309 | |||
2310 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2311 | "Received `%s' message\n", | ||
2312 | "TICKET_ITERATION_STOP"); | ||
2313 | rid = ntohl (tis_msg->id); | ||
2314 | for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next) | ||
2315 | if (ti->r_id == rid) | ||
2316 | break; | ||
2317 | if (NULL == ti) | ||
1511 | { | 2318 | { |
1512 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1513 | "Malformed scopes received!\n"); | ||
1514 | GNUNET_break (0); | 2319 | GNUNET_break (0); |
1515 | return GNUNET_SYSERR; | 2320 | GNUNET_SERVICE_client_drop (client->client); |
2321 | return; | ||
1516 | } | 2322 | } |
1517 | return GNUNET_OK; | 2323 | GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head, |
2324 | client->ticket_iter_tail, | ||
2325 | ti); | ||
2326 | cleanup_ticket_iter_handle (ti); | ||
2327 | GNUNET_SERVICE_client_continue (client->client); | ||
1518 | } | 2328 | } |
1519 | 2329 | ||
1520 | /** | 2330 | |
1521 | * | ||
1522 | * Handler for issue message | ||
1523 | * | ||
1524 | * @param cls unused | ||
1525 | * @param client who sent the message | ||
1526 | * @param message the message | ||
1527 | */ | ||
1528 | static void | 2331 | static void |
1529 | handle_issue_message (void *cls, | 2332 | handle_ticket_iteration_next (void *cls, |
1530 | const struct IssueMessage *im) | 2333 | const struct TicketIterationNextMessage *tis_msg) |
1531 | { | 2334 | { |
1532 | const char *scopes; | 2335 | struct IdpClient *client = cls; |
1533 | char *scopes_tmp; | 2336 | struct TicketIteration *ti; |
1534 | char *scope; | 2337 | uint32_t rid; |
1535 | struct GNUNET_HashCode key; | ||
1536 | struct IssueHandle *issue_handle; | ||
1537 | struct GNUNET_SERVICE_Client *client = cls; | ||
1538 | |||
1539 | scopes = (const char *) &im[1]; | ||
1540 | issue_handle = GNUNET_malloc (sizeof (struct IssueHandle)); | ||
1541 | issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5, | ||
1542 | GNUNET_NO); | ||
1543 | scopes_tmp = GNUNET_strdup (scopes); | ||
1544 | 2338 | ||
1545 | for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) | 2339 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2340 | "Received TICKET_ITERATION_NEXT message\n"); | ||
2341 | rid = ntohl (tis_msg->id); | ||
2342 | for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next) | ||
2343 | if (ti->r_id == rid) | ||
2344 | break; | ||
2345 | if (NULL == ti) | ||
1546 | { | 2346 | { |
1547 | GNUNET_CRYPTO_hash (scope, | 2347 | GNUNET_break (0); |
1548 | strlen (scope), | 2348 | GNUNET_SERVICE_client_drop (client->client); |
1549 | &key); | 2349 | return; |
1550 | GNUNET_CONTAINER_multihashmap_put (issue_handle->attr_map, | ||
1551 | &key, | ||
1552 | scope, | ||
1553 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
1554 | } | 2350 | } |
1555 | GNUNET_free (scopes_tmp); | 2351 | run_ticket_iteration_round (ti); |
1556 | issue_handle->r_id = im->id; | 2352 | GNUNET_SERVICE_client_continue (client->client); |
1557 | issue_handle->aud_key = im->aud_key; | ||
1558 | issue_handle->iss_key = im->iss_key; | ||
1559 | GNUNET_CRYPTO_ecdsa_key_get_public (&im->iss_key, | ||
1560 | &issue_handle->iss_pkey); | ||
1561 | issue_handle->expiration = GNUNET_TIME_absolute_ntoh (im->expiration); | ||
1562 | issue_handle->nonce = ntohl (im->nonce); | ||
1563 | GNUNET_SERVICE_client_continue (client); | ||
1564 | issue_handle->client = client; | ||
1565 | issue_handle->scopes = GNUNET_strdup (scopes); | ||
1566 | issue_handle->token = token_create (&issue_handle->iss_pkey, | ||
1567 | &issue_handle->aud_key); | ||
1568 | |||
1569 | issue_handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle, | ||
1570 | &im->iss_key, | ||
1571 | &find_existing_token_error, | ||
1572 | issue_handle, | ||
1573 | &find_existing_token, | ||
1574 | issue_handle, | ||
1575 | &find_existing_token_finished, | ||
1576 | issue_handle); | ||
1577 | } | 2353 | } |
1578 | 2354 | ||
1579 | 2355 | ||
2356 | |||
2357 | |||
1580 | /** | 2358 | /** |
1581 | * Main function that will be run | 2359 | * Main function that will be run |
1582 | * | 2360 | * |
1583 | * @param cls closure | 2361 | * @param cls closure |
1584 | * @param args remaining command-line arguments | 2362 | * @param c the configuration used |
1585 | * @param cfgfile name of the configuration file used (for saving, can be NULL) | 2363 | * @param server the service handle |
1586 | * @param c configuration | ||
1587 | */ | 2364 | */ |
1588 | static void | 2365 | static void |
1589 | run (void *cls, | 2366 | run (void *cls, |
1590 | const struct GNUNET_CONFIGURATION_Handle *c, | 2367 | const struct GNUNET_CONFIGURATION_Handle *c, |
1591 | struct GNUNET_SERVICE_Handle *server) | 2368 | struct GNUNET_SERVICE_Handle *server) |
1592 | { | 2369 | { |
2370 | char *database; | ||
1593 | cfg = c; | 2371 | cfg = c; |
1594 | 2372 | ||
1595 | stats = GNUNET_STATISTICS_create ("identity-provider", cfg); | 2373 | stats = GNUNET_STATISTICS_create ("identity-provider", cfg); |
@@ -1606,10 +2384,38 @@ run (void *cls, | |||
1606 | { | 2384 | { |
1607 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns"); | 2385 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns"); |
1608 | } | 2386 | } |
1609 | 2387 | credential_handle = GNUNET_CREDENTIAL_connect (cfg); | |
2388 | if (NULL == credential_handle) | ||
2389 | { | ||
2390 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to credential"); | ||
2391 | } | ||
1610 | identity_handle = GNUNET_IDENTITY_connect (cfg, | 2392 | identity_handle = GNUNET_IDENTITY_connect (cfg, |
1611 | &list_ego, | 2393 | NULL, |
1612 | NULL); | 2394 | NULL); |
2395 | stats_handle = GNUNET_STATISTICS_create ("identity-provider", | ||
2396 | cfg); | ||
2397 | /* Loading DB plugin */ | ||
2398 | if (GNUNET_OK != | ||
2399 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
2400 | "identity-provider", | ||
2401 | "database", | ||
2402 | &database)) | ||
2403 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2404 | "No database backend configured\n"); | ||
2405 | GNUNET_asprintf (&db_lib_name, | ||
2406 | "libgnunet_plugin_identity_provider_%s", | ||
2407 | database); | ||
2408 | TKT_database = GNUNET_PLUGIN_load (db_lib_name, | ||
2409 | (void *) cfg); | ||
2410 | GNUNET_free (database); | ||
2411 | if (NULL == TKT_database) | ||
2412 | { | ||
2413 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
2414 | "Could not load database backend `%s'\n", | ||
2415 | db_lib_name); | ||
2416 | GNUNET_SCHEDULER_shutdown (); | ||
2417 | return; | ||
2418 | } | ||
1613 | 2419 | ||
1614 | if (GNUNET_OK == | 2420 | if (GNUNET_OK == |
1615 | GNUNET_CONFIGURATION_get_value_time (cfg, | 2421 | GNUNET_CONFIGURATION_get_value_time (cfg, |
@@ -1640,9 +2446,39 @@ client_disconnect_cb (void *cls, | |||
1640 | struct GNUNET_SERVICE_Client *client, | 2446 | struct GNUNET_SERVICE_Client *client, |
1641 | void *app_ctx) | 2447 | void *app_ctx) |
1642 | { | 2448 | { |
2449 | struct IdpClient *idp = app_ctx; | ||
2450 | struct AttributeIterator *ai; | ||
2451 | struct TicketIteration *ti; | ||
2452 | struct TicketRevocationHandle *rh; | ||
2453 | |||
2454 | //TODO other operations | ||
2455 | |||
1643 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2456 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1644 | "Client %p disconnected\n", | 2457 | "Client %p disconnected\n", |
1645 | client); | 2458 | client); |
2459 | |||
2460 | while (NULL != (ai = idp->op_head)) | ||
2461 | { | ||
2462 | GNUNET_CONTAINER_DLL_remove (idp->op_head, | ||
2463 | idp->op_tail, | ||
2464 | ai); | ||
2465 | GNUNET_free (ai); | ||
2466 | } | ||
2467 | while (NULL != (rh = idp->revocation_list_head)) | ||
2468 | { | ||
2469 | GNUNET_CONTAINER_DLL_remove (idp->revocation_list_head, | ||
2470 | idp->revocation_list_tail, | ||
2471 | rh); | ||
2472 | cleanup_revoke_ticket_handle (rh); | ||
2473 | } | ||
2474 | while (NULL != (ti = idp->ticket_iter_head)) | ||
2475 | { | ||
2476 | GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head, | ||
2477 | idp->ticket_iter_tail, | ||
2478 | ti); | ||
2479 | cleanup_ticket_iter_handle (ti); | ||
2480 | } | ||
2481 | GNUNET_free (idp); | ||
1646 | } | 2482 | } |
1647 | 2483 | ||
1648 | 2484 | ||
@@ -1659,10 +2495,14 @@ client_connect_cb (void *cls, | |||
1659 | struct GNUNET_SERVICE_Client *client, | 2495 | struct GNUNET_SERVICE_Client *client, |
1660 | struct GNUNET_MQ_Handle *mq) | 2496 | struct GNUNET_MQ_Handle *mq) |
1661 | { | 2497 | { |
2498 | struct IdpClient *idp; | ||
1662 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2499 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1663 | "Client %p connected\n", | 2500 | "Client %p connected\n", |
1664 | client); | 2501 | client); |
1665 | return client; | 2502 | idp = GNUNET_new (struct IdpClient); |
2503 | idp->client = client; | ||
2504 | idp->mq = mq; | ||
2505 | return idp; | ||
1666 | } | 2506 | } |
1667 | 2507 | ||
1668 | 2508 | ||
@@ -1677,13 +2517,45 @@ GNUNET_SERVICE_MAIN | |||
1677 | &client_connect_cb, | 2517 | &client_connect_cb, |
1678 | &client_disconnect_cb, | 2518 | &client_disconnect_cb, |
1679 | NULL, | 2519 | NULL, |
1680 | GNUNET_MQ_hd_var_size (issue_message, | 2520 | GNUNET_MQ_hd_var_size (attribute_store_message, |
1681 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE, | 2521 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE, |
1682 | struct IssueMessage, | 2522 | struct AttributeStoreMessage, |
2523 | NULL), | ||
2524 | GNUNET_MQ_hd_fixed_size (iteration_start, | ||
2525 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START, | ||
2526 | struct AttributeIterationStartMessage, | ||
2527 | NULL), | ||
2528 | GNUNET_MQ_hd_fixed_size (iteration_next, | ||
2529 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT, | ||
2530 | struct AttributeIterationNextMessage, | ||
2531 | NULL), | ||
2532 | GNUNET_MQ_hd_fixed_size (iteration_stop, | ||
2533 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP, | ||
2534 | struct AttributeIterationStopMessage, | ||
2535 | NULL), | ||
2536 | GNUNET_MQ_hd_var_size (issue_ticket_message, | ||
2537 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET, | ||
2538 | struct IssueTicketMessage, | ||
2539 | NULL), | ||
2540 | GNUNET_MQ_hd_var_size (consume_ticket_message, | ||
2541 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET, | ||
2542 | struct ConsumeTicketMessage, | ||
1683 | NULL), | 2543 | NULL), |
1684 | GNUNET_MQ_hd_var_size (exchange_message, | 2544 | GNUNET_MQ_hd_fixed_size (ticket_iteration_start, |
1685 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE, | 2545 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START, |
1686 | struct ExchangeMessage, | 2546 | struct TicketIterationStartMessage, |
2547 | NULL), | ||
2548 | GNUNET_MQ_hd_fixed_size (ticket_iteration_next, | ||
2549 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT, | ||
2550 | struct TicketIterationNextMessage, | ||
2551 | NULL), | ||
2552 | GNUNET_MQ_hd_fixed_size (ticket_iteration_stop, | ||
2553 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP, | ||
2554 | struct TicketIterationStopMessage, | ||
2555 | NULL), | ||
2556 | GNUNET_MQ_hd_var_size (revoke_ticket_message, | ||
2557 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET, | ||
2558 | struct RevokeTicketMessage, | ||
1687 | NULL), | 2559 | NULL), |
1688 | GNUNET_MQ_handler_end()); | 2560 | GNUNET_MQ_handler_end()); |
1689 | /* end of gnunet-service-identity-provider.c */ | 2561 | /* end of gnunet-service-identity-provider.c */ |
diff --git a/src/identity-provider/identity-provider.conf b/src/identity-provider/identity-provider.conf index bac8e69ed..7ee5e50d8 100644 --- a/src/identity-provider/identity-provider.conf +++ b/src/identity-provider/identity-provider.conf | |||
@@ -10,3 +10,7 @@ UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-identity-provider.sock | |||
10 | UNIX_MATCH_UID = NO | 10 | UNIX_MATCH_UID = NO |
11 | UNIX_MATCH_GID = YES | 11 | UNIX_MATCH_GID = YES |
12 | TOKEN_EXPIRATION_INTERVAL = 30 m | 12 | TOKEN_EXPIRATION_INTERVAL = 30 m |
13 | DATABASE = sqlite | ||
14 | |||
15 | [identity-provider-sqlite] | ||
16 | FILENAME = $GNUNET_DATA_HOME/identity-provider/sqlite.db | ||
diff --git a/src/identity-provider/identity_provider.h b/src/identity-provider/identity_provider.h index 6fe6102c8..b1fe6e1fd 100644 --- a/src/identity-provider/identity_provider.h +++ b/src/identity-provider/identity_provider.h | |||
@@ -34,34 +34,157 @@ | |||
34 | GNUNET_NETWORK_STRUCT_BEGIN | 34 | GNUNET_NETWORK_STRUCT_BEGIN |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * The token | 37 | * Use to store an identity attribute |
38 | */ | 38 | */ |
39 | struct GNUNET_IDENTITY_PROVIDER_Token | 39 | struct AttributeStoreMessage |
40 | { | 40 | { |
41 | /** | 41 | /** |
42 | * The JWT representation of the identity token | 42 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT |
43 | */ | ||
44 | struct GNUNET_MessageHeader header; | ||
45 | |||
46 | /** | ||
47 | * Unique identifier for this request (for key collisions). | ||
43 | */ | 48 | */ |
44 | char *data; | 49 | uint32_t id GNUNET_PACKED; |
50 | |||
51 | /** | ||
52 | * The length of the attribute | ||
53 | */ | ||
54 | uint32_t attr_len GNUNET_PACKED; | ||
55 | |||
56 | /** | ||
57 | * Identity | ||
58 | */ | ||
59 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
60 | |||
61 | /* followed by the serialized attribute */ | ||
62 | |||
45 | }; | 63 | }; |
46 | 64 | ||
47 | /** | 65 | /** |
48 | * The ticket | 66 | * Attribute store response message |
49 | */ | 67 | */ |
50 | struct GNUNET_IDENTITY_PROVIDER_Ticket | 68 | struct AttributeStoreResultMessage |
51 | { | 69 | { |
52 | /** | 70 | /** |
53 | * The Base64 representation of the ticket | 71 | * Message header |
72 | */ | ||
73 | struct GNUNET_MessageHeader header; | ||
74 | |||
75 | /** | ||
76 | * Unique identifier for this request (for key collisions). | ||
77 | */ | ||
78 | uint32_t id GNUNET_PACKED; | ||
79 | |||
80 | /** | ||
81 | * #GNUNET_SYSERR on failure, #GNUNET_OK on success | ||
82 | */ | ||
83 | int32_t op_result GNUNET_PACKED; | ||
84 | |||
85 | }; | ||
86 | |||
87 | /** | ||
88 | * Attribute is returned from the idp. | ||
89 | */ | ||
90 | struct AttributeResultMessage | ||
91 | { | ||
92 | /** | ||
93 | * Message header | ||
94 | */ | ||
95 | struct GNUNET_MessageHeader header; | ||
96 | |||
97 | /** | ||
98 | * Unique identifier for this request (for key collisions). | ||
99 | */ | ||
100 | uint32_t id GNUNET_PACKED; | ||
101 | |||
102 | /** | ||
103 | * Length of serialized attribute data | ||
104 | */ | ||
105 | uint16_t attr_len GNUNET_PACKED; | ||
106 | |||
107 | /** | ||
108 | * always zero (for alignment) | ||
109 | */ | ||
110 | uint16_t reserved GNUNET_PACKED; | ||
111 | |||
112 | /** | ||
113 | * The public key of the identity. | ||
114 | */ | ||
115 | struct GNUNET_CRYPTO_EcdsaPublicKey identity; | ||
116 | |||
117 | /* followed by: | ||
118 | * serialized attribute data | ||
119 | */ | ||
120 | }; | ||
121 | |||
122 | |||
123 | /** | ||
124 | * Start a attribute iteration for the given identity | ||
125 | */ | ||
126 | struct AttributeIterationStartMessage | ||
127 | { | ||
128 | /** | ||
129 | * Message | ||
130 | */ | ||
131 | struct GNUNET_MessageHeader header; | ||
132 | |||
133 | /** | ||
134 | * Unique identifier for this request (for key collisions). | ||
135 | */ | ||
136 | uint32_t id GNUNET_PACKED; | ||
137 | |||
138 | /** | ||
139 | * Identity. | ||
140 | */ | ||
141 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
142 | |||
143 | }; | ||
144 | |||
145 | |||
146 | /** | ||
147 | * Ask for next result of attribute iteration for the given operation | ||
148 | */ | ||
149 | struct AttributeIterationNextMessage | ||
150 | { | ||
151 | /** | ||
152 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT | ||
153 | */ | ||
154 | struct GNUNET_MessageHeader header; | ||
155 | |||
156 | /** | ||
157 | * Unique identifier for this request (for key collisions). | ||
158 | */ | ||
159 | uint32_t id GNUNET_PACKED; | ||
160 | |||
161 | }; | ||
162 | |||
163 | |||
164 | /** | ||
165 | * Stop attribute iteration for the given operation | ||
166 | */ | ||
167 | struct AttributeIterationStopMessage | ||
168 | { | ||
169 | /** | ||
170 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP | ||
171 | */ | ||
172 | struct GNUNET_MessageHeader header; | ||
173 | |||
174 | /** | ||
175 | * Unique identifier for this request (for key collisions). | ||
54 | */ | 176 | */ |
55 | char *data; | 177 | uint32_t id GNUNET_PACKED; |
178 | |||
56 | }; | 179 | }; |
57 | 180 | ||
58 | /** | 181 | /** |
59 | * Answer from service to client after issue operation | 182 | * Start a ticket iteration for the given identity |
60 | */ | 183 | */ |
61 | struct IssueResultMessage | 184 | struct TicketIterationStartMessage |
62 | { | 185 | { |
63 | /** | 186 | /** |
64 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE | 187 | * Message |
65 | */ | 188 | */ |
66 | struct GNUNET_MessageHeader header; | 189 | struct GNUNET_MessageHeader header; |
67 | 190 | ||
@@ -70,18 +193,25 @@ struct IssueResultMessage | |||
70 | */ | 193 | */ |
71 | uint32_t id GNUNET_PACKED; | 194 | uint32_t id GNUNET_PACKED; |
72 | 195 | ||
73 | /* followed by 0-terminated label,ticket,token */ | 196 | /** |
197 | * Identity. | ||
198 | */ | ||
199 | struct GNUNET_CRYPTO_EcdsaPublicKey identity; | ||
74 | 200 | ||
201 | /** | ||
202 | * Identity is audience or issuer | ||
203 | */ | ||
204 | uint32_t is_audience GNUNET_PACKED; | ||
75 | }; | 205 | }; |
76 | 206 | ||
77 | 207 | ||
78 | /** | 208 | /** |
79 | * Ticket exchange message. | 209 | * Ask for next result of ticket iteration for the given operation |
80 | */ | 210 | */ |
81 | struct ExchangeResultMessage | 211 | struct TicketIterationNextMessage |
82 | { | 212 | { |
83 | /** | 213 | /** |
84 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE | 214 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT |
85 | */ | 215 | */ |
86 | struct GNUNET_MessageHeader header; | 216 | struct GNUNET_MessageHeader header; |
87 | 217 | ||
@@ -90,25 +220,35 @@ struct ExchangeResultMessage | |||
90 | */ | 220 | */ |
91 | uint32_t id GNUNET_PACKED; | 221 | uint32_t id GNUNET_PACKED; |
92 | 222 | ||
223 | }; | ||
224 | |||
225 | |||
226 | /** | ||
227 | * Stop ticket iteration for the given operation | ||
228 | */ | ||
229 | struct TicketIterationStopMessage | ||
230 | { | ||
93 | /** | 231 | /** |
94 | * Nonce found in ticket. NBO | 232 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP |
95 | * 0 on error. | ||
96 | */ | 233 | */ |
97 | uint64_t ticket_nonce GNUNET_PACKED; | 234 | struct GNUNET_MessageHeader header; |
98 | 235 | ||
99 | /* followed by 0-terminated token */ | 236 | /** |
237 | * Unique identifier for this request (for key collisions). | ||
238 | */ | ||
239 | uint32_t id GNUNET_PACKED; | ||
100 | 240 | ||
101 | }; | 241 | }; |
102 | 242 | ||
103 | 243 | ||
104 | 244 | ||
105 | /** | 245 | /** |
106 | * Client requests IdP to issue token. | 246 | * Ticket issue message |
107 | */ | 247 | */ |
108 | struct IssueMessage | 248 | struct IssueTicketMessage |
109 | { | 249 | { |
110 | /** | 250 | /** |
111 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT | 251 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET |
112 | */ | 252 | */ |
113 | struct GNUNET_MessageHeader header; | 253 | struct GNUNET_MessageHeader header; |
114 | 254 | ||
@@ -117,40 +257,98 @@ struct IssueMessage | |||
117 | */ | 257 | */ |
118 | uint32_t id GNUNET_PACKED; | 258 | uint32_t id GNUNET_PACKED; |
119 | 259 | ||
260 | /** | ||
261 | * Identity. | ||
262 | */ | ||
263 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
120 | 264 | ||
121 | /** | 265 | /** |
122 | * Issuer identity private key | 266 | * Requesting party. |
123 | */ | 267 | */ |
124 | struct GNUNET_CRYPTO_EcdsaPrivateKey iss_key; | 268 | struct GNUNET_CRYPTO_EcdsaPublicKey rp; |
125 | 269 | ||
126 | /** | 270 | /** |
127 | * Audience public key | 271 | * length of serialized attribute list |
128 | */ | 272 | */ |
129 | struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; | 273 | uint32_t attr_len GNUNET_PACKED; |
130 | 274 | ||
275 | //Followed by a serialized attribute list | ||
276 | }; | ||
277 | |||
278 | /** | ||
279 | * Ticket revoke message | ||
280 | */ | ||
281 | struct RevokeTicketMessage | ||
282 | { | ||
131 | /** | 283 | /** |
132 | * Nonce | 284 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET |
133 | */ | 285 | */ |
134 | uint64_t nonce; | 286 | struct GNUNET_MessageHeader header; |
135 | 287 | ||
136 | /** | 288 | /** |
137 | * Expiration of token in NBO. | 289 | * Unique identifier for this request (for key collisions). |
138 | */ | 290 | */ |
139 | struct GNUNET_TIME_AbsoluteNBO expiration; | 291 | uint32_t id GNUNET_PACKED; |
140 | 292 | ||
293 | /** | ||
294 | * Identity. | ||
295 | */ | ||
296 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
141 | 297 | ||
142 | /* followed by 0-terminated comma-separated scope list */ | 298 | /** |
299 | * length of serialized attribute list | ||
300 | */ | ||
301 | uint32_t attrs_len GNUNET_PACKED; | ||
143 | 302 | ||
303 | //Followed by a ticket and serialized attribute list | ||
304 | }; | ||
305 | |||
306 | /** | ||
307 | * Ticket revoke message | ||
308 | */ | ||
309 | struct RevokeTicketResultMessage | ||
310 | { | ||
311 | /** | ||
312 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT | ||
313 | */ | ||
314 | struct GNUNET_MessageHeader header; | ||
315 | |||
316 | /** | ||
317 | * Unique identifier for this request (for key collisions). | ||
318 | */ | ||
319 | uint32_t id GNUNET_PACKED; | ||
320 | |||
321 | /** | ||
322 | * Revocation result | ||
323 | */ | ||
324 | uint32_t success GNUNET_PACKED; | ||
144 | }; | 325 | }; |
145 | 326 | ||
146 | 327 | ||
147 | /** | 328 | /** |
148 | * Use to exchange a ticket for a token | 329 | * Ticket result message |
149 | */ | 330 | */ |
150 | struct ExchangeMessage | 331 | struct TicketResultMessage |
151 | { | 332 | { |
152 | /** | 333 | /** |
153 | * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT | 334 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT |
335 | */ | ||
336 | struct GNUNET_MessageHeader header; | ||
337 | |||
338 | /** | ||
339 | * Unique identifier for this request (for key collisions). | ||
340 | */ | ||
341 | uint32_t id GNUNET_PACKED; | ||
342 | |||
343 | }; | ||
344 | |||
345 | /** | ||
346 | * Ticket consume message | ||
347 | */ | ||
348 | struct ConsumeTicketMessage | ||
349 | { | ||
350 | /** | ||
351 | * Type will be #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET | ||
154 | */ | 352 | */ |
155 | struct GNUNET_MessageHeader header; | 353 | struct GNUNET_MessageHeader header; |
156 | 354 | ||
@@ -160,15 +358,50 @@ struct ExchangeMessage | |||
160 | uint32_t id GNUNET_PACKED; | 358 | uint32_t id GNUNET_PACKED; |
161 | 359 | ||
162 | /** | 360 | /** |
163 | * Audience identity private key | 361 | * Identity. |
362 | */ | ||
363 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
364 | |||
365 | //Followed by a serialized ticket | ||
366 | }; | ||
367 | |||
368 | /** | ||
369 | * Attribute list is returned from the idp. | ||
370 | */ | ||
371 | struct ConsumeTicketResultMessage | ||
372 | { | ||
373 | /** | ||
374 | * Message header | ||
375 | */ | ||
376 | struct GNUNET_MessageHeader header; | ||
377 | |||
378 | /** | ||
379 | * Unique identifier for this request (for key collisions). | ||
380 | */ | ||
381 | uint32_t id GNUNET_PACKED; | ||
382 | |||
383 | /** | ||
384 | * Length of serialized attribute data | ||
164 | */ | 385 | */ |
165 | struct GNUNET_CRYPTO_EcdsaPrivateKey aud_privkey; | 386 | uint16_t attrs_len GNUNET_PACKED; |
166 | 387 | ||
167 | /* followed by 0-terminated ticket string */ | 388 | /** |
389 | * always zero (for alignment) | ||
390 | */ | ||
391 | uint16_t reserved GNUNET_PACKED; | ||
168 | 392 | ||
393 | /** | ||
394 | * The public key of the identity. | ||
395 | */ | ||
396 | struct GNUNET_CRYPTO_EcdsaPublicKey identity; | ||
397 | |||
398 | /* followed by: | ||
399 | * serialized attributes data | ||
400 | */ | ||
169 | }; | 401 | }; |
170 | 402 | ||
171 | 403 | ||
404 | |||
172 | GNUNET_NETWORK_STRUCT_END | 405 | GNUNET_NETWORK_STRUCT_END |
173 | 406 | ||
174 | #endif | 407 | #endif |
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index 845d1f753..d0ece80fe 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c | |||
@@ -29,12 +29,12 @@ | |||
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | #include "gnunet_mq_lib.h" | 30 | #include "gnunet_mq_lib.h" |
31 | #include "gnunet_identity_provider_service.h" | 31 | #include "gnunet_identity_provider_service.h" |
32 | #include "gnunet_identity_attribute_lib.h" | ||
32 | #include "identity_provider.h" | 33 | #include "identity_provider.h" |
33 | 34 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__) | 35 | #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__) |
35 | 36 | ||
36 | 37 | ||
37 | |||
38 | /** | 38 | /** |
39 | * Handle for an operation with the service. | 39 | * Handle for an operation with the service. |
40 | */ | 40 | */ |
@@ -63,16 +63,24 @@ struct GNUNET_IDENTITY_PROVIDER_Operation | |||
63 | const struct GNUNET_MessageHeader *msg; | 63 | const struct GNUNET_MessageHeader *msg; |
64 | 64 | ||
65 | /** | 65 | /** |
66 | * Continuation to invoke with the result of the transmission; @e cb | 66 | * Continuation to invoke after attribute store call |
67 | * will be NULL in this case. | 67 | */ |
68 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus as_cb; | ||
69 | |||
70 | /** | ||
71 | * Attribute result callback | ||
72 | */ | ||
73 | GNUNET_IDENTITY_PROVIDER_AttributeResult ar_cb; | ||
74 | |||
75 | /** | ||
76 | * Revocation result callback | ||
68 | */ | 77 | */ |
69 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback ex_cb; | 78 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus rvk_cb; |
70 | 79 | ||
71 | /** | 80 | /** |
72 | * Continuation to invoke with the result of the transmission for | 81 | * Ticket result callback |
73 | * 'issue' operations (@e cont will be NULL in this case). | ||
74 | */ | 82 | */ |
75 | GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb; | 83 | GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb; |
76 | 84 | ||
77 | /** | 85 | /** |
78 | * Envelope with the message for this queue entry. | 86 | * Envelope with the message for this queue entry. |
@@ -91,6 +99,140 @@ struct GNUNET_IDENTITY_PROVIDER_Operation | |||
91 | 99 | ||
92 | }; | 100 | }; |
93 | 101 | ||
102 | /** | ||
103 | * Handle for a ticket iterator operation | ||
104 | */ | ||
105 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator | ||
106 | { | ||
107 | |||
108 | /** | ||
109 | * Kept in a DLL. | ||
110 | */ | ||
111 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *next; | ||
112 | |||
113 | /** | ||
114 | * Kept in a DLL. | ||
115 | */ | ||
116 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *prev; | ||
117 | |||
118 | /** | ||
119 | * Main handle to access the idp. | ||
120 | */ | ||
121 | struct GNUNET_IDENTITY_PROVIDER_Handle *h; | ||
122 | |||
123 | /** | ||
124 | * Function to call on completion. | ||
125 | */ | ||
126 | GNUNET_SCHEDULER_TaskCallback finish_cb; | ||
127 | |||
128 | /** | ||
129 | * Closure for @e error_cb. | ||
130 | */ | ||
131 | void *finish_cb_cls; | ||
132 | |||
133 | /** | ||
134 | * The continuation to call with the results | ||
135 | */ | ||
136 | GNUNET_IDENTITY_PROVIDER_TicketCallback tr_cb; | ||
137 | |||
138 | /** | ||
139 | * Closure for @e tr_cb. | ||
140 | */ | ||
141 | void *cls; | ||
142 | |||
143 | /** | ||
144 | * Function to call on errors. | ||
145 | */ | ||
146 | GNUNET_SCHEDULER_TaskCallback error_cb; | ||
147 | |||
148 | /** | ||
149 | * Closure for @e error_cb. | ||
150 | */ | ||
151 | void *error_cb_cls; | ||
152 | |||
153 | /** | ||
154 | * Envelope of the message to send to the service, if not yet | ||
155 | * sent. | ||
156 | */ | ||
157 | struct GNUNET_MQ_Envelope *env; | ||
158 | |||
159 | /** | ||
160 | * The operation id this zone iteration operation has | ||
161 | */ | ||
162 | uint32_t r_id; | ||
163 | |||
164 | }; | ||
165 | |||
166 | |||
167 | /** | ||
168 | * Handle for a attribute iterator operation | ||
169 | */ | ||
170 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator | ||
171 | { | ||
172 | |||
173 | /** | ||
174 | * Kept in a DLL. | ||
175 | */ | ||
176 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *next; | ||
177 | |||
178 | /** | ||
179 | * Kept in a DLL. | ||
180 | */ | ||
181 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *prev; | ||
182 | |||
183 | /** | ||
184 | * Main handle to access the idp. | ||
185 | */ | ||
186 | struct GNUNET_IDENTITY_PROVIDER_Handle *h; | ||
187 | |||
188 | /** | ||
189 | * Function to call on completion. | ||
190 | */ | ||
191 | GNUNET_SCHEDULER_TaskCallback finish_cb; | ||
192 | |||
193 | /** | ||
194 | * Closure for @e error_cb. | ||
195 | */ | ||
196 | void *finish_cb_cls; | ||
197 | |||
198 | /** | ||
199 | * The continuation to call with the results | ||
200 | */ | ||
201 | GNUNET_IDENTITY_PROVIDER_AttributeResult proc; | ||
202 | |||
203 | /** | ||
204 | * Closure for @e proc. | ||
205 | */ | ||
206 | void *proc_cls; | ||
207 | |||
208 | /** | ||
209 | * Function to call on errors. | ||
210 | */ | ||
211 | GNUNET_SCHEDULER_TaskCallback error_cb; | ||
212 | |||
213 | /** | ||
214 | * Closure for @e error_cb. | ||
215 | */ | ||
216 | void *error_cb_cls; | ||
217 | |||
218 | /** | ||
219 | * Envelope of the message to send to the service, if not yet | ||
220 | * sent. | ||
221 | */ | ||
222 | struct GNUNET_MQ_Envelope *env; | ||
223 | |||
224 | /** | ||
225 | * Private key of the zone. | ||
226 | */ | ||
227 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
228 | |||
229 | /** | ||
230 | * The operation id this zone iteration operation has | ||
231 | */ | ||
232 | uint32_t r_id; | ||
233 | |||
234 | }; | ||
235 | |||
94 | 236 | ||
95 | /** | 237 | /** |
96 | * Handle for the service. | 238 | * Handle for the service. |
@@ -123,6 +265,27 @@ struct GNUNET_IDENTITY_PROVIDER_Handle | |||
123 | struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail; | 265 | struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail; |
124 | 266 | ||
125 | /** | 267 | /** |
268 | * Head of active iterations | ||
269 | */ | ||
270 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_head; | ||
271 | |||
272 | /** | ||
273 | * Tail of active iterations | ||
274 | */ | ||
275 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail; | ||
276 | |||
277 | /** | ||
278 | * Head of active iterations | ||
279 | */ | ||
280 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_head; | ||
281 | |||
282 | /** | ||
283 | * Tail of active iterations | ||
284 | */ | ||
285 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it_tail; | ||
286 | |||
287 | |||
288 | /** | ||
126 | * Currently pending transmission request, or NULL for none. | 289 | * Currently pending transmission request, or NULL for none. |
127 | */ | 290 | */ |
128 | struct GNUNET_CLIENT_TransmitHandle *th; | 291 | struct GNUNET_CLIENT_TransmitHandle *th; |
@@ -154,14 +317,13 @@ struct GNUNET_IDENTITY_PROVIDER_Handle | |||
154 | 317 | ||
155 | }; | 318 | }; |
156 | 319 | ||
157 | |||
158 | /** | 320 | /** |
159 | * Try again to connect to the service. | 321 | * Try again to connect to the service. |
160 | * | 322 | * |
161 | * @param cls handle to the service. | 323 | * @param h handle to the identity provider service. |
162 | */ | 324 | */ |
163 | static void | 325 | static void |
164 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle); | 326 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h); |
165 | 327 | ||
166 | /** | 328 | /** |
167 | * Reconnect | 329 | * Reconnect |
@@ -181,7 +343,7 @@ reconnect_task (void *cls) | |||
181 | /** | 343 | /** |
182 | * Disconnect from service and then reconnect. | 344 | * Disconnect from service and then reconnect. |
183 | * | 345 | * |
184 | * @param handle our handle | 346 | * @param handle our service |
185 | */ | 347 | */ |
186 | static void | 348 | static void |
187 | force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle) | 349 | force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle) |
@@ -197,6 +359,26 @@ force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle) | |||
197 | } | 359 | } |
198 | 360 | ||
199 | /** | 361 | /** |
362 | * Free @a it. | ||
363 | * | ||
364 | * @param it entry to free | ||
365 | */ | ||
366 | static void | ||
367 | free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it) | ||
368 | { | ||
369 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; | ||
370 | |||
371 | GNUNET_CONTAINER_DLL_remove (h->it_head, | ||
372 | h->it_tail, | ||
373 | it); | ||
374 | if (NULL != it->env) | ||
375 | GNUNET_MQ_discard (it->env); | ||
376 | GNUNET_free (it); | ||
377 | } | ||
378 | |||
379 | |||
380 | |||
381 | /** | ||
200 | * Generic error handler, called with the appropriate error code and | 382 | * Generic error handler, called with the appropriate error code and |
201 | * the same closure specified at the creation of the message queue. | 383 | * the same closure specified at the creation of the message queue. |
202 | * Not every message queue implementation supports an error handler. | 384 | * Not every message queue implementation supports an error handler. |
@@ -213,22 +395,68 @@ mq_error_handler (void *cls, | |||
213 | } | 395 | } |
214 | 396 | ||
215 | /** | 397 | /** |
216 | * Check validity of message received from the service | 398 | * Handle an incoming message of type |
399 | * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE | ||
400 | * | ||
401 | * @param cls | ||
402 | * @param msg the message we received | ||
403 | */ | ||
404 | static void | ||
405 | handle_attribute_store_response (void *cls, | ||
406 | const struct AttributeStoreResultMessage *msg) | ||
407 | { | ||
408 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | ||
409 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
410 | uint32_t r_id = ntohl (msg->id); | ||
411 | int res; | ||
412 | const char *emsg; | ||
413 | |||
414 | for (op = h->op_head; NULL != op; op = op->next) | ||
415 | if (op->r_id == r_id) | ||
416 | break; | ||
417 | if (NULL == op) | ||
418 | return; | ||
419 | |||
420 | res = ntohl (msg->op_result); | ||
421 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
422 | "Received ATTRIBUTE_STORE_RESPONSE with result %d\n", | ||
423 | res); | ||
424 | |||
425 | /* TODO: add actual error message to response... */ | ||
426 | if (GNUNET_SYSERR == res) | ||
427 | emsg = _("failed to store record\n"); | ||
428 | else | ||
429 | emsg = NULL; | ||
430 | if (NULL != op->as_cb) | ||
431 | op->as_cb (op->cls, | ||
432 | res, | ||
433 | emsg); | ||
434 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
435 | h->op_tail, | ||
436 | op); | ||
437 | GNUNET_free (op); | ||
438 | |||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * Handle an incoming message of type | ||
444 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT | ||
217 | * | 445 | * |
218 | * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` | 446 | * @param cls |
219 | * @param result_msg the incoming message | 447 | * @param msg the message we received |
448 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
220 | */ | 449 | */ |
221 | static int | 450 | static int |
222 | check_exchange_result (void *cls, | 451 | check_consume_ticket_result (void *cls, |
223 | const struct ExchangeResultMessage *erm) | 452 | const struct ConsumeTicketResultMessage *msg) |
224 | { | 453 | { |
225 | char *str; | 454 | size_t msg_len; |
226 | size_t size = ntohs (erm->header.size) - sizeof (*erm); | 455 | size_t attrs_len; |
227 | |||
228 | 456 | ||
229 | str = (char *) &erm[1]; | 457 | msg_len = ntohs (msg->header.size); |
230 | if ( (size > sizeof (struct ExchangeResultMessage)) && | 458 | attrs_len = ntohs (msg->attrs_len); |
231 | ('\0' != str[size - sizeof (struct ExchangeResultMessage) - 1]) ) | 459 | if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len) |
232 | { | 460 | { |
233 | GNUNET_break (0); | 461 | GNUNET_break (0); |
234 | return GNUNET_SYSERR; | 462 | return GNUNET_SYSERR; |
@@ -238,20 +466,85 @@ check_exchange_result (void *cls, | |||
238 | 466 | ||
239 | 467 | ||
240 | /** | 468 | /** |
241 | * Check validity of message received from the service | 469 | * Handle an incoming message of type |
470 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT | ||
471 | * | ||
472 | * @param cls | ||
473 | * @param msg the message we received | ||
474 | */ | ||
475 | static void | ||
476 | handle_consume_ticket_result (void *cls, | ||
477 | const struct ConsumeTicketResultMessage *msg) | ||
478 | { | ||
479 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | ||
480 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
481 | size_t attrs_len; | ||
482 | uint32_t r_id = ntohl (msg->id); | ||
483 | |||
484 | attrs_len = ntohs (msg->attrs_len); | ||
485 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
486 | "Processing attribute result.\n"); | ||
487 | |||
488 | |||
489 | for (op = h->op_head; NULL != op; op = op->next) | ||
490 | if (op->r_id == r_id) | ||
491 | break; | ||
492 | if (NULL == op) | ||
493 | return; | ||
494 | |||
495 | { | ||
496 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; | ||
497 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
498 | attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize ((char*)&msg[1], | ||
499 | attrs_len); | ||
500 | if (NULL != op->ar_cb) | ||
501 | { | ||
502 | if (NULL == attrs) | ||
503 | { | ||
504 | op->ar_cb (op->cls, | ||
505 | &msg->identity, | ||
506 | NULL); | ||
507 | } | ||
508 | else | ||
509 | { | ||
510 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
511 | op->ar_cb (op->cls, | ||
512 | &msg->identity, | ||
513 | le->claim); | ||
514 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (attrs); | ||
515 | } | ||
516 | } | ||
517 | op->ar_cb (op->cls, | ||
518 | NULL, | ||
519 | NULL); | ||
520 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
521 | h->op_tail, | ||
522 | op); | ||
523 | GNUNET_free (op); | ||
524 | return; | ||
525 | } | ||
526 | GNUNET_assert (0); | ||
527 | } | ||
528 | |||
529 | |||
530 | /** | ||
531 | * Handle an incoming message of type | ||
532 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT | ||
242 | * | 533 | * |
243 | * @param cls the `struct GNUNET_IDENTITY_PROVIDER_Handle *` | 534 | * @param cls |
244 | * @param result_msg the incoming message | 535 | * @param msg the message we received |
536 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
245 | */ | 537 | */ |
246 | static int | 538 | static int |
247 | check_result (void *cls, | 539 | check_attribute_result (void *cls, |
248 | const struct IssueResultMessage *irm) | 540 | const struct AttributeResultMessage *msg) |
249 | { | 541 | { |
250 | char *str; | 542 | size_t msg_len; |
251 | size_t size = ntohs (irm->header.size) - sizeof (*irm); | 543 | size_t attr_len; |
252 | str = (char*) &irm[1]; | 544 | |
253 | if ( (size > sizeof (struct IssueResultMessage)) && | 545 | msg_len = ntohs (msg->header.size); |
254 | ('\0' != str[size - sizeof (struct IssueResultMessage) - 1]) ) | 546 | attr_len = ntohs (msg->attr_len); |
547 | if (msg_len != sizeof (struct AttributeResultMessage) + attr_len) | ||
255 | { | 548 | { |
256 | GNUNET_break (0); | 549 | GNUNET_break (0); |
257 | return GNUNET_SYSERR; | 550 | return GNUNET_SYSERR; |
@@ -259,119 +552,254 @@ check_result (void *cls, | |||
259 | return GNUNET_OK; | 552 | return GNUNET_OK; |
260 | } | 553 | } |
261 | 554 | ||
555 | |||
262 | /** | 556 | /** |
263 | * Handler for messages received from the GNS service | 557 | * Handle an incoming message of type |
558 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT | ||
264 | * | 559 | * |
265 | * @param cls the `struct GNUNET_GNS_Handle *` | 560 | * @param cls |
266 | * @param loookup_msg the incoming message | 561 | * @param msg the message we received |
267 | */ | 562 | */ |
268 | static void | 563 | static void |
269 | handle_exchange_result (void *cls, | 564 | handle_attribute_result (void *cls, |
270 | const struct ExchangeResultMessage *erm) | 565 | const struct AttributeResultMessage *msg) |
271 | { | 566 | { |
272 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; | 567 | static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; |
568 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | ||
569 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it; | ||
273 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 570 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
274 | struct GNUNET_IDENTITY_PROVIDER_Token token; | 571 | size_t attr_len; |
275 | uint64_t ticket_nonce; | 572 | uint32_t r_id = ntohl (msg->id); |
276 | uint32_t r_id = ntohl (erm->id); | 573 | |
277 | char *str; | 574 | attr_len = ntohs (msg->attr_len); |
278 | 575 | LOG (GNUNET_ERROR_TYPE_DEBUG, | |
279 | for (op = handle->op_head; NULL != op; op = op->next) | 576 | "Processing attribute result.\n"); |
577 | |||
578 | |||
579 | for (it = h->it_head; NULL != it; it = it->next) | ||
580 | if (it->r_id == r_id) | ||
581 | break; | ||
582 | for (op = h->op_head; NULL != op; op = op->next) | ||
280 | if (op->r_id == r_id) | 583 | if (op->r_id == r_id) |
281 | break; | 584 | break; |
282 | if (NULL == op) | 585 | if ((NULL == it) && (NULL == op)) |
283 | return; | 586 | return; |
284 | str = GNUNET_strdup ((char*)&erm[1]); | ||
285 | op = handle->op_head; | ||
286 | GNUNET_CONTAINER_DLL_remove (handle->op_head, | ||
287 | handle->op_tail, | ||
288 | op); | ||
289 | token.data = str; | ||
290 | ticket_nonce = ntohl (erm->ticket_nonce); | ||
291 | if (NULL != op->ex_cb) | ||
292 | op->ex_cb (op->cls, &token, ticket_nonce); | ||
293 | GNUNET_free (str); | ||
294 | GNUNET_free (op); | ||
295 | 587 | ||
588 | if ( (0 == (memcmp (&msg->identity, | ||
589 | &identity_dummy, | ||
590 | sizeof (identity_dummy)))) ) | ||
591 | { | ||
592 | if ((NULL == it) && (NULL == op)) | ||
593 | { | ||
594 | GNUNET_break (0); | ||
595 | force_reconnect (h); | ||
596 | return; | ||
597 | } | ||
598 | if (NULL != it) | ||
599 | { | ||
600 | if (NULL != it->finish_cb) | ||
601 | it->finish_cb (it->finish_cb_cls); | ||
602 | free_it (it); | ||
603 | } | ||
604 | if (NULL != op) | ||
605 | { | ||
606 | if (NULL != op->ar_cb) | ||
607 | op->ar_cb (op->cls, | ||
608 | NULL, | ||
609 | NULL); | ||
610 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
611 | h->op_tail, | ||
612 | op); | ||
613 | GNUNET_free (op); | ||
614 | |||
615 | } | ||
616 | return; | ||
617 | } | ||
618 | |||
619 | { | ||
620 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr; | ||
621 | attr = GNUNET_IDENTITY_ATTRIBUTE_deserialize ((char*)&msg[1], | ||
622 | attr_len); | ||
623 | if (NULL != it) | ||
624 | { | ||
625 | if (NULL != it->proc) | ||
626 | it->proc (it->proc_cls, | ||
627 | &msg->identity, | ||
628 | attr); | ||
629 | } else if (NULL != op) | ||
630 | { | ||
631 | if (NULL != op->ar_cb) | ||
632 | op->ar_cb (op->cls, | ||
633 | &msg->identity, | ||
634 | attr); | ||
635 | |||
636 | } | ||
637 | GNUNET_free (attr); | ||
638 | return; | ||
639 | } | ||
640 | GNUNET_assert (0); | ||
641 | } | ||
642 | |||
643 | /** | ||
644 | * Handle an incoming message of type | ||
645 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT | ||
646 | * | ||
647 | * @param cls | ||
648 | * @param msg the message we received | ||
649 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
650 | */ | ||
651 | static int | ||
652 | check_ticket_result (void *cls, | ||
653 | const struct TicketResultMessage *msg) | ||
654 | { | ||
655 | size_t msg_len; | ||
656 | |||
657 | msg_len = ntohs (msg->header.size); | ||
658 | if (msg_len < sizeof (struct TicketResultMessage)) | ||
659 | { | ||
660 | GNUNET_break (0); | ||
661 | return GNUNET_SYSERR; | ||
662 | } | ||
663 | return GNUNET_OK; | ||
296 | } | 664 | } |
297 | 665 | ||
666 | |||
667 | |||
298 | /** | 668 | /** |
299 | * Handler for messages received from the GNS service | 669 | * Handle an incoming message of type |
670 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT | ||
300 | * | 671 | * |
301 | * @param cls the `struct GNUNET_GNS_Handle *` | 672 | * @param cls |
302 | * @param loookup_msg the incoming message | 673 | * @param msg the message we received |
303 | */ | 674 | */ |
304 | static void | 675 | static void |
305 | handle_result (void *cls, | 676 | handle_ticket_result (void *cls, |
306 | const struct IssueResultMessage *irm) | 677 | const struct TicketResultMessage *msg) |
307 | { | 678 | { |
308 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; | 679 | struct GNUNET_IDENTITY_PROVIDER_Handle *handle = cls; |
309 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 680 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
310 | struct GNUNET_IDENTITY_PROVIDER_Token token; | 681 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; |
311 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | 682 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket; |
312 | uint32_t r_id = ntohl (irm->id); | 683 | uint32_t r_id = ntohl (msg->id); |
313 | char *str; | 684 | size_t msg_len; |
314 | char *label_str; | ||
315 | char *ticket_str; | ||
316 | char *token_str; | ||
317 | 685 | ||
318 | for (op = handle->op_head; NULL != op; op = op->next) | 686 | for (op = handle->op_head; NULL != op; op = op->next) |
319 | if (op->r_id == r_id) | 687 | if (op->r_id == r_id) |
320 | break; | 688 | break; |
321 | if (NULL == op) | 689 | for (it = handle->ticket_it_head; NULL != it; it = it->next) |
690 | if (it->r_id == r_id) | ||
691 | break; | ||
692 | if ((NULL == op) && (NULL == it)) | ||
322 | return; | 693 | return; |
323 | str = GNUNET_strdup ((char*)&irm[1]); | 694 | msg_len = ntohs (msg->header.size); |
324 | label_str = strtok (str, ","); | 695 | if (NULL != op) |
325 | |||
326 | if (NULL == label_str) | ||
327 | { | 696 | { |
328 | GNUNET_free (str); | 697 | GNUNET_CONTAINER_DLL_remove (handle->op_head, |
329 | GNUNET_break (0); | 698 | handle->op_tail, |
699 | op); | ||
700 | if (msg_len == sizeof (struct TicketResultMessage)) | ||
701 | { | ||
702 | if (NULL != op->tr_cb) | ||
703 | op->tr_cb (op->cls, NULL); | ||
704 | } else { | ||
705 | ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1]; | ||
706 | if (NULL != op->tr_cb) | ||
707 | op->tr_cb (op->cls, ticket); | ||
708 | } | ||
709 | GNUNET_free (op); | ||
330 | return; | 710 | return; |
331 | } | 711 | } else if (NULL != it) { |
332 | ticket_str = strtok (NULL, ","); | 712 | if (msg_len == sizeof (struct TicketResultMessage)) |
333 | if (NULL == ticket_str) | 713 | { |
334 | { | 714 | if (NULL != it->tr_cb) |
335 | GNUNET_free (str); | 715 | GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head, |
336 | GNUNET_break (0); | 716 | handle->ticket_it_tail, |
717 | it); | ||
718 | it->finish_cb (it->finish_cb_cls); | ||
719 | GNUNET_free (it); | ||
720 | } else { | ||
721 | ticket = (struct GNUNET_IDENTITY_PROVIDER_Ticket *)&msg[1]; | ||
722 | if (NULL != it->tr_cb) | ||
723 | it->tr_cb (it->cls, ticket); | ||
724 | } | ||
337 | return; | 725 | return; |
338 | } | 726 | } |
339 | token_str = strtok (NULL, ","); | 727 | GNUNET_break (0); |
340 | if (NULL == token_str) | 728 | } |
729 | |||
730 | /** | ||
731 | * Handle an incoming message of type | ||
732 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT | ||
733 | * | ||
734 | * @param cls | ||
735 | * @param msg the message we received | ||
736 | */ | ||
737 | static void | ||
738 | handle_revoke_ticket_result (void *cls, | ||
739 | const struct RevokeTicketResultMessage *msg) | ||
740 | { | ||
741 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | ||
742 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
743 | uint32_t r_id = ntohl (msg->id); | ||
744 | int32_t success; | ||
745 | |||
746 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
747 | "Processing revocation result.\n"); | ||
748 | |||
749 | |||
750 | for (op = h->op_head; NULL != op; op = op->next) | ||
751 | if (op->r_id == r_id) | ||
752 | break; | ||
753 | if (NULL == op) | ||
754 | return; | ||
755 | success = ntohl (msg->success); | ||
341 | { | 756 | { |
342 | GNUNET_free (str); | 757 | if (NULL != op->rvk_cb) |
343 | GNUNET_break (0); | 758 | { |
759 | op->rvk_cb (op->cls, | ||
760 | success, | ||
761 | NULL); | ||
762 | } | ||
763 | GNUNET_CONTAINER_DLL_remove (h->op_head, | ||
764 | h->op_tail, | ||
765 | op); | ||
766 | GNUNET_free (op); | ||
344 | return; | 767 | return; |
345 | } | 768 | } |
346 | GNUNET_CONTAINER_DLL_remove (handle->op_head, | 769 | GNUNET_assert (0); |
347 | handle->op_tail, | ||
348 | op); | ||
349 | ticket.data = ticket_str; | ||
350 | token.data = token_str; | ||
351 | if (NULL != op->iss_cb) | ||
352 | op->iss_cb (op->cls, label_str, &ticket, &token); | ||
353 | GNUNET_free (str); | ||
354 | GNUNET_free (op); | ||
355 | |||
356 | } | 770 | } |
357 | 771 | ||
772 | |||
773 | |||
358 | /** | 774 | /** |
359 | * Try again to connect to the service. | 775 | * Try again to connect to the service. |
360 | * | 776 | * |
361 | * @param cls handle to the identity provider service. | 777 | * @param h handle to the identity provider service. |
362 | */ | 778 | */ |
363 | static void | 779 | static void |
364 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | 780 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) |
365 | { | 781 | { |
366 | struct GNUNET_MQ_MessageHandler handlers[] = { | 782 | struct GNUNET_MQ_MessageHandler handlers[] = { |
367 | GNUNET_MQ_hd_var_size (result, | 783 | GNUNET_MQ_hd_fixed_size (attribute_store_response, |
368 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT, | 784 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE, |
369 | struct IssueResultMessage, | 785 | struct AttributeStoreResultMessage, |
786 | h), | ||
787 | GNUNET_MQ_hd_var_size (attribute_result, | ||
788 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT, | ||
789 | struct AttributeResultMessage, | ||
370 | h), | 790 | h), |
371 | GNUNET_MQ_hd_var_size (exchange_result, | 791 | GNUNET_MQ_hd_var_size (ticket_result, |
372 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, | 792 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT, |
373 | struct ExchangeResultMessage, | 793 | struct TicketResultMessage, |
374 | h), | 794 | h), |
795 | GNUNET_MQ_hd_var_size (consume_ticket_result, | ||
796 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT, | ||
797 | struct ConsumeTicketResultMessage, | ||
798 | h), | ||
799 | GNUNET_MQ_hd_fixed_size (revoke_ticket_result, | ||
800 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT, | ||
801 | struct RevokeTicketResultMessage, | ||
802 | h), | ||
375 | GNUNET_MQ_handler_end () | 803 | GNUNET_MQ_handler_end () |
376 | }; | 804 | }; |
377 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 805 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
@@ -417,111 +845,6 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
417 | 845 | ||
418 | 846 | ||
419 | /** | 847 | /** |
420 | * Issue an identity token | ||
421 | * | ||
422 | * @param id identity service to query | ||
423 | * @param service_name for which service is an identity wanted | ||
424 | * @param cb function to call with the result (will only be called once) | ||
425 | * @param cb_cls closure for @a cb | ||
426 | * @return handle to abort the operation | ||
427 | */ | ||
428 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
429 | GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | ||
430 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, | ||
431 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | ||
432 | const char* scopes, | ||
433 | struct GNUNET_TIME_Absolute expiration, | ||
434 | uint64_t nonce, | ||
435 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, | ||
436 | void *cb_cls) | ||
437 | { | ||
438 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
439 | struct IssueMessage *im; | ||
440 | size_t slen; | ||
441 | |||
442 | slen = strlen (scopes) + 1; | ||
443 | if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct IssueMessage)) | ||
444 | { | ||
445 | GNUNET_break (0); | ||
446 | return NULL; | ||
447 | } | ||
448 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); | ||
449 | op->h = id; | ||
450 | op->iss_cb = cb; | ||
451 | op->cls = cb_cls; | ||
452 | op->r_id = id->r_id_gen++; | ||
453 | op->env = GNUNET_MQ_msg_extra (im, | ||
454 | slen, | ||
455 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE); | ||
456 | im->id = op->r_id; | ||
457 | im->iss_key = *iss_key; | ||
458 | im->aud_key = *aud_key; | ||
459 | im->nonce = htonl (nonce); | ||
460 | im->expiration = GNUNET_TIME_absolute_hton (expiration); | ||
461 | GNUNET_memcpy (&im[1], scopes, slen); | ||
462 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | ||
463 | id->op_tail, | ||
464 | op); | ||
465 | if (NULL != id->mq) | ||
466 | GNUNET_MQ_send_copy (id->mq, | ||
467 | op->env); | ||
468 | return op; | ||
469 | } | ||
470 | |||
471 | |||
472 | /** | ||
473 | * Exchange a token ticket for a token | ||
474 | * | ||
475 | * @param id identity provider service | ||
476 | * @param ticket ticket to exchange | ||
477 | * @param cont function to call once the operation finished | ||
478 | * @param cont_cls closure for @a cont | ||
479 | * @return handle to abort the operation | ||
480 | */ | ||
481 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
482 | GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | ||
483 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
484 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, | ||
485 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, | ||
486 | void *cont_cls) | ||
487 | { | ||
488 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
489 | struct ExchangeMessage *em; | ||
490 | size_t slen; | ||
491 | char *ticket_str; | ||
492 | |||
493 | ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); | ||
494 | |||
495 | slen = strlen (ticket_str) + 1; | ||
496 | if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct ExchangeMessage)) | ||
497 | { | ||
498 | GNUNET_free (ticket_str); | ||
499 | GNUNET_break (0); | ||
500 | return NULL; | ||
501 | } | ||
502 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); | ||
503 | op->h = id; | ||
504 | op->ex_cb = cont; | ||
505 | op->cls = cont_cls; | ||
506 | op->r_id = id->r_id_gen++; | ||
507 | op->env = GNUNET_MQ_msg_extra (em, | ||
508 | slen, | ||
509 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE); | ||
510 | em->aud_privkey = *aud_privkey; | ||
511 | em->id = htonl (op->r_id); | ||
512 | GNUNET_memcpy (&em[1], ticket_str, slen); | ||
513 | GNUNET_free (ticket_str); | ||
514 | GNUNET_CONTAINER_DLL_insert_tail (id->op_head, | ||
515 | id->op_tail, | ||
516 | op); | ||
517 | if (NULL != id->mq) | ||
518 | GNUNET_MQ_send_copy (id->mq, | ||
519 | op->env); | ||
520 | return op; | ||
521 | } | ||
522 | |||
523 | |||
524 | /** | ||
525 | * Cancel an operation. Note that the operation MAY still | 848 | * Cancel an operation. Note that the operation MAY still |
526 | * be executed; this merely cancels the continuation; if the request | 849 | * be executed; this merely cancels the continuation; if the request |
527 | * was already transmitted, the service may still choose to complete | 850 | * was already transmitted, the service may still choose to complete |
@@ -566,80 +889,482 @@ GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | |||
566 | } | 889 | } |
567 | 890 | ||
568 | /** | 891 | /** |
569 | * Convenience API | 892 | * Store an attribute. If the attribute is already present, |
893 | * it is replaced with the new attribute. | ||
894 | * | ||
895 | * @param h handle to the identity provider | ||
896 | * @param pkey private key of the identity | ||
897 | * @param attr the attribute value | ||
898 | * @param cont continuation to call when done | ||
899 | * @param cont_cls closure for @a cont | ||
900 | * @return handle to abort the request | ||
570 | */ | 901 | */ |
902 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
903 | GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
904 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, | ||
905 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr, | ||
906 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont, | ||
907 | void *cont_cls) | ||
908 | { | ||
909 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
910 | struct AttributeStoreMessage *sam; | ||
911 | size_t attr_len; | ||
912 | |||
913 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); | ||
914 | op->h = h; | ||
915 | op->as_cb = cont; | ||
916 | op->cls = cont_cls; | ||
917 | op->r_id = h->r_id_gen++; | ||
918 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, | ||
919 | h->op_tail, | ||
920 | op); | ||
921 | attr_len = GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (attr); | ||
922 | op->env = GNUNET_MQ_msg_extra (sam, | ||
923 | attr_len, | ||
924 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE); | ||
925 | sam->identity = *pkey; | ||
926 | sam->id = htonl (op->r_id); | ||
927 | |||
928 | GNUNET_IDENTITY_ATTRIBUTE_serialize (attr, | ||
929 | (char*)&sam[1]); | ||
930 | |||
931 | sam->attr_len = htons (attr_len); | ||
932 | if (NULL != h->mq) | ||
933 | GNUNET_MQ_send_copy (h->mq, | ||
934 | op->env); | ||
935 | return op; | ||
936 | |||
937 | } | ||
938 | |||
939 | |||
940 | /** | ||
941 | * List all attributes for a local identity. | ||
942 | * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle` | ||
943 | * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and | ||
944 | * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once | ||
945 | * immediately, and then again after | ||
946 | * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked. | ||
947 | * | ||
948 | * On error (disconnect), @a error_cb will be invoked. | ||
949 | * On normal completion, @a finish_cb proc will be | ||
950 | * invoked. | ||
951 | * | ||
952 | * @param h handle to the idp | ||
953 | * @param identity identity to access | ||
954 | * @param error_cb function to call on error (i.e. disconnect), | ||
955 | * the handle is afterwards invalid | ||
956 | * @param error_cb_cls closure for @a error_cb | ||
957 | * @param proc function to call on each attribute; it | ||
958 | * will be called repeatedly with a value (if available) | ||
959 | * @param proc_cls closure for @a proc | ||
960 | * @param finish_cb function to call on completion | ||
961 | * the handle is afterwards invalid | ||
962 | * @param finish_cb_cls closure for @a finish_cb | ||
963 | * @return an iterator handle to use for iteration | ||
964 | */ | ||
965 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator * | ||
966 | GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
967 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
968 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
969 | void *error_cb_cls, | ||
970 | GNUNET_IDENTITY_PROVIDER_AttributeResult proc, | ||
971 | void *proc_cls, | ||
972 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
973 | void *finish_cb_cls) | ||
974 | { | ||
975 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it; | ||
976 | struct GNUNET_MQ_Envelope *env; | ||
977 | struct AttributeIterationStartMessage *msg; | ||
978 | uint32_t rid; | ||
979 | |||
980 | rid = h->r_id_gen++; | ||
981 | it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator); | ||
982 | it->h = h; | ||
983 | it->error_cb = error_cb; | ||
984 | it->error_cb_cls = error_cb_cls; | ||
985 | it->finish_cb = finish_cb; | ||
986 | it->finish_cb_cls = finish_cb_cls; | ||
987 | it->proc = proc; | ||
988 | it->proc_cls = proc_cls; | ||
989 | it->r_id = rid; | ||
990 | it->identity = *identity; | ||
991 | GNUNET_CONTAINER_DLL_insert_tail (h->it_head, | ||
992 | h->it_tail, | ||
993 | it); | ||
994 | env = GNUNET_MQ_msg (msg, | ||
995 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START); | ||
996 | msg->id = htonl (rid); | ||
997 | msg->identity = *identity; | ||
998 | if (NULL == h->mq) | ||
999 | it->env = env; | ||
1000 | else | ||
1001 | GNUNET_MQ_send (h->mq, | ||
1002 | env); | ||
1003 | return it; | ||
1004 | } | ||
571 | 1005 | ||
572 | 1006 | ||
573 | /** | 1007 | /** |
574 | * Destroy token | 1008 | * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start |
1009 | * for the next record. | ||
575 | * | 1010 | * |
576 | * @param token the token | 1011 | * @param it the iterator |
577 | */ | 1012 | */ |
578 | void | 1013 | void |
579 | GNUNET_IDENTITY_PROVIDER_token_destroy(struct GNUNET_IDENTITY_PROVIDER_Token *token) | 1014 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it) |
1015 | { | ||
1016 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; | ||
1017 | struct AttributeIterationNextMessage *msg; | ||
1018 | struct GNUNET_MQ_Envelope *env; | ||
1019 | |||
1020 | env = GNUNET_MQ_msg (msg, | ||
1021 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT); | ||
1022 | msg->id = htonl (it->r_id); | ||
1023 | GNUNET_MQ_send (h->mq, | ||
1024 | env); | ||
1025 | } | ||
1026 | |||
1027 | |||
1028 | /** | ||
1029 | * Stops iteration and releases the idp handle for further calls. Must | ||
1030 | * be called on any iteration that has not yet completed prior to calling | ||
1031 | * #GNUNET_IDENTITY_PROVIDER_disconnect. | ||
1032 | * | ||
1033 | * @param it the iterator | ||
1034 | */ | ||
1035 | void | ||
1036 | GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it) | ||
1037 | { | ||
1038 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; | ||
1039 | struct GNUNET_MQ_Envelope *env; | ||
1040 | struct AttributeIterationStopMessage *msg; | ||
1041 | |||
1042 | if (NULL != h->mq) | ||
1043 | { | ||
1044 | env = GNUNET_MQ_msg (msg, | ||
1045 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP); | ||
1046 | msg->id = htonl (it->r_id); | ||
1047 | GNUNET_MQ_send (h->mq, | ||
1048 | env); | ||
1049 | } | ||
1050 | free_it (it); | ||
1051 | } | ||
1052 | |||
1053 | |||
1054 | /** TODO | ||
1055 | * Issues a ticket to another identity. The identity may use | ||
1056 | * @GNUNET_IDENTITY_PROVIDER_authorization_ticket_consume to consume the ticket | ||
1057 | * and retrieve the attributes specified in the AttributeList. | ||
1058 | * | ||
1059 | * @param h the identity provider to use | ||
1060 | * @param iss the issuing identity | ||
1061 | * @param rp the subject of the ticket (the relying party) | ||
1062 | * @param attrs the attributes that the relying party is given access to | ||
1063 | * @param cb the callback | ||
1064 | * @param cb_cls the callback closure | ||
1065 | * @return handle to abort the operation | ||
1066 | */ | ||
1067 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
1068 | GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
1069 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, | ||
1070 | const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, | ||
1071 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
1072 | GNUNET_IDENTITY_PROVIDER_TicketCallback cb, | ||
1073 | void *cb_cls) | ||
1074 | { | ||
1075 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
1076 | struct IssueTicketMessage *tim; | ||
1077 | size_t attr_len; | ||
1078 | |||
1079 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); | ||
1080 | op->h = h; | ||
1081 | op->tr_cb = cb; | ||
1082 | op->cls = cb_cls; | ||
1083 | op->r_id = h->r_id_gen++; | ||
1084 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, | ||
1085 | h->op_tail, | ||
1086 | op); | ||
1087 | attr_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs); | ||
1088 | op->env = GNUNET_MQ_msg_extra (tim, | ||
1089 | attr_len, | ||
1090 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET); | ||
1091 | tim->identity = *iss; | ||
1092 | tim->rp = *rp; | ||
1093 | tim->id = htonl (op->r_id); | ||
1094 | |||
1095 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs, | ||
1096 | (char*)&tim[1]); | ||
1097 | |||
1098 | tim->attr_len = htons (attr_len); | ||
1099 | if (NULL != h->mq) | ||
1100 | GNUNET_MQ_send_copy (h->mq, | ||
1101 | op->env); | ||
1102 | return op; | ||
1103 | } | ||
1104 | |||
1105 | /** | ||
1106 | * Consumes an issued ticket. The ticket is persisted | ||
1107 | * and used to retrieve identity information from the issuer | ||
1108 | * | ||
1109 | * @param h the identity provider to use | ||
1110 | * @param identity the identity that is the subject of the issued ticket (the relying party) | ||
1111 | * @param ticket the issued ticket to consume | ||
1112 | * @param cb the callback to call | ||
1113 | * @param cb_cls the callback closure | ||
1114 | * @return handle to abort the operation | ||
1115 | */ | ||
1116 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
1117 | GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
1118 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
1119 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
1120 | GNUNET_IDENTITY_PROVIDER_AttributeResult cb, | ||
1121 | void *cb_cls) | ||
580 | { | 1122 | { |
581 | GNUNET_assert (NULL != token); | 1123 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
582 | if (NULL != token->data) | 1124 | struct ConsumeTicketMessage *ctm; |
583 | GNUNET_free (token->data); | 1125 | |
584 | GNUNET_free (token); | 1126 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); |
1127 | op->h = h; | ||
1128 | op->ar_cb = cb; | ||
1129 | op->cls = cb_cls; | ||
1130 | op->r_id = h->r_id_gen++; | ||
1131 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, | ||
1132 | h->op_tail, | ||
1133 | op); | ||
1134 | op->env = GNUNET_MQ_msg_extra (ctm, | ||
1135 | sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket), | ||
1136 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET); | ||
1137 | ctm->identity = *identity; | ||
1138 | ctm->id = htonl (op->r_id); | ||
1139 | |||
1140 | GNUNET_memcpy ((char*)&ctm[1], | ||
1141 | ticket, | ||
1142 | sizeof (const struct GNUNET_IDENTITY_PROVIDER_Ticket)); | ||
1143 | |||
1144 | if (NULL != h->mq) | ||
1145 | GNUNET_MQ_send_copy (h->mq, | ||
1146 | op->env); | ||
1147 | return op; | ||
1148 | |||
585 | } | 1149 | } |
586 | 1150 | ||
1151 | |||
587 | /** | 1152 | /** |
588 | * Returns string representation of token. A JSON-Web-Token. | 1153 | * Lists all tickets that have been issued to remote |
1154 | * identites (relying parties) | ||
589 | * | 1155 | * |
590 | * @param token the token | 1156 | * @param h the identity provider to use |
591 | * @return The JWT (must be freed) | 1157 | * @param identity the issuing identity |
1158 | * @param error_cb function to call on error (i.e. disconnect), | ||
1159 | * the handle is afterwards invalid | ||
1160 | * @param error_cb_cls closure for @a error_cb | ||
1161 | * @param proc function to call on each ticket; it | ||
1162 | * will be called repeatedly with a value (if available) | ||
1163 | * @param proc_cls closure for @a proc | ||
1164 | * @param finish_cb function to call on completion | ||
1165 | * the handle is afterwards invalid | ||
1166 | * @param finish_cb_cls closure for @a finish_cb | ||
1167 | * @return an iterator handle to use for iteration | ||
592 | */ | 1168 | */ |
593 | char * | 1169 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator * |
594 | GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token) | 1170 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
1171 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
1172 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1173 | void *error_cb_cls, | ||
1174 | GNUNET_IDENTITY_PROVIDER_TicketCallback proc, | ||
1175 | void *proc_cls, | ||
1176 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
1177 | void *finish_cb_cls) | ||
595 | { | 1178 | { |
596 | return GNUNET_strdup (token->data); | 1179 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; |
1180 | struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; | ||
1181 | struct GNUNET_MQ_Envelope *env; | ||
1182 | struct TicketIterationStartMessage *msg; | ||
1183 | uint32_t rid; | ||
1184 | |||
1185 | GNUNET_CRYPTO_ecdsa_key_get_public (identity, | ||
1186 | &identity_pub); | ||
1187 | rid = h->r_id_gen++; | ||
1188 | it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator); | ||
1189 | it->h = h; | ||
1190 | it->error_cb = error_cb; | ||
1191 | it->error_cb_cls = error_cb_cls; | ||
1192 | it->finish_cb = finish_cb; | ||
1193 | it->finish_cb_cls = finish_cb_cls; | ||
1194 | it->tr_cb = proc; | ||
1195 | it->cls = proc_cls; | ||
1196 | it->r_id = rid; | ||
1197 | GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, | ||
1198 | h->ticket_it_tail, | ||
1199 | it); | ||
1200 | env = GNUNET_MQ_msg (msg, | ||
1201 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START); | ||
1202 | msg->id = htonl (rid); | ||
1203 | msg->identity = identity_pub; | ||
1204 | msg->is_audience = htonl (GNUNET_NO); | ||
1205 | if (NULL == h->mq) | ||
1206 | it->env = env; | ||
1207 | else | ||
1208 | GNUNET_MQ_send (h->mq, | ||
1209 | env); | ||
1210 | return it; | ||
1211 | |||
597 | } | 1212 | } |
598 | 1213 | ||
1214 | |||
599 | /** | 1215 | /** |
600 | * Returns string representation of ticket. Base64-Encoded | 1216 | * Lists all tickets that have been issued to remote |
1217 | * identites (relying parties) | ||
601 | * | 1218 | * |
602 | * @param ticket the ticket | 1219 | * @param h the identity provider to use |
603 | * @return the Base64-Encoded ticket | 1220 | * @param identity the issuing identity |
1221 | * @param error_cb function to call on error (i.e. disconnect), | ||
1222 | * the handle is afterwards invalid | ||
1223 | * @param error_cb_cls closure for @a error_cb | ||
1224 | * @param proc function to call on each ticket; it | ||
1225 | * will be called repeatedly with a value (if available) | ||
1226 | * @param proc_cls closure for @a proc | ||
1227 | * @param finish_cb function to call on completion | ||
1228 | * the handle is afterwards invalid | ||
1229 | * @param finish_cb_cls closure for @a finish_cb | ||
1230 | * @return an iterator handle to use for iteration | ||
604 | */ | 1231 | */ |
605 | char * | 1232 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator * |
606 | GNUNET_IDENTITY_PROVIDER_ticket_to_string (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) | 1233 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
1234 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | ||
1235 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
1236 | void *error_cb_cls, | ||
1237 | GNUNET_IDENTITY_PROVIDER_TicketCallback proc, | ||
1238 | void *proc_cls, | ||
1239 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
1240 | void *finish_cb_cls) | ||
607 | { | 1241 | { |
608 | return GNUNET_strdup (ticket->data); | 1242 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it; |
1243 | struct GNUNET_MQ_Envelope *env; | ||
1244 | struct TicketIterationStartMessage *msg; | ||
1245 | uint32_t rid; | ||
1246 | |||
1247 | rid = h->r_id_gen++; | ||
1248 | it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_TicketIterator); | ||
1249 | it->h = h; | ||
1250 | it->error_cb = error_cb; | ||
1251 | it->error_cb_cls = error_cb_cls; | ||
1252 | it->finish_cb = finish_cb; | ||
1253 | it->finish_cb_cls = finish_cb_cls; | ||
1254 | it->tr_cb = proc; | ||
1255 | it->cls = proc_cls; | ||
1256 | it->r_id = rid; | ||
1257 | GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, | ||
1258 | h->ticket_it_tail, | ||
1259 | it); | ||
1260 | env = GNUNET_MQ_msg (msg, | ||
1261 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START); | ||
1262 | msg->id = htonl (rid); | ||
1263 | msg->identity = *identity; | ||
1264 | msg->is_audience = htonl (GNUNET_YES); | ||
1265 | if (NULL == h->mq) | ||
1266 | it->env = env; | ||
1267 | else | ||
1268 | GNUNET_MQ_send (h->mq, | ||
1269 | env); | ||
1270 | return it; | ||
1271 | |||
1272 | |||
609 | } | 1273 | } |
610 | 1274 | ||
611 | /** | 1275 | /** |
612 | * Created a ticket from a string (Base64 encoded ticket) | 1276 | * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start |
1277 | * for the next record. | ||
613 | * | 1278 | * |
614 | * @param input Base64 encoded ticket | 1279 | * @param it the iterator |
615 | * @param ticket pointer where the ticket is stored | ||
616 | * @return GNUNET_OK | ||
617 | */ | 1280 | */ |
618 | int | 1281 | void |
619 | GNUNET_IDENTITY_PROVIDER_string_to_ticket (const char* input, | 1282 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it) |
620 | struct GNUNET_IDENTITY_PROVIDER_Ticket **ticket) | ||
621 | { | 1283 | { |
622 | *ticket = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); | 1284 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; |
623 | (*ticket)->data = GNUNET_strdup (input); | 1285 | struct TicketIterationNextMessage *msg; |
624 | return GNUNET_OK; | 1286 | struct GNUNET_MQ_Envelope *env; |
1287 | |||
1288 | env = GNUNET_MQ_msg (msg, | ||
1289 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT); | ||
1290 | msg->id = htonl (it->r_id); | ||
1291 | GNUNET_MQ_send (h->mq, | ||
1292 | env); | ||
625 | } | 1293 | } |
626 | 1294 | ||
627 | 1295 | ||
628 | /** | 1296 | /** |
629 | * Destroys a ticket | 1297 | * Stops iteration and releases the idp handle for further calls. Must |
1298 | * be called on any iteration that has not yet completed prior to calling | ||
1299 | * #GNUNET_IDENTITY_PROVIDER_disconnect. | ||
630 | * | 1300 | * |
631 | * @param ticket the ticket to destroy | 1301 | * @param it the iterator |
632 | */ | 1302 | */ |
633 | void | 1303 | void |
634 | GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) | 1304 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it) |
635 | { | 1305 | { |
636 | GNUNET_assert (NULL != ticket); | 1306 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; |
637 | if (NULL != ticket->data) | 1307 | struct GNUNET_MQ_Envelope *env; |
638 | GNUNET_free (ticket->data); | 1308 | struct TicketIterationStopMessage *msg; |
639 | GNUNET_free (ticket); | 1309 | |
1310 | if (NULL != h->mq) | ||
1311 | { | ||
1312 | env = GNUNET_MQ_msg (msg, | ||
1313 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP); | ||
1314 | msg->id = htonl (it->r_id); | ||
1315 | GNUNET_MQ_send (h->mq, | ||
1316 | env); | ||
1317 | } | ||
1318 | GNUNET_free (it); | ||
640 | } | 1319 | } |
641 | 1320 | ||
1321 | /** | ||
1322 | * Revoked an issued ticket. The relying party will be unable to retrieve | ||
1323 | * updated attributes. | ||
1324 | * | ||
1325 | * @param h the identity provider to use | ||
1326 | * @param identity the issuing identity | ||
1327 | * @param ticket the ticket to revoke | ||
1328 | * @param cb the callback | ||
1329 | * @param cb_cls the callback closure | ||
1330 | * @return handle to abort the operation | ||
1331 | */ | ||
1332 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
1333 | GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
1334 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
1335 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
1336 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb, | ||
1337 | void *cb_cls) | ||
1338 | { | ||
1339 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | ||
1340 | struct GNUNET_MQ_Envelope *env; | ||
1341 | struct RevokeTicketMessage *msg; | ||
1342 | uint32_t rid; | ||
642 | 1343 | ||
1344 | rid = h->r_id_gen++; | ||
1345 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); | ||
1346 | op->h = h; | ||
1347 | op->rvk_cb = cb; | ||
1348 | op->cls = cb_cls; | ||
1349 | op->r_id = rid; | ||
1350 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, | ||
1351 | h->op_tail, | ||
1352 | op); | ||
1353 | env = GNUNET_MQ_msg_extra (msg, | ||
1354 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket), | ||
1355 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET); | ||
1356 | msg->id = htonl (rid); | ||
1357 | msg->identity = *identity; | ||
1358 | memcpy (&msg[1], | ||
1359 | ticket, | ||
1360 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); | ||
1361 | if (NULL == h->mq) | ||
1362 | op->env = env; | ||
1363 | else | ||
1364 | GNUNET_MQ_send (h->mq, | ||
1365 | env); | ||
1366 | return op; | ||
1367 | } | ||
643 | 1368 | ||
644 | 1369 | ||
645 | 1370 | ||
diff --git a/src/identity-provider/identity_token.c b/src/identity-provider/identity_token.c deleted file mode 100644 index 31249840b..000000000 --- a/src/identity-provider/identity_token.c +++ /dev/null | |||
@@ -1,964 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity-provider/identity_token.c | ||
23 | * @brief helper library to manage identity tokens | ||
24 | * @author Martin Schanzenbach | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_signatures.h" | ||
29 | #include "identity_token.h" | ||
30 | #include <jansson.h> | ||
31 | #include <inttypes.h> | ||
32 | |||
33 | #define JWT_ALG "alg" | ||
34 | |||
35 | #define JWT_ALG_VALUE "ED512" | ||
36 | |||
37 | #define JWT_TYP "typ" | ||
38 | |||
39 | #define JWT_TYP_VALUE "jwt" | ||
40 | |||
41 | /** | ||
42 | * Crypto helper functions | ||
43 | */ | ||
44 | |||
45 | static int | ||
46 | create_sym_key_from_ecdh(const struct GNUNET_HashCode *new_key_hash, | ||
47 | struct GNUNET_CRYPTO_SymmetricSessionKey *skey, | ||
48 | struct GNUNET_CRYPTO_SymmetricInitializationVector *iv) | ||
49 | { | ||
50 | struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str; | ||
51 | |||
52 | GNUNET_CRYPTO_hash_to_enc (new_key_hash, | ||
53 | &new_key_hash_str); | ||
54 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str); | ||
55 | static const char ctx_key[] = "gnuid-aes-ctx-key"; | ||
56 | GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey), | ||
57 | new_key_hash, sizeof (struct GNUNET_HashCode), | ||
58 | ctx_key, strlen (ctx_key), | ||
59 | NULL, 0); | ||
60 | static const char ctx_iv[] = "gnuid-aes-ctx-iv"; | ||
61 | GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector), | ||
62 | new_key_hash, sizeof (struct GNUNET_HashCode), | ||
63 | ctx_iv, strlen (ctx_iv), | ||
64 | NULL, 0); | ||
65 | return GNUNET_OK; | ||
66 | } | ||
67 | |||
68 | |||
69 | |||
70 | /** | ||
71 | * Decrypts data part from a token code | ||
72 | */ | ||
73 | static int | ||
74 | decrypt_str_ecdhe (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
75 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key, | ||
76 | const char *cyphertext, | ||
77 | size_t cyphertext_len, | ||
78 | char **result_str) | ||
79 | { | ||
80 | struct GNUNET_HashCode new_key_hash; | ||
81 | struct GNUNET_CRYPTO_SymmetricSessionKey enc_key; | ||
82 | struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv; | ||
83 | |||
84 | char *str_buf = GNUNET_malloc (cyphertext_len); | ||
85 | size_t str_size; | ||
86 | |||
87 | //Calculate symmetric key from ecdh parameters | ||
88 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_ecdh (priv_key, | ||
89 | ecdh_key, | ||
90 | &new_key_hash)); | ||
91 | |||
92 | create_sym_key_from_ecdh (&new_key_hash, | ||
93 | &enc_key, | ||
94 | &enc_iv); | ||
95 | |||
96 | str_size = GNUNET_CRYPTO_symmetric_decrypt (cyphertext, | ||
97 | cyphertext_len, | ||
98 | &enc_key, | ||
99 | &enc_iv, | ||
100 | str_buf); | ||
101 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
102 | "Decrypted bytes: %zd Expected bytes: %zd\n", | ||
103 | str_size, | ||
104 | cyphertext_len); | ||
105 | if (-1 == str_size) | ||
106 | { | ||
107 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH invalid\n"); | ||
108 | GNUNET_free (str_buf); | ||
109 | return GNUNET_SYSERR; | ||
110 | } | ||
111 | *result_str = GNUNET_malloc (str_size+1); | ||
112 | GNUNET_memcpy (*result_str, str_buf, str_size); | ||
113 | (*result_str)[str_size] = '\0'; | ||
114 | GNUNET_free (str_buf); | ||
115 | return GNUNET_OK; | ||
116 | |||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Decrypt string using pubkey and ECDHE | ||
121 | */ | ||
122 | static int | ||
123 | decrypt_str_ecdhe2 (const struct GNUNET_CRYPTO_EcdhePrivateKey *ecdh_privkey, | ||
124 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | ||
125 | const char *ciphertext, | ||
126 | size_t ciphertext_len, | ||
127 | char **plaintext) | ||
128 | { | ||
129 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
130 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
131 | struct GNUNET_HashCode new_key_hash; | ||
132 | |||
133 | //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt | ||
134 | *plaintext = GNUNET_malloc (ciphertext_len); | ||
135 | |||
136 | // Derived key K = H(eB) | ||
137 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (ecdh_privkey, | ||
138 | aud_key, | ||
139 | &new_key_hash)); | ||
140 | create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); | ||
141 | GNUNET_CRYPTO_symmetric_decrypt (ciphertext, | ||
142 | ciphertext_len, | ||
143 | &skey, &iv, | ||
144 | *plaintext); | ||
145 | return GNUNET_OK; | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
150 | * Encrypt string using pubkey and ECDHE | ||
151 | * Returns ECDHE pubkey to be used for decryption | ||
152 | */ | ||
153 | static int | ||
154 | encrypt_str_ecdhe (const char *plaintext, | ||
155 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub_key, | ||
156 | char **cyphertext, | ||
157 | struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, | ||
158 | struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_pubkey) | ||
159 | { | ||
160 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
161 | struct GNUNET_CRYPTO_SymmetricInitializationVector iv; | ||
162 | struct GNUNET_HashCode new_key_hash; | ||
163 | ssize_t enc_size; | ||
164 | |||
165 | // ECDH keypair E = eG | ||
166 | *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create(); | ||
167 | GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey, | ||
168 | ecdh_pubkey); | ||
169 | |||
170 | //This is true see documentation for GNUNET_CRYPTO_symmetric_encrypt | ||
171 | *cyphertext = GNUNET_malloc (strlen (plaintext)); | ||
172 | |||
173 | // Derived key K = H(eB) | ||
174 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey, | ||
175 | pub_key, | ||
176 | &new_key_hash)); | ||
177 | create_sym_key_from_ecdh(&new_key_hash, &skey, &iv); | ||
178 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting string %s\n (len=%zd)", | ||
179 | plaintext, | ||
180 | strlen (plaintext)); | ||
181 | enc_size = GNUNET_CRYPTO_symmetric_encrypt (plaintext, | ||
182 | strlen (plaintext), | ||
183 | &skey, &iv, | ||
184 | *cyphertext); | ||
185 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted (len=%zd)", enc_size); | ||
186 | return GNUNET_OK; | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Identity Token API | ||
192 | */ | ||
193 | |||
194 | |||
195 | /** | ||
196 | * Create an Identity Token | ||
197 | * | ||
198 | * @param type the JSON API resource type | ||
199 | * @param id the JSON API resource id | ||
200 | * @return a new JSON API resource or NULL on error. | ||
201 | */ | ||
202 | struct IdentityToken* | ||
203 | token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey* iss, | ||
204 | const struct GNUNET_CRYPTO_EcdsaPublicKey* aud) | ||
205 | { | ||
206 | struct IdentityToken *token; | ||
207 | char* audience; | ||
208 | char* issuer; | ||
209 | |||
210 | issuer = GNUNET_STRINGS_data_to_string_alloc (iss, | ||
211 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
212 | audience = GNUNET_STRINGS_data_to_string_alloc (aud, | ||
213 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
214 | |||
215 | token = GNUNET_malloc (sizeof (struct IdentityToken)); | ||
216 | token_add_attr (token, "iss", issuer); | ||
217 | token_add_attr (token, "aud", audience); | ||
218 | token_add_attr (token, "sub", issuer); | ||
219 | token->aud_key = *aud; | ||
220 | GNUNET_free (issuer); | ||
221 | GNUNET_free (audience); | ||
222 | return token; | ||
223 | } | ||
224 | |||
225 | void | ||
226 | token_destroy (struct IdentityToken *token) | ||
227 | { | ||
228 | struct TokenAttr *attr; | ||
229 | struct TokenAttr *tmp_attr; | ||
230 | struct TokenAttrValue *val; | ||
231 | struct TokenAttrValue *tmp_val; | ||
232 | |||
233 | for (attr = token->attr_head; NULL != attr;) | ||
234 | { | ||
235 | tmp_attr = attr->next; | ||
236 | GNUNET_CONTAINER_DLL_remove (token->attr_head, | ||
237 | token->attr_tail, | ||
238 | attr); | ||
239 | for (val = attr->val_head; NULL != val;) | ||
240 | { | ||
241 | tmp_val = val->next; | ||
242 | GNUNET_CONTAINER_DLL_remove (attr->val_head, | ||
243 | attr->val_tail, | ||
244 | val); | ||
245 | if (NULL != val->value) | ||
246 | GNUNET_free (val->value); | ||
247 | GNUNET_free (val); | ||
248 | val = tmp_val; | ||
249 | } | ||
250 | GNUNET_free (attr->name); | ||
251 | GNUNET_free (attr); | ||
252 | attr = tmp_attr; | ||
253 | } | ||
254 | |||
255 | |||
256 | GNUNET_free (token); | ||
257 | } | ||
258 | |||
259 | void | ||
260 | token_add_attr (struct IdentityToken *token, | ||
261 | const char* key, | ||
262 | const char* value) | ||
263 | { | ||
264 | struct TokenAttr *attr; | ||
265 | struct TokenAttrValue *new_val; | ||
266 | GNUNET_assert (NULL != token); | ||
267 | |||
268 | new_val = GNUNET_malloc (sizeof (struct TokenAttrValue)); | ||
269 | new_val->value = GNUNET_strdup (value); | ||
270 | for (attr = token->attr_head; NULL != attr; attr = attr->next) | ||
271 | { | ||
272 | if (0 == strcmp (key, attr->name)) | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | if (NULL == attr) | ||
277 | { | ||
278 | attr = GNUNET_malloc (sizeof (struct TokenAttr)); | ||
279 | attr->name = GNUNET_strdup (key); | ||
280 | GNUNET_CONTAINER_DLL_insert (token->attr_head, | ||
281 | token->attr_tail, | ||
282 | attr); | ||
283 | } | ||
284 | |||
285 | GNUNET_CONTAINER_DLL_insert (attr->val_head, | ||
286 | attr->val_tail, | ||
287 | new_val); | ||
288 | } | ||
289 | |||
290 | void | ||
291 | token_add_attr_int (struct IdentityToken *token, | ||
292 | const char* key, | ||
293 | uint64_t value) | ||
294 | { | ||
295 | struct TokenAttr *attr; | ||
296 | struct TokenAttrValue *new_val; | ||
297 | GNUNET_assert (NULL != token); | ||
298 | |||
299 | new_val = GNUNET_malloc (sizeof (struct TokenAttrValue)); | ||
300 | new_val->int_value = value; | ||
301 | for (attr = token->attr_head; NULL != attr; attr = attr->next) | ||
302 | { | ||
303 | if (0 == strcmp (key, attr->name)) | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | if (NULL == attr) | ||
308 | { | ||
309 | attr = GNUNET_malloc (sizeof (struct TokenAttr)); | ||
310 | attr->name = GNUNET_strdup (key); | ||
311 | GNUNET_CONTAINER_DLL_insert (token->attr_head, | ||
312 | token->attr_tail, | ||
313 | attr); | ||
314 | } | ||
315 | |||
316 | GNUNET_CONTAINER_DLL_insert (attr->val_head, | ||
317 | attr->val_tail, | ||
318 | new_val); | ||
319 | } | ||
320 | |||
321 | static void | ||
322 | parse_json_payload(const char* payload_base64, | ||
323 | struct IdentityToken *token) | ||
324 | { | ||
325 | const char *key; | ||
326 | const json_t *value; | ||
327 | const json_t *arr_value; | ||
328 | char *payload; | ||
329 | int idx; | ||
330 | json_t *payload_json; | ||
331 | json_error_t err_json; | ||
332 | |||
333 | GNUNET_STRINGS_base64_decode (payload_base64, | ||
334 | strlen (payload_base64), | ||
335 | &payload); | ||
336 | //TODO signature and aud key | ||
337 | payload_json = json_loads (payload, JSON_DECODE_ANY, &err_json); | ||
338 | |||
339 | json_object_foreach (payload_json, key, value) | ||
340 | { | ||
341 | if (json_is_array (value)) | ||
342 | { | ||
343 | json_array_foreach (value, idx, arr_value) | ||
344 | { | ||
345 | if (json_is_integer (arr_value)) | ||
346 | token_add_attr_int (token, key, | ||
347 | json_integer_value (arr_value)); | ||
348 | else | ||
349 | token_add_attr (token, | ||
350 | key, | ||
351 | json_string_value (arr_value)); | ||
352 | } | ||
353 | } else { | ||
354 | if (json_is_integer (value)) | ||
355 | token_add_attr_int (token, key, | ||
356 | json_integer_value (value)); | ||
357 | else | ||
358 | token_add_attr (token, key, json_string_value (value)); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | json_decref (payload_json); | ||
363 | GNUNET_free (payload); | ||
364 | } | ||
365 | |||
366 | int | ||
367 | token_parse2 (const char* raw_data, | ||
368 | const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key, | ||
369 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | ||
370 | struct IdentityToken **result) | ||
371 | { | ||
372 | char *enc_token_str; | ||
373 | char *tmp_buf; | ||
374 | char *token_str; | ||
375 | char *enc_token; | ||
376 | char *payload_base64; | ||
377 | size_t enc_token_len; | ||
378 | |||
379 | GNUNET_asprintf (&tmp_buf, "%s", raw_data); | ||
380 | strtok (tmp_buf, ","); | ||
381 | enc_token_str = strtok (NULL, ","); | ||
382 | |||
383 | enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str, | ||
384 | strlen (enc_token_str), | ||
385 | &enc_token); | ||
386 | if (GNUNET_OK != decrypt_str_ecdhe2 (priv_key, | ||
387 | aud_key, | ||
388 | enc_token, | ||
389 | enc_token_len, | ||
390 | &token_str)) | ||
391 | { | ||
392 | GNUNET_free (tmp_buf); | ||
393 | GNUNET_free (enc_token); | ||
394 | return GNUNET_SYSERR; | ||
395 | } | ||
396 | |||
397 | GNUNET_assert (NULL != strtok (token_str, ".")); | ||
398 | payload_base64 = strtok (NULL, "."); | ||
399 | |||
400 | *result = GNUNET_malloc (sizeof (struct IdentityToken)); | ||
401 | parse_json_payload (payload_base64, *result); | ||
402 | |||
403 | (*result)->aud_key = *aud_key; | ||
404 | GNUNET_free (enc_token); | ||
405 | GNUNET_free (token_str); | ||
406 | GNUNET_free (tmp_buf); | ||
407 | return GNUNET_OK; | ||
408 | } | ||
409 | |||
410 | int | ||
411 | token_parse (const char* raw_data, | ||
412 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
413 | struct IdentityToken **result) | ||
414 | { | ||
415 | char *ecdh_pubkey_str; | ||
416 | char *enc_token_str; | ||
417 | char *tmp_buf; | ||
418 | char *token_str; | ||
419 | char *enc_token; | ||
420 | char *payload_base64; | ||
421 | size_t enc_token_len; | ||
422 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; | ||
423 | |||
424 | GNUNET_asprintf (&tmp_buf, "%s", raw_data); | ||
425 | ecdh_pubkey_str = strtok (tmp_buf, ","); | ||
426 | enc_token_str = strtok (NULL, ","); | ||
427 | |||
428 | GNUNET_assert (NULL != ecdh_pubkey_str); | ||
429 | GNUNET_assert (NULL != enc_token_str); | ||
430 | |||
431 | GNUNET_STRINGS_string_to_data (ecdh_pubkey_str, | ||
432 | strlen (ecdh_pubkey_str), | ||
433 | &ecdh_pubkey, | ||
434 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
435 | enc_token_len = GNUNET_STRINGS_base64_decode (enc_token_str, | ||
436 | strlen (enc_token_str), | ||
437 | &enc_token); | ||
438 | if (GNUNET_OK != decrypt_str_ecdhe (priv_key, | ||
439 | &ecdh_pubkey, | ||
440 | enc_token, | ||
441 | enc_token_len, | ||
442 | &token_str)) | ||
443 | { | ||
444 | GNUNET_free (tmp_buf); | ||
445 | GNUNET_free (enc_token); | ||
446 | return GNUNET_SYSERR; | ||
447 | } | ||
448 | |||
449 | GNUNET_assert (NULL != strtok (token_str, ".")); | ||
450 | payload_base64 = strtok (NULL, "."); | ||
451 | |||
452 | *result = GNUNET_malloc (sizeof (struct IdentityToken)); | ||
453 | parse_json_payload (payload_base64, *result); | ||
454 | |||
455 | GNUNET_free (enc_token); | ||
456 | GNUNET_free (token_str); | ||
457 | GNUNET_free (tmp_buf); | ||
458 | return GNUNET_OK; | ||
459 | } | ||
460 | |||
461 | static char* | ||
462 | create_json_payload (const struct IdentityToken *token) | ||
463 | { | ||
464 | struct TokenAttr *attr; | ||
465 | struct TokenAttrValue *val; | ||
466 | json_t *root; | ||
467 | char *json_str; | ||
468 | |||
469 | root = json_object(); | ||
470 | for (attr = token->attr_head; NULL != attr; attr = attr->next) | ||
471 | { | ||
472 | for (val = attr->val_head; NULL != val; val = val->next) | ||
473 | { | ||
474 | if (NULL != val->value) | ||
475 | { | ||
476 | json_object_set_new (root, | ||
477 | attr->name, | ||
478 | json_string (val->value)); | ||
479 | } else { | ||
480 | json_object_set_new (root, | ||
481 | attr->name, | ||
482 | json_integer (val->int_value)); | ||
483 | } | ||
484 | } | ||
485 | } | ||
486 | json_str = json_dumps (root, JSON_INDENT(1)); | ||
487 | json_decref (root); | ||
488 | return json_str; | ||
489 | } | ||
490 | |||
491 | static char* | ||
492 | create_json_header(void) | ||
493 | { | ||
494 | json_t *root; | ||
495 | char *json_str; | ||
496 | |||
497 | root = json_object (); | ||
498 | json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE)); | ||
499 | json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE)); | ||
500 | |||
501 | json_str = json_dumps (root, JSON_INDENT(1)); | ||
502 | json_decref (root); | ||
503 | return json_str; | ||
504 | } | ||
505 | |||
506 | int | ||
507 | token_to_string (const struct IdentityToken *token, | ||
508 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
509 | char **result) | ||
510 | { | ||
511 | char *payload_str; | ||
512 | char *header_str; | ||
513 | char *payload_base64; | ||
514 | char *header_base64; | ||
515 | char *padding; | ||
516 | char *signature_target; | ||
517 | char *signature_str; | ||
518 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | ||
519 | header_str = create_json_header(); | ||
520 | GNUNET_STRINGS_base64_encode (header_str, | ||
521 | strlen (header_str), | ||
522 | &header_base64); | ||
523 | //Remove GNUNET padding of base64 | ||
524 | padding = strtok(header_base64, "="); | ||
525 | while (NULL != padding) | ||
526 | padding = strtok(NULL, "="); | ||
527 | |||
528 | payload_str = create_json_payload (token); | ||
529 | GNUNET_STRINGS_base64_encode (payload_str, | ||
530 | strlen (payload_str), | ||
531 | &payload_base64); | ||
532 | |||
533 | //Remove GNUNET padding of base64 | ||
534 | padding = strtok(payload_base64, "="); | ||
535 | while (NULL != padding) | ||
536 | padding = strtok(NULL, "="); | ||
537 | |||
538 | GNUNET_asprintf (&signature_target, "%s,%s", header_base64, payload_base64); | ||
539 | purpose = | ||
540 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
541 | strlen (signature_target)); | ||
542 | purpose->size = | ||
543 | htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); | ||
544 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); | ||
545 | GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target)); | ||
546 | if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, | ||
547 | purpose, | ||
548 | (struct GNUNET_CRYPTO_EcdsaSignature *)&token->signature)) | ||
549 | { | ||
550 | GNUNET_free (signature_target); | ||
551 | GNUNET_free (payload_str); | ||
552 | GNUNET_free (payload_base64); | ||
553 | GNUNET_free (header_base64); | ||
554 | GNUNET_free (purpose); | ||
555 | return GNUNET_SYSERR; | ||
556 | } | ||
557 | |||
558 | GNUNET_STRINGS_base64_encode ((const char*)&token->signature, | ||
559 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature), | ||
560 | &signature_str); | ||
561 | GNUNET_asprintf (result, "%s.%s.%s", | ||
562 | header_base64, payload_base64, signature_str); | ||
563 | GNUNET_free (signature_target); | ||
564 | GNUNET_free (payload_str); | ||
565 | GNUNET_free (header_str); | ||
566 | GNUNET_free (signature_str); | ||
567 | GNUNET_free (payload_base64); | ||
568 | GNUNET_free (header_base64); | ||
569 | GNUNET_free (purpose); | ||
570 | return GNUNET_OK; | ||
571 | } | ||
572 | |||
573 | int | ||
574 | token_serialize (const struct IdentityToken *token, | ||
575 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
576 | struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey, | ||
577 | char **result) | ||
578 | { | ||
579 | char *token_str; | ||
580 | char *enc_token; | ||
581 | char *dh_key_str; | ||
582 | char *enc_token_base64; | ||
583 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; | ||
584 | |||
585 | GNUNET_assert (GNUNET_OK == token_to_string (token, | ||
586 | priv_key, | ||
587 | &token_str)); | ||
588 | |||
589 | GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (token_str, | ||
590 | &token->aud_key, | ||
591 | &enc_token, | ||
592 | ecdh_privkey, | ||
593 | &ecdh_pubkey)); | ||
594 | GNUNET_STRINGS_base64_encode (enc_token, | ||
595 | strlen (token_str), | ||
596 | &enc_token_base64); | ||
597 | dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ecdh_pubkey, | ||
598 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
599 | GNUNET_asprintf (result, "%s,%s", dh_key_str, enc_token_base64); | ||
600 | GNUNET_free (dh_key_str); | ||
601 | GNUNET_free (enc_token_base64); | ||
602 | GNUNET_free (enc_token); | ||
603 | GNUNET_free (token_str); | ||
604 | return GNUNET_OK; | ||
605 | } | ||
606 | |||
607 | struct TokenTicketPayload* | ||
608 | ticket_payload_create (uint64_t nonce, | ||
609 | const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, | ||
610 | const char* lbl_str) | ||
611 | { | ||
612 | struct TokenTicketPayload* payload; | ||
613 | |||
614 | payload = GNUNET_malloc (sizeof (struct TokenTicketPayload)); | ||
615 | payload->nonce = nonce; | ||
616 | payload->identity_key = *identity_pkey; | ||
617 | GNUNET_asprintf (&payload->label, lbl_str, strlen (lbl_str)); | ||
618 | return payload; | ||
619 | } | ||
620 | |||
621 | void | ||
622 | ticket_payload_destroy (struct TokenTicketPayload* payload) | ||
623 | { | ||
624 | if (NULL != payload->label) | ||
625 | GNUNET_free (payload->label); | ||
626 | GNUNET_free (payload); | ||
627 | } | ||
628 | |||
629 | void | ||
630 | ticket_payload_serialize (struct TokenTicketPayload *payload, | ||
631 | char **result) | ||
632 | { | ||
633 | char* identity_key_str; | ||
634 | |||
635 | identity_key_str = GNUNET_STRINGS_data_to_string_alloc (&payload->identity_key, | ||
636 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
637 | |||
638 | GNUNET_asprintf (result, | ||
639 | "{\"nonce\": \"%"SCNu64"\",\"identity\": \"%s\",\"label\": \"%s\"}", | ||
640 | payload->nonce, identity_key_str, payload->label); | ||
641 | GNUNET_free (identity_key_str); | ||
642 | |||
643 | } | ||
644 | |||
645 | |||
646 | /** | ||
647 | * Create the token code | ||
648 | * The data is encrypted with a share ECDH derived secret using B (aud_key) | ||
649 | * and e (ecdh_privkey) | ||
650 | * The ticket also contains E (ecdh_pubkey) and a signature over the | ||
651 | * data and E | ||
652 | */ | ||
653 | struct TokenTicket* | ||
654 | ticket_create (uint64_t nonce, | ||
655 | const struct GNUNET_CRYPTO_EcdsaPublicKey* identity_pkey, | ||
656 | const char* lbl_str, | ||
657 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key) | ||
658 | { | ||
659 | struct TokenTicket *ticket; | ||
660 | struct TokenTicketPayload *code_payload; | ||
661 | |||
662 | ticket = GNUNET_malloc (sizeof (struct TokenTicket)); | ||
663 | code_payload = ticket_payload_create (nonce, | ||
664 | identity_pkey, | ||
665 | lbl_str); | ||
666 | ticket->aud_key = *aud_key; | ||
667 | ticket->payload = code_payload; | ||
668 | |||
669 | |||
670 | return ticket; | ||
671 | } | ||
672 | |||
673 | void | ||
674 | ticket_destroy (struct TokenTicket *ticket) | ||
675 | { | ||
676 | ticket_payload_destroy (ticket->payload); | ||
677 | GNUNET_free (ticket); | ||
678 | } | ||
679 | |||
680 | int | ||
681 | ticket_serialize (struct TokenTicket *ticket, | ||
682 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
683 | char **result) | ||
684 | { | ||
685 | char *code_payload_str; | ||
686 | char *enc_ticket_payload; | ||
687 | char *ticket_payload_str; | ||
688 | char *ticket_sig_str; | ||
689 | char *ticket_str; | ||
690 | char *dh_key_str; | ||
691 | char *write_ptr; | ||
692 | struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey; | ||
693 | |||
694 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | ||
695 | |||
696 | ticket_payload_serialize (ticket->payload, | ||
697 | &code_payload_str); | ||
698 | |||
699 | GNUNET_assert (GNUNET_OK == encrypt_str_ecdhe (code_payload_str, | ||
700 | &ticket->aud_key, | ||
701 | &enc_ticket_payload, | ||
702 | &ecdhe_privkey, | ||
703 | &ticket->ecdh_pubkey)); | ||
704 | |||
705 | GNUNET_free (ecdhe_privkey); | ||
706 | |||
707 | purpose = | ||
708 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
709 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E | ||
710 | strlen (code_payload_str)); // E_K (code_str) | ||
711 | purpose->size = | ||
712 | htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
713 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + | ||
714 | strlen (code_payload_str)); | ||
715 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); | ||
716 | write_ptr = (char*) &purpose[1]; | ||
717 | GNUNET_memcpy (write_ptr, | ||
718 | &ticket->ecdh_pubkey, | ||
719 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
720 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); | ||
721 | GNUNET_memcpy (write_ptr, enc_ticket_payload, strlen (code_payload_str)); | ||
722 | GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (priv_key, | ||
723 | purpose, | ||
724 | &ticket->signature)); | ||
725 | GNUNET_STRINGS_base64_encode (enc_ticket_payload, | ||
726 | strlen (code_payload_str), | ||
727 | &ticket_payload_str); | ||
728 | ticket_sig_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->signature, | ||
729 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); | ||
730 | |||
731 | dh_key_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->ecdh_pubkey, | ||
732 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
733 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s to encrypt\n", dh_key_str); | ||
734 | GNUNET_asprintf (&ticket_str, "{\"data\": \"%s\", \"ecdh\": \"%s\", \"signature\": \"%s\"}", | ||
735 | ticket_payload_str, dh_key_str, ticket_sig_str); | ||
736 | GNUNET_STRINGS_base64_encode (ticket_str, strlen (ticket_str), result); | ||
737 | GNUNET_free (dh_key_str); | ||
738 | GNUNET_free (purpose); | ||
739 | GNUNET_free (ticket_str); | ||
740 | GNUNET_free (ticket_sig_str); | ||
741 | GNUNET_free (code_payload_str); | ||
742 | GNUNET_free (enc_ticket_payload); | ||
743 | GNUNET_free (ticket_payload_str); | ||
744 | return GNUNET_OK; | ||
745 | } | ||
746 | |||
747 | int | ||
748 | ticket_payload_parse(const char *raw_data, | ||
749 | ssize_t data_len, | ||
750 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
751 | const struct GNUNET_CRYPTO_EcdhePublicKey *ecdhe_pkey, | ||
752 | struct TokenTicketPayload **result) | ||
753 | { | ||
754 | const char* label_str; | ||
755 | const char* nonce_str; | ||
756 | const char* identity_key_str; | ||
757 | |||
758 | json_t *root; | ||
759 | json_t *label_json; | ||
760 | json_t *identity_json; | ||
761 | json_t *nonce_json; | ||
762 | json_error_t err_json; | ||
763 | char* data_str; | ||
764 | uint64_t nonce; | ||
765 | struct GNUNET_CRYPTO_EcdsaPublicKey id_pkey; | ||
766 | |||
767 | if (GNUNET_OK != decrypt_str_ecdhe (priv_key, | ||
768 | ecdhe_pkey, | ||
769 | raw_data, | ||
770 | data_len, | ||
771 | &data_str)) | ||
772 | { | ||
773 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Data decryption failed\n"); | ||
774 | return GNUNET_SYSERR; | ||
775 | } | ||
776 | |||
777 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data: %s\n", data_str); | ||
778 | root = json_loads (data_str, JSON_DECODE_ANY, &err_json); | ||
779 | if (!root) | ||
780 | { | ||
781 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
782 | "Error parsing data: %s\n", err_json.text); | ||
783 | GNUNET_free (data_str); | ||
784 | return GNUNET_SYSERR; | ||
785 | } | ||
786 | |||
787 | identity_json = json_object_get (root, "identity"); | ||
788 | if (!json_is_string (identity_json)) | ||
789 | { | ||
790 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
791 | "Error parsing data: %s\n", err_json.text); | ||
792 | json_decref (root); | ||
793 | GNUNET_free (data_str); | ||
794 | return GNUNET_SYSERR; | ||
795 | } | ||
796 | identity_key_str = json_string_value (identity_json); | ||
797 | GNUNET_STRINGS_string_to_data (identity_key_str, | ||
798 | strlen (identity_key_str), | ||
799 | &id_pkey, | ||
800 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
801 | |||
802 | |||
803 | label_json = json_object_get (root, "label"); | ||
804 | if (!json_is_string (label_json)) | ||
805 | { | ||
806 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
807 | "Error parsing data: %s\n", err_json.text); | ||
808 | json_decref (root); | ||
809 | GNUNET_free (data_str); | ||
810 | return GNUNET_SYSERR; | ||
811 | } | ||
812 | |||
813 | label_str = json_string_value (label_json); | ||
814 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found label: %s\n", label_str); | ||
815 | |||
816 | nonce_json = json_object_get (root, "nonce"); | ||
817 | if (!json_is_string (label_json)) | ||
818 | { | ||
819 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
820 | "Error parsing data: %s\n", err_json.text); | ||
821 | json_decref (root); | ||
822 | GNUNET_free (data_str); | ||
823 | return GNUNET_SYSERR; | ||
824 | } | ||
825 | |||
826 | nonce_str = json_string_value (nonce_json); | ||
827 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found nonce: %s\n", nonce_str); | ||
828 | |||
829 | GNUNET_assert (0 != sscanf (nonce_str, "%"SCNu64, &nonce)); | ||
830 | |||
831 | *result = ticket_payload_create (nonce, | ||
832 | (const struct GNUNET_CRYPTO_EcdsaPublicKey*)&id_pkey, | ||
833 | label_str); | ||
834 | GNUNET_free (data_str); | ||
835 | json_decref (root); | ||
836 | return GNUNET_OK; | ||
837 | |||
838 | } | ||
839 | |||
840 | int | ||
841 | ticket_parse (const char *raw_data, | ||
842 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
843 | struct TokenTicket **result) | ||
844 | { | ||
845 | const char* enc_data_str; | ||
846 | const char* ecdh_enc_str; | ||
847 | const char* signature_enc_str; | ||
848 | |||
849 | json_t *root; | ||
850 | json_t *signature_json; | ||
851 | json_t *ecdh_json; | ||
852 | json_t *enc_data_json; | ||
853 | json_error_t err_json; | ||
854 | char* enc_data; | ||
855 | char* ticket_decoded; | ||
856 | char* write_ptr; | ||
857 | size_t enc_data_len; | ||
858 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | ||
859 | struct TokenTicket *ticket; | ||
860 | struct TokenTicketPayload *ticket_payload; | ||
861 | |||
862 | ticket_decoded = NULL; | ||
863 | GNUNET_STRINGS_base64_decode (raw_data, strlen (raw_data), &ticket_decoded); | ||
864 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ticket: %s\n", ticket_decoded); | ||
865 | root = json_loads (ticket_decoded, JSON_DECODE_ANY, &err_json); | ||
866 | if (!root) | ||
867 | { | ||
868 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
869 | "%s\n", err_json.text); | ||
870 | return GNUNET_SYSERR; | ||
871 | } | ||
872 | |||
873 | signature_json = json_object_get (root, "signature"); | ||
874 | ecdh_json = json_object_get (root, "ecdh"); | ||
875 | enc_data_json = json_object_get (root, "data"); | ||
876 | |||
877 | signature_enc_str = json_string_value (signature_json); | ||
878 | ecdh_enc_str = json_string_value (ecdh_json); | ||
879 | enc_data_str = json_string_value (enc_data_json); | ||
880 | |||
881 | ticket = GNUNET_malloc (sizeof (struct TokenTicket)); | ||
882 | |||
883 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (ecdh_enc_str, | ||
884 | strlen (ecdh_enc_str), | ||
885 | &ticket->ecdh_pubkey, | ||
886 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey))) | ||
887 | { | ||
888 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH PKEY %s invalid in data\n", ecdh_enc_str); | ||
889 | json_decref (root); | ||
890 | GNUNET_free (ticket); | ||
891 | return GNUNET_SYSERR; | ||
892 | } | ||
893 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using ECDH pubkey %s for data decryption\n", ecdh_enc_str); | ||
894 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (signature_enc_str, | ||
895 | strlen (signature_enc_str), | ||
896 | &ticket->signature, | ||
897 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature))) | ||
898 | { | ||
899 | json_decref (root); | ||
900 | GNUNET_free (ticket_decoded); | ||
901 | GNUNET_free (ticket); | ||
902 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ECDH signature invalid in data\n"); | ||
903 | return GNUNET_SYSERR; | ||
904 | } | ||
905 | |||
906 | enc_data_len = GNUNET_STRINGS_base64_decode (enc_data_str, | ||
907 | strlen (enc_data_str), | ||
908 | &enc_data); | ||
909 | |||
910 | |||
911 | if (GNUNET_OK != ticket_payload_parse (enc_data, | ||
912 | enc_data_len, | ||
913 | priv_key, | ||
914 | (const struct GNUNET_CRYPTO_EcdhePublicKey*)&ticket->ecdh_pubkey, | ||
915 | &ticket_payload)) | ||
916 | { | ||
917 | json_decref (root); | ||
918 | GNUNET_free (enc_data); | ||
919 | GNUNET_free (ticket_decoded); | ||
920 | GNUNET_free (ticket); | ||
921 | return GNUNET_SYSERR; | ||
922 | } | ||
923 | |||
924 | ticket->payload = ticket_payload; | ||
925 | purpose = | ||
926 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
927 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + //E | ||
928 | enc_data_len); // E_K (code_str) | ||
929 | purpose->size = | ||
930 | htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
931 | sizeof (struct GNUNET_CRYPTO_EcdhePublicKey) + | ||
932 | enc_data_len); | ||
933 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET); | ||
934 | write_ptr = (char*) &purpose[1]; | ||
935 | GNUNET_memcpy (write_ptr, &ticket->ecdh_pubkey, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); | ||
936 | write_ptr += sizeof (struct GNUNET_CRYPTO_EcdhePublicKey); | ||
937 | GNUNET_memcpy (write_ptr, enc_data, enc_data_len); | ||
938 | |||
939 | if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify (GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET, | ||
940 | purpose, | ||
941 | &ticket->signature, | ||
942 | &ticket_payload->identity_key)) | ||
943 | { | ||
944 | ticket_destroy (ticket); | ||
945 | GNUNET_free (ticket_decoded); | ||
946 | json_decref (root); | ||
947 | GNUNET_free (purpose); | ||
948 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
949 | "Error verifying signature for ticket\n"); | ||
950 | return GNUNET_SYSERR; | ||
951 | } | ||
952 | *result = ticket; | ||
953 | GNUNET_free (purpose); | ||
954 | |||
955 | GNUNET_free (enc_data); | ||
956 | GNUNET_free (ticket_decoded); | ||
957 | json_decref (root); | ||
958 | return GNUNET_OK; | ||
959 | |||
960 | } | ||
961 | |||
962 | |||
963 | |||
964 | /* end of identity_token.c */ | ||
diff --git a/src/identity-provider/identity_token.h b/src/identity-provider/identity_token.h deleted file mode 100644 index 7ded6662e..000000000 --- a/src/identity-provider/identity_token.h +++ /dev/null | |||
@@ -1,346 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @author Martin Schanzenbach | ||
22 | * @file identity-provider/identity_token.h | ||
23 | * @brief GNUnet Identity Provider library | ||
24 | * | ||
25 | */ | ||
26 | #ifndef IDENTITY_TOKEN_H | ||
27 | #define IDENTITY_TOKEN_H | ||
28 | |||
29 | #include "gnunet_crypto_lib.h" | ||
30 | #include <jansson.h> | ||
31 | |||
32 | struct IdentityToken | ||
33 | { | ||
34 | /** | ||
35 | * DLL | ||
36 | */ | ||
37 | struct TokenAttr *attr_head; | ||
38 | |||
39 | /** | ||
40 | * DLL | ||
41 | */ | ||
42 | struct TokenAttr *attr_tail; | ||
43 | |||
44 | /** | ||
45 | * Token Signature | ||
46 | */ | ||
47 | struct GNUNET_CRYPTO_EcdsaSignature signature; | ||
48 | |||
49 | /** | ||
50 | * Audience Pubkey | ||
51 | */ | ||
52 | struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; | ||
53 | }; | ||
54 | |||
55 | struct TokenAttr | ||
56 | { | ||
57 | /** | ||
58 | * DLL | ||
59 | */ | ||
60 | struct TokenAttr *next; | ||
61 | |||
62 | /** | ||
63 | * DLL | ||
64 | */ | ||
65 | struct TokenAttr *prev; | ||
66 | |||
67 | /** | ||
68 | * Attribute name | ||
69 | */ | ||
70 | char *name; | ||
71 | |||
72 | /** | ||
73 | * Attribute value DLL | ||
74 | */ | ||
75 | struct TokenAttrValue *val_head; | ||
76 | |||
77 | /** | ||
78 | * Attribute value DLL | ||
79 | */ | ||
80 | struct TokenAttrValue *val_tail; | ||
81 | |||
82 | }; | ||
83 | |||
84 | struct TokenAttrValue | ||
85 | { | ||
86 | /** | ||
87 | * DLL | ||
88 | */ | ||
89 | struct TokenAttrValue *next; | ||
90 | |||
91 | /** | ||
92 | * DLL | ||
93 | */ | ||
94 | struct TokenAttrValue *prev; | ||
95 | |||
96 | /** | ||
97 | * Attribute value | ||
98 | */ | ||
99 | char *value; | ||
100 | |||
101 | /** | ||
102 | * Attribute int value | ||
103 | * used if NULL == value | ||
104 | */ | ||
105 | uint64_t int_value; | ||
106 | }; | ||
107 | |||
108 | struct TokenTicketPayload | ||
109 | { | ||
110 | /** | ||
111 | * Nonce | ||
112 | */ | ||
113 | uint64_t nonce; | ||
114 | |||
115 | /** | ||
116 | * Label | ||
117 | */ | ||
118 | char *label; | ||
119 | |||
120 | /** | ||
121 | * Issuing Identity | ||
122 | */ | ||
123 | struct GNUNET_CRYPTO_EcdsaPublicKey identity_key; | ||
124 | }; | ||
125 | |||
126 | |||
127 | struct TokenTicket | ||
128 | { | ||
129 | /** | ||
130 | * Meta info | ||
131 | */ | ||
132 | struct TokenTicketPayload *payload; | ||
133 | |||
134 | /** | ||
135 | * ECDH Pubkey | ||
136 | */ | ||
137 | struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey; | ||
138 | |||
139 | /** | ||
140 | * Signature | ||
141 | */ | ||
142 | struct GNUNET_CRYPTO_EcdsaSignature signature; | ||
143 | |||
144 | /** | ||
145 | * Target identity | ||
146 | */ | ||
147 | struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; | ||
148 | }; | ||
149 | |||
150 | |||
151 | |||
152 | /** | ||
153 | * Create an identity token | ||
154 | * | ||
155 | * @param iss the issuer string for the token | ||
156 | * @param aud the audience of the token | ||
157 | * | ||
158 | * @return a new token | ||
159 | */ | ||
160 | struct IdentityToken* | ||
161 | token_create (const struct GNUNET_CRYPTO_EcdsaPublicKey *iss, | ||
162 | const struct GNUNET_CRYPTO_EcdsaPublicKey* aud); | ||
163 | |||
164 | /** | ||
165 | * Destroy an identity token | ||
166 | * | ||
167 | * @param token the token to destroy | ||
168 | */ | ||
169 | void | ||
170 | token_destroy (struct IdentityToken*token); | ||
171 | |||
172 | /** | ||
173 | * Add a new key value pair to the token | ||
174 | * | ||
175 | * @param token the token to modify | ||
176 | * @param key the key | ||
177 | * @param value the value | ||
178 | */ | ||
179 | void | ||
180 | token_add_attr (struct IdentityToken *token, | ||
181 | const char* key, | ||
182 | const char* value); | ||
183 | |||
184 | /** | ||
185 | * Add a new key value pair to the token | ||
186 | * | ||
187 | * @param token the token to modify | ||
188 | * @param key the key | ||
189 | * @param value the value | ||
190 | */ | ||
191 | void | ||
192 | token_add_attr_int (struct IdentityToken *token, | ||
193 | const char* key, | ||
194 | uint64_t value); | ||
195 | |||
196 | |||
197 | |||
198 | /** | ||
199 | * Add a value to a TokenAttribute | ||
200 | * | ||
201 | * @param attr the token attribute | ||
202 | * @param value value to add | ||
203 | */ | ||
204 | void | ||
205 | token_attr_add_value (const struct TokenAttr *attr, | ||
206 | const char *value); | ||
207 | |||
208 | /** | ||
209 | * Add a new key value pair to the token with the value as json | ||
210 | * | ||
211 | * @param the token to modify | ||
212 | * @param key the key | ||
213 | * @param value the value | ||
214 | * | ||
215 | */ | ||
216 | void | ||
217 | token_add_json (const struct IdentityToken *token, | ||
218 | const char* key, | ||
219 | json_t* value); | ||
220 | |||
221 | /** | ||
222 | * Serialize a token. The token will be signed and base64 according to the | ||
223 | * JWT format. The signature is base32-encoded ECDSA. | ||
224 | * The resulting JWT is encrypted using | ||
225 | * ECDHE for the audience and Base64 | ||
226 | * encoded in result. The audience requires the ECDHE public key P | ||
227 | * to decrypt the token T. The key P is included in the result and prepended | ||
228 | * before the token | ||
229 | * | ||
230 | * @param token the token to serialize | ||
231 | * @param priv_key the private key used to sign the token | ||
232 | * @param ecdhe_privkey the ECDHE private key used to encrypt the token | ||
233 | * @param result P,Base64(E(T)) | ||
234 | * | ||
235 | * @return GNUNET_OK on success | ||
236 | */ | ||
237 | int | ||
238 | token_serialize (const struct IdentityToken*token, | ||
239 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
240 | struct GNUNET_CRYPTO_EcdhePrivateKey **ecdhe_privkey, | ||
241 | char **result); | ||
242 | |||
243 | /** | ||
244 | * Parses the serialized token and returns a token | ||
245 | * | ||
246 | * @param data the serialized token | ||
247 | * @param priv_key the private key of the audience | ||
248 | * @param result the token | ||
249 | * | ||
250 | * @return GNUNET_OK on success | ||
251 | */ | ||
252 | int | ||
253 | token_parse (const char* data, | ||
254 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
255 | struct IdentityToken **result); | ||
256 | |||
257 | /** | ||
258 | * Parses the serialized token and returns a token | ||
259 | * This variant is intended for the party that issued the token and also | ||
260 | * wants to decrypt the serialized token. | ||
261 | * | ||
262 | * @param data the serialized token | ||
263 | * @param priv_key the private (!) ECDHE key | ||
264 | * @param aud_key the identity of the audience | ||
265 | * @param result the token | ||
266 | * | ||
267 | * @return GNUNET_OK on success | ||
268 | */ | ||
269 | int | ||
270 | token_parse2 (const char* data, | ||
271 | const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_key, | ||
272 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | ||
273 | struct IdentityToken **result); | ||
274 | |||
275 | |||
276 | /** | ||
277 | * | ||
278 | * Returns a JWT-string representation of the token | ||
279 | * | ||
280 | * @param token the token | ||
281 | * @param priv_key the private key used to sign the JWT | ||
282 | * @param result the JWT | ||
283 | * | ||
284 | * @return GNUNET_OK on success | ||
285 | */ | ||
286 | int | ||
287 | token_to_string (const struct IdentityToken *token, | ||
288 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
289 | char **result); | ||
290 | |||
291 | /** | ||
292 | * | ||
293 | * Creates a ticket that can be exchanged by the audience for | ||
294 | * the token. The token must be placed under the label | ||
295 | * | ||
296 | * @param nonce nonce provided by the audience that requested the ticket | ||
297 | * @param iss_pkey the issuer pubkey used to sign the ticket | ||
298 | * @param label the label encoded in the ticket | ||
299 | * @param aud_ley the audience pubkey used to encrypt the ticket payload | ||
300 | * | ||
301 | * @return the ticket | ||
302 | */ | ||
303 | struct TokenTicket* | ||
304 | ticket_create (uint64_t nonce, | ||
305 | const struct GNUNET_CRYPTO_EcdsaPublicKey* iss_pkey, | ||
306 | const char* lbl_str, | ||
307 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key); | ||
308 | |||
309 | /** | ||
310 | * Serialize a ticket. Returns the Base64 representation of the ticket. | ||
311 | * Format: Base64( { payload: E(Payload), ecdhe: K, signature: signature } ) | ||
312 | * | ||
313 | * @param ticket the ticket to serialize | ||
314 | * @param priv_key the issuer private key to sign the ticket payload | ||
315 | * @param result the serialized ticket | ||
316 | * | ||
317 | * @return GNUNET_OK on success | ||
318 | */ | ||
319 | int | ||
320 | ticket_serialize (struct TokenTicket *ticket, | ||
321 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
322 | char **result); | ||
323 | |||
324 | /** | ||
325 | * Destroys a ticket | ||
326 | * | ||
327 | * @param the ticket to destroy | ||
328 | */ | ||
329 | void | ||
330 | ticket_destroy (struct TokenTicket *ticket); | ||
331 | |||
332 | /** | ||
333 | * Parses a serialized ticket | ||
334 | * | ||
335 | * @param data the serialized ticket | ||
336 | * @param priv_key the audience private key | ||
337 | * @param ticket the ticket | ||
338 | * | ||
339 | * @return GNUNET_OK on success | ||
340 | */ | ||
341 | int | ||
342 | ticket_parse (const char* raw_data, | ||
343 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key, | ||
344 | struct TokenTicket **ticket); | ||
345 | |||
346 | #endif | ||
diff --git a/src/identity-provider/jwt.c b/src/identity-provider/jwt.c new file mode 100644 index 000000000..2f1e3240b --- /dev/null +++ b/src/identity-provider/jwt.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010-2015 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity-provider/jwt.c | ||
23 | * @brief helper library for JSON-Web-Tokens | ||
24 | * @author Martin Schanzenbach | ||
25 | */ | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_signatures.h" | ||
29 | #include "gnunet_identity_attribute_lib.h" | ||
30 | #include <jansson.h> | ||
31 | |||
32 | |||
33 | #define JWT_ALG "alg" | ||
34 | |||
35 | /*TODO is this the correct way to define new algs? */ | ||
36 | #define JWT_ALG_VALUE "ED512" | ||
37 | |||
38 | #define JWT_TYP "typ" | ||
39 | |||
40 | #define JWT_TYP_VALUE "jwt" | ||
41 | |||
42 | static char* | ||
43 | create_jwt_header(void) | ||
44 | { | ||
45 | json_t *root; | ||
46 | char *json_str; | ||
47 | |||
48 | root = json_object (); | ||
49 | json_object_set_new (root, JWT_ALG, json_string (JWT_ALG_VALUE)); | ||
50 | json_object_set_new (root, JWT_TYP, json_string (JWT_TYP_VALUE)); | ||
51 | |||
52 | json_str = json_dumps (root, JSON_INDENT(1)); | ||
53 | json_decref (root); | ||
54 | return json_str; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Create a JWT from attributes | ||
59 | * | ||
60 | * @param sub_key the public of the subject | ||
61 | * @param attrs the attribute list | ||
62 | * @param priv_key the key used to sign the JWT | ||
63 | * @return a new base64-encoded JWT string. | ||
64 | */ | ||
65 | char* | ||
66 | jwt_create_from_list (const struct GNUNET_CRYPTO_EcdsaPublicKey *sub_key, | ||
67 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
68 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key) | ||
69 | { | ||
70 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | ||
71 | struct GNUNET_CRYPTO_EcdsaPublicKey iss_key; | ||
72 | struct GNUNET_CRYPTO_EcdsaSignature signature; | ||
73 | struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; | ||
74 | char* audience; | ||
75 | char* issuer; | ||
76 | char* header; | ||
77 | char* padding; | ||
78 | char* body_str; | ||
79 | char* result; | ||
80 | char* header_base64; | ||
81 | char* body_base64; | ||
82 | char* signature_target; | ||
83 | char* signature_base64; | ||
84 | char* attr_val_str; | ||
85 | json_t* body; | ||
86 | |||
87 | GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &iss_key); | ||
88 | /* TODO maybe we should use a local identity here */ | ||
89 | issuer = GNUNET_STRINGS_data_to_string_alloc (&iss_key, | ||
90 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
91 | audience = GNUNET_STRINGS_data_to_string_alloc (sub_key, | ||
92 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
93 | header = create_jwt_header (); | ||
94 | body = json_object (); | ||
95 | /* TODO who is the issuer? local IdP or subject ? See self-issued tokens? */ | ||
96 | json_object_set_new (body, | ||
97 | "iss", json_string (issuer)); | ||
98 | json_object_set_new (body, | ||
99 | "sub", json_string (issuer)); | ||
100 | /* TODO what should be in here exactly? */ | ||
101 | json_object_set_new (body, | ||
102 | "aud", json_string (audience)); | ||
103 | for (le = attrs->list_head; NULL != le; le = le->next) | ||
104 | { | ||
105 | /** | ||
106 | * TODO here we should have a function that | ||
107 | * calls the Attribute plugins to create a | ||
108 | * json representation for its value | ||
109 | */ | ||
110 | attr_val_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (le->claim->type, | ||
111 | le->claim->data, | ||
112 | le->claim->data_size); | ||
113 | json_object_set_new (body, | ||
114 | le->claim->name, | ||
115 | json_string (attr_val_str)); | ||
116 | GNUNET_free (attr_val_str); | ||
117 | } | ||
118 | body_str = json_dumps (body, JSON_INDENT(0)); | ||
119 | json_decref (body); | ||
120 | |||
121 | GNUNET_STRINGS_base64_encode (header, | ||
122 | strlen (header), | ||
123 | &header_base64); | ||
124 | //Remove GNUNET padding of base64 | ||
125 | padding = strtok(header_base64, "="); | ||
126 | while (NULL != padding) | ||
127 | padding = strtok(NULL, "="); | ||
128 | |||
129 | GNUNET_STRINGS_base64_encode (body_str, | ||
130 | strlen (body_str), | ||
131 | &body_base64); | ||
132 | |||
133 | //Remove GNUNET padding of base64 | ||
134 | padding = strtok(body_base64, "="); | ||
135 | while (NULL != padding) | ||
136 | padding = strtok(NULL, "="); | ||
137 | |||
138 | GNUNET_free (issuer); | ||
139 | GNUNET_free (audience); | ||
140 | |||
141 | /** | ||
142 | * TODO | ||
143 | * Creating the JWT signature. This might not be | ||
144 | * standards compliant, check. | ||
145 | */ | ||
146 | GNUNET_asprintf (&signature_target, "%s,%s", header_base64, body_base64); | ||
147 | |||
148 | purpose = | ||
149 | GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + | ||
150 | strlen (signature_target)); | ||
151 | purpose->size = | ||
152 | htonl (strlen (signature_target) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose)); | ||
153 | purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN); | ||
154 | GNUNET_memcpy (&purpose[1], signature_target, strlen (signature_target)); | ||
155 | if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key, | ||
156 | purpose, | ||
157 | (struct GNUNET_CRYPTO_EcdsaSignature *)&signature)) | ||
158 | { | ||
159 | GNUNET_free (signature_target); | ||
160 | GNUNET_free (body_str); | ||
161 | GNUNET_free (body_base64); | ||
162 | GNUNET_free (header_base64); | ||
163 | GNUNET_free (purpose); | ||
164 | return NULL; | ||
165 | } | ||
166 | GNUNET_STRINGS_base64_encode ((const char*)&signature, | ||
167 | sizeof (struct GNUNET_CRYPTO_EcdsaSignature), | ||
168 | &signature_base64); | ||
169 | GNUNET_asprintf (&result, "%s.%s.%s", | ||
170 | header_base64, body_base64, signature_base64); | ||
171 | |||
172 | GNUNET_free (signature_target); | ||
173 | GNUNET_free (header); | ||
174 | GNUNET_free (body_str); | ||
175 | GNUNET_free (signature_base64); | ||
176 | GNUNET_free (body_base64); | ||
177 | GNUNET_free (header_base64); | ||
178 | GNUNET_free (purpose); | ||
179 | return result; | ||
180 | } | ||
diff --git a/src/identity/plugin_gnsrecord_identity.c b/src/identity-provider/plugin_gnsrecord_identity_provider.c index c26c04074..6ed0b0852 100644 --- a/src/identity/plugin_gnsrecord_identity.c +++ b/src/identity-provider/plugin_gnsrecord_identity_provider.c | |||
@@ -19,9 +19,9 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file identity/plugin_gnsrecord_identity.c | 22 | * @file identity-provider/plugin_gnsrecord_identity_provider.c |
23 | * @brief gnsrecord plugin to provide the API for identity records | 23 | * @brief gnsrecord plugin to provide the API for identity records |
24 | * @author Christian Grothoff | 24 | * @author Martin Schanzenbach |
25 | */ | 25 | */ |
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
@@ -54,9 +54,13 @@ value_to_string (void *cls, | |||
54 | switch (type) | 54 | switch (type) |
55 | { | 55 | { |
56 | case GNUNET_GNSRECORD_TYPE_ID_ATTR: | 56 | case GNUNET_GNSRECORD_TYPE_ID_ATTR: |
57 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN: | 57 | return GNUNET_STRINGS_data_to_string_alloc (data, data_size); |
58 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN: //DEPRECATED | ||
58 | return GNUNET_strndup (data, data_size); | 59 | return GNUNET_strndup (data, data_size); |
59 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA: | 60 | case GNUNET_GNSRECORD_TYPE_ABE_KEY: |
61 | case GNUNET_GNSRECORD_TYPE_ABE_MASTER: | ||
62 | return GNUNET_STRINGS_data_to_string_alloc (data, data_size); | ||
63 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA: //DEPRECATED | ||
60 | ecdhe_privkey = data; | 64 | ecdhe_privkey = data; |
61 | audience_pubkey = data+sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey); | 65 | audience_pubkey = data+sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey); |
62 | scopes = (char*) audience_pubkey+(sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | 66 | scopes = (char*) audience_pubkey+(sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); |
@@ -106,12 +110,22 @@ string_to_value (void *cls, | |||
106 | switch (type) | 110 | switch (type) |
107 | { | 111 | { |
108 | case GNUNET_GNSRECORD_TYPE_ID_ATTR: | 112 | case GNUNET_GNSRECORD_TYPE_ID_ATTR: |
113 | return GNUNET_STRINGS_string_to_data (s, | ||
114 | strlen (s), | ||
115 | *data, | ||
116 | *data_size); | ||
109 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN: | 117 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN: |
110 | *data = GNUNET_strdup (s); | 118 | *data = GNUNET_strdup (s); |
111 | *data_size = strlen (s); | 119 | *data_size = strlen (s); |
112 | return GNUNET_OK; | 120 | return GNUNET_OK; |
121 | case GNUNET_GNSRECORD_TYPE_ABE_KEY: | ||
122 | case GNUNET_GNSRECORD_TYPE_ABE_MASTER: | ||
123 | return GNUNET_STRINGS_string_to_data (s, | ||
124 | strlen (s), | ||
125 | *data, | ||
126 | *data_size); | ||
113 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA: | 127 | case GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA: |
114 | tmp_tok = GNUNET_strdup (s); | 128 | tmp_tok = GNUNET_strdup (s); |
115 | ecdhe_str = strtok (tmp_tok, ";"); | 129 | ecdhe_str = strtok (tmp_tok, ";"); |
116 | if (NULL == ecdhe_str) | 130 | if (NULL == ecdhe_str) |
117 | { | 131 | { |
@@ -160,15 +174,17 @@ string_to_value (void *cls, | |||
160 | * Mapping of record type numbers to human-readable | 174 | * Mapping of record type numbers to human-readable |
161 | * record type names. | 175 | * record type names. |
162 | */ | 176 | */ |
163 | static struct { | 177 | static struct { |
164 | const char *name; | 178 | const char *name; |
165 | uint32_t number; | 179 | uint32_t number; |
166 | } name_map[] = { | 180 | } name_map[] = { |
167 | { "ID_ATTR", GNUNET_GNSRECORD_TYPE_ID_ATTR }, | 181 | { "ID_ATTR", GNUNET_GNSRECORD_TYPE_ID_ATTR }, |
168 | { "ID_TOKEN", GNUNET_GNSRECORD_TYPE_ID_TOKEN }, | 182 | { "ID_TOKEN", GNUNET_GNSRECORD_TYPE_ID_TOKEN }, |
169 | { "ID_TOKEN_METADATA", GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA }, | 183 | { "ABE_KEY", GNUNET_GNSRECORD_TYPE_ABE_KEY }, |
170 | { NULL, UINT32_MAX } | 184 | { "ABE_MASTER", GNUNET_GNSRECORD_TYPE_ABE_MASTER }, |
171 | }; | 185 | { "ID_TOKEN_METADATA", GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA }, |
186 | { NULL, UINT32_MAX } | ||
187 | }; | ||
172 | 188 | ||
173 | 189 | ||
174 | /** | 190 | /** |
@@ -220,7 +236,7 @@ number_to_typename (void *cls, | |||
220 | * @return the exported block API | 236 | * @return the exported block API |
221 | */ | 237 | */ |
222 | void * | 238 | void * |
223 | libgnunet_plugin_gnsrecord_identity_init (void *cls) | 239 | libgnunet_plugin_gnsrecord_identity_provider_init (void *cls) |
224 | { | 240 | { |
225 | struct GNUNET_GNSRECORD_PluginFunctions *api; | 241 | struct GNUNET_GNSRECORD_PluginFunctions *api; |
226 | 242 | ||
@@ -240,7 +256,7 @@ libgnunet_plugin_gnsrecord_identity_init (void *cls) | |||
240 | * @return NULL | 256 | * @return NULL |
241 | */ | 257 | */ |
242 | void * | 258 | void * |
243 | libgnunet_plugin_gnsrecord_identity_done (void *cls) | 259 | libgnunet_plugin_gnsrecord_identity_provider_done (void *cls) |
244 | { | 260 | { |
245 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; | 261 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; |
246 | 262 | ||
diff --git a/src/identity-provider/plugin_identity_provider_sqlite.c b/src/identity-provider/plugin_identity_provider_sqlite.c new file mode 100644 index 000000000..0071528b9 --- /dev/null +++ b/src/identity-provider/plugin_identity_provider_sqlite.c | |||
@@ -0,0 +1,736 @@ | |||
1 | /* | ||
2 | * This file is part of GNUnet | ||
3 | * Copyright (C) 2009-2017 GNUnet e.V. | ||
4 | * | ||
5 | * GNUnet is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published | ||
7 | * by the Free Software Foundation; either version 3, or (at your | ||
8 | * 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 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with GNUnet; see the file COPYING. If not, write to the | ||
17 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | * Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity-provider/plugin_identity_provider_sqlite.c | ||
23 | * @brief sqlite-based idp backend | ||
24 | * @author Martin Schanzenbach | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_identity_provider_service.h" | ||
29 | #include "gnunet_identity_provider_plugin.h" | ||
30 | #include "gnunet_identity_attribute_lib.h" | ||
31 | #include "gnunet_sq_lib.h" | ||
32 | #include <sqlite3.h> | ||
33 | |||
34 | /** | ||
35 | * After how many ms "busy" should a DB operation fail for good? A | ||
36 | * low value makes sure that we are more responsive to requests | ||
37 | * (especially PUTs). A high value guarantees a higher success rate | ||
38 | * (SELECTs in iterate can take several seconds despite LIMIT=1). | ||
39 | * | ||
40 | * The default value of 1s should ensure that users do not experience | ||
41 | * huge latencies while at the same time allowing operations to | ||
42 | * succeed with reasonable probability. | ||
43 | */ | ||
44 | #define BUSY_TIMEOUT_MS 1000 | ||
45 | |||
46 | |||
47 | /** | ||
48 | * Log an error message at log-level 'level' that indicates | ||
49 | * a failure of the command 'cmd' on file 'filename' | ||
50 | * with the message given by strerror(errno). | ||
51 | */ | ||
52 | #define LOG_SQLITE(db, level, cmd) do { GNUNET_log_from (level, "identity-provider", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0) | ||
53 | |||
54 | #define LOG(kind,...) GNUNET_log_from (kind, "identity-provider-sqlite", __VA_ARGS__) | ||
55 | |||
56 | |||
57 | /** | ||
58 | * Context for all functions in this plugin. | ||
59 | */ | ||
60 | struct Plugin | ||
61 | { | ||
62 | |||
63 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
64 | |||
65 | /** | ||
66 | * Database filename. | ||
67 | */ | ||
68 | char *fn; | ||
69 | |||
70 | /** | ||
71 | * Native SQLite database handle. | ||
72 | */ | ||
73 | sqlite3 *dbh; | ||
74 | |||
75 | /** | ||
76 | * Precompiled SQL to store ticket. | ||
77 | */ | ||
78 | sqlite3_stmt *store_ticket; | ||
79 | |||
80 | /** | ||
81 | * Precompiled SQL to delete existing ticket. | ||
82 | */ | ||
83 | sqlite3_stmt *delete_ticket; | ||
84 | |||
85 | /** | ||
86 | * Precompiled SQL to iterate tickets. | ||
87 | */ | ||
88 | sqlite3_stmt *iterate_tickets; | ||
89 | |||
90 | /** | ||
91 | * Precompiled SQL to get ticket attributes. | ||
92 | */ | ||
93 | sqlite3_stmt *get_ticket_attrs; | ||
94 | |||
95 | /** | ||
96 | * Precompiled SQL to iterate tickets by audience. | ||
97 | */ | ||
98 | sqlite3_stmt *iterate_tickets_by_audience; | ||
99 | }; | ||
100 | |||
101 | |||
102 | /** | ||
103 | * @brief Prepare a SQL statement | ||
104 | * | ||
105 | * @param dbh handle to the database | ||
106 | * @param zSql SQL statement, UTF-8 encoded | ||
107 | * @param ppStmt set to the prepared statement | ||
108 | * @return 0 on success | ||
109 | */ | ||
110 | static int | ||
111 | sq_prepare (sqlite3 *dbh, | ||
112 | const char *zSql, | ||
113 | sqlite3_stmt **ppStmt) | ||
114 | { | ||
115 | char *dummy; | ||
116 | int result; | ||
117 | |||
118 | result = | ||
119 | sqlite3_prepare_v2 (dbh, | ||
120 | zSql, | ||
121 | strlen (zSql), | ||
122 | ppStmt, | ||
123 | (const char **) &dummy); | ||
124 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
125 | "Prepared `%s' / %p: %d\n", | ||
126 | zSql, | ||
127 | *ppStmt, | ||
128 | result); | ||
129 | return result; | ||
130 | } | ||
131 | |||
132 | /** | ||
133 | * Create our database indices. | ||
134 | * | ||
135 | * @param dbh handle to the database | ||
136 | */ | ||
137 | static void | ||
138 | create_indices (sqlite3 * dbh) | ||
139 | { | ||
140 | /* create indices */ | ||
141 | if ( (SQLITE_OK != | ||
142 | sqlite3_exec (dbh, | ||
143 | "CREATE INDEX IF NOT EXISTS identity_reverse ON identity001tickets (identity,audience)", | ||
144 | NULL, NULL, NULL)) || | ||
145 | (SQLITE_OK != | ||
146 | sqlite3_exec (dbh, | ||
147 | "CREATE INDEX IF NOT EXISTS it_iter ON identity001tickets (rnd)", | ||
148 | NULL, NULL, NULL)) ) | ||
149 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
150 | "Failed to create indices: %s\n", | ||
151 | sqlite3_errmsg (dbh)); | ||
152 | } | ||
153 | |||
154 | |||
155 | |||
156 | #if 0 | ||
157 | #define CHECK(a) GNUNET_break(a) | ||
158 | #define ENULL NULL | ||
159 | #else | ||
160 | #define ENULL &e | ||
161 | #define ENULL_DEFINED 1 | ||
162 | #define CHECK(a) if (! (a)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", e); sqlite3_free(e); } | ||
163 | #endif | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Initialize the database connections and associated | ||
168 | * data structures (create tables and indices | ||
169 | * as needed as well). | ||
170 | * | ||
171 | * @param plugin the plugin context (state for this module) | ||
172 | * @return #GNUNET_OK on success | ||
173 | */ | ||
174 | static int | ||
175 | database_setup (struct Plugin *plugin) | ||
176 | { | ||
177 | sqlite3_stmt *stmt; | ||
178 | char *afsdir; | ||
179 | #if ENULL_DEFINED | ||
180 | char *e; | ||
181 | #endif | ||
182 | |||
183 | if (GNUNET_OK != | ||
184 | GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, | ||
185 | "identity-provider-sqlite", | ||
186 | "FILENAME", | ||
187 | &afsdir)) | ||
188 | { | ||
189 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
190 | "identity-provider-sqlite", | ||
191 | "FILENAME"); | ||
192 | return GNUNET_SYSERR; | ||
193 | } | ||
194 | if (GNUNET_OK != | ||
195 | GNUNET_DISK_file_test (afsdir)) | ||
196 | { | ||
197 | if (GNUNET_OK != | ||
198 | GNUNET_DISK_directory_create_for_file (afsdir)) | ||
199 | { | ||
200 | GNUNET_break (0); | ||
201 | GNUNET_free (afsdir); | ||
202 | return GNUNET_SYSERR; | ||
203 | } | ||
204 | } | ||
205 | /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */ | ||
206 | plugin->fn = afsdir; | ||
207 | |||
208 | /* Open database and precompile statements */ | ||
209 | if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK) | ||
210 | { | ||
211 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
212 | _("Unable to initialize SQLite: %s.\n"), | ||
213 | sqlite3_errmsg (plugin->dbh)); | ||
214 | return GNUNET_SYSERR; | ||
215 | } | ||
216 | CHECK (SQLITE_OK == | ||
217 | sqlite3_exec (plugin->dbh, | ||
218 | "PRAGMA temp_store=MEMORY", NULL, NULL, | ||
219 | ENULL)); | ||
220 | CHECK (SQLITE_OK == | ||
221 | sqlite3_exec (plugin->dbh, | ||
222 | "PRAGMA synchronous=NORMAL", NULL, NULL, | ||
223 | ENULL)); | ||
224 | CHECK (SQLITE_OK == | ||
225 | sqlite3_exec (plugin->dbh, | ||
226 | "PRAGMA legacy_file_format=OFF", NULL, NULL, | ||
227 | ENULL)); | ||
228 | CHECK (SQLITE_OK == | ||
229 | sqlite3_exec (plugin->dbh, | ||
230 | "PRAGMA auto_vacuum=INCREMENTAL", NULL, | ||
231 | NULL, ENULL)); | ||
232 | CHECK (SQLITE_OK == | ||
233 | sqlite3_exec (plugin->dbh, | ||
234 | "PRAGMA encoding=\"UTF-8\"", NULL, | ||
235 | NULL, ENULL)); | ||
236 | CHECK (SQLITE_OK == | ||
237 | sqlite3_exec (plugin->dbh, | ||
238 | "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, | ||
239 | ENULL)); | ||
240 | CHECK (SQLITE_OK == | ||
241 | sqlite3_exec (plugin->dbh, | ||
242 | "PRAGMA page_size=4092", NULL, NULL, | ||
243 | ENULL)); | ||
244 | |||
245 | CHECK (SQLITE_OK == | ||
246 | sqlite3_busy_timeout (plugin->dbh, | ||
247 | BUSY_TIMEOUT_MS)); | ||
248 | |||
249 | |||
250 | /* Create table */ | ||
251 | CHECK (SQLITE_OK == | ||
252 | sq_prepare (plugin->dbh, | ||
253 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'identity001tickets'", | ||
254 | &stmt)); | ||
255 | if ((sqlite3_step (stmt) == SQLITE_DONE) && | ||
256 | (sqlite3_exec | ||
257 | (plugin->dbh, | ||
258 | "CREATE TABLE identity001tickets (" | ||
259 | " identity BLOB NOT NULL DEFAULT ''," | ||
260 | " audience BLOB NOT NULL DEFAULT ''," | ||
261 | " rnd INT8 NOT NULL DEFAULT ''," | ||
262 | " attributes BLOB NOT NULL DEFAULT ''" | ||
263 | ")", | ||
264 | NULL, NULL, NULL) != SQLITE_OK)) | ||
265 | { | ||
266 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, | ||
267 | "sqlite3_exec"); | ||
268 | sqlite3_finalize (stmt); | ||
269 | return GNUNET_SYSERR; | ||
270 | } | ||
271 | sqlite3_finalize (stmt); | ||
272 | |||
273 | create_indices (plugin->dbh); | ||
274 | |||
275 | if ( (SQLITE_OK != | ||
276 | sq_prepare (plugin->dbh, | ||
277 | "INSERT INTO identity001tickets (identity, audience, rnd, attributes)" | ||
278 | " VALUES (?, ?, ?, ?)", | ||
279 | &plugin->store_ticket)) || | ||
280 | (SQLITE_OK != | ||
281 | sq_prepare (plugin->dbh, | ||
282 | "DELETE FROM identity001tickets WHERE identity=? AND rnd=?", | ||
283 | &plugin->delete_ticket)) || | ||
284 | (SQLITE_OK != | ||
285 | sq_prepare (plugin->dbh, | ||
286 | "SELECT identity,audience,rnd,attributes" | ||
287 | " FROM identity001tickets WHERE identity=? AND rnd=?", | ||
288 | &plugin->get_ticket_attrs)) || | ||
289 | (SQLITE_OK != | ||
290 | sq_prepare (plugin->dbh, | ||
291 | "SELECT identity,audience,rnd,attributes" | ||
292 | " FROM identity001tickets WHERE identity=?" | ||
293 | " ORDER BY rnd LIMIT 1 OFFSET ?", | ||
294 | &plugin->iterate_tickets)) || | ||
295 | (SQLITE_OK != | ||
296 | sq_prepare (plugin->dbh, | ||
297 | "SELECT identity,audience,rnd,attributes" | ||
298 | " FROM identity001tickets WHERE audience=?" | ||
299 | " ORDER BY rnd LIMIT 1 OFFSET ?", | ||
300 | &plugin->iterate_tickets_by_audience)) ) | ||
301 | { | ||
302 | LOG_SQLITE (plugin, | ||
303 | GNUNET_ERROR_TYPE_ERROR, | ||
304 | "precompiling"); | ||
305 | return GNUNET_SYSERR; | ||
306 | } | ||
307 | return GNUNET_OK; | ||
308 | } | ||
309 | |||
310 | |||
311 | /** | ||
312 | * Shutdown database connection and associate data | ||
313 | * structures. | ||
314 | * @param plugin the plugin context (state for this module) | ||
315 | */ | ||
316 | static void | ||
317 | database_shutdown (struct Plugin *plugin) | ||
318 | { | ||
319 | int result; | ||
320 | sqlite3_stmt *stmt; | ||
321 | |||
322 | if (NULL != plugin->store_ticket) | ||
323 | sqlite3_finalize (plugin->store_ticket); | ||
324 | if (NULL != plugin->delete_ticket) | ||
325 | sqlite3_finalize (plugin->delete_ticket); | ||
326 | if (NULL != plugin->iterate_tickets) | ||
327 | sqlite3_finalize (plugin->iterate_tickets); | ||
328 | if (NULL != plugin->iterate_tickets_by_audience) | ||
329 | sqlite3_finalize (plugin->iterate_tickets_by_audience); | ||
330 | if (NULL != plugin->get_ticket_attrs) | ||
331 | sqlite3_finalize (plugin->get_ticket_attrs); | ||
332 | result = sqlite3_close (plugin->dbh); | ||
333 | if (result == SQLITE_BUSY) | ||
334 | { | ||
335 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
336 | _("Tried to close sqlite without finalizing all prepared statements.\n")); | ||
337 | stmt = sqlite3_next_stmt (plugin->dbh, | ||
338 | NULL); | ||
339 | while (NULL != stmt) | ||
340 | { | ||
341 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
342 | "sqlite", | ||
343 | "Closing statement %p\n", | ||
344 | stmt); | ||
345 | result = sqlite3_finalize (stmt); | ||
346 | if (result != SQLITE_OK) | ||
347 | GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, | ||
348 | "sqlite", | ||
349 | "Failed to close statement %p: %d\n", | ||
350 | stmt, | ||
351 | result); | ||
352 | stmt = sqlite3_next_stmt (plugin->dbh, | ||
353 | NULL); | ||
354 | } | ||
355 | result = sqlite3_close (plugin->dbh); | ||
356 | } | ||
357 | if (SQLITE_OK != result) | ||
358 | LOG_SQLITE (plugin, | ||
359 | GNUNET_ERROR_TYPE_ERROR, | ||
360 | "sqlite3_close"); | ||
361 | |||
362 | GNUNET_free_non_null (plugin->fn); | ||
363 | } | ||
364 | |||
365 | |||
366 | /** | ||
367 | * Store a ticket in the database. | ||
368 | * | ||
369 | * @param cls closure (internal context for the plugin) | ||
370 | * @param ticket the ticket to persist | ||
371 | * @param attrs the attributes associated with the ticket | ||
372 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
373 | */ | ||
374 | static int | ||
375 | identity_provider_sqlite_store_ticket (void *cls, | ||
376 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
377 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs) | ||
378 | { | ||
379 | struct Plugin *plugin = cls; | ||
380 | size_t attrs_len; | ||
381 | char *attrs_ser; | ||
382 | int n; | ||
383 | |||
384 | { | ||
385 | /* First delete duplicates */ | ||
386 | struct GNUNET_SQ_QueryParam dparams[] = { | ||
387 | GNUNET_SQ_query_param_auto_from_type (&ticket->identity), | ||
388 | GNUNET_SQ_query_param_uint64 (&ticket->rnd), | ||
389 | GNUNET_SQ_query_param_end | ||
390 | }; | ||
391 | if (GNUNET_OK != | ||
392 | GNUNET_SQ_bind (plugin->delete_ticket, | ||
393 | dparams)) | ||
394 | { | ||
395 | LOG_SQLITE (plugin, | ||
396 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
397 | "sqlite3_bind_XXXX"); | ||
398 | GNUNET_SQ_reset (plugin->dbh, | ||
399 | plugin->delete_ticket); | ||
400 | return GNUNET_SYSERR; | ||
401 | } | ||
402 | n = sqlite3_step (plugin->delete_ticket); | ||
403 | GNUNET_SQ_reset (plugin->dbh, | ||
404 | plugin->delete_ticket); | ||
405 | |||
406 | attrs_len = GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (attrs); | ||
407 | attrs_ser = GNUNET_malloc (attrs_len); | ||
408 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize (attrs, | ||
409 | attrs_ser); | ||
410 | struct GNUNET_SQ_QueryParam sparams[] = { | ||
411 | GNUNET_SQ_query_param_auto_from_type (&ticket->identity), | ||
412 | GNUNET_SQ_query_param_auto_from_type (&ticket->audience), | ||
413 | GNUNET_SQ_query_param_uint64 (&ticket->rnd), | ||
414 | GNUNET_SQ_query_param_fixed_size (attrs_ser, attrs_len), | ||
415 | GNUNET_SQ_query_param_end | ||
416 | }; | ||
417 | |||
418 | if (GNUNET_OK != | ||
419 | GNUNET_SQ_bind (plugin->store_ticket, | ||
420 | sparams)) | ||
421 | { | ||
422 | LOG_SQLITE (plugin, | ||
423 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
424 | "sqlite3_bind_XXXX"); | ||
425 | GNUNET_SQ_reset (plugin->dbh, | ||
426 | plugin->store_ticket); | ||
427 | return GNUNET_SYSERR; | ||
428 | } | ||
429 | n = sqlite3_step (plugin->store_ticket); | ||
430 | GNUNET_SQ_reset (plugin->dbh, | ||
431 | plugin->store_ticket); | ||
432 | GNUNET_free (attrs_ser); | ||
433 | } | ||
434 | switch (n) | ||
435 | { | ||
436 | case SQLITE_DONE: | ||
437 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
438 | "sqlite", | ||
439 | "Ticket stored\n"); | ||
440 | return GNUNET_OK; | ||
441 | case SQLITE_BUSY: | ||
442 | LOG_SQLITE (plugin, | ||
443 | GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
444 | "sqlite3_step"); | ||
445 | return GNUNET_NO; | ||
446 | default: | ||
447 | LOG_SQLITE (plugin, | ||
448 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
449 | "sqlite3_step"); | ||
450 | return GNUNET_SYSERR; | ||
451 | } | ||
452 | } | ||
453 | |||
454 | |||
455 | /** | ||
456 | * Store a ticket in the database. | ||
457 | * | ||
458 | * @param cls closure (internal context for the plugin) | ||
459 | * @param ticket the ticket to delete | ||
460 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
461 | */ | ||
462 | static int | ||
463 | identity_provider_sqlite_delete_ticket (void *cls, | ||
464 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) | ||
465 | { | ||
466 | struct Plugin *plugin = cls; | ||
467 | int n; | ||
468 | |||
469 | { | ||
470 | struct GNUNET_SQ_QueryParam sparams[] = { | ||
471 | GNUNET_SQ_query_param_auto_from_type (&ticket->identity), | ||
472 | GNUNET_SQ_query_param_uint64 (&ticket->rnd), | ||
473 | GNUNET_SQ_query_param_end | ||
474 | }; | ||
475 | |||
476 | if (GNUNET_OK != | ||
477 | GNUNET_SQ_bind (plugin->delete_ticket, | ||
478 | sparams)) | ||
479 | { | ||
480 | LOG_SQLITE (plugin, | ||
481 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
482 | "sqlite3_bind_XXXX"); | ||
483 | GNUNET_SQ_reset (plugin->dbh, | ||
484 | plugin->store_ticket); | ||
485 | return GNUNET_SYSERR; | ||
486 | } | ||
487 | n = sqlite3_step (plugin->delete_ticket); | ||
488 | GNUNET_SQ_reset (plugin->dbh, | ||
489 | plugin->delete_ticket); | ||
490 | } | ||
491 | switch (n) | ||
492 | { | ||
493 | case SQLITE_DONE: | ||
494 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
495 | "sqlite", | ||
496 | "Ticket deleted\n"); | ||
497 | return GNUNET_OK; | ||
498 | case SQLITE_BUSY: | ||
499 | LOG_SQLITE (plugin, | ||
500 | GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
501 | "sqlite3_step"); | ||
502 | return GNUNET_NO; | ||
503 | default: | ||
504 | LOG_SQLITE (plugin, | ||
505 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
506 | "sqlite3_step"); | ||
507 | return GNUNET_SYSERR; | ||
508 | } | ||
509 | } | ||
510 | |||
511 | |||
512 | /** | ||
513 | * The given 'sqlite' statement has been prepared to be run. | ||
514 | * It will return a record which should be given to the iterator. | ||
515 | * Runs the statement and parses the returned record. | ||
516 | * | ||
517 | * @param plugin plugin context | ||
518 | * @param stmt to run (and then clean up) | ||
519 | * @param iter iterator to call with the result | ||
520 | * @param iter_cls closure for @a iter | ||
521 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
522 | */ | ||
523 | static int | ||
524 | get_ticket_and_call_iterator (struct Plugin *plugin, | ||
525 | sqlite3_stmt *stmt, | ||
526 | GNUNET_IDENTITY_PROVIDER_TicketIterator iter, | ||
527 | void *iter_cls) | ||
528 | { | ||
529 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | ||
530 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs; | ||
531 | int ret; | ||
532 | int sret; | ||
533 | size_t attrs_len; | ||
534 | char *attrs_ser; | ||
535 | |||
536 | ret = GNUNET_NO; | ||
537 | if (SQLITE_ROW == (sret = sqlite3_step (stmt))) | ||
538 | { | ||
539 | struct GNUNET_SQ_ResultSpec rs[] = { | ||
540 | GNUNET_SQ_result_spec_auto_from_type (&ticket.identity), | ||
541 | GNUNET_SQ_result_spec_auto_from_type (&ticket.audience), | ||
542 | GNUNET_SQ_result_spec_uint64 (&ticket.rnd), | ||
543 | GNUNET_SQ_result_spec_variable_size ((void**)&attrs_ser, | ||
544 | &attrs_len), | ||
545 | GNUNET_SQ_result_spec_end | ||
546 | |||
547 | }; | ||
548 | ret = GNUNET_SQ_extract_result (stmt, | ||
549 | rs); | ||
550 | if (GNUNET_OK != ret) | ||
551 | { | ||
552 | GNUNET_break (0); | ||
553 | ret = GNUNET_SYSERR; | ||
554 | } | ||
555 | else | ||
556 | { | ||
557 | attrs = GNUNET_IDENTITY_ATTRIBUTE_list_deserialize (attrs_ser, | ||
558 | attrs_len); | ||
559 | if (NULL != iter) | ||
560 | iter (iter_cls, | ||
561 | &ticket, | ||
562 | attrs); | ||
563 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (attrs); | ||
564 | ret = GNUNET_YES; | ||
565 | } | ||
566 | GNUNET_SQ_cleanup_result (rs); | ||
567 | } | ||
568 | else | ||
569 | { | ||
570 | if (SQLITE_DONE != sret) | ||
571 | LOG_SQLITE (plugin, | ||
572 | GNUNET_ERROR_TYPE_ERROR, | ||
573 | "sqlite_step"); | ||
574 | } | ||
575 | GNUNET_SQ_reset (plugin->dbh, | ||
576 | stmt); | ||
577 | return ret; | ||
578 | } | ||
579 | |||
580 | |||
581 | /** | ||
582 | * Lookup tickets in the datastore. | ||
583 | * | ||
584 | * @param cls closure (internal context for the plugin) | ||
585 | * @param ticket the ticket to retrieve attributes for | ||
586 | * @param iter function to call with the result | ||
587 | * @param iter_cls closure for @a iter | ||
588 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
589 | */ | ||
590 | static int | ||
591 | identity_provider_sqlite_ticket_get_attrs (void *cls, | ||
592 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
593 | GNUNET_IDENTITY_PROVIDER_TicketIterator iter, | ||
594 | void *iter_cls) | ||
595 | { | ||
596 | struct Plugin *plugin = cls; | ||
597 | struct GNUNET_SQ_QueryParam params[] = { | ||
598 | GNUNET_SQ_query_param_auto_from_type (&ticket->identity), | ||
599 | GNUNET_SQ_query_param_uint64 (&ticket->rnd), | ||
600 | GNUNET_SQ_query_param_end | ||
601 | }; | ||
602 | |||
603 | if (GNUNET_OK != | ||
604 | GNUNET_SQ_bind (plugin->get_ticket_attrs, | ||
605 | params)) | ||
606 | { | ||
607 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
608 | "sqlite3_bind_XXXX"); | ||
609 | GNUNET_SQ_reset (plugin->dbh, | ||
610 | plugin->get_ticket_attrs); | ||
611 | return GNUNET_SYSERR; | ||
612 | } | ||
613 | return get_ticket_and_call_iterator (plugin, | ||
614 | plugin->get_ticket_attrs, | ||
615 | iter, | ||
616 | iter_cls); | ||
617 | } | ||
618 | |||
619 | |||
620 | /** | ||
621 | * Iterate over the results for a particular key and zone in the | ||
622 | * datastore. Will return at most one result to the iterator. | ||
623 | * | ||
624 | * @param cls closure (internal context for the plugin) | ||
625 | * @param identity the issuing identity or audience (depending on audience switch) | ||
626 | * @param audience GNUNET_YES if identity is audience | ||
627 | * @param offset offset in the list of all matching records | ||
628 | * @param iter function to call with the result | ||
629 | * @param iter_cls closure for @a iter | ||
630 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
631 | */ | ||
632 | static int | ||
633 | identity_provider_sqlite_iterate_tickets (void *cls, | ||
634 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | ||
635 | int audience, | ||
636 | uint64_t offset, | ||
637 | GNUNET_IDENTITY_PROVIDER_TicketIterator iter, | ||
638 | void *iter_cls) | ||
639 | { | ||
640 | struct Plugin *plugin = cls; | ||
641 | sqlite3_stmt *stmt; | ||
642 | int err; | ||
643 | |||
644 | if (NULL == identity) | ||
645 | { | ||
646 | GNUNET_break (0); | ||
647 | return GNUNET_SYSERR; | ||
648 | } | ||
649 | struct GNUNET_SQ_QueryParam params[] = { | ||
650 | GNUNET_SQ_query_param_auto_from_type (identity), | ||
651 | GNUNET_SQ_query_param_uint64 (&offset), | ||
652 | GNUNET_SQ_query_param_end | ||
653 | }; | ||
654 | if (GNUNET_YES == audience) | ||
655 | { | ||
656 | stmt = plugin->iterate_tickets_by_audience; | ||
657 | err = GNUNET_SQ_bind (stmt, | ||
658 | params); | ||
659 | } | ||
660 | else | ||
661 | { | ||
662 | stmt = plugin->iterate_tickets; | ||
663 | err = GNUNET_SQ_bind (stmt, | ||
664 | params); | ||
665 | } | ||
666 | if (GNUNET_OK != err) | ||
667 | { | ||
668 | LOG_SQLITE (plugin, | ||
669 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
670 | "sqlite3_bind_XXXX"); | ||
671 | GNUNET_SQ_reset (plugin->dbh, | ||
672 | stmt); | ||
673 | return GNUNET_SYSERR; | ||
674 | } | ||
675 | return get_ticket_and_call_iterator (plugin, | ||
676 | stmt, | ||
677 | iter, | ||
678 | iter_cls); | ||
679 | } | ||
680 | |||
681 | |||
682 | /** | ||
683 | * Entry point for the plugin. | ||
684 | * | ||
685 | * @param cls the "struct GNUNET_IDENTITY_PROVIDER_PluginEnvironment*" | ||
686 | * @return NULL on error, otherwise the plugin context | ||
687 | */ | ||
688 | void * | ||
689 | libgnunet_plugin_identity_provider_sqlite_init (void *cls) | ||
690 | { | ||
691 | static struct Plugin plugin; | ||
692 | const struct GNUNET_CONFIGURATION_Handle *cfg = cls; | ||
693 | struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *api; | ||
694 | |||
695 | if (NULL != plugin.cfg) | ||
696 | return NULL; /* can only initialize once! */ | ||
697 | memset (&plugin, 0, sizeof (struct Plugin)); | ||
698 | plugin.cfg = cfg; | ||
699 | if (GNUNET_OK != database_setup (&plugin)) | ||
700 | { | ||
701 | database_shutdown (&plugin); | ||
702 | return NULL; | ||
703 | } | ||
704 | api = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_PluginFunctions); | ||
705 | api->cls = &plugin; | ||
706 | api->store_ticket = &identity_provider_sqlite_store_ticket; | ||
707 | api->delete_ticket = &identity_provider_sqlite_delete_ticket; | ||
708 | api->iterate_tickets = &identity_provider_sqlite_iterate_tickets; | ||
709 | api->get_ticket_attributes = &identity_provider_sqlite_ticket_get_attrs; | ||
710 | LOG (GNUNET_ERROR_TYPE_INFO, | ||
711 | _("Sqlite database running\n")); | ||
712 | return api; | ||
713 | } | ||
714 | |||
715 | |||
716 | /** | ||
717 | * Exit point from the plugin. | ||
718 | * | ||
719 | * @param cls the plugin context (as returned by "init") | ||
720 | * @return always NULL | ||
721 | */ | ||
722 | void * | ||
723 | libgnunet_plugin_identity_provider_sqlite_done (void *cls) | ||
724 | { | ||
725 | struct GNUNET_IDENTITY_PROVIDER_PluginFunctions *api = cls; | ||
726 | struct Plugin *plugin = api->cls; | ||
727 | |||
728 | database_shutdown (plugin); | ||
729 | plugin->cfg = NULL; | ||
730 | GNUNET_free (api); | ||
731 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
732 | "sqlite plugin is finished\n"); | ||
733 | return NULL; | ||
734 | } | ||
735 | |||
736 | /* end of plugin_identity_provider_sqlite.c */ | ||
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c index 907b28ba9..6eb856435 100644 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ b/src/identity-provider/plugin_rest_identity_provider.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <jansson.h> | 37 | #include <jansson.h> |
38 | #include <inttypes.h> | 38 | #include <inttypes.h> |
39 | #include "gnunet_signatures.h" | 39 | #include "gnunet_signatures.h" |
40 | #include "gnunet_identity_attribute_lib.h" | ||
40 | #include "gnunet_identity_provider_service.h" | 41 | #include "gnunet_identity_provider_service.h" |
41 | 42 | ||
42 | /** | 43 | /** |
@@ -45,39 +46,40 @@ | |||
45 | #define GNUNET_REST_API_NS_IDENTITY_PROVIDER "/idp" | 46 | #define GNUNET_REST_API_NS_IDENTITY_PROVIDER "/idp" |
46 | 47 | ||
47 | /** | 48 | /** |
48 | * Issue namespace | 49 | * Attribute namespace |
49 | */ | 50 | */ |
50 | #define GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE "/idp/issue" | 51 | #define GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES "/idp/attributes" |
51 | 52 | ||
52 | /** | 53 | /** |
53 | * Check namespace TODO | 54 | * Ticket namespace |
54 | */ | 55 | */ |
55 | #define GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK "/idp/check" | 56 | #define GNUNET_REST_API_NS_IDENTITY_TICKETS "/idp/tickets" |
56 | 57 | ||
57 | /** | 58 | /** |
58 | * Token namespace | 59 | * Revoke namespace |
59 | */ | 60 | */ |
60 | #define GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN "/idp/token" | 61 | #define GNUNET_REST_API_NS_IDENTITY_REVOKE "/idp/revoke" |
61 | 62 | ||
62 | /** | 63 | /** |
63 | * The parameter name in which the ticket must be provided | 64 | * Revoke namespace |
64 | */ | 65 | */ |
65 | #define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET "ticket" | 66 | #define GNUNET_REST_API_NS_IDENTITY_CONSUME "/idp/consume" |
66 | 67 | ||
67 | /** | 68 | /** |
68 | * The parameter name in which the expected nonce must be provided | 69 | * Attribute key |
69 | */ | 70 | */ |
70 | #define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE "expected_nonce" | 71 | #define GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE "attribute" |
71 | 72 | ||
72 | /** | 73 | /** |
73 | * The parameter name in which the ticket must be provided | 74 | * Ticket key |
74 | */ | 75 | */ |
75 | #define GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN "token" | 76 | #define GNUNET_REST_JSONAPI_IDENTITY_TICKET "ticket" |
77 | |||
76 | 78 | ||
77 | /** | 79 | /** |
78 | * The URL parameter name in which the nonce must be provided | 80 | * Value key |
79 | */ | 81 | */ |
80 | #define GNUNET_IDENTITY_TOKEN_REQUEST_NONCE "nonce" | 82 | #define GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE_VALUE "value" |
81 | 83 | ||
82 | /** | 84 | /** |
83 | * State while collecting all egos | 85 | * State while collecting all egos |
@@ -89,41 +91,6 @@ | |||
89 | */ | 91 | */ |
90 | #define ID_REST_STATE_POST_INIT 1 | 92 | #define ID_REST_STATE_POST_INIT 1 |
91 | 93 | ||
92 | /** | ||
93 | * Resource type | ||
94 | */ | ||
95 | #define GNUNET_REST_JSONAPI_IDENTITY_TOKEN "token" | ||
96 | |||
97 | /** | ||
98 | * URL parameter to create a GNUid token for a specific audience | ||
99 | */ | ||
100 | #define GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST "audience" | ||
101 | |||
102 | /** | ||
103 | * URL parameter to create a GNUid token for a specific issuer (EGO) | ||
104 | */ | ||
105 | #define GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST "issuer" | ||
106 | |||
107 | /** | ||
108 | * Attributes passed to issue request | ||
109 | */ | ||
110 | #define GNUNET_IDENTITY_TOKEN_ATTR_LIST "requested_attrs" | ||
111 | |||
112 | /** | ||
113 | * Token expiration string | ||
114 | */ | ||
115 | #define GNUNET_IDENTITY_TOKEN_EXP_STRING "expiration" | ||
116 | |||
117 | /** | ||
118 | * Error messages | ||
119 | */ | ||
120 | #define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid" | ||
121 | #define GNUNET_REST_ERROR_NO_DATA "No data" | ||
122 | |||
123 | /** | ||
124 | * GNUid token lifetime | ||
125 | */ | ||
126 | #define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000 | ||
127 | 94 | ||
128 | /** | 95 | /** |
129 | * The configuration handle | 96 | * The configuration handle |
@@ -198,11 +165,6 @@ struct RequestHandle | |||
198 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | 165 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; |
199 | 166 | ||
200 | /** | 167 | /** |
201 | * Handle to the rest connection | ||
202 | */ | ||
203 | struct GNUNET_REST_RequestHandle *conndata_handle; | ||
204 | |||
205 | /** | ||
206 | * The processing state | 168 | * The processing state |
207 | */ | 169 | */ |
208 | int state; | 170 | int state; |
@@ -213,6 +175,12 @@ struct RequestHandle | |||
213 | struct GNUNET_IDENTITY_Handle *identity_handle; | 175 | struct GNUNET_IDENTITY_Handle *identity_handle; |
214 | 176 | ||
215 | /** | 177 | /** |
178 | * Rest connection | ||
179 | */ | ||
180 | struct GNUNET_REST_RequestHandle *rest_handle; | ||
181 | |||
182 | |||
183 | /** | ||
216 | * IDENTITY Operation | 184 | * IDENTITY Operation |
217 | */ | 185 | */ |
218 | struct GNUNET_IDENTITY_Operation *op; | 186 | struct GNUNET_IDENTITY_Operation *op; |
@@ -228,19 +196,14 @@ struct RequestHandle | |||
228 | struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op; | 196 | struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op; |
229 | 197 | ||
230 | /** | 198 | /** |
231 | * Handle to NS service | 199 | * Attribute iterator |
232 | */ | ||
233 | struct GNUNET_NAMESTORE_Handle *ns_handle; | ||
234 | |||
235 | /** | ||
236 | * NS iterator | ||
237 | */ | 200 | */ |
238 | struct GNUNET_NAMESTORE_ZoneIterator *ns_it; | 201 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_it; |
239 | 202 | ||
240 | /** | 203 | /** |
241 | * NS Handle | 204 | * Ticket iterator |
242 | */ | 205 | */ |
243 | struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | 206 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator *ticket_it; |
244 | 207 | ||
245 | /** | 208 | /** |
246 | * Desired timeout for the lookup (default is no timeout). | 209 | * Desired timeout for the lookup (default is no timeout). |
@@ -285,6 +248,7 @@ struct RequestHandle | |||
285 | }; | 248 | }; |
286 | 249 | ||
287 | 250 | ||
251 | |||
288 | /** | 252 | /** |
289 | * Cleanup lookup handle | 253 | * Cleanup lookup handle |
290 | * @param handle Handle to clean up | 254 | * @param handle Handle to clean up |
@@ -302,14 +266,12 @@ cleanup_handle (struct RequestHandle *handle) | |||
302 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | 266 | GNUNET_SCHEDULER_cancel (handle->timeout_task); |
303 | if (NULL != handle->identity_handle) | 267 | if (NULL != handle->identity_handle) |
304 | GNUNET_IDENTITY_disconnect (handle->identity_handle); | 268 | GNUNET_IDENTITY_disconnect (handle->identity_handle); |
269 | if (NULL != handle->attr_it) | ||
270 | GNUNET_IDENTITY_PROVIDER_get_attributes_stop (handle->attr_it); | ||
271 | if (NULL != handle->ticket_it) | ||
272 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (handle->ticket_it); | ||
305 | if (NULL != handle->idp) | 273 | if (NULL != handle->idp) |
306 | GNUNET_IDENTITY_PROVIDER_disconnect (handle->idp); | 274 | GNUNET_IDENTITY_PROVIDER_disconnect (handle->idp); |
307 | if (NULL != handle->ns_it) | ||
308 | GNUNET_NAMESTORE_zone_iteration_stop (handle->ns_it); | ||
309 | if (NULL != handle->ns_qe) | ||
310 | GNUNET_NAMESTORE_cancel (handle->ns_qe); | ||
311 | if (NULL != handle->ns_handle) | ||
312 | GNUNET_NAMESTORE_disconnect (handle->ns_handle); | ||
313 | if (NULL != handle->url) | 275 | if (NULL != handle->url) |
314 | GNUNET_free (handle->url); | 276 | GNUNET_free (handle->url); |
315 | if (NULL != handle->emsg) | 277 | if (NULL != handle->emsg) |
@@ -326,6 +288,12 @@ cleanup_handle (struct RequestHandle *handle) | |||
326 | GNUNET_free (handle); | 288 | GNUNET_free (handle); |
327 | } | 289 | } |
328 | 290 | ||
291 | static void | ||
292 | cleanup_handle_delayed (void *cls) | ||
293 | { | ||
294 | cleanup_handle (cls); | ||
295 | } | ||
296 | |||
329 | 297 | ||
330 | /** | 298 | /** |
331 | * Task run on error, sends error message. Cleans up everything. | 299 | * Task run on error, sends error message. Cleans up everything. |
@@ -363,622 +331,663 @@ do_timeout (void *cls) | |||
363 | } | 331 | } |
364 | 332 | ||
365 | 333 | ||
366 | /** | ||
367 | * Task run on shutdown. Cleans up everything. | ||
368 | * | ||
369 | * @param cls unused | ||
370 | */ | ||
371 | static void | 334 | static void |
372 | do_cleanup_handle_delayed (void *cls) | 335 | collect_error_cb (void *cls) |
373 | { | 336 | { |
374 | struct RequestHandle *handle = cls; | 337 | struct RequestHandle *handle = cls; |
375 | 338 | ||
376 | cleanup_handle (handle); | 339 | do_error (handle); |
377 | } | 340 | } |
378 | 341 | ||
379 | |||
380 | /** | ||
381 | * Get a ticket for identity | ||
382 | * @param cls the handle | ||
383 | * @param ticket the ticket returned from the idp | ||
384 | */ | ||
385 | static void | 342 | static void |
386 | token_creat_cont (void *cls, | 343 | finished_cont (void *cls, |
387 | const char *label, | 344 | int32_t success, |
388 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | 345 | const char *emsg) |
389 | const struct GNUNET_IDENTITY_PROVIDER_Token *token) | ||
390 | { | 346 | { |
391 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
392 | struct RequestHandle *handle = cls; | 347 | struct RequestHandle *handle = cls; |
393 | struct MHD_Response *resp; | 348 | struct MHD_Response *resp; |
394 | json_t *ticket_json; | ||
395 | json_t *token_json; | ||
396 | char *ticket_str; | ||
397 | char *token_str; | ||
398 | char *result_str; | ||
399 | 349 | ||
400 | if (NULL == ticket) | 350 | resp = GNUNET_REST_create_response (emsg); |
351 | if (GNUNET_OK != success) | ||
401 | { | 352 | { |
402 | handle->emsg = GNUNET_strdup ("Error in token issue"); | ||
403 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 353 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
404 | return; | 354 | return; |
405 | } | 355 | } |
356 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
357 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | ||
358 | } | ||
406 | 359 | ||
407 | handle->resp_object = GNUNET_JSONAPI_document_new (); | 360 | |
408 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, | 361 | /** |
409 | label); | 362 | * Return attributes for identity |
410 | ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); | 363 | * |
411 | token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token); | 364 | * @param cls the request handle |
412 | ticket_json = json_string (ticket_str); | 365 | */ |
413 | token_json = json_string (token_str); | 366 | static void |
414 | GNUNET_JSONAPI_resource_add_attr (json_resource, | 367 | return_response (void *cls) |
415 | GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, | 368 | { |
416 | ticket_json); | 369 | char* result_str; |
417 | GNUNET_JSONAPI_resource_add_attr (json_resource, | 370 | struct RequestHandle *handle = cls; |
418 | GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TOKEN, | 371 | struct MHD_Response *resp; |
419 | token_json); | ||
420 | GNUNET_free (ticket_str); | ||
421 | GNUNET_free (token_str); | ||
422 | json_decref (ticket_json); | ||
423 | json_decref (token_json); | ||
424 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); | ||
425 | 372 | ||
426 | GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); | 373 | GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); |
427 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); | 374 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); |
428 | resp = GNUNET_REST_create_response (result_str); | 375 | resp = GNUNET_REST_create_response (result_str); |
429 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 376 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
430 | GNUNET_free (result_str); | 377 | GNUNET_free (result_str); |
431 | GNUNET_SCHEDULER_add_now (&do_cleanup_handle_delayed, handle); | 378 | cleanup_handle (handle); |
379 | } | ||
380 | |||
381 | |||
382 | static void | ||
383 | collect_finished_cb (void *cls) | ||
384 | { | ||
385 | struct RequestHandle *handle = cls; | ||
386 | //Done | ||
387 | handle->attr_it = NULL; | ||
388 | handle->ticket_it = NULL; | ||
389 | GNUNET_SCHEDULER_add_now (&return_response, handle); | ||
432 | } | 390 | } |
433 | 391 | ||
434 | 392 | ||
435 | /** | 393 | /** |
436 | * Continueationf for token issue request | 394 | * Collect all attributes for an ego |
437 | * | 395 | * |
438 | * @param con the Rest handle | ||
439 | * @param url the requested url | ||
440 | * @param cls the request handle | ||
441 | */ | 396 | */ |
442 | static void | 397 | static void |
443 | issue_token_cont (struct GNUNET_REST_RequestHandle *con, | 398 | ticket_collect (void *cls, |
444 | const char *url, | 399 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket) |
445 | void *cls) | ||
446 | { | 400 | { |
447 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | 401 | struct GNUNET_JSONAPI_Resource *json_resource; |
448 | const char *egoname; | 402 | struct RequestHandle *handle = cls; |
403 | json_t *value; | ||
404 | char* tmp; | ||
405 | |||
406 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n"); | ||
407 | tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, | ||
408 | sizeof (uint64_t)); | ||
409 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TICKET, | ||
410 | tmp); | ||
411 | GNUNET_free (tmp); | ||
412 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); | ||
413 | |||
414 | tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity, | ||
415 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
416 | value = json_string (tmp); | ||
417 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
418 | "issuer", | ||
419 | value); | ||
420 | GNUNET_free (tmp); | ||
421 | json_decref (value); | ||
422 | tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, | ||
423 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
424 | value = json_string (tmp); | ||
425 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
426 | "audience", | ||
427 | value); | ||
428 | GNUNET_free (tmp); | ||
429 | json_decref (value); | ||
430 | tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, | ||
431 | sizeof (uint64_t)); | ||
432 | value = json_string (tmp); | ||
433 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
434 | "rnd", | ||
435 | value); | ||
436 | GNUNET_free (tmp); | ||
437 | json_decref (value); | ||
438 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (handle->ticket_it); | ||
439 | } | ||
440 | |||
449 | 441 | ||
442 | |||
443 | /** | ||
444 | * List tickets for identity request | ||
445 | * | ||
446 | * @param con_handle the connection handle | ||
447 | * @param url the url | ||
448 | * @param cls the RequestHandle | ||
449 | */ | ||
450 | static void | ||
451 | list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
452 | const char* url, | ||
453 | void *cls) | ||
454 | { | ||
455 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | ||
450 | struct RequestHandle *handle = cls; | 456 | struct RequestHandle *handle = cls; |
451 | struct EgoEntry *ego_entry; | 457 | struct EgoEntry *ego_entry; |
452 | struct GNUNET_HashCode key; | 458 | char *identity; |
453 | struct MHD_Response *resp; | 459 | |
454 | struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; | 460 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting tickets for %s.\n", |
455 | struct GNUNET_CRYPTO_EcdsaPublicKey aud_key; | 461 | handle->url); |
456 | struct GNUNET_TIME_Relative etime_rel; | 462 | if ( strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= |
457 | struct GNUNET_TIME_Absolute exp_time; | 463 | strlen (handle->url)) |
458 | char *ego_val; | ||
459 | char *audience; | ||
460 | char *exp_str; | ||
461 | char *nonce_str; | ||
462 | char *scopes; | ||
463 | uint64_t time; | ||
464 | uint64_t nonce; | ||
465 | |||
466 | if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, | ||
467 | GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE)) | ||
468 | { | ||
469 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "URL invalid: %s\n", handle->url); | ||
470 | resp = GNUNET_REST_create_response (NULL); | ||
471 | handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); | ||
472 | cleanup_handle (handle); | ||
473 | return; | ||
474 | } | ||
475 | egoname = NULL; | ||
476 | ego_entry = NULL; | ||
477 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, | ||
478 | strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST), | ||
479 | &key); | ||
480 | if ( GNUNET_YES != | ||
481 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | ||
482 | &key) ) | ||
483 | { | ||
484 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
485 | "Issuer not found\n"); | ||
486 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
487 | return; | ||
488 | } | ||
489 | ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | ||
490 | &key); | ||
491 | if (NULL == ego_val) | ||
492 | { | 464 | { |
465 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); | ||
493 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 466 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
494 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
495 | "Ego invalid: %s\n", | ||
496 | ego_val); | ||
497 | return; | 467 | return; |
498 | } | 468 | } |
469 | identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; | ||
470 | |||
499 | for (ego_entry = handle->ego_head; | 471 | for (ego_entry = handle->ego_head; |
500 | NULL != ego_entry; | 472 | NULL != ego_entry; |
501 | ego_entry = ego_entry->next) | 473 | ego_entry = ego_entry->next) |
474 | if (0 == strcmp (identity, ego_entry->identifier)) | ||
475 | break; | ||
476 | handle->resp_object = GNUNET_JSONAPI_document_new (); | ||
477 | |||
478 | if (NULL == ego_entry) | ||
502 | { | 479 | { |
503 | if (0 != strcmp (ego_val, ego_entry->identifier)) | 480 | //Done |
504 | continue; | 481 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", |
505 | egoname = ego_entry->identifier; | 482 | identity); |
506 | break; | 483 | GNUNET_SCHEDULER_add_now (&return_response, handle); |
507 | } | ||
508 | if ( (NULL == egoname) || | ||
509 | (NULL == ego_entry) ) | ||
510 | { | ||
511 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
512 | "Ego not found: %s\n", | ||
513 | ego_val); | ||
514 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
515 | return; | 484 | return; |
516 | } | 485 | } |
517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 486 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
518 | "Ego to issue token for: %s\n", | 487 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); |
519 | egoname); | 488 | handle->ticket_it = GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (handle->idp, |
489 | priv_key, | ||
490 | &collect_error_cb, | ||
491 | handle, | ||
492 | &ticket_collect, | ||
493 | handle, | ||
494 | &collect_finished_cb, | ||
495 | handle); | ||
496 | } | ||
520 | 497 | ||
521 | 498 | ||
522 | //Meta info | 499 | static void |
523 | GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_ATTR_LIST, | 500 | add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, |
524 | strlen (GNUNET_IDENTITY_TOKEN_ATTR_LIST), | 501 | const char* url, |
525 | &key); | 502 | void *cls) |
503 | { | ||
504 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; | ||
505 | const char* identity; | ||
506 | const char* name_str; | ||
507 | const char* value_str; | ||
526 | 508 | ||
527 | scopes = NULL; | 509 | struct RequestHandle *handle = cls; |
528 | if ( GNUNET_YES != | 510 | struct EgoEntry *ego_entry; |
529 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | 511 | struct MHD_Response *resp; |
530 | &key) ) | 512 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attribute; |
513 | struct GNUNET_JSONAPI_Document *json_obj; | ||
514 | struct GNUNET_JSONAPI_Resource *json_res; | ||
515 | char term_data[handle->rest_handle->data_size+1]; | ||
516 | json_t *value_json; | ||
517 | json_t *data_json; | ||
518 | json_error_t err; | ||
519 | struct GNUNET_JSON_Specification docspec[] = { | ||
520 | GNUNET_JSON_spec_jsonapi_document (&json_obj), | ||
521 | GNUNET_JSON_spec_end() | ||
522 | }; | ||
523 | |||
524 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n", | ||
525 | handle->url); | ||
526 | if ( strlen (GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES) >= | ||
527 | strlen (handle->url)) | ||
531 | { | 528 | { |
532 | handle->emsg = GNUNET_strdup ("Scopes missing!\n"); | 529 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); |
533 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 530 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
534 | return; | 531 | return; |
535 | } | 532 | } |
536 | scopes = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | 533 | identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES) + 1; |
537 | &key); | 534 | |
538 | 535 | for (ego_entry = handle->ego_head; | |
539 | 536 | NULL != ego_entry; | |
540 | //Token audience | 537 | ego_entry = ego_entry->next) |
541 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST, | 538 | if (0 == strcmp (identity, ego_entry->identifier)) |
542 | strlen (GNUNET_REST_JSONAPI_IDENTITY_AUD_REQUEST), | 539 | break; |
543 | &key); | 540 | |
544 | audience = NULL; | 541 | if (NULL == ego_entry) |
545 | if ( GNUNET_YES != | ||
546 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | ||
547 | &key) ) | ||
548 | { | 542 | { |
549 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 543 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
550 | "Audience missing!\n"); | 544 | "Identity unknown (%s)\n", identity); |
551 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 545 | GNUNET_JSONAPI_document_delete (json_obj); |
552 | return; | 546 | return; |
553 | } | 547 | } |
554 | audience = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | 548 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
555 | &key); | ||
556 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
557 | "Audience to issue token for: %s\n", | ||
558 | audience); | ||
559 | |||
560 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
561 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, | ||
562 | &pub_key); | ||
563 | GNUNET_STRINGS_string_to_data (audience, | ||
564 | strlen (audience), | ||
565 | &aud_key, | ||
566 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
567 | 549 | ||
568 | //Remote nonce | 550 | if (0 >= handle->rest_handle->data_size) |
569 | nonce_str = NULL; | ||
570 | GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE, | ||
571 | strlen (GNUNET_IDENTITY_TOKEN_REQUEST_NONCE), | ||
572 | &key); | ||
573 | if ( GNUNET_YES != | ||
574 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | ||
575 | &key) ) | ||
576 | { | 551 | { |
577 | handle->emsg = GNUNET_strdup ("Request nonce missing!\n"); | ||
578 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 552 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
579 | return; | 553 | return; |
580 | } | 554 | } |
581 | nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | 555 | |
582 | &key); | 556 | term_data[handle->rest_handle->data_size] = '\0'; |
583 | GNUNET_assert (NULL != nonce_str); | 557 | GNUNET_memcpy (term_data, |
584 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 558 | handle->rest_handle->data, |
585 | "Request nonce: %s\n", | 559 | handle->rest_handle->data_size); |
586 | nonce_str); | 560 | data_json = json_loads (term_data, |
587 | GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &nonce)); | 561 | JSON_DECODE_ANY, |
588 | 562 | &err); | |
589 | //Get expiration for token from URL parameter | 563 | GNUNET_assert (GNUNET_OK == |
590 | GNUNET_CRYPTO_hash (GNUNET_IDENTITY_TOKEN_EXP_STRING, | 564 | GNUNET_JSON_parse (data_json, docspec, |
591 | strlen (GNUNET_IDENTITY_TOKEN_EXP_STRING), | 565 | NULL, NULL)); |
592 | &key); | 566 | json_decref (data_json); |
593 | 567 | if (NULL == json_obj) | |
594 | exp_str = NULL; | ||
595 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | ||
596 | &key)) | ||
597 | { | 568 | { |
598 | exp_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | 569 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
599 | &key); | 570 | "Unable to parse JSONAPI Object from %s\n", |
600 | } | 571 | term_data); |
601 | if (NULL == exp_str) { | ||
602 | handle->emsg = GNUNET_strdup ("No expiration given!\n"); | ||
603 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 572 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
604 | return; | 573 | return; |
605 | } | 574 | } |
606 | 575 | if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) | |
607 | if (GNUNET_OK != | ||
608 | GNUNET_STRINGS_fancy_time_to_relative (exp_str, | ||
609 | &etime_rel)) | ||
610 | { | 576 | { |
611 | handle->emsg = GNUNET_strdup ("Expiration invalid!\n"); | 577 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
578 | "Cannot create more than 1 resource! (Got %d)\n", | ||
579 | GNUNET_JSONAPI_document_resource_count (json_obj)); | ||
580 | GNUNET_JSONAPI_document_delete (json_obj); | ||
612 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 581 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
613 | return; | 582 | return; |
614 | } | 583 | } |
615 | time = GNUNET_TIME_absolute_get().abs_value_us; | 584 | json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); |
616 | exp_time.abs_value_us = time + etime_rel.rel_value_us; | 585 | if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, |
617 | 586 | GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE)) | |
587 | { | ||
588 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
589 | "Unsupported JSON data type\n"); | ||
590 | GNUNET_JSONAPI_document_delete (json_obj); | ||
591 | resp = GNUNET_REST_create_response (NULL); | ||
592 | handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); | ||
593 | cleanup_handle (handle); | ||
594 | return; | ||
595 | } | ||
596 | name_str = GNUNET_JSONAPI_resource_get_id (json_res); | ||
597 | value_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
598 | "value"); | ||
599 | value_str = json_string_value (value_json); | ||
600 | attribute = GNUNET_IDENTITY_ATTRIBUTE_claim_new (name_str, | ||
601 | GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING, | ||
602 | value_str, | ||
603 | strlen (value_str) + 1); | ||
618 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); | 604 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); |
619 | handle->idp_op = GNUNET_IDENTITY_PROVIDER_issue_token (handle->idp, | 605 | handle->idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (handle->idp, |
620 | priv_key, | 606 | identity_priv, |
621 | &aud_key, | 607 | attribute, |
622 | scopes, | 608 | &finished_cont, |
623 | exp_time, | 609 | handle); |
624 | nonce, | 610 | GNUNET_free (attribute); |
625 | &token_creat_cont, | 611 | GNUNET_JSONAPI_document_delete (json_obj); |
626 | handle); | ||
627 | |||
628 | } | ||
629 | |||
630 | |||
631 | /** | ||
632 | * Build a GNUid token for identity | ||
633 | * | ||
634 | * @param cls the request handle | ||
635 | */ | ||
636 | static void | ||
637 | return_token_list (void *cls) | ||
638 | { | ||
639 | char* result_str; | ||
640 | struct RequestHandle *handle = cls; | ||
641 | struct MHD_Response *resp; | ||
642 | |||
643 | GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); | ||
644 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); | ||
645 | resp = GNUNET_REST_create_response (result_str); | ||
646 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
647 | GNUNET_free (result_str); | ||
648 | cleanup_handle (handle); | ||
649 | } | 612 | } |
650 | 613 | ||
651 | 614 | ||
652 | static void | ||
653 | token_collect_error_cb (void *cls) | ||
654 | { | ||
655 | struct RequestHandle *handle = cls; | ||
656 | |||
657 | do_error (handle); | ||
658 | } | ||
659 | |||
660 | 615 | ||
661 | /** | 616 | /** |
662 | * Collect all tokens for an ego | 617 | * Collect all attributes for an ego |
663 | * | ||
664 | * TODO move this into the identity-provider service | ||
665 | * | 618 | * |
666 | */ | 619 | */ |
667 | static void | 620 | static void |
668 | token_collect (void *cls, | 621 | attr_collect (void *cls, |
669 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 622 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, |
670 | const char *label, | 623 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) |
671 | unsigned int rd_count, | ||
672 | const struct GNUNET_GNSRECORD_Data *rd); | ||
673 | |||
674 | |||
675 | static void | ||
676 | token_collect_finished_cb (void *cls) | ||
677 | { | 624 | { |
625 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
678 | struct RequestHandle *handle = cls; | 626 | struct RequestHandle *handle = cls; |
679 | struct EgoEntry *ego_tmp; | 627 | json_t *value; |
680 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | 628 | |
681 | 629 | if ((NULL == attr->name) || (NULL == attr->data)) | |
682 | ego_tmp = handle->ego_head; | ||
683 | GNUNET_CONTAINER_DLL_remove (handle->ego_head, | ||
684 | handle->ego_tail, | ||
685 | ego_tmp); | ||
686 | GNUNET_free (ego_tmp->identifier); | ||
687 | GNUNET_free (ego_tmp->keystring); | ||
688 | GNUNET_free (ego_tmp); | ||
689 | |||
690 | if (NULL == handle->ego_head) | ||
691 | { | 630 | { |
692 | //Done | 631 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it); |
693 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token END\n"); | ||
694 | handle->ns_it = NULL; | ||
695 | GNUNET_SCHEDULER_add_now (&return_token_list, handle); | ||
696 | return; | 632 | return; |
697 | } | 633 | } |
698 | 634 | ||
699 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 635 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", |
700 | "Next ego: %s\n", | 636 | attr->name); |
701 | handle->ego_head->identifier); | 637 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE, |
702 | priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); | 638 | attr->name); |
703 | handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, | 639 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); |
704 | priv_key, | ||
705 | &token_collect_error_cb, | ||
706 | handle, | ||
707 | &token_collect, | ||
708 | handle, | ||
709 | &token_collect_finished_cb, | ||
710 | handle); | ||
711 | } | ||
712 | |||
713 | |||
714 | /** | ||
715 | * Collect all tokens for an ego | ||
716 | * | ||
717 | * TODO move this into the identity-provider service | ||
718 | * | ||
719 | */ | ||
720 | static void | ||
721 | token_collect (void *cls, | ||
722 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
723 | const char *label, | ||
724 | unsigned int rd_count, | ||
725 | const struct GNUNET_GNSRECORD_Data *rd) | ||
726 | { | ||
727 | struct RequestHandle *handle = cls; | ||
728 | int i; | ||
729 | char* data; | ||
730 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
731 | json_t *issuer; | ||
732 | json_t *token; | ||
733 | |||
734 | for (i = 0; i < rd_count; i++) | ||
735 | { | ||
736 | if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_TOKEN) | ||
737 | { | ||
738 | data = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, | ||
739 | rd[i].data, | ||
740 | rd[i].data_size); | ||
741 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding token: %s\n", data); | ||
742 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TOKEN, | ||
743 | label); | ||
744 | issuer = json_string (handle->ego_head->identifier); | ||
745 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
746 | GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, | ||
747 | issuer); | ||
748 | json_decref (issuer); | ||
749 | token = json_string (data); | ||
750 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
751 | GNUNET_REST_JSONAPI_IDENTITY_TOKEN, | ||
752 | token); | ||
753 | json_decref (token); | ||
754 | |||
755 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); | ||
756 | GNUNET_free (data); | ||
757 | } | ||
758 | } | ||
759 | 640 | ||
760 | GNUNET_NAMESTORE_zone_iterator_next (handle->ns_it); | 641 | value = json_string (attr->data); |
642 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
643 | "value", | ||
644 | value); | ||
645 | json_decref (value); | ||
646 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it); | ||
761 | } | 647 | } |
762 | 648 | ||
763 | 649 | ||
764 | 650 | ||
765 | /** | 651 | /** |
766 | * Respond to OPTIONS request | 652 | * List attributes for identity request |
767 | * | 653 | * |
768 | * @param con_handle the connection handle | 654 | * @param con_handle the connection handle |
769 | * @param url the url | 655 | * @param url the url |
770 | * @param cls the RequestHandle | 656 | * @param cls the RequestHandle |
771 | */ | 657 | */ |
772 | static void | 658 | static void |
773 | list_token_cont (struct GNUNET_REST_RequestHandle *con_handle, | 659 | list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, |
774 | const char* url, | 660 | const char* url, |
775 | void *cls) | 661 | void *cls) |
776 | { | 662 | { |
777 | char* ego_val; | ||
778 | struct GNUNET_HashCode key; | ||
779 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; | 663 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; |
780 | struct RequestHandle *handle = cls; | 664 | struct RequestHandle *handle = cls; |
781 | struct EgoEntry *ego_entry; | 665 | struct EgoEntry *ego_entry; |
782 | struct EgoEntry *ego_tmp; | 666 | char *identity; |
783 | 667 | ||
784 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST, | 668 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n", |
785 | strlen (GNUNET_REST_JSONAPI_IDENTITY_ISS_REQUEST), | 669 | handle->url); |
786 | &key); | 670 | if ( strlen (GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES) >= |
787 | 671 | strlen (handle->url)) | |
788 | if ( GNUNET_YES != | ||
789 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | ||
790 | &key) ) | ||
791 | { | 672 | { |
792 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No issuer given.\n"); | 673 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); |
793 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 674 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
794 | return; | 675 | return; |
795 | } | 676 | } |
796 | ego_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | 677 | identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES) + 1; |
797 | &key); | 678 | |
798 | GNUNET_assert (NULL != ego_val); | ||
799 | //Remove non-matching egos | ||
800 | for (ego_entry = handle->ego_head; | 679 | for (ego_entry = handle->ego_head; |
801 | NULL != ego_entry;) | 680 | NULL != ego_entry; |
802 | { | 681 | ego_entry = ego_entry->next) |
803 | ego_tmp = ego_entry; | 682 | if (0 == strcmp (identity, ego_entry->identifier)) |
804 | ego_entry = ego_entry->next; | 683 | break; |
805 | if (0 != strcmp (ego_val, ego_tmp->identifier)) | ||
806 | { | ||
807 | GNUNET_CONTAINER_DLL_remove (handle->ego_head, | ||
808 | handle->ego_tail, | ||
809 | ego_tmp); | ||
810 | GNUNET_free (ego_tmp->identifier); | ||
811 | GNUNET_free (ego_tmp->keystring); | ||
812 | GNUNET_free (ego_tmp); | ||
813 | } | ||
814 | } | ||
815 | handle->resp_object = GNUNET_JSONAPI_document_new (); | 684 | handle->resp_object = GNUNET_JSONAPI_document_new (); |
816 | if (NULL == handle->ego_head) | 685 | |
686 | |||
687 | if (NULL == ego_entry) | ||
817 | { | 688 | { |
818 | //Done | 689 | //Done |
819 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No results.\n"); | 690 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", |
820 | GNUNET_SCHEDULER_add_now (&return_token_list, handle); | 691 | identity); |
692 | GNUNET_SCHEDULER_add_now (&return_response, handle); | ||
821 | return; | 693 | return; |
822 | } | 694 | } |
823 | priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); | 695 | priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); |
824 | handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); | 696 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); |
825 | handle->ns_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, | 697 | handle->attr_it = GNUNET_IDENTITY_PROVIDER_get_attributes_start (handle->idp, |
826 | priv_key, | 698 | priv_key, |
827 | &token_collect_error_cb, | 699 | &collect_error_cb, |
828 | handle, | 700 | handle, |
829 | &token_collect, | 701 | &attr_collect, |
830 | handle, | 702 | handle, |
831 | &token_collect_finished_cb, | 703 | &collect_finished_cb, |
832 | handle); | 704 | handle); |
833 | |||
834 | } | 705 | } |
835 | 706 | ||
836 | /** | 707 | |
837 | * Return token to requestor | ||
838 | * | ||
839 | * @param cls request handle | ||
840 | * @param token the token | ||
841 | */ | ||
842 | static void | 708 | static void |
843 | exchange_cont (void *cls, | 709 | revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, |
844 | const struct GNUNET_IDENTITY_PROVIDER_Token *token, | 710 | const char* url, |
845 | uint64_t ticket_nonce) | 711 | void *cls) |
846 | { | 712 | { |
847 | json_t *root; | 713 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; |
714 | const char* identity_str; | ||
715 | const char* audience_str; | ||
716 | const char* rnd_str; | ||
717 | |||
848 | struct RequestHandle *handle = cls; | 718 | struct RequestHandle *handle = cls; |
719 | struct EgoEntry *ego_entry; | ||
849 | struct MHD_Response *resp; | 720 | struct MHD_Response *resp; |
850 | struct GNUNET_HashCode key; | 721 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; |
851 | char* result; | 722 | struct GNUNET_JSONAPI_Document *json_obj; |
852 | char* token_str; | 723 | struct GNUNET_JSONAPI_Resource *json_res; |
853 | char* nonce_str; | 724 | struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; |
854 | uint64_t expected_nonce; | 725 | char term_data[handle->rest_handle->data_size+1]; |
855 | 726 | json_t *rnd_json; | |
856 | //Get nonce | 727 | json_t *identity_json; |
857 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE, | 728 | json_t *audience_json; |
858 | strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_EXPECTED_NONCE), | 729 | json_t *data_json; |
859 | &key); | 730 | json_error_t err; |
860 | 731 | struct GNUNET_JSON_Specification docspec[] = { | |
861 | if ( GNUNET_NO == | 732 | GNUNET_JSON_spec_jsonapi_document (&json_obj), |
862 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | 733 | GNUNET_JSON_spec_end() |
863 | &key) ) | 734 | }; |
735 | |||
736 | if (0 >= handle->rest_handle->data_size) | ||
864 | { | 737 | { |
865 | handle->emsg = GNUNET_strdup ("No nonce given."); | ||
866 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 738 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
867 | return; | 739 | return; |
868 | } | 740 | } |
869 | nonce_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | ||
870 | &key); | ||
871 | GNUNET_assert (NULL != nonce_str); | ||
872 | GNUNET_assert (1 == sscanf (nonce_str, "%"SCNu64, &expected_nonce)); | ||
873 | 741 | ||
874 | if (ticket_nonce != expected_nonce) | 742 | term_data[handle->rest_handle->data_size] = '\0'; |
743 | GNUNET_memcpy (term_data, | ||
744 | handle->rest_handle->data, | ||
745 | handle->rest_handle->data_size); | ||
746 | data_json = json_loads (term_data, | ||
747 | JSON_DECODE_ANY, | ||
748 | &err); | ||
749 | GNUNET_assert (GNUNET_OK == | ||
750 | GNUNET_JSON_parse (data_json, docspec, | ||
751 | NULL, NULL)); | ||
752 | json_decref (data_json); | ||
753 | if (NULL == json_obj) | ||
754 | { | ||
755 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
756 | "Unable to parse JSONAPI Object from %s\n", | ||
757 | term_data); | ||
758 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
759 | return; | ||
760 | } | ||
761 | if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) | ||
875 | { | 762 | { |
876 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 763 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
877 | "Ticket nonce %"SCNu64" does not match expected nonce %"SCNu64"\n", | 764 | "Cannot create more than 1 resource! (Got %d)\n", |
878 | ticket_nonce, expected_nonce); | 765 | GNUNET_JSONAPI_document_resource_count (json_obj)); |
879 | handle->emsg = GNUNET_strdup ("Ticket nonce does not match expected nonce\n"); | 766 | GNUNET_JSONAPI_document_delete (json_obj); |
880 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 767 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
881 | return; | 768 | return; |
882 | } | 769 | } |
770 | json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); | ||
771 | if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, | ||
772 | GNUNET_REST_JSONAPI_IDENTITY_TICKET)) | ||
773 | { | ||
774 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
775 | "Unsupported JSON data type\n"); | ||
776 | GNUNET_JSONAPI_document_delete (json_obj); | ||
777 | resp = GNUNET_REST_create_response (NULL); | ||
778 | handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); | ||
779 | cleanup_handle (handle); | ||
780 | return; | ||
781 | } | ||
782 | rnd_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
783 | "rnd"); | ||
784 | identity_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
785 | "identity"); | ||
786 | audience_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
787 | "audience"); | ||
788 | rnd_str = json_string_value (rnd_json); | ||
789 | identity_str = json_string_value (identity_json); | ||
790 | audience_str = json_string_value (audience_json); | ||
791 | |||
792 | GNUNET_STRINGS_string_to_data (rnd_str, | ||
793 | strlen (rnd_str), | ||
794 | &ticket.rnd, | ||
795 | sizeof (uint64_t)); | ||
796 | GNUNET_STRINGS_string_to_data (identity_str, | ||
797 | strlen (identity_str), | ||
798 | &ticket.identity, | ||
799 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
800 | GNUNET_STRINGS_string_to_data (audience_str, | ||
801 | strlen (audience_str), | ||
802 | &ticket.audience, | ||
803 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
883 | 804 | ||
884 | root = json_object (); | 805 | for (ego_entry = handle->ego_head; |
885 | token_str = GNUNET_IDENTITY_PROVIDER_token_to_string (token); | 806 | NULL != ego_entry; |
886 | json_object_set_new (root, "token", json_string (token_str)); | 807 | ego_entry = ego_entry->next) |
887 | json_object_set_new (root, "token_type", json_string ("jwt")); | 808 | { |
888 | GNUNET_free (token_str); | 809 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, |
810 | &tmp_pk); | ||
811 | if (0 == memcmp (&ticket.identity, | ||
812 | &tmp_pk, | ||
813 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
814 | break; | ||
815 | } | ||
816 | if (NULL == ego_entry) | ||
817 | { | ||
818 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
819 | "Identity unknown (%s)\n", identity_str); | ||
820 | GNUNET_JSONAPI_document_delete (json_obj); | ||
821 | return; | ||
822 | } | ||
823 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
889 | 824 | ||
890 | result = json_dumps (root, JSON_INDENT(1)); | 825 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); |
891 | resp = GNUNET_REST_create_response (result); | 826 | handle->idp_op = GNUNET_IDENTITY_PROVIDER_ticket_revoke (handle->idp, |
892 | GNUNET_free (result); | 827 | identity_priv, |
893 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 828 | &ticket, |
894 | cleanup_handle (handle); | 829 | &finished_cont, |
895 | json_decref (root); | 830 | handle); |
831 | GNUNET_JSONAPI_document_delete (json_obj); | ||
896 | } | 832 | } |
897 | 833 | ||
898 | |||
899 | /** | ||
900 | * | ||
901 | * Callback called when identity for token exchange has been found | ||
902 | * | ||
903 | * @param cls request handle | ||
904 | * @param ego the identity to use as issuer | ||
905 | * @param ctx user context | ||
906 | * @param name identity name | ||
907 | * | ||
908 | */ | ||
909 | static void | 834 | static void |
910 | exchange_token_ticket_cb (void *cls, | 835 | consume_cont (void *cls, |
911 | struct GNUNET_IDENTITY_Ego *ego, | 836 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, |
912 | void **ctx, | 837 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr) |
913 | const char *name) | ||
914 | { | 838 | { |
915 | struct RequestHandle *handle = cls; | 839 | struct RequestHandle *handle = cls; |
916 | struct GNUNET_HashCode key; | 840 | struct GNUNET_JSONAPI_Resource *json_resource; |
917 | struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket; | 841 | json_t *value; |
918 | char* ticket_str; | ||
919 | 842 | ||
920 | handle->op = NULL; | 843 | if (NULL == identity) |
844 | { | ||
845 | GNUNET_SCHEDULER_add_now (&return_response, handle); | ||
846 | return; | ||
847 | } | ||
848 | |||
849 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", | ||
850 | attr->name); | ||
851 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE, | ||
852 | attr->name); | ||
853 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); | ||
854 | |||
855 | value = json_string (attr->data); | ||
856 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
857 | "value", | ||
858 | value); | ||
859 | json_decref (value); | ||
860 | } | ||
921 | 861 | ||
922 | if (NULL == ego) | 862 | static void |
863 | consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
864 | const char* url, | ||
865 | void *cls) | ||
866 | { | ||
867 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; | ||
868 | const char* identity_str; | ||
869 | const char* audience_str; | ||
870 | const char* rnd_str; | ||
871 | |||
872 | struct RequestHandle *handle = cls; | ||
873 | struct EgoEntry *ego_entry; | ||
874 | struct MHD_Response *resp; | ||
875 | struct GNUNET_IDENTITY_PROVIDER_Ticket ticket; | ||
876 | struct GNUNET_JSONAPI_Document *json_obj; | ||
877 | struct GNUNET_JSONAPI_Resource *json_res; | ||
878 | struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; | ||
879 | char term_data[handle->rest_handle->data_size+1]; | ||
880 | json_t *rnd_json; | ||
881 | json_t *identity_json; | ||
882 | json_t *audience_json; | ||
883 | json_t *data_json; | ||
884 | json_error_t err; | ||
885 | struct GNUNET_JSON_Specification docspec[] = { | ||
886 | GNUNET_JSON_spec_jsonapi_document (&json_obj), | ||
887 | GNUNET_JSON_spec_end() | ||
888 | }; | ||
889 | |||
890 | if (0 >= handle->rest_handle->data_size) | ||
923 | { | 891 | { |
924 | handle->emsg = GNUNET_strdup ("No identity found."); | ||
925 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 892 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
926 | return; | 893 | return; |
927 | } | 894 | } |
928 | 895 | ||
929 | //Get ticket | 896 | term_data[handle->rest_handle->data_size] = '\0'; |
930 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, | 897 | GNUNET_memcpy (term_data, |
931 | strlen (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET), | 898 | handle->rest_handle->data, |
932 | &key); | 899 | handle->rest_handle->data_size); |
933 | 900 | data_json = json_loads (term_data, | |
934 | if ( GNUNET_NO == | 901 | JSON_DECODE_ANY, |
935 | GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map, | 902 | &err); |
936 | &key) ) | 903 | GNUNET_assert (GNUNET_OK == |
904 | GNUNET_JSON_parse (data_json, docspec, | ||
905 | NULL, NULL)); | ||
906 | json_decref (data_json); | ||
907 | if (NULL == json_obj) | ||
908 | { | ||
909 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
910 | "Unable to parse JSONAPI Object from %s\n", | ||
911 | term_data); | ||
912 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
913 | return; | ||
914 | } | ||
915 | if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) | ||
937 | { | 916 | { |
938 | handle->emsg = GNUNET_strdup ("No ticket given."); | 917 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
918 | "Cannot create more than 1 resource! (Got %d)\n", | ||
919 | GNUNET_JSONAPI_document_resource_count (json_obj)); | ||
920 | GNUNET_JSONAPI_document_delete (json_obj); | ||
939 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 921 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
940 | return; | 922 | return; |
941 | } | 923 | } |
942 | ticket_str = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map, | 924 | json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); |
943 | &key); | 925 | if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, |
944 | handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (ego); | 926 | GNUNET_REST_JSONAPI_IDENTITY_TICKET)) |
945 | GNUNET_IDENTITY_PROVIDER_string_to_ticket (ticket_str, | 927 | { |
946 | &ticket); | 928 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
929 | "Unsupported JSON data type\n"); | ||
930 | GNUNET_JSONAPI_document_delete (json_obj); | ||
931 | resp = GNUNET_REST_create_response (NULL); | ||
932 | handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); | ||
933 | cleanup_handle (handle); | ||
934 | return; | ||
935 | } | ||
936 | rnd_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
937 | "rnd"); | ||
938 | identity_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
939 | "identity"); | ||
940 | audience_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
941 | "audience"); | ||
942 | rnd_str = json_string_value (rnd_json); | ||
943 | identity_str = json_string_value (identity_json); | ||
944 | audience_str = json_string_value (audience_json); | ||
945 | |||
946 | GNUNET_STRINGS_string_to_data (rnd_str, | ||
947 | strlen (rnd_str), | ||
948 | &ticket.rnd, | ||
949 | sizeof (uint64_t)); | ||
950 | GNUNET_STRINGS_string_to_data (identity_str, | ||
951 | strlen (identity_str), | ||
952 | &ticket.identity, | ||
953 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
954 | GNUNET_STRINGS_string_to_data (audience_str, | ||
955 | strlen (audience_str), | ||
956 | &ticket.audience, | ||
957 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); | ||
947 | 958 | ||
959 | for (ego_entry = handle->ego_head; | ||
960 | NULL != ego_entry; | ||
961 | ego_entry = ego_entry->next) | ||
962 | { | ||
963 | GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, | ||
964 | &tmp_pk); | ||
965 | if (0 == memcmp (&ticket.audience, | ||
966 | &tmp_pk, | ||
967 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
968 | break; | ||
969 | } | ||
970 | if (NULL == ego_entry) | ||
971 | { | ||
972 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
973 | "Identity unknown (%s)\n", identity_str); | ||
974 | GNUNET_JSONAPI_document_delete (json_obj); | ||
975 | return; | ||
976 | } | ||
977 | identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); | ||
978 | handle->resp_object = GNUNET_JSONAPI_document_new (); | ||
948 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); | 979 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); |
949 | handle->idp_op = GNUNET_IDENTITY_PROVIDER_exchange_ticket (handle->idp, | 980 | handle->idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume (handle->idp, |
950 | ticket, | 981 | identity_priv, |
951 | handle->priv_key, | 982 | &ticket, |
952 | &exchange_cont, | 983 | &consume_cont, |
953 | handle); | 984 | handle); |
954 | GNUNET_IDENTITY_PROVIDER_ticket_destroy (ticket); | 985 | GNUNET_JSONAPI_document_delete (json_obj); |
955 | |||
956 | } | 986 | } |
957 | 987 | ||
958 | 988 | ||
959 | 989 | ||
960 | /** | 990 | /** |
961 | * Respond to issue request | ||
962 | * | ||
963 | * @param con_handle the connection handle | ||
964 | * @param url the url | ||
965 | * @param cls the RequestHandle | ||
966 | */ | ||
967 | static void | ||
968 | exchange_token_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
969 | const char* url, | ||
970 | void *cls) | ||
971 | { | ||
972 | struct RequestHandle *handle = cls; | ||
973 | |||
974 | //Get token from GNS | ||
975 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | ||
976 | "gns-master", | ||
977 | &exchange_token_ticket_cb, | ||
978 | handle); | ||
979 | } | ||
980 | |||
981 | /** | ||
982 | * Respond to OPTIONS request | 991 | * Respond to OPTIONS request |
983 | * | 992 | * |
984 | * @param con_handle the connection handle | 993 | * @param con_handle the connection handle |
@@ -1013,15 +1022,17 @@ init_cont (struct RequestHandle *handle) | |||
1013 | { | 1022 | { |
1014 | struct GNUNET_REST_RequestHandlerError err; | 1023 | struct GNUNET_REST_RequestHandlerError err; |
1015 | static const struct GNUNET_REST_RequestHandler handlers[] = { | 1024 | static const struct GNUNET_REST_RequestHandler handlers[] = { |
1016 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TOKEN_ISSUE, &issue_token_cont}, | 1025 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont}, |
1017 | //{MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_TOKEN_CHECK, &check_token_cont}, | 1026 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, |
1018 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &list_token_cont}, | 1027 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, |
1019 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, &options_cont}, | 1028 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, |
1020 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_OAUTH2_TOKEN, &exchange_token_ticket_cont}, | 1029 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, |
1030 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, | ||
1031 | &options_cont}, | ||
1021 | GNUNET_REST_HANDLER_END | 1032 | GNUNET_REST_HANDLER_END |
1022 | }; | 1033 | }; |
1023 | 1034 | ||
1024 | if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle, | 1035 | if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, |
1025 | handlers, | 1036 | handlers, |
1026 | &err, | 1037 | &err, |
1027 | handle)) | 1038 | handle)) |
@@ -1092,19 +1103,8 @@ list_ego (void *cls, | |||
1092 | 1103 | ||
1093 | } | 1104 | } |
1094 | 1105 | ||
1095 | /** | ||
1096 | * Function processing the REST call | ||
1097 | * | ||
1098 | * @param method HTTP method | ||
1099 | * @param url URL of the HTTP request | ||
1100 | * @param data body of the HTTP request (optional) | ||
1101 | * @param data_size length of the body | ||
1102 | * @param proc callback function for the result | ||
1103 | * @param proc_cls closure for callback function | ||
1104 | * @return GNUNET_OK if request accepted | ||
1105 | */ | ||
1106 | static void | 1106 | static void |
1107 | rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, | 1107 | rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, |
1108 | GNUNET_REST_ResultProcessor proc, | 1108 | GNUNET_REST_ResultProcessor proc, |
1109 | void *proc_cls) | 1109 | void *proc_cls) |
1110 | { | 1110 | { |
@@ -1114,10 +1114,9 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, | |||
1114 | handle->proc_cls = proc_cls; | 1114 | handle->proc_cls = proc_cls; |
1115 | handle->proc = proc; | 1115 | handle->proc = proc; |
1116 | handle->state = ID_REST_STATE_INIT; | 1116 | handle->state = ID_REST_STATE_INIT; |
1117 | handle->conndata_handle = conndata_handle; | 1117 | handle->rest_handle = rest_handle; |
1118 | 1118 | ||
1119 | 1119 | handle->url = GNUNET_strdup (rest_handle->url); | |
1120 | handle->url = GNUNET_strdup (conndata_handle->url); | ||
1121 | if (handle->url[strlen (handle->url)-1] == '/') | 1120 | if (handle->url[strlen (handle->url)-1] == '/') |
1122 | handle->url[strlen (handle->url)-1] = '\0'; | 1121 | handle->url[strlen (handle->url)-1] = '\0'; |
1123 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1122 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1162,8 +1161,8 @@ libgnunet_plugin_rest_identity_provider_init (void *cls) | |||
1162 | MHD_HTTP_METHOD_DELETE, | 1161 | MHD_HTTP_METHOD_DELETE, |
1163 | MHD_HTTP_METHOD_OPTIONS); | 1162 | MHD_HTTP_METHOD_OPTIONS); |
1164 | 1163 | ||
1165 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1166 | _("Identity Token REST API initialized\n")); | 1165 | _("Identity Provider REST API initialized\n")); |
1167 | return api; | 1166 | return api; |
1168 | } | 1167 | } |
1169 | 1168 | ||
@@ -1184,8 +1183,8 @@ libgnunet_plugin_rest_identity_provider_done (void *cls) | |||
1184 | GNUNET_free_non_null (allow_methods); | 1183 | GNUNET_free_non_null (allow_methods); |
1185 | GNUNET_free (api); | 1184 | GNUNET_free (api); |
1186 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1185 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1187 | "Identity Token REST plugin is finished\n"); | 1186 | "Identity Provider REST plugin is finished\n"); |
1188 | return NULL; | 1187 | return NULL; |
1189 | } | 1188 | } |
1190 | 1189 | ||
1191 | /* end of plugin_rest_gns.c */ | 1190 | /* end of plugin_rest_identity_provider.c */ |
diff --git a/src/identity-provider/test_idp.conf b/src/identity-provider/test_idp.conf new file mode 100644 index 000000000..2b76c7bf2 --- /dev/null +++ b/src/identity-provider/test_idp.conf | |||
@@ -0,0 +1,28 @@ | |||
1 | @INLINE@ test_idp_defaults.conf | ||
2 | |||
3 | [PATHS] | ||
4 | GNUNET_TEST_HOME = /tmp/test-gnunet-idp-peer-1/ | ||
5 | |||
6 | [dht] | ||
7 | AUTOSTART = YES | ||
8 | |||
9 | [rest] | ||
10 | AUTOSTART = YES | ||
11 | #PREFIX = valgrind --leak-check=full --track-origins=yes --log-file=/tmp/restlog | ||
12 | |||
13 | [transport] | ||
14 | PLUGINS = | ||
15 | |||
16 | [identity-provider] | ||
17 | AUTOSTART = YES | ||
18 | #PREFIX = valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --log-file=/tmp/idplog | ||
19 | |||
20 | [gns] | ||
21 | #PREFIX = valgrind --leak-check=full --track-origins=yes | ||
22 | AUTOSTART = YES | ||
23 | AUTO_IMPORT_PKEY = YES | ||
24 | MAX_PARALLEL_BACKGROUND_QUERIES = 10 | ||
25 | DEFAULT_LOOKUP_TIMEOUT = 15 s | ||
26 | RECORD_PUT_INTERVAL = 1 h | ||
27 | ZONE_PUBLISH_TIME_WINDOW = 1 h | ||
28 | DNS_ROOT=PD67SGHF3E0447TU9HADIVU9OM7V4QHTOG0EBU69TFRI2LG63DR0 | ||
diff --git a/src/identity-provider/test_idp.sh b/src/identity-provider/test_idp.sh new file mode 100755 index 000000000..598d1008c --- /dev/null +++ b/src/identity-provider/test_idp.sh | |||
@@ -0,0 +1,31 @@ | |||
1 | #!/bin/bash | ||
2 | #trap "gnunet-arm -e -c test_idp_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_idp.conf | ||
27 | gnunet-identity -C testego -c test_idp.conf | ||
28 | valgrind gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf | ||
29 | gnunet-idp -e testego -a name -V John -c test_idp.conf | ||
30 | gnunet-idp -e testego -D -c test_idp.conf | ||
31 | gnunet-arm -e -c test_idp.conf | ||
diff --git a/src/identity-provider/test_idp_attribute.sh b/src/identity-provider/test_idp_attribute.sh new file mode 100755 index 000000000..7f0f06dac --- /dev/null +++ b/src/identity-provider/test_idp_attribute.sh | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_idp.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_idp.conf | ||
27 | #gnunet-arm -i rest -c test_idp.conf | ||
28 | gnunet-identity -C testego -c test_idp.conf | ||
29 | gnunet-identity -C rpego -c test_idp.conf | ||
30 | TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}') | ||
31 | gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf | ||
32 | gnunet-idp -e testego -a name -V John -c test_idp.conf > /dev/null 2>&1 | ||
33 | if test $? != 0 | ||
34 | then | ||
35 | echo "Failed." | ||
36 | exit 1 | ||
37 | fi | ||
38 | |||
39 | #curl localhost:7776/idp/attributes/testego | ||
40 | gnunet-arm -e -c test_idp.conf | ||
diff --git a/src/identity-provider/test_idp_consume.sh b/src/identity-provider/test_idp_consume.sh new file mode 100755 index 000000000..11f6865a4 --- /dev/null +++ b/src/identity-provider/test_idp_consume.sh | |||
@@ -0,0 +1,43 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_idp.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_idp.conf | ||
27 | #gnunet-arm -i rest -c test_idp.conf | ||
28 | gnunet-identity -C testego -c test_idp.conf | ||
29 | gnunet-identity -C rpego -c test_idp.conf | ||
30 | SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}') | ||
31 | TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}') | ||
32 | gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf | ||
33 | gnunet-idp -e testego -a name -V John -c test_idp.conf | ||
34 | TICKET=$(gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf | awk '{print $1}') | ||
35 | gnunet-idp -e rpego -C $TICKET -c test_idp.conf > /dev/null 2>&1 | ||
36 | |||
37 | if test $? != 0 | ||
38 | then | ||
39 | "Failed." | ||
40 | exit 1 | ||
41 | fi | ||
42 | #curl http://localhost:7776/idp/tickets/testego | ||
43 | gnunet-arm -e -c test_idp.conf | ||
diff --git a/src/identity-provider/test_idp_defaults.conf b/src/identity-provider/test_idp_defaults.conf new file mode 100644 index 000000000..10d89c2fb --- /dev/null +++ b/src/identity-provider/test_idp_defaults.conf | |||
@@ -0,0 +1,24 @@ | |||
1 | @INLINE@ ../../contrib/no_forcestart.conf | ||
2 | |||
3 | [PATHS] | ||
4 | GNUNET_TEST_HOME = /tmp/test-gnunet-idp-testing/ | ||
5 | |||
6 | [namestore-sqlite] | ||
7 | FILENAME = $GNUNET_TEST_HOME/namestore/sqlite_test.db | ||
8 | |||
9 | [namecache-sqlite] | ||
10 | FILENAME=$GNUNET_TEST_HOME/namecache/namecache.db | ||
11 | |||
12 | [identity] | ||
13 | # Directory where we store information about our egos | ||
14 | EGODIR = $GNUNET_TEST_HOME/identity/egos/ | ||
15 | |||
16 | [dhtcache] | ||
17 | DATABASE = heap | ||
18 | |||
19 | [transport] | ||
20 | PLUGINS = tcp | ||
21 | |||
22 | [transport-tcp] | ||
23 | BINDTO = 127.0.0.1 | ||
24 | |||
diff --git a/src/identity-provider/test_idp_issue.sh b/src/identity-provider/test_idp_issue.sh new file mode 100755 index 000000000..90487ee73 --- /dev/null +++ b/src/identity-provider/test_idp_issue.sh | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_idp.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_idp.conf | ||
27 | #gnunet-arm -i rest -c test_idp.conf | ||
28 | gnunet-identity -C testego -c test_idp.conf | ||
29 | gnunet-identity -C rpego -c test_idp.conf | ||
30 | SUBJECT_KEY=$(gnunet-identity -d -c test_idp.conf | grep rpego | awk '{print $3}') | ||
31 | TEST_KEY=$(gnunet-identity -d -c test_idp.conf | grep testego | awk '{print $3}') | ||
32 | gnunet-idp -e testego -a email -V john@doe.gnu -c test_idp.conf > /dev/null 2>&1 | ||
33 | gnunet-idp -e testego -a name -V John -c test_idp.conf > /dev/null 2>&1 | ||
34 | #gnunet-idp -e testego -D -c test_idp.conf | ||
35 | gnunet-idp -e testego -i "email,name" -r $SUBJECT_KEY -c test_idp.conf > /dev/null 2>&1 | ||
36 | if test $? != 0 | ||
37 | then | ||
38 | echo "Failed." | ||
39 | exit 1 | ||
40 | fi | ||
41 | #curl http://localhost:7776/idp/attributes/testego | ||
42 | gnunet-arm -e -c test_idp.conf | ||
diff --git a/src/identity-provider/test_idp_revoke.sh b/src/identity-provider/test_idp_revoke.sh new file mode 100755 index 000000000..d5c2c3f77 --- /dev/null +++ b/src/identity-provider/test_idp_revoke.sh | |||
@@ -0,0 +1,60 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_idp.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_idp.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | |||
18 | # (1) PKEY1.user -> PKEY2.resu.user | ||
19 | # (2) PKEY2.resu -> PKEY3 | ||
20 | # (3) PKEY3.user -> PKEY4 | ||
21 | |||
22 | |||
23 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
24 | |||
25 | TEST_ATTR="test" | ||
26 | gnunet-arm -s -c test_idp.conf | ||
27 | gnunet-identity -C alice -c test_idp.conf | ||
28 | gnunet-identity -C bob -c test_idp.conf | ||
29 | gnunet-identity -C eve -c test_idp.conf | ||
30 | ALICE_KEY=$(gnunet-identity -d -c test_idp.conf | grep alice | awk '{print $3}') | ||
31 | BOB_KEY=$(gnunet-identity -d -c test_idp.conf | grep bob | awk '{print $3}') | ||
32 | EVE_KEY=$(gnunet-identity -d -c test_idp.conf | grep eve | awk '{print $3}') | ||
33 | |||
34 | gnunet-idp -e alice -a email -V john@doe.gnu -c test_idp.conf | ||
35 | gnunet-idp -e alice -a name -V John -c test_idp.conf | ||
36 | TICKET_BOB=$(gnunet-idp -e alice -i "email,name" -r $BOB_KEY -c test_idp.conf | awk '{print $1}') | ||
37 | #gnunet-idp -e bob -C $TICKET_BOB -c test_idp.conf | ||
38 | TICKET_EVE=$(gnunet-idp -e alice -i "email" -r $EVE_KEY -c test_idp.conf | awk '{print $1}') | ||
39 | |||
40 | |||
41 | #echo "Consuming $TICKET" | ||
42 | #gnunet-idp -e eve -C $TICKET_EVE -c test_idp.conf | ||
43 | gnunet-idp -e alice -R $TICKET_EVE -c test_idp.conf | ||
44 | |||
45 | gnunet-idp -e eve -C $TICKET_EVE -c test_idp.conf > /dev/null 2>&1 | ||
46 | if test $? == 0 | ||
47 | then | ||
48 | echo "Eve can still resolve attributes..." | ||
49 | gnunet-arm -e -c test_idp.conf | ||
50 | exit 1 | ||
51 | fi | ||
52 | gnunet-idp -e bob -C $TICKET_BOB -c test_idp.conf > /dev/null 2>&1 | ||
53 | if test $? != 0 | ||
54 | then | ||
55 | echo "Bob cannot resolve attributes..." | ||
56 | gnunet-arm -e -c test_idp.conf | ||
57 | exit 1 | ||
58 | fi | ||
59 | |||
60 | gnunet-arm -e -c test_idp.conf | ||
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am index 94e8c5e94..b8e70fffb 100644 --- a/src/identity/Makefile.am +++ b/src/identity/Makefile.am | |||
@@ -42,8 +42,7 @@ libexec_PROGRAMS = \ | |||
42 | if HAVE_MHD | 42 | if HAVE_MHD |
43 | if HAVE_JSON | 43 | if HAVE_JSON |
44 | plugin_LTLIBRARIES = \ | 44 | plugin_LTLIBRARIES = \ |
45 | libgnunet_plugin_rest_identity.la \ | 45 | libgnunet_plugin_rest_identity.la |
46 | libgnunet_plugin_gnsrecord_identity.la | ||
47 | endif | 46 | endif |
48 | endif | 47 | endif |
49 | 48 | ||
@@ -55,14 +54,6 @@ gnunet_service_identity_LDADD = \ | |||
55 | $(top_builddir)/src/util/libgnunetutil.la \ | 54 | $(top_builddir)/src/util/libgnunetutil.la \ |
56 | $(GN_LIBINTL) | 55 | $(GN_LIBINTL) |
57 | 56 | ||
58 | libgnunet_plugin_gnsrecord_identity_la_SOURCES = \ | ||
59 | plugin_gnsrecord_identity.c | ||
60 | libgnunet_plugin_gnsrecord_identity_la_LIBADD = \ | ||
61 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
62 | $(LTLIBINTL) | ||
63 | libgnunet_plugin_gnsrecord_identity_la_LDFLAGS = \ | ||
64 | $(GN_PLUGIN_LDFLAGS) | ||
65 | |||
66 | 57 | ||
67 | libgnunet_plugin_rest_identity_la_SOURCES = \ | 58 | libgnunet_plugin_rest_identity_la_SOURCES = \ |
68 | plugin_rest_identity.c | 59 | plugin_rest_identity.c |
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c index e64b2685a..5f34d0f1b 100644 --- a/src/identity/plugin_rest_identity.c +++ b/src/identity/plugin_rest_identity.c | |||
@@ -427,9 +427,6 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con, | |||
427 | continue; | 427 | continue; |
428 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_EGO, | 428 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_EGO, |
429 | ego_entry->keystring); | 429 | ego_entry->keystring); |
430 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
431 | "Egoname: %s\n", | ||
432 | ego_entry->identifier); | ||
433 | name_str = json_string (ego_entry->identifier); | 430 | name_str = json_string (ego_entry->identifier); |
434 | GNUNET_JSONAPI_resource_add_attr ( | 431 | GNUNET_JSONAPI_resource_add_attr ( |
435 | json_resource, | 432 | json_resource, |
diff --git a/src/include/gnunet_abe_lib.h b/src/include/gnunet_abe_lib.h new file mode 100644 index 000000000..f73ea2431 --- /dev/null +++ b/src/include/gnunet_abe_lib.h | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2001-2018 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file include/gnunet_abe_lib.h | ||
23 | * @brief Attribute-Based Encryption primitives for GNUnet | ||
24 | * | ||
25 | * @author Martin Schanzenbach | ||
26 | * | ||
27 | * @defgroup abe ABE Crypto library: Attribute-Based Encryption operations | ||
28 | * | ||
29 | */ | ||
30 | #ifndef GNUNET_ABE_LIB_H | ||
31 | #define GNUNET_ABE_LIB_H | ||
32 | |||
33 | #ifdef __cplusplus | ||
34 | extern "C" | ||
35 | { | ||
36 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
37 | } | ||
38 | #endif | ||
39 | #endif | ||
40 | |||
41 | #include "gnunet_common.h" | ||
42 | #include <gcrypt.h> | ||
43 | |||
44 | /** | ||
45 | * @brief type for ABE master keys | ||
46 | */ | ||
47 | struct GNUNET_CRYPTO_AbeMasterKey; | ||
48 | |||
49 | /** | ||
50 | * @brief type for ABE keys | ||
51 | */ | ||
52 | struct GNUNET_CRYPTO_AbeKey; | ||
53 | |||
54 | |||
55 | |||
56 | /** | ||
57 | * @ingroup abe | ||
58 | * Create a new CP-ABE master key. Caller must free return value. | ||
59 | * | ||
60 | * @return fresh private key; free using #GNUNET_ABE_cpabe_delete_master_key | ||
61 | */ | ||
62 | struct GNUNET_ABE_AbeMasterKey * | ||
63 | GNUNET_ABE_cpabe_create_master_key (void); | ||
64 | |||
65 | /** | ||
66 | * @ingroup abe | ||
67 | * Delete a CP-ABE master key. | ||
68 | * | ||
69 | * @param key the master key | ||
70 | * @return fresh private key; free using #GNUNET_free | ||
71 | */ | ||
72 | void | ||
73 | GNUNET_ABE_cpabe_delete_master_key (struct GNUNET_ABE_AbeMasterKey *key); | ||
74 | |||
75 | /** | ||
76 | * @ingroup abe | ||
77 | * Create a new CP-ABE key. Caller must free return value. | ||
78 | * | ||
79 | * @param key the master key | ||
80 | * @param attrs the attributes to append to the key | ||
81 | * @return fresh private key; free using #GNUNET_ABE_cpabe_delete_key | ||
82 | */ | ||
83 | struct GNUNET_ABE_AbeKey * | ||
84 | GNUNET_ABE_cpabe_create_key (struct GNUNET_ABE_AbeMasterKey *key, | ||
85 | char **attrs); | ||
86 | |||
87 | /** | ||
88 | * @ingroup abe | ||
89 | * Delete a CP-ABE key. | ||
90 | * | ||
91 | * @param key the key to delete | ||
92 | * @param delete_pub GNUNE_YES if the public key should also be freed (bug in gabe) | ||
93 | * @return fresh private key; free using #GNUNET_free | ||
94 | */ | ||
95 | void | ||
96 | GNUNET_ABE_cpabe_delete_key (struct GNUNET_ABE_AbeKey *key, | ||
97 | int delete_pub); | ||
98 | |||
99 | |||
100 | /** | ||
101 | * @ingroup abe | ||
102 | * Encrypt a block using sessionkey. | ||
103 | * | ||
104 | * @param block the block to encrypt | ||
105 | * @param size the size of the @a block | ||
106 | * @param policy the ABE policy | ||
107 | * @param key the key used to encrypt | ||
108 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
109 | * @return the size of the encrypted block, -1 for errors | ||
110 | */ | ||
111 | ssize_t | ||
112 | GNUNET_ABE_cpabe_encrypt (const void *block, | ||
113 | size_t size, | ||
114 | const char *policy, | ||
115 | const struct GNUNET_ABE_AbeMasterKey *key, | ||
116 | void **result); | ||
117 | |||
118 | /** | ||
119 | * @ingroup abe | ||
120 | * Decrypt a block using the ABE key. | ||
121 | * | ||
122 | * @param block the block to encrypt | ||
123 | * @param size the size of the @a block | ||
124 | * @param key the key used to decrypt | ||
125 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
126 | * @return the size of the encrypted block, -1 for errors | ||
127 | */ | ||
128 | ssize_t | ||
129 | GNUNET_ABE_cpabe_decrypt (const void *block, | ||
130 | size_t size, | ||
131 | const struct GNUNET_ABE_AbeKey *key, | ||
132 | void **result); | ||
133 | |||
134 | /** | ||
135 | * @ingroup abe | ||
136 | * Serialize an ABE key. | ||
137 | * | ||
138 | * @param key the key to serialize | ||
139 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
140 | * @return the size of the encrypted block, -1 for errors | ||
141 | */ | ||
142 | ssize_t | ||
143 | GNUNET_ABE_cpabe_serialize_key (const struct GNUNET_ABE_AbeKey *key, | ||
144 | void **result); | ||
145 | |||
146 | /** | ||
147 | * @ingroup abe | ||
148 | * Deserialize a serialized ABE key. | ||
149 | * | ||
150 | * @param data the data to deserialize | ||
151 | * @param len the length of the data. | ||
152 | * @return the ABE key. NULL of unsuccessful | ||
153 | */ | ||
154 | struct GNUNET_ABE_AbeKey* | ||
155 | GNUNET_ABE_cpabe_deserialize_key (const void *data, | ||
156 | size_t len); | ||
157 | |||
158 | /** | ||
159 | * @ingroup abe | ||
160 | * Serialize an ABE master key. | ||
161 | * | ||
162 | * @param key the key to serialize | ||
163 | * @param result the result buffer. Will be allocated. Free using #GNUNET_free | ||
164 | * @return the size of the encrypted block, -1 for errors | ||
165 | */ | ||
166 | ssize_t | ||
167 | GNUNET_ABE_cpabe_serialize_master_key (const struct GNUNET_ABE_AbeMasterKey *key, | ||
168 | void **result); | ||
169 | |||
170 | /** | ||
171 | * @ingroup abe | ||
172 | * Deserialize an ABE master key. | ||
173 | * | ||
174 | * @param data the data to deserialize | ||
175 | * @param len the length of the data. | ||
176 | * @return the ABE key. NULL of unsuccessful | ||
177 | */ | ||
178 | struct GNUNET_ABE_AbeMasterKey* | ||
179 | GNUNET_ABE_cpabe_deserialize_master_key (const void *data, | ||
180 | size_t len); | ||
181 | |||
182 | |||
183 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
184 | { | ||
185 | #endif | ||
186 | #ifdef __cplusplus | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | |||
191 | /* ifndef GNUNET_ABE_LIB_H */ | ||
192 | #endif | ||
193 | /* end of gnunet_abe_lib.h */ | ||
diff --git a/src/include/gnunet_credential_service.h b/src/include/gnunet_credential_service.h index 9e765c12b..7d6f9e973 100644 --- a/src/include/gnunet_credential_service.h +++ b/src/include/gnunet_credential_service.h | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include "gnunet_util_lib.h" | 35 | #include "gnunet_util_lib.h" |
36 | #include "gnunet_gns_service.h" | 36 | #include "gnunet_gns_service.h" |
37 | #include "gnunet_identity_service.h" | ||
37 | 38 | ||
38 | #ifdef __cplusplus | 39 | #ifdef __cplusplus |
39 | extern "C" | 40 | extern "C" |
@@ -52,7 +53,157 @@ struct GNUNET_CREDENTIAL_Handle; | |||
52 | /** | 53 | /** |
53 | * Handle to control a lookup operation. | 54 | * Handle to control a lookup operation. |
54 | */ | 55 | */ |
55 | struct GNUNET_CREDENTIAL_LookupRequest; | 56 | struct GNUNET_CREDENTIAL_Request; |
57 | |||
58 | /* | ||
59 | * Enum used for checking whether the issuer has the authority to issue credentials or is just a subject | ||
60 | */ | ||
61 | enum GNUNET_CREDENTIAL_CredentialFlags { | ||
62 | |||
63 | //Subject had credentials before, but have been revoked now | ||
64 | GNUNET_CREDENTIAL_FLAG_REVOKED=0, | ||
65 | |||
66 | //Subject flag indicates that the subject is a holder of this credential and may present it as such | ||
67 | GNUNET_CREDENTIAL_FLAG_SUBJECT=1, | ||
68 | |||
69 | //Issuer flag is used to signify that the subject is allowed to issue this credential and delegate issuance | ||
70 | GNUNET_CREDENTIAL_FLAG_ISSUER=2 | ||
71 | |||
72 | }; | ||
73 | |||
74 | GNUNET_NETWORK_STRUCT_BEGIN | ||
75 | /** | ||
76 | * The attribute delegation record | ||
77 | */ | ||
78 | struct GNUNET_CREDENTIAL_DelegationRecord { | ||
79 | |||
80 | /** | ||
81 | * Number of delegation sets in this record | ||
82 | */ | ||
83 | uint32_t set_count; | ||
84 | |||
85 | /** | ||
86 | * Length of delegation sets | ||
87 | */ | ||
88 | uint64_t data_size; | ||
89 | /** | ||
90 | * Followed by set_count DelegationSetRecords | ||
91 | * | ||
92 | */ | ||
93 | }; | ||
94 | |||
95 | /** | ||
96 | * The attribute delegation record | ||
97 | */ | ||
98 | struct GNUNET_CREDENTIAL_DelegationRecordSet { | ||
99 | |||
100 | /** | ||
101 | * Public key of the subject this attribute was delegated to | ||
102 | */ | ||
103 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
104 | |||
105 | /** | ||
106 | * Length of attribute, may be 0 | ||
107 | */ | ||
108 | uint32_t subject_attribute_len; | ||
109 | }; | ||
110 | |||
111 | |||
112 | GNUNET_NETWORK_STRUCT_END | ||
113 | |||
114 | /** | ||
115 | * The attribute delegation record | ||
116 | */ | ||
117 | struct GNUNET_CREDENTIAL_DelegationSet { | ||
118 | |||
119 | /** | ||
120 | * Public key of the subject this attribute was delegated to | ||
121 | */ | ||
122 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
123 | |||
124 | uint32_t subject_attribute_len; | ||
125 | |||
126 | /** | ||
127 | * The subject attribute | ||
128 | */ | ||
129 | const char *subject_attribute; | ||
130 | }; | ||
131 | |||
132 | |||
133 | /** | ||
134 | * A delegation | ||
135 | */ | ||
136 | struct GNUNET_CREDENTIAL_Delegation { | ||
137 | |||
138 | /** | ||
139 | * The issuer of the delegation | ||
140 | */ | ||
141 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
142 | |||
143 | /** | ||
144 | * Public key of the subject this attribute was delegated to | ||
145 | */ | ||
146 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
147 | |||
148 | /** | ||
149 | * Length of the attribute | ||
150 | */ | ||
151 | uint32_t issuer_attribute_len; | ||
152 | |||
153 | /** | ||
154 | * The attribute | ||
155 | */ | ||
156 | const char *issuer_attribute; | ||
157 | |||
158 | /** | ||
159 | * Length of the attribute | ||
160 | */ | ||
161 | uint32_t subject_attribute_len; | ||
162 | |||
163 | /** | ||
164 | * The attribute | ||
165 | */ | ||
166 | const char *subject_attribute; | ||
167 | }; | ||
168 | |||
169 | |||
170 | /** | ||
171 | * A credential | ||
172 | */ | ||
173 | struct GNUNET_CREDENTIAL_Credential { | ||
174 | |||
175 | /** | ||
176 | * The issuer of the credential | ||
177 | */ | ||
178 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
179 | |||
180 | /** | ||
181 | * Public key of the subject this credential was issued to | ||
182 | */ | ||
183 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
184 | |||
185 | /** | ||
186 | * Signature of this credential | ||
187 | */ | ||
188 | struct GNUNET_CRYPTO_EcdsaSignature signature; | ||
189 | |||
190 | /** | ||
191 | * Expiration of this credential | ||
192 | */ | ||
193 | struct GNUNET_TIME_Absolute expiration; | ||
194 | |||
195 | /** | ||
196 | * Length of the attribute | ||
197 | */ | ||
198 | uint32_t issuer_attribute_len; | ||
199 | |||
200 | /** | ||
201 | * The attribute | ||
202 | */ | ||
203 | const char *issuer_attribute; | ||
204 | |||
205 | }; | ||
206 | |||
56 | 207 | ||
57 | 208 | ||
58 | /** | 209 | /** |
@@ -61,7 +212,7 @@ struct GNUNET_CREDENTIAL_LookupRequest; | |||
61 | * @param cfg configuration to use | 212 | * @param cfg configuration to use |
62 | * @return handle to the Credential service, or NULL on error | 213 | * @return handle to the Credential service, or NULL on error |
63 | */ | 214 | */ |
64 | struct GNUNET_Credential_Handle * | 215 | struct GNUNET_CREDENTIAL_Handle * |
65 | GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); | 216 | GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); |
66 | 217 | ||
67 | 218 | ||
@@ -75,73 +226,131 @@ GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle); | |||
75 | 226 | ||
76 | 227 | ||
77 | /** | 228 | /** |
78 | * Iterator called on obtained result for a Credential lookup. | 229 | * Iterator called on obtained result for an attribute verification. |
230 | * | ||
231 | * @param cls closure | ||
232 | * @param d_count the number of delegations processed | ||
233 | * @param delegation_chain the delegations processed | ||
234 | * @param c_count the number of credentials found | ||
235 | * @param credential the credentials | ||
236 | */ | ||
237 | typedef void (*GNUNET_CREDENTIAL_CredentialResultProcessor) (void *cls, | ||
238 | unsigned int d_count, | ||
239 | struct GNUNET_CREDENTIAL_Delegation *delegation_chain, | ||
240 | unsigned int c_count, | ||
241 | struct GNUNET_CREDENTIAL_Credential *credential); | ||
242 | |||
243 | /** | ||
244 | * Iterator called on obtained result for an attribute delegation. | ||
245 | * | ||
246 | * @param cls closure | ||
247 | * @param success GNUNET_YES if successful | ||
248 | * @param result the record data that can be handed to the subject | ||
249 | */ | ||
250 | typedef void (*GNUNET_CREDENTIAL_DelegateResultProcessor) (void *cls, | ||
251 | uint32_t success); | ||
252 | |||
253 | /** | ||
254 | * Iterator called on obtained result for an attribute delegation removal. | ||
79 | * | 255 | * |
80 | * @param cls closure | 256 | * @param cls closure |
81 | * @param issuer the issuer chain | 257 | * @param success GNUNET_YES if successful |
82 | * @param issuer_len length of issuer chain | 258 | * @param result the record data that can be handed to the subject |
83 | * @param value the value returned | ||
84 | */ | 259 | */ |
85 | typedef void | 260 | typedef void (*GNUNET_CREDENTIAL_RemoveDelegateResultProcessor) (void *cls, |
86 | (*GNUNET_CREDENTIAL_LookupResultProcessor) (void *cls, | 261 | uint32_t success); |
87 | struct GNUNET_IDENTITY_Ego *issuer, | ||
88 | uint16_t issuer_len, | ||
89 | const struct GNUNET_CREDENTIAL_Value *value); | ||
90 | 262 | ||
91 | 263 | ||
92 | /** | 264 | /** |
93 | * Perform an asynchronous lookup operation for a credential. | 265 | * Performs attribute verification. |
266 | * Checks if there is a delegation chain from | ||
267 | * attribute ``issuer_attribute'' issued by the issuer | ||
268 | * with public key ``issuer_key'' maps to the attribute | ||
269 | * ``subject_attribute'' claimed by the subject with key | ||
270 | * ``subject_key'' | ||
94 | * | 271 | * |
95 | * @param handle handle to the Credential service | 272 | * @param handle handle to the Credential service |
96 | * @param credential the credential to look up | 273 | * @param issuer_key the issuer public key |
97 | * @param subject Ego to check the credential for | 274 | * @param issuer_attribute the issuer attribute |
275 | * @param subject_key the subject public key | ||
276 | * @param credential_count number of credentials | ||
277 | * @param credentials the subject credentials | ||
98 | * @param proc function to call on result | 278 | * @param proc function to call on result |
99 | * @param proc_cls closure for processor | 279 | * @param proc_cls closure for processor |
100 | * @return handle to the queued request | 280 | * @return handle to the queued request |
101 | */ | 281 | */ |
102 | struct GNUNET_CREDENTIAL_LookupRequest * | 282 | struct GNUNET_CREDENTIAL_Request* |
103 | GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle, | 283 | GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, |
104 | const char *credential, | 284 | const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, |
105 | const struct GNUNET_IDENTITY_Ego *subject, | 285 | const char *issuer_attribute, |
106 | GNUNET_CREDENTIAL_LookupResultProcessor proc, | 286 | const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, |
287 | uint32_t credential_count, | ||
288 | const struct GNUNET_CREDENTIAL_Credential *credentials, | ||
289 | GNUNET_CREDENTIAL_CredentialResultProcessor proc, | ||
107 | void *proc_cls); | 290 | void *proc_cls); |
108 | 291 | ||
292 | struct GNUNET_CREDENTIAL_Request* | ||
293 | GNUNET_CREDENTIAL_collect (struct GNUNET_CREDENTIAL_Handle *handle, | ||
294 | const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, | ||
295 | const char *issuer_attribute, | ||
296 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *subject_key, | ||
297 | GNUNET_CREDENTIAL_CredentialResultProcessor proc, | ||
298 | void *proc_cls); | ||
109 | 299 | ||
110 | /** | 300 | /** |
111 | * Issue a credential to an identity | 301 | * Delegate an attribute |
112 | * | 302 | * |
113 | * @param handle handle to the Credential service | 303 | * @param handle handle to the Credential service |
114 | * @param issuer the identity that issues the credential | 304 | * @param issuer the ego that should be used to delegate the attribute |
115 | * @param subject the subject of the credential | 305 | * @param attribute the name of the attribute to delegate |
116 | * @param credential the name of the credential | 306 | * @param subject the subject of the delegation |
117 | * @param value the value of the credential | 307 | * @param delegated_attribute the name of the attribute that is delegated to |
308 | * @param proc the result callback | ||
309 | * @param proc_cls the result closure context | ||
118 | * @return handle to the queued request | 310 | * @return handle to the queued request |
119 | */ | 311 | */ |
120 | struct GNUNET_CREDENTIAL_IssueRequest * | 312 | struct GNUNET_CREDENTIAL_Request * |
121 | GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle, | 313 | GNUNET_CREDENTIAL_add_delegation (struct GNUNET_CREDENTIAL_Handle *handle, |
122 | struct GNUNET_IDENTITY_Ego *issuer, | 314 | struct GNUNET_IDENTITY_Ego *issuer, |
123 | struct GNUNET_IDENTITY_Ego *subject, | 315 | const char *attribute, |
124 | const char *credential, | 316 | struct GNUNET_CRYPTO_EcdsaPublicKey *subject, |
125 | struct GNUNET_CREDENTIAL_Value *value, | 317 | const char *delegated_attribute, |
126 | GNUNET_CREDENTIAL_IssueResultProcessor proc, | 318 | GNUNET_CREDENTIAL_DelegateResultProcessor proc, |
127 | void *proc_cls); | 319 | void *proc_cls); |
128 | 320 | ||
129 | /** | 321 | /** |
130 | * Remove a credential | 322 | * Remove a delegation |
131 | * | 323 | * |
132 | * @param handle handle to the Credential service | 324 | * @param handle handle to the Credential service |
133 | * @param issuer the identity that issued the credential | 325 | * @param issuer the ego that was used to delegate the attribute |
134 | * @param subject the subject of the credential | 326 | * @param attribute the name of the attribute that is delegated |
135 | * @param credential the name of the credential | 327 | * @param proc the callback |
328 | * @param proc_cls callback closure | ||
136 | * @return handle to the queued request | 329 | * @return handle to the queued request |
137 | */ | 330 | */ |
138 | struct GNUNET_CREDENTIAL_IssueRequest * | 331 | struct GNUNET_CREDENTIAL_Request * |
139 | GNUNET_CREDENTIAL_remove (struct GNUNET_CREDENTIAL_Handle *handle, | 332 | GNUNET_CREDENTIAL_remove_delegation (struct GNUNET_CREDENTIAL_Handle *handle, |
140 | struct GNUNET_IDENTITY_Ego *issuer, | 333 | struct GNUNET_IDENTITY_Ego *issuer, |
141 | struct GNUNET_IDENTITY_Ego *subject, | 334 | const char *attribute, |
142 | const char *credential, | 335 | GNUNET_CREDENTIAL_RemoveDelegateResultProcessor proc, |
143 | GNUNET_CREDENTIAL_IssueResultProcessor proc, | 336 | void *proc_cls); |
144 | void *proc_cls); | 337 | |
338 | |||
339 | |||
340 | /** | ||
341 | * Issue an attribute to a subject | ||
342 | * | ||
343 | * @param issuer the ego that should be used to issue the attribute | ||
344 | * @param subject the subject of the attribute | ||
345 | * @param attribute the name of the attribute | ||
346 | * @param expiration the TTL of the credential | ||
347 | * @return handle to the queued request | ||
348 | */ | ||
349 | struct GNUNET_CREDENTIAL_Credential* | ||
350 | GNUNET_CREDENTIAL_credential_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, | ||
351 | struct GNUNET_CRYPTO_EcdsaPublicKey *subject, | ||
352 | const char *attribute, | ||
353 | struct GNUNET_TIME_Absolute *expiration); | ||
145 | 354 | ||
146 | 355 | ||
147 | 356 | ||
@@ -151,7 +360,7 @@ GNUNET_CREDENTIAL_remove (struct GNUNET_CREDENTIAL_Handle *handle, | |||
151 | * @param lr the lookup request to cancel | 360 | * @param lr the lookup request to cancel |
152 | */ | 361 | */ |
153 | void | 362 | void |
154 | GNUNET_CREDENTIAL_lookup_cancel (struct GNUNET_CREDENTIAL_LookupRequest *lr); | 363 | GNUNET_CREDENTIAL_request_cancel (struct GNUNET_CREDENTIAL_Request *lr); |
155 | 364 | ||
156 | 365 | ||
157 | #if 0 /* keep Emacsens' auto-indent happy */ | 366 | #if 0 /* keep Emacsens' auto-indent happy */ |
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h index 985ae1f7a..d03b4db3b 100644 --- a/src/include/gnunet_gnsrecord_lib.h +++ b/src/include/gnunet_gnsrecord_lib.h | |||
@@ -109,9 +109,29 @@ extern "C" | |||
109 | #define GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA 65546 | 109 | #define GNUNET_GNSRECORD_TYPE_ID_TOKEN_METADATA 65546 |
110 | 110 | ||
111 | /** | 111 | /** |
112 | * Record type for credential | ||
113 | */ | ||
114 | #define GNUNET_GNSRECORD_TYPE_CREDENTIAL 65547 | ||
115 | |||
116 | /** | ||
117 | * Record type for policies | ||
118 | */ | ||
119 | #define GNUNET_GNSRECORD_TYPE_POLICY 65548 | ||
120 | |||
121 | /** | ||
112 | * Record type for reverse lookups | 122 | * Record type for reverse lookups |
113 | */ | 123 | */ |
114 | #define GNUNET_GNSRECORD_TYPE_REVERSE 65548 | 124 | #define GNUNET_GNSRECORD_TYPE_ATTRIBUTE 65549 |
125 | |||
126 | /** | ||
127 | * Record type for ABE records | ||
128 | */ | ||
129 | #define GNUNET_GNSRECORD_TYPE_ABE_KEY 65550 | ||
130 | |||
131 | /** | ||
132 | * Record type for ABE master keys | ||
133 | */ | ||
134 | #define GNUNET_GNSRECORD_TYPE_ABE_MASTER 65551 | ||
115 | 135 | ||
116 | /** | 136 | /** |
117 | * Flags that can be set for a record. | 137 | * Flags that can be set for a record. |
diff --git a/src/include/gnunet_identity_attribute_lib.h b/src/include/gnunet_identity_attribute_lib.h new file mode 100644 index 000000000..316b0bf95 --- /dev/null +++ b/src/include/gnunet_identity_attribute_lib.h | |||
@@ -0,0 +1,277 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2017 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Martin Schanzenbach | ||
23 | * | ||
24 | * @file | ||
25 | * Identity attribute definitions | ||
26 | * | ||
27 | * @defgroup identity-provider Identity Provider service | ||
28 | * @{ | ||
29 | */ | ||
30 | #ifndef GNUNET_IDENTITY_ATTRIBUTE_LIB_H | ||
31 | #define GNUNET_IDENTITY_ATTRIBUTE_LIB_H | ||
32 | |||
33 | #ifdef __cplusplus | ||
34 | extern "C" | ||
35 | { | ||
36 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
37 | } | ||
38 | #endif | ||
39 | #endif | ||
40 | |||
41 | #include "gnunet_util_lib.h" | ||
42 | |||
43 | |||
44 | /** | ||
45 | * No value attribute. | ||
46 | */ | ||
47 | #define GNUNET_IDENTITY_ATTRIBUTE_TYPE_NONE 0 | ||
48 | |||
49 | /** | ||
50 | * String attribute. | ||
51 | */ | ||
52 | #define GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING 1 | ||
53 | |||
54 | |||
55 | |||
56 | /** | ||
57 | * An attribute. | ||
58 | */ | ||
59 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim | ||
60 | { | ||
61 | /** | ||
62 | * The name of the attribute. Note "name" must never be individually | ||
63 | * free'd | ||
64 | */ | ||
65 | const char* name; | ||
66 | |||
67 | /** | ||
68 | * Type of Claim | ||
69 | */ | ||
70 | uint32_t type; | ||
71 | |||
72 | /** | ||
73 | * Version | ||
74 | */ | ||
75 | uint32_t version; | ||
76 | |||
77 | /** | ||
78 | * Number of bytes in @e data. | ||
79 | */ | ||
80 | size_t data_size; | ||
81 | |||
82 | /** | ||
83 | * Binary value stored as attribute value. Note: "data" must never | ||
84 | * be individually 'malloc'ed, but instead always points into some | ||
85 | * existing data area. | ||
86 | */ | ||
87 | const void *data; | ||
88 | |||
89 | }; | ||
90 | |||
91 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList | ||
92 | { | ||
93 | /** | ||
94 | * List head | ||
95 | */ | ||
96 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *list_head; | ||
97 | |||
98 | /** | ||
99 | * List tail | ||
100 | */ | ||
101 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *list_tail; | ||
102 | }; | ||
103 | |||
104 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry | ||
105 | { | ||
106 | /** | ||
107 | * DLL | ||
108 | */ | ||
109 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *prev; | ||
110 | |||
111 | /** | ||
112 | * DLL | ||
113 | */ | ||
114 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *next; | ||
115 | |||
116 | /** | ||
117 | * The attribute claim | ||
118 | */ | ||
119 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim; | ||
120 | }; | ||
121 | |||
122 | /** | ||
123 | * Create a new attribute claim. | ||
124 | * | ||
125 | * @param attr_name the attribute name | ||
126 | * @param type the attribute type | ||
127 | * @param data the attribute value | ||
128 | * @param data_size the attribute value size | ||
129 | * @return the new attribute | ||
130 | */ | ||
131 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim * | ||
132 | GNUNET_IDENTITY_ATTRIBUTE_claim_new (const char* attr_name, | ||
133 | uint32_t type, | ||
134 | const void* data, | ||
135 | size_t data_size); | ||
136 | |||
137 | |||
138 | /** | ||
139 | * Get required size for serialization buffer | ||
140 | * | ||
141 | * @param attrs the attribute list to serialize | ||
142 | * | ||
143 | * @return the required buffer size | ||
144 | */ | ||
145 | size_t | ||
146 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); | ||
147 | |||
148 | void | ||
149 | GNUNET_IDENTITY_ATTRIBUTE_list_destroy (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); | ||
150 | |||
151 | |||
152 | /** | ||
153 | * Serialize an attribute list | ||
154 | * | ||
155 | * @param attrs the attribute list to serialize | ||
156 | * @param result the serialized attribute | ||
157 | * | ||
158 | * @return length of serialized data | ||
159 | */ | ||
160 | size_t | ||
161 | GNUNET_IDENTITY_ATTRIBUTE_list_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
162 | char *result); | ||
163 | |||
164 | /** | ||
165 | * Deserialize an attribute list | ||
166 | * | ||
167 | * @param data the serialized attribute list | ||
168 | * @param data_size the length of the serialized data | ||
169 | * | ||
170 | * @return a GNUNET_IDENTITY_PROVIDER_AttributeList, must be free'd by caller | ||
171 | */ | ||
172 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList * | ||
173 | GNUNET_IDENTITY_ATTRIBUTE_list_deserialize (const char* data, | ||
174 | size_t data_size); | ||
175 | |||
176 | |||
177 | /** | ||
178 | * Get required size for serialization buffer | ||
179 | * | ||
180 | * @param attr the attribute to serialize | ||
181 | * | ||
182 | * @return the required buffer size | ||
183 | */ | ||
184 | size_t | ||
185 | GNUNET_IDENTITY_ATTRIBUTE_serialize_get_size (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr); | ||
186 | |||
187 | |||
188 | |||
189 | /** | ||
190 | * Serialize an attribute | ||
191 | * | ||
192 | * @param attr the attribute to serialize | ||
193 | * @param result the serialized attribute | ||
194 | * | ||
195 | * @return length of serialized data | ||
196 | */ | ||
197 | size_t | ||
198 | GNUNET_IDENTITY_ATTRIBUTE_serialize (const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr, | ||
199 | char *result); | ||
200 | |||
201 | /** | ||
202 | * Deserialize an attribute | ||
203 | * | ||
204 | * @param data the serialized attribute | ||
205 | * @param data_size the length of the serialized data | ||
206 | * | ||
207 | * @return a GNUNET_IDENTITY_PROVIDER_Attribute, must be free'd by caller | ||
208 | */ | ||
209 | struct GNUNET_IDENTITY_ATTRIBUTE_Claim * | ||
210 | GNUNET_IDENTITY_ATTRIBUTE_deserialize (const char* data, | ||
211 | size_t data_size); | ||
212 | |||
213 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList* | ||
214 | GNUNET_IDENTITY_ATTRIBUTE_list_dup (const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); | ||
215 | |||
216 | /** | ||
217 | * Convert a type name to the corresponding number | ||
218 | * | ||
219 | * @param typename name to convert | ||
220 | * @return corresponding number, UINT32_MAX on error | ||
221 | */ | ||
222 | uint32_t | ||
223 | GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (const char *typename); | ||
224 | |||
225 | /** | ||
226 | * Convert human-readable version of a 'claim' of an attribute to the binary | ||
227 | * representation | ||
228 | * | ||
229 | * @param type type of the claim | ||
230 | * @param s human-readable string | ||
231 | * @param data set to value in binary encoding (will be allocated) | ||
232 | * @param data_size set to number of bytes in @a data | ||
233 | * @return #GNUNET_OK on success | ||
234 | */ | ||
235 | int | ||
236 | GNUNET_IDENTITY_ATTRIBUTE_string_to_value (uint32_t type, | ||
237 | const char *s, | ||
238 | void **data, | ||
239 | size_t *data_size); | ||
240 | |||
241 | /** | ||
242 | * Convert the 'claim' of an attribute to a string | ||
243 | * | ||
244 | * @param type the type of attribute | ||
245 | * @param data claim in binary encoding | ||
246 | * @param data_size number of bytes in @a data | ||
247 | * @return NULL on error, otherwise human-readable representation of the claim | ||
248 | */ | ||
249 | char * | ||
250 | GNUNET_IDENTITY_ATTRIBUTE_value_to_string (uint32_t type, | ||
251 | const void* data, | ||
252 | size_t data_size); | ||
253 | |||
254 | /** | ||
255 | * Convert a type number to the corresponding type string | ||
256 | * | ||
257 | * @param type number of a type | ||
258 | * @return corresponding typestring, NULL on error | ||
259 | */ | ||
260 | const char* | ||
261 | GNUNET_IDENTITY_ATTRIBUTE_number_to_typename (uint32_t type); | ||
262 | |||
263 | |||
264 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
265 | { | ||
266 | #endif | ||
267 | #ifdef __cplusplus | ||
268 | } | ||
269 | #endif | ||
270 | |||
271 | |||
272 | /* ifndef GNUNET_IDENTITY_ATTRIBUTE_LIB_H */ | ||
273 | #endif | ||
274 | |||
275 | /** @} */ /* end of group identity */ | ||
276 | |||
277 | /* end of gnunet_identity_attribute_lib.h */ | ||
diff --git a/src/include/gnunet_identity_attribute_plugin.h b/src/include/gnunet_identity_attribute_plugin.h new file mode 100644 index 000000000..edeed57fd --- /dev/null +++ b/src/include/gnunet_identity_attribute_plugin.h | |||
@@ -0,0 +1,149 @@ | |||
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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Martin Schanzenbach | ||
23 | * | ||
24 | * @file | ||
25 | * Plugin API for the idp database backend | ||
26 | * | ||
27 | * @defgroup identity-provider-plugin IdP service plugin API | ||
28 | * Plugin API for the idp database backend | ||
29 | * @{ | ||
30 | */ | ||
31 | #ifndef GNUNET_IDENTITY_ATTRIBUTE_PLUGIN_H | ||
32 | #define GNUNET_IDENTITY_ATTRIBUTE_PLUGIN_H | ||
33 | |||
34 | #include "gnunet_util_lib.h" | ||
35 | #include "gnunet_identity_attribute_lib.h" | ||
36 | |||
37 | #ifdef __cplusplus | ||
38 | extern "C" | ||
39 | { | ||
40 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
41 | } | ||
42 | #endif | ||
43 | #endif | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Function called to convert the binary value @a data of an attribute of | ||
48 | * type @a type to a human-readable string. | ||
49 | * | ||
50 | * @param cls closure | ||
51 | * @param type type of the attribute | ||
52 | * @param data value in binary encoding | ||
53 | * @param data_size number of bytes in @a data | ||
54 | * @return NULL on error, otherwise human-readable representation of the value | ||
55 | */ | ||
56 | typedef char * (*GNUNET_IDENTITY_ATTRIBUTE_ValueToStringFunction) (void *cls, | ||
57 | uint32_t type, | ||
58 | const void *data, | ||
59 | size_t data_size); | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Function called to convert human-readable version of the value @a s | ||
64 | * of an attribute of type @a type to the respective binary | ||
65 | * representation. | ||
66 | * | ||
67 | * @param cls closure | ||
68 | * @param type type of the attribute | ||
69 | * @param s human-readable string | ||
70 | * @param data set to value in binary encoding (will be allocated) | ||
71 | * @param data_size set to number of bytes in @a data | ||
72 | * @return #GNUNET_OK on success | ||
73 | */ | ||
74 | typedef int (*GNUNET_IDENTITY_ATTRIBUTE_StringToValueFunction) (void *cls, | ||
75 | uint32_t type, | ||
76 | const char *s, | ||
77 | void **data, | ||
78 | size_t *data_size); | ||
79 | |||
80 | |||
81 | /** | ||
82 | * Function called to convert a type name to the | ||
83 | * corresponding number. | ||
84 | * | ||
85 | * @param cls closure | ||
86 | * @param typename name to convert | ||
87 | * @return corresponding number, UINT32_MAX on error | ||
88 | */ | ||
89 | typedef uint32_t (*GNUNET_IDENTITY_ATTRIBUTE_TypenameToNumberFunction) (void *cls, | ||
90 | const char *typename); | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Function called to convert a type number (i.e. 1) to the | ||
95 | * corresponding type string | ||
96 | * | ||
97 | * @param cls closure | ||
98 | * @param type number of a type to convert | ||
99 | * @return corresponding typestring, NULL on error | ||
100 | */ | ||
101 | typedef const char * (*GNUNET_IDENTITY_ATTRIBUTE_NumberToTypenameFunction) (void *cls, | ||
102 | uint32_t type); | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Each plugin is required to return a pointer to a struct of this | ||
107 | * type as the return value from its entry point. | ||
108 | */ | ||
109 | struct GNUNET_IDENTITY_ATTRIBUTE_PluginFunctions | ||
110 | { | ||
111 | |||
112 | /** | ||
113 | * Closure for all of the callbacks. | ||
114 | */ | ||
115 | void *cls; | ||
116 | |||
117 | /** | ||
118 | * Conversion to string. | ||
119 | */ | ||
120 | GNUNET_IDENTITY_ATTRIBUTE_ValueToStringFunction value_to_string; | ||
121 | |||
122 | /** | ||
123 | * Conversion to binary. | ||
124 | */ | ||
125 | GNUNET_IDENTITY_ATTRIBUTE_StringToValueFunction string_to_value; | ||
126 | |||
127 | /** | ||
128 | * Typename to number. | ||
129 | */ | ||
130 | GNUNET_IDENTITY_ATTRIBUTE_TypenameToNumberFunction typename_to_number; | ||
131 | |||
132 | /** | ||
133 | * Number to typename. | ||
134 | */ | ||
135 | GNUNET_IDENTITY_ATTRIBUTE_NumberToTypenameFunction number_to_typename; | ||
136 | |||
137 | }; | ||
138 | |||
139 | |||
140 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
141 | { | ||
142 | #endif | ||
143 | #ifdef __cplusplus | ||
144 | } | ||
145 | #endif | ||
146 | |||
147 | #endif | ||
148 | |||
149 | /** @} */ /* end of group */ | ||
diff --git a/src/include/gnunet_identity_provider_plugin.h b/src/include/gnunet_identity_provider_plugin.h new file mode 100644 index 000000000..4b5098d58 --- /dev/null +++ b/src/include/gnunet_identity_provider_plugin.h | |||
@@ -0,0 +1,123 @@ | |||
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 | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @author Martin Schanzenbach | ||
23 | * | ||
24 | * @file | ||
25 | * Plugin API for the idp database backend | ||
26 | * | ||
27 | * @defgroup identity-provider-plugin IdP service plugin API | ||
28 | * Plugin API for the idp database backend | ||
29 | * @{ | ||
30 | */ | ||
31 | #ifndef GNUNET_IDENTITY_PROVIDER_PLUGIN_H | ||
32 | #define GNUNET_IDENTITY_PROVIDER_PLUGIN_H | ||
33 | |||
34 | #include "gnunet_util_lib.h" | ||
35 | #include "gnunet_identity_provider_service.h" | ||
36 | |||
37 | #ifdef __cplusplus | ||
38 | extern "C" | ||
39 | { | ||
40 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
41 | } | ||
42 | #endif | ||
43 | #endif | ||
44 | |||
45 | |||
46 | /** | ||
47 | * Function called by for each matching ticket. | ||
48 | * | ||
49 | * @param cls closure | ||
50 | * @param ticket the ticket | ||
51 | */ | ||
52 | typedef void (*GNUNET_IDENTITY_PROVIDER_TicketIterator) (void *cls, | ||
53 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
54 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); | ||
55 | |||
56 | |||
57 | /** | ||
58 | * @brief struct returned by the initialization function of the plugin | ||
59 | */ | ||
60 | struct GNUNET_IDENTITY_PROVIDER_PluginFunctions | ||
61 | { | ||
62 | |||
63 | /** | ||
64 | * Closure to pass to all plugin functions. | ||
65 | */ | ||
66 | void *cls; | ||
67 | |||
68 | /** | ||
69 | * Store a ticket in the database. | ||
70 | * | ||
71 | * @param cls closure (internal context for the plugin) | ||
72 | * @param ticket the ticket to store | ||
73 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
74 | */ | ||
75 | int (*store_ticket) (void *cls, | ||
76 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
77 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs); | ||
78 | |||
79 | /** | ||
80 | * Delete a ticket from the database. | ||
81 | * | ||
82 | * @param cls closure (internal context for the plugin) | ||
83 | * @param ticket the ticket to store | ||
84 | * @return #GNUNET_OK on success, else #GNUNET_SYSERR | ||
85 | */ | ||
86 | int (*delete_ticket) (void *cls, | ||
87 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); | ||
88 | |||
89 | |||
90 | |||
91 | /** | ||
92 | * Iterate over all tickets | ||
93 | * | ||
94 | * @param cls closure (internal context for the plugin) | ||
95 | * @param identity the identity | ||
96 | * @param audience GNUNET_YES if the identity is the audience of the ticket | ||
97 | * else it is considered the issuer | ||
98 | * @param iter function to call with the result | ||
99 | * @param iter_cls closure for @a iter | ||
100 | * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error | ||
101 | */ | ||
102 | int (*iterate_tickets) (void *cls, | ||
103 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | ||
104 | int audience, | ||
105 | uint64_t offset, | ||
106 | GNUNET_IDENTITY_PROVIDER_TicketIterator iter, void *iter_cls); | ||
107 | |||
108 | int (*get_ticket_attributes) (void* cls, | ||
109 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
110 | GNUNET_IDENTITY_PROVIDER_TicketIterator iter, | ||
111 | void *iter_cls); | ||
112 | }; | ||
113 | |||
114 | #if 0 /* keep Emacsens' auto-indent happy */ | ||
115 | { | ||
116 | #endif | ||
117 | #ifdef __cplusplus | ||
118 | } | ||
119 | #endif | ||
120 | |||
121 | #endif | ||
122 | |||
123 | /** @} */ /* end of group */ | ||
diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h index e533f6f8c..be935e898 100644 --- a/src/include/gnunet_identity_provider_service.h +++ b/src/include/gnunet_identity_provider_service.h | |||
@@ -39,7 +39,7 @@ extern "C" | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #include "gnunet_util_lib.h" | 41 | #include "gnunet_util_lib.h" |
42 | 42 | #include "gnunet_identity_attribute_lib.h" | |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * Version number of GNUnet Identity Provider API. | 45 | * Version number of GNUnet Identity Provider API. |
@@ -57,169 +57,310 @@ struct GNUNET_IDENTITY_PROVIDER_Handle; | |||
57 | struct GNUNET_IDENTITY_PROVIDER_Token; | 57 | struct GNUNET_IDENTITY_PROVIDER_Token; |
58 | 58 | ||
59 | /** | 59 | /** |
60 | * Handle for a ticket | 60 | * The ticket |
61 | */ | 61 | */ |
62 | struct GNUNET_IDENTITY_PROVIDER_Ticket; | 62 | struct GNUNET_IDENTITY_PROVIDER_Ticket |
63 | { | ||
64 | /** | ||
65 | * The ticket issuer | ||
66 | */ | ||
67 | struct GNUNET_CRYPTO_EcdsaPublicKey identity; | ||
68 | |||
69 | /** | ||
70 | * The ticket audience | ||
71 | */ | ||
72 | struct GNUNET_CRYPTO_EcdsaPublicKey audience; | ||
73 | |||
74 | /** | ||
75 | * The ticket random (NBO) | ||
76 | */ | ||
77 | uint64_t rnd; | ||
78 | }; | ||
63 | 79 | ||
64 | /** | 80 | /** |
65 | * Handle for an operation with the identity provider service. | 81 | * Handle for an operation with the identity provider service. |
66 | */ | 82 | */ |
67 | struct GNUNET_IDENTITY_PROVIDER_Operation; | 83 | struct GNUNET_IDENTITY_PROVIDER_Operation; |
68 | 84 | ||
85 | |||
69 | /** | 86 | /** |
70 | * Method called when a token has been exchanged for a ticket. | 87 | * Connect to the identity provider service. |
71 | * On success returns a token | ||
72 | * | 88 | * |
73 | * @param cls closure | 89 | * @param cfg Configuration to contact the identity provider service. |
74 | * @param token the token | 90 | * @return handle to communicate with identity provider service |
75 | */ | 91 | */ |
76 | typedef void | 92 | struct GNUNET_IDENTITY_PROVIDER_Handle * |
77 | (*GNUNET_IDENTITY_PROVIDER_ExchangeCallback)(void *cls, | 93 | GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); |
78 | const struct GNUNET_IDENTITY_PROVIDER_Token *token, | ||
79 | uint64_t ticket_nonce); | ||
80 | 94 | ||
81 | /** | 95 | /** |
82 | * Method called when a token has been issued. | 96 | * Continuation called to notify client about result of the |
83 | * On success returns a ticket that can be given to the audience to retrive the | 97 | * operation. |
84 | * token | ||
85 | * | 98 | * |
86 | * @param cls closure | 99 | * @param cls closure |
87 | * @param grant the label in GNS pointing to the token | 100 | * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) |
88 | * @param ticket the ticket | 101 | * #GNUNET_NO if content was already there or not found |
89 | * @param token the issued token | 102 | * #GNUNET_YES (or other positive value) on success |
90 | * @param name name assigned by the user for this ego, | 103 | * @param emsg NULL on success, otherwise an error message |
91 | * NULL if the user just deleted the ego and it | ||
92 | * must thus no longer be used | ||
93 | */ | 104 | */ |
94 | typedef void | 105 | typedef void |
95 | (*GNUNET_IDENTITY_PROVIDER_IssueCallback)(void *cls, | 106 | (*GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus) (void *cls, |
96 | const char *grant, | 107 | int32_t success, |
97 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | 108 | const char *emsg); |
98 | const struct GNUNET_IDENTITY_PROVIDER_Token *token); | ||
99 | 109 | ||
100 | 110 | ||
101 | /** | 111 | /** |
102 | * Connect to the identity provider service. | 112 | * Store an attribute. If the attribute is already present, |
113 | * it is replaced with the new attribute. | ||
103 | * | 114 | * |
104 | * @param cfg Configuration to contact the identity provider service. | 115 | * @param h handle to the identity provider |
105 | * @return handle to communicate with identity provider service | 116 | * @param pkey private key of the identity |
117 | * @param attr the attribute | ||
118 | * @param cont continuation to call when done | ||
119 | * @param cont_cls closure for @a cont | ||
120 | * @return handle to abort the request | ||
106 | */ | 121 | */ |
107 | struct GNUNET_IDENTITY_PROVIDER_Handle * | 122 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
108 | GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); | 123 | GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
124 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, | ||
125 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr, | ||
126 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont, | ||
127 | void *cont_cls); | ||
109 | 128 | ||
110 | 129 | ||
111 | /** | 130 | /** |
112 | * Issue a token for a specific audience. | 131 | * Process an attribute that was stored in the idp. |
113 | * | 132 | * |
114 | * @param id identity provider service to use | 133 | * @param cls closure |
115 | * @param iss issuer (identity) | 134 | * @param identity the identity |
116 | * @param aud audience (identity) | 135 | * @param attr the attribute |
117 | * @param scope the identity attributes requested, comman separated | ||
118 | * @param expiration the token expiration | ||
119 | * @param nonce the nonce that will be included in token and ticket | ||
120 | * @param cb callback to call with result | ||
121 | * @param cb_cls closure | ||
122 | * @return handle to abort the operation | ||
123 | */ | 136 | */ |
124 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 137 | typedef void |
125 | GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | 138 | (*GNUNET_IDENTITY_PROVIDER_AttributeResult) (void *cls, |
126 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, | 139 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, |
127 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | 140 | const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr); |
128 | const char* scope, | 141 | |
129 | struct GNUNET_TIME_Absolute expiration, | ||
130 | uint64_t nonce, | ||
131 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, | ||
132 | void *cb_cls); | ||
133 | 142 | ||
134 | 143 | ||
135 | /** | 144 | /** |
136 | * Exchange a ticket for a token. Intended to be used by audience that | 145 | * List all attributes for a local identity. |
137 | * received a ticket. | 146 | * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle` |
147 | * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and | ||
148 | * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once | ||
149 | * immediately, and then again after | ||
150 | * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked. | ||
138 | * | 151 | * |
139 | * @param id identity provider service to use | 152 | * On error (disconnect), @a error_cb will be invoked. |
140 | * @param ticket the ticket to exchange | 153 | * On normal completion, @a finish_cb proc will be |
141 | * @param aud_privkey the audience of the ticket | 154 | * invoked. |
142 | * @param cont function to call once the operation finished | 155 | * |
143 | * @param cont_cls closure for @a cont | 156 | * @param h handle to the idp |
144 | * @return handle to abort the operation | 157 | * @param identity identity to access |
158 | * @param error_cb function to call on error (i.e. disconnect), | ||
159 | * the handle is afterwards invalid | ||
160 | * @param error_cb_cls closure for @a error_cb | ||
161 | * @param proc function to call on each attribute; it | ||
162 | * will be called repeatedly with a value (if available) | ||
163 | * @param proc_cls closure for @a proc | ||
164 | * @param finish_cb function to call on completion | ||
165 | * the handle is afterwards invalid | ||
166 | * @param finish_cb_cls closure for @a finish_cb | ||
167 | * @return an iterator handle to use for iteration | ||
145 | */ | 168 | */ |
146 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 169 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator * |
147 | GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | 170 | GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
148 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | 171 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, |
149 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, | 172 | GNUNET_SCHEDULER_TaskCallback error_cb, |
150 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, | 173 | void *error_cb_cls, |
151 | void *cont_cls); | 174 | GNUNET_IDENTITY_PROVIDER_AttributeResult proc, |
175 | void *proc_cls, | ||
176 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
177 | void *finish_cb_cls); | ||
152 | 178 | ||
153 | 179 | ||
154 | /** | 180 | /** |
155 | * Disconnect from identity provider service. | 181 | * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start |
182 | * for the next record. | ||
156 | * | 183 | * |
157 | * @param h identity provider service to disconnect | 184 | * @param it the iterator |
158 | */ | 185 | */ |
159 | void | 186 | void |
160 | GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h); | 187 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it); |
161 | 188 | ||
162 | 189 | ||
163 | /** | 190 | /** |
164 | * Cancel an identity provider operation. Note that the operation MAY still | 191 | * Stops iteration and releases the idp handle for further calls. Must |
165 | * be executed; this merely cancels the continuation; if the request | 192 | * be called on any iteration that has not yet completed prior to calling |
166 | * was already transmitted, the service may still choose to complete | 193 | * #GNUNET_IDENTITY_PROVIDER_disconnect. |
167 | * the operation. | ||
168 | * | 194 | * |
169 | * @param op operation to cancel | 195 | * @param it the iterator |
170 | */ | 196 | */ |
171 | void | 197 | void |
172 | GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op); | 198 | GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it); |
173 | 199 | ||
174 | 200 | ||
175 | /** | 201 | /** |
176 | * Convenience API | 202 | * Method called when a token has been issued. |
203 | * On success returns a ticket that can be given to the audience to retrive the | ||
204 | * token | ||
205 | * | ||
206 | * @param cls closure | ||
207 | * @param ticket the ticket | ||
177 | */ | 208 | */ |
209 | typedef void | ||
210 | (*GNUNET_IDENTITY_PROVIDER_TicketCallback)(void *cls, | ||
211 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); | ||
178 | 212 | ||
179 | /** | 213 | /** |
180 | * Destroy token | 214 | * Issues a ticket to another identity. The identity may use |
215 | * GNUNET_IDENTITY_PROVIDER_ticket_consume to consume the ticket | ||
216 | * and retrieve the attributes specified in the AttributeList. | ||
181 | * | 217 | * |
182 | * @param token the token | 218 | * @param h the identity provider to use |
219 | * @param iss the issuing identity | ||
220 | * @param rp the subject of the ticket (the relying party) | ||
221 | * @param attrs the attributes that the relying party is given access to | ||
222 | * @param cb the callback | ||
223 | * @param cb_cls the callback closure | ||
224 | * @return handle to abort the operation | ||
183 | */ | 225 | */ |
184 | void | 226 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
185 | GNUNET_IDENTITY_PROVIDER_token_destroy(struct GNUNET_IDENTITY_PROVIDER_Token *token); | 227 | GNUNET_IDENTITY_PROVIDER_ticket_issue (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
228 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss, | ||
229 | const struct GNUNET_CRYPTO_EcdsaPublicKey *rp, | ||
230 | const struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attrs, | ||
231 | GNUNET_IDENTITY_PROVIDER_TicketCallback cb, | ||
232 | void *cb_cls); | ||
186 | 233 | ||
187 | /** | 234 | /** |
188 | * Returns string representation of token. A JSON-Web-Token. | 235 | * Revoked an issued ticket. The relying party will be unable to retrieve |
236 | * updated attributes. | ||
189 | * | 237 | * |
190 | * @param token the token | 238 | * @param h the identity provider to use |
191 | * @return The JWT (must be freed) | 239 | * @param identity the issuing identity |
240 | * @param ticket the ticket to revoke | ||
241 | * @param cb the callback | ||
242 | * @param cb_cls the callback closure | ||
243 | * @return handle to abort the operation | ||
192 | */ | 244 | */ |
193 | char * | 245 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
194 | GNUNET_IDENTITY_PROVIDER_token_to_string (const struct GNUNET_IDENTITY_PROVIDER_Token *token); | 246 | GNUNET_IDENTITY_PROVIDER_ticket_revoke (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
247 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
248 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
249 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cb, | ||
250 | void *cb_cls); | ||
251 | |||
252 | |||
195 | 253 | ||
196 | /** | 254 | /** |
197 | * Returns string representation of ticket. Base64-Encoded | 255 | * Consumes an issued ticket. The ticket is persisted |
256 | * and used to retrieve identity information from the issuer | ||
198 | * | 257 | * |
199 | * @param ticket the ticket | 258 | * @param h the identity provider to use |
200 | * @return the Base64-Encoded ticket | 259 | * @param identity the identity that is the subject of the issued ticket (the audience) |
260 | * @param ticket the issued ticket to consume | ||
261 | * @param cb the callback to call | ||
262 | * @param cb_cls the callback closure | ||
263 | * @return handle to abort the operation | ||
264 | */ | ||
265 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
266 | GNUNET_IDENTITY_PROVIDER_ticket_consume (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
267 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
268 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | ||
269 | GNUNET_IDENTITY_PROVIDER_AttributeResult cb, | ||
270 | void *cb_cls); | ||
271 | |||
272 | /** | ||
273 | * Lists all tickets that have been issued to remote | ||
274 | * identites (relying parties) | ||
275 | * | ||
276 | * @param h the identity provider to use | ||
277 | * @param identity the issuing identity | ||
278 | * @param error_cb function to call on error (i.e. disconnect), | ||
279 | * the handle is afterwards invalid | ||
280 | * @param error_cb_cls closure for @a error_cb | ||
281 | * @param proc function to call on each ticket; it | ||
282 | * will be called repeatedly with a value (if available) | ||
283 | * @param proc_cls closure for @a proc | ||
284 | * @param finish_cb function to call on completion | ||
285 | * the handle is afterwards invalid | ||
286 | * @param finish_cb_cls closure for @a finish_cb | ||
287 | * @return an iterator handle to use for iteration | ||
288 | */ | ||
289 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator * | ||
290 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
291 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
292 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
293 | void *error_cb_cls, | ||
294 | GNUNET_IDENTITY_PROVIDER_TicketCallback proc, | ||
295 | void *proc_cls, | ||
296 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
297 | void *finish_cb_cls); | ||
298 | |||
299 | /** | ||
300 | * Lists all tickets that have been issued to remote | ||
301 | * identites (relying parties) | ||
302 | * | ||
303 | * @param h the identity provider to use | ||
304 | * @param identity the issuing identity | ||
305 | * @param error_cb function to call on error (i.e. disconnect), | ||
306 | * the handle is afterwards invalid | ||
307 | * @param error_cb_cls closure for @a error_cb | ||
308 | * @param proc function to call on each ticket; it | ||
309 | * will be called repeatedly with a value (if available) | ||
310 | * @param proc_cls closure for @a proc | ||
311 | * @param finish_cb function to call on completion | ||
312 | * the handle is afterwards invalid | ||
313 | * @param finish_cb_cls closure for @a finish_cb | ||
314 | * @return an iterator handle to use for iteration | ||
201 | */ | 315 | */ |
202 | char * | 316 | struct GNUNET_IDENTITY_PROVIDER_TicketIterator * |
203 | GNUNET_IDENTITY_PROVIDER_ticket_to_string (const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); | 317 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_start_rp (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
318 | const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, | ||
319 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
320 | void *error_cb_cls, | ||
321 | GNUNET_IDENTITY_PROVIDER_TicketCallback proc, | ||
322 | void *proc_cls, | ||
323 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
324 | void *finish_cb_cls); | ||
204 | 325 | ||
205 | /** | 326 | /** |
206 | * Created a ticket from a string (Base64 encoded ticket) | 327 | * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_ticket_iteration_start |
328 | * for the next record. | ||
207 | * | 329 | * |
208 | * @param input Base64 encoded ticket | 330 | * @param it the iterator |
209 | * @param ticket pointer where the ticket is stored | ||
210 | * @return GNUNET_OK | ||
211 | */ | 331 | */ |
212 | int | 332 | void |
213 | GNUNET_IDENTITY_PROVIDER_string_to_ticket (const char* input, | 333 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_next (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it); |
214 | struct GNUNET_IDENTITY_PROVIDER_Ticket **ticket); | ||
215 | 334 | ||
216 | /** | 335 | /** |
217 | * Destroys a ticket | 336 | * Stops iteration and releases the idp handle for further calls. Must |
337 | * be called on any iteration that has not yet completed prior to calling | ||
338 | * #GNUNET_IDENTITY_PROVIDER_disconnect. | ||
218 | * | 339 | * |
219 | * @param ticket the ticket to destroy | 340 | * @param it the iterator |
220 | */ | 341 | */ |
221 | void | 342 | void |
222 | GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket); | 343 | GNUNET_IDENTITY_PROVIDER_ticket_iteration_stop (struct GNUNET_IDENTITY_PROVIDER_TicketIterator *it); |
344 | |||
345 | /** | ||
346 | * Disconnect from identity provider service. | ||
347 | * | ||
348 | * @param h identity provider service to disconnect | ||
349 | */ | ||
350 | void | ||
351 | GNUNET_IDENTITY_PROVIDER_disconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h); | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Cancel an identity provider operation. Note that the operation MAY still | ||
356 | * be executed; this merely cancels the continuation; if the request | ||
357 | * was already transmitted, the service may still choose to complete | ||
358 | * the operation. | ||
359 | * | ||
360 | * @param op operation to cancel | ||
361 | */ | ||
362 | void | ||
363 | GNUNET_IDENTITY_PROVIDER_cancel (struct GNUNET_IDENTITY_PROVIDER_Operation *op); | ||
223 | 364 | ||
224 | #if 0 /* keep Emacsens' auto-indent happy */ | 365 | #if 0 /* keep Emacsens' auto-indent happy */ |
225 | { | 366 | { |
diff --git a/src/include/gnunet_jsonapi_lib.h b/src/include/gnunet_jsonapi_lib.h index f95bff836..2f6b810f0 100644 --- a/src/include/gnunet_jsonapi_lib.h +++ b/src/include/gnunet_jsonapi_lib.h | |||
@@ -248,7 +248,7 @@ GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource | |||
248 | * @param res the JSON resource | 248 | * @param res the JSON resource |
249 | * @return the resource id | 249 | * @return the resource id |
250 | */ | 250 | */ |
251 | char* | 251 | const char* |
252 | GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource); | 252 | GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource); |
253 | 253 | ||
254 | 254 | ||
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 9cfd00e39..436adc5a4 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2628,13 +2628,47 @@ extern "C" | |||
2628 | * | 2628 | * |
2629 | * IDENTITY PROVIDER MESSAGE TYPES | 2629 | * IDENTITY PROVIDER MESSAGE TYPES |
2630 | */ | 2630 | */ |
2631 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE 961 | 2631 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE 961 |
2632 | 2632 | ||
2633 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE 962 | 2633 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE 962 |
2634 | 2634 | ||
2635 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT 963 | 2635 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START 963 |
2636 | 2636 | ||
2637 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT 964 | 2637 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP 964 |
2638 | |||
2639 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT 965 | ||
2640 | |||
2641 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT 966 | ||
2642 | |||
2643 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_TICKET 967 | ||
2644 | |||
2645 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_RESULT 968 | ||
2646 | |||
2647 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET 969 | ||
2648 | |||
2649 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_REVOKE_TICKET_RESULT 970 | ||
2650 | |||
2651 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET 971 | ||
2652 | |||
2653 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_CONSUME_TICKET_RESULT 972 | ||
2654 | |||
2655 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_START 973 | ||
2656 | |||
2657 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_STOP 974 | ||
2658 | |||
2659 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_TICKET_ITERATION_NEXT 975 | ||
2660 | |||
2661 | /************************************************** | ||
2662 | * | ||
2663 | * CREDENTIAL MESSAGE TYPES | ||
2664 | */ | ||
2665 | #define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY 981 | ||
2666 | |||
2667 | #define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT 982 | ||
2668 | |||
2669 | #define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT 983 | ||
2670 | |||
2671 | #define GNUNET_MESSAGE_TYPE_CREDENTIAL_COLLECT_RESULT 984 | ||
2638 | 2672 | ||
2639 | /******************************************************************************/ | 2673 | /******************************************************************************/ |
2640 | 2674 | ||
diff --git a/src/include/gnunet_rest_lib.h b/src/include/gnunet_rest_lib.h index a4dbb0696..e571eead3 100644 --- a/src/include/gnunet_rest_lib.h +++ b/src/include/gnunet_rest_lib.h | |||
@@ -89,7 +89,7 @@ typedef void (*GNUNET_REST_ResultProcessor) (void *cls, | |||
89 | * | 89 | * |
90 | * @param url URL to check | 90 | * @param url URL to check |
91 | * @param namespace namespace to check against | 91 | * @param namespace namespace to check against |
92 | * @retun GNUNET_YES if namespace matches | 92 | * @return GNUNET_YES if namespace matches |
93 | */ | 93 | */ |
94 | int | 94 | int |
95 | GNUNET_REST_namespace_match (const char *url, const char *namespace); | 95 | GNUNET_REST_namespace_match (const char *url, const char *namespace); |
@@ -98,7 +98,7 @@ GNUNET_REST_namespace_match (const char *url, const char *namespace); | |||
98 | * Create REST MHD response | 98 | * Create REST MHD response |
99 | * | 99 | * |
100 | * @param data result | 100 | * @param data result |
101 | * @retun MHD response | 101 | * @return MHD response |
102 | */ | 102 | */ |
103 | struct MHD_Response* | 103 | struct MHD_Response* |
104 | GNUNET_REST_create_response (const char *data); | 104 | GNUNET_REST_create_response (const char *data); |
diff --git a/src/include/gnunet_rest_plugin.h b/src/include/gnunet_rest_plugin.h index ecd5f66f1..424dbb1fc 100644 --- a/src/include/gnunet_rest_plugin.h +++ b/src/include/gnunet_rest_plugin.h | |||
@@ -57,7 +57,7 @@ struct GNUNET_REST_Plugin | |||
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Plugin name. Used as the namespace for the API. | 59 | * Plugin name. Used as the namespace for the API. |
60 | * e.g. http://hostname:port/<name> | 60 | * e.g. http://hostname:port/name |
61 | */ | 61 | */ |
62 | char *name; | 62 | char *name; |
63 | 63 | ||
diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h index c1e0d005c..03bc4575e 100644 --- a/src/include/gnunet_signatures.h +++ b/src/include/gnunet_signatures.h | |||
@@ -185,6 +185,11 @@ extern "C" | |||
185 | */ | 185 | */ |
186 | #define GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET 27 | 186 | #define GNUNET_SIGNATURE_PURPOSE_GNUID_TICKET 27 |
187 | 187 | ||
188 | /** | ||
189 | * Signature for a GNUnet credential | ||
190 | */ | ||
191 | #define GNUNET_SIGNATURE_PURPOSE_CREDENTIAL 28 | ||
192 | |||
188 | #if 0 /* keep Emacsens' auto-indent happy */ | 193 | #if 0 /* keep Emacsens' auto-indent happy */ |
189 | { | 194 | { |
190 | #endif | 195 | #endif |
diff --git a/src/jsonapi/jsonapi_document.c b/src/jsonapi/jsonapi_document.c index 600b7ee6a..3a60940f6 100644 --- a/src/jsonapi/jsonapi_document.c +++ b/src/jsonapi/jsonapi_document.c | |||
@@ -332,28 +332,20 @@ GNUNET_JSONAPI_document_to_json (const struct GNUNET_JSONAPI_Document *doc, | |||
332 | GNUNET_JSONAPI_KEY_ERRORS, | 332 | GNUNET_JSONAPI_KEY_ERRORS, |
333 | res_json); | 333 | res_json); |
334 | } else { | 334 | } else { |
335 | switch (doc->res_count) | 335 | if (0 == doc->res_count) |
336 | { | 336 | { |
337 | case 0: | 337 | res_json = json_null(); |
338 | res_json = json_null(); | 338 | } else { |
339 | break; | 339 | res_json = json_array (); |
340 | case 1: | 340 | for (res = doc->res_list_head; |
341 | res != NULL; | ||
342 | res = res->next) | ||
343 | { | ||
341 | GNUNET_assert (GNUNET_OK == | 344 | GNUNET_assert (GNUNET_OK == |
342 | GNUNET_JSONAPI_resource_to_json (doc->res_list_head, | 345 | GNUNET_JSONAPI_resource_to_json (res, |
343 | &res_json)); | 346 | &res_json_tmp)); |
344 | break; | 347 | json_array_append_new (res_json, res_json_tmp); |
345 | default: | 348 | } |
346 | res_json = json_array (); | ||
347 | for (res = doc->res_list_head; | ||
348 | res != NULL; | ||
349 | res = res->next) | ||
350 | { | ||
351 | GNUNET_assert (GNUNET_OK == | ||
352 | GNUNET_JSONAPI_resource_to_json (res, | ||
353 | &res_json_tmp)); | ||
354 | json_array_append (res_json, res_json_tmp); | ||
355 | } | ||
356 | break; | ||
357 | } | 349 | } |
358 | json_object_set_new (*root_json, | 350 | json_object_set_new (*root_json, |
359 | GNUNET_JSONAPI_KEY_DATA, | 351 | GNUNET_JSONAPI_KEY_DATA, |
diff --git a/src/jsonapi/jsonapi_resource.c b/src/jsonapi/jsonapi_resource.c index 85bca10ee..be28ad5df 100644 --- a/src/jsonapi/jsonapi_resource.c +++ b/src/jsonapi/jsonapi_resource.c | |||
@@ -92,9 +92,9 @@ GNUNET_JSONAPI_resource_new (const char *type, const char *id) | |||
92 | { | 92 | { |
93 | struct GNUNET_JSONAPI_Resource *res; | 93 | struct GNUNET_JSONAPI_Resource *res; |
94 | 94 | ||
95 | if ( (NULL == type) || (0 == strlen (type)) ) | 95 | if (NULL == type) |
96 | return NULL; | 96 | return NULL; |
97 | if ( (NULL == id) || (0 == strlen (id)) ) | 97 | if (NULL == id) |
98 | return NULL; | 98 | return NULL; |
99 | 99 | ||
100 | res = GNUNET_new (struct GNUNET_JSONAPI_Resource); | 100 | res = GNUNET_new (struct GNUNET_JSONAPI_Resource); |
@@ -245,7 +245,7 @@ GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource | |||
245 | * @param res the JSON resource | 245 | * @param res the JSON resource |
246 | * @return the resource id | 246 | * @return the resource id |
247 | */ | 247 | */ |
248 | char* | 248 | const char* |
249 | GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource) | 249 | GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource) |
250 | { | 250 | { |
251 | return resource->id; | 251 | return resource->id; |
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index 50957a5b4..05776801b 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c | |||
@@ -401,11 +401,16 @@ namestore_list_finished (void *cls) | |||
401 | struct MHD_Response *resp; | 401 | struct MHD_Response *resp; |
402 | 402 | ||
403 | handle->list_it = NULL; | 403 | handle->list_it = NULL; |
404 | if (NULL == handle->resp_object) | ||
405 | handle->resp_object = GNUNET_JSONAPI_document_new (); | ||
406 | |||
404 | if (GNUNET_SYSERR == | 407 | if (GNUNET_SYSERR == |
405 | GNUNET_JSONAPI_document_serialize (handle->resp_object, | 408 | GNUNET_JSONAPI_document_serialize (handle->resp_object, |
406 | &result)) | 409 | &result)) |
407 | { | 410 | { |
408 | do_error (handle); | 411 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; |
412 | GNUNET_SCHEDULER_add_now (&do_error, | ||
413 | handle); | ||
409 | return; | 414 | return; |
410 | } | 415 | } |
411 | resp = GNUNET_REST_create_response (result); | 416 | resp = GNUNET_REST_create_response (result); |
@@ -467,10 +472,10 @@ namestore_list_response (void *cls, | |||
467 | if (0 < json_array_size(result_array)) | 472 | if (0 < json_array_size(result_array)) |
468 | { | 473 | { |
469 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO, | 474 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO, |
470 | rname); | 475 | rname); |
471 | GNUNET_JSONAPI_resource_add_attr (json_resource, | 476 | GNUNET_JSONAPI_resource_add_attr (json_resource, |
472 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD, | 477 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD, |
473 | result_array); | 478 | result_array); |
474 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); | 479 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); |
475 | } | 480 | } |
476 | 481 | ||
@@ -767,8 +772,8 @@ namestore_create_cont (struct GNUNET_REST_RequestHandle *con, | |||
767 | } | 772 | } |
768 | term_data[handle->rest_handle->data_size] = '\0'; | 773 | term_data[handle->rest_handle->data_size] = '\0'; |
769 | GNUNET_memcpy (term_data, | 774 | GNUNET_memcpy (term_data, |
770 | handle->rest_handle->data, | 775 | handle->rest_handle->data, |
771 | handle->rest_handle->data_size); | 776 | handle->rest_handle->data_size); |
772 | data_js = json_loads (term_data, | 777 | data_js = json_loads (term_data, |
773 | JSON_DECODE_ANY, | 778 | JSON_DECODE_ANY, |
774 | &err); | 779 | &err); |
@@ -902,7 +907,7 @@ namestore_zkey_cont (struct GNUNET_REST_RequestHandle *con, | |||
902 | if ((NULL == handle->zkey_str) || | 907 | if ((NULL == handle->zkey_str) || |
903 | (GNUNET_OK != | 908 | (GNUNET_OK != |
904 | GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->zkey_str, | 909 | GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->zkey_str, |
905 | strlen (handle->zkey_str), | 910 | strlen (handle->zkey_str), |
906 | &pubkey))) | 911 | &pubkey))) |
907 | { | 912 | { |
908 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 913 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -1021,13 +1026,13 @@ identity_cb (void *cls, | |||
1021 | 1026 | ||
1022 | if (GNUNET_OK != | 1027 | if (GNUNET_OK != |
1023 | GNUNET_JSONAPI_handle_request (handle->rest_handle, | 1028 | GNUNET_JSONAPI_handle_request (handle->rest_handle, |
1024 | handlers, | 1029 | handlers, |
1025 | &err, | 1030 | &err, |
1026 | handle)) | 1031 | handle)) |
1027 | { | 1032 | { |
1028 | handle->response_code = err.error_code; | 1033 | handle->response_code = err.error_code; |
1029 | GNUNET_SCHEDULER_add_now (&do_error, | 1034 | GNUNET_SCHEDULER_add_now (&do_error, |
1030 | (void *) handle); | 1035 | (void *) handle); |
1031 | } | 1036 | } |
1032 | } | 1037 | } |
1033 | 1038 | ||
diff --git a/src/rest/rest.conf b/src/rest/rest.conf index 6cd013345..b86e6c1a0 100644 --- a/src/rest/rest.conf +++ b/src/rest/rest.conf | |||
@@ -1,4 +1,5 @@ | |||
1 | [rest] | 1 | [rest] |
2 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-rest.sock | ||
2 | BINARY=gnunet-rest-server | 3 | BINARY=gnunet-rest-server |
3 | REST_PORT=7776 | 4 | REST_PORT=7776 |
4 | REST_ALLOW_HEADERS=Authorization,Accept,Content-Type | 5 | REST_ALLOW_HEADERS=Authorization,Accept,Content-Type |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index c26e3e84b..eb655157d 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -123,7 +123,6 @@ libgnunetutil_la_LDFLAGS = \ | |||
123 | $(GN_LIB_LDFLAGS) \ | 123 | $(GN_LIB_LDFLAGS) \ |
124 | -version-info 13:0:0 | 124 | -version-info 13:0:0 |
125 | 125 | ||
126 | |||
127 | libgnunetutil_taler_wallet_la_SOURCES = \ | 126 | libgnunetutil_taler_wallet_la_SOURCES = \ |
128 | common_allocation.c \ | 127 | common_allocation.c \ |
129 | common_endian.c \ | 128 | common_endian.c \ |
diff --git a/src/util/crypto_abe.c b/src/util/crypto_abe.c new file mode 100644 index 000000000..fcaa826ed --- /dev/null +++ b/src/util/crypto_abe.c | |||
@@ -0,0 +1,416 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. Copyright (C) 2001-2014 Christian Grothoff | ||
3 | (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | 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 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | |||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * @file util/crypto_random.c | ||
24 | * @brief functions to gather random numbers | ||
25 | * @author Christian Grothoff | ||
26 | */ | ||
27 | |||
28 | |||
29 | #include "platform.h" | ||
30 | #include <pbc/pbc.h> | ||
31 | #include <gabe.h> | ||
32 | |||
33 | #include "gnunet_crypto_lib.h" | ||
34 | |||
35 | struct GNUNET_CRYPTO_AbeMasterKey | ||
36 | { | ||
37 | gabe_pub_t* pub; | ||
38 | gabe_msk_t* msk; | ||
39 | }; | ||
40 | |||
41 | struct GNUNET_CRYPTO_AbeKey | ||
42 | { | ||
43 | gabe_pub_t* pub; | ||
44 | gabe_prv_t* prv; | ||
45 | }; | ||
46 | |||
47 | static int | ||
48 | init_aes( element_t k, int enc, | ||
49 | gcry_cipher_hd_t* handle, | ||
50 | struct GNUNET_CRYPTO_SymmetricSessionKey *key, | ||
51 | unsigned char* iv) | ||
52 | { | ||
53 | int rc; | ||
54 | int key_len; | ||
55 | unsigned char* key_buf; | ||
56 | |||
57 | key_len = element_length_in_bytes(k) < 33 ? 3 : element_length_in_bytes(k); | ||
58 | key_buf = (unsigned char*) malloc(key_len); | ||
59 | element_to_bytes(key_buf, k); | ||
60 | |||
61 | memcpy (key->aes_key, key_buf, GNUNET_CRYPTO_AES_KEY_LENGTH); | ||
62 | GNUNET_assert (0 == | ||
63 | gcry_cipher_open (handle, GCRY_CIPHER_AES256, | ||
64 | GCRY_CIPHER_MODE_CFB, 0)); | ||
65 | rc = gcry_cipher_setkey (*handle, | ||
66 | key->aes_key, | ||
67 | sizeof (key->aes_key)); | ||
68 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
69 | memset (iv, 0, 16); //TODO make reasonable | ||
70 | rc = gcry_cipher_setiv (*handle, | ||
71 | iv, | ||
72 | 16); | ||
73 | GNUNET_assert ((0 == rc) || ((char) rc == GPG_ERR_WEAK_KEY)); | ||
74 | |||
75 | free(key_buf); | ||
76 | return rc; | ||
77 | } | ||
78 | |||
79 | static int | ||
80 | aes_128_cbc_encrypt( char* pt, | ||
81 | int size, | ||
82 | element_t k, | ||
83 | char **ct ) | ||
84 | { | ||
85 | gcry_cipher_hd_t handle; | ||
86 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
87 | unsigned char iv[16]; | ||
88 | char* buf; | ||
89 | int padding; | ||
90 | int buf_size; | ||
91 | uint8_t len[4]; | ||
92 | init_aes(k, 1, &handle, &skey, iv); | ||
93 | |||
94 | /* TODO make less crufty */ | ||
95 | |||
96 | /* stuff in real length (big endian) before padding */ | ||
97 | len[0] = (size & 0xff000000)>>24; | ||
98 | len[1] = (size & 0xff0000)>>16; | ||
99 | len[2] = (size & 0xff00)>>8; | ||
100 | len[3] = (size & 0xff)>>0; | ||
101 | padding = 16 - ((4+size) % 16); | ||
102 | buf_size = 4 + size + padding; | ||
103 | buf = GNUNET_malloc (buf_size); | ||
104 | GNUNET_memcpy (buf, len, 4); | ||
105 | GNUNET_memcpy (buf+4, pt, size); | ||
106 | *ct = GNUNET_malloc (buf_size); | ||
107 | |||
108 | GNUNET_assert (0 == gcry_cipher_encrypt (handle, *ct, buf_size, buf, buf_size)); | ||
109 | gcry_cipher_close (handle); | ||
110 | //AES_cbc_encrypt(pt->data, ct->data, pt->len, &key, iv, AES_ENCRYPT); | ||
111 | GNUNET_free (buf); | ||
112 | return buf_size; | ||
113 | } | ||
114 | |||
115 | static int | ||
116 | aes_128_cbc_decrypt( char* ct, | ||
117 | int size, | ||
118 | element_t k, | ||
119 | char **pt ) | ||
120 | { | ||
121 | struct GNUNET_CRYPTO_SymmetricSessionKey skey; | ||
122 | gcry_cipher_hd_t handle; | ||
123 | unsigned char iv[16]; | ||
124 | char* tmp; | ||
125 | uint32_t len; | ||
126 | |||
127 | init_aes(k, 1, &handle, &skey, iv); | ||
128 | |||
129 | tmp = GNUNET_malloc (size); | ||
130 | |||
131 | //AES_cbc_encrypt(ct->data, pt->data, ct->len, &key, iv, AES_DECRYPT); | ||
132 | GNUNET_assert (0 == gcry_cipher_decrypt (handle, tmp, size, ct, size)); | ||
133 | gcry_cipher_close (handle); | ||
134 | /* TODO make less crufty */ | ||
135 | |||
136 | /* get real length */ | ||
137 | len = 0; | ||
138 | len = len | ||
139 | | ((tmp[0])<<24) | ((tmp[1])<<16) | ||
140 | | ((tmp[2])<<8) | ((tmp[3])<<0); | ||
141 | /* truncate any garbage from the padding */ | ||
142 | *pt = GNUNET_malloc (len); | ||
143 | GNUNET_memcpy (*pt, tmp+4, len); | ||
144 | GNUNET_free (tmp); | ||
145 | return len; | ||
146 | } | ||
147 | |||
148 | struct GNUNET_CRYPTO_AbeMasterKey* | ||
149 | GNUNET_CRYPTO_cpabe_create_master_key (void) | ||
150 | { | ||
151 | struct GNUNET_CRYPTO_AbeMasterKey* key; | ||
152 | key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey); | ||
153 | gabe_setup(&key->pub, &key->msk); | ||
154 | GNUNET_assert (NULL != key->pub); | ||
155 | GNUNET_assert (NULL != key->msk); | ||
156 | return key; | ||
157 | } | ||
158 | |||
159 | void | ||
160 | GNUNET_CRYPTO_cpabe_delete_master_key (struct GNUNET_CRYPTO_AbeMasterKey *key) | ||
161 | { | ||
162 | gabe_msk_free (key->msk); | ||
163 | gabe_pub_free (key->pub); | ||
164 | //GNUNET_free (key->msk); | ||
165 | //gabe_msk_free (key->msk); //For some reason free of pub implicit? | ||
166 | GNUNET_free (key); | ||
167 | } | ||
168 | |||
169 | struct GNUNET_CRYPTO_AbeKey* | ||
170 | GNUNET_CRYPTO_cpabe_create_key (struct GNUNET_CRYPTO_AbeMasterKey *key, | ||
171 | char **attrs) | ||
172 | { | ||
173 | struct GNUNET_CRYPTO_AbeKey *prv_key; | ||
174 | int size; | ||
175 | char *tmp; | ||
176 | |||
177 | prv_key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey); | ||
178 | prv_key->prv = gabe_keygen(key->pub, key->msk, attrs); | ||
179 | size = gabe_pub_serialize(key->pub, &tmp); | ||
180 | prv_key->pub = gabe_pub_unserialize(tmp, size); | ||
181 | GNUNET_free (tmp); | ||
182 | GNUNET_assert (NULL != prv_key->prv); | ||
183 | return prv_key; | ||
184 | } | ||
185 | |||
186 | void | ||
187 | GNUNET_CRYPTO_cpabe_delete_key (struct GNUNET_CRYPTO_AbeKey *key, | ||
188 | int delete_pub) | ||
189 | { | ||
190 | //Memory management in gabe is buggy | ||
191 | gabe_prv_free (key->prv); | ||
192 | if (GNUNET_YES == delete_pub) | ||
193 | gabe_pub_free (key->pub); | ||
194 | GNUNET_free (key); | ||
195 | } | ||
196 | |||
197 | ssize_t | ||
198 | write_cpabe (void **result, | ||
199 | uint32_t file_len, | ||
200 | char* cph_buf, | ||
201 | int cph_buf_len, | ||
202 | char* aes_buf, | ||
203 | int aes_buf_len) | ||
204 | { | ||
205 | char *ptr; | ||
206 | uint32_t *len; | ||
207 | |||
208 | *result = GNUNET_malloc (12 + cph_buf_len + aes_buf_len); | ||
209 | ptr = *result; | ||
210 | len = (uint32_t*) ptr; | ||
211 | *len = htonl (file_len); | ||
212 | ptr += 4; | ||
213 | len = (uint32_t*) ptr; | ||
214 | *len = htonl (aes_buf_len); | ||
215 | ptr += 4; | ||
216 | memcpy (ptr, aes_buf, aes_buf_len); | ||
217 | ptr += aes_buf_len; | ||
218 | len = (uint32_t*) ptr; | ||
219 | *len = htonl (cph_buf_len); | ||
220 | ptr += 4; | ||
221 | memcpy (ptr, cph_buf, cph_buf_len); | ||
222 | return 12 + cph_buf_len + aes_buf_len; | ||
223 | } | ||
224 | |||
225 | ssize_t | ||
226 | read_cpabe (const void *data, | ||
227 | char** cph_buf, | ||
228 | int *cph_buf_len, | ||
229 | char** aes_buf, | ||
230 | int *aes_buf_len) | ||
231 | { | ||
232 | int buf_len; | ||
233 | char *ptr; | ||
234 | uint32_t *len; | ||
235 | |||
236 | ptr = (char*)data; | ||
237 | len = (uint32_t*)ptr; | ||
238 | buf_len = ntohl (*len); | ||
239 | ptr += 4; | ||
240 | len = (uint32_t*)ptr; | ||
241 | *aes_buf_len = ntohl (*len); | ||
242 | ptr += 4; | ||
243 | *aes_buf = GNUNET_malloc (*aes_buf_len); | ||
244 | memcpy(*aes_buf, ptr, *aes_buf_len); | ||
245 | ptr += *aes_buf_len; | ||
246 | len = (uint32_t*)ptr; | ||
247 | *cph_buf_len = ntohl (*len); | ||
248 | ptr += 4; | ||
249 | *cph_buf = GNUNET_malloc (*cph_buf_len); | ||
250 | memcpy(*cph_buf, ptr, *cph_buf_len); | ||
251 | |||
252 | return buf_len; | ||
253 | } | ||
254 | |||
255 | ssize_t | ||
256 | GNUNET_CRYPTO_cpabe_encrypt (const void *block, | ||
257 | size_t size, | ||
258 | const char *policy, | ||
259 | const struct GNUNET_CRYPTO_AbeMasterKey *key, | ||
260 | void **result) | ||
261 | { | ||
262 | gabe_cph_t* cph; | ||
263 | char* plt; | ||
264 | char* cph_buf; | ||
265 | char* aes_buf; | ||
266 | element_t m; | ||
267 | int cph_buf_len; | ||
268 | int aes_buf_len; | ||
269 | ssize_t result_len; | ||
270 | |||
271 | if( !(cph = gabe_enc(key->pub, m, (char*)policy)) ) | ||
272 | return GNUNET_SYSERR; | ||
273 | cph_buf_len = gabe_cph_serialize(cph, | ||
274 | &cph_buf); | ||
275 | gabe_cph_free(cph); | ||
276 | GNUNET_free (cph); | ||
277 | plt = GNUNET_memdup (block, size); | ||
278 | aes_buf_len = aes_128_cbc_encrypt(plt, size, m, &aes_buf); | ||
279 | GNUNET_free (plt); | ||
280 | element_clear(m); | ||
281 | result_len = write_cpabe(result, size, cph_buf, cph_buf_len, aes_buf, aes_buf_len); | ||
282 | GNUNET_free(cph_buf); | ||
283 | GNUNET_free(aes_buf); | ||
284 | return result_len; | ||
285 | } | ||
286 | |||
287 | ssize_t | ||
288 | GNUNET_CRYPTO_cpabe_decrypt (const void *block, | ||
289 | size_t size, | ||
290 | const struct GNUNET_CRYPTO_AbeKey *key, | ||
291 | void **result) | ||
292 | { | ||
293 | char* aes_buf; | ||
294 | char* cph_buf; | ||
295 | gabe_cph_t* cph; | ||
296 | element_t m; | ||
297 | int cph_buf_size; | ||
298 | int aes_buf_size; | ||
299 | int plt_len; | ||
300 | |||
301 | read_cpabe(block, &cph_buf, &cph_buf_size, &aes_buf, &aes_buf_size); | ||
302 | cph = gabe_cph_unserialize(key->pub, cph_buf, cph_buf_size); | ||
303 | if( !gabe_dec(key->pub, key->prv, cph, m) ) { | ||
304 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
305 | "%s\n", gabe_error()); | ||
306 | GNUNET_free (aes_buf); | ||
307 | GNUNET_free (cph_buf); | ||
308 | gabe_cph_free(cph); | ||
309 | GNUNET_free (cph); | ||
310 | element_clear (m); | ||
311 | return GNUNET_SYSERR; | ||
312 | } | ||
313 | gabe_cph_free(cph); | ||
314 | GNUNET_free (cph); | ||
315 | plt_len = aes_128_cbc_decrypt(aes_buf, aes_buf_size, m, (char**)result); | ||
316 | GNUNET_free (cph_buf); | ||
317 | GNUNET_free (aes_buf); | ||
318 | element_clear (m); | ||
319 | //freeing is buggy in gabe | ||
320 | //gabe_prv_free (prv); | ||
321 | //gabe_pub_free (pub); | ||
322 | return plt_len; | ||
323 | } | ||
324 | |||
325 | ssize_t | ||
326 | GNUNET_CRYPTO_cpabe_serialize_key (const struct GNUNET_CRYPTO_AbeKey *key, | ||
327 | void **result) | ||
328 | { | ||
329 | ssize_t len; | ||
330 | char *pub; | ||
331 | char *prv; | ||
332 | int pub_len; | ||
333 | int prv_len; | ||
334 | |||
335 | pub_len = gabe_pub_serialize (key->pub, &pub); | ||
336 | prv_len = gabe_prv_serialize (key->prv, &prv); | ||
337 | |||
338 | len = pub_len + prv_len + 12; | ||
339 | write_cpabe (result, len, pub, pub_len, prv, prv_len); | ||
340 | |||
341 | GNUNET_free (pub); | ||
342 | GNUNET_free (prv); | ||
343 | |||
344 | return len; | ||
345 | } | ||
346 | |||
347 | struct GNUNET_CRYPTO_AbeKey* | ||
348 | GNUNET_CRYPTO_cpabe_deserialize_key (const void *data, | ||
349 | size_t len) | ||
350 | { | ||
351 | struct GNUNET_CRYPTO_AbeKey *key; | ||
352 | char *pub; | ||
353 | char *prv; | ||
354 | int prv_len; | ||
355 | int pub_len; | ||
356 | |||
357 | key = GNUNET_new (struct GNUNET_CRYPTO_AbeKey); | ||
358 | read_cpabe (data, | ||
359 | &pub, | ||
360 | &pub_len, | ||
361 | &prv, | ||
362 | &prv_len); | ||
363 | key->pub = gabe_pub_unserialize (pub, pub_len); | ||
364 | key->prv = gabe_prv_unserialize (key->pub, prv, prv_len); | ||
365 | |||
366 | GNUNET_free (pub); | ||
367 | GNUNET_free (prv); | ||
368 | return key; | ||
369 | } | ||
370 | |||
371 | ssize_t | ||
372 | GNUNET_CRYPTO_cpabe_serialize_master_key (const struct GNUNET_CRYPTO_AbeMasterKey *key, | ||
373 | void **result) | ||
374 | { | ||
375 | ssize_t len; | ||
376 | char *pub; | ||
377 | char *msk; | ||
378 | int pub_len; | ||
379 | int msk_len; | ||
380 | |||
381 | pub_len = gabe_pub_serialize (key->pub, &pub); | ||
382 | msk_len = gabe_msk_serialize (key->msk, &msk); | ||
383 | |||
384 | len = pub_len + msk_len + 12; | ||
385 | write_cpabe (result, len, pub, pub_len, msk, msk_len); | ||
386 | |||
387 | GNUNET_free (pub); | ||
388 | GNUNET_free (msk); | ||
389 | |||
390 | return len; | ||
391 | } | ||
392 | |||
393 | struct GNUNET_CRYPTO_AbeMasterKey* | ||
394 | GNUNET_CRYPTO_cpabe_deserialize_master_key (const void *data, | ||
395 | size_t len) | ||
396 | { | ||
397 | struct GNUNET_CRYPTO_AbeMasterKey *key; | ||
398 | char *msk; | ||
399 | char *pub; | ||
400 | int msk_len; | ||
401 | int pub_len; | ||
402 | |||
403 | key = GNUNET_new (struct GNUNET_CRYPTO_AbeMasterKey); | ||
404 | read_cpabe (data, | ||
405 | &pub, | ||
406 | &pub_len, | ||
407 | &msk, | ||
408 | &msk_len); | ||
409 | key->pub = gabe_pub_unserialize (pub, pub_len); | ||
410 | key->msk = gabe_msk_unserialize (key->pub, msk, msk_len); | ||
411 | |||
412 | GNUNET_free (pub); | ||
413 | GNUNET_free (msk); | ||
414 | |||
415 | return key; | ||
416 | } | ||