e1c25b8539afac74ba0c4ae0044bdf329a1820f4
[silc.git] / lib / silcske / silcske.h
1 /*
2
3   silcske.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 - 2005 Pekka Riikonen
8
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.
12
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.
17
18 */
19
20 #ifndef SILCSKE_H
21 #define SILCSKE_H
22
23 /****h* silcske/SILC SKE Interface
24  *
25  * DESCRIPTION
26  *
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
33  * stream.
34  *
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.
42  *
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
51  * timeout.
52  *
53  ***/
54
55 #include "silcske_status.h"
56
57 /* Length of cookie in Start Payload */
58 #define SILC_SKE_COOKIE_LEN 16
59
60 /* Forward declarations */
61 typedef struct SilcSKECallbacksStruct *SilcSKECallbacks;
62 typedef struct SilcSKEStruct *SilcSKE;
63
64 #include "silcske_groups.h"
65 #include "silcske_payload.h"
66
67 /****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag
68  *
69  * NAME
70  *
71  *    typedef enum { ... } SilcSKESecurityPropertyFlag
72  *
73  * DESCRIPTION
74  *
75  *    SKE security property flags as defined by the SK protocol.
76  *
77  * SOURCE
78  */
79 typedef enum {
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;
85 /***/
86
87 /****s* silcske/SilcSKEAPI/SilcSKESecurityProperties
88  *
89  * NAME
90  *
91  *    typedef struct { ... } *SilcSKESecurityProperties;
92  *
93  * DESCRIPTION
94  *
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
98  *    communication.
99  *
100  * SOURCE
101  */
102 typedef struct {
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;
110 /***/
111
112 /****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial
113  *
114  * NAME
115  *
116  *    typedef struct { ... } *SilcSKEKeyMaterial;
117  *
118  * DESCRIPTION
119  *
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.
123  *
124  */
125 typedef struct {
126   unsigned char *send_iv;
127   unsigned char *receive_iv;
128   SilcUInt32 iv_len;
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;
136 /***/
137
138 /****s* silcske/SilcSKEAPI/SilcSKERekeyMaterial
139  *
140  * NAME
141  *
142  *    typedef struct { ... } *SilcSKERekeyMaterial;
143  *
144  * DESCRIPTION
145  *
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.
151  *
152  *    Application may save application specific data to `user_context'.
153  *
154  */
155 typedef struct {
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;
162 /***/
163
164 /****d* silcske/SilcSKEAPI/SilcSKEPKType
165  *
166  * NAME
167  *
168  *    typedef enum { ... } SilcSKEPKType;
169  *
170  * DESCRIPTION
171  *
172  *    Public key and certificate types defined by the SKE protocol.
173  *
174  * SOURCE
175  */
176 typedef enum {
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 */
182 } SilcSKEPKType;
183 /***/
184
185 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCbCompletion
186  *
187  * SYNOPSIS
188  *
189  *    typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
190  *                                              SilcSKEStatus status,
191  *                                              void *context);
192  *
193  * DESCRIPTION
194  *
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
201  *    information.
202  *
203  ***/
204 typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
205                                           SilcSKEStatus status,
206                                           void *context);
207
208 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCb
209  *
210  * SYNOPSIS
211  *
212  *    typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
213  *                                    const unsigned char *pk_data,
214  *                                    SilcUInt32 pk_len,
215  *                                    SilcSKEPKType pk_type,
216  *                                    void *context,
217  *                                    SilcSKEVerifyCbCompletion completion,
218  *                                    void *completion_context);
219  *
220  * DESCRIPTION
221  *
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
227  *    more information.
228  *
229  ***/
230 typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
231                                 const unsigned char *pk_data,
232                                 SilcUInt32 pk_len,
233                                 SilcSKEPKType pk_type,
234                                 void *context,
235                                 SilcSKEVerifyCbCompletion completion,
236                                 void *completion_context);
237
238 /****f* silcske/SilcSKEAPI/SilcSKECheckVersion
239  *
240  * SYNOPSIS
241  *
242  *    typedef SilcSKEStatus
243  *    (*SilcSKECheckVersionCb)(SilcSKE ske,
244  *                             const unsigned char *version,
245  *                             SilcUInt32 len, void *context);
246  *
247  * DESCRIPTION
248  *
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.
254  *
255  ***/
256 typedef SilcSKEStatus (*SilcSKECheckVersionCb)(SilcSKE ske,
257                                                const unsigned char *version,
258                                                SilcUInt32 len, void *context);
259
260 /****f* silcske/SilcSKEAPI/SilcSKECompletionCb
261  *
262  * SYNOPSIS
263  *
264  *
265  * DESCRIPTION
266  *
267  *
268  ***/
269 typedef void (*SilcSKECompletionCb)(SilcSKE ske,
270                                     SilcSKEStatus status,
271                                     SilcSKESecurityProperties prop,
272                                     SilcSKEKeyMaterial keymat,
273                                     SilcSKERekeyMaterial rekey,
274                                     void *context);
275
276 /****s* silcske/SilcSKEAPI/SilcSKEStruct
277  *
278  * NAME
279  *
280  *    struct SilcSKEStruct { ... };
281  *
282  * DESCRIPTION
283  *
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.
291  *
292  * SOURCE
293  */
294 struct SilcSKEStruct {
295   /* The network socket connection stream.  Set by application. */
296   SilcPacketStream stream;
297
298   /* Negotiated Security properties.  May be NULL in case of error. */
299   SilcSKESecurityProperties prop;
300
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;
307
308   /* Temporary copy of the KE Start Payload used in the
309      HASH computation. */
310   SilcBuffer start_payload_copy;
311
312   /* Random number x, 1 < x < q. This is the secret exponent
313      used in Diffie Hellman computations. */
314   SilcMPInt *x;
315
316   /* The secret shared key */
317   SilcMPInt *KEY;
318
319   /* The hash value HASH of the key exchange */
320   unsigned char *hash;
321   SilcUInt32 hash_len;
322
323   /* Random Number Generator. This is set by the caller and must
324      be free'd by the caller. */
325   SilcRng rng;
326
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. */
329   void *user_data;
330
331   /* Current status of SKE */
332   SilcSKEStatus status;
333
334   /* Reference counter. This is used when SKE library is performing async
335      operations, like public key verification. */
336   int users;
337
338   /* SKE callbacks. */
339   SilcSKECallbacks callbacks;
340
341   /* Backwards support version indicator */
342   SilcUInt32 backward_version;
343
344   char *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;
353   SilcFSMStruct fsm;
354   SilcAsyncOperationStruct op;
355   SilcBool aborted;
356 };
357 /***/
358
359 /* Prototypes */
360
361 /****f* silcske/SilcSKEAPI/silc_ske_alloc
362  *
363  * SYNOPSIS
364  *
365  *    SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
366  *                           void *context);
367  *
368  * DESCRIPTION
369  *
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.
378  *
379  * EXMPALE
380  *
381  *    // Initiator example
382  *    ske = silc_ske_alloc(rng, scheduler, app);
383  *    silc_ske_set_callbacks(ske, verify_public_key, check_version, app);
384  *    start_payload =
385  *      silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_PFS |
386  *                                            SILC_SKE_SP_FLAG_MUTUAL,
387  *                                            version);
388  *    silc_ske_initiator_start(ske);
389  *
390  ***/
391 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule, void *context);
392
393 /****f* silcske/SilcSKEAPI/silc_ske_free
394  *
395  * SYNOPSIS
396  *
397  *    void silc_ske_free(SilcSKE ske);
398  *
399  * DESCRIPTION
400  *
401  *    Frees the SKE session context and all allocated resources.
402  *
403  ***/
404 void silc_ske_free(SilcSKE ske);
405
406 /****f* silcske/SilcSKEAPI/silc_ske_get_context
407  *
408  * SYNOPSIS
409  *
410  *    void *silc_ske_get_context(SilcSKE ske);
411  *
412  * DESCRIPTION
413  *
414  *    Returns the context that was given as argument to silc_ske_alloc.
415  *
416  ***/
417 void *silc_ske_get_context(SilcSKE ske);
418
419 /****f* silcske/SilcSKEAPI/silc_ske_set_callbacks
420  *
421  * SYNOPSIS
422  *
423  *    void silc_ske_set_callbacks(SilcSKE ske,
424  *                                SilcSKEVerifyCb verify_key,
425  *                                SilcSKECheckVersion check_version,
426  *                                SilcSKECompletion completed,
427  *                                void *context);
428  *
429  * DESCRIPTION
430  *
431  *    Sets the callback functions for the SKE session.
432  *
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.
440  *
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
444  *    is possible.
445  *
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.
449  *
450  *    The `context' is passed as argument to all of the above callback
451  *    functions.
452  *
453  ***/
454 void silc_ske_set_callbacks(SilcSKE ske,
455                             SilcSKEVerifyCb verify_key,
456                             SilcSKECheckVersionCb check_version,
457                             SilcSKECompletionCb completed,
458                             void *context);
459
460 /****f* silcske/SilcSKEAPI/silc_ske_initiator_start
461  *
462  * SYNOPSIS
463  *
464  *    SilcAsyncOperation
465  *    silc_ske_initiator_start(SilcSKE ske,
466  *                             SilcPacketStream stream,
467  *                             SilcSKEStartPayload start_payload);
468  *
469  * DESCRIPTION
470  *
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.
474  *
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.
480  *
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.
486  *
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
490  *    NULL on error.
491  *
492  ***/
493 SilcAsyncOperation
494 silc_ske_initiator_start(SilcSKE ske,
495                          SilcPacketStream stream,
496                          SilcSKEStartPayload start_payload);
497
498 /****f* silcske/SilcSKEAPI/silc_ske_responder_start
499  *
500  * SYNOPSIS
501  *
502  *    SilcAsyncOperation
503  *    silc_ske_responder_start(SilcSKE ske,
504  *                             SilcPacketStream stream,
505  *                             const char *version,
506  *                             SilcBuffer start_payload,
507  *                             SilcSKESecurityPropertyFlag flags);
508  *
509  * DESCRIPTION
510  *
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.
514  *
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.
520  *
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.
529  *
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
533  *    NULL on error.
534  *
535  ***/
536 SilcAsyncOperation
537 silc_ske_responder_start(SilcSKE ske,
538                          SilcPacketStream stream,
539                          const char *version,
540                          SilcBuffer start_payload,
541                          SilcSKESecurityPropertyFlag flags);
542
543 SilcAsyncOperation
544 silc_ske_rekey_initiator_start(SilcSKE ske,
545                                SilcPacketStream stream,
546                                SilcSKERekeyMaterial rekey);
547
548 SilcAsyncOperation
549 silc_ske_rekey_responder_start(SilcSKE ske,
550                                SilcPacketStream stream,
551                                SilcBuffer ke_payload,
552                                SilcSKERekeyMaterial rekey);
553
554 /****f* silcske/SilcSKEAPI/silc_ske_assemble_security_properties
555  *
556  * SYNOPSIS
557  *
558  *    SilcSKEStartPayload
559  *    silc_ske_assemble_security_properties(SilcSKE ske,
560  *                                          SilcSKESecurityPropertyFlag flags,
561  *                                          const char *version);
562  *
563  * DESCRIPTION
564  *
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.
571  *
572  ***/
573 SilcSKEStartPayload
574 silc_ske_assemble_security_properties(SilcSKE ske,
575                                       SilcSKESecurityPropertyFlag flags,
576                                       const char *version);
577
578 /****f* silcske/SilcSKEAPI/silc_ske_parse_version
579  *
580  * SYNOPSIS
581  *
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);
588  *
589  * DESCRIPTION
590  *
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.
597  *
598  ***/
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);
605
606 #endif  /* !SILCSKE_H */