locked
Use smartcard credential to log on to AD (LDAP) RRS feed

  • Question

  • Goal
    I want to use a smart card to:
    - identify a user
    - authenticate him (or her) against LDAP
    - check on group membership (e.g. must be member of "Department A")

    Environment
    There is a Windows domain, using Active Directory. The exact configuration is not 'known', though one can safely assume that LDAP will work. The site has a PKI infrastructure and users use smartcards to log in on Windows.
    A client machine is running Windows Embedded. This machine is typically NOT a member of the Windows domain. The machine does have a cardreader and the middleware to support it.

    What I accomplished so far
    I can obtain the public certificate from a smartcard, and get the user's distinguished name. The user does not have to provide a PIN for this, this is identification only, not authentication. I can use this DN and query the LDAP server for group membership (memberOf attribute). To do so, I use a fixed plaintext username/password to connect and bind to LDAP, and then search for the user's CN. Thus I can see that the user's account is active and whether he's member of the correct group.

    What I failed to accomplish
    - I want to use the user's own credentials to authenticate to the LDAP server instead of some plaintext 'guest' account.
    - I want to authenticate the user, thus proof that he's really the card's owner, and that the card is trusted by the domain CA. I guess this is basically the same question but in slightly different words, as authentication to LDAP implies authenticating the user to the domain.

    From what I read, LDAP_AUTH_EXTERNAL (or SASL with correct parameters?) should be able to authenticate using a client certificate. However, I was unable to find any documentation on this, and my LDAP server (installed a 2003 server from MSDN and configured it) apparently refuses to do so.
    Wednesday, March 3, 2010 8:31 AM

All replies

  • Setting a LDAP_OPT_CLIENT_CERTIFICATE callback on the LDAP client connection appears to be the way to go.

    If I let Windows handle the SSL, I am (mysteriously) asked to insert a smartcard, and some cards even succeed to set up a TLS connection to the LDAP server.

    With the following code (a LdapClient is a C++ wrapper that simply calls ldap_ functions)
    LdapClient ldap(ldapHost, ldapPort, ldapSecureMode);
    							ldap.set_option(LDAP_OPT_PROTOCOL_VERSION, LDAP_VERSION3);
    ldap.set_option(LDAP_OPT_SSL, LDAP_OPT_ON);
    ldap.set_option(LDAP_OPT_CLIENT_CERTIFICATE, OnQueryClientCertificate);
    ldap.connect(NULL);
    ldap.bind_s(ldapRoot, NULL, LDAP_AUTH_EXTERNAL);
    
    I never succeed to do the same. In the OnQueryClientCertificate function, I provide the smart card's CSP and return TRUE. Returning FALSE there works, and I have to authenticate with plaintext passwords to proceed (using NEGOTIATE). Setting a client certificate and returning TRUE returns "Error 0x51 (81): Server Down" on connecting.
    Thursday, March 4, 2010 8:39 AM
  • Have you figured this out yet by chance? also, what ldapclient are you using? I'm trying to do something similar to you.  Thanks.
    Tuesday, March 16, 2010 8:10 PM
  • There are a bunch of things that can go wrong, and some did. LDAP always gives "Server down" if the SSL stuff fails, regardless of what actually went wrong.

    The main thing to get right was the certificate, see my other thread:

    http://social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/5bfedf2d-499f-4e45-9976-b1d72b4eac24

     

    Another thing is that when using a client certificate, don't use the bind functions at all, the authentication has been done already. The bind will actually 'kill' the authentication.

    I'm using Windows' own ldap functions (ldap_init etc.), see http://msdn.microsoft.com/en-us/library/aa367033%28VS.85%29.aspx

    Friday, March 19, 2010 6:58 AM