/* * 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_clear_realloc(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); }
size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len) { char *ret; size_t n; if (str->length >= len) { if (str->data != NULL) 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->flags & BUF_MEM_FLAG_SECURE)) ret = sec_alloc_realloc(str, n); else ret = OPENSSL_clear_realloc(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 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; i = bufsize; if (buf[i - 1] == '\n') buf[--i] = '\0'; if (i == 0) goto err; if (buf[i - 1] == '\r') buf[--i] = '\0'; if (i == 0) goto err; 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; bufp = (unsigned char *)buf; if (first) { first = 0; if ((bufp[0] == '0') && (bufp[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); OPENSSL_free(s); return 0; } i /= 2; if (num + i > slen) { sp = OPENSSL_clear_realloc(s, slen, num + i * 2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); OPENSSL_free(s); return 0; } s = sp; slen = num + i * 2; } for (j = 0; j < i; j++, k += 2) { for (n = 0; n < 2; n++) { m = OPENSSL_hexchar2int(bufp[k + n]); if (m < 0) { 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; return 1; err: ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); OPENSSL_free(s); return 0; }
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) { 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; i = bufsize; if (buf[i - 1] == '\n') buf[--i] = '\0'; if (i == 0) goto err; if (buf[i - 1] == '\r') buf[--i] = '\0'; if (i == 0) goto err; again = (buf[i - 1] == '\\'); for (j = 0; j < i; j++) { if (!ossl_isxdigit(buf[j])) { i = j; break; } } buf[i] = '\0'; /* * We have now cleared all the crap off the end of the line */ if (i < 2) goto err; bufp = (unsigned char *)buf; if (first) { first = 0; if ((bufp[0] == '0') && (bufp[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); OPENSSL_free(s); return 0; } i /= 2; if (num + i > slen) { sp = OPENSSL_clear_realloc(s, slen, num + i * 2); if (sp == NULL) { ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); OPENSSL_free(s); return 0; } s = sp; slen = num + i * 2; } for (j = 0; j < i; j++, k += 2) { for (n = 0; n < 2; n++) { m = OPENSSL_hexchar2int(bufp[k + n]); if (m < 0) { 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; return 1; err: ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); OPENSSL_free(s); return 0; }