X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcske%2Fsilcske.h;h=9c637de61942b32f1654f903312ed80bea8529c5;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=5c552e03b7051962ea6eee7359f15d9c2eaa4522;hpb=a818c5b5411bbc4436d1c5f011236985c96bb787;p=silc.git diff --git a/lib/silcske/silcske.h b/lib/silcske/silcske.h index 5c552e03..9c637de6 100644 --- a/lib/silcske/silcske.h +++ b/lib/silcske/silcske.h @@ -1,10 +1,10 @@ /* - silcske.h + silcske.h Author: Pekka Riikonen - Copyright (C) 2000 - 2002 Pekka Riikonen + Copyright (C) 2000 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,142 +17,224 @@ */ -#ifndef SILCSKE_H -#define SILCSKE_H - -/****h* silcske/SilcSKEAPI +/****h* silcske/SILC SKE Interface * * DESCRIPTION * - * Implementation of the SILC Key Exchange Protocol (SKE). The SKE protocol + * The SILC Key Exchange (SKE) protocol interface. The SKE protocol * is used to negotiate secret key material between two parties, to be used * as session key or some other key. For example, when client connects to * 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. - * - * SKE is based on Diffie-Hellman, and it derives its functionality from - * SSH2 Key Exchange protocol, OAKLEY Key Determination protocol and - * Station-To-Station (STS) protocols. - * - * 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. For the interface application must provide - * a packet sending function which SKE library can call when it wants - * to send packet to the remote host. The actual network connection - * therefore is handled in the application and not by the SKE library. - * - * 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" +#ifndef SILCSKE_H +#define SILCSKE_H + +/* Forward declarations */ +typedef struct SilcSKECallbacksStruct *SilcSKECallbacks; +typedef struct SilcSKEStruct *SilcSKE; -/****s* silcske/SilcSKEAPI/SilcSKE +/****d* silcske/SilcSKEAPI/SilcSKEStatus * * NAME * - * typedef struct SilcSKEStruct *SilcSKE; + * typedef enum { ... } SilcSKEStatus; * * DESCRIPTION * - * This context is forward declaration for the SilcSKEStruct. - * This is allocated by the silc_ske_alloc and freed by the - * silc_ske_free function. This context represents the SKE session. + * 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. * - ***/ -typedef struct SilcSKEStruct *SilcSKE; + * 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 */ + SILC_SKE_STATUS_TIMEOUT, /* Timeout */ +} SilcSKEStatus; +/***/ -/****s* silcske/SilcSKEAPI/SilcSKESecurityProperties +#include "silcske_groups.h" +#include "silcske_payload.h" + +/****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag * * NAME * - * typedef struct SilcSKESecurityPropertiesStruct - * *SilcSKESecurityProperties; + * typedef enum { ... } SilcSKESecurityPropertyFlag * * DESCRIPTION * - * This context is forward declaration for the - * SilcSKESecurityPropertiesStruct structure. It is allocated by the - * library, and it represents the security properties selected during - * the SKE negotiation. + * SKE security property flags as defined by the SK protocol. * - ***/ -typedef struct SilcSKESecurityPropertiesStruct *SilcSKESecurityProperties; + * SOURCE + */ +typedef enum { + SILC_SKE_SP_FLAG_NONE = 0x00, /* No flags */ + SILC_SKE_SP_FLAG_IV_INCLUDED = 0x01, /* IV included in packet */ + SILC_SKE_SP_FLAG_PFS = 0x02, /* Perfect Forward Secrecy */ + SILC_SKE_SP_FLAG_MUTUAL = 0x04, /* Mutual authentication */ +} SilcSKESecurityPropertyFlag; +/***/ -/* Forward declaration for SKE callbacks structure, which is internal. */ -typedef struct SilcSKECallbacksStruct *SilcSKECallbacks; +/****s* silcske/SilcSKEAPI/SilcSKESecurityProperties + * + * NAME + * + * typedef struct { ... } *SilcSKESecurityProperties; + * + * DESCRIPTION + * + * 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 must be used in the + * communication. + * + * SOURCE + */ +typedef struct SilcSKESecurityPropertiesStruct { + SilcSKESecurityPropertyFlag flags; /* Flags */ + SilcSKEDiffieHellmanGroup group; /* Selected Diffie Hellman group */ + SilcCipher cipher; /* Selected cipher */ + SilcHmac hmac; /* Selected HMAC */ + SilcHash hash; /* Selected hash algorithm */ + SilcPublicKey public_key; /* Remote public key */ + SilcUInt16 remote_port; /* Remote port, set when IV Included + set and using UDP/IP */ +} *SilcSKESecurityProperties; +/***/ -/****d* silcske/SilcSKEAPI/SilcSKEPKType +/****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial * * NAME * - * typedef enum { ... } SilcSKEPKType; + * typedef struct { ... } *SilcSKEKeyMaterial; * * DESCRIPTION * - * Public key and certificate types defined by the SKE protocol. + * This is the key material structure, and is passed as argument by the + * application to silc_ske_process_key_material_data function. It includes + * the processed key material which can be used as SILC session keys. * * SOURCE */ -typedef enum { - SILC_SKE_PK_TYPE_SILC = 1, /* Mandatory type */ - /* Optional types. These are not implemented currently */ - SILC_SKE_PK_TYPE_SSH2 = 2, - SILC_SKE_PK_TYPE_X509V3 = 3, - SILC_SKE_PK_TYPE_OPENPGP = 4, - SILC_SKE_PK_TYPE_SPKI = 5 -} SilcSKEPKType; +typedef struct SilcSKEKeyMaterialStruct { + unsigned char *send_iv; + unsigned char *receive_iv; + SilcUInt32 iv_len; + unsigned char *send_enc_key; + unsigned char *receive_enc_key; + SilcUInt32 enc_key_len; /* Key length in bits */ + unsigned char *send_hmac_key; + unsigned char *receive_hmac_key; + SilcUInt32 hmac_key_len; /* Key length in bytes */ +} *SilcSKEKeyMaterial; /***/ -/****f* silcske/SilcSKEAPI/SilcSKESendPacketCb +/****s* silcske/SilcSKEAPI/SilcSKERekeyMaterial * - * SYNOPSIS + * NAME * - * typedef void (*SilcSKESendPacketCb)(SilcSKE ske, SilcBuffer packet, - * SilcPacketType type, void *context); + * typedef struct { ... } *SilcSKERekeyMaterial; * * DESCRIPTION * - * Packet sending callback. Caller of the SKE routines must provide - * a routine to send packets to negotiation parties. See the - * silc_ske_set_callbacks for more information. + * This context is returned after key exchange protocol to application + * in the completion callback. Application may save it and use it later + * to perform the rekey with silc_ske_rekey_initiator and/or + * silc_ske_rekey_responder functions. If application does not + * need the context, it may free it with silc_ske_free_rekey_material + * function. * ***/ -typedef void (*SilcSKESendPacketCb)(SilcSKE ske, SilcBuffer packet, - SilcPacketType type, void *context); +typedef struct SilcSKERekeyMaterialStruct { + unsigned char *send_enc_key; + char *hash; + unsigned int enc_key_len : 23; + unsigned int ske_group : 8; + unsigned int pfs : 1; +} *SilcSKERekeyMaterial; -/****f* silcske/SilcSKEAPI/SilcSKECb +/****s* silcske/SilcSKEAPI/SilcSKEParams * - * SYNOPSIS + * NAME * - * typedef void (*SilcSKECb)(SilcSKE ske, void *context); + * typedef struct { ... } *SilcSKEParams, SilcSKEParamsStruct; * * DESCRIPTION * - * Generic SKE callback function. This is called in various SKE - * routines. The SilcSKE object sent as argument provides all the data - * callers routine might need (payloads etc). This is usually called - * to indicate that the application may continue the execution of the - * SKE protocol. The application should check the ske->status in this - * callback function. This callback is also called when Start Payload - * is processed. See silc_ske_set_callbacks function for more information. + * SKE parameters structure. This structure is given as argument to + * silc_ske_initiator and silc_ske_responder functions. * - ***/ -typedef void (*SilcSKECb)(SilcSKE ske, void *context); + * SOURCE + */ +typedef struct SilcSKEParamsObject { + /* The SKE version string that is sent to the remote end. This field + must be set. Caller must free the pointer. */ + char *version; + + /* Security property flags. When initiator sets these it requests them + from the responder. Responder may set here the flags it supports + and wants to enforce for the initiator. */ + SilcSKESecurityPropertyFlag flags; + + /* SILC Session port when using UDP/IP and SILC_SKE_SP_FLAG_IV_INCLUDED + flag. It is the port the remote will use as SILC session port after + the key exchange protocol. Ignored without SILC_SKE_SP_FLAG_IV_INCLUDED + flag. */ + SilcUInt16 session_port; + + /* Key exchange timeout in seconds. If key exchange is not completed in + this time it will timeout. If not specified (zero), default value + (30 seconds) will be used. */ + SilcUInt16 timeout_secs; +} *SilcSKEParams, SilcSKEParamsStruct; +/***/ + +/****d* silcske/SilcSKEAPI/SilcSKEPKType + * + * NAME + * + * typedef enum { ... } SilcSKEPKType; + * + * DESCRIPTION + * + * Public key and certificate types defined by the SKE protocol. + * + * SOURCE + */ +typedef enum { + SILC_SKE_PK_TYPE_SILC = 1, /* SILC Public Key, mandatory */ + SILC_SKE_PK_TYPE_SSH2 = 2, /* SSH2 Public key, not supported */ + SILC_SKE_PK_TYPE_X509V3 = 3, /* X.509v3 certificate, not supported */ + SILC_SKE_PK_TYPE_OPENPGP = 4, /* OpenPGP certificate, not supported */ + SILC_SKE_PK_TYPE_SPKI = 5 /* SPKI certificate, not supported */ +} SilcSKEPKType; +/***/ /****f* silcske/SilcSKEAPI/SilcSKEVerifyCbCompletion * @@ -166,11 +248,7 @@ typedef void (*SilcSKECb)(SilcSKE ske, void *context); * * Completion callback that will be called when the public key * has been verified. The `status' will indicate whether the public - * key were trusted or not. If the `status' is PENDING then the status - * is not considered to be available at this moment. In this case the - * SKE libary will assume that the caller will call this callback again - * when the status is available. See silc_ske_set_callbacks for more - * information. + * key were trusted or not. * ***/ typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske, @@ -182,9 +260,7 @@ typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske, * SYNOPSIS * * typedef void (*SilcSKEVerifyCb)(SilcSKE ske, - * unsigned char *pk_data, - * SilcUInt32 pk_len, - * SilcSKEPKType pk_type, + * SilcPublicKey public_key, * void *context, * SilcSKEVerifyCbCompletion completion, * void *completion_context); @@ -192,187 +268,57 @@ typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske, * DESCRIPTION * * Callback function used to verify the received public key or certificate. - * The verification process is most likely asynchronous. That's why the + * The verification process is most likely asynchronous. That's why the * application must call the `completion' callback when the verification - * process has been completed. The library then calls the user callback - * (SilcSKECb), if it was provided for the function that takes this callback - * function as argument, to indicate that the SKE protocol may continue. - * See silc_ske_set_callbacks for more information. + * process has been completed. The `context' is the context given as + * 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, - unsigned char *pk_data, - SilcUInt32 pk_len, - SilcSKEPKType pk_type, + SilcPublicKey public_key, void *context, SilcSKEVerifyCbCompletion completion, void *completion_context); -/****f* silcske/SilcSKEAPI/SilcSKECheckVersion +/****f* silcske/SilcSKEAPI/SilcSKECompletionCb * * SYNOPSIS * - * typedef SilcSKEStatus (*SilcSKECheckVersion)(SilcSKE ske, - * 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 (*SilcSKECheckVersion)(SilcSKE ske, - unsigned char *version, - SilcUInt32 len, void *context); - -/****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial - * - * NAME - * - * typedef struct { ... } SilcSKEKeyMaterial; + * typedef void (*SilcSKECompletionCb)(SilcSKE ske, + * SilcSKEStatus status, + * const SilcSKESecurityProperties prop, + * const SilcSKEKeyMaterial keymat, + * SilcSKERekeyMaterial rekey, + * void *context); * * DESCRIPTION * - * This is the key material structure, and is passed as argument by the - * application to silc_ske_process_key_material* functions. It includes - * the processed key material which can be used as SILC session keys. + * 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' and `keymat' + * will remain valid as long as `ske' is valid. The `rekey' will remain + * valid until silc_ske_free_rekey_material is called. The application + * must call it to free the `rekey'. + * + * When doing rekey, this completion callback delivers the `keymat' and + * new `rekey'. The `prop' is ignored. The `keymat' has already been set + * to the packet stream associated with the `ske'. Thus, after this + * is called the new keys are in use. * ***/ -typedef struct { - unsigned char *send_iv; - unsigned char *receive_iv; - SilcUInt32 iv_len; - unsigned char *send_enc_key; - unsigned char *receive_enc_key; - SilcUInt32 enc_key_len; - unsigned char *send_hmac_key; - unsigned char *receive_hmac_key; - SilcUInt32 hmac_key_len; -} SilcSKEKeyMaterial; - -/* Length of cookie in Start Payload */ -#define SILC_SKE_COOKIE_LEN 16 - -#include "silcske_groups.h" -#include "silcske_payload.h" - -/****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag - * - * NAME - * - * typedef enum { ... } SilcSKESecurityPropertyFlag - * - * DESCRIPTION - * - * SKE security property flags as defined by the SK protocol. - * - * SOURCE - */ -typedef enum { - SILC_SKE_SP_FLAG_NONE = 0x00, /* No flags */ - SILC_SKE_SP_FLAG_NO_REPLY = 0x01, /* No reply required to payload */ - SILC_SKE_SP_FLAG_PFS = 0x02, /* Perfect Forward Secrecy */ - SILC_SKE_SP_FLAG_MUTUAL = 0x04, /* Mutual authentication */ -} SilcSKESecurityPropertyFlag; -/***/ - -/****s* silcske/SilcSKEAPI/SilcSKESecurityPropertiesStruct - * - * NAME - * - * struct SilcSKESecurityPropertiesStruct { ... }; - * - * DESCRIPTION - * - * 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 - * communication. - * - * SOURCE - */ -struct SilcSKESecurityPropertiesStruct { - 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 */ -}; -/***/ - -/****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, - * securit 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 connection object. This is initialized by the caller. */ - SilcSocketConnection sock; - - /* Security properties negotiated */ - 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; - - /* 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; -}; -/***/ +typedef void (*SilcSKECompletionCb)(SilcSKE ske, + SilcSKEStatus status, + const SilcSKESecurityProperties prop, + const SilcSKEKeyMaterial keymat, + SilcSKERekeyMaterial rekey, + void *context); /* Prototypes */ @@ -380,21 +326,49 @@ struct SilcSKEStruct { * * SYNOPSIS * - * SilcSKE silc_ske_alloc(SilcRng rng, void *context); + * SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule, + * SilcSKR repository, SilcPublicKey public_key, + * SilcPrivateKey private_key, void *context); * * DESCRIPTION * * Allocates the SKE session context and returns it. The `rng' is * the random number generator the SKE is going to use when it needs * random number generation during the SKE session. The `context' is - * user context that the libary will not touch. The application can - * access that context with the ske->user_context if needed. The + * user context that the libary will not touch. Application can get the + * context by calling the fuction silc_ske_get_context function. The * application is responsible of freeing the `context'. After the * 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. Giving `private_key' is optional if the + * SILC_SKE_SP_FLAG_MUTUAL is not set and you are initiator. For + * responder both `public_key' and `private_key' must be set. + * + * When allocating SKE session for rekey, the `repository' and `private_key' + * pointers must be NULL and the SilcSKEVerifyCb callback must not be + * set with silc_ske_set_callbacks. + * + * EXMPALE + * + * // Initiator example + * params.version = version; + * params.flags = SILC_SKE_SP_FLAG_PFS | SILC_SKE_SP_FLAG_MUTUAL; + * ske = silc_ske_alloc(rng, scheduler, NULL, pk, prv, app); + * silc_ske_set_callbacks(ske, verify_public_key, completion, app); + * silc_ske_initiator(ske, stream, ¶ms, NULL); + * ***/ -SilcSKE silc_ske_alloc(SilcRng rng, 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 * @@ -409,487 +383,333 @@ SilcSKE silc_ske_alloc(SilcRng rng, void *context); ***/ void silc_ske_free(SilcSKE ske); +/****f* silcske/SilcSKEAPI/silc_ske_get_context + * + * SYNOPSIS + * + * void *silc_ske_get_context(SilcSKE ske); + * + * DESCRIPTION + * + * Returns the context that was given as argument to silc_ske_alloc. + * + ***/ +void *silc_ske_get_context(SilcSKE ske); + /****f* silcske/SilcSKEAPI/silc_ske_set_callbacks * * SYNOPSIS * * void silc_ske_set_callbacks(SilcSKE ske, - * SilcSKESendPacketCb send_packet, - * SilcSKECb payload_receive, * SilcSKEVerifyCb verify_key, - * SilcSKECb proto_continue, - * SilcSKECheckVersion check_version, + * SilcSKECompletion completed, * void *context); * * DESCRIPTION * * Sets the callback functions for the SKE session. * - * The `send_packet' callback is a function that sends the packet to - * network. The SKE library will call it at any time packet needs to - * be sent to the remote host. - * - * The `payload_receive' callback is called when the remote host's Key - * Exchange Start Payload has been processed. The payload is saved - * to ske->start_payload if the application would need it. The application - * must also provide the payload to the next state of the SKE. - * * The `verify_key' callback is called to verify the received public key * or certificate. The verification process is most likely asynchronous. * That is why the application must call the completion callback when the - * verification process has been completed. The library then calls the user - * callback (`proto_continue'), if it is provided to indicate that the SKE - * protocol may continue. If this SKE session context is used to perform - * rekey, this callback usually is not provided as argument since sending - * public key in rekey is not mandatory. Setting this callback implies - * that remote end MUST send its public key, and this could cause - * problems when performing rekey. When doing normal SKE session this - * callback should be set. - * - * The `proto_continue' callback is called to indicate that it is - * safe to continue the execution of the SKE protocol after executing - * an asynchronous operation, such as calling the `verify_key' callback - * function, which is asynchronous. The application should check the - * ske->status in this function to check whether it is Ok to continue - * the execution of the protocol. - * - * 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. + * verification process has been completed. If this SKE session context + * is used to perform rekey, this callback usually is not provided as + * argument since sending public key in rekey is not mandatory. Setting + * this callback implies that remote end MUST send its public key. + * + * 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. * * The `context' is passed as argument to all of the above callback * functions. * ***/ void silc_ske_set_callbacks(SilcSKE ske, - SilcSKESendPacketCb send_packet, - SilcSKECb payload_receive, SilcSKEVerifyCb verify_key, - SilcSKECb proto_continue, - SilcSKECheckVersion check_version, + SilcSKECompletionCb completed, void *context); -/****f* silcske/SilcSKEAPI/silc_ske_initiator_start +/****f* silcske/SilcSKEAPI/silc_ske_initiator * * SYNOPSIS * - * SilcSKEStatus silc_ske_initiator_start(SilcSKE ske, SilcRng rng, - * SilcSocketConnection sock, - * SilcSKEStartPayload - * *start_payload); + * SilcAsyncOperation + * silc_ske_initiator(SilcSKE ske, + * SilcPacketStream stream, + * SilcSKEParams params, + * SilcSKEStartPayload start_payload); * * DESCRIPTION * - * Starts the SILC Key Exchange protocol for initiator. The connection - * to the responder end must be established before calling this function - * and the connecting socket must be sent as argument. This function - * creates the Key Exchange Start Payload which includes all our - * configured security properties. This payload is then sent to the - * responder end for further processing. This payload must be sent as - * argument to the function, however, it must not be encoded - * already, it is done by this function. The caller must not free - * the `start_payload' since the SKE library will save it. - * - * Before calling this function application calls the - * silc_ske_assemble_security_properties which returns the `start_payload' - * which application must provide for this function. - * - * After calling this function the application must wait for reply - * from the responder. + * 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. The SKE library will handle all key exchange + * packets sent and received in the `stream' connection. The library will + * also set the remote host's ID automatically to the `stream' if it is + * present in the exchanged packets. The `params' include SKE parameters, + * and it must be provided. + * + * If the `start_payload' is NULL the library will generate it + * automatically. Caller may provide it if it wants to send its own + * security properties instead of using the default ones library + * generates. If caller provides it, it must not free it once it has + * been given as argument to this function. + * + * This function returns SilcAsyncOperation operation context which can + * be used to control the protocol from the application. Application may + * for example safely abort the protocol at any point, if needed. Returns + * NULL on error. * ***/ -SilcSKEStatus silc_ske_initiator_start(SilcSKE ske, SilcRng rng, - SilcSocketConnection sock, - SilcSKEStartPayload *start_payload); +SilcAsyncOperation silc_ske_initiator(SilcSKE ske, + SilcPacketStream stream, + SilcSKEParams params, + SilcSKEStartPayload start_payload); -/****f* silcske/SilcSKEAPI/silc_ske_initiator_phase_1 +/****f* silcske/SilcSKEAPI/silc_ske_responder * * SYNOPSIS * - * SilcSKEStatus silc_ske_initiator_phase_1(SilcSKE ske, - * SilcBuffer start_payload); + * SilcAsyncOperation + * silc_ske_responder(SilcSKE ske, + * SilcPacketStream stream, + * SilcSKEParams params); * * DESCRIPTION * - * Function called after ske_initiator_start fuction. This receives - * the responder's Key Exchange Start payload which includes the - * security properties selected by the responder from our payload - * sent in the silc_ske_initiator_start function. The `start_payload' - * is the received payload and the application must send it as argument. + * 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. The SKE library will handle all key exchange + * packets sent and received in the `stream' connection. The library will + * also set the remote hosts's ID automatically to the `stream' if it is + * present in the exchanged packets. The `params' include SKE parameters, + * and must be provided. * - * After calling this function the application must call immediately, - * or with short timeout, the silc_ske_initiator_phase_2 function. + * This function returns SilcAsyncOperation operation context which can + * be used to control the protocol from the application. Application may + * for example safely abort the protocol at any point, if needed. Returns + * NULL on error. * ***/ -SilcSKEStatus silc_ske_initiator_phase_1(SilcSKE ske, - SilcBuffer start_payload); +SilcAsyncOperation silc_ske_responder(SilcSKE ske, + SilcPacketStream stream, + SilcSKEParams params); -/****f* silcske/SilcSKEAPI/silc_ske_initiator_phase_2 +/****f* silcske/SilcSKEAPI/silc_ske_rekey_initiator * * SYNOPSIS * - * SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske, - * SilcPublicKey public_key, - * SilcPrivateKey private_key, - * SilcSKEPKType pk_type) + * SilcAsyncOperation + * silc_ske_rekey_initiator(SilcSKE ske, + * SilcPacketStream stream, + * SilcSKERekeyMaterial rekey); * * DESCRIPTION * - * This function continues the SKE session after the initiator has - * called the silc_ske_initiator_phase_1. After that function returns - * the application should call immediately, or with short timeout, this - * function which will continue with the session, and sends next phase - * packet to the responder. The caller must provide the caller's - * public key and private key as argument, since the public key is - * sent to the responder, and the private key is be used to generate - * digital signature. + * Starts SILC Key Exchange key regeneration (rekey) protocol. The `rekey' + * is the rekey material received earlier in SilcSKECompletionCb. That + * same callback is called after the rekey protocol is over to deliver new + * key material and new rekey material. When the rekey is completed the + * SKE library will automatically update the new keys into `stream'. The + * completion callback is called after the new keys has been taken into + * use. * - * After this function the application must wait for reply from the - * responder. + * This function returns SilcAsyncOperation operation context which can + * be used to control the protocol from the application. Application may + * for example safely abort the protocol at any point, if needed. Returns + * NULL on error. * ***/ -SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske, - SilcPublicKey public_key, - SilcPrivateKey private_key, - SilcSKEPKType pk_type); +SilcAsyncOperation silc_ske_rekey_initiator(SilcSKE ske, + SilcPacketStream stream, + SilcSKERekeyMaterial rekey); -/****f* silcske/SilcSKEAPI/silc_ske_initiator_finish +/****f* silcske/SilcSKEAPI/silc_ske_rekey_responder * * SYNOPSIS * - * SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske, - * SilcBuffer ke_payload); + * SilcAsyncOperation + * silc_ske_rekey_responder(SilcSKE ske, + * SilcPacketStream stream, + * SilcSKERekeyMaterial rekey, + * SilcPacket packet); * * DESCRIPTION * - * Receives the reply from the responder and processes it. The - * `ke_payload' is the reply and application must provide it as argument. - * This function will verify the responder's public key, by calling - * the `verify_key' callback that was set with silc_ske_set_callbacks - * function. + * Starts SILC Key Exchange key regeneration (rekey) protocol as responder. + * The `rekey' is the rekey material received earlier in + * SilcSKECompletionCb. That same callback is called after the rekey + * protocol is over to deliver new key material and new rekey material. + * When the rekey is completed the SKE library will automatically update + * the new keys into `stream'. The completion callback is called after + * the new keys has been taken into use. * - * If this function returns error, no callbacks will be called. If - * this function needs to verify remote end's public key, this will - * return SILC_SKE_STATUS_PENDING, which indicates application that - * SKE is performing asynchronous operation and is in pending status. - * When in this status application must not continue with calling - * any other SKE routine. The asynchronous operation is the `verify_key' - * callback, which application completes by calling its completion - * callback. After completion the SKE libary will call the - * `proto_continue' callback, to indicate application that pending - * status is over and it is safe to continue the execution of SKE, - * which application does by calling the silc_ske_end function. - * - * If this function returns SILC_SKE_STATUS_OK, it will not call the - * `verify_key' callback, however, it will or has already called the - * `proto_continue' callback. - * - * Application must not continue execution of the SKE before library - * has called the `proto_continue' callback. After it is called - * the application finishes SKE session by calling silc_ske_end - * function. + * The `packet' is the SILC_PACKET_REKEY received to start the rekey + * protocol. If `packet' is NULL it is assumed that the packet will be + * received from the `stream'. * - ***/ -SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske, - SilcBuffer ke_payload); - -/****f* silcske/SilcSKEAPI/silc_ske_responder_start - * - * SYNOPSIS - * - * SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng, - * SilcSocketConnection sock, - * const char *version, - * SilcBuffer start_payload, - * SilcSKESecurityPropertyFlag - * flags); - * - * DESCRIPTION - * - * Starts Key Exchange protocol for responder. 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 - * SilcSKESecurityPropertyFlag flags that responder enforces for the - * initiator. Responder may, for example, enforce that the PFS - * will be performed in rekey. This example can be done by providing - * SILC_SKE_SP_FLAG_PFS as `flags'. The `flags' is a bit mask of - * enforced flags. - * - * After this function the responder calls immediately, or with short - * timeout the silc_ske_responder_phase_1 function. + * This function returns SilcAsyncOperation operation context which can + * be used to control the protocol from the application. Application may + * for example safely abort the protocol at any point, if needed. Returns + * NULL on error. * ***/ -SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng, - SilcSocketConnection sock, - const char *version, - SilcBuffer start_payload, - SilcSKESecurityPropertyFlag flags); +SilcAsyncOperation silc_ske_rekey_responder(SilcSKE ske, + SilcPacketStream stream, + SilcSKERekeyMaterial rekey, + SilcPacket packet); -/****f* silcske/SilcSKEAPI/silc_ske_responder_phase_1 +/****f* silcske/SilcSKEAPI/silc_ske_set_keys * * SYNOPSIS * - * SilcSKEStatus silc_ske_responder_phase_1(SilcSKE ske); + * 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 is called after the silc_ske_responder_start, and - * is used to send our reply to the initiator. This function is - * called either immediately, or with short timeout, after the - * silc_ske_responder_start function returned. - * - * After this function the responder must wait for reply from the - * initiator. + * 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. * ***/ -SilcSKEStatus silc_ske_responder_phase_1(SilcSKE ske); +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_responder_phase_2 +/****f* silcske/SilcSKEAPI/silc_ske_parse_version * * SYNOPSIS * - * SilcSKEStatus silc_ske_responder_phase_2(SilcSKE ske, - * SilcBuffer ke_payload); + * 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 * - * Receives the reply from the initiator and procedses it. The - * `ke_payload' is the reply and application must provide it as argument. - * This function will verify the remote host's public key, by calling - * the `verify_key' callback that was set with silc_ske_set_callbacks - * function. - * - * If this function returns error, no callbacks will be called. If - * this function needs to verify remote end's public key, this will - * return SILC_SKE_STATUS_PENDING, which indicates application that - * SKE is performing asynchronous operation and is in pending status. - * When in this status application must not continue with calling - * any other SKE routine. The asynchronous operation is the `verify_key' - * callback, which application completes by calling its completion - * callback. After completion the SKE libary will call the - * `proto_continue' callback, to indicate application that pending - * status is over and it is safe to continue the execution of SKE, - * which application does by calling the silc_ske_responder_finish - * function. - * - * If this function returns SILC_SKE_STATUS_OK, it will not call the - * `verify_key' callback, however, it will or has already called the - * `proto_continue' callback. - * - * Application must not continue execution of the SKE before library - * has called the `proto_continue' callback. After it is called - * the application calls the silc_ske_responder_finish function. + * Utility function to parse the remote host's version string. This can + * be called after the key exchange has been completed. * ***/ -SilcSKEStatus silc_ske_responder_phase_2(SilcSKE ske, - SilcBuffer ke_payload); +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_responder_finish +/****f* silcske/SilcSKEAPI/silc_ske_get_security_properties * * SYNOPSIS * - * SilcSKEStatus silc_ske_responder_finish(SilcSKE ske, - * SilcPublicKey public_key, - * SilcPrivateKey private_key, - * SilcSKEPKType pk_type); + * SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske); * * DESCRIPTION * - * This function finishes the responder's SKE session, and this function - * is called either immediately, or with short timeout, after the - * silc_ske_responder_phase_2 returned. This will send our reply to - * the initiator. The caller must provide the caller's public key and - * private key as argument, since the public key is sent to the responder, - * and the private key is be used to generate digital signature. - * - * After this function the application must wait for the end indication - * from the intiator, and when it is received the silc_ske_end is called. + * Returns negotiated security properties from the `ske' or NULL if they + * have not yet been negotiated. This may be called to retrieve the + * security properties after the SilcSKECompletionCb has been called. * ***/ -SilcSKEStatus silc_ske_responder_finish(SilcSKE ske, - SilcPublicKey public_key, - SilcPrivateKey private_key, - SilcSKEPKType pk_type); +SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske); -/****f* silcske/SilcSKEAPI/silc_ske_end +/****f* silcske/SilcSKEAPI/silc_ske_get_key_material * * SYNOPSIS * - * SilcSKEStatus silc_ske_end(SilcSKE ske); + * SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske); * * DESCRIPTION * - * The Key Exchange protocol is ended by calling this function. This - * must not be called until the keys are processed by calling the - * silc_ske_process_key_material function. The protocol prohibits - * calling this function before key material is processed properly. - * - * This function is for both initiator and responder. After calling - * this function initiator must wait for end indication from the - * responder. After that the silc_ske_free may be called. The responder - * calls this function after it has received the intiator's end - * indication. - * - * NOTES - * - * Initiator must not start using the negotiated key material before - * calling this function or before remote end has sent its end - * indication. Only after that the key material may be taken in use. + * Returns the negotiated key material from the `ske' or NULL if the + * key material does not exist. The caller must not free the returned + * pointer. * ***/ -SilcSKEStatus silc_ske_end(SilcSKE ske); +SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske); -/****f* silcske/SilcSKEAPI/silc_ske_abort - * - * SYNOPSIS - * - * SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status); - * - * DESCRIPTION - * - * Aborts the Key Exchange protocol. This is called if error occurs - * while performing the protocol. The status argument is the error - * status and it is sent to the remote end. - * - ***/ -SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status); - -/****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties +/****f* silcske/SilcSKEAPI/silc_ske_process_key_material_data * * SYNOPSIS * - * SilcSKEStatus - * silc_ske_assemble_security_properties(SilcSKE ske, - * SilcSKESecurityPropertyFlag flags, - * const char *version, - * SilcSKEStartPayload - * **return_payload); + * const char *silc_ske_map_status(SilcSKEStatus status); * * DESCRIPTION * - * 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. The assembled payload is returned into - * the `return_payload' pointer. + * Utility function to process key data `data' in the way specified + * by the SILC Key Exchange protocol. This returns the processed key + * material or NULL on error. Caller must free the returned key + * material context by calling silc_ske_free_key_material. * ***/ -SilcSKEStatus -silc_ske_assemble_security_properties(SilcSKE ske, - SilcSKESecurityPropertyFlag flags, - const char *version, - SilcSKEStartPayload **return_payload); +SilcSKEKeyMaterial +silc_ske_process_key_material_data(unsigned char *data, + SilcUInt32 data_len, + SilcUInt32 req_iv_len, + SilcUInt32 req_enc_key_len, + SilcUInt32 req_hmac_key_len, + SilcHash hash); -/****f* silcske/SilcSKEAPI/silc_ske_select_security_properties +/****f* silcske/SilcSKEAPI/silc_ske_free_key_material * * SYNOPSIS * - * SilcSKEStatus - * silc_ske_select_security_properties(SilcSKE ske, - * const char *version, - * SilcSKEStartPayload *payload, - * SilcSKEStartPayload *remote_payload); + * void silc_ske_free_key_material(SilcSKEKeyMaterial key) * * DESCRIPTION * - * Parses the Key Exchange Start Payload indicated by `remote_payload', - * and selects the security properties properties from it, and puts the - * selection into the `payload'. This always attempts to select the - * best security properties from the payload, and it always selects - * one of each kind of security property, as this is dictated by the - * protocol. The `version' is our version, that we will put to the - * `payload', since the `payload' is usually sent to the remote end. - * the `check_version' callback will be called in this function so - * that application can do version check with the remote end. + * Utility function to free the key material created by calling + * silc_ske_process_key_material_data. * ***/ -SilcSKEStatus -silc_ske_select_security_properties(SilcSKE ske, - const char *version, - SilcSKEStartPayload *payload, - SilcSKEStartPayload *remote_payload); +void silc_ske_free_key_material(SilcSKEKeyMaterial key); -/****f* silcske/SilcSKEAPI/silc_ske_process_key_material +/****f* silcske/SilcSKEAPI/silc_ske_free_rekey_material * * SYNOPSIS * - * SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, - * SilcUInt32 req_iv_len, - * SilcUInt32 req_enc_key_len, - * SilcUInt32 req_hmac_key_len, - * SilcSKEKeyMaterial *key); + * void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey); * * DESCRIPTION * - * This function is used by the application to process the key material - * negotiated with the SKE session, to actually produce the keys that - * is to be used in SILC protocol. The key processing is defined by the - * protocol. The `req_iv_len', `req_enc_key_len' and `req_hmac_key_len' - * are the request IV length, requested encryption/decrypt key length, - * and requested HMAC key length, respectively, and they cannot be - * zero (0). They tell the function how long the keys should be, and - * it will produce the requested length keys for the application. - * The key material is returned in to the `key', which the caller must - * free. + * Utility function to free the rekey material returned in the + * SilcSKECompletionCb callback. * ***/ -SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, - SilcUInt32 req_iv_len, - SilcUInt32 req_enc_key_len, - SilcUInt32 req_hmac_key_len, - SilcSKEKeyMaterial *key); +void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey); -/****f* silcske/SilcSKEAPI/silc_ske_process_key_material_data +/****f* silcske/SilcSKEAPI/silc_ske_map_status * * SYNOPSIS * - * SilcSKEStatus - * silc_ske_process_key_material_data(unsigned char *data, - * SilcUInt32 data_len, - * SilcUInt32 req_iv_len, - * SilcUInt32 req_enc_key_len, - * SilcUInt32 req_hmac_key_len, - * SilcHash hash, - * SilcSKEKeyMaterial *key); + * const char *silc_ske_map_status(SilcSKEStatus status); * * DESCRIPTION * - * This function is equivalent to silc_ske_process_key_material, except - * that the caller provides the raw key material as argument, the `data' - * and `data_len'. This is special utility function provided for the - * application, if it needs to generate key material as the protocol - * defines for some other purpose than strictly SILC session key usage. - * Hence, this function can be used outside SKE protocol to just produce - * key material from some raw data. The `hash' is a hash algorithm that - * is used as part of key processing, and caller must provide it. + * Utility function to map the `status' into human readable message. * ***/ -SilcSKEStatus -silc_ske_process_key_material_data(unsigned char *data, - SilcUInt32 data_len, - SilcUInt32 req_iv_len, - SilcUInt32 req_enc_key_len, - SilcUInt32 req_hmac_key_len, - SilcHash hash, - SilcSKEKeyMaterial *key); +const char *silc_ske_map_status(SilcSKEStatus status); -/****f* silcske/SilcSKEAPI/silc_ske_free_key_material - * - * SYNOPSIS - * - * void silc_ske_free_key_material(SilcSKEKeyMaterial *key); - * - * DESCRIPTION - * - * Frees the key material indicated by `key', and all data in it. - * - ***/ -void silc_ske_free_key_material(SilcSKEKeyMaterial *key); +#include "silcske_i.h" #endif /* !SILCSKE_H */