5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2005 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 /****h* silcske/SILC SKE Interface
24 * The SILC Key Exchange (SKE) protocol interface. The SKE protocol
25 * is used to negotiate secret key material between two parties, to be used
26 * as session key or some other key. For example, when client connects to
27 * server SKE is performed to exchange public keys, and to generate the key
28 * that is then used as session key. Two clients can execute SKE as well
29 * two create secret key material for securing for example file transfer
30 * stream. This SKE implementation provides easy interface for application
31 * that wants to use SKE.
38 /* Forward declarations */
39 typedef struct SilcSKECallbacksStruct *SilcSKECallbacks;
40 typedef struct SilcSKEStruct *SilcSKE;
42 /****d* silcske/SilcSKEAPI/SilcSKEStatus
46 * typedef enum { ... } SilcSKEStatus;
50 * Status types returned in SKE callbacks. This tell the status of
51 * the SKE session, and if an error occurred. Application can map the
52 * status to human readable string with silc_ske_map_status function.
57 /* These are defined by the protocol */
58 SILC_SKE_STATUS_OK = 0, /* No error */
59 SILC_SKE_STATUS_ERROR = 1, /* Unknown error */
60 SILC_SKE_STATUS_BAD_PAYLOAD = 2, /* Malformed payload */
61 SILC_SKE_STATUS_UNKNOWN_GROUP = 3, /* Unsupported DH group */
62 SILC_SKE_STATUS_UNKNOWN_CIPHER = 4, /* Unsupported cipher */
63 SILC_SKE_STATUS_UNKNOWN_PKCS = 5, /* Unsupported PKCS algorithm */
64 SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION = 6, /* Unsupported hash function */
65 SILC_SKE_STATUS_UNKNOWN_HMAC = 7, /* Unsupported HMAC */
66 SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY = 8, /* Unsupported/not trusted PK */
67 SILC_SKE_STATUS_INCORRECT_SIGNATURE = 9, /* Incorrect signature */
68 SILC_SKE_STATUS_BAD_VERSION = 10, /* Unsupported version */
69 SILC_SKE_STATUS_INVALID_COOKIE = 11, /* Cookie was modified */
71 /* Implementation specific status types */
72 SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED, /* Remote did not send PK */
73 SILC_SKE_STATUS_BAD_RESERVED_FIELD, /* Reserved field was not 0 */
74 SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH, /* Payload includes garbage */
75 SILC_SKE_STATUS_SIGNATURE_ERROR, /* Error computing signature */
76 SILC_SKE_STATUS_OUT_OF_MEMORY, /* System out of memory */
80 #include "silcske_groups.h"
81 #include "silcske_payload.h"
83 /****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag
87 * typedef enum { ... } SilcSKESecurityPropertyFlag
91 * SKE security property flags as defined by the SK protocol.
96 SILC_SKE_SP_FLAG_NONE = 0x00, /* No flags */
97 SILC_SKE_SP_FLAG_IV_INCLUDED = 0x01, /* IV included in packet */
98 SILC_SKE_SP_FLAG_PFS = 0x02, /* Perfect Forward Secrecy */
99 SILC_SKE_SP_FLAG_MUTUAL = 0x04, /* Mutual authentication */
100 } SilcSKESecurityPropertyFlag;
103 /****s* silcske/SilcSKEAPI/SilcSKESecurityProperties
107 * typedef struct { ... } *SilcSKESecurityProperties;
111 * Security Properties negotiated between key exchange parties. This
112 * structure is filled from the Key Exchange Start Payload which is used
113 * to negotiate what security properties must be used in the
119 SilcSKESecurityPropertyFlag flags; /* Flags */
120 SilcSKEDiffieHellmanGroup group; /* Selected Diffie Hellman group */
121 SilcCipher cipher; /* Selected cipher */
122 SilcHmac hmac; /* Selected HMAC */
123 SilcHash hash; /* Selected hash algorithm */
124 SilcPKCS pkcs; /* Selected PKCS and remote's
125 public key/certificate */
126 } *SilcSKESecurityProperties;
129 /****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial
133 * typedef struct { ... } *SilcSKEKeyMaterial;
137 * This is the key material structure, and is passed as argument by the
138 * application to silc_ske_process_key_material* functions. It includes
139 * the processed key material which can be used as SILC session keys.
144 unsigned char *send_iv;
145 unsigned char *receive_iv;
147 unsigned char *send_enc_key;
148 unsigned char *receive_enc_key;
149 SilcUInt32 enc_key_len;
150 unsigned char *send_hmac_key;
151 unsigned char *receive_hmac_key;
152 SilcUInt32 hmac_key_len;
153 } *SilcSKEKeyMaterial;
156 /****s* silcske/SilcSKEAPI/SilcSKERekeyMaterial
160 * typedef struct { ... } *SilcSKERekeyMaterial;
164 * This context is returned after key exchange protocol to application
165 * in the completion callback. Application may save it and use it later
166 * to perform the rekey with silc_ske_rekey_initiator_start and/or
167 * silc_ske_rekey_responder_start functions. If application does not
168 * need the context, it may free it with silc_free function.
170 * Application may save application specific data to `user_context'.
175 void *user_context; /* Application specific data */
176 unsigned char *send_enc_key;
177 unsigned int enc_key_len : 23;
178 unsigned int ske_group : 8;
179 unsigned int pfs : 1;
180 } *SilcSKERekeyMaterial;
183 /****d* silcske/SilcSKEAPI/SilcSKEPKType
187 * typedef enum { ... } SilcSKEPKType;
191 * Public key and certificate types defined by the SKE protocol.
196 SILC_SKE_PK_TYPE_SILC = 1, /* SILC Public Key, mandatory */
197 SILC_SKE_PK_TYPE_SSH2 = 2, /* SSH2 Public key, not supported */
198 SILC_SKE_PK_TYPE_X509V3 = 3, /* X.509v3 certificate, not supported */
199 SILC_SKE_PK_TYPE_OPENPGP = 4, /* OpenPGP certificate, not supported */
200 SILC_SKE_PK_TYPE_SPKI = 5 /* SPKI certificate, not supported */
204 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCbCompletion
208 * typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
209 * SilcSKEStatus status,
214 * Completion callback that will be called when the public key
215 * has been verified. The `status' will indicate whether the public
216 * key were trusted or not. If the `status' is PENDING then the status
217 * is not considered to be available at this moment. In this case the
218 * SKE libary will assume that the caller will call this callback again
219 * when the status is available. See silc_ske_set_callbacks for more
223 typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
224 SilcSKEStatus status,
227 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCb
231 * typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
232 * const unsigned char *pk_data,
234 * SilcSKEPKType pk_type,
236 * SilcSKEVerifyCbCompletion completion,
237 * void *completion_context);
241 * Callback function used to verify the received public key or certificate.
242 * The verification process is most likely asynchronous. That's why the
243 * application must call the `completion' callback when the verification
244 * process has been completed. The `context' is the context given as
245 * arugment to silc_ske_set_callbacks. See silc_ske_set_callbacks for
249 typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
250 const unsigned char *pk_data,
252 SilcSKEPKType pk_type,
254 SilcSKEVerifyCbCompletion completion,
255 void *completion_context);
257 /****f* silcske/SilcSKEAPI/SilcSKECompletionCb
261 * typedef void (*SilcSKECompletionCb)(SilcSKE ske,
262 * SilcSKEStatus status,
263 * SilcSKESecurityProperties prop,
264 * SilcSKEKeyMaterial keymat,
265 * SilcSKERekeyMaterial rekey,
270 * Completion callback. This is called after the key exchange protocol
271 * has been completed. It delivers the status of the protocol, and if
272 * successful the security properties `prop' that was negotiated in the
273 * protocol and the key material `keymat' that can be set into use by
274 * calling silc_ske_set_keys, and the rekey key material `rekey' which
275 * can be used later to start rekey protocol. The `prop' will remain
276 * valid as long as `ske' is valid. After `ske' is freed `prop' will
280 typedef void (*SilcSKECompletionCb)(SilcSKE ske,
281 SilcSKEStatus status,
282 SilcSKESecurityProperties prop,
283 SilcSKEKeyMaterial keymat,
284 SilcSKERekeyMaterial rekey,
289 /****f* silcske/SilcSKEAPI/silc_ske_alloc
293 * SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
294 * SilcPublicKey public_key,
295 * SilcPrivateKey private_key, void *context);
299 * Allocates the SKE session context and returns it. The `rng' is
300 * the random number generator the SKE is going to use when it needs
301 * random number generation during the SKE session. The `context' is
302 * user context that the libary will not touch. Application can get the
303 * context by calling the fuction silc_ske_get_context function. The
304 * application is responsible of freeing the `context'. After the
305 * SKE session context is allocated application must call the
306 * silc_ske_set_callbacks.
310 * // Initiator example
311 * ske = silc_ske_alloc(rng, scheduler, app);
312 * silc_ske_set_callbacks(ske, verify_public_key, completion, app);
314 * silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_PFS |
315 * SILC_SKE_SP_FLAG_MUTUAL,
317 * silc_ske_initiator_start(ske);
320 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
321 SilcPublicKey public_key, SilcPrivateKey private_key,
324 /****f* silcske/SilcSKEAPI/silc_ske_free
328 * void silc_ske_free(SilcSKE ske);
332 * Frees the SKE session context and all allocated resources.
335 void silc_ske_free(SilcSKE ske);
337 /****f* silcske/SilcSKEAPI/silc_ske_get_context
341 * void *silc_ske_get_context(SilcSKE ske);
345 * Returns the context that was given as argument to silc_ske_alloc.
348 void *silc_ske_get_context(SilcSKE ske);
350 /****f* silcske/SilcSKEAPI/silc_ske_set_callbacks
354 * void silc_ske_set_callbacks(SilcSKE ske,
355 * SilcSKEVerifyCb verify_key,
356 * SilcSKECompletion completed,
361 * Sets the callback functions for the SKE session.
363 * The `verify_key' callback is called to verify the received public key
364 * or certificate. The verification process is most likely asynchronous.
365 * That is why the application must call the completion callback when the
366 * verification process has been completed. If this SKE session context
367 * is used to perform rekey, this callback usually is not provided as
368 * argument since sending public key in rekey is not mandatory. Setting
369 * this callback implies that remote end MUST send its public key.
371 * The `completed' callback will be called once the protocol has completed,
372 * either successfully or with an error. The status of the protocol is
373 * delivered to application with the callback.
375 * The `context' is passed as argument to all of the above callback
379 void silc_ske_set_callbacks(SilcSKE ske,
380 SilcSKEVerifyCb verify_key,
381 SilcSKECompletionCb completed,
384 /****f* silcske/SilcSKEAPI/silc_ske_initiator_start
389 * silc_ske_initiator_start(SilcSKE ske,
390 * SilcPacketStream stream,
391 * SilcSKEStartPayload start_payload);
395 * Starts the SILC Key Exchange protocol as initiator. The completion
396 * callback that was set in silc_ske_set_callbacks will be called once
397 * the protocol has completed.
399 * The `stream' is the network connection to the remote host. Note that
400 * SKE library will take over the packet stream `stream' while the
401 * protocol is in process. The application will not receive any packets
402 * for `stream' after this function is called. The `stream' is turned
403 * over to application once the completion callback is called.
405 * The `start_payload' includes all configured security properties that
406 * will be sent to the responder. The `start_payload' must be provided.
407 * It can be created by calling silc_ske_assemble_security_properties
408 * function. The caller must not free the payload once it has been
409 * given as argument to this function.
411 * This function returns SilcAsyncOperation operation context which can
412 * be used to control the protocol from the application. Application may
413 * for example safely abort the protocol at any point, if needed. Returns
418 silc_ske_initiator(SilcSKE ske,
419 SilcPacketStream stream,
420 SilcSKEStartPayload start_payload);
422 /****f* silcske/SilcSKEAPI/silc_ske_responder_start
427 * silc_ske_responder_start(SilcSKE ske,
428 * SilcPacketStream stream,
429 * const char *version,
430 * SilcBuffer start_payload,
431 * SilcSKESecurityPropertyFlag flags);
435 * Starts SILC Key Exchange protocol as responder. The completion
436 * callback that was set in silc_ske_set_callbacks will be called once
437 * the protocol has completed.
439 * The `stream' is the network connection to the remote host. Note that
440 * SKE library will take over the packet stream `stream' while the
441 * protocol is in process. The application will not receive any packets
442 * for `stream' after this function is called. The `stream' is turned
443 * over to application once the completion callback is called.
445 * The `version' is the responder's SILC protocol version that will be
446 * sent in reply to the initiator. The `flags' indicates the
447 * SilcSKESecurityPropertyFlag flags that responder supports and enforces
448 * for the initiator. Responder may, for example, enforce that the PFS
449 * will be performed in rekey.
451 * This function returns SilcAsyncOperation operation context which can
452 * be used to control the protocol from the application. Application may
453 * for example safely abort the protocol at any point, if needed. Returns
458 silc_ske_responder(SilcSKE ske,
459 SilcPacketStream stream,
461 SilcSKESecurityPropertyFlag flags);
464 silc_ske_rekey_initiator(SilcSKE ske,
465 SilcPacketStream stream,
466 SilcSKERekeyMaterial rekey);
469 silc_ske_rekey_responder(SilcSKE ske,
470 SilcPacketStream stream,
471 SilcBuffer ke_payload,
472 SilcSKERekeyMaterial rekey);
474 /****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties
478 * SilcSKEStartPayload
479 * silc_ske_assemble_security_properties(SilcSKE ske,
480 * SilcSKESecurityPropertyFlag flags,
481 * const char *version);
485 * Assembles security properties to Key Exchange Start Payload to be
486 * sent to the remote end. This checks system wide (SILC system, that is)
487 * settings and chooses from those. However, if other properties
488 * should be used this function is easy to replace by another function.
489 * Returns NULL on error. This is an utility function. This is used
490 * by the initiator of the protocol. The `version' is the local SILC
491 * protocol version string.
495 silc_ske_assemble_security_properties(SilcSKE ske,
496 SilcSKESecurityPropertyFlag flags,
497 const char *version);
499 /****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties
503 * SilcBool silc_ske_set_keys(SilcSKE ske,
504 * SilcSKEKeyMaterial keymat,
505 * SilcSKESecurityProperties prop,
506 * SilcCipher *ret_send_key,
507 * SilcCipher *ret_receive_key,
508 * SilcHmac *ret_hmac_send,
509 * SilcHmac *ret_hmac_receive,
510 * SilcHash *ret_hash);
514 * This function can be used after successful key exchange to take the
515 * key material `keymat' with security properties `prop' into use.
516 * This will allocate send and receive ciphers, HMACs and hash for the
517 * application. Caller must free the returned contexts. This is an
521 SilcBool silc_ske_set_keys(SilcSKE ske,
522 SilcSKEKeyMaterial keymat,
523 SilcSKESecurityProperties prop,
524 SilcCipher *ret_send_key,
525 SilcCipher *ret_receive_key,
526 SilcHmac *ret_hmac_send,
527 SilcHmac *ret_hmac_receive,
530 /****f* silcske/SilcSKEAPI/silc_ske_parse_version
534 * SilcBool silc_ske_parse_version(SilcSKE ske,
535 * SilcUInt32 *protocol_version,
536 * char **protocol_version_string,
537 * SilcUInt32 *software_version,
538 * char **software_version_string,
539 * char **vendor_version);
543 * Utility function to parse the remote host's version string.
546 SilcBool silc_ske_parse_version(SilcSKE ske,
547 SilcUInt32 *protocol_version,
548 char **protocol_version_string,
549 SilcUInt32 *software_version,
550 char **software_version_string,
551 char **vendor_version);
553 /****f* silcske/SilcSKEAPI/silc_ske_map_status
557 * const char *silc_ske_map_status(SilcSKEStatus status);
561 * Utility function to map the `status' into human readable message.
564 const char *silc_ske_map_status(SilcSKEStatus status);
566 #include "silcske_i.h"
568 #endif /* !SILCSKE_H */