https://www.rfc-editor.org/rfc/rfc6520 does not explain why a heartbeat request/response round-trip is supposed to contain a payload. It just specifies that there is room for payload and that the response has to contain the same payload as the request.
What is this payload good for? My questions are:
What could it be that the engineers thought when they designed the protocol to allow for including arbitrary payload into the heartbeat request? What are the advantages?
What are the reasons that this payload must be contained in the response?
I see that by allowing for arbitrary payload the application is able to unambiguously match a certain response with a certain request. Is that the only advantage? If yes, then why did one not force the payload to be of a certain length? What is the flexibility in the payload length good for? Does it have to do with a cryptographic concept, such that the length of heartbeat requests must be unpredictable?
Other "heartbeat"-like protocol extensions simply pre-define the exact request (e.g. "ping") and the corresponding response (e.g. "pong"). Why did https://www.rfc-editor.org/rfc/rfc6520 take a different route?
It is important to understand the reasoning behind the choices made in RFC6520 in order to properly assess hypotheses that all this might have been an intelligently placed backdoor.
Regarding the arbitrary size: the rfc abtract states that the Hearbeat extension is a basis for path MTU (PMTU) discovery for DTLS. Varying the size is a basis to implement that protocol (http://en.wikipedia.org/wiki/Path_MTU_Discovery)
Regarding the arbitrary content: packet delivery may not be preserved or packets may be lost. varying the content helps to identify them
Related
Sometimes I receive this strange responses from other nodes. Transaction id match to my request transaction id as well as the remote IP so I tend to believe that node responded with this but it looks like sort of a mix of response and request
d1:q9:find_node1:rd2:id20:.éV0özý.?tjN.?.!2:ip4:DÄ.^7:nodes.v26:.ï?M.:iSµLW.Ðä¸úzDÄ.^æCe1:t2:..1:y1:re
Worst of all is that it is malformed. Look at 7:nodes.v it means that I add nodes.v to the dictionary. It is supposed to be 5:nodes. So, I'm lost. What is it?
The internet and remote nodes is unreliable or buggy. You have to code defensively. Do not assume that everything you receive will be valid.
Remote peers might
send invalid bencoding, discard those, don't even try to recover.
send truncated messages. usually not recoverable unless it happens to be the very last e of the root dictionary.
omit mandatory keys. you can either ignore those messages or return an error message
contain corrupted data
include unknown keys beyond the mandatory ones. this is not an error, just treat them as if they weren't there for the sake of forward-compatibility
actually be attackers trying to fuzz your implementation or use you as DoS amplifier
I also suspect that some really shoddy implementations are based on whatever string types their programming language supports and incorrectly handle encoding instead of using arrays of uint8 as bencoding demands. There's nothing that can be done about those. Ignore or occasionally send an error message.
Specified dictionary keys are usually ASCII-mappable, but this is not a requirement. E.g. there are some tracker response types that actually use random binary data as dictionary keys.
Here are a few examples of junk I'm seeing[1] that even fails bdecoding:
d1:ad2:id20:�w)��-��t����=?�������i�&�i!94h�#7U���P�)�x��f��YMlE���p:q9Q�etjy��r7�:t�5�����N��H�|1�S�
d1:e�����������������H#
d1:ad2:id20:�����:��m�e��2~�����9>inm�_hash20:X�j�D��nY��-������X�6:noseedi1ee1:q9:get_peers1:t2:�=1:v4:LT��1:y1:qe
d1:ad2:id20:�����:��m�e��2~�����9=inl�_hash20:X�j�D��nY���������X�6:noseedi1ee1:q9:get_peers1:t2:�=1:v4:LT��1:y1:qe
d1:ad2:id20:�����:��m�e��2~�����9?ino�_hash20:X�j�D��nY���������X�6:noseedi1ee1:q9:get_peers1:t2:�=1:v4:LT��1:y1:qe
[1] preserved char count. replaced all non-printable, ASCII-incompatible bytes with the unicode replacement character.
I am left with a few questions after reading the RFC 6520 for Heartbeat:
https://www.rfc-editor.org/rfc/rfc6520
Specifically, I don't understand why a heartbeat needs to include arbitrary payloads or even padding for that matter. From what I can understand, the purpose of the heartbeat is to verify that the other party is still paying attention at the other end of the line.
What does these variable length custom payloads provide that a fixed request and response do not?
E.g.
Alice: still alive?
Bob: still alive!
After all, FTP uses the NOOP command to keep connections alive, which seem to work fine.
There is, in fact, a reason for this payload/padding within RFC 6520
From the document:
The user can use the new HeartbeatRequest message,
which has to be answered by the peer with a HeartbeartResponse
immediately. To perform PMTU discovery, HeartbeatRequest messages
containing padding can be used as probe packets, as described in
[RFC4821].
>In particular, after a number of retransmissions without
receiving a corresponding HeartbeatResponse message having the
expected payload, the DTLS connection SHOULD be terminated.
>When a HeartbeatRequest message is received and sending a
HeartbeatResponse is not prohibited as described elsewhere in this
document, the receiver MUST send a corresponding HeartbeatResponse
message carrying an exact copy of the payload of the received
HeartbeatRequest.
If a received HeartbeatResponse message does not contain the expected
payload, the message MUST be discarded silently. If it does contain
the expected payload, the retransmission timer MUST be stopped.
Credit to pwg at HackerNews. There is a good and relevant discussion there as well.
(The following is not a direct answer, but is here to highlight related comments on another question about Heartbleed.)
There are arguments against the protocol design that allowed an arbitrary limit - either that there should have been no payload (or even echo/heartbeat feature) or that a small finite/fixed payload would have been a better design.
From the comments on the accepted answer in Is the heartbleed bug a manifestation of the classic buffer overflow exploit in C?
(R..) In regards to the last question, I would say any large echo request is malicious. It's consuming server resources (bandwidth, which costs money) to do something completely useless. There's really no valid reason for the heartbeat operation to support any length but zero
(Eric Lippert) Had the designers of the API believed that then they would not have allowed a buffer to be passed at all, so clearly they did not believe that. There must be some by-design reason to support the echo feature; why it was not a fixed-size 4 byte buffer, which seems adequate to me, I do not know.
(R..) .. Nobody thinking from a security standpoint would think that supporting arbitrary echo requests is reasonable. Even if it weren't for the heartbleed overflow issue, there may be cryptographic weaknesses related to having such control over the content the peer sends; this seems unlikely, but in the absence of a strong reason to support a[n echo] feature, a cryptographic system should not support it. It should be as simple as possible.
While I don't know the exact motivation behind this decision, it may have been motivated by the ICMP echo request packets used by the ping utility. In an ICMP echo request, an arbitrary payload of data can be attached to the packet, and the destination server will return exactly that payload if it is reachable and responding to ping requests. This can be used to verify that data is being properly sent across the network and that payloads aren't being corrupted in transit.
I have bunch of records in my offcard application and I want to save them all in javacard,
The question is:
What is the best way of transferring data to Java Card?
Should I transfer all data record by record (each one with a APDU) or send all the records in just one APDU?
Of course I know the limitation size of APDU and I'm using extended APDU in order to send all data just in one extended APDU which is more than 255 bytes..
It does not matter much if you send your data in one extended length APDU or one single APDU security wise. It is however much better to send unrelated information using separate APDU's. This would make your application much more modular. Note that if you send related information using separate APDU's, you may need to keep state between those APDU's for validation purposes (e.g. you may have to send either none or all of them, or send the APDU's in specific order).
Furthermore, ISO 7816-4 only defines 2 byte status words to send back to the sender, e.g. 8A80 to indicate any error in the command data. This means that it is impossible to tell from the status word which of the records contains failure information.
Finally, there are certainly still readers and software out there that have issues handling extended length APDU's. So if your software is going to be used by other parties you may want to stick to normal length APDU's.
guys need some insight here.
I know the definition of a protocol, being new to this c++ programming is quite a challenging
task.I am creating a Multi-threaded chat using SDL/C++, this is a learning experience for me
and now i have encounter a hump in which I need to overcome but understanding it is a little more difficult than I had thought.I need to make a chat protocol of some sort, I think...but am stump. Up until this point i have been sending messages in strings of characters.Now that am improving the application to the point where clients can register and login, I need a better way to communicating with my clients and server.
thank you.
Create objects that represent a message, then serialize the object, send it over the network, then deserialize at the other end.
For example, you could create a class called LoginMessage that contains two fields. One for a user name, and one for a password. To login, you would do something like:
LoginMessage *msg = new LoginMessage();
msg->username = "Fred";
msg->password = "you'll never guess";
char *serialized_msg = serialize(msg);
// send the bytes over the network
You would do something similar at the other end to convert the byte stream back into an object.
There are APIs for creating message objects and serializing them for you. Here are two popular ones. Both should suit your needs.
Protocol Buffers by Google
Thrift By Facebook
If you want the serialized messages to be readable, you can use YAML. Google has an API called yaml-cpp for serializing data to YAML format.
UPDATE:
Those APIs are for making your own protocol. They just handle the conversion of messages from object form to byte stream form. They do have feature for the actual transport of the messages over the network, but you don't need to use those features. How you design your protocol it up to you. But if you want to create messages by hand, you can do that too.
I'll give you some ideas for creating your own message format.
This is one way to do it.
Have the first 4 bytes of the message represent the length of the message as an unsigned integer. This is necessary to figure out where one message ends and where the next one starts. You will need to convert between host and network byte order when reading and writing to/from these four bytes.
Have the 5th byte represent the message type. For example, you could use a 1 to indicate a login request, a 2 to indicate a login response, and 3 to indicate a chat message. This byte is necessary for interpreting the meaning of the remaining bytes.
The remaining bytes would contain the message contents. For example, if it was a login message, you would encode the username and password into these bytes somehow. If it is a chat message, these bytes would contain the chat text.
I had a discussion with a developer earlier today re identifying TCP packets going out on a particular interface with the same payload. He told me that the probability of finding a TCP packet that has an equal payload (even if the same data is sent out several times) is very low due to the way TCP packets are constructed at system level. I was aware this may be the case due to the system's MTU settings (usually 1500 bytes) etc., but what sort of probability stats am I really looking at? Are there any specific protocols that would make it easier identifying matching payloads?
It is the protocol running over tcp that defines the uniqueness of the payload, not the tcp protocol itself.
For example, you might naively think that HTTP requests would all be identical when asking for a server's home page, but the referrer and user agent strings make the payloads different.
Similarly, if the response is dynamically generated, it may have a date header:
Date: Fri, 12 Sep 2008 10:44:27 GMT
So that will render the response payloads different. However, subsequent payloads may be identical, if the content is static.
Keep in mind that the actual packets will be different because of differing sequence numbers, which are supposed to be incrementing and pseudorandom.
Chris is right. More specifically, two or three pieces of information in the packet header should be different:
the sequence number (which is
intended to be unpredictable) which
is increases with the number of
bytes transmitted and received.
the timestamp, a field containing two
timestamps (although this field is optional).
the checksum, since both the payload and header are checksummed, including the changing sequence number.
EDIT: Sorry, my original idea was ridiculous.
You got me interested so I googled a little bit and found this. If you wanted to write your own tool you would probably have to inspect each payload, the easiest way would probably be some sort of hash/checksum to check for identical payloads. Just make sure you are checking the payload, not the whole packet.
As for the statistics I will have to defer to someone with greater knowledge on the workings of TCP.
Sending the same PAYLOAD is probably fairly common (particularly if you're running some sort of network service). If you mean sending out the same tcp segment (header and all) or the whole network packet (ip and up), then the probability is substantially reduced.