diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2019-07-15 13:11:39 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2019-07-15 13:11:39 +0000 |
commit | 602cc6400cb24da99e9a7581a33ae07d904d4fa9 (patch) | |
tree | dbb3123564cdfa7bd0ca6cede349720170df4bca /usr.bin | |
parent | 130f2b7e50ebc5880fd6a2861903dc1dd1431020 (diff) |
two more bounds-checking sshbuf counterparts to common string
operations: sshbuf_cmp() (bcmp-like) and sshbuf_find() (memmem like)
feedback and ok markus@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/sshbuf-misc.c | 39 | ||||
-rw-r--r-- | usr.bin/ssh/sshbuf.h | 29 |
2 files changed, 66 insertions, 2 deletions
diff --git a/usr.bin/ssh/sshbuf-misc.c b/usr.bin/ssh/sshbuf-misc.c index 7251630de8a..7f018c86adc 100644 --- a/usr.bin/ssh/sshbuf-misc.c +++ b/usr.bin/ssh/sshbuf-misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-misc.c,v 1.7 2019/07/07 01:05:00 dtucker Exp $ */ +/* $OpenBSD: sshbuf-misc.c,v 1.8 2019/07/15 13:11:38 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -154,3 +154,40 @@ sshbuf_dup_string(struct sshbuf *buf) return r; } +int +sshbuf_cmp(const struct sshbuf *b, size_t offset, + const u_char *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 u_char *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; +} diff --git a/usr.bin/ssh/sshbuf.h b/usr.bin/ssh/sshbuf.h index 48a301e2c26..608a9845ec2 100644 --- a/usr.bin/ssh/sshbuf.h +++ b/usr.bin/ssh/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.14 2019/07/14 23:32:27 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.15 2019/07/15 13:11:38 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -249,6 +249,33 @@ char *sshbuf_dtob64(struct sshbuf *buf); int sshbuf_b64tod(struct sshbuf *buf, const char *b64); /* + * Tests whether the buffer contains the specified byte sequence at the + * specified offset. Returns 0 on successful match, or a ssherr.h code + * otherwise. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were + * present but the buffer contents did not match those supplied. Zero- + * length comparisons are not allowed. + * + * If sufficient data is present to make a comparison, then it is + * performed with timing independent of the value of the data. If + * insufficient data is present then the comparison is not attempted at + * all. + */ +int sshbuf_cmp(const struct sshbuf *b, size_t offset, + const u_char *s, size_t len); + +/* + * Searches the buffer for the specified string. Returns 0 on success + * and updates *offsetp with the offset of the first match, relative to + * the start of the buffer. Otherwise sshbuf_find will return a ssherr.h + * error code. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were + * present in the buffer for a match to be possible but none was found. + * Searches for zero-length data are not allowed. + */ +int +sshbuf_find(const struct sshbuf *b, size_t start_offset, + const u_char *s, size_t len, size_t *offsetp); + +/* * Duplicate the contents of a buffer to a string (caller to free). * Returns NULL on buffer error, or if the buffer contains a premature * nul character. |