LCOV - code coverage report
Current view: top level - lib - fko_encode.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 89 93 95.7 %
Date: 2016-06-07 Functions: 4 4 100.0 %
Branches: 61 84 72.6 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * \file lib/fko_encode.c
       3                 :            :  *
       4                 :            :  * \brief Encodes some pieces of the spa data then puts together all of
       5                 :            :  *          the necessary pieces to gether to create the single encoded
       6                 :            :  *          message string.
       7                 :            :  */
       8                 :            : 
       9                 :            : /*  Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
      10                 :            :  *  Copyright (C) 2009-2015 fwknop developers and contributors. For a full
      11                 :            :  *  list of contributors, see the file 'CREDITS'.
      12                 :            :  *
      13                 :            :  *  License (GNU General Public License):
      14                 :            :  *
      15                 :            :  *  This program is free software; you can redistribute it and/or
      16                 :            :  *  modify it under the terms of the GNU General Public License
      17                 :            :  *  as published by the Free Software Foundation; either version 2
      18                 :            :  *  of the License, or (at your option) any later version.
      19                 :            :  *
      20                 :            :  *  This program is distributed in the hope that it will be useful,
      21                 :            :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      22                 :            :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      23                 :            :  *  GNU General Public License for more details.
      24                 :            :  *
      25                 :            :  *  You should have received a copy of the GNU General Public License
      26                 :            :  *  along with this program; if not, write to the Free Software
      27                 :            :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
      28                 :            :  *  USA
      29                 :            :  *
      30                 :            :  *****************************************************************************
      31                 :            : */
      32                 :            : #include "fko_common.h"
      33                 :            : #include "fko.h"
      34                 :            : #include "base64.h"
      35                 :            : #include "digest.h"
      36                 :            : 
      37                 :            : /* Take a given string, base64-encode it and append it to the given
      38                 :            :  * buffer.
      39                 :            : */
      40                 :            : static int
      41                 :       5417 : append_b64(char* tbuf, char *str)
      42                 :            : {
      43                 :       5417 :     int   len = strnlen(str, MAX_SPA_ENCODED_MSG_SIZE);
      44                 :            :     char *bs;
      45                 :            : 
      46                 :            : #if HAVE_LIBFIU
      47         [ +  + ]:       5417 :     fiu_return_on("append_b64_toobig",
      48                 :            :             FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG);
      49                 :            : #endif
      50                 :            : 
      51         [ +  - ]:       5416 :     if(len >= MAX_SPA_ENCODED_MSG_SIZE)
      52                 :            :         return(FKO_ERROR_INVALID_DATA_ENCODE_MESSAGE_TOOBIG);
      53                 :            : 
      54                 :            : #if HAVE_LIBFIU
      55         [ +  + ]:       5416 :     fiu_return_on("append_b64_calloc", FKO_ERROR_MEMORY_ALLOCATION);
      56                 :            : #endif
      57                 :            : 
      58                 :       5415 :     bs = calloc(1, ((len/3)*4)+8);
      59         [ +  + ]:       5415 :     if(bs == NULL)
      60                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
      61                 :            : 
      62                 :       5406 :     b64_encode((unsigned char*)str, bs, len);
      63                 :            : 
      64                 :            :     /* --DSS XXX: make sure to check here if later decoding
      65                 :            :      *            becomes a problem.
      66                 :            :     */
      67                 :       5406 :     strip_b64_eq(bs);
      68                 :            : 
      69                 :       5406 :     strlcat(tbuf, bs, FKO_ENCODE_TMP_BUF_SIZE);
      70                 :            : 
      71                 :       5406 :     free(bs);
      72                 :            : 
      73                 :       5406 :     return(FKO_SUCCESS);
      74                 :            : }
      75                 :            : 
      76                 :            : /* Set the SPA encryption type.
      77                 :            : */
      78                 :            : int
      79                 :      57277 : fko_encode_spa_data(fko_ctx_t ctx)
      80                 :            : {
      81                 :      57277 :     int     res, offset = 0;
      82                 :            :     char   *tbuf;
      83                 :            : 
      84                 :            : #if HAVE_LIBFIU
      85         [ +  + ]:      57277 :     fiu_return_on("fko_encode_spa_data_init", FKO_ERROR_CTX_NOT_INITIALIZED);
      86                 :            : #endif
      87                 :            :     /* Must be initialized
      88                 :            :     */
      89 [ +  - ][ +  - ]:      57276 :     if(!CTX_INITIALIZED(ctx))
      90                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
      91                 :            : 
      92                 :            :     /* Check prerequisites.
      93                 :            :      * --DSS XXX:  Needs review.  Also, we could make this more robust (or
      94                 :            :      *             (at leaset expand the error reporting for the missing
      95                 :            :      *             data).
      96                 :            :     */
      97                 :            : #if HAVE_LIBFIU
      98         [ +  + ]:      57276 :     fiu_return_on("fko_encode_spa_data_valid", FKO_ERROR_INCOMPLETE_SPA_DATA);
      99                 :            : #endif
     100         [ +  - ]:      57275 :     if(  validate_username(ctx->username) != FKO_SUCCESS
     101 [ +  - ][ +  - ]:      57275 :       || ctx->version  == NULL || strnlen(ctx->version, MAX_SPA_VERSION_SIZE)  == 0
     102 [ +  + ][ +  - ]:      57275 :       || ctx->message  == NULL || strnlen(ctx->message, MAX_SPA_MESSAGE_SIZE)  == 0)
     103                 :            :     {
     104                 :            :         return(FKO_ERROR_INCOMPLETE_SPA_DATA);
     105                 :            :     }
     106                 :            : 
     107         [ +  + ]:       2582 :     if(ctx->message_type == FKO_NAT_ACCESS_MSG)
     108                 :            :     {
     109 [ +  - ][ +  - ]:         40 :         if(ctx->nat_access == NULL || strnlen(ctx->nat_access, MAX_SPA_MESSAGE_SIZE) == 0)
     110                 :            :             return(FKO_ERROR_INCOMPLETE_SPA_DATA);
     111                 :            :     }
     112                 :            : 
     113                 :            : #if HAVE_LIBFIU
     114         [ +  + ]:       2582 :     fiu_return_on("fko_encode_spa_data_calloc", FKO_ERROR_MEMORY_ALLOCATION);
     115                 :            : #endif
     116                 :            :     /* Allocate our initial tmp buffer.
     117                 :            :     */
     118                 :       2581 :     tbuf = calloc(1, FKO_ENCODE_TMP_BUF_SIZE);
     119         [ +  + ]:       2581 :     if(tbuf == NULL)
     120                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     121                 :            : 
     122                 :            :     /* Put it together a piece at a time, starting with the rand val.
     123                 :            :     */
     124                 :       2575 :     strlcpy(tbuf, ctx->rand_val, FKO_ENCODE_TMP_BUF_SIZE);
     125                 :            : 
     126                 :            :     /* Add the base64-encoded username.
     127                 :            :     */
     128                 :       2575 :     strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE);
     129         [ +  + ]:       2575 :     if((res = append_b64(tbuf, ctx->username)) != FKO_SUCCESS)
     130                 :            :     {
     131                 :          7 :         free(tbuf);
     132                 :          7 :         return(res);
     133                 :            :     }
     134                 :            : 
     135                 :            :     /* Add the timestamp.
     136                 :            :     */
     137                 :       2568 :     offset = strlen(tbuf);
     138                 :       2568 :     snprintf(((char*)tbuf+offset), FKO_ENCODE_TMP_BUF_SIZE - offset,
     139                 :       2568 :             ":%u:", (unsigned int) ctx->timestamp);
     140                 :            : 
     141                 :            :     /* Add the version string.
     142                 :            :     */
     143                 :       2568 :     strlcat(tbuf, ctx->version, FKO_ENCODE_TMP_BUF_SIZE);
     144                 :            : 
     145                 :            :     /* Before we add the message type value, we will once again
     146                 :            :      * check for whether or not a client_timeout was specified
     147                 :            :      * since the message_type was set.  If this is the case, then
     148                 :            :      * we want to adjust the message_type first.  The easy way
     149                 :            :      * to do this is simply call fko_set_spa_client_timeout and set
     150                 :            :      * it to its current value.  This will force a re-check and
     151                 :            :      * possible reset of the message type.
     152                 :            :      *
     153                 :            :     */
     154                 :       2568 :     fko_set_spa_client_timeout(ctx, ctx->client_timeout);
     155                 :            : 
     156                 :            :     /* Add the message type value.
     157                 :            :     */
     158                 :       2568 :     offset = strlen(tbuf);
     159                 :       2568 :     snprintf(((char*)tbuf+offset), FKO_ENCODE_TMP_BUF_SIZE - offset,
     160                 :       2568 :             ":%i:", ctx->message_type);
     161                 :            : 
     162                 :            :     /* Add the base64-encoded SPA message.
     163                 :            :     */
     164         [ +  + ]:       2568 :     if((res = append_b64(tbuf, ctx->message)) != FKO_SUCCESS)
     165                 :            :     {
     166                 :          4 :         free(tbuf);
     167                 :          4 :         return(res);
     168                 :            :     }
     169                 :            : 
     170                 :            :     /* If a nat_access message was given, add it to the SPA
     171                 :            :      * message.
     172                 :            :     */
     173         [ +  + ]:       2564 :     if(ctx->nat_access != NULL)
     174                 :            :     {
     175                 :        159 :         strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE);
     176         [ -  + ]:        159 :         if((res = append_b64(tbuf, ctx->nat_access)) != FKO_SUCCESS)
     177                 :            :         {
     178                 :          0 :             free(tbuf);
     179                 :          0 :             return(res);
     180                 :            :         }
     181                 :            :     }
     182                 :            : 
     183                 :            :     /* If we have a server_auth field set.  Add it here.
     184                 :            :      *
     185                 :            :     */
     186         [ +  + ]:       2564 :     if(ctx->server_auth != NULL)
     187                 :            :     {
     188                 :        115 :         strlcat(tbuf, ":", FKO_ENCODE_TMP_BUF_SIZE);
     189         [ -  + ]:        115 :         if((res = append_b64(tbuf, ctx->server_auth)) != FKO_SUCCESS)
     190                 :            :         {
     191                 :          0 :             free(tbuf);
     192                 :          0 :             return(res);
     193                 :            :         }
     194                 :            :     }
     195                 :            : 
     196                 :            :     /* If a client timeout is specified and we are not dealing with a
     197                 :            :      * SPA command message, add the timeout here.
     198                 :            :     */
     199 [ +  + ][ +  - ]:       2564 :     if(ctx->client_timeout > 0 && ctx->message_type != FKO_COMMAND_MSG)
     200                 :            :     {
     201                 :        126 :         offset = strlen(tbuf);
     202                 :        126 :         snprintf(((char*)tbuf+offset), FKO_ENCODE_TMP_BUF_SIZE - offset,
     203                 :            :                 ":%i", ctx->client_timeout);
     204                 :            :     }
     205                 :            : 
     206                 :            :     /* If encoded_msg is not null, then we assume it needs to
     207                 :            :      * be freed before re-assignment.
     208                 :            :     */
     209         [ +  + ]:       2564 :     if(ctx->encoded_msg != NULL)
     210                 :        410 :         free(ctx->encoded_msg);
     211                 :            : 
     212                 :            :     /* Copy our encoded data into the context.
     213                 :            :     */
     214                 :       2564 :     ctx->encoded_msg = strdup(tbuf);
     215                 :       2564 :     free(tbuf);
     216                 :            : 
     217         [ +  - ]:       2564 :     if(ctx->encoded_msg == NULL)
     218                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     219                 :            : 
     220                 :       2564 :     ctx->encoded_msg_len = strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE);
     221                 :            : 
     222         [ +  - ]:       2564 :     if(! is_valid_encoded_msg_len(ctx->encoded_msg_len))
     223                 :            :         return(FKO_ERROR_INVALID_DATA_ENCODE_MSGLEN_VALIDFAIL);
     224                 :            : 
     225                 :            :     /* At this point we can compute the digest for this SPA data.
     226                 :            :     */
     227         [ +  + ]:       2564 :     if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS)
     228                 :            :         return(res);
     229                 :            : 
     230                 :            :     /* Here we can clear the modified flags on the SPA data fields.
     231                 :            :     */
     232                 :       2557 :     FKO_CLEAR_SPA_DATA_MODIFIED(ctx);
     233                 :            : 
     234                 :       2557 :     return(FKO_SUCCESS);
     235                 :            : }
     236                 :            : 
     237                 :            : /* Return the fko SPA encrypted data.
     238                 :            : */
     239                 :            : int
     240                 :       3929 : fko_get_encoded_data(fko_ctx_t ctx, char **enc_msg)
     241                 :            : {
     242                 :            :     /* Must be initialized
     243                 :            :     */
     244 [ +  + ][ +  - ]:       3929 :     if(!CTX_INITIALIZED(ctx))
     245                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     246                 :            : 
     247         [ +  + ]:       3777 :     if(enc_msg == NULL)
     248                 :            :         return(FKO_ERROR_INVALID_DATA);
     249                 :            : 
     250                 :       3709 :     *enc_msg = ctx->encoded_msg;
     251                 :            : 
     252                 :       3709 :     return(FKO_SUCCESS);
     253                 :            : }
     254                 :            : 
     255                 :            : /* Set the fko SPA encoded data (this is a convenience
     256                 :            :  * function mostly used for tests that involve fuzzing).
     257                 :            : */
     258                 :            : #if FUZZING_INTERFACES
     259                 :            : int
     260                 :     846510 : fko_set_encoded_data(fko_ctx_t ctx,
     261                 :            :         const char * const encoded_msg, const int msg_len,
     262                 :            :         const int require_digest, const int digest_type)
     263                 :            : {
     264                 :     846510 :     char *tbuf   = NULL;
     265                 :     846510 :     int          res = FKO_SUCCESS, mlen;
     266                 :            : 
     267                 :            :     /* Must be initialized
     268                 :            :     */
     269 [ +  - ][ +  - ]:     846510 :     if(!CTX_INITIALIZED(ctx))
     270                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     271                 :            : 
     272         [ +  - ]:     846510 :     if(encoded_msg == NULL)
     273                 :            :         return(FKO_ERROR_INVALID_DATA);
     274                 :            : 
     275                 :     846510 :     ctx->encoded_msg = strdup(encoded_msg);
     276                 :            : 
     277                 :     846510 :     ctx->state |= FKO_DATA_MODIFIED;
     278                 :            : 
     279         [ +  - ]:     846510 :     if(ctx->encoded_msg == NULL)
     280                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     281                 :            : 
     282                 :            :     /* allow arbitrary length (i.e. let the decode routines validate
     283                 :            :      * SPA message length).
     284                 :            :     */
     285                 :     846510 :     ctx->encoded_msg_len = msg_len;
     286                 :            : 
     287         [ +  - ]:     846510 :     if(require_digest)
     288                 :            :     {
     289                 :     846510 :         fko_set_spa_digest_type(ctx, digest_type);
     290         [ +  + ]:     846510 :         if((res = fko_set_spa_digest(ctx)) != FKO_SUCCESS)
     291                 :            :         {
     292                 :            :             return res;
     293                 :            :         }
     294                 :            : 
     295                 :            :         /* append the digest to the encoded message buffer
     296                 :            :         */
     297                 :     801502 :         mlen = ctx->encoded_msg_len + ctx->digest_len + 2;
     298                 :     801502 :         tbuf = calloc(1, mlen);
     299         [ +  - ]:     801502 :         if(tbuf == NULL)
     300                 :            :             return(FKO_ERROR_MEMORY_ALLOCATION);
     301                 :            : 
     302                 :            :         /* memcpy since the provided encoded buffer might
     303                 :            :          * have an embedded NULL?
     304                 :            :         */
     305                 :    1603004 :         mlen = snprintf(tbuf, mlen, "%s:%s", ctx->encoded_msg, ctx->digest);
     306                 :            : 
     307         [ +  - ]:     801502 :         if(ctx->encoded_msg != NULL)
     308                 :     801502 :             free(ctx->encoded_msg);
     309                 :            : 
     310                 :     801502 :         ctx->encoded_msg = strdup(tbuf);
     311                 :     801502 :         free(tbuf);
     312                 :            : 
     313         [ +  - ]:     801502 :         if(ctx->encoded_msg == NULL)
     314                 :            :             return(FKO_ERROR_MEMORY_ALLOCATION);
     315                 :            : 
     316                 :     801502 :         ctx->encoded_msg_len = mlen;
     317                 :            :     }
     318                 :            : 
     319                 :     801502 :     FKO_CLEAR_SPA_DATA_MODIFIED(ctx);
     320                 :            : 
     321                 :     801502 :     return(FKO_SUCCESS);
     322                 :            : }
     323                 :            : #endif
     324                 :            : 
     325                 :            : /***EOF***/

Generated by: LCOV version 1.10