~ubuntu-branches/ubuntu/trusty/ocamlnet/trusty

« back to all changes in this revision

Viewing changes to src/netmech-scram/netmech_scram.mli

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu
  • Date: 2011-09-02 14:12:33 UTC
  • mfrom: (18.2.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110902141233-zbj0ygxb92u6gy4z
Tags: 3.4-1
* New upstream release
  - add a new NetcgiRequire directive to ease dependency management
    (Closes: #637147)
  - remove patches that were applied upstream:
    + Added-missing-shebang-lines-in-example-shell-scripts
    + Try-also-ocamlc-for-POSIX-threads

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(* $Id: netmech_scram.mli 1560 2011-03-04 22:05:14Z gerd $ *)
 
2
 
 
3
(** SCRAM mechanism for authentication (RFC 5802) *)
 
4
 
 
5
(** This implements SCRAM-SHA-1 for GSSAPI. Other profiles may be added later.
 
6
 
 
7
    As we do not implement SASLprep, usernames and passwords are restricted
 
8
    to US-ASCII.
 
9
 *)
 
10
 
 
11
type ptype = [ `GSSAPI ]
 
12
  (** Currently only the variant for [`GSSAPI] is supported *)
 
13
 
 
14
type mechanism = [ `SHA_1 ]
 
15
 
 
16
type profile =
 
17
    { ptype : ptype;
 
18
      mechanism : mechanism;       (** Which mechanism *)
 
19
      return_unknown_user : bool;  (** Whether servers exhibit the fact that the
 
20
                                       user is unknown *)
 
21
      iteration_count_limit : int; (** Largest supported iteration number *)
 
22
    }
 
23
  (** Profile *)
 
24
 
 
25
 
 
26
type server_error =
 
27
    [ `Invalid_encoding
 
28
    | `Extensions_not_supported
 
29
    | `Invalid_proof
 
30
    | `Channel_bindings_dont_match
 
31
    | `Server_does_support_channel_binding
 
32
    | `Channel_binding_not_supported
 
33
    | `Unsupported_channel_binding_type
 
34
    | `Unknown_user
 
35
    | `Invalid_username_encoding
 
36
    | `No_resources
 
37
    | `Other_error
 
38
    | `Extension of string
 
39
    ]
 
40
  (** Error codes of this protocol *)
 
41
 
 
42
type client_session
 
43
  (** Session context for clients *)
 
44
 
 
45
 
 
46
type server_session
 
47
  (** Session context for servers *)
 
48
 
 
49
 
 
50
exception Invalid_encoding of string * string
 
51
  (** Raised by clients when something cannot be decoded. First string
 
52
      is an error message, the second string the raw message that cannot
 
53
      be decoded
 
54
   *)
 
55
 
 
56
exception Invalid_username_encoding of string * string
 
57
  (** Raised by clients when the username does not match the requirements.
 
58
      Arguments as for [Invalid_encoding].
 
59
   *)
 
60
 
 
61
exception Extensions_not_supported of string * string
 
62
  (** Raised by clients when the server enables an unsupported extension.
 
63
      Arguments as for [Invalid_encoding].
 
64
   *)
 
65
 
 
66
exception Protocol_error of string
 
67
  (** Raised by clients when the server violates the protocol. The argument
 
68
      is a message.
 
69
   *)
 
70
 
 
71
exception Invalid_server_signature
 
72
  (** Raised by clients when the signature sent by the server is invalid
 
73
      (i.e. the server does not know the client password)
 
74
   *)
 
75
 
 
76
exception Server_error of server_error
 
77
  (** Raised by clients when the server sent an error code *)
 
78
 
 
79
 
 
80
val profile : ?return_unknown_user:bool -> ?iteration_count_limit:int ->
 
81
              ptype -> profile
 
82
  (** Creates a profile *)
 
83
 
 
84
val string_of_server_error : server_error -> string
 
85
val server_error_of_string : string -> server_error
 
86
  (** Conversion *)
 
87
 
 
88
 
 
89
(** {2 Clients} *)
 
90
 
 
91
(** The idea is to create a client session [s] first. The functions
 
92
    [client_emit_flag] and [client_recv_flag] indicate now whether
 
93
    the client needs to emit a new message, or whether it needs to
 
94
    receive a message, respectively. Emission is done by [client_emit_message],
 
95
    reception by [client_recv_message]. If everything goes well, the
 
96
    protocol state advances, and finally [client_finish_flag] is true.
 
97
    This indicates that the client is authenticated and that the server
 
98
    knows the client's password. If an error occurs, an exception is
 
99
    raised (see above for possibilities), and [client_error_flag] signals
 
100
    [true].
 
101
 *)
 
102
 
 
103
val create_client_session : profile -> string -> string -> client_session
 
104
  (** [create_client_session p username password]: Creates a new client
 
105
      session for profile [p] so that the client authenticates as user
 
106
      [username], and proves its identify with the given [password].
 
107
   *)
 
108
 
 
109
val client_configure_channel_binding : client_session -> string -> unit
 
110
  (** Instruct the client to require a channel binding. The passed string
 
111
      is the [c] parameter (before encoding it via Base64. The function
 
112
      needs to be called before sending the second message to the server.
 
113
      It fails if called too late.
 
114
   *)
 
115
(* SASL: The string would have to include the gs2-header. For a SASL-enabled
 
116
   profile we would need some additional functions
 
117
   (client_negotiate_channel_binding).
 
118
 *)
 
119
 
 
120
val client_emit_flag : client_session -> bool
 
121
  (** Whether [client_emit_message] can now be called *)
 
122
 
 
123
val client_recv_flag : client_session -> bool
 
124
  (** Whether [client_recv_message] can now be called *)
 
125
 
 
126
val client_finish_flag : client_session -> bool
 
127
  (** Whether the client is authenticated and the server verified *)
 
128
 
 
129
val client_error_flag : client_session -> bool
 
130
  (** Whether an error occurred, and the protocol cannot advance anymore *)
 
131
 
 
132
val client_channel_binding : client_session -> string
 
133
  (** Returns the channel binding ("" of none) *)
 
134
 
 
135
val client_emit_message : client_session -> string
 
136
  (** Emits the next message to be sent to the server *)
 
137
 
 
138
val client_recv_message : client_session -> string -> unit
 
139
  (** Receives the next message from the server *)
 
140
 
 
141
val client_protocol_key : client_session -> string option
 
142
  (** The 128-bit protocol key for encrypting messages. This is available 
 
143
      as soon as the second client message is emitted.
 
144
   *)
 
145
 
 
146
val client_user_name : client_session -> string
 
147
  (** The user name *)
 
148
 
 
149
val client_export : client_session -> string
 
150
val client_import : string -> client_session
 
151
  (** Exports a client session as string, and imports the string again.
 
152
      Only established sessions are allowed to be exported
 
153
      (for which [client_finish_flag] is true).
 
154
 
 
155
      The export format is just a marshalled Ocaml value.
 
156
   *)
 
157
 
 
158
 
 
159
(** {2 Servers} *)
 
160
 
 
161
(** The idea is to create a server session [s] first. The functions
 
162
    [server_emit_flag] and [server_recv_flag] indicate now whether
 
163
    the server needs to emit a new message, or whether it needs to
 
164
    receive a message, respectively. Emission is done by [server_emit_message],
 
165
    reception by [server_recv_message]. If everything goes well, the
 
166
    protocol state advances, and finally [server_finish_flag] is true.
 
167
    This indicates that the client could be authenticated.
 
168
 
 
169
    If an error occurs, {b no} exception is raised, and the protocol
 
170
    advances nevertheless, and finally the server sends an error token
 
171
    to the client. After this, [server_error_flag] returns true.
 
172
 *)
 
173
 
 
174
 
 
175
val create_server_session : 
 
176
      profile -> (string -> string * string * int) -> server_session
 
177
  (** [create_server_session p auth]: Creates a new server session with
 
178
      profile [p] and authenticator function [auth].
 
179
 
 
180
      The function is [auth] is called when the credentials of the
 
181
      client have been received to check whether the client can be
 
182
      authenticated. It is called as
 
183
 
 
184
      {[
 
185
      let (salted_password, salt, iteration_count) = auth username
 
186
      ]}
 
187
 
 
188
      where [username] is the user name. The function can now raise
 
189
      [Not_found] if the user is unknown, or it can return the
 
190
      shown triple. Note that the cleartext password needs not to
 
191
      be known. [salt] is a random string, and [iteration_count] a
 
192
      security parameter that should be at least 4096. Whereas [salt]
 
193
      should be different for each user, the [iteration_count] can be
 
194
      chosen as a constant (e.g. 4096). Now [salted_password] can be
 
195
      computed from the cleartext password and these two extra parameters.
 
196
      See [salt_password] below.
 
197
   *)
 
198
 
 
199
val create_salt : unit -> string
 
200
  (** Creates a random string suited as salt *)
 
201
 
 
202
val salt_password : string -> string -> int -> string
 
203
  (** [let salted_password = salt_password password salt iteration_count]
 
204
 
 
205
      As we do not implement [SASLprep] only passwords consisting of
 
206
      US-ASCII characters are accepted ([Invalid_encoding] otherwise).
 
207
   *)
 
208
 
 
209
val server_emit_flag : server_session -> bool
 
210
  (** Whether [server_emit_message] can now be called *)
 
211
 
 
212
val server_recv_flag : server_session -> bool
 
213
  (** Whether [server_recv_message] can now be called *)
 
214
 
 
215
val server_finish_flag : server_session -> bool
 
216
  (** Whether the client is authenticated *)
 
217
 
 
218
val server_error_flag : server_session -> bool
 
219
  (** Whether an error occurred, and the protocol cannot advance anymore *)
 
220
 
 
221
val server_emit_message : server_session -> string
 
222
  (** Emits the next message to be sent to the client *)
 
223
 
 
224
val server_recv_message : server_session -> string -> unit
 
225
  (** Receives the next message from the client *)
 
226
 
 
227
val server_protocol_key : server_session -> string option
 
228
  (** The 128-bit protocol key for encrypting messages. This is available 
 
229
      as soon as the second client message has been received.
 
230
   *)
 
231
 
 
232
val server_channel_binding : server_session -> string option
 
233
  (** Returns the channel binding requirement (the "c" parameter). It is
 
234
      up to the application to enforce the binding. This information is 
 
235
      available as soon as the second client message has been received
 
236
   *)
 
237
 
 
238
val server_user_name : server_session -> string option
 
239
  (** The user name as transmitted from the client. This is returned here
 
240
      even before the authentication is completed!
 
241
   *)
 
242
 
 
243
val server_export : server_session -> string
 
244
val server_import : string -> server_session
 
245
  (** Exports a server session as string, and imports the string again.
 
246
      Only established sessions are allowed to be exported
 
247
      (for which [server_finish_flag] is true).
 
248
 
 
249
      The export format is just a marshalled Ocaml value.
 
250
   *)
 
251
 
 
252
 
 
253
(** {2 Confidentiality} *)
 
254
 
 
255
type specific_keys =
 
256
    { kc : string;
 
257
      ke : string;
 
258
      ki : string
 
259
    }
 
260
  (** The specific keys to use *)
 
261
 
 
262
(** This module implements AES in Ciphertext Stealing mode (see RFC 3962) *)
 
263
module AES_CTS : sig
 
264
  val c : int
 
265
  val m : int
 
266
  val encrypt : string -> string -> string
 
267
  val encrypt_mstrings : 
 
268
    string -> Xdr_mstring.mstring list -> Xdr_mstring.mstring list
 
269
  val decrypt : string -> string -> string
 
270
  val decrypt_mstrings : 
 
271
    string -> Xdr_mstring.mstring list -> Xdr_mstring.mstring list
 
272
  val tests : (string * string * string) list
 
273
  val run_tests : unit -> bool
 
274
  val run_mtests : unit -> bool
 
275
end
 
276
 
 
277
 
 
278
(** This is the cryptosystem as defined in RFC 3961, so far needed here.
 
279
    This uses [AES_CTS] as cipher, and SHA1-96 for signing.
 
280
 *)
 
281
module Cryptosystem : sig
 
282
  exception Integrity_error
 
283
 
 
284
  val derive_keys : string -> int -> specific_keys
 
285
    (** [derive_keys protocol_key usage]: Returns the specific keys for
 
286
        this [protocol_key] and this [usage] numbers. See RFC 4121 for
 
287
        applicable usage numbers
 
288
     *)
 
289
 
 
290
  val encrypt_and_sign :  specific_keys -> string -> string
 
291
    (** Encrypts the plaintext message and adds a signature to the
 
292
        ciphertext.
 
293
 
 
294
        Returns [ciphertext_with_signature].
 
295
     *)
 
296
 
 
297
  val encrypt_and_sign_mstrings : 
 
298
         specific_keys -> Xdr_mstring.mstring list -> Xdr_mstring.mstring list
 
299
    (** Same, but with data representation as [mstring list] *)
 
300
 
 
301
  val decrypt_and_verify :  specific_keys -> string -> string
 
302
    (** Decrypts the ciphertext and verifies the attached signature.
 
303
        Returns the restored plaintext. 
 
304
 
 
305
        For very short plaintexts (< 16 bytes) there will be some
 
306
        padding at the end ("residue"), as returned as [ec] above.
 
307
        We ignore this problem generally,
 
308
        because GSS-API adds a 16-byte header to the plaintext anyway,
 
309
        so these short messages do not occur.
 
310
 
 
311
        If the signature is not valid, the exception [Integrity_error]
 
312
        is raised.
 
313
     *)
 
314
 
 
315
  val decrypt_and_verify_mstrings :
 
316
         specific_keys -> Xdr_mstring.mstring list -> Xdr_mstring.mstring list
 
317
    (** Same, but with data representation as [mstring list] *)
 
318
 
 
319
  val get_ec : specific_keys -> int -> int
 
320
    (** [let ec = get_ec e_keys n]:
 
321
        Returns the required value for the "extra count" field of
 
322
        RFC 4121 if the plaintext message has size [n]. Here,
 
323
        [n] is the size of the payload message plus the token
 
324
        header of 16 bytes, i.e. the function is always called with
 
325
        [n >= 16].
 
326
 
 
327
        Here, the returned [ec] value is always 0.
 
328
     *)
 
329
 
 
330
  val get_mic : specific_keys -> string -> string
 
331
    (** Returns a message integrity code *)
 
332
 
 
333
  val get_mic_mstrings :
 
334
         specific_keys -> Xdr_mstring.mstring list -> string
 
335
    (** Same, but with data representation as [mstring list] *)
 
336
end
 
337
 
 
338
 
 
339
module Debug : sig
 
340
  val enable : bool ref
 
341
    (** Enable debugging of this module *)
 
342
end