Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


AcquireCredentialsHandleW fails in kernelmode with error RPC_NT_CALL_FAILED

Louis_BernardLouis_Bernard Member Posts: 8

I'm trying to implement secure sockets in my kernel mode application. For this, I want to use Schannel provided by the Windows OS (KSecDD).

For some odd reason, my call to AcquireCredentialsHandleW fails with NT error RPC_NT_CALL_FAILED. All parameters passed to the function are allocated in usermode memory using ZwAllocateVirtualMemory.

My current code looks like this:

    NTSTATUS retVal;
    SECURITY_STATUS secStatus, initStatus;
    PSCHANNEL_CRED creds;
    SECURE_SOCKET_CONNECTION *con = NULL;
    PSECURITY_STRING packageName = NULL;

    creds = AllocUserMemory(sizeof(SCHANNEL_CRED));

    creds->dwVersion = SCHANNEL_CRED_VERSION;
    creds->grbitEnabledProtocols = SP_PROT_TLS1_2;
    creds->dwFlags = SCH_USE_STRONG_CRYPTO |
        SCH_CRED_AUTO_CRED_VALIDATION |
        SCH_CRED_NO_DEFAULT_CREDS;

    /*
    con = ExAllocatePool2(
        POOL_FLAG_NON_PAGED,
        sizeof(SECURE_SOCKET_CONNECTION),
        'noc'
    );
    */

    con = AllocUserMemory(sizeof(SECURE_SOCKET_CONNECTION));

    if (!con)
    {
        retVal = STATUS_NO_MEMORY;
        goto Done;
    }

    packageName = AllocUnicodeStringUserMem(
        L"Microsoft Unified Security Protocol Provider"
    );

    if (!packageName)
    {
        retVal = STATUS_NO_MEMORY;
        goto Done;
    }

    con->SecureFuncs = InitSecurityInterfaceW();

    if (!con->SecureFuncs)
    {
        retVal = STATUS_UNSATISFIED_DEPENDENCIES;
        goto Done;
    }

    secStatus = con->SecureFuncs->AcquireCredentialsHandleW(
        NULL,
        packageName,
        SECPKG_CRED_OUTBOUND,
        NULL,
        creds,
        NULL,
        NULL,
        &con->CredHandle,
        NULL
    );

    DbgPrintEx(0, 0, "Str %wZ\n", packageName);
    DbgPrintEx(0, 0, "SecStatus %x\n", secStatus); //Error 0xC002001B

...

On top of that I have another question:
MSDN states that you have to call ApplyControlToken to shutdown a schannel connection. However, according to the documentation, this function is not available in kernelmode (although KSecDD.sys does export it). What am I supposed to do in this case? Is this an error with the documentation?

Comments

  • MBond2MBond2 Member Posts: 631

    when you say secure sockets, I assume you mean one of the TLS protocols that have superseded SSL. Authentication is only one small part of an implementation like that, but I further assume that you want to implement windows integrated authentication via the SSPI API. This is not a trivial project, and it is unclear what you will gain by implementing your own. This is all well documented standard technology

    as you your actual problem, APIs like AcquireCredentialHandle can often fail while a debugger is attached because the debugger prevents other activity in the system and causes timeouts. If that's not your issue, then you need to tell us more about your setup

  • Louis_BernardLouis_Bernard Member Posts: 8
    edited March 14

    @MBond2 said:
    when you say secure sockets, I assume you mean one of the TLS protocols that have superseded SSL. Authentication is only one small part of an implementation like that, but I further assume that you want to implement windows integrated authentication via the SSPI API. This is not a trivial project, and it is unclear what you will gain by implementing your own. This is all well documented standard technology

    as you your actual problem, APIs like AcquireCredentialHandle can often fail while a debugger is attached because the debugger prevents other activity in the system and causes timeouts. If that's not your issue, then you need to tell us more about your setup

    Yes, I mean enabling secure communication using TLS. As a student I think that this is an interesting project to study both kernel mode programming and networking.

    I have solved the issue by allocating the parameters for AcquireCredentialsHandleW on the stack instead of the virtual user memory. One thing I don't understand is why the documentation states that a kernel mode caller MUST allocate the buffers in user memory and not in the pool. What's the reason for this? And why is it ok to allocate them on the stack?

  • MBond2MBond2 Member Posts: 631

    The correct use of these APIs is a subject too large for a forum post. And the TLS protocol is much larger again. So good luck with your studies

    As to your specific question, look at what your AllocUserMemory function does. Probably it allocates memory in a context that cannot be used. Then think about what this API must do and how that could be accomplished. what parts of the OS must be involved and what requirements do they have in terms of paging and memory accessibility

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 13-17 May 2024 Live, Online
Developing Minifilters 1-5 Apr 2024 Live, Online
Internals & Software Drivers 11-15 Mar 2024 Live, Online
Writing WDF Drivers 26 Feb - 1 Mar 2024 Live, Online