#define _POSIX_C_SOURCE 200809L #include #include #include "tlse.h" #include "buffer.h" void tls_buffer_init(struct tls_buffer *buffer, size_t initial) { buffer->buffer = 0; buffer->len = 0; buffer->size = 0; buffer->error = 0; if (initial) { errno = 0; buffer->buffer = malloc(initial); if (buffer->buffer) { memset(buffer->buffer, 0, initial); buffer->size = initial; } else { buffer->error = errno; } } } void tls_buffer_compact(struct tls_buffer *b) { void *new; if (b->error || b->size == b->len) { return; } errno = 0; new = realloc(b->buffer, b->len); if (new == NULL) { b->error = errno; return; } b->buffer = new; return; } /* makes sure there's at least need bytes free */ void tls_buffer_expand(struct tls_buffer *buf, size_t need) { size_t want; if (buf->error) { return; } want = buf->len + need; if (want <= buf->size) { return; } errno = 0; char *new = realloc(buf->buffer, want); if (new) { buf->buffer = new; buf->size = want; memset(buf->buffer + buf->len, 0, buf->size - buf->len); } else { buf->error = errno; } } void tls_buffer_free(struct tls_buffer *buffer) { /* TODO only zero out memory if it's "secure" buffer */ if (buffer->buffer && buffer->len) { memset(buffer->buffer, 0, buffer->len); } free(buffer->buffer); tls_buffer_init(buffer, 0); } void tls_buffer_set(struct tls_buffer *buffer, int ch) { /* TODO only zero out memory if it's "secure" buffer */ if (buffer->buffer && buffer->size) { memset(buffer->buffer, ch, buffer->size); } } void tls_buffer_append(struct tls_buffer *buffer, const unsigned char *bytes, size_t n) { tls_buffer_expand(buffer, n); if (buffer->error || !bytes) { return; } memcpy(buffer->buffer + buffer->len, bytes, n); buffer->len += n; } void tls_buffer_append_str(struct tls_buffer *buf, const unsigned char *s) { tls_buffer_append(buf, s, strlen(s)); } void tls_buffer_append16(struct tls_buffer *buffer, uint16_t n) { tls_buffer_expand(buffer, 2); if (buffer->error) { return; } buffer->buffer[buffer->len++] = (n >> 8) & 0xff; buffer->buffer[buffer->len++] = n & 0xff; } void tls_buffer_append24(struct tls_buffer *buffer, uint32_t n) { tls_buffer_expand(buffer, 3); if (buffer->error) { return; } buffer->buffer[buffer->len++] = (n >> 16) & 0xff; buffer->buffer[buffer->len++] = (n >> 8) & 0xff; buffer->buffer[buffer->len++] = n & 0xff; } void tls_buffer_append_byte(struct tls_buffer *buffer, uint8_t n) { tls_buffer_expand(buffer, 1); if (buffer->error) { return; } buffer->buffer[buffer->len++] = n & 0xff; } void tls_buffer_write16(struct tls_buffer *buffer, uint16_t n, size_t at) { if (at+2 > buffer->size) { tls_buffer_expand(buffer, at+2 - buffer->size); } if (buffer->error) { return; } buffer->buffer[at] = (n >> 8) & 0xff; buffer->buffer[at+1] = n & 0xff; if (at+2 > buffer->len) { buffer->len = at + 2; } } uint16_t tls_buffer_read16(struct tls_buffer *buffer, size_t at) { uint16_t res = 0; if (buffer->error || at+2 < buffer->len) { return 0; } res = (buffer->buffer[at] << 8) + buffer->buffer[at+1]; return res; } uint64_t tls_buffer_readbe(struct tls_buffer *buffer, int bytes, size_t at) { uint16_t res = 0; int i; if (buffer->error || at+bytes < buffer->len) { return 0; } for (i=0; ibuffer[at+i]; } return res; } void tls_buffer_writebe(struct tls_buffer *buffer, int bytes, size_t at, uint64_t val) { int i; if (at+bytes > buffer->size) { tls_buffer_expand(buffer, at+bytes - buffer->size); } if (buffer->error) { return; } for (i=bytes-1; i>=0; i--) { buffer->buffer[at+i] = val & 0xff; val >>= 8; } return; } void tls_buffer_shift(struct tls_buffer *buffer, size_t n) { if (buffer->error) { return; } if (buffer->len < n) { n = buffer->len; } if (n) { memmove(buffer->buffer, buffer->buffer + n, buffer->len - n); memset(buffer->buffer + buffer->len - n, 0, n); #if 0 fprintf(stderr, "memmove(%p, %p, %zu)\n", buffer->buffer, buffer->buffer+n, buffer->len - n); fprintf(stderr, "memset(%p, %d, %zu)\n", buffer->buffer+n, 0, n); #endif buffer->len -= n; } } /* make room at the beginning */ void tls_buffer_unshift(struct tls_buffer *buffer, size_t n) { tls_buffer_expand(buffer, n); if (buffer->error) { return; } memmove(buffer->buffer + n, buffer->buffer, n); memset(buffer->buffer, 0, n); } #if 0 uint32_t tls_buffer_next3(struct tls_buffer_reader *rb) { uint32_t r; r = tls_buffer_readbe(rb, 3, rb->cursor); rb->cursor += 3; return r; } uint16_t tls_buffer_next2(struct tls_buffer_reader *rb) { uint16_t r; r = tls_buffer_readbe(rb, 2, rb->cursor); rb->cursor += 2; return r; } uint8_t tls_buffer_next(struct tls_buffer_reader *rb) { uint16_t r; r = tls_buffer_readbe(rb, 2, rb->cursor); rb->cursor += 2; } void tls_buffer_nextn(struct tls_buffer_reader *rb, unsigned char *b, size_t n) { tls_buffer_read(rb, b, n, rb->cursor); rb->cursor += n; } #endif