summaryrefslogtreecommitdiff
path: root/sshbuf-getput-basic.c
diff options
context:
space:
mode:
Diffstat (limited to 'sshbuf-getput-basic.c')
-rw-r--r--sshbuf-getput-basic.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c
index b7d0758c2..8ff8a0a28 100644
--- a/sshbuf-getput-basic.c
+++ b/sshbuf-getput-basic.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshbuf-getput-basic.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */ 1/* $OpenBSD: sshbuf-getput-basic.c,v 1.4 2015/01/14 15:02:39 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2011 Damien Miller 3 * Copyright (c) 2011 Damien Miller
4 * 4 *
@@ -34,7 +34,7 @@ sshbuf_get(struct sshbuf *buf, void *v, size_t len)
34 34
35 if ((r = sshbuf_consume(buf, len)) < 0) 35 if ((r = sshbuf_consume(buf, len)) < 0)
36 return r; 36 return r;
37 if (v != NULL) 37 if (v != NULL && len != 0)
38 memcpy(v, p, len); 38 memcpy(v, p, len);
39 return 0; 39 return 0;
40} 40}
@@ -109,7 +109,8 @@ sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)
109 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); 109 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL"));
110 return SSH_ERR_ALLOC_FAIL; 110 return SSH_ERR_ALLOC_FAIL;
111 } 111 }
112 memcpy(*valp, val, len); 112 if (len != 0)
113 memcpy(*valp, val, len);
113 (*valp)[len] = '\0'; 114 (*valp)[len] = '\0';
114 } 115 }
115 if (lenp != NULL) 116 if (lenp != NULL)
@@ -200,7 +201,8 @@ sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp)
200 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); 201 SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL"));
201 return SSH_ERR_ALLOC_FAIL; 202 return SSH_ERR_ALLOC_FAIL;
202 } 203 }
203 memcpy(*valp, p, len); 204 if (len != 0)
205 memcpy(*valp, p, len);
204 (*valp)[len] = '\0'; 206 (*valp)[len] = '\0';
205 } 207 }
206 if (lenp != NULL) 208 if (lenp != NULL)
@@ -236,7 +238,8 @@ sshbuf_put(struct sshbuf *buf, const void *v, size_t len)
236 238
237 if ((r = sshbuf_reserve(buf, len, &p)) < 0) 239 if ((r = sshbuf_reserve(buf, len, &p)) < 0)
238 return r; 240 return r;
239 memcpy(p, v, len); 241 if (len != 0)
242 memcpy(p, v, len);
240 return 0; 243 return 0;
241} 244}
242 245
@@ -352,14 +355,15 @@ sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
352 if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0) 355 if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0)
353 return r; 356 return r;
354 POKE_U32(d, len); 357 POKE_U32(d, len);
355 memcpy(d + 4, v, len); 358 if (len != 0)
359 memcpy(d + 4, v, len);
356 return 0; 360 return 0;
357} 361}
358 362
359int 363int
360sshbuf_put_cstring(struct sshbuf *buf, const char *v) 364sshbuf_put_cstring(struct sshbuf *buf, const char *v)
361{ 365{
362 return sshbuf_put_string(buf, (u_char *)v, strlen(v)); 366 return sshbuf_put_string(buf, (u_char *)v, v == NULL ? 0 : strlen(v));
363} 367}
364 368
365int 369int
@@ -416,6 +420,43 @@ sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len)
416 POKE_U32(d, len + prepend); 420 POKE_U32(d, len + prepend);
417 if (prepend) 421 if (prepend)
418 d[4] = 0; 422 d[4] = 0;
419 memcpy(d + 4 + prepend, s, len); 423 if (len != 0)
424 memcpy(d + 4 + prepend, s, len);
425 return 0;
426}
427
428int
429sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,
430 const u_char **valp, size_t *lenp)
431{
432 const u_char *d;
433 size_t len, olen;
434 int r;
435
436 if ((r = sshbuf_peek_string_direct(buf, &d, &olen)) < 0)
437 return r;
438 len = olen;
439 /* Refuse negative (MSB set) bignums */
440 if ((len != 0 && (*d & 0x80) != 0))
441 return SSH_ERR_BIGNUM_IS_NEGATIVE;
442 /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */
443 if (len > SSHBUF_MAX_BIGNUM + 1 ||
444 (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0))
445 return SSH_ERR_BIGNUM_TOO_LARGE;
446 /* Trim leading zeros */
447 while (len > 0 && *d == 0x00) {
448 d++;
449 len--;
450 }
451 if (valp != 0)
452 *valp = d;
453 if (lenp != NULL)
454 *lenp = len;
455 if (sshbuf_consume(buf, olen + 4) != 0) {
456 /* Shouldn't happen */
457 SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR"));
458 SSHBUF_ABORT();
459 return SSH_ERR_INTERNAL_ERROR;
460 }
420 return 0; 461 return 0;
421} 462}