106
edits
m (More wordsmithing, use database and DBM consistently) |
(Fix big formatting issues and some more wordsmithing) |
||
Line 444: | Line 444: | ||
#The database is password protected and the user never logs into the token during the lifetime of the application. | #The database is password protected and the user never logs into the token during the lifetime of the application. | ||
Applications can avoid | Applications can avoid that third failure case by forcing the user to authenticate to softoken using PK11_Authenticate(). | ||
<pre> | <pre> | ||
Line 464: | Line 464: | ||
====== Mode 3A ====== | ====== Mode 3A ====== | ||
Mode 3A Applications are the most complicated. NSS provides some services to help applications get through | Mode 3A Applications are the most complicated. NSS provides some services to help applications get through an update and merge with the least interaction with the user of the application. The steps a Mode 3A application should use whenever initializing NSS are listed below. | ||
Step 0: Preparation: collect the directory and prefix names of both the source and target databases. Prepare two strings for the operation: | Step 0: Preparation: collect the directory and prefix names of both the source and target databases. Prepare two strings for the operation: | ||
Line 477: | Line 477: | ||
second or subsequent attempt to merge the same source file into the | second or subsequent attempt to merge the same source file into the | ||
destination file.</nowiki><br><br><nowiki> | destination file.</nowiki><br><br><nowiki> | ||
Note: The purpose of this string is to prevent multiple updates from the same old | Note: The purpose of this string is to prevent multiple updates from the same old database. This merge sequence is meant to be sufficiently light weight that applications can safely call it each time they initialize.</nowiki><br> | ||
# <nowiki>A string that will be the name of the removable PKCS#11 token that | # <nowiki>A string that will be the name of the removable PKCS#11 token that | ||
will represent the source database. This string must follow the rules for a | will represent the source database. This string must follow the rules for a | ||
Line 490: | Line 490: | ||
* Otherwise proceed to step 2. | * Otherwise proceed to step 2. | ||
Step 2: Determine if a merge is | Step 2: Determine if a merge is necessary. If a merge is necessary, | ||
NSS will set the slot to a 'removable slot'. You can use PK11_IsPerm to | NSS will set the slot to a 'removable slot'. You can use PK11_IsPerm to | ||
test for this. | test for this. | ||
Line 502: | Line 502: | ||
# <nowiki>(optional) Call PK11_GetTokenName to get the name of the token. With | # <nowiki>(optional) Call PK11_GetTokenName to get the name of the token. With | ||
that name, you can be sure that you are authenticating to the source token. Skipping this step is not harmful, it is only necessary if the application absolutely needs to know which token the following PK11_Authenticate() will be called on (for instance pwArg contains the actual password for the token). For | that name, you can be sure that you are authenticating to the source token. Skipping this step is not harmful, it is only necessary if the application or user absolutely needs to know which token the following PK11_Authenticate() will be called on (for instance pwArg contains the actual password for the token). For some NSS applications the underlying password prompt system will properly disambiguate the appropriate password to the user (or it's password cache).</nowiki> | ||
#* If the token name does not match the token name skip to step 5. | #* If the token name does not match the token name skip to step 5. | ||
#* Otherwise proced to | #* Otherwise proced to the next substep. | ||
# <nowiki>Call PK11_Authenticate() to authenticate to the source token. This | # <nowiki>Call PK11_Authenticate() to authenticate to the source token. This | ||
step is likely to call the application-supplied PKCS11 password callback | step is likely to call the application-supplied PKCS11 password callback | ||
Line 528: | Line 528: | ||
callback function to retrieve the password. | callback function to retrieve the password. | ||
* If this step fails: stop. A | * If this step fails: stop. A failure at this point is described below as "Exception B". | ||
* Otherwise, continue with step 7. | * Otherwise, continue with step 7. | ||
Line 535: | Line 535: | ||
====== Failures and recovery ====== | ====== Failures and recovery ====== | ||
Exception A. Failure to authenticate to the source database | Exception A. Failure to authenticate to the source database | ||
Application needs to decide what happens if the legacy password | Application needs to decide what happens if the legacy password | ||
is not supplied. Application can choose to: | is not supplied. Application can choose to: | ||
# continue to use the legacy database and try to update later. (Probably a future restart of the application). | # continue to use the legacy database and try to update later. (Probably a future restart of the application). | ||
# reset the legacy database, | # reset the legacy database password, discarding any private or secret keys in the old database. | ||
# shutdown NSS and initialize it only with the new shareable database. | # shutdown NSS and initialize it only with the new shareable database. | ||
: The exact strategy for recovering is application dependent and depends on factors like | : The exact strategy for recovering is application dependent and depends on factors like | ||
Line 545: | Line 546: | ||
:# possible input from the user. | :# possible input from the user. | ||
:# the likelihood that the password will every be recovered. | :# the likelihood that the password will every be recovered. | ||
Exception B. Failure to authenticate to the target database | Exception B. Failure to authenticate to the target database | ||
Applications needs to decide what happens if the new shareable database | Applications needs to decide what happens if the new shareable database | ||
password is not supplied. Application can choose to: | password is not supplied. Application can choose to: | ||
Line 552: | Line 554: | ||
# force NSS to update those objects it can from the legacy database, throwing away private keys and saved passwords, and trust information from the legacy database. | # force NSS to update those objects it can from the legacy database, throwing away private keys and saved passwords, and trust information from the legacy database. | ||
# force NSS to reset the shareable database password, throwing away private keys and saved passwords, and trust information from the shareable database. | # force NSS to reset the shareable database password, throwing away private keys and saved passwords, and trust information from the shareable database. | ||
Notes: | Notes: | ||
Line 562: | Line 564: | ||
have the same password or different passwords, and when the | have the same password or different passwords, and when the | ||
authentication attempts, if any, succeed. The system tries to complete the | authentication attempts, if any, succeed. The system tries to complete the | ||
merge as soon as it is able, to increase reliability of the merge update actually completing. | merge as soon as it is able, to increase reliability of the merge update actually completing. The API does not make it | ||
possible to predict, accurately, which step will actually perform the | possible to predict, accurately, which step will actually perform the | ||
merge. The application | merge. The application can only follow the steps. Since multiple calls to PK11_Authenticate() do not hurt, the application can simply follow each step in order, and fail only on bad returns from PK11_Authenticate. (PK11_Authenticate will automatically return without prompting, so applications that just need to merge, without caring which step does the merge, may do so.) | ||
2. If the attempt to open the | 2. If the attempt to open the | ||
source database fails for any reason, the operation will behave as if the | source database fails for any reason, the operation will behave as if the | ||
source database was empty. It will record the unique source database identifier | source database was empty. It will record the unique source database identifier | ||
string in the target database and act as if the merger is complete. This is | string in the target database and act as if the merger is complete. This is similar to what happens in all previous versions of NSS during database update. See "Database Merge" below for how to recover from this. | ||
<pre> | <pre> | ||
/* | /* | ||
Line 677: | Line 679: | ||
In Mode 1, NSS never needs to do an update or a merge. | In Mode 1, NSS never needs to do an update or a merge. | ||
<pre> | |||
State machine of NSS update actions for Mode 1: | State machine of NSS update actions for Mode 1: | ||
Line 686: | Line 689: | ||
V | V | ||
done | done | ||
</pre> | |||
In Mode 2, the new database is uninitialized, so NSS only needs the | In Mode 2, the new database is uninitialized, so NSS only needs the | ||
Line 701: | Line 705: | ||
the old database on future opens until the update succeeds. | the old database on future opens until the update succeeds. | ||
<pre> | |||
State machine of NSS update actions for Mode 2: | State machine of NSS update actions for Mode 2: | ||
Line 760: | Line 765: | ||
V | V | ||
done | done | ||
</pre> | |||
In Mode 3, the new database may or may not be initialized. For the first mode 3 | In Mode 3, the new database may or may not be initialized. For the first mode 3 | ||
Line 780: | Line 783: | ||
application shared directory that the shared database lives in. | application shared directory that the shared database lives in. | ||
<pre> | |||
Flow chart of NSS update actions for Mode 3: | Flow chart of NSS update actions for Mode 3: | ||
Line 866: | Line 870: | ||
V | V | ||
done | done | ||
</pre> | |||
===== Merge Conflicts (Mode 3A only) ===== | ===== Merge Conflicts (Mode 3A only) ===== | ||
Line 875: | Line 880: | ||
# don't update duplicate trust (shared database copy wins). | # don't update duplicate trust (shared database copy wins). | ||
# overwrite trust from the legacy database (legacy database copy wins). | # overwrite trust from the legacy database (legacy database copy wins). | ||
# calculate the | # calculate the intersection of trust between them (take the least trusted values). (turning off trust wins). | ||
# calculate the | # calculate the union of trust between the two (turning on trust wins). | ||
From the user perspective, each of these choices means: | From the user perspective, each of these choices means that after the update: | ||
# | # the application that just updated may then trust certs that it had previously marked untrusted, and may no longer trust certs that it had previously marked trusted. | ||
# | # other applications that share the database may then trust certs they had previously marked untrusted, and may no longer trust certs that they had previously marked trusted. | ||
# | # all apps may find that they no longer trust certs that had previously been marked trusted. | ||
# | # all apps may find that they trust certs that had previously been marked untrusted. | ||
Option 3 is the most secure, Option 4 will break have less breakage. Trust | Option 3 is the most secure, Option 4 will break have less breakage. Trust | ||
Line 936: | Line 941: | ||
:Exception case A | |||
:If we fail to get this password, we need to handle the exception A case. If the user has a master password set, but does not know what the master password is, then the following data is lost for sure: | |||
:* The user's private keys. | |||
:* The user's secret keys. | |||
:* Any data encrypted to the private keys. | |||
:* Any data encrpted with the secret keys. | |||
:I believe we can identify if the private keys are associated with a certificate. If so, then we can tell the user what certificate would no longer work. Data encrypted with the private keys in Mozilla products are currently only email messages. Secret keys encrypt saved passwords. The Mozilla app knows which saved passwords are encrypted with that key. | |||
:If we hit Exception case A we can do one of the following: | |||
:# attempt to just update the certs, trust, crl and s/mime records, skipping the all the keys. We would loose all the data described above. | |||
:# decide not to update. In this case we would loose all the data in the paragraph above as well as all the certs, trust crl and s/mime records. | |||
:# run with the legacy database and allow the user to update later. | |||
:# run with the new shared database and allow the user to update later. | |||
:I would suggest we only offer the user the choice of 1 or 4. Note: if the user selects 1, the update could fail again in exception case B. From a UI perspective, we may want to handle exception case B as we handle case A so the user is only asked once about forcing an update while losing data. | |||
Once we have a legacy database password, or if we determine we don't need the legacy | Once we have a legacy database password, or if we determine we don't need the legacy | ||
Line 987: | Line 980: | ||
:Exception case B | |||
:If we fail to get this password, we need to handle the exception B case. If the user has a master password set on his shareable database, but does not know what that master password is, we now have the following choices: | |||
:# eshew any private keys, secret keys and trust updates from the legacy database. | |||
:# reset the password on the shareable database (losing all private and secret keys, possibly losing some trust). | |||
:# run with the legacy database and allow the user to update later. | |||
:# run with the new shareable database and allow the user to update later. | |||
:It seems pretty unlikely that the user truly does not know the shareable database password, since he had to create or set it recently. However as the deployment time increases, this becomes more likely. | |||
:Again, I think giving the user a choice between options 1) and 4) are the best alternatives. If the user had already tripped over Exception case A, we can presume the user intends to make a similiar choice here. Case 2 can be handled later under the same way the user handles a forgotten master password today (only now resetting the master password affects all mozilla apps). | |||
Line 1,041: | Line 1,024: | ||
Characteristic 3 allows database merge to work on arbitrary database types. You can merge a shareable database into a shareable database as well as an old database into a shareable database (in fact, to a point, on arbitrary tokens - you can merge a hardware token into a shareable database as long as the keys are extractable). | Characteristic 3 allows database merge to work on arbitrary database types. You can merge a shareable database into a shareable database as well as an old database into a shareable database (in fact, to a point, on arbitrary tokens - you can merge a hardware token into a shareable database as long as the keys are extractable). | ||
To merge 2 databases, the application simply opens | To merge 2 databases, the application simply opens both databases (using SECMOD_OpenUserDB) and then calls the new PK11_MergeTokens() function. PK11_MergeTokens() has the following signature: | ||
<pre> | |||
#include <pk11pub.h> | #include <pk11pub.h> | ||
Line 1,050: | Line 1,034: | ||
PK11MergeLog *log, | PK11MergeLog *log, | ||
void *pwdata); | void *pwdata); | ||
</pre> | |||
Parameters: | Parameters: | ||
Line 1,061: | Line 1,046: | ||
''pwdata'' password arg | ''pwdata'' password arg | ||
The ''targetSlot'' and ''sourceSlot'' parameters could be slots that are simply looked up, or additional databases opened with SECMOD_OpenUserDB(). In order for the merge to be successful, ''targetSlot'' must support all the | The ''targetSlot'' and ''sourceSlot'' parameters could be slots that are simply looked up, or additional databases opened with SECMOD_OpenUserDB(). In order for the merge to be successful, ''targetSlot'' must support all the object types in the following list for which token objects exist in the ''sourceSlot'': | ||
* CKO_CERTIFICATE, | |||
* CKO_PUBLIC_KEY, | |||
* CKO_PRIVATE_KEY, | |||
* CKO_SECRET_KEY, | |||
* CKO_NSS_TRUST, | |||
* CKO_NSS_CRL, | |||
* CKO_NSS_SMIME. | |||
The source Slot must also have extractable keys or the merge will fail (sensitive keys are OK, as long as the source slot supports PBE's if it contains private keys). All softoken slots (including those opened with SECMOD_OpenUserDB()) support these charateristics. | |||
Multiple calls to merge will only attempt to merge those objects which were created since the last merge, or failed to merge in the last call to merge. | Multiple calls to merge will only attempt to merge those objects which were created since the last merge, or failed to merge in the last call to merge. | ||
Line 1,134: | Line 1,127: | ||
The returned SDB structure has the following format: | The returned SDB structure has the following format: | ||
<pre> | |||
typedef struct SDBStr SDB; | typedef struct SDBStr SDB; | ||
Line 1,162: | Line 1,156: | ||
CK_RV (*sdb_Close)(SDB *sdb); | CK_RV (*sdb_Close)(SDB *sdb); | ||
}; | }; | ||
</pre> | |||
where: | where: |
edits