aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/stuffer
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/restricted/aws/s2n/stuffer
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/aws/s2n/stuffer')
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c822
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h338
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer_base64.c418
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer_file.c214
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer_network_order.c394
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c342
-rw-r--r--contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c388
7 files changed, 1458 insertions, 1458 deletions
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c
index 04ced5b229..026a909850 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.c
@@ -1,411 +1,411 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#include <sys/param.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-
-S2N_RESULT s2n_stuffer_validate(const struct s2n_stuffer* stuffer)
-{
- /**
- * Note that we do not assert any properties on the alloced, growable, and tainted fields,
- * as all possible combinations of boolean values in those fields are valid.
- */
- ENSURE_REF(stuffer);
- GUARD_RESULT(s2n_blob_validate(&stuffer->blob));
-
- /* <= is valid because we can have a fully written/read stuffer */
- DEBUG_ENSURE(stuffer->high_water_mark <= stuffer->blob.size, S2N_ERR_SAFETY);
- DEBUG_ENSURE(stuffer->write_cursor <= stuffer->high_water_mark, S2N_ERR_SAFETY);
- DEBUG_ENSURE(stuffer->read_cursor <= stuffer->write_cursor, S2N_ERR_SAFETY);
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_stuffer_reservation_validate(const struct s2n_stuffer_reservation* reservation)
-{
- /**
- * Note that we need two dereferences here to decrease proof complexity
- * for CBMC (see https://github.com/awslabs/s2n/issues/2290). We can roll back
- * this change once CBMC can handle common subexpression elimination.
- */
- ENSURE_REF(reservation);
- const struct s2n_stuffer_reservation reserve_obj = *reservation;
- GUARD_RESULT(s2n_stuffer_validate(reserve_obj.stuffer));
- const struct s2n_stuffer stuffer_obj = *(reserve_obj.stuffer);
- ENSURE(stuffer_obj.blob.size >= reserve_obj.length, S2N_ERR_SAFETY);
-
- if (reserve_obj.length > 0) {
- ENSURE(reserve_obj.write_cursor < stuffer_obj.write_cursor, S2N_ERR_SAFETY);
- ENSURE(
- S2N_MEM_IS_WRITABLE(stuffer_obj.blob.data + reserve_obj.write_cursor, reserve_obj.length),
- S2N_ERR_SAFETY
- );
- }
-
- return S2N_RESULT_OK;
-}
-
-int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in)
-{
- ENSURE_POSIX_MUT(stuffer);
- PRECONDITION_POSIX(s2n_blob_validate(in));
- stuffer->blob = *in;
- stuffer->read_cursor = 0;
- stuffer->write_cursor = 0;
- stuffer->high_water_mark = 0;
- stuffer->alloced = 0;
- stuffer->growable = 0;
- stuffer->tainted = 0;
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size)
-{
- notnull_check(stuffer);
- *stuffer = (struct s2n_stuffer) {0};
- GUARD(s2n_alloc(&stuffer->blob, size));
- GUARD(s2n_stuffer_init(stuffer, &stuffer->blob));
-
- stuffer->alloced = 1;
-
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size)
-{
- GUARD(s2n_stuffer_alloc(stuffer, size));
-
- stuffer->growable = 1;
-
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_free(struct s2n_stuffer *stuffer)
-{
- if (stuffer != NULL) {
- if (stuffer->alloced) {
- GUARD(s2n_free(&stuffer->blob));
- }
- *stuffer = (struct s2n_stuffer) {0};
- }
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- ENSURE_POSIX(!stuffer->tainted, S2N_ERR_RESIZE_TAINTED_STUFFER);
- ENSURE_POSIX(stuffer->growable, S2N_ERR_RESIZE_STATIC_STUFFER);
-
- if (size == stuffer->blob.size) {
- return S2N_SUCCESS;
- }
-
- if (size == 0) {
- s2n_stuffer_wipe(stuffer);
- return s2n_free(&stuffer->blob);
- }
-
- if (size < stuffer->blob.size) {
- memset_check(stuffer->blob.data + size, S2N_WIPE_PATTERN, (stuffer->blob.size - size));
- if (stuffer->read_cursor > size) stuffer->read_cursor = size;
- if (stuffer->write_cursor > size) stuffer->write_cursor = size;
- if (stuffer->high_water_mark > size) stuffer->high_water_mark = size;
- stuffer->blob.size = size;
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
- }
-
- GUARD(s2n_realloc(&stuffer->blob, size));
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- if (stuffer->blob.data == NULL) {
- ENSURE_POSIX(!stuffer->tainted, S2N_ERR_RESIZE_TAINTED_STUFFER);
- ENSURE_POSIX(stuffer->growable, S2N_ERR_RESIZE_STATIC_STUFFER);
- GUARD(s2n_realloc(&stuffer->blob, size));
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_rewrite(struct s2n_stuffer *stuffer)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- stuffer->write_cursor = 0;
- stuffer->read_cursor = 0;
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- ENSURE_POSIX(stuffer->read_cursor >= size, S2N_ERR_STUFFER_OUT_OF_DATA);
- stuffer->read_cursor -= size;
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_reread(struct s2n_stuffer *stuffer)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- stuffer->read_cursor = 0;
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_wipe_n(struct s2n_stuffer *stuffer, const uint32_t size)
-{
- if (size >= stuffer->write_cursor) {
- return s2n_stuffer_wipe(stuffer);
- }
-
- /* We know that size is now less than write_cursor */
- stuffer->write_cursor -= size;
- memset_check(stuffer->blob.data + stuffer->write_cursor, S2N_WIPE_PATTERN, size);
- stuffer->read_cursor = MIN(stuffer->read_cursor, stuffer->write_cursor);
-
- return S2N_SUCCESS;
-}
-
-bool s2n_stuffer_is_consumed(struct s2n_stuffer *stuffer) {
- return stuffer && (stuffer->read_cursor == stuffer->write_cursor);
-}
-
-int s2n_stuffer_wipe(struct s2n_stuffer *stuffer)
-{
- if (!s2n_stuffer_is_wiped(stuffer)) {
- memset_check(stuffer->blob.data, S2N_WIPE_PATTERN, stuffer->high_water_mark);
- }
-
- stuffer->tainted = 0;
- stuffer->write_cursor = 0;
- stuffer->read_cursor = 0;
- stuffer->high_water_mark = 0;
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) < n, S2N_ERR_STUFFER_OUT_OF_DATA);
-
- stuffer->read_cursor += n;
- return S2N_SUCCESS;
-}
-
-void *s2n_stuffer_raw_read(struct s2n_stuffer *stuffer, uint32_t data_len)
-{
- GUARD_PTR(s2n_stuffer_skip_read(stuffer, data_len));
-
- stuffer->tainted = 1;
-
- return stuffer->blob.data + stuffer->read_cursor - data_len;
-}
-
-int s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out)
-{
- notnull_check(out);
-
- return s2n_stuffer_read_bytes(stuffer, out->data, out->size);
-}
-
-int s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out)
-{
- GUARD(s2n_stuffer_skip_read(stuffer, out->size));
-
- void *ptr = stuffer->blob.data + stuffer->read_cursor - out->size;
- ENSURE_POSIX(S2N_MEM_IS_READABLE(ptr, out->size), S2N_ERR_NULL);
-
- memcpy_check(out->data, ptr, out->size);
- memset_check(ptr, 0, out->size);
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t * data, uint32_t size)
-{
- notnull_check(data);
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- GUARD(s2n_stuffer_skip_read(stuffer, size));
- notnull_check(stuffer->blob.data);
- void *ptr = stuffer->blob.data + stuffer->read_cursor - size;
-
- memcpy_check(data, ptr, size);
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t * data, uint32_t size)
-{
- GUARD(s2n_stuffer_skip_read(stuffer, size));
- notnull_check(stuffer->blob.data);
- void *ptr = stuffer->blob.data + stuffer->read_cursor - size;
-
- memcpy_check(data, ptr, size);
- memset_check(ptr, 0, size);
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- GUARD(s2n_stuffer_reserve_space(stuffer, n));
- stuffer->write_cursor += n;
- stuffer->high_water_mark = MAX(stuffer->write_cursor, stuffer->high_water_mark);
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-void *s2n_stuffer_raw_write(struct s2n_stuffer *stuffer, const uint32_t data_len)
-{
- GUARD_PTR(s2n_stuffer_skip_write(stuffer, data_len));
-
- stuffer->tainted = 1;
-
- return stuffer->blob.data + stuffer->write_cursor - data_len;
-}
-
-int s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- PRECONDITION_POSIX(s2n_blob_validate(in));
- return s2n_stuffer_write_bytes(stuffer, in->data, in->size);
-}
-
-int s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t * data, const uint32_t size)
-{
- ENSURE_POSIX(S2N_MEM_IS_READABLE(data, size), S2N_ERR_SAFETY);
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- GUARD(s2n_stuffer_skip_write(stuffer, size));
-
- void *ptr = stuffer->blob.data + stuffer->write_cursor - size;
- ENSURE_POSIX(S2N_MEM_IS_READABLE(ptr, size), S2N_ERR_NULL);
-
- if (ptr == data) {
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
- }
-
- memcpy_check(ptr, data, size);
-
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec* iov, size_t iov_count, uint32_t offs, uint32_t size)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- notnull_check(iov);
- void *ptr = s2n_stuffer_raw_write(stuffer, size);
- ENSURE_POSIX(S2N_MEM_IS_READABLE(ptr, size), S2N_ERR_NULL);
-
- size_t size_left = size, to_skip = offs;
- for (int i = 0; i < iov_count; i++) {
- if (to_skip >= iov[i].iov_len) {
- to_skip -= iov[i].iov_len;
- continue;
- }
- size_t iov_len_op = iov[i].iov_len - to_skip;
- ENSURE_POSIX(iov_len_op <= UINT32_MAX, S2N_FAILURE);
- uint32_t iov_len = (uint32_t)iov_len_op;
- uint32_t iov_size_to_take = MIN(size_left, iov_len);
- notnull_check(iov[i].iov_base);
- ENSURE_POSIX(to_skip < iov[i].iov_len, S2N_FAILURE);
- memcpy_check(ptr, ((uint8_t*)(iov[i].iov_base)) + to_skip, iov_size_to_take);
- size_left -= iov_size_to_take;
- if (size_left == 0) {
- break;
- }
- ptr = (void*)((uint8_t*)ptr + iov_size_to_take);
- to_skip = 0;
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_stuffer_copy_impl(struct s2n_stuffer *from, struct s2n_stuffer *to, const uint32_t len)
-{
- GUARD(s2n_stuffer_skip_read(from, len));
- GUARD(s2n_stuffer_skip_write(to, len));
-
- uint8_t *from_ptr = from->blob.data + from->read_cursor - len;
- uint8_t *to_ptr = to->blob.data + to->write_cursor - len;
-
- memcpy_check(to_ptr, from_ptr, len);
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- if (s2n_stuffer_space_remaining(stuffer) < n) {
- S2N_ERROR_IF(!stuffer->growable, S2N_ERR_STUFFER_IS_FULL);
- /* Always grow a stuffer by at least 1k */
- const uint32_t growth = MAX(n - s2n_stuffer_space_remaining(stuffer), S2N_MIN_STUFFER_GROWTH_IN_BYTES);
- uint32_t new_size = 0;
- GUARD(s2n_add_overflow(stuffer->blob.size, growth, &new_size));
- GUARD(s2n_stuffer_resize(stuffer, new_size));
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-/* Copies "len" bytes from "from" to "to".
- * If the copy cannot succeed (i.e. there are either not enough bytes available, or there is not enough space to write them
- * restore the old value of the stuffer */
-int s2n_stuffer_copy(struct s2n_stuffer *from, struct s2n_stuffer *to, const uint32_t len)
-{
- const uint32_t orig_read_cursor = from->read_cursor;
- const uint32_t orig_write_cursor = to->write_cursor;
-
- if (s2n_stuffer_copy_impl(from, to, len) < 0) {
- from->read_cursor = orig_read_cursor;
- to->write_cursor = orig_write_cursor;
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- notnull_check(out);
- GUARD(s2n_realloc(out , s2n_stuffer_data_available(stuffer)));
-
- if (s2n_stuffer_data_available(stuffer) > 0) {
- memcpy_check(out->data,
- stuffer->blob.data + stuffer->read_cursor,
- s2n_stuffer_data_available(stuffer));
- }
-
- POSTCONDITION_POSIX(s2n_blob_validate(out));
- return S2N_SUCCESS;
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <sys/param.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+
+S2N_RESULT s2n_stuffer_validate(const struct s2n_stuffer* stuffer)
+{
+ /**
+ * Note that we do not assert any properties on the alloced, growable, and tainted fields,
+ * as all possible combinations of boolean values in those fields are valid.
+ */
+ ENSURE_REF(stuffer);
+ GUARD_RESULT(s2n_blob_validate(&stuffer->blob));
+
+ /* <= is valid because we can have a fully written/read stuffer */
+ DEBUG_ENSURE(stuffer->high_water_mark <= stuffer->blob.size, S2N_ERR_SAFETY);
+ DEBUG_ENSURE(stuffer->write_cursor <= stuffer->high_water_mark, S2N_ERR_SAFETY);
+ DEBUG_ENSURE(stuffer->read_cursor <= stuffer->write_cursor, S2N_ERR_SAFETY);
+ return S2N_RESULT_OK;
+}
+
+S2N_RESULT s2n_stuffer_reservation_validate(const struct s2n_stuffer_reservation* reservation)
+{
+ /**
+ * Note that we need two dereferences here to decrease proof complexity
+ * for CBMC (see https://github.com/awslabs/s2n/issues/2290). We can roll back
+ * this change once CBMC can handle common subexpression elimination.
+ */
+ ENSURE_REF(reservation);
+ const struct s2n_stuffer_reservation reserve_obj = *reservation;
+ GUARD_RESULT(s2n_stuffer_validate(reserve_obj.stuffer));
+ const struct s2n_stuffer stuffer_obj = *(reserve_obj.stuffer);
+ ENSURE(stuffer_obj.blob.size >= reserve_obj.length, S2N_ERR_SAFETY);
+
+ if (reserve_obj.length > 0) {
+ ENSURE(reserve_obj.write_cursor < stuffer_obj.write_cursor, S2N_ERR_SAFETY);
+ ENSURE(
+ S2N_MEM_IS_WRITABLE(stuffer_obj.blob.data + reserve_obj.write_cursor, reserve_obj.length),
+ S2N_ERR_SAFETY
+ );
+ }
+
+ return S2N_RESULT_OK;
+}
+
+int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in)
+{
+ ENSURE_POSIX_MUT(stuffer);
+ PRECONDITION_POSIX(s2n_blob_validate(in));
+ stuffer->blob = *in;
+ stuffer->read_cursor = 0;
+ stuffer->write_cursor = 0;
+ stuffer->high_water_mark = 0;
+ stuffer->alloced = 0;
+ stuffer->growable = 0;
+ stuffer->tainted = 0;
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size)
+{
+ notnull_check(stuffer);
+ *stuffer = (struct s2n_stuffer) {0};
+ GUARD(s2n_alloc(&stuffer->blob, size));
+ GUARD(s2n_stuffer_init(stuffer, &stuffer->blob));
+
+ stuffer->alloced = 1;
+
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size)
+{
+ GUARD(s2n_stuffer_alloc(stuffer, size));
+
+ stuffer->growable = 1;
+
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_free(struct s2n_stuffer *stuffer)
+{
+ if (stuffer != NULL) {
+ if (stuffer->alloced) {
+ GUARD(s2n_free(&stuffer->blob));
+ }
+ *stuffer = (struct s2n_stuffer) {0};
+ }
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ ENSURE_POSIX(!stuffer->tainted, S2N_ERR_RESIZE_TAINTED_STUFFER);
+ ENSURE_POSIX(stuffer->growable, S2N_ERR_RESIZE_STATIC_STUFFER);
+
+ if (size == stuffer->blob.size) {
+ return S2N_SUCCESS;
+ }
+
+ if (size == 0) {
+ s2n_stuffer_wipe(stuffer);
+ return s2n_free(&stuffer->blob);
+ }
+
+ if (size < stuffer->blob.size) {
+ memset_check(stuffer->blob.data + size, S2N_WIPE_PATTERN, (stuffer->blob.size - size));
+ if (stuffer->read_cursor > size) stuffer->read_cursor = size;
+ if (stuffer->write_cursor > size) stuffer->write_cursor = size;
+ if (stuffer->high_water_mark > size) stuffer->high_water_mark = size;
+ stuffer->blob.size = size;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+ }
+
+ GUARD(s2n_realloc(&stuffer->blob, size));
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ if (stuffer->blob.data == NULL) {
+ ENSURE_POSIX(!stuffer->tainted, S2N_ERR_RESIZE_TAINTED_STUFFER);
+ ENSURE_POSIX(stuffer->growable, S2N_ERR_RESIZE_STATIC_STUFFER);
+ GUARD(s2n_realloc(&stuffer->blob, size));
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_rewrite(struct s2n_stuffer *stuffer)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ stuffer->write_cursor = 0;
+ stuffer->read_cursor = 0;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ ENSURE_POSIX(stuffer->read_cursor >= size, S2N_ERR_STUFFER_OUT_OF_DATA);
+ stuffer->read_cursor -= size;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_reread(struct s2n_stuffer *stuffer)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ stuffer->read_cursor = 0;
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_wipe_n(struct s2n_stuffer *stuffer, const uint32_t size)
+{
+ if (size >= stuffer->write_cursor) {
+ return s2n_stuffer_wipe(stuffer);
+ }
+
+ /* We know that size is now less than write_cursor */
+ stuffer->write_cursor -= size;
+ memset_check(stuffer->blob.data + stuffer->write_cursor, S2N_WIPE_PATTERN, size);
+ stuffer->read_cursor = MIN(stuffer->read_cursor, stuffer->write_cursor);
+
+ return S2N_SUCCESS;
+}
+
+bool s2n_stuffer_is_consumed(struct s2n_stuffer *stuffer) {
+ return stuffer && (stuffer->read_cursor == stuffer->write_cursor);
+}
+
+int s2n_stuffer_wipe(struct s2n_stuffer *stuffer)
+{
+ if (!s2n_stuffer_is_wiped(stuffer)) {
+ memset_check(stuffer->blob.data, S2N_WIPE_PATTERN, stuffer->high_water_mark);
+ }
+
+ stuffer->tainted = 0;
+ stuffer->write_cursor = 0;
+ stuffer->read_cursor = 0;
+ stuffer->high_water_mark = 0;
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ S2N_ERROR_IF(s2n_stuffer_data_available(stuffer) < n, S2N_ERR_STUFFER_OUT_OF_DATA);
+
+ stuffer->read_cursor += n;
+ return S2N_SUCCESS;
+}
+
+void *s2n_stuffer_raw_read(struct s2n_stuffer *stuffer, uint32_t data_len)
+{
+ GUARD_PTR(s2n_stuffer_skip_read(stuffer, data_len));
+
+ stuffer->tainted = 1;
+
+ return stuffer->blob.data + stuffer->read_cursor - data_len;
+}
+
+int s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out)
+{
+ notnull_check(out);
+
+ return s2n_stuffer_read_bytes(stuffer, out->data, out->size);
+}
+
+int s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out)
+{
+ GUARD(s2n_stuffer_skip_read(stuffer, out->size));
+
+ void *ptr = stuffer->blob.data + stuffer->read_cursor - out->size;
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(ptr, out->size), S2N_ERR_NULL);
+
+ memcpy_check(out->data, ptr, out->size);
+ memset_check(ptr, 0, out->size);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t * data, uint32_t size)
+{
+ notnull_check(data);
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ GUARD(s2n_stuffer_skip_read(stuffer, size));
+ notnull_check(stuffer->blob.data);
+ void *ptr = stuffer->blob.data + stuffer->read_cursor - size;
+
+ memcpy_check(data, ptr, size);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t * data, uint32_t size)
+{
+ GUARD(s2n_stuffer_skip_read(stuffer, size));
+ notnull_check(stuffer->blob.data);
+ void *ptr = stuffer->blob.data + stuffer->read_cursor - size;
+
+ memcpy_check(data, ptr, size);
+ memset_check(ptr, 0, size);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ GUARD(s2n_stuffer_reserve_space(stuffer, n));
+ stuffer->write_cursor += n;
+ stuffer->high_water_mark = MAX(stuffer->write_cursor, stuffer->high_water_mark);
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+void *s2n_stuffer_raw_write(struct s2n_stuffer *stuffer, const uint32_t data_len)
+{
+ GUARD_PTR(s2n_stuffer_skip_write(stuffer, data_len));
+
+ stuffer->tainted = 1;
+
+ return stuffer->blob.data + stuffer->write_cursor - data_len;
+}
+
+int s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ PRECONDITION_POSIX(s2n_blob_validate(in));
+ return s2n_stuffer_write_bytes(stuffer, in->data, in->size);
+}
+
+int s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t * data, const uint32_t size)
+{
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(data, size), S2N_ERR_SAFETY);
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ GUARD(s2n_stuffer_skip_write(stuffer, size));
+
+ void *ptr = stuffer->blob.data + stuffer->write_cursor - size;
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(ptr, size), S2N_ERR_NULL);
+
+ if (ptr == data) {
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+ }
+
+ memcpy_check(ptr, data, size);
+
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec* iov, size_t iov_count, uint32_t offs, uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ notnull_check(iov);
+ void *ptr = s2n_stuffer_raw_write(stuffer, size);
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(ptr, size), S2N_ERR_NULL);
+
+ size_t size_left = size, to_skip = offs;
+ for (int i = 0; i < iov_count; i++) {
+ if (to_skip >= iov[i].iov_len) {
+ to_skip -= iov[i].iov_len;
+ continue;
+ }
+ size_t iov_len_op = iov[i].iov_len - to_skip;
+ ENSURE_POSIX(iov_len_op <= UINT32_MAX, S2N_FAILURE);
+ uint32_t iov_len = (uint32_t)iov_len_op;
+ uint32_t iov_size_to_take = MIN(size_left, iov_len);
+ notnull_check(iov[i].iov_base);
+ ENSURE_POSIX(to_skip < iov[i].iov_len, S2N_FAILURE);
+ memcpy_check(ptr, ((uint8_t*)(iov[i].iov_base)) + to_skip, iov_size_to_take);
+ size_left -= iov_size_to_take;
+ if (size_left == 0) {
+ break;
+ }
+ ptr = (void*)((uint8_t*)ptr + iov_size_to_take);
+ to_skip = 0;
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_stuffer_copy_impl(struct s2n_stuffer *from, struct s2n_stuffer *to, const uint32_t len)
+{
+ GUARD(s2n_stuffer_skip_read(from, len));
+ GUARD(s2n_stuffer_skip_write(to, len));
+
+ uint8_t *from_ptr = from->blob.data + from->read_cursor - len;
+ uint8_t *to_ptr = to->blob.data + to->write_cursor - len;
+
+ memcpy_check(to_ptr, from_ptr, len);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ if (s2n_stuffer_space_remaining(stuffer) < n) {
+ S2N_ERROR_IF(!stuffer->growable, S2N_ERR_STUFFER_IS_FULL);
+ /* Always grow a stuffer by at least 1k */
+ const uint32_t growth = MAX(n - s2n_stuffer_space_remaining(stuffer), S2N_MIN_STUFFER_GROWTH_IN_BYTES);
+ uint32_t new_size = 0;
+ GUARD(s2n_add_overflow(stuffer->blob.size, growth, &new_size));
+ GUARD(s2n_stuffer_resize(stuffer, new_size));
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+/* Copies "len" bytes from "from" to "to".
+ * If the copy cannot succeed (i.e. there are either not enough bytes available, or there is not enough space to write them
+ * restore the old value of the stuffer */
+int s2n_stuffer_copy(struct s2n_stuffer *from, struct s2n_stuffer *to, const uint32_t len)
+{
+ const uint32_t orig_read_cursor = from->read_cursor;
+ const uint32_t orig_write_cursor = to->write_cursor;
+
+ if (s2n_stuffer_copy_impl(from, to, len) < 0) {
+ from->read_cursor = orig_read_cursor;
+ to->write_cursor = orig_write_cursor;
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ notnull_check(out);
+ GUARD(s2n_realloc(out , s2n_stuffer_data_available(stuffer)));
+
+ if (s2n_stuffer_data_available(stuffer) > 0) {
+ memcpy_check(out->data,
+ stuffer->blob.data + stuffer->read_cursor,
+ s2n_stuffer_data_available(stuffer));
+ }
+
+ POSTCONDITION_POSIX(s2n_blob_validate(out));
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
index c67e1c4a73..54154fd74c 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer.h
@@ -1,169 +1,169 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#pragma once
-
-#include <limits.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/uio.h>
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-#define S2N_MIN_STUFFER_GROWTH_IN_BYTES 1024
-
-/* Using a non-zero value
- * (a) makes wiped data easy to see in the debugger
- * (b) makes use of wiped data obvious since this is unlikely to be a valid bit pattern
- */
-#define S2N_WIPE_PATTERN 'w'
-
-#define SIZEOF_IN_BITS( t ) (sizeof(t) * CHAR_BIT)
-
-#define SIZEOF_UINT24 3
-
-struct s2n_stuffer {
- /* The data for the s2n_stuffer */
- struct s2n_blob blob;
-
- /* Cursors to the current read/write position in the s2n_stuffer */
- uint32_t read_cursor;
- uint32_t write_cursor;
- uint32_t high_water_mark;
-
- /* Was this stuffer alloc()'d ? */
- unsigned int alloced:1;
-
- /* Is this stuffer growable? */
- unsigned int growable:1;
-
- /* Can this stuffer be safely resized?
- * A growable stuffer can be temporarily tainted by a raw read/write,
- * preventing it from resizing. */
- unsigned int tainted:1;
-};
-
-#define s2n_stuffer_data_available( s ) ((s)->write_cursor - (s)->read_cursor)
-#define s2n_stuffer_space_remaining( s ) ((s)->blob.size - (s)->write_cursor)
-#define s2n_stuffer_is_wiped( s ) ((s)->high_water_mark == 0)
-/* Check basic validity constraints on the stuffer: e.g. that cursors point within the blob */
-extern S2N_RESULT s2n_stuffer_validate(const struct s2n_stuffer* stuffer);
-
-/* Initialize and destroying stuffers */
-extern int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in);
-extern int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
-extern int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
-extern int s2n_stuffer_free(struct s2n_stuffer *stuffer);
-extern int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size);
-extern int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size);
-extern int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size);
-extern int s2n_stuffer_reread(struct s2n_stuffer *stuffer);
-extern int s2n_stuffer_rewrite(struct s2n_stuffer *stuffer);
-extern int s2n_stuffer_wipe(struct s2n_stuffer *stuffer);
-extern int s2n_stuffer_wipe_n(struct s2n_stuffer *stuffer, const uint32_t n);
-extern bool s2n_stuffer_is_consumed(struct s2n_stuffer *stuffer);
-
-/* Basic read and write */
-extern int s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
-extern int s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
-extern int s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in);
-extern int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t * out, uint32_t n);
-extern int s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t * data, uint32_t size);
-extern int s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t * in, const uint32_t n);
-extern int s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec* iov, size_t iov_count, uint32_t offs, uint32_t size);
-extern int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n);
-extern int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n);
-
-/* Tries to reserve enough space to write n additional bytes into the stuffer.*/
-extern int s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n);
-
-/* Raw read/write move the cursor along and give you a pointer you can
- * read/write data_len bytes from/to in-place.
- */
-extern void *s2n_stuffer_raw_write(struct s2n_stuffer *stuffer, const uint32_t data_len);
-extern void *s2n_stuffer_raw_read(struct s2n_stuffer *stuffer, uint32_t data_len);
-
-/* Send/receive stuffer to/from a file descriptor */
-extern int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const uint32_t len, uint32_t *bytes_written);
-extern int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent);
-
-/* Read and write integers in network order */
-extern int s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t * u);
-extern int s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t * u);
-extern int s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t * u);
-extern int s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t * u);
-extern int s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t * u);
-
-extern int s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u);
-extern int s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u);
-extern int s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u);
-extern int s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u);
-extern int s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u);
-
-/* Allocate space now for network order integers that will be written later.
- * These are primarily intended to handle the vector type defined in the RFC:
- * https://tools.ietf.org/html/rfc8446#section-3.4 */
-struct s2n_stuffer_reservation {
- struct s2n_stuffer *stuffer;
- uint32_t write_cursor;
- uint8_t length;
-};
-/* Check basic validity constraints on the s2n_stuffer_reservation: e.g. stuffer validity. */
-extern S2N_RESULT s2n_stuffer_reservation_validate(const struct s2n_stuffer_reservation* reservation);
-extern int s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
-extern int s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
-extern int s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation *reservation);
-
-/* Copy one stuffer to another */
-extern int s2n_stuffer_copy(struct s2n_stuffer *from, struct s2n_stuffer *to, uint32_t len);
-
-/* Read and write base64 */
-extern int s2n_stuffer_read_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *out);
-extern int s2n_stuffer_write_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *in);
-
-/* Useful for text manipulation ... */
-#define s2n_stuffer_write_char( stuffer, c ) s2n_stuffer_write_uint8( (stuffer), (uint8_t) (c) )
-#define s2n_stuffer_read_char( stuffer, c ) s2n_stuffer_read_uint8( (stuffer), (uint8_t *) (c) )
-#define s2n_stuffer_write_str( stuffer, c ) s2n_stuffer_write_bytes( (stuffer), (const uint8_t *) (c), strlen((c)) )
-#define s2n_stuffer_write_text( stuffer, c, n ) s2n_stuffer_write_bytes( (stuffer), (const uint8_t *) (c), (n) )
-#define s2n_stuffer_read_text( stuffer, c, n ) s2n_stuffer_read_bytes( (stuffer), (uint8_t *) (c), (n) )
-extern int s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char* expected);
-extern int s2n_stuffer_peek_char(struct s2n_stuffer *stuffer, char *c);
-extern int s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim);
-extern int s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token);
-extern int s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected);
-extern int s2n_stuffer_skip_whitespace(struct s2n_stuffer *stuffer, uint32_t *skipped);
-extern int s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, char target);
-extern int s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min, const uint32_t max, uint32_t *skipped);
-extern int s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char* target);
-extern int s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str);
-
-/* Read a private key from a PEM encoded stuffer to an ASN1/DER encoded one */
-extern int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
-
-/* Read a certificate from a PEM encoded stuffer to an ASN1/DER encoded one */
-extern int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
-
-/* Read DH parameters om a PEM encoded stuffer to a PKCS3 encoded one */
-extern int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3);
-
-extern bool s2n_is_base64_char(unsigned char c);
-
-/* Copies all valid data from "stuffer" into "out".
- * The old blob "out" pointed to is freed.
- * It is the responsibility of the caller to free the free "out".
- */
-extern int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out);
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#pragma once
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/uio.h>
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+#define S2N_MIN_STUFFER_GROWTH_IN_BYTES 1024
+
+/* Using a non-zero value
+ * (a) makes wiped data easy to see in the debugger
+ * (b) makes use of wiped data obvious since this is unlikely to be a valid bit pattern
+ */
+#define S2N_WIPE_PATTERN 'w'
+
+#define SIZEOF_IN_BITS( t ) (sizeof(t) * CHAR_BIT)
+
+#define SIZEOF_UINT24 3
+
+struct s2n_stuffer {
+ /* The data for the s2n_stuffer */
+ struct s2n_blob blob;
+
+ /* Cursors to the current read/write position in the s2n_stuffer */
+ uint32_t read_cursor;
+ uint32_t write_cursor;
+ uint32_t high_water_mark;
+
+ /* Was this stuffer alloc()'d ? */
+ unsigned int alloced:1;
+
+ /* Is this stuffer growable? */
+ unsigned int growable:1;
+
+ /* Can this stuffer be safely resized?
+ * A growable stuffer can be temporarily tainted by a raw read/write,
+ * preventing it from resizing. */
+ unsigned int tainted:1;
+};
+
+#define s2n_stuffer_data_available( s ) ((s)->write_cursor - (s)->read_cursor)
+#define s2n_stuffer_space_remaining( s ) ((s)->blob.size - (s)->write_cursor)
+#define s2n_stuffer_is_wiped( s ) ((s)->high_water_mark == 0)
+/* Check basic validity constraints on the stuffer: e.g. that cursors point within the blob */
+extern S2N_RESULT s2n_stuffer_validate(const struct s2n_stuffer* stuffer);
+
+/* Initialize and destroying stuffers */
+extern int s2n_stuffer_init(struct s2n_stuffer *stuffer, struct s2n_blob *in);
+extern int s2n_stuffer_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
+extern int s2n_stuffer_growable_alloc(struct s2n_stuffer *stuffer, const uint32_t size);
+extern int s2n_stuffer_free(struct s2n_stuffer *stuffer);
+extern int s2n_stuffer_resize(struct s2n_stuffer *stuffer, const uint32_t size);
+extern int s2n_stuffer_resize_if_empty(struct s2n_stuffer *stuffer, const uint32_t size);
+extern int s2n_stuffer_rewind_read(struct s2n_stuffer *stuffer, const uint32_t size);
+extern int s2n_stuffer_reread(struct s2n_stuffer *stuffer);
+extern int s2n_stuffer_rewrite(struct s2n_stuffer *stuffer);
+extern int s2n_stuffer_wipe(struct s2n_stuffer *stuffer);
+extern int s2n_stuffer_wipe_n(struct s2n_stuffer *stuffer, const uint32_t n);
+extern bool s2n_stuffer_is_consumed(struct s2n_stuffer *stuffer);
+
+/* Basic read and write */
+extern int s2n_stuffer_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
+extern int s2n_stuffer_erase_and_read(struct s2n_stuffer *stuffer, struct s2n_blob *out);
+extern int s2n_stuffer_write(struct s2n_stuffer *stuffer, const struct s2n_blob *in);
+extern int s2n_stuffer_read_bytes(struct s2n_stuffer *stuffer, uint8_t * out, uint32_t n);
+extern int s2n_stuffer_erase_and_read_bytes(struct s2n_stuffer *stuffer, uint8_t * data, uint32_t size);
+extern int s2n_stuffer_write_bytes(struct s2n_stuffer *stuffer, const uint8_t * in, const uint32_t n);
+extern int s2n_stuffer_writev_bytes(struct s2n_stuffer *stuffer, const struct iovec* iov, size_t iov_count, uint32_t offs, uint32_t size);
+extern int s2n_stuffer_skip_read(struct s2n_stuffer *stuffer, uint32_t n);
+extern int s2n_stuffer_skip_write(struct s2n_stuffer *stuffer, const uint32_t n);
+
+/* Tries to reserve enough space to write n additional bytes into the stuffer.*/
+extern int s2n_stuffer_reserve_space(struct s2n_stuffer *stuffer, uint32_t n);
+
+/* Raw read/write move the cursor along and give you a pointer you can
+ * read/write data_len bytes from/to in-place.
+ */
+extern void *s2n_stuffer_raw_write(struct s2n_stuffer *stuffer, const uint32_t data_len);
+extern void *s2n_stuffer_raw_read(struct s2n_stuffer *stuffer, uint32_t data_len);
+
+/* Send/receive stuffer to/from a file descriptor */
+extern int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const uint32_t len, uint32_t *bytes_written);
+extern int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent);
+
+/* Read and write integers in network order */
+extern int s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t * u);
+extern int s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t * u);
+extern int s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t * u);
+extern int s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t * u);
+extern int s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t * u);
+
+extern int s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u);
+extern int s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u);
+extern int s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u);
+extern int s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u);
+extern int s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u);
+
+/* Allocate space now for network order integers that will be written later.
+ * These are primarily intended to handle the vector type defined in the RFC:
+ * https://tools.ietf.org/html/rfc8446#section-3.4 */
+struct s2n_stuffer_reservation {
+ struct s2n_stuffer *stuffer;
+ uint32_t write_cursor;
+ uint8_t length;
+};
+/* Check basic validity constraints on the s2n_stuffer_reservation: e.g. stuffer validity. */
+extern S2N_RESULT s2n_stuffer_reservation_validate(const struct s2n_stuffer_reservation* reservation);
+extern int s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
+extern int s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation);
+extern int s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation *reservation);
+
+/* Copy one stuffer to another */
+extern int s2n_stuffer_copy(struct s2n_stuffer *from, struct s2n_stuffer *to, uint32_t len);
+
+/* Read and write base64 */
+extern int s2n_stuffer_read_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *out);
+extern int s2n_stuffer_write_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *in);
+
+/* Useful for text manipulation ... */
+#define s2n_stuffer_write_char( stuffer, c ) s2n_stuffer_write_uint8( (stuffer), (uint8_t) (c) )
+#define s2n_stuffer_read_char( stuffer, c ) s2n_stuffer_read_uint8( (stuffer), (uint8_t *) (c) )
+#define s2n_stuffer_write_str( stuffer, c ) s2n_stuffer_write_bytes( (stuffer), (const uint8_t *) (c), strlen((c)) )
+#define s2n_stuffer_write_text( stuffer, c, n ) s2n_stuffer_write_bytes( (stuffer), (const uint8_t *) (c), (n) )
+#define s2n_stuffer_read_text( stuffer, c, n ) s2n_stuffer_read_bytes( (stuffer), (uint8_t *) (c), (n) )
+extern int s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char* expected);
+extern int s2n_stuffer_peek_char(struct s2n_stuffer *stuffer, char *c);
+extern int s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim);
+extern int s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token);
+extern int s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected);
+extern int s2n_stuffer_skip_whitespace(struct s2n_stuffer *stuffer, uint32_t *skipped);
+extern int s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, char target);
+extern int s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min, const uint32_t max, uint32_t *skipped);
+extern int s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char* target);
+extern int s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str);
+
+/* Read a private key from a PEM encoded stuffer to an ASN1/DER encoded one */
+extern int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
+
+/* Read a certificate from a PEM encoded stuffer to an ASN1/DER encoded one */
+extern int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1);
+
+/* Read DH parameters om a PEM encoded stuffer to a PKCS3 encoded one */
+extern int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3);
+
+extern bool s2n_is_base64_char(unsigned char c);
+
+/* Copies all valid data from "stuffer" into "out".
+ * The old blob "out" pointed to is freed.
+ * It is the responsibility of the caller to free the free "out".
+ */
+extern int s2n_stuffer_extract_blob(struct s2n_stuffer *stuffer, struct s2n_blob *out);
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_base64.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_base64.c
index bb156ac5f5..d091c7b12b 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_base64.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_base64.c
@@ -1,209 +1,209 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#include <string.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-static const uint8_t b64[64] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
-};
-
-/* Generated with this python:
- *
- * b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
- *
- * for i in range(0, 256):
- * if chr(i) in b64:
- * print str(b64.index(chr(i))) + ", ",
- * else:
- * print "255, ",
- *
- * if (i + 1) % 16 == 0:
- * print
- *
- * Note that '=' maps to 64.
- */
-static const uint8_t b64_inverse[256] = {
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
- 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
- 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
-};
-
-bool s2n_is_base64_char(unsigned char c)
-{
- return (b64_inverse[*((uint8_t*)(&c))] != 255);
-}
-
-/**
- * NOTE:
- * In general, shift before masking. This avoids needing to worry about how the
- * signed bit may be handled.
- */
-int s2n_stuffer_read_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *out)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- PRECONDITION_POSIX(s2n_stuffer_validate(out));
- int bytes_this_round = 3;
- s2n_stack_blob(o, 4, 4);
-
- do {
- if (s2n_stuffer_data_available(stuffer) < o.size) {
- break;
- }
-
- GUARD(s2n_stuffer_read(stuffer, &o));
-
- uint8_t value1 = b64_inverse[o.data[0]];
- uint8_t value2 = b64_inverse[o.data[1]];
- uint8_t value3 = b64_inverse[o.data[2]];
- uint8_t value4 = b64_inverse[o.data[3]];
-
- /* We assume the entire thing is base64 data, thus, terminate cleanly if we encounter a non-base64 character */
- if (value1 == 255) {
- /* Undo the read */
- stuffer->read_cursor -= o.size;
- S2N_ERROR(S2N_ERR_INVALID_BASE64);
- }
-
- /* The first two characters can never be '=' and in general
- * everything has to be a valid character.
- */
- S2N_ERROR_IF(value1 == 64 || value2 == 64 || value2 == 255 || value3 == 255 || value4 == 255, S2N_ERR_INVALID_BASE64);
-
- if (o.data[2] == '=') {
- /* If there is only one output byte, then the second value
- * should have none of its bottom four bits set.
- */
- S2N_ERROR_IF(o.data[3] != '=' || value2 & 0x0f, S2N_ERR_INVALID_BASE64);
- bytes_this_round = 1;
- value3 = 0;
- value4 = 0;
- } else if (o.data[3] == '=') {
- /* The last two bits of the final value should be unset */
- S2N_ERROR_IF(value3 & 0x03, S2N_ERR_INVALID_BASE64);
-
- bytes_this_round = 2;
- value4 = 0;
- }
-
- /* Advance by bytes_this_round, and then fill in the data */
- GUARD(s2n_stuffer_skip_write(out, bytes_this_round));
- uint8_t *ptr = out->blob.data + out->write_cursor - bytes_this_round;
-
- /* value1 maps to the first 6 bits of the first data byte */
- /* value2's top two bits are the rest */
- *ptr = ((value1 << 2) & 0xfc) | ((value2 >> 4) & 0x03);
-
- if (bytes_this_round > 1) {
- /* Put the next four bits in the second data byte */
- /* Put the next four bits in the third data byte */
- ptr++;
- *ptr = ((value2 << 4) & 0xf0) | ((value3 >> 2) & 0x0f);
- }
-
- if (bytes_this_round > 2) {
- /* Put the next two bits in the third data byte */
- /* Put the next six bits in the fourth data byte */
- ptr++;
- *ptr = ((value3 << 6) & 0xc0) | (value4 & 0x3f);
- }
- } while (bytes_this_round == 3);
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *in)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- PRECONDITION_POSIX(s2n_stuffer_validate(in));
- s2n_stack_blob(o, 4, 4);
- s2n_stack_blob(i, 3, 3);
-
- while (s2n_stuffer_data_available(in) > 2) {
- GUARD(s2n_stuffer_read(in, &i));
-
- /* Take the top 6-bits of the first data byte */
- o.data[0] = b64[(i.data[0] >> 2) & 0x3f];
-
- /* Take the bottom 2-bits of the first data byte - 0b00110000 = 0x30
- * and take the top 4-bits of the second data byte - 0b00001111 = 0x0f
- */
- o.data[1] = b64[((i.data[0] << 4) & 0x30) | ((i.data[1] >> 4) & 0x0f)];
-
- /* Take the bottom 4-bits of the second data byte - 0b00111100 = 0x3c
- * and take the top 2-bits of the third data byte - 0b00000011 = 0x03
- */
- o.data[2] = b64[((i.data[1] << 2) & 0x3c) | ((i.data[2] >> 6) & 0x03)];
-
- /* Take the bottom 6-bits of the second data byte - 0b00111111 = 0x3f
- */
- o.data[3] = b64[i.data[2] & 0x3f];
-
- GUARD(s2n_stuffer_write(stuffer, &o));
- }
-
- if (s2n_stuffer_data_available(in)) {
- /* Read just one byte */
- i.size = 1;
- GUARD(s2n_stuffer_read(in, &i));
- uint8_t c = i.data[0];
-
- /* We at least one data byte left to encode, encode
- * its first six bits
- */
- o.data[0] = b64[(c >> 2) & 0x3f];
-
- /* And our end has to be an equals */
- o.data[3] = '=';
-
- /* How many bytes are actually left? */
- if (s2n_stuffer_data_available(in) == 0) {
- /* We just have the last two bits to deal with */
- o.data[1] = b64[(c << 4) & 0x30];
- o.data[2] = '=';
- } else {
- /* Read the last byte */
- GUARD(s2n_stuffer_read(in, &i));
-
- o.data[1] = b64[((c << 4) & 0x30) | ((i.data[0] >> 4) & 0x0f)];
- o.data[2] = b64[((i.data[0] << 2) & 0x3c)];
- }
-
- GUARD(s2n_stuffer_write(stuffer, &o));
- }
-
- return S2N_SUCCESS;
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <string.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+static const uint8_t b64[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
+
+/* Generated with this python:
+ *
+ * b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ *
+ * for i in range(0, 256):
+ * if chr(i) in b64:
+ * print str(b64.index(chr(i))) + ", ",
+ * else:
+ * print "255, ",
+ *
+ * if (i + 1) % 16 == 0:
+ * print
+ *
+ * Note that '=' maps to 64.
+ */
+static const uint8_t b64_inverse[256] = {
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 64, 255, 255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
+};
+
+bool s2n_is_base64_char(unsigned char c)
+{
+ return (b64_inverse[*((uint8_t*)(&c))] != 255);
+}
+
+/**
+ * NOTE:
+ * In general, shift before masking. This avoids needing to worry about how the
+ * signed bit may be handled.
+ */
+int s2n_stuffer_read_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *out)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ PRECONDITION_POSIX(s2n_stuffer_validate(out));
+ int bytes_this_round = 3;
+ s2n_stack_blob(o, 4, 4);
+
+ do {
+ if (s2n_stuffer_data_available(stuffer) < o.size) {
+ break;
+ }
+
+ GUARD(s2n_stuffer_read(stuffer, &o));
+
+ uint8_t value1 = b64_inverse[o.data[0]];
+ uint8_t value2 = b64_inverse[o.data[1]];
+ uint8_t value3 = b64_inverse[o.data[2]];
+ uint8_t value4 = b64_inverse[o.data[3]];
+
+ /* We assume the entire thing is base64 data, thus, terminate cleanly if we encounter a non-base64 character */
+ if (value1 == 255) {
+ /* Undo the read */
+ stuffer->read_cursor -= o.size;
+ S2N_ERROR(S2N_ERR_INVALID_BASE64);
+ }
+
+ /* The first two characters can never be '=' and in general
+ * everything has to be a valid character.
+ */
+ S2N_ERROR_IF(value1 == 64 || value2 == 64 || value2 == 255 || value3 == 255 || value4 == 255, S2N_ERR_INVALID_BASE64);
+
+ if (o.data[2] == '=') {
+ /* If there is only one output byte, then the second value
+ * should have none of its bottom four bits set.
+ */
+ S2N_ERROR_IF(o.data[3] != '=' || value2 & 0x0f, S2N_ERR_INVALID_BASE64);
+ bytes_this_round = 1;
+ value3 = 0;
+ value4 = 0;
+ } else if (o.data[3] == '=') {
+ /* The last two bits of the final value should be unset */
+ S2N_ERROR_IF(value3 & 0x03, S2N_ERR_INVALID_BASE64);
+
+ bytes_this_round = 2;
+ value4 = 0;
+ }
+
+ /* Advance by bytes_this_round, and then fill in the data */
+ GUARD(s2n_stuffer_skip_write(out, bytes_this_round));
+ uint8_t *ptr = out->blob.data + out->write_cursor - bytes_this_round;
+
+ /* value1 maps to the first 6 bits of the first data byte */
+ /* value2's top two bits are the rest */
+ *ptr = ((value1 << 2) & 0xfc) | ((value2 >> 4) & 0x03);
+
+ if (bytes_this_round > 1) {
+ /* Put the next four bits in the second data byte */
+ /* Put the next four bits in the third data byte */
+ ptr++;
+ *ptr = ((value2 << 4) & 0xf0) | ((value3 >> 2) & 0x0f);
+ }
+
+ if (bytes_this_round > 2) {
+ /* Put the next two bits in the third data byte */
+ /* Put the next six bits in the fourth data byte */
+ ptr++;
+ *ptr = ((value3 << 6) & 0xc0) | (value4 & 0x3f);
+ }
+ } while (bytes_this_round == 3);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_base64(struct s2n_stuffer *stuffer, struct s2n_stuffer *in)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ PRECONDITION_POSIX(s2n_stuffer_validate(in));
+ s2n_stack_blob(o, 4, 4);
+ s2n_stack_blob(i, 3, 3);
+
+ while (s2n_stuffer_data_available(in) > 2) {
+ GUARD(s2n_stuffer_read(in, &i));
+
+ /* Take the top 6-bits of the first data byte */
+ o.data[0] = b64[(i.data[0] >> 2) & 0x3f];
+
+ /* Take the bottom 2-bits of the first data byte - 0b00110000 = 0x30
+ * and take the top 4-bits of the second data byte - 0b00001111 = 0x0f
+ */
+ o.data[1] = b64[((i.data[0] << 4) & 0x30) | ((i.data[1] >> 4) & 0x0f)];
+
+ /* Take the bottom 4-bits of the second data byte - 0b00111100 = 0x3c
+ * and take the top 2-bits of the third data byte - 0b00000011 = 0x03
+ */
+ o.data[2] = b64[((i.data[1] << 2) & 0x3c) | ((i.data[2] >> 6) & 0x03)];
+
+ /* Take the bottom 6-bits of the second data byte - 0b00111111 = 0x3f
+ */
+ o.data[3] = b64[i.data[2] & 0x3f];
+
+ GUARD(s2n_stuffer_write(stuffer, &o));
+ }
+
+ if (s2n_stuffer_data_available(in)) {
+ /* Read just one byte */
+ i.size = 1;
+ GUARD(s2n_stuffer_read(in, &i));
+ uint8_t c = i.data[0];
+
+ /* We at least one data byte left to encode, encode
+ * its first six bits
+ */
+ o.data[0] = b64[(c >> 2) & 0x3f];
+
+ /* And our end has to be an equals */
+ o.data[3] = '=';
+
+ /* How many bytes are actually left? */
+ if (s2n_stuffer_data_available(in) == 0) {
+ /* We just have the last two bits to deal with */
+ o.data[1] = b64[(c << 4) & 0x30];
+ o.data[2] = '=';
+ } else {
+ /* Read the last byte */
+ GUARD(s2n_stuffer_read(in, &i));
+
+ o.data[1] = b64[((c << 4) & 0x30) | ((i.data[0] >> 4) & 0x0f)];
+ o.data[2] = b64[((i.data[0] << 2) & 0x3c)];
+ }
+
+ GUARD(s2n_stuffer_write(stuffer, &o));
+ }
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_file.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_file.c
index b86e725604..2385572123 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_file.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_file.c
@@ -1,107 +1,107 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const uint32_t len, uint32_t *bytes_written)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- /* Make sure we have enough space to write */
- GUARD(s2n_stuffer_skip_write(stuffer, len));
-
- /* "undo" the skip write */
- stuffer->write_cursor -= len;
-
- ssize_t r = 0;
- do {
- r = read(rfd, stuffer->blob.data + stuffer->write_cursor, len);
- S2N_ERROR_IF(r < 0 && errno != EINTR, S2N_ERR_READ);
- } while (r < 0);
-
- /* Record just how many bytes we have written */
- S2N_ERROR_IF(r > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
- GUARD(s2n_stuffer_skip_write(stuffer, (uint32_t)r));
- if (bytes_written != NULL) *bytes_written = r;
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
-
- /* Make sure we even have the data */
- GUARD(s2n_stuffer_skip_read(stuffer, len));
-
- /* "undo" the skip read */
- stuffer->read_cursor -= len;
-
- ssize_t w = 0;
- do {
- w = write(wfd, stuffer->blob.data + stuffer->read_cursor, len);
- S2N_ERROR_IF(w < 0 && errno != EINTR, S2N_ERR_WRITE);
- } while (w < 0);
-
- S2N_ERROR_IF(w > UINT32_MAX - stuffer->read_cursor, S2N_ERR_INTEGER_OVERFLOW);
- stuffer->read_cursor += w;
- if (bytes_sent != NULL) *bytes_sent = w;
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_alloc_ro_from_fd(struct s2n_stuffer *stuffer, int rfd)
-{
- ENSURE_POSIX_MUT(stuffer);
- struct stat st = {0};
-
- ENSURE_POSIX(fstat(rfd, &st) >= 0, S2N_ERR_FSTAT);
-
- ENSURE_POSIX(st.st_size > 0, S2N_FAILURE);
- ENSURE_POSIX(st.st_size <= UINT32_MAX, S2N_FAILURE);
-
- uint8_t *map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, rfd, 0);
- ENSURE_POSIX(map != MAP_FAILED, S2N_ERR_MMAP);
-
- struct s2n_blob b = {0};
- ENSURE_POSIX(s2n_blob_init(&b, map, (uint32_t)st.st_size), S2N_FAILURE);
- return s2n_stuffer_init(stuffer, &b);
-}
-
-int s2n_stuffer_alloc_ro_from_file(struct s2n_stuffer *stuffer, const char *file)
-{
- ENSURE_POSIX_MUT(stuffer);
- notnull_check(file);
- int fd;
-
- do {
- fd = open(file, O_RDONLY);
- ENSURE_POSIX(fd >= 0 || errno == EINTR, S2N_ERR_OPEN);
- } while (fd < 0);
-
- int r = s2n_stuffer_alloc_ro_from_fd(stuffer, fd);
-
- GUARD(close(fd));
-
- return r;
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const uint32_t len, uint32_t *bytes_written)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ /* Make sure we have enough space to write */
+ GUARD(s2n_stuffer_skip_write(stuffer, len));
+
+ /* "undo" the skip write */
+ stuffer->write_cursor -= len;
+
+ ssize_t r = 0;
+ do {
+ r = read(rfd, stuffer->blob.data + stuffer->write_cursor, len);
+ S2N_ERROR_IF(r < 0 && errno != EINTR, S2N_ERR_READ);
+ } while (r < 0);
+
+ /* Record just how many bytes we have written */
+ S2N_ERROR_IF(r > UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ GUARD(s2n_stuffer_skip_write(stuffer, (uint32_t)r));
+ if (bytes_written != NULL) *bytes_written = r;
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+
+ /* Make sure we even have the data */
+ GUARD(s2n_stuffer_skip_read(stuffer, len));
+
+ /* "undo" the skip read */
+ stuffer->read_cursor -= len;
+
+ ssize_t w = 0;
+ do {
+ w = write(wfd, stuffer->blob.data + stuffer->read_cursor, len);
+ S2N_ERROR_IF(w < 0 && errno != EINTR, S2N_ERR_WRITE);
+ } while (w < 0);
+
+ S2N_ERROR_IF(w > UINT32_MAX - stuffer->read_cursor, S2N_ERR_INTEGER_OVERFLOW);
+ stuffer->read_cursor += w;
+ if (bytes_sent != NULL) *bytes_sent = w;
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_alloc_ro_from_fd(struct s2n_stuffer *stuffer, int rfd)
+{
+ ENSURE_POSIX_MUT(stuffer);
+ struct stat st = {0};
+
+ ENSURE_POSIX(fstat(rfd, &st) >= 0, S2N_ERR_FSTAT);
+
+ ENSURE_POSIX(st.st_size > 0, S2N_FAILURE);
+ ENSURE_POSIX(st.st_size <= UINT32_MAX, S2N_FAILURE);
+
+ uint8_t *map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, rfd, 0);
+ ENSURE_POSIX(map != MAP_FAILED, S2N_ERR_MMAP);
+
+ struct s2n_blob b = {0};
+ ENSURE_POSIX(s2n_blob_init(&b, map, (uint32_t)st.st_size), S2N_FAILURE);
+ return s2n_stuffer_init(stuffer, &b);
+}
+
+int s2n_stuffer_alloc_ro_from_file(struct s2n_stuffer *stuffer, const char *file)
+{
+ ENSURE_POSIX_MUT(stuffer);
+ notnull_check(file);
+ int fd;
+
+ do {
+ fd = open(file, O_RDONLY);
+ ENSURE_POSIX(fd >= 0 || errno == EINTR, S2N_ERR_OPEN);
+ } while (fd < 0);
+
+ int r = s2n_stuffer_alloc_ro_from_fd(stuffer, fd);
+
+ GUARD(close(fd));
+
+ return r;
+}
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_network_order.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_network_order.c
index f30c10e82f..d86e8e538a 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_network_order.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_network_order.c
@@ -1,197 +1,197 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_annotations.h"
-#include "utils/s2n_safety.h"
-
-/* Writes length bytes of input to stuffer, in network order, starting from the smallest byte of input. */
-int s2n_stuffer_write_network_order(struct s2n_stuffer *stuffer, const uint64_t input, const uint8_t length)
-{
- ENSURE_POSIX(length <= sizeof(input), S2N_ERR_SAFETY);
- GUARD(s2n_stuffer_skip_write(stuffer, length));
- uint8_t *data = stuffer->blob.data + stuffer->write_cursor - length;
-
- for (int i = 0; i < length; i++) {
- S2N_INVARIENT(i <= length);
- uint8_t shift = (length - i - 1) * CHAR_BIT;
- data[i] = (input >> (shift)) & UINT8_MAX;
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_reserve(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation, const uint8_t length)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- notnull_check(reservation);
-
- *reservation = (struct s2n_stuffer_reservation) {.stuffer = stuffer, .write_cursor = stuffer->write_cursor, .length = length};
-
- GUARD(s2n_stuffer_skip_write(stuffer, reservation->length));
- memset_check(stuffer->blob.data + reservation->write_cursor, S2N_WIPE_PATTERN, reservation->length);
- POSTCONDITION_POSIX(s2n_stuffer_reservation_validate(reservation));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t * u)
-{
- GUARD(s2n_stuffer_read_bytes(stuffer, u, sizeof(uint8_t)));
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u)
-{
- GUARD(s2n_stuffer_write_bytes(stuffer, &u, sizeof(u)));
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t * u)
-{
- notnull_check(u);
- uint8_t data[sizeof(uint16_t)];
-
- GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
-
- *u = data[0] << 8;
- *u |= data[1];
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u)
-{
- return s2n_stuffer_write_network_order(stuffer, u, sizeof(u));
-}
-
-int s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation)
-{
- return s2n_stuffer_reserve(stuffer, reservation, sizeof(uint16_t));
-}
-
-int s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t * u)
-{
- notnull_check(u);
- uint8_t data[SIZEOF_UINT24];
-
- GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
-
- *u = data[0] << 16;
- *u |= data[1] << 8;
- *u |= data[2];
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u)
-{
- return s2n_stuffer_write_network_order(stuffer, u, SIZEOF_UINT24);
-}
-
-int s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation)
-{
- return s2n_stuffer_reserve(stuffer, reservation, SIZEOF_UINT24);
-}
-
-int s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t * u)
-{
- notnull_check(u);
- uint8_t data[sizeof(uint32_t)];
-
- GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
-
- *u = ((uint32_t) data[0]) << 24;
- *u |= data[1] << 16;
- *u |= data[2] << 8;
- *u |= data[3];
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u)
-{
- return s2n_stuffer_write_network_order(stuffer, u, sizeof(u));
-}
-
-int s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t * u)
-{
- notnull_check(u);
- uint8_t data[sizeof(uint64_t)];
-
- GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
-
- *u = ((uint64_t) data[0]) << 56;
- *u |= ((uint64_t) data[1]) << 48;
- *u |= ((uint64_t) data[2]) << 40;
- *u |= ((uint64_t) data[3]) << 32;
- *u |= ((uint64_t) data[4]) << 24;
- *u |= ((uint64_t) data[5]) << 16;
- *u |= ((uint64_t) data[6]) << 8;
- *u |= data[7];
-
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u)
-{
- return s2n_stuffer_write_network_order(stuffer, u, sizeof(u));
-}
-
-static int length_matches_value_check(uint32_t value, uint8_t length)
-{
- /* Value is represented as a uint32_t, so shouldn't be assumed larger */
- S2N_ERROR_IF(length > sizeof(uint32_t), S2N_ERR_SIZE_MISMATCH);
-
- if (length < sizeof(uint32_t)) {
- /* Value should be less than the maximum for its length */
- S2N_ERROR_IF(value >= (0x01 << (length * 8)), S2N_ERR_SIZE_MISMATCH);
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_stuffer_write_reservation_impl(struct s2n_stuffer_reservation* reservation, const uint32_t u)
-{
- reservation->stuffer->write_cursor = reservation->write_cursor;
- PRECONDITION_POSIX(s2n_stuffer_validate(reservation->stuffer));
-
- GUARD(length_matches_value_check(u, reservation->length));
- GUARD(s2n_stuffer_write_network_order(reservation->stuffer, u, reservation->length));
- POSTCONDITION_POSIX(s2n_stuffer_validate(reservation->stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_write_reservation(struct s2n_stuffer_reservation* reservation, const uint32_t u)
-{
- PRECONDITION_POSIX(s2n_stuffer_reservation_validate(reservation));
- uint32_t old_write_cursor = reservation->stuffer->write_cursor;
- int result = s2n_stuffer_write_reservation_impl(reservation, u);
- reservation->stuffer->write_cursor = old_write_cursor;
- return result;
-}
-
-int s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation* reservation)
-{
- PRECONDITION_POSIX(s2n_stuffer_reservation_validate(reservation));
- uint32_t size = 0;
- GUARD(s2n_sub_overflow(reservation->stuffer->write_cursor, reservation->write_cursor, &size));
- GUARD(s2n_sub_overflow(size, reservation->length, &size));
- return s2n_stuffer_write_reservation(reservation, size);
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_annotations.h"
+#include "utils/s2n_safety.h"
+
+/* Writes length bytes of input to stuffer, in network order, starting from the smallest byte of input. */
+int s2n_stuffer_write_network_order(struct s2n_stuffer *stuffer, const uint64_t input, const uint8_t length)
+{
+ ENSURE_POSIX(length <= sizeof(input), S2N_ERR_SAFETY);
+ GUARD(s2n_stuffer_skip_write(stuffer, length));
+ uint8_t *data = stuffer->blob.data + stuffer->write_cursor - length;
+
+ for (int i = 0; i < length; i++) {
+ S2N_INVARIENT(i <= length);
+ uint8_t shift = (length - i - 1) * CHAR_BIT;
+ data[i] = (input >> (shift)) & UINT8_MAX;
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_reserve(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation, const uint8_t length)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ notnull_check(reservation);
+
+ *reservation = (struct s2n_stuffer_reservation) {.stuffer = stuffer, .write_cursor = stuffer->write_cursor, .length = length};
+
+ GUARD(s2n_stuffer_skip_write(stuffer, reservation->length));
+ memset_check(stuffer->blob.data + reservation->write_cursor, S2N_WIPE_PATTERN, reservation->length);
+ POSTCONDITION_POSIX(s2n_stuffer_reservation_validate(reservation));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_read_uint8(struct s2n_stuffer *stuffer, uint8_t * u)
+{
+ GUARD(s2n_stuffer_read_bytes(stuffer, u, sizeof(uint8_t)));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_uint8(struct s2n_stuffer *stuffer, const uint8_t u)
+{
+ GUARD(s2n_stuffer_write_bytes(stuffer, &u, sizeof(u)));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_read_uint16(struct s2n_stuffer *stuffer, uint16_t * u)
+{
+ notnull_check(u);
+ uint8_t data[sizeof(uint16_t)];
+
+ GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
+
+ *u = data[0] << 8;
+ *u |= data[1];
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_uint16(struct s2n_stuffer *stuffer, const uint16_t u)
+{
+ return s2n_stuffer_write_network_order(stuffer, u, sizeof(u));
+}
+
+int s2n_stuffer_reserve_uint16(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation)
+{
+ return s2n_stuffer_reserve(stuffer, reservation, sizeof(uint16_t));
+}
+
+int s2n_stuffer_read_uint24(struct s2n_stuffer *stuffer, uint32_t * u)
+{
+ notnull_check(u);
+ uint8_t data[SIZEOF_UINT24];
+
+ GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
+
+ *u = data[0] << 16;
+ *u |= data[1] << 8;
+ *u |= data[2];
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_uint24(struct s2n_stuffer *stuffer, const uint32_t u)
+{
+ return s2n_stuffer_write_network_order(stuffer, u, SIZEOF_UINT24);
+}
+
+int s2n_stuffer_reserve_uint24(struct s2n_stuffer *stuffer, struct s2n_stuffer_reservation *reservation)
+{
+ return s2n_stuffer_reserve(stuffer, reservation, SIZEOF_UINT24);
+}
+
+int s2n_stuffer_read_uint32(struct s2n_stuffer *stuffer, uint32_t * u)
+{
+ notnull_check(u);
+ uint8_t data[sizeof(uint32_t)];
+
+ GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
+
+ *u = ((uint32_t) data[0]) << 24;
+ *u |= data[1] << 16;
+ *u |= data[2] << 8;
+ *u |= data[3];
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_uint32(struct s2n_stuffer *stuffer, const uint32_t u)
+{
+ return s2n_stuffer_write_network_order(stuffer, u, sizeof(u));
+}
+
+int s2n_stuffer_read_uint64(struct s2n_stuffer *stuffer, uint64_t * u)
+{
+ notnull_check(u);
+ uint8_t data[sizeof(uint64_t)];
+
+ GUARD(s2n_stuffer_read_bytes(stuffer, data, sizeof(data)));
+
+ *u = ((uint64_t) data[0]) << 56;
+ *u |= ((uint64_t) data[1]) << 48;
+ *u |= ((uint64_t) data[2]) << 40;
+ *u |= ((uint64_t) data[3]) << 32;
+ *u |= ((uint64_t) data[4]) << 24;
+ *u |= ((uint64_t) data[5]) << 16;
+ *u |= ((uint64_t) data[6]) << 8;
+ *u |= data[7];
+
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_uint64(struct s2n_stuffer *stuffer, const uint64_t u)
+{
+ return s2n_stuffer_write_network_order(stuffer, u, sizeof(u));
+}
+
+static int length_matches_value_check(uint32_t value, uint8_t length)
+{
+ /* Value is represented as a uint32_t, so shouldn't be assumed larger */
+ S2N_ERROR_IF(length > sizeof(uint32_t), S2N_ERR_SIZE_MISMATCH);
+
+ if (length < sizeof(uint32_t)) {
+ /* Value should be less than the maximum for its length */
+ S2N_ERROR_IF(value >= (0x01 << (length * 8)), S2N_ERR_SIZE_MISMATCH);
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_stuffer_write_reservation_impl(struct s2n_stuffer_reservation* reservation, const uint32_t u)
+{
+ reservation->stuffer->write_cursor = reservation->write_cursor;
+ PRECONDITION_POSIX(s2n_stuffer_validate(reservation->stuffer));
+
+ GUARD(length_matches_value_check(u, reservation->length));
+ GUARD(s2n_stuffer_write_network_order(reservation->stuffer, u, reservation->length));
+ POSTCONDITION_POSIX(s2n_stuffer_validate(reservation->stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_write_reservation(struct s2n_stuffer_reservation* reservation, const uint32_t u)
+{
+ PRECONDITION_POSIX(s2n_stuffer_reservation_validate(reservation));
+ uint32_t old_write_cursor = reservation->stuffer->write_cursor;
+ int result = s2n_stuffer_write_reservation_impl(reservation, u);
+ reservation->stuffer->write_cursor = old_write_cursor;
+ return result;
+}
+
+int s2n_stuffer_write_vector_size(struct s2n_stuffer_reservation* reservation)
+{
+ PRECONDITION_POSIX(s2n_stuffer_reservation_validate(reservation));
+ uint32_t size = 0;
+ GUARD(s2n_sub_overflow(reservation->stuffer->write_cursor, reservation->write_cursor, &size));
+ GUARD(s2n_sub_overflow(size, reservation->length, &size));
+ return s2n_stuffer_write_reservation(reservation, size);
+}
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c
index a0805980c2..2028d9a6a6 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_pem.c
@@ -1,171 +1,171 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#include <string.h>
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-
-#define S2N_PEM_DELIMTER_CHAR '-'
-#define S2N_PEM_DELIMITER_MIN_COUNT 1
-#define S2N_PEM_DELIMITER_MAX_COUNT 64
-#define S2N_PEM_BEGIN_TOKEN "BEGIN "
-#define S2N_PEM_END_TOKEN "END "
-#define S2N_PEM_PKCS1_RSA_PRIVATE_KEY "RSA PRIVATE KEY"
-#define S2N_PEM_PKCS1_EC_PRIVATE_KEY "EC PRIVATE KEY"
-#define S2N_PEM_PKCS8_PRIVATE_KEY "PRIVATE KEY"
-#define S2N_PEM_DH_PARAMETERS "DH PARAMETERS"
-#define S2N_PEM_EC_PARAMETERS "EC PARAMETERS"
-#define S2N_PEM_CERTIFICATE "CERTIFICATE"
-
-static int s2n_stuffer_pem_read_encapsulation_line(struct s2n_stuffer *pem, const char* encap_marker, const char *keyword) {
-
- /* Skip any number of Chars until a "-" is reached */
- GUARD(s2n_stuffer_skip_to_char(pem, S2N_PEM_DELIMTER_CHAR));
-
- /* Ensure between 1 and 64 '-' chars at start of line */
- GUARD(s2n_stuffer_skip_expected_char(pem, S2N_PEM_DELIMTER_CHAR, S2N_PEM_DELIMITER_MIN_COUNT, S2N_PEM_DELIMITER_MAX_COUNT, NULL));
-
- /* Ensure next string in stuffer is "BEGIN " or "END " */
- GUARD(s2n_stuffer_read_expected_str(pem, encap_marker));
-
- /* Ensure next string is stuffer is the keyword (Eg "CERTIFICATE", "PRIVATE KEY", etc) */
- GUARD(s2n_stuffer_read_expected_str(pem, keyword));
-
- /* Ensure between 1 and 64 '-' chars at end of line */
- GUARD(s2n_stuffer_skip_expected_char(pem, S2N_PEM_DELIMTER_CHAR, S2N_PEM_DELIMITER_MIN_COUNT, S2N_PEM_DELIMITER_MAX_COUNT, NULL));
-
- /* Check for missing newline between dashes case: "-----END CERTIFICATE----------BEGIN CERTIFICATE-----" */
- if (strncmp(encap_marker, S2N_PEM_END_TOKEN, strlen(S2N_PEM_END_TOKEN)) == 0
- && s2n_stuffer_peek_check_for_str(pem, S2N_PEM_BEGIN_TOKEN) == S2N_SUCCESS) {
- /* Rewind stuffer by 1 byte before BEGIN, so that next read will find the dash before the BEGIN */
- GUARD(s2n_stuffer_rewind_read(pem, 1));
- }
-
- /* Skip newlines and other whitepsace that may be after the dashes */
- return s2n_stuffer_skip_whitespace(pem, NULL);
-}
-
-static int s2n_stuffer_pem_read_begin(struct s2n_stuffer *pem, const char *keyword)
-{
- return s2n_stuffer_pem_read_encapsulation_line(pem, S2N_PEM_BEGIN_TOKEN, keyword);
-}
-
-static int s2n_stuffer_pem_read_end(struct s2n_stuffer *pem, const char *keyword)
-{
- return s2n_stuffer_pem_read_encapsulation_line(pem, S2N_PEM_END_TOKEN, keyword);
-}
-
-static int s2n_stuffer_pem_read_contents(struct s2n_stuffer *pem, struct s2n_stuffer *asn1)
-{
- s2n_stack_blob(base64__blob, 64, 64);
- struct s2n_stuffer base64_stuffer = {0};
- GUARD(s2n_stuffer_init(&base64_stuffer, &base64__blob));
-
- while (1) {
- /* We need a byte... */
- ENSURE_POSIX(s2n_stuffer_data_available(pem) >= 1, S2N_ERR_STUFFER_OUT_OF_DATA);
-
- /* Peek to see if the next char is a dash, meaning end of pem_contents */
- uint8_t c = pem->blob.data[pem->read_cursor];
- if (c == '-') {
- break;
- }
- /* Else, move read pointer forward by 1 byte since we will be consuming it. */
- pem->read_cursor += 1;
-
- /* Skip non-base64 characters */
- if (!s2n_is_base64_char(c)) {
- continue;
- }
-
- /* Flush base64_stuffer to asn1 stuffer if we're out of space, and reset base64_stuffer read/write pointers */
- if (s2n_stuffer_space_remaining(&base64_stuffer) == 0) {
- GUARD(s2n_stuffer_read_base64(&base64_stuffer, asn1));
- GUARD(s2n_stuffer_rewrite(&base64_stuffer));
- }
-
- /* Copy next char to base64_stuffer */
- GUARD(s2n_stuffer_write_bytes(&base64_stuffer, (uint8_t *) &c, 1));
-
- };
-
- /* Flush any remaining bytes to asn1 */
- GUARD(s2n_stuffer_read_base64(&base64_stuffer, asn1));
-
- return S2N_SUCCESS;
-}
-
-static int s2n_stuffer_data_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, const char *keyword)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(pem));
- PRECONDITION_POSIX(s2n_stuffer_validate(asn1));
- notnull_check(keyword);
-
- GUARD(s2n_stuffer_pem_read_begin(pem, keyword));
- GUARD(s2n_stuffer_pem_read_contents(pem, asn1));
- GUARD(s2n_stuffer_pem_read_end(pem, keyword));
-
- POSTCONDITION_POSIX(s2n_stuffer_validate(pem));
- POSTCONDITION_POSIX(s2n_stuffer_validate(asn1));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1) {
- PRECONDITION_POSIX(s2n_stuffer_validate(pem));
- PRECONDITION_POSIX(s2n_stuffer_validate(asn1));
- int rc;
-
- rc = s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS1_RSA_PRIVATE_KEY);
- if (!rc) {
- return rc;
- }
-
- s2n_stuffer_reread(pem);
- s2n_stuffer_reread(asn1);
-
- /* By default, OpenSSL tools always generate both "EC PARAMETERS" and "EC PRIVATE
- * KEY" PEM objects in the keyfile. Skip the first "EC PARAMETERS" object so that we're
- * compatible with OpenSSL's default output, and since "EC PARAMETERS" is
- * only needed for non-standard curves that aren't currently supported.
- */
- rc = s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_EC_PARAMETERS);
- if (rc < 0) {
- s2n_stuffer_reread(pem);
- }
- s2n_stuffer_wipe(asn1);
-
- rc = s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS1_EC_PRIVATE_KEY);
- if (!rc) {
- return rc;
- }
-
- /* If it does not match either format, try PKCS#8 */
- s2n_stuffer_reread(pem);
- s2n_stuffer_reread(asn1);
- return s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS8_PRIVATE_KEY);
-}
-
-int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1)
-{
- return s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_CERTIFICATE);
-}
-
-int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3)
-{
- return s2n_stuffer_data_from_pem(pem, pkcs3, S2N_PEM_DH_PARAMETERS);
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <string.h>
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+
+#define S2N_PEM_DELIMTER_CHAR '-'
+#define S2N_PEM_DELIMITER_MIN_COUNT 1
+#define S2N_PEM_DELIMITER_MAX_COUNT 64
+#define S2N_PEM_BEGIN_TOKEN "BEGIN "
+#define S2N_PEM_END_TOKEN "END "
+#define S2N_PEM_PKCS1_RSA_PRIVATE_KEY "RSA PRIVATE KEY"
+#define S2N_PEM_PKCS1_EC_PRIVATE_KEY "EC PRIVATE KEY"
+#define S2N_PEM_PKCS8_PRIVATE_KEY "PRIVATE KEY"
+#define S2N_PEM_DH_PARAMETERS "DH PARAMETERS"
+#define S2N_PEM_EC_PARAMETERS "EC PARAMETERS"
+#define S2N_PEM_CERTIFICATE "CERTIFICATE"
+
+static int s2n_stuffer_pem_read_encapsulation_line(struct s2n_stuffer *pem, const char* encap_marker, const char *keyword) {
+
+ /* Skip any number of Chars until a "-" is reached */
+ GUARD(s2n_stuffer_skip_to_char(pem, S2N_PEM_DELIMTER_CHAR));
+
+ /* Ensure between 1 and 64 '-' chars at start of line */
+ GUARD(s2n_stuffer_skip_expected_char(pem, S2N_PEM_DELIMTER_CHAR, S2N_PEM_DELIMITER_MIN_COUNT, S2N_PEM_DELIMITER_MAX_COUNT, NULL));
+
+ /* Ensure next string in stuffer is "BEGIN " or "END " */
+ GUARD(s2n_stuffer_read_expected_str(pem, encap_marker));
+
+ /* Ensure next string is stuffer is the keyword (Eg "CERTIFICATE", "PRIVATE KEY", etc) */
+ GUARD(s2n_stuffer_read_expected_str(pem, keyword));
+
+ /* Ensure between 1 and 64 '-' chars at end of line */
+ GUARD(s2n_stuffer_skip_expected_char(pem, S2N_PEM_DELIMTER_CHAR, S2N_PEM_DELIMITER_MIN_COUNT, S2N_PEM_DELIMITER_MAX_COUNT, NULL));
+
+ /* Check for missing newline between dashes case: "-----END CERTIFICATE----------BEGIN CERTIFICATE-----" */
+ if (strncmp(encap_marker, S2N_PEM_END_TOKEN, strlen(S2N_PEM_END_TOKEN)) == 0
+ && s2n_stuffer_peek_check_for_str(pem, S2N_PEM_BEGIN_TOKEN) == S2N_SUCCESS) {
+ /* Rewind stuffer by 1 byte before BEGIN, so that next read will find the dash before the BEGIN */
+ GUARD(s2n_stuffer_rewind_read(pem, 1));
+ }
+
+ /* Skip newlines and other whitepsace that may be after the dashes */
+ return s2n_stuffer_skip_whitespace(pem, NULL);
+}
+
+static int s2n_stuffer_pem_read_begin(struct s2n_stuffer *pem, const char *keyword)
+{
+ return s2n_stuffer_pem_read_encapsulation_line(pem, S2N_PEM_BEGIN_TOKEN, keyword);
+}
+
+static int s2n_stuffer_pem_read_end(struct s2n_stuffer *pem, const char *keyword)
+{
+ return s2n_stuffer_pem_read_encapsulation_line(pem, S2N_PEM_END_TOKEN, keyword);
+}
+
+static int s2n_stuffer_pem_read_contents(struct s2n_stuffer *pem, struct s2n_stuffer *asn1)
+{
+ s2n_stack_blob(base64__blob, 64, 64);
+ struct s2n_stuffer base64_stuffer = {0};
+ GUARD(s2n_stuffer_init(&base64_stuffer, &base64__blob));
+
+ while (1) {
+ /* We need a byte... */
+ ENSURE_POSIX(s2n_stuffer_data_available(pem) >= 1, S2N_ERR_STUFFER_OUT_OF_DATA);
+
+ /* Peek to see if the next char is a dash, meaning end of pem_contents */
+ uint8_t c = pem->blob.data[pem->read_cursor];
+ if (c == '-') {
+ break;
+ }
+ /* Else, move read pointer forward by 1 byte since we will be consuming it. */
+ pem->read_cursor += 1;
+
+ /* Skip non-base64 characters */
+ if (!s2n_is_base64_char(c)) {
+ continue;
+ }
+
+ /* Flush base64_stuffer to asn1 stuffer if we're out of space, and reset base64_stuffer read/write pointers */
+ if (s2n_stuffer_space_remaining(&base64_stuffer) == 0) {
+ GUARD(s2n_stuffer_read_base64(&base64_stuffer, asn1));
+ GUARD(s2n_stuffer_rewrite(&base64_stuffer));
+ }
+
+ /* Copy next char to base64_stuffer */
+ GUARD(s2n_stuffer_write_bytes(&base64_stuffer, (uint8_t *) &c, 1));
+
+ };
+
+ /* Flush any remaining bytes to asn1 */
+ GUARD(s2n_stuffer_read_base64(&base64_stuffer, asn1));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_stuffer_data_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1, const char *keyword)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(pem));
+ PRECONDITION_POSIX(s2n_stuffer_validate(asn1));
+ notnull_check(keyword);
+
+ GUARD(s2n_stuffer_pem_read_begin(pem, keyword));
+ GUARD(s2n_stuffer_pem_read_contents(pem, asn1));
+ GUARD(s2n_stuffer_pem_read_end(pem, keyword));
+
+ POSTCONDITION_POSIX(s2n_stuffer_validate(pem));
+ POSTCONDITION_POSIX(s2n_stuffer_validate(asn1));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_private_key_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1) {
+ PRECONDITION_POSIX(s2n_stuffer_validate(pem));
+ PRECONDITION_POSIX(s2n_stuffer_validate(asn1));
+ int rc;
+
+ rc = s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS1_RSA_PRIVATE_KEY);
+ if (!rc) {
+ return rc;
+ }
+
+ s2n_stuffer_reread(pem);
+ s2n_stuffer_reread(asn1);
+
+ /* By default, OpenSSL tools always generate both "EC PARAMETERS" and "EC PRIVATE
+ * KEY" PEM objects in the keyfile. Skip the first "EC PARAMETERS" object so that we're
+ * compatible with OpenSSL's default output, and since "EC PARAMETERS" is
+ * only needed for non-standard curves that aren't currently supported.
+ */
+ rc = s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_EC_PARAMETERS);
+ if (rc < 0) {
+ s2n_stuffer_reread(pem);
+ }
+ s2n_stuffer_wipe(asn1);
+
+ rc = s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS1_EC_PRIVATE_KEY);
+ if (!rc) {
+ return rc;
+ }
+
+ /* If it does not match either format, try PKCS#8 */
+ s2n_stuffer_reread(pem);
+ s2n_stuffer_reread(asn1);
+ return s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_PKCS8_PRIVATE_KEY);
+}
+
+int s2n_stuffer_certificate_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *asn1)
+{
+ return s2n_stuffer_data_from_pem(pem, asn1, S2N_PEM_CERTIFICATE);
+}
+
+int s2n_stuffer_dhparams_from_pem(struct s2n_stuffer *pem, struct s2n_stuffer *pkcs3)
+{
+ return s2n_stuffer_data_from_pem(pem, pkcs3, S2N_PEM_DH_PARAMETERS);
+}
diff --git a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c
index dc60ca5099..6be5fdbbad 100644
--- a/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c
+++ b/contrib/restricted/aws/s2n/stuffer/s2n_stuffer_text.c
@@ -1,194 +1,194 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-#include <string.h>
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-
-int s2n_stuffer_peek_char(struct s2n_stuffer *s2n_stuffer, char *c)
-{
- int r = s2n_stuffer_read_uint8(s2n_stuffer, (uint8_t *) c);
- if (r == S2N_SUCCESS) {
- s2n_stuffer->read_cursor--;
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
- return r;
-}
-
-/* Peeks in stuffer to see if expected string is present. */
-int s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
- uint32_t orig_read_pos = s2n_stuffer->read_cursor;
- int rc = s2n_stuffer_read_expected_str(s2n_stuffer, expected);
- s2n_stuffer->read_cursor = orig_read_pos;
- POSTCONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
- return rc;
-}
-
-int s2n_stuffer_skip_whitespace(struct s2n_stuffer *s2n_stuffer, uint32_t *skipped)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
- uint32_t initial_read_cursor = s2n_stuffer->read_cursor;
- while (s2n_stuffer->read_cursor < s2n_stuffer->write_cursor) {
- switch (s2n_stuffer->blob.data[s2n_stuffer->read_cursor]) {
- case ' ': /* We don't use isspace, because it changes under locales */
- case '\t':
- case '\n':
- case '\r':
- s2n_stuffer->read_cursor += 1;
- break;
- default:
- goto finished;
- }
- }
- finished:
- if(skipped != NULL) *skipped = s2n_stuffer->read_cursor - initial_read_cursor;
- POSTCONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char *expected)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- notnull_check(expected);
- size_t expected_length = strlen(expected);
- if (expected_length == 0) {
- return S2N_SUCCESS;
- }
- ENSURE_POSIX(s2n_stuffer_data_available(stuffer) >= expected_length, S2N_ERR_STUFFER_OUT_OF_DATA);
- uint8_t *actual = stuffer->blob.data + stuffer->read_cursor;
- notnull_check(actual);
- ENSURE_POSIX(!memcmp(actual, expected, expected_length), S2N_ERR_STUFFER_NOT_FOUND);
- stuffer->read_cursor += expected_length;
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-/* Read from stuffer until the target string is found, or until there is no more data. */
-int s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char *target)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- notnull_check(target);
- const int len = strlen(target);
- if (len == 0) {
- return S2N_SUCCESS;
- }
- while (s2n_stuffer_data_available(stuffer) >= len) {
- GUARD(s2n_stuffer_skip_to_char(stuffer, target[0]));
- GUARD(s2n_stuffer_skip_read(stuffer, len));
- uint8_t *actual = stuffer->blob.data + stuffer->read_cursor - len;
- notnull_check(actual);
-
- if (strncmp((char*)actual, target, len) == 0){
- return S2N_SUCCESS;
- } else {
- /* If string doesn't match, rewind stuffer to 1 byte after last read */
- GUARD(s2n_stuffer_rewind_read(stuffer, len - 1));
- continue;
- }
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-/* Skips the stuffer until the first instance of the target character or until there is no more data. */
-int s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, const char target)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- while (s2n_stuffer_data_available(stuffer) > 0) {
- if (stuffer->blob.data[stuffer->read_cursor] == target) {
- break;
- }
- stuffer->read_cursor += 1;
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-/* Skips an expected character in the stuffer between min and max times */
-int s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min, const uint32_t max, uint32_t *skipped)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- ENSURE_POSIX(min <= max, S2N_ERR_SAFETY);
-
- uint32_t skip = 0;
- while (stuffer->read_cursor < stuffer->write_cursor && skip < max) {
- if (stuffer->blob.data[stuffer->read_cursor] == expected){
- stuffer->read_cursor += 1;
- skip += 1;
- } else {
- break;
- }
- }
- ENSURE_POSIX(skip >= min, S2N_ERR_STUFFER_NOT_FOUND);
- if(skipped != NULL) *skipped = skip;
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- return S2N_SUCCESS;
-}
-
-/* Read a line of text. Agnostic to LF or CR+LF line endings. */
-int s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- PRECONDITION_POSIX(s2n_stuffer_validate(token));
- /* Consume an LF terminated line */
- GUARD(s2n_stuffer_read_token(stuffer, token, '\n'));
-
- /* Snip off the carriage return if it's present */
- if ((s2n_stuffer_data_available(token) > 0) && (token->blob.data[(token->write_cursor - 1)] == '\r')) {
- token->write_cursor--;
- }
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- POSTCONDITION_POSIX(s2n_stuffer_validate(token));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- PRECONDITION_POSIX(s2n_stuffer_validate(token));
- uint32_t token_size = 0;
-
- while ((stuffer->read_cursor + token_size) < stuffer->write_cursor) {
- if (stuffer->blob.data[stuffer->read_cursor + token_size] == delim) {
- break;
- }
- token_size++;
- }
-
- GUARD(s2n_stuffer_copy(stuffer, token, token_size));
-
- /* Consume the delimiter too */
- if (stuffer->read_cursor < stuffer->write_cursor) {
- stuffer->read_cursor++;
- }
-
- POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
- POSTCONDITION_POSIX(s2n_stuffer_validate(token));
- return S2N_SUCCESS;
-}
-
-int s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str)
-{
- PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
- notnull_check(str);
- uint32_t length = strlen(str);
- GUARD(s2n_stuffer_alloc(stuffer, length + 1));
- return s2n_stuffer_write_bytes(stuffer, (const uint8_t *)str, length);
-}
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+#include <string.h>
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+
+int s2n_stuffer_peek_char(struct s2n_stuffer *s2n_stuffer, char *c)
+{
+ int r = s2n_stuffer_read_uint8(s2n_stuffer, (uint8_t *) c);
+ if (r == S2N_SUCCESS) {
+ s2n_stuffer->read_cursor--;
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
+ return r;
+}
+
+/* Peeks in stuffer to see if expected string is present. */
+int s2n_stuffer_peek_check_for_str(struct s2n_stuffer *s2n_stuffer, const char *expected)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
+ uint32_t orig_read_pos = s2n_stuffer->read_cursor;
+ int rc = s2n_stuffer_read_expected_str(s2n_stuffer, expected);
+ s2n_stuffer->read_cursor = orig_read_pos;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
+ return rc;
+}
+
+int s2n_stuffer_skip_whitespace(struct s2n_stuffer *s2n_stuffer, uint32_t *skipped)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
+ uint32_t initial_read_cursor = s2n_stuffer->read_cursor;
+ while (s2n_stuffer->read_cursor < s2n_stuffer->write_cursor) {
+ switch (s2n_stuffer->blob.data[s2n_stuffer->read_cursor]) {
+ case ' ': /* We don't use isspace, because it changes under locales */
+ case '\t':
+ case '\n':
+ case '\r':
+ s2n_stuffer->read_cursor += 1;
+ break;
+ default:
+ goto finished;
+ }
+ }
+ finished:
+ if(skipped != NULL) *skipped = s2n_stuffer->read_cursor - initial_read_cursor;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(s2n_stuffer));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_read_expected_str(struct s2n_stuffer *stuffer, const char *expected)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ notnull_check(expected);
+ size_t expected_length = strlen(expected);
+ if (expected_length == 0) {
+ return S2N_SUCCESS;
+ }
+ ENSURE_POSIX(s2n_stuffer_data_available(stuffer) >= expected_length, S2N_ERR_STUFFER_OUT_OF_DATA);
+ uint8_t *actual = stuffer->blob.data + stuffer->read_cursor;
+ notnull_check(actual);
+ ENSURE_POSIX(!memcmp(actual, expected, expected_length), S2N_ERR_STUFFER_NOT_FOUND);
+ stuffer->read_cursor += expected_length;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+/* Read from stuffer until the target string is found, or until there is no more data. */
+int s2n_stuffer_skip_read_until(struct s2n_stuffer *stuffer, const char *target)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ notnull_check(target);
+ const int len = strlen(target);
+ if (len == 0) {
+ return S2N_SUCCESS;
+ }
+ while (s2n_stuffer_data_available(stuffer) >= len) {
+ GUARD(s2n_stuffer_skip_to_char(stuffer, target[0]));
+ GUARD(s2n_stuffer_skip_read(stuffer, len));
+ uint8_t *actual = stuffer->blob.data + stuffer->read_cursor - len;
+ notnull_check(actual);
+
+ if (strncmp((char*)actual, target, len) == 0){
+ return S2N_SUCCESS;
+ } else {
+ /* If string doesn't match, rewind stuffer to 1 byte after last read */
+ GUARD(s2n_stuffer_rewind_read(stuffer, len - 1));
+ continue;
+ }
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+/* Skips the stuffer until the first instance of the target character or until there is no more data. */
+int s2n_stuffer_skip_to_char(struct s2n_stuffer *stuffer, const char target)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ while (s2n_stuffer_data_available(stuffer) > 0) {
+ if (stuffer->blob.data[stuffer->read_cursor] == target) {
+ break;
+ }
+ stuffer->read_cursor += 1;
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+/* Skips an expected character in the stuffer between min and max times */
+int s2n_stuffer_skip_expected_char(struct s2n_stuffer *stuffer, const char expected, const uint32_t min, const uint32_t max, uint32_t *skipped)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ ENSURE_POSIX(min <= max, S2N_ERR_SAFETY);
+
+ uint32_t skip = 0;
+ while (stuffer->read_cursor < stuffer->write_cursor && skip < max) {
+ if (stuffer->blob.data[stuffer->read_cursor] == expected){
+ stuffer->read_cursor += 1;
+ skip += 1;
+ } else {
+ break;
+ }
+ }
+ ENSURE_POSIX(skip >= min, S2N_ERR_STUFFER_NOT_FOUND);
+ if(skipped != NULL) *skipped = skip;
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ return S2N_SUCCESS;
+}
+
+/* Read a line of text. Agnostic to LF or CR+LF line endings. */
+int s2n_stuffer_read_line(struct s2n_stuffer *stuffer, struct s2n_stuffer *token)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ PRECONDITION_POSIX(s2n_stuffer_validate(token));
+ /* Consume an LF terminated line */
+ GUARD(s2n_stuffer_read_token(stuffer, token, '\n'));
+
+ /* Snip off the carriage return if it's present */
+ if ((s2n_stuffer_data_available(token) > 0) && (token->blob.data[(token->write_cursor - 1)] == '\r')) {
+ token->write_cursor--;
+ }
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ POSTCONDITION_POSIX(s2n_stuffer_validate(token));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_read_token(struct s2n_stuffer *stuffer, struct s2n_stuffer *token, char delim)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ PRECONDITION_POSIX(s2n_stuffer_validate(token));
+ uint32_t token_size = 0;
+
+ while ((stuffer->read_cursor + token_size) < stuffer->write_cursor) {
+ if (stuffer->blob.data[stuffer->read_cursor + token_size] == delim) {
+ break;
+ }
+ token_size++;
+ }
+
+ GUARD(s2n_stuffer_copy(stuffer, token, token_size));
+
+ /* Consume the delimiter too */
+ if (stuffer->read_cursor < stuffer->write_cursor) {
+ stuffer->read_cursor++;
+ }
+
+ POSTCONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ POSTCONDITION_POSIX(s2n_stuffer_validate(token));
+ return S2N_SUCCESS;
+}
+
+int s2n_stuffer_alloc_ro_from_string(struct s2n_stuffer *stuffer, const char *str)
+{
+ PRECONDITION_POSIX(s2n_stuffer_validate(stuffer));
+ notnull_check(str);
+ uint32_t length = strlen(str);
+ GUARD(s2n_stuffer_alloc(stuffer, length + 1));
+ return s2n_stuffer_write_bytes(stuffer, (const uint8_t *)str, length);
+}