Azure / iot-identity-service

Source of the Azure IoT Identity Service and related services.
MIT License
37 stars 46 forks source link

HTTP Request written to keyd.pipe is "not spec compliant" #396

Open quality-leftovers opened 2 years ago

quality-leftovers commented 2 years ago

Currently when a request to the keyd socket is written the request looks like this:

POST /parameters/algorithm?api-version=2020-09-01 HTTP/1.1
content-length: 256
content-type: application/json

{"keyHandle":"..."}

This is not a valid HTTP 1.1 request, because it is missing the "Host" header.

While this is not a problem for the normal functionality (provisioning, etc) I've been experimenting with giving an additional container access to the keyd via a sidecar and ran into a problem with our proxy that forwards the requests from the unix domain socket to the sidecar, because it rejects the requests due to being "malformed".

Maybe it would be possible to set Host: localhost for the requests?

quality-leftovers commented 2 years ago

Being able to configure the target URI for the requests would be nice, too but I assume this is not desired

arsing commented 2 years ago

So, your setup is:

process --[keyd.sock]--> proxy --[tcp]--> sidecar --[keyd.sock]--> keyd

? And because "process" sends requests without the host header, the proxy rejects them?

quality-leftovers commented 2 years ago

Yes, exactly.

arsing commented 2 years ago

What is "process" ? One of the aziot-identity-service processes? Something of yours that uses the openssl engine?

quality-leftovers commented 2 years ago

The process is our application and uses aziot openssl engine and Microsoft Azure IoT Hub device SDK for C# to connect to IoT Hub

image

arsing commented 2 years ago

We could make an engine ctrl command to allow setting a custom host in the keyd client that it uses internally. Does dotnet have the ability to call openssl's ENGINE_ctrl_cmd / ENGINE_ctrl_cmd_string ? I vaguely remember being told during the early days of i-i-s dev that dotnet would have a hard time interoping with openssl engines; not sure.

If dotnet can't do that, we could additionally have some bespoke env var like AZIOT_KEY_ENGINE_HOSTNAME.

(And of course, the fallback option of just adding a hard-coded host:localhost as you suggested is still available.)

quality-leftovers commented 2 years ago

Calling openssl functions is not a problem and actually you need to call ENGINE_load_private_key to get an "raw" EVP_PKEY which is then used to initialize the .NET key wrapper class SafeEvpPKeyHandle. After that .NET assymetric crypto classes can be used and will use the aziot key engine.

I'd prefer ENGINE_ctrl_cmd_string over ENGINE_ctrl_cmd though, because passing function pointers to unmanaged code can be a bit of a PITA.

A fallback would of course be really great too, since that would make everything easier when using 3rd party software like nginx.

As for environment maybe we can at some point have an AZIOT_KEY_ENGINE_URL to forward requests to either URL (http://) or UDS (unix://) because then we'd enter sidecare wonderland. But I'm already pretty happy with what the iot-identity-service offers. Great stuff.

arsing commented 2 years ago

The problem with supporting http:// is that we would need to make it https:// for our security requirements, since such requests can be cross-machine / cross-Kubernetes-pod. And that brings with it its own can of worms like needing to support certs that aren't in the OS's openssl bundle.

quality-leftovers commented 2 years ago

Good points.