/* * These next 2 functions from Goetz Babin-Ebell <*****@*****.**> */ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) { int w, v, iv; unsigned char *c; 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->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); return 0; } if (w + 1 - a->length > 0) memset(c + a->length, 0, w + 1 - a->length); a->data = c; 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); }
static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) { char *new_buf; size_t n, alloc_size; if (buf->length >= len) { buf->length = len; return len; } if (buf->max >= len) { memset(&buf->data[buf->length], 0, len - buf->length); buf->length = len; return len; } n = len + 3; if (n < len) { /* overflow */ OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE); return 0; } n = n / 3; alloc_size = n * 4; if (alloc_size / 4 != n) { /* overflow */ OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE); return 0; } if (buf->data == NULL) { new_buf = OPENSSL_malloc(alloc_size); } else { if (clean) { new_buf = OPENSSL_realloc_clean(buf->data, buf->max, alloc_size); } else { new_buf = OPENSSL_realloc(buf->data, alloc_size); } } if (new_buf == NULL) { OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE); len = 0; } else { buf->data = new_buf; buf->max = alloc_size; memset(&buf->data[buf->length], 0, len - buf->length); buf->length = len; } return len; }
int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) { char *ret; size_t n; if (str->length >= len) { memset(&str->data[len],0,str->length-len); str->length=len; return(len); } if (str->max >= len) { memset(&str->data[str->length],0,len-str->length); str->length=len; return(len); } /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); return 0; } n=(len+3)/3*4; if (str->data == NULL) ret=OPENSSL_malloc(n); else ret=OPENSSL_realloc_clean(str->data,str->max,n); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); len=0; } else { str->data=ret; str->max=n; memset(&str->data[str->length],0,len-str->length); str->length=len; } return(len); }
static int buf_mem_reserve(BUF_MEM *buf, size_t cap, int clean) { if (buf->max >= cap) { return 1; } size_t n = cap + 3; if (n < cap) { /* overflow */ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return 0; } n = n / 3; size_t alloc_size = n * 4; if (alloc_size / 4 != n) { /* overflow */ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return 0; } char *new_buf; if (buf->data == NULL) { new_buf = OPENSSL_malloc(alloc_size); } else { if (clean) { new_buf = OPENSSL_realloc_clean(buf->data, buf->max, alloc_size); } else { new_buf = OPENSSL_realloc(buf->data, alloc_size); } } if (new_buf == NULL) { OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); return 0; } buf->data = new_buf; buf->max = alloc_size; return 1; }
int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) { char *ret; size_t n; if (str->length >= len) { memset(&str->data[len],0,str->length-len); str->length=len; return(len); } if (str->max >= len) { memset(&str->data[str->length],0,len-str->length); str->length=len; return(len); } n=(len+3)/3*4; if (str->data == NULL) ret=OPENSSL_malloc(n); else ret=OPENSSL_realloc_clean(str->data,str->max,n); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); len=0; } else { str->data=ret; str->max=n; memset(&str->data[str->length],0,len-str->length); str->length=len; } return(len); }
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) { int ret=0; int i,j,k,m,n,again,bufsize; unsigned char *s=NULL,*sp; unsigned char *bufp; int num=0,slen=0,first=1; bs->type=V_ASN1_INTEGER; bufsize=BIO_gets(bp,buf,size); for (;;) { if (bufsize < 1) goto err_sl; i=bufsize; if (buf[i-1] == '\n') buf[--i]='\0'; if (i == 0) goto err_sl; if (buf[i-1] == '\r') buf[--i]='\0'; if (i == 0) goto err_sl; again=(buf[i-1] == '\\'); for (j=0; j<i; j++) { #ifndef CHARSET_EBCDIC if (!( ((buf[j] >= '0') && (buf[j] <= '9')) || ((buf[j] >= 'a') && (buf[j] <= 'f')) || ((buf[j] >= 'A') && (buf[j] <= 'F')))) #else /* This #ifdef is not strictly necessary, since * the characters A...F a...f 0...9 are contiguous * (yes, even in EBCDIC - but not the whole alphabet). * Nevertheless, isxdigit() is faster. */ if (!isxdigit(buf[j])) #endif { i=j; break; } } buf[i]='\0'; /* We have now cleared all the crap off the end of the * line */ if (i < 2) goto err_sl; bufp=(unsigned char *)buf; if (first) { first=0; if ((bufp[0] == '0') && (buf[1] == '0')) { bufp+=2; i-=2; } } k=0; i-=again; if (i%2 != 0) { ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_ODD_NUMBER_OF_CHARS); goto err; } i/=2; if (num+i > slen) { if (s == NULL) sp=(unsigned char *)OPENSSL_malloc( (unsigned int)num+i*2); else sp=OPENSSL_realloc_clean(s,slen,num+i*2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE); if (s != NULL) OPENSSL_free(s); goto err; } s=sp; slen=num+i*2; } for (j=0; j<i; j++,k+=2) { for (n=0; n<2; n++) { m=bufp[k+n]; if ((m >= '0') && (m <= '9')) m-='0'; else if ((m >= 'a') && (m <= 'f')) m=m-'a'+10; else if ((m >= 'A') && (m <= 'F')) m=m-'A'+10; else { ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_NON_HEX_CHARACTERS); goto err; } s[num+j]<<=4; s[num+j]|=m; } } num+=i; if (again) bufsize=BIO_gets(bp,buf,size); else break; } bs->length=num; bs->data=s; ret=1; err: if (0) { err_sl: ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_SHORT_LINE); } return(ret); }
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) { int ret=0; int i,j,k,m,n,again,bufsize; unsigned char *s=NULL,*sp; unsigned char *bufp; int num=0,slen=0,first=1; bs->type=V_ASN1_INTEGER; bufsize=BIO_gets(bp,buf,size); for (;;) { if (bufsize < 1) goto err_sl; i=bufsize; if (buf[i-1] == '\n') buf[--i]='\0'; if (i == 0) goto err_sl; if (buf[i-1] == '\r') buf[--i]='\0'; if (i == 0) goto err_sl; again=(buf[i-1] == '\\'); for (j=0; j<i; j++) { if (!( ((buf[j] >= '0') && (buf[j] <= '9')) || ((buf[j] >= 'a') && (buf[j] <= 'f')) || ((buf[j] >= 'A') && (buf[j] <= 'F')))) { i=j; break; } } buf[i]='\0'; /* We have now cleared all the crap off the end of the * line */ if (i < 2) goto err_sl; bufp=(unsigned char *)buf; if (first) { first=0; if ((bufp[0] == '0') && (buf[1] == '0')) { bufp+=2; i-=2; } } k=0; i-=again; if (i%2 != 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS); goto err; } i/=2; if (num+i > slen) { if (s == NULL) sp=(unsigned char *)OPENSSL_malloc( (unsigned int)num+i*2); else sp=OPENSSL_realloc_clean(s,slen,num+i*2); if (sp == NULL) { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); goto err; } s=sp; slen=num+i*2; } for (j=0; j<i; j++,k+=2) { for (n=0; n<2; n++) { m=bufp[k+n]; if ((m >= '0') && (m <= '9')) m-='0'; else if ((m >= 'a') && (m <= 'f')) m=m-'a'+10; else if ((m >= 'A') && (m <= 'F')) m=m-'A'+10; else { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS); goto err; } s[num+j]<<=4; s[num+j]|=m; } } num+=i; if (again) bufsize=BIO_gets(bp,buf,size); else break; } bs->length=num; bs->data=s; ret=1; err: if (0) { err_sl: OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE); } if (s != NULL) OPENSSL_free(s); return(ret); }