diff options
author | Ed Maste <emaste@FreeBSD.org> | 2021-02-14 21:00:25 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2021-02-14 21:00:25 +0000 |
commit | 0194e6d04277a638afac6c4a664d3bc6a0d944eb (patch) | |
tree | e97a6dcafc6763aea7c804e4e113c2750cb1400d /sshbuf-misc.c | |
parent | f02e39982452024dafcf0ea6e536ebff586ffce4 (diff) | |
download | src-0194e6d04277a638afac6c4a664d3bc6a0d944eb.tar.gz src-0194e6d04277a638afac6c4a664d3bc6a0d944eb.zip |
Diffstat (limited to 'sshbuf-misc.c')
-rw-r--r-- | sshbuf-misc.c | 96 |
1 files changed, 83 insertions, 13 deletions
diff --git a/sshbuf-misc.c b/sshbuf-misc.c index 15dcfbc79196..a73f008b0c82 100644 --- a/sshbuf-misc.c +++ b/sshbuf-misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-misc.c,v 1.6 2016/05/02 08:49:03 djm Exp $ */ +/* $OpenBSD: sshbuf-misc.c,v 1.11 2019/07/30 05:04:49 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -23,7 +23,7 @@ #include <errno.h> #include <stdlib.h> #ifdef HAVE_STDINT_H -#include <stdint.h> +# include <stdint.h> #endif #include <stdio.h> #include <limits.h> @@ -89,24 +89,58 @@ sshbuf_dtob16(struct sshbuf *buf) return ret; } +int +sshbuf_dtob64(const struct sshbuf *d, struct sshbuf *b64, int wrap) +{ + size_t i, slen = 0; + char *s = NULL; + int r; + + if (d == NULL || b64 == NULL || sshbuf_len(d) >= SIZE_MAX / 2) + return SSH_ERR_INVALID_ARGUMENT; + if (sshbuf_len(d) == 0) + return 0; + slen = ((sshbuf_len(d) + 2) / 3) * 4 + 1; + if ((s = malloc(slen)) == NULL) + return SSH_ERR_ALLOC_FAIL; + if (b64_ntop(sshbuf_ptr(d), sshbuf_len(d), s, slen) == -1) { + r = SSH_ERR_INTERNAL_ERROR; + goto fail; + } + if (wrap) { + for (i = 0; s[i] != '\0'; i++) { + if ((r = sshbuf_put_u8(b64, s[i])) != 0) + goto fail; + if (i % 70 == 69 && (r = sshbuf_put_u8(b64, '\n')) != 0) + goto fail; + } + if ((i - 1) % 70 != 69 && (r = sshbuf_put_u8(b64, '\n')) != 0) + goto fail; + } else { + if ((r = sshbuf_put(b64, s, strlen(s))) != 0) + goto fail; + } + /* Success */ + r = 0; + fail: + freezero(s, slen); + return r; +} + char * -sshbuf_dtob64(struct sshbuf *buf) +sshbuf_dtob64_string(const struct sshbuf *buf, int wrap) { - size_t len = sshbuf_len(buf), plen; - const u_char *p = sshbuf_ptr(buf); + struct sshbuf *tmp; char *ret; - int r; - if (len == 0) - return strdup(""); - plen = ((len + 2) / 3) * 4 + 1; - if (SIZE_MAX / 2 <= len || (ret = malloc(plen)) == NULL) + if ((tmp = sshbuf_new()) == NULL) return NULL; - if ((r = b64_ntop(p, len, ret, plen)) == -1) { - explicit_bzero(ret, plen); - free(ret); + if (sshbuf_dtob64(buf, tmp, wrap) != 0) { + sshbuf_free(tmp); return NULL; } + ret = sshbuf_dup_string(tmp); + sshbuf_free(tmp); return ret; } @@ -159,3 +193,39 @@ sshbuf_dup_string(struct sshbuf *buf) return r; } +int +sshbuf_cmp(const struct sshbuf *b, size_t offset, + const void *s, size_t len) +{ + if (sshbuf_ptr(b) == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (offset > SSHBUF_SIZE_MAX || len > SSHBUF_SIZE_MAX || len == 0) + return SSH_ERR_INVALID_ARGUMENT; + if (offset + len > sshbuf_len(b)) + return SSH_ERR_MESSAGE_INCOMPLETE; + if (timingsafe_bcmp(sshbuf_ptr(b) + offset, s, len) != 0) + return SSH_ERR_INVALID_FORMAT; + return 0; +} + +int +sshbuf_find(const struct sshbuf *b, size_t start_offset, + const void *s, size_t len, size_t *offsetp) +{ + void *p; + + if (offsetp != NULL) + *offsetp = 0; + if (sshbuf_ptr(b) == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (start_offset > SSHBUF_SIZE_MAX || len > SSHBUF_SIZE_MAX || len == 0) + return SSH_ERR_INVALID_ARGUMENT; + if (start_offset > sshbuf_len(b) || start_offset + len > sshbuf_len(b)) + return SSH_ERR_MESSAGE_INCOMPLETE; + if ((p = memmem(sshbuf_ptr(b) + start_offset, + sshbuf_len(b) - start_offset, s, len)) == NULL) + return SSH_ERR_INVALID_FORMAT; + if (offsetp != NULL) + *offsetp = (const u_char *)p - sshbuf_ptr(b); + return 0; +} |