Branch data Line data Source code
1 : : /**
2 : : * \file lib/fko_encryption.c
3 : : *
4 : : * \brief Set/Get the spa encryption type.
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 : : #if HAVE_LIBGPGME
37 : : #include "gpgme_funcs.h"
38 : : #if HAVE_SYS_STAT_H
39 : : #include <sys/stat.h>
40 : : #endif
41 : : #endif
42 : :
43 : : /* Prep and encrypt using Rijndael
44 : : */
45 : : static int
46 : 802639 : _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key, const int enc_key_len)
47 : : {
48 : : char *plaintext;
49 : : char *b64ciphertext;
50 : : unsigned char *ciphertext;
51 : : int cipher_len;
52 : : int pt_len;
53 : 802639 : int zero_free_rv = FKO_SUCCESS;
54 : :
55 [ + + ]: 802639 : if(enc_key_len < 0 || enc_key_len > RIJNDAEL_MAX_KEYSIZE)
56 : : return(FKO_ERROR_INVALID_KEY_LEN);
57 : :
58 [ + - ]: 800710 : if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
59 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_MSGLEN_VALIDFAIL);
60 : :
61 [ + - ]: 800710 : switch(ctx->digest_len)
62 : : {
63 : : case MD5_B64_LEN:
64 : : break;
65 : : case SHA1_B64_LEN:
66 : : break;
67 : : case SHA256_B64_LEN:
68 : : break;
69 : : case SHA384_B64_LEN:
70 : : break;
71 : : case SHA512_B64_LEN:
72 : : break;
73 : : default:
74 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_DIGESTLEN_VALIDFAIL);
75 : : }
76 : :
77 : 800710 : pt_len = ctx->encoded_msg_len + ctx->digest_len + RIJNDAEL_BLOCKSIZE + 2;
78 : :
79 : : /* Make a bucket big enough to hold the enc msg + digest (plaintext)
80 : : * and populate it appropriately.
81 : : */
82 : 800710 : plaintext = calloc(1, pt_len);
83 : :
84 [ + + ]: 800710 : if(plaintext == NULL)
85 : : return(FKO_ERROR_MEMORY_ALLOCATION);
86 : :
87 : 1601408 : pt_len = snprintf(plaintext, pt_len, "%s:%s", ctx->encoded_msg, ctx->digest);
88 : :
89 [ + + ]: 800704 : if(! is_valid_pt_msg_len(pt_len))
90 : : {
91 [ - + ]: 1 : if(zero_free(plaintext, pt_len) == FKO_SUCCESS)
92 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_PTLEN_VALIDFAIL);
93 : : else
94 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
95 : : }
96 : :
97 : : /* Make a bucket for the encrypted version and populate it.
98 : : */
99 : 800703 : ciphertext = calloc(1, pt_len + 32); /* Plus padding for salt and Block */
100 [ + + ]: 800703 : if(ciphertext == NULL)
101 : : {
102 [ - + ]: 1 : if(zero_free(plaintext, pt_len) == FKO_SUCCESS)
103 : : return(FKO_ERROR_MEMORY_ALLOCATION);
104 : : else
105 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
106 : : }
107 : :
108 : 800702 : cipher_len = rij_encrypt(
109 : : (unsigned char*)plaintext, pt_len,
110 : : (char*)enc_key, enc_key_len,
111 : : ciphertext, ctx->encryption_mode
112 : : );
113 : :
114 : : /* Now make a bucket for the base64-encoded version and populate it.
115 : : */
116 : 800702 : b64ciphertext = calloc(1, ((cipher_len / 3) * 4) + 8);
117 [ + + ]: 800702 : if(b64ciphertext == NULL)
118 : : {
119 [ + - ]: 3 : if(zero_free((char *) ciphertext, pt_len+32) == FKO_SUCCESS
120 [ - + ]: 3 : && zero_free(plaintext, pt_len) == FKO_SUCCESS)
121 : : return(FKO_ERROR_MEMORY_ALLOCATION);
122 : : else
123 : : return(FKO_ERROR_ZERO_OUT_DATA);
124 : : }
125 : :
126 : 800699 : b64_encode(ciphertext, b64ciphertext, cipher_len);
127 : 800699 : strip_b64_eq(b64ciphertext);
128 : :
129 [ + + ]: 800699 : if(ctx->encrypted_msg != NULL)
130 : 3819 : zero_free_rv = zero_free(ctx->encrypted_msg,
131 : 3819 : strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE));
132 : :
133 : 800699 : ctx->encrypted_msg = strdup(b64ciphertext);
134 : :
135 : : /* Clean-up
136 : : */
137 [ + + ]: 800699 : if(zero_free(plaintext, pt_len) != FKO_SUCCESS)
138 : 2 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
139 : :
140 [ + + ]: 800699 : if(zero_free((char *) ciphertext, pt_len+32) != FKO_SUCCESS)
141 : 6578 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
142 : :
143 [ + + ]: 800699 : if(zero_free(b64ciphertext, strnlen(b64ciphertext,
144 : : MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
145 : 2 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
146 : :
147 [ + - ]: 800699 : if(ctx->encrypted_msg == NULL)
148 : : return(FKO_ERROR_MEMORY_ALLOCATION);
149 : :
150 : 800699 : ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE);
151 : :
152 [ + + ]: 800699 : if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
153 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_RESULT_MSGLEN_VALIDFAIL);
154 : :
155 : 757267 : return(zero_free_rv);
156 : : }
157 : :
158 : : /* Decode, decrypt, and parse SPA data into the context.
159 : : */
160 : : static int
161 : 551403 : _rijndael_decrypt(fko_ctx_t ctx,
162 : : const char *dec_key, const int key_len, int encryption_mode)
163 : : {
164 : : unsigned char *ndx;
165 : : unsigned char *cipher;
166 : 551403 : int cipher_len=0, pt_len, i, err = 0, res = FKO_SUCCESS;
167 : 551403 : int zero_free_rv = FKO_SUCCESS;
168 : :
169 [ + + ]: 551403 : if(key_len < 0 || key_len > RIJNDAEL_MAX_KEYSIZE)
170 : : return(FKO_ERROR_INVALID_KEY_LEN);
171 : :
172 : : /* Now see if we need to add the "Salted__" string to the front of the
173 : : * encrypted data.
174 : : */
175 [ + + ]: 551402 : if(! ctx->added_salted_str)
176 : : {
177 : 4787 : res = add_salted_str(ctx);
178 [ + - ]: 4787 : if(res != FKO_SUCCESS)
179 : : return res;
180 : : }
181 : :
182 : : /* Create a bucket for the (base64) decoded encrypted data and get the
183 : : * raw cipher data.
184 : : */
185 : 551402 : cipher = calloc(1, ctx->encrypted_msg_len);
186 [ + - ]: 551402 : if(cipher == NULL)
187 : : return(FKO_ERROR_MEMORY_ALLOCATION);
188 : :
189 : : #if AFL_FUZZING
190 : : cipher_len = ctx->encrypted_msg_len;
191 : : memcpy(cipher, ctx->encrypted_msg, ctx->encrypted_msg_len);
192 : : #else
193 [ - + ]: 551402 : if((cipher_len = b64_decode(ctx->encrypted_msg, cipher)) < 0)
194 : : {
195 [ # # ]: 0 : if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS)
196 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_DECODEFAIL);
197 : : else
198 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
199 : : }
200 : : #endif
201 : :
202 : : /* Since we're using AES, make sure the incoming data is a multiple of
203 : : * the blocksize
204 : : */
205 [ + + ]: 551402 : if((cipher_len % RIJNDAEL_BLOCKSIZE) != 0)
206 : : {
207 [ - + ]: 19 : if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS)
208 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_CIPHERLEN_VALIDFAIL);
209 : : else
210 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
211 : : }
212 : :
213 [ + + ]: 551383 : if(ctx->encoded_msg != NULL)
214 : 4 : zero_free_rv = zero_free(ctx->encoded_msg,
215 : 4 : strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE));
216 : :
217 : : /* Create a bucket for the plaintext data and decrypt the message
218 : : * data into it.
219 : : */
220 : 551383 : ctx->encoded_msg = calloc(1, cipher_len);
221 [ - + ]: 551383 : if(ctx->encoded_msg == NULL)
222 : : {
223 [ # # ]: 0 : if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS)
224 : : return(FKO_ERROR_MEMORY_ALLOCATION);
225 : : else
226 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
227 : : }
228 : :
229 : 551383 : pt_len = rij_decrypt(cipher, cipher_len, dec_key, key_len,
230 : : (unsigned char*)ctx->encoded_msg, encryption_mode);
231 : :
232 : : /* Done with cipher...
233 : : */
234 [ - + ]: 551383 : if(zero_free((char *)cipher, ctx->encrypted_msg_len) != FKO_SUCCESS)
235 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
236 : :
237 : : /* The length of the decrypted data should be within 32 bytes of the
238 : : * length of the encrypted version.
239 : : */
240 [ + - ][ + - ]: 551383 : if(pt_len < (cipher_len - 32) || pt_len <= 0)
241 : : return(FKO_ERROR_DECRYPTION_SIZE);
242 : :
243 [ + - ]: 551383 : if(ctx->encoded_msg == NULL)
244 : : return(FKO_ERROR_MISSING_ENCODED_DATA);
245 : :
246 [ + - ]: 551383 : if(! is_valid_encoded_msg_len(pt_len))
247 : : return(FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL);
248 : :
249 [ + - ]: 551383 : if(zero_free_rv != FKO_SUCCESS)
250 : : return(zero_free_rv);
251 : :
252 : 551383 : ctx->encoded_msg_len = pt_len;
253 : :
254 : : /* At this point we can check the data to see if we have a good
255 : : * decryption by ensuring the first field (16-digit random decimal
256 : : * value) is valid and is followed by a colon. Additional checks
257 : : * are made in fko_decode_spa_data().
258 : : */
259 : 551383 : ndx = (unsigned char *)ctx->encoded_msg;
260 [ + + ]: 9373511 : for(i=0; i<FKO_RAND_VAL_SIZE; i++)
261 [ + + ]: 8822128 : if(!isdigit(*(ndx++)))
262 : 761416 : err++;
263 : :
264 [ + + ][ + + ]: 551383 : if(err > 0 || *ndx != ':')
265 : : return(FKO_ERROR_DECRYPTION_FAILURE);
266 : :
267 : : /* Call fko_decode and return the results.
268 : : */
269 : 438905 : return(fko_decode_spa_data(ctx));
270 : : }
271 : :
272 : :
273 : : #if HAVE_LIBGPGME
274 : :
275 : : /* Prep and encrypt using gpgme
276 : : */
277 : : static int
278 : 85 : gpg_encrypt(fko_ctx_t ctx, const char *enc_key)
279 : : {
280 : : int res;
281 : : char *plain;
282 : 85 : int pt_len, zero_free_rv = FKO_SUCCESS;
283 : : char *b64cipher;
284 : 85 : unsigned char *cipher = NULL;
285 : : size_t cipher_len;
286 : 85 : char *empty_key = "";
287 : :
288 [ + - ]: 85 : if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
289 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MESSAGE_VALIDFAIL);
290 : :
291 [ + - ]: 85 : switch(ctx->digest_len)
292 : : {
293 : : case MD5_B64_LEN:
294 : : break;
295 : : case SHA1_B64_LEN:
296 : : break;
297 : : case SHA256_B64_LEN:
298 : : break;
299 : : case SHA384_B64_LEN:
300 : : break;
301 : : case SHA512_B64_LEN:
302 : : break;
303 : : default:
304 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_DIGEST_VALIDFAIL);
305 : : }
306 : :
307 : : /* First make sure we have a recipient key set.
308 : : */
309 [ + + ]: 85 : if(ctx->gpg_recipient == NULL)
310 : : return(FKO_ERROR_MISSING_GPG_KEY_DATA);
311 : :
312 : 77 : pt_len = ctx->encoded_msg_len + ctx->digest_len + 2;
313 : :
314 : : /* Make a bucket big enough to hold the enc msg + digest (plaintext)
315 : : * and populate it appropriately.
316 : : */
317 : 77 : plain = calloc(1, ctx->encoded_msg_len + ctx->digest_len + 2);
318 [ + - ]: 77 : if(plain == NULL)
319 : : return(FKO_ERROR_MEMORY_ALLOCATION);
320 : :
321 : 154 : pt_len = snprintf(plain, pt_len+1, "%s:%s", ctx->encoded_msg, ctx->digest);
322 : :
323 [ - + ]: 77 : if(! is_valid_pt_msg_len(pt_len))
324 : : {
325 [ # # ]: 0 : if(zero_free(plain, pt_len) == FKO_SUCCESS)
326 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_MSGLEN_VALIDFAIL);
327 : : else
328 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
329 : : }
330 : :
331 [ + - ]: 77 : if (enc_key != NULL)
332 : : {
333 : 77 : res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len,
334 : : enc_key, &cipher, &cipher_len
335 : : );
336 : : }
337 : : else
338 : : {
339 : 0 : res = gpgme_encrypt(ctx, (unsigned char*)plain, pt_len,
340 : : empty_key, &cipher, &cipher_len
341 : : );
342 : : }
343 : :
344 : : /* --DSS XXX: Better parsing of what went wrong would be nice :)
345 : : */
346 [ - + ]: 77 : if(res != FKO_SUCCESS)
347 : : {
348 : 0 : zero_free_rv = zero_free(plain, pt_len);
349 : :
350 [ # # ]: 0 : if(cipher != NULL)
351 [ # # ]: 0 : if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS)
352 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
353 : :
354 [ # # ]: 0 : if(zero_free_rv == FKO_SUCCESS)
355 : : return(res);
356 : : else
357 : 0 : return(zero_free_rv);
358 : : }
359 : :
360 : : /* Now make a bucket for the base64-encoded version and populate it.
361 : : */
362 : 77 : b64cipher = calloc(1, ((cipher_len / 3) * 4) + 8);
363 [ - + ]: 77 : if(b64cipher == NULL)
364 : : {
365 [ # # ]: 0 : if(zero_free(plain, pt_len) != FKO_SUCCESS)
366 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
367 : :
368 [ # # ]: 0 : if(cipher != NULL)
369 [ # # ]: 0 : if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS)
370 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
371 : :
372 [ # # ]: 0 : if(zero_free_rv == FKO_SUCCESS)
373 : : return(FKO_ERROR_MEMORY_ALLOCATION);
374 : : else
375 : 0 : return(zero_free_rv);
376 : : }
377 : :
378 : 77 : b64_encode(cipher, b64cipher, cipher_len);
379 : 77 : strip_b64_eq(b64cipher);
380 : :
381 [ - + ]: 77 : if(ctx->encrypted_msg != NULL)
382 : 0 : zero_free_rv = zero_free(ctx->encrypted_msg,
383 : 0 : strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE));
384 : :
385 : 77 : ctx->encrypted_msg = strdup(b64cipher);
386 : :
387 : : /* Clean-up
388 : : */
389 [ - + ]: 77 : if(zero_free(plain, pt_len) != FKO_SUCCESS)
390 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
391 : :
392 [ - + ]: 77 : if(zero_free((char *) cipher, cipher_len) != FKO_SUCCESS)
393 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
394 : :
395 [ - + ]: 77 : if(zero_free(b64cipher, strnlen(b64cipher,
396 : : MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
397 : 0 : zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
398 : :
399 [ + - ]: 77 : if(ctx->encrypted_msg == NULL)
400 : : return(FKO_ERROR_MEMORY_ALLOCATION);
401 : :
402 : 77 : ctx->encrypted_msg_len = strnlen(ctx->encrypted_msg, MAX_SPA_ENCODED_MSG_SIZE);
403 : :
404 [ + + ]: 77 : if(! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
405 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_RESULT_MSGLEN_VALIDFAIL);
406 : :
407 : 76 : return(zero_free_rv);
408 : : }
409 : :
410 : : /* Prep and decrypt using gpgme
411 : : */
412 : : static int
413 : 75 : gpg_decrypt(fko_ctx_t ctx, const char *dec_key)
414 : : {
415 : : unsigned char *cipher;
416 : : size_t cipher_len;
417 : : int res, pt_len, b64_decode_len;
418 : :
419 : : /* Now see if we need to add the "hQ" string to the front of the
420 : : * base64-encoded-GPG-encrypted data.
421 : : */
422 [ + + ]: 75 : if(! ctx->added_gpg_prefix)
423 : 52 : add_gpg_prefix(ctx);
424 : :
425 : : /* Create a bucket for the (base64) decoded encrypted data and get the
426 : : * raw cipher data.
427 : : */
428 : 75 : cipher = calloc(1, ctx->encrypted_msg_len);
429 [ + - ]: 75 : if(cipher == NULL)
430 : : return(FKO_ERROR_MEMORY_ALLOCATION);
431 : :
432 [ - + ]: 75 : if((b64_decode_len = b64_decode(ctx->encrypted_msg, cipher)) < 0)
433 : : {
434 [ # # ]: 0 : if(zero_free((char *) cipher, ctx->encrypted_msg_len) == FKO_SUCCESS)
435 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_GPG_CIPHER_DECODEFAIL);
436 : : else
437 : 0 : return(FKO_ERROR_ZERO_OUT_DATA);
438 : :
439 : : }
440 : :
441 : 75 : cipher_len = b64_decode_len;
442 : :
443 : : /* Create a bucket for the plaintext data and decrypt the message
444 : : * data into it.
445 : : */
446 : : /* --DSS Actually, the needed memory will be malloced in the gpgme_decrypt
447 : : // function. Just leaving this here for reference (for now).
448 : : //ctx->encoded_msg = malloc(cipher_len);
449 : : //if(ctx->encoded_msg == NULL)
450 : : // return(FKO_ERROR_MEMORY_ALLOCATION);
451 : : */
452 : :
453 : 75 : res = gpgme_decrypt(ctx, cipher, cipher_len,
454 : 75 : dec_key, (unsigned char**)&ctx->encoded_msg, &cipher_len
455 : : );
456 : :
457 : : /* Done with cipher...
458 : : */
459 [ + - ]: 75 : if(zero_free((char *) cipher, ctx->encrypted_msg_len) != FKO_SUCCESS)
460 : : return(FKO_ERROR_ZERO_OUT_DATA);
461 : : else
462 [ + + ]: 75 : if(res != FKO_SUCCESS) /* bail if there was some other problem */
463 : : return(res);
464 : :
465 : 61 : pt_len = strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE);
466 : :
467 [ + - ]: 61 : if(ctx->encoded_msg == NULL)
468 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MESSAGE_MISSING);
469 : :
470 [ + - ]: 61 : if(! is_valid_encoded_msg_len(pt_len))
471 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_DECRYPTED_MSGLEN_VALIDFAIL);
472 : :
473 : 61 : ctx->encoded_msg_len = pt_len;
474 : :
475 : : /* Call fko_decode and return the results.
476 : : */
477 : 61 : return(fko_decode_spa_data(ctx));
478 : : }
479 : :
480 : : #endif /* HAVE_LIBGPGME */
481 : :
482 : : /* Set the SPA encryption type.
483 : : */
484 : : int
485 : 871007 : fko_set_spa_encryption_type(fko_ctx_t ctx, const short encrypt_type)
486 : : {
487 : : #if HAVE_LIBFIU
488 [ + + ]: 871007 : fiu_return_on("fko_set_spa_encryption_type_init",
489 : : FKO_ERROR_CTX_NOT_INITIALIZED);
490 : : #endif
491 : : /* Must be initialized
492 : : */
493 [ + + ][ + - ]: 871004 : if(!CTX_INITIALIZED(ctx))
494 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
495 : :
496 : : #if HAVE_LIBFIU
497 [ + + ]: 870182 : fiu_return_on("fko_set_spa_encryption_type_val",
498 : : FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL);
499 : : #endif
500 [ + + ]: 870179 : if(encrypt_type < 0 || encrypt_type >= FKO_LAST_ENCRYPTION_TYPE)
501 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_VALIDFAIL);
502 : :
503 : 866138 : ctx->encryption_type = encrypt_type;
504 : :
505 : 866138 : ctx->state |= FKO_ENCRYPT_TYPE_MODIFIED;
506 : :
507 : 866138 : return(FKO_SUCCESS);
508 : : }
509 : :
510 : : /* Return the SPA encryption type.
511 : : */
512 : : int
513 : 5284 : fko_get_spa_encryption_type(fko_ctx_t ctx, short *enc_type)
514 : : {
515 : : /* Must be initialized
516 : : */
517 [ + + ][ + - ]: 5284 : if(!CTX_INITIALIZED(ctx))
518 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
519 : :
520 : 4874 : *enc_type = ctx->encryption_type;
521 : :
522 : 4874 : return(FKO_SUCCESS);
523 : : }
524 : :
525 : : /* Set the SPA encryption mode.
526 : : */
527 : : int
528 : 1660772 : fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode)
529 : : {
530 : : #if HAVE_LIBFIU
531 [ + + ]: 1660772 : fiu_return_on("fko_set_spa_encryption_mode_init",
532 : : FKO_ERROR_CTX_NOT_INITIALIZED);
533 : : #endif
534 : : /* Must be initialized
535 : : */
536 [ + + ][ + - ]: 1660768 : if(!CTX_INITIALIZED(ctx))
537 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
538 : :
539 : : #if HAVE_LIBFIU
540 [ + + ]: 1659914 : fiu_return_on("fko_set_spa_encryption_mode_val",
541 : : FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL);
542 : : #endif
543 [ + + ]: 1659910 : if(encrypt_mode < 0 || encrypt_mode >= FKO_LAST_ENC_MODE)
544 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_MODE_VALIDFAIL);
545 : :
546 : 1655890 : ctx->encryption_mode = encrypt_mode;
547 : :
548 : 1655890 : ctx->state |= FKO_ENCRYPT_MODE_MODIFIED;
549 : :
550 : 1655890 : return(FKO_SUCCESS);
551 : : }
552 : :
553 : : /* Return the SPA encryption mode.
554 : : */
555 : : int
556 : 5724 : fko_get_spa_encryption_mode(fko_ctx_t ctx, int *enc_mode)
557 : : {
558 : : /* Must be initialized
559 : : */
560 [ + + ][ + - ]: 5724 : if(!CTX_INITIALIZED(ctx))
561 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
562 : :
563 [ + + ]: 5152 : if(enc_mode == NULL)
564 : : return(FKO_ERROR_INVALID_DATA);
565 : :
566 : 5084 : *enc_mode = ctx->encryption_mode;
567 : :
568 : 5084 : return(FKO_SUCCESS);
569 : : }
570 : :
571 : : /* Encrypt the encoded SPA data.
572 : : */
573 : : int
574 : 866516 : fko_encrypt_spa_data(fko_ctx_t ctx, const char * const enc_key,
575 : : const int enc_key_len)
576 : : {
577 : 866516 : int res = 0;
578 : :
579 : : /* Must be initialized
580 : : */
581 [ + - ][ + - ]: 866516 : if(!CTX_INITIALIZED(ctx))
582 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
583 : :
584 [ + - ]: 866516 : if(enc_key_len < 0)
585 : : return(FKO_ERROR_INVALID_KEY_LEN);
586 : :
587 : : /* If there is no encoded data or the SPA data has been modified,
588 : : * go ahead and re-encode here.
589 : : */
590 [ + + ][ + + ]: 866516 : if(ctx->encoded_msg == NULL || FKO_IS_SPA_DATA_MODIFIED(ctx))
591 : 57277 : res = fko_encode_spa_data(ctx);
592 : :
593 [ + + ]: 866516 : if(res != FKO_SUCCESS)
594 : : return(res);
595 : :
596 : : /* Croak on invalid encoded message as well. At present this is a
597 : : * check for a somewhat arbitrary minimum length for the encoded
598 : : * data.
599 : : */
600 [ + + ]: 811796 : if (! is_valid_encoded_msg_len(ctx->encoded_msg_len))
601 : : return(FKO_ERROR_MISSING_ENCODED_DATA);
602 : :
603 : : /* Encrypt according to type and return...
604 : : */
605 [ + + ]: 805124 : if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL)
606 : : {
607 [ + + ]: 805039 : if(enc_key == NULL)
608 : : return(FKO_ERROR_INVALID_KEY_LEN);
609 : 802639 : res = _rijndael_encrypt(ctx, enc_key, enc_key_len);
610 : : }
611 [ + - ]: 85 : else if(ctx->encryption_type == FKO_ENCRYPTION_GPG)
612 : : #if HAVE_LIBGPGME
613 : 85 : res = gpg_encrypt(ctx, enc_key);
614 : : #else
615 : : res = FKO_ERROR_UNSUPPORTED_FEATURE;
616 : : #endif
617 : : else
618 : : res = FKO_ERROR_INVALID_ENCRYPTION_TYPE;
619 : :
620 : 802724 : return(res);
621 : : }
622 : :
623 : : /* Decode, decrypt, and parse SPA data into the context.
624 : : */
625 : : int
626 : 771175 : fko_decrypt_spa_data(fko_ctx_t ctx, const char * const dec_key, const int key_len)
627 : : {
628 : : int enc_type, res;
629 : :
630 [ + + ][ + - ]: 771175 : if(!CTX_INITIALIZED(ctx))
631 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
632 : :
633 [ + - ]: 771115 : if(key_len < 0)
634 : : return(FKO_ERROR_INVALID_KEY_LEN);
635 : :
636 : : /* Get the (assumed) type of encryption used. This will also provide
637 : : * some data validation.
638 : : */
639 : 771115 : enc_type = fko_encryption_type(ctx->encrypted_msg);
640 : :
641 [ + + ]: 771115 : if(enc_type == FKO_ENCRYPTION_GPG
642 [ + + ]: 219618 : && ctx->encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
643 : : {
644 : 75 : ctx->encryption_type = FKO_ENCRYPTION_GPG;
645 : : #if HAVE_LIBGPGME
646 : 75 : res = gpg_decrypt(ctx, dec_key);
647 : : #else
648 : : res = FKO_ERROR_UNSUPPORTED_FEATURE;
649 : : #endif
650 : : }
651 [ + + ]: 771040 : else if(enc_type == FKO_ENCRYPTION_RIJNDAEL)
652 : : {
653 : 551403 : ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL;
654 : 551403 : res = _rijndael_decrypt(ctx,
655 : : dec_key, key_len, ctx->encryption_mode);
656 : : }
657 : : else
658 : : return(FKO_ERROR_INVALID_DATA_ENCRYPT_TYPE_UNKNOWN);
659 : :
660 : 551478 : return(res);
661 : : }
662 : :
663 : : /* Return the assumed encryption type based on the raw encrypted data.
664 : : */
665 : : int
666 : 786017 : fko_encryption_type(const char * const enc_data)
667 : : {
668 : : int enc_data_len;
669 : :
670 : : /* Sanity check the data.
671 : : */
672 [ + + ]: 786017 : if(enc_data == NULL)
673 : : return(FKO_ENCRYPTION_INVALID_DATA);
674 : :
675 : 785923 : enc_data_len = strnlen(enc_data, MAX_SPA_ENCODED_MSG_SIZE);
676 : :
677 [ + - ]: 785923 : if(! is_valid_encoded_msg_len(enc_data_len))
678 : : return(FKO_ENCRYPTION_UNKNOWN);
679 : :
680 [ + + ]: 785923 : if(enc_data_len >= MIN_GNUPG_MSG_SIZE)
681 : : return(FKO_ENCRYPTION_GPG);
682 : :
683 [ - + ]: 562769 : else if(enc_data_len < MIN_GNUPG_MSG_SIZE
684 : 562769 : && enc_data_len >= MIN_SPA_ENCODED_MSG_SIZE)
685 : : return(FKO_ENCRYPTION_RIJNDAEL);
686 : :
687 : : else
688 : 0 : return(FKO_ENCRYPTION_UNKNOWN);
689 : : }
690 : :
691 : : /* Set the GPG recipient key name.
692 : : */
693 : : int
694 : 149 : fko_set_gpg_recipient(fko_ctx_t ctx, const char * const recip)
695 : : {
696 : : #if HAVE_LIBGPGME
697 : : int res;
698 : 149 : gpgme_key_t key = NULL;
699 : :
700 : : /* Must be initialized
701 : : */
702 [ + - ][ + - ]: 149 : if(!CTX_INITIALIZED(ctx))
703 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
704 : :
705 [ + + ]: 149 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
706 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
707 : :
708 [ - + ]: 79 : if(ctx->gpg_recipient != NULL)
709 : 0 : free(ctx->gpg_recipient);
710 : :
711 : 79 : ctx->gpg_recipient = strdup(recip);
712 [ + - ]: 79 : if(ctx->gpg_recipient == NULL)
713 : : return(FKO_ERROR_MEMORY_ALLOCATION);
714 : :
715 : : /* Get the key.
716 : : */
717 : 79 : res = get_gpg_key(ctx, &key, 0);
718 [ + + ]: 79 : if(res != FKO_SUCCESS)
719 : : {
720 : 1 : free(ctx->gpg_recipient);
721 : 1 : ctx->gpg_recipient = NULL;
722 : 1 : return(res);
723 : : }
724 : :
725 : 78 : ctx->recipient_key = key;
726 : :
727 : 78 : ctx->state |= FKO_DATA_MODIFIED;
728 : :
729 : 78 : return(FKO_SUCCESS);
730 : : #else
731 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
732 : : #endif /* HAVE_LIBGPGME */
733 : : }
734 : :
735 : : /* Set the GPG home dir.
736 : : */
737 : : int
738 : 6 : fko_set_gpg_exe(fko_ctx_t ctx, const char * const gpg_exe)
739 : : {
740 : : #if HAVE_LIBGPGME
741 : : struct stat st;
742 : :
743 : : /* Must be initialized
744 : : */
745 [ + - ][ + - ]: 6 : if(!CTX_INITIALIZED(ctx))
746 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
747 : :
748 : : /* If we are unable to stat the given path/file and determine if it
749 : : * is a regular file or symbolic link, then return with error.
750 : : */
751 [ + + ]: 6 : if(stat(gpg_exe, &st) != 0)
752 : : return(FKO_ERROR_GPGME_BAD_GPG_EXE);
753 : :
754 [ + - ]: 2 : if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
755 : : return(FKO_ERROR_GPGME_BAD_GPG_EXE);
756 : :
757 [ - + ]: 2 : if(ctx->gpg_exe != NULL)
758 : 0 : free(ctx->gpg_exe);
759 : :
760 : 2 : ctx->gpg_exe = strdup(gpg_exe);
761 [ + - ]: 2 : if(ctx->gpg_exe == NULL)
762 : : return(FKO_ERROR_MEMORY_ALLOCATION);
763 : :
764 : 2 : return(FKO_SUCCESS);
765 : : #else
766 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
767 : : #endif /* HAVE_LIBGPGME */
768 : : }
769 : :
770 : : /* Get the GPG home dir.
771 : : */
772 : : int
773 : 137 : fko_get_gpg_exe(fko_ctx_t ctx, char **gpg_exe)
774 : : {
775 : : #if HAVE_LIBGPGME
776 : : /* Must be initialized
777 : : */
778 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
779 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
780 : :
781 : 137 : *gpg_exe = ctx->gpg_exe;
782 : :
783 : 137 : return(FKO_SUCCESS);
784 : : #else
785 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
786 : : #endif /* HAVE_LIBGPGME */
787 : : }
788 : :
789 : : /* Get the GPG recipient key name.
790 : : */
791 : : int
792 : 137 : fko_get_gpg_recipient(fko_ctx_t ctx, char **recipient)
793 : : {
794 : : #if HAVE_LIBGPGME
795 : : /* Must be initialized
796 : : */
797 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
798 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
799 : :
800 : 137 : *recipient = ctx->gpg_recipient;
801 : :
802 : 137 : return(FKO_SUCCESS);
803 : : #else
804 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
805 : : #endif /* HAVE_LIBGPGME */
806 : : }
807 : :
808 : : /* Set the GPG signer key name.
809 : : */
810 : : int
811 : 78 : fko_set_gpg_signer(fko_ctx_t ctx, const char * const signer)
812 : : {
813 : : #if HAVE_LIBGPGME
814 : : int res;
815 : 78 : gpgme_key_t key = NULL;
816 : :
817 : : /* Must be initialized
818 : : */
819 [ + - ][ + - ]: 78 : if(!CTX_INITIALIZED(ctx))
820 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
821 : :
822 [ + - ]: 78 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
823 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
824 : :
825 [ - + ]: 78 : if(ctx->gpg_signer != NULL)
826 : 0 : free(ctx->gpg_signer);
827 : :
828 : 78 : ctx->gpg_signer = strdup(signer);
829 [ + - ]: 78 : if(ctx->gpg_signer == NULL)
830 : : return(FKO_ERROR_MEMORY_ALLOCATION);
831 : :
832 : : /* Get the key.
833 : : */
834 : 78 : res = get_gpg_key(ctx, &key, 1);
835 [ + + ]: 78 : if(res != FKO_SUCCESS)
836 : : {
837 : 1 : free(ctx->gpg_signer);
838 : 1 : ctx->gpg_signer = NULL;
839 : 1 : return(res);
840 : : }
841 : :
842 : 77 : ctx->signer_key = key;
843 : :
844 : 77 : ctx->state |= FKO_DATA_MODIFIED;
845 : :
846 : 77 : return(FKO_SUCCESS);
847 : : #else
848 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
849 : : #endif /* HAVE_LIBGPGME */
850 : : }
851 : :
852 : : /* Get the GPG signer key name.
853 : : */
854 : : int
855 : 137 : fko_get_gpg_signer(fko_ctx_t ctx, char **signer)
856 : : {
857 : : #if HAVE_LIBGPGME
858 : : /* Must be initialized
859 : : */
860 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
861 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
862 : :
863 : 137 : *signer = ctx->gpg_signer;
864 : :
865 : 137 : return(FKO_SUCCESS);
866 : : #else
867 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
868 : : #endif /* HAVE_LIBGPGME */
869 : : }
870 : :
871 : : /* Set the GPG home dir.
872 : : */
873 : : int
874 : 155 : fko_set_gpg_home_dir(fko_ctx_t ctx, const char * const gpg_home_dir)
875 : : {
876 : : #if HAVE_LIBGPGME
877 : : struct stat st;
878 : :
879 : : /* Must be initialized
880 : : */
881 [ + - ][ + - ]: 155 : if(!CTX_INITIALIZED(ctx))
882 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
883 : :
884 : : /* If we are unable to stat the given dir, then return with error.
885 : : */
886 [ + + ]: 155 : if(stat(gpg_home_dir, &st) != 0)
887 : : return(FKO_ERROR_GPGME_BAD_HOME_DIR);
888 : :
889 [ + - ]: 154 : if(!S_ISDIR(st.st_mode))
890 : : return(FKO_ERROR_GPGME_BAD_HOME_DIR);
891 : :
892 [ - + ]: 154 : if(ctx->gpg_home_dir != NULL)
893 : 0 : free(ctx->gpg_home_dir);
894 : :
895 : 154 : ctx->gpg_home_dir = strdup(gpg_home_dir);
896 [ + - ]: 154 : if(ctx->gpg_home_dir == NULL)
897 : : return(FKO_ERROR_MEMORY_ALLOCATION);
898 : :
899 : 154 : return(FKO_SUCCESS);
900 : : #else
901 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
902 : : #endif /* HAVE_LIBGPGME */
903 : : }
904 : :
905 : : /* Get the GPG home dir.
906 : : */
907 : : int
908 : 137 : fko_get_gpg_home_dir(fko_ctx_t ctx, char **home_dir)
909 : : {
910 : : #if HAVE_LIBGPGME
911 : : /* Must be initialized
912 : : */
913 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
914 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
915 : :
916 : 137 : *home_dir = ctx->gpg_home_dir;
917 : :
918 : 137 : return(FKO_SUCCESS);
919 : : #else
920 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
921 : : #endif /* HAVE_LIBGPGME */
922 : : }
923 : :
924 : : int
925 : 70 : fko_set_gpg_signature_verify(fko_ctx_t ctx, const unsigned char val)
926 : : {
927 : : #if HAVE_LIBGPGME
928 : : /* Must be initialized
929 : : */
930 [ + - ][ + - ]: 70 : if(!CTX_INITIALIZED(ctx))
931 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
932 : :
933 : 70 : ctx->verify_gpg_sigs = (val != 0) ? 1 : 0;
934 : :
935 : 70 : return(FKO_SUCCESS);
936 : : #else
937 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
938 : : #endif /* HAVE_LIBGPGME */
939 : : }
940 : :
941 : : int
942 : 137 : fko_get_gpg_signature_verify(fko_ctx_t ctx, unsigned char * const val)
943 : : {
944 : : #if HAVE_LIBGPGME
945 : : /* Must be initialized
946 : : */
947 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
948 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
949 : :
950 : 137 : *val = ctx->verify_gpg_sigs;
951 : :
952 : 137 : return(FKO_SUCCESS);
953 : : #else
954 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
955 : : #endif /* HAVE_LIBGPGME */
956 : : }
957 : :
958 : : int
959 : 70 : fko_set_gpg_ignore_verify_error(fko_ctx_t ctx, const unsigned char val)
960 : : {
961 : : #if HAVE_LIBGPGME
962 : : /* Must be initialized
963 : : */
964 [ + - ][ + - ]: 70 : if(!CTX_INITIALIZED(ctx))
965 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
966 : :
967 : 70 : ctx->ignore_gpg_sig_error = (val != 0) ? 1 : 0;
968 : :
969 : 70 : return(FKO_SUCCESS);
970 : : #else
971 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
972 : : #endif /* HAVE_LIBGPGME */
973 : : }
974 : :
975 : : int
976 : 137 : fko_get_gpg_ignore_verify_error(fko_ctx_t ctx, unsigned char * const val)
977 : : {
978 : : #if HAVE_LIBGPGME
979 : : /* Must be initialized
980 : : */
981 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
982 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
983 : :
984 : 137 : *val = ctx->ignore_gpg_sig_error;
985 : :
986 : 137 : return(FKO_SUCCESS);
987 : : #else
988 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
989 : : #endif /* HAVE_LIBGPGME */
990 : : }
991 : :
992 : :
993 : : int
994 : 192 : fko_get_gpg_signature_fpr(fko_ctx_t ctx, char **fpr)
995 : : {
996 : : #if HAVE_LIBGPGME
997 : : /* Must be initialized
998 : : */
999 [ + - ][ + - ]: 192 : if(!CTX_INITIALIZED(ctx))
1000 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
1001 : :
1002 : : /* Must be using GPG encryption.
1003 : : */
1004 [ + - ]: 192 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
1005 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
1006 : :
1007 : : /* Make sure we are supposed to verify signatures.
1008 : : */
1009 [ + + ]: 192 : if(ctx->verify_gpg_sigs == 0)
1010 : : return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED);
1011 : :
1012 : : /* Make sure we have a signature to work with.
1013 : : */
1014 [ + + ]: 191 : if(ctx->gpg_sigs == NULL)
1015 : : return(FKO_ERROR_GPGME_NO_SIGNATURE);
1016 : :
1017 : 115 : *fpr = ctx->gpg_sigs->fpr;
1018 : :
1019 : 115 : return(FKO_SUCCESS);
1020 : : #else
1021 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
1022 : : #endif /* HAVE_LIBGPGME */
1023 : : }
1024 : :
1025 : : int
1026 : 245 : fko_get_gpg_signature_id(fko_ctx_t ctx, char **id)
1027 : : {
1028 : : #if HAVE_LIBGPGME
1029 : : /* Must be initialized
1030 : : */
1031 [ + - ][ + - ]: 245 : if(!CTX_INITIALIZED(ctx))
1032 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
1033 : :
1034 : : /* Must be using GPG encryption.
1035 : : */
1036 [ + - ]: 245 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
1037 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
1038 : :
1039 : : /* Make sure we are supposed to verify signatures.
1040 : : */
1041 [ + + ]: 245 : if(ctx->verify_gpg_sigs == 0)
1042 : : return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED);
1043 : :
1044 : : /* Make sure we have a signature to work with.
1045 : : */
1046 [ + + ]: 244 : if(ctx->gpg_sigs == NULL)
1047 : : return(FKO_ERROR_GPGME_NO_SIGNATURE);
1048 : :
1049 : 168 : *id = ctx->gpg_sigs->fpr + strlen(ctx->gpg_sigs->fpr) - 8;
1050 : :
1051 : 168 : return(FKO_SUCCESS);
1052 : : #else
1053 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
1054 : : #endif /* HAVE_LIBGPGME */
1055 : : }
1056 : :
1057 : : int
1058 : 137 : fko_get_gpg_signature_summary(fko_ctx_t ctx, int *sigsum)
1059 : : {
1060 : : #if HAVE_LIBGPGME
1061 : : /* Must be initialized
1062 : : */
1063 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
1064 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
1065 : :
1066 : : /* Must be using GPG encryption.
1067 : : */
1068 [ + - ]: 137 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
1069 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
1070 : :
1071 : : /* Make sure we are supposed to verify signatures.
1072 : : */
1073 [ + + ]: 137 : if(ctx->verify_gpg_sigs == 0)
1074 : : return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED);
1075 : :
1076 : : /* Make sure we have a signature to work with.
1077 : : */
1078 [ + + ]: 136 : if(ctx->gpg_sigs == NULL)
1079 : : return(FKO_ERROR_GPGME_NO_SIGNATURE);
1080 : :
1081 : 60 : *sigsum = ctx->gpg_sigs->summary;
1082 : :
1083 : 60 : return(FKO_SUCCESS);
1084 : : #else
1085 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
1086 : : #endif /* HAVE_LIBGPGME */
1087 : : }
1088 : :
1089 : : int
1090 : 137 : fko_get_gpg_signature_status(fko_ctx_t ctx, int *sigstat)
1091 : : {
1092 : : #if HAVE_LIBGPGME
1093 : : /* Must be initialized
1094 : : */
1095 [ + - ][ + - ]: 137 : if(!CTX_INITIALIZED(ctx))
1096 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
1097 : :
1098 : : /* Must be using GPG encryption.
1099 : : */
1100 [ + - ]: 137 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
1101 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
1102 : :
1103 : : /* Make sure we are supposed to verify signatures.
1104 : : */
1105 [ + + ]: 137 : if(ctx->verify_gpg_sigs == 0)
1106 : : return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED);
1107 : :
1108 : : /* Make sure we have a signature to work with.
1109 : : */
1110 [ + + ]: 136 : if(ctx->gpg_sigs == NULL)
1111 : : return(FKO_ERROR_GPGME_NO_SIGNATURE);
1112 : :
1113 : 60 : *sigstat = ctx->gpg_sigs->status;
1114 : :
1115 : 60 : return(FKO_SUCCESS);
1116 : : #else
1117 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
1118 : : #endif /* HAVE_LIBGPGME */
1119 : : }
1120 : :
1121 : : int
1122 : 53 : fko_gpg_signature_id_match(fko_ctx_t ctx, const char * const id,
1123 : : unsigned char * const result)
1124 : : {
1125 : : #if HAVE_LIBGPGME
1126 : : char *curr_id;
1127 : 53 : int rv = FKO_SUCCESS;
1128 : :
1129 : : /* Must be initialized
1130 : : */
1131 [ + - ][ + - ]: 53 : if(!CTX_INITIALIZED(ctx))
1132 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
1133 : :
1134 : : /* Must be using GPG encryption.
1135 : : */
1136 [ + - ]: 53 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
1137 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
1138 : :
1139 : : /* Make sure we are supposed to verify signatures.
1140 : : */
1141 [ + - ]: 53 : if(ctx->verify_gpg_sigs == 0)
1142 : : return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED);
1143 : :
1144 : : /* Make sure we have a signature to work with.
1145 : : */
1146 [ + - ]: 53 : if(ctx->gpg_sigs == NULL)
1147 : : return(FKO_ERROR_GPGME_NO_SIGNATURE);
1148 : :
1149 : 53 : rv = fko_get_gpg_signature_id(ctx, &curr_id);
1150 [ + - ]: 53 : if(rv != FKO_SUCCESS)
1151 : : return rv;
1152 : :
1153 : 53 : *result = strcmp(id, curr_id) == 0 ? 1 : 0;
1154 : :
1155 : 53 : return(FKO_SUCCESS);
1156 : : #else
1157 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
1158 : : #endif /* HAVE_LIBGPGME */
1159 : : }
1160 : :
1161 : : int
1162 : 2 : fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char * const id,
1163 : : unsigned char * const result)
1164 : : {
1165 : : #if HAVE_LIBGPGME
1166 : : /* Must be initialized
1167 : : */
1168 [ + - ][ + - ]: 2 : if(!CTX_INITIALIZED(ctx))
1169 : : return(FKO_ERROR_CTX_NOT_INITIALIZED);
1170 : :
1171 : : /* Must be using GPG encryption.
1172 : : */
1173 [ + - ]: 2 : if(ctx->encryption_type != FKO_ENCRYPTION_GPG)
1174 : : return(FKO_ERROR_WRONG_ENCRYPTION_TYPE);
1175 : :
1176 : : /* Make sure we are supposed to verify signatures.
1177 : : */
1178 [ + - ]: 2 : if(ctx->verify_gpg_sigs == 0)
1179 : : return(FKO_ERROR_GPGME_SIGNATURE_VERIFY_DISABLED);
1180 : :
1181 : : /* Make sure we have a signature to work with.
1182 : : */
1183 [ + - ]: 2 : if(ctx->gpg_sigs == NULL)
1184 : : return(FKO_ERROR_GPGME_NO_SIGNATURE);
1185 : :
1186 : 2 : *result = strcmp(id, ctx->gpg_sigs->fpr) == 0 ? 1 : 0;
1187 : :
1188 : 2 : return(FKO_SUCCESS);
1189 : : #else
1190 : : return(FKO_ERROR_UNSUPPORTED_FEATURE);
1191 : : #endif /* HAVE_LIBGPGME */
1192 : : }
1193 : :
1194 : : /***EOF***/
|