diff options
author | djm@openbsd.org <djm@openbsd.org> | 2019-07-15 13:11:38 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-07-15 23:21:18 +1000 |
commit | e18a27eedccb024acb3cd9820b650a5dff323f01 (patch) | |
tree | 8b7c4d8e03e092fc296cf3c899e4ce907dc31556 | |
parent | bc551dfebb55845537b1095cf3ccd01640a147b7 (diff) |
upstream: two more bounds-checking sshbuf counterparts to common
string operations: sshbuf_cmp() (bcmp-like) and sshbuf_find() (memmem like)
feedback and ok markus@
OpenBSD-Commit-ID: fd071ec2485c7198074a168ff363a0d6052a706a
-rw-r--r-- | sshbuf-misc.c | 39 | ||||
-rw-r--r-- | sshbuf.h | 29 |
2 files changed, 66 insertions, 2 deletions
diff --git a/sshbuf-misc.c b/sshbuf-misc.c index a077a01ef..83b598103 100644 --- a/sshbuf-misc.c +++ b/sshbuf-misc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshbuf-misc.c,v 1.7 2019/07/07 01:05:00 dtucker Exp $ */ | 1 | /* $OpenBSD: sshbuf-misc.c,v 1.8 2019/07/15 13:11:38 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller | 3 | * Copyright (c) 2011 Damien Miller |
4 | * | 4 | * |
@@ -158,3 +158,40 @@ sshbuf_dup_string(struct sshbuf *buf) | |||
158 | return r; | 158 | return r; |
159 | } | 159 | } |
160 | 160 | ||
161 | int | ||
162 | sshbuf_cmp(const struct sshbuf *b, size_t offset, | ||
163 | const u_char *s, size_t len) | ||
164 | { | ||
165 | if (sshbuf_ptr(b) == NULL) | ||
166 | return SSH_ERR_INTERNAL_ERROR; | ||
167 | if (offset > SSHBUF_SIZE_MAX || len > SSHBUF_SIZE_MAX || len == 0) | ||
168 | return SSH_ERR_INVALID_ARGUMENT; | ||
169 | if (offset + len > sshbuf_len(b)) | ||
170 | return SSH_ERR_MESSAGE_INCOMPLETE; | ||
171 | if (timingsafe_bcmp(sshbuf_ptr(b) + offset, s, len) != 0) | ||
172 | return SSH_ERR_INVALID_FORMAT; | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | int | ||
177 | sshbuf_find(const struct sshbuf *b, size_t start_offset, | ||
178 | const u_char *s, size_t len, size_t *offsetp) | ||
179 | { | ||
180 | void *p; | ||
181 | |||
182 | if (offsetp != NULL) | ||
183 | *offsetp = 0; | ||
184 | |||
185 | if (sshbuf_ptr(b) == NULL) | ||
186 | return SSH_ERR_INTERNAL_ERROR; | ||
187 | if (start_offset > SSHBUF_SIZE_MAX || len > SSHBUF_SIZE_MAX || len == 0) | ||
188 | return SSH_ERR_INVALID_ARGUMENT; | ||
189 | if (start_offset > sshbuf_len(b) || start_offset + len > sshbuf_len(b)) | ||
190 | return SSH_ERR_MESSAGE_INCOMPLETE; | ||
191 | if ((p = memmem(sshbuf_ptr(b) + start_offset, | ||
192 | sshbuf_len(b) - start_offset, s, len)) == NULL) | ||
193 | return SSH_ERR_INVALID_FORMAT; | ||
194 | if (offsetp != NULL) | ||
195 | *offsetp = (const u_char *)p - sshbuf_ptr(b); | ||
196 | return 0; | ||
197 | } | ||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshbuf.h,v 1.14 2019/07/14 23:32:27 djm Exp $ */ | 1 | /* $OpenBSD: sshbuf.h,v 1.15 2019/07/15 13:11:38 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller | 3 | * Copyright (c) 2011 Damien Miller |
4 | * | 4 | * |
@@ -257,6 +257,33 @@ char *sshbuf_dtob64(struct sshbuf *buf); | |||
257 | int sshbuf_b64tod(struct sshbuf *buf, const char *b64); | 257 | int sshbuf_b64tod(struct sshbuf *buf, const char *b64); |
258 | 258 | ||
259 | /* | 259 | /* |
260 | * Tests whether the buffer contains the specified byte sequence at the | ||
261 | * specified offset. Returns 0 on successful match, or a ssherr.h code | ||
262 | * otherwise. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were | ||
263 | * present but the buffer contents did not match those supplied. Zero- | ||
264 | * length comparisons are not allowed. | ||
265 | * | ||
266 | * If sufficient data is present to make a comparison, then it is | ||
267 | * performed with timing independent of the value of the data. If | ||
268 | * insufficient data is present then the comparison is not attempted at | ||
269 | * all. | ||
270 | */ | ||
271 | int sshbuf_cmp(const struct sshbuf *b, size_t offset, | ||
272 | const u_char *s, size_t len); | ||
273 | |||
274 | /* | ||
275 | * Searches the buffer for the specified string. Returns 0 on success | ||
276 | * and updates *offsetp with the offset of the first match, relative to | ||
277 | * the start of the buffer. Otherwise sshbuf_find will return a ssherr.h | ||
278 | * error code. SSH_ERR_INVALID_FORMAT indicates sufficient bytes were | ||
279 | * present in the buffer for a match to be possible but none was found. | ||
280 | * Searches for zero-length data are not allowed. | ||
281 | */ | ||
282 | int | ||
283 | sshbuf_find(const struct sshbuf *b, size_t start_offset, | ||
284 | const u_char *s, size_t len, size_t *offsetp); | ||
285 | |||
286 | /* | ||
260 | * Duplicate the contents of a buffer to a string (caller to free). | 287 | * Duplicate the contents of a buffer to a string (caller to free). |
261 | * Returns NULL on buffer error, or if the buffer contains a premature | 288 | * Returns NULL on buffer error, or if the buffer contains a premature |
262 | * nul character. | 289 | * nul character. |