int tlsio_bearssl_open()

in adapters/tlsio_bearssl.c [1075:1180]


int tlsio_bearssl_open(CONCRETE_IO_HANDLE tls_io, ON_IO_OPEN_COMPLETE on_io_open_complete, void *on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void *on_bytes_received_context, ON_IO_ERROR on_io_error, void *on_io_error_context)
{
    int result = 0;
    unsigned int cert_signer_algo;                        

    if (tls_io == NULL)
    {
        LogError("NULL tls_io");
        result = MU_FAILURE;
    }
    else
    {
        TLS_IO_INSTANCE *tls_io_instance = (TLS_IO_INSTANCE *)tls_io;

        if (tls_io_instance->tlsio_state != TLSIO_STATE_NOT_OPEN)
        {
            LogError("TLS already open");
            result = MU_FAILURE;
        }
        else
        {

            tls_io_instance->on_bytes_received = on_bytes_received;
            tls_io_instance->on_bytes_received_context = on_bytes_received_context;

            tls_io_instance->on_io_open_complete = on_io_open_complete;
            tls_io_instance->on_io_open_complete_context = on_io_open_complete_context;

            tls_io_instance->on_io_error = on_io_error;
            tls_io_instance->on_io_error_context = on_io_error_context;

            tls_io_instance->tlsio_state = TLSIO_STATE_OPENING_UNDERLYING_IO;

            if (tls_io_instance->ta_count == 0)
            {
                LogError("Trusted certificates are required but missing");
                result = MU_FAILURE;
            }
            else
            {
                if ((tls_io_instance->x509_pk == NULL && tls_io_instance->x509_cert != NULL) ||
                    (tls_io_instance->x509_pk != NULL && tls_io_instance->x509_cert == NULL))
                {
                    LogError("X.509 certificate and private key need to be both present or both absent");
                    result = MU_FAILURE;
                }
                else
                {
                    br_ssl_client_init_full(&tls_io_instance->sc, &tls_io_instance->xc, tls_io_instance->tas, tls_io_instance->ta_count);
                    br_ssl_engine_set_buffer(&tls_io_instance->sc.eng, tls_io_instance->iobuf, sizeof(tls_io_instance->iobuf), 1);
                    br_ssl_client_reset(&tls_io_instance->sc, tls_io_instance->hostname, 0);

                    if (tls_io_instance->x509_cert != NULL)
                    {
                        switch (tls_io_instance->x509_pk->key_type)
                        {
                        case BR_KEYTYPE_RSA:
                			br_ssl_client_set_single_rsa(&tls_io_instance->sc, 
                                                         tls_io_instance->x509_cert,
                                                         tls_io_instance->x509_cert_len,
                                                         &tls_io_instance->x509_pk->key.rsa,
                                                         br_rsa_pkcs1_sign_get_default());
                            break;
                        case BR_KEYTYPE_EC:
                            cert_signer_algo = get_cert_signer_algo(tls_io_instance->x509_cert);

                            if (cert_signer_algo == 0)
                            {
                                result = MU_FAILURE;
                            }
                            else
                            {
                                br_ssl_client_set_single_ec(&tls_io_instance->sc,
                                                            tls_io_instance->x509_cert,
                                                            tls_io_instance->x509_cert_len,
                                                            &tls_io_instance->x509_pk->key.ec,
                                                            BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN, 
                                                            cert_signer_algo,
                                                            br_ec_get_default(),
                                                            br_ecdsa_sign_asn1_get_default());
                            }
                            break;
                        default:
                            LogError("Unrecognized private key type");
                            tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
                            result = MU_FAILURE;
                        }
                    }

                    if (result == 0)
                    {
                        if (xio_open(tls_io_instance->socket_io, on_underlying_io_open_complete, tls_io_instance, on_underlying_io_bytes_received, tls_io_instance, on_underlying_io_error, tls_io_instance) != 0)
                        {

                            LogError("Underlying IO open failed");
                            tls_io_instance->tlsio_state = TLSIO_STATE_NOT_OPEN;
                            result = MU_FAILURE;
                        }
                    }
                }
            }
        }
    }

    return result;
}