glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / credential / credential_misc.c
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 it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14 */
15
16
17 /**
18  * @file credential/credential_misc.c
19  * @brief Misc API for credentials
20  *
21  * @author Martin Schanzenbach
22  */
23 #include "platform.h"
24 #include "gnunet_util_lib.h"
25 #include "gnunet_constants.h"
26 #include "gnunet_credential_service.h"
27 #include "gnunet_signatures.h"
28 #include "credential.h"
29 #include <inttypes.h>
30
31 char*
32 GNUNET_CREDENTIAL_credential_to_string (const struct GNUNET_CREDENTIAL_Credential *cred)
33 {
34   char *cred_str;
35   char *subject_pkey;
36   char *issuer_pkey;
37   char *signature;
38
39
40   subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->subject_key);
41   issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred->issuer_key);
42   GNUNET_STRINGS_base64_encode ((char*)&cred->signature,
43                                 sizeof (struct GNUNET_CRYPTO_EcdsaSignature),
44                                 &signature);
45   GNUNET_asprintf (&cred_str,
46                    "%s.%s -> %s | %s | %"SCNu64,
47                    issuer_pkey,
48                    cred->issuer_attribute,
49                    subject_pkey,
50                    signature,
51                    cred->expiration.abs_value_us);
52   GNUNET_free (subject_pkey);
53   GNUNET_free (issuer_pkey);
54   GNUNET_free (signature);
55   return cred_str;
56 }
57
58 struct GNUNET_CREDENTIAL_Credential*
59 GNUNET_CREDENTIAL_credential_from_string (const char* s)
60 {
61   struct GNUNET_CREDENTIAL_Credential *cred;
62   size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
63   if (enclen % 5 > 0)
64     enclen += 5 - enclen % 5;
65   enclen /= 5; /* 260/5 = 52 */
66   char subject_pkey[enclen + 1];
67   char issuer_pkey[enclen + 1];
68   char name[253 + 1];
69   char signature[256]; //TODO max payload size
70
71   struct GNUNET_CRYPTO_EcdsaSignature *sig;
72   struct GNUNET_TIME_Absolute etime_abs;
73
74   if (5 != SSCANF (s,
75                    "%52s.%253s -> %52s | %s | %"SCNu64,
76                    issuer_pkey,
77                    name,
78                    subject_pkey,
79                    signature,
80                    &etime_abs.abs_value_us))
81   {
82     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
83                 _("Unable to parse CRED record string `%s'\n"),
84                 s);
85     return NULL;
86   }
87   cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + strlen (name) + 1);
88   GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey,
89                                               strlen (subject_pkey),
90                                               &cred->subject_key);
91   GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey,
92                                               strlen (issuer_pkey),
93                                               &cred->issuer_key);
94   GNUNET_assert (sizeof (struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode (signature,
95                                 strlen (signature),
96                                 (char**)&sig));
97   cred->signature = *sig;
98   cred->expiration = etime_abs;
99   GNUNET_free (sig);
100   GNUNET_memcpy (&cred[1],
101                  name,
102                  strlen (name)+1);
103   cred->issuer_attribute_len = strlen ((char*)&cred[1]);
104   cred->issuer_attribute = (char*)&cred[1];
105   return cred;
106 }
107
108 /**
109  * Issue an attribute to a subject
110  *
111  * @param issuer the ego that should be used to issue the attribute
112  * @param subject the subject of the attribute
113  * @param attribute the name of the attribute
114  * @return handle to the queued request
115  */
116 struct GNUNET_CREDENTIAL_Credential *
117 GNUNET_CREDENTIAL_credential_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
118                                     struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
119                                     const char *attribute,
120                                     struct GNUNET_TIME_Absolute *expiration)
121 {
122   struct CredentialEntry *crd;
123   struct GNUNET_CREDENTIAL_Credential *cred;
124   size_t size;
125
126   size = sizeof (struct CredentialEntry) + strlen (attribute) + 1;
127   crd = GNUNET_malloc (size);
128   cred = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) + strlen (attribute) + 1);
129   crd->purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
130
131   crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
132   GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
133                                       &crd->issuer_key);
134   crd->subject_key = *subject;
135   crd->expiration = GNUNET_htonll (expiration->abs_value_us);
136   crd->issuer_attribute_len = htonl (strlen (attribute)+1);
137   GNUNET_memcpy ((char*)&crd[1],
138                  attribute,
139                  strlen (attribute)+1);
140   if (GNUNET_OK !=
141       GNUNET_CRYPTO_ecdsa_sign (issuer,
142                                 &crd->purpose,
143                                 &crd->signature))
144   {
145     GNUNET_break (0);
146     GNUNET_free (crd);
147     GNUNET_free (cred);
148     return NULL;
149   }
150   cred->signature = crd->signature;
151   cred->expiration = *expiration;
152   GNUNET_CRYPTO_ecdsa_key_get_public (issuer,
153                                       &cred->issuer_key);
154
155   cred->subject_key = *subject;
156   GNUNET_memcpy (&cred[1],
157                  attribute,
158                  strlen (attribute)+1);
159   cred->issuer_attribute = (char*)&cred[1];
160   GNUNET_free (crd);
161   return cred;
162 }
163
164