[openssl] master update

dev at ddvo.net dev at ddvo.net
Wed Apr 21 13:06:44 UTC 2021


The branch master has been updated
       via  3e73111d133dda63ec42437ff5706ac3142f17a5 (commit)
       via  db76a35e26ea09781caa5b941bdfeacb52e720d8 (commit)
      from  c0e724fcbe3b78f098534fd5b76c1d0393b2a42c (commit)


- Log -----------------------------------------------------------------
commit 3e73111d133dda63ec42437ff5706ac3142f17a5
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Mar 1 14:45:23 2021 +0100

    ASN.1: Add some sanity checks for input len <= 0; related coding improvements
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14357)

commit db76a35e26ea09781caa5b941bdfeacb52e720d8
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Mar 1 14:43:19 2021 +0100

    tasn_dec.c: Add checks for it == NULL arguments; improve coding style
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14357)

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

Summary of changes:
 crypto/asn1/a_d2i_fp.c | 16 +++++++++-----
 crypto/asn1/asn1_lib.c |  6 +++--
 crypto/asn1/tasn_dec.c | 59 ++++++++++++++++++++++++++++++++------------------
 3 files changed, 52 insertions(+), 29 deletions(-)

diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c
index 4151a96561..6dfa37c7a2 100644
--- a/crypto/asn1/a_d2i_fp.c
+++ b/crypto/asn1/a_d2i_fp.c
@@ -101,6 +101,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
     uint32_t eos = 0;
     size_t off = 0;
     size_t len = 0;
+    size_t diff;
 
     const unsigned char *q;
     long slen;
@@ -114,15 +115,16 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
 
     ERR_clear_error();
     for (;;) {
-        if (want >= (len - off)) {
-            want -= (len - off);
+        diff = len - off;
+        if (want >= diff) {
+            want -= diff;
 
             if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
                 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
             i = BIO_read(in, &(b->data[len]), want);
-            if ((i < 0) && ((len - off) == 0)) {
+            if (i < 0 && diff == 0) {
                 ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA);
                 goto err;
             }
@@ -138,15 +140,17 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
 
         p = (unsigned char *)&(b->data[off]);
         q = p;
-        inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
+        diff = len - off;
+        if (diff == 0)
+            goto err;
+        inf = ASN1_get_object(&q, &slen, &tag, &xclass, diff);
         if (inf & 0x80) {
             unsigned long e;
 
             e = ERR_GET_REASON(ERR_peek_error());
             if (e != ASN1_R_TOO_LONG)
                 goto err;
-            else
-                ERR_clear_error(); /* clear error */
+            ERR_clear_error();
         }
         i = q - p;            /* header length */
         off += i;               /* end of data */
diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c
index d45419e5f0..72d15acc7e 100644
--- a/crypto/asn1/asn1_lib.c
+++ b/crypto/asn1/asn1_lib.c
@@ -52,8 +52,10 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
     int tag, xclass, inf;
     long max = omax;
 
-    if (!max)
-        goto err;
+    if (omax <= 0) {
+        ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
+        return 0x80;
+    }
     ret = (*p & V_ASN1_CONSTRUCTED);
     xclass = (*p & V_ASN1_PRIVATE);
     i = *p & V_ASN1_PRIMITIVE_TAG;
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index ef29a16394..20717df461 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -90,7 +90,7 @@ unsigned long ASN1_tag2bit(int tag)
 
 /* Macro to initialize and invalidate the cache */
 
-#define asn1_tlc_clear(c)       if (c) (c)->valid = 0
+#define asn1_tlc_clear(c)       if ((c) != NULL) (c)->valid = 0
 /* Version to avoid compiler warning about 'c' always non-NULL */
 #define asn1_tlc_clear_nc(c)    (c)->valid = 0
 
@@ -121,6 +121,11 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                      int tag, int aclass, char opt, ASN1_TLC *ctx)
 {
     int rv;
+
+    if (pval == NULL || it == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
     rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0);
     if (rv <= 0)
         ASN1_item_ex_free(pval, it);
@@ -139,7 +144,7 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
 {
     const ASN1_TEMPLATE *tt, *errtt = NULL;
     const ASN1_EXTERN_FUNCS *ef;
-    const ASN1_AUX *aux = it->funcs;
+    const ASN1_AUX *aux;
     ASN1_aux_cb *asn1_cb;
     const unsigned char *p = NULL, *q;
     unsigned char oclass;
@@ -150,8 +155,15 @@ static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
     int ret = 0;
     ASN1_VALUE **pchptr;
 
-    if (pval == NULL)
+    if (pval == NULL || it == NULL) {
+        ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (len <= 0) {
+        ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
         return 0;
+    }
+    aux = it->funcs;
     if (aux && aux->asn1_cb)
         asn1_cb = aux->asn1_cb;
     else
@@ -1100,7 +1112,11 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
     p = *in;
     q = p;
 
-    if (ctx && ctx->valid) {
+    if (len <= 0) {
+        ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
+        goto err;
+    }
+    if (ctx != NULL && ctx->valid) {
         i = ctx->ret;
         plen = ctx->plen;
         pclass = ctx->pclass;
@@ -1108,7 +1124,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
         p += ctx->hdrlen;
     } else {
         i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
-        if (ctx) {
+        if (ctx != NULL) {
             ctx->ret = i;
             ctx->plen = plen;
             ctx->pclass = pclass;
@@ -1119,29 +1135,26 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
              * If definite length, and no error, length + header can't exceed
              * total amount of data available.
              */
-            if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+            if ((i & 0x81) == 0 && (plen + ctx->hdrlen) > len) {
                 ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LONG);
-                asn1_tlc_clear(ctx);
-                return 0;
+                goto err;
             }
         }
     }
 
-    if (i & 0x80) {
+    if ((i & 0x80) != 0) {
         ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER);
-        asn1_tlc_clear(ctx);
-        return 0;
+        goto err;
     }
     if (exptag >= 0) {
-        if ((exptag != ptag) || (expclass != pclass)) {
+        if (exptag != ptag || expclass != pclass) {
             /*
              * If type is OPTIONAL, not an error: indicate missing type.
              */
-            if (opt)
+            if (opt != 0)
                 return -1;
-            asn1_tlc_clear(ctx);
             ERR_raise(ERR_LIB_ASN1, ASN1_R_WRONG_TAG);
-            return 0;
+            goto err;
         }
         /*
          * We have a tag and class match: assume we are going to do something
@@ -1150,24 +1163,28 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
         asn1_tlc_clear(ctx);
     }
 
-    if (i & 1)
+    if ((i & 1) != 0)
         plen = len - (p - q);
 
-    if (inf)
+    if (inf != NULL)
         *inf = i & 1;
 
-    if (cst)
+    if (cst != NULL)
         *cst = i & V_ASN1_CONSTRUCTED;
 
-    if (olen)
+    if (olen != NULL)
         *olen = plen;
 
-    if (oclass)
+    if (oclass != NULL)
         *oclass = pclass;
 
-    if (otag)
+    if (otag != NULL)
         *otag = ptag;
 
     *in = p;
     return 1;
+
+ err:
+    asn1_tlc_clear(ctx);
+    return 0;
 }


More information about the openssl-commits mailing list