Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2000 - 2005 Pekka Riikonen
+ Copyright (C) 2000 - 2006 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
*/
-#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"
*
* 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
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 */
+ SilcPublicKey public_key; /* Remote public key */
} *SilcSKESecurityProperties;
/***/
* 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;
*
* Application may save application specific data to `user_context'.
*
+ * SOURCE
*/
typedef struct {
void *user_context; /* Application specific data */
* SYNOPSIS
*
* typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
- * const unsigned char *pk_data,
- * SilcUInt32 pk_len,
- * SilcSKEPKType pk_type,
+ * SilcPublicKey public_key,
* void *context,
* SilcSKEVerifyCbCompletion completion,
* void *completion_context);
* arugment to silc_ske_set_callbacks. See silc_ske_set_callbacks for
* more information.
*
+ * If the key repository was provided in silc_ske_alloc this callback
+ * is called only if the public key was not found from the repository.
+ *
***/
typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
- const unsigned char *pk_data,
- SilcUInt32 pk_len,
- SilcSKEPKType pk_type,
+ SilcPublicKey public_key,
void *context,
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,
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;
- bool aborted;
-};
-/***/
-
/* Prototypes */
/****f* silcske/SilcSKEAPI/silc_ske_alloc
* SYNOPSIS
*
* SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
- * void *context);
+ * SilcSKR repository, SilcPublicKey public_key,
+ * SilcPrivateKey private_key, void *context);
*
* DESCRIPTION
*
* SKE session context is allocated application must call the
* silc_ske_set_callbacks.
*
+ * If the `repository' is non-NULL then the remote's public key will be
+ * verified from the repository. If it is not provided then the
+ * SilcSKEVerifyCb callback must be set, and it will be called to
+ * verify the key. If both `repository' and the callback is provided the
+ * callback is called only if the key is not found from the repository.
+ *
+ * The `public_key' and `private_key' is the caller's identity used
+ * during the key exchange.
+ *
* EXMPALE
*
* // Initiator example
- * ske = silc_ske_alloc(rng, scheduler, app);
- * silc_ske_set_callbacks(ske, verify_public_key, check_version, app);
+ * ske = silc_ske_alloc(rng, scheduler, NULL, pk, prv, 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,
* version);
- * silc_ske_initiator_start(ske);
+ * silc_ske_initiator_start(ske, stream, start_payload);
*
***/
-SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule, void *context);
+SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
+ SilcSKR repository, SilcPublicKey public_key,
+ SilcPrivateKey private_key, void *context);
/****f* silcske/SilcSKEAPI/silc_ske_free
*
*
* void silc_ske_set_callbacks(SilcSKE ske,
* SilcSKEVerifyCb verify_key,
- * SilcSKECheckVersion check_version,
* SilcSKECompletion completed,
* void *context);
*
* 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.
***/
void silc_ske_set_callbacks(SilcSKE ske,
SilcSKEVerifyCb verify_key,
- SilcSKECheckVersionCb check_version,
SilcSKECompletionCb completed,
void *context);
*
* Starts the SILC Key Exchange protocol as initiator. The completion
* callback that was set in silc_ske_set_callbacks will be called once
- * the protocol has completed.
- *
- * The `stream' is the network connection to the remote host. Note that
- * SKE library will take over the packet stream `stream' while the
- * protocol is in process. The application will not receive any packets
- * for `stream' after this function is called. The `stream' is turned
- * over to application once the completion callback is called.
+ * the protocol has completed. The `stream' is the network connection
+ * to the remote host. The SKE library will handle all key exchange
+ * packets sent and received in the `stream' connection.
*
* The `start_payload' includes all configured security properties that
* will be sent to the responder. The `start_payload' must be provided.
*
***/
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
*
*
* Starts SILC Key Exchange protocol as responder. The completion
* callback that was set in silc_ske_set_callbacks will be called once
- * the protocol has completed.
- *
- * The `stream' is the network connection to the remote host. Note that
- * SKE library will take over the packet stream `stream' while the
- * protocol is in process. The application will not receive any packets
- * 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 protocol has completed. The `stream' is the network connection
+ * to the remote host. The SKE library will handle all key exchange
+ * packets sent and received in the `stream' connection.
+ *
+ * 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.
*
***/
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
*
* 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
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
*
- * bool silc_ske_parse_version(SilcSKE ske,
- * SilcUInt32 *protocol_version,
- * char **protocol_version_string,
- * SilcUInt32 *software_version,
- * char **software_version_string,
- * char **vendor_version);
+ * SilcBool silc_ske_parse_version(SilcSKE ske,
+ * SilcUInt32 *protocol_version,
+ * char **protocol_version_string,
+ * SilcUInt32 *software_version,
+ * char **software_version_string,
+ * char **vendor_version);
+ *
+ * DESCRIPTION
+ *
+ * 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);
+
+/****f* silcske/SilcSKEAPI/silc_ske_map_status
+ *
+ * SYNOPSIS
+ *
+ * const char *silc_ske_map_status(SilcSKEStatus status);
*
* 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 map the `status' into human readable message.
*
***/
-bool silc_ske_parse_version(SilcSKE ske,
- SilcUInt32 *protocol_version,
- char **protocol_version_string,
- SilcUInt32 *software_version,
- char **software_version_string,
- char **vendor_version);
+const char *silc_ske_map_status(SilcSKEStatus status);
+
+#include "silcske_i.h"
#endif /* !SILCSKE_H */