Verify that GCD(m,n) != 1 when n is an RSA modulus
[oweals/gnunet.git] / src / dns / plugin_block_dns.c
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 dns/plugin_block_dns.c
23  * @brief block plugin for advertising a DNS exit service
24  * @author Christian Grothoff
25  *
26  * Note that this plugin might more belong with EXIT and PT
27  * as those two are using this type of block.  Still, this
28  * might be a natural enough place for people to find the code...
29  */
30 #include "platform.h"
31 #include "gnunet_block_plugin.h"
32 #include "block_dns.h"
33 #include "gnunet_signatures.h"
34
35
36 /**
37  * Function called to validate a reply or a request.  For
38  * request evaluation, simply pass "NULL" for the reply_block.
39  *
40  * @param cls closure
41  * @param type block type
42  * @param eo control flags
43  * @param query original query (hash)
44  * @param bf pointer to bloom filter associated with query; possibly updated (!)
45  * @param bf_mutator mutation value for bf
46  * @param xquery extended query data (can be NULL, depending on type)
47  * @param xquery_size number of bytes in @a xquery
48  * @param reply_block response to validate
49  * @param reply_block_size number of bytes in @a reply_block
50  * @return characterization of result
51  */
52 static enum GNUNET_BLOCK_EvaluationResult
53 block_plugin_dns_evaluate (void *cls,
54                            enum GNUNET_BLOCK_Type type,
55                            enum GNUNET_BLOCK_EvaluationOptions eo,
56                            const struct GNUNET_HashCode * query,
57                            struct GNUNET_CONTAINER_BloomFilter **bf,
58                            int32_t bf_mutator,
59                            const void *xquery,
60                            size_t xquery_size,
61                            const void *reply_block,
62                            size_t reply_block_size)
63 {
64   const struct GNUNET_DNS_Advertisement *ad;
65
66   switch (type)
67   {
68   case GNUNET_BLOCK_TYPE_DNS:
69     if (0 != xquery_size)
70       return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID;
71
72     if (0 == reply_block_size)
73       return GNUNET_BLOCK_EVALUATION_REQUEST_VALID;
74
75     if (sizeof (struct GNUNET_DNS_Advertisement) != reply_block_size)
76     {
77       GNUNET_break_op (0);
78       return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
79     }
80     ad = reply_block;
81
82     if (ntohl (ad->purpose.size) !=
83         sizeof (struct GNUNET_DNS_Advertisement) -
84         sizeof (struct GNUNET_CRYPTO_EddsaSignature))
85     {
86       GNUNET_break_op (0);
87       return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
88     }
89     if (0 ==
90         GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_ntoh
91                                             (ad->expiration_time)).rel_value_us)
92     {
93       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
94                   "DNS advertisement has expired\n");
95       return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
96     }
97     if (GNUNET_OK !=
98         GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_DNS_RECORD,
99                                   &ad->purpose,
100                                   &ad->signature,
101                                   &ad->peer.public_key))
102     {
103       GNUNET_break_op (0);
104       return GNUNET_BLOCK_EVALUATION_RESULT_INVALID;
105     }
106     return GNUNET_BLOCK_EVALUATION_OK_MORE;
107   default:
108     return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED;
109   }
110 }
111
112
113 /**
114  * Function called to obtain the key for a block.
115  *
116  * @param cls closure
117  * @param type block type
118  * @param block block to get the key for
119  * @param block_size number of bytes in @a block
120  * @param key set to the key (query) for the given block
121  * @return #GNUNET_OK on success, #GNUNET_SYSERR if type not supported
122  *         (or if extracting a key from a block of this type does not work)
123  */
124 static int
125 block_plugin_dns_get_key (void *cls,
126                           enum GNUNET_BLOCK_Type type,
127                           const void *block,
128                           size_t block_size,
129                           struct GNUNET_HashCode *key)
130 {
131   /* we cannot extract a key from a block of this type */
132   return GNUNET_SYSERR;
133 }
134
135
136 /**
137  * Entry point for the plugin.
138  */
139 void *
140 libgnunet_plugin_block_dns_init (void *cls)
141 {
142   static enum GNUNET_BLOCK_Type types[] =
143   {
144     GNUNET_BLOCK_TYPE_DNS,
145     GNUNET_BLOCK_TYPE_ANY       /* end of list */
146   };
147   struct GNUNET_BLOCK_PluginFunctions *api;
148
149   api = GNUNET_new (struct GNUNET_BLOCK_PluginFunctions);
150   api->evaluate = &block_plugin_dns_evaluate;
151   api->get_key = &block_plugin_dns_get_key;
152   api->types = types;
153   return api;
154 }
155
156
157 /**
158  * Exit point from the plugin.
159  */
160 void *
161 libgnunet_plugin_block_dns_done (void *cls)
162 {
163   struct GNUNET_BLOCK_PluginFunctions *api = cls;
164
165   GNUNET_free (api);
166   return NULL;
167 }
168
169 /* end of plugin_block_dns.c */