LCOV - code coverage report
Current view: top level - shishi/lib - ticket.c (source / functions) Hit Total Coverage
Test: GNU Shishi Lines: 13 120 10.8 %
Date: 2010-05-20 Functions: 3 11 27.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 54 3.7 %

           Branch data     Line data    Source code
       1                 :            : /* ticket.c --- Low-level ASN.1 Ticket handling.
       2                 :            :  * Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008  Simon Josefsson
       3                 :            :  *
       4                 :            :  * This file is part of Shishi.
       5                 :            :  *
       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.
      10                 :            :  *
      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.
      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                 :            : #define SHISHI_TICKET_DEFAULT_TKTVNO "5"
      26                 :            : #define SHISHI_TICKET_DEFAULT_TKTVNO_LEN 0
      27                 :            : 
      28                 :            : /**
      29                 :            :  * shishi_ticket:
      30                 :            :  * @handle: shishi handle as allocated by shishi_init().
      31                 :            :  *
      32                 :            :  * This function creates a new ASN.1 Ticket, populated with some
      33                 :            :  * default values.
      34                 :            :  *
      35                 :            :  * Return value: Returns the ticket or NULL on failure.
      36                 :            :  **/
      37                 :            : Shishi_asn1
      38                 :          2 : shishi_ticket (Shishi * handle)
      39                 :            : {
      40                 :          2 :   Shishi_asn1 node = NULL;
      41                 :            :   int rc;
      42                 :            : 
      43                 :          2 :   node = shishi_asn1_ticket (handle);
      44         [ -  + ]:          2 :   if (!node)
      45                 :          0 :     return NULL;
      46                 :            : 
      47                 :          2 :   rc = shishi_asn1_write (handle, node, "tkt-vno",
      48                 :            :                           SHISHI_TICKET_DEFAULT_TKTVNO,
      49                 :            :                           SHISHI_TICKET_DEFAULT_TKTVNO_LEN);
      50         [ -  + ]:          2 :   if (rc != SHISHI_OK)
      51                 :          0 :     goto error;
      52                 :            : 
      53                 :          2 :   return node;
      54                 :            : 
      55                 :            : error:
      56                 :          0 :   shishi_asn1_done (handle, node);
      57                 :          2 :   return NULL;
      58                 :            : }
      59                 :            : 
      60                 :            : /**
      61                 :            :  * shishi_ticket_realm_get:
      62                 :            :  * @handle: shishi handle as allocated by shishi_init().
      63                 :            :  * @ticket: input variable with ticket info.
      64                 :            :  * @realm: output array with newly allocated name of realm in ticket.
      65                 :            :  * @realmlen: size of output array.
      66                 :            :  *
      67                 :            :  * Extract realm from ticket.
      68                 :            :  *
      69                 :            :  * Return value: Returns SHISHI_OK iff successful.
      70                 :            :  **/
      71                 :            : int
      72                 :          0 : shishi_ticket_realm_get (Shishi * handle,
      73                 :            :                          Shishi_asn1 ticket, char **realm, size_t * realmlen)
      74                 :            : {
      75                 :          0 :   return shishi_asn1_read (handle, ticket, "realm", realm, realmlen);
      76                 :            : }
      77                 :            : 
      78                 :            : /**
      79                 :            :  * shishi_ticket_realm_set:
      80                 :            :  * @handle: shishi handle as allocated by shishi_init().
      81                 :            :  * @ticket: input variable with ticket info.
      82                 :            :  * @realm: input array with name of realm.
      83                 :            :  *
      84                 :            :  * Set the realm field in the Ticket.
      85                 :            :  *
      86                 :            :  * Return value: Returns SHISHI_OK iff successful.
      87                 :            :  **/
      88                 :            : int
      89                 :          0 : shishi_ticket_realm_set (Shishi * handle, Shishi_asn1 ticket,
      90                 :            :                          const char *realm)
      91                 :            : {
      92                 :            :   int res;
      93                 :            : 
      94                 :          0 :   res = shishi_asn1_write (handle, ticket, "realm", realm, 0);
      95         [ #  # ]:          0 :   if (res != SHISHI_OK)
      96                 :          0 :     return res;
      97                 :            : 
      98                 :          0 :   return SHISHI_OK;
      99                 :            : }
     100                 :            : 
     101                 :            : /**
     102                 :            :  * shishi_ticket_server:
     103                 :            :  * @handle: Shishi library handle create by shishi_init().
     104                 :            :  * @ticket: ASN.1 Ticket variable to get server name from.
     105                 :            :  * @server: pointer to newly allocated zero terminated string containing
     106                 :            :  *   principal name.  May be %NULL (to only populate @serverlen).
     107                 :            :  * @serverlen: pointer to length of @server on output, excluding terminating
     108                 :            :  *   zero.  May be %NULL (to only populate @server).
     109                 :            :  *
     110                 :            :  * Represent server principal name in Ticket as zero-terminated
     111                 :            :  * string.  The string is allocate by this function, and it is the
     112                 :            :  * responsibility of the caller to deallocate it.  Note that the
     113                 :            :  * output length @serverlen does not include the terminating zero.
     114                 :            :  *
     115                 :            :  * Return value: Returns SHISHI_OK iff successful.
     116                 :            :  **/
     117                 :            : int
     118                 :          8 : shishi_ticket_server (Shishi * handle, Shishi_asn1 ticket,
     119                 :            :                       char **server, size_t * serverlen)
     120                 :            : {
     121                 :          8 :   return shishi_principal_name (handle, ticket, "sname", server, serverlen);
     122                 :            : }
     123                 :            : 
     124                 :            : /**
     125                 :            :  * shishi_ticket_sname_set:
     126                 :            :  * @handle: shishi handle as allocated by shishi_init().
     127                 :            :  * @ticket: Ticket variable to set server name field in.
     128                 :            :  * @name_type: type of principial, see Shishi_name_type, usually
     129                 :            :  *             SHISHI_NT_UNKNOWN.
     130                 :            :  * @sname: input array with principal name.
     131                 :            :  *
     132                 :            :  * Set the server name field in the Ticket.
     133                 :            :  *
     134                 :            :  * Return value: Returns SHISHI_OK iff successful.
     135                 :            :  **/
     136                 :            : int
     137                 :          0 : shishi_ticket_sname_set (Shishi * handle,
     138                 :            :                          Shishi_asn1 ticket,
     139                 :            :                          Shishi_name_type name_type, char *sname[])
     140                 :            : {
     141                 :          0 :   int res = SHISHI_OK;
     142                 :            :   char *buf;
     143                 :            :   int i;
     144                 :            : 
     145                 :          0 :   asprintf (&buf, "%d", name_type);
     146                 :          0 :   res = shishi_asn1_write (handle, ticket, "sname.name-type", buf, 0);
     147                 :          0 :   free (buf);
     148         [ #  # ]:          0 :   if (res != SHISHI_OK)
     149                 :          0 :     return res;
     150                 :            : 
     151                 :          0 :   res = shishi_asn1_write (handle, ticket, "sname.name-string", NULL, 0);
     152         [ #  # ]:          0 :   if (res != SHISHI_OK)
     153                 :          0 :     return res;
     154                 :            : 
     155                 :          0 :   i = 1;
     156         [ #  # ]:          0 :   while (sname[i - 1])
     157                 :            :     {
     158                 :          0 :       res = shishi_asn1_write (handle, ticket, "sname.name-string", "NEW", 1);
     159         [ #  # ]:          0 :       if (res != SHISHI_OK)
     160                 :          0 :         return res;
     161                 :            : 
     162                 :          0 :       asprintf (&buf, "sname.name-string.?%d", i);
     163                 :          0 :       res = shishi_asn1_write (handle, ticket, buf, sname[i - 1], 0);
     164                 :          0 :       free (buf);
     165         [ #  # ]:          0 :       if (res != SHISHI_OK)
     166                 :          0 :         return res;
     167                 :            : 
     168                 :          0 :       i++;
     169                 :            :     }
     170                 :            : 
     171                 :          0 :   return SHISHI_OK;
     172                 :            : }
     173                 :            : 
     174                 :            : int
     175                 :          0 : shishi_ticket_set_server (Shishi * handle,
     176                 :            :                           Shishi_asn1 ticket, const char *server)
     177                 :            : {
     178                 :            :   char *tmpserver;
     179                 :            :   char **serverbuf;
     180                 :          0 :   char *tokptr = NULL;
     181                 :            :   int res;
     182                 :            :   int i;
     183                 :            : 
     184                 :          0 :   tmpserver = xstrdup (server);
     185                 :          0 :   serverbuf = xmalloc (sizeof (*serverbuf));
     186                 :            : 
     187         [ #  # ]:          0 :   for (i = 0;
     188         [ #  # ]:          0 :        (serverbuf[i] = strtok_r (i == 0 ? tmpserver : NULL, "/", &tokptr));
     189                 :          0 :        i++)
     190                 :            :     {
     191                 :          0 :       serverbuf = xrealloc (serverbuf, (i + 2) * sizeof (*serverbuf));
     192                 :            :     }
     193                 :          0 :   res = shishi_ticket_sname_set (handle, ticket,
     194                 :            :                                  SHISHI_NT_PRINCIPAL, serverbuf);
     195         [ #  # ]:          0 :   if (res != SHISHI_OK)
     196                 :            :     {
     197                 :          0 :       fprintf (stderr, _("Could not set sname: %s\n"), shishi_error (handle));
     198                 :          0 :       return res;
     199                 :            :     }
     200                 :          0 :   free (serverbuf);
     201                 :          0 :   free (tmpserver);
     202                 :            : 
     203                 :          0 :   return SHISHI_OK;
     204                 :            : }
     205                 :            : 
     206                 :            : int
     207                 :          0 : shishi_ticket_srealmserver_set (Shishi * handle,
     208                 :            :                                 Shishi_asn1 ticket,
     209                 :            :                                 const char *realm, const char *server)
     210                 :            : {
     211                 :            :   int res;
     212                 :            : 
     213                 :          0 :   res = shishi_ticket_realm_set (handle, ticket, realm);
     214         [ #  # ]:          0 :   if (res != SHISHI_OK)
     215                 :          0 :     return res;
     216                 :            : 
     217                 :          0 :   res = shishi_ticket_set_server (handle, ticket, server);
     218         [ #  # ]:          0 :   if (res != SHISHI_OK)
     219                 :          0 :     return res;
     220                 :            : 
     221                 :          0 :   return SHISHI_OK;
     222                 :            : }
     223                 :            : 
     224                 :            : /**
     225                 :            :  * shishi_ticket_get_enc_part_etype:
     226                 :            :  * @handle: shishi handle as allocated by shishi_init().
     227                 :            :  * @ticket: Ticket variable to get value from.
     228                 :            :  * @etype: output variable that holds the value.
     229                 :            :  *
     230                 :            :  * Extract Ticket.enc-part.etype.
     231                 :            :  *
     232                 :            :  * Return value: Returns SHISHI_OK iff successful.
     233                 :            :  **/
     234                 :            : int
     235                 :          2 : shishi_ticket_get_enc_part_etype (Shishi * handle,
     236                 :            :                                   Shishi_asn1 ticket, int32_t * etype)
     237                 :            : {
     238                 :            :   int res;
     239                 :            : 
     240                 :          2 :   res = shishi_asn1_read_int32 (handle, ticket, "enc-part.etype", etype);
     241                 :            : 
     242                 :          2 :   return res;
     243                 :            : }
     244                 :            : 
     245                 :            : int
     246                 :          0 : shishi_ticket_decrypt (Shishi * handle,
     247                 :            :                        Shishi_asn1 ticket,
     248                 :            :                        Shishi_key * key, Shishi_asn1 * encticketpart)
     249                 :            : {
     250                 :            :   int res;
     251                 :            :   int i;
     252                 :            :   char *buf;
     253                 :            :   size_t buflen;
     254                 :            :   char *cipher;
     255                 :            :   size_t cipherlen;
     256                 :            :   int etype;
     257                 :            : 
     258                 :          0 :   res = shishi_ticket_get_enc_part_etype (handle, ticket, &etype);
     259         [ #  # ]:          0 :   if (res != SHISHI_OK)
     260                 :          0 :     return res;
     261                 :            : 
     262         [ #  # ]:          0 :   if (etype != shishi_key_type (key))
     263                 :          0 :     return SHISHI_TICKET_BAD_KEYTYPE;
     264                 :            : 
     265                 :          0 :   res = shishi_asn1_read (handle, ticket, "enc-part.cipher",
     266                 :            :                           &cipher, &cipherlen);
     267         [ #  # ]:          0 :   if (res != SHISHI_OK)
     268                 :          0 :     return res;
     269                 :            : 
     270                 :          0 :   res = shishi_decrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
     271                 :            :                         cipher, cipherlen, &buf, &buflen);
     272                 :          0 :   free (cipher);
     273         [ #  # ]:          0 :   if (res != SHISHI_OK)
     274                 :            :     {
     275                 :          0 :       shishi_error_printf (handle,
     276                 :            :                            "Ticket decrypt failed, wrong password?\n");
     277                 :          0 :       return SHISHI_TICKET_DECRYPT_FAILED;
     278                 :            :     }
     279                 :            : 
     280                 :            :   /* The crypto is so 1980; no length indicator. Trim off pad bytes
     281                 :            :      until we can parse it. */
     282         [ #  # ]:          0 :   for (i = 0; i < 8; i++)
     283                 :            :     {
     284         [ #  # ]:          0 :       if (VERBOSEASN1 (handle))
     285                 :          0 :         printf ("Trying with %d pad in enckdcrep...\n", i);
     286                 :            : 
     287                 :          0 :       *encticketpart = shishi_der2asn1_encticketpart (handle, &buf[0],
     288                 :            :                                                       buflen - i);
     289         [ #  # ]:          0 :       if (*encticketpart != NULL)
     290                 :          0 :         break;
     291                 :            :     }
     292                 :            : 
     293         [ #  # ]:          0 :   if (*encticketpart == NULL)
     294                 :            :     {
     295                 :          0 :       shishi_error_printf (handle, "Could not DER decode EncTicketPart. "
     296                 :            :                            "Password probably correct (decrypt ok) though\n");
     297                 :          0 :       return SHISHI_ASN1_ERROR;
     298                 :            :     }
     299                 :            : 
     300                 :          0 :   return SHISHI_OK;
     301                 :            : }
     302                 :            : 
     303                 :            : /**
     304                 :            :  * shishi_ticket_set_enc_part:
     305                 :            :  * @handle: shishi handle as allocated by shishi_init().
     306                 :            :  * @ticket: Ticket to add enc-part field to.
     307                 :            :  * @etype: encryption type used to encrypt enc-part.
     308                 :            :  * @kvno: key version number.
     309                 :            :  * @buf: input array with encrypted enc-part.
     310                 :            :  * @buflen: size of input array with encrypted enc-part.
     311                 :            :  *
     312                 :            :  * Set the encrypted enc-part field in the Ticket.  The encrypted data
     313                 :            :  * is usually created by calling shishi_encrypt() on the DER encoded
     314                 :            :  * enc-part.  To save time, you may want to use
     315                 :            :  * shishi_ticket_add_enc_part() instead, which calculates the
     316                 :            :  * encrypted data and calls this function in one step.
     317                 :            :  *
     318                 :            :  * Return value: Returns SHISHI_OK iff successful.
     319                 :            :  **/
     320                 :            : int
     321                 :          0 : shishi_ticket_set_enc_part (Shishi * handle,
     322                 :            :                             Shishi_asn1 ticket,
     323                 :            :                             int32_t etype, uint32_t kvno,
     324                 :            :                             const char *buf, size_t buflen)
     325                 :            : {
     326                 :          0 :   int res = SHISHI_OK;
     327                 :            : 
     328                 :          0 :   res = shishi_asn1_write (handle, ticket, "enc-part.cipher", buf, buflen);
     329         [ #  # ]:          0 :   if (res != SHISHI_OK)
     330                 :          0 :     return res;
     331                 :            : 
     332                 :          0 :   res = shishi_asn1_write_int32 (handle, ticket, "enc-part.etype", etype);
     333         [ #  # ]:          0 :   if (res != SHISHI_OK)
     334                 :          0 :     return res;
     335                 :            : 
     336         [ #  # ]:          0 :   if (kvno == UINT32_MAX)
     337                 :          0 :     res = shishi_asn1_write (handle, ticket, "enc-part.kvno", NULL, 0);
     338                 :            :   else
     339                 :          0 :     res = shishi_asn1_write_uint32 (handle, ticket, "enc-part.kvno", kvno);
     340         [ #  # ]:          0 :   if (res != SHISHI_OK)
     341                 :          0 :     return res;
     342                 :            : 
     343                 :          0 :   return SHISHI_OK;
     344                 :            : }
     345                 :            : 
     346                 :            : /**
     347                 :            :  * shishi_ticket_add_enc_part:
     348                 :            :  * @handle: shishi handle as allocated by shishi_init().
     349                 :            :  * @ticket: Ticket to add enc-part field to.
     350                 :            :  * @key: key used to encrypt enc-part.
     351                 :            :  * @encticketpart: EncTicketPart to add.
     352                 :            :  *
     353                 :            :  * Encrypts DER encoded EncTicketPart using key and stores it in the
     354                 :            :  * Ticket.
     355                 :            :  *
     356                 :            :  * Return value: Returns SHISHI_OK iff successful.
     357                 :            :  **/
     358                 :            : int
     359                 :          0 : shishi_ticket_add_enc_part (Shishi * handle,
     360                 :            :                             Shishi_asn1 ticket,
     361                 :            :                             Shishi_key * key, Shishi_asn1 encticketpart)
     362                 :            : {
     363                 :          0 :   int res = SHISHI_OK;
     364                 :            :   char *buf;
     365                 :            :   size_t buflen;
     366                 :            :   char *der;
     367                 :            :   size_t derlen;
     368                 :            : 
     369                 :          0 :   res = shishi_asn1_to_der (handle, encticketpart, &der, &derlen);
     370         [ #  # ]:          0 :   if (res != SHISHI_OK)
     371                 :            :     {
     372                 :          0 :       shishi_error_printf (handle, "Could not DER encode encticketpart: %s\n",
     373                 :            :                            shishi_strerror (res));
     374                 :          0 :       return res;
     375                 :            :     }
     376                 :            : 
     377                 :          0 :   res = shishi_encrypt (handle, key, SHISHI_KEYUSAGE_ENCTICKETPART,
     378                 :            :                         der, derlen, &buf, &buflen);
     379                 :            : 
     380                 :          0 :   free (der);
     381                 :            : 
     382         [ #  # ]:          0 :   if (res != SHISHI_OK)
     383                 :            :     {
     384                 :          0 :       shishi_error_printf (handle,
     385                 :            :                            "Cannot encrypt encrypted part of ticket\n");
     386                 :          0 :       return res;
     387                 :            :     }
     388                 :            : 
     389                 :          0 :   res = shishi_ticket_set_enc_part (handle, ticket, shishi_key_type (key),
     390                 :            :                                     shishi_key_version (key), buf, buflen);
     391                 :            : 
     392                 :          0 :   free (buf);
     393                 :            : 
     394                 :          0 :   return res;
     395                 :            : }

Generated by: LCOV version 1.8