Thank you for your help, I'll answer directly into your answers, too:

Robert Relyea schrieb:


If I remember well, the PKCS11 specs tell that there's exactly 1
crypto-object per token (soft or hardware).

FALSE- A token can and does regularly have multiple crypto-objects
active at any given time. I suspect getting this wrong will make
understanding the rest impossible.


thanks, with that correction in mind, maybe some points are going to be clearer in a few minutes, when I'll walk through the code again.


If that's true, I don't understand the key arrays
PK11SymKey *freeSymKeysWithSessionHead;
PK11SymKey *freeSymKeysHead;
in PK11SlotInfo, and neither why they are tagged as "free".

These are an internal free list of empty key objects. The are a
performance enhancement to reduce the time to allocate a new symkey
object. They have nothing to do with actual symkeys. NOTE: I think your
confusion, however, is caused by the assumption that there is only one
possible key in a token. This is not true.


Oh ok, I didn't understand that. My last conception was that PK11SlotInfo must be a sort of session-handling object, besides the information about a slot, but that's wrong too, I guess. Which object/instance holds an overview of all existing (instanciated) key-instances with or without an opened session to the crypto-objects in the tokens, in NSS?



My question is:
What do those code-lines do? Why do I need them in order to find the
key-id, before a key can be found using that key-id?

PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
     if (keyID) {
         PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); attrs++;
     }
     tsize = attrs - findTemp;
     PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));

This is a basic set up to do a PKCS #11 C_FindObjects. This call is
looking for a key that is already in the token. The call will return a
handle, which is the only address we have for the key. For the meaning
of this you really need to be familiar with the PKCS #11 spec.


Thanks, I'll look for it in the specs. But if I now know there are several objects in a token (that must be sooo basic, I feel like a stupid chicken), I guess C_FindObjects uses those attributes to look for an object that matches them, isn't it? Do C_something functions (I read in the specs C stands for "function") refer to operations on the pk11libraries of a module-provider? So the "leafs" of the "implementation-tree" of NSS is always a C_something, which is finally executed by the module-libraries, to interact with the reader/slots/tokens/objects themselves?


By the way, I don't know why this key is called "fixed", and do I need
to have opened sessions at that point?

It's an unfortunate name. It's looking for a TokenKey (which is also an
unfortunate name). Fixed == Token == Persistant. A key that does not
disappear when the session it was created on goes away, or when the
token it's created on powers down.


This is a rare point I clearly understand now, I think :-) It means one of the crypto-objects inside a token, but one that is a key.




I don't know if FindFixedKey() looks into tokens
or looks in existing NSS-PK11SymKey-Objects which already have
sessions opened.

It's looking into the token, only for those symetric keys that are
Persistant.


Are there unpersistant keys in a token? I'll also look for that point in the specs.



If you can see that I'm wrong in my structure-conception, please tell
me ^^
Mostly at the very beginning;(.


:-D  I'm a looser...



If I may ask, what is it you are trying to accomplish?


Yes, of course! I'm still trying to find the best way to modify nsSDR.cpp. I want SecretDecoderRing use a DES3key from another token than the NSS internal software one (I want to use the TPM on my mainboard with IBM's Trousers softwarestack. Instead of using their API, I want to use pkcs11. They also implemented pkcs11, so my goal is to use that interface to have my des3symkey, which is used to encrypt my logins and pwds in the mozStorage sqliteDB, there) To be able to do that, I need to know how those key-stories really work in pkcs11, and how it's implemented in NSS. Thanks to you Bob, I now know 2 important aspects of that implementation: The key handle is what I need, and that there are several objects in 1 token :-) I also know I can use already implemented functions to create, modify and handle lists of available keys. I guess I'm speaking about persistant keys as crypto-objects at that point. But I'm sure there's a way to list all instanciated nss-key-objects with handles to those crypto-objects, too (and their opened sessions). I don't know how yet, cause I'm a noob, but I'll find out, for sure :-) I know what I want to do, I only have to find out how, with NSS ^^ ...Which is pretty a cool tool, by the way.

If you don't mind, I'll put the few lines of pseudo-Code I wrote some time ago. I know its not good, it's a first "mindmapping", but I'm looking for a way to implement something like that. Some of the things written in there a wrong, I see now, after you explained me those things. But I'll copy-paste it as is anyway. You also wrote that the handle is the single way to reference the keys (key-crypto-objects) inside the tokens, so in my pseudo-code, "key-ID" should be replaced by "handle". Well, lots of things are wrong there, I could correct lots by myself now ^^ The aim is to become familiar enough with NSS / pkcs11specs to be able to do those changes by myself.


Synopsis:

- Use another des3 key than the one in nss softtoken to run Encrypt and Decrypt in nsSDR. - there should be a standard key chosen/set in settings (e.g. in Firefox, which is the application for which I want to change the NSS behavior in nsSDR) - to encrypt, try to use that key set. if you can't find it, use another one: ask user if he/she wants to use the soft-tok-standard one, or look for another in another token.

- to decrypt, try to use/find key set in settings. If you can't find it, try the softtok one. If that doesn't work, try to find the matching one automatically or ask user to tell which one.

- User should be able to reencrypt his data (for login, pwd in mozStorage) using another key, and set it as default.

- User should also be able to create a new (persistant) key, store it inside a chosen token (if free space available), use this one to encrypt / decrypt, and set it as "standard key"




******** nsSDR modifications, (very) dirty first projection ***********

Set key-ID in FF-settings:

After you put in your pkcs11-device and loaded the module, you should be able to go to the settings and choose the token that has to be used. Maybe the "cryptography module manager" could be used to do so. Just set a "hook" next to the token that should be used per default. By the way, is the cryptography module manager capable of deleting token-contents, resetting authentication-pwds, like e.g. the Master PWD for the default softtoken?

Settings should memorize which token and which key-ID that should be used (maybe the slot and module too) (maybe token ID changes when you plug in and out, I don't know. But key-ID should be unique identifier I guess).

Default Setting if not set should be the internal soft token


Here my first lignes of pseudo-code for SDR


to Encrypt:

//*************************************************************************

Read FF-settings
if FF-settings not set: goto "1:"


//try to use the key set in the settings//

if FF-settings set, try to authenticate to token set as default
   if authentication fails goto "1:"
   if authentication successes or already authenticated
      look in the token set for the key
if key available: test if it's a 3deskey (and other important things maybe)
            if it is and symkey->key-ID is the same as set: use key to encrypt()
            if it is, but key-ID is different:
                Tell user key is probably in another token
Ask user if he/she wants to encrypt() using that token anyway and change FF-settings (could create probs in databases, not all encrypted data with same keys need a better solution. But sdr-decrypt could be programmed in a way it wouldn't matter. If key doesn't match, try to find another one. So not every dataset in the DB would have to be encrypted with the same key)
                    if user doesn't want to use new token goto "1:"
            if it is not: tell user and go to "1:"
            (future: try to find key in another token/slot/module)


//FF-settings key not found, ask the user to use another key//  

             if key not available:


          1:    Ask user: use default key | use another key | create key ?

                    if use default: try to find default softtoken key to 
encrypt()
                        try to authenticate to softtoken
                            if authentication fails after several tries: goto 
"1:"
                            if authentication successes
                                and if default softtoken key available: use key 
to encrypt()
                                and if default softtoken key not available: try 
to create one
if success: use key to encrypt() and ask user if new key should be set as default
                                    if not success: goto "1:"

                    if use another one:
                        Create a list with all available tokens, let user choose
                        try to authenticate to token chosen
                            if authentication fails goto "1:"
                            if authentication successes or already authenticated
                                look in the token chosen for a key
                                if no key is available: goto "1:"
if a key is available: test if it's a 3deskey (and other important things maybe) if it is a 3deskey: use key to encrypt() and ask user if new key should be set as default
                                    if it is not: goto "1:"

                                                                                
                    if create one
                        Create a list with all available tokens
                        Ask user: choose the token which should carry a new key 
from the list
                            try to authenticate to token chosen
                                if authentication fails goto "1:"
                                if authentication successes or already 
authenticated
                                    look in the token chosen if there's no key
if there is no key: create new 3DESkey and encrypt() using that key
                                        if there is already a key/other data
tell user what kind of data, and if it should be overwritten with new key
                                                if user says no: goto "1:"
if user says yes, create new key, store it in token, encrypt() using that key, and ask user if new key should be set as default


//*************************************************************************


to Decrypt:

//*************************************************************************
Read FF-settings
if FF-settings not set: goto "2:"

//try decryption with key set in settings//

if FF settings set, try to authenticate to token set
    if it fails, goto "2:"
    if success, compare symkey->keyID with FF-settings
if it is the key set, use key to decrypt() (authentication needed if not authenticated yet)
            if decryption fails: goto "2:"
        if wrong key: goto "2:"
                


//try decryption with internal key//

2: Try to find the internal soft token
    if it can't be found (is that case possible?) goto 3:       
if default softtoken key found: try to decrypt() using default softtoken key
                        if decryption success: yeah!
if settings <> softtoken: ask user if he/she wants to reencrypt using key set in settings (make sure authentication is ok)
                        if decryption fails:


   Make a list of all available tokens

//try to find the key in another token//

3: Ask user to choose if the key should be looked for automatically or not
       if user wants to look for it manually, let user choose from the list
           try to authenticate to token
               if it fails: goto:3
               if it successes
                   try to decrypt() with that key
                       if it fails: goto: 3
if it successes: yeah!, and ask user if he/she wants to reencrypt using key set in settings (make sure authentication is ok)


   if user wants to automatically find the key:
       make a list of all tokens (or just keep it if already generated)


//try to find the key in those with no authentication needed, then those which need authentication//

find the tokens in the list that need no authentication, or already authenticated
       do a loop:
           look for the key in token n
               if you find a key try to decrypt() using key
                   if it fails, take next token
       if no already authenticated token had the key:
           find the tokens in the list that need authentication
           do a loop:
               try to authenticate to token i
                   if it fails: try next token
                   if success:look for the key in token i
                       try to decrypt() using key
                           if it fails: try next token
if it successes: if it successes: yeah!, and ask user if he/she wants to reencrypt using key set in settings (make sure authentication is ok)
       if no key could be found in any token: say sorry








--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to