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)