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