Re: [grpc-io] Re: Problem of request validation by hash signature.

2018-02-09 Thread Mehrdad Afshari
While it certainly seems like the TLS client certificate is a better way to 
identify the peer on the other end, if for any reason you need to 
authenticate the payload of the RPC, I recommend directly signing the 
payload and sending the signature alongside it (instead of metadata). You 
can do this by wrapping the request_serializer/response_deserializer 
functions on the client side and request_deserializer/response_serializer 
objects on the server side. Here's probably the easiest way to do it:

On the client side, create your own object implementing the grpc.Channel 
interface, wrapping the gRPC channel object, and wrapping the serializers 
in unary_unary, unary_stream, stream_unary, stream_stream:


def _signing_serializer(identity, serializer):
def sign_and_serialize(message):
binary_message = message if serializer is None else serializer(message)
# _sign implements your signing logic and returns a bytestring with message 
and signature
return _sign(identity, binary_message)
return sign_and_serialize

def _verifying_deserializer(identity, deserializer):
def verify_and_deserialize(message):
# _verify_and_unwrap implements your custom verification logic and returns 
the original binary message and a boolean to indicate validity
binary_message, valid = _verify_and_unwrap(message)
if not valid:
return None
return binary_message if deserializer is None else deserializer(message)
return verify_and_deserialize

class PayloadSigningChannel(grpc.Channel)

def __init__(channel, identity):
self._channel = channel
self._identity = identity

def unary_unary(self,
method,
request_serializer=None,
response_deserializer=None):
return self._wrapped_channel.unary_unary(method, 
request_serializer=_signing_request_serializer(self._identity, 
request_serializer),
response_deserializer=_verifying_deserializer(self._identity, 
response_deserializer))


and on the server, you can register a simple interceptor to accomplish the 
same thing:

class PayloadSigningServerInterceptor(grpc.ServerInterceptor):
def __init__(identity):
self._identity = identity
def intercept_service(self, continuation, handler_call_details):
handler = continuation(handler_call_details)
if handler is None:
return None
if handler.request_streaming and handler.response_streaming:
return grpc.stream_stream_rpc_method_handler(handler.stream_stream,
request_deserializer=_verifying_deserializer(self._identity, handler.
request_deserializer),
response_serializer=_signing_serializer(self._identity, handler.
_response_serializer))
elif handler.request_streaming and not handler.response_streaming:
return grpc.stream_unary_rpc_method_handler(handler.stream_unary,
request_deserializer=_verifying_deserializer(self._identity, handler.
request_deserializer),
response_serializer=_signing_serializer(self._identity, handler.
_response_serializer))
elif not handler.request_streaming and handler.response_streaming:
return grpc.unary_stream_rpc_method_handler(handler.unary_stream,
request_deserializer=_verifying_deserializer(self._identity, handler.
request_deserializer),
response_serializer=_signing_serializer(self._identity, handler.
_response_serializer))
else:
return grpc.unary_unary_rpc_method_handler(handler.unary_unary,
request_deserializer=_verifying_deserializer(self._identity, handler.
request_deserializer),
response_serializer=_signing_serializer(self._identity, handler.
_response_serializer))


On Thursday, February 8, 2018 at 10:34:37 PM UTC-8, Carl Mastrangelo wrote:
>
> One thing to realize is that Protobuf is not always going to serialize the 
> message the same way, so you'll need to use raw bytes to wrap the message 
> anyways.   
>
> I'm surprised that the interceptor is a lot of boiler plate; what language 
> are you using gRPC with?
>
> Lastly: gRPC is protobuf agnostic.   You can use it without using proto at 
> all, so you should always be able to get at the raw message bytes, and not 
> just through the call credentials api.
>
>
> On Thu, Feb 8, 2018 at 10:19 PM Haiwei Zhou  > wrote:
>
>> Thanks for replying.
>>
>> TLS had been adopted, otherwise call credentials cannot be used. 
>>
>> A RPC service is designed to handle core logic. A Web service provides UI 
>> to proxy user request to the RPC service. Then a request signature should 
>> be introduced to verify the real authorization.
>>
>> Using customized interceptor means a lot of boilerplate code, which I try 
>> to avoid. The best way I guess is that call credentials API provides raw 
>> request buffer.
>>
>>
>> On 9 February 2018 at 11:34, 'Carl Mastrangelo' via grpc.io <
>> grp...@googlegroups.com > wrote:
>>
>>> To do this, you'll need to wrap the serialized proto.   Actually, you 
>>> don't even need to put the signature in the headers.   For example:
>>>
>>>
>>> message Wrapper {
>>>   bytes signature = 1;
>>>   bytes message = 2;
>>> }
>>>
>>>
>>> From the client:
>>>
>>> 1.   Serialize your messsage
>>> 2.   Put this in field 2
>>> 3.   Sign the message and put this in field 1.
>>>

Re: [grpc-io] Re: Problem of request validation by hash signature.

2018-02-08 Thread 'Carl Mastrangelo' via grpc.io
One thing to realize is that Protobuf is not always going to serialize the
message the same way, so you'll need to use raw bytes to wrap the message
anyways.

I'm surprised that the interceptor is a lot of boiler plate; what language
are you using gRPC with?

Lastly: gRPC is protobuf agnostic.   You can use it without using proto at
all, so you should always be able to get at the raw message bytes, and not
just through the call credentials api.


On Thu, Feb 8, 2018 at 10:19 PM Haiwei Zhou  wrote:

> Thanks for replying.
>
> TLS had been adopted, otherwise call credentials cannot be used.
>
> A RPC service is designed to handle core logic. A Web service provides UI
> to proxy user request to the RPC service. Then a request signature should
> be introduced to verify the real authorization.
>
> Using customized interceptor means a lot of boilerplate code, which I try
> to avoid. The best way I guess is that call credentials API provides raw
> request buffer.
>
>
> On 9 February 2018 at 11:34, 'Carl Mastrangelo' via grpc.io <
> grpc-io@googlegroups.com> wrote:
>
>> To do this, you'll need to wrap the serialized proto.   Actually, you
>> don't even need to put the signature in the headers.   For example:
>>
>>
>> message Wrapper {
>>   bytes signature = 1;
>>   bytes message = 2;
>> }
>>
>>
>> From the client:
>>
>> 1.   Serialize your messsage
>> 2.   Put this in field 2
>> 3.   Sign the message and put this in field 1.
>>
>> Send the wrapper as your message type.
>>
>> From the server:
>>
>> 1.  Receive the wrapper proto
>> 2.   Verify the signature on the data
>> 3.  Deserialize the data.
>>
>>
>> You can also do this from an interceptor, which would make the process
>> transparent from the application point of view.
>>
>> That said, you're probably better off just using TLS with a client side
>> certificate, which the server can verify and then you can trust all the
>> data that comes over the wire.
>>
>>
>> On Thursday, February 8, 2018 at 1:27:04 AM UTC-8, high...@gmail.com
>> wrote:
>>>
>>> Hi,
>>>
>>>   I try to use call credentials to verify the request sanity:
>>>
>>>   In the client,
>>>  serialize the request to string,
>>>  sign the string,
>>>  and send the signature as metadata.
>>>
>>>   In the server,
>>> serialize the request to string,
>>> sign the string,
>>> sign the request,
>>> and compare the signature to the one in metadata.
>>>
>>>   It works perfect until I met a message with a map. Protobuf
>>>  serialization doesn't guarantee the order of map items.
>>>
>>>   How could I get original serialization string of the request in the
>>> server side using python API?
>>>
>>> Thanks,
>>> Haiwei
>>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "grpc.io" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/grpc-io/SPAv92gUypA/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> grpc-io+unsubscr...@googlegroups.com.
>> To post to this group, send email to grpc-io@googlegroups.com.
>> Visit this group at https://groups.google.com/group/grpc-io.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/grpc-io/e1cfcfca-9da1-4439-b4e3-d9a37d533648%40googlegroups.com
>> 
>> .
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To post to this group, send email to grpc-io@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/CAAcqB%2Bv40RPKB2Hn__W3KjO0ytsm4CRw60k_449syXVTvGgBjA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [grpc-io] Re: Problem of request validation by hash signature.

2018-02-08 Thread Haiwei Zhou
Thanks for replying.

TLS had been adopted, otherwise call credentials cannot be used.

A RPC service is designed to handle core logic. A Web service provides UI
to proxy user request to the RPC service. Then a request signature should
be introduced to verify the real authorization.

Using customized interceptor means a lot of boilerplate code, which I try
to avoid. The best way I guess is that call credentials API provides raw
request buffer.


On 9 February 2018 at 11:34, 'Carl Mastrangelo' via grpc.io <
grpc-io@googlegroups.com> wrote:

> To do this, you'll need to wrap the serialized proto.   Actually, you
> don't even need to put the signature in the headers.   For example:
>
>
> message Wrapper {
>   bytes signature = 1;
>   bytes message = 2;
> }
>
>
> From the client:
>
> 1.   Serialize your messsage
> 2.   Put this in field 2
> 3.   Sign the message and put this in field 1.
>
> Send the wrapper as your message type.
>
> From the server:
>
> 1.  Receive the wrapper proto
> 2.   Verify the signature on the data
> 3.  Deserialize the data.
>
>
> You can also do this from an interceptor, which would make the process
> transparent from the application point of view.
>
> That said, you're probably better off just using TLS with a client side
> certificate, which the server can verify and then you can trust all the
> data that comes over the wire.
>
>
> On Thursday, February 8, 2018 at 1:27:04 AM UTC-8, high...@gmail.com
> wrote:
>>
>> Hi,
>>
>>   I try to use call credentials to verify the request sanity:
>>
>>   In the client,
>>  serialize the request to string,
>>  sign the string,
>>  and send the signature as metadata.
>>
>>   In the server,
>> serialize the request to string,
>> sign the string,
>> sign the request,
>> and compare the signature to the one in metadata.
>>
>>   It works perfect until I met a message with a map. Protobuf
>>  serialization doesn't guarantee the order of map items.
>>
>>   How could I get original serialization string of the request in the
>> server side using python API?
>>
>> Thanks,
>> Haiwei
>>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "grpc.io" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/grpc-io/SPAv92gUypA/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> grpc-io+unsubscr...@googlegroups.com.
> To post to this group, send email to grpc-io@googlegroups.com.
> Visit this group at https://groups.google.com/group/grpc-io.
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/grpc-io/e1cfcfca-9da1-4439-b4e3-d9a37d533648%40googlegroups.com
> 
> .
>
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To post to this group, send email to grpc-io@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/CABLXuO-GSSSHd0fcH35F%3DUAGcK2ckpbNGHCacS6fD5xMdq%3D2aw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.