OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.


Help: OASIS Mailing Lists Help | MarkMail Help

pkcs11 message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]

Subject: RE: [pkcs11] Strong User authentication - Discussion thread

Hi Mike


We use the context in the extended login to provide a struct pointer with function pointers inside of that.  That’s worked for both an RSA based and biometric based additional login mechanism for us.  Here’s a snippet of code from my test mechanism provider – I’ve not included most of the RSA credential provider because it’s long – what’s there should be enough to provide an idea of how it works.  The biometric credential provider


enum {





typedef CK_ULONG (*auth_func_ptr)(CK_VOID_PTR cred, CK_NOTIFY callback);


typedef struct {

    CK_ULONG                     cred_type;          /* Which type of auth is this? */

    auth_func_ptr              auth_func;          /* Callback to do the actual auth */

} auth_cred_t;


static CK_ULONG biometric_auth(CK_VOID_PTR cred, CK_NOTIFY callback);

static CK_ULONG rsa_auth(CK_VOID_PTR cred, CK_NOTIFY callback);


static auth_cred_t auth_creds[] = {

    { BIOMETRIC_AUTH_CRED,     biometric_auth },

    { RSA_AUTH_CRED,                    rsa_auth              }



static CK_ULONG

rsa_auth(CK_VOID_PTR cred, CK_NOTIFY callback)


    CK_EXTENDED_LOGIN               *login = (CK_EXTENDED_LOGIN *)cred;


    if(!login || !callback)

                return CKR_DEVICE_ERROR;


    printf("RSA authorization provider invoked\n");


    /* Generate an RSA challenge for the user */



    /* Send out the challenge */

    callback(session, CKN_EXT_LOGIN_WRITE, (CK_VOID_PTR)login);


    /* Read back the response */

    callback(session, CKN_EXT_LOGIN_READ, (CK_VOID_PTR)login);



   /*Verify the response */




static CK_ULONG

biometric_auth(CK_VOID_PTR cred, CK_NOTIFY callback)


    if(!cred || !callback)

                return CKR_DEVICE_ERROR;


    printf("Biometric authorization provider invoked\n");




    return CKR_OK;




sw_extended_login(CK_EXTENDED_LOGIN *ext_login)


    CK_NOTIFY                     callback;

    CK_RV                              rv = CKR_OK;

    int                                       i;



                return CKR_ARGUMENTS_BAD;


    /* Get the callback function */

    if((rv = sw_get_session_callback((CK_SESSION_HANDLE)ext_login->context, &callback)) != CKR_OK)

                return rv;



     * Given the choice of auth creds now available,

     * pick from the order available


    for(i = 0; i < sizeof(auth_creds) / sizeof(auth_cred_t); i++) {

                switch(auth_creds[i].cred_type) {

                case RSA_AUTH_CRED:

                case BIOMETRIC_AUTH_CRED:

                    auth_creds[auth_creds[i].cred_type].auth_func(ext_login, callback);



                    rv = CKR_DEVICE_ERROR;




    return rv;




My intention in doing it this was way to provide some means to preserve as much backward compatibility as possible and to allow people to arbitrarily define the “strong auth” mechanisms as they saw fit, while trying to keep the interface consistent.


Given that the callback is just a means to move data in and out, and the token is free to do whatever it needs with said data, it should be able to accommodate pretty much anything.






From: pkcs11@lists.oasis-open.org [mailto:pkcs11@lists.oasis-open.org] On Behalf Of Michael StJohns
Sent: Sunday, October 13, 2013 5:12 PM
To: pkcs11@lists.oasis-open.org
Subject: [pkcs11] Strong User authentication - Discussion thread


For the purposes of this discussion, I'm considering strong authentication as authentication that's resistant or immune to replay attacks and to attacks based on the capture of the login interaction.

The problem I'm trying to solve?  Seriously - we're still using plaintext passwords!

Most of the simple strong authentication models available are challenge/signature approaches.  The token generates a challenge, and the user logging into the token generates a signature over the challenge (and possibly other data).  The signature can either symmetric based (e.g. something like the CHAP protocol for IMAP or POP where both sides know the password), or asymmetric based (where the token has the public key and the user has the private key).

Other pseudo-strong models include OTP approaches based on a known shared secret seed, a PRNG and a common time source.

Let's assume we want to provide support for one or more of the above, and that we want to define an extensible model so we don't have to do this again.

On the user management side, we need to tag the user with his role, the mechanism being used for the login, and the authenticator material (e.g. shared secret, public key, shared seed).  But the user management piece could be a completely implementation dependent and not require changes to the PKCS11 model.   

As a general approach, C_Login doesn't constrain the format of the pin provided - it can be a string of any length of UTF8 characters.  Implementing the above may be as simple as encoding a user name and the user's calculated authenticator (e.g. OTP password, signed challenge)  in the pin field.

The last piece of the puzzle is how to get the challenge (if the mechanism needs it) out of the token.  One simple approach would be to define a CKU_GET_CHALLENGE and have C_Login place the challenge in the space provided for the PIN.  I'm slightly leery of this because the pin field in C_Login has always been defined as an "IN" field, but since the field wouldn't be written unless you specified this user type, it would probably work.  The other approach is to define an object with a well known handle and use C_GetAttributeValue to grab the challenge from a specific attribute (CKA_VALUE?).

Session security based on strong authentication:

The above all deal with the basics of enhancing the C_Login function, but may not provide a lot of additional security.  They change the state of the token from logged out to logged in, but do nothing to protect the login session itself.  An attacker could possibly insert data between the user and the token. 

One possible enhancement here is that the creation of the login session could result in the creation of shared symmetric keys on both sides of the session (on the token and with the user).  Those keys could then be used to "sign" each of the PKCS11 transaction calls.  That would require definitions of how to serialize each PKCS11 call and how the serialization would be signed.  That would also require being specific about the size of CK_ULONG and all the rest of the types.



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]