Merge commit 'origin/silc.1.1.branch'
[silc.git] / lib / silccore / silcmessage.h
index 32e40c93498ce3f8582ad6fb4acc5142ff0dd16d..ef6ed3a8af6778147fe470cef49fd99c15c74ce0 100644 (file)
@@ -1,10 +1,10 @@
 /*
 
-  silcmessage.h 
+  silcmessage.h
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2002 Pekka Riikonen
+  Copyright (C) 1997 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
  * DESCRIPTION
  *
  * This interface includes the implementation of the Message Payload that
- * is used to send private messages and channel messages.
- *
- * This interface defines also the SILC_MESSAGE_FLAG_SIGNED Payload,
- * which defines how channel messages and private messages can be digitally
- * signed.  This interface provides the payload parsing, encoding, 
- * signature computing and signature verification routines.
+ * is used to send private messages and channel messages.  The interface
+ * is also able to automatically provide digital signature in the messages
+ * if it is requested.  Message digital signatures may also be verified with
+ * this interface.
  *
  ***/
 
@@ -37,8 +35,9 @@
 /****s* silccore/SilcMessageAPI/SilcMessagePayload
  *
  * NAME
- * 
- *    typedef struct SilcMessagePayloadStruct *SilcMessagePayload;
+ *
+ *    typedef struct SilcMessagePayloadObject
+ *      *SilcMessagePayload, SilcMessagePayloadStruct;
  *
  *
  * DESCRIPTION
  *    silc_message_payload_free function.
  *
  ***/
-typedef struct SilcMessagePayloadStruct *SilcMessagePayload;
-
-/****s* silccore/SilcMessageAPI/SilcMessageSignedPayload
- *
- * NAME
- * 
- *    typedef struct SilcMessageSignedPayloadStruct *SilcMessageSignedPayload;
- *
- *
- * DESCRIPTION
- *
- *    This context represents the SILC_MESSAGE_FLAG_SIGNED Payload which
- *    is used with channel messages and private messages to indicate that
- *    the message is digitally signed.  This payload may include the
- *    message sender's public key and it includes the digital signature.
- *    This payload MUST NOT be used in any other context except with
- *    channel and private message sending and reception.
- *
- ***/
-typedef struct SilcMessageSignedPayloadStruct *SilcMessageSignedPayload;
+typedef struct SilcMessagePayloadObject
+  *SilcMessagePayload, SilcMessagePayloadStruct;
 
 /****d* silccore/SilcMessageAPI/SilcMessageFlags
  *
  * NAME
- * 
+ *
  *    typedef SilcUInt16 SilcMessageFlags;
  *
  * DESCRIPTION
  *
- *    The message flags type definition and the message flags.  The 
+ *    The message flags type definition and the message flags.  The
  *    message flags are used to indicate some status of the message.
  *
  * SOURCE
@@ -97,7 +78,8 @@ typedef SilcUInt16 SilcMessageFlags;
 #define SILC_MESSAGE_FLAG_DATA        0x0080     /* MIME object */
 #define SILC_MESSAGE_FLAG_UTF8        0x0100     /* UTF-8 string */
 #define SILC_MESSAGE_FLAG_ACK         0x0200     /* ACK messages */
-#define SILC_MESSAGE_FLAG_RESERVED    0x0400     /* to 0x1000 */
+#define SILC_MESSAGE_FLAG_STOP        0x0400      /* Stop indication */
+#define SILC_MESSAGE_FLAG_RESERVED    0x0800      /* to 0x1000 */
 #define SILC_MESSAGE_FLAG_PRIVATE     0x2000     /* to 0x8000 */
 /***/
 
@@ -105,13 +87,17 @@ typedef SilcUInt16 SilcMessageFlags;
  *
  * SYNOPSIS
  *
- *    bool silc_message_payload_decrypt(unsigned char *data,
- *                                      size_t data_len,
- *                                      bool private_message,
- *                                      bool static_key,
- *                                      SilcCipher cipher,
- *                                      SilcHmac hmac,
- *                                      bool check_mac);
+ *    SilcBool silc_message_payload_decrypt(unsigned char *data,
+ *                                          size_t data_len,
+ *                                          SilcBool private_message,
+ *                                          SilcBool static_key,
+ *                                          SilcCipher cipher,
+ *                                          SilcHmac hmac,
+ *                                          unsigned char *sender_id,
+ *                                          SilcUInt32 sender_id_len,
+ *                                          unsigned char *receiver_id,
+ *                                          SilcUInt32 receiver_id_len,
+ *                                          SilcBool check_mac);
  *
  * DESCRIPTION
  *
@@ -123,32 +109,46 @@ typedef SilcUInt16 SilcMessageFlags;
  *    (Key Agreement was done for the key) then it MUST be FALSE.  For
  *    channel messages the `static_key' is ignored.
  *
+ *    The `sender_id' and `receiver_id' are the IDs from the packet header
+ *    of the packet where this message payload was received.
+ *
  *    This is usually used by the Message Payload interface itself but can
  *    be called by the appliation if separate decryption process is required.
- *    For example server might need to call this directly in some 
+ *    For example server might need to call this directly in some
  *    circumstances. The `cipher' is used to decrypt the payload.  If
  *    `check_mac' is FALSE then MAC is not verified.
  *
  ***/
-bool silc_message_payload_decrypt(unsigned char *data,
-                                 size_t data_len,
-                                 bool private_message,
-                                 bool static_key,
-                                 SilcCipher cipher,
-                                 SilcHmac hmac,
-                                 bool check_mac);
+SilcBool silc_message_payload_decrypt(unsigned char *data,
+                                     size_t data_len,
+                                     SilcBool private_message,
+                                     SilcBool static_key,
+                                     SilcCipher cipher,
+                                     SilcHmac hmac,
+                                     unsigned char *sender_id,
+                                     SilcUInt32 sender_id_len,
+                                     unsigned char *receiver_id,
+                                     SilcUInt32 receiver_id_len,
+                                     SilcBool check_mac);
 
 /****f* silccore/SilcMessageAPI/silc_message_payload_parse
  *
  * SYNOPSIS
  *
- *    SilcMessagePayload 
+ *    SilcMessagePayload
  *    silc_message_payload_parse(unsigned char *payload,
  *                               SilcUInt32 payload_len,
- *                               bool private_message,
- *                               bool static_key,
+ *                               SilcBool private_message,
+ *                               SilcBool static_key,
  *                               SilcCipher cipher,
- *                               SilcHmac hmac);
+ *                               SilcHmac hmac,
+ *                               unsigned char *sender_id,
+ *                               SilcUInt32 sender_id_len,
+ *                               unsigned char *receiver_id,
+ *                               SilcUInt32 receiver_id_len,
+ *                               SilcStack stack,
+ *                               SilcBool no_allocation,
+ *                               SilcMessagePayload message);
  *
  * DESCRIPTION
  *
@@ -166,26 +166,45 @@ bool silc_message_payload_decrypt(unsigned char *data,
  *    then this assumes that the packet was decrypted with session keys
  *    (no private message key) and this merely decodes the payload.
  *
+ *    The `sender_id' and `receiver_id' are the IDs from the packet header
+ *    of the packet where this message payload was received.
+ *
+ *    If the `message' is non-NULL then that pre-allocated context is
+ *    used in parsing.  Same context is returned.  Otherwise new context
+ *    is allocated and returned.  If the `stack' is non-NULL then memory
+ *    is allocated from that stack.  If `no_allocation' is TRUE then the
+ *    `message' must be provided and data is merely parsed and referenced
+ *    from `payload' and will become invalid when `payload' invalidates.
+ *    If `no_allocation' is TRUE the routine does not do any allocations.
+ *
  ***/
-SilcMessagePayload 
+SilcMessagePayload
 silc_message_payload_parse(unsigned char *payload,
                           SilcUInt32 payload_len,
-                          bool private_message,
-                          bool static_key,
+                          SilcBool private_message,
+                          SilcBool static_key,
                           SilcCipher cipher,
-                          SilcHmac hmac);
+                          SilcHmac hmac,
+                          unsigned char *sender_id,
+                          SilcUInt32 sender_id_len,
+                          unsigned char *receiver_id,
+                          SilcUInt32 receiver_id_len,
+                          SilcStack stack,
+                          SilcBool no_allocation,
+                          SilcMessagePayload message);
 
 /****f* silccore/SilcMessageAPI/silc_message_payload_encrypt
  *
  * SYNOPSIS
  *
- *    bool silc_message_payload_encrypt(unsigned char *data,
- *                                      SilcUInt32 data_len,
- *                                      SilcUInt32 true_len,
- *                                      unsigned char *iv,
- *                                      SilcUInt32 iv_len,
- *                                      SilcCipher cipher,
- *                                      SilcHmac hmac);
+ *    SilcBool silc_message_payload_encrypt(unsigned char *data,
+ *                                          SilcUInt32 data_len,
+ *                                          SilcUInt32 true_len,
+ *                                          unsigned char *iv,
+ *                                          SilcID *sender_id,
+ *                                          SilcID *receiver_id,
+ *                                          SilcCipher cipher,
+ *                                          SilcHmac hmac);
  *
  * DESCRIPTION
  *
@@ -193,47 +212,73 @@ silc_message_payload_parse(unsigned char *payload,
  *    the `data' and `data_len'.  The `data_len' is the data length which
  *    is used to create MAC out of.  The `data' MUST have additional space
  *    after `true_len' bytes for the MAC which is appended to the data.
+ *    The `sender_id' is the ID message sender and `receiver_id' is ID of
+ *    message receiver.
  *
  *    This is usually used by the Message Payload interface itself but can
  *    be called by the appliation if separate encryption process is required.
- *    For example server might need to call this directly in some 
+ *    For example server might need to call this directly in some
  *    circumstances. The `cipher' is used to encrypt the payload and `hmac'
  *    to compute the MAC for the payload.
  *
  ***/
-bool silc_message_payload_encrypt(unsigned char *data,
-                                 SilcUInt32 data_len,
-                                 SilcUInt32 true_len,
-                                 unsigned char *iv,
-                                 SilcUInt32 iv_len,
-                                 SilcCipher cipher,
-                                 SilcHmac hmac);
+SilcBool silc_message_payload_encrypt(unsigned char *data,
+                                     SilcUInt32 data_len,
+                                     SilcUInt32 true_len,
+                                     unsigned char *iv,
+                                     SilcID *sender_id,
+                                     SilcID *receiver_id,
+                                     SilcCipher cipher,
+                                     SilcHmac hmac);
+
+/****f* silccore/SilcMessageAPI/SilcMessagePayloadEncoded
+ *
+ * SYNOPSIS
+ *
+ *    typedef void (*SilcMessagePayloadEncoded)(const SilcBuffer message,
+ *                                              void *context);
+ *
+ * DESCRIPTION
+ *
+ *    This callback is given as arugment to silc_message_payload_encode
+ *    and will be called when the message payload has been encoded.  If
+ *    `message' is NULL, encoding failed.
+ *
+ ***/
+typedef void (*SilcMessagePayloadEncoded)(SilcBuffer message,
+                                         void *context);
 
 /****f* silccore/SilcMessageAPI/silc_message_payload_encode
  *
  * SYNOPSIS
  *
- *    SilcBuffer silc_message_payload_encode(SilcMessageFlags flags,
- *                                           const unsigned char *data,
- *                                           SilcUInt32 data_len,
- *                                           bool generate_iv,
- *                                           bool private_message,
- *                                           SilcCipher cipher,
- *                                           SilcHmac hmac,
- *                                           SilcRng rng,
- *                                           SilcPublicKey public_key,
- *                                           SilcPrivateKey private_key,
- *                                           SilcHash hash);
+ *    SilcAsyncOperation
+ *    silc_message_payload_encode(SilcMessageFlags flags,
+ *                                const unsigned char *data,
+ *                                SilcUInt32 data_len,
+ *                                SilcBool generate_iv,
+ *                                SilcBool private_message,
+ *                                SilcCipher cipher,
+ *                                SilcHmac hmac,
+ *                                SilcRng rng,
+ *                                SilcPublicKey public_key,
+ *                                SilcPrivateKey private_key,
+ *                                SilcHash hash,
+ *                                SilcID *sender_id,
+ *                                SilcID *receiver_id,
+ *                                SilcStack stack,
+ *                                SilcMessagePayloadEncoded encoded,
+ *                                void *context);
  *
  * DESCRIPTION
  *
- *    Encodes a Message Payload into a buffer and returns it.  This is
- *    used to encode channel messages and private messages into a packet.
- *    If `private_message' is FALSE then this encodes channel message, if
- *    it is TRUE this encodes private message.  If `private_message' is
- *    TRUE then `generate_iv' MUST be FALSE if the private message key
- *    `cipher' is not static key (pre-shared key).  If it is static key
- *    then protocol dictates that IV must be present in the Message Payload
+ *    Encodes a Message Payload into a buffer and returns it to the `encoded'
+ *    callback.  This is used to encode channel messages and private messages
+ *    into a packet.  If `private_message' is FALSE then this encodes channel
+ *    message, if it is TRUE this encodes private message.  If
+ *    `private_message' is TRUE then `generate_iv' MUST be FALSE if the private
+ *    message key `cipher' is not static key (pre-shared key).  If it is static
+ *    key then protocol dictates that IV must be present in the Message Payload
  *    and `generate_iv' must be TRUE.  The caller must know whether the key
  *    is static or not for private messages.  If the key was generated with
  *    Key Agreement protocol then `generate_iv' is always FALSE.  For
@@ -253,18 +298,31 @@ bool silc_message_payload_encrypt(unsigned char *data,
  *    be included in the message.  The `private_message' and `hash' MUST
  *    be provided.  The `hash' SHOULD be SHA1.
  *
+ *    The `sender_id' is the ID message sender and `receiver_id' is ID of
+ *    message receiver.
+ *
+ *    If `stack' is non-NULL the message payload is allocated from stack.
+ *    The memory will be returned back to `stack' after the `encoded' has
+ *    been called.
+ *
  ***/
-SilcBuffer silc_message_payload_encode(SilcMessageFlags flags,
-                                      const unsigned char *data,
-                                      SilcUInt32 data_len,
-                                      bool generate_iv,
-                                      bool private_message,
-                                      SilcCipher cipher,
-                                      SilcHmac hmac,
-                                      SilcRng rng,
-                                      SilcPublicKey public_key,
-                                      SilcPrivateKey private_key,
-                                      SilcHash hash);
+SilcAsyncOperation
+silc_message_payload_encode(SilcMessageFlags flags,
+                           const unsigned char *data,
+                           SilcUInt32 data_len,
+                           SilcBool generate_iv,
+                           SilcBool private_message,
+                           SilcCipher cipher,
+                           SilcHmac hmac,
+                           SilcRng rng,
+                           SilcPublicKey public_key,
+                           SilcPrivateKey private_key,
+                           SilcHash hash,
+                           SilcID *sender_id,
+                           SilcID *receiver_id,
+                           SilcStack stack,
+                           SilcMessagePayloadEncoded encoded,
+                           void *context);
 
 /****f* silccore/SilcMessageAPI/silc_message_payload_free
  *
@@ -318,161 +376,61 @@ unsigned char *silc_message_get_data(SilcMessagePayload payload,
  *
  * DESCRIPTION
  *
- *    Return the MAC of the payload. The caller must already know the 
+ *    Return the MAC of the payload. The caller must already know the
  *    length of the MAC. The caller must not free the MAC.
  *
  ***/
 unsigned char *silc_message_get_mac(SilcMessagePayload payload);
 
-/****f* silccore/SilcMessageAPI/silc_message_get_iv
- *
- * SYNOPSIS
- *
- *    unsigned char *
- *    silc_message_get_iv(SilcMessagePayload payload);
- *
- * DESCRIPTION
- *
- *    Return the IV of the payload. The caller must already know the 
- *    length of the IV. The caller must not free the IV.
- *
- ***/
-unsigned char *silc_message_get_iv(SilcMessagePayload payload);
-
-/****f* silccore/SilcMessageAPI/silc_message_get_signature
- *
- * SYNOPSIS
- *
- *    SilcMessageSignedPayload
- *    silc_message_get_signature(SilcMessagePayload payload);
- *
- * DESCRIPTION
- *
- *    Returns the pointer to the signature of the message if the
- *    SILC_MESSAGE_FLAG_SIGNED was set.  If the flag is set and this
- *    function returns NULL then error had occurred and the signature
- *    could not be retrieved from the message.
- *
- *    The caller SHOULD verify the signature by calling the
- *    silc_message_signed_verify function.  Caller must not free the
- *    returned payload pointer.
- *
- ***/
-SilcMessageSignedPayload
-silc_message_get_signature(SilcMessagePayload payload);
-
-/****f* silccore/SilcMessageAPI/silc_message_signed_payload_parse
- *
- * SYNOPSIS
- *
- *    SilcMessageSignedPayload
- *    silc_message_signed_payload_parse(const unsigned char *data,
- *                                      SilcUInt32 data_len);
- *
- * DESCRIPTION
- *
- *    Parses the SilcMessageSignedPayload Payload from the `data' of
- *    length of `data_len' bytes.  The `data' must be payload without
- *    the actual message payload.  Returns the parsed payload or NULL
- *    on error.  Caller must free the returned payload.  Application
- *    usually does not need to call this since the function
- *    silc_message_payload_parse calls this automatically for signed
- *    messages.
- *
- ***/
-SilcMessageSignedPayload
-silc_message_signed_payload_parse(const unsigned char *data,
-                                 SilcUInt32 data_len);
-
-/****f* silccore/SilcMessageAPI/silc_message_signed_payload_encode
- *
- * SYNOPSIS
- *
- *    SilcBuffer
- *    silc_message_signed_payload_encode(const unsigned char *message_payload,
- *                                       SilcUInt32 message_payload_len,
- *                                       SilcPublicKey public_key,
- *                                       SilcPrivateKey private_key,
- *                                       SilcHash hash);
- *
- * DESCRIPTION
- *
- *    Encodes the SilcMessageSignedPayload Payload and computes the
- *    digital signature.  The `message_payload' is the message data that
- *    is used in the signature computation.  The encoding of the buffer
- *    is specified in the SILC protocol.  If `public_key' is provided
- *    then the public key included in the payload.  The `private_key'
- *    is used to produce the signature.  This function returns the encoded
- *    payload with the signature or NULL on error.  Caller must free the
- *    returned buffer.  The `hash' SHOULD be SHA-1 hash function.
- *    
- *    Application usually does not need to call this since the function
- *    silc_message_payload_encode calls this automatically if the caller
- *    wants to sign the message.
- *
- ***/
-SilcBuffer
-silc_message_signed_payload_encode(const unsigned char *message_payload,
-                                  SilcUInt32 message_payload_len,
-                                  SilcPublicKey public_key,
-                                  SilcPrivateKey private_key,
-                                  SilcHash hash);
-
-/****f* silccore/SilcMessageAPI/silc_message_signed_payload_free
- *
- * SYNOPSIS
- *
- *    void silc_message_signed_payload_free(SilcMessageSignedPayload sig);
- *
- * DESCRIPTION
- *
- *    Frees the SilcMessageSignedPayload Payload.
- *
- ***/
-void silc_message_signed_payload_free(SilcMessageSignedPayload sig);
-
 /****f* silccore/SilcMessageAPI/silc_message_signed_verify
  *
  * SYNOPSIS
  *
- *    int silc_message_signed_verify(SilcMessageSignedPayload sig,
- *                                   SilcMessagePayload message,
- *                                   SilcPublicKey remote_public_key,
- *                                   SilcHash hash);
+ *    SilcAsyncOperation
+ *    silc_message_signed_verify(SilcMessagePayload message,
+ *                               SilcPublicKey remote_public_key,
+ *                               SilcHash hash,
+ *                               SilcAuthResultCb result,
+ *                               void *context);
+ *
  *
  * DESCRIPTION
  *
- *    This routine can be used to verify the signature found in
- *    SilcMessageSignedPayload Payload.  This returns SILC_AUTH_OK if the
- *    signature verification was successful.
+ *    This routine can be used to verify the digital signature from the
+ *    message indicated by `message'.  The signature is present only if
+ *    the SILC_MESSAGE_FLAG_SIGNED is set in the message flags.  The
+ *    result of the verification is returned to `result' callback.
  *
  ***/
-int silc_message_signed_verify(SilcMessageSignedPayload sig,
-                              SilcMessagePayload message,
-                              SilcPublicKey remote_public_key,
-                              SilcHash hash);
+SilcAsyncOperation silc_message_signed_verify(SilcMessagePayload message,
+                                             SilcPublicKey remote_public_key,
+                                             SilcHash hash,
+                                             SilcAuthResultCb result,
+                                             void *context);
 
 /****f* silccore/SilcMessageAPI/silc_message_signed_get_public_key
  *
  * SYNOPSIS
  *
  *    SilcPublicKey
- *    silc_message_signed_get_public_key(SilcMessageSignedPayload sig,
- *                                       unsigned char **pk_data,
+ *    silc_message_signed_get_public_key(SilcMessagePayload payload,
+ *                                       const unsigned char **pk_data,
  *                                       SilcUInt32 *pk_data_len);
  *
  * DESCRIPTION
  *
- *    Returns the decoded SilcPublicKey from the SilcMessageSignedPayload
- *    Payload or NULL if it does not include public key.  The caller must
- *    free the returned public key pointer.  This also returns the raw
- *    public key (before decoding) into `pk_data' and `pk_data_len' if
- *    they are provided.  The caller must not free these pointers.
+ *    Returns the decoded SilcPublicKey from the message payload or NULL
+ *    if it does not include public key.  The caller must free the returned
+ *    public key pointer.  This also returns the raw public key (before
+ *    decoding) into `pk_data' and `pk_data_len' if they are provided.  The
+ *    caller must not free these pointers.
  *
  ***/
 SilcPublicKey
-silc_message_signed_get_public_key(SilcMessageSignedPayload sig,
-                                  unsigned char **pk_data,
+silc_message_signed_get_public_key(SilcMessagePayload payload,
+                                  const unsigned char **pk_data,
                                   SilcUInt32 *pk_data_len);
 
+#include "silcmessage_i.h"
+
 #endif /* SILCMESSAGE_H */