bufaux.c revision 181097
1251767Sgibbs/* $OpenBSD: bufaux.c,v 1.44 2006/08/03 03:34:41 deraadt Exp $ */ 2251767Sgibbs/* 3251767Sgibbs * Author: Tatu Ylonen <ylo@cs.hut.fi> 4251767Sgibbs * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5251767Sgibbs * All rights reserved 6251767Sgibbs * Auxiliary functions for storing and retrieving various data types to/from 7251767Sgibbs * Buffers. 8251767Sgibbs * 9251767Sgibbs * As far as I am concerned, the code I have written for this software 10251767Sgibbs * can be used freely for any purpose. Any derived versions of this 11251767Sgibbs * software must be clearly marked as such, and if the derived work is 12251767Sgibbs * incompatible with the protocol description in the RFC file, it must be 13251767Sgibbs * called by a name other than "ssh" or "Secure Shell". 14251767Sgibbs * 15251767Sgibbs * 16251767Sgibbs * SSH2 packet format added by Markus Friedl 17251767Sgibbs * Copyright (c) 2000 Markus Friedl. All rights reserved. 18251767Sgibbs * 19251767Sgibbs * Redistribution and use in source and binary forms, with or without 20251767Sgibbs * modification, are permitted provided that the following conditions 21251767Sgibbs * are met: 22251767Sgibbs * 1. Redistributions of source code must retain the above copyright 23251767Sgibbs * notice, this list of conditions and the following disclaimer. 24251767Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 25251767Sgibbs * notice, this list of conditions and the following disclaimer in the 26255040Sgibbs * documentation and/or other materials provided with the distribution. 27255040Sgibbs * 28255040Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 29251767Sgibbs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30251767Sgibbs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31251767Sgibbs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 32251767Sgibbs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33251767Sgibbs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34251767Sgibbs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35251767Sgibbs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36251767Sgibbs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37251767Sgibbs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38251767Sgibbs */ 39251767Sgibbs 40251767Sgibbs#include "includes.h" 41251767Sgibbs__RCSID("$FreeBSD: head/crypto/openssh/bufaux.c 181097 2008-08-01 01:13:41Z des $"); 42251767Sgibbs 43251767Sgibbs#include <sys/types.h> 44251767Sgibbs 45251767Sgibbs#include <openssl/bn.h> 46251767Sgibbs 47251767Sgibbs#include <string.h> 48251767Sgibbs#include <stdarg.h> 49251767Sgibbs 50251767Sgibbs#include "xmalloc.h" 51251767Sgibbs#include "buffer.h" 52251767Sgibbs#include "log.h" 53251767Sgibbs#include "misc.h" 54251767Sgibbs 55251767Sgibbs/* 56251767Sgibbs * Returns integers from the buffer (msb first). 57251767Sgibbs */ 58251767Sgibbs 59251767Sgibbsint 60251767Sgibbsbuffer_get_short_ret(u_short *ret, Buffer *buffer) 61251767Sgibbs{ 62251767Sgibbs u_char buf[2]; 63251767Sgibbs 64251767Sgibbs if (buffer_get_ret(buffer, (char *) buf, 2) == -1) 65251767Sgibbs return (-1); 66251767Sgibbs *ret = get_u16(buf); 67251767Sgibbs return (0); 68251767Sgibbs} 69251767Sgibbs 70251767Sgibbsu_short 71251767Sgibbsbuffer_get_short(Buffer *buffer) 72251767Sgibbs{ 73251767Sgibbs u_short ret; 74251767Sgibbs 75251767Sgibbs if (buffer_get_short_ret(&ret, buffer) == -1) 76251767Sgibbs fatal("buffer_get_short: buffer error"); 77251767Sgibbs 78251767Sgibbs return (ret); 79251767Sgibbs} 80251767Sgibbs 81251767Sgibbsint 82251767Sgibbsbuffer_get_int_ret(u_int *ret, Buffer *buffer) 83251767Sgibbs{ 84251767Sgibbs u_char buf[4]; 85251767Sgibbs 86251767Sgibbs if (buffer_get_ret(buffer, (char *) buf, 4) == -1) 87251767Sgibbs return (-1); 88251767Sgibbs *ret = get_u32(buf); 89251767Sgibbs return (0); 90251767Sgibbs} 91251767Sgibbs 92251767Sgibbsu_int 93251767Sgibbsbuffer_get_int(Buffer *buffer) 94251767Sgibbs{ 95251767Sgibbs u_int ret; 96255726Sgibbs 97251767Sgibbs if (buffer_get_int_ret(&ret, buffer) == -1) 98 fatal("buffer_get_int: buffer error"); 99 100 return (ret); 101} 102 103int 104buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer) 105{ 106 u_char buf[8]; 107 108 if (buffer_get_ret(buffer, (char *) buf, 8) == -1) 109 return (-1); 110 *ret = get_u64(buf); 111 return (0); 112} 113 114u_int64_t 115buffer_get_int64(Buffer *buffer) 116{ 117 u_int64_t ret; 118 119 if (buffer_get_int64_ret(&ret, buffer) == -1) 120 fatal("buffer_get_int: buffer error"); 121 122 return (ret); 123} 124 125/* 126 * Stores integers in the buffer, msb first. 127 */ 128void 129buffer_put_short(Buffer *buffer, u_short value) 130{ 131 char buf[2]; 132 133 put_u16(buf, value); 134 buffer_append(buffer, buf, 2); 135} 136 137void 138buffer_put_int(Buffer *buffer, u_int value) 139{ 140 char buf[4]; 141 142 put_u32(buf, value); 143 buffer_append(buffer, buf, 4); 144} 145 146void 147buffer_put_int64(Buffer *buffer, u_int64_t value) 148{ 149 char buf[8]; 150 151 put_u64(buf, value); 152 buffer_append(buffer, buf, 8); 153} 154 155/* 156 * Returns an arbitrary binary string from the buffer. The string cannot 157 * be longer than 256k. The returned value points to memory allocated 158 * with xmalloc; it is the responsibility of the calling function to free 159 * the data. If length_ptr is non-NULL, the length of the returned data 160 * will be stored there. A null character will be automatically appended 161 * to the returned string, and is not counted in length. 162 */ 163void * 164buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) 165{ 166 u_char *value; 167 u_int len; 168 169 /* Get the length. */ 170 len = buffer_get_int(buffer); 171 if (len > 256 * 1024) { 172 error("buffer_get_string_ret: bad string length %u", len); 173 return (NULL); 174 } 175 /* Allocate space for the string. Add one byte for a null character. */ 176 value = xmalloc(len + 1); 177 /* Get the string. */ 178 if (buffer_get_ret(buffer, value, len) == -1) { 179 error("buffer_get_string_ret: buffer_get failed"); 180 xfree(value); 181 return (NULL); 182 } 183 /* Append a null character to make processing easier. */ 184 value[len] = 0; 185 /* Optionally return the length of the string. */ 186 if (length_ptr) 187 *length_ptr = len; 188 return (value); 189} 190 191void * 192buffer_get_string(Buffer *buffer, u_int *length_ptr) 193{ 194 void *ret; 195 196 if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL) 197 fatal("buffer_get_string: buffer error"); 198 return (ret); 199} 200 201/* 202 * Stores and arbitrary binary string in the buffer. 203 */ 204void 205buffer_put_string(Buffer *buffer, const void *buf, u_int len) 206{ 207 buffer_put_int(buffer, len); 208 buffer_append(buffer, buf, len); 209} 210void 211buffer_put_cstring(Buffer *buffer, const char *s) 212{ 213 if (s == NULL) 214 fatal("buffer_put_cstring: s == NULL"); 215 buffer_put_string(buffer, s, strlen(s)); 216} 217 218/* 219 * Returns a character from the buffer (0 - 255). 220 */ 221int 222buffer_get_char_ret(char *ret, Buffer *buffer) 223{ 224 if (buffer_get_ret(buffer, ret, 1) == -1) { 225 error("buffer_get_char_ret: buffer_get_ret failed"); 226 return (-1); 227 } 228 return (0); 229} 230 231int 232buffer_get_char(Buffer *buffer) 233{ 234 char ch; 235 236 if (buffer_get_char_ret(&ch, buffer) == -1) 237 fatal("buffer_get_char: buffer error"); 238 return (u_char) ch; 239} 240 241/* 242 * Stores a character in the buffer. 243 */ 244void 245buffer_put_char(Buffer *buffer, int value) 246{ 247 char ch = value; 248 249 buffer_append(buffer, &ch, 1); 250} 251