LCOV - code coverage report
Current view: top level - openssh-6.6p1 - bufaux.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 87 145 60.0 %
Date: 2014-08-01 Functions: 18 23 78.3 %
Branches: 30 72 41.7 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: bufaux.c,v 1.56 2014/02/02 03:44:31 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Author: Tatu Ylonen <ylo@cs.hut.fi>
       4                 :            :  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
       5                 :            :  *                    All rights reserved
       6                 :            :  * Auxiliary functions for storing and retrieving various data types to/from
       7                 :            :  * Buffers.
       8                 :            :  *
       9                 :            :  * As far as I am concerned, the code I have written for this software
      10                 :            :  * can be used freely for any purpose.  Any derived versions of this
      11                 :            :  * software must be clearly marked as such, and if the derived work is
      12                 :            :  * incompatible with the protocol description in the RFC file, it must be
      13                 :            :  * called by a name other than "ssh" or "Secure Shell".
      14                 :            :  *
      15                 :            :  *
      16                 :            :  * SSH2 packet format added by Markus Friedl
      17                 :            :  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
      18                 :            :  *
      19                 :            :  * Redistribution and use in source and binary forms, with or without
      20                 :            :  * modification, are permitted provided that the following conditions
      21                 :            :  * are met:
      22                 :            :  * 1. Redistributions of source code must retain the above copyright
      23                 :            :  *    notice, this list of conditions and the following disclaimer.
      24                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      25                 :            :  *    notice, this list of conditions and the following disclaimer in the
      26                 :            :  *    documentation and/or other materials provided with the distribution.
      27                 :            :  *
      28                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      29                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      30                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      31                 :            :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      32                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      33                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      34                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      35                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      36                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      37                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      38                 :            :  */
      39                 :            : 
      40                 :            : #include "includes.h"
      41                 :            : 
      42                 :            : #include <sys/types.h>
      43                 :            : 
      44                 :            : #include <openssl/bn.h>
      45                 :            : 
      46                 :            : #include <string.h>
      47                 :            : #include <stdarg.h>
      48                 :            : #include <stdlib.h>
      49                 :            : 
      50                 :            : #include "xmalloc.h"
      51                 :            : #include "buffer.h"
      52                 :            : #include "log.h"
      53                 :            : #include "misc.h"
      54                 :            : 
      55                 :            : /*
      56                 :            :  * Returns integers from the buffer (msb first).
      57                 :            :  */
      58                 :            : 
      59                 :            : int
      60                 :          0 : buffer_get_short_ret(u_short *ret, Buffer *buffer)
      61                 :            : {
      62                 :            :         u_char buf[2];
      63                 :            : 
      64         [ #  # ]:          0 :         if (buffer_get_ret(buffer, (char *) buf, 2) == -1)
      65                 :            :                 return (-1);
      66                 :          0 :         *ret = get_u16(buf);
      67                 :          0 :         return (0);
      68                 :            : }
      69                 :            : 
      70                 :            : u_short
      71                 :          0 : buffer_get_short(Buffer *buffer)
      72                 :            : {
      73                 :            :         u_short ret;
      74                 :            : 
      75         [ #  # ]:          0 :         if (buffer_get_short_ret(&ret, buffer) == -1)
      76                 :          0 :                 fatal("buffer_get_short: buffer error");
      77                 :            : 
      78                 :          0 :         return (ret);
      79                 :            : }
      80                 :            : 
      81                 :            : int
      82                 :    4737791 : buffer_get_int_ret(u_int *ret, Buffer *buffer)
      83                 :            : {
      84                 :            :         u_char buf[4];
      85                 :            : 
      86         [ +  - ]:    4737791 :         if (buffer_get_ret(buffer, (char *) buf, 4) == -1)
      87                 :            :                 return (-1);
      88         [ +  - ]:    4737791 :         if (ret != NULL)
      89                 :    4737791 :                 *ret = get_u32(buf);
      90                 :            :         return (0);
      91                 :            : }
      92                 :            : 
      93                 :            : u_int
      94                 :    3731945 : buffer_get_int(Buffer *buffer)
      95                 :            : {
      96                 :            :         u_int ret;
      97                 :            : 
      98         [ -  + ]:    3731945 :         if (buffer_get_int_ret(&ret, buffer) == -1)
      99                 :          0 :                 fatal("buffer_get_int: buffer error");
     100                 :            : 
     101                 :    3731945 :         return (ret);
     102                 :            : }
     103                 :            : 
     104                 :            : int
     105                 :      10571 : buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer)
     106                 :            : {
     107                 :            :         u_char buf[8];
     108                 :            : 
     109         [ +  - ]:      10571 :         if (buffer_get_ret(buffer, (char *) buf, 8) == -1)
     110                 :            :                 return (-1);
     111         [ +  - ]:      10571 :         if (ret != NULL)
     112                 :      10571 :                 *ret = get_u64(buf);
     113                 :            :         return (0);
     114                 :            : }
     115                 :            : 
     116                 :            : u_int64_t
     117                 :       5503 : buffer_get_int64(Buffer *buffer)
     118                 :            : {
     119                 :            :         u_int64_t ret;
     120                 :            : 
     121         [ -  + ]:       5503 :         if (buffer_get_int64_ret(&ret, buffer) == -1)
     122                 :          0 :                 fatal("buffer_get_int: buffer error");
     123                 :            : 
     124                 :       5503 :         return (ret);
     125                 :            : }
     126                 :            : 
     127                 :            : /*
     128                 :            :  * Stores integers in the buffer, msb first.
     129                 :            :  */
     130                 :            : void
     131                 :          0 : buffer_put_short(Buffer *buffer, u_short value)
     132                 :            : {
     133                 :            :         char buf[2];
     134                 :            : 
     135                 :          0 :         put_u16(buf, value);
     136                 :          0 :         buffer_append(buffer, buf, 2);
     137                 :          0 : }
     138                 :            : 
     139                 :            : void
     140                 :    4623867 : buffer_put_int(Buffer *buffer, u_int value)
     141                 :            : {
     142                 :            :         char buf[4];
     143                 :            : 
     144                 :    4623867 :         put_u32(buf, value);
     145                 :    4623867 :         buffer_append(buffer, buf, 4);
     146                 :    4623867 : }
     147                 :            : 
     148                 :            : void
     149                 :    1420585 : buffer_put_int64(Buffer *buffer, u_int64_t value)
     150                 :            : {
     151                 :            :         char buf[8];
     152                 :            : 
     153                 :    1420585 :         put_u64(buf, value);
     154                 :    1420585 :         buffer_append(buffer, buf, 8);
     155                 :    1420585 : }
     156                 :            : 
     157                 :            : /*
     158                 :            :  * Returns an arbitrary binary string from the buffer.  The string cannot
     159                 :            :  * be longer than 256k.  The returned value points to memory allocated
     160                 :            :  * with xmalloc; it is the responsibility of the calling function to free
     161                 :            :  * the data.  If length_ptr is non-NULL, the length of the returned data
     162                 :            :  * will be stored there.  A null character will be automatically appended
     163                 :            :  * to the returned string, and is not counted in length.
     164                 :            :  */
     165                 :            : void *
     166                 :     984591 : buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
     167                 :            : {
     168                 :            :         u_char *value;
     169                 :            :         u_int len;
     170                 :            : 
     171                 :            :         /* Get the length. */
     172         [ -  + ]:     984591 :         if (buffer_get_int_ret(&len, buffer) != 0) {
     173                 :          0 :                 error("buffer_get_string_ret: cannot extract length");
     174                 :          0 :                 return (NULL);
     175                 :            :         }
     176         [ -  + ]:     984591 :         if (len > 256 * 1024) {
     177                 :          0 :                 error("buffer_get_string_ret: bad string length %u", len);
     178                 :          0 :                 return (NULL);
     179                 :            :         }
     180                 :            :         /* Allocate space for the string.  Add one byte for a null character. */
     181                 :     984591 :         value = xmalloc(len + 1);
     182                 :            :         /* Get the string. */
     183         [ +  + ]:     984591 :         if (buffer_get_ret(buffer, value, len) == -1) {
     184                 :          2 :                 error("buffer_get_string_ret: buffer_get failed");
     185                 :          2 :                 free(value);
     186                 :          2 :                 return (NULL);
     187                 :            :         }
     188                 :            :         /* Append a null character to make processing easier. */
     189                 :     984589 :         value[len] = '\0';
     190                 :            :         /* Optionally return the length of the string. */
     191         [ +  + ]:     984589 :         if (length_ptr)
     192                 :     875600 :                 *length_ptr = len;
     193                 :     984589 :         return (value);
     194                 :            : }
     195                 :            : 
     196                 :            : void *
     197                 :     850043 : buffer_get_string(Buffer *buffer, u_int *length_ptr)
     198                 :            : {
     199                 :            :         void *ret;
     200                 :            : 
     201         [ -  + ]:     850043 :         if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL)
     202                 :          0 :                 fatal("buffer_get_string: buffer error");
     203                 :     850043 :         return (ret);
     204                 :            : }
     205                 :            : 
     206                 :            : char *
     207                 :      91727 : buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr)
     208                 :            : {
     209                 :            :         u_int length;
     210                 :      91727 :         char *cp, *ret = buffer_get_string_ret(buffer, &length);
     211                 :            : 
     212         [ +  - ]:      91727 :         if (ret == NULL)
     213                 :            :                 return NULL;
     214         [ -  + ]:      91727 :         if ((cp = memchr(ret, '\0', length)) != NULL) {
     215                 :            :                 /* XXX allow \0 at end-of-string for a while, remove later */
     216         [ #  # ]:          0 :                 if (cp == ret + length - 1)
     217                 :          0 :                         error("buffer_get_cstring_ret: string contains \\0");
     218                 :            :                 else {
     219                 :          0 :                         explicit_bzero(ret, length);
     220                 :          0 :                         free(ret);
     221                 :          0 :                         return NULL;
     222                 :            :                 }
     223                 :            :         }
     224         [ +  + ]:      91727 :         if (length_ptr != NULL)
     225                 :       5300 :                 *length_ptr = length;
     226                 :      91727 :         return ret;
     227                 :            : }
     228                 :            : 
     229                 :            : char *
     230                 :      49568 : buffer_get_cstring(Buffer *buffer, u_int *length_ptr)
     231                 :            : {
     232                 :            :         char *ret;
     233                 :            : 
     234         [ -  + ]:      49568 :         if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL)
     235                 :          0 :                 fatal("buffer_get_cstring: buffer error");
     236                 :      49568 :         return ret;
     237                 :            : }
     238                 :            : 
     239                 :            : void *
     240                 :      19333 : buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr)
     241                 :            : {
     242                 :            :         void *ptr;
     243                 :            :         u_int len;
     244                 :            : 
     245         [ +  - ]:      19333 :         if (buffer_get_int_ret(&len, buffer) != 0)
     246                 :            :                 return NULL;
     247         [ -  + ]:      19333 :         if (len > 256 * 1024) {
     248                 :          0 :                 error("buffer_get_string_ptr: bad string length %u", len);
     249                 :          0 :                 return NULL;
     250                 :            :         }
     251                 :      19333 :         ptr = buffer_ptr(buffer);
     252                 :      19333 :         buffer_consume(buffer, len);
     253         [ +  + ]:      19333 :         if (length_ptr)
     254                 :       4020 :                 *length_ptr = len;
     255                 :      19333 :         return (ptr);
     256                 :            : }
     257                 :            : 
     258                 :            : void *
     259                 :       4253 : buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr)
     260                 :            : {
     261                 :            :         void *ret;
     262                 :            : 
     263         [ -  + ]:       4253 :         if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL)
     264                 :          0 :                 fatal("buffer_get_string_ptr: buffer error");
     265                 :       4253 :         return (ret);
     266                 :            : }
     267                 :            : 
     268                 :            : /*
     269                 :            :  * Stores and arbitrary binary string in the buffer.
     270                 :            :  */
     271                 :            : void
     272                 :    2196194 : buffer_put_string(Buffer *buffer, const void *buf, u_int len)
     273                 :            : {
     274                 :    2331269 :         buffer_put_int(buffer, len);
     275                 :    2331269 :         buffer_append(buffer, buf, len);
     276                 :    2196194 : }
     277                 :            : void
     278                 :     133466 : buffer_put_cstring(Buffer *buffer, const char *s)
     279                 :            : {
     280         [ -  + ]:     133466 :         if (s == NULL)
     281                 :          0 :                 fatal("buffer_put_cstring: s == NULL");
     282                 :     133466 :         buffer_put_string(buffer, s, strlen(s));
     283                 :     133466 : }
     284                 :            : 
     285                 :            : /*
     286                 :            :  * Returns a character from the buffer (0 - 255).
     287                 :            :  */
     288                 :            : int
     289                 :    1531452 : buffer_get_char_ret(u_char *ret, Buffer *buffer)
     290                 :            : {
     291         [ -  + ]:    1531452 :         if (buffer_get_ret(buffer, ret, 1) == -1) {
     292                 :          0 :                 error("buffer_get_char_ret: buffer_get_ret failed");
     293                 :          0 :                 return (-1);
     294                 :            :         }
     295                 :            :         return (0);
     296                 :            : }
     297                 :            : 
     298                 :            : int
     299                 :    1530384 : buffer_get_char(Buffer *buffer)
     300                 :            : {
     301                 :            :         u_char ch;
     302                 :            : 
     303         [ -  + ]:    1530384 :         if (buffer_get_char_ret(&ch, buffer) == -1)
     304                 :          0 :                 fatal("buffer_get_char: buffer error");
     305                 :    1530384 :         return ch;
     306                 :            : }
     307                 :            : 
     308                 :            : /*
     309                 :            :  * Stores a character in the buffer.
     310                 :            :  */
     311                 :            : void
     312                 :    1461130 : buffer_put_char(Buffer *buffer, int value)
     313                 :            : {
     314                 :    1461130 :         char ch = value;
     315                 :            : 
     316                 :    1461130 :         buffer_append(buffer, &ch, 1);
     317                 :    1461130 : }
     318                 :            : 
     319                 :            : /* Pseudo bignum functions */
     320                 :            : 
     321                 :            : void *
     322                 :          0 : buffer_get_bignum2_as_string_ret(Buffer *buffer, u_int *length_ptr)
     323                 :            : {
     324                 :            :         u_int len;
     325                 :            :         u_char *bin, *p, *ret;
     326                 :            : 
     327         [ #  # ]:          0 :         if ((p = bin = buffer_get_string_ret(buffer, &len)) == NULL) {
     328                 :          0 :                 error("%s: invalid bignum", __func__);
     329                 :          0 :                 return NULL;
     330                 :            :         }
     331                 :            : 
     332 [ #  # ][ #  # ]:          0 :         if (len > 0 && (bin[0] & 0x80)) {
     333                 :          0 :                 error("%s: negative numbers not supported", __func__);
     334                 :          0 :                 free(bin);
     335                 :          0 :                 return NULL;
     336                 :            :         }
     337         [ #  # ]:          0 :         if (len > 8 * 1024) {
     338                 :          0 :                 error("%s: cannot handle BN of size %d", __func__, len);
     339                 :          0 :                 free(bin);
     340                 :          0 :                 return NULL;
     341                 :            :         }
     342                 :            :         /* Skip zero prefix on numbers with the MSB set */
     343 [ #  # ][ #  # ]:          0 :         if (len > 1 && bin[0] == 0x00 && (bin[1] & 0x80) != 0) {
                 [ #  # ]
     344                 :          0 :                 p++;
     345                 :          0 :                 len--;
     346                 :            :         }
     347                 :          0 :         ret = xmalloc(len);
     348                 :          0 :         memcpy(ret, p, len);
     349                 :          0 :         explicit_bzero(p, len);
     350                 :          0 :         free(bin);
     351                 :          0 :         return ret;
     352                 :            : }
     353                 :            : 
     354                 :            : void *
     355                 :          0 : buffer_get_bignum2_as_string(Buffer *buffer, u_int *l)
     356                 :            : {
     357                 :          0 :         void *ret = buffer_get_bignum2_as_string_ret(buffer, l);
     358                 :            : 
     359         [ #  # ]:          0 :         if (ret == NULL)
     360                 :          0 :                 fatal("%s: buffer error", __func__);
     361                 :          0 :         return ret;
     362                 :            : }
     363                 :            : 
     364                 :            : /*
     365                 :            :  * Stores a string using the bignum encoding rules (\0 pad if MSB set).
     366                 :            :  */
     367                 :            : void
     368                 :       1609 : buffer_put_bignum2_from_string(Buffer *buffer, const u_char *s, u_int l)
     369                 :            : {
     370                 :            :         u_char *buf, *p;
     371                 :       1609 :         int pad = 0;
     372                 :            : 
     373         [ -  + ]:       1609 :         if (l > 8 * 1024)
     374                 :          0 :                 fatal("%s: length %u too long", __func__, l);
     375                 :       1609 :         p = buf = xmalloc(l + 1);
     376                 :            :         /*
     377                 :            :          * If most significant bit is set then prepend a zero byte to
     378                 :            :          * avoid interpretation as a negative number.
     379                 :            :          */
     380 [ +  - ][ +  + ]:       1609 :         if (l > 0 && (s[0] & 0x80) != 0) {
     381                 :        805 :                 *p++ = '\0';
     382                 :        805 :                 pad = 1;
     383                 :            :         }
     384                 :       1609 :         memcpy(p, s, l);
     385                 :       1609 :         buffer_put_string(buffer, buf, l + pad);
     386                 :       1609 :         explicit_bzero(buf, l + pad);
     387                 :       1609 :         free(buf);
     388                 :       1609 : }
     389                 :            : 
     390                 :            : 

Generated by: LCOV version 1.9