[BACK]Return to sshbuf-getput-basic.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/sshbuf-getput-basic.c, Revision 1.12

1.12    ! djm         1: /*     $OpenBSD: sshbuf-getput-basic.c,v 1.11 2020/06/05 03:25:35 djm Exp $    */
1.1       djm         2: /*
                      3:  * Copyright (c) 2011 Damien Miller
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17:
                     18: #include <sys/types.h>
1.6       dtucker    19:
                     20: #include <stdarg.h>
1.1       djm        21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
1.9       djm        24: #include <stdint.h>
1.1       djm        25:
                     26: #include "ssherr.h"
                     27: #define SSHBUF_INTERNAL
                     28: #include "sshbuf.h"
                     29:
                     30: int
                     31: sshbuf_get(struct sshbuf *buf, void *v, size_t len)
                     32: {
                     33:        const u_char *p = sshbuf_ptr(buf);
                     34:        int r;
                     35:
                     36:        if ((r = sshbuf_consume(buf, len)) < 0)
                     37:                return r;
1.3       djm        38:        if (v != NULL && len != 0)
1.1       djm        39:                memcpy(v, p, len);
                     40:        return 0;
                     41: }
                     42:
                     43: int
                     44: sshbuf_get_u64(struct sshbuf *buf, u_int64_t *valp)
                     45: {
                     46:        const u_char *p = sshbuf_ptr(buf);
                     47:        int r;
                     48:
                     49:        if ((r = sshbuf_consume(buf, 8)) < 0)
                     50:                return r;
                     51:        if (valp != NULL)
                     52:                *valp = PEEK_U64(p);
                     53:        return 0;
                     54: }
                     55:
                     56: int
                     57: sshbuf_get_u32(struct sshbuf *buf, u_int32_t *valp)
                     58: {
                     59:        const u_char *p = sshbuf_ptr(buf);
                     60:        int r;
                     61:
                     62:        if ((r = sshbuf_consume(buf, 4)) < 0)
                     63:                return r;
                     64:        if (valp != NULL)
                     65:                *valp = PEEK_U32(p);
                     66:        return 0;
                     67: }
                     68:
                     69: int
                     70: sshbuf_get_u16(struct sshbuf *buf, u_int16_t *valp)
                     71: {
                     72:        const u_char *p = sshbuf_ptr(buf);
                     73:        int r;
                     74:
                     75:        if ((r = sshbuf_consume(buf, 2)) < 0)
                     76:                return r;
                     77:        if (valp != NULL)
                     78:                *valp = PEEK_U16(p);
                     79:        return 0;
                     80: }
                     81:
                     82: int
                     83: sshbuf_get_u8(struct sshbuf *buf, u_char *valp)
                     84: {
                     85:        const u_char *p = sshbuf_ptr(buf);
                     86:        int r;
                     87:
                     88:        if ((r = sshbuf_consume(buf, 1)) < 0)
                     89:                return r;
                     90:        if (valp != NULL)
                     91:                *valp = (u_int8_t)*p;
                     92:        return 0;
                     93: }
                     94:
1.8       djm        95: static int
                     96: check_offset(const struct sshbuf *buf, int wr, size_t offset, size_t len)
                     97: {
                     98:        if (sshbuf_ptr(buf) == NULL) /* calls sshbuf_check_sanity() */
                     99:                return SSH_ERR_INTERNAL_ERROR;
                    100:        if (offset >= SIZE_MAX - len)
                    101:                return SSH_ERR_INVALID_ARGUMENT;
                    102:        if (offset + len > sshbuf_len(buf)) {
                    103:                return wr ?
                    104:                    SSH_ERR_NO_BUFFER_SPACE : SSH_ERR_MESSAGE_INCOMPLETE;
                    105:        }
                    106:        return 0;
                    107: }
                    108:
                    109: static int
                    110: check_roffset(const struct sshbuf *buf, size_t offset, size_t len,
                    111:     const u_char **p)
                    112: {
                    113:        int r;
                    114:
                    115:        *p = NULL;
                    116:        if ((r = check_offset(buf, 0, offset, len)) != 0)
                    117:                return r;
                    118:        *p = sshbuf_ptr(buf) + offset;
                    119:        return 0;
                    120: }
                    121:
                    122: int
                    123: sshbuf_peek_u64(const struct sshbuf *buf, size_t offset, u_int64_t *valp)
                    124: {
                    125:        const u_char *p = NULL;
                    126:        int r;
                    127:
                    128:        if (valp != NULL)
                    129:                *valp = 0;
                    130:        if ((r = check_roffset(buf, offset, 8, &p)) != 0)
                    131:                return r;
                    132:        if (valp != NULL)
                    133:                *valp = PEEK_U64(p);
                    134:        return 0;
                    135: }
                    136:
                    137: int
                    138: sshbuf_peek_u32(const struct sshbuf *buf, size_t offset, u_int32_t *valp)
                    139: {
                    140:        const u_char *p = NULL;
                    141:        int r;
                    142:
                    143:        if (valp != NULL)
                    144:                *valp = 0;
                    145:        if ((r = check_roffset(buf, offset, 4, &p)) != 0)
                    146:                return r;
                    147:        if (valp != NULL)
                    148:                *valp = PEEK_U32(p);
                    149:        return 0;
                    150: }
                    151:
                    152: int
                    153: sshbuf_peek_u16(const struct sshbuf *buf, size_t offset, u_int16_t *valp)
                    154: {
                    155:        const u_char *p = NULL;
                    156:        int r;
                    157:
                    158:        if (valp != NULL)
                    159:                *valp = 0;
                    160:        if ((r = check_roffset(buf, offset, 2, &p)) != 0)
                    161:                return r;
                    162:        if (valp != NULL)
                    163:                *valp = PEEK_U16(p);
                    164:        return 0;
                    165: }
                    166:
                    167: int
                    168: sshbuf_peek_u8(const struct sshbuf *buf, size_t offset, u_char *valp)
                    169: {
                    170:        const u_char *p = NULL;
                    171:        int r;
                    172:
                    173:        if (valp != NULL)
                    174:                *valp = 0;
                    175:        if ((r = check_roffset(buf, offset, 1, &p)) != 0)
                    176:                return r;
                    177:        if (valp != NULL)
                    178:                *valp = *p;
                    179:        return 0;
                    180: }
                    181:
1.1       djm       182: int
                    183: sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp)
                    184: {
                    185:        const u_char *val;
                    186:        size_t len;
                    187:        int r;
                    188:
                    189:        if (valp != NULL)
                    190:                *valp = NULL;
                    191:        if (lenp != NULL)
                    192:                *lenp = 0;
                    193:        if ((r = sshbuf_get_string_direct(buf, &val, &len)) < 0)
                    194:                return r;
                    195:        if (valp != NULL) {
                    196:                if ((*valp = malloc(len + 1)) == NULL) {
1.12    ! djm       197:                        SSHBUF_DBG("SSH_ERR_ALLOC_FAIL");
1.1       djm       198:                        return SSH_ERR_ALLOC_FAIL;
                    199:                }
1.3       djm       200:                if (len != 0)
                    201:                        memcpy(*valp, val, len);
1.1       djm       202:                (*valp)[len] = '\0';
                    203:        }
                    204:        if (lenp != NULL)
                    205:                *lenp = len;
                    206:        return 0;
                    207: }
                    208:
                    209: int
                    210: sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp)
                    211: {
                    212:        size_t len;
                    213:        const u_char *p;
                    214:        int r;
                    215:
                    216:        if (valp != NULL)
                    217:                *valp = NULL;
                    218:        if (lenp != NULL)
                    219:                *lenp = 0;
                    220:        if ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0)
                    221:                return r;
1.5       mmcc      222:        if (valp != NULL)
1.1       djm       223:                *valp = p;
                    224:        if (lenp != NULL)
                    225:                *lenp = len;
                    226:        if (sshbuf_consume(buf, len + 4) != 0) {
                    227:                /* Shouldn't happen */
1.12    ! djm       228:                SSHBUF_DBG("SSH_ERR_INTERNAL_ERROR");
1.1       djm       229:                SSHBUF_ABORT();
                    230:                return SSH_ERR_INTERNAL_ERROR;
                    231:        }
                    232:        return 0;
                    233: }
                    234:
                    235: int
                    236: sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
                    237:     size_t *lenp)
                    238: {
                    239:        u_int32_t len;
                    240:        const u_char *p = sshbuf_ptr(buf);
                    241:
                    242:        if (valp != NULL)
                    243:                *valp = NULL;
                    244:        if (lenp != NULL)
                    245:                *lenp = 0;
                    246:        if (sshbuf_len(buf) < 4) {
1.12    ! djm       247:                SSHBUF_DBG("SSH_ERR_MESSAGE_INCOMPLETE");
1.1       djm       248:                return SSH_ERR_MESSAGE_INCOMPLETE;
                    249:        }
                    250:        len = PEEK_U32(p);
                    251:        if (len > SSHBUF_SIZE_MAX - 4) {
1.12    ! djm       252:                SSHBUF_DBG("SSH_ERR_STRING_TOO_LARGE");
1.1       djm       253:                return SSH_ERR_STRING_TOO_LARGE;
                    254:        }
                    255:        if (sshbuf_len(buf) - 4 < len) {
1.12    ! djm       256:                SSHBUF_DBG("SSH_ERR_MESSAGE_INCOMPLETE");
1.1       djm       257:                return SSH_ERR_MESSAGE_INCOMPLETE;
                    258:        }
1.5       mmcc      259:        if (valp != NULL)
1.1       djm       260:                *valp = p + 4;
                    261:        if (lenp != NULL)
                    262:                *lenp = len;
                    263:        return 0;
                    264: }
                    265:
                    266: int
                    267: sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp)
                    268: {
                    269:        size_t len;
                    270:        const u_char *p, *z;
                    271:        int r;
                    272:
                    273:        if (valp != NULL)
                    274:                *valp = NULL;
                    275:        if (lenp != NULL)
                    276:                *lenp = 0;
                    277:        if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0)
                    278:                return r;
                    279:        /* Allow a \0 only at the end of the string */
                    280:        if (len > 0 &&
                    281:            (z = memchr(p , '\0', len)) != NULL && z < p + len - 1) {
1.12    ! djm       282:                SSHBUF_DBG("SSH_ERR_INVALID_FORMAT");
1.1       djm       283:                return SSH_ERR_INVALID_FORMAT;
                    284:        }
                    285:        if ((r = sshbuf_skip_string(buf)) != 0)
                    286:                return -1;
                    287:        if (valp != NULL) {
                    288:                if ((*valp = malloc(len + 1)) == NULL) {
1.12    ! djm       289:                        SSHBUF_DBG("SSH_ERR_ALLOC_FAIL");
1.1       djm       290:                        return SSH_ERR_ALLOC_FAIL;
                    291:                }
1.3       djm       292:                if (len != 0)
                    293:                        memcpy(*valp, p, len);
1.1       djm       294:                (*valp)[len] = '\0';
                    295:        }
                    296:        if (lenp != NULL)
                    297:                *lenp = (size_t)len;
                    298:        return 0;
                    299: }
                    300:
                    301: int
                    302: sshbuf_get_stringb(struct sshbuf *buf, struct sshbuf *v)
                    303: {
                    304:        u_int32_t len;
                    305:        u_char *p;
                    306:        int r;
                    307:
                    308:        /*
                    309:         * Use sshbuf_peek_string_direct() to figure out if there is
                    310:         * a complete string in 'buf' and copy the string directly
                    311:         * into 'v'.
                    312:         */
                    313:        if ((r = sshbuf_peek_string_direct(buf, NULL, NULL)) != 0 ||
                    314:            (r = sshbuf_get_u32(buf, &len)) != 0 ||
                    315:            (r = sshbuf_reserve(v, len, &p)) != 0 ||
                    316:            (r = sshbuf_get(buf, p, len)) != 0)
                    317:                return r;
                    318:        return 0;
                    319: }
                    320:
                    321: int
                    322: sshbuf_put(struct sshbuf *buf, const void *v, size_t len)
                    323: {
                    324:        u_char *p;
                    325:        int r;
                    326:
                    327:        if ((r = sshbuf_reserve(buf, len, &p)) < 0)
                    328:                return r;
1.3       djm       329:        if (len != 0)
                    330:                memcpy(p, v, len);
1.1       djm       331:        return 0;
                    332: }
                    333:
                    334: int
                    335: sshbuf_putb(struct sshbuf *buf, const struct sshbuf *v)
                    336: {
1.11      djm       337:        if (v == NULL)
                    338:                return 0;
1.1       djm       339:        return sshbuf_put(buf, sshbuf_ptr(v), sshbuf_len(v));
                    340: }
                    341:
                    342: int
                    343: sshbuf_putf(struct sshbuf *buf, const char *fmt, ...)
                    344: {
                    345:        va_list ap;
                    346:        int r;
                    347:
                    348:        va_start(ap, fmt);
                    349:        r = sshbuf_putfv(buf, fmt, ap);
                    350:        va_end(ap);
                    351:        return r;
                    352: }
                    353:
                    354: int
                    355: sshbuf_putfv(struct sshbuf *buf, const char *fmt, va_list ap)
                    356: {
                    357:        va_list ap2;
                    358:        int r, len;
                    359:        u_char *p;
                    360:
                    361:        va_copy(ap2, ap);
                    362:        if ((len = vsnprintf(NULL, 0, fmt, ap2)) < 0) {
                    363:                r = SSH_ERR_INVALID_ARGUMENT;
                    364:                goto out;
                    365:        }
                    366:        if (len == 0) {
                    367:                r = 0;
                    368:                goto out; /* Nothing to do */
                    369:        }
                    370:        va_end(ap2);
                    371:        va_copy(ap2, ap);
                    372:        if ((r = sshbuf_reserve(buf, (size_t)len + 1, &p)) < 0)
                    373:                goto out;
                    374:        if ((r = vsnprintf((char *)p, len + 1, fmt, ap2)) != len) {
                    375:                r = SSH_ERR_INTERNAL_ERROR;
                    376:                goto out; /* Shouldn't happen */
                    377:        }
                    378:        /* Consume terminating \0 */
                    379:        if ((r = sshbuf_consume_end(buf, 1)) != 0)
                    380:                goto out;
                    381:        r = 0;
                    382:  out:
                    383:        va_end(ap2);
                    384:        return r;
                    385: }
                    386:
                    387: int
                    388: sshbuf_put_u64(struct sshbuf *buf, u_int64_t val)
                    389: {
                    390:        u_char *p;
                    391:        int r;
                    392:
                    393:        if ((r = sshbuf_reserve(buf, 8, &p)) < 0)
                    394:                return r;
                    395:        POKE_U64(p, val);
                    396:        return 0;
                    397: }
                    398:
                    399: int
                    400: sshbuf_put_u32(struct sshbuf *buf, u_int32_t val)
                    401: {
                    402:        u_char *p;
                    403:        int r;
                    404:
                    405:        if ((r = sshbuf_reserve(buf, 4, &p)) < 0)
                    406:                return r;
                    407:        POKE_U32(p, val);
                    408:        return 0;
                    409: }
                    410:
                    411: int
                    412: sshbuf_put_u16(struct sshbuf *buf, u_int16_t val)
                    413: {
                    414:        u_char *p;
                    415:        int r;
                    416:
                    417:        if ((r = sshbuf_reserve(buf, 2, &p)) < 0)
                    418:                return r;
                    419:        POKE_U16(p, val);
                    420:        return 0;
                    421: }
                    422:
                    423: int
                    424: sshbuf_put_u8(struct sshbuf *buf, u_char val)
                    425: {
                    426:        u_char *p;
                    427:        int r;
                    428:
                    429:        if ((r = sshbuf_reserve(buf, 1, &p)) < 0)
                    430:                return r;
                    431:        p[0] = val;
1.8       djm       432:        return 0;
                    433: }
                    434:
                    435: static int
                    436: check_woffset(struct sshbuf *buf, size_t offset, size_t len, u_char **p)
                    437: {
                    438:        int r;
                    439:
                    440:        *p = NULL;
                    441:        if ((r = check_offset(buf, 1, offset, len)) != 0)
                    442:                return r;
                    443:        if (sshbuf_mutable_ptr(buf) == NULL)
                    444:                return SSH_ERR_BUFFER_READ_ONLY;
                    445:        *p = sshbuf_mutable_ptr(buf) + offset;
                    446:        return 0;
                    447: }
                    448:
                    449: int
                    450: sshbuf_poke_u64(struct sshbuf *buf, size_t offset, u_int64_t val)
                    451: {
                    452:        u_char *p = NULL;
                    453:        int r;
                    454:
                    455:        if ((r = check_woffset(buf, offset, 8, &p)) != 0)
                    456:                return r;
                    457:        POKE_U64(p, val);
                    458:        return 0;
                    459: }
                    460:
                    461: int
                    462: sshbuf_poke_u32(struct sshbuf *buf, size_t offset, u_int32_t val)
                    463: {
                    464:        u_char *p = NULL;
                    465:        int r;
                    466:
                    467:        if ((r = check_woffset(buf, offset, 4, &p)) != 0)
                    468:                return r;
                    469:        POKE_U32(p, val);
                    470:        return 0;
                    471: }
                    472:
                    473: int
                    474: sshbuf_poke_u16(struct sshbuf *buf, size_t offset, u_int16_t val)
                    475: {
                    476:        u_char *p = NULL;
                    477:        int r;
                    478:
                    479:        if ((r = check_woffset(buf, offset, 2, &p)) != 0)
                    480:                return r;
                    481:        POKE_U16(p, val);
                    482:        return 0;
                    483: }
                    484:
                    485: int
                    486: sshbuf_poke_u8(struct sshbuf *buf, size_t offset, u_char val)
                    487: {
                    488:        u_char *p = NULL;
                    489:        int r;
                    490:
                    491:        if ((r = check_woffset(buf, offset, 1, &p)) != 0)
                    492:                return r;
                    493:        *p = val;
                    494:        return 0;
                    495: }
                    496:
                    497: int
                    498: sshbuf_poke(struct sshbuf *buf, size_t offset, void *v, size_t len)
                    499: {
                    500:        u_char *p = NULL;
                    501:        int r;
                    502:
                    503:        if ((r = check_woffset(buf, offset, len, &p)) != 0)
                    504:                return r;
                    505:        memcpy(p, v, len);
1.1       djm       506:        return 0;
                    507: }
                    508:
                    509: int
                    510: sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len)
                    511: {
                    512:        u_char *d;
                    513:        int r;
                    514:
                    515:        if (len > SSHBUF_SIZE_MAX - 4) {
1.12    ! djm       516:                SSHBUF_DBG("SSH_ERR_NO_BUFFER_SPACE");
1.1       djm       517:                return SSH_ERR_NO_BUFFER_SPACE;
                    518:        }
                    519:        if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0)
                    520:                return r;
                    521:        POKE_U32(d, len);
1.3       djm       522:        if (len != 0)
                    523:                memcpy(d + 4, v, len);
1.1       djm       524:        return 0;
                    525: }
                    526:
                    527: int
                    528: sshbuf_put_cstring(struct sshbuf *buf, const char *v)
                    529: {
1.7       djm       530:        return sshbuf_put_string(buf, v, v == NULL ? 0 : strlen(v));
1.1       djm       531: }
                    532:
                    533: int
                    534: sshbuf_put_stringb(struct sshbuf *buf, const struct sshbuf *v)
                    535: {
1.10      djm       536:        if (v == NULL)
                    537:                return sshbuf_put_string(buf, NULL, 0);
                    538:
1.1       djm       539:        return sshbuf_put_string(buf, sshbuf_ptr(v), sshbuf_len(v));
                    540: }
                    541:
                    542: int
                    543: sshbuf_froms(struct sshbuf *buf, struct sshbuf **bufp)
                    544: {
                    545:        const u_char *p;
                    546:        size_t len;
                    547:        struct sshbuf *ret;
                    548:        int r;
                    549:
                    550:        if (buf == NULL || bufp == NULL)
                    551:                return SSH_ERR_INVALID_ARGUMENT;
                    552:        *bufp = NULL;
                    553:        if ((r = sshbuf_peek_string_direct(buf, &p, &len)) != 0)
                    554:                return r;
                    555:        if ((ret = sshbuf_from(p, len)) == NULL)
                    556:                return SSH_ERR_ALLOC_FAIL;
                    557:        if ((r = sshbuf_consume(buf, len + 4)) != 0 ||  /* Shouldn't happen */
                    558:            (r = sshbuf_set_parent(ret, buf)) != 0) {
                    559:                sshbuf_free(ret);
                    560:                return r;
                    561:        }
                    562:        *bufp = ret;
                    563:        return 0;
                    564: }
                    565:
                    566: int
                    567: sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len)
                    568: {
                    569:        u_char *d;
                    570:        const u_char *s = (const u_char *)v;
                    571:        int r, prepend;
                    572:
                    573:        if (len > SSHBUF_SIZE_MAX - 5) {
1.12    ! djm       574:                SSHBUF_DBG("SSH_ERR_NO_BUFFER_SPACE");
1.1       djm       575:                return SSH_ERR_NO_BUFFER_SPACE;
                    576:        }
                    577:        /* Skip leading zero bytes */
                    578:        for (; len > 0 && *s == 0; len--, s++)
                    579:                ;
                    580:        /*
                    581:         * If most significant bit is set then prepend a zero byte to
                    582:         * avoid interpretation as a negative number.
                    583:         */
                    584:        prepend = len > 0 && (s[0] & 0x80) != 0;
                    585:        if ((r = sshbuf_reserve(buf, len + 4 + prepend, &d)) < 0)
                    586:                return r;
                    587:        POKE_U32(d, len + prepend);
                    588:        if (prepend)
                    589:                d[4] = 0;
1.3       djm       590:        if (len != 0)
                    591:                memcpy(d + 4 + prepend, s, len);
1.4       djm       592:        return 0;
                    593: }
                    594:
                    595: int
                    596: sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf,
                    597:     const u_char **valp, size_t *lenp)
                    598: {
                    599:        const u_char *d;
                    600:        size_t len, olen;
                    601:        int r;
                    602:
                    603:        if ((r = sshbuf_peek_string_direct(buf, &d, &olen)) < 0)
                    604:                return r;
                    605:        len = olen;
                    606:        /* Refuse negative (MSB set) bignums */
                    607:        if ((len != 0 && (*d & 0x80) != 0))
                    608:                return SSH_ERR_BIGNUM_IS_NEGATIVE;
                    609:        /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */
                    610:        if (len > SSHBUF_MAX_BIGNUM + 1 ||
                    611:            (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0))
                    612:                return SSH_ERR_BIGNUM_TOO_LARGE;
                    613:        /* Trim leading zeros */
                    614:        while (len > 0 && *d == 0x00) {
                    615:                d++;
                    616:                len--;
                    617:        }
1.5       mmcc      618:        if (valp != NULL)
1.4       djm       619:                *valp = d;
                    620:        if (lenp != NULL)
                    621:                *lenp = len;
                    622:        if (sshbuf_consume(buf, olen + 4) != 0) {
                    623:                /* Shouldn't happen */
1.12    ! djm       624:                SSHBUF_DBG("SSH_ERR_INTERNAL_ERROR");
1.4       djm       625:                SSHBUF_ABORT();
                    626:                return SSH_ERR_INTERNAL_ERROR;
                    627:        }
1.1       djm       628:        return 0;
                    629: }