summaryrefslogtreecommitdiffstats
path: root/src/libcryptobox/keypair.h
blob: 64461b7d4356360078b1b268e814b9acc4978221 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/*-
 * Copyright 2016 Vsevolod Stakhov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef SRC_LIBCRYPTOBOX_KEYPAIR_H_
#define SRC_LIBCRYPTOBOX_KEYPAIR_H_

#include "config.h"
#include "cryptobox.h"
#include "ucl.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Keypair type
 */
enum rspamd_cryptobox_keypair_type {
	RSPAMD_KEYPAIR_KEX = 0,
	RSPAMD_KEYPAIR_SIGN
};

extern const guchar encrypted_magic[7];

/**
 * Opaque structure for the full (public + private) keypair
 */
struct rspamd_cryptobox_keypair;
/**
 * Opaque structure for public only keypair
 */
struct rspamd_cryptobox_pubkey;

/**
 * Creates new full keypair
 * @param type type of the keypair
 * @param alg algorithm for the keypair
 * @return fresh keypair generated
 */
struct rspamd_cryptobox_keypair *rspamd_keypair_new(
	enum rspamd_cryptobox_keypair_type type,
	enum rspamd_cryptobox_mode alg);

/**
 * Increase refcount for the specific keypair
 * @param kp
 * @return
 */
struct rspamd_cryptobox_keypair *rspamd_keypair_ref(
	struct rspamd_cryptobox_keypair *kp);

/**
 * Decrease refcount for the specific keypair (or destroy when refcount == 0)
 * @param kp
 */
void rspamd_keypair_unref(struct rspamd_cryptobox_keypair *kp);

/**
 * Increase refcount for the specific pubkey
 * @param kp
 * @return
 */
struct rspamd_cryptobox_pubkey *rspamd_pubkey_ref(
	struct rspamd_cryptobox_pubkey *kp);

/**
 * Load pubkey from base32 string
 * @param b32 input string
 * @param type type of key (signing or kex)
 * @param alg algorithm of the key (nist or curve25519)
 * @return new pubkey or NULL in case of error
 */
struct rspamd_cryptobox_pubkey *rspamd_pubkey_from_base32(const gchar *b32,
														  gsize len,
														  enum rspamd_cryptobox_keypair_type type,
														  enum rspamd_cryptobox_mode alg);

/**
 * Load pubkey from hex string
 * @param hex input string
 * @param type type of key (signing or kex)
 * @param alg algorithm of the key (nist or curve25519)
 * @return new pubkey or NULL in case of error
 */
struct rspamd_cryptobox_pubkey *rspamd_pubkey_from_hex(const gchar *hex,
													   gsize len,
													   enum rspamd_cryptobox_keypair_type type,
													   enum rspamd_cryptobox_mode alg);

/**
 * Load pubkey from raw chunk string
 * @param hex input data
 * @param type type of key (signing or kex)
 * @param alg algorithm of the key (nist or curve25519)
 * @return new pubkey or NULL in case of error
 */
struct rspamd_cryptobox_pubkey *rspamd_pubkey_from_bin(const guchar *raw,
													   gsize len,
													   enum rspamd_cryptobox_keypair_type type,
													   enum rspamd_cryptobox_mode alg);


/**
 * Decrease refcount for the specific pubkey (or destroy when refcount == 0)
 * @param kp
 */
void rspamd_pubkey_unref(struct rspamd_cryptobox_pubkey *kp);

/**
 * Get type of keypair
 */
enum rspamd_cryptobox_keypair_type rspamd_keypair_type(
	struct rspamd_cryptobox_keypair *kp);

/**
 * Get type of pubkey
 */
enum rspamd_cryptobox_keypair_type rspamd_pubkey_type(
	struct rspamd_cryptobox_pubkey *p);

/**
 * Get algorithm of keypair
 */
enum rspamd_cryptobox_mode rspamd_keypair_alg(struct rspamd_cryptobox_keypair *kp);

/**
 * Get algorithm of pubkey
 */
enum rspamd_cryptobox_mode rspamd_pubkey_alg(struct rspamd_cryptobox_pubkey *p);

/**
 * Get cached NM for this specific pubkey
 * @param p
 * @return
 */
const guchar *rspamd_pubkey_get_nm(struct rspamd_cryptobox_pubkey *p,
								   struct rspamd_cryptobox_keypair *kp);

/**
 * Calculate and store nm value for the specified local key (performs ECDH)
 * @param p
 * @return
 */
const guchar *rspamd_pubkey_calculate_nm(struct rspamd_cryptobox_pubkey *p,
										 struct rspamd_cryptobox_keypair *kp);

/**
 * Get raw public key id for a specified keypair (rspamd_cryptobox_HASHBYTES)
 * @param kp
 * @return
 */
const guchar *rspamd_keypair_get_id(struct rspamd_cryptobox_keypair *kp);

/**
 * Returns keypair extensions if any
 * @param kp
 * @return
 */
const ucl_object_t *rspamd_keypair_get_extensions(struct rspamd_cryptobox_keypair *kp);

/**
 * Get raw public key id for a specified key (rspamd_cryptobox_HASHBYTES)
 * @param kp
 * @return
 */
const guchar *rspamd_pubkey_get_id(struct rspamd_cryptobox_pubkey *pk);

/**
 * Get raw public key from pubkey opaque structure
 * @param pk
 * @param len
 * @return
 */
const guchar *rspamd_pubkey_get_pk(struct rspamd_cryptobox_pubkey *pk,
								   guint *len);

/** Short ID characters count */
#define RSPAMD_KEYPAIR_SHORT_ID_LEN 5
/** Print pubkey */
#define RSPAMD_KEYPAIR_PUBKEY 0x1
/** Print secret key */
#define RSPAMD_KEYPAIR_PRIVKEY 0x2
/** Print key id */
#define RSPAMD_KEYPAIR_ID 0x4
/** Print short key id */
#define RSPAMD_KEYPAIR_ID_SHORT 0x8
/** Encode output with base 32 */
#define RSPAMD_KEYPAIR_BASE32 0x10
/** Human readable output */
#define RSPAMD_KEYPAIR_HUMAN 0x20
#define RSPAMD_KEYPAIR_HEX 0x40

/**
 * Print keypair encoding it if needed
 * @param key key to print
 * @param how flags that specifies printing behaviour
 * @return newly allocated string with keypair
 */
GString *rspamd_keypair_print(struct rspamd_cryptobox_keypair *kp,
							  guint how);

/**
 * Print pubkey encoding it if needed
 * @param key key to print
 * @param how flags that specifies printing behaviour
 * @return newly allocated string with keypair
 */
GString *rspamd_pubkey_print(struct rspamd_cryptobox_pubkey *pk,
							 guint how);

/** Get keypair pubkey ID */
#define RSPAMD_KEYPAIR_COMPONENT_ID 0
/** Get keypair public key */
#define RSPAMD_KEYPAIR_COMPONENT_PK 1
/** Get keypair private key */
#define RSPAMD_KEYPAIR_COMPONENT_SK 2

/**
 * Get specific component of a keypair
 * @param kp keypair
 * @param ncomp component number
 * @param len length of input
 * @return raw content of the component
 */
const guchar *rspamd_keypair_component(struct rspamd_cryptobox_keypair *kp,
									   guint ncomp, guint *len);

/**
 * Create a new keypair from ucl object
 * @param obj object to load
 * @return new structure or NULL if an object is invalid
 */
struct rspamd_cryptobox_keypair *rspamd_keypair_from_ucl(const ucl_object_t *obj);


enum rspamd_keypair_dump_flags {
	RSPAMD_KEYPAIR_DUMP_DEFAULT = 0,
	RSPAMD_KEYPAIR_DUMP_HEX = 1u << 0u,
	RSPAMD_KEYPAIR_DUMP_NO_SECRET = 1u << 1u,
	RSPAMD_KEYPAIR_DUMP_FLATTENED = 1u << 2u,
};

/**
 * Converts keypair to ucl object
 * @param kp
 * @return
 */
ucl_object_t *rspamd_keypair_to_ucl(struct rspamd_cryptobox_keypair *kp,
									enum rspamd_keypair_dump_flags flags);


/**
 * Decrypts data using keypair and a pubkey stored in in, in must start from
 * `encrypted_magic` constant
 * @param kp keypair
 * @param in raw input
 * @param inlen input length
 * @param out output (allocated internally using g_malloc)
 * @param outlen output size
 * @return TRUE if decryption is completed, out must be freed in this case
 */
gboolean rspamd_keypair_decrypt(struct rspamd_cryptobox_keypair *kp,
								const guchar *in, gsize inlen,
								guchar **out, gsize *outlen,
								GError **err);

/**
 * Encrypts data usign specific keypair.
 * This method actually generates ephemeral local keypair, use public key from
 * the remote keypair and encrypts data
 * @param kp keypair
 * @param in raw input
 * @param inlen input length
 * @param out output (allocated internally using g_malloc)
 * @param outlen output size
 * @param err pointer to error
 * @return TRUE if encryption has been completed, out must be freed in this case
 */
gboolean rspamd_keypair_encrypt(struct rspamd_cryptobox_keypair *kp,
								const guchar *in, gsize inlen,
								guchar **out, gsize *outlen,
								GError **err);

/**
 * Encrypts data usign specific pubkey (must have KEX type).
 * This method actually generates ephemeral local keypair, use public key from
 * the remote keypair and encrypts data
 * @param kp keypair
 * @param in raw input
 * @param inlen input length
 * @param out output (allocated internally using g_malloc)
 * @param outlen output size
 * @param err pointer to error
 * @return TRUE if encryption has been completed, out must be freed in this case
 */
gboolean rspamd_pubkey_encrypt(struct rspamd_cryptobox_pubkey *pk,
							   const guchar *in, gsize inlen,
							   guchar **out, gsize *outlen,
							   GError **err);

#ifdef __cplusplus
}
#endif

#endif /* SRC_LIBCRYPTOBOX_KEYPAIR_H_ */