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 _______________________________________________ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev