int tlsio_bearssl_setoption()

in adapters/tlsio_bearssl.c [1521:1659]


int tlsio_bearssl_setoption(CONCRETE_IO_HANDLE tls_io, const char *optionName, const void *value)
{
    int result = 0;
    size_t i;
    VECTOR_HANDLE certs;

    if (tls_io == NULL || optionName == NULL)
    {
        result = MU_FAILURE;
    }
    else
    {
        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)tls_io;

        if (strcmp(OPTION_TRUSTED_CERT, optionName) == 0)
        {
            if (tls_io_instance->tas != NULL)
            {
                // Free the memory if it has been previously allocated
                for (i = 0; i < tls_io_instance->ta_count; i++)
                {
		            free_ta_contents(&(tls_io_instance->tas[i]));
                }

                free(tls_io_instance->tas);
                tls_io_instance->tas = NULL;
                tls_io_instance->ta_count = 0;
                free(tls_io_instance->trusted_certificates);
                tls_io_instance->trusted_certificates = NULL;
            }

            if (value != NULL)
            {
                mallocAndStrcpy_s(&tls_io_instance->trusted_certificates, (const char *)value);

                if (tls_io_instance->trusted_certificates == NULL)
                {
                    LogError("Failed to allocate memory for certificate string");
                    result = MU_FAILURE;
                }
                else
                {
                    tls_io_instance->ta_count = get_trusted_anchors((const char*)value, strlen((const char *)value) + 1, &tls_io_instance->tas);

                    if (tls_io_instance->ta_count == 0)
                    {
                        LogError("Failed to extract certificate from option value");
                        result = MU_FAILURE;
                    }
                    else
                    {
                        result = 0;
                    }
                }
            }
        }
        else if (strcmp(optionName, OPTION_UNDERLYING_IO_OPTIONS) == 0)
        {
            if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, (void*)tls_io_instance->socket_io) != OPTIONHANDLER_OK)
            {
                LogError("failed feeding options to underlying I/O instance");
                result = MU_FAILURE;
            }
            else
            {
                result = 0;
            }
        }
        else if (strcmp(SU_OPTION_X509_CERT, optionName) == 0 || strcmp(OPTION_X509_ECC_CERT, optionName) == 0)
        {
            if (tls_io_instance->x509_certificate != NULL)
            {
                // Free the memory if it has been previously allocated
                free(tls_io_instance->x509_certificate);
                tls_io_instance->x509_certificate = NULL;
            }

            if (mallocAndStrcpy_s(&tls_io_instance->x509_certificate, (const char *)value) != 0)
            {
                LogError("unable to mallocAndStrcpy_s on certificate");
                result = MU_FAILURE;
            }
            else
            {
                if (tls_io_instance->x509_cert != NULL)
                {
                    free_certificates(tls_io_instance->x509_cert, tls_io_instance->x509_cert_len);
                    free(tls_io_instance->x509_cert);
                    tls_io_instance->x509_cert = NULL;
                }

                certs = read_certificates_string(value, strlen(value));
                tls_io_instance->x509_cert_len = VECTOR_size(certs);
                tls_io_instance->x509_cert = VECTOR_front(certs);
                free(certs);
                result = 0;
            }
        }
        else if (strcmp(SU_OPTION_X509_PRIVATE_KEY, optionName) == 0 || strcmp(OPTION_X509_ECC_KEY, optionName) == 0)
        {
            if (tls_io_instance->x509_private_key != NULL)
            {
                // Free the memory if it has been previously allocated
                free(tls_io_instance->x509_private_key);
                tls_io_instance->x509_private_key = NULL;
            }

            if (mallocAndStrcpy_s(&tls_io_instance->x509_private_key, (const char *)value) != 0)
            {
                LogError("unable to mallocAndStrcpy_s on private key");
                result = MU_FAILURE;
            }
            else
            {
                if (tls_io_instance->x509_pk != NULL)
                {
                    free_private_key(tls_io_instance->x509_pk);
                    free(tls_io_instance->x509_pk);
                    tls_io_instance->x509_pk = NULL;
                }

                tls_io_instance->x509_pk = read_private_key(value, strlen(value));
                result = 0;
            }
        }
        else if (strcmp(optionName, OPTION_SET_TLS_RENEGOTIATION) == 0)
        {
            // No need to do anything for BearSSL
            result = 0;
        }
        else
        {
            // tls_io_instance->socket_io is never NULL
            result = xio_setoption(tls_io_instance->socket_io, optionName, value);
        }
    }

    return result;
}