updates.
[silc.git] / lib / silcske / silcske.h
1 /*
2
3   silcske.h
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
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 *hmac_key;
105   uint32 hmac_key_len;
106 } SilcSKEKeyMaterial;
107
108 /* Length of cookie in Start Payload */
109 #define SILC_SKE_COOKIE_LEN 16
110
111 #include "groups.h"
112 #include "payload.h"
113
114 /* Security Property Flags. */
115 typedef enum {
116   SILC_SKE_SP_FLAG_NONE      = 0x00,
117   SILC_SKE_SP_FLAG_NO_REPLY  = 0x01,
118   SILC_SKE_SP_FLAG_PFS       = 0x02,
119   SILC_SKE_SP_FLAG_MUTUAL    = 0x04,
120 } SilcSKESecurityPropertyFlag;
121
122 /* Security Properties negotiated between key exchange parties. This
123    structure is filled from the Key Exchange Start Payload which is used
124    to negotiate what security properties should be used in the
125    communication. */
126 struct SilcSKESecurityPropertiesStruct {
127   unsigned char flags;
128   SilcSKEDiffieHellmanGroup group;
129   SilcPKCS pkcs;
130   SilcCipher cipher;
131   SilcHash hash;
132   SilcHmac hmac;
133   /* XXX SilcZip comp; */
134 };
135
136 struct SilcSKEStruct {
137   /* The connection object. This is initialized by the caller. */
138   SilcSocketConnection sock;
139
140   /* Security properties negotiated */
141   SilcSKESecurityProperties prop;
142
143   /* Key Exchange payloads filled during key negotiation with
144      remote data. Responder may save local data here as well. */
145   SilcSKEStartPayload *start_payload;
146   SilcSKEKEPayload *ke1_payload;
147   SilcSKEKEPayload *ke2_payload;
148
149   /* Temporary copy of the KE Start Payload used in the
150      HASH computation. */
151   SilcBuffer start_payload_copy;
152
153   /* If initiator, this is responders public key. If responder this
154      is our own public key. */
155   unsigned char *pk;
156   uint32 pk_len;
157
158   /* Random number x, 1 < x < q. This is the secret exponent
159      used in Diffie Hellman computations. */
160   SilcMPInt *x;
161   
162   /* The secret shared key */
163   SilcMPInt *KEY;
164   
165   /* The hash value HASH of the key exchange */
166   unsigned char *hash;
167   uint32 hash_len;
168
169   /* Random Number Generator. This is set by the caller and must
170      be free'd by the caller. */
171   SilcRng rng;
172
173   /* Pointer to the what ever user data. This is set by the caller
174      and is not touched by the SKE. The caller must also free this one. */
175   void *user_data;
176
177   /* Current status of SKE */
178   SilcSKEStatus status;
179
180   /* Reference counter. This is used when SKE library is performing async
181      operations, like public key verification. */
182   int users;
183
184   /* SKE callbacks. */
185   SilcSKECallbacks callbacks;
186 };
187
188 /* Prototypes */
189 SilcSKE silc_ske_alloc();
190 void silc_ske_free(SilcSKE ske);
191 void silc_ske_set_callbacks(SilcSKE ske,
192                             SilcSKESendPacketCb send_packet,
193                             SilcSKECb payload_receive,
194                             SilcSKEVerifyCb verify_key,
195                             SilcSKECb proto_continue,
196                             SilcSKECheckVersion check_version,
197                             void *context);
198 SilcSKEStatus silc_ske_initiator_start(SilcSKE ske, SilcRng rng,
199                                        SilcSocketConnection sock,
200                                        SilcSKEStartPayload *start_payload);
201 SilcSKEStatus silc_ske_initiator_phase_1(SilcSKE ske, 
202                                          SilcBuffer start_payload);
203 SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
204                                          SilcPublicKey public_key,
205                                          SilcPrivateKey private_key);
206 SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske,
207                                         SilcBuffer ke_payload);
208 SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
209                                        SilcSocketConnection sock,
210                                        char *version,
211                                        SilcBuffer start_payload,
212                                        bool mutual_auth);
213 SilcSKEStatus silc_ske_responder_phase_1(SilcSKE ske, 
214                                          SilcSKEStartPayload *start_payload);
215 SilcSKEStatus silc_ske_responder_phase_2(SilcSKE ske,
216                                          SilcBuffer ke_payload);
217 SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
218                                         SilcPublicKey public_key,
219                                         SilcPrivateKey private_key,
220                                         SilcSKEPKType pk_type);
221 SilcSKEStatus silc_ske_end(SilcSKE ske);
222 SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status);
223 SilcSKEStatus 
224 silc_ske_assemble_security_properties(SilcSKE ske,
225                                       unsigned char flags,
226                                       char *version,
227                                       SilcSKEStartPayload **return_payload);
228 SilcSKEStatus 
229 silc_ske_select_security_properties(SilcSKE ske,
230                                     char *version,
231                                     SilcSKEStartPayload *payload,
232                                     SilcSKEStartPayload *remote_payload);
233 SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt n, 
234                                   uint32 len, 
235                                   SilcMPInt *rnd);
236 SilcSKEStatus silc_ske_make_hash(SilcSKE ske, 
237                                  unsigned char *return_hash,
238                                  uint32 *return_hash_len,
239                                  int initiator);
240 SilcSKEStatus 
241 silc_ske_process_key_material_data(unsigned char *data,
242                                    uint32 data_len,
243                                    uint32 req_iv_len,
244                                    uint32 req_enc_key_len,
245                                    uint32 req_hmac_key_len,
246                                    SilcHash hash,
247                                    SilcSKEKeyMaterial *key);
248 SilcSKEStatus silc_ske_process_key_material(SilcSKE ske, 
249                                             uint32 req_iv_len,
250                                             uint32 req_enc_key_len,
251                                             uint32 req_hmac_key_len,
252                                             SilcSKEKeyMaterial *key);
253 void silc_ske_free_key_material(SilcSKEKeyMaterial *key);
254
255 #endif