[openssl] master update

Matt Caswell matt at openssl.org
Sat Apr 4 09:41:25 UTC 2020


The branch master has been updated
       via  a056ee28ed0971be2e29b49c3357a4065c98e51d (commit)
       via  d3ba3916d4fb5f8f7dbacb6cd7dab2909abb8e25 (commit)
      from  e2bf331bc0c735ebd8d9b86725bc3dc32245f986 (commit)


- Log -----------------------------------------------------------------
commit a056ee28ed0971be2e29b49c3357a4065c98e51d
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Apr 2 12:26:47 2020 +0100

    Add a WPACKET test for the new DER capability
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11462)

commit d3ba3916d4fb5f8f7dbacb6cd7dab2909abb8e25
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Apr 2 11:21:24 2020 +0100

    Add "endfirst" writing to WPACKET
    
    Support the concept of writing to the end of the packet first.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11462)

-----------------------------------------------------------------------

Summary of changes:
 crypto/packet.c           | 55 +++++++++++++++++++++++++++++++++++++-
 include/internal/packet.h | 17 ++++++++++++
 test/wpackettest.c        | 67 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/crypto/packet.c b/crypto/packet.c
index 75a0317606..6dacebfee5 100644
--- a/crypto/packet.c
+++ b/crypto/packet.c
@@ -65,8 +65,11 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
         if (BUF_MEM_grow(pkt->buf, newlen) == 0)
             return 0;
     }
-    if (allocbytes != NULL)
+    if (allocbytes != NULL) {
         *allocbytes = WPACKET_get_curr(pkt);
+        if (pkt->endfirst && *allocbytes != NULL)
+            *allocbytes -= len;
+    }
 
     return 1;
 }
@@ -74,6 +77,9 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
 int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
                                 unsigned char **allocbytes, size_t lenbytes)
 {
+    if (pkt->endfirst && lenbytes > 0)
+        return 0;
+
     if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes))
         return 0;
 
@@ -131,10 +137,25 @@ int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len,
     pkt->staticbuf = buf;
     pkt->buf = NULL;
     pkt->maxsize = (max < len) ? max : len;
+    pkt->endfirst = 0;
 
     return wpacket_intern_init_len(pkt, lenbytes);
 }
 
+int WPACKET_init_der(WPACKET *pkt, unsigned char *buf, size_t len)
+{
+    /* Internal API, so should not fail */
+    if (!ossl_assert(buf != NULL && len > 0))
+        return 0;
+
+    pkt->staticbuf = buf;
+    pkt->buf = NULL;
+    pkt->maxsize = len;
+    pkt->endfirst = 1;
+
+    return wpacket_intern_init_len(pkt, 0);
+}
+
 int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes)
 {
     /* Internal API, so should not fail */
@@ -144,6 +165,7 @@ int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes)
     pkt->staticbuf = NULL;
     pkt->buf = buf;
     pkt->maxsize = maxmaxsize(lenbytes);
+    pkt->endfirst = 0;
 
     return wpacket_intern_init_len(pkt, lenbytes);
 }
@@ -158,6 +180,17 @@ int WPACKET_init_null(WPACKET *pkt, size_t lenbytes)
     pkt->staticbuf = NULL;
     pkt->buf = NULL;
     pkt->maxsize = maxmaxsize(lenbytes);
+    pkt->endfirst = 0;
+
+    return wpacket_intern_init_len(pkt, 0);
+}
+
+int WPACKET_init_null_der(WPACKET *pkt)
+{
+    pkt->staticbuf = NULL;
+    pkt->buf = NULL;
+    pkt->maxsize = SIZE_MAX;
+    pkt->endfirst = 1;
 
     return wpacket_intern_init_len(pkt, 0);
 }
@@ -232,6 +265,19 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
                 && !put_value(&buf[sub->packet_len], packlen,
                               sub->lenbytes))
             return 0;
+    } else if (pkt->endfirst && sub->parent != NULL) {
+        size_t tmplen = packlen;
+        size_t numlenbytes = 1;
+
+        while ((tmplen = tmplen >> 8) > 0)
+            numlenbytes++;
+        if (!WPACKET_put_bytes__(pkt, packlen, numlenbytes))
+            return 0;
+        if (packlen > 0x7f) {
+            numlenbytes |= 0x80;
+            if (!WPACKET_put_bytes_u8(pkt, numlenbytes))
+                return 0;
+        }
     }
 
     if (doclose) {
@@ -298,6 +344,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
     if (!ossl_assert(pkt->subs != NULL))
         return 0;
 
+    /* We don't support lenbytes greater than 0 when doing endfirst writing */
+    if (lenbytes > 0 && pkt->endfirst)
+        return 0;
+
     if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) {
         SSLerr(SSL_F_WPACKET_START_SUB_PACKET_LEN__, ERR_R_MALLOC_FAILURE);
         return 0;
@@ -436,6 +486,9 @@ unsigned char *WPACKET_get_curr(WPACKET *pkt)
     if (buf == NULL)
         return NULL;
 
+    if (pkt->endfirst)
+        return buf + pkt->maxsize - pkt->curr;
+
     return buf + pkt->curr;
 }
 
diff --git a/include/internal/packet.h b/include/internal/packet.h
index c03d917da7..1620ff838f 100644
--- a/include/internal/packet.h
+++ b/include/internal/packet.h
@@ -638,6 +638,9 @@ struct wpacket_st {
 
     /* Our sub-packets (always at least one if not finished) */
     WPACKET_SUB *subs;
+
+    /* Writing from the end first? */
+    unsigned int endfirst : 1;
 };
 
 /* Flags */
@@ -676,6 +679,12 @@ int WPACKET_init(WPACKET *pkt, BUF_MEM *buf);
  */
 int WPACKET_init_null(WPACKET *pkt, size_t lenbytes);
 
+/*
+ * Same as WPACKET_init_null except we set the WPACKET to assume DER length
+ * encoding for sub-packets.
+ */
+int WPACKET_init_null_der(WPACKET *pkt);
+
 /*
  * Same as WPACKET_init_len except we do not use a growable BUF_MEM structure.
  * A fixed buffer of memory |buf| of size |len| is used instead. A failure will
@@ -683,6 +692,14 @@ int WPACKET_init_null(WPACKET *pkt, size_t lenbytes);
  */
 int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len,
                             size_t lenbytes);
+
+/*
+ * Same as WPACKET_init_static_len except lenbytes is always 0, and we set the
+ * WPACKET to write to the end of the buffer moving towards the start and use
+ * DER length encoding for sub-packets.
+ */
+int WPACKET_init_der(WPACKET *pkt, unsigned char *buf, size_t len);
+
 /*
  * Set the flags to be applied to the current sub-packet
  */
diff --git a/test/wpackettest.c b/test/wpackettest.c
index abb001ea14..b2fa650424 100644
--- a/test/wpackettest.c
+++ b/test/wpackettest.c
@@ -9,6 +9,7 @@
 
 #include <string.h>
 #include <openssl/buffer.h>
+#include <openssl/rand.h>
 #include "internal/packet.h"
 #include "testutil.h"
 
@@ -21,6 +22,9 @@ static const unsigned char empty[] = { 0x00 };
 static const unsigned char alloc[] = { 0x02, 0xfe, 0xff };
 static const unsigned char submem[] = { 0x03, 0x02, 0xfe, 0xff };
 static const unsigned char fixed[] = { 0xff, 0xff, 0xff };
+static const unsigned char simpleder[] = {
+    0xfc, 0x04, 0x00, 0x01, 0x02, 0x03, 0xff, 0xfe, 0xfd
+};
 
 static BUF_MEM *buf;
 
@@ -349,6 +353,68 @@ static int test_WPACKET_memcpy(void)
     return 1;
 }
 
+static int test_WPACKET_init_der(void)
+{
+    WPACKET pkt;
+    unsigned char sbuf[1024];
+    unsigned char testdata[] = { 0x00, 0x01, 0x02, 0x03 };
+    unsigned char testdata2[259]  = { 0x82, 0x01, 0x00 };
+    size_t written[2];
+    int i;
+
+    /* Test initialising for writing DER */
+    if (!TEST_true(WPACKET_init_der(&pkt, sbuf, sizeof(sbuf)))
+            || !TEST_true(WPACKET_put_bytes_u24(&pkt, 0xfffefd))
+               /* Test writing data in a length prefixed sub-packet */
+            || !TEST_true(WPACKET_start_sub_packet(&pkt))
+            || !TEST_true(WPACKET_memcpy(&pkt, testdata, sizeof(testdata)))
+            || !TEST_true(WPACKET_close(&pkt))
+            || !TEST_true(WPACKET_put_bytes_u8(&pkt, 0xfc))
+            || !TEST_true(WPACKET_finish(&pkt))
+            || !TEST_true(WPACKET_get_total_written(&pkt, &written[0]))
+            || !TEST_mem_eq(WPACKET_get_curr(&pkt), written[0], simpleder,
+                            sizeof(simpleder)))
+        return cleanup(&pkt);
+
+    /* Generate random packet data for test */
+    if (!TEST_true(RAND_bytes(&testdata2[3], sizeof(testdata2) - 3)))
+        return 0;
+
+    /*
+     * Test with a sub-packet that has 2 length bytes. We do 2 passes - first
+     * with a NULL buffer, just to calculate lengths, and a second pass with a
+     * real buffer to actually generate a packet
+     */
+    for (i = 0; i < 2; i++) {
+        if (i == 0) {
+            if (!TEST_true(WPACKET_init_null_der(&pkt)))
+                return 0;
+        } else { 
+            if (!TEST_true(WPACKET_init_der(&pkt, sbuf, sizeof(sbuf))))
+                return 0;
+        }
+        if (!TEST_true(WPACKET_start_sub_packet(&pkt))
+            || !TEST_true(WPACKET_memcpy(&pkt, &testdata2[3],
+                                         sizeof(testdata2) - 3))
+            || !TEST_true(WPACKET_close(&pkt))
+            || !TEST_true(WPACKET_finish(&pkt))
+            || !TEST_true(WPACKET_get_total_written(&pkt, &written[i])))
+        return cleanup(&pkt);
+    }
+
+    /*
+     * Check that the size calculated in the first pass equals the size of the
+     * packet actually generated in the second pass. Also check the generated
+     * packet looks as we expect it to.
+     */
+    if (!TEST_size_t_eq(written[0], written[1])
+            || !TEST_mem_eq(WPACKET_get_curr(&pkt), written[1], testdata2,
+                            sizeof(testdata2)))
+        return 0;
+
+    return 1;
+}
+
 int setup_tests(void)
 {
     if (!TEST_ptr(buf = BUF_MEM_new()))
@@ -360,6 +426,7 @@ int setup_tests(void)
     ADD_TEST(test_WPACKET_set_flags);
     ADD_TEST(test_WPACKET_allocate_bytes);
     ADD_TEST(test_WPACKET_memcpy);
+    ADD_TEST(test_WPACKET_init_der);
     return 1;
 }
 


More information about the openssl-commits mailing list