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
,
256 const char *buf
, size_t buflen
)
260 res
= shishi_asn1_write (handle
, aprep
, "enc-part.cipher", buf
, buflen
);
261 if (res
!= SHISHI_OK
)
264 res
= shishi_asn1_write_integer (handle
, aprep
, "enc-part.etype", etype
);
265 if (res
!= SHISHI_OK
)
272 shishi_aprep_enc_part_add (Shishi
* handle
,
274 Shishi_asn1 encticketpart
,
275 Shishi_asn1 encapreppart
)
284 res
= shishi_encticketpart_get_key (handle
, encticketpart
, &key
);
285 if (res
!= SHISHI_OK
)
288 res
= shishi_new_a2d (handle
, encapreppart
, &der
, &derlen
);
289 if (res
!= SHISHI_OK
)
291 shishi_error_printf (handle
, "Could not DER encode authenticator: %s\n",
292 shishi_strerror (res
));
296 while ((derlen
% 8) != 0)
302 res
= shishi_encrypt (handle
, key
, SHISHI_KEYUSAGE_ENCAPREPPART
,
303 der
, derlen
, &buf
, &buflen
);
307 if (res
!= SHISHI_OK
)
309 shishi_error_printf (handle
, "APRep encryption failed\n");
313 res
= shishi_aprep_enc_part_set (handle
, aprep
, shishi_key_type (key
),
322 shishi_aprep_enc_part_make (Shishi
* handle
,
324 Shishi_asn1 authenticator
,
325 Shishi_asn1 encticketpart
)
327 Shishi_asn1 encapreppart
= NULL
;
330 encapreppart
= shishi_encapreppart (handle
);
331 if (encapreppart
== NULL
)
333 shishi_error_printf (handle
, "Could not create EncAPRepPart: %s\n",
334 shishi_error (handle
));
335 return SHISHI_ASN1_ERROR
;
338 res
= shishi_encapreppart_time_copy (handle
, encapreppart
, authenticator
);
339 if (res
!= SHISHI_OK
)
341 shishi_error_printf (handle
, "Could not copy time: %s\n",
342 shishi_error (handle
));
346 res
= shishi_aprep_enc_part_add (handle
, aprep
, encticketpart
,
348 if (res
!= SHISHI_OK
)
350 shishi_error_printf (handle
, "Could not add encapreppart: %s\n",
351 shishi_error (handle
));
359 * shishi_aprep_get_enc_part_etype:
360 * @handle: shishi handle as allocated by shishi_init().
361 * @aprep: AP-REP variable to get value from.
362 * @etype: output variable that holds the value.
364 * Extract AP-REP.enc-part.etype.
366 * Return value: Returns SHISHI_OK iff successful.
369 shishi_aprep_get_enc_part_etype (Shishi
* handle
,
370 Shishi_asn1 aprep
, int32_t * etype
)
372 return shishi_asn1_read_int32 (handle
, aprep
, "enc-part.etype", etype
);
376 shishi_aprep_decrypt (Shishi
* handle
,
379 int keyusage
, Shishi_asn1
* encapreppart
)
389 res
= shishi_aprep_get_enc_part_etype (handle
, aprep
, &etype
);
390 if (res
!= SHISHI_OK
)
393 if (etype
!= shishi_key_type (key
))
394 return SHISHI_APREP_BAD_KEYTYPE
;
396 res
= shishi_asn1_read2 (handle
, aprep
, "enc-part.cipher",
397 &cipher
, &cipherlen
);
398 if (res
!= SHISHI_OK
)
401 res
= shishi_decrypt (handle
, key
, keyusage
, cipher
, cipherlen
,
404 if (res
!= SHISHI_OK
)
406 shishi_error_printf (handle
,
407 "APRep decryption failed, wrong password?\n");
411 /* The crypto is so 1980; no length indicator. Trim off pad bytes
412 until we can parse it. */
413 for (i
= 0; i
< 8; i
++)
415 if (VERBOSEASN1 (handle
))
416 printf ("Trying with %d pad in enckdcrep...\n", i
);
418 *encapreppart
= shishi_der2asn1_encapreppart (handle
, &buf
[0],
420 if (*encapreppart
!= NULL
)
424 if (*encapreppart
== NULL
)
426 shishi_error_printf (handle
, "Could not DER decode EncAPRepPart. "
427 "Password probably correct (decrypt ok) though\n");
428 return SHISHI_ASN1_ERROR
;
435 shishi_aprep_verify (Shishi
* handle
,
436 Shishi_asn1 authenticator
, Shishi_asn1 encapreppart
)
438 char *authenticatorctime
;
439 char *encapreppartctime
;
440 int authenticatorcusec
;
441 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 (handle
, authenticator
,
458 &authenticatorctime
);
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 (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
,
485 different
= authenticatorcusec
!= encapreppartcusec
||
486 strcmp (authenticatorctime
, encapreppartctime
) != 0;
488 free (authenticatorctime
);
489 free (encapreppartctime
);
492 return SHISHI_APREP_VERIFY_FAILED
;