LCOV - code coverage report
Current view: top level - fwknop.git/lib - fko_encryption.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 290 326 89.0 %
Date: 2014-07-28 Functions: 29 29 100.0 %
Branches: 220 348 63.2 %

           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***/

Generated by: LCOV version 1.9