On 08/19/2016 01:02 PM, Richard Barnes wrote:
> Just for clarity, I assume the proposal would be to require something
> like { "account": "accountURL" } in the JWS header instead of the "jwk"
> field. Then the server would look up the appropriate JWK to verify the
> signature.
Approximately correct. As I mentioned in my earlier email, I think the
JWS "kid" header is a natural fit for this, since the the client is
identifying to the server which key should be used to validate its request.
> However, we've already said that you can look up an account based on a
> public key (#163), so if you can somehow reproduce a valid account key,
> it's game over anyway.
The threat is not that someone could illegitimately find an account URL.
The threat is that someone can come up with key X, sign a payload with
key X, and present that signed payload such that when the ACME server
looks up key X, it finds key Y. For instance, this could be possible
with a broken hash function, or an ambiguity in JWK representation, or a
silently truncated database field.
> Given that there's no security difference between the two scenarios, I
> have a pretty strong preference for identifying the key by value rather
> than by the account URI. It lets you have a clean transport layer that
> can do validation before any ACME logic gets involved.
I've described above the potential security difference. There's also a
philosophical question here: Should raw keypairs be the fundamental unit
identifying users of ACME, with accounts being some metadata stapled
weakly on the side? or should and account be the fundamental identifying
factor, with a public key associated for authentication purposes?
I think best practice in general is not to treat raw keypairs as an
identifier on their own. For x509, we wrap keypairs in certificates to
associate them with data. For SSH, keypairs are listed in an
authorization file associated with a login account.
Additionally, the raw keypair notion is not a good fit for how any CA
actually models their users. I believe all paid CAs organize usage
primarily around accounts. And even Let's Encrypt, which carries
relatively little long-term state around the account, still treats the
account as the fundamental unit of organization, rather than the raw
keypair.
> For example, if you identify keys by account URI, you need to a lookup
> in the ACME DB before you can reject a bad request. If you identify
> keys directly, you can just have validation as a middleware step, which
> is a natural fit for how modern web services are built. See
> https://github.com/bifurcation/rocket-skates/blob/master/lib/server/transport-server.js#L41
As someone who has worked on the security team for a very large, modern
web service, and implemented their authentication code, I strongly disagree.
Additionally, there is nothing about "middleware" that implies "no
database lookup."
_______________________________________________
Acme mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/acme