5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2000 - 2014 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 */
77 SILC_SKE_STATUS_TIMEOUT, /* Timeout */
78 SILC_SKE_STATUS_PROBE_TIMEOUT, /* Probe timeout */
82 #include "silcske_groups.h"
83 #include "silcske_payload.h"
85 /****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag
89 * typedef enum { ... } SilcSKESecurityPropertyFlag
93 * SKE security property flags as defined by the SK protocol.
98 SILC_SKE_SP_FLAG_NONE = 0x00, /* No flags */
99 SILC_SKE_SP_FLAG_IV_INCLUDED = 0x01, /* IV included in packet */
100 SILC_SKE_SP_FLAG_PFS = 0x02, /* Perfect Forward Secrecy */
101 SILC_SKE_SP_FLAG_MUTUAL = 0x04, /* Mutual authentication */
102 } SilcSKESecurityPropertyFlag;
105 /****s* silcske/SilcSKEAPI/SilcSKESecurityProperties
109 * typedef struct { ... } *SilcSKESecurityProperties;
113 * Security Properties negotiated between key exchange parties. This
114 * structure is filled from the Key Exchange Start Payload which is used
115 * to negotiate what security properties must be used in the
120 typedef struct SilcSKESecurityPropertiesStruct {
121 SilcSKESecurityPropertyFlag flags; /* Flags */
122 SilcSKEDiffieHellmanGroup group; /* Selected Diffie Hellman group */
123 SilcCipher cipher; /* Selected cipher */
124 SilcHmac hmac; /* Selected HMAC */
125 SilcHash hash; /* Selected hash algorithm */
126 SilcPublicKey public_key; /* Remote public key */
127 SilcUInt16 remote_port; /* Remote port, set when IV Included
128 set and using UDP/IP */
129 } *SilcSKESecurityProperties;
132 /****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial
136 * typedef struct { ... } *SilcSKEKeyMaterial;
140 * This is the key material structure, and is passed as argument by the
141 * application to silc_ske_process_key_material_data function. It includes
142 * the processed key material which can be used as SILC session keys.
146 typedef struct SilcSKEKeyMaterialStruct {
147 unsigned char *send_iv;
148 unsigned char *receive_iv;
150 unsigned char *send_enc_key;
151 unsigned char *receive_enc_key;
152 SilcUInt32 enc_key_len; /* Key length in bits */
153 unsigned char *send_hmac_key;
154 unsigned char *receive_hmac_key;
155 SilcUInt32 hmac_key_len; /* Key length in bytes */
156 } *SilcSKEKeyMaterial;
159 /****s* silcske/SilcSKEAPI/SilcSKERekeyMaterial
163 * typedef struct { ... } *SilcSKERekeyMaterial;
167 * This context is returned after key exchange protocol to application
168 * in the completion callback. Application may save it and use it later
169 * to perform the rekey with silc_ske_rekey_initiator and/or
170 * silc_ske_rekey_responder functions. If application does not
171 * need the context, it may free it with silc_ske_free_rekey_material
175 typedef struct SilcSKERekeyMaterialStruct {
176 unsigned char *send_enc_key;
178 unsigned int enc_key_len : 23;
179 unsigned int ske_group : 8;
180 unsigned int pfs : 1;
181 } *SilcSKERekeyMaterial;
183 /****s* silcske/SilcSKEAPI/SilcSKEParams
187 * typedef struct { ... } *SilcSKEParams, SilcSKEParamsStruct;
191 * SKE parameters structure. This structure is given as argument to
192 * silc_ske_initiator and silc_ske_responder functions.
196 typedef struct SilcSKEParamsObject {
197 /* The SKE version string that is sent to the remote end. This field
198 must be set. Caller must free the pointer. */
201 /* Security property flags. When initiator sets these it requests them
202 from the responder. Responder may set here the flags it supports
203 and wants to enforce for the initiator. */
204 SilcSKESecurityPropertyFlag flags;
206 /* SILC Session port when using UDP/IP and SILC_SKE_SP_FLAG_IV_INCLUDED
207 flag. It is the port the remote will use as SILC session port after
208 the key exchange protocol. Ignored without SILC_SKE_SP_FLAG_IV_INCLUDED
210 SilcUInt16 session_port;
212 /* Key exchange timeout in seconds. If key exchange is not completed in
213 this time it will timeout. If not specified (zero), default value
214 (30 seconds) will be used. */
215 SilcUInt16 timeout_secs;
217 /* Same as timeout_secs but affects only the first packet sent as
218 initiator. If the responder does not reply to the first packet in this
219 time frame the key exchange will timeout. If not specified (zero),
220 default value (30 seconds) will be used. */
221 SilcUInt16 probe_timeout_secs;
223 /* If TRUE small proposal is sent with only one security property
224 proposed instead of list of all currently registered. */
225 SilcBool small_proposal;
227 /* If TRUE protocol does not end in SUCCESS acknowledgements. */
230 /* Pre-allocated security properties to use in negotiation. If provided
231 the library will perform only key exchange and proposals aren't
233 SilcSKESecurityProperties prop;
234 } *SilcSKEParams, SilcSKEParamsStruct;
237 /****d* silcske/SilcSKEAPI/SilcSKEPKType
241 * typedef enum { ... } SilcSKEPKType;
245 * Public key and certificate types defined by the SKE protocol.
250 SILC_SKE_PK_TYPE_SILC = 1, /* SILC Public Key, mandatory */
251 SILC_SKE_PK_TYPE_SSH2 = 2, /* SSH2 Public key, not supported */
252 SILC_SKE_PK_TYPE_X509V3 = 3, /* X.509v3 certificate, not supported */
253 SILC_SKE_PK_TYPE_OPENPGP = 4, /* OpenPGP certificate, not supported */
254 SILC_SKE_PK_TYPE_SPKI = 5 /* SPKI certificate, not supported */
258 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCbCompletion
262 * typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
263 * SilcSKEStatus status,
268 * Completion callback that will be called when the public key
269 * has been verified. The `status' will indicate whether the public
270 * key were trusted or not.
273 typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
274 SilcSKEStatus status,
277 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCb
281 * typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
282 * SilcPublicKey public_key,
284 * SilcSKEVerifyCbCompletion completion,
285 * void *completion_context);
289 * Callback function used to verify the received public key or certificate.
290 * The verification process is most likely asynchronous. That's why the
291 * application must call the `completion' callback when the verification
292 * process has been completed. The `context' is the context given as
293 * arugment to silc_ske_set_callbacks. See silc_ske_set_callbacks for
296 * If the key repository was provided in silc_ske_alloc this callback
297 * is called only if the public key was not found from the repository.
300 typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
301 SilcPublicKey public_key,
303 SilcSKEVerifyCbCompletion completion,
304 void *completion_context);
306 /****f* silcske/SilcSKEAPI/SilcSKECompletionCb
310 * typedef void (*SilcSKECompletionCb)(SilcSKE ske,
311 * SilcSKEStatus status,
312 * const SilcSKESecurityProperties prop,
313 * const SilcSKEKeyMaterial keymat,
314 * SilcSKERekeyMaterial rekey,
319 * Completion callback. This is called after the key exchange protocol
320 * has been completed. It delivers the status of the protocol, and if
321 * successful the security properties `prop' that was negotiated in the
322 * protocol and the key material `keymat' that can be set into use by
323 * calling silc_ske_set_keys, and the rekey key material `rekey' which
324 * can be used later to start rekey protocol. The `prop' and `keymat'
325 * will remain valid as long as `ske' is valid. The `rekey' will remain
326 * valid until silc_ske_free_rekey_material is called. The application
327 * must call it to free the `rekey'.
329 * When doing rekey, this completion callback delivers the `keymat' and
330 * new `rekey'. The `prop' is ignored. The `keymat' has already been set
331 * to the packet stream associated with the `ske'. Thus, after this
332 * is called the new keys are in use.
335 typedef void (*SilcSKECompletionCb)(SilcSKE ske,
336 SilcSKEStatus status,
337 const SilcSKESecurityProperties prop,
338 const SilcSKEKeyMaterial keymat,
339 SilcSKERekeyMaterial rekey,
344 /****f* silcske/SilcSKEAPI/silc_ske_alloc
348 * SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
349 * SilcSKR repository, SilcPublicKey public_key,
350 * SilcPrivateKey private_key, void *context);
354 * Allocates the SKE session context and returns it. The `rng' is
355 * the random number generator the SKE is going to use when it needs
356 * random number generation during the SKE session. The `context' is
357 * user context that the libary will not touch. Application can get the
358 * context by calling the fuction silc_ske_get_context function. The
359 * application is responsible of freeing the `context'. After the
360 * SKE session context is allocated application must call the
361 * silc_ske_set_callbacks.
363 * If the `repository' is non-NULL then the remote's public key will be
364 * verified from the repository. If it is not provided then the
365 * SilcSKEVerifyCb callback must be set, and it will be called to
366 * verify the key. If both `repository' and the callback is provided the
367 * callback is called only if the key is not found from the repository.
369 * The `public_key' and `private_key' is the caller's identity used
370 * during the key exchange. Giving `private_key' is optional if the
371 * SILC_SKE_SP_FLAG_MUTUAL is not set and you are initiator. For
372 * responder both `public_key' and `private_key' must be set.
374 * When allocating SKE session for rekey, the `repository' and `private_key'
375 * pointers must be NULL and the SilcSKEVerifyCb callback must not be
376 * set with silc_ske_set_callbacks.
380 * // Initiator example
381 * params.version = version;
382 * params.flags = SILC_SKE_SP_FLAG_PFS | SILC_SKE_SP_FLAG_MUTUAL;
383 * ske = silc_ske_alloc(rng, scheduler, NULL, pk, prv, app);
384 * silc_ske_set_callbacks(ske, verify_public_key, completion, app);
385 * silc_ske_initiator(ske, stream, ¶ms, NULL);
388 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
389 SilcSKR repository, SilcPublicKey public_key,
390 SilcPrivateKey private_key, void *context);
392 /****f* silcske/SilcSKEAPI/silc_ske_free
396 * void silc_ske_free(SilcSKE ske);
400 * Frees the SKE session context and all allocated resources.
403 void silc_ske_free(SilcSKE ske);
405 /****f* silcske/SilcSKEAPI/silc_ske_get_context
409 * void *silc_ske_get_context(SilcSKE ske);
413 * Returns the context that was given as argument to silc_ske_alloc.
416 void *silc_ske_get_context(SilcSKE ske);
418 /****f* silcske/SilcSKEAPI/silc_ske_set_callbacks
422 * void silc_ske_set_callbacks(SilcSKE ske,
423 * SilcSKEVerifyCb verify_key,
424 * SilcSKECompletion completed,
429 * Sets the callback functions for the SKE session.
431 * The `verify_key' callback is called to verify the received public key
432 * or certificate. The verification process is most likely asynchronous.
433 * That is why the application must call the completion callback when the
434 * verification process has been completed. If this SKE session context
435 * is used to perform rekey, this callback usually is not provided as
436 * argument since sending public key in rekey is not mandatory. Setting
437 * this callback implies that remote end MUST send its public key.
439 * The `completed' callback will be called once the protocol has completed,
440 * either successfully or with an error. The status of the protocol is
441 * delivered to application with the callback.
443 * The `context' is passed as argument to all of the above callback
447 void silc_ske_set_callbacks(SilcSKE ske,
448 SilcSKEVerifyCb verify_key,
449 SilcSKECompletionCb completed,
452 /****f* silcske/SilcSKEAPI/silc_ske_initiator
457 * silc_ske_initiator(SilcSKE ske,
458 * SilcPacketStream stream,
459 * SilcSKEParams params,
460 * SilcSKEStartPayload start_payload);
464 * Starts the SILC Key Exchange protocol as initiator. The completion
465 * callback that was set in silc_ske_set_callbacks will be called once
466 * the protocol has completed. The `stream' is the network connection
467 * to the remote host. The SKE library will handle all key exchange
468 * packets sent and received in the `stream' connection. The library will
469 * also set the remote host's ID automatically to the `stream' if it is
470 * present in the exchanged packets. The `params' include SKE parameters,
471 * and it must be provided.
473 * If the `start_payload' is NULL the library will generate it
474 * automatically. Caller may provide it if it wants to send its own
475 * security properties instead of using the default ones library
476 * generates. If caller provides it, it must not free it once it has
477 * been given as argument to this function.
479 * This function returns SilcAsyncOperation operation context which can
480 * be used to control the protocol from the application. Application may
481 * for example safely abort the protocol at any point, if needed. Returns
485 SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
486 SilcPacketStream stream,
487 SilcSKEParams params,
488 SilcSKEStartPayload start_payload);
490 /****f* silcske/SilcSKEAPI/silc_ske_responder
495 * silc_ske_responder(SilcSKE ske,
496 * SilcPacketStream stream,
497 * SilcSKEParams params);
501 * Starts SILC Key Exchange protocol as responder. The completion
502 * callback that was set in silc_ske_set_callbacks will be called once
503 * the protocol has completed. The `stream' is the network connection
504 * to the remote host. The SKE library will handle all key exchange
505 * packets sent and received in the `stream' connection. The library will
506 * also set the remote hosts's ID automatically to the `stream' if it is
507 * present in the exchanged packets. The `params' include SKE parameters,
508 * and must be provided.
510 * This function returns SilcAsyncOperation operation context which can
511 * be used to control the protocol from the application. Application may
512 * for example safely abort the protocol at any point, if needed. Returns
516 SilcAsyncOperation silc_ske_responder(SilcSKE ske,
517 SilcPacketStream stream,
518 SilcSKEParams params);
520 /****f* silcske/SilcSKEAPI/silc_ske_rekey_initiator
525 * silc_ske_rekey_initiator(SilcSKE ske,
526 * SilcPacketStream stream,
527 * SilcSKERekeyMaterial rekey);
531 * Starts SILC Key Exchange key regeneration (rekey) protocol. The `rekey'
532 * is the rekey material received earlier in SilcSKECompletionCb. That
533 * same callback is called after the rekey protocol is over to deliver new
534 * key material and new rekey material. When the rekey is completed the
535 * SKE library will automatically update the new keys into `stream'. The
536 * completion callback is called after the new keys has been taken into
539 * This function returns SilcAsyncOperation operation context which can
540 * be used to control the protocol from the application. Application may
541 * for example safely abort the protocol at any point, if needed. Returns
545 SilcAsyncOperation silc_ske_rekey_initiator(SilcSKE ske,
546 SilcPacketStream stream,
547 SilcSKERekeyMaterial rekey);
549 /****f* silcske/SilcSKEAPI/silc_ske_rekey_responder
554 * silc_ske_rekey_responder(SilcSKE ske,
555 * SilcPacketStream stream,
556 * SilcSKERekeyMaterial rekey,
557 * SilcPacket packet);
561 * Starts SILC Key Exchange key regeneration (rekey) protocol as responder.
562 * The `rekey' is the rekey material received earlier in
563 * SilcSKECompletionCb. That same callback is called after the rekey
564 * protocol is over to deliver new key material and new rekey material.
565 * When the rekey is completed the SKE library will automatically update
566 * the new keys into `stream'. The completion callback is called after
567 * the new keys has been taken into use.
569 * The `packet' is the SILC_PACKET_REKEY received to start the rekey
570 * protocol. If `packet' is NULL it is assumed that the packet will be
571 * received from the `stream'.
573 * This function returns SilcAsyncOperation operation context which can
574 * be used to control the protocol from the application. Application may
575 * for example safely abort the protocol at any point, if needed. Returns
579 SilcAsyncOperation silc_ske_rekey_responder(SilcSKE ske,
580 SilcPacketStream stream,
581 SilcSKERekeyMaterial rekey,
584 /****f* silcske/SilcSKEAPI/silc_ske_set_keys
588 * SilcBool silc_ske_set_keys(SilcSKE ske,
589 * SilcSKEKeyMaterial keymat,
590 * SilcSKESecurityProperties prop,
591 * SilcCipher *ret_send_key,
592 * SilcCipher *ret_receive_key,
593 * SilcHmac *ret_hmac_send,
594 * SilcHmac *ret_hmac_receive,
595 * SilcHash *ret_hash);
599 * This function can be used after successful key exchange to take the
600 * key material `keymat' with security properties `prop' into use.
601 * This will allocate send and receive ciphers, HMACs and hash for the
602 * application. Caller must free the returned contexts. This is an
606 SilcBool silc_ske_set_keys(SilcSKE ske,
607 SilcSKEKeyMaterial keymat,
608 SilcSKESecurityProperties prop,
609 SilcCipher *ret_send_key,
610 SilcCipher *ret_receive_key,
611 SilcHmac *ret_hmac_send,
612 SilcHmac *ret_hmac_receive,
615 /****f* silcske/SilcSKEAPI/silc_ske_parse_version
619 * SilcBool silc_ske_parse_version(SilcSKE ske,
620 * SilcUInt32 *protocol_version,
621 * char **protocol_version_string,
622 * SilcUInt32 *software_version,
623 * char **software_version_string,
624 * char **vendor_version);
628 * Utility function to parse the remote host's version string. This can
629 * be called after the key exchange has been completed.
632 SilcBool silc_ske_parse_version(SilcSKE ske,
633 SilcUInt32 *protocol_version,
634 char **protocol_version_string,
635 SilcUInt32 *software_version,
636 char **software_version_string,
637 char **vendor_version);
639 /****f* silcske/SilcSKEAPI/silc_ske_get_security_properties
643 * SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske);
647 * Returns negotiated security properties from the `ske' or NULL if they
648 * have not yet been negotiated. This may be called to retrieve the
649 * security properties after the SilcSKECompletionCb has been called.
652 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske);
654 /****f* silcske/SilcSKEAPI/silc_ske_get_key_material
658 * SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske);
662 * Returns the negotiated key material from the `ske' or NULL if the
663 * key material does not exist. The caller must not free the returned
667 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske);
669 /****f* silcske/SilcSKEAPI/silc_ske_process_key_material_data
673 * const char *silc_ske_map_status(SilcSKEStatus status);
677 * Utility function to process key data `data' in the way specified
678 * by the SILC Key Exchange protocol. This returns the processed key
679 * material or NULL on error. Caller must free the returned key
680 * material context by calling silc_ske_free_key_material.
684 silc_ske_process_key_material_data(unsigned char *data,
686 SilcUInt32 req_iv_len,
687 SilcUInt32 req_enc_key_len,
688 SilcUInt32 req_hmac_key_len,
691 /****f* silcske/SilcSKEAPI/silc_ske_free_key_material
695 * void silc_ske_free_key_material(SilcSKEKeyMaterial key)
699 * Utility function to free the key material created by calling
700 * silc_ske_process_key_material_data.
703 void silc_ske_free_key_material(SilcSKEKeyMaterial key);
705 /****f* silcske/SilcSKEAPI/silc_ske_free_rekey_material
709 * void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey);
713 * Utility function to free the rekey material returned in the
714 * SilcSKECompletionCb callback.
717 void silc_ske_free_rekey_material(SilcSKERekeyMaterial rekey);
719 /****f* silcske/SilcSKEAPI/silc_ske_map_status
723 * const char *silc_ske_map_status(SilcSKEStatus status);
727 * Utility function to map the `status' into human readable message.
730 const char *silc_ske_map_status(SilcSKEStatus status);
732 #include "silcske_i.h"
734 #endif /* !SILCSKE_H */