OASIS PKCS 11 TC

 View Only
  • 1.  User types - discussion thread

    Posted 10-13-2013 20:34
    In PKCS11 there are currently two types of users, CKU_USER, CKU_SO and CKU_CONTEXT_SPECIFIC. The USER type, when logged in, can access all the keys on the token, use them and change their attributes within the limits of PKCS11 policy. The SO user type has only a single function defined in PKCS11 as far as I can tell - marking keys as trusted. The CONTEXT_SPECIFIC user seems to be used only for those keys that require authentication each time they're used. The above provides only a minimal amount of role based policy protections. Over the years I've found this minimal set of roles to be somewhat constricting in building PKCS11 applications as they don't provide granular enough control over the token. We've added a few additional attributes (CKA_COPYABLE and CKA_DESTROYABLE) as of 2.40 that provide some improvements, but I think we should consider modifying the model either slightly or comprehensively: Slightly: One of the big issues I've encountered with PKCS11 is that the creators of the key materials are not always the users of the key materials. That leads to complications in managing the token in that we'd (e.g. my customers) *really* like to prevent the users of the key materials from either creating or destroying key material. CKA_DESTROYABLE works for the destroying part, but there's no way to prevent the creation. A slight modification to the above set of user types might be the addition of a CKU_SESSION_USER who's allowed read-only access to token key material for use, but can't create or destroy any CKA_TOKEN=true objects - the session user MAY create session key material as necessary. A second slight modification might include the addition of a CKU_OWNER_USER who in addition to all the access a CKU_USER gets may set key protection attributes on the keys irrespective of normal policy (e.g. can violate the stickyness rules for attributes). So CKU_OWNER_USER > CKU_USER > CKU_SESSION_USER in terms of access. Comprehensive: Another possible approach may be to go to a full user (vs role) based system where each object is tagged both with the owner (who gets to set attributes) and the users allowed to use the object. There's probably also the concept of a token owner who gets add and delete users. Obviously, this would be a bit more disruptive than the simple additions described above. It would require a more comprehensive user management system than currently exists, and a set of functions to manage the access control lists for the objects. But this approach may be required to support multi-party (m of n) authorization models. A third option is to standardize both - but make the "comprehensive" version optional. Thoughts? Mike


  • 2.  RE: [pkcs11] User types - discussion thread

    Posted 10-22-2013 18:21
    Hi Mike I would agree with your comment around role based access control in terms of it being constricting. For our needs, it just simply did not work. To that end, we added CKU_EXTENDED_LOGIN: #if defined(BPKCS11_EXTENDED_LOGIN) /* Bloomberg extension for token login */ #define CKU_EXTENDED 3 typedef struct { CK_UTF8CHAR_PTR *username; /* User name */ CK_ULONG name_len; /* Length of user name */ CK_VOID_PTR context; /* Used to pass around token specific context data */ CK_ULONG context_size; /* Size of context data */ } CK_EXTENDED_LOGIN; #endif /* defined(BPKCS11_EXTENDED_LOGIN) */ We have the extended attributes to do things that you mention, such as allow one user to create a key and provide fine grained access control to other users that can access the key. You can extend this somewhat arbitrarily as well in terms of the access control policies (e.g. user X creates a key, shares with user Y, but says that user Y can only use the key M-F between 8AM - 5PM, etc.). --Chris


  • 3.  Re: [pkcs11] User types - discussion thread

    Posted 10-25-2013 16:07
    Hi Chris - Could you comment a bit on how you do user management? E.g. adding/deleting/changing privileges for individual users? Is this external to PKCS11 or done via something like the object creation/deletion process? For the structure below - how is this passed? Is it passed in via the PIN pointer? or did you come up with a different login command? Lastly, how is the context data used by the rest of PKCS11? Thanks - Mike On 10/22/2013 2:21 PM, Chris Zimman wrote: Hi Mike I would agree with your comment around role based access control in terms of it being constricting. For our needs, it just simply did not work. To that end, we added CKU_EXTENDED_LOGIN: #if defined(BPKCS11_EXTENDED_LOGIN) /* Bloomberg extension for token login */ #define CKU_EXTENDED 3 typedef struct { CK_UTF8CHAR_PTR *username; /* User name */ CK_ULONG name_len; /* Length of user name */ CK_VOID_PTR context; /* Used to pass around token specific context data */ CK_ULONG context_size; /* Size of context data */ } CK_EXTENDED_LOGIN; #endif /* defined(BPKCS11_EXTENDED_LOGIN) */ We have the extended attributes to do things that you mention, such as allow one user to create a key and provide fine grained access control to other users that can access the key. You can extend this somewhat arbitrarily as well in terms of the access control policies (e.g. user X creates a key, shares with user Y, but says that user Y can only use the key M-F between 8AM - 5PM, etc.). --Chris


  • 4.  RE: [pkcs11] User types - discussion thread

    Posted 10-25-2013 17:16
    Hi Mike Yes, we manage the users through an external mechanism. As you're aware, PKCS11 doesn't really have the notion of add/delete/change privs in the existing API. I wanted to preserve compatability. The structure is passed as a void * to the PIN argument and sizeof(CK_EXTENDED_LOGIN) for the length argument. In my implementation, there is a table/attribute driven state machine that allows you to define somewhat arbitrary rules for each type of C_* operation via callbacks. typedef struct { CK_ATTRIBUTE_TYPE attr_type; CK_BBOOL token_impl_specific; CK_RV (*set)(CK_ATTRIBUTE *); CK_RV (*validate)(CK_ATTRIBUTE *); } bpkcs11_vendor_attr_list_item; An example of how this is used looks something like this: static bpkcs11_vendor_attr_list_item bpkcs11_vendor_attrs[] = { { CKA_OWNER_UUID, CK_TRUE, set_uuid, validate_uuid }, { CKA_ALLOWED_USE_TIME_START, CK_TRUE, set_use_time_start, validate_use_time_start }, { CKA_ALLOWED_USE_TIME_STOP, CK_TRUE, set_use_time_stop validate_use_time_stop }, { CKA_EXPORT_SHARE_REQUIRED, CK_TRUE, set_share_exp_req, validate_share_exp_req }, { CKA_EXPORT_SHARE_REQUIRED_NUM, CK_TRUE, set_share_exp_req_num, validate_share_exp_req_num }, }; The attributes are for things like checking an object owner via UUID, checking the time that an object is legal to use, or that to export an object requires a threshold. --Chris


  • 5.  Re: [pkcs11] User types - discussion thread

    Posted 10-25-2013 17:25
    On 10/25/2013 1:16 PM, Chris Zimman wrote: Hi Mike Yes, we manage the users through an external mechanism. As you're aware, PKCS11 doesn't really have the notion of add/delete/change privs in the existing API. I wanted to preserve compatability. OK. I may try and define a CKO_USER_CREDENTIALS object - I think that may work for doing things similar to what you do. The structure is passed as a void * to the PIN argument and sizeof(CK_EXTENDED_LOGIN) for the length argument. That's what I thought. Unfortunately, that won't work well with the Java PKCS11 implementation due to strong typing. Void pointers are to be avoided. :-) In my implementation, there is a table/attribute driven state machine that allows you to define somewhat arbitrary rules for each type of C_* operation via callbacks. typedef struct { CK_ATTRIBUTE_TYPE attr_type; CK_BBOOL token_impl_specific; CK_RV (*set)(CK_ATTRIBUTE *); CK_RV (*validate)(CK_ATTRIBUTE *); } bpkcs11_vendor_attr_list_item; An example of how this is used looks something like this: static bpkcs11_vendor_attr_list_item bpkcs11_vendor_attrs[] = { { CKA_OWNER_UUID, CK_TRUE, set_uuid, validate_uuid }, { CKA_ALLOWED_USE_TIME_START, CK_TRUE, set_use_time_start, validate_use_time_start }, { CKA_ALLOWED_USE_TIME_STOP, CK_TRUE, set_use_time_stop validate_use_time_stop }, { CKA_EXPORT_SHARE_REQUIRED, CK_TRUE, set_share_exp_req, validate_share_exp_req }, { CKA_EXPORT_SHARE_REQUIRED_NUM, CK_TRUE, set_share_exp_req_num, validate_share_exp_req_num }, }; The attributes are for things like checking an object owner via UUID, checking the time that an object is legal to use, or that to export an object requires a threshold. --Chris


  • 6.  Re: [pkcs11] User types - discussion thread

    Posted 11-01-2013 20:52
    Related to the user types discussion and to key protection and to a bunch of other things is what a user (vs role) model might look like. Some of the following is based on my experience with the Utimaco line of HSMs and how they do and use strong authentication. As a side note, Utimaco provides a free HSM simulator that exactly mimics their hardware product and the documentation provided with the simulator is the same documentation used for the HSM. If you want more details on what I'm discussing here - that's a good place to go look. UT uses the normal pin login as the "finish" operation for logging in to a token. It can be preceded by any number of "strong" logins. UT uses the concept of a "login state" consisting of 8 uint4's packed into a single 32 bit word. A normal login (e.g. pin based login) contributes a 00000000 login state value. A strong auth user contributes whatever login state value is set for the user - basically any of the 8 uint4s can be set to 0-2. So if I have one user with a state vector of 00000001 and another with a state vector of 00000010, if both login the login state for the session is 00000011. UT tags the token (not the individual keys) with the option to require strong authentication. The token has an attribute that's settable through a well-known handle to a required login state (which is represented similar to the above). Say you want the token to require at least one strong auth - so you set the required strong auth login state value to 00000001. The login state of the token is compared to the required value (each uint4 in the login state to each matching uint4 in the required value) and if the login state is equal to or superset of the required value, the login succeeds and the token may be used. This construct is used to implement M of N systems. Say for example I want require that both QA and Firmware sign off on the use of the token (for example to sign firmware). I assign users in the firmware groups a login value of 00000001, and the users in the QA group a login value of 00000010. I assign the token a use value of 00000011. So this requires at least one user from QA and one user from Firmware to login before the token can be used. Alternately, I can implement a 3 of N system by setting the token use value to something like 00003000 and then assigning users the appropriate login values. I can give certain users more privileges (e.g. bosses) by assigning them higher values in specific uint4 nibbles or by assigning them values in multiple buckets. We (the company I work with) have found over time that the 8 nibble construct is probably too few buckets for a truly flexible system, but it's worked pretty well for the applications we've built. If PKCS11 wants to use something like this I might suggest an expandable approach for the state and use vectors where the vectors are arrays of uint8 values instead of being stored as 32bit words. Leaving aside for a minute the question of how exactly strong authentication is done, let's consider how something like this could be used on a per-object basis. I would probably mark each object with a use vector - and if the use vector isn't present, the object can be used without strong authentication. If the vector is present, the login state must be equal to or greater the use vector to use the object I would probably also mark each object with an admin vector - that vector would control things like whether or not the key could be deleted, copied or modified. It may actually make sense to mark each individual admin function with a vector - so that you could allow one admin to delete or export the object, but not change its privileges. This would require some more thought than I'm prepared to do right at this minute. I like the UT approach because its pretty clean to implement and to understand how to get specific behaviors. The user administration process UT uses is outside of the PKCS11 scope, but I think it would be possible to actually create a PKCS11 user admin model based on the PKCS11 object model that would work quite well. Thoughts? Mike


  • 7.  Re: [pkcs11] User types - discussion thread

    Posted 10-29-2013 09:38
    On 13.10.2013 22:34, Michael StJohns wrote: > In PKCS11 there are currently two types of users, CKU_USER, CKU_SO and > CKU_CONTEXT_SPECIFIC. The USER type, when logged in, can access all the > keys on the token, use them and change their attributes within the > limits of PKCS11 policy. > > The SO user type has only a single function defined in PKCS11 as far as > I can tell - marking keys as trusted. > > The CONTEXT_SPECIFIC user seems to be used only for those keys that > require authentication each time they're used. > > The above provides only a minimal amount of role based policy > protections. Over the years I've found this minimal set of roles to be > somewhat constricting in building PKCS11 applications as they don't > provide granular enough control over the token. We've added a few > additional attributes (CKA_COPYABLE and CKA_DESTROYABLE) as of 2.40 that > provide some improvements, but I think we should consider modifying the > model either slightly or comprehensively: > > Slightly: One of the big issues I've encountered with PKCS11 is that > the creators of the key materials are not always the users of the key > materials. That leads to complications in managing the token in that > we'd (e.g. my customers) *really* like to prevent the users of the key > materials from either creating or destroying key material. > CKA_DESTROYABLE works for the destroying part, but there's no way to > prevent the creation. A slight modification to the above set of user > types might be the addition of a CKU_SESSION_USER who's allowed > read-only access to token key material for use, but can't create or > destroy any CKA_TOKEN=true objects - the session user MAY create session > key material as necessary. A second slight modification might include > the addition of a CKU_OWNER_USER who in addition to all the access a > CKU_USER gets may set key protection attributes on the keys irrespective > of normal policy (e.g. can violate the stickyness rules for > attributes). So CKU_OWNER_USER > CKU_USER > CKU_SESSION_USER in terms > of access. > > Comprehensive: Another possible approach may be to go to a full user > (vs role) based system where each object is tagged both with the owner > (who gets to set attributes) and the users allowed to use the object. > There's probably also the concept of a token owner who gets add and > delete users. Obviously, this would be a bit more disruptive than the > simple additions described above. It would require a more > comprehensive user management system than currently exists, and a set of > functions to manage the access control lists for the objects. But > this approach may be required to support multi-party (m of n) > authorization models. > > > A third option is to standardize both - but make the "comprehensive" > version optional. FWIW, I'd be more interested in implementing the former, albeit less comprehensive version. Wouldn't multiple user's on a token be representable as separate tokens? If a multi-user token is inserted, then multiple tokens would be present. However, I am interested to see what an optional standardized comprehensive version might look like, and how the two would interact. Cheers, Stef


  • 8.  RE: [pkcs11] User types - discussion thread

    Posted 10-29-2013 13:46
    > Wouldn't multiple user's on a token be representable as separate tokens? Not necessarily. What do you do where you have a situation where multiple users need access to a shared resource on a single token? That's the problem we originally had.