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.
23 /****h* silcske/SILC SKE Interface
27 * The SILC Key Exchange (SKE) protocol interface. The SKE protocol
28 * is used to negotiate secret key material between two parties, to be used
29 * as session key or some other key. For example, when client connects to
30 * server SKE is performed to exchange public keys, and to generate the key
31 * that is then used as session key. Two clients can execute SKE as well
32 * two create secret key material for securing for example file transfer
35 * This SKE implementation provides easy interface for application
36 * that wants to use SKE. In fact, the interface is designed to be
37 * application independent, and does not expect that the application using
38 * SKE would actually relate in any way to SILC. Hence, the interface
39 * can be used in any kind of application needing to perform key exchange
40 * protocol with two parties. The network connection is also handled
41 * outside the SKE interface.
43 * The protocol has initiator and responder. The initiator is the one
44 * that starts the protocol, and the responder is the one that receives
45 * negotiation request. The protocol has phases, and the interface is
46 * split into several phases that the application may call when
47 * needed. Heavy operations has been splitted so that application may
48 * call next phase with a timeout to give processing times to other
49 * things in the application. On the other hand, if application does
50 * not care about this it may call the phases immediately without any
55 #include "silcske_status.h"
57 /* Length of cookie in Start Payload */
58 #define SILC_SKE_COOKIE_LEN 16
60 /* Forward declarations */
61 typedef struct SilcSKECallbacksStruct *SilcSKECallbacks;
62 typedef struct SilcSKEStruct *SilcSKE;
64 #include "silcske_groups.h"
65 #include "silcske_payload.h"
67 /****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag
71 * typedef enum { ... } SilcSKESecurityPropertyFlag
75 * SKE security property flags as defined by the SK protocol.
80 SILC_SKE_SP_FLAG_NONE = 0x00, /* No flags */
81 SILC_SKE_SP_FLAG_IV_INCLUDED = 0x01, /* IV included in packet */
82 SILC_SKE_SP_FLAG_PFS = 0x02, /* Perfect Forward Secrecy */
83 SILC_SKE_SP_FLAG_MUTUAL = 0x04, /* Mutual authentication */
84 } SilcSKESecurityPropertyFlag;
87 /****s* silcske/SilcSKEAPI/SilcSKESecurityProperties
91 * typedef struct { ... } *SilcSKESecurityProperties;
95 * Security Properties negotiated between key exchange parties. This
96 * structure is filled from the Key Exchange Start Payload which is used
97 * to negotiate what security properties should be used in the
103 SilcSKESecurityPropertyFlag flags; /* Flags */
104 SilcSKEDiffieHellmanGroup group; /* Selected Diffie Hellman group */
105 SilcPKCS pkcs; /* Selected PKCS algorithm */
106 SilcCipher cipher; /* Selected cipher */
107 SilcHash hash; /* Selected hash algorithm */
108 SilcHmac hmac; /* Selected HMAC */
109 } *SilcSKESecurityProperties;
112 /****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial
116 * typedef struct { ... } *SilcSKEKeyMaterial;
120 * This is the key material structure, and is passed as argument by the
121 * application to silc_ske_process_key_material* functions. It includes
122 * the processed key material which can be used as SILC session keys.
126 unsigned char *send_iv;
127 unsigned char *receive_iv;
129 unsigned char *send_enc_key;
130 unsigned char *receive_enc_key;
131 SilcUInt32 enc_key_len;
132 unsigned char *send_hmac_key;
133 unsigned char *receive_hmac_key;
134 SilcUInt32 hmac_key_len;
135 } *SilcSKEKeyMaterial;
138 /****s* silcske/SilcSKEAPI/SilcSKERekeyMaterial
142 * typedef struct { ... } *SilcSKERekeyMaterial;
146 * This context is returned after key exchange protocol to application
147 * in the completion callback. Application may save it and use it later
148 * to perform the rekey with silc_ske_rekey_initiator_start and/or
149 * silc_ske_rekey_responder_start functions. If application does not
150 * need the context, it may free it with silc_free function.
152 * Application may save application specific data to `user_context'.
156 void *user_context; /* Application specific data */
157 unsigned char *send_enc_key;
158 unsigned int enc_key_len : 23;
159 unsigned int ske_group : 8;
160 unsigned int pfs : 1;
161 } *SilcSKERekeyMaterial;
164 /****d* silcske/SilcSKEAPI/SilcSKEPKType
168 * typedef enum { ... } SilcSKEPKType;
172 * Public key and certificate types defined by the SKE protocol.
177 SILC_SKE_PK_TYPE_SILC = 1, /* SILC Public Key, mandatory */
178 SILC_SKE_PK_TYPE_SSH2 = 2, /* SSH2 Public key, not supported */
179 SILC_SKE_PK_TYPE_X509V3 = 3, /* X.509v3 certificate, not supported */
180 SILC_SKE_PK_TYPE_OPENPGP = 4, /* OpenPGP certificate, not supported */
181 SILC_SKE_PK_TYPE_SPKI = 5 /* SPKI certificate, not supported */
185 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCbCompletion
189 * typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
190 * SilcSKEStatus status,
195 * Completion callback that will be called when the public key
196 * has been verified. The `status' will indicate whether the public
197 * key were trusted or not. If the `status' is PENDING then the status
198 * is not considered to be available at this moment. In this case the
199 * SKE libary will assume that the caller will call this callback again
200 * when the status is available. See silc_ske_set_callbacks for more
204 typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
205 SilcSKEStatus status,
208 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCb
212 * typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
213 * const unsigned char *pk_data,
215 * SilcSKEPKType pk_type,
217 * SilcSKEVerifyCbCompletion completion,
218 * void *completion_context);
222 * Callback function used to verify the received public key or certificate.
223 * The verification process is most likely asynchronous. That's why the
224 * application must call the `completion' callback when the verification
225 * process has been completed. The `context' is the context given as
226 * arugment to silc_ske_set_callbacks. See silc_ske_set_callbacks for
230 typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
231 const unsigned char *pk_data,
233 SilcSKEPKType pk_type,
235 SilcSKEVerifyCbCompletion completion,
236 void *completion_context);
238 /****f* silcske/SilcSKEAPI/SilcSKECheckVersion
242 * typedef SilcSKEStatus
243 * (*SilcSKECheckVersionCb)(SilcSKE ske,
244 * const unsigned char *version,
245 * SilcUInt32 len, void *context);
249 * Callback function used to check the version of the remote SKE server.
250 * The SKE library will call this function so that the appliation may
251 * check its version against the remote host's version. This returns
252 * SILC_SKE_STATUS_OK if the version string is Ok, and returns
253 * SILC_SKE_STATUS_BAD_VERSION if the version was not acceptable.
256 typedef SilcSKEStatus (*SilcSKECheckVersionCb)(SilcSKE ske,
257 const unsigned char *version,
258 SilcUInt32 len, void *context);
260 /****f* silcske/SilcSKEAPI/SilcSKECompletionCb
269 typedef void (*SilcSKECompletionCb)(SilcSKE ske,
270 SilcSKEStatus status,
271 SilcSKESecurityProperties prop,
272 SilcSKEKeyMaterial keymat,
273 SilcSKERekeyMaterial rekey,
276 /****s* silcske/SilcSKEAPI/SilcSKEStruct
280 * struct SilcSKEStruct { ... };
284 * This structure is the SKE session context, and has a type definition
285 * to SilcSKE. The structure includes the network connection socket,
286 * security properties collected during the SKE negotiation, payloads
287 * sent and received during the negotiation, and the actual raw key
288 * material too. The application usually does not need to reference
289 * to the inside of this structure. However, checking the current
290 * status of the session can easily be checked with ske->status.
294 struct SilcSKEStruct {
295 /* The network socket connection stream. Set by application. */
296 SilcPacketStream stream;
298 /* Negotiated Security properties. May be NULL in case of error. */
299 SilcSKESecurityProperties prop;
301 /* Key Exchange payloads filled during key negotiation with
302 remote data. Responder may save local data here as well. */
303 SilcSKEStartPayload start_payload;
304 SilcSKEKEPayload ke1_payload;
305 SilcSKEKEPayload ke2_payload;
306 unsigned char *remote_version;
308 /* Temporary copy of the KE Start Payload used in the
310 SilcBuffer start_payload_copy;
312 /* Random number x, 1 < x < q. This is the secret exponent
313 used in Diffie Hellman computations. */
316 /* The secret shared key */
319 /* The hash value HASH of the key exchange */
323 /* Random Number Generator. This is set by the caller and must
324 be free'd by the caller. */
327 /* Pointer to the what ever user data. This is set by the caller
328 and is not touched by the SKE. The caller must also free this one. */
331 /* Current status of SKE */
332 SilcSKEStatus status;
334 /* Reference counter. This is used when SKE library is performing async
335 operations, like public key verification. */
339 SilcSKECallbacks callbacks;
341 /* Backwards support version indicator */
342 SilcUInt32 backward_version;
345 SilcPublicKey public_key;
346 SilcPrivateKey private_key;
347 SilcSKEPKType pk_type;
348 SilcBuffer packet_buf;
349 SilcSKESecurityPropertyFlag flags;
350 SilcSKEKeyMaterial keymat;
351 SilcSKERekeyMaterial rekey;
352 SilcSchedule schedule;
354 SilcAsyncOperationStruct op;
361 /****f* silcske/SilcSKEAPI/silc_ske_alloc
365 * SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
370 * Allocates the SKE session context and returns it. The `rng' is
371 * the random number generator the SKE is going to use when it needs
372 * random number generation during the SKE session. The `context' is
373 * user context that the libary will not touch. Application can get the
374 * context by calling the fuction silc_ske_get_context function. The
375 * application is responsible of freeing the `context'. After the
376 * SKE session context is allocated application must call the
377 * silc_ske_set_callbacks.
381 * // Initiator example
382 * ske = silc_ske_alloc(rng, scheduler, app);
383 * silc_ske_set_callbacks(ske, verify_public_key, check_version, app);
385 * silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_PFS |
386 * SILC_SKE_SP_FLAG_MUTUAL,
388 * silc_ske_initiator_start(ske);
391 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule, void *context);
393 /****f* silcske/SilcSKEAPI/silc_ske_free
397 * void silc_ske_free(SilcSKE ske);
401 * Frees the SKE session context and all allocated resources.
404 void silc_ske_free(SilcSKE ske);
406 /****f* silcske/SilcSKEAPI/silc_ske_get_context
410 * void *silc_ske_get_context(SilcSKE ske);
414 * Returns the context that was given as argument to silc_ske_alloc.
417 void *silc_ske_get_context(SilcSKE ske);
419 /****f* silcske/SilcSKEAPI/silc_ske_set_callbacks
423 * void silc_ske_set_callbacks(SilcSKE ske,
424 * SilcSKEVerifyCb verify_key,
425 * SilcSKECheckVersion check_version,
426 * SilcSKECompletion completed,
431 * Sets the callback functions for the SKE session.
433 * The `verify_key' callback is called to verify the received public key
434 * or certificate. The verification process is most likely asynchronous.
435 * That is why the application must call the completion callback when the
436 * verification process has been completed. If this SKE session context
437 * is used to perform rekey, this callback usually is not provided as
438 * argument since sending public key in rekey is not mandatory. Setting
439 * this callback implies that remote end MUST send its public key.
441 * The `check_version' callback is called to verify the remote host's
442 * version. The application may check its own version against the remote
443 * host's version and determine whether supporting the remote host
446 * The `completed' callback will be called once the protocol has completed,
447 * either successfully or with an error. The status of the protocol is
448 * delivered to application with the callback.
450 * The `context' is passed as argument to all of the above callback
454 void silc_ske_set_callbacks(SilcSKE ske,
455 SilcSKEVerifyCb verify_key,
456 SilcSKECheckVersionCb check_version,
457 SilcSKECompletionCb completed,
460 /****f* silcske/SilcSKEAPI/silc_ske_initiator_start
465 * silc_ske_initiator_start(SilcSKE ske,
466 * SilcPacketStream stream,
467 * SilcSKEStartPayload start_payload);
471 * Starts the SILC Key Exchange protocol as initiator. The completion
472 * callback that was set in silc_ske_set_callbacks will be called once
473 * the protocol has completed.
475 * The `stream' is the network connection to the remote host. Note that
476 * SKE library will take over the packet stream `stream' while the
477 * protocol is in process. The application will not receive any packets
478 * for `stream' after this function is called. The `stream' is turned
479 * over to application once the completion callback is called.
481 * The `start_payload' includes all configured security properties that
482 * will be sent to the responder. The `start_payload' must be provided.
483 * It can be created by calling silc_ske_assemble_security_properties
484 * function. The caller must not free the payload once it has been
485 * given as argument to this function.
487 * This function returns SilcAsyncOperation operation context which can
488 * be used to control the protocol from the application. Application may
489 * for example safely abort the protocol at any point, if needed. Returns
494 silc_ske_initiator_start(SilcSKE ske,
495 SilcPacketStream stream,
496 SilcSKEStartPayload start_payload);
498 /****f* silcske/SilcSKEAPI/silc_ske_responder_start
503 * silc_ske_responder_start(SilcSKE ske,
504 * SilcPacketStream stream,
505 * const char *version,
506 * SilcBuffer start_payload,
507 * SilcSKESecurityPropertyFlag flags);
511 * Starts SILC Key Exchange protocol as responder. The completion
512 * callback that was set in silc_ske_set_callbacks will be called once
513 * the protocol has completed.
515 * The `stream' is the network connection to the remote host. Note that
516 * SKE library will take over the packet stream `stream' while the
517 * protocol is in process. The application will not receive any packets
518 * for `stream' after this function is called. The `stream' is turned
519 * over to application once the completion callback is called.
521 * The application has received initiator's first packet from network
522 * and it must provide it as `start_payload' argument to this function.
523 * The function processes the packet and makes security property selection
524 * from the initiator's proposal. The `version' is the responder's version
525 * that will be sent in reply to the initiator. The `flags' indicates
526 * SilcSKESecurityPropertyFlag flags that responder supports and enforces
527 * for the initiator. Responder may, for example, enforce that the PFS
528 * will be performed in rekey.
530 * This function returns SilcAsyncOperation operation context which can
531 * be used to control the protocol from the application. Application may
532 * for example safely abort the protocol at any point, if needed. Returns
537 silc_ske_responder_start(SilcSKE ske,
538 SilcPacketStream stream,
540 SilcBuffer start_payload,
541 SilcSKESecurityPropertyFlag flags);
544 silc_ske_rekey_initiator_start(SilcSKE ske,
545 SilcPacketStream stream,
546 SilcSKERekeyMaterial rekey);
549 silc_ske_rekey_responder_start(SilcSKE ske,
550 SilcPacketStream stream,
551 SilcBuffer ke_payload,
552 SilcSKERekeyMaterial rekey);
554 /****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties
558 * SilcSKEStartPayload
559 * silc_ske_assemble_security_properties(SilcSKE ske,
560 * SilcSKESecurityPropertyFlag flags,
561 * const char *version);
565 * Assembles security properties to Key Exchange Start Payload to be
566 * sent to the remote end. This checks system wide (SILC system, that is)
567 * settings and chooses from those. However, if other properties
568 * should be used this function is easy to replace by another function,
569 * as, this function is called by the caller of the library and not
570 * by the SKE library itself. Returns NULL on error.
574 silc_ske_assemble_security_properties(SilcSKE ske,
575 SilcSKESecurityPropertyFlag flags,
576 const char *version);
578 /****f* silcske/SilcSKEAPI/silc_ske_parse_version
582 * SilcBool silc_ske_parse_version(SilcSKE ske,
583 * SilcUInt32 *protocol_version,
584 * char **protocol_version_string,
585 * SilcUInt32 *software_version,
586 * char **software_version_string,
587 * char **vendor_version);
591 * This utility function can be used to parse the remote host's version
592 * string. This returns the protocol version, and software version into
593 * the `protocol_version', `software_version' and `vendor_version' pointers
594 * if they are provided. The string versions of the versions are saved
595 * in *_string pointers if they are provided. Returns TRUE if the version
596 * string was successfully parsed.
599 SilcBool silc_ske_parse_version(SilcSKE ske,
600 SilcUInt32 *protocol_version,
601 char **protocol_version_string,
602 SilcUInt32 *software_version,
603 char **software_version_string,
604 char **vendor_version);
606 #endif /* !SILCSKE_H */