Branch data Line data Source code
1 : : /**
2 : : * \file lib/fko_funcs.c
3 : : *
4 : : * \brief General utility functions for libfko
5 : : */
6 : :
7 : : /* Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
8 : : * Copyright (C) 2009-2015 fwknop developers and contributors. For a full
9 : : * list of contributors, see the file 'CREDITS'.
10 : : *
11 : : * License (GNU General Public License):
12 : : *
13 : : * This program is free software; you can redistribute it and/or
14 : : * modify it under the terms of the GNU General Public License
15 : : * as published by the Free Software Foundation; either version 2
16 : : * of the License, or (at your option) any later version.
17 : : *
18 : : * This program is distributed in the hope that it will be useful,
19 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 : : * GNU General Public License for more details.
22 : : *
23 : : * You should have received a copy of the GNU General Public License
24 : : * along with this program; if not, write to the Free Software
25 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 : : * USA
27 : : *
28 : : *****************************************************************************
29 : : */
30 : : #include "fko_common.h"
31 : : #include "fko.h"
32 : : #include "cipher_funcs.h"
33 : : #include "base64.h"
34 : : #include "digest.h"
35 : :
36 : : /* Initialize an fko context.
37 : : */
38 : : int
39 : 866162 : fko_new(fko_ctx_t *r_ctx)
40 : : {
41 : 866162 : fko_ctx_t ctx = NULL;
42 : : int res;
43 : : char *ver;
44 : :
45 : : #if HAVE_LIBFIU
46 [ + + ]: 866162 : fiu_return_on("fko_new_calloc", FKO_ERROR_MEMORY_ALLOCATION);
47 : : #endif
48 : :
49 : 866159 : ctx = calloc(1, sizeof *ctx);
50 [ + + ]: 866159 : if(ctx == NULL)
51 : : return(FKO_ERROR_MEMORY_ALLOCATION);
52 : :
53 : : /* Set default values and state.
54 : : *
55 : : * Note: We initialize the context early so that the fko_set_xxx
56 : : * functions can operate properly. If there are any problems during
57 : : * initialization, then fko_destroy() is called which will clean up
58 : : * the context.
59 : : */
60 : 866126 : ctx->initval = FKO_CTX_INITIALIZED;
61 : :
62 : : /* Set the version string.
63 : : */
64 : 866126 : ver = strdup(FKO_PROTOCOL_VERSION);
65 [ + + ]: 866126 : if(ver == NULL)
66 : : {
67 : 48 : fko_destroy(ctx);
68 : 48 : ctx = NULL;
69 : 48 : return(FKO_ERROR_MEMORY_ALLOCATION);
70 : : }
71 : 866078 : ctx->version = ver;
72 : :
73 : : /* Rand value.
74 : : */
75 : 866078 : res = fko_set_rand_value(ctx, NULL);
76 [ + + ]: 866078 : if(res != FKO_SUCCESS)
77 : : {
78 : 71 : fko_destroy(ctx);
79 : 71 : ctx = NULL;
80 : 71 : return res;
81 : : }
82 : :
83 : : /* Username.
84 : : */
85 : 866007 : res = fko_set_username(ctx, NULL);
86 [ + + ]: 866007 : if(res != FKO_SUCCESS)
87 : : {
88 : 59 : fko_destroy(ctx);
89 : 59 : ctx = NULL;
90 : 59 : return res;
91 : : }
92 : :
93 : : /* Timestamp.
94 : : */
95 : 865948 : res = fko_set_timestamp(ctx, 0);
96 [ + + ]: 865948 : if(res != FKO_SUCCESS)
97 : : {
98 : 6 : fko_destroy(ctx);
99 : 6 : ctx = NULL;
100 : 6 : return res;
101 : : }
102 : :
103 : : /* Default Digest Type.
104 : : */
105 : 865942 : res = fko_set_spa_digest_type(ctx, FKO_DEFAULT_DIGEST);
106 [ + + ]: 865942 : if(res != FKO_SUCCESS)
107 : : {
108 : 6 : fko_destroy(ctx);
109 : 6 : ctx = NULL;
110 : 6 : return res;
111 : : }
112 : :
113 : : /* Default Message Type.
114 : : */
115 : 865936 : res = fko_set_spa_message_type(ctx, FKO_DEFAULT_MSG_TYPE);
116 [ + + ]: 865936 : if(res != FKO_SUCCESS)
117 : : {
118 : 6 : fko_destroy(ctx);
119 : 6 : ctx = NULL;
120 : 6 : return res;
121 : : }
122 : :
123 : : /* Default Encryption Type.
124 : : */
125 : 865930 : res = fko_set_spa_encryption_type(ctx, FKO_DEFAULT_ENCRYPTION);
126 [ + + ]: 865930 : if(res != FKO_SUCCESS)
127 : : {
128 : 6 : fko_destroy(ctx);
129 : 6 : ctx = NULL;
130 : 6 : return res;
131 : : }
132 : :
133 : : /* Default is Rijndael in CBC mode
134 : : */
135 : 865924 : res = fko_set_spa_encryption_mode(ctx, FKO_DEFAULT_ENC_MODE);
136 [ + + ]: 865924 : if(res != FKO_SUCCESS)
137 : : {
138 : 6 : fko_destroy(ctx);
139 : 6 : ctx = NULL;
140 : 6 : return res;
141 : : }
142 : :
143 : : #if HAVE_LIBGPGME
144 : : /* Set gpg signature verify on.
145 : : */
146 : 865918 : ctx->verify_gpg_sigs = 1;
147 : :
148 : : #endif /* HAVE_LIBGPGME */
149 : :
150 : 865918 : FKO_SET_CTX_INITIALIZED(ctx);
151 : :
152 : 865918 : *r_ctx = ctx;
153 : :
154 : 865918 : return(FKO_SUCCESS);
155 : : }
156 : :
157 : : /* Initialize an fko context with external (encrypted/encoded) data.
158 : : * This is used to create a context with the purpose of decoding
159 : : * and parsing the provided data into the context data.
160 : : */
161 : : int
162 : 784854 : fko_new_with_data(fko_ctx_t *r_ctx, const char * const enc_msg,
163 : : const char * const dec_key, const int dec_key_len,
164 : : int encryption_mode, const char * const hmac_key,
165 : : const int hmac_key_len, const int hmac_type)
166 : : {
167 : 784854 : fko_ctx_t ctx = NULL;
168 : 784854 : int res = FKO_SUCCESS; /* Are we optimistic or what? */
169 : : int enc_msg_len;
170 : :
171 : : #if HAVE_LIBFIU
172 [ + + ]: 784854 : fiu_return_on("fko_new_with_data_msg",
173 : : FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING);
174 : : #endif
175 : :
176 [ + + ]: 784853 : if(enc_msg == NULL)
177 : : return(FKO_ERROR_INVALID_DATA_FUNCS_NEW_ENCMSG_MISSING);
178 : :
179 : : #if HAVE_LIBFIU
180 [ + + ]: 784847 : fiu_return_on("fko_new_with_data_keylen",
181 : : FKO_ERROR_INVALID_KEY_LEN);
182 : : #endif
183 : :
184 [ + - ]: 784846 : if(dec_key_len < 0 || hmac_key_len < 0)
185 : : return(FKO_ERROR_INVALID_KEY_LEN);
186 : :
187 : 784846 : ctx = calloc(1, sizeof *ctx);
188 [ + + ]: 784846 : if(ctx == NULL)
189 : : return(FKO_ERROR_MEMORY_ALLOCATION);
190 : :
191 : 784793 : enc_msg_len = strnlen(enc_msg, MAX_SPA_ENCODED_MSG_SIZE);
192 : :
193 [ + + ]: 784793 : if(! is_valid_encoded_msg_len(enc_msg_len))
194 : : {
195 : 9 : free(ctx);
196 : 9 : return(FKO_ERROR_INVALID_DATA_FUNCS_NEW_MSGLEN_VALIDFAIL);
197 : : }
198 : :
199 : : /* First, add the data to the context.
200 : : */
201 : 784784 : ctx->encrypted_msg = strdup(enc_msg);
202 : 784784 : ctx->encrypted_msg_len = enc_msg_len;
203 : :
204 [ - + ]: 784784 : if(ctx->encrypted_msg == NULL)
205 : : {
206 : 0 : free(ctx);
207 : 0 : return(FKO_ERROR_MEMORY_ALLOCATION);
208 : : }
209 : :
210 : : /* Default Encryption Mode (Rijndael in CBC mode)
211 : : */
212 : 784784 : ctx->initval = FKO_CTX_INITIALIZED;
213 : 784784 : res = fko_set_spa_encryption_mode(ctx, encryption_mode);
214 [ + + ]: 784784 : if(res != FKO_SUCCESS)
215 : : {
216 : 2 : fko_destroy(ctx);
217 : 2 : ctx = NULL;
218 : 2 : return res;
219 : : }
220 : :
221 : : /* HMAC digest type
222 : : */
223 : 784782 : res = fko_set_spa_hmac_type(ctx, hmac_type);
224 [ + + ]: 784782 : if(res != FKO_SUCCESS)
225 : : {
226 : 2 : fko_destroy(ctx);
227 : 2 : ctx = NULL;
228 : 2 : return res;
229 : : }
230 : :
231 : : /* Check HMAC if the access stanza had an HMAC key
232 : : */
233 [ + + ]: 784780 : if(hmac_key_len > 0 && hmac_key != NULL)
234 : 768066 : res = fko_verify_hmac(ctx, hmac_key, hmac_key_len);
235 [ + + ]: 784780 : if(res != FKO_SUCCESS)
236 : : {
237 : 2189 : fko_destroy(ctx);
238 : 2189 : ctx = NULL;
239 : 2189 : return res;
240 : : }
241 : :
242 : : /* Consider it initialized here.
243 : : */
244 : 782591 : FKO_SET_CTX_INITIALIZED(ctx);
245 : :
246 : : /* If a decryption key is provided, go ahead and decrypt and decode.
247 : : */
248 [ + + ]: 782591 : if(dec_key != NULL)
249 : : {
250 : 764171 : res = fko_decrypt_spa_data(ctx, dec_key, dec_key_len);
251 : :
252 [ + + ]: 764171 : if(res != FKO_SUCCESS)
253 : : {
254 : 719456 : fko_destroy(ctx);
255 : 719456 : ctx = NULL;
256 : 719456 : *r_ctx = NULL; /* Make sure the caller ctx is null just in case */
257 : 719456 : return(res);
258 : : }
259 : : }
260 : :
261 : : #if HAVE_LIBGPGME
262 : : /* Set gpg signature verify on.
263 : : */
264 : 63135 : ctx->verify_gpg_sigs = 1;
265 : :
266 : : #endif /* HAVE_LIBGPGME */
267 : :
268 : 63135 : *r_ctx = ctx;
269 : :
270 : 63135 : return(res);
271 : : }
272 : :
273 : : /* Destroy a context and free its resources
274 : : */
275 : : int
276 : 2369807 : fko_destroy(fko_ctx_t ctx)
277 : : {
278 : 2369807 : int zero_free_rv = FKO_SUCCESS;
279 : :
280 : : #if HAVE_LIBGPGME
281 : : fko_gpg_sig_t gsig, tgsig;
282 : : #endif
283 : :
284 [ + + ][ + - ]: 2369807 : if(!CTX_INITIALIZED(ctx))
285 : : return(zero_free_rv);
286 : :
287 [ + + ]: 1650910 : if(ctx->rand_val != NULL)
288 : 1186530 : free(ctx->rand_val);
289 : :
290 [ + + ]: 1650910 : if(ctx->username != NULL)
291 : 1180575 : free(ctx->username);
292 : :
293 [ + + ]: 1650910 : if(ctx->version != NULL)
294 : 1080050 : free(ctx->version);
295 : :
296 [ + + ]: 1650910 : if(ctx->message != NULL)
297 : 496397 : free(ctx->message);
298 : :
299 [ + + ]: 1650910 : if(ctx->nat_access != NULL)
300 : 193478 : free(ctx->nat_access);
301 : :
302 [ + + ]: 1650910 : if(ctx->server_auth != NULL)
303 : 63194 : free(ctx->server_auth);
304 : :
305 [ + + ]: 1650910 : if(ctx->digest != NULL)
306 [ - + ]: 1132196 : if(zero_free(ctx->digest, ctx->digest_len) != FKO_SUCCESS)
307 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
308 : :
309 [ + + ]: 1650910 : if(ctx->raw_digest != NULL)
310 [ + + ]: 15951 : if(zero_free(ctx->raw_digest, ctx->raw_digest_len) != FKO_SUCCESS)
311 : 2 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
312 : :
313 [ + + ]: 1650910 : if(ctx->encoded_msg != NULL)
314 [ + + ]: 1400103 : if(zero_free(ctx->encoded_msg, ctx->encoded_msg_len) != FKO_SUCCESS)
315 : 51296 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
316 : :
317 [ + + ]: 1650910 : if(ctx->encrypted_msg != NULL)
318 [ + + ]: 1586144 : if(zero_free(ctx->encrypted_msg, ctx->encrypted_msg_len) != FKO_SUCCESS)
319 : 4 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
320 : :
321 [ + + ]: 1650910 : if(ctx->msg_hmac != NULL)
322 [ + + ]: 1520190 : if(zero_free(ctx->msg_hmac, ctx->msg_hmac_len) != FKO_SUCCESS)
323 : 2 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
324 : :
325 : : #if HAVE_LIBGPGME
326 [ + + ]: 1650910 : if(ctx->gpg_exe != NULL)
327 : 2 : free(ctx->gpg_exe);
328 : :
329 [ + + ]: 1650910 : if(ctx->gpg_home_dir != NULL)
330 : 154 : free(ctx->gpg_home_dir);
331 : :
332 [ + + ]: 1650910 : if(ctx->gpg_recipient != NULL)
333 : 78 : free(ctx->gpg_recipient);
334 : :
335 [ + + ]: 1650910 : if(ctx->gpg_signer != NULL)
336 : 77 : free(ctx->gpg_signer);
337 : :
338 [ + + ]: 1650910 : if(ctx->recipient_key != NULL)
339 : 78 : gpgme_key_unref(ctx->recipient_key);
340 : :
341 [ + + ]: 1650910 : if(ctx->signer_key != NULL)
342 : 77 : gpgme_key_unref(ctx->signer_key);
343 : :
344 [ + + ]: 1650910 : if(ctx->gpg_ctx != NULL)
345 : 140 : gpgme_release(ctx->gpg_ctx);
346 : :
347 : 1650910 : gsig = ctx->gpg_sigs;
348 [ + + ]: 1650970 : while(gsig != NULL)
349 : : {
350 [ + - ]: 60 : if(gsig->fpr != NULL)
351 : 60 : free(gsig->fpr);
352 : :
353 : 60 : tgsig = gsig;
354 : 60 : gsig = gsig->next;
355 : :
356 : 60 : free(tgsig);
357 : : }
358 : :
359 : : #endif /* HAVE_LIBGPGME */
360 : :
361 : : memset(ctx, 0x0, sizeof(*ctx));
362 : :
363 : 1650910 : free(ctx);
364 : :
365 : 1650910 : return(zero_free_rv);
366 : : }
367 : :
368 : : /* Generate Rijndael and HMAC keys from /dev/random and base64
369 : : * encode them
370 : : */
371 : : int
372 : 217 : fko_key_gen(char * const key_base64, const int key_len,
373 : : char * const hmac_key_base64, const int hmac_key_len,
374 : : const int hmac_type)
375 : : {
376 : : unsigned char key[RIJNDAEL_MAX_KEYSIZE];
377 : : unsigned char hmac_key[SHA512_BLOCK_LEN];
378 : 217 : int klen = key_len;
379 : 217 : int hmac_klen = hmac_key_len;
380 : 217 : int b64_len = 0;
381 : :
382 [ + - ]: 217 : if(key_len == FKO_DEFAULT_KEY_LEN)
383 : 217 : klen = RIJNDAEL_MAX_KEYSIZE;
384 : :
385 [ + - ]: 217 : if(hmac_key_len == FKO_DEFAULT_KEY_LEN)
386 : : {
387 [ + + ]: 217 : if(hmac_type == FKO_DEFAULT_HMAC_MODE
388 : : || hmac_type == FKO_HMAC_SHA256)
389 : : hmac_klen = SHA256_BLOCK_LEN;
390 [ + + ]: 4 : else if(hmac_type == FKO_HMAC_MD5)
391 : : hmac_klen = MD5_DIGEST_LEN;
392 [ + + ]: 3 : else if(hmac_type == FKO_HMAC_SHA1)
393 : : hmac_klen = SHA1_DIGEST_LEN;
394 [ + + ]: 2 : else if(hmac_type == FKO_HMAC_SHA384)
395 : : hmac_klen = SHA384_BLOCK_LEN;
396 [ + - ]: 1 : else if(hmac_type == FKO_HMAC_SHA512)
397 : 1 : hmac_klen = SHA512_BLOCK_LEN;
398 : : }
399 : :
400 [ + - ]: 217 : if((klen < 1) || (klen > RIJNDAEL_MAX_KEYSIZE))
401 : : return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEYLEN_VALIDFAIL);
402 : :
403 [ + - ]: 217 : if((hmac_klen < 1) || (hmac_klen > SHA512_BLOCK_LEN))
404 : : return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMACLEN_VALIDFAIL);
405 : :
406 : 217 : get_random_data(key, klen);
407 : 217 : get_random_data(hmac_key, hmac_klen);
408 : :
409 : 217 : b64_len = b64_encode(key, key_base64, klen);
410 [ + - ]: 217 : if(b64_len < klen)
411 : : return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_KEY_ENCODEFAIL);
412 : :
413 : 217 : b64_len = b64_encode(hmac_key, hmac_key_base64, hmac_klen);
414 [ + - ]: 217 : if(b64_len < hmac_klen)
415 : : return(FKO_ERROR_INVALID_DATA_FUNCS_GEN_HMAC_ENCODEFAIL);
416 : :
417 : 217 : return(FKO_SUCCESS);
418 : : }
419 : :
420 : : /* Provide an FKO wrapper around base64 encode/decode functions
421 : : */
422 : : int
423 : 8 : fko_base64_encode(unsigned char * const in, char * const out, int in_len)
424 : : {
425 : 8 : return b64_encode(in, out, in_len);
426 : : }
427 : :
428 : : int
429 : 848466 : fko_base64_decode(const char * const in, unsigned char *out)
430 : : {
431 : 848466 : return b64_decode(in, out);
432 : : }
433 : :
434 : : /* Return the fko version
435 : : */
436 : : int
437 : 5460 : fko_get_version(fko_ctx_t ctx, char **version)
438 : : {
439 : :
440 : : #if HAVE_LIBFIU
441 [ + + ]: 5460 : fiu_return_on("fko_get_version_init", FKO_ERROR_CTX_NOT_INITIALIZED);
442 : : #endif
443 : :
444 : : /* Must be initialized
445 : : */
446 [ + + ][ + - ]: 5458 : if(!CTX_INITIALIZED(ctx))
447 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
448 : :
449 [ + + ]: 5306 : if(version == NULL)
450 : : return(FKO_ERROR_INVALID_DATA);
451 : :
452 : : #if HAVE_LIBFIU
453 [ + + ]: 5238 : fiu_return_on("fko_get_version_val", FKO_ERROR_INVALID_DATA);
454 : : #endif
455 : :
456 : 5236 : *version = ctx->version;
457 : :
458 : 5236 : return(FKO_SUCCESS);
459 : : }
460 : :
461 : : /* Final update and encoding of data in the context.
462 : : * This does require all requisite fields be properly
463 : : * set.
464 : : */
465 : : int
466 : 881465 : fko_spa_data_final(fko_ctx_t ctx,
467 : : const char * const enc_key, const int enc_key_len,
468 : : const char * const hmac_key, const int hmac_key_len)
469 : : {
470 : : char *tbuf;
471 : 881465 : int res = 0, data_with_hmac_len = 0;
472 : :
473 : : /* Must be initialized
474 : : */
475 [ + + ][ + - ]: 881465 : if(!CTX_INITIALIZED(ctx))
476 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
477 : :
478 [ + + ]: 874255 : if(enc_key_len < 0)
479 : : return(FKO_ERROR_INVALID_KEY_LEN);
480 : :
481 : 866515 : res = fko_encrypt_spa_data(ctx, enc_key, enc_key_len);
482 : :
483 : : /* Now calculate hmac if so configured
484 : : */
485 [ + + ][ + + ]: 866515 : if (res == FKO_SUCCESS && ctx->hmac_type != FKO_HMAC_UNKNOWN)
486 : : {
487 [ + + ]: 755635 : if(hmac_key_len < 0)
488 : : return(FKO_ERROR_INVALID_KEY_LEN);
489 : :
490 [ + + ]: 755025 : if(hmac_key == NULL)
491 : : return(FKO_ERROR_INVALID_KEY_LEN);
492 : :
493 : 754865 : res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
494 : :
495 [ + + ]: 754865 : if (res == FKO_SUCCESS)
496 : : {
497 : : /* Now that we have the hmac, append it to the
498 : : * encrypted data (which has already been base64-encoded
499 : : * and the trailing '=' chars stripped off).
500 : : */
501 : : data_with_hmac_len
502 : 754811 : = ctx->encrypted_msg_len+1+ctx->msg_hmac_len+1;
503 : :
504 : 754811 : tbuf = realloc(ctx->encrypted_msg, data_with_hmac_len);
505 [ + - ]: 754811 : if (tbuf == NULL)
506 : : return(FKO_ERROR_MEMORY_ALLOCATION);
507 : :
508 : 754811 : strlcat(tbuf, ctx->msg_hmac, data_with_hmac_len);
509 : :
510 : 754811 : ctx->encrypted_msg = tbuf;
511 : 754811 : ctx->encrypted_msg_len = data_with_hmac_len;
512 : : }
513 : : }
514 : :
515 : 865745 : return res;
516 : : }
517 : :
518 : : /* Return the fko SPA encrypted data.
519 : : */
520 : : int
521 : 759934 : fko_get_spa_data(fko_ctx_t ctx, char **spa_data)
522 : : {
523 : :
524 : : #if HAVE_LIBFIU
525 [ + - ]: 759934 : fiu_return_on("fko_get_spa_data_init", FKO_ERROR_CTX_NOT_INITIALIZED);
526 : : #endif
527 : :
528 : : /* Must be initialized
529 : : */
530 [ + + ][ + - ]: 759934 : if(!CTX_INITIALIZED(ctx))
531 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
532 : :
533 [ + + ]: 759772 : if(spa_data == NULL)
534 : : return(FKO_ERROR_INVALID_DATA);
535 : :
536 : : #if HAVE_LIBFIU
537 [ + - ]: 759704 : fiu_return_on("fko_get_spa_data_val", FKO_ERROR_INVALID_DATA);
538 : : #endif
539 : :
540 : : /* We expect to have encrypted data to process. If not, we bail.
541 : : */
542 [ + + + - ]: 1519340 : if(ctx->encrypted_msg == NULL || ! is_valid_encoded_msg_len(
543 : 759636 : strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE)))
544 : : return(FKO_ERROR_MISSING_ENCODED_DATA);
545 : :
546 : : #if HAVE_LIBFIU
547 [ + - ]: 759636 : fiu_return_on("fko_get_spa_data_encoded", FKO_ERROR_MISSING_ENCODED_DATA);
548 : : #endif
549 : :
550 : 759636 : *spa_data = ctx->encrypted_msg;
551 : :
552 : : /* Notice we omit the first 10 bytes if Rijndael encryption is
553 : : * used (to eliminate the consistent 'Salted__' string), and
554 : : * in GnuPG mode we eliminate the consistent 'hQ' base64 encoded
555 : : * prefix
556 : : */
557 [ + + ]: 759636 : if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL)
558 : 759416 : *spa_data += B64_RIJNDAEL_SALT_STR_LEN;
559 [ + + ]: 220 : else if(ctx->encryption_type == FKO_ENCRYPTION_GPG)
560 : 218 : *spa_data += B64_GPG_PREFIX_STR_LEN;
561 : :
562 : : return(FKO_SUCCESS);
563 : : }
564 : :
565 : : /* Set the fko SPA encrypted data.
566 : : */
567 : : int
568 : 4574 : fko_set_spa_data(fko_ctx_t ctx, const char * const enc_msg)
569 : : {
570 : : int enc_msg_len;
571 : :
572 : : /* Must be initialized
573 : : */
574 [ + + ][ + - ]: 4574 : if(!CTX_INITIALIZED(ctx))
575 : : return FKO_ERROR_CTX_NOT_INITIALIZED;
576 : :
577 [ + + ]: 4554 : if(enc_msg == NULL)
578 : : return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL);
579 : :
580 : 4506 : enc_msg_len = strnlen(enc_msg, MAX_SPA_ENCODED_MSG_SIZE);
581 : :
582 [ + + ]: 4506 : if(! is_valid_encoded_msg_len(enc_msg_len))
583 : : return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL);
584 : :
585 [ + + ]: 4406 : if(ctx->encrypted_msg != NULL)
586 : 2 : free(ctx->encrypted_msg);
587 : :
588 : : /* First, add the data to the context.
589 : : */
590 : 4406 : ctx->encrypted_msg = strdup(enc_msg);
591 : 4406 : ctx->encrypted_msg_len = enc_msg_len;
592 : :
593 [ + - ]: 4406 : if(ctx->encrypted_msg == NULL)
594 : : return(FKO_ERROR_MEMORY_ALLOCATION);
595 : :
596 : 4406 : return(FKO_SUCCESS);
597 : : }
598 : :
599 : : #if AFL_FUZZING
600 : : /* provide a way to set the encrypted data directly without base64 encoding.
601 : : * This allows direct AFL fuzzing against decryption routines.
602 : : */
603 : : int
604 : : fko_afl_set_spa_data(fko_ctx_t ctx, const char * const enc_msg, const int enc_msg_len)
605 : : {
606 : : /* Must be initialized
607 : : */
608 : : if(!CTX_INITIALIZED(ctx))
609 : : return FKO_ERROR_CTX_NOT_INITIALIZED;
610 : :
611 : : if(enc_msg == NULL)
612 : : return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL);
613 : :
614 : : if(! is_valid_encoded_msg_len(enc_msg_len))
615 : : return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL);
616 : :
617 : : if(ctx->encrypted_msg != NULL)
618 : : free(ctx->encrypted_msg);
619 : :
620 : : /* Copy the raw encrypted data into the context
621 : : */
622 : : ctx->encrypted_msg = calloc(1, enc_msg_len);
623 : : if(ctx->encrypted_msg == NULL)
624 : : return(FKO_ERROR_MEMORY_ALLOCATION);
625 : :
626 : : memcpy(ctx->encrypted_msg, enc_msg, enc_msg_len);
627 : :
628 : : ctx->encrypted_msg_len = enc_msg_len;
629 : :
630 : : return(FKO_SUCCESS);
631 : : }
632 : : #endif
633 : :
634 : : /***EOF***/
|