Ophite

KEYP - KeyPrint (Draft Proposal)

18 posts in this topic

(Also known as project Pavlova. This is only a draft write-up; a request for comments, if you will.

I hope to present patches implementing this proposal for Apex soon in the hope that this can appear in a version in the near future, and to submit it as a patch for StrongDC and for vanilla DC++, as well as an official ADC extension. -O1)

KEYP - KeyPrint, fingerprint-based TLS authentication for adcs: (Draft)

1. Synopsis

This extension adds a simple, but secure way to protect against man-in-the-middle attacks against ADC when wrapped with TLS (1.0 or later). It does not require setting up a CA or signing keys, but you still can if you want to.

Specifically, we introduce a "KeyPrint" - the hash of either the certificate signing the server certificate (in a CA-style key-signing configuration) or, simply, the server certificate itself (in a self-signed configuration).

We add this KeyPrint (or simply, KP) to the hub's adcs: URL in a URL-parameter, so that any attempted certificate substitution attack on a TLS hub connection to the hub will be detected.

Additionally, clients should publish their own certificates' KeyPrint in a "KP" string in the ADC "INF" broadcast. Assuming one trusts the hub enough not to maliciously change the KeyPrints en route (a reasonable assumption given the hub's existing position of trust), and given that the connection to the hub has been similarly authenticated (either as above or via a directly downloaded trusted certificate), client-client connections are also protected against attempted man-in-the-middle attacks - without messing around having to get everyone's certificates signed in advance.

2. KeyPrint Specification

2.1. A KeyPrint consists of a hash name, followed by a / (forward slash), followed by a base32-encoded cryptographic hash of either the certificate directly (which is appropriate in the case of a self-signed certificate), or a certificate providing the base of a valid signature chain (which may be more appropriate a CA-signed certificate).

2.2. It is suggested that TTH, which is the Tiger Tree Hash exactly as defined in the [TIGR] extension to ADC, be used for this, as it marks a readily-available, convenient, yet secure baseline[1]. We use "TTH" to specify this; again, in the same way it is specified in [TIGR].

2.3. In a secure ADC (adcs:) hub URL, we add the KeyPrint to the URL as a URL parameter named "kp", encoded (for example) as follows:-

adcs://hub.example.com:12345/?kp=TTH/USNVXMWXL5MSQHR4ITYJITVFY75RUGIDCBQ3BZQ

2.4. Clients which have generated a TLS certificate for secure client-client communication (which in this protocol need not be signed, so this should probably be done by default!) should publish their own KeyPrints (as above) as a string field named KP in their INF broadcast to ADC hubs.

2.5. If a client receives a KP field in an FINF broadcast via a hub to it is connected using adcs: and a trusted key as above (or otherwise), it should be regarded as the valid and correct KeyPrint for that client's IP/port/hub combination, replacing any earlier KeyPrint for that IP/port/hub combination.

3. KeyPrint Verification

3.1. When initiating a TLS handshake with a remote host where we know their KeyPrint, we can verify that a man-in-the-middle attack is not occurring by checking if the hash given in the KeyPrint matches exactly:

  • a root certificate presented in a valid signature chain which covers the certificate presented during the handshake by the remote host; or
  • the entire certificate presented during the handshake by the remote host.

3.2. If we know a remote host's KeyPrint, and in connecting to that remote host, we are presented with a certificate which does not match, and which also does not have form the root of a valid signature chain covering that certificate: then we have detected a certificate substitution attack and we MUST abort the connection with a user-visible, non-modal error stating, for example "Crypto error: Detected attempted man-in-the-middle attack, aborting". (This error quite possibly represents a real attempted attack that has been foiled; we may try auto-reconnecting but we should NEVER ignore it, or it will succeed. We may wish to avoid stating the KeyPrint of the certificate that was actually received)

3.3. Optionally, when receiving a TLS handshake, if we know what the remote host's KeyPrint ought to be, we could also verify this, though it is pointed out that only the initiating side needs to check this for the man-in-the-middle protection to be valid; specifically the hub doesn't need to remember, or even understand, clients' KeyPrints.

4. Security Considerations

4.1. Client-Hub

4.1.1. The KeyPrint in the adcs: url prevents a clandestine man-in-the-middle (certificate substitution) attack on the TLS session with the hub, if and only if the kp parameter hasn't been modified by an attacker.

4.1.2. Suggested countermeasures against this include the following:-

4.1.2.1. Even if otherwise unprotected, an attacker would likely only have a maximum of one opportunity to make the substitution (by changing the kp parameter when the URL is first sent to the user); if it's changed later, it will be detected. ("Casual first-use" security, as often used in SSH.)

4.1.2.2. Checking the fingerprint or transferring the hub URL out-of-band (for example by telephone, or in person) could reveal or thwart man-in-the-middle attacks; something's wrong if you don't have the same URL as the hub operator gives out. (PGP-style "sneakernet" security.)

4.1.2.3. We would be protected if the URL were in a file signed by some secure means by a party we have already decided we trust not to change the URLs maliciously. Encryption would not be necessary, only a signature to ensure no untrusted party has modified the KP fields. (A signed hublist, possibly.)

4.1.2.4. Finally, we would be protected were the hublist/URL retrieved from an https: site signed by a CA we trust not to issue signatures for any domain to someone who doesn't own that domain, and the owner of that domain trusted not to modify the KP fields. (SSL-style security.)

4.2. Client-Client

4.2.1. We are, in particular, trusting the hub not to maliciously modify the KP fields sent by the clients through their TINF broadcasts. However:-

  • the hub would gain nothing from swapping the KeyPrints of its users, as it would not gain anything from mounting a man-in-the-middle attack on its own users that it does not already have the ability to do, as it's the hub; and
  • if we do not trust them enough not to maliciously modify the data, why are we choosing to connect to them and transmit our IP address through them?
  • it could be detected by cross-checking with other clients/hubs, as connecting through a malicious hub would clearly show you to have a different KeyPrint to any other hub; therefore any hub doing this would obviously be quickly removed from hublists.

4.3. General

4.3.1. The certificates, including the name fields, are sent in the clear during the initial handshake. Therefore it is recommended to avoid identifying marks in the certificates CommonName fields (for example) that would clearly single them out as being TLS keys used by adcs:, and the CID field most definitely should not appear. Quite possibly no name fields should appear, or they should be blank.

Bibliography:

[TIGR] - ADC specification, §7.1 - TIGR - Tiger tree hash support: http://adc.sourceforge.net/ADC.html#_tigr_...ee_hash_support

Footnotes:

[1] Regarding the choice of TTH as a baseline hash; it is both convenient - being already present in the TIGR extension and in practice available in all ADC clients - and not insecure - having no known practical second-preimage attacks. It is most certainly not weaker than MD5 or SHA-1, which are often widely used elsewhere in TLS/SSL.

We note further that if a problem arose, then as with the rest of ADC, we could switch to another hash such as SHA-256, or a future SHA-3 algorithm.

Share this post


Link to post
Share on other sites

Two things:

  • Regarding 4.1.2.4, does that mean the hublist location on the net requires SSL certification?
  • Performance wise, are hub hosts going to see a considerable increase in cpu/memory usage for this process?

Share this post


Link to post
Share on other sites

It would be very useful if example connection sequence (displaying protocol commands etc.) for client to hub (as well as client to client) connection could be provided to accompany this draft.

Share this post


Link to post
Share on other sites

Thanks for the comments so far. I'll try to address them as we go and work out any kinks in this.

Two things:

  • Regarding 4.1.2.4, does that mean the hublist location on the net requires SSL certification?

That's what 4.1.2.4 suggests

Share this post


Link to post
Share on other sites

It would be very useful if example connection sequence (displaying protocol commands etc.) for client to hub (as well as client to client) connection could be provided to accompany this draft.

I'll flesh it out a bit more later.

In particular we probably want to avoid agreeing known-weak algorithms in the TLS handshake (the ancient 40-bit "export" algorithms are definitely out-of-bounds, but though I will explicitly check, I wouldn't be surprised if avoiding all that is OpenSSL's default behaviour).

Basically, the hub implements a perfectly normal SSL (well, TLS) listener using, for example, OpenSSL. This could be as well as or instead of the unencrypted port; it'd make a lot more sense to have it on a different port and we're probably better off, in the light of "traffic management" problems, not specifying a default port and allowing hub admins free reign in that.

The only new parts are:

  • A KEYP field added to the TSUP, indicating we support this. (Do we even need this?)
  • A new KP field (43 bytes payload, 46 bytes total extra) in the TINF broadcasts sent by supporting clients to ADC hubs using encryption they trust. (This would be ignored by any non-supporting clients.)
  • The "kp" parameter, with the hub's keyprint, optionally added to an adcs: URL.

The hub doesn't need any modification in its behaviour whatsoever if it already supports SSL; this is already supported, for example, in luadch/luadchjit which I have been using to test with. By all means track that down if you're curious on how the hub might actually support TLS; it really doesn't need much.

In all respects the TLS connections are entirely normal connections as per the TLS 1.0, 1.1 or 1.2 standards, and this is by design.

The only thing that this proposal affects on top of what already exists is that it provides a mechanism for specifying a hub's trusted certificate fingerprint in the URL, and a client's trusted certificate fingerprint in their KP field, which could be picked up by a client which supports it, and would be happily and freely ignored by any client which doesn't. This seems much easier for the handling of client certificates than a system whereby to be secure you'd have to download the certificate of every client and plonk it in your trusted folder (although if you did do that even with Apex 1.1, I do believe it would work).

The point cologic makes is entirely valid; in theory DC++ can indeed do this already at a basic level. As for the basic point of trust design; indeed, whomever passes around adcs: URLs including a kp parameter would be the point of trust in this scheme (and the hub owners to a certain extent as well).

I contend that an existing trust relationship already exists there, and that it is not inappropriate to extend that to key distribution.

Anyone who uses a hublist or accepts a hub link off someone is already trusting them to give them addresses of hubs, and not Evil Honeypots of Doom

Share this post


Link to post
Share on other sites

DCDev is interested in a public discussion its too bad that admins dont move this thread out so they can join in :)

Share this post


Link to post
Share on other sites

Thank you for your explanation, I have yet to dive in the finer details of ADCS on hub side and how things are exactly done there, so that's why I asked. Though since I am forced to learn java anyways I might take a look at dshub at some point in near or little farther future.

As for SUP entry since it modifies INF fields it is certainly needed in my opinion.

Share this post


Link to post
Share on other sites

I'll move this to public area soon...

I suggest waiting on Ophite1's permission, it's his work. ;)

If agreed, we could make an announcement regarding this newly formed discussion topic to gain some interest.

Share this post


Link to post
Share on other sites

Lee the DCDev team wanna join in the discussion it might be considered as rude not to let them take apart of it since they requested it.. its a draft and why not draft it in the open instead since everyone that matters knows about it and wanna help out with pointers

Share this post


Link to post
Share on other sites

I suggest waiting on Ophite1's permission, it's his work. ;)

I sent a PM asking about that to him yesterday, I have yet to receive any kind of reply... I personally think this was ready for public discussion the moment I read through it the first time since it is obviously well though and written.

Besides he did ask for comments, no? Public discussion obviously has much more to offer in regards to that than discussion in here. What can be said here has been said really. You gave your comments (and received reply) and I found no faults either and, not sure if I posted it here before or just said it while discussing about this with either Toast or Spyke, but I also think of this as a splendid idea and a well written proposal.

Share this post


Link to post
Share on other sites

Lee the DCDev team wanna join in the discussion it might be considered as rude not to let them

It's rude to publish somebody's work if it wasn't intended on being published. ;)

I sent a PM asking about that to him yesterday, I have yet to receive any kind of reply...

So lets wait, and be professional about this.

Share this post


Link to post
Share on other sites

It's rude to publish somebody's work if it wasn't intended on being published. ;)

So lets wait, and be professional about this.

Sorry for being impatient, kinda on edge right now... lot of things going on.

Share this post


Link to post
Share on other sites

It's rude to publish somebody's work if it wasn't intended on being published. ;)

So lets wait, and be professional about this.

IMHO is only dumb to wait since ive already shown DCDev the draft and they are interested in giving help and may i remind lee that if one wants this as an official support ext then its better to have it in the open (if u dont then it will be something just for apex and not support by the rest perhaps i would prefer to see it in all instead)

Share this post


Link to post
Share on other sites

IMHO is only dumb to wait since ive already shown DCDev the draft and they are interested in giving help and may i remind lee that if one wants this as an official support ext then its better to have it in the open (if u dont then it will be something just for apex and not support by the rest perhaps i would prefer to see it in all instead)

I missed your original post, I would have brought it up then. I know your intentions are good by giving this info to the correct people, but you should have waited for permission.

Sorry about the lack of respect for your work Ophite. It's only up to you when this information should be given out. :)

I'd be interested in providing our users with some insight into this new idea, if you want to provide us with a brief explanation of its abilities and I'll include it a possible announcement. Unless you just want me to write about it... I assume you're better at PR ;)

Share this post


Link to post
Share on other sites

It's rude to publish somebody's work if it wasn't intended on being published. ;)

So lets wait, and be professional about this.

Fine with me, go for it.

I'm also wondering about the specific implementation details of the KeyPrint myself; I'm exploring all reasonable options while figuring out what the most elegant implementation of this might be. As per arne's comments, I'm leaning now more towards using the X509_digest() function in OpenSSL with whatever hash we choose (because X.509 has very carefully defined what should and shouldn't get hashed, so getting your cert signed won't break anything, but no-one can try to make your RSA key material into invalid ECDSA key material either).

That said, I'm solidly against using MD5 or SHA-1 for this, they're broken.

But SHA-256 might be convenient to implement, given that it's in OpenSSL already (TTH isn't, though TIGER192 is) and it isn't much longer at all; here's a mockup example:

adcs://hub.example.com:12345/?kp=SHA256/7KGKGB44A5AEPZXTNLVBIAE4HLNVBUO42ONIELL2XYFS4RTPMIYT

And, indeed openssl x509 -noout -fingerprint -sha256 < mykey.crt will output the fingerprint in coloned-hex form; if you converted that to base32 and plonked SHA256/ on the front, that'd be a plausible SHA256 KeyPrint.

I rather like that idea, and how naturally that would fit, and am therefore leaning towards the second draft for KEYP switching to SHA256 instead of TTH as the default, and specifying the KeyPrint broadly as an X.509 fingerprint converted to base32, i.e., encode_base32(X509_digest(key, EVP_sha256(), ...))

Share this post


Link to post
Share on other sites

Since the length difference (ie. added traffic) is reasonable I at least have nothing against using SHA256 :)

Edit: Discussion in public from here on out ;) (as per above post, moved to Client Discussion since I think it fits there slightly better than lounge).

Share this post


Link to post
Share on other sites

I'm also wondering about the specific implementation details of the KeyPrint myself; I'm exploring all reasonable options while figuring out what the most elegant implementation of this might be. As per arne's comments, I'm leaning now more towards using the X509_digest() function in OpenSSL with whatever hash we choose (because X.509 has very carefully defined what should and shouldn't get hashed, so getting your cert signed won't break anything, but no-one can try to make your RSA key material into invalid ECDSA key material either).

That said, I'm solidly against using MD5 or SHA-1 for this, they're broken.

But SHA-256 might be convenient to implement, given that it's in OpenSSL already (TTH isn't, though TIGER192 is) and it isn't much longer at all; here's a mockup example:

adcs://hub.example.com:12345/?kp=SHA256/7KGKGB44A5AEPZXTNLVBIAE4HLNVBUO42ONIELL2XYFS4RTPMIYT

yes this is easier to implement and looks less "home-grown" than using TTH.

very well written proposal! :)

you might want to rephrase some of the "we do this and that"s into "x should do this and that"s, so it sounds less personal and more like a real draft. ;)

Share this post


Link to post
Share on other sites