c37dcf3ac8d6acec73ff5d8739c7803e2fdc8a83
[silc.git] / lib / silcske / silcske.h
1 /*
2
3   silcske.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 - 2006 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 /****h* silcske/SILC SKE Interface
21  *
22  * DESCRIPTION
23  *
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.
32  *
33  ***/
34
35 #ifndef SILCSKE_H
36 #define SILCSKE_H
37
38 /* Forward declarations */
39 typedef struct SilcSKECallbacksStruct *SilcSKECallbacks;
40 typedef struct SilcSKEStruct *SilcSKE;
41
42 /****d* silcske/SilcSKEAPI/SilcSKEStatus
43  *
44  * NAME
45  *
46  *    typedef enum { ... } SilcSKEStatus;
47  *
48  * DESCRIPTION
49  *
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.
53  *
54  * SOURCE
55  */
56 typedef enum {
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 */
70
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 } SilcSKEStatus;
78 /***/
79
80 #include "silcske_groups.h"
81 #include "silcske_payload.h"
82
83 /****d* silcske/SilcSKEAPI/SilcSKESecurityPropertyFlag
84  *
85  * NAME
86  *
87  *    typedef enum { ... } SilcSKESecurityPropertyFlag
88  *
89  * DESCRIPTION
90  *
91  *    SKE security property flags as defined by the SK protocol.
92  *
93  * SOURCE
94  */
95 typedef enum {
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;
101 /***/
102
103 /****s* silcske/SilcSKEAPI/SilcSKESecurityProperties
104  *
105  * NAME
106  *
107  *    typedef struct { ... } *SilcSKESecurityProperties;
108  *
109  * DESCRIPTION
110  *
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
114  *    communication.
115  *
116  * SOURCE
117  */
118 typedef struct {
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   SilcPublicKey public_key;              /* Remote public key */
125   SilcUInt16 remote_port;                /* Remote port, set when IV Included
126                                             set and using UDP/IP */
127 } *SilcSKESecurityProperties;
128 /***/
129
130 /****s* silcske/SilcSKEAPI/SilcSKEKeyMaterial
131  *
132  * NAME
133  *
134  *    typedef struct { ... } *SilcSKEKeyMaterial;
135  *
136  * DESCRIPTION
137  *
138  *    This is the key material structure, and is passed as argument by the
139  *    application to silc_ske_process_key_material_data function. It includes
140  *    the processed key material which can be used as SILC session keys.
141  *
142  * SOURCE
143  */
144 typedef struct {
145   unsigned char *send_iv;
146   unsigned char *receive_iv;
147   SilcUInt32 iv_len;
148   unsigned char *send_enc_key;
149   unsigned char *receive_enc_key;
150   SilcUInt32 enc_key_len;
151   unsigned char *send_hmac_key;
152   unsigned char *receive_hmac_key;
153   SilcUInt32 hmac_key_len;
154 } *SilcSKEKeyMaterial;
155 /***/
156
157 /****s* silcske/SilcSKEAPI/SilcSKERekeyMaterial
158  *
159  * NAME
160  *
161  *    typedef struct { ... } *SilcSKERekeyMaterial;
162  *
163  * DESCRIPTION
164  *
165  *    This context is returned after key exchange protocol to application
166  *    in the completion callback.  Application may save it and use it later
167  *    to perform the rekey with silc_ske_rekey_initiator_start and/or
168  *    silc_ske_rekey_responder_start functions.  If application does not
169  *    need the context, it may free it with silc_free function.
170  *
171  *    Application may save application specific data to `user_context'.
172  *
173  * SOURCE
174  */
175 typedef struct {
176   void *user_context;                 /* Application specific data */
177   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;
182 /***/
183
184 /****s* silcske/SilcSKEAPI/SilcSKEParams
185  *
186  * NAME
187  *
188  *    typedef struct { ... } *SilcSKEParams, SilcSKEParamsStruct;
189  *
190  * DESCRIPTION
191  *
192  *    SKE parameters structure.  This structure is given as argument to
193  *    silc_ske_initiator and silc_ske_responder functions.
194  *
195  * SOURCE
196  */
197 typedef struct {
198   /* The SKE version string that is sent to the remote end.  This field
199      must be set.  Caller must free the pointer. */
200   char *version;
201
202   /* Security property flags.  When initiator sets these it requests them
203      from the responder.  Responder may set here the flags it supports
204      and wants to enforce for the initiator. */
205   SilcSKESecurityPropertyFlag flags;
206
207   /* SILC Session port when using UDP/IP and SILC_SKE_SP_FLAG_IV_INCLUDED
208      flag.  It is the port the remote will use as SILC session port after
209      the key exchange protocol.  Ignored without SILC_SKE_SP_FLAG_IV_INCLUDED
210      flag. */
211   SilcUInt16 session_port;
212 } *SilcSKEParams, SilcSKEParamsStruct;
213 /***/
214
215 /****d* silcske/SilcSKEAPI/SilcSKEPKType
216  *
217  * NAME
218  *
219  *    typedef enum { ... } SilcSKEPKType;
220  *
221  * DESCRIPTION
222  *
223  *    Public key and certificate types defined by the SKE protocol.
224  *
225  * SOURCE
226  */
227 typedef enum {
228   SILC_SKE_PK_TYPE_SILC    = 1, /* SILC Public Key, mandatory */
229   SILC_SKE_PK_TYPE_SSH2    = 2, /* SSH2 Public key, not supported */
230   SILC_SKE_PK_TYPE_X509V3  = 3, /* X.509v3 certificate, not supported */
231   SILC_SKE_PK_TYPE_OPENPGP = 4, /* OpenPGP certificate, not supported */
232   SILC_SKE_PK_TYPE_SPKI    = 5  /* SPKI certificate, not supported */
233 } SilcSKEPKType;
234 /***/
235
236 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCbCompletion
237  *
238  * SYNOPSIS
239  *
240  *    typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
241  *                                              SilcSKEStatus status,
242  *                                              void *context);
243  *
244  * DESCRIPTION
245  *
246  *    Completion callback that will be called when the public key
247  *    has been verified.  The `status' will indicate whether the public
248  *    key were trusted or not.
249  *
250  ***/
251 typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
252                                           SilcSKEStatus status,
253                                           void *context);
254
255 /****f* silcske/SilcSKEAPI/SilcSKEVerifyCb
256  *
257  * SYNOPSIS
258  *
259  *    typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
260  *                                    SilcPublicKey public_key,
261  *                                    void *context,
262  *                                    SilcSKEVerifyCbCompletion completion,
263  *                                    void *completion_context);
264  *
265  * DESCRIPTION
266  *
267  *    Callback function used to verify the received public key or certificate.
268  *    The verification process is most likely asynchronous.  That's why the
269  *    application must call the `completion' callback when the verification
270  *    process has been completed.  The `context' is the context given as
271  *    arugment to silc_ske_set_callbacks.  See silc_ske_set_callbacks for
272  *    more information.
273  *
274  *    If the key repository was provided in silc_ske_alloc this callback
275  *    is called only if the public key was not found from the repository.
276  *
277  ***/
278 typedef void (*SilcSKEVerifyCb)(SilcSKE ske,
279                                 SilcPublicKey public_key,
280                                 void *context,
281                                 SilcSKEVerifyCbCompletion completion,
282                                 void *completion_context);
283
284 /****f* silcske/SilcSKEAPI/SilcSKECompletionCb
285  *
286  * SYNOPSIS
287  *
288  *    typedef void (*SilcSKECompletionCb)(SilcSKE ske,
289  *                                        SilcSKEStatus status,
290  *                                        SilcSKESecurityProperties prop,
291  *                                        SilcSKEKeyMaterial keymat,
292  *                                        SilcSKERekeyMaterial rekey,
293  *                                        void *context);
294  *
295  * DESCRIPTION
296  *
297  *    Completion callback.  This is called after the key exchange protocol
298  *    has been completed.  It delivers the status of the protocol, and if
299  *    successful the security properties `prop' that was negotiated in the
300  *    protocol and the key material `keymat' that can be set into use by
301  *    calling silc_ske_set_keys, and the rekey key material `rekey' which
302  *    can be used later to start rekey protocol.  The `prop' will remain
303  *    valid as long as `ske' is valid.  After `ske' is freed `prop' will
304  *    become invalid.
305  *
306  ***/
307 typedef void (*SilcSKECompletionCb)(SilcSKE ske,
308                                     SilcSKEStatus status,
309                                     SilcSKESecurityProperties prop,
310                                     SilcSKEKeyMaterial keymat,
311                                     SilcSKERekeyMaterial rekey,
312                                     void *context);
313
314 /* Prototypes */
315
316 /****f* silcske/SilcSKEAPI/silc_ske_alloc
317  *
318  * SYNOPSIS
319  *
320  *    SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
321  *                           SilcSKR repository, SilcPublicKey public_key,
322  *                           SilcPrivateKey private_key, void *context);
323  *
324  * DESCRIPTION
325  *
326  *    Allocates the SKE session context and returns it.  The `rng' is
327  *    the random number generator the SKE is going to use when it needs
328  *    random number generation during the SKE session.  The `context' is
329  *    user context that the libary will not touch.  Application can get the
330  *    context by calling the fuction silc_ske_get_context function.  The
331  *    application is responsible of freeing the `context'.  After the
332  *    SKE session context is allocated application must call the
333  *    silc_ske_set_callbacks.
334  *
335  *    If the `repository' is non-NULL then the remote's public key will be
336  *    verified from the repository.  If it is not provided then the
337  *    SilcSKEVerifyCb callback must be set, and it will be called to
338  *    verify the key.  If both `repository' and the callback is provided the
339  *    callback is called only if the key is not found from the repository.
340  *
341  *    The `public_key' and `private_key' is the caller's identity used
342  *    during the key exchange.  Giving `private_key' is optional if the
343  *    SILC_SKE_SP_FLAG_MUTUAL is not set and you are initiator.  For
344  *    responder both `public_key' and `private_key' must be set.
345  *
346  * EXMPALE
347  *
348  *    // Initiator example
349  *    params.version = version;
350  *    params.flags = SILC_SKE_SP_FLAG_PFS | SILC_SKE_SP_FLAG_MUTUAL;
351  *    ske = silc_ske_alloc(rng, scheduler, NULL, pk, prv, app);
352  *    silc_ske_set_callbacks(ske, verify_public_key, completion, app);
353  *    silc_ske_initiator_start(ske, stream, &params, NULL);
354  *
355  ***/
356 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
357                        SilcSKR repository, SilcPublicKey public_key,
358                        SilcPrivateKey private_key, void *context);
359
360 /****f* silcske/SilcSKEAPI/silc_ske_free
361  *
362  * SYNOPSIS
363  *
364  *    void silc_ske_free(SilcSKE ske);
365  *
366  * DESCRIPTION
367  *
368  *    Frees the SKE session context and all allocated resources.
369  *
370  ***/
371 void silc_ske_free(SilcSKE ske);
372
373 /****f* silcske/SilcSKEAPI/silc_ske_get_context
374  *
375  * SYNOPSIS
376  *
377  *    void *silc_ske_get_context(SilcSKE ske);
378  *
379  * DESCRIPTION
380  *
381  *    Returns the context that was given as argument to silc_ske_alloc.
382  *
383  ***/
384 void *silc_ske_get_context(SilcSKE ske);
385
386 /****f* silcske/SilcSKEAPI/silc_ske_set_callbacks
387  *
388  * SYNOPSIS
389  *
390  *    void silc_ske_set_callbacks(SilcSKE ske,
391  *                                SilcSKEVerifyCb verify_key,
392  *                                SilcSKECompletion completed,
393  *                                void *context);
394  *
395  * DESCRIPTION
396  *
397  *    Sets the callback functions for the SKE session.
398  *
399  *    The `verify_key' callback is called to verify the received public key
400  *    or certificate.  The verification process is most likely asynchronous.
401  *    That is why the application must call the completion callback when the
402  *    verification process has been completed.  If this SKE session context
403  *    is used to perform  rekey, this callback usually is not provided as
404  *    argument since sending public key in rekey is not mandatory.  Setting
405  *    this callback implies that remote end MUST send its public key.
406  *
407  *    The `completed' callback will be called once the protocol has completed,
408  *    either successfully or with an error.  The status of the protocol is
409  *    delivered to application with the callback.
410  *
411  *    The `context' is passed as argument to all of the above callback
412  *    functions.
413  *
414  ***/
415 void silc_ske_set_callbacks(SilcSKE ske,
416                             SilcSKEVerifyCb verify_key,
417                             SilcSKECompletionCb completed,
418                             void *context);
419
420 /****f* silcske/SilcSKEAPI/silc_ske_initiator_start
421  *
422  * SYNOPSIS
423  *
424  *    SilcAsyncOperation
425  *    silc_ske_initiator(SilcSKE ske,
426  *                       SilcPacketStream stream,
427  *                       SilcSKEParams params,
428                          SilcSKEStartPayload start_payload);
429  *
430  * DESCRIPTION
431  *
432  *    Starts the SILC Key Exchange protocol as initiator.  The completion
433  *    callback that was set in silc_ske_set_callbacks will be called once
434  *    the protocol has completed.  The `stream' is the network connection
435  *    to the remote host.  The SKE library will handle all key exchange
436  *    packets sent and received in the `stream' connection.  The library will
437  *    also set the remote host's ID automatically to the `stream'.  The
438  *    `params' include SKE parameters, and it must be provided.
439  *
440  *    If the `start_payload' is NULL the library will generate it
441  *    automatically.  Caller may provide it if it wants to send its own
442  *    security properties instead of using the default ones library
443  *    generates.  If caller provides it, it must not free it once it has
444  *    been given as argument to this function.
445  *
446  *    This function returns SilcAsyncOperation operation context which can
447  *    be used to control the protocol from the application.  Application may
448  *    for example safely abort the protocol at any point, if needed.  Returns
449  *    NULL on error.
450  *
451  ***/
452 SilcAsyncOperation
453 silc_ske_initiator(SilcSKE ske,
454                    SilcPacketStream stream,
455                    SilcSKEParams params,
456                    SilcSKEStartPayload start_payload);
457
458 /****f* silcske/SilcSKEAPI/silc_ske_responder_start
459  *
460  * SYNOPSIS
461  *
462  *    SilcAsyncOperation
463  *    silc_ske_responder_start(SilcSKE ske,
464  *                             SilcPacketStream stream,
465  *                             SilcSKEParams params);
466  *
467  * DESCRIPTION
468  *
469  *    Starts SILC Key Exchange protocol as responder.  The completion
470  *    callback that was set in silc_ske_set_callbacks will be called once
471  *    the protocol has completed.  The `stream' is the network connection
472  *    to the remote host.  The SKE library will handle all key exchange
473  *    packets sent and received in the `stream' connection.  The `params'
474  *    include SKE parameters, and must be provided.
475  *
476  *    This function returns SilcAsyncOperation operation context which can
477  *    be used to control the protocol from the application.  Application may
478  *    for example safely abort the protocol at any point, if needed.  Returns
479  *    NULL on error.
480  *
481  ***/
482 SilcAsyncOperation
483 silc_ske_responder(SilcSKE ske,
484                    SilcPacketStream stream,
485                    SilcSKEParams params);
486
487 SilcAsyncOperation
488 silc_ske_rekey_initiator(SilcSKE ske,
489                          SilcPacketStream stream,
490                          SilcSKERekeyMaterial rekey);
491
492 SilcAsyncOperation
493 silc_ske_rekey_responder(SilcSKE ske,
494                          SilcPacketStream stream,
495                          SilcBuffer ke_payload,
496                          SilcSKERekeyMaterial rekey);
497
498 /****f* silcske/SilcSKEAPI/silc_ske_set_keys
499  *
500  * SYNOPSIS
501  *
502  *    SilcBool silc_ske_set_keys(SilcSKE ske,
503  *                               SilcSKEKeyMaterial keymat,
504  *                               SilcSKESecurityProperties prop,
505  *                               SilcCipher *ret_send_key,
506  *                               SilcCipher *ret_receive_key,
507  *                               SilcHmac *ret_hmac_send,
508  *                               SilcHmac *ret_hmac_receive,
509  *                               SilcHash *ret_hash);
510  *
511  * DESCRIPTION
512  *
513  *    This function can be used after successful key exchange to take the
514  *    key material `keymat' with security properties `prop' into use.
515  *    This will allocate send and receive ciphers, HMACs and hash for the
516  *    application.  Caller must free the returned contexts.  This is an
517  *    utility function.
518  *
519  ***/
520 SilcBool silc_ske_set_keys(SilcSKE ske,
521                            SilcSKEKeyMaterial keymat,
522                            SilcSKESecurityProperties prop,
523                            SilcCipher *ret_send_key,
524                            SilcCipher *ret_receive_key,
525                            SilcHmac *ret_hmac_send,
526                            SilcHmac *ret_hmac_receive,
527                            SilcHash *ret_hash);
528
529 /****f* silcske/SilcSKEAPI/silc_ske_parse_version
530  *
531  * SYNOPSIS
532  *
533  *    SilcBool silc_ske_parse_version(SilcSKE ske,
534  *                                    SilcUInt32 *protocol_version,
535  *                                    char **protocol_version_string,
536  *                                    SilcUInt32 *software_version,
537  *                                    char **software_version_string,
538  *                                    char **vendor_version);
539  *
540  * DESCRIPTION
541  *
542  *    Utility function to parse the remote host's version string.  This can
543  *    be called after the key exchange has been completed.
544  *
545  ***/
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);
552
553 /****f* silcske/SilcSKEAPI/silc_ske_get_security_properties
554  *
555  * SYNOPSIS
556  *
557  *    SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske);
558  *
559  * DESCRIPTION
560  *
561  *    Returns negotiated security properties from the `ske' or NULL if they
562  *    have not yet been negotiated.  This may be called to retrieve the
563  *    security properties after the SilcSKECompletionCb has been called.
564  *
565  ***/
566 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske);
567
568 /****f* silcske/SilcSKEAPI/silc_ske_process_key_material_data
569  *
570  * SYNOPSIS
571  *
572  *    const char *silc_ske_map_status(SilcSKEStatus status);
573  *
574  * DESCRIPTION
575  *
576  *    Utility function to process key data `data' in the way specified
577  *    by the SILC Key Exchange protocol.  This returns the processed key
578  *    material or NULL on error.  Caller must free the returned key
579  *    material context by calling silc_ske_free_key_material.
580  *
581  ***/
582 SilcSKEKeyMaterial
583 silc_ske_process_key_material_data(unsigned char *data,
584                                    SilcUInt32 data_len,
585                                    SilcUInt32 req_iv_len,
586                                    SilcUInt32 req_enc_key_len,
587                                    SilcUInt32 req_hmac_key_len,
588                                    SilcHash hash);
589
590 /****f* silcske/SilcSKEAPI/silc_ske_free_key_material
591  *
592  * SYNOPSIS
593  *
594  *    void silc_ske_free_key_material(SilcSKEKeyMaterial key)
595  *
596  * DESCRIPTION
597  *
598  *    Utility function to free the key material created by calling
599  *    silc_ske_process_key_material_data.
600  *
601  ***/
602 void silc_ske_free_key_material(SilcSKEKeyMaterial key);
603
604 /****f* silcske/SilcSKEAPI/silc_ske_map_status
605  *
606  * SYNOPSIS
607  *
608  *    const char *silc_ske_map_status(SilcSKEStatus status);
609  *
610  * DESCRIPTION
611  *
612  *    Utility function to map the `status' into human readable message.
613  *
614  ***/
615 const char *silc_ske_map_status(SilcSKEStatus status);
616
617 #include "silcske_i.h"
618
619 #endif  /* !SILCSKE_H */