NSS Shared DB: Difference between revisions

Jump to navigation Jump to search
16,678 bytes added ,  14 August 2007
Line 344: Line 344:
==== Database Upgrade ====
==== Database Upgrade ====


NSS will automatically upgrade from old databases to new databases if the following conditions are met:
Because there are some semantic differences between the Shared Database version
# The application (either explicitly or implicitly) opens an sql style database read write.
of NSS and the traditional database, We really have 3 modes of operation for
# The sql database does not exist.
the NSS and shared databases.
# A legacy dbm database exists in the same directory of the sql database.
# The application logs into the softoken (supplies the database password for the existing legacy database). If there is no password this condition is met automatically.


This upgrade handles the initial case where applications want to get the new features of the new database, but not necessarily want to participate in any sharing scheme.
Mode 1: Legacy applications which upgrade to the new version of NSS without
making changes to the application itself.


A more natural tact an application may take is move from it's own database instance to a common database instance, shared among several applications. In this case, the application will need to participate in the database upgrade, as it may be necessary to actually merge entries from several databases. In this case NSS will provide services for the application to determine if the shared database it opened had already been updated by the application itself. If not, NSS will provide the application with a function (to be defined), which will read records from the old database and merge them into the new database. NOTE: we may need a couple of functions here to allow recoding such things as passwords encoded with sdr keys which the application may have.
These applications will continue to use the legacy database support and the
old database format. The applications cannot take advantage of new features
in the shared database. In this Mode, the nssdbm3 shared library must be
present. No update is needed in this case.
 
  Summary:
  nssdbm3 shared library: Must be Present
  Update: none needed.
  Application Changes: none.
 
Mode 2: Applications which maintain private copies of their certs and key
stores (various servers, for instance).
 
These applications will use the shared database. NSS will automatically
detect instances of legacy databases when first creating the shared database
and upgrade those legacy databases without user interaction.
 
  Summary:
  nssdbm3 shared library: need only for update
  Update: automatic, no application/user intervention.
  Application Changes:
    minor changes to Init,
    Changes to code that updates trust values or imports certificates with
        trust.
 
Mode 3: Applications which intend to share their keys and certs with other
applications (the common case - browsers, mail clients, secure shells,
vpns, etc.)
 
These applications will share a common database. In order for this to work,
these applications must all open the same set of databases. Currently these
applications have their own independent copies of the databases. These
independent copies must be merged. In order or NSS to complete this merge, it
will need some extra support from the application itself, possibly user
intervention as well.
 
  Summary:
  nssdbm3 shared library: need only for update
  Update: partially automated, requires application interaction, possibly
          user interaction.
  Application Changes:
    minor changes to Init,
    Changes to code that updates trust values or imports certificates with
        trust.
    Changes to aid in update
 
Type A: Type A applications have existing NSS databases. These applications
have upgraded to NSS, and need to merge old databases. All Mode 1 applications
are type A. All Type A applications need nssdbm3 to either upgrade or run.
 
Type B: Type B applications are applications ported to NSS after the new shared
database code. All Type B applications should be either Mode 2 or Mode 3.
Type B applications need no update interactions, nor do the need nssdbm3.
 
 
===Update complications.===
 
Updated complications only affect Type A applications. In order to merge a
legacy database into an existing shared database, NSS needs the password for
both databases.
 
In Mode 1, NSS never needs to do an update or a merge.
 
Flow chart of NSS update actions for Mode 3:
            NSS initialize
                  |
                  V
            open legacy DB
                  |
                  V
                done
 
In Mode 2, the new database is uninitialized, so NSS only needs the
password for the legacy database so it can read the secret keys
in that legacy database, and so the new shared database password
matches the old one. NSS can find the legacy database because
it's in the same directory that the shared database lives in. NSS opens both
databases at initialization time and uses the legacy database until the user
authenticates (providing the legacy database password). NSS then uses that
password to update the new shared database with the records from the old.
The new database takes on the password from the legacy database, and the
legacy database is closed.  Future NSS initializations only open the new
shared database. If the user never supplies a password, NSS will continue to
treat the new shared database as uninitialized and will attempt to update from
the old database on future opens until the update succeeds.
 
  Flow chart of NSS update actions for Mode 2:
            NSS initialize
                  |
                  V
            open shared DB
                  |
                  V
          < is open shared DB >  yes
          <  initialized?    >-------> done
                  | no
                  V
          <  does legacy DB  >  no
          <      exist?      >-------> done
                  | yes
                  V
            open legacy DB
                  |
                  V
      no  < does legacy DB    >
  +-------< have a password?  >
  |              | yes
  |              V
  |          use legacy DB
  |        until password
  |          is supplied
  |              |
  |              V
  |      <  is password  >  no
  |      <    supplied?  >-------> done
  |              |
  +--------------+
                  V
            update shared DB
                  |
                  V
            close legacy DB
                  |
                  V
                done
               
 
In Mode 3, the new database may or may not be initialized. For the first mode 3
application, the new database will be uninitialized. NSS can procede the with
the same procedure as Mode 2. When the second and subsequent applications
start, the new shared database will already be initialized with it's own
password. We potentially need both passwords, the first to read the keys
out of the legacy database, and the second to write those keys, as well as
the required authentication values for any trust data. In order to preserve
the existing data in the second application, NSS must be able to merge the
data in the second application with the data in the existing database.
We only want the merge to happen once, not every time the application starts.
In Mode three we need to be able to identify when a database has already been
updated, so the applications needs to tell us some unique identifier for its
database. The application must be able to tell us where the old database lives,
since it's a application private directory compared the the multiple
application shared directory that the shared DB lives in.
 
  Flow chart of NSS update actions for Mode 3:
                Start
                  |
                  V
            open shared DB
                  |
                  V
          < is open shared DB  >  yes
          < updated with given >-------> done
          <    legacy DB?      >
                  | no
                  V
          <  does legacy DB  >  no
          <      exist?      >-----------+
                  | yes                  |
                  V                      V
            open legacy DB              mark given
                  |                    legacy Updated---> done
                  V
      no  < does legacy DB    >
  +-------< have a password?  >
  |              | yes
  |              V
  |  no  < does legacy DB    >
  +-------< have any private  >
  |      < or secret keys?  >
  |              | yes
  |              V
  |          use legacy DB
  |        until password
  |          is supplied
  |              |
  |              V
  |      <  is password  >  no
  |      <    supplied?  >-------> exception A
  |              |
  +--------------+
                  V
      no  < does shared DB    >
  +-------< have a password?  >
  |              | yes
  |              V
  |  yes  < does shared DB's >
  +--------< password match  >
  |        < legacy DB's PW?  >
  |              | no
  |              V
  |        get shared DB
  |            password
  |              |
  |              V
  |      <  is password  >  no
  |      <    supplied?  >-------> exception B
  |              |
  +--------------+
                  V
            update/merge shared DB
                  |
                  V
            close legacy DB
                  |
                  V
                done
 
exception A. Application needs to decide what happens if the legacy password
is not supplied. Application can choose to:
    1) continue to use the legacy DB and try to update later.
    2) force NSS to mark legacy DB to be updated without actually updating
    the legacy DB (throwing away everything in the legacy DB).
    3) force NSS to update those objects it can from the legacy DB, throwing
    away private keys and saved passwords.
 
exception B. Applications needs to decide what happens if the new shared DB
password is not supplied. Application can choose to:
    1) continue to use the legacy DB and try to update later.
    2) force NSS to mark legacy DB to be updated without actually updating
    the legacy DB (throwing away everything in the legacy DB).
    3) force NSS to update those objects it can from the legacy DB,
throwing away private keys and saved passwords, and trust information
from the legacy DB.
    4) force NSS to reset the shared database password,
throwing away private keys and saved passwords, and trust information
from the shared DB.
 
NOTE: Since we are potentially dealing with 2 different passwords, The
application needs to be clear to the user which password it needs.
 
Merge Conflicts (Mode 3A only)
 
When merging databases in, it's possible (even likely), that the shared
database and legacy DB's have the same objects. In the case of certs and keys,
the merge is a simple matter of identifying duplicates and not updating them.
In the case of trust attributes, however, there are a number of choices:
  1) don't update duplicate trust (shared database copy wins).
  2) overwrite trust from the legacy DB (legacy db copy wins).
  3) calculate the least common denominator trust between them (take the least
  trusted values). (turning off trust wins).
  4) calculate the most common demonimnator trust between the two (turning on
  trust wins).
From the user perspective, each of these choices means:
  1) after the update the application that just updated may trust certs that
it had previously marked untrusted, or certs that it has marked trusted are
no longer trusted.
  2) after the update other applications that share the database may trust
certs they had previously marked untrusted, or certs that they had marked as
trusted are no longer trusted.
  3) after the update all apps may find the certs that they marked trust are
no longer trusted.
  4) after the update all apps may find that they trust certs that have
previously been marked untrusted.
 
Option 3 is the most secure, Option 4 will break have less breakage. Trust
merge conflicts that are real conflicts (application 'A' turned off trust and
application 'B' turned on trust) are expected to be rare. The common case would
be application 'A' turned on SSL trust and application 'B' turned on email
trust. In this case Option 4 is clearly the correct choice.
 
From a programming point of view, NSS should pick a default and implement it.
Ideally no user interaction will occur.
 
Finally password entries are merge issues. If the two databases have different
passwords, the merged database will have to have a
 
Mozilla Applications.
 
Mozilla applications are Mode 3A applications. In fact, for all intents and
purposes, mozilla applications make the complete set of interesting 3A
application. This section tries to map the issues above into actual code for
Mozilla applications.
 
As 3A applications, Mozilla apps need to send NSS a unique identifier for
the old cert and key database, as well as the old profile directory where
the databases are stored. The profile 'salt' value would make a good unique
identifier for mozilla products.
 
On startup, Mozilla apps should note when they are not in done state at
initial nss startup (see flow chart for Mode 3A update above). If mozilla apps
are not at 'done' state after startup, they should proceed to attempt to
enter done state before PSM initialize completes.
 
Mozilla app will be in done state in the following cases
(any of the below apply):
 
1) The Mozilla app is starting as a fresh instance.
2) The Mozilla app has already been updated.
3) The shared database does not have a master password set and
  The legacy database for Mozilla app does a master password set.
 
These are the most common cases.
 
If the state is not done, then we know that this app has not already been
updated, and either the shared database or the legacy database for the Mozilla
app has a master password set.
 
UI question. At this point should we notify the user that we are updating
the database to a shared database? In order to complete this we will need
to do user interaction below.
 
If the legacy db for the mozilla app has a master password set, we prompt for
it. This prompt must be clear we are asking for the master password for
the running Mozilla app (Thunderbird, Firefox, Seamonkey, etc).
 
 
  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:
 
1) 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.
2) 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.
3) run with the legacy database and allow the user to update later.
4) 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 db password, or if we determine we don't need the legacy
db password (either because there isn't one, or because we are willing to loose
the data that was protected by it). We need to acquire the shared db's
password so we can encrypt and mac the data properly. If the shared db doesn't
have a password we can proceed with the update without further prompting the
user. If the shared db has the same password as the legacy db, then we can
detect that and again proceed with the update without further prompting.
 
If both of these fail, we prompt for the password for the shared database. This
prompt is trickier, because we need to ask the user for the password that
he percieves to be the Master password for a different mozilla app. Note: at
this point we are in a pretty uncommon corner case. Most users will not have
different Master passwords for both Thunderbird and Firefox, for instance.
However if we do arrive at this case, it is highly likely the user is not an
experienced/informed user, so we need to treat this case carefully.
 
If we get the password, we complete the update as planned.
 
 
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 shared database, but does not
know what that master password is, we now have the following choices:
 
1) eshew any private keys, secret keys and trust updates from the
legacy database.
2) reset the password on the shared database (loosing all private and secret
keys, possibly loosing some trust).
3) run with the legacy database and allow the user to update later.
4) run with the new shared database and allow the user to update later.
 
It seems pretty unlikely that the user truly does not know the shared 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).
 
 
Profile issues.
 
Mozilla apps can create more than one profile. Developers use this capability
to test bugs that new users are likely to run into without loosing their own
production evironment.
 
Shared databases, in general, means that some of the current semantics of user
profiles will break. Creating a new profile will not create a new
key/cert/master password profile. For developers (the primary users of profiles)
it seems importan to preserve some of the existing semantics. I can see a
couple of options.
 
 
1) Allow profiles to be marked with 'private key/cert DB's. This will change
The Mozilla app from a Mode 3A app to a Mode 2A app. This will return
developers to their previous semantic if they want, while allowing them to
also test the interaction of different profiles and the same database. It would
require UI changes to the profile manager, and it will require action on the
part of the developer to get back to the old semantic.
 
2) Treat only the default profile as Mode 3A and all other profiles as Mode 2A.
This will allow profile separation to operate as is today with no changes. It
does mean, however, that only default profiles will share keys with
appllication.
 
3) Provide the checkbox in option 1, but make it default as in option 2.
 
I think option 3 probably provides the best solution for all worlds.


==== Layering ====
==== Layering ====
439

edits

Navigation menu