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