[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