Right now webapp/nickserver only accepts openpgp keys. The API described in the doc mentions type for send_key. But AFAIK the actual implementation differs from that.
Right now we upload keys by PUT {"user[public_key]": "<openpgp-key>"} to https://nicknym.provider.com/1/users/user@provider.com.json. Can we add an extra entry in the data we send to provide the key type? Something like user[key_type]? I guess for backward compatibility will make sense to default to openpgp if the type entry is not provided.
AFAIK to discover keys the current API is a POST address=user@provider.com to https://nicknym.provider.com that returns a json like:
should not be too hard. the upload api definitly looks more messy then the retrieval.
@meskio, do you have one particular kind of key in mind?
Do you need to publish a single key of that kind or can there be multiple?
Having the ability of storing multiple keys will be really handy for katzenpost. In katzenpost we'll need two types of keys:
EDDSA Identity key. One single key per account, used by senders to encrypt emails to the recipient. The private one we'll share it between devices using the same mechanisms that we currently use for OpenPGP.
ECDH Link keys. One link key per device (bitmask instance) to authenticate the connection between bitmask/katzenpost and the provider (something like the smtp cert). This one will be generated new per device and account.
@meskio, so here's the api usecases i imagine from what i read above:
upload initial identity key (authenticated)
change identity key (authenticated)
retrieve identity key for a given user
add link key (authenticated)
remove link key (authenticated)
list own link keys (authenticated)
retrieve link keys for a given user
Maybe it makes sense to combine the two key retrieval endpoints into one...
retrieve katzenpost keys
I was also considering to just have a general purpose api where you can alter a json doc when authenticated and retrieve it publicly. So you would be free to adjust your datastructure however you see fit. It would however also require that you perform all checks client side (such as checking there is only one identity key). It could also lead to inconsistencies if two devices change the doc at the same time.
So for now i feel like spelling out the different usecases as API endpoints. How do you feel about that?
The usage we'll have for katzenpost is to check if a pair (username, link key) is valid. So we don't need to retrieve the whole list of keys, but I see it simpler to implement the same API to all the keys.
I'm wondering if there is any privacy issues related to everybody being able to discover your link keys, I don't think so but I'll check. The only key everybody needs to be able to discover is the identity key. But we can start with the simple solution, were retrieve of any key doesn't require authentication, and we'll see if we need to change that.
I'm wondering if doesn't make sense for nickserver to don't handle the katzenpost in any especial way, but to have a generic API that we can use to push any key type we want.
@meskio I have started specing the concrete API in !58 (merged). Sadly the syntax highlighting for gherkin files is far from optimal. Hope it's readable never the less.
I think I get the idea and I like it. I guess this means that if we need another type of keys in the future we won't need to modify the webapp to start using them. Nice idea of the revision to don't have collisions on updates.
How does it fit with the existing API? Reading bitmask code it looks like currently we put keys by doing something like:
curl -X PUT https://apiurl/1/users/user@provider.json -d '{"openpgp": "<my openpgp public key>"}' # not type, no revision
And reads keys by doing:
curl -X GET https://apiurl/?address=user@provider{ "openpgp": "<the openpgp public key>"}
We do update keys, even if there is an existing one (without revision number), when we do extend the expiration date or when a user manually changes the private key.
Is this going to still work? I don't have many problems about breaking backward compatibility, I prefer to don't do it if we don't need to, but we don't have real users of email.
@meskio I was thinking I would keep the old API and mark it as deprecated in the docs.
The new and old API will act on the same datastructures. The old API will overwrite without checking revision, the new API will check.
The key retrieval API will be the same just including more keys and values.
You're right about future keys. I'm thinking about including a whitelist of possible key names though. Just so clients easily learn if they use invalid key names. Maybe even required and allowed fields or so. But I guess that is a separate issue. However once that exists using a new key name would require (minor) updates to the webapp or its config.
two clients with different versions - one using old api, one new
both generate a pgp key and try to upload it
If the old client comes first we can signal a conflict to the new client and it will know how to handle this. However if the new client is first there is nothing we could do for the old client because every error while uploading the key would be unexpected i guess.
Need to look further into how we handle this thus far.
@meskio do you have an idea what would happen if i currently try to setup two devices with the same username, password?
Split out issues for the remaining parts.
@meskio basic API for handling your own keys is ready. I hope to get to the key querying through nicknym in the coming days.