From: Pekka Riikonen Date: Fri, 22 Nov 2002 20:06:39 +0000 (+0000) Subject: Unified Channel Message Payload and Private Message Payload X-Git-Tag: silc.server.0.9.6~35 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=054c9b2c9b21c3cbe87e53c0e0bacb2bff918e68 Unified Channel Message Payload and Private Message Payload into one Message Payload. Removed the old implementations and added silcmessage.[ch]. --- diff --git a/doc/CodingStyle b/doc/CodingStyle index cf84647e..6b6b2ff9 100644 --- a/doc/CodingStyle +++ b/doc/CodingStyle @@ -631,8 +631,7 @@ int main() Copyrights of the Code ====================== -The original code in SILC is GPL licensed. MPI is GPL licensed as well -and zlib is with free license as well. New code will be accepted to +The original code in SILC is GPL licensed. New code will be accepted to the official SILC source tree if it is coded in GPL or similiar free license as GPL is, and of course if it is public domain. Code with restricting licenses will not be accepted to the SILC source tree. diff --git a/doc/Makefile.am.pre b/doc/Makefile.am.pre index 1e11f436..e0733aee 100644 --- a/doc/Makefile.am.pre +++ b/doc/Makefile.am.pre @@ -24,12 +24,12 @@ DIST_SUBDIRS = SILC_DISTRIBUTION_SUBDIRS makerfc = ../scripts/makerfc all: - touch draft-riikonen-silc-spec-05.txt - touch draft-riikonen-silc-pp-05.txt - touch draft-riikonen-silc-ke-auth-05.txt - touch draft-riikonen-silc-commands-03.txt - touch draft-riikonen-silc-flags-payloads-00.txt - touch draft-riikonen-presence-attrs-00.txt + touch draft-riikonen-silc-spec-06.txt + touch draft-riikonen-silc-pp-06.txt + touch draft-riikonen-silc-ke-auth-06.txt + touch draft-riikonen-silc-commands-04.txt + touch draft-riikonen-silc-flags-payloads-01.txt + touch draft-riikonen-presence-attrs-01.txt if SILC_DIST_TOOLKIT toolkit-ref-html: @@ -56,35 +56,35 @@ toolkit-ref-pdf: dist-hook: $(SILC_TOP_SRCDIR)/scripts/manpages.pl - touch draft-riikonen-silc-spec-05.txt - touch draft-riikonen-silc-pp-05.txt - touch draft-riikonen-silc-ke-auth-05.txt - touch draft-riikonen-silc-commands-03.txt - touch draft-riikonen-silc-flags-payloads-00.txt - touch draft-riikonen-presence-attrs-00.txt - $(makerfc) draft-riikonen-silc-spec-05.nroff \ - draft-riikonen-silc-spec-05.txt - $(makerfc) draft-riikonen-silc-pp-05.nroff \ - draft-riikonen-silc-pp-05.txt - $(makerfc) draft-riikonen-silc-ke-auth-05.nroff \ - draft-riikonen-silc-ke-auth-05.txt - $(makerfc) draft-riikonen-silc-commands-03.nroff \ - draft-riikonen-silc-commands-03.txt - $(makerfc) draft-riikonen-silc-flags-payloads-00.nroff \ - draft-riikonen-silc-flags-payloads-00.txt - $(makerfc) draft-riikonen-presence-attrs-00.nroff \ - draft-riikonen-presence-attrs-00.txt + touch draft-riikonen-silc-spec-06.txt + touch draft-riikonen-silc-pp-06.txt + touch draft-riikonen-silc-ke-auth-06.txt + touch draft-riikonen-silc-commands-04.txt + touch draft-riikonen-silc-flags-payloads-01.txt + touch draft-riikonen-presence-attrs-01.txt + $(makerfc) draft-riikonen-silc-spec-06.nroff \ + draft-riikonen-silc-spec-06.txt + $(makerfc) draft-riikonen-silc-pp-06.nroff \ + draft-riikonen-silc-pp-06.txt + $(makerfc) draft-riikonen-silc-ke-auth-06.nroff \ + draft-riikonen-silc-ke-auth-06.txt + $(makerfc) draft-riikonen-silc-commands-04.nroff \ + draft-riikonen-silc-commands-04.txt + $(makerfc) draft-riikonen-silc-flags-payloads-01.nroff \ + draft-riikonen-silc-flags-payloads-01.txt + $(makerfc) draft-riikonen-presence-attrs-01.nroff \ + draft-riikonen-presence-attrs-01.txt else dist-hook: $(SILC_TOP_SRCDIR)/scripts/manpages.pl rm draft-riikonen*.txt - touch draft-riikonen-silc-spec-05.txt - touch draft-riikonen-silc-pp-05.txt - touch draft-riikonen-silc-ke-auth-05.txt - touch draft-riikonen-silc-commands-03.txt - touch draft-riikonen-silc-flags-payloads-00.txt - touch draft-riikonen-presence-attrs-00.txt + touch draft-riikonen-silc-spec-06.txt + touch draft-riikonen-silc-pp-06.txt + touch draft-riikonen-silc-ke-auth-06.txt + touch draft-riikonen-silc-commands-04.txt + touch draft-riikonen-silc-flags-payloads-01.txt + touch draft-riikonen-presence-attrs-01.txt endif if SILC_DIST_TOOLKIT diff --git a/doc/draft-riikonen-presence-attrs-01.nroff b/doc/draft-riikonen-presence-attrs-01.nroff index 6ac5ce94..1d0bc1b0 100644 --- a/doc/draft-riikonen-presence-attrs-01.nroff +++ b/doc/draft-riikonen-presence-attrs-01.nroff @@ -8,7 +8,7 @@ .ds RF FORMFEED[Page %] .ds CF .ds LH Internet Draft -.ds RH XXX +.ds RH 25 November 2002 .ds CH .na .hy 0 @@ -16,14 +16,14 @@ .nf Network Working Group P. Riikonen Internet-Draft -draft-riikonen-presence-attrs-00.txt XXX -Expires: XXX +draft-riikonen-presence-attrs-01.txt 25 November 2002 +Expires: 25 April 2003 .in 3 .ce 2 User Online Presence and Information Attributes - + .ti 0 Status of this Memo @@ -81,7 +81,7 @@ Table of Contents 2.5 Attributes ................................................ 5 3 Security Considerations ....................................... 11 4 References .................................................... 12 -5 Author's Address .............................................. 12 +5 Author's Address .............................................. 13 .ti 0 @@ -423,8 +423,8 @@ multiple same attributes in the packet. describing the accuracy of the information can also be provided. Length Type Value - variable string Longitude - variable string Latitude + variable string Longitude (ex. 31 17 14.321W) + variable string Latitude (ex. 12 11 21.2N) variable string Altitude variable string Accuracy in meters @@ -583,7 +583,7 @@ Even though the attributes would be digitally signed by the sender of the attributes, the information contained in the attribute may still be incorrect. The third party server should not apply digital signature unless it can verify every attribute. The receiver of the attributes -should also not trust that the information infact is correct. +should also not trust that the information in fact is correct. However, it is possible that the context where these attributes are used the attributes are provided by a party that can provide the accurate @@ -623,6 +623,8 @@ attributes on behalf of the actual user for some of the attributes. Version 1.5", RFC 2315, March 1998. + + .ti 0 5 Author's Address @@ -633,4 +635,4 @@ Finland EMail: priikone@iki.fi -This Internet-Draft expires XXX +This Internet-Draft expires 25 April 2003 diff --git a/doc/draft-riikonen-silc-commands-04.nroff b/doc/draft-riikonen-silc-commands-04.nroff index 0dfaabeb..773b83ab 100644 --- a/doc/draft-riikonen-silc-commands-04.nroff +++ b/doc/draft-riikonen-silc-commands-04.nroff @@ -595,41 +595,60 @@ List of all defined commands in SILC follows. Max Arguments: 4 Arguments: (1) (2) [] - (3) [] (4) [] + (3) [] (4) [] - This command is used to invite other clients to join to the - channel. The argument is the target client's ID that - is being invited. The is the Channel ID of the - requested channel. The sender of this command MUST be on the - channel. The server MUST also send the notify type - SILC_NOTIFY_TYPE_INVITE to its primary router and then to the - client indicated by the . + This command can be used to invite other clients to join to a + channel, and to manage the channel's invite list. The argument is the target client's ID that is being invited. + The is the Channel ID of the requested channel. + The sender of this command MUST be on the channel. The server + MUST also send the notify type SILC_NOTIFY_TYPE_INVITE to its + primary router and then to the client indicated by the . - The and can be used to add to - and remove from the invite list. The format of the - and is as follows: + The is an argument of size of 1 byte where 0x00 means + adding a client to invite list, and 0x01 means deleting a client + from invite list. The , if present, indicates + the information to be added to or removed from the invite list. + It may include a string for matching clients, public key of a + client or Client ID of a client. The format is + as follows: - [[@]!][]@[] + 2 bytes - Number of arguments in the list + variable length - Argument Payloads + + The following Argument Types has been defined for invite list + Argument Payloads: + + 0x01 - Argument is an invite string of following format: + + [[@]!][]@[] + + The may also be in format of IP/MASK to indicate + a network. + + 0x02 - Argument is the public key of a client + 0x03 - Argument is the Client ID of a client + + If unknown type value is received or there is invalid amount of + Argument Payloads present in the list, the command MUST be + discarded. When argument that is to be deleted from the invite + list does not exist in the list the argument is ignored. When adding to or removing from the invite list the server MUST - send the notify type SILC_NOTIFY_TYPE_INVITE to its primary router - and MUST NOT send it to the client which was added to the list. + send the notify type SILC_NOTIFY_TYPE_INVITE to its primary router. The client which executes this command MUST have at least channel operator privileges to be able to add to or remove from the invite - list. The wildcards MAY be used with this command. If adding or - removing more than one client then the lists are an comma (`,') - separated. - - Note that the provided MUST be resolved into correct - nickname and host name and add to the invite list before sending - the notify packet. - + list. The wildcards MAY be used with this command. When this + command is used to invite explicit client with the + ID MUST be added to the invite list by the server. + When this command is given with only argument then the command merely returns the invite list of the channel. This command MUST fail if the requested channel does not exist, the requested is already on the channel or if the channel is invite only channel and the caller of this command does not - have at least channel operator privileges. + have at least channel operator privileges on the channel. Reply messages to the command: @@ -674,7 +693,7 @@ List of all defined commands in SILC follows. 9 SILC_COMMAND_KILL Max Arguments: 3 - Arguments: (1) (2) [] + Arguments: (1) (2) [] (3) [] This command can be used by SILC operators to remove a client from @@ -695,7 +714,9 @@ List of all defined commands in SILC follows. The packet MUST NOT be sent to the killed client on the channels. Then, the router MUST send the same notify type to its primary router. Finally, the router MUST send the same notify type - directly to the client which was killed. + directly to the client which was killed. The killed client MUST + also be removed from the invite lists of joined channels if it + is explicitly added in the invite lists. Normal client killing by authentication: @@ -935,8 +956,8 @@ List of all defined commands in SILC follows. o The user MUST be invited to the channel if the channel is invite-only channel. - o The Client ID/nickname/username/host name MUST NOT match - any active bans. + o The Client ID/nickname/username/host name/public key + MUST NOT match any active bans. o The correct passphrase MUST be provided if passphrase is set to the channel. @@ -1204,11 +1225,11 @@ List of all defined commands in SILC follows. 17 SILC_COMMAND_CMODE - Max Arguments: 7 + Max Arguments: 8 Arguments: (1) (2) [] (3) [] (4) [] (5) [] (6) [] - (7) [] + (7) [] (8) [] This command is used by client to set or change channel flags on a channel. Channel has several modes that set various properties @@ -1365,15 +1386,17 @@ List of all defined commands in SILC follows. channel founder rights even if the client leaves the channel. The is the Authentication Payload consisting of the public key authentication method and the - authentication data for that method. The passphrase - method cannot be used with this mode. The server MUST NOT - accept NONE authentication method. The server does not - save but MUST verify it. The public key - used to verify the payload is the public key of the - client sending this command. The mode may be set only - if the was verified successfully. The - server also MUST save the founder's public key. The - hash function used with the MUST be sha1. + digital signature for that method. The passphrase or NONE + authentication methods MUST NOT be accepted. + + The server does not save but MUST verify it. + The public key used to verify the payload is the if present, or the public key of the client sending + this command. If is present also that + public key MUST be saved as founder's public key. This + mode may be set only if the was verified + successfully. The hash function used with the MUST be sha1. The public key of the founder is sent in the SILC_NOTIFY_TYPE_CMODE_CHANGE notify type so that other @@ -1384,6 +1407,13 @@ List of all defined commands in SILC follows. user mode, or during joining procedure with the command SILC_COMMAND_JOIN. + If this mode is already set but the is + different the new key will replace the old founder key and + the new key is distribute in the network with the + SILC_NOTIFY_TYPE_CMODE_CHANGE notify. Only the original + founder may set this mode multiple times and the client + MUST have SILC_CUMODE_FOUNDER mode on the channel. + When this channel mode is set the channel also becomes permanent. If all clients leave the channel while this mode is set the channel MUST NOT be destroyed. The founder @@ -1428,12 +1458,13 @@ List of all defined commands in SILC follows. Reply messages to the command: - Max Arguments: 3 - Arguments: (1) (2) - (3) + Max Arguments: 4 + Arguments: (1) (2) + (3) (4) [] This command replies with the changed channel mode mask that - client MUST keep locally. + client MUST keep locally. It may also return the channel + founder's public key if it is set. Status messages: @@ -1582,7 +1613,7 @@ List of all defined commands in SILC follows. 19 SILC_COMMAND_KICK Max Arguments: 3 - Arguments: (1) (2) + Arguments: (1) (2) (3) [] This command is used by channel operators to remove a client from @@ -1593,8 +1624,10 @@ List of all defined commands in SILC follows. After kicking the client the server MUST send the notify type SILC_NOTIFY_TYPE_KICKED to the channel and to its primary router. - The channel key MUST also be re-generated after kicking, unless - the SILC_CMODE_PRIVKEY mode is set. + The kicked client MUST be removed from the invite list of the + channel if it is explicitly added in the list. The channel key + MUST also be re-generated after kicking, unless the + SILC_CMODE_PRIVKEY mode is set. Reply messages to the command: @@ -1620,8 +1653,8 @@ List of all defined commands in SILC follows. 20 SILC_COMMAND_BAN Max Arguments: 3 - Arguments: (1) (2) [] - (3) [] + Arguments: (1) (2) [] + (3) [] This command is used to manage the ban list of the channel indicated by the . A client that is banned from @@ -1629,20 +1662,40 @@ List of all defined commands in SILC follows. is executing this command MUST have at least channel operator privileges on the channel. - The and are used to add to and - remove from the ban list. The format of the and - the is of following format: + The is an argument of size of 1 byte where 0x00 means + adding a client to ban list, and 0x01 means deleting a client + from ban list. The , if present, indicates the + information to be added to or removed from the ban list. It + may include a string for matching clients, public key of a + client or Client ID of a client. The format is + as follows: - [[@]!][]@[] + 2 bytes - Number of arguments in the list + variable length - Argument Payloads - The server MUST send the notify type SILC_NOTIFY_TYPE_BAN to its - primary router after adding to or removing from the ban list. - The wildcards MAY be used with this command. If adding or removing - from than one clients then the lists are an comma (`,') separated. + The following Argument Types has been defined for ban list + Argument Payloads: + + 0x01 - Argument is an ban string of following format: - If this command is executed without the ban arguments the command - merely replies with the current ban list. + [[@]!][]@[] + The may also be in format of IP/MASK to indicate + a network. + + 0x02 - Argument is the public key of a client + 0x03 - Argument is the Client ID of a client + + If unknown type value is received or there is invalid amount of + Argument Payloads present in the list, the command MUST be + discarded. When argument that is to be deleted from the ban + list does not exist in the list the argument is ignored. + + The server MUST send the notify type SILC_NOTIFY_TYPE_BAN to its + primary router after adding to or removing from the ban list. + The wildcards MAY be used with this command. If this command + is executed without the ban arguments the command merely replies + with the current ban list. Reply messages to the command: diff --git a/doc/draft-riikonen-silc-flags-payloads-01.nroff b/doc/draft-riikonen-silc-flags-payloads-01.nroff index cb0240d8..83400760 100644 --- a/doc/draft-riikonen-silc-flags-payloads-01.nroff +++ b/doc/draft-riikonen-silc-flags-payloads-01.nroff @@ -8,7 +8,7 @@ .ds RF FORMFEED[Page %] .ds CF .ds LH Internet Draft -.ds RH XXX +.ds RH 25 November 2002 .ds CH .na .hy 0 @@ -16,8 +16,8 @@ .nf Network Working Group P. Riikonen Internet-Draft -draft-riikonen-flags-payloads-01.txt XXX -Expires: 20 April 2003 +draft-riikonen-flags-payloads-01.txt 25 November 2002 +Expires: 25 April 2003 .in 3 @@ -53,12 +53,12 @@ Abstract This memo describes the data payloads associated with the SILC Message Flags, as defined in the SILC Packet Protocol Internet Draft [SILC2]. The -purpose of the Message Flags is to augment the function of the Private -Message Payload and Channel Message Payload by allowing the sender to -tell the receiver what type of data the payload includes, and how the -data should be processed. Some of the Message Flags may define additional -payloads to be associated with the flag, and this memo describes these -payloads. +purpose of the Message Flags is to augment the function of the Message +Payload used to send both private and channel messages, by allowing the +sender to tell the receiver what type of data the payload includes, and +how the data should be processed. Some of the Message Flags may define +additional payloads to be associated with the flag, and this memo +describes these payloads. @@ -78,10 +78,10 @@ Table of Contents 3.1 SILC_MESSAGE_FLAG_REQUEST ................................. 3 3.2 SILC_MESSAGE_FLAG_REPLY ................................... 3 3.3 SILC_MESSAGE_FLAG_SIGNED .................................. 4 - 3.4 SILC_MESSAGE_FLAG_DATA .................................... 4 -4 Security Considerations ....................................... 5 -5 References .................................................... 5 -6 Author's Address .............................................. 6 + 3.4 SILC_MESSAGE_FLAG_DATA .................................... 6 +4 Security Considerations ....................................... 7 +5 References .................................................... 7 +6 Author's Address .............................................. 8 .ti 0 @@ -90,14 +90,14 @@ Table of Contents The Secure Internet Live Conferencing [SILC1] supports sending binary messages between users in the network. To make the data sending, and processing at the receiver's end as simple as possible the SILC defines -Message Flags to the Private Message Payload and Channel Message Payload -[SILC2], which can help the receiver to decide how the data is encoded, -and how it should be interpreted. Some of the Message Flags may define -additional payloads to be associated with the flag, but the [SILC2] does -not define them. This memo defines the payloads for those Message Flags -that was marked to include additional payloads in [SILC2]. - -By defining the payloads for the Message Flags the SILC message payloads +Message Flags to the Message Payload [SILC2] that is used to send private +and channel messages, which can help the receiver to decide how the data +is encoded, and how it should be interpreted. Some of the Message Flags +may define additional payloads to be associated with the flag, but the +[SILC2] does not define them. This memo defines the payloads for those +Message Flags that was marked to include additional payloads in [SILC2]. + +By defining the payloads for the Message Flags the Message Payload can be augmented to support any kind of data, which can be easily interpreted at the receiver end. For example, it would be possible to send audio stream, video stream, image files and HTML pages as messages, @@ -128,12 +128,12 @@ such problems since they do not generally support sending of binary data at all, or require encoding of the data before it can be sent over the network. -SILC Private Message Payload and Channel Message Payload can have flags -that can augment the function of the payload. The flags can tell for -example that the message is a request, or a reply to an earlier received -request. They can tell that the message is some action that the sender -is performing, or they can tell that the message is an auto reply, or -that it is explicitly digitally signed by the sender. +The Message Payload in SILC can have flags that can augment the function +of the payload. The flags can tell for example that the message is a +request, or a reply to an earlier received request. They can tell that +the message is some action that the sender is performing, or they can tell +that the message is an auto reply, or that it is explicitly digitally +signed by the sender. The problem of Message Flags is that the space for flags mask is only 16 bits, so there is a limited number of flags available. For this reason a @@ -179,7 +179,7 @@ additional payload. 3.3 SILC_MESSAGE_FLAG_SIGNED This flag is used to tell the recipient that the sent message is -digitally signed by the sender, and that the receipient should verify +digitally signed by the sender, and that the recipient should verify the signature to verify the true authenticity of the received message. All message payloads in SILC provides message authentication code (MAC) which can be used to verify that the sender produced and sent the message. @@ -216,26 +216,23 @@ Figure 1: SILC_MESSAGE_FLAG_SIGNED Payload .in 6 -o Message Payload (variable length) - This is a message payload - consisting of the encrypted message. When this flag is used - with channel messages it include Channel Message Payload, and - when used with private messages it include Private Message - Payload [SILC2]. +o Message Payload (variable length) - This is the Message Payload + [SILC2] consisting of the encrypted message. o Public Key Payload (variable length) - This includes the - Public Key Payload which can be used to deliver the sender's - public key (or certificate). It also indicates the type of the - public key (or certificate) which the recipient use to identify - how the signature must be verified. This payload must always - be present but it is not required to include the public key - data. The Public Key Type field in the Public Key Payload - MUST be set to the correct type of the key, even if the - actual public key data is not included. + Public Key Payload [SILC2] which can be used to deliver the + sender's public key (or certificate). It also indicates the + type of the public key (or certificate) which the recipient + use to identify how the signature must be verified. This + payload must always be present but it is not required to + include the public key data. The Public Key Type field in + the Public Key Payload MUST be set to the correct type of + the key, even if the actual public key data is not included. o Signature Data Length (2 bytes) - Indicates the length of the Signature Data field not including any other field. -o Signature Data (variable lenght) - Includes the actual +o Signature Data (variable length) - Includes the actual signature data. The signature computation and encoding is key type specific. See [SILC3] for all key types, and their respective references of how to compute and encode @@ -244,17 +241,13 @@ o Signature Data (variable lenght) - Includes the actual How the data is processed before it is signed is key type specific. The actual data that to be signed MUST be the plaintext message -payload before encryption. For Channel Message Payload the data to -be signed is concatenation of Message Flags, Message Length, Message -Data, Padding Length, Padding, Initial Vector fields and the Public -Key Payload. Any other field is not included for signature data. -For Private Message Payload the data to be signed is concatenation -of Message Flags, Message Data Length, Message Data, Padding fields and -the Public Key Payload fields. Any other field is not included for -signature data. Before signing, the data is always processed, usually -hashed. The hash function to be used is defined in the key type -specific definitions. See the key type specific references in -[SILC3]. +payload before encryption. The data to be signed is concatenation +of Message Flags, Message Length, Message Data, Padding Length, +Padding and Initial Vector fields, and the Public Key Payload, in +that order. Any other fields is not included for signature data. +Before signing, the data is always processed, usually hashed. The +hash function to be used is defined in the key type specific +definitions. See the key type specific references in [SILC3]. If the public key of the sender is included in the payload the recipient SHOULD verify before accepting the public key. Recipient @@ -280,6 +273,7 @@ the data area of the message payload this flag may be masked with the other flags. + .ti 0 3.4 SILC_MESSAGE_FLAG_DATA @@ -300,15 +294,15 @@ media type received in the MIME header, it SHOULD be treated as "application/octet-stream". The receiver MAY also ignore and discard messages that it does not support. -The MIME header MUST be at the start of the data area of the Private -Message Payload or Channel Message Payload. The MIME header received in -the data area of the payload SHOULD have the MIME-Version field at first -and then Content-Type field. The MIME-Version field is not required to be -present in each body part of multipart entity. Additionally the header -MAY also include any other MIME compliant headers. The character encoding -for the MIME Header strings inside the message payload is US-ASCII, as -defined in [RFC2045]. The actual MIME object may define additional -character sets or encodings for the data it delivers. +The MIME header MUST be at the start of the data area of the Message +Payload. The MIME header received in the data area of the payload SHOULD +have the MIME-Version field at first and then Content-Type field. The +MIME-Version field is not required to be present in each body part of +multipart entity. Additionally the header MAY also include any other +MIME compliant headers. The character encoding for the MIME Header +strings inside the message payload is US-ASCII, as defined in [RFC2045]. +The actual MIME object may define additional character sets or encodings +for the data it delivers. Hence, the MIME Header in the message payload may be as follows: @@ -405,4 +399,4 @@ Finland EMail: priikone@iki.fi -This Internet-Draft expires 20 April 2003 +This Internet-Draft expires 25 April 2003 diff --git a/doc/draft-riikonen-silc-ke-auth-06.nroff b/doc/draft-riikonen-silc-ke-auth-06.nroff index b017ff77..c54062f4 100644 --- a/doc/draft-riikonen-silc-ke-auth-06.nroff +++ b/doc/draft-riikonen-silc-ke-auth-06.nroff @@ -8,7 +8,7 @@ .ds RF FORMFEED[Page %] .ds CF .ds LH Internet-Draft -.ds RH 15 May 2002 +.ds RH 25 November 2002 .ds CH .na .hy 0 @@ -16,14 +16,14 @@ .nf Network Working Group P. Riikonen Internet-Draft -draft-riikonen-silc-ke-auth-05.txt 15 May 2002 -Expires: 15 November 2002 +draft-riikonen-silc-ke-auth-06.txt 25 November 2002 +Expires: 25 April 2003 .in 3 .ce 2 SILC Key Exchange and Authentication Protocols - + .ti 0 Status of this Memo @@ -53,19 +53,20 @@ Abstract This memo describes two protocols used in the Secure Internet Live Conferencing (SILC) protocol, specified in the Secure Internet Live -Conferencing, Protocol Specification internet-draft [SILC1]. The -SILC Key Exchange (SKE) protocol provides secure key exchange between -two parties resulting into shared secret key material. The protocol -is based on Diffie-Hellman key exchange algorithm and its functionality -is derived from several key exchange protocols. SKE uses best parts +Conferencing, Protocol Specification [SILC1]. The SILC Key Exchange +(SKE) protocol provides secure key exchange between two parties +resulting into shared secret key material. The protocol is based +on Diffie-Hellman key exchange algorithm and its functionality is +derived from several key exchange protocols. SKE use best parts of the SSH2 Key Exchange protocol, Station-To-Station (STS) protocol and the OAKLEY Key Determination protocol [OAKLEY]. -The SILC Connection Authentication protocol provides user level -authentication used when creating connections in SILC network. The -protocol is transparent to the authentication data which means that it -can be used to authenticate the user with, for example, passphrase -(pre-shared-secret) or public key (and certificate). +The second protocol, SILC Connection Authentication protocol provides +user level authentication used when creating connections in SILC +network. The protocol is transparent to the authentication data +which means that it can be used to authenticate the user with, for +example, passphrase (pre-shared secret) or public key (and certificate) +based on digital signatures. @@ -79,21 +80,22 @@ Table of Contents 2.1 Key Exchange Payloads ..................................... 4 2.1.1 Key Exchange Start Payload .......................... 4 2.1.2 Key Exchange Payload ................................ 8 - 2.2 Key Exchange Procedure .................................... 10 + 2.2 Key Exchange Procedure .................................... 11 2.3 Processing the Key Material ............................... 12 2.4 SILC Key Exchange Groups .................................. 14 2.4.1 diffie-hellman-group1 ............................... 14 - 2.4.2 diffie-hellman-group2 ............................... 14 - 2.5 Key Exchange Status Types ................................. 15 -3 SILC Connection Authentication Protocol ....................... 16 + 2.4.2 diffie-hellman-group2 ............................... 15 + 2.4.3 diffie-hellman-group3 ............................... 15 + 2.5 Key Exchange Status Types ................................. 16 +3 SILC Connection Authentication Protocol ....................... 17 3.1 Connection Auth Payload ................................... 18 3.2 Connection Authentication Types ........................... 19 3.2.1 Passphrase Authentication ........................... 19 3.2.2 Public Key Authentication ........................... 20 - 3.3 Connection Authentication Status Types .................... 20 + 3.3 Connection Authentication Status Types .................... 21 4 Security Considerations ....................................... 21 5 References .................................................... 21 -6 Author's Address .............................................. 22 +6 Author's Address .............................................. 23 .ti 0 @@ -110,32 +112,32 @@ Figure 3: Connection Auth Payload This memo describes two protocols used in the Secure Internet Live Conferencing (SILC) protocol specified in the Secure Internet Live -Conferencing, Protocol Specification Internet-Draft [SILC1]. The -SILC Key Exchange (SKE) protocol provides secure key exchange between -two parties resulting into shared secret key material. The protocol -is based on Diffie-Hellman key exchange algorithm and its functionality -is derived from several key exchange protocols. SKE uses best parts -of the SSH2 Key Exchange protocol, Station-To-Station (STS) protocol -and the OAKLEY Key Determination protocol. +Conferencing, Protocol Specification [SILC1]. The SILC Key Exchange +(SKE) protocol provides secure key exchange between two parties +resulting into shared secret key material. The protocol is based on +Diffie-Hellman key exchange algorithm and its functionality is derived +from several key exchange protocols. SKE use best parts of the SSH2 +Key Exchange protocol, Station-To-Station (STS) protocol and the +OAKLEY Key Determination protocol [OAKLEY]. -The SILC Connection Authentication protocol provides user level -authentication used when creating connections in SILC network. The -protocol is transparent to the authentication data which means that it -can be used to authenticate the user with, for example, passphrase -(pre-shared- secret) or public key (and certificate). +The second protocol, SILC Connection Authentication protocol provides +user level authentication used when creating connections in SILC +network. The protocol is transparent to the authentication data which +means that it can be used to authenticate the user with, for example, +passphrase (pre-shared secret) or public key (and certificate) based +on digital signatures. The basis of secure SILC session requires strong and secure key exchange -protocol and authentication. The authentication protocol is entirely -secured and no authentication data is ever sent in the network without -encrypting and authenticating it first. Thus, authentication protocol -may be used only after the key exchange protocol has been successfully -completed. - -This document refers constantly to other SILC protocol specification -Internet Drafts that are a must read for those who wants to understand -the function of these protocols. The most important references are +protocol and authentication. The authentication protocol is secured and +no authentication data is ever sent in the network without encrypting +and authenticating it first. Thus, authentication protocol may be used +only after the key exchange protocol has been successfully completed. + +This document constantly refers to other SILC protocol specifications +that should be read to be able to fully understand the functionality +and purpose of these protocols. The most important references are the Secure Internet Live Conferencing, Protocol Specification [SILC1] -and the SILC Packet Protocol [SILC2] Internet Drafts. +and the SILC Packet Protocol [SILC2]. The protocol is intended to be used with the SILC protocol thus it does not define own framework that could be used. The framework is @@ -155,25 +157,22 @@ interpreted as described in [RFC2119]. SILC Key Exchange Protocol (SKE) is used to exchange shared secret between connecting entities. The result of this protocol is a key -material used to secure the communication channel. The protocol uses +material used to secure the communication channel. The protocol use Diffie-Hellman key exchange algorithm and its functionality is derived -from several key exchange protocols. SKE uses best parts of the SSH2 +from several key exchange protocols. SKE use best parts of the SSH2 Key Exchange protocol, Station-To-Station (STS) protocol and the OAKLEY Key Determination protocol. The protocol does not claim any conformance -to any of these protocols, they were merely used as a reference when +to any of these protocols, they were only used as a reference when designing this protocol. The purpose of SILC Key Exchange protocol is to create session keys to be used in current SILC session. The keys are valid only for some period of time (usually an hour) or at most until the session ends. These keys -are used to protect packets like commands, command replies and other -communication between two entities. If connection is server to router -connection, the keys are used to protect all traffic between those -servers. In client connections usually all the packets are protected -with this key except channel messages; channels has their own keys and -they are not exchanged with this protocol. - -The Diffie-Hellman implementation used in the SILC SHOULD be compliant +are used to protect packets traveling between the two entities. +Usually all traffic is secured with the key material derived from this +protocol. + +The Diffie-Hellman implementation used in the SILC SHOULD be compliant to the PKCS #3. @@ -184,9 +183,9 @@ During the key exchange procedure public data is sent between initiator and responder. This data is later used in the key exchange procedure. There are several payloads used in the key exchange. As for all SILC packets, SILC Packet Header, described in [SILC2], is at the start of -all packets. The same is done with these payloads as well. All the -fields in the payloads are always in MSB (most significant byte first) -order. Following descriptions of these payloads. +all packets sent in during this protocol. All the fields in the +following payloads are in MSB (most significant byte first) order. +Following descriptions of these payloads. .ti 0 @@ -201,8 +200,8 @@ whether it supports the security properties. It then sends a Key Exchange Start Payload to the initiator filled with security properties it selected from the original payload. The payload sent by responder MUST include only one chosen property per list. The -character encoding for the security property values as defined in [SILC1] -SHOULD be UTF-8 [RFC2279]. +character encoding for the security property values as defined in [SILC1] +SHOULD be UTF-8 [RFC2279] in Key Exchange Start Payload. The Key Exchange Start Payload is used to tell connecting entities what security properties and algorithms should be used in the communication. @@ -219,7 +218,7 @@ is never encrypted, as there are no keys to encrypt it with. A cookie is also sent in this payload. A cookie is used to randomize the payload so that none of the key exchange parties can determine this payload before the key exchange procedure starts. The cookie MUST be -returned to the original sender by the responder. +returned to the original sender unmodified by the responder. Following diagram represents the Key Exchange Start Payload. The lists mentioned below are always comma (`,') separated and the list MUST NOT @@ -303,10 +302,19 @@ o Flags (1 byte) - Indicates flags to be used in the key In this case the field is ignored. - No Reply 0x01 + IV Included 0x01 - If set the receiver of the payload does not reply to - the packet. + This flag is used to indicate that Initial Vector (IV) + in encryption will be included in the ciphertext + which the recipient must use in decryption. The IV + MUST be set after the last ciphertext block. With + this flag it is possible to use SILC protocol on + unreliable transport such as UDP/IP which may cause + packet reordering and packet losses. By default, + this flag is not set and thus IV is not included + in the ciphertext. Setting this flag increases the + ciphertext size by one ciphertext block. Responder + MAY override this flag for the initiator. PFS 0x02 @@ -347,7 +355,7 @@ o Version String Length (2 bytes) - The length of the Version o Version String (variable length) - Indicates the version of the sender of this payload. Initiator sets this when sending the payload and responder sets this when it replies by sending - this payload. See [SILC1] for definition of the version + this payload. See [SILC1] for definition for the version string format. This field MUST be present and include valid version string. @@ -382,7 +390,7 @@ o HMAC Length (2 bytes) - The length of the HMAC list, not including any other field. o HMACs (variable length) - The list of HMACs. The HMAC's - are used to compute the Message Authentication Codes (MAC) + are used to compute the Message Authentication Code (MAC) of the SILC packets. This field MUST be present. o Compression Alg Length (2 bytes) - The length of the @@ -408,12 +416,12 @@ authentication protocol will not be executed for the initiator of the protocol. This is case for example when the SKE is performed between two SILC clients. In normal case, where client is connecting to a server, or server is connecting to a router the Mutual Authentication -flag may be omitted. However, if the connection authentication protocol -for the connecting entity is not based on public key authentication (it -is based on passphrase) then the Mutual Authentication flag SHOULD be +flag MAY be omitted. However, if the connection authentication protocol +for the connecting entity is not based on digital signatures (it is +on pre-shared key) then the Mutual Authentication flag SHOULD be enabled. This way the connecting entity has to provide proof of possession of the private key for the public key it will provide in -SILC Key Exchange protocol. +this protocol. When performing re-key with PFS selected this is the only payload that is sent in the SKE protocol. The Key Exchange Start Payload MUST NOT @@ -476,7 +484,7 @@ o Public Key Type (2 bytes) - The public key (or certificate) The only required type to support is type number 1. See [SILC1] for the SILC public key specification. See - SSH public key specification in [SSH-TRANS]. See X.509v3 + SSH2 public key specification in [SSH-TRANS]. See X.509v3 certificate specification in [PKIX-Part1]. See OpenPGP certificate specification in [PGP]. See SPKI certificate specification in [SPKI]. If this field includes zero (0) @@ -510,7 +518,7 @@ o Signature Data (variable length) - The signature signed MUST NOT provide this field and the Signature Length field MUST be set to zero (0) value. If the flag is set then also the initiator MUST provide this field. The responder - MUST always provide this field. + always MUST provide this field. .in 3 @@ -539,8 +547,9 @@ Setup: p is a large and public safe prime. This is one of the MUST also produce signature data SIGN_i which the responder will verify. The initiator MUST compute a hash value HASH_i = hash(Initiator's Key Exchange Start Payload | - public key (or certificate) | e). It then signs the HASH_i - value with its private key resulting a signature SIGN_i. + public key (or certificate) | e). The '|' stands for + concatenation. It then signs the HASH_i value with its + private key resulting a signature SIGN_i. 2. Responder generates a random number y, where 1 < y < q, and computes f = g ^ y mod p. It then computes the @@ -671,12 +680,13 @@ of the hash output to generate the MAC keys. These procedures are performed by all parties of the key exchange protocol. This MUST be done before the protocol has been ended by -sending the SILC_PACKET_SUCCESS packet. +sending the SILC_PACKET_SUCCESS packet, to assure that parties can +successfully process the key material. -This same procedure is used in the SILC in some other circumstances -as well. Any changes to this procedure is mentioned separately when -this procedure is needed. See the [SILC1] and the [SILC2] for these -circumstances. +This same key processing procedure MAY be used in the SILC in some +other circumstances as well. Any changes to this procedure is defined +separately when this procedure is needed. See the [SILC1] and the +[SILC2] for these circumstances. .ti 0 @@ -696,17 +706,6 @@ requested group (however, it does not have to be the first in the list). The length of this group is 1024 bits. This is REQUIRED group. The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. -Its decimal value is - -.in 6 -179769313486231590770839156793787453197860296048756011706444 -423684197180216158519368947833795864925541502180565485980503 -646440548199239100050792877003355816639229553136239076508735 -759914822574862575007425302077447712589550957937778424442426 -617334727629299387668709205606050270810842907692932019128194 -467627007 -.in 3 - Its hexadecimal value is .in 6 @@ -731,21 +730,30 @@ This group was taken from the OAKLEY specification. The length of this group is 1536 bits. This is OPTIONAL group. The prime is 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }. +Its hexadecimal value is +.in 6 +FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 +29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD +EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 +E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED +EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D +C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F +83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D +670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF +.in 3 +The generator used with this prime is g = 2. The group order q is +(p - 1) / 2. -Its decimal value is +This group was taken from the OAKLEY specification. -.in 6 -241031242692103258855207602219756607485695054850245994265411 -694195810883168261222889009385826134161467322714147790401219 -650364895705058263194273070680500922306273474534107340669624 -601458936165977404102716924945320037872943417032584377865919 -814376319377685986952408894019557734611984354530154704374720 -774996976375008430892633929555996888245787241299381012913029 -459299994792636526405928464720973038494721168143446471443848 -8520940127459844288859336526896320919633919 -.in 3 + +.ti 0 +2.4.3 diffie-hellman-group3 + +The length of this group is 2048 bits. This is OPTIONAL group. +This prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }. Its hexadecimal value is @@ -757,13 +765,17 @@ E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D -670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF +670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B +E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 +DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 +15728E5A 8AACAA68 FFFFFFFF FFFFFFFF .in 3 The generator used with this prime is g = 2. The group order q is (p - 1) / 2. -This group was taken from the OAKLEY specification. + + .ti 0 @@ -848,12 +860,12 @@ connecting party with server. Usually connecting party is client but server may connect to router server as well. Its other purpose is to provide information for the server about which type of connection this is. The type defines whether this is client, server or router -connection. Server uses this information to create the ID for the +connection. Server use this information to create the ID for the connection. Server MUST verify the authentication data received and if it is to fail the authentication MUST be failed by sending SILC_PACKET_FAILURE packet. -If everything checks out fine the protocol is ended by server by sending +If authentication is successful the protocol is ended by server by sending SILC_PACKET_SUCCESS packet. The protocol is executed after the SILC Key Exchange protocol. It MUST @@ -876,22 +888,23 @@ sending the request is not necessary. See [SILC1] and section Connection Auth Request Payload in [SILC2] also for the list of different authentication methods. Authentication method MAY also be NONE, in which case the server does not require -authentication at all. However, in this case the protocol still MUST be -executed; the authentication data just is empty indicating no -authentication is required. +authentication. However, in this case the protocol still MUST be +executed; the authentication data is empty indicating no authentication +is required. If authentication method is passphrase the authentication data is -plaintext passphrase. As the payload is entirely encrypted it is safe -to have plaintext passphrase. It is also provided as plaintext passphrase +plaintext passphrase. As the payload is encrypted it is safe to have +plaintext passphrase. It is also provided as plaintext passphrase because the receiver may need to pass the entire passphrase into a -passphrase checker, and hash digest of the passphrase would prevent this. -See the section 3.2.1 Passphrase Authentication for more information. +passphrase verifier, and a message digest of the passphrase would +prevent this. See the section 3.2.1 Passphrase Authentication for +more information. If authentication method is public key authentication the authentication -data is a signature of the hash value of hash HASH plus Key Exchange -Start Payload, established by the SILC Key Exchange protocol. This -signature MUST then be verified by the server. See the section 3.2.2 -Public Key Authentication for more information. +data is a digital signature of the hash value of hash HASH and Key +Exchange Start Payload, established by the SILC Key Exchange protocol. +This signature MUST then be verified by the server. See the section +3.2.2 Public Key Authentication for more information. See the section 4 SILC Procedures in [SILC1] for more information about client creating connection to server, and server creating connection @@ -912,6 +925,11 @@ It MUST NOT be sent in any other packet type. The following diagram represent the Connection Auth Payload. + + + + + .in 5 .nf 1 2 3 @@ -946,21 +964,20 @@ o Authentication Data (variable length) - The actual .in 3 - - .ti 0 3.2 Connection Authentication Types SILC supports two authentication types to be used in the connection -authentication protocol; passphrase or public key based authentication. -The following sections defines the authentication methods. See [SILC2] -for defined numerical authentication method types. +authentication protocol; passphrase authentication or public key +authentication based on digital signatures. The following sections +defines the authentication methods. See [SILC2] for defined numerical +authentication method types. .ti 0 3.2.1 Passphrase Authentication -Passphrase authentication or pre-shared-key based authentication is +Passphrase authentication or pre-shared key based authentication is simply an authentication where the party that wants to authenticate itself to the other end sends the passphrase that is required by the other end, for example server. The plaintext passphrase is put @@ -990,8 +1007,8 @@ packet. Public key authentication may be used if passphrase based authentication is not desired. The public key authentication works by sending a -signature as authentication data to the other end, say, server. The -server MUST then verify the signature by the public key of the sender, +digital signature as authentication data to the other end, say, server. +The server MUST then verify the signature by the public key of the sender, which the server has received earlier in SKE protocol. The signature is computed using the private key of the sender by signing @@ -1006,7 +1023,8 @@ which is then signed. The hash() function used to compute the value is the hash function negotiated in the SKE protocol. The server MUST verify the data, thus it must keep the HASH and the Key Exchange Start Payload saved during -SKE and authentication protocols. +SKE and authentication protocols. These values can be discarded after +Connection Authentication protocol is completed. If the verified signature matches the sent signature, the authentication were successful and SILC_PACKET_SUCCESS is sent. If it failed the @@ -1016,6 +1034,7 @@ This is REQUIRED authentication method to be supported by all SILC implementations. + .ti 0 3.3 Connection Authentication Status Types @@ -1037,8 +1056,6 @@ are defined: Authentication failed. - - .ti 0 4 Security Considerations @@ -1049,7 +1066,6 @@ symmetric and asymmetric keys must be followed in order to maintain the security of this protocol. - .ti 0 5 References @@ -1129,4 +1145,4 @@ Finland EMail: priikone@iki.fi -This Internet-Draft expires 15 November 2002 +This Internet-Draft expires 25 April 2003 diff --git a/doc/draft-riikonen-silc-pp-06.nroff b/doc/draft-riikonen-silc-pp-06.nroff index 48544993..64b90143 100644 --- a/doc/draft-riikonen-silc-pp-06.nroff +++ b/doc/draft-riikonen-silc-pp-06.nroff @@ -8,7 +8,7 @@ .ds RF FORMFEED[Page %] .ds CF .ds LH Internet Draft -.ds RH 15 May 2002 +.ds RH XXX .ds CH .na .hy 0 @@ -16,8 +16,8 @@ .nf Network Working Group P. Riikonen Internet-Draft -draft-riikonen-silc-pp-05.txt 15 May 2002 -Expires: 15 November 2002 +draft-riikonen-silc-pp-05.txt XXX +Expires: XXX .in 3 @@ -82,6 +82,7 @@ Table of Contents 2.3.2.2 Argument Payload ............................ 18 2.3.2.3 Channel Payload ............................. 19 2.3.2.4 Public Key Payload .......................... 20 + 2.3.2.5 Message Payload ............................. 20 2.3.3 Disconnect Payload .................................. 20 2.3.4 Success Payload ..................................... 21 2.3.5 Failure Payload ..................................... 22 @@ -129,24 +130,23 @@ Figure 3: ID Payload Figure 4: Argument Payload Figure 5: Channel Payload Figure 6: Public Key Payload -Figure 7: Disconnect Payload -Figure 8: Success Payload -Figure 9: Failure Payload -Figure 10: Reject Payload -Figure 11: Notify Payload -Figure 12: Error Payload -Figure 13: Channel Message Payload +Figure 7: Message Payload +Figure 8: Disconnect Payload +Figure 9: Success Payload +Figure 10: Failure Payload +Figure 11: Reject Payload +Figure 12: Notify Payload +Figure 13: Error Payload Figure 14: Channel Key Payload -Figure 15: Private Message Payload -Figure 16: Private Message Key Payload -Figure 17: Command Payload -Figure 18: Connection Auth Request Payload -Figure 19: New Client Payload -Figure 20: New Server Payload -Figure 21: Key Agreement Payload -Figure 22: Resume Router Payload -Figure 23: File Transfer Payload -Figure 24: Resume Client Payload +Figure 15: Private Message Key Payload +Figure 16: Command Payload +Figure 17: Connection Auth Request Payload +Figure 18: New Client Payload +Figure 19: New Server Payload +Figure 20: Key Agreement Payload +Figure 21: Resume Router Payload +Figure 22: File Transfer Payload +Figure 23: Resume Client Payload .ti 0 @@ -920,17 +920,17 @@ Figure 4: Argument Payload .in 6 -o Payload Length (2 bytes) - Length of the argument payload data - area not including the length of any other fields in the +o Payload Length (2 bytes) - Length of the Argument Data + area not including the length of any other field in the payload. o Argument Type (1 byte) - Indicates the type of the argument. - Every argument may have a specific type that MUST be defined + Every argument can have a specific type that MUST be defined by the packet payload needing the argument. For example - every command specify a number for each argument that maybe + every command specify a number for each argument that may be associated with the command. By using this number the receiver of the packet knows what type of argument this is. If there is - no specific argument type this field is set to zero (0). + no specific argument type this field is set to zero (0) value. o Argument Data (variable length) - Argument data. .in 3 @@ -997,8 +997,6 @@ The following diagram represents the Public Key Payload. - - .in 5 .nf 1 2 3 @@ -1029,6 +1027,176 @@ o Public Key (or certificate) (variable length) - The .in 3 +.ti 0 +2.3.2.5 Message Payload + +Generic Message Payload can be used to send message in SILC. It +is used to send channel messages and private messages. + +The following diagram represents the Message Payload. + +(*) indicates that the field is not encrypted. + +.in 5 +.nf + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Message Flags | Message Length | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| | +~ Message Data ~ +| | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Padding Length | | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +| | +~ Padding ~ +| | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| | +~ Initial Vector * ~ +| | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| | +~ MAC * ~ +| | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +.in 3 + +.ce +Figure 7: Message Payload + + +.in 6 +o Message Flags (2 bytes) - Includes the Message Flags of the + message. The flags can indicate a reason or purpose for + the message. The following Message Flags are defined: + + 0x0000 SILC_MESSAGE_FLAG_NONE + + No specific flags set. + + 0x0001 SILC_MESSAGE_FLAG_AUTOREPLY + + This message is an automatic reply to an earlier + received message. + + 0x0002 SILC_MESSAGE_FLAG_NOREPLY + + There should not be reply messages to this + message. + + 0x0004 SILC_MESSAGE_FLAG_ACTION + + The sender is performing an action and the message + is the indication of the action. + + 0x0008 SILC_MESSAGE_FLAG_NOTICE + + The message is for example an informational notice + type message. + + 0x0010 SILC_MESSAGE_FLAG_REQUEST + + This is a generic request flag to send request + messages. A separate document should define any + payloads associated to this flag. + + 0x0020 SILC_MESSAGE_FLAG_SIGNED + + This flag indicates that the message is signed + with sender's private key and thus can be verified + by the receiver using the sender's public key. A + separate document should define the detailed procedure + of the signing process and any associated payloads + of this flag. + + 0x0040 SILC_MESSAGE_FLAG_REPLY + + This is a generic reply flag to send a reply to + previously received request. A separate document + should define any payloads associated to this flag. + + 0x0080 SILC_MESSAGE_FLAG_DATA + + This is a generic data flag, indicating that the + message includes some data which can be interpreted + in a specific way. Using this flag any kind of data + can be delivered inside message payload. A separate + document should define how this flag is interpreted + and define any associated payloads. + + 0x0100 SILC_MESSAGE_FLAG_UTF8 + + This flag indicates that the message is UTF-8 encoded + textual message. When sending text messages this + flag SHOULD be used. When this flag is used the text + sent as message MUST be UTF-8 encoded. + + 0x0200 - 0x0800 RESERVED + + Reserved for future flags. + + 0x1000 - 0x8000 PRIVATE RANGE + + Private range for free use. + +o Message Length (2 bytes) - Indicates the length of the + Message Data field in the payload, not including any + other field. + +o Message Data (variable length) - The actual message data. + +o Padding Length (2 bytes) - Indicates the length of the + Padding field in the payload, not including any other + field. + +o Padding (variable length) - If this payload is used as + channel messages, the padding MUST be applied because + this payload is encrypted separately from other parts + of the packet. If this payload is used as private + messages, the padding is present only when the payload + is encrypted with private message key. If encrypted + with session keys this field is not present and the + Padding Length field includes a zero (0) value. The + padding SHOULD be random data. + +o Initial Vector (variable length) - This field MUST be + present when this payload is used as channel messages. + + When encrypting private messages with session keys this + field MUST NOT be present. For private messages this + field is present only when encrypting with a static + private message key (pre-shared key). If randomly + generated key material is used this field MUST NOT be + present. Also, If Key Agreement (SKE) was used to + negotiate fresh key material for private message key + this field MUST NOT be present. See the section 4.6 + in [SILC1] for more information about IVs when + encrypting private messages. + + This field includes the initial vector used in message + encryption. It need to be used in the packet decryption + as well. Contents of this field depends on the encryption + algorithm and encryption mode. This field is not encrypted, + is not included in padding calculation and its length + equals to cipher's block size. This field is authenticated + by the message MAC. + +o MAC (variable length) - The MAC computed from the + Message Flags, Message Length, Message Data, Padding Length, + Padding and Initial Vector fields in that order. The MAC + is computed after the payload is encrypted. This is so + called Encrypt-Then-MAC order; first encrypt, then compute + MAC from ciphertext. The MAC protects the integrity of + the Message Payload. Also, when used as channel messages + it is possible to have multiple private channel keys set, + and receiver can use MAC to verify which of the keys must + be used in decryption. This field is not encrypted. +.in 3 + + .ti 0 2.3.3 Disconnect Payload @@ -1054,7 +1222,7 @@ represents the Disconnect Payload. .in 3 .ce -Figure 7: Disconnect Payload +Figure 8: Disconnect Payload .in 6 o Status (1 byte) - Indicates the Status Type, defined in [SILC3] @@ -1085,7 +1253,7 @@ This may be any data, including binary or human readable data. .in 3 .ce -Figure 8: Success Payload +Figure 9: Success Payload .in 6 @@ -1118,7 +1286,7 @@ some protocol is sent in the payload. .in 3 .ce -Figure 9: Failure Payload +Figure 10: Failure Payload .in 6 @@ -1152,7 +1320,7 @@ may be binary or human readable data. .in 3 .ce -Figure 10: Reject Payload +Figure 11: Reject Payload .in 6 @@ -1193,7 +1361,7 @@ the Notify Payload. .in 3 .ce -Figure 11: Notify Payload +Figure 12: Notify Payload .in 6 @@ -1225,7 +1393,7 @@ sent in arguments are actually Public Key Payloads. Max Arguments: 1 Arguments: (1) - The is implementation specific free text string. + The is implementation specific free UTF-8 text string. Receiver MAY ignore this message. @@ -1238,21 +1406,21 @@ sent in arguments are actually Public Key Payloads. Max Arguments: 5 Arguments: (1) (2) - (3) [] (4) [] - (5) [] + (3) [] (4) [] + (5) [] The is the channel. The is the name of the channel and is provided because the client which receives this notify packet may not have a way to resolve the name of the channel from the . The is the - Client ID which invited the client to the channel. The and the indicates the added or removed - client from the channel's invite list. The format of the and the is defined in the [SILC4] with - SILC_COMMAND_INVITE command. - - The and MUST NOT be sent when - the packet is destined to a client. + Client ID which invited the client to the channel. The + is an argument of size of 1 byte where 0x00 means adding a client + to invite list, and 0x01 means deleting a client from invite list. + The , if present, indicates the information to be + added to or removed from the invite list. The + format is defined in [SILC4] with SILC_COMMAND_INVITE command. + When this notify is destined to a client the and + MUST NOT be sent. 2 SILC_NOTIFY_TYPE_JOIN @@ -1434,10 +1602,11 @@ sent in arguments are actually Public Key Payloads. Sent when a client has been kicked from a channel. This is sent also to the client which was kicked from the channel. The client which was kicked from the channel MUST be removed - from the channel. This notify type is always destined to the - channel. The router or server receiving the packet distributes - this type to the local clients on the channel and broadcast it - to the network. + from the channel. The client MUST also be removed from channel's + invite list if it is explicitly added in the list. This notify + type is always destined to the channel. The router or server + receiving the packet distributes this type to the local clients + on the channel and broadcast it to the network. Max Arguments: 3 Arguments: (1) (2) [] @@ -1456,7 +1625,9 @@ sent in arguments are actually Public Key Payloads. This notify type is destined directly to the client which was killed and to channel if the client is on any channel. The router or server receiving the packet distributes this type to the local - clients on the channel and broadcast it to the network. + clients on the channel and broadcast it to the network. The client + MUST also be removed from joined channels invite list if it is + explicitly added in the lists. Max Arguments: 3 Arguments: (1) (2) [] @@ -1486,15 +1657,15 @@ sent in arguments are actually Public Key Payloads. sent only between routers as broadcast packet. Max Arguments: 3 - Arguments: (1) (2) [] - (3) [] + Arguments: (1) (2) [] + (3) [] - The is the channel which ban list was changed. The - is used to indicate that a ban was added and the - is used to indicate that a ban was removed from - the ban list. The format of the and the - is defined in the [SILC4] with SILC_COMMAND_BAN - command. + The is the channel which ban list was changed. + The is an argument of size of 1 byte where 0x00 means + adding a client to ban list, and 0x01 means deleting a client + from ban list. The indicates the information to be + added to or removed from the ban list. The format + format is defined in [SILC4] with SILC_COMMAND_BAN command. 16 SILC_NOTIFY_TYPE_ERROR @@ -1580,12 +1751,12 @@ that the client takes error packet seriously. .in 3 .ce -Figure 12: Error Payload +Figure 13: Error Payload .in 6 o Error Message (variable length) - Human readable error - message. + message as UTF-8 string. .in 3 @@ -1601,9 +1772,8 @@ reception of channel message is required. Padding MUST be applied into this payload since the payload is encrypted separately from other parts of the packet with the channel specific key. Hence the requirement of the padding. -The padding SHOULD be random data. The packet MUST be made -multiple by eight (8) or by the block size of the cipher, which -ever is larger. +The packet MUST be made multiple by eight (8) or by the block +size of the cipher, which ever is larger. The SILC header in this packet is encrypted with the session key of the next receiver of the packet. Nothing else is encrypted @@ -1619,154 +1789,8 @@ The original sender of the packet is also determined by checking the source ID from the header which tells the client which sent the message. -The payload may only be sent with SILC_PACKET_CHANNEL_MESSAGE packet. -It MUST NOT be sent in any other packet type. The following diagram -represents the Channel Message Payload. - -(*) indicates that the field is not encrypted. - - -.in 5 -.nf - 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Message Flags | Message Length | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -~ Message Data ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Padding Length | | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + -| | -~ Padding ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -~ Initial Vector * ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -~ MAC * ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -.in 3 - -.ce -Figure 13: Channel Message Payload - - -.in 6 -o Message Flags (2 bytes) - Includes the Message Flags of - the channel messages. The flags can indicate a reason or - purpose for the channel message. Note that the Private - Message Payload use these same Message Flags for the same - purpose. The following Message Flags are defined: - - 0x0000 SILC_MESSAGE_FLAG_NONE - - No specific flags set. - - 0x0001 SILC_MESSAGE_FLAG_AUTOREPLY - - This message is an automatic reply to an earlier - received message. - - 0x0002 SILC_MESSAGE_FLAG_NOREPLY - - There should not be reply messages to this - message. - - 0x0004 SILC_MESSAGE_FLAG_ACTION - - The sender is performing an action and the message - is the indication of the action. - - 0x0008 SILC_MESSAGE_FLAG_NOTICE - - The message is for example an informational notice - type message. - - 0x0010 SILC_MESSAGE_FLAG_REQUEST - - This is a generic request flag to send request - messages. A separate document should define any - payloads associated to this flag. - - 0x0020 SILC_MESSAGE_FLAG_SIGNED - - This flag indicates that the message is signed - with sender's private key and thus can be verified - by the receiver using the sender's public key. A - separate document should define the detailed procedure - of the signing process and any associated payloads - of this flag. - - 0x0040 SILC_MESSAGE_FLAG_REPLY - - This is a generic reply flag to send a reply to - previously received request. A separate document - should define any payloads associated to this flag. - - 0x0080 SILC_MESSAGE_FLAG_DATA - - This is a generic data flag, indicating that the - message includes some data which can be interpreted - in a specific way. Using this flag any kind of data - can be delivered inside message payload. A separate - document should define how this flag is interpreted - and define any associated payloads. - - 0x0100 SILC_MESSAGE_FLAG_UTF8 - - This flag indicates that the message is UTF-8 encoded - textual message. When sending text messages this - flag SHOULD be used. When this flag is used the text - sent as message MUST be UTF-8 encoded. - - 0x0200 - 0x0800 RESERVED - - Reserved for future flags - - 0x1000 - 0x8000 PRIVATE RANGE - - Private range for free use. - -o Message Length (2 bytes) - Indicates the length of the - Message Data field in the payload, not including any - other field. - -o Message Data (variable length) - The actual message to - the channel. - -o Padding Length (2 bytes) - Indicates the length of the - Padding field in the payload, not including any other - field. - -o Padding (variable length) - The padding that MUST be - applied because this payload is encrypted separately from - other parts of the packet. - -o Initial Vector (variable length) - The initial vector - that has been used in packet encryption. It needs to be - used in the packet decryption as well. Contents of this - field depends on the encryption algorithm and mode. This - field is not encrypted, is not included in padding - calculation and its length equals to cipher's block size. - This field is authenticated by the channel message MAC. - -o MAC (variable length) - The MAC computed from the - Message Flags, Message Length, Message Data, Padding Length, - Padding and Initial Vector fields in that order. The MAC - is computed after the payload is encrypted. This is so - called Encrypt-Then-MAC order; first encrypt, then compute - MAC from ciphertext. The MAC protects the integrity of - the channel message. Also, if more than one private key - has been set for the channel, the receiver can verify which - of the keys must be used in decryption. This field is not - encrypted. -.in 3 +This packet use generic Message Payload as Channel Message Payload. +See section 2.3.2.5 for generic Message Payload. .ti 0 @@ -1861,19 +1885,18 @@ o Channel Key (variable length) - The actual channel key 2.3.11 Private Message Payload Private Message Payload is used to send private message between -two clients (or users for that matter). The messages are sent only -to the specified user and no other user inside SILC network is -able to see the message. The message is protected by the session -key established by the SILC Key Exchange Protocol. - -However, it is also possible to agree to use a private key to -protect just the private messages. It is for example possible to -perform Key Agreement between two clients. See section 2.3.20 -Key Agreement Payload how to perform key agreement. See also -section 2.3.12 Private Message Key Payload for another way of -using private keys with private messages. See [SILC1] section -4.6 for detailed description for private message key generation -procedure. +two clients. The messages are sent only to the specified user +and no other user inside SILC network is able to see the message. + +The message can be protected by the session key established by the +SILC Key Exchange Protocol. However, it is also possible to agree +to use a private key to protect just the private messages. It is +for example possible to perform Key Agreement between two clients. +See section 2.3.20 Key Agreement Payload how to perform key +agreement. See also section 2.3.12 Private Message Key Payload +for another way of using private keys with private messages. See +[SILC1] section 4.6 for detailed description for private message +key generation procedure. If normal session key is used to protect the message, every server between the sender client and the receiving client MUST decrypt the @@ -1885,71 +1908,8 @@ the sender and the receiver needs not to decrypt/re-encrypt the packet. Section Client To Client in [SILC1] gives example of this scheme as well. -The payload may only be sent with SILC_PACKET_PRIVATE_MESSAGE -packet. It MUST NOT be sent in any other packet type. The following -diagram represents the Private Message Payload. - -(*) indicates that the field is not encrypted. - - -.in 5 -.nf - 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Message Flags | Message Data Length | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -~ Message Data ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -~ Padding ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -~ MAC * ~ -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -.in 3 - -.ce -Figure 15: Private Message Payload - - -.in 6 -o Message Flags (2 bytes) - This field includes the Message - Flags of the private message. They can indicate a different - reason or purpose for the private message. See the section - 2.3.9 Channel Message Payload for defined flags. Note that - the Channel Message Payload use the same flags for the - same purpose. - -o Message Data Length (2 bytes) - Indicates the length of the - Message Data field, not including any other field. - -o Message Data (variable length) - The actual message to - the client. - -o Padding (variable length) - This field is present only - when the private message payload is encrypted with private - message key. In this case the padding is applied to make - the payload multiple by eight (8), or by the block size of - the cipher, which ever is larger. When encrypted with - normal session keys, this field MUST NOT be included. - -o MAC (variable length) - This field is present only when - the private message payload is encrypted with private - message key. The MAC is computed from the Message Flags, - Message Data Length, Message Data and Padding fields in - that order. The MAC protects the integrity of the private - message. The MAC is computed after encryption from the - ciphertext. This is so called Encrypt-Then-MAC order; - first encrypt, then compute MAC from ciphertext. Note that, - this field is not encrypted and thus not included in the - padding calculation. When encrypted with normal session - keys, this field MUST NOT be included. -.in 3 +This packet use generic Message Payload as Private Message Payload. +See section 2.3.2.5 for generic Message Payload. .ti 0 @@ -2004,7 +1964,7 @@ diagram represents the Private Message Key Payload. .in 3 .ce -Figure 16: Private Message Key Payload +Figure 15: Private Message Key Payload @@ -2057,7 +2017,7 @@ represents the Command Payload. .in 3 .ce -Figure 17: Command Payload +Figure 16: Command Payload .in 6 @@ -2139,7 +2099,7 @@ diagram represents the Connection Auth Request Payload. .in 3 .ce -Figure 18: Connection Auth Request Payload +Figure 17: Connection Auth Request Payload .in 6 @@ -2209,7 +2169,7 @@ Thus, this payload is very important and used every time when some new entity is registered to the SILC network. Client MUST NOT send this payload. Both client and server (and router) MAY receive this payload. -The packet uses generic ID Payload as New ID Payload. See section +The packet use generic ID Payload as New ID Payload. See section 2.3.2.1 for generic ID Payload. @@ -2257,7 +2217,7 @@ represents the New Client Payload. .in 3 .ce -Figure 19: New Client Payload +Figure 18: New Client Payload .in 6 @@ -2310,7 +2270,7 @@ represents the New Server Payload. .in 3 .ce -Figure 20: New Server Payload +Figure 19: New Server Payload .in 6 @@ -2341,7 +2301,7 @@ send this packet. Server may send this packet to a router when it is announcing its existing channels to the router after it has connected to the router. -The packet uses generic Channel Payload as New Channel Payload. See +The packet use generic Channel Payload as New Channel Payload. See section 2.3.2.3 for generic Channel Payload. The Mode Mask field in the Channel Payload is the mode of the channel. @@ -2387,7 +2347,7 @@ types. The following diagram represents the Key Agreement Payload. .in 3 .ce -Figure 21: Key Agreement Payload +Figure 20: Key Agreement Payload .in 6 @@ -2433,7 +2393,7 @@ represents the Resume Router Payload. .in 3 .ce -Figure 22: Resume Router Payload +Figure 21: Resume Router Payload .in 6 @@ -2483,7 +2443,7 @@ File Transfer Payload. .in 3 .ce -Figure 23: File Transfer Payload +Figure 22: File Transfer Payload .in 6 @@ -2491,7 +2451,7 @@ o Type (1 byte) - Indicates the type of the file transfer protocol. The following file transfer protocols has been defined: - 1 SSH File Transfer Protocol (SFTP) (mandatory) + 1 Secure File Transfer Protocol (SFTP) (mandatory) If zero (0) value or any unsupported file transfer protocol type is found in this field the packet must be discarded. @@ -2551,7 +2511,7 @@ represents the Resume Client Payload. .in 3 .ce -Figure 24: Resume Client Payload +Figure 23: Resume Client Payload .in 6 @@ -2580,7 +2540,7 @@ network. .in 6 0 No ID - When ever specific ID cannot be used this is used. + This is used when other ID type is available at the time. 1 Server ID @@ -2753,7 +2713,7 @@ See [SILC1] for defined and allowed MAC algorithms. 2.7 Packet Padding Generation Padding is needed in the packet because the packet is encrypted. It -MUST always be multiple by eight (8) or multiple by the block size +always MUST be multiple by eight (8) or multiple by the block size of the cipher, which ever is larger. The padding is always encrypted. For normal packets the padding is added after the SILC Packet Header diff --git a/doc/draft-riikonen-silc-spec-06.nroff b/doc/draft-riikonen-silc-spec-06.nroff index 0cf5c3ad..7f92b13b 100644 --- a/doc/draft-riikonen-silc-spec-06.nroff +++ b/doc/draft-riikonen-silc-spec-06.nroff @@ -103,6 +103,9 @@ Table of Contents 3.9.1 Authentication Payload .............................. 21 3.10 Algorithms ............................................... 23 3.10.1 Ciphers ............................................ 23 + 3.10.1.1 CBC Mode .................................. XXX + 3.10.1.2 CTR Mode .................................. XXX + 3.10.1.3 Randomized CBC Mode ....................... XXX 3.10.2 Public Key Algorithms .............................. 24 3.10.3 Hash Functions ..................................... 24 3.10.4 MAC Algorithms ..................................... 25 @@ -141,6 +144,7 @@ Figure 2: Communication Inside cell Figure 3: Communication Between Cells Figure 4: Router Connections Figure 5: SILC Public Key +Figure 6: Counter Block .ti 0 @@ -1161,7 +1165,7 @@ The receiver will compute the signature using the random data received in the payload, the ID associated to the connection and the public key (or certificate) received in the SKE protocol. After computing the receiver MUST verify the signature. In case of public key authentication -this payload is also encrypted. +also this payload is encrypted. .ti 0 @@ -1183,33 +1187,133 @@ must be supported in order to be compliant with this protocol. The following ciphers are defined in SILC protocol: .in 6 -aes-256-cbc AES in CBC mode, 256 bit key (REQUIRED) -aes-192-cbc AES in CBC mode, 192 bit key (OPTIONAL) -aes-128-cbc AES in CBC mode, 128 bit key (OPTIONAL) -twofish-256-cbc Twofish in CBC mode, 256 bit key (OPTIONAL) -twofish-192-cbc Twofish in CBC mode, 192 bit key (OPTIONAL) -twofish-128-cbc Twofish in CBC mode, 128 bit key (OPTIONAL) -blowfish-128-cbc Blowfish in CBC mode, 128 bit key (OPTIONAL) -cast-256-cbc CAST-256 in CBC mode, 256 bit key (OPTIONAL) -cast-192-cbc CAST-256 in CBC mode, 192 bit key (OPTIONAL) -cast-128-cbc CAST-256 in CBC mode, 128 bit key (OPTIONAL) -rc6-256-cbc RC6 in CBC mode, 256 bit key (OPTIONAL) -rc6-192-cbc RC6 in CBC mode, 192 bit key (OPTIONAL) -rc6-128-cbc RC6 in CBC mode, 128 bit key (OPTIONAL) -mars-256-cbc Mars in CBC mode, 256 bit key (OPTIONAL) -mars-192-cbc Mars in CBC mode, 192 bit key (OPTIONAL) -mars-128-cbc Mars in CBC mode, 128 bit key (OPTIONAL) -none No encryption (OPTIONAL) +aes-256-cbc AES in CBC mode, 256 bit key (REQUIRED) +aes-256-ctr AES in CTR mode, 256 bit key (RECOMMENDED) +aes-256-rcbc AES in randomized CBC mode, 256 bit key (OPTIONAL) +aes-192- AES in mode, 192 bit key (OPTIONAL) +aes-128- AES in mode, 128 bit key (RECOMMENDED) +twofish-256- Twofish in mode, 256 bit key (OPTIONAL) +twofish-192- Twofish in mode, 192 bit key (OPTIONAL) +twofish-128- Twofish in mode, 128 bit key (OPTIONAL) +cast-256- CAST-256 in mode, 256 bit key (OPTIONAL) +cast-192- CAST-256 in mode, 192 bit key (OPTIONAL) +cast-128- CAST-256 in mode, 128 bit key (OPTIONAL) +serpent-- Serpent in mode, bit key (OPTIONAL) +rc6-- RC6 in mode, bit key (OPTIONAL) +mars-- MARS in mode, bit key (OPTIONAL) +none No encryption (OPTIONAL) .in 3 -Algorithm none does not perform any encryption process at all and +The is either "cbc", "ctr" or "rcbc". Other encryption modes MAY +be defined as to be used in SILC using the same format. The is +either 256, 192 or 128 bit key length. Also, additional ciphers MAY be +defined to be used in SILC by using the same name format as above. + +Algorithm "none" does not perform any encryption process at all and thus is not recommended to be used. It is recommended that no client -or server implementation would accept none algorithms except in special +or server implementation would accept none algorithm except in special debugging mode. -Additional ciphers MAY be defined to be used in SILC by using the -same name format as above. + +.ti 0 +3.10.1.1 CBC Mode + +The "cbc" encryption mode is CBC mode with inter-packet chaining. This +means that the Initial Vector (IV) for the next encryption block is +the previous ciphertext block. The very first IV MUST be random and is +generated as described in [SILC3]. + + +.ti 0 +3.10.1.2 CTR Mode + +The "ctr" encryption mode is CTR mode. The CTR mode in SILC is stateful +in encryption and decryption. Both sender and receiver maintain the +counter for the CTR mode and thus can precompute the key stream for +encryption and decryption. By default, CTR mode does not require +plaintext padding, however implementations MAY apply padding to the +packets. If the last key block is larger than the last plaintext block +the resulted value is truncated to the size of the plaintext block and +the most significant bits are used. When sending authentication data +inside packets the maximum amount of padding SHOULD be applied with +CTR mode as well. + +In CTR mode only the encryption operation of the cipher is used. The +decryption operation is not needed since both encryption and decryption +process is simple XOR with the plaintext block and the key stream block. + +The counter block is used to create the key for the CTR mode. When +SILC specifications refer to Initial Vector (IV) in general cases, in +case of CTR mode it refers to the counter block. The format of the +128 bit counter block is as follows: + +.in 5 +.nf + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Truncated HASH from SKE | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Sending/Receiving IV from SKE | +| | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Block Counter | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +.in 3 + +.ce +Figure 6: Counter Block + +.in 6 +o Truncated HASH from SKE (4 bytes) - This value is the 32 most + significant bits from the HASH value that was computed as a + result of SKE protocol. This acts as session identifier and + each rekey MUST produce a new HASH value. + +o Sending/Receiving IV from SKE (8 bytes) - This value is the 64 + most significant bits from the Sending IV or Receiving IV + generated in the SKE protocol. When this mode is used to + encrypt sending traffic the Sending IV is used, when used to + decrypt receiving traffic the Receiving IV is used. This + assures that two parties of the protocol use different IV + for sending traffic. Each rekey MUST produce a new value. + +o Block Counter (4 bytes) - This is the counter value for the + counter block and is MSB ordered number starting from one (1) + value for first block and incrementing for subsequent blocks. + The same value MUST NOT be used twice. The rekey MUST be + performed before this counter value wraps. +.in 3 + +CTR mode MUST NOT be used with "none" MAC. Implementations also MUST +assure that the same counter block is not used to encrypt more than +one block. Also, the key material used with CTR mode MUST be fresh +key material. Static keys (pre-shared keys) MUST NOT be used with +CTR mode. For this reason using CTR mode to encrypt for example +channel messages or private messages with a pre-shared key is +inappropriate. For private messages, the Key Agreement could be +performed to produce fresh key material. + +If the IV Included flag was negotiated in SKE, implementations SHOULD +still use the same counter block format as defined above. However, +implementations are RECOMMENDED to replace the Truncated HASH field +with a 32 bit random value for each IV (counter block) per encrypted +SILC packet. Also note, that in this case the decryption process is +not stateful and receiver cannot precompute the key stream. + + +.ti 0 +3.10.1.3 Randomized CBC Mode + +The "rcbc" encryption mode is CBC mode with randomized IV. This means +that each IV for each packet MUST be chosen randomly. In this mode the +IV is appended at the end of the last ciphertext block and thus delivered +to the recipient. This mode increases the ciphertext size by one +ciphertext block. Note also that some data payloads in SILC are capable +of delivering the IV to the recipient. When explicitly encrypting these +payloads with randomized CBC the IV MUST NOT be appended at the end +of the ciphertext. .ti 0 @@ -1261,7 +1365,7 @@ The following Hash algorithm are defined in SILC protocol: .in 6 sha1 SHA-1, length = 20 (REQUIRED) -md5 MD5, length = 16 (OPTIONAL) +md5 MD5, length = 16 (RECOMMENDED) .in 3 @@ -1275,21 +1379,21 @@ MAC. The following MAC algorithms are defined in SILC protocol: .in 6 -hmac-sha1-96 HMAC-SHA1, length = 12 (REQUIRED) -hmac-md5-96 HMAC-MD5, length = 12 (OPTIONAL) -hmac-sha1 HMAC-SHA1, length = 20 (OPTIONAL) -hmac-md5 HMAC-MD5, length = 16 (OPTIONAL) -none No MAC (OPTIONAL) +hmac-sha1-96 HMAC-SHA1, length = 12 bytes (REQUIRED) +hmac-md5-96 HMAC-MD5, length = 12 bytes (OPTIONAL) +hmac-sha1 HMAC-SHA1, length = 20 bytes (OPTIONAL) +hmac-md5 HMAC-MD5, length = 16 bytes (OPTIONAL) +none No MAC (OPTIONAL) .in 3 -The none MAC is not recommended to be used as the packet is not +The "none" MAC is not recommended to be used as the packet is not authenticated when MAC is not computed. It is recommended that no client or server would accept none MAC except in special debugging mode. The HMAC algorithm is described in [HMAC] and hash algorithms that are used as part of the HMACs are described in [Scheneir] and in -[Menezes] +[Menezes]. Additional MAC algorithms MAY be defined to be used in SILC. @@ -1578,9 +1682,19 @@ All the other parties of the protocol must also update their local database to understand that the route to the primary router will now go to the backup router. -The servers connected to the backup router must announce their clients, -channels, channel users, channel user modes and channel modes to the -backup router. This is to assure that none of the important notify +Servers connected to the backup router MUST send SILC_PACKET_RESUME_ROUTER +packet with type number 21, to indicate that the server will start using +the backup router as primary router. The backup router MUST NOT allow +this action if it detects that primary is still up and running. If +backup router knows that primary is up and running it MUST send type +number 22 back to the server. The server then MUST NOT use the backup +as primary router, but must try to establish connection back to the +primary router. If the action is allowed type number 21 is sent back +to the server from the backup router. + +The servers connected to the backup router must then announce their +clients, channels, channel users, channel user modes and channel modes +to the backup router. This is to assure that none of the important notify packets were lost during the switch to the backup router. The backup router must check which of these announced entities it already have and distribute the new ones to the primary route. @@ -1614,6 +1728,13 @@ resuming protocol is executed. The protocol is advanced as follows: all of its channels, channel users, modes etc. to the primary router. + If the primary knows that it has not been replaced (for example + the backup itself disconnected from the primary router and thinks + that it is now primary in the cell) the primary router send + SILC_PACKET_FAILURE with the type value 1 back to the backup + router. If backup receives this it MUST NOT continue with the + backup resuming protocol. + 2. Backup router sends SILC_PACKET_RESUME_ROUTER packet with type value 2 to its current primary router to indicate that it will resign as being primary router. Then, backup router sends the @@ -1693,6 +1814,8 @@ packet: 5 SILC_SERVER_BACKUP_START_RESUMED 6 SILC_SERVER_BACKUP_START_RESUMED_GLOBAL 20 SILC_SERVER_BACKUP_START_REPLACED + 21 SILC_SERVER_BACKUP_START_USE + 22 SILC_SERVER_BACKUP_START_USE_DENIED If any other value is found in the type field the packet must be discarded. The SILC_PACKET_RESUME_ROUTER packet and its payload @@ -2019,32 +2142,38 @@ process. .ti 0 4.6 Private Message Key Generation -Private message MAY be protected by the key generated by the client. +Private message MAY be protected with a key generated by the client. The key may be generated and sent to the other client by sending packet SILC_PACKET_PRIVATE_MESSAGE_KEY which travels through the network and is secured by session keys. After that the private message key is used in the private message communication between those clients. +The key sent inside the payload SHOULD be randomly generated. This +packet MUST NOT be used to send pre-shared keys. Other choice is to entirely use keys that are not sent through the SILC network at all. This significantly adds security. This key -would be pre-shared-key that is known by both of the clients. Both +could be a pre-shared-key that is known by both of the clients. Both agree about using the key and starts sending packets that indicate -that the private message is secured using private message key. - -The key material used as private message key is implementation issue. -However, SILC_PACKET_KEY_AGREEMENT packet MAY be used to negotiate -the key material. If the key is normal pre-shared-key or randomly -generated key, and the SILC_PACKET_KEY_AGREEMENT was not used, then -the key material SHOULD be processed as defined in the [SILC3]. In -the processing, however, the HASH, as defined in [SILC3] MUST be -ignored. After processing the key material it is employed as defined -in [SILC3]. - -If the key is pre-shared-key or randomly generated the implementations -SHOULD use the SILC protocol's mandatory cipher as the cipher, and the -mandatory HMAC as the HMAC. If the SKE was used to negotiate key material -the cipher was negotiated as well, and may be different from default -cipher and default HMAC. +that the private message is secured using private message key. In +case of pre-shared keys (static keys) the IV used in encryption SHOULD +be chosen randomly. + +It is also possible to negotiate fresh key material by performing +Key Agreement. The SILC_PACKET_KEY_AGREEMENT packet MAY be used to +negotiate the fresh key material. In this case the resulted key +material is used to secure the private messages. Also, the IV used +in encryption is used as defined in [SILC3], unless otherwise stated +by the encryption mode used. By performing Key Agreement the clients +may negotiate the cipher and HMAC to be used in the private message +encryption and to negotiate additional security parameters. + +If the key is pre-shared key or other key material not generated by +Key Agreement, then the key material SHOULD be processed as defined +in [SILC3]. In the processing, however, the HASH, as defined in +[SILC3] MUST be ignored. After processing the key material it is +employed as defined in [SILC3]. In this case also, implementations +SHOULD use the SILC protocol's mandatory cipher and HMAC in private +message encryption. .ti 0 diff --git a/includes/silcincludes.h.in b/includes/silcincludes.h.in index 16bbf4d2..9c37c009 100644 --- a/includes/silcincludes.h.in +++ b/includes/silcincludes.h.in @@ -257,12 +257,12 @@ extern "C" { #include "silcidcache.h" #include "silcargument.h" #include "silccommand.h" +#include "silcmessage.h" #include "silcchannel.h" #include "silcpacket.h" #include "silcnotify.h" #include "silcmode.h" #include "silcauth.h" -#include "silcprivate.h" #include "silcattrs.h" #include "silcvcard.h" diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 0eb263c1..67cde554 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -41,7 +41,6 @@ void silc_client_send_channel_message(SilcClient client, SilcUInt32 data_len, bool force_send) { - int i; SilcSocketConnection sock; SilcBuffer payload; SilcPacketContext packetdata; @@ -49,7 +48,6 @@ void silc_client_send_channel_message(SilcClient client, SilcCipher cipher; SilcHmac hmac; unsigned char *id_string; - SilcUInt32 iv_len; int block_len; SilcChannelUser chu; @@ -109,18 +107,9 @@ void silc_client_send_channel_message(SilcClient client, block_len = silc_cipher_get_block_len(cipher); - /* Generate IV */ - iv_len = silc_cipher_get_block_len(cipher); - if (channel->iv[0] == '\0') - for (i = 0; i < iv_len; i++) channel->iv[i] = - silc_rng_get_byte(client->rng); - else - silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv); - - /* Encode the channel payload. This also encrypts the message payload. */ - payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len, - channel->iv, cipher, hmac, - client->rng); + /* Encode the message payload. This also encrypts the message payload. */ + payload = silc_message_payload_encode(flags, data, data_len, TRUE, FALSE, + cipher, hmac, client->rng); /* Get data used in packet header encryption, keys and stuff. */ cipher = conn->internal->send_key; @@ -181,7 +170,7 @@ void silc_client_send_channel_message(SilcClient client, } typedef struct { - SilcChannelMessagePayload payload; + SilcMessagePayload payload; SilcChannelID *channel_id; } *SilcChannelClientResolve; @@ -212,24 +201,24 @@ static void silc_client_channel_message_cb(SilcClient client, silc_hash_table_add(clients[0]->channels, channel, chu); } - message = silc_channel_message_get_data(res->payload, &message_len); + message = silc_message_get_data(res->payload, &message_len); /* Pass the message to application */ client->internal->ops->channel_message( client, conn, clients[0], channel, - silc_channel_message_get_flags(res->payload), + silc_message_get_flags(res->payload), message, message_len); } out: - silc_channel_message_payload_free(res->payload); + silc_message_payload_free(res->payload); silc_free(res->channel_id); silc_free(res); } /* Process received message to a channel (or from a channel, really). This decrypts the channel message with channel specific key and parses the - channel payload. Finally it displays the message on the screen. */ + message payload. Finally it displays the message on the screen. */ void silc_client_channel_message(SilcClient client, SilcSocketConnection sock, @@ -237,7 +226,7 @@ void silc_client_channel_message(SilcClient client, { SilcClientConnection conn = (SilcClientConnection)sock->user_data; SilcBuffer buffer = packet->buffer; - SilcChannelMessagePayload payload = NULL; + SilcMessagePayload payload = NULL; SilcChannelID *id = NULL; SilcChannelEntry channel; SilcClientEntry client_entry; @@ -269,9 +258,9 @@ void silc_client_channel_message(SilcClient client, all private keys and check what decrypts correctly. */ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { /* Parse the channel message payload. This also decrypts the payload */ - payload = silc_channel_message_payload_parse(buffer->data, buffer->len, - channel->channel_key, - channel->hmac); + payload = silc_message_payload_parse(buffer->data, buffer->len, FALSE, + FALSE, channel->channel_key, + channel->hmac); /* If decryption failed and we have just performed channel key rekey we will use the old key in decryption. If that fails too then we @@ -281,9 +270,10 @@ void silc_client_channel_message(SilcClient client, goto out; } - payload = silc_channel_message_payload_parse(buffer->data, buffer->len, - channel->old_channel_key, - channel->old_hmac); + payload = silc_message_payload_parse(buffer->data, buffer->len, + FALSE, FALSE, + channel->old_channel_key, + channel->old_hmac); if (!payload) { goto out; } @@ -293,10 +283,10 @@ void silc_client_channel_message(SilcClient client, silc_dlist_start(channel->private_keys); while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) { - /* Parse the channel message payload. This also decrypts the payload */ - payload = silc_channel_message_payload_parse(buffer->data, buffer->len, - entry->cipher, - entry->hmac); + /* Parse the message payload. This also decrypts the payload */ + payload = silc_message_payload_parse(buffer->data, buffer->len, + FALSE, FALSE, + entry->cipher, entry->hmac); if (payload) break; } @@ -322,19 +312,19 @@ void silc_client_channel_message(SilcClient client, goto out; } - message = silc_channel_message_get_data(payload, &message_len); + message = silc_message_get_data(payload, &message_len); /* Pass the message to application */ client->internal->ops->channel_message( client, conn, client_entry, channel, - silc_channel_message_get_flags(payload), + silc_message_get_flags(payload), message, message_len); out: silc_free(id); silc_free(client_id); if (payload) - silc_channel_message_payload_free(payload); + silc_message_payload_free(payload); } /* Timeout callback that is called after a short period of time after the diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index d447e0af..aff49a23 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -53,11 +53,12 @@ void silc_client_send_private_message(SilcClient client, SILC_LOG_DEBUG(("Sending private message")); /* Encode private message payload */ - buffer = silc_private_message_payload_encode(flags, - data_len, data, - client_entry->send_key, - client_entry->hmac_send, - client->rng); + buffer = silc_message_payload_encode(flags, data, data_len, + !client_entry->send_key ? FALSE : + !client_entry->generated, + TRUE, client_entry->send_key, + client_entry->hmac_send, + client->rng); /* If we don't have private message specific key then private messages are just as any normal packet thus call normal packet sending. If @@ -153,7 +154,7 @@ void silc_client_private_message(SilcClient client, SilcPacketContext *packet) { SilcClientConnection conn = (SilcClientConnection)sock->user_data; - SilcPrivateMessagePayload payload = NULL; + SilcMessagePayload payload = NULL; SilcClientID *remote_id = NULL; SilcClientEntry remote_client; SilcMessageFlags flags; @@ -197,18 +198,19 @@ void silc_client_private_message(SilcClient client, } /* Parse the payload and decrypt it also if private message key is set */ - payload = silc_private_message_payload_parse(packet->buffer->data, - packet->buffer->len, - cipher, hmac); + payload = silc_message_payload_parse(packet->buffer->data, + packet->buffer->len, TRUE, + !remote_client->generated, + cipher, hmac); if (!payload) { silc_free(remote_id); return; } - flags = silc_private_message_get_flags(payload); + flags = silc_message_get_flags(payload); /* Pass the private message to application */ - message = silc_private_message_get_message(payload, &message_len); + message = silc_message_get_data(payload, &message_len); client->internal->ops->private_message(client, conn, remote_client, flags, message, message_len); @@ -230,7 +232,7 @@ void silc_client_private_message(SilcClient client, out: if (payload) - silc_private_message_payload_free(payload); + silc_message_payload_free(payload); silc_free(remote_id); } @@ -452,6 +454,8 @@ bool silc_client_add_private_message_key_ske(SilcClient client, if (!silc_hmac_is_supported(hmac)) return FALSE; + client_entry->generated = TRUE; + /* Allocate the cipher and HMAC */ silc_cipher_alloc(cipher, &client_entry->send_key); silc_cipher_alloc(cipher, &client_entry->receive_key); diff --git a/lib/silccore/DIRECTORY b/lib/silccore/DIRECTORY index 26f07763..6d0fbb6f 100644 --- a/lib/silccore/DIRECTORY +++ b/lib/silccore/DIRECTORY @@ -2,6 +2,7 @@ @LIBRARY=SILC Core Library @FILENAME=silccorelib.html @LINK=silcauth.html:SILC Authentication Interface +@LINK=silcmessage.html:SILC Message Interface @LINK=silcchannel.html:SILC Channel Interface @LINK=silccommand.html:SILC Command Interface @LINK=silcnotify.html:SILC Notify Interface @@ -10,7 +11,6 @@ @LINK=silcid.html:SILC ID Interface @LINK=silcidcache.html:SILC ID Cache Interface @LINK=silcargument.html:SILC Argument Interface -@LINK=silcprivate.html:SILC Private Message Interface @LINK=silcattrs.html:SILC Attributes Interface @LINK=silcpacket.html:Packet Protocol Interface --> diff --git a/lib/silccore/Makefile.am b/lib/silccore/Makefile.am index 50dd1dd0..afefc362 100644 --- a/lib/silccore/Makefile.am +++ b/lib/silccore/Makefile.am @@ -22,19 +22,20 @@ noinst_LTLIBRARIES = libsilccore.la libsilccore_la_SOURCES = \ silcid.c \ silcidcache.c \ + silcmessage.c \ silcchannel.c \ silccommand.c \ silcpacket.c \ silcargument.c \ silcnotify.c \ silcauth.c \ - silcattrs.c \ - silcprivate.c + silcattrs.c if SILC_DIST_TOOLKIT include_HEADERS = \ silcauth.h \ silcchannel.h \ + silcmessage.h \ silccommand.h \ silcidcache.h \ silcid.h \ @@ -43,8 +44,7 @@ include_HEADERS = \ silcpacket.h \ silcargument.h \ silcstatus.h \ - silcattrs.h \ - silcprivate.h + silcattrs.h endif EXTRA_DIST = *.h diff --git a/lib/silccore/silcauth.c b/lib/silccore/silcauth.c index c93f02df..7b7128ce 100644 --- a/lib/silccore/silcauth.c +++ b/lib/silccore/silcauth.c @@ -20,8 +20,6 @@ #include "silcincludes.h" #include "silcauth.h" -#include "silcchannel_i.h" -#include "silcprivate_i.h" /****************************************************************************** @@ -540,319 +538,3 @@ SilcUInt32 silc_key_agreement_get_port(SilcKeyAgreementPayload payload) { return payload->port; } - -/****************************************************************************** - - SILC_MESSAGE_FLAG_SIGNED Payload - -******************************************************************************/ - -/* The SILC_MESSAGE_FLAG_SIGNED Payload */ -struct SilcSignedPayloadStruct { - SilcUInt16 pk_len; - SilcUInt16 pk_type; - SilcUInt16 sign_len; - unsigned char *pk_data; - unsigned char *sign_data; -}; - -/* Encodes the data to be signed to SILC_MESSAGE_FLAG_SIGNED Payload */ - -static SilcBuffer -silc_signed_payload_encode_data(const unsigned char *message_payload, - SilcUInt32 message_payload_len, - unsigned char *pk, - SilcUInt32 pk_len, SilcUInt32 pk_type) -{ - SilcBuffer sign; - - sign = silc_buffer_alloc_size(message_payload_len + 4 + pk_len); - if (!sign) - return NULL; - - silc_buffer_format(sign, - SILC_STR_UI_XNSTRING(message_payload, - message_payload_len), - SILC_STR_UI_SHORT(pk_len), - SILC_STR_UI_SHORT(pk_type), - SILC_STR_END); - - if (pk && pk_len) { - silc_buffer_pull(sign, message_payload_len + 4); - silc_buffer_format(sign, - SILC_STR_UI_XNSTRING(pk, pk_len), - SILC_STR_END); - silc_buffer_push(sign, message_payload_len + 4); - } - - return sign; -} - -/* Parses the SILC_MESSAGE_FLAG_SIGNED Payload */ - -SilcSignedPayload silc_signed_payload_parse(const unsigned char *data, - SilcUInt32 data_len) -{ - SilcSignedPayload sig; - SilcBufferStruct buffer; - int ret; - - SILC_LOG_DEBUG(("Parsing SILC_MESSAGE_FLAG_SIGNED Payload")); - - silc_buffer_set(&buffer, (unsigned char *)data, data_len); - sig = silc_calloc(1, sizeof(*sig)); - if (!sig) - return NULL; - - /* Parse the payload */ - ret = silc_buffer_unformat(&buffer, - SILC_STR_UI_SHORT(&sig->pk_len), - SILC_STR_UI_SHORT(&sig->pk_type), - SILC_STR_END); - if (ret == -1 || sig->pk_len > data_len - 4) { - silc_signed_payload_free(sig); - return NULL; - } - - silc_buffer_pull(&buffer, 4); - ret = silc_buffer_unformat(&buffer, - SILC_STR_UI_XNSTRING_ALLOC(&sig->pk_data, - sig->pk_len), - SILC_STR_UI16_NSTRING_ALLOC(&sig->sign_data, - &sig->sign_len), - SILC_STR_END); - if (ret == -1) { - silc_signed_payload_free(sig); - return NULL; - } - silc_buffer_push(&buffer, 4); - - /* Signature must be provided */ - if (sig->sign_len < 1) { - silc_signed_payload_free(sig); - return NULL; - } - - return sig; -} - -/* Encodes the SILC_MESSAGE_FLAG_SIGNED Payload and computes the digital - signature. */ - -SilcBuffer silc_signed_payload_encode(const unsigned char *message_payload, - SilcUInt32 message_payload_len, - SilcPublicKey public_key, - SilcPrivateKey private_key, - SilcHash hash, - bool include_public_key) -{ - SilcBuffer buffer, sign; - SilcPKCS pkcs; - unsigned char auth_data[2048]; - SilcUInt32 auth_len; - unsigned char *pk = NULL; - SilcUInt32 pk_len = 0; - SilcUInt16 pk_type; - - if (!message_payload || !message_payload_len || !private_key || !hash) - return NULL; - if (include_public_key && !public_key) - return NULL; - - if (include_public_key) - pk = silc_pkcs_public_key_encode(public_key, &pk_len); - - /* Now we support only SILC style public key */ - pk_type = SILC_SKE_PK_TYPE_SILC; - - /* Encode the data to be signed */ - sign = silc_signed_payload_encode_data(message_payload, - message_payload_len, - pk, pk_len, pk_type); - if (!sign) { - silc_free(pk); - return NULL; - } - - /* Sign the buffer */ - - /* Allocate PKCS object */ - if (!silc_pkcs_alloc(private_key->name, &pkcs)) { - silc_buffer_clear(sign); - silc_buffer_free(sign); - silc_free(pk); - return NULL; - } - silc_pkcs_private_key_set(pkcs, private_key); - - /* Compute the hash and the signature. */ - if (silc_pkcs_get_key_len(pkcs) / 8 > sizeof(auth_data) - 1 || - !silc_pkcs_sign_with_hash(pkcs, hash, sign->data, sign->len, auth_data, - &auth_len)) { - silc_buffer_clear(sign); - silc_buffer_free(sign); - silc_pkcs_free(pkcs); - silc_free(pk); - return NULL; - } - - /* Encode the SILC_MESSAGE_FLAG_SIGNED Payload */ - - buffer = silc_buffer_alloc_size(4 + pk_len + 2 + auth_len); - if (!buffer) { - silc_buffer_clear(sign); - silc_buffer_free(sign); - silc_pkcs_free(pkcs); - memset(auth_data, 0, sizeof(auth_data)); - silc_free(pk); - return NULL; - } - - silc_buffer_format(sign, - SILC_STR_UI_SHORT(pk_len), - SILC_STR_UI_SHORT(pk_type), - SILC_STR_END); - - if (pk_len && pk) { - silc_buffer_pull(sign, 4); - silc_buffer_format(sign, - SILC_STR_UI_XNSTRING(pk, pk_len), - SILC_STR_END); - silc_buffer_push(sign, 4); - } - - silc_buffer_pull(sign, 4 + pk_len); - silc_buffer_format(sign, - SILC_STR_UI_SHORT(auth_len), - SILC_STR_UI_XNSTRING(auth_data, auth_len), - SILC_STR_END); - silc_buffer_push(sign, 4 + pk_len); - - memset(auth_data, 0, sizeof(auth_data)); - silc_pkcs_free(pkcs); - silc_buffer_clear(sign); - silc_buffer_free(sign); - silc_free(pk); - - return buffer; -} - -/* Free the payload */ - -void silc_signed_payload_free(SilcSignedPayload sig) -{ - if (sig) { - memset(sig->sign_data, 0, sig->sign_len); - silc_free(sig->sign_data); - silc_free(sig->pk_data); - silc_free(sig); - } -} - -/* Verify the signature in SILC_MESSAGE_FLAG_SIGNED Payload */ - -int silc_signed_payload_verify(SilcSignedPayload sig, - bool channel_message, - void *message_payload, - SilcPublicKey remote_public_key, - SilcHash hash) -{ - int ret = SILC_AUTH_FAILED; -#if 0 - SilcBuffer sign; - SilcPKCS pkcs; - - if (!sig || !remote_public_key || !hash) - return ret; - - /* Generate the signature verification data */ - if (channel_message) { - SilcChannelMessagePayload chm = - (SilcChannelMessagePayload)message_payload; - SilcBuffer tmp; - - /* Encode Channel Message Payload */ - tmp = silc_buffer_alloc_size(6 + chm->data_len + chm->pad_len + - chm->iv_len); - silc_buffer_format(tmp, - SILC_STR_UI_SHORT(chm->flags), - SILC_STR_UI_SHORT(chm->data_len), - SILC_STR_UI_XNSTRING(chm->data, chm->data_len), - SILC_STR_UI_SHORT(chm->pad_len), - SILC_STR_UI_XNSTRING(chm->pad, chm->pad_len), - SILC_STR_UI_XNSTRING(chm->iv, chm->iv_len), - SILC_STR_END); - - sign = silc_signed_payload_encode_data(tmp->data, tmp->len, - sig->pk_data, sig->pk_len, - sig->pk_type); - silc_buffer_clear(tmp); - silc_buffer_free(tmp); - } else { - SilcPrivateMessagePayload prm = - (SilcPrivateMessagePayload)message_payload; - SilcBuffer tmp; - - /* Encode Private Message Payload */ - tmp = silc_buffer_alloc_size(4 + prm->data_len + - SILC_PRIVATE_MESSAGE_PAD(4 + prm->data_len)); - silc_buffer_format(tmp, - SILC_STR_UI_SHORT(prm->flags), - SILC_STR_UI_SHORT(prm->message_len), - SILC_STR_UI_XNSTRING(prm->message, prm->message_len), - SILC_STR_END); - - sign = silc_signed_payload_encode_data(tmp->data, tmp->len, - sig->pk_data, sig->pk_len, - sig->pk_type); - silc_buffer_clear(tmp); - silc_buffer_free(tmp); - } - - if (!sign) - return ret; - - /* Allocate PKCS object */ - if (!silc_pkcs_alloc(remote_public_key->name, &pkcs)) { - silc_buffer_clear(sign); - silc_buffer_free(sign); - return ret; - } - silc_pkcs_public_key_set(pkcs, remote_public_key); - - /* Verify the authentication data */ - if (!silc_pkcs_verify_with_hash(pkcs, hash, payload->sign_data - payload->sign_len, - sign->data, sign->len)) { - - silc_buffer_clear(sign); - silc_buffer_free(sign); - silc_pkcs_free(pkcs); - SILC_LOG_DEBUG(("Signature verification failed")); - return ret; - } - - ret = SILC_AUTH_OK; - - silc_buffer_clear(sign); - silc_buffer_free(sign); - silc_pkcs_free(pkcs); - - SILC_LOG_DEBUG(("Signature verification successful")); - -#endif - return ret; -} - -/* Return the public key from the payload */ - -SilcPublicKey silc_signed_payload_get_public_key(SilcSignedPayload sig) -{ - SilcPublicKey pk; - - if (!sig->pk_data || !silc_pkcs_public_key_decode(sig->pk_data, - sig->pk_len, &pk)) - return NULL; - - return pk; -} diff --git a/lib/silccore/silcauth.h b/lib/silccore/silcauth.h index be30c1a6..6f874d95 100644 --- a/lib/silccore/silcauth.h +++ b/lib/silccore/silcauth.h @@ -32,11 +32,6 @@ * used by client to agree on key material usually with another client * in the network. * - * 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. - * ***/ #ifndef SILCAUTH_H @@ -385,126 +380,4 @@ char *silc_key_agreement_get_hostname(SilcKeyAgreementPayload payload); ***/ SilcUInt32 silc_key_agreement_get_port(SilcKeyAgreementPayload payload); -/****s* silccore/SilcAuthAPI/SilcSignedPayload - * - * NAME - * - * typedef struct SilcSignedPayloadStruct *SilcSignedPayload; - * - * - * 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 SilcSignedPayloadStruct *SilcSignedPayload; - -/****f* silccore/SilcAuthAPI/silc_signed_payload_parse - * - * SYNOPSIS - * - * SilcSignedPayload silc_signed_payload_parse(const unsigned char *data, - * SilcUInt32 data_len); - * - * DESCRIPTION - * - * Parses the SILC_MESSAGE_FLAG_SIGNED 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. - * - ***/ -SilcSignedPayload silc_signed_payload_parse(const unsigned char *data, - SilcUInt32 data_len); - -/****f* silccore/SilcAuthAPI/silc_signed_payload_encode - * - * SYNOPSIS - * - * SilcBuffer - * silc_signed_payload_encode(const unsigned char *message_payload, - * SilcUInt32 message_payload_len, - * SilcPublicKey public_key, - * SilcPrivateKey private_key, - * bool include_public_key); - * - * DESCRIPTION - * - * Encodes the SILC_MESSAGE_FLAG_SIGNED 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 `include_public_key' is - * TRUE 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. - * - ***/ -SilcBuffer silc_signed_payload_encode(const unsigned char *message_payload, - SilcUInt32 message_payload_len, - SilcPublicKey public_key, - SilcPrivateKey private_key, - SilcHash hash, - bool include_public_key); - -/****f* silccore/SilcAuthAPI/silc_signed_payload_free - * - * SYNOPSIS - * - * void silc_signed_payload_free(SilcSignedPayload sig); - * - * DESCRIPTION - * - * Frees the SILC_MESSAGE_FLAG_SIGNED Payload. - * - ***/ -void silc_signed_payload_free(SilcSignedPayload sig); - -/****f* silccore/SilcAuthAPI/silc_signed_payload_verify - * - * SYNOPSIS - * - * int silc_signed_payload_verify(SilcSignedPayload sig, - * bool channel_message, - * void *message_payload, - * SilcPublicKey remote_public_key, - * SilcHash hash); - * - * DESCRIPTION - * - * This routine can be used to verify the signature found in - * SILC_MESSAGE_FLAG_SIGNED Payload. The `remote_public_key' is the - * sender's public key and is used in the verification. If the - * `channel_message' is TRUE then `message_payload' must include the - * SilcChannelMessagePayload. If it is FALSE then it must include - * SilcPrivateMessagePayload. This returns SILC_AUTH_OK if the - * signature verification was successful. - * - ***/ -int silc_signed_payload_verify(SilcSignedPayload sig, - bool channel_message, - void *message_payload, - SilcPublicKey remote_public_key, - SilcHash hash); - -/****f* silccore/SilcAuthAPI/silc_signed_payload_get_public_key - * - * SYNOPSIS - * - * SilcPublicKey silc_signed_payload_get_public_key(SilcSignedPayload sig); - * - * DESCRIPTION - * - * Returns the public key from the SILC_MESSAGE_FLAG_SIGNED Payload - * or NULL if it does not include public key. The caller must free - * the returned public key. - * - ***/ -SilcPublicKey silc_signed_payload_get_public_key(SilcSignedPayload sig); - #endif diff --git a/lib/silccore/silcchannel.c b/lib/silccore/silcchannel.c index 491743c5..f9e6ff85 100644 --- a/lib/silccore/silcchannel.c +++ b/lib/silccore/silcchannel.c @@ -210,259 +210,6 @@ SilcUInt32 silc_channel_get_mode(SilcChannelPayload payload) return payload->mode; } -/****************************************************************************** - - Channel Message Payload - -******************************************************************************/ - -/* Decrypts the channel message payload. First push the IV out of the - packet. The IV is used in the decryption process. Then decrypt the - message. After decyprtion, take the MAC from the decrypted packet, - compute MAC and compare the MACs. If they match, the decryption was - successful and we have the channel message ready to be displayed. */ - -bool silc_channel_message_payload_decrypt(unsigned char *data, - size_t data_len, - SilcCipher cipher, - SilcHmac hmac, - bool check_mac) -{ - SilcUInt32 iv_len, mac_len; - unsigned char *mac, mac2[32]; - - mac_len = silc_hmac_len(hmac); - iv_len = silc_cipher_get_block_len(cipher); - - if (data_len < mac_len) - return FALSE; - - if (check_mac) { - /* Take the MAC */ - mac = data + (data_len - mac_len); - - /* Check the MAC of the message */ - SILC_LOG_DEBUG(("Checking channel message MAC")); - silc_hmac_init(hmac); - silc_hmac_update(hmac, data, data_len - mac_len); - silc_hmac_final(hmac, mac2, &mac_len); - if (memcmp(mac, mac2, mac_len)) { - SILC_LOG_DEBUG(("Channel message MAC does not match")); - return FALSE; - } - SILC_LOG_DEBUG(("MAC is Ok")); - } - - /* Decrypt the channel message */ - silc_cipher_decrypt(cipher, data, data, - data_len - iv_len - mac_len, - data + (data_len - iv_len - mac_len)); - return TRUE; -} - -/* Parses channel message payload returning new channel payload structure. - This also decrypts it and checks the MAC. */ - -SilcChannelMessagePayload -silc_channel_message_payload_parse(unsigned char *payload, - SilcUInt32 payload_len, - SilcCipher cipher, - SilcHmac hmac) -{ - SilcBufferStruct buffer; - SilcChannelMessagePayload newp; - int ret; - SilcUInt32 iv_len, mac_len; - - SILC_LOG_DEBUG(("Parsing channel message payload")); - - silc_buffer_set(&buffer, payload, payload_len); - - /* Decrypt the payload */ - ret = silc_channel_message_payload_decrypt(buffer.data, buffer.len, - cipher, hmac, TRUE); - if (ret == FALSE) - return NULL; - - iv_len = silc_cipher_get_block_len(cipher); - mac_len = silc_hmac_len(hmac); - - newp = silc_calloc(1, sizeof(*newp)); - if (!newp) - return NULL; - - /* Parse the Channel Message Payload. */ - ret = silc_buffer_unformat(&buffer, - SILC_STR_UI_SHORT(&newp->flags), - SILC_STR_UI16_NSTRING_ALLOC(&newp->data, - &newp->data_len), - SILC_STR_UI16_NSTRING_ALLOC(&newp->pad, - &newp->pad_len), - SILC_STR_UI_XNSTRING(&newp->iv, iv_len), - SILC_STR_UI_XNSTRING(&newp->mac, mac_len), - SILC_STR_END); - if (ret == -1) - goto err; - - if ((newp->data_len > buffer.len - 6 - mac_len - iv_len) || - (newp->pad_len + newp->data_len > buffer.len - 6 - mac_len - iv_len)) { - SILC_LOG_ERROR(("Incorrect channel message payload in packet, " - "packet dropped")); - goto err; - } - - newp->iv_len = iv_len; - - return newp; - - err: - silc_channel_message_payload_free(newp); - return NULL; -} - -/* This function is used to encrypt the Channel Messsage Payload which is - the `data' and `data_len'. This is used internally by the Channel Message - Payload encoding routines but application may call this too if needed. - The `data_len' is the data lenght which is used to create MAC out of. - The `true_len' is the true length of `data' message payload and is used - assemble rest of the packet after MAC creation. The `true_len' length - packet will then be encrypted. */ - -bool silc_channel_message_payload_encrypt(unsigned char *data, - SilcUInt32 data_len, - unsigned char *iv, - SilcUInt32 iv_len, - SilcCipher cipher, - SilcHmac hmac) -{ - unsigned char mac[32]; - SilcUInt32 mac_len; - SilcBufferStruct buf; - - /* Encrypt payload of the packet. This is encrypted with the channel key. */ - silc_cipher_encrypt(cipher, data, data, data_len - iv_len, iv); - - /* Compute the MAC of the encrypted channel message data */ - silc_hmac_init(hmac); - silc_hmac_update(hmac, data, data_len); - silc_hmac_final(hmac, mac, &mac_len); - - /* Put rest of the data to the payload */ - silc_buffer_set(&buf, data, data_len + mac_len); - silc_buffer_pull(&buf, data_len); - silc_buffer_put(&buf, mac, mac_len); - - return TRUE; -} - -/* Encodes channel message payload into a buffer and returns it. This is used - to add channel message payload into a packet. As the channel payload is - encrypted separately from other parts of the packet padding must - be applied to the payload. */ - -SilcBuffer silc_channel_message_payload_encode(SilcMessageFlags flags, - SilcUInt16 data_len, - const unsigned char *data, - SilcUInt16 iv_len, - unsigned char *iv, - SilcCipher cipher, - SilcHmac hmac, - SilcRng rng) -{ - int i; - SilcBuffer buffer; - SilcUInt32 len, pad_len, mac_len; - unsigned char pad[16]; - - SILC_LOG_DEBUG(("Encoding channel message payload")); - - /* 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; - pad_len = SILC_CHANNEL_MESSAGE_PAD(len); - - /* Allocate channel payload buffer */ - len += pad_len + iv_len + mac_len; - buffer = silc_buffer_alloc(len); - if (!buffer) - return NULL; - - /* Generate padding */ - if (rng) { - for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte_fast(rng); - } else { - for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte_fast(); - } - - /* Encode the Channel Message Payload */ - silc_buffer_pull_tail(buffer, 6 + data_len + pad_len + iv_len); - silc_buffer_format(buffer, - SILC_STR_UI_SHORT(flags), - SILC_STR_UI_SHORT(data_len), - SILC_STR_UI_XNSTRING(data, data_len), - SILC_STR_UI_SHORT(pad_len), - SILC_STR_UI_XNSTRING(pad, pad_len), - SILC_STR_UI_XNSTRING(iv, iv_len), - SILC_STR_END); - - memset(pad, 0, sizeof(pad)); - - if (!silc_channel_message_payload_encrypt(buffer->data, buffer->len, - iv, iv_len, cipher, hmac)) { - silc_buffer_free(buffer); - return NULL; - } - - silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer) - buffer->len); - - return buffer; -} - -/* Free's Channel Message Payload */ - -void silc_channel_message_payload_free(SilcChannelMessagePayload payload) -{ - if (payload->data) { - memset(payload->data, 0, payload->data_len); - silc_free(payload->data); - } - silc_free(payload); -} - -/* Return flags */ - -SilcMessageFlags -silc_channel_message_get_flags(SilcChannelMessagePayload payload) -{ - return payload->flags; -} - -/* Return data */ - -unsigned char *silc_channel_message_get_data(SilcChannelMessagePayload payload, - SilcUInt32 *data_len) -{ - if (data_len) - *data_len = payload->data_len; - - return payload->data; -} - -/* Return MAC. The caller knows the length of the MAC */ - -unsigned char *silc_channel_message_get_mac(SilcChannelMessagePayload payload) -{ - return payload->mac; -} - -/* Return IV. The caller knows the length of the IV */ - -unsigned char *silc_channel_message_get_iv(SilcChannelMessagePayload payload) -{ - return payload->iv; -} /****************************************************************************** diff --git a/lib/silccore/silcchannel.h b/lib/silccore/silcchannel.h index ea280aa8..5e6ddf6e 100644 --- a/lib/silccore/silcchannel.h +++ b/lib/silccore/silcchannel.h @@ -22,14 +22,11 @@ * * DESCRIPTION * - * Implementations of the Channel Payload, Channel Message Payload and - * Channel Key Payload. The Channel Payload represents new channel and - * is used to distribute the information of the new channel. The Channel - * Message Payload is used to deliver messages to the channel. The routines - * for Channel Message Payload also handles the encryption and decryption - * of the payload. Last, the Channel Key Payload is used to distribute - * a new key to the channel. It is done for example every time someone - * joins a channel or the old key expires. + * Implementations of the Channel Payload and Channel Key Payload. The + * Channel Payload represents new channel and is used to distribute the + * information of the new channel. The Channel Key Payload is used to + * distribute a new key to the channel. It is done for example every + * time someone joins a channel or the old key expires. * ***/ @@ -54,23 +51,6 @@ ***/ typedef struct SilcChannelPayloadStruct *SilcChannelPayload; -/****s* silccore/SilcChannelAPI/SilcChannelMessagePayload - * - * NAME - * - * typedef struct - * SilcChannelMessagePayloadStruct *SilcChannelMessagePayload; - * - * DESCRIPTION - * - * This context is the actual Channel Message Payload and is allocated - * by silc_channel_message_payload_parse and given as argument usually to - * all silc_channel_message_payload_* functions. It is freed by the - * silc_channel_message_payload_free function. - * - ***/ -typedef struct SilcChannelMessagePayloadStruct *SilcChannelMessagePayload; - /****s* silccore/SilcChannelAPI/SilcChannelKeyPayload * * NAME @@ -87,37 +67,6 @@ typedef struct SilcChannelMessagePayloadStruct *SilcChannelMessagePayload; ***/ typedef struct SilcChannelKeyPayloadStruct *SilcChannelKeyPayload; -/****d* silccore/SilcChannelAPI/SilcMessageFlags - * - * NAME - * - * typedef SilcUInt16 SilcMessageFlags; - * - * DESCRIPTION - * - * The message flags type definition and the message flags. The - * message flags are used to indicate some status of the message. - * These flags are also used by the private message interfaces. - * - * SOURCE - */ -typedef SilcUInt16 SilcMessageFlags; - -/* The message flags (shared by both channel and private messages) */ -#define SILC_MESSAGE_FLAG_NONE 0x0000 /* No flags */ -#define SILC_MESSAGE_FLAG_AUTOREPLY 0x0001 /* Automatically replied */ -#define SILC_MESSAGE_FLAG_NOREPLY 0x0002 /* Send no reply to this */ -#define SILC_MESSAGE_FLAG_ACTION 0x0004 /* Action message */ -#define SILC_MESSAGE_FLAG_NOTICE 0x0008 /* Notice message */ -#define SILC_MESSAGE_FLAG_REQUEST 0x0010 /* A request */ -#define SILC_MESSAGE_FLAG_SIGNED 0x0020 /* Message is signed */ -#define SILC_MESSAGE_FLAG_REPLY 0x0040 /* A reply */ -#define SILC_MESSAGE_FLAG_DATA 0x0080 /* MIME object */ -#define SILC_MESSAGE_FLAG_UTF8 0x0100 /* UTF-8 string */ -#define SILC_MESSAGE_FLAG_RESERVED 0x0200 /* to 0x0800 */ -#define SILC_MESSAGE_FLAG_PRIVATE 0x1000 /* to 0x8000 */ -/***/ - /* Prototypes */ /****f* silccore/SilcChannelAPI/silc_channel_payload_parse @@ -262,204 +211,6 @@ SilcChannelID *silc_channel_get_id_parse(SilcChannelPayload payload); ***/ SilcUInt32 silc_channel_get_mode(SilcChannelPayload payload); -/****f* silccore/SilcChannelAPI/silc_channel_message_payload_decrypt - * - * SYNOPSIS - * - * bool silc_channel_message_payload_decrypt(unsigned char *data, - * size_t data_len, - * SilcCipher cipher, - * SilcHmac hmac); - * - * DESCRIPTION - * - * Decrypt the channel message. First push the IV out of the packet `data'. - * The IV is used in the decryption process. Then decrypt the message. - * After decryption, take the MAC from the decrypted packet, compute MAC - * and compare the MACs. If they match, the decryption was successful - * and we have the channel message ready to be displayed. - * - * This is usually used by the Channel Message 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 - * circumstances. The `cipher' is used to decrypt the payload. - * - * If `check_mac' is FALSE then MAC is not verified. - * - ***/ -bool silc_channel_message_payload_decrypt(unsigned char *data, - size_t data_len, - SilcCipher cipher, - SilcHmac hmac, - bool check_mac); - -/****f* silccore/SilcChannelAPI/silc_channel_message_payload_parse - * - * SYNOPSIS - * - * SilcChannelMessagePayload - * silc_channel_message_payload_parse(const unsigned char *payload, - * SilcUInt32 payload_len, - * SilcCipher cipher, - * SilcHmac hmac); - * - * DESCRIPTION - * - * Parses channel message payload returning new channel payload structure. - * This also decrypts it and checks the MAC. The `cipher's is used to - * decrypt the payload. - * - * If the `hmac' is no provided then the MAC of the channel message is - * not verified. - * - ***/ -SilcChannelMessagePayload -silc_channel_message_payload_parse(unsigned char *payload, - SilcUInt32 payload_len, - SilcCipher cipher, - SilcHmac hmac); - -/****f* silccore/SilcChannelAPI/silc_channel_message_payload_encrypt - * - * SYNOPSIS - * - * bool silc_channel_message_payload_encrypt(unsigned char *data, - * SilcUInt32 data_len, - * unsigned char *iv, - * SilcUInt32 iv_len, - * SilcCipher cipher, - * SilcHmac hmac); - * - * DESCRIPTION - * - * This function is used to encrypt the Channel Messsage Payload which is - * 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 `data_len' bytes for the MAC which is appended to the data. - * - * This is usually used by the Channel Message 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 - * circumstances. The `cipher' is used to encrypt the payload. - * - ***/ -bool silc_channel_message_payload_encrypt(unsigned char *data, - SilcUInt32 data_len, - unsigned char *iv, - SilcUInt32 iv_len, - SilcCipher cipher, - SilcHmac hmac); - -/****f* silccore/SilcChannelAPI/silc_channel_message_payload_encode - * - * SYNOPSIS - * - * SilcBuffer silc_channel_message_payload_encode(SilcMessageFlags flags, - * SilcUInt16 data_len, - * const unsigned char *data, - * SilcUInt16 iv_len, - * unsigned char *iv, - * SilcCipher cipher, - * SilcHmac hmac. - * SilcRng rng); - * - * DESCRIPTION - * - * Encodes channel message payload into a buffer and returns it. This - * is used to add channel message payload into a packet. As the channel - * payload is encrypted separately from other parts of the packet padding - * must be applied to the payload. The function generates the padding - * automatically from random data. The `cipher' is the cipher used - * encrypt the payload and `hmac' is used to compute the MAC for the - * payload. If `rng' is NULL then global RNG is used, if non-NULL then - * the `rng' is used. - * - ***/ -SilcBuffer silc_channel_message_payload_encode(SilcMessageFlags flags, - SilcUInt16 data_len, - const unsigned char *data, - SilcUInt16 iv_len, - unsigned char *iv, - SilcCipher cipher, - SilcHmac hmac, - SilcRng rng); - -/****f* silccore/SilcChannelAPI/silc_channel_message_payload_free - * - * SYNOPSIS - * - * void - * silc_channel_message_payload_free(SilcChannelMessagePayload payload); - * - * DESCRIPTION - * - * Free's Channel Message Payload and all data in it. - * - ***/ -void silc_channel_message_payload_free(SilcChannelMessagePayload payload); - -/****f* silccore/SilcChannelAPI/silc_channel_message_get_flags - * - * SYNOPSIS - * - * SilcMessageFlags - * silc_channel_message_get_flags(SilcChannelMessagePayload payload); - * - * DESCRIPTION - * - * Returns the message flags from the payload. - * - ***/ -SilcMessageFlags -silc_channel_message_get_flags(SilcChannelMessagePayload payload); - -/****f* silccore/SilcChannelAPI/silc_channel_message_get_data - * - * SYNOPSIS - * - * unsigned char * - * silc_channel_message_get_data(SilcChannelMessagePayload payload, - * SilcUInt32 *data_len); - * - * DESCRIPTION - * - * Return the data in the payload, that is, the actual channel message. - * The caller must not free it. - * - ***/ -unsigned char *silc_channel_message_get_data(SilcChannelMessagePayload payload, - SilcUInt32 *data_len); - -/****f* silccore/SilcChannelAPI/silc_channel_message_get_mac - * - * SYNOPSIS - * - * unsigned char * - * silc_channel_message_get_mac(SilcChannelMessagePayload payload); - * - * DESCRIPTION - * - * 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_channel_message_get_mac(SilcChannelMessagePayload payload); - -/****f* silccore/SilcChannelAPI/silc_channel_message_get_iv - * - * SYNOPSIS - * - * unsigned char * - * silc_channel_message_get_iv(SilcChannelMessagePayload 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_channel_message_get_iv(SilcChannelMessagePayload payload); - /****f* silccore/SilcChannelAPI/silc_channel_key_payload_parse * * SYNOPSIS diff --git a/lib/silccore/silcchannel_i.h b/lib/silccore/silcchannel_i.h index 372094d1..34dc5bb0 100644 --- a/lib/silccore/silcchannel_i.h +++ b/lib/silccore/silcchannel_i.h @@ -41,40 +41,6 @@ struct SilcChannelPayloadStruct { }; -/****************************************************************************** - - Channel Message 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 { - unsigned char *data; - unsigned char *pad; - unsigned char *mac; - unsigned char *iv; - SilcMessageFlags flags; - SilcUInt16 data_len; - SilcUInt16 pad_len; - SilcUInt16 iv_len; -}; - - /****************************************************************************** Channel Key Payload diff --git a/lib/silccore/silcmessage.c b/lib/silccore/silcmessage.c new file mode 100644 index 00000000..f1fbe932 --- /dev/null +++ b/lib/silccore/silcmessage.c @@ -0,0 +1,625 @@ +/* + + silcmessage.c + + Author: Pekka Riikonen + + Copyright (C) 1997 - 2002 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ +/* Implementation of the Message Payload used as channel messages and + private messages. */ +/* $Id$ */ + +#include "silcincludes.h" +#include "silcmessage.h" + +/****************************************************************************** + + Message Payload + +******************************************************************************/ + +/* Calculates padding length for message payload */ +#define SILC_MESSAGE_PAD(__payloadlen) (16 - ((__payloadlen) % 16)) + +/* Header length plus maximum padding length */ +#define SILC_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_MESSAGE_DATALEN(data_len, header_len) \ + ((data_len + SILC_MESSAGE_HLEN + header_len) > \ + SILC_PACKET_MAX_LEN ? \ + data_len - ((data_len + SILC_MESSAGE_HLEN + header_len) - \ + SILC_PACKET_MAX_LEN) : data_len) + +/* Message Payload structure. Contents of this structure is parsed + from SILC packets. */ +struct SilcMessagePayloadStruct { + SilcMessageFlags flags; + SilcUInt16 data_len; + SilcUInt16 pad_len; + SilcUInt16 iv_len; + unsigned char *data; + unsigned char *pad; + unsigned char *iv; + unsigned char *mac; + /*SilcMessageSignedPayload sig;*/ +}; + +/* Decrypts the Message Payload. The `data' is the actual Message Payload */ + +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) +{ + SilcUInt32 mac_len = 0, iv_len = 0; + unsigned char *mac, mac2[32]; + + mac_len = silc_hmac_len(hmac); + + /* IV is present for channel messages and private messages when static + key (pre-shared key) is used. */ + if (!private_message || (private_message && static_key)) + iv_len = silc_cipher_get_block_len(cipher); + + if (data_len < mac_len) + return FALSE; + + if (check_mac) { + /* Take the MAC */ + mac = data + (data_len - mac_len); + + /* Check the MAC of the message */ + SILC_LOG_DEBUG(("Checking message MAC")); + silc_hmac_init(hmac); + silc_hmac_update(hmac, data, data_len - mac_len); + silc_hmac_final(hmac, mac2, &mac_len); + if (memcmp(mac, mac2, mac_len)) { + SILC_LOG_DEBUG(("Message MAC does not match")); + return FALSE; + } + SILC_LOG_DEBUG(("MAC is Ok")); + } + + /* Decrypt the message */ + silc_cipher_decrypt(cipher, data, data, data_len - iv_len - mac_len, + (iv_len ? data + (data_len - iv_len - mac_len) : + silc_cipher_get_iv(cipher))); + return TRUE; +} + +/* Parses Message Payload returning new payload structure. This also + decrypts it and checks the MAC. */ + +SilcMessagePayload +silc_message_payload_parse(unsigned char *payload, + SilcUInt32 payload_len, + bool private_message, + bool static_key, + SilcCipher cipher, + SilcHmac hmac) +{ + SilcBufferStruct buffer; + SilcMessagePayload newp; + int ret; + SilcUInt32 mac_len = 0, iv_len = 0; + + SILC_LOG_DEBUG(("Parsing Message Payload")); + + silc_buffer_set(&buffer, payload, payload_len); + + /* Decrypt the payload */ + if (cipher) { + ret = silc_message_payload_decrypt(buffer.data, buffer.len, + private_message, static_key, + cipher, hmac, TRUE); + if (ret == FALSE) + return NULL; + } + + if (hmac) + mac_len = silc_hmac_len(hmac); + + /* IV is present for channel messages and private messages when static + key (pre-shared key) is used. */ + if (cipher && (!private_message || (private_message && static_key))) + iv_len = silc_cipher_get_block_len(cipher); + + newp = silc_calloc(1, sizeof(*newp)); + if (!newp) + return NULL; + + /* Parse the Message Payload. */ + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&newp->flags), + SILC_STR_UI16_NSTRING_ALLOC(&newp->data, + &newp->data_len), + SILC_STR_UI16_NSTRING_ALLOC(&newp->pad, + &newp->pad_len), + SILC_STR_UI_XNSTRING(&newp->iv, iv_len), + SILC_STR_UI_XNSTRING(&newp->mac, mac_len), + SILC_STR_END); + if (ret == -1) + goto err; + + if ((newp->data_len > buffer.len - 6 - mac_len - iv_len) || + (newp->pad_len + newp->data_len > buffer.len - 6 - mac_len - iv_len)) { + SILC_LOG_ERROR(("Incorrect Message Payload in packet")); + goto err; + } + + newp->iv_len = iv_len; + + return newp; + + err: + silc_message_payload_free(newp); + return NULL; +} + +/* This function is used to encrypt the Messsage Payload which is + the `data' and `data_len'. This is used internally by the Message + Payload encoding routines but application may call this too if needed. + The `data_len' is the data lenght which is used to create MAC out of. */ + +bool silc_message_payload_encrypt(unsigned char *data, + SilcUInt32 data_len, + unsigned char *iv, + SilcUInt32 iv_len, + SilcCipher cipher, + SilcHmac hmac) +{ + unsigned char mac[32]; + SilcUInt32 mac_len; + SilcBufferStruct buf; + + /* Encrypt payload of the packet. If the IV is added to packet do + not encrypt that. */ + silc_cipher_encrypt(cipher, data, data, data_len - iv_len, + iv_len ? iv : silc_cipher_get_iv(cipher)); + + /* Compute the MAC of the encrypted message data */ + silc_hmac_init(hmac); + silc_hmac_update(hmac, data, data_len); + silc_hmac_final(hmac, mac, &mac_len); + + /* Put rest of the data to the payload */ + silc_buffer_set(&buf, data, data_len + mac_len); + silc_buffer_pull(&buf, data_len); + silc_buffer_put(&buf, mac, mac_len); + + return TRUE; +} + +/* Encodes Message Payload into a buffer and returns it. */ + +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) +{ + int i; + SilcBuffer buffer; + SilcUInt32 len, pad_len = 0, mac_len = 0, iv_len = 0; + unsigned char pad[16], iv[SILC_CIPHER_MAX_IV_SIZE]; + + SILC_LOG_DEBUG(("Encoding Message Payload")); + + if (!data_len) + return NULL; + + /* For channel messages IV is always generated */ + if (!private_message && !generate_iv) + generate_iv = TRUE; + + /* Generate IV */ + if (cipher && generate_iv) { + iv_len = silc_cipher_get_block_len(cipher); + if (rng) { + for (i = 0; i < iv_len; i++) iv[i] = silc_rng_get_byte_fast(rng); + } else { + for (i = 0; i < iv_len; i++) iv[i] = silc_rng_global_get_byte_fast(); + } + } + + if (hmac) + mac_len = silc_hmac_len(hmac); + data_len = SILC_MESSAGE_DATALEN(data_len, mac_len + iv_len); + + /* Calculate length of padding. IV is not included into the calculation + since it is not encrypted. */ + len = 6 + data_len; + pad_len = SILC_MESSAGE_PAD(len); + + /* Allocate payload buffer */ + len += pad_len + iv_len + mac_len; + buffer = silc_buffer_alloc(len); + if (!buffer) + return NULL; + + /* Generate padding */ + if (cipher) { + if (rng) { + for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte_fast(rng); + } else { + for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte_fast(); + } + } + + /* Encode the Message Payload */ + silc_buffer_pull_tail(buffer, 6 + data_len + pad_len + iv_len); + silc_buffer_format(buffer, + SILC_STR_UI_SHORT(flags), + SILC_STR_UI_SHORT(data_len), + SILC_STR_UI_XNSTRING(data, data_len), + SILC_STR_UI_SHORT(pad_len), + SILC_STR_UI_XNSTRING(pad, pad_len), + SILC_STR_UI_XNSTRING(iv, iv_len), + SILC_STR_END); + + memset(pad, 0, sizeof(pad)); + + /* Now encrypt the Message Payload */ + if (cipher) { + if (!silc_message_payload_encrypt(buffer->data, buffer->len, + iv, iv_len, cipher, hmac)) { + silc_buffer_free(buffer); + return NULL; + } + } + silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer) - buffer->len); + + return buffer; +} + +/* Free's Message Payload */ + +void silc_message_payload_free(SilcMessagePayload payload) +{ + if (payload->data) { + memset(payload->data, 0, payload->data_len); + silc_free(payload->data); + } + silc_free(payload->pad); + silc_free(payload); +} + +/* Return flags */ + +SilcMessageFlags silc_message_get_flags(SilcMessagePayload payload) +{ + return payload->flags; +} + +/* Return data */ + +unsigned char *silc_message_get_data(SilcMessagePayload payload, + SilcUInt32 *data_len) +{ + if (data_len) + *data_len = payload->data_len; + return payload->data; +} + +/* Return MAC. The caller knows the length of the MAC */ + +unsigned char *silc_message_get_mac(SilcMessagePayload payload) +{ + return payload->mac; +} + +/* Return IV. The caller knows the length of the IV */ + +unsigned char *silc_message_get_iv(SilcMessagePayload payload) +{ + return payload->iv; +} + +/****************************************************************************** + + SILC_MESSAGE_FLAG_SIGNED Payload + +******************************************************************************/ + +/* The SILC_MESSAGE_FLAG_SIGNED Payload */ +struct SilcMessageSignedPayloadStruct { + SilcUInt16 pk_len; + SilcUInt16 pk_type; + SilcUInt16 sign_len; + unsigned char *pk_data; + unsigned char *sign_data; +}; + +/* Encodes the data to be signed to SILC_MESSAGE_FLAG_SIGNED Payload */ + +static SilcBuffer +silc_message_signed_encode_data(const unsigned char *message_payload, + SilcUInt32 message_payload_len, + unsigned char *pk, + SilcUInt32 pk_len, SilcUInt32 pk_type) +{ + SilcBuffer sign; + + sign = silc_buffer_alloc_size(message_payload_len + 4 + pk_len); + if (!sign) + return NULL; + + silc_buffer_format(sign, + SILC_STR_UI_XNSTRING(message_payload, + message_payload_len), + SILC_STR_UI_SHORT(pk_len), + SILC_STR_UI_SHORT(pk_type), + SILC_STR_END); + + if (pk && pk_len) { + silc_buffer_pull(sign, message_payload_len + 4); + silc_buffer_format(sign, + SILC_STR_UI_XNSTRING(pk, pk_len), + SILC_STR_END); + silc_buffer_push(sign, message_payload_len + 4); + } + + return sign; +} + +/* Parses the SILC_MESSAGE_FLAG_SIGNED Payload */ + +SilcMessageSignedPayload +silc_message_signed_payload_parse(const unsigned char *data, + SilcUInt32 data_len) +{ + SilcMessageSignedPayload sig; + SilcBufferStruct buffer; + int ret; + + SILC_LOG_DEBUG(("Parsing SILC_MESSAGE_FLAG_SIGNED Payload")); + + silc_buffer_set(&buffer, (unsigned char *)data, data_len); + sig = silc_calloc(1, sizeof(*sig)); + if (!sig) + return NULL; + + /* Parse the payload */ + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&sig->pk_len), + SILC_STR_UI_SHORT(&sig->pk_type), + SILC_STR_END); + if (ret == -1 || sig->pk_len > data_len - 4) { + silc_message_signed_payload_free(sig); + return NULL; + } + + silc_buffer_pull(&buffer, 4); + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_XNSTRING_ALLOC(&sig->pk_data, + sig->pk_len), + SILC_STR_UI16_NSTRING_ALLOC(&sig->sign_data, + &sig->sign_len), + SILC_STR_END); + if (ret == -1) { + silc_message_signed_payload_free(sig); + return NULL; + } + silc_buffer_push(&buffer, 4); + + /* Signature must be provided */ + if (sig->sign_len < 1) { + silc_message_signed_payload_free(sig); + return NULL; + } + + return sig; +} + +/* Encodes the SILC_MESSAGE_FLAG_SIGNED Payload and computes the digital + signature. */ + +SilcBuffer +silc_message_signed_payload_encode(const unsigned char *message_payload, + SilcUInt32 message_payload_len, + SilcPublicKey public_key, + SilcPrivateKey private_key, + SilcHash hash, + bool include_public_key) +{ + SilcBuffer buffer, sign; + SilcPKCS pkcs; + unsigned char auth_data[2048]; + SilcUInt32 auth_len; + unsigned char *pk = NULL; + SilcUInt32 pk_len = 0; + SilcUInt16 pk_type; + + if (!message_payload || !message_payload_len || !private_key || !hash) + return NULL; + if (include_public_key && !public_key) + return NULL; + + if (include_public_key) + pk = silc_pkcs_public_key_encode(public_key, &pk_len); + + /* Now we support only SILC style public key */ + pk_type = SILC_SKE_PK_TYPE_SILC; + + /* Encode the data to be signed */ + sign = silc_message_signed_encode_data(message_payload, + message_payload_len, + pk, pk_len, pk_type); + if (!sign) { + silc_free(pk); + return NULL; + } + + /* Sign the buffer */ + + /* Allocate PKCS object */ + if (!silc_pkcs_alloc(private_key->name, &pkcs)) { + silc_buffer_clear(sign); + silc_buffer_free(sign); + silc_free(pk); + return NULL; + } + silc_pkcs_private_key_set(pkcs, private_key); + + /* Compute the hash and the signature. */ + if (silc_pkcs_get_key_len(pkcs) / 8 > sizeof(auth_data) - 1 || + !silc_pkcs_sign_with_hash(pkcs, hash, sign->data, sign->len, auth_data, + &auth_len)) { + silc_buffer_clear(sign); + silc_buffer_free(sign); + silc_pkcs_free(pkcs); + silc_free(pk); + return NULL; + } + + /* Encode the SILC_MESSAGE_FLAG_SIGNED Payload */ + + buffer = silc_buffer_alloc_size(4 + pk_len + 2 + auth_len); + if (!buffer) { + silc_buffer_clear(sign); + silc_buffer_free(sign); + silc_pkcs_free(pkcs); + memset(auth_data, 0, sizeof(auth_data)); + silc_free(pk); + return NULL; + } + + silc_buffer_format(sign, + SILC_STR_UI_SHORT(pk_len), + SILC_STR_UI_SHORT(pk_type), + SILC_STR_END); + + if (pk_len && pk) { + silc_buffer_pull(sign, 4); + silc_buffer_format(sign, + SILC_STR_UI_XNSTRING(pk, pk_len), + SILC_STR_END); + silc_buffer_push(sign, 4); + } + + silc_buffer_pull(sign, 4 + pk_len); + silc_buffer_format(sign, + SILC_STR_UI_SHORT(auth_len), + SILC_STR_UI_XNSTRING(auth_data, auth_len), + SILC_STR_END); + silc_buffer_push(sign, 4 + pk_len); + + memset(auth_data, 0, sizeof(auth_data)); + silc_pkcs_free(pkcs); + silc_buffer_clear(sign); + silc_buffer_free(sign); + silc_free(pk); + + return buffer; +} + +/* Free the payload */ + +void silc_message_signed_payload_free(SilcMessageSignedPayload sig) +{ + if (sig) { + memset(sig->sign_data, 0, sig->sign_len); + silc_free(sig->sign_data); + silc_free(sig->pk_data); + silc_free(sig); + } +} + +/* Verify the signature in SILC_MESSAGE_FLAG_SIGNED Payload */ + +int silc_message_signed_verify(SilcMessageSignedPayload sig, + SilcMessagePayload message, + SilcPublicKey remote_public_key, + SilcHash hash) +{ + int ret = SILC_AUTH_FAILED; + SilcBuffer sign; + SilcPKCS pkcs; + SilcBuffer tmp; + + if (!sig || !remote_public_key || !hash) + return ret; + + /* Generate the signature verification data, the Message Payload */ + tmp = silc_buffer_alloc_size(6 + message->data_len + message->pad_len + + message->iv_len); + silc_buffer_format(tmp, + SILC_STR_UI_SHORT(message->flags), + SILC_STR_UI_SHORT(message->data_len), + SILC_STR_UI_XNSTRING(message->data, message->data_len), + SILC_STR_UI_SHORT(message->pad_len), + SILC_STR_UI_XNSTRING(message->pad, message->pad_len), + SILC_STR_UI_XNSTRING(message->iv, message->iv_len), + SILC_STR_END); + sign = silc_message_signed_encode_data(tmp->data, tmp->len, + sig->pk_data, sig->pk_len, + sig->pk_type); + silc_buffer_clear(tmp); + silc_buffer_free(tmp); + + if (!sign) + return ret; + + /* Allocate PKCS object */ + if (!silc_pkcs_alloc(remote_public_key->name, &pkcs)) { + silc_buffer_clear(sign); + silc_buffer_free(sign); + return ret; + } + silc_pkcs_public_key_set(pkcs, remote_public_key); + + /* Verify the authentication data */ + if (!silc_pkcs_verify_with_hash(pkcs, hash, sig->sign_data, + sig->sign_len, + sign->data, sign->len)) { + + silc_buffer_clear(sign); + silc_buffer_free(sign); + silc_pkcs_free(pkcs); + SILC_LOG_DEBUG(("Signature verification failed")); + return ret; + } + + ret = SILC_AUTH_OK; + + silc_buffer_clear(sign); + silc_buffer_free(sign); + silc_pkcs_free(pkcs); + + SILC_LOG_DEBUG(("Signature verification successful")); + + return ret; +} + +/* Return the public key from the payload */ + +SilcPublicKey +silc_message_signed_get_public_key(SilcMessageSignedPayload sig) +{ + SilcPublicKey pk; + + if (!sig->pk_data || !silc_pkcs_public_key_decode(sig->pk_data, + sig->pk_len, &pk)) + return NULL; + + return pk; +} diff --git a/lib/silccore/silcmessage.h b/lib/silccore/silcmessage.h new file mode 100644 index 00000000..e003e029 --- /dev/null +++ b/lib/silccore/silcmessage.h @@ -0,0 +1,430 @@ +/* + + silcmessage.h + + Author: Pekka Riikonen + + Copyright (C) 1997 -2002 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 + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +*/ + +/****h* silccore/SILC Message Interface + * + * 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. + * + ***/ + +#ifndef SILCMESSAGE_H +#define SILCMESSAGE_H + +/****s* silccore/SilcMessageAPI/SilcMessagePayload + * + * NAME + * + * typedef struct SilcMessagePayloadStruct *SilcMessagePayload; + * + * + * DESCRIPTION + * + * This context is the actual Message Payload and is allocated + * by silc_message_payload_parse and given as argument usually + * to all silc_message_* functions. It is freed by the + * silc_message_payload_free function. + * + ***/ +typedef struct SilcMessagePayloadStruct *SilcMessagePayload; + +/****d* silccore/SilcMessageAPI/SilcMessageFlags + * + * NAME + * + * typedef SilcUInt16 SilcMessageFlags; + * + * DESCRIPTION + * + * The message flags type definition and the message flags. The + * message flags are used to indicate some status of the message. + * + * SOURCE + */ +typedef SilcUInt16 SilcMessageFlags; + +/* The message flags */ +#define SILC_MESSAGE_FLAG_NONE 0x0000 /* No flags */ +#define SILC_MESSAGE_FLAG_AUTOREPLY 0x0001 /* Automatically replied */ +#define SILC_MESSAGE_FLAG_NOREPLY 0x0002 /* Send no reply to this */ +#define SILC_MESSAGE_FLAG_ACTION 0x0004 /* Action message */ +#define SILC_MESSAGE_FLAG_NOTICE 0x0008 /* Notice message */ +#define SILC_MESSAGE_FLAG_REQUEST 0x0010 /* A request */ +#define SILC_MESSAGE_FLAG_SIGNED 0x0020 /* Message is signed */ +#define SILC_MESSAGE_FLAG_REPLY 0x0040 /* A reply */ +#define SILC_MESSAGE_FLAG_DATA 0x0080 /* MIME object */ +#define SILC_MESSAGE_FLAG_UTF8 0x0100 /* UTF-8 string */ +#define SILC_MESSAGE_FLAG_RESERVED 0x0200 /* to 0x0800 */ +#define SILC_MESSAGE_FLAG_PRIVATE 0x1000 /* to 0x8000 */ +/***/ + +/****f* silccore/SilcMessageAPI/silc_message_payload_decrypt + * + * 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); + * + * DESCRIPTION + * + * Decrypt Message Payload indicated by `data'. If the payload is + * channel message then `private_message' is FALSE, and if it is + * private message it is TRUE. If the private message key is static + * (pre-shared key) then protocol dictates that the IV is present + * and `static_key' must be set to TRUE. If the key is not static + * (Key Agreement was done for the key) then it MUST be FALSE. For + * channel messages the `static_key' is ignored. + * + * 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 + * 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); + +/****f* silccore/SilcMessageAPI/silc_message_payload_parse + * + * SYNOPSIS + * + * SilcMessagePayload + * silc_message_payload_parse(unsigned char *payload, + * SilcUInt32 payload_len, + * bool private_message, + * bool static_key, + * SilcCipher cipher, + * SilcHmac hmac); + * + * DESCRIPTION + * + * Parses Message Payload returning new payload structure. This also + * decrypts the payload and checks the MAC. If the payload is + * channel message then `private_message' is FALSE, and if it is + * private message it is TRUE. If the private message key is static + * (pre-shared key) then protocol dictates that the IV is present + * and `static_key' must be set to TRUE. If the key is not static + * (Key Agreement was done for the key) then it MUST be FALSE. For + * channel messages the `static_key' is ignored. + * + * If the `hmac' is no provided then the MAC of the channel message is + * not verified. If the message is private message and `cipher' is NULL + * then this assumes that the packet was decrypted with session keys + * (no private message key) and this merely decodes the payload. + * + ***/ +SilcMessagePayload +silc_message_payload_parse(unsigned char *payload, + SilcUInt32 payload_len, + bool private_message, + bool static_key, + SilcCipher cipher, + SilcHmac hmac); + +/****f* silccore/SilcMessageAPI/silc_message_payload_encrypt + * + * SYNOPSIS + * + * bool silc_message_payload_encrypt(unsigned char *data, + * SilcUInt32 data_len, + * unsigned char *iv, + * SilcUInt32 iv_len, + * SilcCipher cipher, + * SilcHmac hmac); + * + * DESCRIPTION + * + * This function is used to encrypt the Messsage Payload which is + * 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 `data_len' bytes for the MAC which is appended to the data. + * + * 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 + * 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, + unsigned char *iv, + SilcUInt32 iv_len, + SilcCipher cipher, + SilcHmac hmac); + +/****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); + * + * 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 + * 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 + * channel messages `generate_iv' is always set to TRUE value. + * + * The `cipher' is the cipher used to encrypt the message and `hmac' + * is used to compute the MAC for the payload. If encoding private + * message that will be encrypted with session keys (no private message + * key) then `cipher' and `hmac' is NULL and this merely encodes the + * payload buffer, and the caller must encrypt the packet later. + * + * If `rng' is NULL then global RNG is used, if non-NULL then the + * `rng' is used (for IV and padding generation). + * + ***/ +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); + +/****f* silccore/SilcMessageAPI/silc_message_payload_free + * + * SYNOPSIS + * + * void silc_message_payload_free(SilcMessagePayload payload); + * + * DESCRIPTION + * + * Free's Message Payload and all data in it. + * + ***/ +void silc_message_payload_free(SilcMessagePayload payload); + +/****f* silccore/SilcMessageAPI/silc_message_get_flags + * + * SYNOPSIS + * + * SilcMessageFlags silc_message_get_flags(SilcMessagePayload payload); + * + * DESCRIPTION + * + * Returns the message flags from the payload. + * + ***/ +SilcMessageFlags silc_message_get_flags(SilcMessagePayload payload); + +/****f* silccore/SilcMessageAPI/silc_message_get_data + * + * SYNOPSIS + * + * unsigned char * + * silc_message_get_data(SilcMessagePayload payload, + * SilcUInt32 *data_len); + * + * DESCRIPTION + * + * Return the data in the payload, that is, the actual message data. + * The caller must not free it. + * + ***/ +unsigned char *silc_message_get_data(SilcMessagePayload payload, + SilcUInt32 *data_len); + +/****f* silccore/SilcMessageAPI/silc_message_get_mac + * + * SYNOPSIS + * + * unsigned char * + * silc_message_get_mac(SilcMessagePayload payload); + * + * DESCRIPTION + * + * 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); + +/****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; + +/****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 SILC_MESSAGE_FLAG_SIGNED 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. + * + ***/ +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, + * bool include_public_key); + * + * DESCRIPTION + * + * Encodes the SILC_MESSAGE_FLAG_SIGNED 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 `include_public_key' is + * TRUE 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. + * + ***/ +SilcBuffer +silc_message_signed_payload_encode(const unsigned char *message_payload, + SilcUInt32 message_payload_len, + SilcPublicKey public_key, + SilcPrivateKey private_key, + SilcHash hash, + bool include_public_key); + +/****f* silccore/SilcMessageAPI/silc_message_signed_payload_free + * + * SYNOPSIS + * + * void silc_message_signed_payload_free(SilcMessageSignedPayload sig); + * + * DESCRIPTION + * + * Frees the SILC_MESSAGE_FLAG_SIGNED 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); + * + * DESCRIPTION + * + * This routine can be used to verify the signature found in + * SILC_MESSAGE_FLAG_SIGNED Payload. This returns SILC_AUTH_OK if the + * signature verification was successful. + * + ***/ +int silc_message_signed_verify(SilcMessageSignedPayload sig, + SilcMessagePayload message, + SilcPublicKey remote_public_key, + SilcHash hash); + +/****f* silccore/SilcMessageAPI/silc_message_signed_get_public_key + * + * SYNOPSIS + * + * SilcPublicKey + * silc_message_signed_get_public_key(SilcMessageSignedPayload sig); + * + * DESCRIPTION + * + * Returns the public key from the SILC_MESSAGE_FLAG_SIGNED Payload + * or NULL if it does not include public key. The caller must free + * the returned public key. + * + ***/ +SilcPublicKey +silc_message_signed_get_public_key(SilcMessageSignedPayload sig); + +#endif /* SILCMESSAGE_H */ diff --git a/lib/silccore/silcprivate.c b/lib/silccore/silcprivate.c deleted file mode 100644 index b90d0109..00000000 --- a/lib/silccore/silcprivate.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - - silcprivate.c - - Author: Pekka Riikonen - - Copyright (C) 1997 - 2001 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -*/ -/* Includes the Private Message Payload implementation */ -/* $Id$ */ - -#include "silcincludes.h" -#include "silcprivate.h" -#include "silcprivate_i.h" - -/****************************************************************************** - - Private Message Payload - -******************************************************************************/ - -/* Parses private message payload returning new private mesage payload - structure. This also decrypts the message if the `cipher' is provided. */ - -SilcPrivateMessagePayload -silc_private_message_payload_parse(unsigned char *payload, - SilcUInt32 payload_len, - SilcCipher cipher, - SilcHmac hmac) -{ - SilcBufferStruct buffer; - SilcPrivateMessagePayload newp; - SilcUInt32 mac_len = 0, block_len, pad_len = 0; - unsigned char data[16], mac[32]; - int len, totlen; - - SILC_LOG_DEBUG(("Parsing private message payload")); - - silc_buffer_set(&buffer, payload, payload_len); - - newp = silc_calloc(1, sizeof(*newp)); - if (!newp) - return NULL; - - /* Decrypt the payload */ - if (cipher) { - /* Decrypt first block. This is to get the true length of the data in - payload. It is possible there is additional data after the message - payload with private messages. */ - block_len = silc_cipher_get_block_len(cipher); - if (block_len > buffer.len) - goto err; - silc_cipher_decrypt(cipher, buffer.data, data, block_len, - silc_cipher_get_iv(cipher)); - - /* Length of encrypted area */ - SILC_GET16_MSB(newp->message_len, data + 2); - totlen = 4 + newp->message_len; - pad_len = SILC_PRIVATE_MESSAGE_PAD(4 + newp->message_len); - totlen += pad_len; - - /* Sanity checks */ - if (totlen > buffer.len || newp->message_len < 1 || - newp->message_len > buffer.len - 4) { - SILC_LOG_DEBUG(("Incorrect private message payload in packet")); - goto err; - } - - /* Compute MAC for integrity check from the cipher text */ - if (hmac) { - SILC_LOG_DEBUG(("Checking private message MAC")); - silc_hmac_init(hmac); - silc_hmac_update(hmac, buffer.data, totlen); - silc_hmac_final(hmac, mac, &mac_len); - if (memcmp(mac, buffer.data + totlen, mac_len)) { - SILC_LOG_DEBUG(("Private message MAC does not match")); - goto err; - } - SILC_LOG_DEBUG(("MAC is Ok")); - } - - /* Now decrypt rest of the data */ - memcpy(buffer.data, data, block_len); - if (totlen - block_len > 0) - silc_cipher_decrypt(cipher, buffer.data + block_len, - buffer.data + block_len, totlen - block_len, - silc_cipher_get_iv(cipher)); - memset(data, 0, sizeof(data)); - } - - /* Parse the Private Message Payload. */ - len = silc_buffer_unformat(&buffer, - SILC_STR_UI_SHORT(&newp->flags), - SILC_STR_UI16_NSTRING_ALLOC(&newp->message, - &newp->message_len), - SILC_STR_END); - if (len == -1 || newp->message_len < 1 || - newp->message_len > buffer.len - 4) { - SILC_LOG_DEBUG(("Incorrect private message payload in packet")); - goto err; - } - - /* Parse also padding and MAC */ - if (cipher) { - silc_buffer_pull(&buffer, 4 + newp->message_len); - len = silc_buffer_unformat(&buffer, - SILC_STR_UI_XNSTRING_ALLOC(&newp->pad, - pad_len), - SILC_STR_UI_XNSTRING_ALLOC(&newp->mac, - mac_len), - SILC_STR_END); - silc_buffer_push(&buffer, 4 + newp->message_len); - } - - return newp; - - err: - silc_private_message_payload_free(newp); - return NULL; -} - -/* Encodes private message payload into a buffer and returns it. If - 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(SilcUInt16 flags, - SilcUInt16 data_len, - const unsigned char *data, - SilcCipher cipher, - SilcHmac hmac, - SilcRng rng) -{ - int i; - SilcBuffer buffer; - SilcUInt32 len, pad_len = 0, mac_len = 0; - unsigned char pad[16], mac[32]; - - SILC_LOG_DEBUG(("Encoding private message payload")); - - data_len = SILC_PRIVATE_MESSAGE_DATALEN(data_len); - len = 4 + data_len; - - if (cipher) { - /* Calculate length of padding. */ - pad_len = SILC_PRIVATE_MESSAGE_PAD(len); - len += pad_len; - mac_len = hmac ? silc_hmac_len(hmac) : 0; - len += mac_len; - - /* Generate padding */ - if (rng) { - for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte_fast(rng); - } else { - for (i = 0; i < pad_len; i++) pad[i] = silc_rng_global_get_byte_fast(); - } - } - - /* Allocate private message payload buffer */ - buffer = silc_buffer_alloc_size(len); - if (!buffer) - return NULL; - - /* Encode the Channel Message Payload */ - silc_buffer_format(buffer, - SILC_STR_UI_SHORT(flags), - SILC_STR_UI_SHORT(data_len), - SILC_STR_UI_XNSTRING(data, data_len), - SILC_STR_UI_XNSTRING(pad, pad_len), - SILC_STR_END); - - if (cipher) { - /* Encrypt payload of the packet. */ - silc_cipher_encrypt(cipher, buffer->data, buffer->data, - buffer->len - mac_len, silc_cipher_get_iv(cipher)); - memset(pad, 0, sizeof(pad)); - - /* Compute MAC from the ciphertext */ - if (hmac) { - silc_hmac_init(hmac); - silc_hmac_update(hmac, buffer->data, buffer->len - mac_len); - silc_hmac_final(hmac, mac, &mac_len); - memcpy(buffer->data + (buffer->len - mac_len), mac, mac_len); - memset(mac, 0, sizeof(mac)); - } - } - - return buffer; -} - -/* Frees Private Message Payload */ - -void silc_private_message_payload_free(SilcPrivateMessagePayload payload) -{ - if (payload->message) { - memset(payload->message, 0, payload->message_len); - silc_free(payload->message); - } - silc_free(payload); -} - -/* Return flags */ - -SilcUInt16 -silc_private_message_get_flags(SilcPrivateMessagePayload payload) -{ - return payload->flags; -} - -/* Return message */ - -unsigned char * -silc_private_message_get_message(SilcPrivateMessagePayload payload, - SilcUInt32 *message_len) -{ - if (message_len) - *message_len = payload->message_len; - - return payload->message; -} - -/* Return MAC. Caller knows its length */ - -unsigned char * -silc_private_message_get_mac(SilcPrivateMessagePayload payload) -{ - return payload->mac; -} diff --git a/lib/silccore/silcprivate.h b/lib/silccore/silcprivate.h deleted file mode 100644 index d776bf6d..00000000 --- a/lib/silccore/silcprivate.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - - silcprivate.h - - Author: Pekka Riikonen - - Copyright (C) 1997 - 2001 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -*/ - -/****h* silccore/SILC Private Message Interface - * - * DESCRIPTION - * - * Implementation of the SILC Private Message Payload that is used to - * deliver private messages. - * - ***/ - -#ifndef SILCPRIVATE_H -#define SILCPRIVATE_H - -/****s* silccore/SilcPrivateAPI/SilcPrivateMessagePayload - * - * NAME - * - * typedef struct SilcPrivateMessagePayloadStruct - * *SilcPrivateMessagePayload; - * - * - * DESCRIPTION - * - * This context is the actual Private Message Payload and is allocated - * by silc_private_message_payload_parse and given as argument usually - * to all silc_private_message_* functions. It is freed by the - * silc_private_message_payload_free function. - * - ***/ -typedef struct SilcPrivateMessagePayloadStruct *SilcPrivateMessagePayload; - -/* Prototypes */ - -/****f* silccore/SilcPrivateAPI/silc_private_message_payload_parse - * - * SYNOPSIS - * - * SilcPrivateMessagePayload - * silc_private_message_payload_parse(unsigned char *payload, - * SilcUInt32 payload_len, - * SilcCipher cipher, - * SilcHmac hmac); - * - * DESCRIPTION - * - * Parses private message payload returning new private mesage payload - * structure. This also decrypts the message if the `cipher' is provided. - * The data integrity is checked with `hmac'. - * - ***/ -SilcPrivateMessagePayload -silc_private_message_payload_parse(unsigned char *payload, - SilcUInt32 payload_len, - SilcCipher cipher, - SilcHmac hmac); - -/****f* silccore/SilcPrivateAPI/silc_private_message_payload_encode - * - * SYNOPSIS - * - * SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags, - * SilcUInt16 data_len, - * const unsigned char *data, - * SilcCipher cipher, - * SilcHmac hmac, - * SilcRng rng); - * - * DESCRIPTION - * - * Encodes private message payload into a buffer and returns it. If - * the `cipher' is provided the packet is also encrypted here. It is - * provided if the private message private keys are used. If the `rng' - * is NULL then global RNG is used, if non-NULL then `rng' is used. - * The MAC for the message is computed with `hmac'. - * - ***/ -SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags, - SilcUInt16 data_len, - const unsigned char *data, - SilcCipher cipher, - SilcHmac hmac, - SilcRng rng); - -/****f* silccore/SilcPrivateAPI/silc_private_message_payload_free - * - * SYNOPSIS - * - * void - * silc_private_message_payload_free(SilcPrivateMessagePayload payload); - * - * DESCRIPTION - * - * Frees Private Message Payload - * - ***/ -void silc_private_message_payload_free(SilcPrivateMessagePayload payload); - -/****f* silccore/SilcPrivateAPI/silc_private_message_get_flags - * - * SYNOPSIS - * - * SilcUInt16 - * silc_private_message_get_flags(SilcPrivateMessagePayload payload); - * - * DESCRIPTION - * - * Returns flags from the payload. Message flags may indicate some - * status of the message. Private message flags are equivalent to the - * channel message flags. - * - ***/ -SilcUInt16 -silc_private_message_get_flags(SilcPrivateMessagePayload payload); - -/****f* silccore/SilcPrivateAPI/silc_private_message_get_message - * - * SYNOPSIS - * - * unsigned char * - * silc_private_message_get_message(SilcPrivateMessagePayload payload, - * SilcUInt32 *message_len); - * - * DESCRIPTION - * - * Returns the actual private message. The caller must not free it. - * - ***/ -unsigned char * -silc_private_message_get_message(SilcPrivateMessagePayload payload, - SilcUInt32 *message_len); - -/****f* silccore/SilcPrivateAPI/silc_private_message_get_mac - * - * SYNOPSIS - * - * unsigned char * - * silc_private_message_get_mac(SilcPrivateMessagePayload payload); - * - * DESCRIPTION - * - * Returns the MAC from the payload. The caller knows its length. - * The caller must not free it. - * - ***/ -unsigned char * -silc_private_message_get_mac(SilcPrivateMessagePayload payload); - -#endif diff --git a/lib/silccore/silcprivate_i.h b/lib/silccore/silcprivate_i.h deleted file mode 100644 index d3ad843b..00000000 --- a/lib/silccore/silcprivate_i.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - - silcprivate_i.h - - Author: Pekka Riikonen - - Copyright (C) 1997 - 2002 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 - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -*/ - -#ifndef SILCPRIVATE_I_H -#define SILCPRIVATE_I_H - -#ifndef SILCPRIVATE_H -#error "Do not include internal header file directly" -#endif - -/****************************************************************************** - - Private Message Payload - -******************************************************************************/ - -/* 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 { - SilcUInt16 flags; - SilcUInt16 message_len; - unsigned char *message; - unsigned char *pad; - unsigned char *mac; -}; - -#endif /* SILCPRIVATE_I_H */