lsds / TaLoS

Efficient TLS termination inside Intel SGX enclaves for existing applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bugs found

LeoneChen opened this issue · comments

Null Pointer Dereference (NPD) (70)

In ecall_OBJ_nid2sn, invalid n fed to OBJ_nid2sn will cause NULL is returned to str (e.g. when ecall_OBJ_create is not called before), and then strlen(str) will crash

In ecall_ENGINE_get_name, ename is obtained from e, and can be null, then strlen can crash

In ecall_SSL_CIPHER_get_name, ret obtained from c can be null, then strlen(ret) can crash.

In ecall_SSL_set_fd, when ssl_hardening is never initialized before (get_ssl_hardening not called before), then m obtained is newly created and m->count is 0, cause output in_s with null in hashmapGet, then in SSL_copy_fields_to_in_struct, in->state crashes. What's more, out_s assigned with parameter can be null but without any check, then out->state crashes. Below are functions that have same problem:

  • ecall_SSL_connect
  • ecall_SSL_accept
  • ecall_SSL_pending
  • ecall_SSL_ctrl
  • ecall_SSL_state
  • ecall_SSL_shutdown
  • ecall_SSL_read
  • ecall_SSL_write
  • ecall_SSL_free (in_s can be null, then in_s->references crash)
  • ecall_SSL_set_fd
  • ecall_SSL_set_verify
  • ecall_SSL_set_verify_result
  • ecall_SSL_set_session_id_context
  • ecall_SSL_set_alpn_protos
  • ecall_SSL_set_shutdown
  • ecall_SSL_set_cipher_list
  • ecall_SSL_set_bio
  • ecall_SSL_get_ciphers
  • ecall_SSL_get_peer_certificate
  • ecall_SSL_get_verify_result
  • ecall_SSL_get_verify_mode
  • ecall_SSL_get_wbio
  • ecall_SSL_get_rbio
  • ecall_SSL_get_servername
  • ecall_SSL_get_SSL_CTX
  • ecall_SSL_get_shutdown

Another simliar case is ecall_SSL_set_info_callback->SSL_copy_fields_to_out_struct, invalid in_s output out_s with null in hashmapGet, then out->state crash. Below are functions that have same problem:

  • ecall_SSL_set_info_callback

In ecall_BN_to_ASN1_INTEGER -> BN_to_ASN1_INTEGER, when bn is null, BN_is_negative(bn) can crash.

ecall_X509_get_ex_data -> X509_get_ex_data -> CRYPTO_get_ex_data. When r in ECALL is fed with null, ad is 0x28, then ad->sk cause NPD.

ecall_SSL_CTX_get_client_CA_list -> SSL_CTX_get_client_CA_list. When ctx is null, ctx->client_CA crashes.

ecall_X509_get_cert_key_algor_algorithm->X509_get_cert_key_algor_algorithm. x->cert_info->key->algor can be null, then x->cert_info->key->algor->algorithm; cause NPD. Below are functions that have same problem:

  • ecall_X509_get_cert_key_algor_algorithm
  • ecall_X509_get_algorithm

ecall_SSL_use_PrivateKey->SSL_use_PrivateKey->ssl_cert_inst. ssl in SSL_use_PrivateKey can be null, then o from &ssl->cert is 0xf8, then *o == NULL crash.

ecall_SSL_set_connect_state->SSL_set_connect_state. s can be null, then s->server = 0; crash. Below are functions that have same problem:

  • ecall_SSL_set_connect_state
  • ecall_SSL_set_accept_state
  • ecall_SSL_get_certificate (s->cert in SSL_get_certificate)
  • ecall_SSL_get_privatekey (s->cert in SSL_get_privatekey)
  • ecall_SSL_do_handshake (s->handshake_func in SSL_do_handshake)
  • ecall_SSL_CTX_get_cert_store (ctx->cert_store in SSL_CTX_get_cert_store)
  • ecall_X509_sign (x->cert_info in X509_sign)
  • ecall_SSL_CTX_get_verify_mode (ctx in SSL_CTX_get_verify_mode)
  • ecall_SSL_CTX_set_default_passwd_cb (ctx in SSL_CTX_set_default_passwd_cb)
  • ecall_SSL_CTX_ctrl (ctx in SSL_CTX_ctrl)
  • ecall_EVP_DigestFinal_ex (ctx and ctx->digest in EVP_DigestFinal_ex)
  • ecall_X509_get_ext (X509_get_ext in X509_get_ext)
  • ecall_SSL_CTX_get_verify_callback (ctx in SSL_CTX_get_verify_callback)
  • ecall_X509_get_subject_name (a in X509_get_subject_name)
  • ecall_ENGINE_get_name (e in ENGINE_get_name)
  • ecall_X509_pubkey_digest (x->cert_info->key in X509_pubkey_digest->X509_get0_pubkey_bitstr)
  • ecall_SSL_select_next_proto (server in SSL_select_next_proto, server[i])
  • ecall_DH_free (r->meth in DH_free)
  • ecall_SSL_CTX_sess_set_get_cb (ctx in SSL_CTX_sess_set_get_cb)
  • ecall_BN_is_zero (a in BN_is_zero)
  • ecall_BN_num_bits (a in BN_num_bits)
  • ecall_ENGINE_get_id (e in ENGINE_get_id)
  • ecall_d2i_SSL_SESSION (p is from *pp which is one of ECALL parameters, in d2i_SSL_SESSION->asn1_GetSequence->ASN1_get_object)
  • ecall_SSL_CTX_set_ex_data (s in SSL_CTX_set_ex_data, then &s->ex_data is 0xd0, ad->sk in CRYPTO_set_ex_data crash)

ecall_BN_dup->BN_dup->BN_copy. A is from a->d and is null since a is newly allocated from BN_new. Then A[0] crashes. When i smaller then 0, A[1] crashes in case 3, case 2 and case 1

ecall_SSL_CTX_set_default_verify_paths->SSL_CTX_set_default_verify_paths. ctx can be null, then ctx->cert_store crashes

ecall_SSL_get_error->SSL_get_error->SSL_want_read (SSL_want). s can be null, then s->rwstate crashes

ecall_X509_check_issued->X509_check_issued->X509_NAME_cmp->i2d_X509_NAME->ASN1_item_i2d->asn1_item_flags_i2d->ASN1_item_ex_i2d->ef->asn1_ex_i2d->x509_name_encode->BUF_MEM_grow. str can be null, then str->length crashes.

ecall_SSL_CTX_set_cipher_list->SSL_CTX_set_cipher_list. ctx can be null, then ctx->method crashes

ecall_SSL_CTX_set_default_verify_paths->SSL_CTX_set_default_verify_paths->X509_STORE_set_default_paths->X509_STORE_add_lookup->sk_X509_LOOKUP_push (sk_push)->sk_insert. st->data can be null, st->data[st->num] crashes

ecall_X509_digest->X509_digest->ASN1_item_digest->ASN1_item_i2d->asn1_item_flags_i2d->ASN1_item_ex_i2d->asn1_template_ex_i2d->ASN1_item_ex_i2d->asn1_template_ex_i2d->ASN1_item_ex_i2d->asn1_i2d_ex_primitive->asn1_ex_i2c. pf can be null, then pf->prim_i2c crashes

ecall_EC_KEY_free->EC_KEY_free->EC_GROUP_free. group

ecall_SSL_CTX_use_PrivateKey_file->SSL_CTX_use_PrivateKey_file->BIO_new->execute_bio_ocall_malloc->bio_alloc_from_pool. When first call get_bio_mempool, m_memStart of returned pool is 0, then in pool_alloc, AddrFromIndex return p with null, then *p crashes

ecall_X509_set_ex_data->X509_set_ex_data->CRYPTO_set_ex_data->sk_void_set (sk_set). st->data can be null.

Arbitrarily access

In ecall_EC_KEY_free -> EC_KEY_free -> EC_GROUP_free -> EC_EX_DATA_free_all_data, in d->free_func(d->data), d is from ecall parameter, and d->free_func can be set by host, cause arbitrarily execute. And can also cause NPD.

In ecall_EVP_DigestUpdate -> EVP_DigestUpdate, ctx->update can be set by host arbitrarily.ctx itself can also be null.

In ecall_SSL_CTX_set_cipher_list -> SSL_CTX_set_cipher_list -> ssl_create_cipher_list, ssl_method->num_ciphers can be set by host arbitrarily, and ssl_method->num_ciphers(); cause arbitrarily execute.

ecall_SSL_CTX_ctrl -> SSL_CTX_ctrl. ctx->method->ssl_ctx_ctrl can be set by host, then arbitrarily execute.

Enclave OOB

ecall_BN_set_word->BN_set_word->bn_expand->bn_expand2->bn_expand_internal. A is from reallocarray with size words * sizeof(BN_ULONG), when words is 1, A's size is 8, then A[1] will cause OOB.

Integer overflow

ecall_MD5_Update->MD5_Update. HASH_CBLOCK is ox40, when len is 0xd130a30f9e12c8b6, n is 0xadebd7, p is 0x13f0828 and data is 0x13f0ba0, if condition will pass and HASH_CBLOCK - n is 0xffffffffff521469 which cause integer overflow, then cause data OOB. When p + n is 0xfcab52d3, data is null and HASH_CBLOCK - n is 0xffffffff04ac32c5, cause range overlap in memcpy

if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
memcpy (p + n, data, HASH_CBLOCK - n);

ecall_ERR_error_string_n->ERR_error_string_n->snprintf. len can be set by host, e.g. 0x18bf9cf050e4bd9c.

Host OOB (Which can overflow to anywhere)

In ecall_BN_to_ASN1_INTEGER -> BN_to_ASN1_INTEGER -> BN_num_bits, when i so large can cause a->d[i] point to anywhere. Below are functions that have same problem:

  • ecall_BN_to_ASN1_INTEGER
  • ecall_BN_num_bits

In ecall_ASN1_INTEGER_to_BN -> ASN1_INTEGER_to_BN -> BN_bin2bn, when i so large can cause ret->d[--i] point to anywhere

ecall_MD5_Final -> MD5_Final. n can be so large, then p[n] = 0x80; cause OOB

In ecall_X509_NAME_delete_entry -> X509_NAME_delete_entry, name->entries->data can be null, cause st->data[loc] in X509_NAME_delete_entry crash, since loc is provided by untrusted host, and range limit of loc is also provided by host, then st->data[loc] can cause OOB

ecall_SSL_CTX_set_default_verify_paths -> SSL_CTX_set_default_verify_paths -> X509_STORE_set_default_paths -> X509_STORE_add_lookup -> sk_X509_LOOKUP_value (sk_value), st->data can be set by host and i is also controlled by host, then st->data[i] can cause OOB.

ecall_BN_clear_bit->BN_clear_bit. i can be so large, a->d[i] cause OOB

ecall_BN_is_bit_set->BN_is_bit_set. i can be so large, a->d[i] cause OOB

ecall_X509_set_notBefore->X509_set_notBefore->ASN1_STRING_dup->ASN1_STRING_copy->ASN1_STRING_set->memmove. When len so large, e.g. 0x43c5423a, cause OOB.

ecall_BN_free->BN_free->BN_clear_free->bzero. a->dmax * sizeof(a->d[0]) can be so lareg, e.g. 0x1e1731050, then a->d OOB

ecall_SSL_select_next_proto->SSL_select_next_proto. client_len can be large e.g. 0x2300fee2, then j can be 420, client[j] OOB

Host OOB (Which overflow to redzone of ASan)

Not importent, ignored

Assert fail

In ecall_start_sgx_thread -> __initschedqueue, when maxlthreads is 0xffffffffc8e33fdc for example, roundup2(maxlthreads) output 0, then in mpmc_queue_new, buffer_size is 0 and assert((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0)); fail. When buffer_size so large can cause out of memory

TOCTOU (40)

ecall_X509_set_subject_name -> X509_set_subject_name -> X509_NAME_set -> X509_NAME_dup -> ASN1_item_dup -> ASN1_item_i2d -> asn1_item_flags_i2d -> ASN1_item_ex_i2d -> ef->asn1_ex_i2d -> x509_name_canon, a is from ecall parameter, a->canon_enc can be set by host. In this case, a->canon_enc can reside in host memory, after check, content of a->canon_enc can be modified by host.

if (a->canon_enc) {
free(a->canon_enc);

ecall_X509_set_version->X509_set_version. x->cert_info->version reside in host and can be modified by host after check, then in ASN1_INTEGER_set, a can be everything (e.g. null).

if (x->cert_info->version == NULL) {
if ((x->cert_info->version = ASN1_INTEGER_new()) == NULL)
return (0);
}
return (ASN1_INTEGER_set(x->cert_info->version, version));

ecall_EVP_MD_CTX_destroy->EVP_MD_CTX_cleanup. ctx->digest and ctx->md_data can be modified (set to null) by host after check.

if (ctx->digest && ctx->digest->cleanup &&
!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
ctx->digest->cleanup(ctx);
if (ctx->digest && ctx->digest->ctx_size && ctx->md_data &&
!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
explicit_bzero(ctx->md_data, ctx->digest->ctx_size);
free(ctx->md_data);
}

Below are functions have same problem:

  • ecall_EVP_MD_CTX_destroy
  • ecall_EVP_DigestInit_ex

ecall_X509_alias_get0->X509_alias_get0. x->aux.

if (!x->aux || !x->aux->alias)

ecall_X509_set_notBefore->X509_set_notBefore. x->cert_info->validity.

if ((x == NULL) || (x->cert_info->validity == NULL))
return (0);
in = x->cert_info->validity->notBefore;

Below are functions have same problem:

  • ecall_X509_set_notBefore
  • ecall_X509_set_notAfter

ecall_BIO_new_file->BIO_new_file->BIO_set_fp(BIO_ctrl). b->method

if ((b->method == NULL) || (b->method->ctrl == NULL)) {
BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
return (ret);
ret = b->method->ctrl(b, cmd, larg, parg);

ecall_BIO_free->BIO_free->CRYPTO_free_ex_data->EX_IMPL(free_ex_data)->int_free_ex_data. ad->sk.

if (ad->sk) {
sk_void_free(ad->sk);

ecall_PEM_read_bio_ECPKParameters->PEM_read_bio_ECPKParameters->IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)(PEM_ASN1_read_bio)->PEM_bytes_read_bio->PEM_read_bio->BIO_gets. b->method

if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
return (i);
if (!b->init) {
BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bgets(b, in, inl);

ecall_X509_check_private_key->X509_check_private_key->X509_get_pubkey. x->cert_info

if ((x == NULL) || (x->cert_info == NULL))
return (NULL);
return (X509_PUBKEY_get(x->cert_info->key));

ecall_X509_digest->X509_digest->ASN1_item_digest->ASN1_item_i2d->asn1_item_flags_i2d->ASN1_item_ex_i2d->asn1_enc_restore. enc

if (!enc || enc->modified)

ecall_SSL_CTX_check_private_key->SSL_CTX_check_private_key. ctx->cert.

if ((ctx == NULL) || (ctx->cert == NULL) ||
(ctx->cert->key->x509 == NULL)) {

ecall_BN_dec2bn->BN_dec2bn. *bn

if (*bn == NULL) {
if ((ret = BN_new()) == NULL)
return (0);
} else {
ret = *bn;
BN_zero(ret);
}

ecall_SSL_set_SSL_CTX->SSL_set_SSL_CTX->ssl_cert_free->CRYPTO_add. c

if (c == NULL)
return;
i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);

ecall_SSL_get_current_cipher->SSL_get_current_cipher. s->session TOCTOU, and s can be null.

if ((s->session != NULL) && (s->session->cipher != NULL))
return (s->session->cipher);

ecall_DH_free->DH_free->ENGINE_finish. e is from r->engine, and reside in host memory.

if (e == NULL) {
ENGINEerr(ENGINE_F_ENGINE_FINISH, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
to_return = engine_unlocked_finish(e, 1);

ecall_X509_get_ex_data->X509_get_ex_data->CRYPTO_get_ex_data. ad->sk

if (ad->sk == NULL)
return (0);
else if (idx >= sk_void_num(ad->sk))

ecall_X509_NAME_ENTRY_free->X509_NAME_ENTRY_free->ASN1_item_free->asn1_item_combine_free->ASN1_template_free->asn1_item_combine_free->ASN1_primitive_free. *pval.

if (!it) {
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type;
pval = &typ->value.asn1_value;
if (!*pval)
return;
} else if (it->itype == ASN1_ITYPE_MSTRING) {
utype = -1;
if (!*pval)
return;
} else {
utype = it->utype;
if ((utype != V_ASN1_BOOLEAN) && !*pval)
return;
}
switch (utype) {
case V_ASN1_OBJECT:
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);

ecall_EVP_PKEY_bits->EVP_PKEY_bits. pkey->ameth.

if (pkey && pkey->ameth && pkey->ameth->pkey_bits)

ecall_SSL_CTX_set_ex_data->SSL_CTX_set_ex_data->CRYPTO_set_ex_data. ad->sk

if (ad->sk == NULL) {
if ((ad->sk = sk_void_new_null()) == NULL) {
CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,
ERR_R_MALLOC_FAILURE);
return (0);
}
}
i = sk_void_num(ad->sk);
while (i <= idx) {
if (!sk_void_push(ad->sk, NULL)) {
CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA,
ERR_R_MALLOC_FAILURE);
return (0);
}
i++;
}
sk_void_set(ad->sk, idx, val);

ecall_SSL_new->SSL_new->ssl_cert_dup. ctx->cert.

if (ctx->cert != NULL) {
/*
* Earlier library versions used to copy the pointer to
* the CERT, not its contents; only when setting new
* parameters for the per-SSL copy, ssl_cert_new would be
* called (and the direct reference to the per-SSL_CTX
* settings would be lost, but those still were indirectly
* accessed for various purposes, and for that reason they
* used to be known as s->ctx->default_cert).
* Now we don't look at the SSL_CTX's CERT after having
* duplicated it once.
*/
s->cert = ssl_cert_dup(ctx->cert);

ecall_EVP_PKEY_free->EVP_PKEY_free->EVP_PKEY_free_it. x->ameth

if (x->ameth && x->ameth->pkey_free) {

ecall_X509_digest->X509_digest->ASN1_item_digest->ASN1_item_i2d->asn1_item_flags_i2d->ASN1_item_ex_i2d->asn1_template_ex_i2d->ASN1_item_ex_i2d->asn1_template_ex_i2d->ASN1_item_ex_i2d->asn1_i2d_ex_primitive->asn1_ex_i2c->i2c_ASN1_INTEGER. *pval.

if (!*pval)
return -1;
}
if (it->itype == ASN1_ITYPE_MSTRING) {
/* If MSTRING type set the underlying type */
strtmp = (ASN1_STRING *)*pval;
utype = strtmp->type;
*putype = utype;
} else if (it->utype == V_ASN1_ANY) {
/* If ANY set type and pointer to value */
ASN1_TYPE *typ;
typ = (ASN1_TYPE *)*pval;
utype = typ->type;
*putype = utype;
pval = &typ->value.asn1_value;
} else
utype = *putype;
switch (utype) {
case V_ASN1_OBJECT:
otmp = (ASN1_OBJECT *)*pval;
cont = otmp->data;
len = otmp->length;
break;
case V_ASN1_NULL:
cont = NULL;
len = 0;
break;
case V_ASN1_BOOLEAN:
tbool = (ASN1_BOOLEAN *)pval;
if (*tbool == -1)
return -1;
if (it->utype != V_ASN1_ANY) {
/* Default handling if value == size field then omit */
if (*tbool && (it->size > 0))
return -1;
if (!*tbool && !it->size)
return -1;
}
c = (unsigned char)*tbool;
cont = &c;
len = 1;
break;
case V_ASN1_BIT_STRING:
return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
cout ? &cout : NULL);
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
/* These are all have the same content format
* as ASN1_INTEGER
*/
return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,

ecall_X509_set_subject_name->X509_set_subject_name. x->cert_info

if ((x == NULL) || (x->cert_info == NULL))
return (0);
return (X509_NAME_set(&x->cert_info->subject, name));

Below are functions have same problem:

  • ecall_X509_set_subject_name
  • ecall_X509_set_issuer_name
  • ecall_SSL_CTX_free (a->param in SSL_CTX_free)
  • ecall_BIO_free (a->method in BIO_free)
  • ecall_i2d_SSL_SESSION (in->cipher in i2d_SSL_SESSION)
  • ecall_SSL_set_SSL_CTX (ssl->cert in SSL_set_SSL_CTX)

ecall_BN_dec2bn->BN_dec2bn->BN_zero (BN_set_word)->bn_expand->bn_expand2. b->d

if (b->d) {
explicit_bzero(b->d, b->dmax * sizeof(b->d[0]));
free(b->d);

ecall_X509_set_version->X509_set_version->ASN1_INTEGER_set. a->data.

if (a->data == NULL) {
ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_INTEGER;
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];

ecall_X509_sign->X509_sign->ASN1_item_sign->EVP_DigestSignInit->do_sigver_init->EVP_PKEY_CTX_new->int_ctx_new. pkey->ameth and pkey->engine.

if (!pkey || !pkey->ameth)
return NULL;
id = pkey->ameth->pkey_id;
}
#ifndef OPENSSL_NO_ENGINE
if (pkey && pkey->engine)
e = pkey->engine;

ecall_X509_set_version->X509_set_version->ASN1_INTEGER_set. a->data

if (a->data == NULL) {
ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_INTEGER;
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];

ecall_X509_free->X509_free->ASN1_item_free->asn1_item_combine_free->ASN1_template_free->asn1_item_combine_free->ASN1_primitive_free->ASN1_STRING_free``->ASN1_STRING_free. a->data TOCTOU, what's more, since a->data can be set by host arbitrarily, then host let bzero clear arbitrary Enclave memory, e.g. secret key.

if (a->data != NULL && !(a->flags & ASN1_STRING_FLAG_NDEF)) {
explicit_bzero(a->data, a->length);
free(a->data);
}

ecall_EVP_MD_CTX_destroy->EVP_MD_CTX_destroy->EVP_MD_CTX_cleanup->EVP_PKEY_CTX_free. ctx->pmeth

if (ctx->pmeth && ctx->pmeth->cleanup)
ctx->pmeth->cleanup(ctx);

ecall_X509_set_pubkey->X509_set_pubkey->X509_PUBKEY_set. pkey->ameth TOCTOU, and pkey can be null

if (pkey->ameth) {
if (pkey->ameth->pub_encode) {
if (!pkey->ameth->pub_encode(pk, pkey)) {

ecall_X509_add_ext->X509_add_ext->X509v3_add_ext->X509_EXTENSION_dup->ASN1_item_dup->ASN1_item_i2d->asn1_item_flags_i2d->ASN1_item_ex_i2d->asn1_template_ex_i2d->ASN1_item_ex_i2d->asn1_i2d_ex_primitive->asn1_ex_i2c. strtmp from *pval

strtmp = (ASN1_STRING *)*pval;
/* Special handling for NDEF */
if ((it->size == ASN1_TFLG_NDEF) &&
(strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
if (cout) {
strtmp->data = cout;
strtmp->length = 0;
}
/* Special return code */
return -2;
}
cont = strtmp->data;

ecall_SSL_CTX_use_PrivateKey_file->SSL_CTX_use_PrivateKey_file->BIO_free->a->method->destroy (file_free). a->ptr

if ((a->init) && (a->ptr != NULL)) {
fclose (a->ptr);

ecall_X509_free->X509_free->ASN1_item_free->asn1_item_combine_free->ASN1_template_free->asn1_item_combine_free->asn1_enc_free->asn1_get_enc_ptr. *pval

@LeoneChen Thank you for your contribution to this project and for raising the issues. However, this project is only a research prototype designed to easily inspect and modify protected data to run various experiments, not for production. It is also no longer actively maintained.

Thanks for reply! I list bugs here to prevent other developers from making the same mistake.