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