ROBODoc documented lib/silcrypt/silccipher.h. Patch by Toni
[silc.git] / lib / silccore / silcprivate.c
index 60534f6be8735c332d7ca31d4bb943be5914dd4b..67cb967b078c039c477cb4af05f687d5083ed7e0 100644 (file)
 
 ******************************************************************************/
 
-#define SILC_PRIVATE_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
+/* 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 {
-  uint16 flags;
-  uint16 message_len;
+  SilcUInt16 flags;
+  SilcUInt16 message_len;
   unsigned char *message;
 };
 
@@ -43,41 +54,48 @@ struct SilcPrivateMessagePayloadStruct {
    structure. This also decrypts the message if the `cipher' is provided. */
 
 SilcPrivateMessagePayload 
-silc_private_message_payload_parse(SilcBuffer buffer, SilcCipher cipher)
+silc_private_message_payload_parse(unsigned char *payload,
+                                  SilcUInt32 payload_len,
+                                  SilcCipher cipher)
 {
-  SilcPrivateMessagePayload new;
+  SilcBufferStruct buffer;
+  SilcPrivateMessagePayload newp;
   int ret;
 
   SILC_LOG_DEBUG(("Parsing private message payload"));
 
+  silc_buffer_set(&buffer, payload, payload_len);
+
   /* Decrypt the payload */
   if (cipher)
-    silc_cipher_decrypt(cipher, buffer->data, buffer->data, 
-                       buffer->len, cipher->iv);
+    silc_cipher_decrypt(cipher, buffer.data, buffer.data, 
+                       buffer.len, silc_cipher_get_iv(cipher));
 
-  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),
+  ret = silc_buffer_unformat(&buffer,
+                            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;
 }
 
@@ -85,18 +103,20 @@ silc_private_message_payload_parse(SilcBuffer buffer, SilcCipher cipher)
    the cipher is provided the packet is also encrypted here.  It is provided
    if the private message private keys are used. */
 
-SilcBuffer silc_private_message_payload_encode(uint16 flags,
-                                              uint16 data_len,
-                                              unsigned char *data,
-                                              SilcCipher cipher)
+SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
+                                              SilcUInt16 data_len,
+                                              const unsigned char *data,
+                                              SilcCipher cipher,
+                                              SilcRng rng)
 {
   int i;
   SilcBuffer buffer;
-  uint32 len, pad_len = 0;
+  SilcUInt32 len, pad_len = 0;
   unsigned char pad[16];
 
   SILC_LOG_DEBUG(("Encoding private message payload"));
 
+  data_len = SILC_PRIVATE_MESSAGE_DATALEN(data_len);
   len = 4 + data_len;
 
   if (cipher) {
@@ -109,10 +129,11 @@ SilcBuffer silc_private_message_payload_encode(uint16 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),
@@ -123,7 +144,7 @@ SilcBuffer silc_private_message_payload_encode(uint16 flags,
   if (cipher) {
     /* Encrypt payload of the packet. */
     silc_cipher_encrypt(cipher, buffer->data, buffer->data, 
-                       buffer->len, cipher->iv);
+                       buffer->len, silc_cipher_get_iv(cipher));
     memset(pad, 0, sizeof(pad));
   }
 
@@ -143,7 +164,7 @@ void silc_private_message_payload_free(SilcPrivateMessagePayload payload)
 
 /* Return flags */
 
-uint16 
+SilcUInt16 
 silc_private_message_get_flags(SilcPrivateMessagePayload payload)
 {
   return payload->flags;
@@ -153,7 +174,7 @@ silc_private_message_get_flags(SilcPrivateMessagePayload payload)
 
 unsigned char *
 silc_private_message_get_message(SilcPrivateMessagePayload payload,
-                                uint32 *message_len)
+                                SilcUInt32 *message_len)
 {
   if (message_len)
     *message_len = payload->message_len;