Group: GNU Social P2P/Keys
Keys and Identity in GNU Social
Contents
User Keys
The fundamental unit of user identity in GNU Social will be a standard OpenPGP public key (hereafter Kpu). Identity will be proved by correctly signing challenges with the key, and privacy can be guaranteed by using these keys for end-to-end encryption.
Specifically, any user wishing to use GNU Social must configure their Agent with the public key ID from their user keyring they would like to use as their personal key. If they do not have a key, the Agent should generate one for them.
To set a privacy constraint on a given user object, that object should be encrypted to the user keys of all users to whom the *owner* of that object wishes to share the data. This ensures that only those users have access to those objects, presuming that the owner's trust in those users is well-placed.
Data Keys
These are symmetric keys with which objects in the GNU Social datastore are encrypted. These keys are encrypted with user keys to add users to access lists for private data objects.
Data Keys and Key Packets
Every object in the data store is encrypted to a object specific symmetric key, the "data key" (abbreviated hereafter as Kd). That key is then encrypted to all keys in the set of user keys who are allowed access to the object (hereafter target users). The encrypted keys are stored in key packets. It is to our good fortune that such interactions are already implemented in the OpenPGP protocol. The relevant concepts from the OpenPGP standard are Symmetric-Key Encrypted Session Key Packet and Public-Key Encrypted Session Key Packet.
To reduce the computational effort and to increase flexibility, intermediate symmetric keys are introduced. Kd is encrypted with a symmetric key generated once per target user - Ksu. Ksu is further encrypted with the target user's public key Kpu. When the user attempts to retrieve the data, they are presented with the chain E(Kd, d), E(Ksu, Kd). The user has previously obtained E(Kpu, Ksu). They are then able to decrypt the chain using their private key. On the originating node, E(Kd, d) is the encrypted data and is only stored once. E(Ksu, Kd) is stored with the data in a collection, one per target user. E(Kpu, Ksu) is stored with the friend record - as part of the structure that keeps track of the social graph.
To authenticate the requesting user, and send their specific E(Ksu, Kd), the core needs to match the user with the specific key packet. In addition to the key packet, we also store Hash(Ksu, path) with each packet. When the user requests a path, they provide this value. Because the value is different for each path, the core is prevented from acquiring information about the social graph.
Core keys
Core keys are public keys used to identify a core in the long term. Since cores do not have access to unencrypted data, they do not need to be trusted for the purpose of basic privacy. However, cores provide additional services that enhance privacy (such as routing). Therefore, we would still like to determine if cores are trustworthy. This may be verified through the Web of Trust.
In a GNU Social packet, inter-core routing information is encrypted to the Core key.
Transport Keys
Some transports may use their own keys. These must be rotated regularly, and presented to each connection signed with the Core key. The key type and method of presentation is left entirely to the transport.
Friending
The friending process (creating a link between two users) is performed as follows:
Request Phase
- The origin user initiates a friend request
- The origin Agent obtains the target Agent public key through various means (from another friend, from a directory or as a last resort by contacting the target Agent at a manually entered URL)
- The origin Agent creates a friend request packet, which includes: the origin Kpu, the origin Ksu (generated per friend connection), routing information from target to source. The packet is encrypted with the target Agent public key and signed with the origin Kpu.
- The origin Agent asks the origin Core to route the packet to the target Agent
Response Phase
- The target Agent decrypts the friend request and presents the request to the target user
- The target user approves the request
- The target Agent stores the friend information in the Core, including: the origin Kpu, the origin Ksu (both items encrypted to the target user public key).
- The target Agent creates and sends a friend request reply packet, including: a generated target Ksu, the target Kpu, routing information from origin to target. The packet is encrypted with the origin user public key and signed with the target Kpu.
- The origin Agent stores the friend information
Further Communication
Further communication is routed using the exchanged routing information. Routing information can be updated as needed.
Resources
- http://www.openpgp.org/technical/ - OpenPGP specs
- http://openpgp.rubyforge.org/ - Ruby OpenPGP implementation
- http://bouncycastle.org/java.html - Java OpenPGP implementation