static OpensslStatus_t failFunctionFrom_Openssl_Connect()

in platform/posix/transport/utest/openssl_utest.c [197:444]


static OpensslStatus_t failFunctionFrom_Openssl_Connect( FunctionNames_t functionToFail,
                                                         const void * retValue )
{
    OpensslStatus_t returnStatus = OPENSSL_SUCCESS;
    SocketStatus_t socketStatus = SOCKETS_SUCCESS;
    bool fileOpened = false,
         sslCtxCreated = false, sslCreated = false;

    /* Depending on the function to fail,
     * this function must return the correct status to expect. */
    if( functionToFail == Sockets_Connect_fn )
    {
        TEST_ASSERT_NOT_NULL( retValue );
        socketStatus = *( ( SocketStatus_t * ) retValue );
        Sockets_Connect_ExpectAnyArgsAndReturn( socketStatus );
        returnStatus = convertToOpensslStatus( socketStatus );
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        Sockets_Connect_ExpectAnyArgsAndReturn( SOCKETS_SUCCESS );
    }

    /* Calls like this can't fail no matter what you return. */
    if( returnStatus == OPENSSL_SUCCESS )
    {
        TLS_client_method_ExpectAndReturn( &sslMethod );
    }

    if( functionToFail == SSL_CTX_new_fn )
    {
        SSL_CTX_new_ExpectAnyArgsAndReturn( NULL );
        returnStatus = OPENSSL_API_ERROR;
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_CTX_new_ExpectAnyArgsAndReturn( &sslCtx );
        sslCtxCreated = true;
    }

    /* SSL_CTX_set_mode is actually what the API uses, but CMock expects the
     * actual method rather than the macro wrapper. */
    if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_CTX_ctrl_ExpectAnyArgsAndReturn( 1 );
    }

    /* Path to Root CA must be set for handshake to succeed. */
    if( opensslCredentials.pRootCaPath == NULL )
    {
        returnStatus = OPENSSL_INVALID_CREDENTIALS;
    }
    else
    {
        /* These calls are only expected when #LIBRARY_LOG_LEVEL
         * is set to #LOG_DEBUG. */
        #if ( LIBRARY_LOG_LEVEL == LOG_DEBUG )
            if( returnStatus == OPENSSL_SUCCESS )
            {
                getcwd_ExpectAnyArgsAndReturn( NULL );
            }
        #endif

        if( functionToFail == fopen_fn )
        {
            fopen_ExpectAnyArgsAndReturn( NULL );
            returnStatus = OPENSSL_INVALID_CREDENTIALS;
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            fopen_ExpectAnyArgsAndReturn( &rootCaFile );
            fileOpened = true;
        }

        if( functionToFail == PEM_read_X509_fn )
        {
            PEM_read_X509_ExpectAnyArgsAndReturn( NULL );
            returnStatus = OPENSSL_INVALID_CREDENTIALS;
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            PEM_read_X509_ExpectAnyArgsAndReturn( &rootCa );
        }

        if( returnStatus == OPENSSL_SUCCESS )
        {
            SSL_CTX_get_cert_store_ExpectAnyArgsAndReturn( &CaStore );
        }

        if( functionToFail == X509_STORE_add_cert_fn )
        {
            X509_STORE_add_cert_ExpectAnyArgsAndReturn( -1 );
            returnStatus = OPENSSL_INVALID_CREDENTIALS;
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            X509_STORE_add_cert_ExpectAnyArgsAndReturn( 1 );
        }

        if( fileOpened )
        {
            /* Fail fclose on a branch path for coverage. */
            if( functionToFail == PEM_read_X509_fn )
            {
                fclose_ExpectAnyArgsAndReturn( -1 );
            }
            else
            {
                X509_free_ExpectAnyArgs();
                fclose_ExpectAnyArgsAndReturn( 0 );
            }
        }
    }

    if( opensslCredentials.pClientCertPath != NULL )
    {
        if( functionToFail == SSL_CTX_use_certificate_chain_file_fn )
        {
            SSL_CTX_use_certificate_chain_file_ExpectAnyArgsAndReturn( -1 );
            returnStatus = OPENSSL_INVALID_CREDENTIALS;
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            SSL_CTX_use_certificate_chain_file_ExpectAnyArgsAndReturn( 1 );
        }
    }

    if( opensslCredentials.pPrivateKeyPath != NULL )
    {
        if( functionToFail == SSL_CTX_use_PrivateKey_file_fn )
        {
            SSL_CTX_use_PrivateKey_file_ExpectAnyArgsAndReturn( -1 );
            returnStatus = OPENSSL_INVALID_CREDENTIALS;
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            SSL_CTX_use_PrivateKey_file_ExpectAnyArgsAndReturn( 1 );
        }
    }

    if( functionToFail == SSL_new_fn )
    {
        SSL_new_ExpectAnyArgsAndReturn( NULL );
        returnStatus = OPENSSL_API_ERROR;
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_new_ExpectAnyArgsAndReturn( &ssl );
        sslCreated = true;
    }

    if( functionToFail == SSL_set1_host_fn )
    {
        SSL_set1_host_ExpectAnyArgsAndReturn( 0 );
        returnStatus = OPENSSL_API_ERROR;
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_set1_host_ExpectAnyArgsAndReturn( 1 );
    }

    if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_set_verify_ExpectAnyArgs();
    }

    if( functionToFail == SSL_set_fd_fn )
    {
        SSL_set_fd_ExpectAnyArgsAndReturn( -1 );
        returnStatus = OPENSSL_API_ERROR;
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_set_fd_ExpectAnyArgsAndReturn( 1 );
    }

    /* For any functions that set optional TLS configurations,
     * none of them should cause Openssl_Connect to fail even when they do. */
    if( ( opensslCredentials.pAlpnProtos != NULL ) &&
        ( opensslCredentials.alpnProtosLen > 0 ) )
    {
        if( functionToFail == SSL_set_alpn_protos_fn )
        {
            SSL_set_alpn_protos_ExpectAnyArgsAndReturn( 1 );
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            SSL_set_alpn_protos_ExpectAnyArgsAndReturn( 0 );
        }
    }

    if( opensslCredentials.maxFragmentLength > 0 )
    {
        if( functionToFail == SSL_set_max_send_fragment_fn )
        {
            SSL_ctrl_ExpectAnyArgsAndReturn( 0 );
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            SSL_ctrl_ExpectAnyArgsAndReturn( 1 );
            SSL_set_default_read_buffer_len_ExpectAnyArgs();
        }
    }

    if( opensslCredentials.sniHostName != NULL )
    {
        if( functionToFail == SSL_set_tlsext_host_name_fn )
        {
            SSL_ctrl_ExpectAnyArgsAndReturn( 0 );
        }
        else if( returnStatus == OPENSSL_SUCCESS )
        {
            SSL_ctrl_ExpectAnyArgsAndReturn( 1 );
        }
    }

    if( functionToFail == SSL_connect_fn )
    {
        SSL_connect_ExpectAnyArgsAndReturn( -1 );
        returnStatus = OPENSSL_HANDSHAKE_FAILED;
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_connect_ExpectAnyArgsAndReturn( 1 );
    }

    if( functionToFail == SSL_get_verify_result_fn )
    {
        SSL_get_verify_result_ExpectAnyArgsAndReturn( -1 );
        returnStatus = OPENSSL_HANDSHAKE_FAILED;
    }
    else if( returnStatus == OPENSSL_SUCCESS )
    {
        SSL_get_verify_result_ExpectAnyArgsAndReturn( X509_V_OK );
    }

    /* Expect objects to be freed depending upon whether they were created. */
    if( sslCtxCreated )
    {
        SSL_CTX_free_ExpectAnyArgs();
    }

    if( ( returnStatus != OPENSSL_SUCCESS ) && sslCreated )
    {
        SSL_free_ExpectAnyArgs();
    }

    return returnStatus;
}