1 /* ap.c --- AP functions
2  * Copyright (C) 2002-2013 Simon Josefsson
3  *
4  * This file is part of Shishi.
5  *
6  * Shishi is free software; you can redistribute it and/or modify it 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.
10  *
11  * Shishi is distributed in the hope that it will be useful, but but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
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
20  *
21  */
22 
23 #include "internal.h"
24 
25 struct Shishi_ap
26 {
27   Shishi *handle;
28   Shishi_tkt *tkt;
29   Shishi_key *key;
30   Shishi_asn1 authenticator;
31   Shishi_asn1 apreq;
32   Shishi_asn1 aprep;
33   Shishi_asn1 encapreppart;
34   /* Key usage for encryption entire Authenticator ASN.1 blob, stored
35      in AP-REQ. */
36   int authenticatorkeyusage;
37   /* Key usage for computing checksum of authenticatorcksumdata in the
38      Authenticator, in AP-REQ. */
39   int authenticatorcksumkeyusage;
40   /* Sets the checksum algorithm type in Authenticator, in AP-REQ.  If
41      there is data in authenticatorcksumdata to compute a checksum on,
42      this also indicate the algorithm to use for this computation. */
43   int32_t authenticatorcksumtype;
44   /* Auxilliary application data to compute checksum on and store in
45      Authenticator, in AP-REQ.  Note that data is not stored in
46      AP-REQ, only a checksum of it. */
47   char *authenticatorcksumdata;
48   size_t authenticatorcksumdatalen;
49   /* Raw checksum data to store in Authenticator, in AP-REQ.
50      Normally, this is the output of the checksum algorithm computed
51      on the data in authenticatorcksumdata, but some applications
52      (e.g., GSS-API) put something weird in the checksum field. */
53   char *authenticatorcksumraw;
54   size_t authenticatorcksumrawlen;
55 };
56 
57 /**
58  * shishi_ap:
59  * @handle: shishi handle as allocated by shishi_init().
60  * @ap: pointer to new structure that holds information about AP exchange
61  *
62  * Create a new AP exchange with a random subkey of the default
63  * encryption type from configuration.  Note that there is no
64  * guarantee that the receiver will understand that key type, you
65  * should probably use shishi_ap_etype() or shishi_ap_nosubkey()
66  * instead.  In the future, this function will likely behave as
67  * shishi_ap_nosubkey() and shishi_ap_nosubkey() will be removed.
68  *
69  * Return value: Returns SHISHI_OK iff successful.
70  **/
71 int
shishi_ap(Shishi * handle,Shishi_ap ** ap)72 shishi_ap (Shishi * handle, Shishi_ap ** ap)
73 {
74   int res;
75 
76   res = shishi_ap_nosubkey (handle, ap);
77   if (res != SHISHI_OK)
78     {
79       shishi_error_printf (handle, "Could not create Authenticator: %s\n",
80 			   shishi_error (handle));
81       return res;
82     }
83 
84   res = shishi_authenticator_add_random_subkey (handle, (*ap)->authenticator);
85   if (res != SHISHI_OK)
86     {
87       shishi_error_printf (handle, "Could not add random subkey in AP: %s\n",
88 			   shishi_strerror (res));
89       return res;
90     }
91 
92   return SHISHI_OK;
93 }
94 
95 /**
96  * shishi_ap_etype:
97  * @handle: shishi handle as allocated by shishi_init().
98  * @ap: pointer to new structure that holds information about AP exchange
99  * @etype: encryption type of newly generated random subkey.
100  *
101  * Create a new AP exchange with a random subkey of indicated
102  * encryption type.
103  *
104  * Return value: Returns SHISHI_OK iff successful.
105  **/
106 int
shishi_ap_etype(Shishi * handle,Shishi_ap ** ap,int etype)107 shishi_ap_etype (Shishi * handle, Shishi_ap ** ap, int etype)
108 {
109   int res;
110 
111   res = shishi_ap_nosubkey (handle, ap);
112   if (res != SHISHI_OK)
113     {
114       shishi_error_printf (handle, "Could not create Authenticator: %s\n",
115 			   shishi_error (handle));
116       return res;
117     }
118 
119   res = shishi_authenticator_add_random_subkey_etype (handle,
120 						      (*ap)->authenticator,
121 						      etype);
122   if (res != SHISHI_OK)
123     {
124       shishi_error_printf (handle, "Could not add random subkey in AP: %s\n",
125 			   shishi_strerror (res));
126       return res;
127     }
128 
129   return SHISHI_OK;
130 }
131 
132 /**
133  * shishi_ap_nosubkey:
134  * @handle: shishi handle as allocated by shishi_init().
135  * @ap: pointer to new structure that holds information about AP exchange
136  *
137  * Create a new AP exchange without subkey in authenticator.
138  *
139  * Return value: Returns SHISHI_OK iff successful.
140  **/
141 int
shishi_ap_nosubkey(Shishi * handle,Shishi_ap ** ap)142 shishi_ap_nosubkey (Shishi * handle, Shishi_ap ** ap)
143 {
144   Shishi_ap *lap;
145 
146   *ap = xcalloc (1, sizeof (**ap));
147   lap = *ap;
148 
149   lap->handle = handle;
150   lap->authenticatorcksumtype = SHISHI_NO_CKSUMTYPE;
151   lap->authenticatorcksumkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR_CKSUM;
152   lap->authenticatorkeyusage = SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR;
153 
154   lap->authenticator = shishi_authenticator (handle);
155   if (lap->authenticator == NULL)
156     {
157       shishi_error_printf (handle, "Could not create Authenticator: %s\n",
158 			   shishi_error (handle));
159       return SHISHI_ASN1_ERROR;
160     }
161 
162   lap->apreq = shishi_apreq (handle);
163   if (lap->apreq == NULL)
164     {
165       shishi_error_printf (handle, "Could not create AP-REQ: %s\n",
166 			   shishi_error (handle));
167       return SHISHI_ASN1_ERROR;
168     }
169 
170   lap->aprep = shishi_aprep (handle);
171   if (lap->aprep == NULL)
172     {
173       shishi_error_printf (handle, "Could not create AP-REP: %s\n",
174 			   shishi_error (handle));
175       return SHISHI_ASN1_ERROR;
176     }
177 
178   lap->encapreppart = shishi_encapreppart (handle);
179   if (lap->encapreppart == NULL)
180     {
181       shishi_error_printf (handle, "Could not create EncAPRepPart: %s\n",
182 			   shishi_error (handle));
183       return SHISHI_ASN1_ERROR;
184     }
185 
186   return SHISHI_OK;
187 }
188 
189 /**
190  * shishi_ap_done:
191  * @ap: structure that holds information about AP exchange
192  *
193  * Deallocate resources associated with AP exchange.  This should be
194  * called by the application when it no longer need to utilize the AP
195  * exchange handle.
196  **/
197 void
shishi_ap_done(Shishi_ap * ap)198 shishi_ap_done (Shishi_ap * ap)
199 {
200   free (ap->authenticatorcksumdata);
201   free (ap->authenticatorcksumraw);
202   shishi_asn1_done (ap->handle, ap->authenticator);
203   shishi_asn1_done (ap->handle, ap->apreq);
204   shishi_asn1_done (ap->handle, ap->aprep);
205   shishi_asn1_done (ap->handle, ap->encapreppart);
206   free (ap);
207 }
208 
209 /**
210  * shishi_ap_set_tktoptions:
211  * @ap: structure that holds information about AP exchange
212  * @tkt: ticket to set in AP.
213  * @options: AP-REQ options to set in AP.
214  *
215  * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
216  * apoptions (see shishi_apreq_options_set()).
217  *
218  * Return value: Returns SHISHI_OK iff successful.
219  **/
220 int
shishi_ap_set_tktoptions(Shishi_ap * ap,Shishi_tkt * tkt,int options)221 shishi_ap_set_tktoptions (Shishi_ap * ap, Shishi_tkt * tkt, int options)
222 {
223   int rc;
224 
225   shishi_ap_tkt_set (ap, tkt);
226 
227   rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
228   if (rc != SHISHI_OK)
229     {
230       printf ("Could not set AP-Options: %s", shishi_strerror (rc));
231       return rc;
232     }
233 
234   return SHISHI_OK;
235 }
236 
237 /**
238  * shishi_ap_set_tktoptionsdata:
239  * @ap: structure that holds information about AP exchange
240  * @tkt: ticket to set in AP.
241  * @options: AP-REQ options to set in AP.
242  * @data: input array with data to checksum in Authenticator.
243  * @len: length of input array with data to checksum in Authenticator.
244  *
245  * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
246  * apoptions (see shishi_apreq_options_set()) and set the
247  * Authenticator checksum data.
248  *
249  * Return value: Returns SHISHI_OK iff successful.
250  **/
251 int
shishi_ap_set_tktoptionsdata(Shishi_ap * ap,Shishi_tkt * tkt,int options,const char * data,size_t len)252 shishi_ap_set_tktoptionsdata (Shishi_ap * ap,
253 			      Shishi_tkt * tkt,
254 			      int options, const char *data, size_t len)
255 {
256   int rc;
257 
258   shishi_ap_tkt_set (ap, tkt);
259 
260   rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
261   if (rc != SHISHI_OK)
262     {
263       printf ("Could not set AP-Options: %s", shishi_strerror (rc));
264       return rc;
265     }
266 
267   shishi_ap_authenticator_cksumdata_set (ap, data, len);
268 
269   return SHISHI_OK;
270 }
271 
272 
273 /**
274  * shishi_ap_set_tktoptionsraw:
275  * @ap: structure that holds information about AP exchange
276  * @tkt: ticket to set in AP.
277  * @options: AP-REQ options to set in AP.
278  * @cksumtype: authenticator checksum type to set in AP.
279  * @data: input array with data to store in checksum field in Authenticator.
280  * @len: length of input array with data to store in checksum field in
281  *   Authenticator.
282  *
283  * Set the ticket (see shishi_ap_tkt_set()) and set the AP-REQ
284  * apoptions (see shishi_apreq_options_set()) and set the raw
285  * Authenticator checksum data.
286  *
287  * Return value: Returns SHISHI_OK iff successful.
288  **/
289 int
shishi_ap_set_tktoptionsraw(Shishi_ap * ap,Shishi_tkt * tkt,int options,int32_t cksumtype,const char * data,size_t len)290 shishi_ap_set_tktoptionsraw (Shishi_ap * ap,
291 			     Shishi_tkt * tkt,
292 			     int options,
293 			     int32_t cksumtype, const char *data, size_t len)
294 {
295   int rc;
296 
297   shishi_ap_tkt_set (ap, tkt);
298 
299   rc = shishi_apreq_options_set (ap->handle, shishi_ap_req (ap), options);
300   if (rc != SHISHI_OK)
301     {
302       printf ("Could not set AP-Options: %s", shishi_strerror (rc));
303       return rc;
304     }
305 
306   shishi_ap_authenticator_cksumraw_set (ap, cksumtype, data, len);
307 
308   return SHISHI_OK;
309 }
310 
311 /**
312  * shishi_ap_set_tktoptionsasn1usage:
313  * @ap: structure that holds information about AP exchange
314  * @tkt: ticket to set in AP.
315  * @options: AP-REQ options to set in AP.
316  * @node: input ASN.1 structure to store as authenticator checksum data.
317  * @field: field in ASN.1 structure to use.
318  * @authenticatorcksumkeyusage: key usage for checksum in authenticator.
319  * @authenticatorkeyusage: key usage for authenticator.
320  *
321  * Set ticket, options and authenticator checksum data using
322  * shishi_ap_set_tktoptionsdata().  The authenticator checksum data is
323  * the DER encoding of the ASN.1 field provided.
324  *
325  * Return value: Returns SHISHI_OK iff successful.
326  **/
327 int
shishi_ap_set_tktoptionsasn1usage(Shishi_ap * ap,Shishi_tkt * tkt,int options,Shishi_asn1 node,const char * field,int authenticatorcksumkeyusage,int authenticatorkeyusage)328 shishi_ap_set_tktoptionsasn1usage (Shishi_ap * ap,
329 				   Shishi_tkt * tkt,
330 				   int options,
331 				   Shishi_asn1 node,
332 				   const char *field,
333 				   int authenticatorcksumkeyusage,
334 				   int authenticatorkeyusage)
335 {
336   char *buf;
337   size_t buflen;
338   int res;
339 
340   res = shishi_asn1_to_der_field (ap->handle, node, field, &buf, &buflen);
341   if (res != SHISHI_OK)
342     return res;
343 
344   res = shishi_ap_set_tktoptionsdata (ap, tkt, options, buf, buflen);
345   if (res != SHISHI_OK)
346     return res;
347 
348   ap->authenticatorcksumkeyusage = authenticatorcksumkeyusage;
349   ap->authenticatorkeyusage = authenticatorkeyusage;
350 
351   return SHISHI_OK;
352 }
353 
354 /**
355  * shishi_ap_tktoptions:
356  * @handle: shishi handle as allocated by shishi_init().
357  * @ap: pointer to new structure that holds information about AP exchange
358  * @tkt: ticket to set in newly created AP.
359  * @options: AP-REQ options to set in newly created AP.
360  *
361  * Create a new AP exchange using shishi_ap(), and set the ticket and
362  * AP-REQ apoptions using shishi_ap_set_tktoptions().  A random
363  * session key is added to the authenticator, using the same keytype
364  * as the ticket.
365  *
366  * Return value: Returns SHISHI_OK iff successful.
367  **/
368 int
shishi_ap_tktoptions(Shishi * handle,Shishi_ap ** ap,Shishi_tkt * tkt,int options)369 shishi_ap_tktoptions (Shishi * handle,
370 		      Shishi_ap ** ap, Shishi_tkt * tkt, int options)
371 {
372   int rc;
373 
374   rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
375   if (rc != SHISHI_OK)
376     return rc;
377 
378   rc = shishi_ap_set_tktoptions (*ap, tkt, options);
379   if (rc != SHISHI_OK)
380     return rc;
381 
382   return SHISHI_OK;
383 }
384 
385 /**
386  * shishi_ap_tktoptionsdata:
387  * @handle: shishi handle as allocated by shishi_init().
388  * @ap: pointer to new structure that holds information about AP exchange
389  * @tkt: ticket to set in newly created AP.
390  * @options: AP-REQ options to set in newly created AP.
391  * @data: input array with data to checksum in Authenticator.
392  * @len: length of input array with data to checksum in Authenticator.
393  *
394  * Create a new AP exchange using shishi_ap(), and set the ticket,
395  * AP-REQ apoptions and the Authenticator checksum data using
396  * shishi_ap_set_tktoptionsdata(). A random session key is added to
397  * the authenticator, using the same keytype as the ticket.
398  *
399  * Return value: Returns SHISHI_OK iff successful.
400  **/
401 int
shishi_ap_tktoptionsdata(Shishi * handle,Shishi_ap ** ap,Shishi_tkt * tkt,int options,const char * data,size_t len)402 shishi_ap_tktoptionsdata (Shishi * handle,
403 			  Shishi_ap ** ap,
404 			  Shishi_tkt * tkt, int options,
405 			  const char *data, size_t len)
406 {
407   int rc;
408 
409   rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
410   if (rc != SHISHI_OK)
411     return rc;
412 
413   rc = shishi_ap_set_tktoptionsdata (*ap, tkt, options, data, len);
414   if (rc != SHISHI_OK)
415     return rc;
416 
417   return SHISHI_OK;
418 }
419 
420 /**
421  * shishi_ap_tktoptionsraw:
422  * @handle: shishi handle as allocated by shishi_init().
423  * @ap: pointer to new structure that holds information about AP exchange
424  * @tkt: ticket to set in newly created AP.
425  * @options: AP-REQ options to set in newly created AP.
426  * @cksumtype: authenticator checksum type to set in AP.
427  * @data: input array with data to store in checksum field in Authenticator.
428  * @len: length of input array with data to store in checksum field in
429  *   Authenticator.
430  *
431  * Create a new AP exchange using shishi_ap(), and set the ticket,
432  * AP-REQ apoptions and the raw Authenticator checksum data field
433  * using shishi_ap_set_tktoptionsraw().  A random session key is added
434  * to the authenticator, using the same keytype as the ticket.
435  *
436  * Return value: Returns SHISHI_OK iff successful.
437  **/
438 int
shishi_ap_tktoptionsraw(Shishi * handle,Shishi_ap ** ap,Shishi_tkt * tkt,int options,int32_t cksumtype,const char * data,size_t len)439 shishi_ap_tktoptionsraw (Shishi * handle,
440 			 Shishi_ap ** ap,
441 			 Shishi_tkt * tkt, int options,
442 			 int32_t cksumtype, const char *data, size_t len)
443 {
444   int rc;
445 
446   rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
447   if (rc != SHISHI_OK)
448     return rc;
449 
450   rc = shishi_ap_set_tktoptionsraw (*ap, tkt, options, cksumtype, data, len);
451   if (rc != SHISHI_OK)
452     return rc;
453 
454   return SHISHI_OK;
455 }
456 
457 /**
458  * shishi_ap_etype_tktoptionsdata:
459  * @handle: shishi handle as allocated by shishi_init().
460  * @ap: pointer to new structure that holds information about AP exchange
461  * @etype: encryption type of newly generated random subkey.
462  * @tkt: ticket to set in newly created AP.
463  * @options: AP-REQ options to set in newly created AP.
464  * @data: input array with data to checksum in Authenticator.
465  * @len: length of input array with data to checksum in Authenticator.
466  *
467  * Create a new AP exchange using shishi_ap(), and set the ticket,
468  * AP-REQ apoptions and the Authenticator checksum data using
469  * shishi_ap_set_tktoptionsdata(). A random session key is added to
470  * the authenticator, using the same keytype as the ticket.
471  *
472  * Return value: Returns SHISHI_OK iff successful.
473  **/
474 int
shishi_ap_etype_tktoptionsdata(Shishi * handle,Shishi_ap ** ap,int32_t etype,Shishi_tkt * tkt,int options,const char * data,size_t len)475 shishi_ap_etype_tktoptionsdata (Shishi * handle,
476 				Shishi_ap ** ap,
477 				int32_t etype,
478 				Shishi_tkt * tkt, int options,
479 				const char *data, size_t len)
480 {
481   int rc;
482 
483   rc = shishi_ap_etype (handle, ap, etype);
484   if (rc != SHISHI_OK)
485     return rc;
486 
487   rc = shishi_ap_set_tktoptionsdata (*ap, tkt, options, data, len);
488   if (rc != SHISHI_OK)
489     return rc;
490 
491   return SHISHI_OK;
492 }
493 
494 /**
495  * shishi_ap_tktoptionsasn1usage:
496  * @handle: shishi handle as allocated by shishi_init().
497  * @ap: pointer to new structure that holds information about AP exchange
498  * @tkt: ticket to set in newly created AP.
499  * @options: AP-REQ options to set in newly created AP.
500  * @node: input ASN.1 structure to store as authenticator checksum data.
501  * @field: field in ASN.1 structure to use.
502  * @authenticatorcksumkeyusage: key usage for checksum in authenticator.
503  * @authenticatorkeyusage: key usage for authenticator.
504  *
505  * Create a new AP exchange using shishi_ap(), and set ticket, options
506  * and authenticator checksum data from the DER encoding of the ASN.1
507  * field using shishi_ap_set_tktoptionsasn1usage().  A random session
508  * key is added to the authenticator, using the same keytype as the
509  * ticket.
510  *
511  * Return value: Returns SHISHI_OK iff successful.
512  **/
513 int
shishi_ap_tktoptionsasn1usage(Shishi * handle,Shishi_ap ** ap,Shishi_tkt * tkt,int options,Shishi_asn1 node,const char * field,int authenticatorcksumkeyusage,int authenticatorkeyusage)514 shishi_ap_tktoptionsasn1usage (Shishi * handle,
515 			       Shishi_ap ** ap,
516 			       Shishi_tkt * tkt,
517 			       int options,
518 			       Shishi_asn1 node,
519 			       const char *field,
520 			       int authenticatorcksumkeyusage,
521 			       int authenticatorkeyusage)
522 {
523   int rc;
524 
525   rc = shishi_ap_etype (handle, ap, shishi_tkt_keytype_fast (tkt));
526   if (rc != SHISHI_OK)
527     return rc;
528 
529   rc = shishi_ap_set_tktoptionsasn1usage (*ap, tkt, options,
530 					  node, field,
531 					  authenticatorcksumkeyusage,
532 					  authenticatorkeyusage);
533   if (rc != SHISHI_OK)
534     return rc;
535 
536   return SHISHI_OK;
537 }
538 
539 /**
540  * shishi_ap_tkt:
541  * @ap: structure that holds information about AP exchange
542  *
543  * Get Ticket from AP exchange.
544  *
545  * Return value: Returns the ticket from the AP exchange, or NULL if
546  *               not yet set or an error occured.
547  **/
548 Shishi_tkt *
shishi_ap_tkt(Shishi_ap * ap)549 shishi_ap_tkt (Shishi_ap * ap)
550 {
551   return ap->tkt;
552 }
553 
554 /**
555  * shishi_ap_tkt_set:
556  * @ap: structure that holds information about AP exchange
557  * @tkt: ticket to store in AP.
558  *
559  * Set the Ticket in the AP exchange.
560  **/
561 void
shishi_ap_tkt_set(Shishi_ap * ap,Shishi_tkt * tkt)562 shishi_ap_tkt_set (Shishi_ap * ap, Shishi_tkt * tkt)
563 {
564   ap->tkt = tkt;
565 }
566 
567 /**
568  * shishi_ap_authenticator_cksumdata:
569  * @ap: structure that holds information about AP exchange
570  * @out: output array that holds authenticator checksum data.
571  * @len: on input, maximum length of output array that holds
572  *       authenticator checksum data, on output actual length of
573  *       output array that holds authenticator checksum data.
574  *
575  * Get checksum data from Authenticator.
576  *
577  * Return value: Returns %SHISHI_OK if successful, or
578  *   %SHISHI_TOO_SMALL_BUFFER if buffer provided was too small (then @len
579  *   will hold necessary buffer size).
580  **/
581 int
shishi_ap_authenticator_cksumdata(Shishi_ap * ap,char * out,size_t * len)582 shishi_ap_authenticator_cksumdata (Shishi_ap * ap, char *out, size_t * len)
583 {
584   if (*len < ap->authenticatorcksumdatalen)
585     {
586       *len = ap->authenticatorcksumdatalen;
587       return SHISHI_TOO_SMALL_BUFFER;
588     }
589   if (out && ap->authenticatorcksumdata)
590     memcpy (out, ap->authenticatorcksumdata, ap->authenticatorcksumdatalen);
591   *len = ap->authenticatorcksumdatalen;
592   return SHISHI_OK;
593 }
594 
595 /**
596  * shishi_ap_authenticator_cksumdata_set:
597  * @ap: structure that holds information about AP exchange
598  * @authenticatorcksumdata: input array with data to compute checksum
599  *   on and store in Authenticator in AP-REQ.
600  * @authenticatorcksumdatalen: length of input array with data to
601  *   compute checksum on and store in Authenticator in AP-REQ.
602  *
603  * Set the Authenticator Checksum Data in the AP exchange.  This is
604  * the data that will be checksumed, and the checksum placed in the
605  * checksum field.  It is not the actual checksum field.  See also
606  * shishi_ap_authenticator_cksumraw_set.
607  **/
608 void
shishi_ap_authenticator_cksumdata_set(Shishi_ap * ap,const char * authenticatorcksumdata,size_t authenticatorcksumdatalen)609 shishi_ap_authenticator_cksumdata_set (Shishi_ap * ap,
610 				       const char *authenticatorcksumdata,
611 				       size_t authenticatorcksumdatalen)
612 {
613   ap->authenticatorcksumdata = xmemdup (authenticatorcksumdata,
614 					authenticatorcksumdatalen);
615   ap->authenticatorcksumdatalen = authenticatorcksumdatalen;
616 }
617 
618 /**
619  * shishi_ap_authenticator_cksumraw_set:
620  * @ap: structure that holds information about AP exchange
621  * @authenticatorcksumtype: authenticator checksum type to set in AP.
622  * @authenticatorcksumraw: input array with authenticator checksum
623  *   field value to set in Authenticator in AP-REQ.
624  * @authenticatorcksumrawlen: length of input array with
625  *   authenticator checksum field value to set in Authenticator in AP-REQ.
626  *
627  * Set the Authenticator Checksum Data in the AP exchange.  This is
628  * the actual checksum field, not data to compute checksum on and then
629  * store in the checksum field.  See also
630  * shishi_ap_authenticator_cksumdata_set.
631  **/
632 void
shishi_ap_authenticator_cksumraw_set(Shishi_ap * ap,int32_t authenticatorcksumtype,const char * authenticatorcksumraw,size_t authenticatorcksumrawlen)633 shishi_ap_authenticator_cksumraw_set (Shishi_ap * ap,
634 				      int32_t authenticatorcksumtype,
635 				      const char *authenticatorcksumraw,
636 				      size_t authenticatorcksumrawlen)
637 {
638   shishi_ap_authenticator_cksumtype_set (ap, authenticatorcksumtype);
639   ap->authenticatorcksumraw = xmemdup (authenticatorcksumraw,
640 				       authenticatorcksumrawlen);
641   ap->authenticatorcksumrawlen = authenticatorcksumrawlen;
642 }
643 
644 /**
645  * shishi_ap_authenticator_cksumtype:
646  * @ap: structure that holds information about AP exchange
647  *
648  * Get the Authenticator Checksum Type in the AP exchange.
649  *
650  * Return value: Return the authenticator checksum type.
651  **/
652 int32_t
shishi_ap_authenticator_cksumtype(Shishi_ap * ap)653 shishi_ap_authenticator_cksumtype (Shishi_ap * ap)
654 {
655   return ap->authenticatorcksumtype;
656 }
657 
658 /**
659  * shishi_ap_authenticator_cksumtype_set:
660  * @ap: structure that holds information about AP exchange
661  * @cksumtype: authenticator checksum type to set in AP.
662  *
663  * Set the Authenticator Checksum Type in the AP exchange.
664  **/
665 void
shishi_ap_authenticator_cksumtype_set(Shishi_ap * ap,int32_t cksumtype)666 shishi_ap_authenticator_cksumtype_set (Shishi_ap * ap, int32_t cksumtype)
667 {
668   ap->authenticatorcksumtype = cksumtype;
669 }
670 
671 /**
672  * shishi_ap_authenticator:
673  * @ap: structure that holds information about AP exchange
674  *
675  * Get ASN.1 Authenticator structure from AP exchange.
676  *
677  * Return value: Returns the Authenticator from the AP exchange, or
678  *               NULL if not yet set or an error occured.
679  **/
680 
681 Shishi_asn1
shishi_ap_authenticator(Shishi_ap * ap)682 shishi_ap_authenticator (Shishi_ap * ap)
683 {
684   return ap->authenticator;
685 }
686 
687 /**
688  * shishi_ap_authenticator_set:
689  * @ap: structure that holds information about AP exchange
690  * @authenticator: authenticator to store in AP.
691  *
692  * Set the Authenticator in the AP exchange.
693  **/
694 void
shishi_ap_authenticator_set(Shishi_ap * ap,Shishi_asn1 authenticator)695 shishi_ap_authenticator_set (Shishi_ap * ap, Shishi_asn1 authenticator)
696 {
697   if (ap->authenticator)
698     shishi_asn1_done (ap->handle, ap->authenticator);
699   ap->authenticator = authenticator;
700 }
701 
702 /**
703  * shishi_ap_req:
704  * @ap: structure that holds information about AP exchange
705  *
706  * Get ASN.1 AP-REQ structure from AP exchange.
707  *
708  * Return value: Returns the AP-REQ from the AP exchange, or NULL if
709  *               not yet set or an error occured.
710  **/
711 Shishi_asn1
shishi_ap_req(Shishi_ap * ap)712 shishi_ap_req (Shishi_ap * ap)
713 {
714   return ap->apreq;
715 }
716 
717 
718 /**
719  * shishi_ap_req_set:
720  * @ap: structure that holds information about AP exchange
721  * @apreq: apreq to store in AP.
722  *
723  * Set the AP-REQ in the AP exchange.
724  **/
725 void
shishi_ap_req_set(Shishi_ap * ap,Shishi_asn1 apreq)726 shishi_ap_req_set (Shishi_ap * ap, Shishi_asn1 apreq)
727 {
728   if (ap->apreq)
729     shishi_asn1_done (ap->handle, ap->apreq);
730   ap->apreq = apreq;
731 }
732 
733 /**
734  * shishi_ap_req_der:
735  * @ap: structure that holds information about AP exchange
736  * @out: pointer to output array with der encoding of AP-REQ.
737  * @outlen: pointer to length of output array with der encoding of AP-REQ.
738  *
739  * Build AP-REQ using shishi_ap_req_build() and DER encode it.  @out
740  * is allocated by this function, and it is the responsibility of
741  * caller to deallocate it.
742  *
743  * Return value: Returns SHISHI_OK iff successful.
744  **/
745 int
shishi_ap_req_der(Shishi_ap * ap,char ** out,size_t * outlen)746 shishi_ap_req_der (Shishi_ap * ap, char **out, size_t * outlen)
747 {
748   int rc;
749 
750   rc = shishi_ap_req_build (ap);
751   if (rc != SHISHI_OK)
752     return rc;
753 
754   rc = shishi_asn1_to_der (ap->handle, ap->apreq, out, outlen);
755   if (rc != SHISHI_OK)
756     return rc;
757 
758   return SHISHI_OK;
759 }
760 
761 /**
762  * shishi_ap_req_der_set:
763  * @ap: structure that holds information about AP exchange
764  * @der: input array with DER encoded AP-REQ.
765  * @derlen: length of input array with DER encoded AP-REQ.
766  *
767  * DER decode AP-REQ and set it AP exchange.  If decoding fails, the
768  * AP-REQ in the AP exchange is lost.
769  *
770  * Return value: Returns SHISHI_OK.
771  **/
772 int
shishi_ap_req_der_set(Shishi_ap * ap,char * der,size_t derlen)773 shishi_ap_req_der_set (Shishi_ap * ap, char *der, size_t derlen)
774 {
775   ap->apreq = shishi_der2asn1_apreq (ap->handle, der, derlen);
776 
777   if (ap->apreq)
778     return SHISHI_OK;
779   else
780     return SHISHI_ASN1_ERROR;
781 }
782 
783 /**
784  * shishi_ap_req_build:
785  * @ap: structure that holds information about AP exchange
786  *
787  * Checksum data in authenticator and add ticket and authenticator to
788  * AP-REQ.
789  *
790  * Return value: Returns SHISHI_OK iff successful.
791  **/
792 int
shishi_ap_req_build(Shishi_ap * ap)793 shishi_ap_req_build (Shishi_ap * ap)
794 {
795   int res;
796   int cksumtype;
797 
798   if (VERBOSE (ap->handle))
799     printf ("Building AP-REQ...\n");
800 
801   if (VERBOSEASN1 (ap->handle))
802     {
803       shishi_ticket_print (ap->handle, stdout, shishi_tkt_ticket (ap->tkt));
804       shishi_key_print (ap->handle, stdout, shishi_tkt_key (ap->tkt));
805     }
806 
807 
808   res = shishi_apreq_set_ticket (ap->handle, ap->apreq,
809 				 shishi_tkt_ticket (ap->tkt));
810   if (res != SHISHI_OK)
811     {
812       shishi_error_printf (ap->handle, "Could not set ticket in AP-REQ: %s\n",
813 			   shishi_error (ap->handle));
814       return res;
815     }
816 
817   cksumtype = shishi_ap_authenticator_cksumtype (ap);
818   if (ap->authenticatorcksumraw && ap->authenticatorcksumrawlen > 0)
819     res = shishi_authenticator_set_cksum (ap->handle, ap->authenticator,
820 					  cksumtype,
821 					  ap->authenticatorcksumraw,
822 					  ap->authenticatorcksumrawlen);
823   else if (cksumtype == SHISHI_NO_CKSUMTYPE)
824     res = shishi_authenticator_add_cksum (ap->handle, ap->authenticator,
825 					  shishi_tkt_key (ap->tkt),
826 					  ap->authenticatorcksumkeyusage,
827 					  ap->authenticatorcksumdata,
828 					  ap->authenticatorcksumdatalen);
829   else
830     res = shishi_authenticator_add_cksum_type (ap->handle, ap->authenticator,
831 					       shishi_tkt_key (ap->tkt),
832 					       ap->authenticatorcksumkeyusage,
833 					       cksumtype,
834 					       ap->authenticatorcksumdata,
835 					       ap->authenticatorcksumdatalen);
836   if (res != SHISHI_OK)
837     {
838       shishi_error_printf (ap->handle,
839 			   "Could not add checksum to authenticator: %s\n",
840 			   shishi_error (ap->handle));
841       return res;
842     }
843 
844   if (VERBOSE (ap->handle))
845     printf ("Got Authenticator...\n");
846 
847   if (VERBOSEASN1 (ap->handle))
848     shishi_authenticator_print (ap->handle, stdout, ap->authenticator);
849 
850   res = shishi_apreq_add_authenticator (ap->handle, ap->apreq,
851 					shishi_tkt_key (ap->tkt),
852 					ap->authenticatorkeyusage,
853 					ap->authenticator);
854   if (res != SHISHI_OK)
855     {
856       shishi_error_printf (ap->handle, "Could not set authenticator: %s\n",
857 			   shishi_error (ap->handle));
858       return res;
859     }
860 
861   if (VERBOSEASN1 (ap->handle))
862     shishi_apreq_print (ap->handle, stdout, ap->apreq);
863 
864   return SHISHI_OK;
865 }
866 
867 /**
868  * shishi_ap_req_decode:
869  * @ap: structure that holds information about AP exchange
870  *
871  * Decode ticket in AP-REQ and set the Ticket fields in the AP
872  * exchange.
873  *
874  * Return value: Returns SHISHI_OK iff successful.
875  **/
876 int
shishi_ap_req_decode(Shishi_ap * ap)877 shishi_ap_req_decode (Shishi_ap * ap)
878 {
879   Shishi_asn1 ticket;
880   int rc;
881 
882   if (VERBOSEASN1 (ap->handle))
883     shishi_apreq_print (ap->handle, stdout, ap->apreq);
884 
885   rc = shishi_apreq_get_ticket (ap->handle, ap->apreq, &ticket);
886   if (rc != SHISHI_OK)
887     {
888       shishi_error_printf (ap->handle,
889 			   "Could not extract ticket from AP-REQ: %s\n",
890 			   shishi_strerror (rc));
891       return rc;
892     }
893 
894   if (VERBOSEASN1 (ap->handle))
895     shishi_ticket_print (ap->handle, stdout, ticket);
896 
897   rc = shishi_tkt (ap->handle, &ap->tkt);
898   if (rc != SHISHI_OK)
899     return rc;
900 
901   shishi_tkt_ticket_set (ap->tkt, ticket);
902 
903   return SHISHI_OK;
904 }
905 
906 /**
907  * shishi_ap_req_process_keyusage:
908  * @ap: structure that holds information about AP exchange
909  * @key: cryptographic key used to decrypt ticket in AP-REQ.
910  * @keyusage: key usage to use during decryption, for normal
911  *   AP-REQ's this is normally SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR,
912  *   for AP-REQ's part of TGS-REQ's, this is normally
913  *   SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR.
914  *
915  * Decrypt ticket in AP-REQ using supplied key and decrypt
916  * Authenticator in AP-REQ using key in decrypted ticket, and on
917  * success set the Ticket and Authenticator fields in the AP exchange.
918  *
919  * Return value: Returns SHISHI_OK iff successful.
920  **/
921 int
shishi_ap_req_process_keyusage(Shishi_ap * ap,Shishi_key * key,int32_t keyusage)922 shishi_ap_req_process_keyusage (Shishi_ap * ap,
923 				Shishi_key * key, int32_t keyusage)
924 {
925   Shishi_asn1 authenticator;
926   Shishi_key *tktkey;
927   int rc;
928 
929   rc = shishi_ap_req_decode (ap);
930   if (rc != SHISHI_OK)
931     {
932       shishi_error_printf (ap->handle, "Error decoding ticket: %s\n",
933 			   shishi_strerror (rc));
934       return rc;
935     }
936 
937   rc = shishi_tkt_decrypt (ap->tkt, key);
938   if (rc != SHISHI_OK)
939     {
940       shishi_error_printf (ap->handle, "Error decrypting ticket: %s\n",
941 			   shishi_strerror (rc));
942       return rc;
943     }
944 
945   rc = shishi_encticketpart_get_key (ap->handle,
946 				     shishi_tkt_encticketpart (ap->tkt),
947 				     &tktkey);
948   if (rc != SHISHI_OK)
949     {
950       shishi_error_printf (ap->handle, "Could not get key from ticket: %s\n",
951 			   shishi_strerror (rc));
952       return rc;
953     }
954 
955   if (VERBOSEASN1 (ap->handle))
956     shishi_encticketpart_print (ap->handle, stdout,
957 				shishi_tkt_encticketpart (ap->tkt));
958 
959   rc = shishi_apreq_decrypt (ap->handle, ap->apreq, tktkey,
960 			     keyusage, &authenticator);
961   if (rc != SHISHI_OK)
962     {
963       shishi_error_printf (ap->handle, "Error decrypting apreq: %s\n",
964 			   shishi_strerror (rc));
965       return rc;
966     }
967 
968   /* XXX? verify checksum in authenticator. */
969 
970   if (VERBOSEASN1 (ap->handle))
971     shishi_authenticator_print (ap->handle, stdout, authenticator);
972 
973   free (ap->authenticatorcksumdata);
974 
975   rc = shishi_authenticator_cksum (ap->handle, authenticator,
976 				   &ap->authenticatorcksumtype,
977 				   &ap->authenticatorcksumdata,
978 				   &ap->authenticatorcksumdatalen);
979   if (rc != SHISHI_OK)
980     {
981       shishi_error_printf (ap->handle,
982 			   "Error extracting authenticator checksum: %s\n",
983 			   shishi_strerror (rc));
984       return rc;
985     }
986 
987   ap->authenticator = authenticator;
988 
989   return SHISHI_OK;
990 }
991 
992 /**
993  * shishi_ap_req_process:
994  * @ap: structure that holds information about AP exchange
995  * @key: cryptographic key used to decrypt ticket in AP-REQ.
996  *
997  * Decrypt ticket in AP-REQ using supplied key and decrypt
998  * Authenticator in AP-REQ using key in decrypted ticket, and on
999  * success set the Ticket and Authenticator fields in the AP exchange.
1000  *
1001  * Return value: Returns SHISHI_OK iff successful.
1002  **/
1003 int
shishi_ap_req_process(Shishi_ap * ap,Shishi_key * key)1004 shishi_ap_req_process (Shishi_ap * ap, Shishi_key * key)
1005 {
1006   return shishi_ap_req_process_keyusage (ap, key,
1007 					 SHISHI_KEYUSAGE_APREQ_AUTHENTICATOR);
1008 }
1009 
1010 /**
1011  * shishi_ap_req_asn1:
1012  * @ap: structure that holds information about AP exchange
1013  * @apreq: output AP-REQ variable.
1014  *
1015  * Build AP-REQ using shishi_ap_req_build() and return it.
1016  *
1017  * Return value: Returns SHISHI_OK iff successful.
1018  **/
1019 int
shishi_ap_req_asn1(Shishi_ap * ap,Shishi_asn1 * apreq)1020 shishi_ap_req_asn1 (Shishi_ap * ap, Shishi_asn1 * apreq)
1021 {
1022   int rc;
1023 
1024   rc = shishi_ap_req_build (ap);
1025   if (rc != SHISHI_OK)
1026     return rc;
1027 
1028   *apreq = ap->apreq;
1029 
1030   return SHISHI_OK;
1031 }
1032 
1033 /**
1034  * shishi_ap_key:
1035  * @ap: structure that holds information about AP exchange
1036  *
1037  * Extract the application key from AP.  If subkeys are used, it is
1038  * taken from the Authenticator, otherwise the session key is used.
1039  *
1040  * Return value: Return application key from AP.
1041  **/
1042 Shishi_key *
shishi_ap_key(Shishi_ap * ap)1043 shishi_ap_key (Shishi_ap * ap)
1044 {
1045   int rc;
1046 
1047   /* XXX do real check if subkey is present, don't just assume error
1048      means no subkey */
1049 
1050   rc = shishi_authenticator_get_subkey (ap->handle, ap->authenticator,
1051 					&ap->key);
1052   if (rc != SHISHI_OK)
1053     ap->key = shishi_tkt_key (ap->tkt);
1054 
1055   return ap->key;
1056 }
1057 
1058 /**
1059  * shishi_ap_rep:
1060  * @ap: structure that holds information about AP exchange
1061  *
1062  * Get ASN.1 AP-REP structure from AP exchange.
1063  *
1064  * Return value: Returns the AP-REP from the AP exchange, or NULL if
1065  *               not yet set or an error occured.
1066  **/
1067 Shishi_asn1
shishi_ap_rep(Shishi_ap * ap)1068 shishi_ap_rep (Shishi_ap * ap)
1069 {
1070   return ap->aprep;
1071 }
1072 
1073 /**
1074  * shishi_ap_rep_set:
1075  * @ap: structure that holds information about AP exchange
1076  * @aprep: aprep to store in AP.
1077  *
1078  * Set the AP-REP in the AP exchange.
1079  **/
1080 void
shishi_ap_rep_set(Shishi_ap * ap,Shishi_asn1 aprep)1081 shishi_ap_rep_set (Shishi_ap * ap, Shishi_asn1 aprep)
1082 {
1083   if (ap->aprep)
1084     shishi_asn1_done (ap->handle, ap->aprep);
1085   ap->aprep = aprep;
1086 }
1087 
1088 /**
1089  * shishi_ap_rep_der:
1090  * @ap: structure that holds information about AP exchange
1091  * @out: output array with newly allocated DER encoding of AP-REP.
1092  * @outlen: length of output array with DER encoding of AP-REP.
1093  *
1094  * Build AP-REP using shishi_ap_rep_build() and DER encode it.  @out
1095  * is allocated by this function, and it is the responsibility of
1096  * caller to deallocate it.
1097  *
1098  * Return value: Returns SHISHI_OK iff successful.
1099  **/
1100 int
shishi_ap_rep_der(Shishi_ap * ap,char ** out,size_t * outlen)1101 shishi_ap_rep_der (Shishi_ap * ap, char **out, size_t * outlen)
1102 {
1103   int rc;
1104 
1105   rc = shishi_ap_rep_build (ap);
1106   if (rc != SHISHI_OK)
1107     return rc;
1108 
1109   rc = shishi_asn1_to_der (ap->handle, ap->aprep, out, outlen);
1110   if (rc != SHISHI_OK)
1111     return rc;
1112 
1113   return SHISHI_OK;
1114 }
1115 
1116 /**
1117  * shishi_ap_rep_der_set:
1118  * @ap: structure that holds information about AP exchange
1119  * @der: input array with DER encoded AP-REP.
1120  * @derlen: length of input array with DER encoded AP-REP.
1121  *
1122  * DER decode AP-REP and set it AP exchange.  If decoding fails, the
1123  * AP-REP in the AP exchange remains.
1124  *
1125  * Return value: Returns SHISHI_OK.
1126  **/
1127 int
shishi_ap_rep_der_set(Shishi_ap * ap,char * der,size_t derlen)1128 shishi_ap_rep_der_set (Shishi_ap * ap, char *der, size_t derlen)
1129 {
1130   Shishi_asn1 aprep;
1131 
1132   aprep = shishi_der2asn1_aprep (ap->handle, der, derlen);
1133 
1134   if (!aprep)
1135     return SHISHI_ASN1_ERROR;
1136 
1137   ap->aprep = aprep;
1138 
1139   return SHISHI_OK;
1140 }
1141 
1142 /**
1143  * shishi_ap_rep_build:
1144  * @ap: structure that holds information about AP exchange
1145  *
1146  * Checksum data in authenticator and add ticket and authenticator to
1147  * AP-REP.
1148  *
1149  * Return value: Returns SHISHI_OK iff successful.
1150  **/
1151 int
shishi_ap_rep_build(Shishi_ap * ap)1152 shishi_ap_rep_build (Shishi_ap * ap)
1153 {
1154   Shishi_asn1 aprep;
1155   int rc;
1156 
1157   if (VERBOSE (ap->handle))
1158     printf ("Building AP-REP...\n");
1159 
1160   aprep = shishi_aprep (ap->handle);
1161   rc = shishi_aprep_enc_part_make (ap->handle, aprep, ap->encapreppart,
1162 				   ap->authenticator,
1163 				   shishi_tkt_encticketpart (ap->tkt));
1164   if (rc != SHISHI_OK)
1165     {
1166       shishi_error_printf (ap->handle, "Error creating AP-REP: %s\n",
1167 			   shishi_strerror (rc));
1168       return rc;
1169     }
1170 
1171   if (VERBOSEASN1 (ap->handle))
1172     shishi_aprep_print (ap->handle, stdout, aprep);
1173 
1174   shishi_ap_rep_set (ap, aprep);
1175 
1176   return SHISHI_OK;
1177 }
1178 
1179 /**
1180  * shishi_ap_rep_asn1:
1181  * @ap: structure that holds information about AP exchange
1182  * @aprep: output AP-REP variable.
1183  *
1184  * Build AP-REP using shishi_ap_rep_build() and return it.
1185  *
1186  * Return value: Returns SHISHI_OK iff successful.
1187  **/
1188 int
shishi_ap_rep_asn1(Shishi_ap * ap,Shishi_asn1 * aprep)1189 shishi_ap_rep_asn1 (Shishi_ap * ap, Shishi_asn1 * aprep)
1190 {
1191   int rc;
1192 
1193   rc = shishi_ap_rep_build (ap);
1194   if (rc != SHISHI_OK)
1195     return rc;
1196 
1197   *aprep = ap->aprep;
1198 
1199   return SHISHI_OK;
1200 }
1201 
1202 /**
1203  * shishi_ap_rep_verify:
1204  * @ap: structure that holds information about AP exchange
1205  *
1206  * Verify AP-REP compared to Authenticator.
1207  *
1208  * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1209  * error.
1210  **/
1211 int
shishi_ap_rep_verify(Shishi_ap * ap)1212 shishi_ap_rep_verify (Shishi_ap * ap)
1213 {
1214   int res;
1215 
1216   if (VERBOSE (ap->handle))
1217     printf ("Decrypting AP-REP...\n");
1218 
1219   if (VERBOSEASN1 (ap->handle))
1220     shishi_aprep_print (ap->handle, stdout, ap->aprep);
1221 
1222   res = shishi_aprep_decrypt (ap->handle, ap->aprep,
1223 			      shishi_tkt_key (ap->tkt),
1224 			      SHISHI_KEYUSAGE_ENCAPREPPART,
1225 			      &ap->encapreppart);
1226   if (res != SHISHI_OK)
1227     return res;
1228 
1229   if (VERBOSEASN1 (ap->handle))
1230     shishi_encapreppart_print (ap->handle, stdout, ap->encapreppart);
1231 
1232   res = shishi_aprep_verify (ap->handle, ap->authenticator, ap->encapreppart);
1233   if (res != SHISHI_OK)
1234     return res;
1235 
1236   if (VERBOSE (ap->handle))
1237     printf ("Verified AP-REP successfully...\n");
1238 
1239   return SHISHI_OK;
1240 }
1241 
1242 /**
1243  * shishi_ap_rep_verify_der:
1244  * @ap: structure that holds information about AP exchange
1245  * @der: input array with DER encoded AP-REP.
1246  * @derlen: length of input array with DER encoded AP-REP.
1247  *
1248  * DER decode AP-REP and set it in AP exchange using
1249  * shishi_ap_rep_der_set() and verify it using shishi_ap_rep_verify().
1250  *
1251  * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1252  * error.
1253  **/
1254 int
shishi_ap_rep_verify_der(Shishi_ap * ap,char * der,size_t derlen)1255 shishi_ap_rep_verify_der (Shishi_ap * ap, char *der, size_t derlen)
1256 {
1257   int res;
1258 
1259   res = shishi_ap_rep_der_set (ap, der, derlen);
1260   if (res != SHISHI_OK)
1261     return res;
1262 
1263   res = shishi_ap_rep_verify (ap);
1264   if (res != SHISHI_OK)
1265     return res;
1266 
1267   return SHISHI_OK;
1268 }
1269 
1270 /**
1271  * shishi_ap_rep_verify_asn1:
1272  * @ap: structure that holds information about AP exchange
1273  * @aprep: input AP-REP.
1274  *
1275  * Set the AP-REP in the AP exchange using shishi_ap_rep_set() and
1276  * verify it using shishi_ap_rep_verify().
1277  *
1278  * Return value: Returns SHISHI_OK, SHISHI_APREP_VERIFY_FAILED or an
1279  * error.
1280  **/
1281 int
shishi_ap_rep_verify_asn1(Shishi_ap * ap,Shishi_asn1 aprep)1282 shishi_ap_rep_verify_asn1 (Shishi_ap * ap, Shishi_asn1 aprep)
1283 {
1284   int res;
1285 
1286   shishi_ap_rep_set (ap, aprep);
1287 
1288   res = shishi_ap_rep_verify (ap);
1289   if (res != SHISHI_OK)
1290     return res;
1291 
1292   return SHISHI_OK;
1293 }
1294 
1295 /**
1296  * shishi_ap_encapreppart:
1297  * @ap: structure that holds information about AP exchange
1298  *
1299  * Get ASN.1 EncAPRepPart structure from AP exchange.
1300  *
1301  * Return value: Returns the EncAPREPPart from the AP exchange, or
1302  *               NULL if not yet set or an error occured.
1303  **/
1304 Shishi_asn1
shishi_ap_encapreppart(Shishi_ap * ap)1305 shishi_ap_encapreppart (Shishi_ap * ap)
1306 {
1307   return ap->encapreppart;
1308 }
1309 
1310 /**
1311  * shishi_ap_encapreppart_set:
1312  * @ap: structure that holds information about AP exchange
1313  * @encapreppart: EncAPRepPart to store in AP.
1314  *
1315  * Set the EncAPRepPart in the AP exchange.
1316  **/
1317 void
shishi_ap_encapreppart_set(Shishi_ap * ap,Shishi_asn1 encapreppart)1318 shishi_ap_encapreppart_set (Shishi_ap * ap, Shishi_asn1 encapreppart)
1319 {
1320   if (ap->encapreppart)
1321     shishi_asn1_done (ap->handle, ap->encapreppart);
1322   ap->encapreppart = encapreppart;
1323 }
1324 
1325 #define APOPTION_RESERVED "reserved"
1326 #define APOPTION_USE_SESSION_KEY "use-session-key"
1327 #define APOPTION_MUTUAL_REQUIRED "mutual-required"
1328 #define APOPTION_UNKNOWN "unknown"
1329 
1330 /**
1331  * shishi_ap_option2string:
1332  * @option: enumerated AP-Option type, see Shishi_apoptions.
1333  *
1334  * Convert AP-Option type to AP-Option name string.  Note that @option
1335  * must be just one of the AP-Option types, it cannot be an binary
1336  * ORed indicating several AP-Options.
1337  *
1338  * Return value: Returns static string with name of AP-Option that
1339  *   must not be deallocated, or "unknown" if AP-Option was not understood.
1340  **/
1341 const char *
shishi_ap_option2string(Shishi_apoptions option)1342 shishi_ap_option2string (Shishi_apoptions option)
1343 {
1344   const char *str;
1345 
1346   switch (option)
1347     {
1348     case SHISHI_APOPTIONS_RESERVED:
1349       str = APOPTION_RESERVED;
1350       break;
1351 
1352     case SHISHI_APOPTIONS_USE_SESSION_KEY:
1353       str = APOPTION_USE_SESSION_KEY;
1354       break;
1355 
1356     case SHISHI_APOPTIONS_MUTUAL_REQUIRED:
1357       str = APOPTION_MUTUAL_REQUIRED;
1358       break;
1359 
1360     default:
1361       str = APOPTION_UNKNOWN;
1362       break;
1363     }
1364 
1365   return str;
1366 }
1367 
1368 /**
1369  * shishi_ap_string2option:
1370  * @str: zero terminated character array with name of AP-Option,
1371  *   e.g. "use-session-key".
1372  *
1373  * Convert AP-Option name to AP-Option type.
1374  *
1375  * Return value: Returns enumerated type member corresponding to AP-Option,
1376  *   or 0 if string was not understood.
1377  **/
1378 Shishi_apoptions
shishi_ap_string2option(const char * str)1379 shishi_ap_string2option (const char *str)
1380 {
1381   int option;
1382 
1383   if (strcasecmp (str, APOPTION_RESERVED) == 0)
1384     option = SHISHI_APOPTIONS_RESERVED;
1385   else if (strcasecmp (str, APOPTION_USE_SESSION_KEY) == 0)
1386     option = SHISHI_APOPTIONS_USE_SESSION_KEY;
1387   else if (strcasecmp (str, APOPTION_MUTUAL_REQUIRED) == 0)
1388     option = SHISHI_APOPTIONS_MUTUAL_REQUIRED;
1389   else
1390     option = strtol (str, (char **) NULL, 0);
1391 
1392   return option;
1393 }
1394