New encode feature allows direct writing of byte string value (#137)
New features for UsefulBuf and for QCBOREncode allows direct writing to the output buffer. For QCBOREncode, this is the direct writing of the value of a byte string. This allows it to be written in chunks or be the output buffer of some function like symmetric encryption.
* fix grammer in security policy
* Half-way start a encoding feature to write byte string values into output
* Add documentation for OpenBstr
* UsefulBuf_Advance mostly working and testing
* OpenBytes() is mostly working and somewhat tested
* Finish up OpenBytes -- error handing, documentation...
Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index e5be98a..f5149a5 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -1,6 +1,6 @@
/*==============================================================================
Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
@@ -41,6 +41,7 @@
when who what, where, why
-------- ---- ---------------------------------------------------
+ 4/11/2022 llundblade Add GetOutPlace and Advance to UsefulOutBuf
3/6/2021 mcr/llundblade Fix warnings related to --Wcast-qual
01/28/2020 llundblade Refine integer signedness to quiet static analysis.
01/08/2020 llundblade Documentation corrections & improved code formatting.
@@ -304,6 +305,64 @@
/*
+ * Public function for advancing data length. See qcbor/UsefulBuf.h
+ */
+void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
+{
+ /* This function is a trimmed down version of
+ * UsefulOutBuf_InsertUsefulBuf(). This could be combined with the
+ * code in UsefulOutBuf_InsertUsefulBuf(), but that would make
+ * UsefulOutBuf_InsertUsefulBuf() bigger and this will be very
+ * rarely used.
+ */
+
+ if(pMe->err) {
+ /* Already in error state. */
+ return;
+ }
+
+ /* 0. Sanity check the UsefulOutBuf structure
+ *
+ * A "counter measure". If magic number is not the right number it
+ * probably means me was not initialized or it was
+ * corrupted. Attackers can defeat this, but it is a hurdle and
+ * does good with very little code.
+ */
+ if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
+ pMe->err = 1;
+ return; /* Magic number is wrong due to uninitalization or corrption */
+ }
+
+ /* Make sure valid data is less than buffer size. This would only
+ * occur if there was corruption of me, but it is also part of the
+ * checks to be sure there is no pointer arithmatic
+ * under/overflow.
+ */
+ if(pMe->data_len > pMe->UB.len) { // Check #1
+ pMe->err = 1;
+ /* Offset of valid data is off the end of the UsefulOutBuf due
+ * to uninitialization or corruption.
+ */
+ return;
+ }
+
+ /* 1. Will it fit?
+ *
+ * WillItFit() is the same as: NewData.len <= (me->UB.len -
+ * me->data_len) Check #1 makes sure subtraction in RoomLeft will
+ * not wrap around
+ */
+ if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
+ /* The new data will not fit into the the buffer. */
+ pMe->err = 1;
+ return;
+ }
+
+ pMe->data_len += uAmount;
+}
+
+
+/*
Public function -- see UsefulBuf.h
*/
UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)