Closed dequbed closed 2 years ago
I don't think the preamble construction should be changed, as it is core to the security of the protocol and should be kept as required with this specific format. The preamble must incorporate its current parameters (client_identity, ke1, server_identity, ke2), as leaving any of them out would not be a good idea.
Perhaps the way the elements are concatenated together could be adjusted without affecting security, but I don't think that that is what you are suggesting...
may i ask why this is necessary? my guess would be that this is for channel binding? if so i don't think channel binding is a useful thing in the context of opaque, since each session is unique and thus implicitly channel-bound. channel binding only makes sense for auth protocols where the authentication token (hashed? password) is static and thus can be replayed/reused easily in other connections.
Right, I put the cart before the horse here a bit.
The first thing I think that I should explain is that I'm treating OPAQUE in this application not as a complete monolithic and immutable protocol but rather as one that can be adapted to its application where necessary.
In this specific application I'm wrapping the OPAQUE exchange for authentication and have the requirement that some additional adjacent data is integrity protected and cryptographically bound into this authentication exchange.
The best approach for that is to protect this adjacent data with the MAC sent in KE2 and KE3.
To illustrate what I'm planning with an example, C:
and S:
meaning messages sent by the client and server side respectively (newlines and comments added for readability):
C: y=tls-exporter,a=admin,n=user,r=rqdPU7Jkr.../QdeUv2Re+uCl
└────── adjacent data ──────┘ └─ b64 encoding of ke1 ─┘
┌──────────────────── adjacent data ────────────────────┐
S: c=YYWzZcN...sq3Ur6/hHBfw==,i=dj0xOSxtPTQwO...D0zLHA9MQo=,
v=f7s7GPGMl2DPCgoPyqh...jhuYAWdMqC4yl3qZYmT58=,p=MAANo1c2VwPlWV7e...0PZhvrpjyKs3+Bko=
└─ b64 encoding of ke2 minus the server MAC ─┘ └─ b64 encoding of the server mac ─┘
C: p=+HU90iCCXustmuDlOejEcig5inkRPlIraEDh7kJwT1w=
└────────── b64 encoding of ke3 ──────────┘
This adjacent data is here the (client) Authorization and Authentication identities, channel binding data, and the parameters to the KSF that need to be used.
My approach to generating a preamble / transaction log here would be to construct a running hash over the wire-format messages and MAC that, the server mac running up to but excluding the ,p=
of its message. (Which is the reason why KE2 needs to be split up)
The preamble must incorporate its current parameters (client_identity, ke1, server_identity, ke2), as leaving any of them out would not be a good idea.
Yes, I am acutely aware of that and as you can see from my above example I do not plan to exclude any data from the transaction hash, and instead only want to include further important data. An open question is however that I would prefer to bind to the public keys of the parties and not other identities like usernames. However, including the public keys of both sides into the transaction log is merely an issue of specifying it.
Perhaps the way the elements are concatenated together could be adjusted without affecting security, but I don't think that that is what you are suggesting...
I did in fact realize yesterday evening that a solution would be to use this adjacent data as client_identity
and server_identity
respectively. It would allow to keep the running hash and would solve most technological hurdles, but it does strike me as violating the spirit of the standard and also makes little obvious sense to users.
re stef:
if so i don't think channel binding is a useful thing in the context of opaque, since each session is unique and thus implicitly channel-bound.
Channel binding is about binding an authentication to an underlying encrypted channel like TLS and thus making sure that both sides see the same channel. That's very much not something that OPAQUE gives you implicitly.
channel binding only makes sense for auth protocols where the authentication token (hashed? password) is static and thus can be replayed/reused easily in other connections.
Well, in that case channel binding would make sense because the password and server-side record are static and reused in other connections. :)
Channel binding is about binding an authentication to an underlying encrypted channel like TLS and thus making sure that both sides see the same channel. That's very much not something that OPAQUE gives you implicitly.
ok, it might seem a dumb question, but it's genuine. what does it matter if a channel is encrypted or not, if the goal is to make sure that both sides see the same channel? and if the two parties can authenticate each other (which they do) then presuming that the ephemeral keys are indeed only used once, the authentication is bound to that tcp connection - limiting here to tcp like transports makes sense i hope, with udp this might not work. so i think opaque does indeed bind to a channel implicitly, and i think the fact of it being encrypted does not matter, as long as the channel is tcp-like connection-based.
@stef This is somewhat derailing the original issue by now, so I'm answering this in a new issue.
As the approach of 'just shove it into the identities' does solve this particular need as far as I can tell I think its appropiate to close this issue for now.
As of 4c36aa9, the Preamble used by OPAQUE-3DH is defined as:
I'm currently working on a SASL mechanism specification using OPAQUE, where it would be benefitial to be able to construct this transcript hash, that is the
preamble
, in a very different way.For one, due to SASLprep and encoding limitates enforced by the wire format,
client_identity
has three different representations. The mechanism specification would need to be careful to make clear which one is used in every context and it would make implementation bugs much more likely, as the representations only differ with identities containing complex unicode or characters such as '=' and ','.Secondly, while the preamble does have a
context
field parts of the data I would like to include are only available after the server response, making constructing the preamble using a running hash function impossible.I think this is a reasonably simple change as making 'preamble' an (opaque) parameter to
AuthServerRespond
andAuthClientFinalize
instead of constructing it inline would already allow me to refer to those functions as-is instead of having to redefine them using a different preamble construction.If this change is something that is wanted I'm happy to write a pull request with updated text to this end.