Added checking for maximum packet length.
[silc.git] / lib / silccore / silcchannel.c
index 8fcc4c539be5cfbbb652a702f3f8fae962a9ee3f..d104cc182aaea154b5c2e438a10e66870ea07d32 100644 (file)
@@ -230,8 +230,20 @@ SilcUInt32 silc_channel_get_mode(SilcChannelPayload payload)
 
 ******************************************************************************/
 
+/* Calculates padding length for message payload */
 #define SILC_CHANNEL_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
 
+/* Header length plus maximum padding length */
+#define SILC_CHANNEL_MESSAGE_HLEN 6 + 16
+
+/* Returns the data length that fits to the packet.  If data length is too
+   big it will be truncated to fit to the payload. */
+#define SILC_CHANNEL_MESSAGE_DATALEN(data_len, header_len)             \
+  ((data_len + SILC_CHANNEL_MESSAGE_HLEN + header_len) >               \
+   SILC_PACKET_MAX_LEN ?                                               \
+   data_len - ((data_len + SILC_CHANNEL_MESSAGE_HLEN + header_len) -   \
+              SILC_PACKET_MAX_LEN) : data_len)
+
 /* Channel Message Payload structure. Contents of this structure is parsed
    from SILC packets. */
 struct SilcChannelMessagePayloadStruct {
@@ -370,7 +382,8 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
                                               SilcUInt16 iv_len,
                                               unsigned char *iv,
                                               SilcCipher cipher,
-                                              SilcHmac hmac)
+                                              SilcHmac hmac,
+                                              SilcRng rng)
 {
   int i;
   SilcBuffer buffer;
@@ -383,6 +396,7 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
   /* Calculate length of padding. IV is not included into the calculation
      since it is not encrypted. */
   mac_len = silc_hmac_len(hmac);
+  data_len = SILC_CHANNEL_MESSAGE_DATALEN(data_len, mac_len + iv_len);
   len = 6 + data_len + mac_len;
   pad_len = SILC_CHANNEL_MESSAGE_PAD(len);
 
@@ -393,7 +407,11 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
     return NULL;
 
   /* Generate padding */
-  for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte();
+  if (rng) {
+    for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte(rng);
+  } else {
+    for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte();
+  }
 
   /* Encode the Channel Message Payload */
   silc_buffer_pull_tail(buffer, 6 + data_len + pad_len);