updates.
[silc.git] / lib / silcske / silcske.h
1 /*
2
3   silcske.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 - 2001 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20
21 #ifndef SILCSKE_H
22 #define SILCSKE_H
23
24 #include "silcske_status.h"
25
26 /* Forward declaration for SKE object. */
27 typedef struct SilcSKEStruct *SilcSKE;
28
29 /* Forward declaration for security properties. */
30 typedef struct SilcSKESecurityPropertiesStruct *SilcSKESecurityProperties;
31
32 /* Forward declaration for SKE callbacks structure. */
33 typedef struct SilcSKECallbacksStruct *SilcSKECallbacks;
34
35 /* Supported Public Key Types, defined by the protocol */
36 typedef enum {
37   SILC_SKE_PK_TYPE_SILC    = 1, /* Mandatory type */
38   /* Optional types. These are not implemented currently */
39   SILC_SKE_PK_TYPE_SSH2    = 2,
40   SILC_SKE_PK_TYPE_X509V3  = 3,
41   SILC_SKE_PK_TYPE_OPENPGP = 4,
42   SILC_SKE_PK_TYPE_SPKI    = 5
43 } SilcSKEPKType;
44
45 /* Packet sending callback. Caller of the SKE routines must provide
46    a routine to send packets to negotiation parties. See the
47    silc_ske_set_callbacks for more information. */
48 typedef void (*SilcSKESendPacketCb)(SilcSKE ske, SilcBuffer packet, 
49                                     SilcPacketType type, void *context);
50
51 /* Generic SKE callback function. This is called in various SKE
52    routines. The SilcSKE object sent as argument provides all the data
53    callers routine might need (payloads etc). This is usually called
54    to indicate that the application may continue the execution of the
55    SKE protocol. The application should check the ske->status in this
56    callback function. This callback is also called when Start Payload
57    is processed. See silc_ske_set_callbacks function for more information. */
58 typedef void (*SilcSKECb)(SilcSKE ske, void *context);
59
60 /* Completion callback that will be called when the public key
61    has been verified.  The `status' will indicate whether the public
62    key were trusted or not. If the `status' is PENDING then the status
63    is not considered to be available at this moment. In this case the
64    SKE libary will assume that the caller will call this callback again
65    when the status is available. See silc_ske_set_callbacks for more
66    information. */
67 typedef void (*SilcSKEVerifyCbCompletion)(SilcSKE ske,
68                                           SilcSKEStatus status,
69                                           void *context);
70
71 /* Callback function used to verify the received public key or certificate. 
72    The verification process is most likely asynchronous. That's why the
73    application must call the `completion' callback when the verification
74    process has been completed. The library then calls the user callback
75    (SilcSKECb), if it was provided for the function that takes this callback
76    function as argument, to indicate that the SKE protocol may continue. 
77    See silc_ske_set_callbacks for more information. */
78 typedef void (*SilcSKEVerifyCb)(SilcSKE ske, 
79                                 unsigned char *pk_data,
80                                 uint32 pk_len,
81                                 SilcSKEPKType pk_type,
82                                 void *context,
83                                 SilcSKEVerifyCbCompletion completion,
84                                 void *completion_context);
85
86 /* Callback function used to check the version of the remote SKE server.
87    The SKE library will call this function so that the appliation may
88    check its version against the remote host's version. This returns
89    SILC_SKE_STATUS_OK if the version string is Ok, and returns
90    SILC_SKE_STATUS_BAD_VERSION if the version was not acceptable. */
91 typedef SilcSKEStatus (*SilcSKECheckVersion)(SilcSKE ske, 
92                                              unsigned char *version, 
93                                              uint32 len, void *context);
94
95 /* Context passed to key material processing function. The function
96    returns the processed key material into this structure. */
97 typedef struct {
98   unsigned char *send_iv;
99   unsigned char *receive_iv;
100   uint32 iv_len;
101   unsigned char *send_enc_key;
102   unsigned char *receive_enc_key;
103   uint32 enc_key_len;
104   unsigned char *send_hmac_key;
105   unsigned char *receive_hmac_key;
106   uint32 hmac_key_len;
107 } SilcSKEKeyMaterial;
108
109 /* Length of cookie in Start Payload */
110 #define SILC_SKE_COOKIE_LEN 16
111
112 #include "groups.h"
113 #include "payload.h"
114
115 /* Security Property Flags. */
116 typedef enum {
117   SILC_SKE_SP_FLAG_NONE      = 0x00,
118   SILC_SKE_SP_FLAG_NO_REPLY  = 0x01,
119   SILC_SKE_SP_FLAG_PFS       = 0x02,
120   SILC_SKE_SP_FLAG_MUTUAL    = 0x04,
121 } SilcSKESecurityPropertyFlag;
122
123 /* Security Properties negotiated between key exchange parties. This
124    structure is filled from the Key Exchange Start Payload which is used
125    to negotiate what security properties should be used in the
126    communication. */
127 struct SilcSKESecurityPropertiesStruct {
128   unsigned char flags;
129   SilcSKEDiffieHellmanGroup group;
130   SilcPKCS pkcs;
131   SilcCipher cipher;
132   SilcHash hash;
133   SilcHmac hmac;
134   /* XXX SilcZip comp; */
135 };
136
137 struct SilcSKEStruct {
138   /* The connection object. This is initialized by the caller. */
139   SilcSocketConnection sock;
140
141   /* Security properties negotiated */
142   SilcSKESecurityProperties prop;
143
144   /* Key Exchange payloads filled during key negotiation with
145      remote data. Responder may save local data here as well. */
146   SilcSKEStartPayload *start_payload;
147   SilcSKEKEPayload *ke1_payload;
148   SilcSKEKEPayload *ke2_payload;
149
150   /* Temporary copy of the KE Start Payload used in the
151      HASH computation. */
152   SilcBuffer start_payload_copy;
153
154   /* Random number x, 1 < x < q. This is the secret exponent
155      used in Diffie Hellman computations. */
156   SilcMPInt *x;
157   
158   /* The secret shared key */
159   SilcMPInt *KEY;
160   
161   /* The hash value HASH of the key exchange */
162   unsigned char *hash;
163   uint32 hash_len;
164
165   /* Random Number Generator. This is set by the caller and must
166      be free'd by the caller. */
167   SilcRng rng;
168
169   /* Pointer to the what ever user data. This is set by the caller
170      and is not touched by the SKE. The caller must also free this one. */
171   void *user_data;
172
173   /* Current status of SKE */
174   SilcSKEStatus status;
175
176   /* Reference counter. This is used when SKE library is performing async
177      operations, like public key verification. */
178   int users;
179
180   /* SKE callbacks. */
181   SilcSKECallbacks callbacks;
182
183   /* Backwards support version indicator */
184   uint32 backward_version;
185 };
186
187 /* Prototypes */
188 SilcSKE silc_ske_alloc();
189 void silc_ske_free(SilcSKE ske);
190 void silc_ske_set_callbacks(SilcSKE ske,
191                             SilcSKESendPacketCb send_packet,
192                             SilcSKECb payload_receive,
193                             SilcSKEVerifyCb verify_key,
194                             SilcSKECb proto_continue,
195                             SilcSKECheckVersion check_version,
196                             void *context);
197 SilcSKEStatus silc_ske_initiator_start(SilcSKE ske, SilcRng rng,
198                                        SilcSocketConnection sock,
199                                        SilcSKEStartPayload *start_payload);
200 SilcSKEStatus silc_ske_initiator_phase_1(SilcSKE ske, 
201                                          SilcBuffer start_payload);
202 SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
203                                          SilcPublicKey public_key,
204                                          SilcPrivateKey private_key);
205 SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske,
206                                         SilcBuffer ke_payload);
207 SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
208                                        SilcSocketConnection sock,
209                                        char *version,
210                                        SilcBuffer start_payload,
211                                        bool mutual_auth);
212 SilcSKEStatus silc_ske_responder_phase_1(SilcSKE ske, 
213                                          SilcSKEStartPayload *start_payload);
214 SilcSKEStatus silc_ske_responder_phase_2(SilcSKE ske,
215                                          SilcBuffer ke_payload);
216 SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
217                                         SilcPublicKey public_key,
218                                         SilcPrivateKey private_key,
219                                         SilcSKEPKType pk_type);
220 SilcSKEStatus silc_ske_end(SilcSKE ske);
221 SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status);
222 SilcSKEStatus 
223 silc_ske_assemble_security_properties(SilcSKE ske,
224                                       unsigned char flags,
225                                       char *version,
226                                       SilcSKEStartPayload **return_payload);
227 SilcSKEStatus 
228 silc_ske_select_security_properties(SilcSKE ske,
229                                     char *version,
230                                     SilcSKEStartPayload *payload,
231                                     SilcSKEStartPayload *remote_payload);
232 SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n, 
233                                   uint32 len, 
234                                   SilcMPInt *rnd);
235 SilcSKEStatus silc_ske_make_hash(SilcSKE ske, 
236                                  unsigned char *return_hash,
237                                  uint32 *return_hash_len,
238                                  int initiator);
239 SilcSKEStatus 
240 silc_ske_process_key_material_data(unsigned char *data,
241                                    uint32 data_len,
242                                    uint32 req_iv_len,
243                                    uint32 req_enc_key_len,
244                                    uint32 req_hmac_key_len,
245                                    SilcHash hash,
246                                    SilcSKEKeyMaterial *key);
247 SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, 
248                                             uint32 req_iv_len,
249                                             uint32 req_enc_key_len,
250                                             uint32 req_hmac_key_len,
251                                             SilcSKEKeyMaterial *key);
252 void silc_ske_free_key_material(SilcSKEKeyMaterial *key);
253 const char *silc_ske_map_status(SilcSKEStatus status);
254
255 #endif