Azure IoT Hub: HTTP Device-to-Cloud Messages without SDK? - c

I'm using a 32-bit microcontroller (program code written in C) with very limited flash space that is communicating with a cellular module. I have an Azure account setup with an IoT Hub and I would like to send some device-to-cloud messages to my IoT Hub. I have tested and confirmed both HTTP and HTTPS communication to other servers. However, I can't find anywhere that specifies what the required HTTP headers are for sending a device-to-cloud message. Can anyone provide a description of the required HTTP message format (the HTTP start line, required HTTP headers and the HTTP header values)?
I found the Azure SDK for C, but even with all the optimization options turned on it takes up too much codespace for my microcontroller. I've tried following the code in the SDK for how the HTTP message is built, but I seem to be missing some pieces. I only have two or three device-to-cloud messages that I am sending, so I assume that if I know what the headers are it won't take much code to generate the device-to-cloud messages.
The cellular module I have is handling the X.509 certificates for mutual TLS authentication. Assume that is working. For this question I'm only concerned with finding the required HTTP message formatting for a Azure IoT device-to-cloud message.
EDIT:
Following a suggestion from a comment, I was eventually led to this page:
https://learn.microsoft.com/en-us/rest/api/iothub/device/senddeviceevent
Using the suggested HTTP POST (with my device specifics replaced), I am now getting a 401 error (IotHubUnauthorizedAccess). I thought I understood how the authentication was supposed to work, but I guess I was wrong.
My IoT device has a symmetric key. I thought I was supposed to include a header formatted as:
Authorization:SharedAccessKey=<my_primary_key>
but that doesn't work. My HTTP body is simply:
{"deviceID":<my_IoT_Device_ID>}
Where am I supposed to include the symmetric key information, and what is its format?

After some trial and error, we found out it's much easier than we thought. If you are using X.509 certificates for client authentication, you don't need to include anything in the HTTP message content to specify your authentication. The minimum required for an Azure device-to-cloud message using X.509 certificates for authentication is:
POST /devices/<id>/messages/events?api-version=2018-06-30 HTTP/1.1
Host:<fully-qualified-iothubname>.azure-devices.net
Content-Length:<number-of-bytes-in-the-JSON-body>
{"deviceID":"<id>",<your-JSON-formatted-custom-d2c-message-data>}
where <id> is the device ID as listed on the Azure IoT Hub and <fully-qualified-iothubname> is the IoT Hub name. I believe Azure supports chunked encoding if you want to do that instead of using the Content-Length header.

Related

How to prevent the software like Fiddler from intercepting requests and intercepting requests sent out in electron

From the request made in electron, I don't want the software like Fiddler to see how it should be done. Any help is very grateful
You can't. Such information is ultimately public (if the traffic is not encrypted by HTTPS, but Fiddler can also read this because it acts as a man in the middle), and there is even more sophisticated software, like Wireshark which lets you read any network traffic which is flowing through your LAN.
In case you are not using HTTPS: Use HTTPS with valid, non-self-signed certificates (like the free Let's Encrypt certificates) and enable certificate checking in Electron if you have it disabled (it's enabled by default) because Electron will then reject the self-signed certificate Fiddler uses for HTTPS traffic and thus will not make any request, which ultimately prevents Fiddler from reading them.
However, I would not bother about this issue at all. Anyone with access to the connection can sniff on it and even on HTTPS traffic if all secrets are accessible (i.e. the one sniffing sits on the same system or has access to it), so there really is no way to keep request/response information "secret" with some third party having access to all the secret stuff.

How to hide data received via HTTP requests?

I am currently designing a web application using AngularJS. In this I am fetching and posting data via Rest API(s) with different methods. The data I retrieving is fetched in the form of JSON.
Problem:
Issue here is, while I am using https, the data sent and received via HTTP requests can still be seen in proxy tool or traffic monitors. All the JSON can be easily read from this.
Each of my request has a token attached in it's header which takes care of authentication. However, once authorized, there is some part I don't want to be displayed in/ caught in such monitoring tools.
Question:
This data is stored in an encrypted way in database and all, however while coming via HTTP request, it is first decrypted and then sent. How can I hide/protect this data?
You can't.
If you give it to the client, then the client has to be able to see it.
If the user has configured their browser to proxy requests, then the proxy is the client.
Once the data leaves your server in an HTTP response then anyone/anything thing the user of the client wants to trust with that data can access it. You don't have control at that point.
proxy tool or traffic monitors will see https data only if the client has accepted the man-in-the-middle (MITM) by installing the ssl certificate used by the MITM:
To see the content (other than the host name) of an https connection, someone who is neither the client or the server must do a MITM.
If someone do a MITM with a certificate not trusted by the client, the client will reject the connection.
WARNING: If the server do NOT use HSTS, the person doing the MITM can do an SSLSTRIP attack if the first connection is http. In that case, the MITM do not need a trusted certificate because the connection will stay in plain text (http)

Camel CXF not decrypting SOAP Response

We're invoking a secured SOAP WebService using Camel CXF deployed in Fuse. In the client, we have configured TrustStore and Keystore as per the standard config. We're able to hit the server via Netscaler. The server is generating the response and sending it back to Netscaler.
When the response is received from Netscaler, it is encrypted and should be decrypted by Camel CXF. The decryption is not happening and on the client we get a parsing error since the response is all encrypted.
Any clues of what could be the problem ?
The only stackTrace that I see is that the message failed to parse because of the presence of Ctrl characters since the message is encrypted.
<http:conduit name="https.*">
<http:tlsClientParameters secureSocketProtocol="TLS">
<sec:keyManagers ref="keyManagersBean"/>
<sec:trustManagers ref="trustManagersBean"/>
</http:tlsClientParameters>
</http:conduit>
The keyManager and trustManager beans are created using a custom factory.
Also, could this issue be because apart from transport level encryption, we also need message level encryption ?
This problem was resolved. The issue was the the content was gzipped before being sent from NetScaler. Hence, after transport level decryption we could still see the headers but not the content. Adding a GZip in & fault interceptor on the CXF endpoint fixed the issue.

How to Send OCSP Request and receive OCSP response on Mobile Phone

I need to make comparison (on the basis of time) on OCSP request/response between a mobile device and desktop clients. I understand that one can use OpenSSL and other similar command line tools to check OCSP on desktop clients. But I don’t know how to go about making OCSP request on a mobile phone.
I want to send OCSP request for known certificate (e.g Facebook's) to its OSCP URL (http://ocsp.digicert.com) and obtain the certificate's revocation status.
Is there any tool or a guide on sample code (preferably J2ME) that I can use to send OCSP request and get response?
I understand that the BouncyCastle library for mobile devices has some sample classes related to OCSP. I have gone through but I have not been able to make much sense from them.
You could base64 the OCSP request and send it across on HTTP to the OCSP URL and then time it. Note that there might be a CDN that would serve the OCSP Response and that would factor in with the latency as well by reducing it.
How do you create an OCSP Request:
http://unmitigatedrisk.com/?p=42

Hotmail/Outlook.com connection failure on AUTH commands

I'm working on an embedded application (running MQX RTOS, written in C) which has SMTP functionality. Recently, TLS support was added using the Mocana NanoSSL library. I'm currently able to successfully send emails using Gmail, Yahoo, and private exchange servers. Unfortunately, Hotmail does not work. Here's the connection parameters i've used:
Server: smtp.live.com
Port: 25 and 587
AUTH method: PLAIN and LOGIN
Basically, i'm able to successfully connect to the server, perform the SSL/TLS handshake (using STARTTLS), and send the encrypted EHLO message to the server (receiving a response). According to this response, the server supports both AUTH PLAIN and AUTH LOGIN. However, once I send either of these commands, the following SSL_recv() call I make to get the response fails with either a timeout or connection reset by peer.
UPDATE:
OK, so after some experimentation it would appear that my issue lies at the SSL library level and not with Microsoft's SMTP server. I tried replacing the SSL_recv() calls with standard RTCS socket recv() calls and was able to receive and view encrypted data. By disabling my response verification, I was then able to continue through the SMTP process and successfully send a message. At this time i'm not sure why the SSL_recv() calls are unable to get the socket data, but i'll keep digging and will hopefully find an answer.
Well, I also got it working here too. I had to replace the
ssl_ctx=SSL_CTX_new(SSLv23_client_method());
with either:
ssl_ctx=SSL_CTX_new(SSLv3_client_method());
or
ssl_ctx=SSL_CTX_new(TLSv1_client_method());
My understanding is that the 23_client method sends a SSL2 client hello first and this confuses the server.
I read this in the HP SSL programming tutorial:
http://h71000.www7.hp.com/doc/83final/ba554_90007/ch04s03.html
it says: "However, the SSL client using the SSLv23 method cannot establish connection with the SSL server with the SSLv3/TLSv1 method because SSLv2 hello message is sent by the client."
SSL3 works too since you can continue after STARTTLS with SSL, you do not have to use TLS.
See here:
https://www.fastmail.fm/help/technology_ssl_vs_tls_starttls.html
So, it's the SSL library itself that appears to be failing me here. I was able to bypass the issue and successfully send email by simply not calling SSL_recv() to verify the server responses. I'm obviously not able to error check or get any meaningful failure feedback, but for a successful use case where the server accepts all of my SMTP messages the email is sent.

Resources