X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fa_bitstr.c;h=0cb899f0580a3dd5459e82263aa0bc1c774d3563;hp=7013a407ad68385d0f82c27ec6d4aed864f5d4ea;hb=f756fb430eb8f5f70696f174460eb90740b318f7;hpb=5584fa1709585ee6d7e4f20551a71077f0e36699 diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c index 7013a407ad..0cb899f058 100644 --- a/crypto/asn1/a_bitstr.c +++ b/crypto/asn1/a_bitstr.c @@ -60,27 +60,9 @@ #include "cryptlib.h" #include -ASN1_BIT_STRING *ASN1_BIT_STRING_new(void) -{ return M_ASN1_BIT_STRING_new(); } - -void ASN1_BIT_STRING_free(ASN1_BIT_STRING *x) -{ M_ASN1_BIT_STRING_free(x); } - int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) { return M_ASN1_BIT_STRING_set(x, d, len); } -int i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) -{ - int len, ret; - len = i2c_ASN1_BIT_STRING(a, NULL); - ret=ASN1_object_size(0,len,V_ASN1_BIT_STRING); - if(pp) { - ASN1_put_object(pp,0,len,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); - i2c_ASN1_BIT_STRING(a, pp); - } - return ret; -} - int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) { int ret,j,bits,len; @@ -89,8 +71,6 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) if (a == NULL) return(0); len=a->length; - ret=1+len; - if (pp == NULL) return(ret); if (len > 0) { @@ -118,6 +98,10 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) } else bits=0; + + ret=1+len; + if (pp == NULL) return(ret); + p= *pp; *(p++)=(unsigned char)bits; @@ -129,47 +113,20 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) return(ret); } - -/* Convert DER encoded ASN1 BIT_STRING to ASN1_BIT_STRING structure */ -ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, - long length) -{ - unsigned char *p; - long len; +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) + { + ASN1_BIT_STRING *ret=NULL; + const unsigned char *p; + unsigned char *s; int i; - int inf,tag,xclass; - ASN1_BIT_STRING *ret; - p= *pp; - inf=ASN1_get_object(&p,&len,&tag,&xclass,length); - if (inf & 0x80) + if (len < 1) { - i=ASN1_R_BAD_OBJECT_HEADER; + i=ASN1_R_STRING_TOO_SHORT; goto err; } - if (tag != V_ASN1_BIT_STRING) - { - i=ASN1_R_EXPECTING_A_BIT_STRING; - goto err; - } - if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } - ret = c2i_ASN1_BIT_STRING(a, &p, len); - if(ret) *pp = p; - return ret; -err: - ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); - return(NULL); - -} - -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, - long len) - { - ASN1_BIT_STRING *ret=NULL; - unsigned char *p,*s; - int i; - if ((a == NULL) || ((*a) == NULL)) { if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL); @@ -208,7 +165,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp, *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))) M_ASN1_BIT_STRING_free(ret); return(NULL); @@ -224,19 +181,28 @@ 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 *)OPENSSL_malloc(w+1); else - c=(unsigned char *)OPENSSL_realloc(a->data,w+1); - if (c == NULL) return(0); - if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length); + 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; } @@ -246,7 +212,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) return(1); } -int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n) +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) { int w,v; @@ -257,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(const ASN1_BIT_STRING *a, + const 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; + }