From bcee82cdde1753650730dda65ff80f9e78e681c2 Mon Sep 17 00:00:00 2001 From: Stefan Tatschner Date: Fri, 29 May 2015 14:20:09 +0200 Subject: [PATCH] Create syncthing-device-ids(7) --- dev/device-ids.rst | 118 ++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/dev/device-ids.rst b/dev/device-ids.rst index 7c9197e62..6912586f2 100644 --- a/dev/device-ids.rst +++ b/dev/device-ids.rst @@ -1,28 +1,28 @@ -######################## Understanding Device IDs -######################## +======================== -Every device is identified by a device ID. The device ID is used for -address resolution, authentication and authorization. The term "device -ID" could interchangably have been "key ID" since the device ID is a -direct properties of the public key in use. +Description +----------- + +Every device is identified by a device ID. The device ID is used for address +resolution, authentication and authorization. The term "device ID" could +interchangably have been "key ID" since the device ID is a direct properties of +the public key in use. Keys -==== +---- -To understand device IDs we need to look at the underlying mechanisms. -At first startup, Syncthing will create an public/private key pair. +To understand device IDs we need to look at the underlying mechanisms. At first +startup, Syncthing will create an public/private key pair. -Currently this is a 3072 bit RSA key. The keys are saved in the form of -the private key (``key.pem``) and a self signed certificate -(``cert.pem``). The self signing part doesn't actually add any security -or functionality as far as Syncthing is concerned but it enables the use -of the keys in a standard TLS exchange. +Currently this is a 3072 bit RSA key. The keys are saved in the form of the +private key (``key.pem``) and a self signed certificate (``cert.pem``). The self +signing part doesn't actually add any security or functionality as far as +Syncthing is concerned but it enables the use of the keys in a standard TLS +exchange. The typical certificate will look something like this, inspected with -``openssl x509``: - -:: +``openssl x509``:: Certificate: Data: @@ -58,28 +58,26 @@ The typical certificate will look something like this, inspected with 88:7e:e2:61:aa:4c:02:e3:64:b0:da:70:3a:cd:1c:3d:86:db: df:54:b9:4e:be:1b -We can see here that the certificate is little more than a container for -the public key; the serial number is zero and the Issuer and Subject are -both "syncthing" where a qualified name might otherwise be expected. +We can see here that the certificate is little more than a container for the +public key; the serial number is zero and the Issuer and Subject are both +"syncthing" where a qualified name might otherwise be expected. -An advanced user could replace the ``key.pem`` and ``cert.pem`` files -with a keypair generated directly by the ``openssl`` utility or other -mechanism. +An advanced user could replace the ``key.pem`` and ``cert.pem`` files with a +keypair generated directly by the ``openssl`` utility or other mechanism. Device IDs -========== +---------- -To form a device ID the SHA-256 hash of the certificate data in DER form -is calculated. This means the hash covers all information under the +To form a device ID the SHA-256 hash of the certificate data in DER form is +calculated. This means the hash covers all information under the ``Certificate:`` section above. -The hashing results in a 256 bit hash, which we encode using base32. -Base32 encodes five bits per character, so we need 256 / 5 = 51.2 -characters to encode the device ID. This becomes 52 characters in -practice, but 52 characters of base32 would decode to 260 bits which is -not an whole number of bytes. The base32 encoding adds padding to 280 -bits (the next multiple of both 5 and 8 bits) so the resulting ID looks -something like +The hashing results in a 256 bit hash, which we encode using base32. Base32 +encodes five bits per character, so we need 256 / 5 = 51.2 characters to encode +the device ID. This becomes 52 characters in practice, but 52 characters of +base32 would decode to 260 bits which is not an whole number of bytes. The +base32 encoding adds padding to 280 bits (the next multiple of both 5 and 8 +bits) so the resulting ID looks something like ``MFZWI3DBONSGYYLTMRWGC43ENRQXGZDMMFZWI3DBONSGYYLTMRWA====``. The padding (``====``) is stripped away, the device ID split in four @@ -90,13 +88,12 @@ grouped with dashes, resulting in the final value: ``MFZWI3D-BONSGYC-YLTMRWG-C43ENR5 -QXGZDMM-FZWI3DP-BONSGYY-LTMRWAD``. Connection Establishment -======================== +~~~~~~~~~~~~~~~~~~~~~~~~ -So now we know what device IDs are, here's how they are used in -Syncthing. When you add a device ID to the syncthing configuration, -Syncthing will attempt to connect to that device. The first thing we -need to do is figure out the IP and port to connect to. There's three -possibilities here; +So now we know what device IDs are, here's how they are used in Syncthing. When +you add a device ID to the syncthing configuration, Syncthing will attempt to +connect to that device. The first thing we need to do is figure out the IP and +port to connect to. There's three possibilities here; - The IP and port can be set statically in the configuration. The IP can equally well be a hostname, so if you have a static IP or a @@ -114,10 +111,10 @@ possibilities here; any local announcements the global discovery server will be queried for an address. -Once we have and address and port a TCP connection is established and a -TLS handshake performed. As part of the handshake both devices present -their certificates. Once the handshake has completed and the peer -certificate is known, the following steps are performed. +Once we have and address and port a TCP connection is established and a TLS +handshake performed. As part of the handshake both devices present their +certificates. Once the handshake has completed and the peer certificate is +known, the following steps are performed. #. Calculate the remote device ID by using the process above on the received certificate. @@ -169,27 +166,26 @@ here: more probable than the SHA-256 collision. Briefly stated, if you find SHA-256 collisions scary then your priorities are wrong. -It's also worth noting that the property of SHA-256 that we are using is -not simply collision resistance but resistance to a preimage attack. -I.e. even if you can find two messages that result in a hash collision -that doesn't help you attack Syncthing (or TLS in general). You need to -create a message that hashes to exactly the hash that my certificate -already has or you won't get in. +It's also worth noting that the property of SHA-256 that we are using is not +simply collision resistance but resistance to a preimage attack. I.e. even if +you can find two messages that result in a hash collision that doesn't help you +attack Syncthing (or TLS in general). You need to create a message that hashes +to exactly the hash that my certificate already has or you won't get in. -Note also that it's not good enough to find a random blob of bits that -happen to have the same hash as my certificate. You need to create a -valid DER- encoded, signed certificate that has the same hash as mine. -The difficulty of this is staggeringly far beyond the already staggering -difficulty of finding a SHA-256 collision. +Note also that it's not good enough to find a random blob of bits that happen to +have the same hash as my certificate. You need to create a valid DER- encoded, +signed certificate that has the same hash as mine. The difficulty of this is +staggeringly far beyond the already staggering difficulty of finding a SHA-256 +collision. Problems and Vulnerabilities -============================ +---------------------------- As far as I know, these are the issues or potential issues with the above mechanism. Discovery Spoofing ------------------- +~~~~~~~~~~~~~~~~~~ Currently, neither the local nor global discovery mechanism is protected by crypto. This means that any device can in theory announce itself for @@ -217,13 +213,13 @@ It's something we might want to look at at some point, but not a huge problem as I see it. Long Device IDs are Painful ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It's a mouthful to read over the phone, annoying to type into an SMS or -even into a computer. And it needs to be done twice, once for each side. +It's a mouthful to read over the phone, annoying to type into an SMS or even +into a computer. And it needs to be done twice, once for each side. -This isn't a vulnerability as such, but a user experience problem. There -are various possible solutions; +This isn't a vulnerability as such, but a user experience problem. There are +various possible solutions: - Use shorter device IDs with verification based on the full ID ("You entered MFZWI3; I found and connected to a device with the ID