int s2n_cert_chain_and_key_free()

in crypto/s2n_certificate.c [417:473]


int s2n_cert_chain_and_key_free(struct s2n_cert_chain_and_key *cert_and_key)
{
    if (cert_and_key == NULL) {
        return 0;
    }

    /* Walk the chain and free the certs */
    if (cert_and_key->cert_chain) {
        struct s2n_cert *node = cert_and_key->cert_chain->head;
        while (node) {
            /* Free the cert */
            POSIX_GUARD(s2n_free(&node->raw));
            /* update head so it won't point to freed memory */
            cert_and_key->cert_chain->head = node->next;
            /* Free the node */
            POSIX_GUARD(s2n_free_object((uint8_t **) &node, sizeof(struct s2n_cert)));
            node = cert_and_key->cert_chain->head;
        }

        POSIX_GUARD(s2n_free_object((uint8_t **) &cert_and_key->cert_chain, sizeof(struct s2n_cert_chain)));
    }

    if (cert_and_key->private_key) {
        POSIX_GUARD(s2n_pkey_free(cert_and_key->private_key));
        POSIX_GUARD(s2n_free_object((uint8_t **) &cert_and_key->private_key, sizeof(s2n_cert_private_key)));
    }

    uint32_t len = 0;

    if (cert_and_key->san_names) {
        POSIX_GUARD_RESULT(s2n_array_num_elements(cert_and_key->san_names, &len));
        for (uint32_t i = 0; i < len; i++) {
            struct s2n_blob *san_name = NULL;
            POSIX_GUARD_RESULT(s2n_array_get(cert_and_key->san_names, i, (void **) &san_name));
            POSIX_GUARD(s2n_free(san_name));
        }
        POSIX_GUARD_RESULT(s2n_array_free(cert_and_key->san_names));
        cert_and_key->san_names = NULL;
    }

    if (cert_and_key->cn_names) {
        POSIX_GUARD_RESULT(s2n_array_num_elements(cert_and_key->cn_names, &len));
        for (uint32_t i = 0; i < len; i++) {
            struct s2n_blob *cn_name = NULL;
            POSIX_GUARD_RESULT(s2n_array_get(cert_and_key->cn_names, i, (void **) &cn_name));
            POSIX_GUARD(s2n_free(cn_name));
        }
        POSIX_GUARD_RESULT(s2n_array_free(cert_and_key->cn_names));
        cert_and_key->cn_names = NULL;
    }

    POSIX_GUARD(s2n_free(&cert_and_key->ocsp_status));
    POSIX_GUARD(s2n_free(&cert_and_key->sct_list));

    POSIX_GUARD(s2n_free_object((uint8_t **) &cert_and_key, sizeof(struct s2n_cert_chain_and_key)));
    return 0;
}