1 /* aprep.c AP-REP functions
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define SHISHI_APREP_DEFAULT_PVNO "5"
25 #define SHISHI_APREP_DEFAULT_PVNO_LEN 0
26 #define SHISHI_APREP_DEFAULT_MSG_TYPE "15" /* KRB_AP_REP */
27 #define SHISHI_APREP_DEFAULT_MSG_TYPE_LEN 0
28 #define SHISHI_APREP_DEFAULT_ENC_PART_ETYPE "0"
29 #define SHISHI_APREP_DEFAULT_ENC_PART_ETYPE_LEN 0
30 #define SHISHI_APREP_DEFAULT_ENC_PART_KVNO "0"
31 #define SHISHI_APREP_DEFAULT_ENC_PART_KVNO_LEN 0
32 #define SHISHI_APREP_DEFAULT_ENC_PART_CIPHER ""
33 #define SHISHI_APREP_DEFAULT_ENC_PART_CIPHER_LEN 0
37 * @handle: shishi handle as allocated by shishi_init().
39 * This function creates a new AP-REP, populated with some default
42 * Return value: Returns the authenticator or NULL on
46 shishi_aprep (Shishi
* handle
)
51 node
= shishi_asn1_aprep (handle
);
55 res
= shishi_asn1_write (handle
, node
, "pvno",
56 SHISHI_APREP_DEFAULT_PVNO
,
57 SHISHI_APREP_DEFAULT_PVNO_LEN
);
61 res
= shishi_asn1_write (handle
, node
, "msg-type",
62 SHISHI_APREP_DEFAULT_MSG_TYPE
,
63 SHISHI_APREP_DEFAULT_MSG_TYPE_LEN
);
67 res
= shishi_asn1_write (handle
, node
, "enc-part.etype",
68 SHISHI_APREP_DEFAULT_ENC_PART_ETYPE
,
69 SHISHI_APREP_DEFAULT_ENC_PART_ETYPE_LEN
);
73 res
= shishi_asn1_write (handle
, node
, "enc-part.kvno",
74 SHISHI_APREP_DEFAULT_ENC_PART_KVNO
,
75 SHISHI_APREP_DEFAULT_ENC_PART_KVNO_LEN
);
79 res
= shishi_asn1_write (handle
, node
, "enc-part.cipher",
80 SHISHI_APREP_DEFAULT_ENC_PART_CIPHER
,
81 SHISHI_APREP_DEFAULT_ENC_PART_CIPHER_LEN
);
88 shishi_asn1_done (handle
, node
);
94 * @handle: shishi handle as allocated by shishi_init().
95 * @fh: file handle open for writing.
96 * @aprep: AP-REP to print.
98 * Print ASCII armored DER encoding of AP-REP to file.
100 * Return value: Returns SHISHI_OK iff successful.
103 shishi_aprep_print (Shishi
* handle
, FILE * fh
, Shishi_asn1 aprep
)
105 return _shishi_print_armored_data (handle
, fh
, aprep
, "AP-REP", NULL
);
110 * @handle: shishi handle as allocated by shishi_init().
111 * @fh: file handle open for writing.
112 * @aprep: AP-REP to save.
114 * Save DER encoding of AP-REP to file.
116 * Return value: Returns SHISHI_OK iff successful.
119 shishi_aprep_save (Shishi
* handle
, FILE * fh
, Shishi_asn1 aprep
)
121 return _shishi_save_data (handle
, fh
, aprep
, "AP-REP");
125 * shishi_aprep_to_file:
126 * @handle: shishi handle as allocated by shishi_init().
127 * @aprep: AP-REP to save.
128 * @filetype: input variable specifying type of file to be written,
129 * see Shishi_filetype.
130 * @filename: input variable with filename to write to.
132 * Write AP-REP to file in specified TYPE. The file will be
133 * truncated if it exists.
135 * Return value: Returns SHISHI_OK iff successful.
138 shishi_aprep_to_file (Shishi
* handle
, Shishi_asn1 aprep
,
139 int filetype
, char *filename
)
144 if (VERBOSE (handle
))
145 printf (_("Writing AP-REP to %s...\n"), filename
);
147 fh
= fopen (filename
, "w");
149 return SHISHI_FOPEN_ERROR
;
151 if (VERBOSE (handle
))
152 printf (_("Writing AP-REP in %s format...\n"),
153 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
155 if (filetype
== SHISHI_FILETYPE_TEXT
)
156 res
= shishi_aprep_print (handle
, fh
, aprep
);
158 res
= shishi_aprep_save (handle
, fh
, aprep
);
159 if (res
!= SHISHI_OK
)
164 return SHISHI_FCLOSE_ERROR
;
166 if (VERBOSE (handle
))
167 printf (_("Writing AP-REP to %s...done\n"), filename
);
173 * shishi_aprep_parse:
174 * @handle: shishi handle as allocated by shishi_init().
175 * @fh: file handle open for reading.
176 * @aprep: output variable with newly allocated AP-REP.
178 * Read ASCII armored DER encoded AP-REP from file and populate given
181 * Return value: Returns SHISHI_OK iff successful.
184 shishi_aprep_parse (Shishi
* handle
, FILE * fh
, Shishi_asn1
* aprep
)
186 return _shishi_aprep_input (handle
, fh
, aprep
, 0);
191 * @handle: shishi handle as allocated by shishi_init().
192 * @fh: file handle open for reading.
193 * @aprep: output variable with newly allocated AP-REP.
195 * Read DER encoded AP-REP from file and populate given variable.
197 * Return value: Returns SHISHI_OK iff successful.
200 shishi_aprep_read (Shishi
* handle
, FILE * fh
, Shishi_asn1
* aprep
)
202 return _shishi_aprep_input (handle
, fh
, aprep
, 1);
206 * shishi_aprep_from_file:
207 * @handle: shishi handle as allocated by shishi_init().
208 * @aprep: output variable with newly allocated AP-REP.
209 * @filetype: input variable specifying type of file to be read,
210 * see Shishi_filetype.
211 * @filename: input variable with filename to read from.
213 * Read AP-REP from file in specified TYPE.
215 * Return value: Returns SHISHI_OK iff successful.
218 shishi_aprep_from_file (Shishi
* handle
, Shishi_asn1
* aprep
,
219 int filetype
, char *filename
)
224 if (VERBOSE (handle
))
225 printf (_("Reading AP-REP from %s...\n"), filename
);
227 fh
= fopen (filename
, "r");
229 return SHISHI_FOPEN_ERROR
;
231 if (VERBOSE (handle
))
232 printf (_("Reading AP-REP in %s format...\n"),
233 filetype
== SHISHI_FILETYPE_TEXT
? "TEXT" : "DER");
235 if (filetype
== SHISHI_FILETYPE_TEXT
)
236 res
= shishi_aprep_parse (handle
, fh
, aprep
);
238 res
= shishi_aprep_read (handle
, fh
, aprep
);
239 if (res
!= SHISHI_OK
)
244 return SHISHI_FCLOSE_ERROR
;
246 if (VERBOSE (handle
))
247 printf (_("Reading AP-REP from %s...done\n"), filename
);
253 shishi_aprep_enc_part_set (Shishi
* handle
,
255 int etype
, const char *buf
, int buflen
)
260 res
= shishi_asn1_write (handle
, aprep
, "enc-part.cipher",
262 if (res
!= SHISHI_OK
)
265 sprintf (format
, "%d", etype
);
266 res
= shishi_asn1_write (handle
, aprep
, "enc-part.etype", format
, 0);
267 if (res
!= SHISHI_OK
)
274 shishi_aprep_enc_part_add (Shishi
* handle
,
276 Shishi_asn1 encticketpart
,
277 Shishi_asn1 encapreppart
)
286 res
= shishi_encticketpart_get_key (handle
, encticketpart
, &key
);
287 if (res
!= SHISHI_OK
)
290 res
= shishi_a2d (handle
, encapreppart
, der
, &derlen
);
291 if (res
!= SHISHI_OK
)
293 shishi_error_printf (handle
, "Could not DER encode authenticator: %s\n",
294 shishi_strerror (res
));
298 while ((derlen
% 8) != 0)
305 res
= shishi_encrypt (handle
, key
, SHISHI_KEYUSAGE_ENCAPREPPART
,
306 der
, derlen
, buf
, &buflen
);
307 if (res
!= SHISHI_OK
)
309 shishi_error_printf (handle
, "des_encrypt fail\n");
313 res
= shishi_aprep_enc_part_set (handle
, aprep
, shishi_key_type (key
),
320 shishi_aprep_enc_part_make (Shishi
* handle
,
322 Shishi_asn1 authenticator
,
323 Shishi_asn1 encticketpart
)
325 Shishi_asn1 encapreppart
= NULL
;
328 encapreppart
= shishi_encapreppart (handle
);
329 if (encapreppart
== NULL
)
331 shishi_error_printf (handle
, "Could not create EncAPRepPart: %s\n",
332 shishi_strerror_details (handle
));
333 return SHISHI_ASN1_ERROR
;
336 res
= shishi_encapreppart_time_copy (handle
, encapreppart
, authenticator
);
337 if (res
!= SHISHI_OK
)
339 shishi_error_printf (handle
, "Could not copy time: %s\n",
340 shishi_strerror_details (handle
));
344 res
= shishi_aprep_enc_part_add (handle
, aprep
, encticketpart
,
346 if (res
!= SHISHI_OK
)
348 shishi_error_printf (handle
, "Could not add encapreppart: %s\n",
349 shishi_strerror_details (handle
));
357 * shishi_aprep_get_enc_part_etype:
358 * @handle: shishi handle as allocated by shishi_init().
359 * @aprep: AP-REP variable to get value from.
360 * @etype: output variable that holds the value.
362 * Extract AP-REP.enc-part.etype.
364 * Return value: Returns SHISHI_OK iff successful.
367 shishi_aprep_get_enc_part_etype (Shishi
* handle
, Shishi_asn1 aprep
,
370 return shishi_asn1_integer_field (handle
, aprep
, etype
,
375 shishi_aprep_decrypt (Shishi
* handle
,
378 int keyusage
, Shishi_asn1
* encapreppart
)
382 size_t buflen
= BUFSIZ
;
388 res
= shishi_aprep_get_enc_part_etype (handle
, aprep
, &etype
);
389 if (res
!= SHISHI_OK
)
392 if (etype
!= shishi_key_type (key
))
393 return SHISHI_APREP_BAD_KEYTYPE
;
396 res
= shishi_asn1_field (handle
, aprep
, cipher
, &cipherlen
,
398 if (res
!= SHISHI_OK
)
401 res
= shishi_decrypt (handle
, key
, keyusage
, cipher
, cipherlen
,
403 if (res
!= SHISHI_OK
)
405 if (VERBOSE (handle
))
406 printf ("decrypt failed: %s\n", shishi_strerror_details (handle
));
407 shishi_error_printf (handle
,
408 "decrypt fail, most likely wrong password\n");
412 /* The crypto is so 1980; no length indicator. Trim off pad bytes
413 until we can parse it. */
414 for (i
= 0; i
< 8; i
++)
416 if (VERBOSEASN1 (handle
))
417 printf ("Trying with %d pad in enckdcrep...\n", i
);
419 *encapreppart
= shishi_der2asn1_encapreppart (handle
, &buf
[0],
421 if (*encapreppart
!= NULL
)
425 if (*encapreppart
== NULL
)
427 shishi_error_printf (handle
, "Could not DER decode EncAPRepPart. "
428 "Password probably correct (decrypt ok) though\n");
429 return SHISHI_ASN1_ERROR
;
436 shishi_aprep_verify (Shishi
* handle
,
437 Shishi_asn1 authenticator
, Shishi_asn1 encapreppart
)
439 char authenticatorctime
[GENERALIZEDTIME_TIME_LEN
+ 1];
440 char encapreppartctime
[GENERALIZEDTIME_TIME_LEN
+ 1];
441 int authenticatorcusec
;
442 int encapreppartcusec
;
446 3.2.5. Receipt of KRB_AP_REP message
448 If a KRB_AP_REP message is returned, the client uses the session key from
449 the credentials obtained for the server[3.10] to decrypt the message, and
450 verifies that the timestamp and microsecond fields match those in the
451 Authenticator it sent to the server. If they match, then the client is
452 assured that the server is genuine. The sequence number and subkey (if
453 present) are retained for later use.
457 res
= shishi_authenticator_ctime_get (handle
, authenticator
,
459 if (res
!= SHISHI_OK
)
462 res
= shishi_authenticator_cusec_get (handle
, authenticator
,
463 &authenticatorcusec
);
464 if (res
!= SHISHI_OK
)
467 res
= shishi_encapreppart_ctime_get (handle
, encapreppart
,
469 if (res
!= SHISHI_OK
)
472 res
= shishi_encapreppart_cusec_get (handle
, encapreppart
,
474 if (res
!= SHISHI_OK
)
477 if (VERBOSE (handle
))
479 printf ("authenticator cusec %08x ctime %s\n", authenticatorcusec
,
481 printf ("encapreppart cusec %08x ctime %s\n", encapreppartcusec
,
486 if (authenticatorcusec
!= encapreppartcusec
||
487 strcmp (authenticatorctime
, encapreppartctime
) != 0)
488 return SHISHI_APREP_VERIFY_FAILED
;