LCOV - code coverage report
Current view: top level - lib - fko_encryption.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 290 326 89.0 %
Date: 2016-06-07 Functions: 29 29 100.0 %
Branches: 221 348 63.5 %

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

Generated by: LCOV version 1.10