-
Notifications
You must be signed in to change notification settings - Fork 5
Organization Design (proposal #4)
Let's try to make a final proposal where (almost) all the privacy leaks should be addressed.
Current info stored on the keyserver:
addresses database
{
address-hash (sha256(sha256(user) + sha256(org))
routing (routing-id of the registered mailserver)
public_key (the public key of the account)
proof (a proof-of-work that proofs that an account has done some work before creation)
serial number (a number that changes on each update)
}
organizations database
{
organization-hash (sha256(sha256(org))
public_key (the public key of the account)
proof (a proof-of-work that proofs that an organisation has done some work before creation)
serial number (a number that changes on each update)
}
routing database
{
routing-id (sha256(uuid))
routing (IP/Host/Onion?)
public_key (the public key of the server)
proof (a proof-of-work that proofs that an account has done some work before creation)
serial number (a number that changes on each update)
}
Setup a mailserver and send routing information to the keyserver
{
routing-id (sha256(public_key))
routing (IP/Host/Onion?)
public_key (the public key of the server)
proof (a proof-of-work that proofs that an account has done some work before creation)
}
Create and register organisation:
organization-hash: sha256(sha256("") + sha256(org))
name: The name of the organisation
public_key: RSA 4096 public key
validation: comma separated list of validation methods
Validation could be one (or more) of the following:
DNS:domain-name
KEYBASE:....
PGP:...
DNS validation:
If validation is not empty, it will point to a domain-name, which holds a TXT record bitmaelum
with the organisation hash as value. This will allow users to verify the organisation.
Other validation: Other methods of validation could be added at a later stage.
- john asks
acme-inc!
to create an account (john@acme-inc!
) on server X. - acme-inc creates an invitation token:
base64(sha256(sign(hash(john@acme-inc!) + route-id + timestamp)) + ":" + timestamp
-
John uses the invitation token to register onto server X.
-
Server X checks if the invitation token is "correct" by creating the signature from
- the organisation's PK
- john's hash address
- route-id
if the invitation token matches, we know the "organisation" has granted the account to john.
-
The mailserver will create the account on the server
-
Once successfully created, the mail CLIENT will send the account info to the key server:
address-hash: sha256(sha256("john") + sha256("acme-inc"))
pub-key: <public key of john>
routing: route-id
pow: proof of work for the account (on data: [address-hash])
When updating or deleting the key, we need additional info:
signature(address-hash) with private key
The key server will check the following:
-
is the signature of the address-hash correct for this public key (this will be a dummy check on an account creation, as there is no public key yet, and we do not use the public key the user has sent with)this is not necessary -
does the hash of org-id, plus hash of user-id combined make up the address-hash? If so, we can safely say that this is the actual organisation for this user.this is not necessary - is the pow correct?
-
create a signature-token with all info (org's pk, hash address, routing info), and check if it matches the one send. If so, we know this organisation has allowed this user.also not necessary
if we update or delete the key, we can only do so if the signature of the address-hash matches the public key currently on record. Only if this is true, we can update key data. This is to ensure that nobody else than the owner of the private key can change data.
user alice!
sends an email to bob!
.
- First, the mail client will look up the address for the hash
bob!
. It will return a public key & routing info. The public key is used to encrypt the message (actually, it encrypts a key that encrypts the message), so only the private key ofbob!
can decrypt it. - Secondly, the message will be sent to the routing mail server of
alice!
, asking it to send the message to the hash ofbob!
. The mail-server, and any other mail-servers in between, including the target mail server, will NOT know anything about the sender and the recipient.
user alice@acme-inc!
sends an email to bob!
.
- The mail client will look up the address for the hash
bob!
. It will return a public key & routing info. The public key is used to encrypt the message (actually, it encrypts a key that encrypts the message), so only the private key ofbob!
can decrypt it. - The mail client will cipher the message body and also it will add a organization field which contains both the organization id and the organization signature (aka invite token)
- The message will be sent to the routing mail server of
alice@acme-inc!
, asking it to send the message to the hash ofbob!
. The mail-server, and any other mail-servers in between, including the target mail server, will NOT know anything about the sender and the recipient. - When
bob!
fetch and decrypt their messages it will see that there is a special fieldorganization
. So his mail client will ask the keyserver for the information aboutorganization
and it will returnorganization
andorganization_signature
. At this point it will verify the organization signature sent on the mail by using the public key stored on the keyserver and all the verifications methods. It will show a green mark for every verification that matches and a red mark for any that doesn't.
In order to avoid direct connections from (bad)mail-clients to mailservers we need to verify the authenticity of the server that is sending the message. Since all the mailserver should be registered on the keyserver (on the routing database) a mailserver should add a header to verify it comes from the server linked to the account.
address_db
{
address-hash: (sha256(sha256("alice") + sha256(""))
routing: 12345678
public_key: whatever...
}
{
address-hash: (sha256(sha256("bob") + sha256(""))
routing: 87654321
public_key: whatever...
}
routing_db
{
routing_id: 12345678
public_key: whatever...
}
{
routing_id: 87654321
public_key: whatever...
}
-
alice!
send a message tobob!
. In order to do so it delivers the message to her server linked to the routing-id12345678
. - The server
12345678
will sign the whole message with its private-key and it will add a header calledserver_signature
with the hashed signature. - The server at
87654321
will receive a message coming fromalice!
. It will ask the keyserver for the routing-id ofalice!
and it will verify that theserver_signature
matches the public_key ofalice!
's server12345678
before accepting the message. - When doing proxying the mailservers in between can see that the
server_signature
is already there and pass it to the next server without altering it. This way the final mailserver can verify that the mail is coming from the original mailserver.
Q: can we force the organisation to remove a key if the organisation says so?
A: if we store the org-id, we can send a command on behalf of the organisation (the command is signed by the private key of the org). This command could be: "remove address", or "change routing". THis implies we need a organisation id stored on the keyserver. Not only the signature of the actual account is valid, also the signature of the organisation account as well.
Q: could we have a default route for organisations, so we don't have to change all addresses when an organisation moves?
A: In theory: when we send a message, we know the organisation. WE could add this to the message routing (but rather not), but this would allow the mailserver to check the keyserver account. If the routing is empty (or 0.0.0.0 for instance), it can fall back to the organisation ID's route. This means a double lookup (which is ok I think). By using routing database this should be addressed.
Who needs to know organisational information:
- the sender of a message The sender of the message knows the organisation. Nothing is really needed from this, as we use the plaintext address.
- sending mailserver
The sending server only receives a header file with routing info to the recipient hash.
If we allow "0.0.0.0", as fallback route, we will fetch the organisation hash from the keyserver, to fetch the default route from the organisation.Inside the message, there is no information about organisations needed. - proxying mailservers Proxying mailservers are not implemented yet.
- receiving mailserver The receiving mailserver does not need to know about organisations. Only the account address hash is important.
- recipient of a message The receiver is already aware of its organisation
- key-server
The key server needs to know the organisation, as it needs to check:
- does the organisation exist (we need to have an organisation before we can add users to it (would make things easier in the future))
-
does the organisation allow this user account on this specific mail server?This is checked through the signature/invitation token system. For this to work we need to upload both the organisation hash and the user hash for validation, but we only need to store the organisation hash for fallback routes.