Yes, if the client claims to be billgates and signs their message with the 
known publickey, then they’re authenticated.  The question is, did they do 
this?  Or not?

Let me now be more detailed about the problem.  The problem is to correlate an 
incoming message with a publickey of the sender.  

When a message arrives from a ROUTER, you have 3 pieces of information.  These 
pieces of information tell you WHAT messages are being sent.  But they do not 
tell you WHO (publickey) is sending them.

For example, a router message looks like this:

[b'\x00\x80\x00A\xa7', b’’, b'message']

An “identity” or “source".  As best as I can tell this field of bytes has no 
broader meaning than an opaque set of bytes set by the router.  If it had a 
broader meaning, and the public key could be worked out from it, that would 
solve the problem.
An empty delimiter.  This is obviously of no use.
A message.  Now (if you are using CURVE) this message is signed and encrypted, 
so it’s not completely untrusted.  However, all we know is that SOME valid user 
signed it.  We do not know WHICH user signed it.  So we couldn’t rely on some 
“I’m Bill Gates!” type message to positively identify that the message came 
from Bill Gates.  We could do custom, application-level digital signatures, but 
the whole point of CurveZMQ is not to roll our own crypto.


Meanwhile, over in the ZAP authentication step, you find out WHO (publickey) is 
connecting.  But there is no way to correlate this with the messages they send.

Under rfc.zeromq.org/spec:27/ZAP, you get the following pieces of information:

> The request message SHALL consist of the following message frames:
> 
>       • An address delimiter frame, which SHALL have a length of zero.
>       • The version frame, which SHALL contain the three octets "1.0".
>       • The request id, which MAY contain an opaque binary blob.
>       • The domain, which SHALL contain a string.
>       • The address, the origin network IP address.
>       • The identity, the identity of the originating ZeroMQ socket.
>       • The mechanism, which SHALL contain a string.
>       • The credentials, which SHALL be zero or more opaque frames.

For example, a ZAP request looks like this.  For reasons that are a bit of a 
mystery to me, it seems to omit the first delimiter frame in the specification, 
so the version frame is request[0].  This may be an artifact of my test setup.

[b'1.0', b'1', b'', b'127.0.0.1', b'', b'CURVE', 
b'\x1f4I\r\x920\xbd\x03\xb1\xa9\x12N\x18k\x95TKB:Upf\x13=&1<\xa4Cg\x12h']

You would think, for example, that the identity field request[5] (request[4] in 
my sample packet) would contain the same “identity” opaque bytes that the 
router gives you in #1.  That would allow you to correlate the publickey with 
the subsequent messages.  In practice, however, the ZAP identity field is the 
empty string, as you can see.  Therefore you cannot correlate messages with 
public keys via this mechanism.

Another obvious mechanism would be for something in the ZAP response to become 
associated with the router in some way.  Under the spec quoted earlier, the 
response contains these frames:

> The reply message SHALL consist of the following message frames:
> 
>       • An address delimiter frame, which SHALL have a length of zero.
>       • The version frame, which SHALL contain the three octets "1.0".
>       • The request id, which MAY contain an opaque binary blob.
>       • The status code, which SHALL contain a string.
>       • The status text, which MAY contain a string.
>       • The user id, which SHALL contain a string.
>       • The metadata, which MAY contain a blob.


One might expect, for example, that the userid here would appear in a lookup 
table that would allow you to map from the ROUTER’s identity field onto the 
userid.  In practice, the userid appears to be ignored entirely by the 
implementation.  As far as I can tell, none of these fields can be used in 
practice to create a mapping between public keys and messages.

The result of all this is that there is no way to correlate the public key of a 
sender with their incoming messages.  We at one time verify that the public key 
is that of an authorized client.  And at another time we receive messages, 
knowing that the messages are sent by some authorized client.  But at no time 
can we find out which client (publickey) particularly is sending which message. 
 These two events cannot be correlated because there is no unique identifier 
common to both events.

Drew



On Dec 31, 2013, at 2:08 AM, Amir Taaki <zgen...@yahoo.com> wrote:

> Well any client can pick their own keypair, so unless you have the public key 
> then it's moot. If the client claims to be billgates and signs their message 
> (and you have their pubkey) then they're authenticated, no?
> 
> 
> 
> 
> 
> On Tuesday, December 31, 2013 7:01 AM, Drew Crawford 
> <d...@sealedabstract.com> wrote:
> Well if I allow just any client to claim to be billgates that’s not going to 
> be very secure…
> 
> …or did I misunderstand your proposal?
> 
> 
> On Dec 31, 2013, at 12:56 AM, Amir Taaki <zgen...@yahoo.com> wrote:
> 
>> Have you thought about a custom frame at the top of your message?
>> 
>> Or the clients can set their own custom identity if they have unique names.
>> 
>> 
>> 
>> 
>> 
>> On Tuesday, December 31, 2013 6:51 AM, Drew Crawford 
>> <d...@sealedabstract.com> wrote:
>> Hey folks,
>> 
>> I’ve got a REQ-ROUTER architecture where clients (with a REP socket) connect 
>> to a server (with a ROUTER socket).  This connection is authenticated via 
>> CURVE.
>> 
>> I need to figure out some person/username/unique identifier that is 
>> associated with the incoming REQ.  There are a couple of reasons.  One is 
>> that not all users have the same level of access privileges.  For example, 
>> there’s an admin user, with more powers than the other users, and so I need 
>> to allow some types of REQs only for that user.  Another reason is that in 
>> this application, users live inside their own sandbox more or less.  So a 
>> REQ that lists data, should only be listing data that the current user is 
>> allowed to see.
>> 
>> rfc.zeromq.org/spec:27/ZAP is apparently built to solve this problem, and 
>> the reply even has a field (field 5, "The user id, which SHALL contain a 
>> string.”) which looks like it is built for the purpose of associating a 
>> username with a session.  Presumably I would just fill that field with the 
>> username (e.g. “billgates”) when I am satisfied that the user has 
>> authenticated successfully as Bill Gates.
>> 
>> The problem is that at the time that a request comes inbound on my ROUTER, 
>> the only data I (seem to) have about the sender is some opaque (to me) 
>> identity bytes in the message envelope.  And I do not see a way to take 
>> those opaque bytes and convert them into either billgates, the client’s 
>> public key, or any other identifying information that would let me figure 
>> out who is making the request.
>> 
>> In an attempt to see where field 5 goes, I have traced the parsing of the 
>> zap field into curve_server.cpp 
>> (https://github.com/zeromq/libzmq/blob/master/src/curve_server.cpp#L617) and 
>> as far as I can tell it’s unused.  So it’s possible that the feature I’m 
>> looking for isn’t implemented.
>> 
>> Any suggestions for how I can identify the sender of a REQ, either within 
>> the current 4.0.3 release, or a general sketch of a patch I could write that 
>> would solve this problem?
>> 
>> Drew
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev@lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev 
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev@lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
> 
> 
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev@lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev@lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev

_______________________________________________
zeromq-dev mailing list
zeromq-dev@lists.zeromq.org
http://lists.zeromq.org/mailman/listinfo/zeromq-dev

Reply via email to