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

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

Generated by: LCOV version 1.9