LCOV - code coverage report
Current view: top level - lib/digest-md5 - session.c (source / functions) Hit Total Coverage
Test: GNU SASL Lines: 72 85 84.7 %
Date: 2012-05-28 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 19 34 55.9 %

           Branch data     Line data    Source code
       1                 :            : /* session.c --- Data integrity/privacy protection of DIGEST-MD5.
       2                 :            :  * Copyright (C) 2002-2012 Simon Josefsson
       3                 :            :  *
       4                 :            :  * This file is part of GNU SASL Library.
       5                 :            :  *
       6                 :            :  * GNU SASL Library is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU Lesser General Public License
       8                 :            :  * as published by the Free Software Foundation; either version 2.1 of
       9                 :            :  * the License, or (at your option) any later version.
      10                 :            :  *
      11                 :            :  * GNU SASL Library is distributed in the hope that it will be useful,
      12                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14                 :            :  * Lesser General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU Lesser General Public
      17                 :            :  * License along with GNU SASL Library; if not, write to the Free
      18                 :            :  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      19                 :            :  * Boston, MA 02110-1301, USA.
      20                 :            :  *
      21                 :            :  */
      22                 :            : 
      23                 :            : #ifdef HAVE_CONFIG_H
      24                 :            : #include "config.h"
      25                 :            : #endif
      26                 :            : 
      27                 :            : /* Get specification. */
      28                 :            : #include "session.h"
      29                 :            : 
      30                 :            : /* Get malloc, free. */
      31                 :            : #include <stdlib.h>
      32                 :            : 
      33                 :            : /* Get memcpy, strdup, strlen. */
      34                 :            : #include <string.h>
      35                 :            : 
      36                 :            : /* Get gc_hmac_md5. */
      37                 :            : #include <gc.h>
      38                 :            : 
      39                 :            : #define MD5LEN 16
      40                 :            : #define SASL_INTEGRITY_PREFIX_LENGTH 4
      41                 :            : #define MAC_DATA_LEN 4
      42                 :            : #define MAC_HMAC_LEN 10
      43                 :            : #define MAC_MSG_TYPE "\x00\x01"
      44                 :            : #define MAC_MSG_TYPE_LEN 2
      45                 :            : #define MAC_SEQNUM_LEN 4
      46                 :            : 
      47                 :            : int
      48                 :         10 : digest_md5_encode (const char *input, size_t input_len,
      49                 :            :                    char **output, size_t * output_len,
      50                 :            :                    digest_md5_qop qop,
      51                 :            :                    unsigned long sendseqnum, char key[DIGEST_MD5_LENGTH])
      52                 :            : {
      53                 :            :   int res;
      54                 :            : 
      55         [ -  + ]:         10 :   if (qop & DIGEST_MD5_QOP_AUTH_CONF)
      56                 :            :     {
      57                 :          0 :       return -1;
      58                 :            :     }
      59         [ +  + ]:         10 :   else if (qop & DIGEST_MD5_QOP_AUTH_INT)
      60                 :            :     {
      61                 :            :       char *seqnumin;
      62                 :            :       char hash[GC_MD5_DIGEST_SIZE];
      63                 :            :       size_t len;
      64                 :            : 
      65                 :          2 :       seqnumin = malloc (MAC_SEQNUM_LEN + input_len);
      66         [ -  + ]:          2 :       if (seqnumin == NULL)
      67                 :          0 :         return -1;
      68                 :            : 
      69                 :          2 :       seqnumin[0] = (sendseqnum >> 24) & 0xFF;
      70                 :          2 :       seqnumin[1] = (sendseqnum >> 16) & 0xFF;
      71                 :          2 :       seqnumin[2] = (sendseqnum >> 8) & 0xFF;
      72                 :          2 :       seqnumin[3] = sendseqnum & 0xFF;
      73                 :          2 :       memcpy (seqnumin + MAC_SEQNUM_LEN, input, input_len);
      74                 :            : 
      75                 :          2 :       res = gc_hmac_md5 (key, MD5LEN,
      76                 :            :                          seqnumin, MAC_SEQNUM_LEN + input_len, hash);
      77                 :          2 :       free (seqnumin);
      78         [ -  + ]:          2 :       if (res)
      79                 :          0 :         return -1;
      80                 :            : 
      81                 :          2 :       *output_len = MAC_DATA_LEN + input_len + MAC_HMAC_LEN +
      82                 :          2 :         MAC_MSG_TYPE_LEN + MAC_SEQNUM_LEN;
      83                 :          2 :       *output = malloc (*output_len);
      84         [ -  + ]:          2 :       if (!*output)
      85                 :          0 :         return -1;
      86                 :            : 
      87                 :          2 :       len = MAC_DATA_LEN;
      88                 :          2 :       memcpy (*output + len, input, input_len);
      89                 :          2 :       len += input_len;
      90                 :          2 :       memcpy (*output + len, hash, MAC_HMAC_LEN);
      91                 :          2 :       len += MAC_HMAC_LEN;
      92                 :          2 :       memcpy (*output + len, MAC_MSG_TYPE, MAC_MSG_TYPE_LEN);
      93                 :          2 :       len += MAC_MSG_TYPE_LEN;
      94                 :          2 :       (*output + len)[0] = (sendseqnum >> 24) & 0xFF;
      95                 :          2 :       (*output + len)[1] = (sendseqnum >> 16) & 0xFF;
      96                 :          2 :       (*output + len)[2] = (sendseqnum >> 8) & 0xFF;
      97                 :          2 :       (*output + len)[3] = sendseqnum & 0xFF;
      98                 :          2 :       len += MAC_SEQNUM_LEN;
      99                 :          2 :       (*output)[0] = ((len - MAC_DATA_LEN) >> 24) & 0xFF;
     100                 :          2 :       (*output)[1] = ((len - MAC_DATA_LEN) >> 16) & 0xFF;
     101                 :          2 :       (*output)[2] = ((len - MAC_DATA_LEN) >> 8) & 0xFF;
     102                 :          2 :       (*output)[3] = (len - MAC_DATA_LEN) & 0xFF;
     103                 :            :     }
     104                 :            :   else
     105                 :            :     {
     106                 :          8 :       *output_len = input_len;
     107                 :          8 :       *output = malloc (input_len);
     108         [ -  + ]:          8 :       if (!*output)
     109                 :          0 :         return -1;
     110                 :          8 :       memcpy (*output, input, input_len);
     111                 :            :     }
     112                 :            : 
     113                 :         10 :   return 0;
     114                 :            : }
     115                 :            : 
     116                 :            : #define C2I(buf) ((buf[3] & 0xFF) |         \
     117                 :            :                   ((buf[2] & 0xFF) << 8) |    \
     118                 :            :                   ((buf[1] & 0xFF) << 16) |   \
     119                 :            :                   ((buf[0] & 0xFF) << 24))
     120                 :            : 
     121                 :            : int
     122                 :         10 : digest_md5_decode (const char *input, size_t input_len,
     123                 :            :                    char **output, size_t * output_len,
     124                 :            :                    digest_md5_qop qop,
     125                 :            :                    unsigned long readseqnum, char key[DIGEST_MD5_LENGTH])
     126                 :            : {
     127         [ -  + ]:         10 :   if (qop & DIGEST_MD5_QOP_AUTH_CONF)
     128                 :            :     {
     129                 :          0 :       return -1;
     130                 :            :     }
     131         [ +  + ]:         10 :   else if (qop & DIGEST_MD5_QOP_AUTH_INT)
     132                 :            :     {
     133                 :            :       char *seqnumin;
     134                 :            :       char hash[GC_MD5_DIGEST_SIZE];
     135                 :            :       unsigned long len;
     136                 :            :       char tmpbuf[SASL_INTEGRITY_PREFIX_LENGTH];
     137                 :            :       int res;
     138                 :            : 
     139         [ -  + ]:          2 :       if (input_len < SASL_INTEGRITY_PREFIX_LENGTH)
     140                 :          0 :         return -2;
     141                 :            : 
     142                 :          2 :       len = C2I (input);
     143                 :            : 
     144         [ -  + ]:          2 :       if (input_len < SASL_INTEGRITY_PREFIX_LENGTH + len)
     145                 :          0 :         return -2;
     146                 :            : 
     147                 :          2 :       len -= MAC_HMAC_LEN + MAC_MSG_TYPE_LEN + MAC_SEQNUM_LEN;
     148                 :            : 
     149                 :          2 :       seqnumin = malloc (SASL_INTEGRITY_PREFIX_LENGTH + len);
     150         [ -  + ]:          2 :       if (seqnumin == NULL)
     151                 :          0 :         return -1;
     152                 :            : 
     153                 :          2 :       tmpbuf[0] = (readseqnum >> 24) & 0xFF;
     154                 :          2 :       tmpbuf[1] = (readseqnum >> 16) & 0xFF;
     155                 :          2 :       tmpbuf[2] = (readseqnum >> 8) & 0xFF;
     156                 :          2 :       tmpbuf[3] = readseqnum & 0xFF;
     157                 :            : 
     158                 :          2 :       memcpy (seqnumin, tmpbuf, SASL_INTEGRITY_PREFIX_LENGTH);
     159                 :          2 :       memcpy (seqnumin + SASL_INTEGRITY_PREFIX_LENGTH,
     160                 :          2 :               input + MAC_DATA_LEN, len);
     161                 :            : 
     162                 :          2 :       res = gc_hmac_md5 (key, MD5LEN, seqnumin, MAC_SEQNUM_LEN + len, hash);
     163                 :          2 :       free (seqnumin);
     164         [ -  + ]:          2 :       if (res)
     165                 :          0 :         return -1;
     166                 :            : 
     167         [ +  - ]:          2 :       if (memcmp
     168                 :          2 :           (hash,
     169                 :          2 :            input + input_len - MAC_SEQNUM_LEN - MAC_MSG_TYPE_LEN -
     170                 :            :            MAC_HMAC_LEN, MAC_HMAC_LEN) == 0
     171         [ +  - ]:          2 :           && memcmp (MAC_MSG_TYPE,
     172                 :          2 :                      input + input_len - MAC_SEQNUM_LEN - MAC_MSG_TYPE_LEN,
     173                 :            :                      MAC_MSG_TYPE_LEN) == 0
     174         [ +  - ]:          2 :           && memcmp (tmpbuf, input + input_len - MAC_SEQNUM_LEN,
     175                 :            :                      MAC_SEQNUM_LEN) == 0)
     176                 :            :         {
     177                 :          2 :           *output_len = len;
     178                 :          2 :           *output = malloc (*output_len);
     179         [ -  + ]:          2 :           if (!*output)
     180                 :          0 :             return -1;
     181                 :          2 :           memcpy (*output, input + MAC_DATA_LEN, len);
     182                 :            :         }
     183                 :            :       else
     184                 :          0 :         return -1;
     185                 :            :     }
     186                 :            :   else
     187                 :            :     {
     188                 :          8 :       *output_len = input_len;
     189                 :          8 :       *output = malloc (input_len);
     190         [ -  + ]:          8 :       if (!*output)
     191                 :          0 :         return -1;
     192                 :          8 :       memcpy (*output, input, input_len);
     193                 :            :     }
     194                 :            : 
     195                 :         10 :   return 0;
     196                 :            : }

Generated by: LCOV version 1.9