Added SILC Server library.
[silc.git] / lib / silcske / silcske.h
index e1c25b8539afac74ba0c4ae0044bdf329a1820f4..6efd1d4577d08d9d0dc2ce897fd72cbe39fb4bed 100644 (file)
@@ -17,9 +17,6 @@
 
 */
 
-#ifndef SILCSKE_H
-#define SILCSKE_H
-
 /****h* silcske/SILC SKE Interface
  *
  * DESCRIPTION
  * server SKE is performed to exchange public keys, and to generate the key
  * that is then used as session key. Two clients can execute SKE as well
  * two create secret key material for securing for example file transfer
- * stream.
- *
- * This SKE implementation provides easy interface for application
- * that wants to use SKE. In fact, the interface is designed to be
- * application independent, and does not expect that the application using
- * SKE would actually relate in any way to SILC. Hence, the interface
- * can be used in any kind of application needing to perform key exchange
- * protocol with two parties. The network connection is also handled
- * outside the SKE interface.
- *
- * The protocol has initiator and responder. The initiator is the one
- * that starts the protocol, and the responder is the one that receives
- * negotiation request. The protocol has phases, and the interface is
- * split into several phases that the application may call when
- * needed. Heavy operations has been splitted so that application may
- * call next phase with a timeout to give processing times to other
- * things in the application. On the other hand, if application does
- * not care about this it may call the phases immediately without any
- * timeout.
+ * stream. This SKE implementation provides easy interface for application
+ * that wants to use SKE.
  *
  ***/
 
-#include "silcske_status.h"
-
-/* Length of cookie in Start Payload */
-#define SILC_SKE_COOKIE_LEN 16
+#ifndef SILCSKE_H
+#define SILCSKE_H
 
 /* Forward declarations */
 typedef struct SilcSKECallbacksStruct *SilcSKECallbacks;
 typedef struct SilcSKEStruct *SilcSKE;
 
+/****d* silcske/SilcSKEAPI/SilcSKEStatus
+ *
+ * NAME
+ *
+ *    typedef enum { ... } SilcSKEStatus;
+ *
+ * DESCRIPTION
+ *
+ *    Status types returned in SKE callbacks. This tell the status of
+ *    the SKE session, and if an error occurred. Application can map the
+ *    status to human readable string with silc_ske_map_status function.
+ *
+ * SOURCE
+ */
+typedef enum {
+  /* These are defined by the protocol */
+  SILC_SKE_STATUS_OK                     = 0,  /* No error */
+  SILC_SKE_STATUS_ERROR                  = 1,  /* Unknown error */
+  SILC_SKE_STATUS_BAD_PAYLOAD            = 2,  /* Malformed payload */
+  SILC_SKE_STATUS_UNKNOWN_GROUP          = 3,  /* Unsupported DH group */
+  SILC_SKE_STATUS_UNKNOWN_CIPHER         = 4,  /* Unsupported cipher */
+  SILC_SKE_STATUS_UNKNOWN_PKCS           = 5,  /* Unsupported PKCS algorithm */
+  SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION  = 6,  /* Unsupported hash function */
+  SILC_SKE_STATUS_UNKNOWN_HMAC           = 7,  /* Unsupported HMAC */
+  SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY = 8,  /* Unsupported/not trusted PK */
+  SILC_SKE_STATUS_INCORRECT_SIGNATURE    = 9,  /* Incorrect signature */
+  SILC_SKE_STATUS_BAD_VERSION            = 10, /* Unsupported version */
+  SILC_SKE_STATUS_INVALID_COOKIE         = 11, /* Cookie was modified */
+
+  /* Implementation specific status types */
+  SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED,     /* Remote did not send PK */
+  SILC_SKE_STATUS_BAD_RESERVED_FIELD,         /* Reserved field was not 0 */
+  SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH,         /* Payload includes garbage */
+  SILC_SKE_STATUS_SIGNATURE_ERROR,            /* Error computing signature */
+  SILC_SKE_STATUS_OUT_OF_MEMORY,              /* System out of memory */
+} SilcSKEStatus;
+/***/
+
 #include "silcske_groups.h"
 #include "silcske_payload.h"
 
@@ -94,7 +110,7 @@ typedef enum {
  *
  *    Security Properties negotiated between key exchange parties. This
  *    structure is filled from the Key Exchange Start Payload which is used
- *    to negotiate what security properties should be used in the
+ *    to negotiate what security properties must be used in the
  *    communication.
  *
  * SOURCE
@@ -102,10 +118,11 @@ typedef enum {
 typedef struct {
   SilcSKESecurityPropertyFlag flags;    /* Flags */
   SilcSKEDiffieHellmanGroup group;      /* Selected Diffie Hellman group */
-  SilcPKCS pkcs;                        /* Selected PKCS algorithm */
   SilcCipher cipher;                    /* Selected cipher */
-  SilcHash hash;                        /* Selected hash algorithm */
   SilcHmac hmac;                        /* Selected HMAC */
+  SilcHash hash;                        /* Selected hash algorithm */
+  SilcPKCS pkcs;                        /* Selected PKCS and remote's
+                                           public key/certificate */
 } *SilcSKESecurityProperties;
 /***/
 
@@ -121,6 +138,7 @@ typedef struct {
  *    application to silc_ske_process_key_material* functions. It includes
  *    the processed key material which can be used as SILC session keys.
  *
+ * SOURCE
  */
 typedef struct {
   unsigned char *send_iv;
@@ -151,6 +169,7 @@ typedef struct {
  *
  *    Application may save application specific data to `user_context'.
  *
+ * SOURCE
  */
 typedef struct {
   void *user_context;                /* Application specific data */
@@ -235,35 +254,27 @@ typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
                                SilcSKEVerifyCbCompletion completion,
                                void *completion_context);
 
-/****f* silcske/SilcSKEAPI/SilcSKECheckVersion
- *
- * SYNOPSIS
- *
- *    typedef SilcSKEStatus
- *    (*SilcSKECheckVersionCb)(SilcSKE ske,
- *                             const unsigned char *version,
- *                             SilcUInt32 len, void *context);
- *
- * DESCRIPTION
- *
- *    Callback function used to check the version of the remote SKE server.
- *    The SKE library will call this function so that the appliation may
- *    check its version against the remote host's version.  This returns
- *    SILC_SKE_STATUS_OK if the version string is Ok, and returns
- *    SILC_SKE_STATUS_BAD_VERSION if the version was not acceptable.
- *
- ***/
-typedef SilcSKEStatus (*SilcSKECheckVersionCb)(SilcSKE ske,
-                                              const unsigned char *version,
-                                              SilcUInt32 len, void *context);
-
 /****f* silcske/SilcSKEAPI/SilcSKECompletionCb
  *
  * SYNOPSIS
  *
+ *    typedef void (*SilcSKECompletionCb)(SilcSKE ske,
+ *                                        SilcSKEStatus status,
+ *                                        SilcSKESecurityProperties prop,
+ *                                        SilcSKEKeyMaterial keymat,
+ *                                        SilcSKERekeyMaterial rekey,
+ *                                        void *context);
  *
  * DESCRIPTION
  *
+ *    Completion callback.  This is called after the key exchange protocol
+ *    has been completed.  It delivers the status of the protocol, and if
+ *    successful the security properties `prop' that was negotiated in the
+ *    protocol and the key material `keymat' that can be set into use by
+ *    calling silc_ske_set_keys, and the rekey key material `rekey' which
+ *    can be used later to start rekey protocol.  The `prop' will remain
+ *    valid as long as `ske' is valid.  After `ske' is freed `prop' will
+ *    become invalid.
  *
  ***/
 typedef void (*SilcSKECompletionCb)(SilcSKE ske,
@@ -273,89 +284,6 @@ typedef void (*SilcSKECompletionCb)(SilcSKE ske,
                                    SilcSKERekeyMaterial rekey,
                                    void *context);
 
-/****s* silcske/SilcSKEAPI/SilcSKEStruct
- *
- * NAME
- *
- *    struct SilcSKEStruct { ... };
- *
- * DESCRIPTION
- *
- *    This structure is the SKE session context, and has a type definition
- *    to SilcSKE. The structure includes the network connection socket,
- *    security properties collected during the SKE negotiation, payloads
- *    sent and received during the negotiation, and the actual raw key
- *    material too. The application usually does not need to reference
- *    to the inside of this structure.  However, checking the current
- *    status of the session can easily be checked with ske->status.
- *
- * SOURCE
- */
-struct SilcSKEStruct {
-  /* The network socket connection stream.  Set by application. */
-  SilcPacketStream stream;
-
-  /* Negotiated Security properties.  May be NULL in case of error. */
-  SilcSKESecurityProperties prop;
-
-  /* Key Exchange payloads filled during key negotiation with
-     remote data. Responder may save local data here as well. */
-  SilcSKEStartPayload start_payload;
-  SilcSKEKEPayload ke1_payload;
-  SilcSKEKEPayload ke2_payload;
-  unsigned char *remote_version;
-
-  /* Temporary copy of the KE Start Payload used in the
-     HASH computation. */
-  SilcBuffer start_payload_copy;
-
-  /* Random number x, 1 < x < q. This is the secret exponent
-     used in Diffie Hellman computations. */
-  SilcMPInt *x;
-
-  /* The secret shared key */
-  SilcMPInt *KEY;
-
-  /* The hash value HASH of the key exchange */
-  unsigned char *hash;
-  SilcUInt32 hash_len;
-
-  /* Random Number Generator. This is set by the caller and must
-     be free'd by the caller. */
-  SilcRng rng;
-
-  /* Pointer to the what ever user data. This is set by the caller
-     and is not touched by the SKE. The caller must also free this one. */
-  void *user_data;
-
-  /* Current status of SKE */
-  SilcSKEStatus status;
-
-  /* Reference counter. This is used when SKE library is performing async
-     operations, like public key verification. */
-  int users;
-
-  /* SKE callbacks. */
-  SilcSKECallbacks callbacks;
-
-  /* Backwards support version indicator */
-  SilcUInt32 backward_version;
-
-  char *version;
-  SilcPublicKey public_key;
-  SilcPrivateKey private_key;
-  SilcSKEPKType pk_type;
-  SilcBuffer packet_buf;
-  SilcSKESecurityPropertyFlag flags;
-  SilcSKEKeyMaterial keymat;
-  SilcSKERekeyMaterial rekey;
-  SilcSchedule schedule;
-  SilcFSMStruct fsm;
-  SilcAsyncOperationStruct op;
-  SilcBool aborted;
-};
-/***/
-
 /* Prototypes */
 
 /****f* silcske/SilcSKEAPI/silc_ske_alloc
@@ -363,7 +291,8 @@ struct SilcSKEStruct {
  * SYNOPSIS
  *
  *    SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
- *                           void *context);
+ *                           SilcPublicKey public_key,
+ *                           SilcPrivateKey private_key, void *context);
  *
  * DESCRIPTION
  *
@@ -380,7 +309,7 @@ struct SilcSKEStruct {
  *
  *    // Initiator example
  *    ske = silc_ske_alloc(rng, scheduler, app);
- *    silc_ske_set_callbacks(ske, verify_public_key, check_version, app);
+ *    silc_ske_set_callbacks(ske, verify_public_key, completion, app);
  *    start_payload =
  *      silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_PFS |
  *                                            SILC_SKE_SP_FLAG_MUTUAL,
@@ -388,7 +317,9 @@ struct SilcSKEStruct {
  *    silc_ske_initiator_start(ske);
  *
  ***/
-SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule, void *context);
+SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
+                      SilcPublicKey public_key, SilcPrivateKey private_key,
+                      void *context);
 
 /****f* silcske/SilcSKEAPI/silc_ske_free
  *
@@ -422,7 +353,6 @@ void *silc_ske_get_context(SilcSKE ske);
  *
  *    void silc_ske_set_callbacks(SilcSKE ske,
  *                                SilcSKEVerifyCb verify_key,
- *                                SilcSKECheckVersion check_version,
  *                                SilcSKECompletion completed,
  *                                void *context);
  *
@@ -438,11 +368,6 @@ void *silc_ske_get_context(SilcSKE ske);
  *    argument since sending public key in rekey is not mandatory.  Setting
  *    this callback implies that remote end MUST send its public key.
  *
- *    The `check_version' callback is called to verify the remote host's
- *    version.  The application may check its own version against the remote
- *    host's version and determine whether supporting the remote host
- *    is possible.
- *
  *    The `completed' callback will be called once the protocol has completed,
  *    either successfully or with an error.  The status of the protocol is
  *    delivered to application with the callback.
@@ -453,7 +378,6 @@ void *silc_ske_get_context(SilcSKE ske);
  ***/
 void silc_ske_set_callbacks(SilcSKE ske,
                            SilcSKEVerifyCb verify_key,
-                           SilcSKECheckVersionCb check_version,
                            SilcSKECompletionCb completed,
                            void *context);
 
@@ -491,9 +415,9 @@ void silc_ske_set_callbacks(SilcSKE ske,
  *
  ***/
 SilcAsyncOperation
-silc_ske_initiator_start(SilcSKE ske,
-                        SilcPacketStream stream,
-                        SilcSKEStartPayload start_payload);
+silc_ske_initiator(SilcSKE ske,
+                  SilcPacketStream stream,
+                  SilcSKEStartPayload start_payload);
 
 /****f* silcske/SilcSKEAPI/silc_ske_responder_start
  *
@@ -518,11 +442,8 @@ silc_ske_initiator_start(SilcSKE ske,
  *    for `stream' after this function is called.  The `stream' is turned
  *    over to application once the completion callback is called.
  *
- *    The application has received initiator's first packet from network
- *    and it must provide it as `start_payload' argument to this function.
- *    The function processes the packet and makes security property selection
- *    from the initiator's proposal.  The `version' is the responder's version
- *    that will be sent in reply to the initiator.  The `flags' indicates
+ *    The `version' is the responder's SILC protocol version that will be
+ *    sent in reply to the initiator.  The `flags' indicates the
  *    SilcSKESecurityPropertyFlag flags that responder supports and enforces
  *    for the initiator.  Responder may, for example, enforce that the PFS
  *    will be performed in rekey.
@@ -534,22 +455,21 @@ silc_ske_initiator_start(SilcSKE ske,
  *
  ***/
 SilcAsyncOperation
-silc_ske_responder_start(SilcSKE ske,
-                        SilcPacketStream stream,
-                        const char *version,
-                        SilcBuffer start_payload,
-                        SilcSKESecurityPropertyFlag flags);
+silc_ske_responder(SilcSKE ske,
+                  SilcPacketStream stream,
+                  const char *version,
+                  SilcSKESecurityPropertyFlag flags);
 
 SilcAsyncOperation
-silc_ske_rekey_initiator_start(SilcSKE ske,
-                              SilcPacketStream stream,
-                              SilcSKERekeyMaterial rekey);
+silc_ske_rekey_initiator(SilcSKE ske,
+                        SilcPacketStream stream,
+                        SilcSKERekeyMaterial rekey);
 
 SilcAsyncOperation
-silc_ske_rekey_responder_start(SilcSKE ske,
-                              SilcPacketStream stream,
-                              SilcBuffer ke_payload,
-                              SilcSKERekeyMaterial rekey);
+silc_ske_rekey_responder(SilcSKE ske,
+                        SilcPacketStream stream,
+                        SilcBuffer ke_payload,
+                        SilcSKERekeyMaterial rekey);
 
 /****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties
  *
@@ -565,9 +485,10 @@ silc_ske_rekey_responder_start(SilcSKE ske,
  *    Assembles security properties to Key Exchange Start Payload to be
  *    sent to the remote end.  This checks system wide (SILC system, that is)
  *    settings and chooses from those.  However, if other properties
- *    should be used this function is easy to replace by another function,
- *    as, this function is called by the caller of the library and not
- *    by the SKE library itself.  Returns NULL on error.
+ *    should be used this function is easy to replace by another function.
+ *    Returns NULL on error.  This is an utility function.  This is used
+ *    by the initiator of the protocol.  The `version' is the local SILC
+ *    protocol version string.
  *
  ***/
 SilcSKEStartPayload
@@ -575,32 +496,73 @@ silc_ske_assemble_security_properties(SilcSKE ske,
                                      SilcSKESecurityPropertyFlag flags,
                                      const char *version);
 
+/****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_ske_set_keys(SilcSKE ske,
+ *                               SilcSKEKeyMaterial keymat,
+ *                               SilcSKESecurityProperties prop,
+ *                               SilcCipher *ret_send_key,
+ *                               SilcCipher *ret_receive_key,
+ *                               SilcHmac *ret_hmac_send,
+ *                               SilcHmac *ret_hmac_receive,
+ *                               SilcHash *ret_hash);
+ *
+ * DESCRIPTION
+ *
+ *    This function can be used after successful key exchange to take the
+ *    key material `keymat' with security properties `prop' into use.
+ *    This will allocate send and receive ciphers, HMACs and hash for the
+ *    application.  Caller must free the returned contexts.  This is an
+ *    utility function.
+ *
+ ***/
+SilcBool silc_ske_set_keys(SilcSKE ske,
+                          SilcSKEKeyMaterial keymat,
+                          SilcSKESecurityProperties prop,
+                          SilcCipher *ret_send_key,
+                          SilcCipher *ret_receive_key,
+                          SilcHmac *ret_hmac_send,
+                          SilcHmac *ret_hmac_receive,
+                          SilcHash *ret_hash);
+
 /****f* silcske/SilcSKEAPI/silc_ske_parse_version
  *
  * SYNOPSIS
  *
  *    SilcBool silc_ske_parse_version(SilcSKE ske,
- *                                SilcUInt32 *protocol_version,
- *                                char **protocol_version_string,
- *                                SilcUInt32 *software_version,
- *                                char **software_version_string,
- *                                char **vendor_version);
+ *                                    SilcUInt32 *protocol_version,
+ *                                    char **protocol_version_string,
+ *                                    SilcUInt32 *software_version,
+ *                                    char **software_version_string,
+ *                                    char **vendor_version);
  *
  * DESCRIPTION
  *
- *    This utility function can be used to parse the remote host's version
- *    string.  This returns the protocol version, and software version into
- *    the `protocol_version', `software_version' and `vendor_version' pointers
- *    if they are provided.  The string versions of the versions are saved
- *    in *_string pointers if they are provided.  Returns TRUE if the version
- *    string was successfully parsed.
+ *    Utility function to parse the remote host's version string.
  *
  ***/
 SilcBool silc_ske_parse_version(SilcSKE ske,
-                           SilcUInt32 *protocol_version,
-                           char **protocol_version_string,
-                           SilcUInt32 *software_version,
-                           char **software_version_string,
-                           char **vendor_version);
+                               SilcUInt32 *protocol_version,
+                               char **protocol_version_string,
+                               SilcUInt32 *software_version,
+                               char **software_version_string,
+                               char **vendor_version);
+
+/****f* silcske/SilcSKEAPI/silc_ske_map_status
+ *
+ * SYNOPSIS
+ *
+ *    const char *silc_ske_map_status(SilcSKEStatus status);
+ *
+ * DESCRIPTION
+ *
+ *    Utility function to map the `status' into human readable message.
+ *
+ ***/
+const char *silc_ske_map_status(SilcSKEStatus status);
+
+#include "silcske_i.h"
 
 #endif /* !SILCSKE_H */