updates
[crypto.git] / lib / silccore / silcprivate.c
index 26a064297028477ee2dba73f94da60fce0220509..3ddf730751bdda1dca22bffa658de6ed6cfc6eda 100644 (file)
 
 ******************************************************************************/
 
+/* Calculates padding length for message payload */
 #define SILC_PRIVATE_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
 
+/* Header length plus maximum padding length */
+#define SILC_PRIVATE_MESSAGE_HLEN 4 + 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_PRIVATE_MESSAGE_DATALEN(data_len)                         \
+  ((data_len + SILC_PRIVATE_MESSAGE_HLEN) > SILC_PACKET_MAX_LEN ?      \
+   data_len - ((data_len + SILC_PRIVATE_MESSAGE_HLEN) -                \
+              SILC_PACKET_MAX_LEN) : data_len)
+
 /* Private Message Payload structure. Contents of this structure is parsed
    from SILC packets. */
 struct SilcPrivateMessagePayloadStruct {
@@ -48,7 +59,7 @@ silc_private_message_payload_parse(unsigned char *payload,
                                   SilcCipher cipher)
 {
   SilcBufferStruct buffer;
-  SilcPrivateMessagePayload new;
+  SilcPrivateMessagePayload newp;
   int ret;
 
   SILC_LOG_DEBUG(("Parsing private message payload"));
@@ -60,29 +71,31 @@ silc_private_message_payload_parse(unsigned char *payload,
     silc_cipher_decrypt(cipher, buffer.data, buffer.data, 
                        buffer.len, cipher->iv);
 
-  new = silc_calloc(1, sizeof(*new));
+  newp = silc_calloc(1, sizeof(*newp));
+  if (!newp)
+    return NULL;
 
   /* Parse the Private Message Payload. Ignore the padding. */
   ret = silc_buffer_unformat(&buffer,
-                            SILC_STR_UI_SHORT(&new->flags),
-                            SILC_STR_UI16_NSTRING_ALLOC(&new->message, 
-                                                        &new->message_len),
+                            SILC_STR_UI_SHORT(&newp->flags),
+                            SILC_STR_UI16_NSTRING_ALLOC(&newp->message, 
+                                                        &newp->message_len),
                             SILC_STR_END);
   if (ret == -1) {
     SILC_LOG_DEBUG(("Incorrect private message payload"));
     goto err;
   }
 
-  if ((new->message_len < 1 || new->message_len > buffer.len)) {
+  if ((newp->message_len < 1 || newp->message_len > buffer.len - 4)) {
     SILC_LOG_DEBUG(("Incorrect private message payload in packet, "
                    "packet dropped"));
     goto err;
   }
 
-  return new;
+  return newp;
 
  err:
-  silc_private_message_payload_free(new);
+  silc_private_message_payload_free(newp);
   return NULL;
 }
 
@@ -93,7 +106,8 @@ silc_private_message_payload_parse(unsigned char *payload,
 SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
                                               SilcUInt16 data_len,
                                               const unsigned char *data,
-                                              SilcCipher cipher)
+                                              SilcCipher cipher,
+                                              SilcRng rng)
 {
   int i;
   SilcBuffer buffer;
@@ -102,6 +116,7 @@ SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
 
   SILC_LOG_DEBUG(("Encoding private message payload"));
 
+  data_len = SILC_PRIVATE_MESSAGE_DATALEN(data_len);
   len = 4 + data_len;
 
   if (cipher) {
@@ -114,10 +129,11 @@ SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
   }
 
   /* Allocate private message payload buffer */
-  buffer = silc_buffer_alloc(len);
+  buffer = silc_buffer_alloc_size(len);
+  if (!buffer)
+    return NULL;
 
   /* Encode the Channel Message Payload */
-  silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
   silc_buffer_format(buffer, 
                     SILC_STR_UI_SHORT(flags),
                     SILC_STR_UI_SHORT(data_len),