aboutsummaryrefslogtreecommitdiff
path: root/src/credential/plugin_gnsrecord_credential.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/credential/plugin_gnsrecord_credential.c')
-rw-r--r--src/credential/plugin_gnsrecord_credential.c257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c
new file mode 100644
index 000000000..6ae3b8980
--- /dev/null
+++ b/src/credential/plugin_gnsrecord_credential.c
@@ -0,0 +1,257 @@
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 Adnan Husain
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
33
34/**
35 * Convert the 'value' of a record to a string.
36 *
37 * @param cls closure, unused
38 * @param type type of the record
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 */
43static char *
44credential_value_to_string (void *cls,
45 uint32_t type,
46 const void *data,
47 size_t data_size)
48{
49
50 const char *cdata;
51
52 switch (type)
53 {
54 case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
55 {
56 struct GNUNET_CREDENTIAL_RecordData cred;
57 char *cred_str;
58 char *subject_pkey;
59 char *issuer_pkey;
60 uint32_t cf; // Credential flags
61 uint32_t mdd; // Max delegation depth
62 if (data_size < sizeof (struct GNUNET_CREDENTIAL_RecordData))
63 return NULL; /* malformed */
64 memcpy (&cred,
65 data,
66 sizeof (cred));
67 cdata = data;
68 subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key);
69 issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key);
70 cf = ntohl (cred.credential_flags);
71 mdd = ntohl (cred.max_delegation_depth);
72
73 GNUNET_asprintf (&cred_str,
74 "%s %s %u %u %s",
75 subject_pkey,
76 issuer_pkey,
77 (unsigned int) cf,
78 (unsigned int) mdd,
79 &cdata[sizeof (cred)]);
80 GNUNET_free (subject_pkey);
81 GNUNET_free (issuer_pkey);
82
83
84
85 return cred_str;
86 }
87 default:
88 return NULL;
89 }
90}
91
92
93/**
94 * Convert human-readable version of a 'value' of a record to the binary
95 * representation.
96 *
97 * @param cls closure, unused
98 * @param type type of the record
99 * @param s human-readable string
100 * @param data set to value in binary encoding (will be allocated)
101 * @param data_size set to number of bytes in @a data
102 * @return #GNUNET_OK on success
103 */
104static int
105credential_string_to_value (void *cls,
106 uint32_t type,
107 const char *s,
108 void **data,
109 size_t *data_size)
110{
111 if (NULL == s)
112 return GNUNET_SYSERR;
113 switch (type)
114 {
115 case GNUNET_GNSRECORD_TYPE_CREDENTIAL:
116 {
117 struct GNUNET_CREDENTIAL_RecordData *cred;
118 unsigned int cf; // credential flags
119 unsigned int mdd; // max delegation depth
120
121 size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
122 if (enclen % 5 > 0)
123 enclen += 5 - enclen % 5;
124 enclen /= 5; /* 260/5 = 52 */
125 char subject_pkey[enclen + 1];
126 char issuer_pkey[enclen + 1];
127 char name[253 + 1];
128
129 if (5 != SSCANF (s,
130 "%52s %52s %u %u %253s",
131 subject_pkey,
132 issuer_pkey,
133 &cf,
134 &mdd,
135 name))
136 {
137 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
138 _("Unable to parse CRED record string `%s'\n"),
139 s);
140 return GNUNET_SYSERR;
141 }
142 *data_size = sizeof (struct GNUNET_CREDENTIAL_RecordData) + strlen (name) + 1;
143 *data = cred = GNUNET_malloc (*data_size);
144 GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
145 strlen (subject_pkey),
146 &cred->subject_key);
147 GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
148 strlen (issuer_pkey),
149 &cred->issuer_key);
150 cred->credential_flags = htonl (cf);
151 cred->max_delegation_depth = htonl (mdd);
152 GNUNET_memcpy (&cred[1],
153 name,
154 strlen (name));
155
156
157 *data = GNUNET_strdup (s);
158 *data_size = strlen (s);
159 return GNUNET_OK;
160 }
161 default:
162 return GNUNET_SYSERR;
163 }
164}
165
166
167/**
168 * Mapping of record type numbers to human-readable
169 * record type names.
170 */
171static struct {
172 const char *name;
173 uint32_t number;
174} name_map[] = {
175 { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL },
176 { NULL, UINT32_MAX }
177};
178
179
180/**
181 * Convert a type name (i.e. "AAAA") to the corresponding number.
182 *
183 * @param cls closure, unused
184 * @param gns_typename name to convert
185 * @return corresponding number, UINT32_MAX on error
186 */
187static uint32_t
188credential_typename_to_number (void *cls,
189 const char *gns_typename)
190{
191 unsigned int i;
192
193 i=0;
194 while ( (name_map[i].name != NULL) &&
195 (0 != strcasecmp (gns_typename, name_map[i].name)) )
196 i++;
197 return name_map[i].number;
198}
199
200
201/**
202 * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A")
203 *
204 * @param cls closure, unused
205 * @param type number of a type to convert
206 * @return corresponding typestring, NULL on error
207 */
208static const char *
209credential_number_to_typename (void *cls,
210 uint32_t type)
211{
212 unsigned int i;
213
214 i=0;
215 while ( (name_map[i].name != NULL) &&
216 (type != name_map[i].number) )
217 i++;
218 return name_map[i].name;
219}
220
221
222/**
223 * Entry point for the plugin.
224 *
225 * @param cls NULL
226 * @return the exported block API
227 */
228void *
229libgnunet_plugin_gnsrecord_credential_init (void *cls)
230{
231 struct GNUNET_GNSRECORD_PluginFunctions *api;
232
233 api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions);
234 api->value_to_string = &credential_value_to_string;
235 api->string_to_value = &credential_string_to_value;
236 api->typename_to_number = &credential_typename_to_number;
237 api->number_to_typename = &credential_number_to_typename;
238 return api;
239}
240
241
242/**
243 * Exit point from the plugin.
244 *
245 * @param cls the return value from #libgnunet_plugin_block_test_init
246 * @return NULL
247 */
248void *
249libgnunet_plugin_gnsrecord_credential_done (void *cls)
250{
251 struct GNUNET_GNSRECORD_PluginFunctions *api = cls;
252
253 GNUNET_free (api);
254 return NULL;
255}
256
257/* end of plugin_gnsrecord_credential.c */