Closed kevinlewi closed 4 years ago
Well, it needs to be included in the transcript for the AKEs, I think, so that's why it's part of the CredentialRequest
message.
The presence of idU is dependent on the AKE protocol used, and so even though it may get sent over as the first message of the AKE, shouldn't this be controlled by the specification of the AKE, and not the OPRF component?
Also, this is only for CredentialRequest
, since RegistrationRequest
does not use idU. I would be happy with delegating the specifying of idU to the AKE component.
The presence of idU is dependent on the AKE protocol used, and so even though it may get sent over as the first message of the AKE, shouldn't this be controlled by the specification of the AKE, and not the OPRF component?
That's true. One thing I have in my implementation notes is whether we ought to include both idU
and pwdU
in the OPRF input, rather than just pwdU
. Given that kU
is unique per idU
, this probably doesn't make a meaningful change in security, though I wonder if it's just cleaner aesthetically?
I could go either way, I guess. I'm curious to hear what @hugokraw thinks.
One thing I have in my implementation notes is whether we ought to include both idU and pwdU in the OPRF input, rather than just pwdU.
That is certainly a valid consideration, but regardless of whether or not this is changed, I believe we can still omit idU from the RegistrationRequest
and CredentialRequest
messages, since the server doesn't use them (except for in the AKE component potentially).
True, though I wonder if that just complicates things. (I don't disagree with the proposal. I just need to think about it more.)
Kevin, as you say correctly some form of user identity needs to be sent to the server for fetching the user's record. I would actually think that this transmission of identity is very much a role of the password authentication protocol, namely, OPAQUE. I can also see that this information may be transmitted in some other way (e.g., a wrapper) but I would not want to rely 100% on that possibility. Can we make the idU in the CredentialRequest message optional? Would that address your concern? The setting in which the RegistrationRequest message acts is more complex as there are many issues involved in this case, particularly ways for the server to validate it is talking to the claimed user. In that case there may be a more complex wrapper. But even then, it feels that a support for a minimal implementation that communicated idU from client to server could be supported. But in issues of implementation and deployment I let you guys have the last word.
As for including idU under the OPRF input, I am ok with it. I am in favor of analyzing minimalistic protocols to understand what's the minimum elements the protocol's security requires. But I am happy to add elements that add robustness to the protocol (against misuse, etc.). I had examples in the past that I thought adding idU would be useful but I do not remember. It seems that if servers choose per-user kU (which they should) then adding idU does not add much value. Otoh, it makes idU more static as you cannot decide to change idU after registration (some websites would let you change userid)
some form of user identity needs to be sent to the server for fetching the user's record.
I think this hinges on whether the protocol is described as a component of a session (L5+). It seems to me that this is one natural way of interpreting (or implementing) the Registration flow, on the one hand, and the Credential flow, on the other hand. During each of those, the idU parameter remains a constant.
Once the session parameters are determined — including of course the user's claim to identity (idU) — there is no need for the application to receive them again in further messages. The repetition would in fact no only consume bandwidth, but complicate implementation, by requiring a check that the idU value has indeed been kept constant on every message of a session, and demanding that the server emits a new error case if that session invariant is broken.
However, such a re-transmission may be useful for auxiliary stateless tooling that does not have an understanding of a session, such as firewalls implementing packet filtering based on the idU field.
We've worked on implementation with a L7 in mind, but it's perfectly understandable that you could think of OPAQUE + KE as a lower-level initial session establishment protocol, in which case the stateless interpretation would make sense.
Are there two recommendations to make to implementers here, depending on their use case?
Just to be extra clear -- the inefficiency I am highlighting is the fact that the idU parameter included by RegistrationRequest is never used by the OPAQUE server implementation. Leaving it out would have no impact on anything within OPAQUE. One could argue the use for it by a wrapper protocol, but then the wrapper protocol would need to inspect the bytes of the OPAQUE protocol in order to extract idU, which could change depending on the OPAQUE version, and in general does not seem like a good abstraction.
For CredentialRequest, the same is true, except that the AKE component may use idU. However, I believe we should include the idU in the "first message of the key exchange" if the specification for that key exchange so requires, rather than placing it next to the OPRF component where it may or may not be consumed by the AKE.
BTW @hugokraw, I believe the idU parameter is already optional (since it can be specified as 0 bytes as per "opaque id<0..2^16-1>;
"). The question I am asking is if we should remove the already-optional parameter from the message being sent from client to server.
I am not completely sure I understand the issue here. I can see that there are cases where sending IdU inside OPAQUE can be redundant or even complicate things. But I think that giving the option to send it as part of the OPAQUE messages is necessary for ensuring one standard way for signaling the userid information to the server when the wrapper/application around it is not doing so. If you take the ability to send userid completely out of OPAQUE, what would be the answer to people's question "how is the client supposed to communicate the identity of the user to the server"?. Would the answer be: "it is not OPAQUE's responsibility but rather the application/wrapper around it"?
A related issue is privacy of the user id/account information. If you send it as part of OPAQUE and you run OPAQUE inside a confidential channel, such as server-authenticated TLS, then you get that protection. If you send it by other means, you need to trust that this other means take care of privacy.
Once thing that is for sure is that the AKE needs to have a notion of identities agreed by both parties (agreement needs to be at the level of bit representation as these are input into the KDF) as verifying such agreement is a fundamental part of the AKE functionality. Since these identities will be known in most cases to the parties before the AKE starts (the server needs it to fetch the user's record and the user will typically have an identity of the server in order to contacting it), sending it in the AKE may be redundant in some/many cases. But I am ok with any decision here as long as we make sure this agreement on identities is established before running the authentication steps in the AKE.
I am not completely sure I understand the issue here. I can see that there are cases where sending IdU inside OPAQUE can be redundant or even complicate things. But I think that giving the option to send it as part of the OPAQUE messages is necessary for ensuring one standard way for signaling the userid information to the server when the wrapper/application around it is not doing so. If you take the ability to send userid completely out of OPAQUE, what would be the answer to people's question "how is the client supposed to communicate the identity of the user to the server"?. Would the answer be: "it is not OPAQUE's responsibility but rather the application/wrapper around it"?
That's correct, I am of the opinion that "it is not OPAQUE's responsibility but rather the application/wrapper around it"
A related issue is privacy of the user id/account information. If you send it as part of OPAQUE and you run OPAQUE inside a confidential channel, such as server-authenticated TLS, then you get that protection. If you send it by other means, you need to trust that this other means take care of privacy.
Once thing that is for sure is that the AKE needs to have a notion of identities agreed by both parties (agreement needs to be at the level of bit representation as these are input into the KDF) as verifying such agreement is a fundamental part of the AKE functionality. Since these identities will be known in most cases to the parties before the AKE starts (the server needs it to fetch the user's record and the user will typically have an identity of the server in order to contacting it), sending it in the AKE may be redundant in some/many cases. But I am ok with any decision here as long as we make sure this agreement on identities is established before running the authentication steps in the AKE.
Agreed on the AKE point. I am also ok with leaving it as an optional parameter in RegistrationRequest and CredentialRequest, but I do want to point out that this idU parameter is the only remaining parameter in the OPAQUE protocol which is sent over the wire, but the receiving party does not do anything with it (within the specification).
To me, the rule I'd like to follow is: the only code which should be interpreting / deserializing any bytes sent as part of the OPAQUE protocol is the OPAQUE code itself -- having a wrapper protocol attempt to do the deserialization may end up causing versioning / upgrading nightmares for these wrapper implementations. As such, I'd like to avoid the possibility of a wrapper call understanding the organization of bytes in the OPAQUE messages, and hence would lean towards completely omitting this idU in OPAQUE's RegistrationRequest and the core part (not the AKE part) of CredentialRequest.
@kevinlewi can you please prep a PR with this suggested change?
I said in a previous post in this thread:
I had examples in the past that I thought adding idU [in the OPRF input, in addition to the password] would be useful but I do not remember
So now I remembered: It helps against an online attack where the attacker poses as the server with its own chosen value k. If only pwd is included then, the attacker can build a universal dictionary of values H(pwd)^k for all pwd in a dictionary and use it against any user to check the client response. On the other hand, if idU is included under H then the attacker needs to build a dictionary per idU. This would mean that at login and before talking to the server, the client knows a value of idU that was set at registration. If this is considered too problematic, one can live with the above issue as online attacks, particularly from the server side are not so damaging (I think). One can also include the server identity under H as may always be needed by the client in order to contact the server.
The idU parameter is not used by the server when receiving the
RegistrationRequest
andCredentialRequest
messages from the client. Can this parameter be omitted from the specification of these messages?In theory, the server does need some "username" equivalent in order to look up the client's record, so this information does need to be sent, but I don't think it should be included in the OPAQUE messages, since it has no function within OPAQUE other than to set/retrieve the appropriate password file.
Presumably, any wrapper protocol which uses OPAQUE will not want to look into the bytes of the OPAQUE messages in order to figure out what the username is.