You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by "C. Michael Pilato" <cm...@collab.net> on 2012/04/06 00:38:37 UTC

Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

[ The following is pretty much stream-of-consciousness.  Quite honestly,   ]
[ if I could organize my thoughts well enough to craft a better email, I'd ]
[ probably not feel the need to write the mail so badly!                   ]

On the trunk, I have -- with vast amounts of help from gstein and danielsh
-- implemented some routines for using a so-called master passphrase (see
http://wiki.apache.org/subversion/MasterPassphrase) to encrypt and decrypt
an arbitrary string of text, ostensibly a Subversion server password.  I'll
not claim that these functions would pass a security review -- in fact, I
would welcome as many eyes as possible on libsvn_subr/crypto.[ch]!  But they
"work", at least enough to start wrapping other code around.

Now I find myself trying to figure out how to best wrap code around them.

Originally, I thought that I'd need a suite of "svn.masterpassphrase"
providers -- siblings to the "svn.simple", "svn.username",
"svn.ssl.client-cert" and "svn.ssl.client-passphrase" providers we already
offer -- whose job it was to fetch/store the master passphrase from various
OS-provided keyings or from the user (via prompt).  But this seems wrong.
The existing providers plug into a collection thereof used by consumers
outside of libsvn_subr (such as the RA layer) to fetch network credentials.
 This ain't that kind of provider -- the master passphrase is an entirely
system-local concept, the knowledge of which is really only required by the
auth system itself (or specific providers within that system, depending on
how we implement things).

So, fine.  The master passphrase stuff isn't a true svn_auth_provider_t.
What is it, then?  Some new provider-like thing that's simpler (only fetches
and stores a single string, after all, not a whole set of various credential
pieces) and private?

Elsebrain, I'm looking at the existing auth provider code and hearing voices
in my head, echoes of recent IRC conversations:

   "Our authn provider system is overly complex and needs a rewrite."

   "It's silly that every time we add a new caching store, we have to
    implement N differing provider flavors of it to cover all the cases."

   "Our auth cache storage layer needs a rewrite."

I fully agree with these statements, but want to be careful not to find
myself rewriting Subversion just to implement one feature, you know?

I've been also frustrated when considering the situation that occurs when a
user changes his/her master password, forcing a re-encryption of all cached
credentials using the new password.  The existing storage framework is a
bunch of little files -- I've had as many as 50 of these things at times in
my ~/.subversion/auth/ area.  You'd really, really like to make a sweeping
change such as a re-encryption of all cached passwords transactionally, not
leaving half the credentials encrypted with an old passphrase if something
goes wrong midstream.  And for compatibility reasons, I really need to
introduce brand new storage for this encrypted stuff anyway so new and old
clients can co-exist on the same machine without trampling each other's
(shared) runtime configuration directory.

It would seem, then, that now *is* a good time to revisit at least the
storage aspect of our authn subsystem, moving to SQLite's ACID goodness.
I've taken a bit of a look-see at the existing storage, capturing my
findings thus far at
http://wiki.apache.org/subversion/AuthenticationCredentialCacheStorageOverhaul,
and trying to find some commonality that would make for a decent DB schema.

So.  Wow.

Is there anyone who is game for helping me tackle a new design for our
client-side authn cache using SQLite?

Should we also, then, attempt to redesign the whole of the auth provider
system?  If not, any suggestions on where the master passphrase fetch/store
bits might best fit in?

If "yes" on redesigning the auth subsystem, can the new hotness be
introduced via private APIs instead of public ones?  (I'm not quite sure why
the current stuff is part of the public Subversion API anyway, unless it's
just because way back then, we just didn't *do* "private-yet-exported
APIs".)  I mean, do third-party clients really need to pick and choose which
providers they want to use?

Sorry.  I know the above reads like a train wreck of thought.  That's what
I've got to offer right now.

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Branko Čibej <br...@apache.org>.
On 06.04.2012 01:10, Daniel Shahaf wrote:
> C. Michael Pilato wrote on Thu, Apr 05, 2012 at 18:38:37 -0400:
>> Is there anyone who is game for helping me tackle a new design for our
>> client-side authn cache using SQLite?
>>
> * danielsh raises hand

I can also offer ... ah, constructive criticism? Does "I told you so"
count as such? :)

-- Brane


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Daniel Shahaf <da...@elego.de>.
C. Michael Pilato wrote on Thu, Apr 05, 2012 at 18:38:37 -0400:
> Is there anyone who is game for helping me tackle a new design for our
> client-side authn cache using SQLite?
> 

* danielsh raises hand

> Should we also, then, attempt to redesign the whole of the auth provider
> system?  If not, any suggestions on where the master passphrase fetch/store
> bits might best fit in?
> 

I don't have any good ideas here offhand, but I'll think about it
(after I digest the rest of your email).

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Branko Čibej <br...@apache.org>.
On 06.04.2012 17:07, C. Michael Pilato wrote:
> On 04/06/2012 11:02 AM, Branko Čibej wrote:
>>> *sigh*  I hadn't considered stale, compromised data not yet purged or
>>> overwritten.  Does SQLite's VACUUM statement help with this problem?
>>> http://sqlite.org/lang_vacuum.html
>> Vacuum will reorder the pages in the file to fill holes, but will then
>> truncate the database file without first overwriting it with random
>> crud. So, no, that's not good enough.
> Hrm.  Given the statements that the "VACUUM command rebuilds the entire
> database" and that the "VACUUM command works by copying the contents of the
> database into a temporary database file and then overwriting the original
> with the contents of the temporary file", I would have expected better.

That's actually even worse, "overwriting the original" most likely means
it does a FS-level rename, this leaving the /entire/ contents of the
original file on disk. :)

-- Brane


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 04/06/2012 11:02 AM, Branko Čibej wrote:
>> *sigh*  I hadn't considered stale, compromised data not yet purged or
>> overwritten.  Does SQLite's VACUUM statement help with this problem?
>> http://sqlite.org/lang_vacuum.html
> 
> Vacuum will reorder the pages in the file to fill holes, but will then
> truncate the database file without first overwriting it with random
> crud. So, no, that's not good enough.

Hrm.  Given the statements that the "VACUUM command rebuilds the entire
database" and that the "VACUUM command works by copying the contents of the
database into a temporary database file and then overwriting the original
with the contents of the temporary file", I would have expected better.  Are
you sure about this?  (And note that I'm not talking about the auto_vacuum
feature, which apparently works differently.)

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Branko Čibej <br...@apache.org>.
On 06.04.2012 16:13, C. Michael Pilato wrote:
> On 04/06/2012 02:06 AM, Branko Čibej wrote:
>> On 06.04.2012 00:38, C. Michael Pilato wrote:
>>> I've been also frustrated when considering the situation that occurs when a
>>> user changes his/her master password, forcing a re-encryption of all cached
>>> credentials using the new password.
>> You could do what whole-disk encryption systems do: only the encyprtion
>> key is encrypted by the master passphrase, actual data are encrypted by
>> that key. This allows different users with different passphrases to
>> decrypt the same data, since they only decrypt a wrapped copy of the
>> same encryption key.
>>
>> In other words, changing the master passphrase only requires decrypting
>> and re-encrypting one 256-bit encryption key, not the whole credentials
>> store.
> That's a neat concept.  I presume that the encryption key is just some
> random data (since the user never needs to know it)?

Yup. You want to generate that with a crypto-grade random generator, of
coruse. Another bit that you do not want to reinvent. OpenSSL can do
that for you, for example; any sane crypto package will have an API that
generates good random bits for symmetric keys.

>>> Is there anyone who is game for helping me tackle a new design for our
>>> client-side authn cache using SQLite?
>> This makes me wonder if we couldn't perhaps keep the whole thing as an
>> in-memory-not-disk-backed SQLite database, then encrypt and dump the
>> whole SQLite memory snapshot to disk. The real trouble with that
>> approach is that debugging the database using the SQLite command-line
>> tools would be impossible, everything would have to happen through the
>> SVN API.
>>
>> (The point here is that, in this way, we could "easily" atomically
>> re-encrypt everything with a new master passphrase, as opposed to doing
>> it transactionally within an ordinary SQLite database -- because we
>> don't have control over what SQLite does with the free space in the
>> file, and it'd be really, really bad if snippets of data that had been
>> encrypted by the old, presumably compromised, passphrase ended up
>> sitting around on disk.)
> *sigh*  I hadn't considered stale, compromised data not yet purged or
> overwritten.  Does SQLite's VACUUM statement help with this problem?
> http://sqlite.org/lang_vacuum.html

Vacuum will reorder the pages in the file to fill holes, but will then
truncate the database file without first overwriting it with random
crud. So, no, that's not good enough.

-- Brane

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 04/06/2012 02:06 AM, Branko Čibej wrote:
> On 06.04.2012 00:38, C. Michael Pilato wrote:
>> I've been also frustrated when considering the situation that occurs when a
>> user changes his/her master password, forcing a re-encryption of all cached
>> credentials using the new password.
> 
> You could do what whole-disk encryption systems do: only the encyprtion
> key is encrypted by the master passphrase, actual data are encrypted by
> that key. This allows different users with different passphrases to
> decrypt the same data, since they only decrypt a wrapped copy of the
> same encryption key.
> 
> In other words, changing the master passphrase only requires decrypting
> and re-encrypting one 256-bit encryption key, not the whole credentials
> store.

That's a neat concept.  I presume that the encryption key is just some
random data (since the user never needs to know it)?

>> Is there anyone who is game for helping me tackle a new design for our
>> client-side authn cache using SQLite?
> 
> This makes me wonder if we couldn't perhaps keep the whole thing as an
> in-memory-not-disk-backed SQLite database, then encrypt and dump the
> whole SQLite memory snapshot to disk. The real trouble with that
> approach is that debugging the database using the SQLite command-line
> tools would be impossible, everything would have to happen through the
> SVN API.
> 
> (The point here is that, in this way, we could "easily" atomically
> re-encrypt everything with a new master passphrase, as opposed to doing
> it transactionally within an ordinary SQLite database -- because we
> don't have control over what SQLite does with the free space in the
> file, and it'd be really, really bad if snippets of data that had been
> encrypted by the old, presumably compromised, passphrase ended up
> sitting around on disk.)

*sigh*  I hadn't considered stale, compromised data not yet purged or
overwritten.  Does SQLite's VACUUM statement help with this problem?
http://sqlite.org/lang_vacuum.html

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Greg Hudson <gh...@MIT.EDU>.
On 04/06/2012 10:47 AM, Greg Stein wrote:
> Correct. Still useful, but even if memory is compromised, the SHA1 is
> not reversible. The original MP cannot be recovered for other uses.

Just as a reminder, SHA-1 is not recommended for use in new applications
at this time (http://csrc.nist.gov/groups/ST/hash/policy.html).

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Greg Stein <gs...@gmail.com>.
On Apr 6, 2012 10:36 AM, "C. Michael Pilato" <cm...@collab.net> wrote:
>
> On 04/06/2012 04:22 AM, Greg Stein wrote:
> > Yeah, I switched the master passphrase param to an svn_string_t on the
> > probable outcome that we would immediately SHA1 the thing, and then use
the
> > resulting hash as the nominal password. That would avoid having the
> > plaintext in memory (and yes, I recognize it is quite possible that
other
> > copies exist; gotta start somewhere, and provide a data flow that
avoids the
> > requirement of plaintext).
>
> To be clear, Greg, you're talking about something a little bit than
Brane's
> "whole-disk encryption via encrypted keys" approach, right?  IIUC, you're
> saying that we'll simply SHA1 the user-provided password plaintext master
> passphrase for the purpose of not holding that passphrase in memory.  It's
> sha1(MP), then, that is the secret in our encryption/decryption steps.
>
> I'm not quite sure how this helps with the situation Brane has raised --
> we'll still be holding the actual encryption secret in memory, it just now
> looks less like a human-readable passphrase.  But maybe that's the
critical
> difference?

Correct. Still useful, but even if memory is compromised, the SHA1 is not
reversible. The original MP cannot be recovered for other uses.

Cheers,
-g

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by "C. Michael Pilato" <cm...@collab.net>.
On 04/06/2012 04:22 AM, Greg Stein wrote:
> Yeah, I switched the master passphrase param to an svn_string_t on the
> probable outcome that we would immediately SHA1 the thing, and then use the
> resulting hash as the nominal password. That would avoid having the
> plaintext in memory (and yes, I recognize it is quite possible that other
> copies exist; gotta start somewhere, and provide a data flow that avoids the
> requirement of plaintext).

To be clear, Greg, you're talking about something a little bit than Brane's
"whole-disk encryption via encrypted keys" approach, right?  IIUC, you're
saying that we'll simply SHA1 the user-provided password plaintext master
passphrase for the purpose of not holding that passphrase in memory.  It's
sha1(MP), then, that is the secret in our encryption/decryption steps.

I'm not quite sure how this helps with the situation Brane has raised --
we'll still be holding the actual encryption secret in memory, it just now
looks less like a human-readable passphrase.  But maybe that's the critical
difference?

-- 
C. Michael Pilato <cm...@collab.net>
CollabNet   <>   www.collab.net   <>   Distributed Development On Demand


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Greg Stein <gs...@gmail.com>.
On Apr 6, 2012 3:58 AM, "Branko Čibej" <br...@apache.org> wrote:
>
> On 06.04.2012 09:51, Daniel Shahaf wrote:
> > Branko Čibej wrote on Fri, Apr 06, 2012 at 08:06:32 +0200:
> >> This makes me wonder if we couldn't perhaps keep the whole thing as an
> >> in-memory-not-disk-backed SQLite database, then encrypt and dump the
> >> whole SQLite memory snapshot to disk. The real trouble with that
> >> approach is that debugging the database using the SQLite command-line
> >> tools would be impossible, everything would have to happen through the
> >> SVN API.
> > Presumably we'd write a tools/dev/ helper that decrypts the memory
> > snapshot and dumps it to an on-disk SQLite db?
>
> This really has other problems, too. Actually, /any/ passphrase-based
> system we use has it: "in-memory" does not, by itself, imply that the
> unencrypted data never end up on disk. At the very least, the
> unencrypted bits need to be stored in locked, access-protected memory,
> so that they don't get swapped out and can't be accessed by (non-root)
> users.
>
> OS-provided password storage systems typically already account for this.
> And, whilst Subversion doesn't take these precautions with individual
> passwords, a passphrase that protects a number of different credentials
> needs more attention to preventing plaintext leaks.

Yeah, I switched the master passphrase param to an svn_string_t on the
probable outcome that we would immediately SHA1 the thing, and then use the
resulting hash as the nominal password. That would avoid having the
plaintext in memory (and yes, I recognize it is quite possible that other
copies exist; gotta start somewhere, and provide a data flow that avoids
the requirement of plaintext).

Cheers,
-g

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Branko Čibej <br...@apache.org>.
On 06.04.2012 09:51, Daniel Shahaf wrote:
> Branko Čibej wrote on Fri, Apr 06, 2012 at 08:06:32 +0200:
>> This makes me wonder if we couldn't perhaps keep the whole thing as an
>> in-memory-not-disk-backed SQLite database, then encrypt and dump the
>> whole SQLite memory snapshot to disk. The real trouble with that
>> approach is that debugging the database using the SQLite command-line
>> tools would be impossible, everything would have to happen through the
>> SVN API.
> Presumably we'd write a tools/dev/ helper that decrypts the memory
> snapshot and dumps it to an on-disk SQLite db?

This really has other problems, too. Actually, /any/ passphrase-based
system we use has it: "in-memory" does not, by itself, imply that the
unencrypted data never end up on disk. At the very least, the
unencrypted bits need to be stored in locked, access-protected memory,
so that they don't get swapped out and can't be accessed by (non-root)
users.

OS-provided password storage systems typically already account for this.
And, whilst Subversion doesn't take these precautions with individual
passwords, a passphrase that protects a number of different credentials
needs more attention to preventing plaintext leaks.

-- Brane

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Daniel Shahaf <da...@elego.de>.
Branko Čibej wrote on Fri, Apr 06, 2012 at 08:06:32 +0200:
> This makes me wonder if we couldn't perhaps keep the whole thing as an
> in-memory-not-disk-backed SQLite database, then encrypt and dump the
> whole SQLite memory snapshot to disk. The real trouble with that
> approach is that debugging the database using the SQLite command-line
> tools would be impossible, everything would have to happen through the
> SVN API.

Presumably we'd write a tools/dev/ helper that decrypts the memory
snapshot and dumps it to an on-disk SQLite db?

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Greg Hudson <gh...@MIT.EDU>.
On 04/06/2012 01:44 PM, Justin Erenkrantz wrote:
> On Fri, Apr 6, 2012 at 8:09 AM, Greg Hudson <gh...@mit.edu> wrote:
>> I also want to caution that PBKDF2 does not provide strong protection
>> against offline dictionary attacks.  Most cryptographic methods provide
>> exponential protection--I do a little bit more work to make you do twice
>> as much work.  PBKDF2 provides only linear protection--I do twice as
>> much work to make you do twice as much work.  It does not make
>> dictionary attacks "impossible" in the same sense that AES-128 makes
>> decryption without knowing the key "impossible".
> 
> Is it worth looking at scrypt[1] instead of PBKDF2?  -- justin

Possibly.  It depends on whether you care about things like NIST review
(PBKDF2 is recommended in NIST SP 800-132) versus the theoretical
advantages of a less heavily scrutinized algorithm.  That's always a
tough choice.

The fundamental nature of scrypt isn't different from the fundamental
nature of PBKDF2; both seek to add a fixed multiplier to the cost of
both the legitimate user and the attacker.  scrypt is designed to make
it more difficult to use massively parallel hardware to mount the
attack, by requiring more memory (if I skimmed the paper correctly).

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
On Fri, Apr 6, 2012 at 8:09 AM, Greg Hudson <gh...@mit.edu> wrote:
> I also want to caution that PBKDF2 does not provide strong protection
> against offline dictionary attacks.  Most cryptographic methods provide
> exponential protection--I do a little bit more work to make you do twice
> as much work.  PBKDF2 provides only linear protection--I do twice as
> much work to make you do twice as much work.  It does not make
> dictionary attacks "impossible" in the same sense that AES-128 makes
> decryption without knowing the key "impossible".

Is it worth looking at scrypt[1] instead of PBKDF2?  -- justin

1. http://www.tarsnap.com/scrypt.html

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Greg Hudson <gh...@MIT.EDU>.
On 04/06/2012 10:55 AM, Greg Stein wrote:
>> In other words, changing the master passphrase only requires decrypting
>> and re-encrypting one 256-bit encryption key, not the whole credentials
>> store.

> PKBDF2 is in the current design to make dict attacks computationally
> "impossible". Assuming we keep that, then the above value would be fed
> in as the secret to PKBDF2, rather than MP or sha1(MP) ?

If I understand you correctly, that wouldn't make sense.  PBKDF2 is
designed to provide some resistance against offline dictionary attacks
against a weak secret, at the cost of computational power for legitimate
users.  If you have a strong secret, there's no point in running it
through PBKDF2.

Under the suggested architecture, you'd use PBKDF2(MP) to decrypt the
master key, and then use the master key to decrypt the individual passwords.

I also want to caution that PBKDF2 does not provide strong protection
against offline dictionary attacks.  Most cryptographic methods provide
exponential protection--I do a little bit more work to make you do twice
as much work.  PBKDF2 provides only linear protection--I do twice as
much work to make you do twice as much work.  It does not make
dictionary attacks "impossible" in the same sense that AES-128 makes
decryption without knowing the key "impossible".

If a system can be designed to prevent offline dictionary attacks
entirely, that's much better.  But for this application, that's probably
impossible, since it's easy to distinguish a valid result (a password,
which will be printable ASCII) from garbage.

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Branko Čibej <br...@apache.org>.
On 06.04.2012 16:55, Greg Stein wrote:
> On Apr 6, 2012 2:06 AM, "Branko Čibej" <br...@apache.org> wrote:
>> On 06.04.2012 00:38, C. Michael Pilato wrote:
>>> I've been also frustrated when considering the situation that occurs
> when a
>>> user changes his/her master password, forcing a re-encryption of all
> cached
>>> credentials using the new password.
>> You could do what whole-disk encryption systems do: only the encyprtion
>> key is encrypted by the master passphrase, actual data are encrypted by
>> that key. This allows different users with different passphrases to
>> decrypt the same data, since they only decrypt a wrapped copy of the
>> same encryption key.
>>
>> In other words, changing the master passphrase only requires decrypting
>> and re-encrypting one 256-bit encryption key, not the whole credentials
>> store.
> PKBDF2 is in the current design to make dict attacks computationally
> "impossible". Assuming we keep that, then the above value would be fed in
> as the secret to PKBDF2, rather than MP or sha1(MP) ?

That's the idea, yes.

-- Brane


Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Greg Stein <gs...@gmail.com>.
On Apr 6, 2012 2:06 AM, "Branko Čibej" <br...@apache.org> wrote:
>
> On 06.04.2012 00:38, C. Michael Pilato wrote:
> > I've been also frustrated when considering the situation that occurs
when a
> > user changes his/her master password, forcing a re-encryption of all
cached
> > credentials using the new password.
>
> You could do what whole-disk encryption systems do: only the encyprtion
> key is encrypted by the master passphrase, actual data are encrypted by
> that key. This allows different users with different passphrases to
> decrypt the same data, since they only decrypt a wrapped copy of the
> same encryption key.
>
> In other words, changing the master passphrase only requires decrypting
> and re-encrypting one 256-bit encryption key, not the whole credentials
> store.

PKBDF2 is in the current design to make dict attacks computationally
"impossible". Assuming we keep that, then the above value would be fed in
as the secret to PKBDF2, rather than MP or sha1(MP) ?

Cheers,
-g

Re: Master passphrase approach, authn storage, cobwebs in C-Mike's head, ...

Posted by Branko Čibej <br...@apache.org>.
On 06.04.2012 00:38, C. Michael Pilato wrote:
> I've been also frustrated when considering the situation that occurs when a
> user changes his/her master password, forcing a re-encryption of all cached
> credentials using the new password.

You could do what whole-disk encryption systems do: only the encyprtion
key is encrypted by the master passphrase, actual data are encrypted by
that key. This allows different users with different passphrases to
decrypt the same data, since they only decrypt a wrapped copy of the
same encryption key.

In other words, changing the master passphrase only requires decrypting
and re-encrypting one 256-bit encryption key, not the whole credentials
store.

> So.  Wow.
>
> Is there anyone who is game for helping me tackle a new design for our
> client-side authn cache using SQLite?

This makes me wonder if we couldn't perhaps keep the whole thing as an
in-memory-not-disk-backed SQLite database, then encrypt and dump the
whole SQLite memory snapshot to disk. The real trouble with that
approach is that debugging the database using the SQLite command-line
tools would be impossible, everything would have to happen through the
SVN API.

(The point here is that, in this way, we could "easily" atomically
re-encrypt everything with a new master passphrase, as opposed to doing
it transactionally within an ordinary SQLite database -- because we
don't have control over what SQLite does with the free space in the
file, and it'd be really, really bad if snippets of data that had been
encrypted by the old, presumably compromised, passphrase ended up
sitting around on disk.)

-- Brane