int sk_insert(_STACK *st, void *data, int loc) { char **s; if (st == NULL) return 0; if (st->num_alloc <= st->num + 1) { s = OPENSSL_realloc((char *)st->data, (unsigned int)sizeof(char *) * st->num_alloc * 2); if (s == NULL) return (0); st->data = s; st->num_alloc *= 2; } if ((loc >= (int)st->num) || (loc < 0)) st->data[st->num] = data; else { int i; char **f, **t; f = st->data; t = &(st->data[1]); for (i = st->num; i >= loc; i--) t[i] = f[i]; #ifdef undef /* no memmove on sunos :-( */ memmove(&(st->data[loc + 1]), &(st->data[loc]), sizeof(char *) * (st->num - loc)); #endif st->data[loc] = data; } st->num++; st->sorted = 0; return (st->num); }
void ERR_add_error_vdata(int num, va_list args) { int i, n, s; char *str, *p, *a; s = 80; str = OPENSSL_malloc(s + 1); if (str == NULL) return; str[0] = '\0'; n = 0; for (i = 0; i < num; i++) { a = va_arg(args, char *); if (a == NULL) a = "<NULL>"; n += strlen(a); if (n > s) { s = n + 20; p = OPENSSL_realloc(str, s + 1); if (p == NULL) { OPENSSL_free(str); return; } str = p; } OPENSSL_strlcat(str, a, (size_t)s + 1); } ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING); }
/* Called by: clear_sign, extract_certificate, extract_request, main, open_private_key, sign */ char* mime_canon(const char* s) { char* d; char* p; int len; len = strlen(s); p = d = (char*)OPENSSL_malloc(len + len); /* Reserve spaces for CR's to be inserted. */ if (!d) GOTO_ERR("no memory?"); /* Scan and copy */ for (; *s; s++) { if (s[0] != '\015' && s[0] != '\012') *(p++) = *s; /* pass thru */ else { if (s[0] == '\015' && s[1] == '\012') s++; /* already CRLF */ *(p++) = '\015'; *(p++) = '\012'; } } *(p++) = '\0'; /* Shrink the buffer back to actual size (not very likely to fail) */ return (char*)OPENSSL_realloc(d, (p-d)); err: return NULL; }
int BUF_MEM_grow(BUF_MEM *str, size_t len) { char *ret; size_t n; if (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, ERR_R_MALLOC_FAILURE); return 0; } n = (len + 3) / 3 * 4; if (str->data == NULL) ret = OPENSSL_malloc(n); else ret = OPENSSL_realloc(str->data, n); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_GROW, 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 encode_ssc(const BIGNUM *ssc, const KA_CTX *ctx, unsigned char **encoded) { unsigned char *p; size_t en_len, bn_len; if (!ctx || !encoded) { log_err("Invalid arguments"); return -1; } en_len = EVP_CIPHER_block_size(ctx->cipher); p = OPENSSL_realloc(*encoded, en_len); if (!p) { log_err("Realloc failure"); return -1; } *encoded = p; bn_len = BN_num_bytes(ssc); if (bn_len <= en_len) { memset(*encoded, 0, en_len - bn_len); BN_bn2bin(ssc, *encoded + en_len - bn_len); } else { p = OPENSSL_malloc(bn_len); if (!p) return -1; BN_bn2bin(ssc, p); /* Flawfinder: ignore */ memcpy(*encoded, p + bn_len - en_len, en_len); OPENSSL_free(p); } return en_len; }
_STACK *sk_dup(_STACK *sk) { _STACK *ret; char **s; if ((ret = sk_new(sk->comp)) == NULL) goto err; s = (char **)OPENSSL_realloc((char *)ret->data, (unsigned int)sizeof(char *) * sk->num_alloc); if (s == NULL) goto err; ret->data = s; ret->num = sk->num; memcpy(ret->data, sk->data, sizeof(char *) * sk->num); ret->sorted = sk->sorted; ret->num_alloc = sk->num_alloc; ret->comp = sk->comp; return (ret); err: if (ret) sk_free(ret); return (NULL); }
int BUF_MEM_grow(BUF_MEM *str, size_t len) { char *ret; size_t n; if (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(str->data,n); if (ret == NULL) { BUFerr(BUF_F_BUF_MEM_GROW,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 append_buf(char **buf, int *size, const char *s) { if (*buf == NULL) { *size = 256; *buf = app_malloc(*size, "engine buffer"); **buf = '\0'; } if (strlen(*buf) + strlen(s) >= (unsigned int)*size) { char *tmp; *size += 256; tmp = OPENSSL_realloc(*buf, *size); if (tmp == NULL) { OPENSSL_free(*buf); *buf = NULL; return 0; } *buf = tmp; } if (**buf != '\0') OPENSSL_strlcat(*buf, ", ", *size); OPENSSL_strlcat(*buf, s, *size); return 1; }
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) { ASN1_ENUMERATED *ret; int len,j; if (ai == NULL) ret=M_ASN1_ENUMERATED_new(); else ret=ai; if (ret == NULL) { OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ASN1_R_NESTED_ASN1_ERROR); goto err; } if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED; else ret->type=V_ASN1_ENUMERATED; j=BN_num_bits(bn); len=((j == 0)?0:((j/8)+1)); if (ret->length < len+4) { unsigned char *new_data=OPENSSL_realloc(ret->data, len+4); if (!new_data) { OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); goto err; } ret->data=new_data; } ret->length=BN_bn2bin(bn,ret->data); return(ret); err: if (ret != ai) M_ASN1_ENUMERATED_free(ret); return(NULL); }
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) { unsigned char *c; const char *data=_data; if (len < 0) { if (data == NULL) return(0); else len=strlen(data); } if ((str->length < len) || (str->data == NULL)) { c=str->data; if (c == NULL) str->data=OPENSSL_malloc(len+1); else str->data=OPENSSL_realloc(c,len+1); if (str->data == NULL) { ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE); str->data=c; return(0); } } str->length=len; if (data != NULL) { memcpy(str->data,data,len); /* an allowance for strings :-) */ str->data[len]='\0'; } return(1); }
int sk_insert(STACK *st, char *data, int loc) { char **s; if(st == NULL) return 0; if (st->num_alloc <= st->num+1) { s=(char **)OPENSSL_realloc((char *)st->data, (unsigned int)sizeof(char *)*st->num_alloc*2); if (s == NULL) return(0); st->data=s; st->num_alloc*=2; } if ((loc >= (int)st->num) || (loc < 0)) st->data[st->num]=data; else { int i; char **f,**t; f=(char **)st->data; t=(char **)&(st->data[1]); for (i=st->num; i>=loc; i--) t[i]=f[i]; st->data[loc]=data; } st->num++; st->sorted=0; return(st->num); }
static int append_buf(char **buf, const char *s, int *size, int step) { int l = strlen(s); if (*buf == NULL) { *size = step; *buf = OPENSSL_malloc(*size); if (*buf == NULL) return 0; **buf = '\0'; } if (**buf != '\0') l += 2; /* ", " */ if (strlen(*buf) + strlen(s) >= (unsigned int)*size) { *size += step; *buf = OPENSSL_realloc(*buf, *size); } if (*buf == NULL) return 0; if (**buf != '\0') BUF_strlcat(*buf, ", ", *size); BUF_strlcat(*buf, s, *size); return 1; }
int sk_insert(_STACK *st, void *data, int loc) { char **s; if (st == NULL) return 0; if (st->num_alloc <= st->num + 1) { s = OPENSSL_realloc((char *)st->data, (unsigned int)sizeof(char *) * st->num_alloc * 2); if (s == NULL) return (0); st->data = s; st->num_alloc *= 2; } if ((loc >= (int)st->num) || (loc < 0)) st->data[st->num] = data; else { memmove(&(st->data[loc + 1]), &(st->data[loc]), sizeof(char *) * (st->num - loc)); st->data[loc] = data; } st->num++; st->sorted = 0; return (st->num); }
void ERR_add_error_vdata(int num, va_list args) { int i, n, s; char *str, *p, *a; s = 80; str = OPENSSL_malloc(s + 1); if (str == NULL) return; str[0] = '\0'; n = 0; for (i = 0; i < num; i++) { a = va_arg(args, char *); /* ignore NULLs, thanks to Bob Beck <*****@*****.**> */ if (a != NULL) { n += strlen(a); if (n > s) { s = n + 20; p = OPENSSL_realloc(str, s + 1); if (p == NULL) { OPENSSL_free(str); return; } str = p; } OPENSSL_strlcat(str, a, (size_t)s + 1); } } ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING); }
void ERR_add_error_vdata(int num, va_list args) { int i, n, s; char *str, *p, *a; s = 80; if ((str = OPENSSL_malloc(s + 1)) == NULL) { /* ERRerr(ERR_F_ERR_ADD_ERROR_VDATA, ERR_R_MALLOC_FAILURE); */ return; } str[0] = '\0'; n = 0; for (i = 0; i < num; i++) { a = va_arg(args, char *); if (a == NULL) a = "<NULL>"; n += strlen(a); if (n > s) { s = n + 20; p = OPENSSL_realloc(str, s + 1); if (p == NULL) { OPENSSL_free(str); return; } str = p; } OPENSSL_strlcat(str, a, (size_t)s + 1); } if (!err_set_error_data_int(str, ERR_TXT_MALLOCED | ERR_TXT_STRING)) OPENSSL_free(str); }
_STACK *sk_dup(const _STACK *sk) { _STACK *ret; void **s; if (sk == NULL) { return NULL; } ret = sk_new(sk->comp); if (ret == NULL) { goto err; } s = (void **)OPENSSL_realloc(ret->data, sizeof(void *) * sk->num_alloc); if (s == NULL) { goto err; } ret->data = s; ret->num = sk->num; OPENSSL_memcpy(ret->data, sk->data, sizeof(void *) * sk->num); ret->sorted = sk->sorted; ret->num_alloc = sk->num_alloc; ret->comp = sk->comp; return ret; err: sk_free(ret); return NULL; }
static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret) { PKCS11_TOKEN_private *tpriv; PKCS11_CERT_private *kpriv; PKCS11_CERT *cert, *tmp; char label[256], data[2048]; unsigned char id[256]; CK_CERTIFICATE_TYPE cert_type; size_t size; size = sizeof(cert_type); if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size)) return -1; /* Ignore any certs we don't understand */ if (cert_type != CKC_X_509) return 0; tpriv = PRIVTOKEN(token); tmp = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs, (tpriv->ncerts + 1) * sizeof(PKCS11_CERT)); if (!tmp) { free(tpriv->certs); tpriv->certs = NULL; return -1; } tpriv->certs = tmp; cert = tpriv->certs + tpriv->ncerts++; memset(cert, 0, sizeof(*cert)); cert->_private = kpriv = PKCS11_NEW(PKCS11_CERT_private); kpriv->object = obj; kpriv->parent = token; if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label))) cert->label = BUF_strdup(label); size = sizeof(data); if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) { const unsigned char *p = (unsigned char *) data; cert->x509 = d2i_X509(NULL, &p, size); } cert->id_len = sizeof(id); if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &cert->id_len)) { cert->id = (unsigned char *) malloc(cert->id_len); memcpy(cert->id, id, cert->id_len); } /* Initialize internal information */ kpriv->id_len = sizeof(kpriv->id); if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len)) kpriv->id_len = 0; if (ret) *ret = cert; return 0; }
/* Called by: attach x9, encrypt1, get_req_attr x3, mime_base64_entity x3, mime_mk_multipart x3, mime_raw_entity x3, sign, smime_mk_multipart_signed x4 */ char* concat(char* b, const char* s) { if (!(b = (char*)OPENSSL_realloc(b, strlen(b)+strlen(s)+1))) GOTO_ERR("no memory?"); strcat(b,s); return b; err: return NULL; }
/* Called by: get_req_attr */ char* concatmem(char* b, const char* s, int len) { int lb = strlen(b); if (!(b = (char*)OPENSSL_realloc(b, lb+len+1))) GOTO_ERR("no memory?"); memcpy(b+lb, s, len); b[lb+len] = '\0'; return b; err: return NULL; }
static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data, unsigned long len) { MD_DATA *md_data = ctx->md_data; if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) return do_digest(md_data->sess.ses, md_data->md, data, len); md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len); memcpy(md_data->data + md_data->len, data, len); md_data->len += len; 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; }
static void list_objects(void) { int max_nid = OBJ_new_nid(0); int i; char *oid_buf = NULL; int oid_size = 0; /* Skip 0, since that's NID_undef */ for (i = 1; i < max_nid; i++) { const ASN1_OBJECT *obj = OBJ_nid2obj(i); const char *sn = OBJ_nid2sn(i); const char *ln = OBJ_nid2ln(i); int n = 0; /* * If one of the retrieved objects somehow generated an error, * we ignore it. The check for NID_undef below will detect the * error and simply skip to the next NID. */ ERR_clear_error(); if (OBJ_obj2nid(obj) == NID_undef) continue; if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) { BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln); continue; } if (n < 0) break; /* Error */ if (n > oid_size) { oid_buf = OPENSSL_realloc(oid_buf, n + 1); if (oid_buf == NULL) { BIO_printf(bio_err, "ERROR: Memory allocation\n"); break; /* Error */ } oid_size = n + 1; } if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0) break; /* Error */ if (ln == NULL || strcmp(sn, ln) == 0) BIO_printf(bio_out, "%s = %s\n", sn, oid_buf); else BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf); } OPENSSL_free(oid_buf); }
/* Set callbacks for a custom extension. */ static int custom_ext_meth_add(custom_ext_methods *exts, unsigned int ext_type, custom_ext_add_cb add_cb, custom_ext_free_cb free_cb, void *add_arg, custom_ext_parse_cb parse_cb, void *parse_arg) { custom_ext_method *meth, *tmp; /* * Check application error: if add_cb is not set free_cb will never be * called. */ if (!add_cb && free_cb) return 0; /* * Don't add if extension supported internally, but make exception * for extension types that previously were not supported, but now are. */ if (SSL_extension_supported(ext_type) && ext_type != TLSEXT_TYPE_signed_certificate_timestamp) return 0; /* Extension type must fit in 16 bits */ if (ext_type > 0xffff) return 0; /* Search for duplicate */ if (custom_ext_find(exts, ext_type)) return 0; tmp = OPENSSL_realloc(exts->meths, (exts->meths_count + 1) * sizeof(custom_ext_method)); if (tmp == NULL) { OPENSSL_free(exts->meths); exts->meths = NULL; exts->meths_count = 0; return 0; } exts->meths = tmp; meth = exts->meths + exts->meths_count; memset(meth, 0, sizeof(*meth)); meth->parse_cb = parse_cb; meth->add_cb = add_cb; meth->free_cb = free_cb; meth->ext_type = ext_type; meth->add_arg = add_arg; meth->parse_arg = parse_arg; exts->meths_count++; return 1; }
/* read_file opens |path| and reads until end-of-file. On success, it returns * one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the * contents. Otherwise, it returns zero. */ static int read_file(char **out_ptr, size_t *out_len, const char *path) { int fd = open_eintr(path, O_RDONLY); if (fd < 0) { return 0; } static const size_t kReadSize = 1024; int ret = 0; size_t cap = kReadSize, len = 0; char *buf = OPENSSL_malloc(cap); if (buf == NULL) { goto err; } for (;;) { if (cap - len < kReadSize) { size_t new_cap = cap * 2; if (new_cap < cap) { goto err; } char *new_buf = OPENSSL_realloc(buf, new_cap); if (new_buf == NULL) { goto err; } buf = new_buf; cap = new_cap; } ssize_t bytes_read = read_eintr(fd, buf + len, kReadSize); if (bytes_read < 0) { goto err; } if (bytes_read == 0) { break; } len += bytes_read; } *out_ptr = buf; *out_len = len; ret = 1; buf = NULL; err: OPENSSL_free(buf); close(fd); return ret; }
static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) { struct crypt_op cryp; struct dev_crypto_state *state = ctx->md_data; struct session_op *sess = &state->d_sess; char *new_mac_data; if (!data || state->d_fd < 0) { printf("cryptodev_digest_update: illegal inputs \n"); return (0); } if (!count) { return (0); } if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { /* if application doesn't support one buffer */ new_mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); if (!new_mac_data) { printf("cryptodev_digest_update: realloc failed\n"); return (0); } state->mac_data = new_mac_data; memcpy(state->mac_data + state->mac_len, data, count); state->mac_len += count; return (1); } memset(&cryp, 0, sizeof(cryp)); cryp.ses = sess->ses; cryp.flags = 0; cryp.len = count; cryp.src = (caddr_t) data; cryp.dst = NULL; cryp.mac = (caddr_t) state->digest_res; if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { printf("cryptodev_digest_update: digest failed\n"); return (0); } return (1); }
/* ERR_add_error_data_vdata takes a variable number of const char* pointers, * concatenates them and sets the result as the data on the most recent * error. */ static void err_add_error_vdata(unsigned num, va_list args) { size_t alloced, new_len, len = 0, substr_len; char *buf; const char *substr; unsigned i; alloced = 80; buf = OPENSSL_malloc(alloced + 1); if (buf == NULL) { return; } for (i = 0; i < num; i++) { substr = va_arg(args, const char *); if (substr == NULL) { continue; } substr_len = strlen(substr); new_len = len + substr_len; if (new_len > alloced) { char *new_buf; if (alloced + 20 + 1 < alloced) { /* overflow. */ OPENSSL_free(buf); return; } alloced = new_len + 20; new_buf = OPENSSL_realloc(buf, alloced + 1); if (new_buf == NULL) { OPENSSL_free(buf); return; } buf = new_buf; } memcpy(buf + len, substr, substr_len); len = new_len; } buf[len] = 0; err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING); }
ASN1_INTEGER *BN_to_ASN1_INTEGER (const BIGNUM * bn, ASN1_INTEGER * ai) { ASN1_INTEGER *ret; int len, j; if (ai == NULL) ret = M_ASN1_INTEGER_new (); else ret = ai; if (ret == NULL) { ASN1err (ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR); goto err; } if (BN_is_negative (bn)) ret->type = V_ASN1_NEG_INTEGER; else ret->type = V_ASN1_INTEGER; j = BN_num_bits (bn); len = ((j == 0) ? 0 : ((j / 8) + 1)); if (ret->length < len + 4) { unsigned char *new_data = OPENSSL_realloc (ret->data, len + 4); if (!new_data) { ASN1err (ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); goto err; } ret->data = new_data; } ret->length = BN_bn2bin (bn, ret->data); /* Correct zero case */ if (!ret->length) { ret->data[0] = 0; ret->length = 1; } return (ret); err: if (ret != ai) M_ASN1_INTEGER_free (ret); return (NULL); }
size_t sk_insert(_STACK *sk, void *p, size_t where) { if (sk == NULL) { return 0; } if (sk->num_alloc <= sk->num + 1) { // Attempt to double the size of the array. size_t new_alloc = sk->num_alloc << 1; size_t alloc_size = new_alloc * sizeof(void *); void **data; // If the doubling overflowed, try to increment. if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { new_alloc = sk->num_alloc + 1; alloc_size = new_alloc * sizeof(void *); } // If the increment also overflowed, fail. if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { return 0; } data = OPENSSL_realloc(sk->data, alloc_size); if (data == NULL) { return 0; } sk->data = data; sk->num_alloc = new_alloc; } if (where >= sk->num) { sk->data[sk->num] = p; } else { OPENSSL_memmove(&sk->data[where + 1], &sk->data[where], sizeof(void *) * (sk->num - where)); sk->data[where] = p; } sk->num++; sk->sorted = 0; return sk->num; }
/* Add EFIAPI for UEFI version. */ void #if defined(OPENSSL_SYS_UEFI) EFIAPI #endif ERR_add_error_data(int num, ...) { va_list args; int i,n,s; char *str,*p,*a; s=80; str=OPENSSL_malloc(s+1); if (str == NULL) return; str[0]='\0'; va_start(args, num); n=0; for (i=0; i<num; i++) { a=va_arg(args, char*); /* ignore NULLs, thanks to Bob Beck <*****@*****.**> */ if (a != NULL) { n+=strlen(a); if (n > s) { s=n+20; p=OPENSSL_realloc(str,s+1); if (p == NULL) { OPENSSL_free(str); goto err; } else str=p; } BUF_strlcat(str,a,(size_t)s+1); } } ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING); err: va_end(args); }
/* Set callbacks for a custom extension. */ static int custom_ext_meth_add(custom_ext_methods *exts, unsigned int ext_type, custom_ext_add_cb add_cb, custom_ext_free_cb free_cb, void *add_arg, custom_ext_parse_cb parse_cb, void *parse_arg) { custom_ext_method *meth; /* * Check application error: if add_cb is not set free_cb will never be * called. */ if (!add_cb && free_cb) return 0; /* Don't add if extension supported internally. */ if (SSL_extension_supported(ext_type)) return 0; /* Extension type must fit in 16 bits */ if (ext_type > 0xffff) return 0; /* Search for duplicate */ if (custom_ext_find(exts, ext_type)) return 0; exts->meths = OPENSSL_realloc(exts->meths, (exts->meths_count + 1) * sizeof(custom_ext_method)); if (!exts->meths) { exts->meths_count = 0; return 0; } meth = exts->meths + exts->meths_count; memset(meth, 0, sizeof(*meth)); meth->parse_cb = parse_cb; meth->add_cb = add_cb; meth->free_cb = free_cb; meth->ext_type = ext_type; meth->add_arg = add_arg; meth->parse_arg = parse_arg; exts->meths_count++; return 1; }