sblin created page: Technical overview
This commit is contained in:
parent
e09c136796
commit
826f6e5d02
|
@ -0,0 +1,274 @@
|
||||||
|
Concepts
|
||||||
|
========
|
||||||
|
|
||||||
|
Ring Account
|
||||||
|
------------
|
||||||
|
|
||||||
|
- A **Ring account** is defined by a cryptographic Ring Identity based
|
||||||
|
of **RSA asymmetric key-pair** and managed with **x.509
|
||||||
|
certificates** as defined by *[RFC
|
||||||
|
5280](https://tools.ietf.org/html/rfc5280)*.
|
||||||
|
- Ring uses the **gnutls** library to generate and manage RSA keys
|
||||||
|
and certificates.
|
||||||
|
|
||||||
|
### Ring certificate
|
||||||
|
|
||||||
|
- This represents the identify of a Ring user.
|
||||||
|
- Generated at account creation
|
||||||
|
- Contains the Ring account public key.
|
||||||
|
- The SHA-1 fingerprint (160-bits) of this public certificate is the
|
||||||
|
**RingId**.
|
||||||
|
- Signed by a CA (from an organization or self-signed).
|
||||||
|
- The subject UID field must be the hexadecimal form of the RingId.
|
||||||
|
- The issuer UID field must be the hexadecimal form of the issuer
|
||||||
|
public key fingerprint (CA).
|
||||||
|
- Random RSA key-pair of at least 4096-bits long.
|
||||||
|
|
||||||
|
### Device certificate
|
||||||
|
|
||||||
|
- This is the identity of one specific device used to run Ring.
|
||||||
|
- One per device.
|
||||||
|
- Generated by Ring (not user provided).
|
||||||
|
- Random and 4096-bits long.
|
||||||
|
- The SHA-1 fingerprint of the public key becomes the **DeviceId**.
|
||||||
|
- Must be signed by the private key that created the Ring certificate.
|
||||||
|
- The subject UID field must be the hexadecimal form of the DeviceId.
|
||||||
|
- The issuer UID field must be the hexadecimal form of the issuer
|
||||||
|
public key fingerprint (RingId).
|
||||||
|
|
||||||
|
### Usages
|
||||||
|
|
||||||
|
- The RingId:
|
||||||
|
- It's the DHT key where the list of account devices are published
|
||||||
|
and where all devices listen to synchronize on account
|
||||||
|
changes (i.e. adding or revoke a device).
|
||||||
|
- The Ring certificate RSA keys are used as long-term keys to
|
||||||
|
sign/encrypt/decrypt messages sent over the DHT:
|
||||||
|
- private key to sign-off and decrypt incoming messages and
|
||||||
|
device certificates.
|
||||||
|
- public key to encrypt messages (this is done by the message
|
||||||
|
issuer using the receiver public key).
|
||||||
|
- A device can be "removed" from a Ring account through revocation of
|
||||||
|
the device certificate:
|
||||||
|
- Revoked device certificates are added to one or more standard
|
||||||
|
x509 Certificate Revocation List (CRL).
|
||||||
|
- CRLs for revoked device must be valid and signed with the
|
||||||
|
corresponding CA key, which is the Ring account private key.
|
||||||
|
|
||||||
|
### Long-term Storage
|
||||||
|
|
||||||
|
- Why storing data?
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
- - Ring needs to load certificates and key-pairs each time the
|
||||||
|
application is started.
|
||||||
|
- When Ring creates a new device, these information are also
|
||||||
|
needed, shared from another trusted device in a secure way.
|
||||||
|
- All platforms doesn't provide secure way to store data, Ring
|
||||||
|
supports this fact by encrypting data stored outside the
|
||||||
|
memory (i.e. on a file-system) using a user defined password
|
||||||
|
during the account creation.
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
- These files are stored on user device (see below for details):
|
||||||
|
- a compressed and encrypted archive with private account data.
|
||||||
|
- the public certificates chain as a CRT file
|
||||||
|
- the device private key.
|
||||||
|
|
||||||
|
#### Ring archive (export.gz)
|
||||||
|
|
||||||
|
- Contains private account data.
|
||||||
|
- Currently transmitted over the DHT network when device is created
|
||||||
|
or revoked.
|
||||||
|
- It's a JSON compressed and encrypted file.
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
- The current format is (could change at any time):
|
||||||
|
|
||||||
|
`{`\
|
||||||
|
` `*`ringCaKey`*`: `<base64 serialized PEM-encoded CA private key>`,`\
|
||||||
|
` `*`ringAccountKey`*`: `<base64 serialized PEM-encoded Ring private key>\
|
||||||
|
` `*`ringAccountCert`*`: `<base64 serialized PEM-encoded Ring certificate (public key)>`,`\
|
||||||
|
` `*`ethKey`*`: `<base64 serialized of the optional 160-bits Etherium key used to register the RingId on a public blockchain>`,`\
|
||||||
|
` `*`ringAccountCRL`*`: `<base64 serialized of packet list of revoked device certificates PEM-encoded>`,`\
|
||||||
|
` `*`ringAccountContacts`*`: `<JSON dictionary to export trusted user contacts>\
|
||||||
|
`}`
|
||||||
|
|
||||||
|
- The JSON byte-stream is compressed using \*gzip\* algorithm.
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
- Then the gzip-stream is encrypted using AES-GCM-256 symmetric cipher
|
||||||
|
with a 256-bits key.
|
||||||
|
- This key is derived from the user provided password, a PIN and a
|
||||||
|
timestamp, using
|
||||||
|
[Argon2](https://github.com/P-H-C/phc-winner-argon2) (a password
|
||||||
|
stretching and normalizer) as follow:
|
||||||
|
|
||||||
|
`salt = PIN + timestamp`\
|
||||||
|
`key = argon2(password, salt)`\
|
||||||
|
` `*`argon2`*` is the argon2i algorithm using t_cost = 16, m_cost = 2^16 (64 MiB), mono-threaded, to generate a 512-bits key and then hashed with SHA-256 to generate a 256-bits key. `\
|
||||||
|
` `*`PIN`*` is a random 32bits number in hexadecimal form.`\
|
||||||
|
` `*`+`*` is string concatenation operator.`\
|
||||||
|
` `*`timestamp`*` is the current UNIX timestamp divided by 1200 (20 minutes).`\
|
||||||
|
` `*`password`*` is a user-chosen password (given at account creation).`
|
||||||
|
|
||||||
|
- The PIN should be shown to the user to be copied manually on the new
|
||||||
|
physical device along with the password to finish the device
|
||||||
|
creation process.
|
||||||
|
|
||||||
|
#### Ring device certificate chain (ring\_device.crt)
|
||||||
|
|
||||||
|
- PEM format
|
||||||
|
- Includes the Device certificate and parent certificates (Ring device
|
||||||
|
certificate and parents)
|
||||||
|
|
||||||
|
#### Device private key (ring\_device.key)
|
||||||
|
|
||||||
|
- PEM format
|
||||||
|
- not encrypted, we let the device file-system protect this file
|
||||||
|
|
||||||
|
#### Exporting data (creating new devices)
|
||||||
|
|
||||||
|
*TBD*
|
||||||
|
|
||||||
|
### The DHT network
|
||||||
|
|
||||||
|
Dedicated [ Ring distributed
|
||||||
|
network](Ring_distributed_network "wikilink") page.
|
||||||
|
|
||||||
|
### Contact Request
|
||||||
|
|
||||||
|
*TBD*
|
||||||
|
|
||||||
|
### Instant Message
|
||||||
|
|
||||||
|
*TBD*
|
||||||
|
|
||||||
|
### Outgoing and Incoming calls
|
||||||
|
|
||||||
|
- Contactable addresses (i.e. IP addresses) of the user are given to
|
||||||
|
peer only:
|
||||||
|
- When we call a peer (outgoing call).
|
||||||
|
- When a **trusted** peer is calling (incoming call).
|
||||||
|
- All combination forms of how a specific device can be contacted is
|
||||||
|
summarized by a ICE message:
|
||||||
|
- *[RFC 5245](https://tools.ietf.org/html/rfc5245)* defines ICE
|
||||||
|
(Interactive Connectivity Establishment), a protocol for
|
||||||
|
NAT traversal.
|
||||||
|
- ICE is used in Ring to establish a peer-to-peer communication
|
||||||
|
between two devices.
|
||||||
|
|
||||||
|
#### Making an outgoing call
|
||||||
|
|
||||||
|
1. The calling device gathers candidates and build an **Initial Offer**
|
||||||
|
according to the ICE specifications.
|
||||||
|
2. The calling device puts the encrypted ICE offer (the *Initial
|
||||||
|
Offer*) on the DHT at:
|
||||||
|
`h("`[`callto:"+DeviceID`](callto:%22+DeviceID)`)` where *h* is
|
||||||
|
SHA1, *+* is the string concatenation, *DeviceID* is in
|
||||||
|
hexadecimal form.
|
||||||
|
3. The calling device waits on the peer answer, with its own ICE
|
||||||
|
candidates lists.
|
||||||
|
4. At peer answer reception, the calling device starts the
|
||||||
|
ICE negotiation.
|
||||||
|
5. If the negotiation succeed, the process continues on a client-side
|
||||||
|
DTLS session establishment over the created ICE socket (see below).
|
||||||
|
|
||||||
|
#### Listening for incoming calls
|
||||||
|
|
||||||
|
1. A device listens for incoming calls by performing a listen OpenDHT
|
||||||
|
operation on `h("`[`callto:"+DeviceID`](callto:%22+DeviceID)`)`
|
||||||
|
where *h* is SHA1, *+* is the string concatenation and *DeviceID* is
|
||||||
|
in hexadecimal form.
|
||||||
|
2. At ICE *Initial Offer* reception, the called device **must** do a
|
||||||
|
security validation of the peer (see below).
|
||||||
|
3. If the security validation succeed, the called device starts the
|
||||||
|
ICE negotiation.
|
||||||
|
4. If the negotiation succeed, the process continues on a server-side
|
||||||
|
DTLS session establishment over the created ICE socket (see below).
|
||||||
|
|
||||||
|
- *Note: OpenDHT drops values that are not properly encrypted or
|
||||||
|
signed, as specified by OpenDHT protocol.*
|
||||||
|
|
||||||
|
#### ICE serialization format
|
||||||
|
|
||||||
|
- ICE messages exchanged between peers during a call set up use
|
||||||
|
following format.
|
||||||
|
- An ICE message is a chunk of binary data, following
|
||||||
|
[msgpack](http://msgpack.org/) data format.
|
||||||
|
|
||||||
|
`<8-bits unsigned integer> giving the version of ICE message format protocol used for the rest of the data,`\
|
||||||
|
<C++ std::pair of string>` of the ICE local session ufrag and the ICE local session password,`\
|
||||||
|
`<8-bits unsigned integer> giving the number of components in the ICE session,`\
|
||||||
|
<array of string>` of the previous number entries, where each string describe the ICE candidate, formated as an "a=" line (without the "a=" header) described in `[`rfc5245,`
|
||||||
|
`section` `4.3`](https://tools.ietf.org/html/rfc5245#page-26)
|
||||||
|
|
||||||
|
- **Current defined protocol is 1**:
|
||||||
|
|
||||||
|
#### Security Validation of the Peer
|
||||||
|
|
||||||
|
- Upon reception of the encrypted and signed Initial ICE Offer
|
||||||
|
(through the listen operation), a called device should perform
|
||||||
|
authorization checks of the calling device, identified as the
|
||||||
|
Initial Offer signer.
|
||||||
|
- Authorization rules are implementation defined, but a typical
|
||||||
|
implementation would authorize known or trusted contacts.
|
||||||
|
- If the calling device is not authorized or if for any implementation
|
||||||
|
defined reason the called device refuses the incoming connection
|
||||||
|
request, the called device must ignore the Initial Offer and may log
|
||||||
|
the event.
|
||||||
|
- If the called device authorizes the caller and wish to accept the
|
||||||
|
connection it must build an ICE answer, start the ICE negotiation
|
||||||
|
process and send the encrypted and signed ICE answer at the same
|
||||||
|
DHT key.
|
||||||
|
|
||||||
|
#### DTLS negotiation
|
||||||
|
|
||||||
|
- Once a peer-to-peer communication channel has been established by
|
||||||
|
ICE protocol, the called device starts a server-side DTLS session on
|
||||||
|
the ICE socket, while the caller starts a client-side DTLS session
|
||||||
|
on the other side of the ICE socket.
|
||||||
|
- The DTLS communication is
|
||||||
|
[RFC6347](https://tools.ietf.org/html/rfc6347) compliant using
|
||||||
|
gnutls library.
|
||||||
|
- To prevent peer certificates to be displayed in plain-text for the
|
||||||
|
call anonymity, the session handshake is done twice:
|
||||||
|
|
||||||
|
1. A first handshake in **anonymous mode** to create a secure but
|
||||||
|
anonymous transport.
|
||||||
|
2. A second handshake in **certificate mode**, over the first one, to
|
||||||
|
prove the identity of peers.
|
||||||
|
|
||||||
|
- Only PFS cipher suites are supported:
|
||||||
|
- The set of supported cipher suites is implementation defined but
|
||||||
|
should include at least ECDHE-AES-GCM.
|
||||||
|
- The actual cipher suites (in gnutls form) is:
|
||||||
|
- anonymous step:
|
||||||
|
`SECURE192:-KX-ALL:+ANON-ECDH:+ANON-DH:+SECURE192:-VERS-TLS-ALL:+VERS-DTLS-ALL:-RSA:%SERVER_PRECEDENCE:%SAFE_RENEGOTIATION`
|
||||||
|
- certificate step:
|
||||||
|
`SECURE192:-VERS-TLS-ALL:+VERS-DTLS-ALL:-RSA:%SERVER_PRECEDENCE:%SAFE_RENEGOTIATION`
|
||||||
|
|
||||||
|
#### SIP signaling
|
||||||
|
|
||||||
|
- Used over the DTLS session to signaling the call (vcard, media
|
||||||
|
negotiation, hangup, instant messaging, ...)
|
||||||
|
- Once an encrypted and authenticated peer-to-peer communication
|
||||||
|
channel is available, the [SIP
|
||||||
|
protocol](https://tools.ietf.org/html/rfc3261) must be used to place
|
||||||
|
a call and send messages.
|
||||||
|
- The caller might send a SIP INVITE as soon as the DTLS channel
|
||||||
|
is established.
|
||||||
|
- The SIP implementation must support ICE and SRTP.
|
||||||
|
- Supported codecs are implementation defined, but Ring clients should
|
||||||
|
support the Opus audio coded and the H264 video codec.
|
||||||
|
- SRTP must be used when negotiating media with SIP, using a new
|
||||||
|
random key for each media and each negotiation. ICE should be used
|
||||||
|
when negotiating media with SIP.
|
||||||
|
|
||||||
|
### Presence
|
||||||
|
|
||||||
|
*TBD*
|
Loading…
Reference in New Issue