Remove.
[shishi.git] / lib / encapreppart.c
blob11a03d5694b1e29cdbdb0c006d6840d7ae6dbb76
1 /* encapreppart.c --- Encrypted authentication reply part functions.
2 * Copyright (C) 2002, 2003, 2004, 2006, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
23 #include "internal.h"
25 /* Get _shishi_print_armored_data, etc. */
26 #include "diskio.h"
28 /**
29 * shishi_encapreppart:
30 * @handle: shishi handle as allocated by shishi_init().
32 * This function creates a new EncAPRepPart, populated with some
33 * default values. It uses the current time as returned by the system
34 * for the ctime and cusec fields.
36 * Return value: Returns the encapreppart or NULL on failure.
37 **/
38 Shishi_asn1
39 shishi_encapreppart (Shishi * handle)
41 int res;
42 Shishi_asn1 node = NULL;
43 struct timeval tv;
44 uint32_t seqnr;
46 res = gettimeofday (&tv, NULL);
47 if (res)
48 return NULL;
50 node = shishi_asn1_encapreppart (handle);
51 if (!node)
52 return NULL;
54 res = shishi_asn1_write (handle, node, "ctime",
55 shishi_generalize_time (handle, time (NULL)), 0);
56 if (res != SHISHI_OK)
57 goto error;
59 res = shishi_encapreppart_cusec_set (handle, node, tv.tv_usec % 1000000);
60 if (res != SHISHI_OK)
61 goto error;
63 res = shishi_asn1_write (handle, node, "subkey", NULL, 0);
64 if (res != SHISHI_OK)
65 goto error;
68 * For sequence numbers to adequately support the detection of
69 * replays they SHOULD be non-repeating, even across connection
70 * boundaries. The initial sequence number SHOULD be random and
71 * uniformly distributed across the full space of possible sequence
72 * numbers, so that it cannot be guessed by an attacker and so that
73 * it and the successive sequence numbers do not repeat other
74 * sequences.
76 shishi_randomize (handle, 0, &seqnr, sizeof (seqnr));
79 * Implementation note: as noted before, some implementations omit
80 * the optional sequence number when its value would be zero.
81 * Implementations MAY accept an omitted sequence number when
82 * expecting a value of zero, and SHOULD NOT transmit an
83 * Authenticator with a initial sequence number of zero.
85 if (seqnr == 0)
86 seqnr++;
88 res = shishi_encapreppart_seqnumber_set (handle, node, seqnr);
89 if (res != SHISHI_OK)
90 goto error;
92 return node;
94 error:
95 shishi_asn1_done (handle, node);
96 return NULL;
99 /**
100 * shishi_encapreppart_print:
101 * @handle: shishi handle as allocated by shishi_init().
102 * @fh: file handle open for writing.
103 * @encapreppart: EncAPRepPart to print.
105 * Print ASCII armored DER encoding of EncAPRepPart to file.
107 * Return value: Returns SHISHI_OK iff successful.
110 shishi_encapreppart_print (Shishi * handle, FILE * fh,
111 Shishi_asn1 encapreppart)
113 return _shishi_print_armored_data (handle, fh, encapreppart,
114 "EncAPRepPart", NULL);
118 * shishi_encapreppart_save:
119 * @handle: shishi handle as allocated by shishi_init().
120 * @fh: file handle open for writing.
121 * @encapreppart: EncAPRepPart to save.
123 * Save DER encoding of EncAPRepPart to file.
125 * Return value: Returns SHISHI_OK iff successful.
128 shishi_encapreppart_save (Shishi * handle, FILE * fh,
129 Shishi_asn1 encapreppart)
131 return _shishi_save_data (handle, fh, encapreppart, "EncAPRepPart");
135 * shishi_encapreppart_to_file:
136 * @handle: shishi handle as allocated by shishi_init().
137 * @encapreppart: EncAPRepPart to save.
138 * @filetype: input variable specifying type of file to be written,
139 * see Shishi_filetype.
140 * @filename: input variable with filename to write to.
142 * Write EncAPRepPart to file in specified TYPE. The file will be
143 * truncated if it exists.
145 * Return value: Returns SHISHI_OK iff successful.
148 shishi_encapreppart_to_file (Shishi * handle, Shishi_asn1 encapreppart,
149 int filetype, const char *filename)
151 FILE *fh;
152 int res;
154 if (VERBOSE (handle))
155 printf (_("Writing EncAPRepPart to %s...\n"), filename);
157 fh = fopen (filename, "w");
158 if (fh == NULL)
159 return SHISHI_FOPEN_ERROR;
161 if (VERBOSE (handle))
162 printf (_("Writing EncAPRepPart in %s format...\n"),
163 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
165 if (filetype == SHISHI_FILETYPE_TEXT)
166 res = shishi_encapreppart_print (handle, fh, encapreppart);
167 else
168 res = shishi_encapreppart_save (handle, fh, encapreppart);
169 if (res != SHISHI_OK)
170 return res;
172 res = fclose (fh);
173 if (res != 0)
174 return SHISHI_IO_ERROR;
176 if (VERBOSE (handle))
177 printf (_("Writing EncAPRepPart to %s...done\n"), filename);
179 return SHISHI_OK;
183 * shishi_encapreppart_parse:
184 * @handle: shishi handle as allocated by shishi_init().
185 * @fh: file handle open for reading.
186 * @encapreppart: output variable with newly allocated EncAPRepPart.
188 * Read ASCII armored DER encoded EncAPRepPart from file and populate given
189 * variable.
191 * Return value: Returns SHISHI_OK iff successful.
194 shishi_encapreppart_parse (Shishi * handle, FILE * fh,
195 Shishi_asn1 * encapreppart)
197 return _shishi_encapreppart_input (handle, fh, encapreppart, 0);
201 * shishi_encapreppart_read:
202 * @handle: shishi handle as allocated by shishi_init().
203 * @fh: file handle open for reading.
204 * @encapreppart: output variable with newly allocated EncAPRepPart.
206 * Read DER encoded EncAPRepPart from file and populate given variable.
208 * Return value: Returns SHISHI_OK iff successful.
211 shishi_encapreppart_read (Shishi * handle, FILE * fh,
212 Shishi_asn1 * encapreppart)
214 return _shishi_encapreppart_input (handle, fh, encapreppart, 1);
218 * shishi_encapreppart_from_file:
219 * @handle: shishi handle as allocated by shishi_init().
220 * @encapreppart: output variable with newly allocated EncAPRepPart.
221 * @filetype: input variable specifying type of file to be read,
222 * see Shishi_filetype.
223 * @filename: input variable with filename to read from.
225 * Read EncAPRepPart from file in specified TYPE.
227 * Return value: Returns SHISHI_OK iff successful.
230 shishi_encapreppart_from_file (Shishi * handle, Shishi_asn1 * encapreppart,
231 int filetype, const char *filename)
233 int res;
234 FILE *fh;
236 if (VERBOSE (handle))
237 printf (_("Reading EncAPRepPart from %s...\n"), filename);
239 fh = fopen (filename, "r");
240 if (fh == NULL)
241 return SHISHI_FOPEN_ERROR;
243 if (VERBOSE (handle))
244 printf (_("Reading EncAPRepPart in %s format...\n"),
245 filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");
247 if (filetype == SHISHI_FILETYPE_TEXT)
248 res = shishi_encapreppart_parse (handle, fh, encapreppart);
249 else
250 res = shishi_encapreppart_read (handle, fh, encapreppart);
251 if (res != SHISHI_OK)
252 return res;
254 res = fclose (fh);
255 if (res != 0)
256 return SHISHI_IO_ERROR;
258 if (VERBOSE (handle))
259 printf (_("Reading EncAPRepPart from %s...done\n"), filename);
261 return SHISHI_OK;
265 * shishi_encapreppart_get_key:
266 * @handle: shishi handle as allocated by shishi_init().
267 * @encapreppart: input EncAPRepPart variable.
268 * @key: newly allocated key.
270 * Extract the subkey from the encrypted AP-REP part.
272 * Return value: Returns SHISHI_OK iff succesful.
275 shishi_encapreppart_get_key (Shishi * handle,
276 Shishi_asn1 encapreppart, Shishi_key ** key)
278 int res;
279 char *buf;
280 size_t buflen;
281 int32_t keytype;
283 res = shishi_asn1_read_int32 (handle, encapreppart,
284 "subkey.keytype", &keytype);
285 if (res != SHISHI_OK)
286 return res;
288 res = shishi_asn1_read (handle, encapreppart, "subkey.keyvalue",
289 &buf, &buflen);
290 if (res != SHISHI_OK)
291 return res;
293 if (shishi_cipher_keylen (keytype) != buflen)
294 return SHISHI_ENCAPREPPART_BAD_KEYTYPE;
296 res = shishi_key_from_value (handle, keytype, buf, key);
297 free (buf);
298 if (res != SHISHI_OK)
299 return res;
301 return SHISHI_OK;
305 * shishi_encapreppart_ctime:
306 * @handle: shishi handle as allocated by shishi_init().
307 * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart().
308 * @t: newly allocated zero-terminated character array with client time.
310 * Extract client time from EncAPRepPart.
312 * Return value: Returns SHISHI_OK iff successful.
315 shishi_encapreppart_ctime (Shishi * handle,
316 Shishi_asn1 encapreppart, char **t)
318 return shishi_time (handle, encapreppart, "ctime", t);
322 * shishi_encapreppart_ctime_set:
323 * @handle: shishi handle as allocated by shishi_init().
324 * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart().
325 * @t: string with generalized time value to store in EncAPRepPart.
327 * Store client time in EncAPRepPart.
329 * Return value: Returns SHISHI_OK iff successful.
332 shishi_encapreppart_ctime_set (Shishi * handle,
333 Shishi_asn1 encapreppart, const char *t)
335 int res;
337 res = shishi_asn1_write (handle, encapreppart, "ctime",
338 t, SHISHI_GENERALIZEDTIME_LENGTH);
339 if (res != SHISHI_OK)
340 return res;
342 return SHISHI_OK;
346 * shishi_encapreppart_cusec_get:
347 * @handle: shishi handle as allocated by shishi_init().
348 * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart().
349 * @cusec: output integer with client microseconds field.
351 * Extract client microseconds field from EncAPRepPart.
353 * Return value: Returns SHISHI_OK iff successful.
356 shishi_encapreppart_cusec_get (Shishi * handle,
357 Shishi_asn1 encapreppart, uint32_t * cusec)
359 int res;
361 res = shishi_asn1_read_uint32 (handle, encapreppart, "cusec", cusec);
362 if (res != SHISHI_OK)
363 return res;
365 return res;
369 * shishi_encapreppart_cusec_set:
370 * @handle: shishi handle as allocated by shishi_init().
371 * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart().
372 * @cusec: client microseconds to set in authenticator, 0-999999.
374 * Set the cusec field in the Authenticator.
376 * Return value: Returns SHISHI_OK iff successful.
379 shishi_encapreppart_cusec_set (Shishi * handle,
380 Shishi_asn1 encapreppart, uint32_t cusec)
382 int res;
384 res = shishi_asn1_write_integer (handle, encapreppart, "cusec", cusec);
385 if (res != SHISHI_OK)
386 return res;
388 return SHISHI_OK;
392 * shishi_encapreppart_seqnumber_get:
393 * @handle: shishi handle as allocated by shishi_init().
394 * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart().
395 * @seqnumber: output integer with sequence number field.
397 * Extract sequence number field from EncAPRepPart.
399 * Return value: Returns SHISHI_OK iff successful.
402 shishi_encapreppart_seqnumber_get (Shishi * handle,
403 Shishi_asn1 encapreppart,
404 uint32_t * seqnumber)
406 int res;
408 res = shishi_asn1_read_uint32 (handle, encapreppart,
409 "seq-number", seqnumber);
410 if (res != SHISHI_OK)
411 return res;
413 return res;
417 * shishi_encapreppart_seqnumber_remove:
418 * @handle: shishi handle as allocated by shishi_init().
419 * @encapreppart: encapreppart as allocated by shishi_encapreppart().
421 * Remove sequence number field in EncAPRepPart.
423 * Return value: Returns %SHISHI_OK iff successful.
426 shishi_encapreppart_seqnumber_remove (Shishi * handle,
427 Shishi_asn1 encapreppart)
429 int res;
431 res = shishi_asn1_write (handle, encapreppart, "seq-number", NULL, 0);
432 if (res != SHISHI_OK)
433 return res;
435 return SHISHI_OK;
439 * shishi_encapreppart_seqnumber_set:
440 * @handle: shishi handle as allocated by shishi_init().
441 * @encapreppart: encapreppart as allocated by shishi_encapreppart().
442 * @seqnumber: integer with sequence number field to store in encapreppart.
444 * Store sequence number field in EncAPRepPart.
446 * Return value: Returns %SHISHI_OK iff successful.
449 shishi_encapreppart_seqnumber_set (Shishi * handle,
450 Shishi_asn1 encapreppart,
451 uint32_t seqnumber)
453 int res;
455 res = shishi_asn1_write_uint32 (handle, encapreppart,
456 "seq-number", seqnumber);
457 if (res != SHISHI_OK)
458 return res;
460 return SHISHI_OK;
464 * shishi_encapreppart_time_copy:
465 * @handle: shishi handle as allocated by shishi_init().
466 * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart().
467 * @authenticator: Authenticator to copy time fields from.
469 * Copy time fields from Authenticator into EncAPRepPart.
471 * Return value: Returns SHISHI_OK iff successful.
474 shishi_encapreppart_time_copy (Shishi * handle,
475 Shishi_asn1 encapreppart,
476 Shishi_asn1 authenticator)
478 char *buf;
479 size_t buflen;
480 int res;
482 res = shishi_asn1_read (handle, authenticator, "cusec", &buf, &buflen);
483 if (res != SHISHI_OK)
484 return res;
486 res = shishi_asn1_write (handle, encapreppart, "cusec", buf, buflen);
487 free (buf);
488 if (res != SHISHI_OK)
489 return res;
491 res = shishi_asn1_read (handle, authenticator, "ctime", &buf, &buflen);
492 if (res != SHISHI_OK)
493 return res;
495 res = shishi_asn1_write (handle, encapreppart, "ctime", buf, buflen);
496 free (buf);
497 if (res != SHISHI_OK)
498 return res;
500 return SHISHI_OK;