uncrustify as demanded.
[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      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21
22 /**
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
69   if (enclen % 5 > 0)
70     enclen += 5 - enclen % 5;
71   enclen /= 5; /* 260/5 = 52 */
72   char subject_pkey[enclen + 1];
73   char issuer_pkey[enclen + 1];
74   char name[253 + 1];
75   char signature[256]; //TODO max payload size
76
77   struct GNUNET_CRYPTO_EcdsaSignature *sig;
78   struct GNUNET_TIME_Absolute etime_abs;
79
80   if (5 != SSCANF(s,
81                   "%52s.%253s -> %52s | %s | %" SCNu64,
82                   issuer_pkey,
83                   name,
84                   subject_pkey,
85                   signature,
86                   &etime_abs.abs_value_us))
87     {
88       GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
89                  _("Unable to parse CRED record string `%s'\n"),
90                  s);
91       return NULL;
92     }
93   cred = GNUNET_malloc(sizeof(struct GNUNET_CREDENTIAL_Credential) + strlen(name) + 1);
94   GNUNET_CRYPTO_ecdsa_public_key_from_string(subject_pkey,
95                                              strlen(subject_pkey),
96                                              &cred->subject_key);
97   GNUNET_CRYPTO_ecdsa_public_key_from_string(issuer_pkey,
98                                              strlen(issuer_pkey),
99                                              &cred->issuer_key);
100   GNUNET_assert(sizeof(struct GNUNET_CRYPTO_EcdsaSignature) == GNUNET_STRINGS_base64_decode(signature,
101                                                                                             strlen(signature),
102                                                                                             (char**)&sig));
103   cred->signature = *sig;
104   cred->expiration = etime_abs;
105   GNUNET_free(sig);
106   GNUNET_memcpy(&cred[1],
107                 name,
108                 strlen(name) + 1);
109   cred->issuer_attribute_len = strlen((char*)&cred[1]);
110   cred->issuer_attribute = (char*)&cred[1];
111   return cred;
112 }
113
114 /**
115  * Issue an attribute to a subject
116  *
117  * @param issuer the ego that should be used to issue the attribute
118  * @param subject the subject of the attribute
119  * @param attribute the name of the attribute
120  * @return handle to the queued request
121  */
122 struct GNUNET_CREDENTIAL_Credential *
123 GNUNET_CREDENTIAL_credential_issue(const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer,
124                                    struct GNUNET_CRYPTO_EcdsaPublicKey *subject,
125                                    const char *attribute,
126                                    struct GNUNET_TIME_Absolute *expiration)
127 {
128   struct CredentialEntry *crd;
129   struct GNUNET_CREDENTIAL_Credential *cred;
130   size_t size;
131
132   size = sizeof(struct CredentialEntry) + strlen(attribute) + 1;
133   crd = GNUNET_malloc(size);
134   cred = GNUNET_malloc(sizeof(struct GNUNET_CREDENTIAL_Credential) + strlen(attribute) + 1);
135   crd->purpose.size = htonl(size - sizeof(struct GNUNET_CRYPTO_EcdsaSignature));
136
137   crd->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_CREDENTIAL);
138   GNUNET_CRYPTO_ecdsa_key_get_public(issuer,
139                                      &crd->issuer_key);
140   crd->subject_key = *subject;
141   crd->expiration = GNUNET_htonll(expiration->abs_value_us);
142   crd->issuer_attribute_len = htonl(strlen(attribute) + 1);
143   GNUNET_memcpy((char*)&crd[1],
144                 attribute,
145                 strlen(attribute) + 1);
146   if (GNUNET_OK !=
147       GNUNET_CRYPTO_ecdsa_sign(issuer,
148                                &crd->purpose,
149                                &crd->signature))
150     {
151       GNUNET_break(0);
152       GNUNET_free(crd);
153       GNUNET_free(cred);
154       return NULL;
155     }
156   cred->signature = crd->signature;
157   cred->expiration = *expiration;
158   GNUNET_CRYPTO_ecdsa_key_get_public(issuer,
159                                      &cred->issuer_key);
160
161   cred->subject_key = *subject;
162   GNUNET_memcpy(&cred[1],
163                 attribute,
164                 strlen(attribute) + 1);
165   cred->issuer_attribute = (char*)&cred[1];
166   GNUNET_free(crd);
167   return cred;
168 }
169
170