[openssl-dev] [openssl.org #3529] [PATCHv2] ASN1 generation: allow bit strings ending with zero regardless of length

Kaarle Ritvanen via RT rt at openssl.org
Thu May 7 21:07:15 UTC 2015


New version of the patch, rebased against the master branch.

---
 crypto/asn1/a_bitstr.c | 12 +++++-------
 crypto/asn1/asn1_gen.c | 15 ++++++++++++++-
 include/openssl/asn1.h |  1 +
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c
index 60b6e6d..3d77e1a 100644
--- a/crypto/asn1/a_bitstr.c
+++ b/crypto/asn1/a_bitstr.c
@@ -187,11 +187,12 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
  */
 int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
 {
-    int w, v, iv;
+    int w, b, v, iv;
     unsigned char *c;
 
     w = n / 8;
-    v = 1 << (7 - (n & 0x07));
+    b = 7 - (n & 0x07);
+    v = 1 << b;
     iv = ~v;
     if (!value)
         v = 0;
@@ -199,11 +200,10 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
     if (a == NULL)
         return 0;
 
-    a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+    if (a->length <= (w + 1))
+        a->flags = (a->flags & ~0x07) | ASN1_STRING_FLAG_BITS_LEFT | b;
 
     if ((a->length < (w + 1)) || (a->data == NULL)) {
-        if (!value)
-            return (1);         /* Don't need to set */
         c = OPENSSL_realloc_clean(a->data, a->length, w + 1);
         if (c == NULL) {
             ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
@@ -215,8 +215,6 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
         a->length = w + 1;
     }
     a->data[w] = ((a->data[w]) & iv) | v;
-    while ((a->length > 0) && (a->data[a->length - 1] == 0))
-        a->length--;
     return (1);
 }
 
diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c
index 84d85e6..107f715 100644
--- a/crypto/asn1/asn1_gen.c
+++ b/crypto/asn1/asn1_gen.c
@@ -87,6 +87,8 @@
 #define ASN1_GEN_FORMAT_HEX     3
 /* List of bits */
 #define ASN1_GEN_FORMAT_BITLIST 4
+/* Binary */
+#define ASN1_GEN_FORMAT_BINARY  5
 
 struct tag_name_st {
     const char *strnam;
@@ -383,6 +385,8 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
             arg->format = ASN1_GEN_FORMAT_HEX;
         else if (strncmp(vstart, "BITLIST", 7) == 0)
             arg->format = ASN1_GEN_FORMAT_BITLIST;
+        else if (!strncmp(vstart, "BINARY", 6))
+            arg->format = ASN1_GEN_FORMAT_BINARY;
         else {
             ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
             return -1;
@@ -638,6 +642,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
     long rdlen;
 
     int no_unused = 1;
+    int i;
 
     if (!(atmp = ASN1_TYPE_new())) {
         ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
@@ -772,7 +777,15 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
                 goto bad_str;
             }
             no_unused = 0;
-
+        } else if ((format == ASN1_GEN_FORMAT_BINARY) && (utype == V_ASN1_BIT_STRING)) {
+            for (i = 0; str[i]; i++) {
+                if (str[i] != '0' && str[i] != '1') {
+                    ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BINARY);
+                    goto bad_str;
+                }
+                ASN1_BIT_STRING_set_bit(atmp->value.bit_string, i, str[i] - '0');
+            }
+            no_unused = 0;
         } else {
             ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
             goto bad_form;
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index b1bcef7..462f66b 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -1066,6 +1066,7 @@ void ERR_load_ASN1_strings(void);
 # define ASN1_R_FIELD_MISSING                             121
 # define ASN1_R_FIRST_NUM_TOO_LARGE                       122
 # define ASN1_R_HEADER_TOO_LONG                           123
+# define ASN1_R_ILLEGAL_BINARY                            224
 # define ASN1_R_ILLEGAL_BITSTRING_FORMAT                  175
 # define ASN1_R_ILLEGAL_BOOLEAN                           176
 # define ASN1_R_ILLEGAL_CHARACTERS                        124
-- 
2.1.0




More information about the openssl-dev mailing list