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
25 /* Get _shishi_print_armored_data, etc. */
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.
39 shishi_encapreppart (Shishi
* handle
)
42 Shishi_asn1 node
= NULL
;
46 res
= gettimeofday (&tv
, NULL
);
50 node
= shishi_asn1_encapreppart (handle
);
54 res
= shishi_asn1_write (handle
, node
, "ctime",
55 shishi_generalize_time (handle
, time (NULL
)), 0);
59 res
= shishi_encapreppart_cusec_set (handle
, node
, tv
.tv_usec
% 1000000);
63 res
= shishi_asn1_write (handle
, node
, "subkey", NULL
, 0);
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
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.
88 res
= shishi_encapreppart_seqnumber_set (handle
, node
, seqnr
);
95 shishi_asn1_done (handle
, node
);
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
)
154 if (VERBOSE (handle
))
155 printf (_("Writing EncAPRepPart to %s...\n"), filename
);
157 fh
= fopen (filename
, "w");
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
);
168 res
= shishi_encapreppart_save (handle
, fh
, encapreppart
);
169 if (res
!= SHISHI_OK
)
174 return SHISHI_IO_ERROR
;
176 if (VERBOSE (handle
))
177 printf (_("Writing EncAPRepPart to %s...done\n"), filename
);
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
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
)
236 if (VERBOSE (handle
))
237 printf (_("Reading EncAPRepPart from %s...\n"), filename
);
239 fh
= fopen (filename
, "r");
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
);
250 res
= shishi_encapreppart_read (handle
, fh
, encapreppart
);
251 if (res
!= SHISHI_OK
)
256 return SHISHI_IO_ERROR
;
258 if (VERBOSE (handle
))
259 printf (_("Reading EncAPRepPart from %s...done\n"), filename
);
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
)
283 res
= shishi_asn1_read_int32 (handle
, encapreppart
,
284 "subkey.keytype", &keytype
);
285 if (res
!= SHISHI_OK
)
288 res
= shishi_asn1_read (handle
, encapreppart
, "subkey.keyvalue",
290 if (res
!= SHISHI_OK
)
293 if (shishi_cipher_keylen (keytype
) != buflen
)
294 return SHISHI_ENCAPREPPART_BAD_KEYTYPE
;
296 res
= shishi_key_from_value (handle
, keytype
, buf
, key
);
298 if (res
!= 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
)
337 res
= shishi_asn1_write (handle
, encapreppart
, "ctime",
338 t
, SHISHI_GENERALIZEDTIME_LENGTH
);
339 if (res
!= 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
)
361 res
= shishi_asn1_read_uint32 (handle
, encapreppart
, "cusec", cusec
);
362 if (res
!= SHISHI_OK
)
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
)
384 res
= shishi_asn1_write_integer (handle
, encapreppart
, "cusec", cusec
);
385 if (res
!= 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
)
408 res
= shishi_asn1_read_uint32 (handle
, encapreppart
,
409 "seq-number", seqnumber
);
410 if (res
!= SHISHI_OK
)
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
)
431 res
= shishi_asn1_write (handle
, encapreppart
, "seq-number", NULL
, 0);
432 if (res
!= 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
,
455 res
= shishi_asn1_write_uint32 (handle
, encapreppart
,
456 "seq-number", seqnumber
);
457 if (res
!= 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
)
482 res
= shishi_asn1_read (handle
, authenticator
, "cusec", &buf
, &buflen
);
483 if (res
!= SHISHI_OK
)
486 res
= shishi_asn1_write (handle
, encapreppart
, "cusec", buf
, buflen
);
488 if (res
!= SHISHI_OK
)
491 res
= shishi_asn1_read (handle
, authenticator
, "ctime", &buf
, &buflen
);
492 if (res
!= SHISHI_OK
)
495 res
= shishi_asn1_write (handle
, encapreppart
, "ctime", buf
, buflen
);
497 if (res
!= SHISHI_OK
)