X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Fasn1%2Fa_bitstr.c;h=34179960b87aed426902213ab2640ec6f4998d58;hb=d82e2718e2a1346b231abda31a102b144ac21090;hp=38ea802be817e7e81e3c1ea12747d7c35a0ca1c5;hpb=a9be3af5ad4836f7e50f0546311ca90c717b861e;p=oweals%2Fopenssl.git diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c index 38ea802be8..34179960b8 100644 --- a/crypto/asn1/a_bitstr.c +++ b/crypto/asn1/a_bitstr.c @@ -60,9 +60,12 @@ #include "cryptlib.h" #include -int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) +{ return M_ASN1_BIT_STRING_set(x, d, len); } + +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { - int ret,j,r,bits,len; + int ret,j,bits,len; unsigned char *p,*d; if (a == NULL) return(0); @@ -95,52 +98,43 @@ int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) } else bits=0; + ret=1+len; - r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); - if (pp == NULL) return(r); + if (pp == NULL) return(ret); + p= *pp; - ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); *(p++)=(unsigned char)bits; d=a->data; memcpy(p,d,len); p+=len; if (len > 0) p[-1]&=(0xff< 1) /* using one because of the bits left byte */ { - s=(unsigned char *)Malloc((int)len); + s=(unsigned char *)OPENSSL_malloc((int)len); if (s == NULL) { i=ERR_R_MALLOC_FAILURE; @@ -164,16 +158,16 @@ ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, s=NULL; ret->length=(int)len; - if (ret->data != NULL) Free((char *)ret->data); + if (ret->data != NULL) OPENSSL_free(ret->data); ret->data=s; ret->type=V_ASN1_BIT_STRING; if (a != NULL) (*a)=ret; *pp=p; return(ret); err: - ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); + ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_BIT_STRING_free(ret); + M_ASN1_BIT_STRING_free(ret); return(NULL); } @@ -187,22 +181,31 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) w=n/8; v=1<<(7-(n&0x07)); iv= ~v; + if (!value) v=0; + + if (a == NULL) + return 0; a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */ - if (a == NULL) return(0); if ((a->length < (w+1)) || (a->data == NULL)) { if (!value) return(1); /* Don't need to set */ if (a->data == NULL) - c=(unsigned char *)Malloc(w+1); + c=(unsigned char *)OPENSSL_malloc(w+1); else - c=(unsigned char *)Realloc(a->data,w+1); - if (c == NULL) return(0); + c=(unsigned char *)OPENSSL_realloc_clean(a->data, + a->length, + w+1); + if (c == NULL) + { + ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT,ERR_R_MALLOC_FAILURE); + return 0; + } + if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length); a->data=c; a->length=w+1; - c[w]=0; - } + } a->data[w]=((a->data[w])&iv)|v; while ((a->length > 0) && (a->data[a->length-1] == 0)) a->length--; @@ -220,3 +223,26 @@ int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n) return((a->data[w]&v) != 0); } +/* + * Checks if the given bit string contains only bits specified by + * the flags vector. Returns 0 if there is at least one bit set in 'a' + * which is not specified in 'flags', 1 otherwise. + * 'len' is the length of 'flags'. + */ +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len) + { + int i, ok; + /* Check if there is one bit set at all. */ + if (!a || !a->data) return 1; + + /* Check each byte of the internal representation of the bit string. */ + ok = 1; + for (i = 0; i < a->length && ok; ++i) + { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + /* We are done if there is an unneeded bit set. */ + ok = (a->data[i] & mask) == 0; + } + return ok; + }